@workerstack/repo 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (438) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/LICENSE +21 -0
  3. package/README.md +0 -3
  4. package/agents/global-settings/antigravity.json +3 -0
  5. package/agents/global-settings/claude.json +6 -0
  6. package/agents/global-settings/codex.toml +2 -0
  7. package/agents/global-settings/cursor.json +3 -0
  8. package/agents/global-settings/grok.toml +36 -0
  9. package/agents/global-settings/manifest.json +36 -0
  10. package/agents/grok/hooks/orchestrate-parent.json +60 -0
  11. package/agents/grok/hooks/rtk.json +16 -0
  12. package/agents/grok/hooks/rulesync.json +3 -0
  13. package/agents/grok/roles/scout.toml +5 -0
  14. package/agents/hooks.jsonc +67 -0
  15. package/agents/mcp-policy.jsonc +16 -0
  16. package/agents/rules/overview.md +21 -0
  17. package/agents/settings/claude.json +5 -0
  18. package/agents/skills/ask/SKILL.md +13 -0
  19. package/agents/skills/auto/SKILL.md +13 -0
  20. package/agents/skills/away/SKILL.md +19 -0
  21. package/agents/skills/blast-radius/SKILL.md +54 -0
  22. package/agents/skills/bro/SKILL.md +9 -0
  23. package/agents/skills/browser/SKILL.md +16 -0
  24. package/agents/skills/clasp/SKILL.md +11 -0
  25. package/agents/skills/commit/SKILL.md +35 -0
  26. package/agents/skills/commit-and-push/SKILL.md +9 -0
  27. package/agents/skills/commit-push/SKILL.md +59 -0
  28. package/agents/skills/commit-push-deploy/SKILL.md +74 -0
  29. package/agents/skills/commit-push-release/SKILL.md +75 -0
  30. package/agents/skills/correct/SKILL.md +39 -0
  31. package/agents/skills/do/SKILL.md +21 -0
  32. package/agents/skills/explain/SKILL.md +13 -0
  33. package/agents/skills/google-workspace/SKILL.md +12 -0
  34. package/agents/skills/handoff/SKILL.md +81 -0
  35. package/agents/skills/implement-plan/SKILL.md +29 -0
  36. package/agents/skills/implement-roadmap/SKILL.md +27 -0
  37. package/agents/skills/jev/SKILL.md +17 -0
  38. package/agents/skills/listen/SKILL.md +15 -0
  39. package/agents/skills/pickup/SKILL.md +58 -0
  40. package/agents/skills/principle-attack-the-premise/SKILL.md +24 -0
  41. package/agents/skills/principle-boundary-discipline/SKILL.md +38 -0
  42. package/agents/skills/principle-build-the-lever/SKILL.md +28 -0
  43. package/agents/skills/principle-encode-lessons-in-structure/SKILL.md +15 -0
  44. package/agents/skills/principle-exhaust-the-design-space/SKILL.md +12 -0
  45. package/agents/skills/principle-experience-first/SKILL.md +22 -0
  46. package/agents/skills/principle-explain-the-number/SKILL.md +21 -0
  47. package/agents/skills/principle-fix-root-causes/SKILL.md +24 -0
  48. package/agents/skills/principle-foundational-thinking/SKILL.md +25 -0
  49. package/agents/skills/principle-guard-the-context-window/SKILL.md +16 -0
  50. package/agents/skills/principle-laziness-protocol/SKILL.md +13 -0
  51. package/agents/skills/principle-make-operations-idempotent/SKILL.md +25 -0
  52. package/agents/skills/principle-migrate-callers-then-delete-legacy-apis/SKILL.md +18 -0
  53. package/agents/skills/principle-minimize-reader-load/SKILL.md +22 -0
  54. package/agents/skills/principle-model-the-domain/SKILL.md +26 -0
  55. package/agents/skills/principle-never-block-on-the-human/SKILL.md +17 -0
  56. package/agents/skills/principle-outcome-oriented-execution/SKILL.md +25 -0
  57. package/agents/skills/principle-prove-it-works/SKILL.md +25 -0
  58. package/agents/skills/principle-redesign-from-first-principles/SKILL.md +18 -0
  59. package/agents/skills/principle-separate-before-serializing-shared-state/SKILL.md +20 -0
  60. package/agents/skills/principle-sequence-verifiable-units/SKILL.md +22 -0
  61. package/agents/skills/principle-subtract-before-you-add/SKILL.md +21 -0
  62. package/agents/skills/principle-test-behavior-not-implementation/SKILL.md +24 -0
  63. package/agents/skills/principle-type-system-discipline/SKILL.md +17 -0
  64. package/agents/skills/review-plan/SKILL.md +28 -0
  65. package/agents/skills/review-roadmap/SKILL.md +28 -0
  66. package/agents/skills/show-me/SKILL.md +21 -0
  67. package/agents/skills/speak/SKILL.md +15 -0
  68. package/agents/skills/su/SKILL.md +11 -0
  69. package/agents/skills/teach/SKILL.md +25 -0
  70. package/agents/skills/tmp/SKILL.md +54 -0
  71. package/agents/skills/typescript-best-practices/SKILL.md +32 -0
  72. package/agents/skills/typescript-best-practices/references/patterns.md +328 -0
  73. package/agents/skills/unslop/SKILL.md +62 -0
  74. package/agents/skills/write-plan/SKILL.md +33 -0
  75. package/agents/skills/write-roadmap/SKILL.md +66 -0
  76. package/agents/subagents/implementer-deep.md +57 -0
  77. package/agents/subagents/implementer-fast.md +57 -0
  78. package/agents/subagents/orchestrator.md +43 -0
  79. package/agents/subagents/researcher.md +47 -0
  80. package/agents/subagents/scout.md +44 -0
  81. package/bin/repo.ts +4 -0
  82. package/cli/actionlint-default.test.ts +38 -0
  83. package/cli/actionlint-download.test.ts +162 -0
  84. package/cli/actionlint-real.test.ts +33 -0
  85. package/cli/actionlint.constants.ts +43 -0
  86. package/cli/actionlint.test.ts +108 -0
  87. package/cli/actionlint.ts +178 -0
  88. package/cli/bin.test.ts +54 -0
  89. package/cli/bin.ts +40 -0
  90. package/cli/check-changelog.test.ts +40 -0
  91. package/cli/check-changelog.ts +12 -0
  92. package/cli/check-comments.test.ts +157 -0
  93. package/cli/check-comments.ts +123 -0
  94. package/cli/check-env-modules.test.ts +85 -0
  95. package/cli/check-env-modules.ts +56 -0
  96. package/cli/check-magic.test.ts +139 -0
  97. package/cli/check-magic.ts +120 -0
  98. package/cli/check-manifests.constants.ts +4 -0
  99. package/cli/check-manifests.test.ts +210 -0
  100. package/cli/check-manifests.ts +71 -0
  101. package/cli/check-nightly.test.ts +103 -0
  102. package/cli/check-nightly.ts +37 -0
  103. package/cli/check-ratchets-missing.test.ts +46 -0
  104. package/cli/check-ratchets-mutation.test.ts +49 -0
  105. package/cli/check-ratchets.constants.ts +20 -0
  106. package/cli/check-ratchets.test.ts +190 -0
  107. package/cli/check-ratchets.ts +193 -0
  108. package/cli/check-rejections.test.ts +220 -0
  109. package/cli/check-rejections.ts +153 -0
  110. package/cli/check-reports.ts +37 -0
  111. package/cli/check-tsconfig.test.ts +507 -0
  112. package/cli/check-tsconfig.ts +205 -0
  113. package/cli/commands.test.ts +114 -0
  114. package/cli/commands.ts +218 -0
  115. package/cli/commit-changelog.ts +27 -0
  116. package/cli/commit-msg-changelog.test.ts +93 -0
  117. package/cli/commit-msg-range.test.ts +126 -0
  118. package/cli/commit-msg-red-proof.test.ts +147 -0
  119. package/cli/commit-msg-repo.test.ts +153 -0
  120. package/cli/commit-msg.test.ts +101 -0
  121. package/cli/commit-msg.ts +194 -0
  122. package/cli/commit-range.constants.ts +17 -0
  123. package/cli/commit-range.ts +57 -0
  124. package/cli/config-knip.test.ts +70 -0
  125. package/cli/config-nightly.test.ts +84 -0
  126. package/cli/config-tdd.test.ts +46 -0
  127. package/cli/config.test.ts +576 -0
  128. package/cli/config.ts +261 -0
  129. package/cli/conventional.ts +9 -0
  130. package/cli/coverage-config.ts +62 -0
  131. package/cli/coverage.constants.ts +6 -0
  132. package/cli/coverage.test.ts +199 -0
  133. package/cli/coverage.ts +127 -0
  134. package/cli/env.constants.ts +10 -0
  135. package/cli/env.test.ts +56 -0
  136. package/cli/env.ts +72 -0
  137. package/cli/fixtures/base-config.ts +13 -0
  138. package/cli/fixtures/gate-world.ts +48 -0
  139. package/cli/fixtures/knip-run.ts +38 -0
  140. package/cli/fixtures/mutate-fakes.ts +137 -0
  141. package/cli/fixtures/planted-repo.ts +50 -0
  142. package/cli/fixtures/publish-world.ts +71 -0
  143. package/cli/fixtures/red-proof-repo.ts +72 -0
  144. package/cli/fixtures/release-context.ts +15 -0
  145. package/cli/fixtures/release-world.ts +111 -0
  146. package/cli/fixtures/stub-bin.ts +40 -0
  147. package/cli/guard-diagnostics.test.ts +157 -0
  148. package/cli/guard-diagnostics.ts +195 -0
  149. package/cli/init.test.ts +487 -0
  150. package/cli/init.ts +275 -0
  151. package/cli/knip-check-ignores.test.ts +106 -0
  152. package/cli/knip-check-real.test.ts +65 -0
  153. package/cli/knip-check.constants.ts +46 -0
  154. package/cli/knip-check.test.ts +114 -0
  155. package/cli/knip-check.ts +169 -0
  156. package/cli/knip-schema.ts +67 -0
  157. package/cli/known-failures.constants.ts +22 -0
  158. package/cli/known-failures.test.ts +138 -0
  159. package/cli/known-failures.ts +131 -0
  160. package/cli/lint/as-needs-reason.ts +41 -0
  161. package/cli/lint/boundaries.ts +73 -0
  162. package/cli/lint/class-file.ts +39 -0
  163. package/cli/lint/config-file.ts +32 -0
  164. package/cli/lint/entry-file.ts +54 -0
  165. package/cli/lint/env-in-config.ts +66 -0
  166. package/cli/lint/filename-matches-export.ts +63 -0
  167. package/cli/lint/index-file.ts +22 -0
  168. package/cli/lint/index.ts +47 -0
  169. package/cli/lint/is-reason.ts +6 -0
  170. package/cli/lint/manifest.ts +46 -0
  171. package/cli/lint/names.ts +59 -0
  172. package/cli/lint/no-commented-out-code.ts +105 -0
  173. package/cli/lint/no-mock-of-subject.ts +64 -0
  174. package/cli/lint/no-module-side-effects.ts +94 -0
  175. package/cli/lint/no-module-state.ts +58 -0
  176. package/cli/lint/no-side-effect-import.ts +17 -0
  177. package/cli/lint/no-v8-ignore.ts +18 -0
  178. package/cli/lint/script-rules.ts +9 -0
  179. package/cli/lint/skip-on-platform.constants.ts +8 -0
  180. package/cli/lint/skip-on-platform.ts +118 -0
  181. package/cli/lint/todo-needs-id.ts +63 -0
  182. package/cli/lint/types-file.ts +28 -0
  183. package/cli/lint-schema.ts +32 -0
  184. package/cli/magic/fixtures/magic-repo.ts +64 -0
  185. package/cli/magic/magic-hit.ts +2 -0
  186. package/cli/magic/magic-nodes.ts +44 -0
  187. package/cli/magic/magic-numbers.test.ts +99 -0
  188. package/cli/magic/magic-numbers.ts +117 -0
  189. package/cli/magic/magic-strings.test.ts +38 -0
  190. package/cli/magic/magic-strings.ts +81 -0
  191. package/cli/main.test.ts +853 -0
  192. package/cli/main.ts +292 -0
  193. package/cli/mutate-args.ts +79 -0
  194. package/cli/mutate-check.test.ts +147 -0
  195. package/cli/mutate-deps.ts +42 -0
  196. package/cli/mutate-edges.test.ts +150 -0
  197. package/cli/mutate-files.test.ts +100 -0
  198. package/cli/mutate-files.ts +31 -0
  199. package/cli/mutate-floors.test.ts +91 -0
  200. package/cli/mutate-floors.ts +104 -0
  201. package/cli/mutate-real-deps.ts +57 -0
  202. package/cli/mutate-real.test.ts +96 -0
  203. package/cli/mutate-report.ts +96 -0
  204. package/cli/mutate-run.ts +128 -0
  205. package/cli/mutate-shards.ts +64 -0
  206. package/cli/mutate.constants.ts +67 -0
  207. package/cli/mutate.test.ts +182 -0
  208. package/cli/mutate.ts +64 -0
  209. package/cli/nested-vitest-flags.ts +8 -0
  210. package/cli/nightly-config.constants.ts +14 -0
  211. package/cli/nightly-config.ts +62 -0
  212. package/cli/prompt.test.ts +202 -0
  213. package/cli/prompt.ts +1 -0
  214. package/cli/red-proof-edges.test.ts +78 -0
  215. package/cli/red-proof-failures.test.ts +82 -0
  216. package/cli/red-proof-tree.test.ts +157 -0
  217. package/cli/red-proof-verdict.test.ts +44 -0
  218. package/cli/red-proof.constants.ts +14 -0
  219. package/cli/red-proof.ts +202 -0
  220. package/cli/release/changelog-parse.ts +83 -0
  221. package/cli/release/changelog.test.ts +141 -0
  222. package/cli/release/changelog.ts +106 -0
  223. package/cli/release/gate-refusals.test.ts +85 -0
  224. package/cli/release/gate.test.ts +63 -0
  225. package/cli/release/gate.ts +70 -0
  226. package/cli/release/git.ts +66 -0
  227. package/cli/release/github.test.ts +128 -0
  228. package/cli/release/github.ts +46 -0
  229. package/cli/release/list-dir.test.ts +11 -0
  230. package/cli/release/list-dir.ts +6 -0
  231. package/cli/release/main.test.ts +48 -0
  232. package/cli/release/main.ts +51 -0
  233. package/cli/release/manifest.test.ts +24 -0
  234. package/cli/release/manifest.ts +34 -0
  235. package/cli/release/pack.test.ts +107 -0
  236. package/cli/release/pack.ts +76 -0
  237. package/cli/release/plan.ts +127 -0
  238. package/cli/release/publish-run.test.ts +98 -0
  239. package/cli/release/publish.test.ts +127 -0
  240. package/cli/release/publish.ts +125 -0
  241. package/cli/release/refuse.ts +5 -0
  242. package/cli/release/release-messages.constants.ts +96 -0
  243. package/cli/release/release-refusals.test.ts +149 -0
  244. package/cli/release/release.constants.ts +128 -0
  245. package/cli/release/release.test.ts +199 -0
  246. package/cli/release/release.ts +145 -0
  247. package/cli/release/version.test.ts +118 -0
  248. package/cli/release/version.ts +69 -0
  249. package/cli/release/wait.test.ts +101 -0
  250. package/cli/release/wait.ts +95 -0
  251. package/cli/script-diagnostics.test.ts +76 -0
  252. package/cli/script-diagnostics.ts +62 -0
  253. package/cli/scripts/board.ts +519 -0
  254. package/cli/scripts/browser.ts +994 -0
  255. package/cli/scripts/change-set.ts +105 -0
  256. package/cli/scripts/check-globals.ts +199 -0
  257. package/cli/scripts/ci-skips.constants.ts +17 -0
  258. package/cli/scripts/ci-skips.ts +118 -0
  259. package/cli/scripts/ci-wait-run.ts +28 -0
  260. package/cli/scripts/ci-wait.constants.ts +44 -0
  261. package/cli/scripts/ci-wait.ts +175 -0
  262. package/cli/scripts/ci.constants.ts +15 -0
  263. package/cli/scripts/ci.ts +208 -0
  264. package/cli/scripts/clean.ts +363 -0
  265. package/cli/scripts/comments-step.ts +15 -0
  266. package/cli/scripts/doctor.ts +828 -0
  267. package/cli/scripts/emit-agent-shell-tools.ts +91 -0
  268. package/cli/scripts/emit-mcp-policy.ts +402 -0
  269. package/cli/scripts/folder-map.ts +353 -0
  270. package/cli/scripts/gate-fat-tools.ts +1095 -0
  271. package/cli/scripts/gitignore-guard.ts +338 -0
  272. package/cli/scripts/google-workspace.ts +779 -0
  273. package/cli/scripts/hook-command.ts +72 -0
  274. package/cli/scripts/hook-input.ts +178 -0
  275. package/cli/scripts/hook-io.constants.ts +5 -0
  276. package/cli/scripts/hook-io.ts +46 -0
  277. package/cli/scripts/hooks-union.ts +469 -0
  278. package/cli/scripts/interactive.ts +30 -0
  279. package/cli/scripts/jev.ts +420 -0
  280. package/cli/scripts/job.ts +934 -0
  281. package/cli/scripts/jsonc.ts +9 -0
  282. package/cli/scripts/lessons.ts +564 -0
  283. package/cli/scripts/lint-baseline.ts +233 -0
  284. package/cli/scripts/lint-main.ts +24 -0
  285. package/cli/scripts/lint-skips.ts +139 -0
  286. package/cli/scripts/lint.constants.ts +6 -0
  287. package/cli/scripts/lint.ts +142 -0
  288. package/cli/scripts/listen.ts +962 -0
  289. package/cli/scripts/managed-text.ts +47 -0
  290. package/cli/scripts/orchestrate-parent.ts +1155 -0
  291. package/cli/scripts/parse-need.ts +81 -0
  292. package/cli/scripts/persist-handoff.ts +228 -0
  293. package/cli/scripts/persist-implementation.ts +276 -0
  294. package/cli/scripts/persist-plan.ts +888 -0
  295. package/cli/scripts/persist-roadmap.ts +478 -0
  296. package/cli/scripts/persist-tmp.ts +177 -0
  297. package/cli/scripts/persist.ts +54 -0
  298. package/cli/scripts/phase-files.ts +121 -0
  299. package/cli/scripts/prompt.ts +38 -0
  300. package/cli/scripts/purge-global-mcps.ts +313 -0
  301. package/cli/scripts/rejections-step.ts +37 -0
  302. package/cli/scripts/rtk-grok.ts +102 -0
  303. package/cli/scripts/scrub-spawn-prompt.ts +103 -0
  304. package/cli/scripts/scrub-text-lib.ts +58 -0
  305. package/cli/scripts/session-map.ts +69 -0
  306. package/cli/scripts/setup.ts +862 -0
  307. package/cli/scripts/skill-conflicts.ts +82 -0
  308. package/cli/scripts/speak.ts +370 -0
  309. package/cli/scripts/strategy.ts +168 -0
  310. package/cli/scripts/sync-global-settings.ts +316 -0
  311. package/cli/scripts/turn-steps.ts +249 -0
  312. package/cli/scripts/turn.ts +157 -0
  313. package/cli/scripts/typecheck-step.ts +43 -0
  314. package/cli/scripts/vscode-tasks.ts +175 -0
  315. package/cli/scripts/workspace-root.ts +160 -0
  316. package/cli/scripts/worktree.ts +806 -0
  317. package/cli/spawn.test.ts +34 -0
  318. package/cli/spawn.ts +27 -0
  319. package/cli/staged-change.constants.ts +11 -0
  320. package/cli/staged-change.ts +79 -0
  321. package/cli/stryker-preload.test.ts +50 -0
  322. package/cli/stryker-preload.ts +9 -0
  323. package/cli/sync/agents/frontmatter.test.ts +197 -0
  324. package/cli/sync/agents/frontmatter.ts +140 -0
  325. package/cli/sync/agents/hooks.test.ts +517 -0
  326. package/cli/sync/agents/hooks.ts +401 -0
  327. package/cli/sync/agents/rules.test.ts +229 -0
  328. package/cli/sync/agents/rules.ts +84 -0
  329. package/cli/sync/agents/sources.test.ts +375 -0
  330. package/cli/sync/agents/sources.ts +244 -0
  331. package/cli/sync/agents/subagents.test.ts +149 -0
  332. package/cli/sync/agents/subagents.ts +158 -0
  333. package/cli/sync/agents-text.test.ts +31 -0
  334. package/cli/sync/agents-text.ts +36 -0
  335. package/cli/sync/fixtures/copied.README.md +35 -0
  336. package/cli/sync/fixtures/copied.tgz +0 -0
  337. package/cli/sync/fixtures/maps/golden/INDEX.md +22 -0
  338. package/cli/sync/fixtures/maps-ws.tgz +0 -0
  339. package/cli/sync/git-files.test.ts +340 -0
  340. package/cli/sync/git-files.ts +197 -0
  341. package/cli/sync/git-hooks.test.ts +94 -0
  342. package/cli/sync/golden.test.ts +15 -0
  343. package/cli/sync/hooks-mode.test.ts +99 -0
  344. package/cli/sync/hosts.ts +28 -0
  345. package/cli/sync/knip-config.constants.ts +4 -0
  346. package/cli/sync/knip-config.test.ts +147 -0
  347. package/cli/sync/knip-config.ts +108 -0
  348. package/cli/sync/manifest.test.ts +78 -0
  349. package/cli/sync/manifest.ts +60 -0
  350. package/cli/sync/maps.test.ts +304 -0
  351. package/cli/sync/maps.ts +297 -0
  352. package/cli/sync/migrate.test.ts +2000 -0
  353. package/cli/sync/migrate.ts +1104 -0
  354. package/cli/sync/nightly-jobs.test.ts +63 -0
  355. package/cli/sync/nightly.constants.ts +48 -0
  356. package/cli/sync/nightly.test.ts +100 -0
  357. package/cli/sync/nightly.ts +75 -0
  358. package/cli/sync/outputs.test.ts +351 -0
  359. package/cli/sync/outputs.ts +168 -0
  360. package/cli/sync/oxlint-config.test.ts +178 -0
  361. package/cli/sync/oxlint-config.ts +168 -0
  362. package/cli/sync/release-jobs.test.ts +29 -0
  363. package/cli/sync/release-reports.test.ts +31 -0
  364. package/cli/sync/release-workflow.constants.ts +61 -0
  365. package/cli/sync/release-workflow.test.ts +192 -0
  366. package/cli/sync/release-workflow.ts +86 -0
  367. package/cli/sync/release.constants.ts +93 -0
  368. package/cli/sync/release.test.ts +187 -0
  369. package/cli/sync/release.ts +112 -0
  370. package/cli/sync/repo-dir.test.ts +371 -0
  371. package/cli/sync/repo-dir.ts +205 -0
  372. package/cli/sync/standards.constants.ts +8 -0
  373. package/cli/sync/standards.test.ts +206 -0
  374. package/cli/sync/standards.ts +179 -0
  375. package/cli/sync/stock-history.json +2796 -0
  376. package/cli/sync/stock-history.test.ts +66 -0
  377. package/cli/sync/stock-history.ts +84 -0
  378. package/cli/sync/stock.test.ts +47 -0
  379. package/cli/sync/stock.ts +24 -0
  380. package/cli/sync/trees.test.ts +621 -0
  381. package/cli/sync/trees.ts +280 -0
  382. package/cli/sync/validate.test.ts +299 -0
  383. package/cli/sync/validate.ts +402 -0
  384. package/cli/sync/workspace.test.ts +180 -0
  385. package/cli/sync/workspace.ts +138 -0
  386. package/cli/sync/write.test.ts +341 -0
  387. package/cli/sync/write.ts +231 -0
  388. package/cli/sync.test.ts +1495 -0
  389. package/cli/sync.ts +360 -0
  390. package/cli/tdd-scope.test.ts +36 -0
  391. package/cli/tdd-scope.ts +41 -0
  392. package/cli/test-files.ts +16 -0
  393. package/cli/ts-program.ts +69 -0
  394. package/cli/tsconfig.constants.ts +8 -0
  395. package/cli/workerstack-config.types.ts +21 -0
  396. package/dist/cli/env.d.ts +10 -0
  397. package/dist/cli/env.js +64 -0
  398. package/dist/presets/temp-root-env.d.ts +10 -0
  399. package/dist/presets/temp-root-env.js +20 -0
  400. package/dist/presets/temp-root.constants.d.ts +6 -0
  401. package/dist/presets/temp-root.constants.js +6 -0
  402. package/dist/presets/temp-root.d.ts +2 -0
  403. package/dist/presets/temp-root.js +60 -0
  404. package/dist/presets/vitest.constants.d.ts +16 -0
  405. package/dist/presets/vitest.constants.js +16 -0
  406. package/dist/presets/vitest.d.ts +11 -0
  407. package/dist/presets/vitest.js +67 -0
  408. package/dist/presets/workers-plugin.d.ts +10 -0
  409. package/dist/presets/workers-plugin.js +54 -0
  410. package/package.json +141 -4
  411. package/references/INDEX.md +100 -0
  412. package/references/browser.md +66 -0
  413. package/references/cascade.md +15 -0
  414. package/references/clasp.md +21 -0
  415. package/references/cloudflare.md +36 -0
  416. package/references/google-workspace.md +79 -0
  417. package/references/hooks.md +103 -0
  418. package/references/implementation-format.md +119 -0
  419. package/references/jev.md +56 -0
  420. package/references/lessons.md +73 -0
  421. package/references/listen.md +80 -0
  422. package/references/map.md +107 -0
  423. package/references/output.md +47 -0
  424. package/references/plan-format.md +264 -0
  425. package/references/review-loop.md +48 -0
  426. package/references/roadmap-format.md +104 -0
  427. package/references/rtk.md +27 -0
  428. package/references/scope.md +76 -0
  429. package/references/setup.md +42 -0
  430. package/references/speak.md +59 -0
  431. package/tsconfig/base.json +28 -0
  432. package/tsconfig/bun.d.ts +1 -0
  433. package/tsconfig/bun.json +8 -0
  434. package/tsconfig/reset.d.ts +1 -0
  435. package/tsconfig/strict.json +12 -0
  436. package/tsconfig/web.json +7 -0
  437. package/tsconfig/worker.d.ts +1 -0
  438. package/tsconfig/worker.json +8 -0
