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
@@ -8,9 +8,12 @@
8
8
  */
9
9
 
10
10
  const fs = require('node:fs');
11
+ const path = require('node:path');
11
12
  const { execFileSync: defaultExecFileSync } = require('node:child_process');
12
13
 
13
14
  const { checkLefthookStatus } = require('./lefthook-check');
15
+ const { resolveIssueBackend } = require('./issue-backend');
16
+ const { getInstallCommand, getAddDevCommand } = require('./package-manager-remediation');
14
17
 
15
18
  const WINDOWS_GIT_BASH_CANDIDATES = [
16
19
  String.raw`C:\Program Files\Git\bin\bash.exe`,
@@ -42,11 +45,149 @@ function normalizeHooksPath(value, platform = process.platform) {
42
45
  return normalized;
43
46
  }
44
47
 
45
- function createDiagnostic(code, subject, message, repair) {
48
+ function isAbsoluteForPlatform(value, platform = process.platform) {
49
+ const raw = toText(value).trim();
50
+ return platform === 'win32' ? path.win32.isAbsolute(raw) : path.posix.isAbsolute(raw);
51
+ }
52
+
53
+ function resolvesToExecutableHookCommand(line, matcher) {
54
+ const trimmed = line.trim();
55
+ if (!trimmed || trimmed.startsWith('#')) return false;
56
+ const firstCommand = commandName(commandTokens(trimmed)[0]);
57
+ if (firstCommand === 'echo' || firstCommand === 'printf') {
58
+ const chainIndex = trimmed.indexOf('&&');
59
+ return chainIndex === -1 ? false : matcher(trimmed.slice(chainIndex + 2).trim());
60
+ }
61
+ return matcher(trimmed);
62
+ }
63
+
64
+ function hasExecutableHookCommand(content, matcher) {
65
+ let heredocEnd = null;
66
+
67
+ for (const line of toText(content).split(/\r?\n/)) {
68
+ const trimmed = line.trim();
69
+ if (heredocEnd) {
70
+ if (trimmed === heredocEnd) heredocEnd = null;
71
+ continue;
72
+ }
73
+
74
+ if (resolvesToExecutableHookCommand(line, matcher)) return true;
75
+
76
+ const delimiter = heredocDelimiter(line);
77
+ if (delimiter) heredocEnd = delimiter;
78
+ }
79
+
80
+ return false;
81
+ }
82
+
83
+ function commandTokens(line) {
84
+ return line
85
+ .replace(/[;"'()]/g, ' ')
86
+ .split(/\s+/)
87
+ .filter(Boolean);
88
+ }
89
+
90
+ function commandName(token) {
91
+ return toText(token)
92
+ .replaceAll('\\', '/')
93
+ .split('/')
94
+ .pop()
95
+ .toLowerCase()
96
+ .replace(/\.(?:exe|cmd)$/, '');
97
+ }
98
+
99
+ function isWhitespace(char) {
100
+ return char === ' ' || char === '\t' || char === '\r' || char === '\n';
101
+ }
102
+
103
+ function isVariableNameStart(char) {
104
+ return (char >= 'A' && char <= 'Z') || (char >= 'a' && char <= 'z') || char === '_';
105
+ }
106
+
107
+ function isVariableNameChar(char) {
108
+ return isVariableNameStart(char) || (char >= '0' && char <= '9');
109
+ }
110
+
111
+ function isAssignmentToken(token) {
112
+ const text = toText(token);
113
+ const equalsIndex = text.indexOf('=');
114
+ if (equalsIndex <= 0 || !isVariableNameStart(text[0])) return false;
115
+
116
+ for (let index = 1; index < equalsIndex; index += 1) {
117
+ if (!isVariableNameChar(text[index])) return false;
118
+ }
119
+
120
+ return true;
121
+ }
122
+
123
+ function heredocDelimiter(line) {
124
+ const markerIndex = line.indexOf('<<');
125
+ if (markerIndex === -1 || line[markerIndex + 2] === '<') return null;
126
+
127
+ let cursor = markerIndex + 2;
128
+ if (line[cursor] === '-') cursor += 1;
129
+ while (cursor < line.length && isWhitespace(line[cursor])) cursor += 1;
130
+
131
+ const quote = line[cursor];
132
+ if (quote === '"' || quote === "'") {
133
+ cursor += 1;
134
+ const endQuote = line.indexOf(quote, cursor);
135
+ return endQuote === -1 ? line.slice(cursor).trim() || null : line.slice(cursor, endQuote) || null;
136
+ }
137
+
138
+ const start = cursor;
139
+ while (cursor < line.length && !isWhitespace(line[cursor])) cursor += 1;
140
+ return line.slice(start, cursor).trim() || null;
141
+ }
142
+
143
+ function isExecutingTokenPosition(tokens, index) {
144
+ const nonExecutingPreviousTokens = new Set(['-e', '-f', '-r', '-x', '[', 'test']);
145
+ const executingPreviousCommands = new Set(['bash', 'bun', 'env', 'exec', 'if', 'node', 'sh', 'then', '&&']);
146
+
147
+ let previousIndex = index - 1;
148
+ while (previousIndex >= 0 && isAssignmentToken(tokens[previousIndex])) {
149
+ previousIndex -= 1;
150
+ }
151
+
152
+ if (previousIndex < 0) return true;
153
+
154
+ const previous = toText(tokens[previousIndex]).toLowerCase();
155
+ if (nonExecutingPreviousTokens.has(previous)) return false;
156
+ return executingPreviousCommands.has(commandName(previous));
157
+ }
158
+
159
+ function invokesLefthook(line) {
160
+ return commandTokens(line).some((token) => commandName(token) === 'lefthook');
161
+ }
162
+
163
+ function invokesForgeHook(line) {
164
+ return commandTokens(line).some((token, index, tokens) => {
165
+ if (token.includes('=')) return false;
166
+ const normalized = token.replaceAll('\\', '/').toLowerCase();
167
+ if (!normalized.endsWith('.forge/hooks/check-tdd.js') && commandName(token) !== 'check-tdd.js') {
168
+ return false;
169
+ }
170
+
171
+ return isExecutingTokenPosition(tokens, index);
172
+ });
173
+ }
174
+
175
+ function invokesBeadsHook(line, hookName) {
176
+ const tokens = commandTokens(line);
177
+ return tokens.some((token, index) => (
178
+ commandName(token) === 'bd'
179
+ && toText(tokens[index + 1]).toLowerCase() === 'hooks'
180
+ && toText(tokens[index + 2]).toLowerCase() === 'run'
181
+ && toText(tokens[index + 3]).toLowerCase() === hookName
182
+ && isExecutingTokenPosition(tokens, index)
183
+ ));
184
+ }
185
+
186
+ function createDiagnostic(code, subject, message, repair, severity = 'hard-stop') {
46
187
  return {
47
188
  code,
48
189
  subject,
49
- severity: 'hard-stop',
190
+ severity,
50
191
  message,
51
192
  ...(repair ? { repair } : {})
52
193
  };
@@ -75,32 +216,159 @@ function isUsableWindowsShellCandidate(candidate, options = {}) {
75
216
  function checkHookInstallation(projectRoot, options = {}) {
76
217
  const exec = options._exec || defaultExecFileSync;
77
218
  const platform = options.platform || process.platform;
78
- const expectedRelativeHooksPath = normalizeHooksPath('.lefthook/hooks', platform);
79
- const expectedAbsoluteHooksPath = normalizeHooksPath(`${projectRoot}/${expectedRelativeHooksPath}`, platform);
219
+ const expectedRelativeHooksPaths = ['.lefthook/hooks', '.beads/hooks'];
220
+ const requiredHooks = ['pre-commit', 'pre-push'];
221
+
222
+ function resolveGitRoot() {
223
+ try {
224
+ const output = exec('git', ['rev-parse', '--show-toplevel'], {
225
+ cwd: projectRoot,
226
+ encoding: 'utf8'
227
+ });
228
+ return toText(output).trim() || projectRoot;
229
+ } catch {
230
+ return projectRoot;
231
+ }
232
+ }
233
+
234
+ const gitRoot = resolveGitRoot();
235
+ const expectedHooksPaths = new Set(expectedRelativeHooksPaths.flatMap((hooksPath) => [
236
+ normalizeHooksPath(hooksPath, platform),
237
+ normalizeHooksPath(`${gitRoot}/${normalizeHooksPath(hooksPath, platform)}`, platform)
238
+ ]));
80
239
 
240
+ function resolveGitHooksDir() {
241
+ try {
242
+ const output = exec('git', ['rev-parse', '--git-path', 'hooks'], {
243
+ cwd: projectRoot,
244
+ encoding: 'utf8'
245
+ });
246
+ const rawPath = toText(output).trim();
247
+ if (!rawPath) return null;
248
+ return path.isAbsolute(rawPath) ? rawPath : path.resolve(projectRoot, rawPath);
249
+ } catch {
250
+ return null;
251
+ }
252
+ }
253
+
254
+ function classifyHookFile(filePath, hookName, visited = new Set()) {
255
+ try {
256
+ const normalizedFilePath = path.resolve(filePath);
257
+ if (visited.has(normalizedFilePath)) {
258
+ return { active: false, provider: 'cycle' };
259
+ }
260
+ visited.add(normalizedFilePath);
261
+
262
+ const stat = fs.statSync(filePath);
263
+ const executable = platform === 'win32'
264
+ || (typeof options._canExecuteHook === 'function'
265
+ ? Boolean(options._canExecuteHook(filePath, stat))
266
+ : (stat.mode & 0o111) !== 0);
267
+ if (!stat.isFile() || stat.size === 0 || !executable) return { active: false, provider: 'missing' };
268
+
269
+ const content = fs.readFileSync(filePath, 'utf8');
270
+ const runsLefthook = hasExecutableHookCommand(content, invokesLefthook);
271
+ const runsForgeHook = hasExecutableHookCommand(content, invokesForgeHook);
272
+ const runsBeadsHook = hasExecutableHookCommand(content, (line) => invokesBeadsHook(line, hookName));
273
+
274
+ if (runsLefthook) return { active: true, provider: 'lefthook' };
275
+ if (runsForgeHook) return { active: true, provider: 'forge' };
276
+
277
+ if (runsBeadsHook) {
278
+ const chainedHookPath = path.join(gitRoot, '.beads', 'hooks', hookName);
279
+ if (path.resolve(chainedHookPath) !== normalizedFilePath && fs.existsSync(chainedHookPath)) {
280
+ const chained = classifyHookFile(chainedHookPath, hookName, visited);
281
+ if (chained.active) {
282
+ return { active: true, provider: `beads->${chained.provider}` };
283
+ }
284
+ }
285
+
286
+ return { active: false, provider: 'beads-unverified' };
287
+ }
288
+
289
+ return { active: false, provider: 'unknown' };
290
+ } catch {
291
+ return { active: false, provider: 'missing' };
292
+ }
293
+ }
294
+
295
+ let hooksPath = null;
81
296
  try {
82
297
  const output = exec('git', ['config', '--get', 'core.hooksPath'], {
83
298
  cwd: projectRoot,
84
299
  encoding: 'utf8'
85
300
  });
86
301
 
87
- const hooksPath = normalizeHooksPath(output, platform);
88
- const active = hooksPath === expectedRelativeHooksPath || hooksPath === expectedAbsoluteHooksPath;
302
+ hooksPath = normalizeHooksPath(output, platform);
303
+ const active = expectedHooksPaths.has(hooksPath);
304
+
305
+ if (active) {
306
+ const rawHooksPath = toText(output).trim();
307
+ const hooksDir = isAbsoluteForPlatform(rawHooksPath, platform)
308
+ ? rawHooksPath
309
+ : path.resolve(gitRoot, normalizeHooksPath(rawHooksPath, platform));
310
+ const hookChecks = requiredHooks.map((hook) => ({
311
+ hook,
312
+ ...classifyHookFile(path.join(hooksDir, hook), hook)
313
+ }));
314
+ const missingHooks = hookChecks.filter(check => !check.active).map(check => check.hook);
315
+ const verifiedActive = missingHooks.length === 0;
316
+ return {
317
+ active: verifiedActive,
318
+ state: verifiedActive ? 'active' : 'inactive',
319
+ verification: 'core.hooksPath',
320
+ hooksPath: hooksPath || null,
321
+ hooksDir,
322
+ providers: Object.fromEntries(hookChecks.map(check => [check.hook, check.provider])),
323
+ missingHooks,
324
+ message: verifiedActive
325
+ ? ''
326
+ : `Git hooks directory is missing required hooks: ${missingHooks.join(', ')}.`
327
+ };
328
+ }
329
+
330
+ if (hooksPath) {
331
+ return {
332
+ active: false,
333
+ state: 'inactive',
334
+ verification: 'core.hooksPath',
335
+ hooksPath,
336
+ message: `Git core.hooksPath is set to "${hooksPath}", not ".lefthook/hooks" or ".beads/hooks".`
337
+ };
338
+ }
339
+ } catch {
340
+ // Fall through to git-path fallback for worktree-safe verification
341
+ }
89
342
 
343
+ const hooksDir = resolveGitHooksDir();
344
+ if (hooksDir) {
345
+ const hookChecks = requiredHooks.map((hook) => ({
346
+ hook,
347
+ ...classifyHookFile(path.join(hooksDir, hook), hook)
348
+ }));
349
+ const missingHooks = hookChecks.filter(check => !check.active).map(check => check.hook);
350
+ const active = missingHooks.length === 0;
90
351
  return {
91
352
  active,
92
353
  state: active ? 'active' : 'inactive',
354
+ verification: 'git-path-hooks',
93
355
  hooksPath: hooksPath || null,
94
- message: active ? '' : 'Git hooks are not pointed at .lefthook/hooks.'
95
- };
96
- } catch {
97
- return {
98
- active: false,
99
- state: 'unverified',
100
- hooksPath: null,
101
- message: 'Git hooks could not be verified.'
356
+ hooksDir,
357
+ providers: Object.fromEntries(hookChecks.map(check => [check.hook, check.provider])),
358
+ missingHooks,
359
+ message: active
360
+ ? ''
361
+ : `Git hooks directory is missing required hooks: ${missingHooks.join(', ')}.`
102
362
  };
103
363
  }
364
+
365
+ return {
366
+ active: false,
367
+ state: 'unverified',
368
+ verification: 'unverified',
369
+ hooksPath: hooksPath || null,
370
+ message: 'Git hooks could not be verified.'
371
+ };
104
372
  }
105
373
 
106
374
  function checkCommandAvailability(command, projectRoot, options = {}) {
@@ -215,25 +483,50 @@ function normalizeProjectRoot(projectRoot) {
215
483
  : process.cwd();
216
484
  }
217
485
 
486
+ // Resolve the active issue backend for the health gate. An already-normalized
487
+ // `options.issueBackend` (passed by enforce-stage) wins; otherwise fall back to the
488
+ // shared resolver (env > .forge/config.yaml > default 'kernel'). Never throws and
489
+ // never warns from the health path.
490
+ function resolveHealthIssueBackend(options, projectRoot) {
491
+ if (options.issueBackend === 'kernel' || options.issueBackend === 'beads') {
492
+ return options.issueBackend;
493
+ }
494
+ return resolveIssueBackend({
495
+ deps: options.backendDeps || {},
496
+ env: options.env || process.env,
497
+ projectRoot,
498
+ warn: () => {}
499
+ });
500
+ }
501
+
218
502
  function checkRuntimeHealth(projectRoot, options = {}) {
219
503
  const platform = options.platform || process.platform;
220
504
  const root = normalizeProjectRoot(projectRoot);
221
505
 
222
- const lefthook = checkLefthookStatus(root);
223
506
  const hooks = checkHookInstallation(root, options);
507
+ const lefthook = checkLefthookStatus(root);
224
508
  const bd = checkCommandAvailability('bd', root, options);
225
509
  const gh = checkCommandAvailability('gh', root, options);
226
510
  const jq = checkCommandAvailability('jq', root, options);
227
511
  const shell = normalizeShellRuntime(options.shellRuntime, platform, options);
228
512
 
513
+ const issueBackend = resolveHealthIssueBackend(options, root);
514
+
229
515
  const diagnostics = [];
516
+ const advisories = [];
517
+
518
+ const lefthookMissing = lefthook.state === 'missing-dependency'
519
+ || lefthook.state === 'missing-binary';
230
520
 
231
- if (lefthook.state !== 'installed') {
521
+ if (lefthookMissing) {
522
+ const lefthookRepair = lefthook.state === 'missing-binary'
523
+ ? getInstallCommand(root)
524
+ : getAddDevCommand(root, 'lefthook');
232
525
  diagnostics.push(createDiagnostic(
233
526
  'LEFTHOOK_MISSING',
234
527
  'lefthook',
235
528
  lefthook.message || 'lefthook is required for hook installation.',
236
- 'bun add -D lefthook && bun install'
529
+ lefthookRepair
237
530
  ));
238
531
  }
239
532
 
@@ -247,11 +540,25 @@ function checkRuntimeHealth(projectRoot, options = {}) {
247
540
  }
248
541
 
249
542
  if (!bd.available) {
250
- diagnostics.push(createDiagnostic(
251
- 'BD_MISSING',
252
- 'bd',
253
- 'bd is required for stage-entry workflow checks.'
254
- ));
543
+ if (issueBackend === 'beads') {
544
+ // Beads is the active issue backend, so bd is a genuine hard prerequisite.
545
+ diagnostics.push(createDiagnostic(
546
+ 'BD_MISSING',
547
+ 'bd',
548
+ 'bd is required for stage-entry workflow checks when the beads issue backend is selected.'
549
+ ));
550
+ } else {
551
+ // Kernel is the default issue backend and needs no bd binary, so a missing bd
552
+ // must NOT hard-stop stage entry (the "no Beads install required" contract).
553
+ // Surface it as a non-blocking advisory instead.
554
+ advisories.push(createDiagnostic(
555
+ 'BD_MISSING',
556
+ 'bd',
557
+ 'bd is not installed. The kernel issue backend does not require it; install bd only if you switch to the beads backend.',
558
+ undefined,
559
+ 'advisory'
560
+ ));
561
+ }
255
562
  }
256
563
 
257
564
  if (!gh.available) {
@@ -285,6 +592,7 @@ function checkRuntimeHealth(projectRoot, options = {}) {
285
592
  ready: healthy,
286
593
  hardStop: !healthy,
287
594
  diagnostics,
595
+ advisories,
288
596
  checks: {
289
597
  projectRoot: root,
290
598
  lefthook,
@@ -292,7 +600,8 @@ function checkRuntimeHealth(projectRoot, options = {}) {
292
600
  bd,
293
601
  gh,
294
602
  jq,
295
- shell
603
+ shell,
604
+ issueBackend
296
605
  }
297
606
  };
298
607
  }