forge-workflow 0.0.9 → 0.1.0-beta.2

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 (479) hide show
  1. package/.claude/rules/{greptile-review-process.md → review-process.md} +56 -41
  2. package/.claude/scripts/{greptile-resolve.sh → review-resolve.sh} +13 -3
  3. package/.cursor/rules/permissions-guidance.mdc +2 -2
  4. package/.forge/hooks/check-tdd.js +3 -0
  5. package/.forge/hooks/forge-native-hook.js +245 -0
  6. package/.forge/protected-paths.yaml +157 -0
  7. package/AGENTS.md +151 -61
  8. package/CHANGELOG.md +681 -0
  9. package/CLAUDE.md +9 -106
  10. package/QUICKSTART.md +171 -0
  11. package/README.md +271 -363
  12. package/bin/forge-cmd.js +120 -9
  13. package/bin/forge-preflight.js +26 -5
  14. package/bin/forge.js +466 -489
  15. package/docs/INDEX.md +93 -0
  16. package/docs/PROJECT_DESIGN.md +685 -0
  17. package/docs/architecture/index.md +66 -0
  18. package/docs/architecture/notes/README.md +35 -0
  19. package/docs/architecture/subsystems/README.md +46 -0
  20. package/docs/{TOOLCHAIN.md → forge/TOOLCHAIN.md} +56 -47
  21. package/docs/forge/VALIDATION.md +82 -0
  22. package/docs/{AGENT_INSTALL_PROMPT.md → guides/AGENT_INSTALL_PROMPT.md} +3 -3
  23. package/docs/guides/BEADS_GITHUB_SYNC.md +32 -0
  24. package/docs/{ENHANCED_ONBOARDING.md → guides/ENHANCED_ONBOARDING.md} +16 -12
  25. package/docs/guides/GREPTILE_SETUP.md +46 -0
  26. package/docs/guides/MANUAL_REVIEW_GUIDE.md +58 -0
  27. package/docs/guides/MIGRATION.md +56 -0
  28. package/docs/guides/SETUP.md +118 -0
  29. package/docs/guides/SUPPORT.md +185 -0
  30. package/docs/guides/WORKFLOW_TEMPLATES.md +74 -0
  31. package/docs/guides/memory-backends.md +183 -0
  32. package/docs/reference/ADAPTERS.md +128 -0
  33. package/docs/reference/AGENT_SKILL_PARITY.md +175 -0
  34. package/docs/reference/COMMANDS.md +205 -0
  35. package/docs/reference/DECISION_DRIFT_GUARDS.md +97 -0
  36. package/docs/{EXAMPLES.md → reference/EXAMPLES.md} +7 -5
  37. package/docs/reference/FORGE_KERNEL_STORAGE_MODEL.md +135 -0
  38. package/docs/reference/HERMES_INTEGRATION.md +118 -0
  39. package/docs/reference/INSIGHTS_RECAP.md +63 -0
  40. package/docs/reference/INSTALL.md +164 -0
  41. package/docs/reference/KERNEL_TAXONOMY_VALIDATION.md +161 -0
  42. package/docs/reference/PROTECTED_PATH_MANIFEST.md +25 -0
  43. package/docs/reference/RELEASE.md +68 -0
  44. package/docs/reference/RESEARCH_TEMPLATE.md +292 -0
  45. package/docs/{ROADMAP.md → reference/ROADMAP.md} +12 -9
  46. package/docs/reference/SKILLS.md +35 -0
  47. package/docs/reference/STATUS_BOARD.md +80 -0
  48. package/docs/reference/TEMPLATES.md +106 -0
  49. package/docs/reference/TOOLCHAIN.md +658 -0
  50. package/docs/reference/VALIDATION.md +82 -0
  51. package/docs/reference/agent-permissions.md +169 -0
  52. package/docs/reference/beads-to-kernel-migration-ux.md +61 -0
  53. package/docs/reference/control-plane-guarantees.md +125 -0
  54. package/docs/reference/dependency-chain.md +331 -0
  55. package/docs/reference/forge-kernel-issue-command-contract.md +161 -0
  56. package/docs/reference/forge-kernel-schema.md +72 -0
  57. package/docs/reference/kernel-conflict-evaluators.md +27 -0
  58. package/docs/reference/patch-md-format.md +77 -0
  59. package/docs/reference/protected-state-surfaces.md +59 -0
  60. package/docs/reference/shepherd.md +115 -0
  61. package/docs/reference/superpowers-analysis.md +320 -0
  62. package/docs/reference/superpowers-integration-options.md +404 -0
  63. package/docs/reference/test-environment.md +519 -0
  64. package/docs/reference/upgrade-safety.md +59 -0
  65. package/lefthook.yml +18 -0
  66. package/lib/adapter-cli.js +307 -0
  67. package/lib/adapters/beads-issue-adapter.js +127 -0
  68. package/lib/adapters/beads-kernel-compat.js +1042 -0
  69. package/lib/adapters/greptile-review-adapter.js +141 -0
  70. package/lib/adapters/kernel-issue-adapter.js +101 -0
  71. package/lib/adapters/pr-state-adapter.js +484 -0
  72. package/lib/adoption-profiles.js +126 -0
  73. package/lib/agents/README.md +2 -6
  74. package/lib/agents/claude.plugin.json +3 -8
  75. package/lib/agents/codex.plugin.json +9 -1
  76. package/lib/agents/cursor.plugin.json +2 -6
  77. package/lib/agents/hermes.plugin.json +22 -0
  78. package/lib/agents-config.js +39 -1236
  79. package/lib/audit-evidence.js +282 -0
  80. package/lib/beads-setup.js +225 -28
  81. package/lib/beads-sync-scaffold.js +36 -107
  82. package/lib/codex-skills.js +51 -1
  83. package/lib/commands/_issue.js +744 -70
  84. package/lib/commands/_manifest.js +91 -0
  85. package/lib/commands/_registry.js +85 -34
  86. package/lib/commands/_resolve-command-opts.js +261 -0
  87. package/lib/commands/_serve-security.js +270 -0
  88. package/lib/commands/adapter.js +12 -0
  89. package/lib/commands/add.js +118 -0
  90. package/lib/commands/audit.js +70 -0
  91. package/lib/commands/blocked.js +5 -0
  92. package/lib/commands/board.js +64 -0
  93. package/lib/commands/claim.js +21 -2
  94. package/lib/commands/claims.js +7 -0
  95. package/lib/commands/clean.js +485 -75
  96. package/lib/commands/close.js +2 -2
  97. package/lib/commands/comment.js +5 -0
  98. package/lib/commands/control.js +148 -0
  99. package/lib/commands/create.js +2 -2
  100. package/lib/commands/dev.js +185 -7
  101. package/lib/commands/doc-gate.js +336 -0
  102. package/lib/commands/doctor.js +156 -0
  103. package/lib/commands/explain.js +15 -0
  104. package/lib/commands/export.js +237 -0
  105. package/lib/commands/gate.js +192 -0
  106. package/lib/commands/hooks.js +242 -0
  107. package/lib/commands/inbox.js +118 -0
  108. package/lib/commands/init.js +598 -0
  109. package/lib/commands/insights.js +79 -0
  110. package/lib/commands/issue.js +12 -1
  111. package/lib/commands/issues.js +66 -0
  112. package/lib/commands/lint.js +5 -0
  113. package/lib/commands/list.js +2 -2
  114. package/lib/commands/merge.js +312 -0
  115. package/lib/commands/migrate.js +523 -0
  116. package/lib/commands/new.js +12 -0
  117. package/lib/commands/options.js +241 -0
  118. package/lib/commands/orient.js +13 -0
  119. package/lib/commands/orphans.js +5 -0
  120. package/lib/commands/patch.js +67 -0
  121. package/lib/commands/plan.js +436 -24
  122. package/lib/commands/preflight.js +211 -0
  123. package/lib/commands/prime.js +13 -0
  124. package/lib/commands/push.js +69 -2
  125. package/lib/commands/ready.js +2 -2
  126. package/lib/commands/recall.js +116 -0
  127. package/lib/commands/recap.js +61 -0
  128. package/lib/commands/recommend.js +22 -2
  129. package/lib/commands/release.js +91 -0
  130. package/lib/commands/remember.js +74 -0
  131. package/lib/commands/role.js +99 -0
  132. package/lib/commands/serve.js +581 -0
  133. package/lib/commands/setup.js +851 -979
  134. package/lib/commands/shepherd.js +436 -0
  135. package/lib/commands/ship.js +23 -1
  136. package/lib/commands/show.js +2 -2
  137. package/lib/commands/stage.js +192 -0
  138. package/lib/commands/stale.js +5 -0
  139. package/lib/commands/status.js +329 -11
  140. package/lib/commands/sync.js +34 -46
  141. package/lib/commands/team.js +15 -2
  142. package/lib/commands/test.js +58 -7
  143. package/lib/commands/update.js +2 -2
  144. package/lib/commands/upgrade.js +47 -0
  145. package/lib/commands/validate.js +56 -25
  146. package/lib/commands/worktree.js +308 -128
  147. package/lib/config-writer.js +202 -0
  148. package/lib/control-plane.js +236 -0
  149. package/lib/core/runtime-graph.js +946 -0
  150. package/lib/dep-guard/keyword-ripple.js +184 -0
  151. package/lib/deprecated-sync-cleanup.js +362 -0
  152. package/lib/detect-agent.js +2 -28
  153. package/lib/detect-worktree.js +42 -17
  154. package/lib/doc-gate/declaration.js +177 -0
  155. package/lib/doc-gate/detect.js +289 -0
  156. package/lib/doc-gate/gate.js +375 -0
  157. package/lib/doc-gate/okf-config.js +128 -0
  158. package/lib/doc-gate/okf.js +429 -0
  159. package/lib/docs-command.js +1161 -6
  160. package/lib/forge-issues.js +697 -0
  161. package/lib/forge-lock.js +262 -0
  162. package/lib/gate-events.js +193 -0
  163. package/lib/global-flags.js +74 -0
  164. package/lib/greptile-match.js +7 -63
  165. package/lib/harness-capability-matrix.js +380 -0
  166. package/lib/hook-global-installer.js +347 -0
  167. package/lib/hook-renderer.js +451 -0
  168. package/lib/inbox.js +391 -0
  169. package/lib/insights.js +397 -0
  170. package/lib/issue-adapter.js +156 -0
  171. package/lib/issue-backend.js +145 -0
  172. package/lib/issue-render.js +220 -0
  173. package/lib/issue-sync/authority.js +100 -0
  174. package/lib/issue-sync/github-pull.js +184 -0
  175. package/lib/issue-sync/import-primitives.js +98 -0
  176. package/lib/issue-sync/legacy-link-bridge.js +436 -0
  177. package/lib/issue-sync/link-store.js +292 -0
  178. package/lib/issue-sync/project-github.js +123 -0
  179. package/lib/issue-sync/reconcile.js +195 -0
  180. package/lib/issue-sync/schema.js +126 -0
  181. package/lib/kernel/backing-issue.js +305 -0
  182. package/lib/kernel/broker.js +1218 -0
  183. package/lib/kernel/cli-broker-factory.js +130 -0
  184. package/lib/kernel/conflict-signal.js +82 -0
  185. package/lib/kernel/evaluators.js +195 -0
  186. package/lib/kernel/fs-class.js +495 -0
  187. package/lib/kernel/issue-command-contract.js +559 -0
  188. package/lib/kernel/issue-id-resolver.js +186 -0
  189. package/lib/kernel/lease-enforcer.js +158 -0
  190. package/lib/kernel/migrations.js +333 -0
  191. package/lib/kernel/planning-buckets-schema.js +109 -0
  192. package/lib/kernel/projection-jsonl-writer.js +450 -0
  193. package/lib/kernel/readiness-model.js +329 -0
  194. package/lib/kernel/schema.js +356 -0
  195. package/lib/kernel/sqlite-driver.js +2504 -0
  196. package/lib/kernel/taxonomy-validator.js +394 -0
  197. package/lib/lefthook-check.js +8 -4
  198. package/lib/lefthook-wiring.js +413 -0
  199. package/lib/mcp-config-renderer.js +288 -0
  200. package/lib/memory/graphiti-mcp.js +106 -0
  201. package/lib/memory/router.js +387 -0
  202. package/lib/memory/typed-api.js +102 -0
  203. package/lib/memory-digest.js +195 -0
  204. package/lib/merge-rules.js +395 -0
  205. package/lib/migrate-dry-run.js +466 -0
  206. package/lib/orientation.js +863 -0
  207. package/lib/package-manager-remediation.js +103 -0
  208. package/lib/package-root.js +381 -0
  209. package/lib/patch-intent.js +890 -0
  210. package/lib/plugin-catalog.js +3 -4
  211. package/lib/plugin-manager.js +0 -5
  212. package/lib/pr-bundle.js +186 -0
  213. package/lib/pr-monitor/differ.js +195 -0
  214. package/lib/pr-monitor/events.js +0 -0
  215. package/lib/pr-monitor/gather.js +124 -0
  216. package/lib/pr-monitor/journal.js +299 -0
  217. package/lib/pr-monitor/monitor.js +146 -0
  218. package/lib/pr-monitor/render-sticky.js +157 -0
  219. package/lib/pr-monitor/watch-lifecycle.js +95 -0
  220. package/lib/pr-monitor/watch.js +247 -0
  221. package/lib/pr-pull.js +1273 -0
  222. package/lib/pr-shepherd.js +494 -0
  223. package/lib/pr-state-validator.js +59 -0
  224. package/lib/preflight/gates.js +237 -0
  225. package/lib/preflight/runner.js +116 -0
  226. package/lib/project-discovery.js +0 -53
  227. package/lib/project-memory.js +166 -0
  228. package/lib/protected-path-manifest.js +281 -0
  229. package/lib/protected-state-surfaces.js +387 -0
  230. package/lib/release-readiness.js +2089 -0
  231. package/lib/reset.js +59 -45
  232. package/lib/review-adapter.js +68 -0
  233. package/lib/rules-sync.js +260 -0
  234. package/lib/runtime-health.js +332 -23
  235. package/lib/safety-config-renderer.js +268 -0
  236. package/lib/setup-action-log.js +1 -7
  237. package/lib/setup.js +27 -65
  238. package/lib/shell-utils.js +76 -6
  239. package/lib/skills-sync.js +330 -0
  240. package/lib/smart-status/conflicts.js +205 -0
  241. package/lib/smart-status/scoring.js +191 -0
  242. package/lib/status/beads-snapshot.js +145 -0
  243. package/lib/status/presenter.js +216 -0
  244. package/lib/status/snapshot.js +186 -0
  245. package/lib/sync-backend.js +202 -0
  246. package/lib/untrusted-content.js +52 -0
  247. package/lib/upgrade-safety.js +199 -0
  248. package/lib/workflow/enforce-stage.js +298 -47
  249. package/lib/workflow/stage-transition.js +115 -0
  250. package/lib/workflow/stages.js +30 -6
  251. package/lib/workflow/state-manager.js +159 -14
  252. package/lib/workflow/state.js +23 -1
  253. package/lib/workflow-profiles.js +17 -5
  254. package/package.json +46 -36
  255. package/rules/documentation.md +19 -0
  256. package/rules/kernel-tracking.md +26 -0
  257. package/rules/security.md +22 -0
  258. package/rules/tdd.md +20 -0
  259. package/rules/workflow.md +27 -0
  260. package/scripts/auto-backing-issue.js +47 -0
  261. package/scripts/beads-context.sh +165 -22
  262. package/scripts/beads-migrate-to-dolt.sh +7 -0
  263. package/scripts/beads-upgrade-smoke.sh +284 -0
  264. package/scripts/behavioral-judge.sh +115 -11
  265. package/scripts/benchmark.js +349 -63
  266. package/scripts/bootstrap-windows-tools.sh +78 -0
  267. package/scripts/branch-protection.js +2 -3
  268. package/scripts/check-agents.js +34 -137
  269. package/scripts/commitlint.js +3 -1
  270. package/scripts/conflict-detect.sh +3 -0
  271. package/scripts/dep-guard-analyze.js +52 -17
  272. package/scripts/dep-guard-keyword-ripple.js +29 -0
  273. package/scripts/dep-guard-render-review.js +86 -0
  274. package/scripts/dep-guard.sh +64 -232
  275. package/scripts/file-index.sh +3 -0
  276. package/scripts/forge-team/lib/claim.sh +34 -18
  277. package/scripts/forge-team/lib/dashboard.sh +61 -86
  278. package/scripts/forge-team/lib/epic.sh +99 -263
  279. package/scripts/forge-team/lib/hooks.sh +26 -28
  280. package/scripts/forge-team/lib/identity.sh +4 -4
  281. package/scripts/forge-team/lib/sync-github.sh +144 -47
  282. package/scripts/forge-team/lib/verify.sh +93 -83
  283. package/scripts/forge-team/lib/workload.sh +41 -65
  284. package/scripts/forge-team/tests/claim.test.sh +25 -19
  285. package/scripts/forge-team/tests/dashboard.test.sh +31 -46
  286. package/scripts/forge-team/tests/epic.test.sh +52 -71
  287. package/scripts/forge-team/tests/hooks.test.sh +38 -50
  288. package/scripts/forge-team/tests/identity.test.sh +3 -3
  289. package/scripts/forge-team/tests/integration.test.sh +44 -66
  290. package/scripts/forge-team/tests/sync-github.test.sh +183 -79
  291. package/scripts/forge-team/tests/verify.test.sh +37 -46
  292. package/scripts/forge-team/tests/workflow-integration.test.sh +4 -4
  293. package/scripts/forge-team/tests/workload.test.sh +32 -66
  294. package/scripts/gen-command-manifest.js +153 -0
  295. package/scripts/gen-embedded-assets.mjs +129 -0
  296. package/scripts/install.ps1 +139 -0
  297. package/scripts/install.sh +268 -0
  298. package/scripts/lib/beads-migrate-to-dolt.mjs +503 -0
  299. package/scripts/lib/release-asset.mjs +84 -0
  300. package/scripts/parity-check.mjs +145 -0
  301. package/scripts/parity-check.test.mjs +58 -0
  302. package/scripts/pin-agentic-workflow-images.js +112 -0
  303. package/scripts/pr-coordinator.sh +3 -0
  304. package/scripts/preflight-sonar.eslint.config.mjs +44 -0
  305. package/scripts/preflight.sh +108 -0
  306. package/scripts/protected-state-check.js +104 -0
  307. package/scripts/smart-status-score.js +31 -0
  308. package/scripts/smart-status-sessions.js +51 -0
  309. package/scripts/smart-status.sh +117 -369
  310. package/scripts/spikes/config-race-bench.js +111 -0
  311. package/scripts/spikes/harness-capability-matrix.js +13 -0
  312. package/scripts/spikes/patch-anchor-stability-bench.js +125 -0
  313. package/scripts/spikes/protected-path-manifest.js +20 -0
  314. package/scripts/spikes/skill-auto-invoke-parity.js +292 -0
  315. package/scripts/sync-agent-skills.js +62 -0
  316. package/scripts/sync-agentic-workflow.js +48 -0
  317. package/scripts/sync-utils.sh +3 -0
  318. package/scripts/test-ci-shard.js +251 -0
  319. package/scripts/test-dashboard.js +188 -52
  320. package/scripts/test-full-suite.js +186 -0
  321. package/scripts/test-profile.js +278 -0
  322. package/scripts/test.js +302 -28
  323. package/scripts/validate.js +143 -0
  324. package/scripts/validate.sh +18 -1
  325. package/skills/claim-safety/SKILL.md +102 -0
  326. package/skills/claim-safety/evals/evals.json +46 -0
  327. package/{.github/prompts/dev.prompt.md → skills/dev/SKILL.md} +46 -52
  328. package/skills/dev/evals/evals.json +50 -0
  329. package/skills/hermes-forge/SKILL.md +185 -0
  330. package/skills/hermes-forge/evals/evals.json +46 -0
  331. package/skills/issue-basics/SKILL.md +111 -0
  332. package/skills/issue-basics/evals/evals.json +46 -0
  333. package/skills/kernel/SKILL.md +166 -0
  334. package/skills/kernel/evals/evals.json +50 -0
  335. package/skills/memory/SKILL.md +102 -0
  336. package/skills/parallel-deep-research/SKILL.md +14 -11
  337. package/skills/parallel-deep-research/evals/evals.json +11 -27
  338. package/{.github/prompts/plan.prompt.md → skills/plan/SKILL.md} +134 -159
  339. package/skills/plan/evals/evals.json +42 -0
  340. package/skills/research/SKILL.md +195 -0
  341. package/skills/research/evals/evals.json +42 -0
  342. package/{.github/prompts/review.prompt.md → skills/review/SKILL.md} +98 -62
  343. package/skills/review/evals/evals.json +42 -0
  344. package/skills/rollback/SKILL.md +110 -0
  345. package/skills/rollback/evals/evals.json +46 -0
  346. package/skills/rollback/references/methods.md +204 -0
  347. package/{.cursor/commands/rollback.md → skills/rollback/references/workflow-integration.md} +10 -284
  348. package/skills/shepherd/SKILL.md +66 -0
  349. package/skills/shepherd/evals/evals.json +42 -0
  350. package/skills/ship/SKILL.md +251 -0
  351. package/skills/ship/evals/evals.json +42 -0
  352. package/skills/smith/SKILL.md +142 -0
  353. package/skills/smith/evals/evals.json +46 -0
  354. package/skills/smith/references/autonomy-and-gates.md +94 -0
  355. package/{.github/prompts/sonarcloud.prompt.md → skills/sonarcloud/SKILL.md} +14 -3
  356. package/skills/sonarcloud/evals/evals.json +46 -0
  357. package/skills/sonarcloud-analysis/SKILL.md +18 -13
  358. package/skills/sonarcloud-analysis/evals/evals.json +11 -15
  359. package/skills/status/SKILL.md +102 -0
  360. package/skills/status/evals/evals.json +50 -0
  361. package/skills/triage-ready/SKILL.md +121 -0
  362. package/skills/triage-ready/evals/evals.json +42 -0
  363. package/{.github/prompts/validate.prompt.md → skills/validate/SKILL.md} +52 -29
  364. package/skills/validate/evals/evals.json +42 -0
  365. package/skills/verify/SKILL.md +299 -0
  366. package/skills/verify/evals/evals.json +50 -0
  367. package/.claude/commands/dev.md +0 -345
  368. package/.claude/commands/plan.md +0 -566
  369. package/.claude/commands/premerge.md +0 -186
  370. package/.claude/commands/research.md +0 -42
  371. package/.claude/commands/review.md +0 -451
  372. package/.claude/commands/rollback.md +0 -721
  373. package/.claude/commands/ship.md +0 -213
  374. package/.claude/commands/sonarcloud.md +0 -152
  375. package/.claude/commands/status.md +0 -90
  376. package/.claude/commands/validate.md +0 -288
  377. package/.claude/commands/verify.md +0 -269
  378. package/.claude/rules/workflow.md +0 -121
  379. package/.cline/workflows/dev.md +0 -342
  380. package/.cline/workflows/plan.md +0 -563
  381. package/.cline/workflows/premerge.md +0 -183
  382. package/.cline/workflows/research.md +0 -39
  383. package/.cline/workflows/review.md +0 -448
  384. package/.cline/workflows/rollback.md +0 -718
  385. package/.cline/workflows/ship.md +0 -210
  386. package/.cline/workflows/sonarcloud.md +0 -146
  387. package/.cline/workflows/status.md +0 -87
  388. package/.cline/workflows/validate.md +0 -285
  389. package/.cline/workflows/verify.md +0 -266
  390. package/.codex/config.toml +0 -11
  391. package/.codex/skills/dev/SKILL.md +0 -345
  392. package/.codex/skills/plan/SKILL.md +0 -566
  393. package/.codex/skills/premerge/SKILL.md +0 -186
  394. package/.codex/skills/research/SKILL.md +0 -42
  395. package/.codex/skills/review/SKILL.md +0 -451
  396. package/.codex/skills/rollback/SKILL.md +0 -721
  397. package/.codex/skills/ship/SKILL.md +0 -213
  398. package/.codex/skills/sonarcloud/SKILL.md +0 -149
  399. package/.codex/skills/status/SKILL.md +0 -90
  400. package/.codex/skills/validate/SKILL.md +0 -288
  401. package/.codex/skills/verify/SKILL.md +0 -269
  402. package/.cursor/commands/dev.md +0 -342
  403. package/.cursor/commands/plan.md +0 -563
  404. package/.cursor/commands/premerge.md +0 -183
  405. package/.cursor/commands/research.md +0 -39
  406. package/.cursor/commands/review.md +0 -448
  407. package/.cursor/commands/ship.md +0 -210
  408. package/.cursor/commands/sonarcloud.md +0 -146
  409. package/.cursor/commands/status.md +0 -87
  410. package/.cursor/commands/validate.md +0 -285
  411. package/.cursor/commands/verify.md +0 -266
  412. package/.cursorrules +0 -149
  413. package/.github/prompts/premerge.prompt.md +0 -188
  414. package/.github/prompts/research.prompt.md +0 -44
  415. package/.github/prompts/rollback.prompt.md +0 -723
  416. package/.github/prompts/ship.prompt.md +0 -215
  417. package/.github/prompts/status.prompt.md +0 -92
  418. package/.github/prompts/verify.prompt.md +0 -271
  419. package/.github/workflows/beads-to-github.yml +0 -56
  420. package/.github/workflows/github-to-beads.yml +0 -97
  421. package/.kilocode/workflows/dev.md +0 -346
  422. package/.kilocode/workflows/plan.md +0 -567
  423. package/.kilocode/workflows/premerge.md +0 -187
  424. package/.kilocode/workflows/research.md +0 -43
  425. package/.kilocode/workflows/review.md +0 -452
  426. package/.kilocode/workflows/rollback.md +0 -722
  427. package/.kilocode/workflows/ship.md +0 -214
  428. package/.kilocode/workflows/sonarcloud.md +0 -150
  429. package/.kilocode/workflows/status.md +0 -91
  430. package/.kilocode/workflows/validate.md +0 -289
  431. package/.kilocode/workflows/verify.md +0 -270
  432. package/.opencode/commands/dev.md +0 -345
  433. package/.opencode/commands/plan.md +0 -566
  434. package/.opencode/commands/premerge.md +0 -186
  435. package/.opencode/commands/research.md +0 -42
  436. package/.opencode/commands/review.md +0 -451
  437. package/.opencode/commands/rollback.md +0 -721
  438. package/.opencode/commands/ship.md +0 -213
  439. package/.opencode/commands/sonarcloud.md +0 -149
  440. package/.opencode/commands/status.md +0 -90
  441. package/.opencode/commands/validate.md +0 -288
  442. package/.opencode/commands/verify.md +0 -269
  443. package/.roo/commands/dev.md +0 -346
  444. package/.roo/commands/plan.md +0 -567
  445. package/.roo/commands/premerge.md +0 -187
  446. package/.roo/commands/research.md +0 -43
  447. package/.roo/commands/review.md +0 -452
  448. package/.roo/commands/rollback.md +0 -722
  449. package/.roo/commands/ship.md +0 -214
  450. package/.roo/commands/sonarcloud.md +0 -150
  451. package/.roo/commands/status.md +0 -91
  452. package/.roo/commands/validate.md +0 -289
  453. package/.roo/commands/verify.md +0 -270
  454. package/docs/BEADS_GITHUB_SYNC.md +0 -255
  455. package/docs/GREPTILE_SETUP.md +0 -400
  456. package/docs/MANUAL_REVIEW_GUIDE.md +0 -106
  457. package/docs/SETUP.md +0 -663
  458. package/docs/VALIDATION.md +0 -363
  459. package/lib/agents/cline.plugin.json +0 -29
  460. package/lib/agents/copilot.plugin.json +0 -24
  461. package/lib/agents/kilocode.plugin.json +0 -22
  462. package/lib/agents/opencode.plugin.json +0 -23
  463. package/lib/agents/roo.plugin.json +0 -30
  464. package/lib/beads-health-check.js +0 -143
  465. package/lib/commands/commands-reset.js +0 -147
  466. package/opencode.json +0 -67
  467. package/scripts/beads-context.test.js +0 -567
  468. package/scripts/github-beads-sync/comment.mjs +0 -64
  469. package/scripts/github-beads-sync/config.mjs +0 -148
  470. package/scripts/github-beads-sync/github-api.mjs +0 -131
  471. package/scripts/github-beads-sync/index.mjs +0 -332
  472. package/scripts/github-beads-sync/label-mapper.mjs +0 -54
  473. package/scripts/github-beads-sync/mapping.mjs +0 -78
  474. package/scripts/github-beads-sync/reverse-sync-cli.mjs +0 -31
  475. package/scripts/github-beads-sync/reverse-sync.mjs +0 -138
  476. package/scripts/github-beads-sync/run-bd.mjs +0 -161
  477. package/scripts/github-beads-sync/sanitize.mjs +0 -121
  478. package/scripts/github-beads-sync.config.json +0 -26
  479. package/scripts/sync-commands.js +0 -600
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Static Command Manifest — GENERATED FILE, DO NOT EDIT.
3
+ *
4
+ * Regenerate with: node scripts/gen-command-manifest.js
5
+ * Drift is enforced by test/structural/command-manifest-drift.test.js.
6
+ *
7
+ * This module `require`s every command by a static relative path so
8
+ * `bun build --compile` can statically bundle the command graph. The registry
9
+ * (lib/commands/_registry.js) consumes `commands` as its fast, bundleable path
10
+ * and falls back to `fs.readdirSync` auto-discovery for dev/extension commands.
11
+ *
12
+ * @module commands/_manifest
13
+ */
14
+
15
+ 'use strict';
16
+
17
+ /**
18
+ * @typedef {Object} ManifestEntry
19
+ * @property {string} file - Command filename (e.g. `status.js`)
20
+ * @property {import("./_registry").CommandModule} module - The required command module
21
+ */
22
+
23
+ /** @type {ManifestEntry[]} */
24
+ const commands = [
25
+ { file: "adapter.js", module: require("./adapter") },
26
+ { file: "add.js", module: require("./add") },
27
+ { file: "audit.js", module: require("./audit") },
28
+ { file: "blocked.js", module: require("./blocked") },
29
+ { file: "board.js", module: require("./board") },
30
+ { file: "claim.js", module: require("./claim") },
31
+ { file: "claims.js", module: require("./claims") },
32
+ { file: "clean.js", module: require("./clean") },
33
+ { file: "close.js", module: require("./close") },
34
+ { file: "comment.js", module: require("./comment") },
35
+ { file: "control.js", module: require("./control") },
36
+ { file: "create.js", module: require("./create") },
37
+ { file: "dev.js", module: require("./dev") },
38
+ { file: "doc-gate.js", module: require("./doc-gate") },
39
+ { file: "doctor.js", module: require("./doctor") },
40
+ { file: "explain.js", module: require("./explain") },
41
+ { file: "export.js", module: require("./export") },
42
+ { file: "gate.js", module: require("./gate") },
43
+ { file: "hooks.js", module: require("./hooks") },
44
+ { file: "inbox.js", module: require("./inbox") },
45
+ { file: "init.js", module: require("./init") },
46
+ { file: "insights.js", module: require("./insights") },
47
+ { file: "issue.js", module: require("./issue") },
48
+ { file: "issues.js", module: require("./issues") },
49
+ { file: "lint.js", module: require("./lint") },
50
+ { file: "list.js", module: require("./list") },
51
+ { file: "merge.js", module: require("./merge") },
52
+ { file: "migrate.js", module: require("./migrate") },
53
+ { file: "new.js", module: require("./new") },
54
+ { file: "options.js", module: require("./options") },
55
+ { file: "orient.js", module: require("./orient") },
56
+ { file: "orphans.js", module: require("./orphans") },
57
+ { file: "patch.js", module: require("./patch") },
58
+ { file: "plan.js", module: require("./plan") },
59
+ { file: "preflight.js", module: require("./preflight") },
60
+ { file: "prime.js", module: require("./prime") },
61
+ { file: "push.js", module: require("./push") },
62
+ { file: "ready.js", module: require("./ready") },
63
+ { file: "recall.js", module: require("./recall") },
64
+ { file: "recap.js", module: require("./recap") },
65
+ { file: "recommend.js", module: require("./recommend") },
66
+ { file: "release.js", module: require("./release") },
67
+ { file: "remember.js", module: require("./remember") },
68
+ { file: "role.js", module: require("./role") },
69
+ { file: "serve.js", module: require("./serve") },
70
+ { file: "setup.js", module: require("./setup") },
71
+ { file: "shepherd.js", module: require("./shepherd") },
72
+ { file: "ship.js", module: require("./ship") },
73
+ { file: "show.js", module: require("./show") },
74
+ { file: "stage.js", module: require("./stage") },
75
+ { file: "stale.js", module: require("./stale") },
76
+ { file: "status.js", module: require("./status") },
77
+ { file: "sync.js", module: require("./sync") },
78
+ { file: "team.js", module: require("./team") },
79
+ { file: "test.js", module: require("./test") },
80
+ { file: "update.js", module: require("./update") },
81
+ { file: "upgrade.js", module: require("./upgrade") },
82
+ { file: "validate.js", module: require("./validate") },
83
+ { file: "worktree.js", module: require("./worktree") },
84
+ ];
85
+
86
+ module.exports = {
87
+ // Absolute path of the canonical commands directory this manifest describes.
88
+ // The registry applies the manifest only when asked to load this exact dir.
89
+ dir: __dirname,
90
+ commands,
91
+ };
@@ -13,11 +13,26 @@ const { existsSync, readdirSync } = require('node:fs');
13
13
  const path = require('node:path');