@@ -0,0 +1,36 @@
1
+ ---
2
+ tags: [cloudflare]
3
+ ---
4
+
5
+ # Cloudflare
6
+
7
+ Use `cf` for every Cloudflare task. Do not run `wrangler` yourself and do not add it to a project that has none.
8
+
9
+ ## Find the command
10
+
11
+ ```
12
+ cf cli search "<describe the task>"
13
+ <command from the result> --help
14
+ cf schema <command from the result, without the leading cf>
15
+ ```
16
+
17
+ `cf cli search` returns five matches. Pick one instead of repeating the search. Write the query as the action and resource type only: no names, domains, emails, account or resource IDs, or tokens. `cf schema` shows the API request detail for a command.
18
+
19
+ ## Project commands
20
+
21
+ - `cf dev` runs the dev server (`--local` uses local resource simulations).
22
+ - `cf deploy` deploys (`--dry-run` builds and checks without uploading).
23
+ - `cf build` builds the project.
24
+ - `cf workers types` generates types from `cloudflare.config.ts`.
25
+ - `cf init workers [directory]` creates or sets up a Workers project.
26
+ - `cf auth` manages login and profiles; `--profile <name>` picks one on any command.
27
+
28
+ `cf dev` and `cf deploy` run the dev server the project declares in `package.json`: `@cloudflare/vite-plugin` (recommended), or `wrangler` for a legacy Worker project that keeps `wrangler.jsonc`. With none declared they print the install choices and stop. Ask before adding a dependency.
29
+
30
+ ## Docs
31
+
32
+ Product docs: https://developers.cloudflare.com/ . Machine-readable index: https://developers.cloudflare.com/llms.txt .
33
+
34
+ ## Status
35
+
36
+ `cf` is in beta, so commands and config can still change. Wrangler is not deprecated yet; Cloudflare plans to maintain it for 18 months after the `cf` beta ends.
@@ -0,0 +1,79 @@
1
+ ---
2
+ tags: [google-workspace]
3
+ ---
4
+
5
+ # google-workspace
6
+
7
+ Create and edit Google Sheets, Docs, Slides, Calendar events, and Gmail from the session.
8
+
9
+ ```
10
+ bun repo google-workspace whoami
11
+ bun repo google-workspace scopes
12
+ bun repo google-workspace login
13
+ bun repo google-workspace sheet create --title "Q3" --csv "item,qty\nA,2"
14
+ bun repo google-workspace sheet set --id ID --cell A1 --value x
15
+ bun repo google-workspace sheet get --id ID --range A1:B10
16
+ bun repo google-workspace sheet append --id ID --csv "c,3"
17
+ bun repo google-workspace sheet clear --id ID --range A1:Z
18
+ bun repo google-workspace doc create --title "Notes" --body "hello"
19
+ bun repo google-workspace doc append --id ID --body "more"
20
+ bun repo google-workspace drive list --query "mimeType='application/vnd.google-apps.spreadsheet'"
21
+ bun repo google-workspace slide create --title "Deck"
22
+ bun repo google-workspace meeting create --title "Standup" --start 2026-09-15T09:00:00Z --end 2026-09-15T09:15:00Z --attendees a@x.com,b@y.com
23
+ bun repo google-workspace mail send --to you@example.com --subject hi --body hello
24
+ bun repo google-workspace mail list
25
+ ```
26
+
27
+ Each person has their own Google Cloud app. Creds stay in `~/.workerstack/` on that machine. Do not share OAuth JSON or tokens. Do not commit them. Inviting others to a meeting is attendee emails, not shared creds.
28
+
29
+ Handheld (any OS): `bun repo setup google-workspace` or `bun repo setup` → google-workspace. Opens each Cloud Console page, waits, copies the Desktop JSON into `~/.workerstack/workspace/default/google-oauth.json`, then browser Allow. Non-TTY: `--creds PATH` to a Desktop download. `--account NAME` for a second Google user.
30
+
31
+ Doctor reports google-workspace as optional: `ok` when Desktop OAuth JSON, tokens, gcloud ADC, or `~/.clasprc.json` exists, else `missing (optional)`. It prints source names (`oauth` `tokens` `adc` `clasprc`), not secrets. `clasprc` is Drive-only.
32
+
33
+ Two Google accounts on one machine: `--account NAME` (or `WORKSPACE_ACCOUNT`). Each account, `default` included, uses `~/.workerstack/workspace/NAME/`.
34
+
35
+ ```
36
+ bun repo google-workspace --account work login
37
+ bun repo google-workspace --account work whoami
38
+ bun repo google-workspace accounts
39
+ ```
40
+
41
+ Each account needs its own Desktop JSON in that folder (`google-oauth.json`) and its own `login`.
42
+
43
+ Clasp’s public OAuth client is Drive-only. Calendar and Gmail are restricted; Google blocks extra scopes on that app. Use **your** Desktop OAuth client.
44
+
45
+ ## Agent: setup e2e
46
+
47
+ If `whoami` works but `meeting` / `mail` / `sheet set` fail with missing scope or “app is blocked”, run **this user** through `bun repo setup google-workspace` (TTY). Do not reuse another person’s JSON. Do not invent a client JSON.
48
+
49
+ Local dir is created by setup (`~/.workerstack/`, mode 700 on Unix). Manual equivalent: `mkdir -p "$HOME/.workerstack" && chmod 700 "$HOME/.workerstack"` then:
50
+
51
+ 1. Open `https://console.cloud.google.com/projectcreate` — **Create**. Org can be their Workspace org. Note **Project ID** from the dashboard URL (`?project=`).
52
+ 2. Open `https://console.cloud.google.com/auth/overview/create?project=PROJECT_ID` (or **Google Auth Platform → Branding**).
53
+ - App name: anything (`autorun` is fine). That string is only the Allow screen.
54
+ - User support email: their address.
55
+ - Audience: **Internal** if the Google account is a paid Workspace org (e.g. `@rearm.co`). **Testing** + add their own address as a test user if it is a personal `@gmail.com` (Internal is not offered). APIs work on both; only this consent type changes.
56
+ - Next / Create through the wizard.
57
+ 3. Open `https://console.cloud.google.com/flows/enableapi?apiid=calendar-json.googleapis.com,gmail.googleapis.com,sheets.googleapis.com,docs.googleapis.com,drive.googleapis.com&project=PROJECT_ID` — **Enable**.
58
+ 4. Open `https://console.cloud.google.com/auth/clients/create?project=PROJECT_ID`.
59
+ - Application type: **Desktop app**.
60
+ - Create → **Download JSON**.
61
+ 5. Copy the download to `$HOME/.workerstack/workspace/default/google-oauth.json` (Windows: `%USERPROFILE%\.workerstack\workspace\default\google-oauth.json`). chmod 600 on Unix. Confirm it has `"installed"` and `client_id`. For `--account NAME`, use `$HOME/.workerstack/workspace/NAME/google-oauth.json`.
62
+ 6. From the repo: `bun repo google-workspace login` (or `--account NAME`) — browser Allow. Tokens write beside the JSON (`workspace/NAME/tokens.json`).
63
+ 7. Smoke:
64
+
65
+ ```
66
+ bun repo google-workspace whoami
67
+ bun repo google-workspace scopes
68
+ bun repo google-workspace sheet create --title smoke-sheet --csv "k,v\nok,1"
69
+ bun repo google-workspace doc create --title smoke-doc --body ok
70
+ bun repo google-workspace slide create --title smoke-slide
71
+ bun repo google-workspace meeting create --title smoke-meeting --start 2026-09-16T09:00:00Z --end 2026-09-16T09:15:00Z
72
+ bun repo google-workspace mail send --to THEIR_EMAIL --subject smoke --body ok
73
+ ```
74
+
75
+ `scopes` must include `calendar`, `gmail.modify` or `gmail.send`, `spreadsheets`, `documents`, `drive`. If login times out, they did not finish Allow; re-run `login`.
76
+
77
+ If `google-oauth.json` is missing, `login` prints `setup: bun repo setup google-workspace`. Prefer the handheld setup (it opens the Project ID URLs). Manual steps above still work.
78
+
79
+ `gcloud` on PATH is an alternate login (`gcloud auth application-default login` with the extra scopes). Still per person, still local.
@@ -0,0 +1,103 @@
1
+ ---
2
+ tags: [hooks]
3
+ ---
4
+
5
+ # Hooks
6
+
7
+ SessionStart carries only the folder map: Claude / Codex run the `session-map` hook, which injects the code-only map `bun repo map` prints as `additionalContext` (capped under Claude Code's 10,000-char per-hook `additionalContext` limit, about 2.4k tokens, below the 5k `bun repo map` budget; cache-stable, fail-open) and logs `{rows, tokens}` to `.tmp/repo/sessions/<sid>/map.json`. Inject nothing else at SessionStart. Antigravity has no generated sessionStart. Do not register a SessionStart hook on `.grok/hooks/orchestrate-parent.json`.
8
+
9
+ Grok PostToolUse / SessionStart are observe-only — do not attempt output scrub; compress via RTK / spawn / isolation facts only. Do not add PostToolUse scrub hooks. UserPromptSubmit may emit a one-line `sessionGate=ask|auto|away` plus session receipt, then up to 8 other live lines from `~/.workerstack/board/` (`hookSpecificOutput.additionalContext`). The current session's own line is omitted. Skip host Stop banners. `/ask` and `/away` exact-match slashes stamp `session-gate-{sid}` to `ask` or `away`. `/auto` unlinks. Sid-less: no stamp. Default: `auto`. The `sessionGate=` word is the effective mode: the newest `in-progress` plan or roadmap in this session's `.tmp/repo/sessions/<sid>/approvals.txt` with a valid `mode:` wins, else the stamp, else `auto`. Another session's plans never count.
10
+
11
+ In `sessionGate=ask`, parent Stop on `end_turn` blocks unless the recap asks (`?`) or is exactly `[orchestrator]: wait scout`. Reason: `ask after this step`. In `sessionGate=away`, parent Stop blocks a reply whose last line ends in `?` and is not a closing line. Reason: `away: do not ask; decide, log "- decision: {question} → {choice}, because {why}" in the plan, and continue`. Both blocks share the `stop-block` counter, cap 3, so a true blocker still reaches the person. `sessionGate=auto` does not Stop-block.
12
+
13
+ Claude / Codex / Antigravity / Cursor PreToolUse still run the `scrub-spawn-prompt` and `gate-fat-tools` hooks. Grok spawn/fat rewrite is the `orchestrate-parent` hook. RTK stays `.grok/hooks/rtk.json`, which runs the `rtk-grok` hook.
14
+ Every repo hook command finds the root (`$GROK_WORKSPACE_ROOT`, else `$CLAUDE_PROJECT_DIR`, else its git top level) and runs `<root>/node_modules/.bin/repo hook <name>`. A checkout with no install prints `repo: <root>/node_modules/.bin/repo is missing; run bun install` and exits 1, which never blocks the tool call. `bun repo sync --check` fails any repo hook in another form.
15
+ Claude Code's `WorktreeCreate` and `WorktreeRemove` come from the `claudecode` block of `hooks.jsonc` and run the `worktree` hook (60s), so its worktrees land in `.worktrees/<name>` on `wt/<name>`. Other harnesses have no such event and call `bun repo worktree add` directly.
16
+
17
+ ## Cursor
18
+
19
+ `cursor-agent` reads `.cursor/hooks.json` (JSONC, `version: 1`, camelCase events `preToolUse` `beforeSubmitPrompt` `stop` `sessionStart`, flat `{command, timeout, matcher}` entries). `bun repo sync` writes it (`cli/sync/agents/hooks.ts`) from `hooks.jsonc` with the matchers untranslated, so the gate and orchestrate-parent matchers name Cursor's tools (`Shell`, `Read`, `Write`, `Grep`) beside the others. `hooks-union.ts` appends a consumer's autorun scripts to it as flat entries (`Write` is Cursor's write matcher). Cursor also reads `.claude/settings.json` hooks and drops a command it already has in its own file, so nothing runs twice. Cursor refuses a hook file with a symlink on its path: keep `.cursor/` a real dir. It reads `AGENTS.md`, so there is no `.cursor/rules`. `bun repo sync` generates `.cursor` in each consumer (gitignored there); it is not in the package `files`.
20
+
21
+ Payload: `cursor_version`, `session_id`, `model`, `tool_name`, `tool_input`, `cwd`; no `turn_id`, no `subagent_type` (every Cursor call counts as the parent). `gate-fat-tools.ts` `harnessOf` tests a string `cursor_version` first, because `session_id` and `model` also match the Codex check. Tools the gate answers:
22
+
23
+ | Tool | Input | Gate |
24
+ | --- | --- | --- |
25
+ | `Shell` | `command`, `cwd` | denylist, `.gitignore`, `git worktree add` and main-checkout git guards; dump, search, `curl` and `ls` rewrites |
26
+ | `Read` | `file_path` | denylist, 200KB deny, re-read deny |
27
+ | `Grep` | `pattern`, `file_path`, `glob` | denylist |
28
+ | `Write` | `file_path`, `content` | main-checkout deny, scratch redirect to the root `.tmp/repo`, `.gitignore` guard; orchestrate-parent persists plans and the like |
29
+
30
+ `Read` takes no offset or limit and `Grep` no `head_limit`, so the gate injects and caps neither (`limits: false` in `TOOLS.cursor`). A re-read of a file this session wrote therefore cannot say "Read with offset+limit": Cursor's reason names `bun repo job --job exec --query 'sed -n 1,200p <file>'`. `List` and `Delete` get no answer.
31
+
32
+ Reply: a deny is `{"permission":"deny","user_message":reason,"agent_message":reason}`. A rewrite is Claude's nested `{"hookSpecificOutput":{"hookEventName":"PreToolUse","updatedInput":{...}}}` with no `permission` and no top-level field (Cursor reads the nested form only then; `permission` would also auto-approve). Cursor applies a rewritten `command` (Shell) and `file_path` (Write), but writes its own `content`: a persisted tmp write lands at the `.tmp/repo/` path with its `TMP_NAME:` line still in the body. Empty stdout with exit 0 allows. Invalid JSON on stdout blocks the call. `stop` may reply `{"decision":"block","reason":...}`. orchestrate-parent handles Cursor's `beforeSubmitPrompt` only to write `git-asked.json` (see Worktrees); there it stamps no `/ask` or `/away`, handles no `y` or `h`, prints no board line and adds no context.
33
+
34
+ Session agent tools are on. Fat Read/Grep/Glob/Bash still gate. Writes under `.tmp/repo/plans/`, `.tmp/repo/handoffs/`, `.tmp/repo/implementations/`, `.tmp/repo/roadmaps/`, and `.tmp/repo/` root files persist via `cli/scripts/persist-plan.ts` / `persist-handoff.ts` / `persist-implementation.ts` / `persist-tmp.ts` / `persist-roadmap.ts`. The hook hands the host the absolute path of the saved file. Invalid body denies. A Write of a saved plan updates that file in place (same serial); an Edit of a saved plan is checked against the text it would produce, and a valid one runs as sent. `## Previous mistakes` entries are append-only on both. Roadmaps follow the same rules: a Write of a saved roadmap is validated and the host writes it, and an Edit is checked against the text it would produce.
35
+
36
+ Writes under `.repo/lessons/` go through `bun repo lessons`: a lesson Write in a managed worktree is validated, saved, and reindexed (`INDEX.md`) there, and the same Write in the main checkout is denied with the Worktrees reason; an Edit of a lesson is denied with the Write and `lessons.ts hit` routes. Lessons match per holding checkout: the root, or the managed worktree that holds the file; an unmanaged linked worktree falls back to the caller's checkout. On any other Write or Edit, PreToolUse adds `additionalContext` for lessons whose globs match the file, each once per session (`.tmp/repo/sessions/<sid>/lessons-seen.json`). It reads only `INDEX.md` and fails open.
37
+
38
+ SubagentStop (and child Stop with `subagentType`) intercepts a parseable `need:` whose jobs are all `search|exec|slice|fetch` (cap 4): runs job in-hook and continues the child with concatenated facts. Mixed/web/test, parse fail, FALLBACK, `stopHookActive`, or more than 3 intercepts per child session → empty stdout (allow stop).
39
+
40
+ Stop and SubagentStop timeout is 30s (job cap is 20s). PreToolUse / UserPromptSubmit stay at 5s.
41
+
42
+ The canonical hooks.jsonc event is `beforeSubmitPrompt` (→ Claude/Codex `UserPromptSubmit`), not `userPromptSubmit`.
43
+
44
+ `[features] two_pass_compaction` must live in `~/.grok/config.toml` (from `agents/global-settings/grok.toml` via `bun repo yolo`). Project `.grok/config.toml` cannot set `[features]`.
45
+
46
+ ## Review strategy
47
+
48
+ A plan or roadmap carries `strategy: default|review-fast|review-deep` (`plan-format.md`). `default` adds nothing here. For `review-*` the main session reviews and an implementer agent writes (`review-loop.md`). The code is `cli/scripts/strategy.ts`, called from `gate-fat-tools.ts` and `cli/scripts/orchestrate-parent.ts`.
49
+
50
+ Stamp: a parent's save of a plan whose frontmatter holds a `review-*` strategy writes `.tmp/repo/sessions/<sid>/strategy.json`, which holds the plan's canonical path. A box tick on such a plan stamps too, so a resumed run in a new session stamps on its first save. A child's save stamps nothing. The gate writes it for every harness. orchestrate-parent calls `stampPlanSave` first for the plan Writes it persists itself. The stamp only points at the plan. `activeReview` reads the plan: it is active while `status` is `in-progress` and `strategy` is `review-*`, so `done` and `blocked` end it with no cleanup.
51
+
52
+ Deny: `reviewGuard` in `processFatTools` sits right after the worktree deny, before the write branch and the scout return. While a review is active in an enforced harness, a parent write whose target is outside the root `.tmp/` is denied. The target is judged by canonical path after the scratch rewrite, not as typed. A child, a missing `sid` and an unenforced harness are not denied. Reason: `plan {n} runs strategy {s}: this session reviews. Spawn {implementer} for product writes; the plan, the journal and .tmp/ stay writable.`
53
+
54
+ Implementer guards apply under every strategy: the spawn prompt names the worktree path, so the implementer's first Write is under `.worktrees/<name>` (the main-checkout deny holds for it too); an `implementer-*` child's write under `.tmp/repo/plans` or `.tmp/repo/implementations` is denied (`implementer writes product files and tests only; the reviewer writes the plan and the journal`), and so is a shell `git add` or `git commit` (`implementer never stages or commits; report the changed files and the reviewer stages them`).
55
+
56
+ Test runs: a plain `bun run test …` (or `vitest`, `npm test`, `pnpm test`) from an `implementer-*` child, or from a parent while a review is active, is rewritten to `<root>/node_modules/.bin/repo job --job test --query '<command>'`. The full log goes to the stash and the caller sees the failing lines. A compound command passes through.
57
+
58
+ Approval: the Stop hook blocks a reply that should ask for approval unless its last line is a closing line that names every pending item with the strategy its file holds. The block reason is `end with: ` and the line `closingLine` renders from the files. On the next prompt, a bare `y` returns `y approves plan {n}: plan {n}: run /implement-plan {n} (<path>)` and leaves the file alone. `y <strategy>` writes that strategy into each approved plan or roadmap (validated through the persist module), and the context says to re-read the file before work. An unknown word approves nothing: `unknown strategy "{word}"; use y, y default, y review-fast or y review-deep`.
59
+
60
+ The closing line `closingLine` renders, for one plan: `Reply "y" to run plan {n} (strategy: {s}), or "y {a}" / "y {b}", or "h" / "h fast" / "h deep" for a fresh session.` A queue joins items with `, then ` and keeps one `or "h" …` tail.
61
+
62
+ Settled review: a parent spawn whose prompt starts `/review-plan {n}` or `/review-roadmap {n}` records `{"plan {n}": <reviews at spawn>}` in `.tmp/repo/sessions/<sid>/reviews-open.json`, keyed by `plan {n}` or `roadmap {n}`, never by path. An item is settled when its file's `reviews` is above the recorded number, or nothing was recorded and `reviews` is at least 1. Stop blocks a closing line that names an unsettled item, before the approval and mode checks: `plan {n}'s review has not settled; wait for it, settle its findings with reviews bumped, then end with the closing line`, or on `reviews: 0`, `plan {n} has reviews: 0; run /review-plan {n} in a fresh agent first`. A Stop block fires once, so a `y` or `h` on an unsettled item is refused too: `y did not approve plan {n}: its review has not settled; wait for it, then end with the closing line again` (`h did not hand off …` for `h`). Unsettled items never count as pending.
63
+
64
+ Handoff: `h` keeps each file's strategy; `h fast` and `h deep` write `review-fast` or `review-deep` through the same validated write as `y <strategy>`. There is no `h default`. The hook writes one handoff for the whole line through `persistHandoff`: H1 `run-plan-{n}` (or `run-{kind}-{n}-then-…`), Goal names the items, State their paths and strategies, Context the source session, Next one leaf per item in order (`/implement-plan {n}`, or `set status locked, then /implement-roadmap {n}`), Watch-outs `(none)`. The context: `h handed off plan {n} (strategy review-fast written) to <abs path>; tell the person to run /pickup {serial} in a fresh session, and do no work here`.
65
+
66
+ Enforcement, from the live probe of each harness's child payload:
67
+
68
+ | Harness | Child marker | Enforced |
69
+ | --- | --- | --- |
70
+ | claude | `agent_type` and `agent_id` | yes |
71
+ | codex | `agent_type` and `agent_id`; shares the parent's `session_id` | yes |
72
+ | grok | `subagentType`, own `sessionId`; `harnessOf` reports `claude` | yes, through `claude` |
73
+ | antigravity | none; only a different `conversationId`, its only session-id key | no |
74
+ | cursor | none; only a different `session_id` | no |
75
+
76
+ An unenforced harness follows the rule as an instruction (`review-loop.md`). Cursor's `beforeSubmitPrompt` writes only `git-asked.json` in orchestrate-parent, so `y <strategy>` and `h` have no effect there and `/away` never stamps; Cursor runs Stop, so `mode:` and the Stop rules still apply. Antigravity has no Stop hook, so the settled-review and away rules are prompt-only there. Headless `cursor-agent -p` (v2026.11.05) never fires `beforeSubmitPrompt`, so no prompt can grant a git subcommand there and the git denies still apply; the Cursor IDE was not tested.
77
+
78
+ `git-asked.json` (Worktrees) is keyed by sid. Claude and Codex children share the parent's sid and so its grant; a Grok, Cursor or Antigravity child has its own sid and gets none. Antigravity has no `git-asked.json`: the gate reads `lastUserInput` from the tool call, and an agy subagent's calls carry an empty one, so a child gets no grant.
79
+
80
+ Main-session compaction window: a user setting, `modelSettings.<model>.autoCompactWindow` in `~/.claude/settings.json`. Each agent carries its own value in its `claudecode` block. Do not set `CLAUDE_CODE_AUTO_COMPACT_WINDOW`: it overrides every agent's value.
81
+
82
+ ## Worktrees
83
+
84
+ The main checkout is `root` (`resolveRoots().root`), outside `<root>/.tmp` and `<root>/.worktrees`. The gate (`gate-fat-tools.ts` `sharedCheckoutReason`, `worktree.ts` `mainCheckoutWriteReason` and `sharedGitReason`) answers for every caller, parent, scout and implementer alike, on every harness whose write tools it knows. It runs beside the `git worktree add` check, ahead of `reviewGuard` and every early return.
85
+
86
+ - Write: a write whose canonical target (after the scratch redirect) is in the main checkout is denied: `the main checkout is shared: run bun repo worktree add <name> and write under <root>/.worktrees/<name>; only <root>/.tmp/ is writable here`. A lesson Write is answered by orchestrate-parent before the gate, so it calls `mainCheckoutWriteReason` itself. `lessons.ts` `persistLesson`, `hitLesson` and `removeLesson` return `{ ok: false, error }` with the same text, and the CLI `hit`, `rm` and `index` exit 1; `match` and `check` stay read-only, and `writeIndex` is unguarded because `bun repo init` and `bun repo sync` call it in a consumer's main checkout.
87
+ - Git in the main checkout: `commit`, `merge`, `cherry-pick`, `revert`, `am` and `pull` are denied with `the main checkout is shared: commit inside <root>/.worktrees/<name>, then run cd <root> && bun repo worktree finish <name>`. `stash`, `reset`, `checkout`, `switch`, `restore`, `clean` and `rebase` are denied with `git <sub> in the main checkout can destroy other sessions' work: do it inside your worktree, or run it here only when the user's message asks for git <sub>`.
88
+ - Anywhere in the repo: a force push (`-f`, `--force`, `--force-with-lease`, `+ref`); `branch -d|-D|-f|-m|-M` of the default branch; `update-ref` of the default branch. The default branch is `origin/HEAD`, else `init.defaultBranch`, `main` or `master` when it exists locally, else the main checkout's current branch.
89
+ - Own worktree: inside the managed worktree the effective cwd is in (`cd` and `git -C` are followed), every other git command runs, `stash`, `reset --hard`, `checkout`, `rebase` and `commit --amend` included.
90
+ - Exception: `.tmp/repo/sessions/<sid>/git-asked.json` holds `{ "words": [...] }`, rewritten on every user prompt (an empty list clears it) by orchestrate-parent on Claude, Codex and Grok `UserPromptSubmit` and on Cursor's `beforeSubmitPrompt`, and read by the gate by sid. A named word lets that subcommand run for the turn. Bare words grant only `stash`, `commit` (so `/commit` grants it), `rebase` and `cherry-pick`; a force push needs `force push`, `force-push`, `push -f` or `push --force`; every other subcommand needs the literal `git <sub>`, since "main checkout", "clean up" and "merge to main" are everyday phrases. A negation ("don't stash") matches too, so the `AGENTS.md` line still applies. Claude and Codex children share the parent's sid and so its grant; Grok and Cursor children do not. Antigravity (1.5.3) writes no file: every tool call carries the user's message as top-level `lastUserInput`, and the gate feeds it through the same word rules. Only the main agent's calls carry it; an agy subagent's calls carry `lastUserInput: ""`, so a child gets no grant and a spawn prompt cannot grant one. Antigravity's gated tools are `write_file {Path, Content}`, `edit_file {Path, Target, Replacement}` and `run_command {CommandLine}`; `read_file {Path, StartLine, EndLine}` is not gated. Headless `cursor-agent -p` (v2026.11.05) never fires `beforeSubmitPrompt` either, so no prompt can grant a git subcommand there and the denies still apply; the Cursor IDE was not tested.
91
+ - Fail-open: not a git repo, a repo with no commit yet, and an error inside the check let the call through. A missing `sid` or an unwritable `git-asked.json` means no grant, so the deny stands. `finish`, `prune` and the `WorktreeRemove` hook run git from node, never the shell, so the git deny cannot block them.
92
+ - Not parsed: `bash -c '...'`, `$(...)` and `xargs git` hide a git command from the gate. An `rtk` or `env VAR=v` prefix and `cd <dir>` or `git -C <dir>` are parsed; a heredoc body is not a command.
93
+ - Shell-write gap: `sed -i`, `>`, `tee` and `rm` write the main checkout past the write deny, and so do the `rm` hints in `bun repo doctor`. The commit deny is the backstop: the change cannot be committed there without the user's message naming commit.
94
+ - `bun repo init` and `bun repo sync` rewrite tracked files from node, so run them inside a worktree. Run in the main checkout they leave it dirty, and only the user can commit that.
95
+ - Unmanaged linked worktrees outside `.worktrees` (T3 Code, Claude Desktop) are outside the root, so writes there pass, `finish` cannot land them, and `/commit` there only commits. They are not "own worktree" for the git rules.
96
+
97
+ `bun repo worktree add <name>` makes `<root>/.worktrees/<name>` on `wt/<name>` and prints the path. When the root has `bun.lock` it also runs `bun install --frozen-lockfile` in the new worktree (output on stderr, sub-second on a warm cache; a failure prints one line naming the command and the path still prints), so tools that look up `<cwd>/node_modules/.bin`, such as pipeline, work there.
98
+
99
+ `bun repo worktree finish [<name>]` lands the branch. With no name it takes the worktree its cwd is in; from the root it exits 2 (`run finish inside .worktrees/<name> or pass its name`). It refuses a dirty worktree (any `git status --porcelain` line, untracked files included) and one mid-rebase, rebases `wt/<name>` onto the default branch inside the worktree, fast-forwards the default (`merge --ff-only` when the root has it checked out, else `fetch . wt/<name>:<default>`), then runs `git worktree remove` (never `--force`) and deletes the branch once the default holds it. If the default moved since the rebase, it rebases again, at most 3 tries (`<default> kept moving while finishing wt/<name>; run finish again`); a fast-forward that fails with the default unchanged reports git's reason with no retry (the root's own changes to the same file do this). A conflict aborts the rebase, keeps the worktree and names the files: resolve them in the worktree, rerun the checks, run `finish` again. A branch with no commits of its own is removed with `wt/<name> has no commits of its own; removed <path>`. A rerun after a crash converges: a merged branch with no worktree is deleted. `finish` never pushes. On success it prints `merged wt/<name> into <default> at <sha> and removed <path>; your shell may still be in it: cd <root>`. Run it from the root: `cd <root> && bun repo worktree finish <name>`. Run inside the worktree it removes, the work succeeds but Claude's Bash reports exit 1 (its own `pwd` fails in the deleted directory); check the `merged …` line and do not rerun.
100
+
101
+ `bun repo doctor` lists a managed worktree with commits the default lacks and a last commit 7 or more days old as `stale worktree <path> (wt/<name>, last commit <n> days ago)` with the `finish <name>` command. Younger ones are live work and are not listed.
102
+
103
+ `bun repo doctor` `agent models` checks that each model a generated agent names is still offered by its CLI: `.codex/agents/*.toml`, `.grok/agents/*.md`, `.grok/roles/*.toml` and `[subagents.models]` in `agents/global-settings/grok.toml`, `.agents/agents/*.md` (Antigravity) and `.cursor/agents/*.md`. Claude agents use the aliases `haiku`, `sonnet`, `opus` and are not checked. Cursor agents use `model: inherit` (the parent session's model, which any Cursor plan can run; a pinned Claude id is listed on a Free plan but refused), and `inherit` is not checked. Codex and agy are checked without running a command. Codex's list comes from `~/.codex/models_cache.json` `models[].slug` (a file). Agy's is a fixed set, the only values agy accepts for an agent's `model:`: `inherit`, `flash`, `pro` and `flash_lite`. `agy models` lists session models, which an agent file cannot name, and agy silently drops an agent whose `model:` is anything else. An agy main agent's `model:` is ignored (it runs on the session model), so the orchestrator uses `inherit`. An agy agent with no `tools:` gets a read-only default, so the orchestrator lists its tools. Grok's and Cursor's lists come from `grok models` and `cursor-agent --list-models`; those two commands run in parallel under one 20 s cap. A dropped model prints `<file>: model <id> is not offered by <cli>; offered: <ids>`. Grok or Cursor is skipped with its reason when it is not installed or its list fails or takes over 20 s, and codex when its cache is missing or malformed (`agent models ok (skipped: ...)`). Agy is never skipped. Report only: the row never fails the run.
@@ -0,0 +1,119 @@
1
+ # Implementation format (SSOT)
2
+
3
+ Local session journal for `/implement-plan`. Not a plan, handoff, or git commit.
4
+
5
+ Created when `/implement-plan` starts. Straight shots skip this file. Do not merge into the plan (plan = flip the box only).
6
+
7
+ ## Path
8
+
9
+ `.tmp/repo/implementations/{serial}-{slug}-{YYYYMMDDTHHMMSSZ}.md`
10
+
11
+ - **serial:** own counter (not plan serials). Unpadded decimal int ≥ 1. Never `0001`.
12
+ - **filename:** unpadded serial, slug, UTC datetime stamp. Same regex as new plans: `^[0-9]+-[a-z0-9]+(-[a-z0-9]+)*-\d{8}T\d{6}Z\.md$`
13
+ - **lookup:** integer equality on leading digits.
14
+ - Frontmatter `serial:` line must match `^serial: [1-9][0-9]*$`.
15
+ - New writes always stamped. Collision: increment serial, same stamp.
16
+
17
+ ## Link
18
+
19
+ Frontmatter `plan:` is the plan serial (`6`) or `none`. Own serial stays independent.
20
+
21
+ ## Slugify / allocate
22
+
23
+ Same as plans (`slugify`, `nextSerial` on this dir). Body line 1: `IMPL_NAME: <3-6 word name>`. Optional `IMPL_PLAN: <n|none>` (default `none`).
24
+
25
+ ## Frontmatter (required)
26
+
27
+ ```yaml
28
+ ---
29
+ serial: 1
30
+ plan: 6 # unpadded int or none
31
+ name: add-auth
32
+ status: in-progress # in-progress | done | blocked
33
+ created: 2026-08-26T14:30:00Z
34
+ source: "<≤120 chars of user task>"
35
+ ---
36
+ ```
37
+
38
+ ### Status machine
39
+
40
+ `in-progress` → `done` | `blocked`
41
+
42
+ - Fresh write: `in-progress`
43
+ - Plan Verify done and journal caught up: `done`
44
+ - Cannot finish: `blocked` (`## Blockers` must not be `(none)`)
45
+
46
+ ## Body headings (this order only)
47
+
48
+ `# {slug}`, `## Done`, `## Issue`, `## Files`, `## Log`, `## Blockers`, `## Notes`
49
+
50
+ No other `##` headings.
51
+
52
+ | Section | Amount |
53
+ |---|---|
54
+ | Done | bullets. What landed and why. Past tense. Fresh: `(none)` |
55
+ | Issue | bug root cause bullets, or `(none)` |
56
+ | Files | repo-relative product paths as `- path` bullets. Default `/commit` stage set. No abs paths. No `.tmp/`. Fresh: `(none)` |
57
+ | Log | append-only. Fresh: `(none)`. After each plan leaf: `N.M [x] one line` (notes, fail, skip). `[x]` allowed |
58
+ | Blockers | open problems. `(none)` unless `status: blocked` |
59
+ | Notes | short leftovers, or `(none)` |
60
+
61
+ ## Write
62
+
63
+ Write under `.tmp/repo/implementations/` (any filename in that dir). Grok `orchestrate-parent.ts` runs `cli/scripts/persist-implementation.ts` on create (`IMPL_NAME:`): serial/slug from the name, injects frontmatter, rewrites path + content. Updates to an existing file keep the path; full-body writes are validated in place. Invalid create/update denies — fix the body, do not retry elsewhere.
64
+
65
+ Host without that hook: name the file per **Path**, or pipe the body to `bun repo persist implementation --workspace {repo}` and use its `absPath`.
66
+
67
+ Never allocate a new serial to log a leaf. Append Log, update Files/Done, flip the plan box.
68
+
69
+ ## Validation checklist
70
+
71
+ - filename stamped unpadded; serial int equals leading digits; `name` equals slug
72
+ - frontmatter keys: `serial`, `plan`, `name`, `status`, `created`, `source`
73
+ - `plan` is `none` or unpadded int ≥ 1; `status` ∈ `in-progress` | `done` | `blocked`
74
+ - headings in order only; no extra `##`
75
+ - Done / Issue / Files / Log / Blockers / Notes: bullets and/or `(none)`; none of those sections empty
76
+ - Files: repo-relative; reject abs and `.tmp/`
77
+ - `status: blocked` ⇒ Blockers is not only `(none)`
78
+
79
+ ## Worked example
80
+
81
+ File: `.tmp/repo/implementations/1-notes-export-json-20260826T143000Z.md`
82
+
83
+ ```markdown
84
+ ---
85
+ serial: 1
86
+ plan: 1
87
+ name: notes-export-json
88
+ status: in-progress
89
+ created: 2026-08-26T14:30:00Z
90
+ source: "add --json to notes export"
91
+ ---
92
+
93
+ # notes-export-json
94
+
95
+ ## Done
96
+ - `notes export --json` prints every note as one JSON array; the text table stays the default
97
+
98
+ ## Issue
99
+ (none)
100
+
101
+ ## Files
102
+ - src/cli.ts
103
+ - src/export.ts
104
+ - src/export.test.ts
105
+
106
+ ## Log
107
+ 1.1 [x] read principle-test-behavior-not-implementation
108
+ 2.1 [x] export tests for two notes and for none
109
+ 2.2 [x] new cases fail on the unknown flag
110
+ 3.1 [x] parse --json in cli.ts
111
+ 3.2 [x] print JSON.stringify of the notes in export.ts
112
+ 3.3 [x] export tests pass
113
+
114
+ ## Blockers
115
+ (none)
116
+
117
+ ## Notes
118
+ (none)
119
+ ```
@@ -0,0 +1,56 @@
1
+ ---
2
+ tags: [jev]
3
+ ---
4
+
5
+ # Jev
6
+
7
+ Closed external decision. The source text is already saved. The question is a yes/no or a named choice. One call. Not open research. Not code. Not job.
8
+
9
+ ## Availability
10
+
11
+ ```
12
+ bun repo jev --available
13
+ ```
14
+
15
+ Prints `yes` or `no` and exits 0. No request. No setup line.
16
+
17
+ `no`: the session answers the question itself. Do not run the decision command. Do not mention Jev, a missing key, or setup.
18
+
19
+ `yes`: continue below.
20
+
21
+ A key is `TYPESAFE_API_KEY` or `apiKey` in `~/.workerstack/jev.json` (mode 0600). Env wins. Setup, when a person asks for it: `bun repo setup jev`. Spec: `node_modules/@workerstack/repo/references/setup.md`.
22
+
23
+ ## Decision
24
+
25
+ Write `.tmp/repo/jev/<slug>-state.txt` (plain text or a JSON object) and `.tmp/repo/jev/<slug>-questions.json` (the System One questions map). Put every label for that study in the one map. At most 8 questions. State at most 64000 characters.
26
+
27
+ ```
28
+ bun repo jev --state .tmp/repo/jev/<slug>-state.txt --questions .tmp/repo/jev/<slug>-questions.json
29
+ ```
30
+
31
+ Yes/no:
32
+
33
+ ```json
34
+ { "keep": { "type": "noul", "instructions": "Does this passage promise zero retention on the default plan?" } }
35
+ ```
36
+
37
+ Named choice:
38
+
39
+ ```json
40
+ {
41
+ "endpoint": {
42
+ "type": "choice",
43
+ "instructions": "Which endpoint should the app call?",
44
+ "criteria": {
45
+ "typesafe": "Vendor host, path, and key",
46
+ "other": "A different host, path, or key"
47
+ }
48
+ }
49
+ }
50
+ ```
51
+
52
+ Model is `jev-1.13.0`. Stdout is at most 8 lines: model, input tokens, then one label line. Exit 0. Use that label and confidence. A low confidence is the result. Do not rephrase and call again.
53
+
54
+ One request per process. UTC-day ledger `~/.workerstack/jev-usage.json` stops at 40 requests or 1000000 input tokens. A 429 or 529 retries once only when `Retry-After` is at most 2 seconds.
55
+
56
+ Exit 2 means the decision call did not return a label. Answer from the sources. Do not invent a label. Do not print the key or the state.
@@ -0,0 +1,73 @@
1
+ ---
2
+ tags: [lessons]
3
+ ---
4
+
5
+ # Lessons
6
+
7
+ Mistakes that outlive one task. One committed file per mistake under `.repo/lessons/`, with a generated index. Not host memory: everything is in the repo and reaches every machine through git.
8
+
9
+ ## Three layers
10
+
11
+ - **Plan:** `## Previous mistakes` in each plan holds that task's details: rejected approaches, failed Verify, accepted review findings. It stays with the plan in `.tmp/`. Format: `node_modules/@workerstack/repo/references/plan-format.md`.
12
+ - **Roadmap:** `## Previous mistakes` in a roadmap holds mistakes about the program: slice order, slice boundaries, and `slice` entries for what a child plan found that changed later slices. A roadmap saved in the old shape also logs its Decisions there; a pointer roadmap's decisions live in the slice plans. It lasts as long as the program, in `.tmp/`. Format: `node_modules/@workerstack/repo/references/roadmap-format.md`.
13
+ - **Repo:** a lesson holds a mistake that will happen again on other tasks. A plan entry that generalizes becomes a lesson, and the entry ends with `(lesson: {slug})`.
14
+
15
+ ## File
16
+
17
+ `.repo/lessons/{slug}.md`, at most 60 lines.
18
+
19
+ ```markdown
20
+ ---
21
+ name: plan-forks
22
+ paths: ["cli/scripts/persist-plan.ts", "agents/grok/hooks/**"]
23
+ hits: 1
24
+ last-hit: 2026-11-01
25
+ evidence: ["plan 16"]
26
+ ---
27
+
28
+ # Plan rewrites fork serials
29
+
30
+ Rewriting a saved plan minted a new serial.
31
+
32
+ ## Mistake
33
+ What went wrong, concretely.
34
+
35
+ ## Fix
36
+ What to do instead.
37
+ ```
38
+
39
+ - `name` is the filename slug. `paths` are repo-relative globs (`**` spans dirs; `*` and `?` stay in one segment) and each must match a file that exists.
40
+ - `hits` counts occurrences. `evidence` keeps the 5 most recent plan serials or commits.
41
+ - A new lesson may leave out `hits` and `last-hit`; the save fills `1` and today.
42
+
43
+ ## Index
44
+
45
+ `.repo/lessons/INDEX.md` is generated: one row per lesson with path, globs, hits, last hit, and summary, sorted by hits. Do not edit it. Every lesson save, `hit`, and `rm` rewrites it, and `bun repo sync` rewrites it too. `bun repo sync --check` fails on index drift, an invalid lesson, or a glob that matches no file.
46
+
47
+ ## Write
48
+
49
+ - Write, `hit`, `rm` and `index` run inside a worktree: the plan's `{serial}-{name}` (`bun repo worktree add {serial}-{name}` if it is missing), else `lesson-{slug}`, and `/correct` uses its `correct-{slug}`. The lesson then lands with that worktree's commit and `finish` (run from the root). In the main checkout the Write is denied, `hit`, `rm` and `index` exit 1 with `the main checkout is shared: run bun repo worktree add <name> and write under <root>/.worktrees/<name>; only <root>/.tmp/ is writable here`, and the library calls return `{ ok: false, error }` with that text.
50
+ - Write the whole file. The hook validates it, renders the standard form, and reindexes; the host saves it. An Edit of a lesson is denied.
51
+ - `bun repo lessons hit <slug> --evidence <text>` counts a repeat. The same evidence counts once.
52
+ - `bun repo lessons rm <slug>` deletes a lesson and reindexes.
53
+ - `bun repo lessons index` rebuilds the index. `check` runs the checks and, like `match`, is read-only, so it runs anywhere.
54
+
55
+ ## When to write
56
+
57
+ After any of these, add a `## Previous mistakes` entry to the plan. If the mistake will happen again on other tasks, run `bun repo lessons match` on the files involved first, then `hit` the matching lesson or write a new one.
58
+
59
+ - Plan feedback from the user (`/write-plan`).
60
+ - A failed Verify, or a test that failed after a fix (`/implement-plan`).
61
+ - `principle-attack-the-premise` firing (`/implement-plan`).
62
+ - An accepted `/review-plan` finding (`/write-plan`).
63
+ - Roadmap feedback, an accepted `/review-roadmap` finding (`/write-roadmap`), a child plan that changes the program, or a failed program Verify (`/implement-roadmap`). These go to the roadmap's log. Before the roadmap is `done`, each entry that outlives the program becomes a lesson with `--evidence "roadmap {n}"`.
64
+ - An operator correction (`/correct`).
65
+
66
+ At `hits: 2` the mistake is a class. `/correct` encodes it as a check (architecture, type, lint, or test), then runs `bun repo lessons rm`.
67
+
68
+ ## When to read
69
+
70
+ - `bun repo lessons match <file...>` prints the lessons whose globs match, most hits first, 10 at most. Each file is matched against the lessons of the checkout that holds it: the root or a managed worktree; a file in an unmanaged linked worktree uses the checkout you run it from.
71
+ - A new plan that names a matched file must cite that lesson's path in Watch-outs, or the save is denied with the lesson listed.
72
+ - The first time a session edits a matched file, the hook adds that lesson's summary and path to the context. Each lesson is shown once per session.
73
+ - `/review-plan` reads the matched lessons and flags one that no leaf acts on.
@@ -0,0 +1,80 @@
1
+ ---
2
+ tags: [listen]
3
+ ---
4
+
5
+ # Listen
6
+
7
+ Speech-to-text from the session. Input only. Not TTS. Not a live voice agent. Not MCP.
8
+
9
+ ```
10
+ bun repo listen whoami
11
+ bun repo listen devices
12
+ bun repo listen rec [--seconds 8] [--device D] [--clip]
13
+ bun repo listen start [--device D]
14
+ bun repo listen stop [--clip]
15
+ bun repo listen toggle [--clip]
16
+ bun repo listen status
17
+ bun repo listen file --path clip.wav [--clip]
18
+ bun repo listen latest
19
+ ```
20
+
21
+ `rec` records then transcribes (default 8s, cap 120s). `toggle` is the hotkey verb: first run starts, second run stops and prints the transcript. Audio and `latest.txt` live under `.tmp/repo/listen/`. `--cwd /path/to/repo` when the hotkey does not already run in the repo.
22
+
23
+ ## Auth and capture
24
+
25
+ Handheld (any OS): `bun repo setup listen` or `bun repo setup` → listen. Prints OS install commands for ffmpeg / whisper-cli (does not run them), optional ggml download into `~/.workerstack/whisper/`, OpenAI fallback key if local STT is missing.
26
+
27
+ If ffmpeg, whisper-cli, a ggml model, or `OPENAI_API_KEY` is missing, the CLI prints `setup: bun repo setup listen` and exits 1. Agents should show that line, not a stack or JSON. Do not invent a key.
28
+
29
+ STT prefers **local whisper.cpp**. Install the binary; the first `listen` downloads `ggml-base.en.bin` (~142MB) into `~/.workerstack/whisper/`. No API cost after that. If the binary or download is missing, it falls back to OpenAI `whisper-1` (`OPENAI_API_KEY` or `~/.workerstack/speak.json`). Force with `LISTEN_STT=local` or `LISTEN_STT=openai`. Never commit keys.
30
+
31
+ | | env | `~/.workerstack/speak.json` |
32
+ | --- | --- | --- |
33
+ | Local model | `WHISPER_MODEL` | `listen.whisperModel` |
34
+ | Force engine | `LISTEN_STT` | `listen.stt` (`auto` / `local` / `openai`) |
35
+ | OpenAI key | `OPENAI_API_KEY` | `openai.apiKey` |
36
+ | OpenAI model | `LISTEN_MODEL` | `listen.model` (default `whisper-1`) |
37
+ | Device | `LISTEN_DEVICE` | `listen.device` |
38
+ | Seconds | `LISTEN_SECONDS` | `listen.seconds` |
39
+
40
+ ### Local Whisper (preferred)
41
+
42
+ One install:
43
+
44
+ - mac: `brew install whisper-cpp` (provides `whisper-cli`)
45
+ - linux: build https://github.com/ggml-org/whisper.cpp (`whisper-cli` on PATH)
46
+ - win: whisper.cpp release `whisper-cli.exe` on PATH
47
+
48
+ Then `bun repo listen whoami` or `rec`. The first run fetches `ggml-base.en.bin` to `~/.workerstack/whisper/`. Do not pip-install OpenAI Whisper. Do not curl the model yourself unless the auto-download fails.
49
+
50
+ Larger models: put another `ggml-*.bin` in that folder or set `WHISPER_MODEL`. Doctor reports `whisper-cli` as optional. `whoami` prints `stt=local` or `stt=openai`.
51
+
52
+ ### ffmpeg (mic only)
53
+
54
+ - mac: `brew install ffmpeg`
55
+ - linux: `sudo apt install ffmpeg`
56
+ - win: `winget install Gyan.FFmpeg`
57
+
58
+ `file` and `latest` work without a mic. Doctor reports ffmpeg as optional.
59
+
60
+ `rec` detaches ffmpeg and does not attach it to the IDE TTY. AVFoundation can stall forever on a VS Code / Electron PTY even when Visual Studio Code already has Microphone access.
61
+
62
+ Default devices: mac `:0` (AVFoundation audio 0), linux Pulse `default` (ALSA if the id is `hw:…`), Windows requires `--device` or `LISTEN_DEVICE` from `listen devices`.
63
+
64
+ ## Hotkeys
65
+
66
+ Bind one key to toggle. Include `--clip` so the transcript is on the clipboard as well as `latest.txt`.
67
+
68
+ ```
69
+ bun --cwd /ABS/repo repo listen toggle --clip
70
+ ```
71
+
72
+ Replace `/ABS/repo` with the repo root.
73
+
74
+ - **mac:** Shortcuts (Run Shell Script) or skhd: `hyper - r : bun --cwd /ABS/repo repo listen toggle --clip`
75
+ - **win:** PowerToys Keyboard Manager or AutoHotkey: `^!r:: Run, bun --cwd C:\ABS\repo repo listen toggle --clip, C:\ABS\repo, Hide`
76
+ - **linux:** desktop custom shortcut or sxhkd to the same command.
77
+
78
+ No daemon. Each keypress is one CLI. First press records; second press transcribes.
79
+
80
+ `--clip` uses `pbcopy` (mac), `clip` (win), or `wl-copy` / `xclip` / `xsel` (linux).