Logbook lives in Harbor and keeps itself current

The board's Logbook view replaces the published page: statistics, the chart
of the executable, where the code stands (with the function tiers), the
trend, milestones and the ship's log, stored as JSON in the Harbor home.
A server thread follows main: each new commit becomes a log entry and the
statistics, chart and trend point are rebuilt with the open-seas progress
tools on a scratch copy. 'harbor logbook add|stats|map|milestone|refresh'.
This commit is contained in:
KeelrLeek committed 2026-10-05 16:30:21 -05:00
1 parent 87631bec52
commit b7e09cfbd1
7 files changed
+497 -6

No files matched your search

+35
View File
@@ -262,6 +262,13 @@ def build_parser():
p.add_argument("--max-bytes", type=int, dest="max_bytes")
p.add_argument("--count", type=int, default=16)
p.add_argument("--as", dest="as_type", default="hex", choices=["hex", "int32", "uint32", "float", "double", "string"])
p = sub.add_parser("logbook", help="the project Logbook: add a log entry, set statistics, the chart or a milestone")
p.add_argument("action", choices=["add", "stats", "map", "milestone", "show", "import", "refresh"])
p.add_argument("--title")
p.add_argument("--kind", default="note")
p.add_argument("--detail", help="the entry text (or --file)")
p.add_argument("--file", help="a text file (add) or a JSON file (stats, map, milestone) or an export folder (import)")
p.add_argument("--no-history", action="store_true", help="stats: do not add a trend point")
p = sub.add_parser("next-functions", help="functions in your bands to decompile next, easiest first")
p.add_argument("-n", type=int, default=10)
p = sub.add_parser("defer", help="set a function aside with a reason and evidence")
@@ -718,6 +725,34 @@ def main(argv=None):
else:
res = r.lookup(args.target)
out(res, json.dumps(res, indent=1))
elif cmd == "logbook":
from . import logbook
project = harbor.project
if args.action in ("add", "stats", "map", "milestone", "import", "refresh") and who() not in harbor.coordinators:
raise HarborError("the Logbook is written by a coordinator")
text = Path(args.file).read_text(encoding="utf-8") if args.file and args.action != "import" else None
if args.action == "add":
res = logbook.add_entry(project, args.title, args.detail or text, kind=args.kind)
out(res, f"logged {res['id']}: {res['title']}")
elif args.action == "stats":
res = logbook.set_stats(project, json.loads(text), history_point=not args.no_history)
out(res, "statistics updated")
elif args.action == "map":
res = logbook.set_map(project, json.loads(text))
out(res, f"chart updated ({res['cells']} cells)")
elif args.action == "milestone":
res = logbook.upsert_milestone(project, json.loads(text))
out(res, f"milestone {res['id']} saved")
elif args.action == "refresh":
from . import logbook_auto
res = logbook_auto.refresh(project, force=True)
out(res, json.dumps(res))
elif args.action == "import":
res = logbook.import_export(project, args.file)
out(res, json.dumps(res))
else:
res = logbook.read_all(project, log_limit=10)
out(res, "\n".join(f"{e['at'][:16]} [{e['kind']}] {e['title']}" for e in res["log"]))
elif cmd in ("next-functions", "defer", "progress"):
from .queue import FunctionQueue
q = FunctionQueue(harbor)