forge-workflow 0.0.10 → 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 (454) 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 +150 -61
  8. package/CHANGELOG.md +681 -0
  9. package/CLAUDE.md +9 -118
  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 +461 -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/forge/TOOLCHAIN.md +670 -0
  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/{TOOLCHAIN.md → reference/TOOLCHAIN.md} +62 -47
  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 +121 -0
  81. package/lib/beads-sync-scaffold.js +25 -101
  82. package/lib/codex-skills.js +51 -1
  83. package/lib/commands/_issue.js +741 -77
  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 +17 -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 +0 -1
  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 +838 -972
  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 +158 -21
  140. package/lib/commands/sync.js +34 -46
  141. package/lib/commands/team.js +4 -1
  142. package/lib/commands/test.js +43 -27
  143. package/lib/commands/update.js +2 -2
  144. package/lib/commands/upgrade.js +47 -0
  145. package/lib/commands/validate.js +43 -18
  146. package/lib/commands/worktree.js +307 -100
  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 +2 -2
  151. package/lib/deprecated-sync-cleanup.js +362 -0
  152. package/lib/detect-agent.js +2 -28
  153. package/lib/detect-worktree.js +35 -9
  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 +382 -11
  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/kernel/backing-issue.js +305 -0
  174. package/lib/kernel/broker.js +1218 -0
  175. package/lib/kernel/cli-broker-factory.js +130 -0
  176. package/lib/kernel/conflict-signal.js +82 -0
  177. package/lib/kernel/evaluators.js +195 -0
  178. package/lib/kernel/fs-class.js +495 -0
  179. package/lib/kernel/issue-command-contract.js +559 -0
  180. package/lib/kernel/issue-id-resolver.js +186 -0
  181. package/lib/kernel/lease-enforcer.js +158 -0
  182. package/lib/kernel/migrations.js +333 -0
  183. package/lib/kernel/planning-buckets-schema.js +109 -0
  184. package/lib/kernel/projection-jsonl-writer.js +450 -0
  185. package/lib/kernel/readiness-model.js +329 -0
  186. package/lib/kernel/schema.js +356 -0
  187. package/lib/kernel/sqlite-driver.js +2504 -0
  188. package/lib/kernel/taxonomy-validator.js +394 -0
  189. package/lib/lefthook-check.js +3 -2
  190. package/lib/lefthook-wiring.js +413 -0
  191. package/lib/mcp-config-renderer.js +288 -0
  192. package/lib/memory/graphiti-mcp.js +106 -0
  193. package/lib/memory/router.js +387 -0
  194. package/lib/memory/typed-api.js +102 -0
  195. package/lib/memory-digest.js +195 -0
  196. package/lib/merge-rules.js +395 -0
  197. package/lib/migrate-dry-run.js +466 -0
  198. package/lib/orientation.js +863 -0
  199. package/lib/package-manager-remediation.js +103 -0
  200. package/lib/package-root.js +381 -0
  201. package/lib/patch-intent.js +890 -0
  202. package/lib/plugin-catalog.js +3 -4
  203. package/lib/plugin-manager.js +0 -5
  204. package/lib/pr-bundle.js +186 -0
  205. package/lib/pr-monitor/differ.js +195 -0
  206. package/lib/pr-monitor/events.js +0 -0
  207. package/lib/pr-monitor/gather.js +124 -0
  208. package/lib/pr-monitor/journal.js +299 -0
  209. package/lib/pr-monitor/monitor.js +146 -0
  210. package/lib/pr-monitor/render-sticky.js +157 -0
  211. package/lib/pr-monitor/watch-lifecycle.js +95 -0
  212. package/lib/pr-monitor/watch.js +247 -0
  213. package/lib/pr-pull.js +1273 -0
  214. package/lib/pr-shepherd.js +494 -0
  215. package/lib/pr-state-validator.js +59 -0
  216. package/lib/preflight/gates.js +237 -0
  217. package/lib/preflight/runner.js +116 -0
  218. package/lib/project-discovery.js +0 -53
  219. package/lib/project-memory.js +99 -497
  220. package/lib/protected-path-manifest.js +281 -0
  221. package/lib/protected-state-surfaces.js +387 -0
  222. package/lib/release-readiness.js +2089 -0
  223. package/lib/reset.js +59 -45
  224. package/lib/review-adapter.js +68 -0
  225. package/lib/rules-sync.js +260 -0
  226. package/lib/runtime-health.js +241 -20
  227. package/lib/safety-config-renderer.js +268 -0
  228. package/lib/setup-action-log.js +1 -7
  229. package/lib/setup.js +27 -65
  230. package/lib/shell-utils.js +76 -6
  231. package/lib/skills-sync.js +330 -0
  232. package/lib/smart-status/scoring.js +17 -3
  233. package/lib/status/beads-snapshot.js +45 -2
  234. package/lib/status/presenter.js +169 -18
  235. package/lib/status/snapshot.js +186 -0
  236. package/lib/sync-backend.js +202 -0
  237. package/lib/untrusted-content.js +52 -0
  238. package/lib/upgrade-safety.js +199 -0
  239. package/lib/workflow/enforce-stage.js +296 -47
  240. package/lib/workflow/stage-transition.js +115 -0
  241. package/lib/workflow/stages.js +30 -6
  242. package/lib/workflow/state-manager.js +11 -22
  243. package/lib/workflow/state.js +23 -1
  244. package/lib/workflow-profiles.js +17 -5
  245. package/package.json +37 -35
  246. package/rules/documentation.md +19 -0
  247. package/rules/kernel-tracking.md +26 -0
  248. package/rules/security.md +22 -0
  249. package/rules/tdd.md +20 -0
  250. package/rules/workflow.md +27 -0
  251. package/scripts/auto-backing-issue.js +47 -0
  252. package/scripts/beads-context.sh +81 -57
  253. package/scripts/beads-upgrade-smoke.sh +24 -3
  254. package/scripts/bootstrap-windows-tools.sh +78 -0
  255. package/scripts/branch-protection.js +2 -3
  256. package/scripts/check-agents.js +34 -137
  257. package/scripts/commitlint.js +3 -1
  258. package/scripts/conflict-detect.sh +3 -0
  259. package/scripts/dep-guard.sh +22 -3
  260. package/scripts/file-index.sh +3 -0
  261. package/scripts/forge-team/lib/claim.sh +34 -18
  262. package/scripts/forge-team/lib/dashboard.sh +61 -86
  263. package/scripts/forge-team/lib/epic.sh +99 -263
  264. package/scripts/forge-team/lib/hooks.sh +26 -28
  265. package/scripts/forge-team/lib/identity.sh +4 -4
  266. package/scripts/forge-team/lib/sync-github.sh +49 -84
  267. package/scripts/forge-team/lib/verify.sh +93 -83
  268. package/scripts/forge-team/lib/workload.sh +41 -65
  269. package/scripts/forge-team/tests/claim.test.sh +25 -19
  270. package/scripts/forge-team/tests/dashboard.test.sh +31 -46
  271. package/scripts/forge-team/tests/epic.test.sh +52 -71
  272. package/scripts/forge-team/tests/hooks.test.sh +38 -50
  273. package/scripts/forge-team/tests/identity.test.sh +3 -3
  274. package/scripts/forge-team/tests/integration.test.sh +44 -66
  275. package/scripts/forge-team/tests/sync-github.test.sh +50 -83
  276. package/scripts/forge-team/tests/verify.test.sh +37 -46
  277. package/scripts/forge-team/tests/workflow-integration.test.sh +4 -4
  278. package/scripts/forge-team/tests/workload.test.sh +32 -66
  279. package/scripts/gen-command-manifest.js +153 -0
  280. package/scripts/gen-embedded-assets.mjs +129 -0
  281. package/scripts/install.ps1 +139 -0
  282. package/scripts/install.sh +268 -0
  283. package/scripts/lib/release-asset.mjs +84 -0
  284. package/scripts/parity-check.mjs +145 -0
  285. package/scripts/parity-check.test.mjs +58 -0
  286. package/scripts/pin-agentic-workflow-images.js +112 -0
  287. package/scripts/pr-coordinator.sh +3 -0
  288. package/scripts/preflight-sonar.eslint.config.mjs +44 -0
  289. package/scripts/preflight.sh +21 -94
  290. package/scripts/protected-state-check.js +104 -0
  291. package/scripts/smart-status.sh +60 -57
  292. package/scripts/spikes/config-race-bench.js +111 -0
  293. package/scripts/spikes/harness-capability-matrix.js +13 -0
  294. package/scripts/spikes/patch-anchor-stability-bench.js +125 -0
  295. package/scripts/spikes/protected-path-manifest.js +20 -0
  296. package/scripts/spikes/skill-auto-invoke-parity.js +292 -0
  297. package/scripts/sync-agent-skills.js +62 -0
  298. package/scripts/sync-utils.sh +3 -0
  299. package/scripts/test-ci-shard.js +13 -6
  300. package/scripts/test.js +95 -12
  301. package/skills/claim-safety/SKILL.md +102 -0
  302. package/skills/claim-safety/evals/evals.json +46 -0
  303. package/{.github/prompts/dev.prompt.md → skills/dev/SKILL.md} +44 -50
  304. package/skills/dev/evals/evals.json +50 -0
  305. package/skills/hermes-forge/SKILL.md +185 -0
  306. package/skills/hermes-forge/evals/evals.json +46 -0
  307. package/skills/issue-basics/SKILL.md +111 -0
  308. package/skills/issue-basics/evals/evals.json +46 -0
  309. package/skills/kernel/SKILL.md +166 -0
  310. package/skills/kernel/evals/evals.json +50 -0
  311. package/skills/memory/SKILL.md +102 -0
  312. package/skills/parallel-deep-research/SKILL.md +14 -11
  313. package/skills/parallel-deep-research/evals/evals.json +11 -27
  314. package/{.github/prompts/plan.prompt.md → skills/plan/SKILL.md} +132 -157
  315. package/skills/plan/evals/evals.json +42 -0
  316. package/skills/research/SKILL.md +195 -0
  317. package/skills/research/evals/evals.json +42 -0
  318. package/{.github/prompts/review.prompt.md → skills/review/SKILL.md} +98 -62
  319. package/skills/review/evals/evals.json +42 -0
  320. package/skills/rollback/SKILL.md +110 -0
  321. package/skills/rollback/evals/evals.json +46 -0
  322. package/skills/rollback/references/methods.md +204 -0
  323. package/{.cursor/commands/rollback.md → skills/rollback/references/workflow-integration.md} +10 -284
  324. package/skills/shepherd/SKILL.md +66 -0
  325. package/skills/shepherd/evals/evals.json +42 -0
  326. package/{.github/prompts/ship.prompt.md → skills/ship/SKILL.md} +81 -45
  327. package/skills/ship/evals/evals.json +42 -0
  328. package/skills/smith/SKILL.md +142 -0
  329. package/skills/smith/evals/evals.json +46 -0
  330. package/skills/smith/references/autonomy-and-gates.md +94 -0
  331. package/{.github/prompts/sonarcloud.prompt.md → skills/sonarcloud/SKILL.md} +14 -3
  332. package/skills/sonarcloud/evals/evals.json +46 -0
  333. package/skills/sonarcloud-analysis/SKILL.md +18 -13
  334. package/skills/sonarcloud-analysis/evals/evals.json +11 -15
  335. package/{.github/prompts/status.prompt.md → skills/status/SKILL.md} +20 -10
  336. package/skills/status/evals/evals.json +50 -0
  337. package/skills/triage-ready/SKILL.md +121 -0
  338. package/skills/triage-ready/evals/evals.json +42 -0
  339. package/{.github/prompts/validate.prompt.md → skills/validate/SKILL.md} +52 -29
  340. package/skills/validate/evals/evals.json +42 -0
  341. package/skills/verify/SKILL.md +299 -0
  342. package/skills/verify/evals/evals.json +50 -0
  343. package/.claude/commands/dev.md +0 -345
  344. package/.claude/commands/plan.md +0 -566
  345. package/.claude/commands/premerge.md +0 -186
  346. package/.claude/commands/research.md +0 -42
  347. package/.claude/commands/review.md +0 -451
  348. package/.claude/commands/rollback.md +0 -721
  349. package/.claude/commands/ship.md +0 -213
  350. package/.claude/commands/sonarcloud.md +0 -152
  351. package/.claude/commands/status.md +0 -90
  352. package/.claude/commands/validate.md +0 -288
  353. package/.claude/commands/verify.md +0 -269
  354. package/.claude/rules/workflow.md +0 -121
  355. package/.cline/workflows/dev.md +0 -342
  356. package/.cline/workflows/plan.md +0 -563
  357. package/.cline/workflows/premerge.md +0 -183
  358. package/.cline/workflows/research.md +0 -39
  359. package/.cline/workflows/review.md +0 -448
  360. package/.cline/workflows/rollback.md +0 -718
  361. package/.cline/workflows/ship.md +0 -210
  362. package/.cline/workflows/sonarcloud.md +0 -146
  363. package/.cline/workflows/status.md +0 -87
  364. package/.cline/workflows/validate.md +0 -285
  365. package/.cline/workflows/verify.md +0 -266
  366. package/.codex/config.toml +0 -11
  367. package/.codex/skills/dev/SKILL.md +0 -345
  368. package/.codex/skills/plan/SKILL.md +0 -566
  369. package/.codex/skills/premerge/SKILL.md +0 -186
  370. package/.codex/skills/research/SKILL.md +0 -42
  371. package/.codex/skills/review/SKILL.md +0 -451
  372. package/.codex/skills/rollback/SKILL.md +0 -721
  373. package/.codex/skills/ship/SKILL.md +0 -213
  374. package/.codex/skills/sonarcloud/SKILL.md +0 -149
  375. package/.codex/skills/status/SKILL.md +0 -90
  376. package/.codex/skills/validate/SKILL.md +0 -288
  377. package/.codex/skills/verify/SKILL.md +0 -269
  378. package/.cursor/commands/dev.md +0 -342
  379. package/.cursor/commands/plan.md +0 -563
  380. package/.cursor/commands/premerge.md +0 -183
  381. package/.cursor/commands/research.md +0 -39
  382. package/.cursor/commands/review.md +0 -448
  383. package/.cursor/commands/ship.md +0 -210
  384. package/.cursor/commands/sonarcloud.md +0 -146
  385. package/.cursor/commands/status.md +0 -87
  386. package/.cursor/commands/validate.md +0 -285
  387. package/.cursor/commands/verify.md +0 -266
  388. package/.cursorrules +0 -149
  389. package/.github/prompts/premerge.prompt.md +0 -188
  390. package/.github/prompts/research.prompt.md +0 -44
  391. package/.github/prompts/rollback.prompt.md +0 -723
  392. package/.github/prompts/verify.prompt.md +0 -271
  393. package/.github/workflows/beads-to-github.yml +0 -89
  394. package/.github/workflows/github-to-beads.yml +0 -100
  395. package/.kilocode/workflows/dev.md +0 -346
  396. package/.kilocode/workflows/plan.md +0 -567
  397. package/.kilocode/workflows/premerge.md +0 -187
  398. package/.kilocode/workflows/research.md +0 -43
  399. package/.kilocode/workflows/review.md +0 -452
  400. package/.kilocode/workflows/rollback.md +0 -722
  401. package/.kilocode/workflows/ship.md +0 -214
  402. package/.kilocode/workflows/sonarcloud.md +0 -150
  403. package/.kilocode/workflows/status.md +0 -91
  404. package/.kilocode/workflows/validate.md +0 -289
  405. package/.kilocode/workflows/verify.md +0 -270
  406. package/.opencode/commands/dev.md +0 -345
  407. package/.opencode/commands/plan.md +0 -566
  408. package/.opencode/commands/premerge.md +0 -186
  409. package/.opencode/commands/research.md +0 -42
  410. package/.opencode/commands/review.md +0 -451
  411. package/.opencode/commands/rollback.md +0 -721
  412. package/.opencode/commands/ship.md +0 -213
  413. package/.opencode/commands/sonarcloud.md +0 -149
  414. package/.opencode/commands/status.md +0 -90
  415. package/.opencode/commands/validate.md +0 -288
  416. package/.opencode/commands/verify.md +0 -269
  417. package/.roo/commands/dev.md +0 -346
  418. package/.roo/commands/plan.md +0 -567
  419. package/.roo/commands/premerge.md +0 -187
  420. package/.roo/commands/research.md +0 -43
  421. package/.roo/commands/review.md +0 -452
  422. package/.roo/commands/rollback.md +0 -722
  423. package/.roo/commands/ship.md +0 -214
  424. package/.roo/commands/sonarcloud.md +0 -150
  425. package/.roo/commands/status.md +0 -91
  426. package/.roo/commands/validate.md +0 -289
  427. package/.roo/commands/verify.md +0 -270
  428. package/docs/BEADS_GITHUB_SYNC.md +0 -281
  429. package/docs/GREPTILE_SETUP.md +0 -400
  430. package/docs/MANUAL_REVIEW_GUIDE.md +0 -106
  431. package/docs/SETUP.md +0 -663
  432. package/docs/VALIDATION.md +0 -363
  433. package/lib/agents/cline.plugin.json +0 -29
  434. package/lib/agents/copilot.plugin.json +0 -24
  435. package/lib/agents/kilocode.plugin.json +0 -22
  436. package/lib/agents/opencode.plugin.json +0 -23
  437. package/lib/agents/roo.plugin.json +0 -30
  438. package/lib/beads-bootstrap.js +0 -225
  439. package/lib/beads-health-check.js +0 -188
  440. package/lib/commands/commands-reset.js +0 -147
  441. package/opencode.json +0 -67
  442. package/scripts/beads-context.test.js +0 -584
  443. package/scripts/github-beads-sync/comment.mjs +0 -64
  444. package/scripts/github-beads-sync/config.mjs +0 -148
  445. package/scripts/github-beads-sync/github-api.mjs +0 -131
  446. package/scripts/github-beads-sync/index.mjs +0 -356
  447. package/scripts/github-beads-sync/label-mapper.mjs +0 -54
  448. package/scripts/github-beads-sync/mapping.mjs +0 -132
  449. package/scripts/github-beads-sync/reverse-sync-cli.mjs +0 -31
  450. package/scripts/github-beads-sync/reverse-sync.mjs +0 -162
  451. package/scripts/github-beads-sync/run-bd.mjs +0 -161
  452. package/scripts/github-beads-sync/sanitize.mjs +0 -121
  453. package/scripts/github-beads-sync.config.json +0 -26
  454. 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
+ };