14
14
  const { normalizeStageId } = require('../workflow/stages');
15
15
 
16
+ // Static command manifest (bundleable fast path). This is a static require so
17
+ // `bun build --compile` can bundle the command graph; the file is generated by
18
+ // scripts/gen-command-manifest.js and drift-checked in test/structural. In a dev
19
+ // checkout before generation (or if removed) it may be absent — fall back to
20
+ // readdir auto-discovery below.
21
+ let STATIC_MANIFEST = null;
22
+ try {
23
+ STATIC_MANIFEST = require('./_manifest');
24
+ } catch (err) {
25
+ if (err.code !== 'MODULE_NOT_FOUND') {
26
+ console.warn(`[registry] Failed to load static manifest: ${err.message}`);
27
+ }
28
+ STATIC_MANIFEST = null;
29
+ }
30
+
16
31
  /**
17
32
  * @typedef {Object} CommandModule
18
33
  * @property {string} name - Command name used for routing
19
34
  * @property {string} description - Human-readable description
20
- * @property {function(Array, Object, string): Promise<*>} handler - Async command handler
35
+ * @property {function(Array, Object, string, Object=): Promise<*>} handler - Async command handler (4th arg: resolved command opts)
21
36
  * @property {string} [usage] - Usage string (optional)
22
37
  * @property {Object<string, string>} [flags] - Flag descriptions (optional)
23
38
  */
