Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
252 commits
Select commit Hold shift + click to select a range
1f34936
fix(agents, hooks): the mods plugin names a subagent's model in its d…
genesiscz Oct 22, 2026
ecc7238
feat(agents, hooks): the mods plugin writes a subagent's model into t…
genesiscz Oct 22, 2026
ac2463b
feat(agents, hooks): the mods plugin puts a subagent's model in front…
genesiscz Oct 22, 2026
24c10f1
feat(worker): the shared worker contract carries a per-tier review bl…
genesiscz Oct 22, 2026
31808fa
feat(codex): spawn --mode review takes a base, injects the diff manif…
genesiscz Oct 22, 2026
f2b19a3
feat(codex): tools codex reviews lists every review run from the ledg…
genesiscz Oct 22, 2026
4d13c8d
docs(skills, babysit, handoff-to): reviews spawn with --mode review -…
genesiscz Oct 22, 2026
8ca69d7
feat(codex): tools codex reviews import backfills the review ledger f…
genesiscz Oct 22, 2026
db30b8d
fix(plugins, hooks): area rules forget only the compacting agent's ar…
genesiscz Oct 22, 2026
00991ca
fix(codex): reviews import logs each import to the day log only, sinc…
genesiscz Oct 22, 2026
41f86c0
feat(agents, hooks): the mods plugin gains /decisions, reply links, a…
genesiscz Oct 22, 2026
432543d
fix(codex, babysit): #507 followup - the review gate keeps underscore…
genesiscz Oct 23, 2026
f8fd3fb
feat(agents, hooks): the mods band gets sidebars like the /diff panel…
genesiscz Oct 23, 2026
d43e118
fix(codex): #507 followup - a review ledger append after a torn last …
genesiscz Oct 23, 2026
8467cfa
fix(du): identify the index volume by its APFS UUID, so a reboot that…
genesiscz Oct 23, 2026
81e72bf
feat(notifications): one ledger of every notification at ~/.genesis-t…
genesiscz Oct 23, 2026
5e0a6e3
feat(GenesisKit, GenesisHub, widgets): the inbox button lists every s…
genesiscz Oct 23, 2026
659b4d4
docs(skills, ux): name the commit of the widget inbox findings
genesiscz Oct 23, 2026
95daa5e
feat(gitlab): a review is signed by $GENESIS_TOOLS_AGENT when --agent…
genesiscz Oct 23, 2026
cb8c22d
fix(agents, hooks): a diff the hook showed itself goes to <call>.hook…
genesiscz Oct 23, 2026
ba34f4e
feat(notifications): GenesisKit NotificationEngine is the one door to…
genesiscz Oct 23, 2026
93fcb07
feat(ai, notifications): session rows carry alive, read at serve time…
genesiscz Oct 23, 2026
844bfd9
feat(GenesisKit, GenesisHub, widgets): bubbles answer the pointer, th…
genesiscz Oct 23, 2026
f23da41
feat(GenesisKit, markdown): open tabs fall into groups by project, fo…
genesiscz Oct 23, 2026
1ac711d
feat(GenesisKit): Claude, Codex and Grok show their marks instead of …
genesiscz Oct 23, 2026
917e29d
feat(agents, hooks): a press on another session's cache chip in the m…
genesiscz Oct 23, 2026
0bf25e6
feat(agents, hooks): the git band says what its counts are (↑14 to pu…
genesiscz Oct 23, 2026
a3a9bf2
fix(agents, hooks): the cache chip says compacted after a compaction …
genesiscz Oct 23, 2026
0b128ba
feat(agents, hooks): the cache chip turns yellow under mods.cacheBand…
genesiscz Oct 23, 2026
8b516aa
fix(GenesisKit, markdown): a press on a tab group chip no longer leav…
genesiscz Oct 23, 2026
fd5931a
feat(tools): tools genesis-tools probe says what of GenesisTools this…
genesiscz Oct 23, 2026
a354d3b
fix(agents, hooks): the mods write a genesis.tools link only for a ki…
genesiscz Oct 23, 2026
89d3cce
feat(GenesisKit, markdown): the wrapped tab bar's bottom line is the …
genesiscz Oct 23, 2026
38395d3
fix(GenesisKit, GenesisHub, widgets): a size the hover list asks for …
genesiscz Oct 23, 2026
16b92bb
fix(GenesisHub): a link's commit range that ends in commits the PR's …
genesiscz Oct 23, 2026
c484619
feat(agents, hooks): the git band shows a row per checkout the sessio…
genesiscz Oct 23, 2026
5f8ffa7
fix(tools): tools update skips the Claude plugin steps with one line …
genesiscz Oct 23, 2026
597e9eb
fix(agents, hooks): each git band row fits the band's width on one li…
genesiscz Oct 23, 2026
aa51f3c
feat(agents, hooks): the Git sidebar says what each button does and w…
genesiscz Oct 23, 2026
efa73ad
fix(GenesisHub, flow, widgets): GenesisTools records with any Genesis…
genesiscz Oct 23, 2026
170c6ee
fix(agents, hooks): the Git sidebar folds checkouts to one line, says…
genesiscz Oct 23, 2026
513b75d
docs(skills, ux): the ledger gets the Git sidebar's three first-try d…
genesiscz Oct 23, 2026
94cf0dd
fix(GenesisKit, GenesisHub, widgets): the widget, markdown and settin…
genesiscz Oct 23, 2026
177412a
feat(GenesisKit, GenesisHub, widgets): a decision click stages the pi…
genesiscz Oct 23, 2026
6d837d8
fix(GenesisKit, Clicky): the key sound starts its audio engine off th…
genesiscz Oct 23, 2026
c9dbb8c
test(GenesisKit, GenesisHub, widgets): staging is tested from the pic…
genesiscz Oct 23, 2026
fb4e184
docs(skills, swift, ux): why today's widget and Clicky hangs reached …
genesiscz Oct 23, 2026
d1d1a48
docs(skills, performance): the native app's hangs come from the dev m…
genesiscz Oct 23, 2026
5ab1d3e
fix(GenesisKit, GenesisHub, widgets): Clicky keeps its own engine sta…
genesiscz Oct 23, 2026
9b5e0cf
docs(skills, swift): asking AVAudioEngine.isRunning waits for a start…
genesiscz Oct 23, 2026
83d9c3b
refactor(agents, hooks): appending to a file is one Host.append (the …
genesiscz Oct 23, 2026
19180ba
fix(GenesisKit, GenesisHub, widgets): a decision card, the alert popu…
genesiscz Oct 23, 2026
4628861
docs(GenesisKit, skills, swift): NoticePill's tone, details and fixes…
genesiscz Oct 23, 2026
187a6c2
fix(GenesisKit, Clicky): the key sound wires its audio graph on the s…
genesiscz Oct 23, 2026
fc3193f
docs(skills, swift): the first mainMixerNode read creates the output …
genesiscz Oct 23, 2026
de461a7
fix(GenesisKit, GenesisHub, widgets): a voice note transcription leav…
genesiscz Oct 23, 2026
ff12fdf
feat(agents, hooks): a stall catcher offers continue when a reply sto…
genesiscz Oct 23, 2026
16b463c
feat(GenesisKit, GenesisHub, widgets): the reply box microphone shows…
genesiscz Oct 23, 2026
ead72ef
fix(GenesisHub, prs): a GitLab MR with more than 100 commits opens ag…
genesiscz Oct 23, 2026
e5f5c5b
feat(GenesisKit, permissions): the vault key window shows the command…
genesiscz Oct 23, 2026
60d0c99
fix(tools): tools ms-teams sync reads messages again, since Teams ren…
genesiscz Oct 23, 2026
68e55ce
feat(agents, hooks): an optional Stop check sends an agent back once …
genesiscz Oct 23, 2026
a1c202e
feat(GenesisKit, GenesisHub, widgets): an Agents card in the widget s…
genesiscz Oct 23, 2026
ce22a2d
fix(GenesisKit, GenesisHub, widgets): a rail bubble takes clicks and …
genesiscz Oct 23, 2026
c16fc3f
fix(GenesisKit, GenesisHub, widgets): a click on the vault key window…
genesiscz Oct 23, 2026
0e4dec7
test(GenesisKit, GenesisHub, widgets): the replay picture comes from …
genesiscz Oct 23, 2026
a7672a3
docs(skills, swift): a control whose label turns fully transparent ig…
genesiscz Oct 23, 2026
cd1a647
fix(GenesisKit, GenesisHub, widgets): the dictation row shows everyth…
genesiscz Oct 23, 2026
7826e66
fix(ax-tool): a recording leaves out the windows --exclude-window-ids…
genesiscz Oct 23, 2026
bfd967c
feat(control): tools control capture session records in segments you …
genesiscz Oct 23, 2026
a673261
feat(control): capture session --no-indicator records without the red…
genesiscz Oct 23, 2026
71b6430
feat(GenesisKit): a generic screen recorder: a target picker for a wi…
genesiscz Oct 23, 2026
6a0af01
feat(GenesisKit, GenesisHub, widgets): the video button picks a windo…
genesiscz Oct 23, 2026
94b22d8
fix(GenesisKit): the recording controls go in once per recording and …
genesiscz Oct 23, 2026
fff3cfb
fix(GenesisKit): the recording picker opens at its content's size eve…
genesiscz Oct 23, 2026
caf5608
docs(skills, swift, ux): a reused hosting view measures 0x0 after a n…
genesiscz Oct 23, 2026
df382f4
fix(agents, hooks): the decision reminder ignores text in quotation m…
genesiscz Oct 23, 2026
2cbf75a
feat(control): under an agent, a call that would bring an app to the …
genesiscz Oct 23, 2026
00e4f71
docs(skills, macos-control, control): the macos-control skill puts th…
genesiscz Oct 23, 2026
d053fc9
feat(agents, hooks): the git band names a worktree <repo>/<worktree>,…
genesiscz Oct 24, 2026
3615e33
fix(control): the first recording after a recorder source change comp…
genesiscz Oct 24, 2026
295e528
fix(control): a recording segment that never got its first frame keep…
genesiscz Oct 24, 2026
593272d
fix(GenesisKit, GenesisHub, widgets): the recording controls say why …
genesiscz Oct 24, 2026
823097c
feat(GenesisKit, permissions): opening a Privacy pane floats the app'…
genesiscz Oct 24, 2026
22089d5
docs(skills, swift): a window per listed item stalled the main thread…
genesiscz Oct 24, 2026
87f2be2
fix(question, GenesisHub, widgets): a Claude session open in two term…
genesiscz Oct 24, 2026
d6ec41f
fix(GenesisKit, GenesisHub, widgets): a decision send says what arriv…
genesiscz Oct 24, 2026
bcb82bb
fix(ai, history): a Claude session is titled by the name Claude Code …
genesiscz Oct 24, 2026
13cbd73
feat(agents, hooks, question): the mods get a Decisions and an Inbox …
genesiscz Oct 24, 2026
690fe69
fix(GenesisKit, GenesisHub, widgets): a glass panel is one surface fo…
genesiscz Oct 24, 2026
8c431c5
feat(GenesisKit, GenesisHub, widgets): switching sessions shows the c…
genesiscz Oct 24, 2026
352cf13
docs(skills, swift, ux): the hover list that closed under a scrolling…
genesiscz Oct 24, 2026
ce210fe
fix(agents, hooks): a band chip opens its sidebar on a narrow termina…
genesiscz Oct 24, 2026
4d91d9c
fix(question): the session read lists its pending forms from a read s…
genesiscz Oct 24, 2026
665535c
feat(agents, hooks, question): the decision store owns staged answers…
genesiscz Oct 24, 2026
d187605
fix(GenesisKit, GenesisHub, widgets): the hover list stays open while…
genesiscz Oct 24, 2026
1e0e919
fix(GenesisKit): the open notes of a repository share one tools agent…
genesiscz Oct 24, 2026
16d902b
feat(GenesisKit, GenesisHub, hub): a burst of child processes is logg…
genesiscz Oct 24, 2026
2745d3e
docs(skills, swift, ux): the hover list closed because SwiftUI's hove…
genesiscz Oct 24, 2026
415d159
fix(GenesisKit): spawn.storm fires at 40 starts in 10 s or 16 running…
genesiscz Oct 24, 2026
5b3eb4e
fix(agents, hooks): the Decisions and Inbox sidebars read the answer …
genesiscz Oct 24, 2026
25ebfaa
feat(GenesisKit): the markdown viewer gets a Settings window (⌘,) wit…
genesiscz Oct 24, 2026
6f179ed
docs(skills, ux): a code audit with passes, search recipes and a scan…
genesiscz Oct 24, 2026
d701b26
docs(skills, performance): the patterns the ledger taught since 2026-…
genesiscz Oct 24, 2026
3e80832
fix(GenesisKit, GenesisHub, widgets): the hover list no longer shrink…
genesiscz Oct 24, 2026
d6adbef
docs(skills, swift, ux): the hover list's real cause was the clear pa…
genesiscz Oct 24, 2026
4e25003
fix(GenesisKit): a spawn.storm label leaves out commit ids and revisi…
genesiscz Oct 24, 2026
6660770
fix(GenesisKit): a spawn.storm ends at the first start or finish that…
genesiscz Oct 24, 2026
0cb5df6
docs(skills, ux): size the surface before an audit (about 5,000 lines…
genesiscz Oct 24, 2026
22ed4f7
docs(skills, swift): a code audit distilled from about 110 SwiftUI an…
genesiscz Oct 24, 2026
c1a5fa4
fix(youtube): the extension builds in production mode even from a she…
genesiscz Oct 25, 2026
46c5f3b
fix(GenesisKit, GenesisHub, widgets): the 88 UX gaps from the 2026-10…
genesiscz Oct 25, 2026
af9c2a3
test(GenesisKit): the rail badge, alert title, recorder failure and O…
genesiscz Oct 24, 2026
245a7f1
fix(GenesisKit, GenesisHub, widgets): review round on the UX fixes: u…
genesiscz Oct 25, 2026
892a2d1
fix(GenesisKit, permissions): review round on the UX fixes: a granted…
genesiscz Oct 25, 2026
99d681b
fix(GenesisHub, settings): review round on the UX fixes: one hub noti…
genesiscz Oct 25, 2026
ab31a59
fix(GenesisKit, GenesisHub, widgets): bot review: staged decisions co…
genesiscz Oct 25, 2026
149c519
fix(GenesisKit): bot review: Clicky restarts after an audio device ch…
genesiscz Oct 25, 2026
97476d5
fix(GenesisHub): bot review: a commit link counts only its own unpush…
genesiscz Oct 25, 2026
6709b6f
fix(GenesisKit, permissions): bot review on the UX fixes: the approva…
genesiscz Oct 25, 2026
ca253b2
fix(GenesisKit, GenesisHub, widgets): bot review on the UX fixes: a d…
genesiscz Oct 25, 2026
235854f
fix(GenesisHub, settings): bot review on the UX fixes: settings searc…
genesiscz Oct 25, 2026
0302757
fix(GenesisKit, GenesisHub, widgets): the staged list declares Reduce…
genesiscz Oct 25, 2026
2015cb8
fix(GenesisKit, GenesisHub, widgets): the session inbox filter opens …
genesiscz Oct 25, 2026
c93aec9
fix(GenesisKit, GenesisHub, permissions): the PR range lookup token a…
genesiscz Oct 25, 2026
2550b50
test(GenesisKit): the widget, recording and daemon tests read the new…
genesiscz Oct 24, 2026
328b296
fix(GenesisKit, markdown): a tab or a group drops before or after the…
genesiscz Oct 25, 2026
7586bb5
fix(GenesisKit): a test run never takes the user's keyboard focus: a …
genesiscz Oct 25, 2026
7d2fcd9
fix(GenesisKit, GenesisHub, widgets): bot review round 2: a voice not…
genesiscz Oct 25, 2026
d75d508
fix(GenesisKit): bot review round 2: Clicky restarts after a device c…
genesiscz Oct 25, 2026
c060966
fix(GenesisHub): bot review round 2: Whole PR cancels a local-commit …
genesiscz Oct 25, 2026
ca6a0a1
fix(GenesisKit, GenesisHub, widgets): bot review round 2: with Send a…
genesiscz Oct 25, 2026
4ed79ed
fix(GenesisHub): bot review round 2: a pane notice carries its tone, …
genesiscz Oct 25, 2026
b8d12ea
docs(rules): the Genesis install now starts Genesis Markdown after ev…
genesiscz Oct 25, 2026
8df7f47
fix(GenesisKit, markdown): the viewer says a failed save, a failed di…
genesiscz Oct 25, 2026
98849d8
feat(Clicky): Clicky picks its audio output: a device of your choice …
genesiscz Oct 25, 2026
795bebb
feat(agents, hooks): mods.agentRow names each subagent's model beside…
genesiscz Oct 25, 2026
af7efa2
docs(agents, hooks): the agent-model mod's header names subagentStatu…
genesiscz Oct 25, 2026
cffba78
fix(GenesisKit, GenesisHub, widgets): bot review round 3: staging an …
genesiscz Oct 25, 2026
81af416
fix(GenesisKit, GenesisHub, widgets): bot review round 3: settings se…
genesiscz Oct 25, 2026
66777d4
fix(Clicky): the performance page reaches back 2 years: minutes past …
genesiscz Oct 25, 2026
3b0d705
fix(GenesisHub): a Cmd+Tab back to GenesisTools that shows no window …
genesiscz Oct 25, 2026
357236e
fix(GenesisKit, markdown): discarding unsaved edits asks first and na…
genesiscz Oct 25, 2026
78483cb
fix(GenesisKit, diff): a diff that fails to draw says so with Reload,…
genesiscz Oct 25, 2026
34069bb
fix(GenesisKit, diff): git states read as words (Modified, In conflic…
genesiscz Oct 25, 2026
fdb3323
fix(GenesisKit, markdown): the default-app prompt no longer blocks Qu…
genesiscz Oct 25, 2026
6442986
fix(GenesisKit, markdown): the find bar offers Use the web renderer i…
genesiscz Oct 25, 2026
7c50bd5
fix(GenesisKit, markdown): Settings gets Tabs and Previews cards (pre…
genesiscz Oct 25, 2026
137b42d
fix(GenesisKit, markdown): the viewer's messages get one slot with a …
genesiscz Oct 25, 2026
acde760
fix(GenesisKit, markdown): the native panes follow the zoom and the t…
genesiscz Oct 25, 2026
172f541
fix(GenesisKit, markdown): the reading page answers a dead heading li…
genesiscz Oct 25, 2026
123e6df
fix(GenesisKit, markdown): the file sidebar works from the keyboard: …
genesiscz Oct 25, 2026
c4e3c2d
fix(GenesisKit, markdown): a Changes pane that cannot read the diff s…
genesiscz Oct 25, 2026
5a113ca
fix(GenesisKit, markdown): Close Other Tabs names its count, is one U…
genesiscz Oct 25, 2026
6c7d467
fix(dashboards, diff-viewer): a reveal or a find match in the diff pa…
genesiscz Oct 25, 2026
923e297
fix(GenesisKit, markdown): the native reading pane follows the window…
genesiscz Oct 25, 2026
493200f
fix(GenesisKit, markdown): the toolbar toggles say on or off to Voice…
genesiscz Oct 25, 2026
031c7ae
fix(GenesisKit, markdown): Replaced N matches offers Undo, and Next C…
genesiscz Oct 25, 2026
4c20105
fix(GenesisHub): Cmd+Tab back to GenesisTools shows the settings, per…
genesiscz Oct 25, 2026
ad1837e
feat(mcp-manager): sign in to servers without dynamic registration (H…
genesiscz Oct 25, 2026
18149c8
fix(Clicky): charts open on the whole picked range and zoom out to it…
genesiscz Oct 25, 2026
4ec1135
feat(Clicky): one range, retention and comparison logic for both stat…
genesiscz Oct 25, 2026
44687bd
feat(Clicky): Stats gets a date range with totals, daily average, act…
genesiscz Oct 25, 2026
a48890c
fix(update): no plugin prompt without a terminal (it hung agents fore…
genesiscz Oct 25, 2026
c65d03d
feat(update): the steps after the pull run the freshly pulled code in…
genesiscz Oct 25, 2026
0c28e30
fix(GenesisKit, GenesisHub, widgets): the alert popup beside the rail…
genesiscz Oct 25, 2026
59fc34d
fix(update): tools update dev from a checkout switched to unified by …
genesiscz Oct 25, 2026
2fb8fb5
fix(GenesisKit, permissions): an install without some parts is stale …
genesiscz Oct 25, 2026
c06d18c
chore(tools): neutral names instead of the notes vault and internal r…
genesiscz Oct 25, 2026
611e6ee
Merge remote-tracking branch 'origin/feat/2026-10-13-enhancements-uni…
genesiscz Oct 25, 2026
370b8a8
fix(tools): the tool-command guard reads a command name held in a con…
genesiscz Oct 25, 2026
8a858c4
fix(update): the dev help names tools update through toolCommand
genesiscz Oct 25, 2026
333a0a4
fix(skills, babysit): the gate snapshot skips a dangling dependency l…
genesiscz Oct 25, 2026
2771158
fix(GenesisKit, markdown): the file sidebar's folder name fits again:…
genesiscz Oct 25, 2026
c250b24
feat(agents, hooks, question): the Decisions sidebar puts the staged …
genesiscz Oct 25, 2026
0751d8a
fix(claude, agents, hooks): a cache chip press focuses only a cmux pa…
genesiscz Oct 25, 2026
0414152
feat(agents, hooks): the agents panel rows name the model and its eff…
genesiscz Oct 25, 2026
1ee5f45
fix(question, claude): a decision is never reported delivered to a Cl…
genesiscz Oct 25, 2026
9c15ba3
feat(ai, history): every provider reader reads a session backwards fr…
genesiscz Oct 25, 2026
060d3c7
feat(agents, hooks, question): the decision Stop hook reads the user'…
genesiscz Oct 25, 2026
8b1e822
docs(rules): every transcript fact is a required provider reader memb…
genesiscz Oct 25, 2026
ef643bd
fix(ai, history): a session tail read that stops at its cap, and an a…
genesiscz Oct 25, 2026
a84796e
fix(question): a chat answer's evidence comment gives the local time,…
genesiscz Oct 25, 2026
780532c
fix(GenesisKit, GenesisHub, widgets): the widget no longer folds unde…
genesiscz Oct 25, 2026
f0ae687
feat(GenesisKit, GenesisHub, widgets): a Panel background setting (Da…
genesiscz Oct 25, 2026
90c2ea5
fix(GenesisHub): the hub's session list refreshes every minute while …
genesiscz Oct 25, 2026
7295fab
feat(GenesisKit, GenesisHub): a navigation history engine that logs e…
genesiscz Oct 25, 2026
a020147
feat(hub): tools hub nav keeps the hub's navigation log in SQLite (wh…
genesiscz Oct 25, 2026
1cbefbe
feat(GenesisKit, GenesisHub): the hub's Back and Forward walk the sha…
genesiscz Oct 25, 2026
3fcf4f4
refactor(GenesisHub, hub): the hub keeps its rows in one database, hu…
genesiscz Oct 25, 2026
33430fc
fix(GenesisKit, GenesisHub, widgets): the alert card lists the decisi…
genesiscz Oct 25, 2026
574fc16
fix(GenesisKit, GenesisHub, widgets): a session's inbox lays out its …
genesiscz Oct 25, 2026
e59af9f
perf(tools): the root TypeScript program checks with 24% fewer instan…
genesiscz Oct 25, 2026
c05c314
perf(package-store, youtube): Stripe is a package-store package insta…
genesiscz Oct 25, 2026
db5b741
docs(tsconfig, dashboards): the utils tsconfig says truly how it mirr…
genesiscz Oct 25, 2026
2756886
feat(ts): tools ts program measures what a TypeScript program costs t…
genesiscz Oct 25, 2026
0ed7019
perf(ai, artifact): the AI model type is the exported LanguageModel i…
genesiscz Oct 25, 2026
9747187
docs(skills, performance): the performance skill learns type-check co…
genesiscz Oct 25, 2026
8b93532
fix(ts): tools ts program measures with a 16 GiB heap unless --heap a…
genesiscz Oct 25, 2026
63c43dd
fix(Clicky): the menu bar popover takes its content's size before it …
genesiscz Oct 25, 2026
a3591b2
fix(Clicky): Clicky settings… in the menu bar popover opens Clicky's …
genesiscz Oct 25, 2026
75986b8
feat(ai-proxy, codex, ai): a Codex model catalog from the live list, …
genesiscz Oct 25, 2026
43d3239
fix(agents, hooks, question): the question nudge reads the decision l…
genesiscz Oct 25, 2026
285d535
feat(agents, hooks): every chat-answer run is logged with each user m…
genesiscz Oct 25, 2026
6fb6788
feat(ai-proxy): every codex account status reads its token through Co…
genesiscz Oct 25, 2026
2ee08bb
feat(ci): lint-rules no-transcript-format-outside-readers fails a Cla…
genesiscz Oct 25, 2026
8bf2c6c
fix(ts): #571 followup - tools ts program stops a check at --timeout …
genesiscz Oct 25, 2026
f3792d3
fix(ai): #571 followup - the structured-output calls pass their Langu…
genesiscz Oct 25, 2026
7c78325
docs(skills, performance): #571 followup - TypeScript 6 stopped only …
genesiscz Oct 25, 2026
f3c3483
fix(ts): #571 followup - the tools ts program help examples are built…
genesiscz Oct 25, 2026
5c0a2ae
docs(tsconfig): #571 followup - TypeScript 6 adds no @types package t…
genesiscz Oct 25, 2026
296e787
fix(ai, history): readBackward walks a row's entries with a plain loo…
genesiscz Oct 25, 2026
c33f2ab
feat(ci): eight more lint rules keep agent homes, harness branches, h…
genesiscz Oct 25, 2026
dd1f077
feat(ai-proxy, ai): one prompt cache key per conversation, Claude Cod…
genesiscz Oct 25, 2026
7023872
fix(ts): #571 followup - tests prove a check's deadline and abort kil…
genesiscz Oct 25, 2026
a5ada58
bench(ai, history): readSessionBackward on real Claude transcripts, o…
genesiscz Oct 25, 2026
7b1e3ff
feat(ai-proxy): session records and gts_ session keys, owner-equivale…
genesiscz Oct 25, 2026
3a5a39c
fix(ci): the lint ratchet comments name their 2026-10-25 survey notes…
genesiscz Oct 25, 2026
3f9aa13
fix(ts): #571 followup - the runner tests probe the fixture child wit…
genesiscz Oct 25, 2026
276f16f
fix(ts): #571 followup - cap program --timeout at the timer limit and…
genesiscz Oct 25, 2026
d6ccdd0
test(ts): #571 followup - the deadline tests wake on the start file e…
genesiscz Oct 25, 2026
8b3d0f7
fix(ai-proxy, hub): the codex bind help, its legacy-login warning and…
genesiscz Oct 25, 2026
7f51404
docs(ci): the ratchet lint rules and their lists name the handoff tha…
genesiscz Oct 25, 2026
3ec3ec7
feat(ts): tools ts program sites ranks what costs the checker by what…
genesiscz Oct 25, 2026
d20be91
fix(GenesisKit, markdown, GenesisHub, hub): a file whose folder was m…
genesiscz Oct 25, 2026
a694643
fix(git, utils): tools git changes pairs a folder moved outside git i…
genesiscz Oct 25, 2026
3b68144
fix(GenesisKit, markdown): the repository status and its file dates f…
genesiscz Oct 25, 2026
70b685c
test(GenesisKit, markdown): a repository panel bench: the viewer's re…
genesiscz Oct 25, 2026
e3f4c78
test(GenesisKit, markdown): the repository panel bench attributes by …
genesiscz Oct 25, 2026
e344f2d
test(GenesisKit, markdown): the repository panel bench samples a phas…
genesiscz Oct 25, 2026
b1e7cd4
perf(GenesisKit, markdown): a status read that finds the same status …
genesiscz Oct 25, 2026
3760141
perf(GenesisKit, markdown): the repository panel's rows live in an Ap…
genesiscz Oct 25, 2026
617ccbb
fix(GenesisKit, markdown): "No unstaged changes in this file." stays …
genesiscz Oct 25, 2026
b192cb1
fix(GenesisKit, diff): the commit sheet's file list marks the keyboar…
genesiscz Oct 25, 2026
d19ed29
feat(GenesisKit, markdown): the git sidebar has This file, Changes an…
genesiscz Oct 25, 2026
14d7438
feat(GenesisKit, markdown): the Changes tab folds its Staged, Changes…
genesiscz Oct 25, 2026
6768456
fix(GenesisKit, diff): the rename hash cache keys on the ctime too, s…
genesiscz Oct 25, 2026
b5adbdc
docs(skills, performance, swift, ux): the repository panel's lessons:…
genesiscz Oct 25, 2026
27fb1e2
docs(skills, ux): review fixes from gt-native-ux: the right SHAs per …
genesiscz Oct 25, 2026
495fe10
feat(GenesisKit, markdown): the Changes list follows the outline keys…
genesiscz Oct 25, 2026
89a02f2
perf(ai, question): structured LLM calls and decision input parsing t…
genesiscz Oct 25, 2026
13f42d5
fix(ai, history): Codex 0.164 compresses old rollouts to .jsonl.zst, …
genesiscz Oct 25, 2026
4ae5373
feat(ai-proxy, ai): tools ai-proxy sessions, session <id> [-f] and st…
genesiscz Oct 25, 2026
ea989f6
feat(ai-proxy): the Codex agent's /v1/messages goes straight to the W…
genesiscz Oct 25, 2026
a71a666
fix(ts, youtube): #571 followup - the review round on 393f073efd
genesiscz Oct 25, 2026
a22da88
feat(ai-proxy, claude): a tools claude codex session routes codex/<id…
genesiscz Oct 25, 2026
b23b5e7
test(claude): the agent-file refusal test names a home folder, a proj…
genesiscz Oct 25, 2026
ccc710e
fix(claude): the codex-worker subagent description names tools codex …
genesiscz Oct 25, 2026
57c1961
fix(GenesisKit, git): the worktree-renames contract fixture uses neut…
genesiscz Oct 25, 2026
a463130
feat(ai-proxy, claude): tools claude codex launches Claude Code with …
genesiscz Oct 25, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
8 changes: 4 additions & 4 deletions .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"$schema": "https://anthropic.com/claude-code/marketplace.schema.json",
"name": "genesis-tools",
"version": "1.0.114",
"version": "1.0.118",
"description": "Plugins for GenesisTools CLI development and management",
"owner": {
"name": "genesiscz",
Expand All @@ -11,7 +11,7 @@
{
"name": "genesis-tools",
"description": "Skills and utilities for working with GenesisTools CLI toolkit. Provides guidance for discovering, executing, and troubleshooting genesis tools with integrated workflow support.",
"version": "1.0.114",
"version": "1.0.118",
"author": {
"name": "GenesisTools"
},
Expand All @@ -26,8 +26,8 @@
},
{
"name": "genesis-tools-mods",
"description": "Claude Code mods for GenesisTools: draws the whole diff of a Bash call whose diff-hook message was cut, with Claude Code's own diff element, under the call's row, and compacts an idle session before its 1-hour prompt cache expires. Install with: tools agents hooks mods install --write.",
"version": "1.5.2",
"description": "Claude Code mods for GenesisTools, each switched by mods.<feature> in the hooks file: the whole diff of a cut diff-hook message under the call's row, the subagent's model on its rows and beside its type in the agents panel (mods.agentRow, through Claude Code's subagentStatusLine), idle compaction before the prompt cache expires, /decisions, links in the streamed reply, a git and PR band with /mod-git, [ask] on tool rows, live spinner progress, a prompt cache countdown across sessions, /tmp usage, a live agents band, and a ledger of what hooks inject with repeat dedupe; the git, agents and hooks parts open sidebars (/mod-git, /mod-agents, /mod-hooks). Every mod but the full diff and idle compaction starts off: tools agents hooks mods enable <name|all> --write. Install with: tools agents hooks mods install --write.",
"version": "1.16.0",
"author": {
"name": "GenesisTools"
},
Expand Down
59 changes: 59 additions & 0 deletions .claude/rules/agent-transcripts.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
---
paths:
- "src/agents/**"
- "src/question/**"
- "src/hub/**"
- "src/claude/**"
- "src/codex/**"
- "src/grok/**"
- "src/ai-spend/**"
- "src/genesis-tools-mcp/**"
- "src/utils/agent-sessions/**"
- "src/utils/ai/transcripts/**"
- "src/utils/session-transcript/**"
- "src/utils/cmux/**"
- "src/utils/claude/**"
- "plugins/**"
---

# Reading a coding agent's transcript (Claude, Codex, Grok)

Loaded by Claude Code when you read, write or edit a file in a folder that reads agent sessions. Martin's rule
(2026-10-25): every fact read from a session transcript is a member of the provider interface, implemented by every
provider, so a new provider is a list of members to fill in and no feature parses a transcript format itself.

- **The interface is `NativeSessionReader`** (`src/utils/agent-sessions/types.ts`), reached through
`ProviderPlugin.codingAgent` and `resolveHistoryProvider(kind)` (`src/utils/agent-sessions/provider.ts`).
Claude, Codex and Grok implement it in `src/utils/agent-sessions/readers/<provider>.ts`. Never add another
provider registry or a `switch (harness)` over transcript formats in a tool.
- **A new transcript capability is a REQUIRED member**, implemented by all three readers in the same change. The
compiler then names every provider (and test fake) that lacks it. When a provider cannot answer, its member says
so in code and in a comment (Grok's chat history carries no timestamps, so its `readBackward` is bounded by
content and bytes, never by time). An optional member lets the next provider forget it; do not add one for a
capability features rely on.
- **Members today:** `discover`, `read`, `readMetadata`, `scan`, `readRecords`, `readStatistics`, and
`readBackward` (the newest entries, from the end back to the entry a caller's `until` accepts; added 2026-10-25
for the decision Stop hook's chat answers). A hook or tool reaches it with `readSessionBackward({ kind,
transcriptPath, until })` (`src/utils/agent-sessions/session-backward.ts`).
- **What a feature gets is normalized**: `NativeHistoryEntry` (role, text, timestamp, tool, paths). Logic over it
(decision answers in `src/question/lib/decisions/chat-answers.ts`, a reply's decision blocks) is provider-neutral
and never names a JSONL field such as `"type":"assistant"`, `response_item`, `continued-in` or `chat_history`.
- **Legacy parsers still exist** (about 20 folders read transcript rows directly: the decision hook's `finalReply`,
`src/claude/lib/usage/session-rows.ts` for `continued-in`, `src/utils/ai/transcripts/`). Do not copy them. When a
change touches one, move the fact it reads into a reader member first.
- **Lint enforces it**: `no-transcript-format-outside-readers` in `scripts/ci/lint-rules.ts` fails a transcript record
type or field literal (`"continued-in"`, `"turn_context"`, `'"type":"user"'`, …) outside the readers. The files that
still do it are listed in `scripts/ci/transcript-format-ratchet.ts`; a file only ever leaves that list.
- **Four more lints guard the same seam** (2026-10-25), each with a list in `scripts/ci/` that only shrinks:
- `no-hand-built-claude-home`, `no-hand-built-codex-grok-home` (`native-home-ratchet.ts`): a path into
`~/.claude`, `~/.codex`, `~/.grok` or their env overrides goes through `nativeHome(kind)` or
`nativeSessionRoots(kind)` in `src/utils/providers/session-paths.ts`.
- `no-harness-name-branch` (`harness-ratchet.ts`): `x.harness === "codex"` or a `case "grok":` in a tool is a
provider member instead.
- `no-hook-payload-read`: a hook payload field (`transcript_path`, `tool_input`, …) is read in
`src/agents/lib/hooks/payload.ts` only; add a typed `HookPayload` field there.
- `no-agent-name-in-command-match`: finding a running agent by its command line goes through
`src/utils/process/classify.ts`.
- **A reader that caps or skips records says so in the log.** A byte cap, a timeout or a skipped row that hides
newer records logs the path, the cap and what was missed, so a frozen age or a missing prompt is found from
`~/.genesis-tools/logs/` and not by a user.
2 changes: 1 addition & 1 deletion .claude/rules/ai.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Everything AI lives under `src/utils/ai/` + `src/utils/security/`, in layers tha

**Codex account ownership:** `src/utils/ai/openai/account-binding.ts` is the shared subscription binding for native terminals, workers, usage and SDK requests. Keep immutable account/workspace identity across refresh and renames. Vault grants have one refresh owner; native auth-file references are read-only. Diagnostics use `AiConfigStore.readOnly()` for metadata too, because ordinary `load()` may run migrations. Native app-server authentication uses external tokens with ephemeral credential storage; never swap the shared home's auth file.

**Native CLI history:** extend `ProviderPlugin.codingAgent` and the readers/index under `src/utils/agent-sessions/`; do not add another provider registry. This derived history index is separate from app-owned `src/utils/ai/session/` conversations. Session identity includes provider, native ID and canonical source home. Import through the provider's native API with source-preserving provenance; never manufacture native SQLite rows or infer historical account ownership from today's login.
**Native CLI history:** extend `ProviderPlugin.codingAgent` and the readers/index under `src/utils/agent-sessions/`; do not add another provider registry. Every fact a feature reads from a transcript is a required `NativeSessionReader` member that all three providers implement: `.claude/rules/agent-transcripts.md`. This derived history index is separate from app-owned `src/utils/ai/session/` conversations. Session identity includes provider, native ID and canonical source home. Import through the provider's native API with source-preserving provenance; never manufacture native SQLite rows or infer historical account ownership from today's login.

**Cost math is `src/utils/ai/llm-cost.ts` only**: `calculateCallCostUsd` (prices cache reads and writes at their own rates) and `estimateLlmCallCostUsd`. No rate table belongs there, or anywhere new.

Expand Down
42 changes: 42 additions & 0 deletions .claude/rules/genesis-links.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
---
paths:
- "src/**/*.ts"
- "src/**/*.tsx"
- "plugins/**"
---

# Links to GenesisTools apps, and code that needs GenesisTools

Loaded by Claude Code when you read, write or edit TypeScript under `src/` or any file under `plugins/`.

A `https://<link host>/…` link (genesis.tools here) opens something only when all of these hold on the Mac that
clicks it: GenesisTools.app is installed, macOS gives https links to it, the router config has a route for that
path, and the app or command the route names is there (Genesis Markdown for `/md/`, the `tools` CLI and cmux for
`/claude/find/`). Miss one and the click goes to the browser, onto a page that does not exist. A `genesis-md://` or
`genesis-tools://` link needs its app. Never write such a link without the check below.

- **`tools genesis-tools probe`** answers it for this Mac: the CLI, the app, the router, Genesis Markdown, cmux, and
for each link kind (`md`, `finder`, `hub`, `claude-find`) whether a click opens it, by the real router config.
`probe md finder` exits 1 when one of them is missing and prints the fix command; `--url <url>` checks one link;
`--json` is for code. It reads only.
- **In `src/`**: build a link with `routerLink()` (`src/utils/browser-router/router-link.ts`), which gives the
fallback with a coded reason when the link would be dead. The lint rule `no-raw-genesis-link` fails a literal
anywhere else. Code that needs the whole picture calls `probeGenesisTools()` or `linkState(url, facts)` from
`src/utils/genesis-tools/probe.ts`.
- **In a plugin**: the marketplace installs a plugin without the GenesisTools checkout, so `tools` itself may be
missing, and a plugin file cannot import `src/`. The mods plugin asks `plugins/genesis-tools-mods/hooks/genesis.ts`:
it runs `tools genesis-tools probe --json` once per 30 minutes (a failed spawn means no CLI, so no links and no
`tools` commands), builds every link from the probe's link host, and returns undefined for a kind that does not
open. A feature that runs `tools …` checks `(await genesisProbe(host)).tools` first and shows no control that
would run it. Something that needs no router does it directly: a Finder reveal is `open -R <path>`.
- **The fallback is part of the feature.** No md link: a note gets `cursor://file<path>:<line>` or its plain path.
No finder link: a folder stays text (a plain folder path opens nothing useful). No hub or decision link: the SHA
or the `❓ DECISION n` stays text.
- **A new link kind** is an entry in `LinkTargets` (`src/utils/app-links/targets.ts`) and its routing in
`router-link.ts`, a router preset that writes its route (`src/utils/browser-router/presets.ts`), and a kind in
`GENESIS_LINK_KINDS` (`src/utils/genesis-tools/probe.ts`) plus the plugin's `LINK_KINDS`. `finder` (2026-10-23)
was only a hand-made route on one Mac until it got its preset.
- **Ask Launch Services, not Spotlight, whether an app is installed.** `appPathForBundleId()`
(`src/utils/macos/launch-services.ts`) is the lookup `open -b` and a scheme click use. On 2026-10-23 `mdfind
kMDItemCFBundleIdentifier == …` found no app on a Mac with indexing on, so the genesis-md preset read "needs app"
while Genesis Markdown opened every link.
5 changes: 3 additions & 2 deletions .claude/rules/markdown-viewer.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ day of review (PRs #499, #501).
`open -g -n ~/Applications/GenesisTools.app --args --markdown <file> --no-focus`.
- Genesis Markdown.app (GenesisPlayground) builds against this checkout's GenesisKit:
`GENESIS_KIT_PATH=<GenesisTools>/src/macos/GenesisKit bun scripts/install.ts` in `GenesisPlayground/Genesis/apps/Genesis`.
It relaunches the viewer only when it was open. Its `swift build` needs `--disable-build-manifest-caching` too.
It starts the viewer after every install, in the background (`open -g`, with its saved tabs), open before or not. Its `swift build` needs `--disable-build-manifest-caching` too.
- The diff page (`src/macos/GenesisTools/web/diff-viewer`) is bundled by `buildDiffViewer` in
`src/macos/lib/permissions/app.ts`; both installs call it.

Expand Down Expand Up @@ -58,7 +58,8 @@ day of review (PRs #499, #501).
the window before, `NSWindowController.init(window:)` drops it.

## Martin's UX calls for this viewer (2026-10-13)
- Lists of changes fold untracked files by folder, page, and stay lazy; counts are meaningful.
- Lists of changes fold untracked files by folder and build only the rows on screen (an AppKit table; no pages and
no "Show more" since 2026-10-25); counts are meaningful.
- Diffs: left strips for whole added or removed blocks, word marks inside changed lines, no row backgrounds; `+`
green, `−` red. Commit choosers are popovers with details, built when opened. Tabs: `GenSegmentedTabs`, animated.
- A pane never goes blank between two contents: the old one stays until the new one has rendered.
Expand Down
7 changes: 7 additions & 0 deletions .claude/rules/models.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@ These read the catalog and need no edit of their own:
- **The OpenRouter snapshot**: `src/utils/ai/catalog/data/openrouter-snapshot.json`, refreshed with `bun scripts/ai/update-openrouter-snapshot.ts`. A diff there is a price change; read it before you commit.
- **The handoff-to skill rankings**: `plugins/genesis-tools/skills/handoff-to/SKILL.md` and `references/codex.md`. Changing them bumps the plugin version (`.claude/rules/plugins.md`).

## Lint

Three lint rules keep model facts in the owners above, each with a list in `scripts/ci/model-facts-ratchet.ts` that
only shrinks (2026-10-25): `no-model-id-literal-outside-catalog` (a whole literal that is a model id), `no-model-price-table`
(`opus: { input: … }`) and `no-effort-vocabulary-list` (an array or union of effort words). A list of efforts for one
provider is `effortRange(from, to)` or a filter of `REASONING_EFFORTS` (`src/utils/ai/catalog/efforts.ts`).

## Checklist for a new model or a price change

1. Read the vendor's own page, not a blog: the model page (`platform.claude.com/docs/en/models/<model>`, `developers.openai.com/api/docs/models/<id>`, `docs.x.ai/developers/<model>`) and the vendor pricing page. Note the date you read it in the code comment.
Expand Down
45 changes: 45 additions & 0 deletions .claude/rules/opinionated-settings.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
---
paths:
- "src/macos/**/*.swift"
- "**/*.tsx"
- "src/*/ui/**"
- "src/dashboard/**"
- "src/dev-dashboard/**"
- "src/hub/lib/widget/**"
- "src/notify/**"
---

# Opinionated behavior gets a setting

Loaded by Claude Code when you read, write or edit native or web UI code, the widget's wire schema, or notifications.

Martin's rule (2026-10-23): when a UI change picks one way where a reasonable user could want another, the choice
is a setting with that way as its default. You decide the default and ship the setting in the same change; do not
ask first, and do not ship the behavior hard-coded.

## Opinionated means

- **Interruptions**: a sound, which sound per kind of event, a popup, a panel that opens or expands by itself, a
notification, a focus steal.
- **Attention cues**: a flash, a pulse, a badge, their length and their colour; "flash the thing that caused it" is
the expected default, and its duration is the setting.
- **Placement and order**: where a composer or toolbar sits (top or bottom), list order, which filter a list opens
with, what a list shows (only what needs you, or everything active).
- **Hover behavior**: a tooltip or a preview on hover, hover delays, whether hover opens anything at all.
- **Timings**: auto-collapse delays, how long a popup stays.

Not opinionated: a bug fix, a layout that was wrong, a missing hover effect, accessibility labels, performance.
Those are fixed, not made optional.

## How

- One preference per choice, stored where its surface already stores preferences (the widget: the zod schema in
`src/hub/lib/widget/types.ts` plus `WidgetPreferences` in GenesisKit `WidgetWireModels.swift`; a native window:
its settings store). An enum over a boolean when a third way is plausible ("auto" | "always" | "never").
- The control goes on the settings page of that surface, in the card the behavior belongs to, with a one-line detail
that says what it does. A sound picker has a play button. A list that has a filter in place gets a settings
shortcut that opens the page at its card (`<page>#<anchor>`, `.nativeSettingsAnchor`), which flashes the card's border.
- The default is your best judgment of what Martin asked for; the option you did not pick stays reachable.
- A shared component's look change keeps the old look as a named option (the `AttentionPulse` presets: the border
flash is the default, the filled flash stays as `.filledFlash`).
- Say in the reply which settings you added and their defaults.
13 changes: 13 additions & 0 deletions .claude/rules/plugins.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,19 @@ Loaded by Claude Code when you read, write or edit a file under `plugins/` or `.

- **A runtime plugin file is standalone.** The harness copies `plugins/**` out of this checkout, so no runtime plugin file imports `@genesiscz/*` or `@app/*`; inline what it needs or import a sibling file. `bun scripts/ci/check-plugin-standalone.ts` fails CI on a violation. Plain `JSON` is allowed in `plugins/**`.
- **A change users should get bumps the version** in `plugins/genesis-tools/.claude-plugin/plugin.json` and in `.claude-plugin/marketplace.json`, which holds it twice (top level and the plugin entry).
- **The mods plugin (`plugins/genesis-tools-mods/`) hot-reloads in every running session** that has its folder in
`CLAUDE_CODE_PLUGIN_DIRS` (the shell, or the `env` block of `~/.claude/settings.json`): Claude Code 2.1.296 watches
that folder in each interactive session (`CLAUDE_CODE_PLUGIN_DIR_WATCH`, on by default in a terminal) and reloads
the mods when a file is saved, so do not ask the user to run `/reload-plugins` after an edit. Proof that a save
reached the sessions: new `"why":"start"` lines in `~/.genesis-tools/agents/mods-log/git.jsonl` within seconds,
one per session (2026-10-23, 18:44). Each save reloads every session, a half-finished edit too: on 2026-10-23 a
session drew four git rows for a moment, because `git-band.tsx` already read a setting that `settings.ts` did not
have yet. Finish the files of one change before you save the one that depends on them.
- **Never start slow work from a mods `ui.render` hook.** The engine aborts a render's in-flight `$` calls when a newer
render of the same view replaces it (`$.process.run(...) aborted`), and the band redraws every second while a live
time shows. On 2026-10-23 the first `tools genesis-tools probe` ran from a render, was aborted, and the plugin kept
"no link opens" for 30 minutes in every session. Start such work from `session.start` or a timer
(`primeGenesisProbe`), let a render only read the result, and never remember a result that came from an abort.
- **Skills load live from this working tree** when the session's folder is the marketplace folder (this repo). Any other folder gets the version-keyed cache: `claude plugin update genesis-tools@genesis-tools` refreshes it, and `/reload-plugins` re-reads it in the middle of a session.
- **Codex runs this plugin too, hooks included**, from its own version-keyed cache (`~/.codex/plugins/cache/genesis-tools/genesis-tools/<version>/`, one per Codex home). An edit reaches Codex only after `codex plugin add genesis-tools@genesis-tools` in each home (`CODEX_HOME=<home> codex plugin add …`). A hook decides the harness from its payload, never from the environment (`hooks/harness.ts`).
- **A hook runs on every matching tool call.** Keep it to one `bun` start (about 35 ms) and exit early when it has nothing to say. A PostToolUse payload from a subagent carries `agent_id`; key per-agent state on it.
Expand Down
Loading