@@ -57,46 +72,68 @@ function validateCommand(mod) {
57
72
  * @param {string} commandsDir - Absolute path to the commands directory
58
73
  * @returns {{ commands: Map<string, CommandModule>, getHelp: () => string }}
59
74
  */
60
- function loadCommands(commandsDir) {
61
- /** @type {Map<string, CommandModule>} */
62
- const commands = new Map();
75
+ function addCommand(commands, file, mod) {
76
+ const validation = validateCommand(mod);
77
+ if (!validation.valid) {
78
+ console.warn(`[registry] Skipping ${file}: ${validation.reason}`);
79
+ return;
80
+ }
63
81
 
64
- if (!commandsDir || !existsSync(commandsDir)) {
65
- return {
66
- commands,
67
- getHelp: () => buildHelp(commands),
68
- };
82
+ if (commands.has(mod.name)) {
83
+ console.warn(
84
+ `[registry] Skipping ${file}: duplicate command name "${mod.name}"`
85
+ );
86
+ return;
69
87
  }
70
88
 
71
- const files = readdirSync(commandsDir)
72
- .filter(f => f.endsWith('.js') && !f.startsWith('_'))
73
- .sort(); // deterministic order — first file wins on duplicates
89
+ commands.set(mod.name, mod);
90
+ }
74
91
 
75
- for (const file of files) {
76
- const filePath = path.join(commandsDir, file);
92
+ function loadCommands(commandsDir) {
93
+ /** @type {Map<string, CommandModule>} */
94
+ const commands = new Map();
77
95
 
78
- let mod;
79
- try {
80
- mod = require(filePath);
81
- } catch (_err) {
82
- console.warn(`[registry] Skipping ${file}: failed to load — ${_err.message}`);
83
- continue;
96
+ // Files already contributed by the static manifest — skip re-requiring them
97
+ // during the readdir pass so they neither double-load nor warn as duplicates.
98
+ const seenFiles = new Set();
99
+
100
+ // 1) Static manifest fast path (bundleable). Applied only when the caller asks
101
+ // for the exact canonical commands dir the manifest describes; extension
102
+ // dirs fall through to readdir below. In a compiled binary there is no real
103
+ // commands dir on disk, so the manifest is the only path that resolves.
104
+ if (
105
+ STATIC_MANIFEST &&
106
+ Array.isArray(STATIC_MANIFEST.commands) &&
107
+ commandsDir &&
108
+ path.resolve(commandsDir) === path.resolve(STATIC_MANIFEST.dir)
109
+ ) {
110
+ for (const entry of STATIC_MANIFEST.commands) {
111
+ seenFiles.add(entry.file);
112
+ addCommand(commands, entry.file, entry.module);
84
113
  }
114
+ }
85
115
 
86
- const validation = validateCommand(mod);
87
- if (!validation.valid) {
88
- console.warn(`[registry] Skipping ${file}: ${validation.reason}`);
89
- continue;
90
- }
116
+ // 2) readdir auto-discovery (dev/extension fallback). Picks up command files
117
+ // not covered by the manifest — including brand-new files a developer or
118
+ // user drops in without regenerating the manifest — preserving extensibility.
119
+ if (commandsDir && existsSync(commandsDir)) {
120
+ const files = readdirSync(commandsDir)
121
+ .filter(f => f.endsWith('.js') && !f.startsWith('_'))
122
+ .sort(); // deterministic order — first file wins on duplicates
123
+
124
+ for (const file of files) {
125
+ if (seenFiles.has(file)) continue;
126
+
127
+ let mod;
128
+ try {
129
+ mod = require(path.join(commandsDir, file));
130
+ } catch (_err) {
131
+ console.warn(`[registry] Skipping ${file}: failed to load — ${_err.message}`);
132
+ continue;
133
+ }
91
134
 
92
- if (commands.has(mod.name)) {
93
- console.warn(
94
- `[registry] Skipping ${file}: duplicate command name "${mod.name}"`
95
- );
96
- continue;
135
+ addCommand(commands, file, mod);
97
136
  }
98
-
99
- commands.set(mod.name, mod);
100
137
  }
101
138
 
102
139
  return {
@@ -143,8 +180,9 @@ async function executeCommand(commands, commandName, args, flags, projectRoot, o
143
180
  }
144
181
 
145
182
  try {
183
+ let enforcement = null;
146
184
  if (typeof options.enforceStage === 'function' && isStageCommand(commandName)) {
147
- const enforcement = await options.enforceStage({
185
+ enforcement = await options.enforceStage({
148
186
  commandName,
149
187
  args,
150
188
  flags,
@@ -161,7 +199,20 @@ async function executeCommand(commands, commandName, args, flags, projectRoot, o
161
199
  }
162
200
  }
163
201
 
164
- return await command.handler(args, flags, projectRoot);
202
+ // Forward a resolved per-command opts object as the handler's 4th arg. Issue/
203
+ // alias handlers read it (shouldUseKernelBroker(opts)); other handlers ignore
204
+ // it. Backward-compatible: defaults to {} so existing 3-arg handlers are
205
+ // unaffected.
206
+ const result = await command.handler(args, flags, projectRoot, options.commandOpts ?? {});
207
+
208
+ // Record stage COMPLETION into the kernel only when the command SUCCEEDED, so
209
+ // a stage counts as 'done' (which gates ship/review) only when its command
210
+ // actually passed — not merely when it was entered.
211
+ if (result?.success !== false && typeof enforcement?.recordCompletion === 'function') {
212
+ enforcement.recordCompletion();
213
+ }
214
+
215
+ return result;
165
216
  } catch (err) {
166
217
  return {
167
218
  success: false,
@@ -0,0 +1,261 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Resolve the per-command opts object that bin/forge.js threads to the registry
5
+ * handler (the 4th arg). For issue/alias commands this:
6
+ *
7
+ * 1. Strips the selector tokens (`--kernel`, `--issue-backend <val>`) from the
8
+ * args BEFORE they reach the handler / bd. This is load-bearing: bin
9
+ * parseFlags() early-returns for issue passthrough commands, so these tokens
10
+ * otherwise flow untouched into the handler and (beads path) into bd, which
11
+ * rejects the unknown flag — and the positional `kernel`/`beads` value would
12
+ * be mistaken for an issue id.
13
+ * 2. Resolves the backend (flag > env > config > default) via the backend
14
+ * authority module (lib/issue-backend.js). The CLI flag tokens are mapped to
15
+ * that module's `deps.issueBackend` signal; env/config/default precedence is
16
+ * applied by the resolver itself.
17
+ * 3. When kernel, assembles the kernel deps (driver + flag) via the CLI broker
18
+ * factory so createKernelIssueBackend has a real driver (B1).
19
+ *
20
+ * Kernel-native tool commands (KERNEL_TOOL_COMMANDS, e.g. `export`) instead get a
21
+ * migrated Kernel broker injected as `_broker` (independent of the selector), and
22
+ * all other non-issue commands get an empty opts object and untouched args.
23
+ *
24
+ * @module commands/resolve-command-opts
25
+ */
26
+
27
+ const { resolveIssueBackend } = require('../issue-backend');
28
+ const {
29
+ buildMigratedKernelIssueDeps: defaultBuildKernelIssueDeps,
30
+ } = require('../kernel/cli-broker-factory');
31
+
32
+ // Commands that route issue operations and therefore honor the selector. Mirrors
33
+ // the alias wrappers in lib/commands/ plus the `issue`/`issues` grouping commands.
34
+ const ISSUE_COMMANDS = new Set([
35
+ 'create',
36
+ 'update',
37
+ 'claim',
38
+ 'release',
39
+ 'comment',
40
+ 'close',
41
+ 'show',
42
+ 'list',
43
+ 'ready',
44
+ 'blocked',
45
+ 'stale',
46
+ 'orphans',
47
+ 'lint',
48
+ // Epic grouping read — must be kernel-routed (its issue.children rollup has no
49
+ // verified Beads equivalent), so it belongs in ISSUE_COMMANDS like the rest.
50
+ 'children',
51
+ // Lease-ownership verification — a kernel-only read (leases live in the Kernel),
52
+ // so it is kernel-routed like the rest of the issue surface.
53
+ 'owns',
54
+ // Active-lease listing — a kernel-only read (leases live in the Kernel), so it
55
+ // is kernel-routed like the rest of the issue surface.
56
+ 'claims',
57
+ 'search',
58
+ 'stats',
59
+ 'dep',
60
+ 'issue',
61
+ 'issues',
62
+ ]);
63
+
64
+ // Kernel-native tool commands that operate directly on the Kernel regardless of the
65
+ // issue-backend selector, so they need a real (migrated) Kernel broker injected as
66
+ // the handler's `_broker`. `export` drains the Kernel projection outbox to
67
+ // git-tracked JSONL (D16); without an injected broker its handler always reports
68
+ // "No Kernel broker available" and writes nothing.
69
+ const KERNEL_TOOL_COMMANDS = new Set([
70
+ 'export',
71
+ ]);
72
+
73
+ const ISSUE_BACKEND_FLAG = '--issue-backend';
74
+ const KERNEL_FLAG = '--kernel';
75
+ const KERNEL = 'kernel';
76
+
77
+ /**
78
+ * Remove the issue-backend selector tokens from an args array and report what
79
+ * they selected. Handles `--kernel`, `--issue-backend <val>` (space form), and
80
+ * `--issue-backend=<val>` (= form). All other tokens pass through unchanged.
81
+ *
82
+ * @param {string[]} rawArgs
83
+ * @returns {{ args: string[], flags: { kernel?: boolean, issueBackend?: string } }}
84
+ */
85
+ function stripSelectorTokens(rawArgs = []) {
86
+ const args = [];
87
+ const flags = {};
88
+ for (let i = 0; i < rawArgs.length; i += 1) {
89
+ const token = rawArgs[i];
90
+ if (token === KERNEL_FLAG) {
91
+ flags.kernel = true;
92
+ continue;
93
+ }
94
+ if (token === ISSUE_BACKEND_FLAG) {
95
+ // Space form: consume the following value token as the backend name. Only a
96
+ // non-flag token counts — a missing value or a following flag (e.g.
97
+ // `--issue-backend --reason=x`) must throw rather than silently swallow the
98
+ // next flag and fall back to the default backend.
99
+ const next = rawArgs[i + 1];
100
+ if (typeof next === 'string' && !next.startsWith('--')) {
101
+ flags.issueBackend = next;
102
+ i += 1;
103
+ } else {
104
+ throw new Error(`${ISSUE_BACKEND_FLAG} requires a value: kernel or beads.`);
105
+ }
106
+ continue;
107
+ }
108
+ if (typeof token === 'string' && token.startsWith(`${ISSUE_BACKEND_FLAG}=`)) {
109
+ // Equals form: reject an empty value (`--issue-backend=`) for the same reason.
110
+ const value = token.slice(ISSUE_BACKEND_FLAG.length + 1).trim();
111
+ if (!value) {
112
+ throw new Error(`${ISSUE_BACKEND_FLAG} requires a value: kernel or beads.`);
113
+ }
114
+ flags.issueBackend = value;
115
+ continue;
116
+ }
117
+ args.push(token);
118
+ }
119
+ return { args, flags };
120
+ }
121
+
122
+ /**
123
+ * Reduce the stripped selector flags to a single explicit backend value (or null
124
+ * when no flag selects one), honoring `--kernel` / `--issue-backend` equivalence
125
+ * and rejecting a mutually-exclusive conflict. Returned values are NOT validated
126
+ * here — the backend authority module normalizes/warns on unknown values.
127
+ *
128
+ * @param {{ kernel?: boolean, issueBackend?: string }} flags
129
+ * @returns {string|null}
130
+ * @throws {Error} when --kernel and --issue-backend select different backends.
131
+ */
132
+ function resolveFlagBackend(flags = {}) {
133
+ const fromBackend = typeof flags.issueBackend === 'string' && flags.issueBackend.trim()
134
+ ? flags.issueBackend.trim()
135
+ : null;
136
+ const fromKernel = flags.kernel === true ? KERNEL : null;
137
+
138
+ if (fromKernel && fromBackend && fromKernel !== fromBackend.toLowerCase()) {
139
+ throw new Error(
140
+ `Conflicting issue backend flags: --kernel selects '${KERNEL}' but `
141
+ + `--issue-backend selects '${fromBackend}'. These are mutually exclusive.`,
142
+ );
143
+ }
144
+
145
+ return fromKernel || fromBackend || null;
146
+ }
147
+
148
+ // Run the first-use Beads import safety net for a kernel-routed command. Resolving the
149
+ // migrate module lives INSIDE the try so even a require() failure (missing/corrupt
150
+ // module) can never break command-opts resolution — the whole point of the safety net.
151
+ // Shared by both kernel branches (issue + KERNEL_TOOL_COMMANDS) so the two call sites
152
+ // cannot drift.
153
+ async function runRuntimeAutoMigrate(deps, kernelDeps) {
154
+ try {
155
+ const autoMigrate = deps.autoMigrateBeadsAtRuntime
156
+ || require('./migrate').autoMigrateBeadsAtRuntime;
157
+ await autoMigrate({
158
+ projectRoot: deps.projectRoot,
159
+ databasePath: kernelDeps.kernelDatabasePath,
160
+ broker: kernelDeps.kernelBroker,
161
+ driver: kernelDeps.kernelDriver,
162
+ });
163
+ } catch {
164
+ // A migration-hook failure (including a require() failure) must never break the
165
+ // command it rides on.
166
+ }
167
+ }
168
+
169
+ /**
170
+ * Resolve the command opts and selector-stripped args for a dispatched command.
171
+ *
172
+ * @param {string} command - The command name (e.g. 'close').
173
+ * @param {string[]} rawArgs - The command args (already `args.slice(1)`).
174
+ * @param {Object} [deps]
175
+ * @param {Object} [deps.env] - Environment snapshot (default process.env).
176
+ * @param {string} [deps.projectRoot] - Repo root for env/config resolution + kernel DB.
177
+ * @param {Function} [deps.buildKernelIssueDeps] - Factory override (tests). May be
178
+ * sync or async; its result is awaited.
179
+ * @returns {Promise<{ commandOpts: Object, args: string[] }>}
180
+ * @throws {Error} on conflicting flags (surfaced to user).
181
+ */
182
+ async function resolveCommandOpts(command, rawArgs = [], deps = {}) {
183
+ const buildKernelIssueDeps = deps.buildKernelIssueDeps || defaultBuildKernelIssueDeps;
184
+
185
+ if (KERNEL_TOOL_COMMANDS.has(command)) {
186
+ // Kernel-native tools (e.g. `export`) always get a migrated Kernel broker the
187
+ // same way issue commands do (the CLI broker factory builds the driver, builds
188
+ // the broker, and runs initialize()). The handler consumes it as `_broker`.
189
+ // If no broker can be built (e.g. no SQLite runtime) we fall through with no
190
+ // broker so the handler skips gracefully rather than hard-failing — these tools
191
+ // are explicitly non-fatal when the Kernel is unavailable.
192
+ try {
193
+ const kernelDeps = await buildKernelIssueDeps({
194
+ projectRoot: deps.projectRoot,
195
+ databasePath: deps.databasePath,
196
+ gitCommonDir: deps.gitCommonDir,
197
+ });
198
+ // Same first-use safety net as the issue branch: an export-first upgrader would
199
+ // otherwise drain an EMPTY kernel and never trigger the one-time Beads import.
200
+ await runRuntimeAutoMigrate(deps, kernelDeps);
201
+ return { commandOpts: { _broker: kernelDeps.kernelBroker }, args: rawArgs };
202
+ } catch {
203
+ return { commandOpts: {}, args: rawArgs };
204
+ }
205
+ }
206
+
207
+ if (!ISSUE_COMMANDS.has(command)) {
208
+ return { commandOpts: {}, args: rawArgs };
209
+ }
210
+
211
+ const env = deps.env || process.env;
212
+
213
+ const { args, flags } = stripSelectorTokens(rawArgs);
214
+ const flagBackend = resolveFlagBackend(flags);
215
+ const issueBackend = resolveIssueBackend({
216
+ deps: flagBackend ? { issueBackend: flagBackend } : {},
217
+ env,
218
+ projectRoot: deps.projectRoot,
219
+ });
220
+
221
+ if (issueBackend !== KERNEL) {
222
+ return {
223
+ commandOpts: {
224
+ issueBackend,
225
+ useKernelBroker: false,
226
+ },
227
+ args,
228
+ };
229
+ }
230
+
231
+ // Kernel backend: assemble the driver (B1) + migrated broker (B2). The factory
232
+ // builder constructs the driver, builds the broker, and runs initialize().
233
+ const kernelDeps = await buildKernelIssueDeps({
234
+ projectRoot: deps.projectRoot,
235
+ databasePath: deps.databasePath,
236
+ gitCommonDir: deps.gitCommonDir,
237
+ });
238
+
239
+ // Safety net: the kernel is the default backend, but onboarding auto-migrate runs
240
+ // only from `forge setup`/`init`. An existing repo whose user merely upgrades forge
241
+ // would read an EMPTY kernel here and their existing Beads issues would appear to
242
+ // vanish. Import them ONCE on first kernel use (idempotent, gated by an in-DB marker
243
+ // that shares the kernel DB lifecycle, stderr only).
244
+ await runRuntimeAutoMigrate(deps, kernelDeps);
245
+
246
+ return {
247
+ commandOpts: {
248
+ issueBackend: KERNEL,
249
+ ...kernelDeps,
250
+ },
251
+ args,
252
+ };
253
+ }
254
+
255
+ module.exports = {
256
+ resolveCommandOpts,
257
+ stripSelectorTokens,
258
+ resolveFlagBackend,
259
+ ISSUE_COMMANDS,
260
+ KERNEL_TOOL_COMMANDS,
261
+ };