forge-workflow 0.0.10 → 0.1.0-beta.3

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 (468) 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 +82 -5
  5. package/.forge/hooks/forge-native-hook.js +431 -0
  6. package/.forge/protected-paths.yaml +157 -0
  7. package/AGENTS.md +151 -61
  8. package/CHANGELOG.md +709 -0
  9. package/CLAUDE.md +9 -118
  10. package/QUICKSTART.md +175 -0
  11. package/README.md +275 -365
  12. package/bin/forge-cmd.js +120 -9
  13. package/bin/forge-preflight.js +26 -5
  14. package/bin/forge.js +532 -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 +121 -0
  29. package/docs/guides/SUPPORT.md +190 -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 +214 -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 +155 -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/activation/ensure-forge-home.js +135 -0
  67. package/lib/adapter-cli.js +307 -0
  68. package/lib/adapters/beads-issue-adapter.js +127 -0
  69. package/lib/adapters/beads-kernel-compat.js +1109 -0
  70. package/lib/adapters/greptile-review-adapter.js +141 -0
  71. package/lib/adapters/kernel-issue-adapter.js +101 -0
  72. package/lib/adapters/pr-state-adapter.js +484 -0
  73. package/lib/adoption-profiles.js +139 -0
  74. package/lib/agents/README.md +2 -6
  75. package/lib/agents/claude.plugin.json +3 -8
  76. package/lib/agents/codex.plugin.json +9 -1
  77. package/lib/agents/cursor.plugin.json +2 -6
  78. package/lib/agents/hermes.plugin.json +22 -0
  79. package/lib/agents-config.js +39 -1236
  80. package/lib/audit-evidence.js +282 -0
  81. package/lib/beads-detect.js +60 -0
  82. package/lib/beads-nudge.js +91 -0
  83. package/lib/beads-setup.js +121 -0
  84. package/lib/beads-sync-scaffold.js +25 -101
  85. package/lib/codex-skills.js +51 -1
  86. package/lib/commands/_aliases.js +248 -0
  87. package/lib/commands/_issue.js +780 -77
  88. package/lib/commands/_manifest.js +93 -0
  89. package/lib/commands/_registry.js +99 -34
  90. package/lib/commands/_resolve-command-opts.js +230 -0
  91. package/lib/commands/_serve-security.js +270 -0
  92. package/lib/commands/adapter.js +12 -0
  93. package/lib/commands/add.js +118 -0
  94. package/lib/commands/audit.js +70 -0
  95. package/lib/commands/blocked.js +5 -0
  96. package/lib/commands/board.js +64 -0
  97. package/lib/commands/claim.js +21 -2
  98. package/lib/commands/claims.js +7 -0
  99. package/lib/commands/clean.js +485 -75
  100. package/lib/commands/close.js +2 -2
  101. package/lib/commands/comment.js +5 -0
  102. package/lib/commands/control.js +148 -0
  103. package/lib/commands/create.js +2 -2
  104. package/lib/commands/dev.js +185 -7
  105. package/lib/commands/doc-gate.js +336 -0
  106. package/lib/commands/doctor.js +156 -0
  107. package/lib/commands/explain.js +15 -0
  108. package/lib/commands/export.js +237 -0
  109. package/lib/commands/gate.js +209 -0
  110. package/lib/commands/hooks.js +377 -0
  111. package/lib/commands/inbox.js +118 -0
  112. package/lib/commands/init.js +604 -0
  113. package/lib/commands/insights.js +79 -0
  114. package/lib/commands/issue.js +12 -1
  115. package/lib/commands/issues.js +17 -0
  116. package/lib/commands/lint.js +5 -0
  117. package/lib/commands/list.js +2 -2
  118. package/lib/commands/memory.js +81 -0
  119. package/lib/commands/merge.js +312 -0
  120. package/lib/commands/migrate.js +362 -0
  121. package/lib/commands/new.js +12 -0
  122. package/lib/commands/options.js +241 -0
  123. package/lib/commands/orient.js +13 -0
  124. package/lib/commands/orphans.js +5 -0
  125. package/lib/commands/patch.js +67 -0
  126. package/lib/commands/plan.js +481 -29
  127. package/lib/commands/pr.js +88 -0
  128. package/lib/commands/preflight.js +211 -0
  129. package/lib/commands/prime.js +13 -0
  130. package/lib/commands/push.js +135 -2
  131. package/lib/commands/ready.js +2 -2
  132. package/lib/commands/recall.js +171 -0
  133. package/lib/commands/recap.js +75 -0
  134. package/lib/commands/recommend.js +0 -1
  135. package/lib/commands/release.js +104 -0
  136. package/lib/commands/remember.js +140 -0
  137. package/lib/commands/role.js +99 -0
  138. package/lib/commands/serve.js +581 -0
  139. package/lib/commands/setup.js +900 -971
  140. package/lib/commands/shepherd.js +501 -0
  141. package/lib/commands/ship.js +59 -1
  142. package/lib/commands/show.js +2 -2
  143. package/lib/commands/stage.js +192 -0
  144. package/lib/commands/stale.js +5 -0
  145. package/lib/commands/status.js +158 -21
  146. package/lib/commands/sync.js +34 -46
  147. package/lib/commands/team.js +4 -1
  148. package/lib/commands/test.js +43 -27
  149. package/lib/commands/update.js +2 -2
  150. package/lib/commands/upgrade.js +47 -0
  151. package/lib/commands/validate.js +43 -18
  152. package/lib/commands/worktree.js +362 -99
  153. package/lib/config-writer.js +202 -0
  154. package/lib/control-plane.js +236 -0
  155. package/lib/core/runtime-graph.js +977 -0
  156. package/lib/dep-guard/keyword-ripple.js +2 -2
  157. package/lib/deprecated-sync-cleanup.js +362 -0
  158. package/lib/detect-agent.js +2 -28
  159. package/lib/detect-worktree.js +35 -9
  160. package/lib/doc-gate/declaration.js +177 -0
  161. package/lib/doc-gate/detect.js +289 -0
  162. package/lib/doc-gate/gate.js +375 -0
  163. package/lib/doc-gate/okf-config.js +128 -0
  164. package/lib/doc-gate/okf.js +429 -0
  165. package/lib/docs-command.js +1161 -6
  166. package/lib/forge-issues.js +382 -11
  167. package/lib/forge-lock.js +262 -0
  168. package/lib/gate-events.js +192 -0
  169. package/lib/global-flags.js +104 -0
  170. package/lib/greptile-match.js +7 -63
  171. package/lib/grounding/context-events.js +230 -0
  172. package/lib/grounding/read-first.js +112 -0
  173. package/lib/harness-capability-matrix.js +380 -0
  174. package/lib/hook-global-installer.js +347 -0
  175. package/lib/hook-renderer.js +541 -0
  176. package/lib/inbox.js +391 -0
  177. package/lib/insights.js +397 -0
  178. package/lib/issue-adapter.js +156 -0
  179. package/lib/issue-backend.js +145 -0
  180. package/lib/issue-render.js +220 -0
  181. package/lib/kernel/backing-issue.js +311 -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/owned-kernel.js +43 -0
  192. package/lib/kernel/planning-buckets-schema.js +109 -0
  193. package/lib/kernel/projection-jsonl-writer.js +450 -0
  194. package/lib/kernel/readiness-model.js +329 -0
  195. package/lib/kernel/schema.js +356 -0
  196. package/lib/kernel/sqlite-driver.js +2540 -0
  197. package/lib/kernel/taxonomy-validator.js +394 -0
  198. package/lib/lefthook-check.js +3 -2
  199. package/lib/lefthook-wiring.js +413 -0
  200. package/lib/mcp-config-renderer.js +288 -0
  201. package/lib/memory/graphiti-mcp.js +106 -0
  202. package/lib/memory/router.js +387 -0
  203. package/lib/memory/typed-api.js +102 -0
  204. package/lib/memory-digest.js +195 -0
  205. package/lib/merge-rules.js +395 -0
  206. package/lib/migrate-dry-run.js +466 -0
  207. package/lib/orientation.js +863 -0
  208. package/lib/package-manager-remediation.js +103 -0
  209. package/lib/package-root.js +381 -0
  210. package/lib/patch-intent.js +890 -0
  211. package/lib/plugin-catalog.js +3 -4
  212. package/lib/plugin-manager.js +0 -5
  213. package/lib/pr-bundle.js +186 -0
  214. package/lib/pr-monitor/auto-actions.js +175 -0
  215. package/lib/pr-monitor/differ.js +195 -0
  216. package/lib/pr-monitor/digest.js +206 -0
  217. package/lib/pr-monitor/events.js +0 -0
  218. package/lib/pr-monitor/gather.js +124 -0
  219. package/lib/pr-monitor/journal.js +299 -0
  220. package/lib/pr-monitor/monitor.js +146 -0
  221. package/lib/pr-monitor/render-sticky.js +192 -0
  222. package/lib/pr-monitor/upsert-sticky.js +169 -0
  223. package/lib/pr-monitor/watch-lifecycle.js +95 -0
  224. package/lib/pr-monitor/watch.js +247 -0
  225. package/lib/pr-pull.js +1314 -0
  226. package/lib/pr-shepherd.js +494 -0
  227. package/lib/pr-state-validator.js +59 -0
  228. package/lib/preflight/gates.js +237 -0
  229. package/lib/preflight/runner.js +116 -0
  230. package/lib/project-discovery.js +0 -53
  231. package/lib/project-memory.js +99 -497
  232. package/lib/protected-path-manifest.js +281 -0
  233. package/lib/protected-state-surfaces.js +387 -0
  234. package/lib/release-readiness.js +2105 -0
  235. package/lib/reset.js +59 -45
  236. package/lib/review-adapter.js +68 -0
  237. package/lib/rules-sync.js +260 -0
  238. package/lib/runtime-health.js +241 -20
  239. package/lib/safety-config-renderer.js +268 -0
  240. package/lib/setup-action-log.js +1 -7
  241. package/lib/setup.js +27 -65
  242. package/lib/shell-utils.js +76 -6
  243. package/lib/skills-sync.js +330 -0
  244. package/lib/smart-status/scoring.js +17 -3
  245. package/lib/status/beads-snapshot.js +45 -2
  246. package/lib/status/presenter.js +169 -18
  247. package/lib/status/snapshot.js +186 -0
  248. package/lib/sync-backend.js +202 -0
  249. package/lib/untrusted-content.js +52 -0
  250. package/lib/upgrade-safety.js +251 -0
  251. package/lib/workflow/enforce-stage.js +351 -45
  252. package/lib/workflow/stage-transition.js +115 -0
  253. package/lib/workflow/stages.js +30 -6
  254. package/lib/workflow/state-manager.js +11 -22
  255. package/lib/workflow/state.js +23 -1
  256. package/lib/workflow-profiles.js +17 -5
  257. package/package.json +37 -35
  258. package/rules/documentation.md +19 -0
  259. package/rules/kernel-tracking.md +26 -0
  260. package/rules/security.md +22 -0
  261. package/rules/tdd.md +20 -0
  262. package/rules/workflow.md +27 -0
  263. package/scripts/auto-backing-issue.js +47 -0
  264. package/scripts/beads-context.sh +81 -57
  265. package/scripts/beads-upgrade-smoke.sh +24 -3
  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.sh +22 -3
  272. package/scripts/file-index.sh +3 -0
  273. package/scripts/forge-team/lib/claim.sh +34 -18
  274. package/scripts/forge-team/lib/dashboard.sh +61 -86
  275. package/scripts/forge-team/lib/epic.sh +99 -263
  276. package/scripts/forge-team/lib/hooks.sh +26 -28
  277. package/scripts/forge-team/lib/identity.sh +4 -4
  278. package/scripts/forge-team/lib/sync-github.sh +49 -84
  279. package/scripts/forge-team/lib/verify.sh +93 -83
  280. package/scripts/forge-team/lib/workload.sh +41 -65
  281. package/scripts/forge-team/tests/claim.test.sh +25 -19
  282. package/scripts/forge-team/tests/dashboard.test.sh +31 -46
  283. package/scripts/forge-team/tests/epic.test.sh +52 -71
  284. package/scripts/forge-team/tests/hooks.test.sh +38 -50
  285. package/scripts/forge-team/tests/identity.test.sh +3 -3
  286. package/scripts/forge-team/tests/integration.test.sh +44 -66
  287. package/scripts/forge-team/tests/sync-github.test.sh +50 -83
  288. package/scripts/forge-team/tests/verify.test.sh +37 -46
  289. package/scripts/forge-team/tests/workflow-integration.test.sh +4 -4
  290. package/scripts/forge-team/tests/workload.test.sh +32 -66
  291. package/scripts/gen-command-manifest.js +153 -0
  292. package/scripts/gen-embedded-assets.mjs +129 -0
  293. package/scripts/install.ps1 +139 -0
  294. package/scripts/install.sh +268 -0
  295. package/scripts/lib/release-asset.mjs +84 -0
  296. package/scripts/parity-check.mjs +145 -0
  297. package/scripts/parity-check.test.mjs +58 -0
  298. package/scripts/pin-agentic-workflow-images.js +112 -0
  299. package/scripts/pr-auto-actions.js +93 -0
  300. package/scripts/pr-coordinator.sh +3 -0
  301. package/scripts/pr-verdict-label.js +50 -0
  302. package/scripts/preflight-sonar.eslint.config.mjs +44 -0
  303. package/scripts/preflight.sh +21 -94
  304. package/scripts/protected-state-check.js +104 -0
  305. package/scripts/smart-status.sh +60 -57
  306. package/scripts/spikes/config-race-bench.js +111 -0
  307. package/scripts/spikes/harness-capability-matrix.js +13 -0
  308. package/scripts/spikes/patch-anchor-stability-bench.js +125 -0
  309. package/scripts/spikes/protected-path-manifest.js +20 -0
  310. package/scripts/spikes/skill-auto-invoke-parity.js +292 -0
  311. package/scripts/sync-agent-skills.js +62 -0
  312. package/scripts/sync-utils.sh +3 -0
  313. package/scripts/test-ci-shard.js +13 -6
  314. package/scripts/test.js +95 -12
  315. package/skills/claim-safety/SKILL.md +102 -0
  316. package/skills/claim-safety/evals/evals.json +46 -0
  317. package/{.github/prompts/dev.prompt.md → skills/dev/SKILL.md} +44 -50
  318. package/skills/dev/evals/evals.json +50 -0
  319. package/skills/hermes-forge/SKILL.md +185 -0
  320. package/skills/hermes-forge/evals/evals.json +46 -0
  321. package/skills/issue-basics/SKILL.md +111 -0
  322. package/skills/issue-basics/evals/evals.json +46 -0
  323. package/skills/kernel/SKILL.md +166 -0
  324. package/skills/kernel/evals/evals.json +50 -0
  325. package/skills/memory/SKILL.md +102 -0
  326. package/skills/parallel-deep-research/SKILL.md +14 -11
  327. package/skills/parallel-deep-research/evals/evals.json +11 -27
  328. package/{.github/prompts/plan.prompt.md → skills/plan/SKILL.md} +132 -157
  329. package/skills/plan/evals/evals.json +42 -0
  330. package/skills/research/SKILL.md +195 -0
  331. package/skills/research/evals/evals.json +42 -0
  332. package/{.github/prompts/review.prompt.md → skills/review/SKILL.md} +98 -62
  333. package/skills/review/evals/evals.json +42 -0
  334. package/skills/rollback/SKILL.md +110 -0
  335. package/skills/rollback/evals/evals.json +46 -0
  336. package/skills/rollback/references/methods.md +204 -0
  337. package/{.cursor/commands/rollback.md → skills/rollback/references/workflow-integration.md} +10 -284
  338. package/skills/shepherd/SKILL.md +66 -0
  339. package/skills/shepherd/evals/evals.json +42 -0
  340. package/{.github/prompts/ship.prompt.md → skills/ship/SKILL.md} +81 -45
  341. package/skills/ship/evals/evals.json +42 -0
  342. package/skills/smith/SKILL.md +142 -0
  343. package/skills/smith/evals/evals.json +46 -0
  344. package/skills/smith/references/autonomy-and-gates.md +94 -0
  345. package/{.github/prompts/sonarcloud.prompt.md → skills/sonarcloud/SKILL.md} +14 -3
  346. package/skills/sonarcloud/evals/evals.json +46 -0
  347. package/skills/sonarcloud-analysis/SKILL.md +18 -13
  348. package/skills/sonarcloud-analysis/evals/evals.json +11 -15
  349. package/{.github/prompts/status.prompt.md → skills/status/SKILL.md} +20 -10
  350. package/skills/status/evals/evals.json +50 -0
  351. package/skills/triage-ready/SKILL.md +121 -0
  352. package/skills/triage-ready/evals/evals.json +42 -0
  353. package/{.github/prompts/validate.prompt.md → skills/validate/SKILL.md} +52 -29
  354. package/skills/validate/evals/evals.json +42 -0
  355. package/skills/verify/SKILL.md +299 -0
  356. package/skills/verify/evals/evals.json +50 -0
  357. package/.claude/commands/dev.md +0 -345
  358. package/.claude/commands/plan.md +0 -566
  359. package/.claude/commands/premerge.md +0 -186
  360. package/.claude/commands/research.md +0 -42
  361. package/.claude/commands/review.md +0 -451
  362. package/.claude/commands/rollback.md +0 -721
  363. package/.claude/commands/ship.md +0 -213
  364. package/.claude/commands/sonarcloud.md +0 -152
  365. package/.claude/commands/status.md +0 -90
  366. package/.claude/commands/validate.md +0 -288
  367. package/.claude/commands/verify.md +0 -269
  368. package/.claude/rules/workflow.md +0 -121
  369. package/.cline/workflows/dev.md +0 -342
  370. package/.cline/workflows/plan.md +0 -563
  371. package/.cline/workflows/premerge.md +0 -183
  372. package/.cline/workflows/research.md +0 -39
  373. package/.cline/workflows/review.md +0 -448
  374. package/.cline/workflows/rollback.md +0 -718
  375. package/.cline/workflows/ship.md +0 -210
  376. package/.cline/workflows/sonarcloud.md +0 -146
  377. package/.cline/workflows/status.md +0 -87
  378. package/.cline/workflows/validate.md +0 -285
  379. package/.cline/workflows/verify.md +0 -266
  380. package/.codex/config.toml +0 -11
  381. package/.codex/skills/dev/SKILL.md +0 -345
  382. package/.codex/skills/plan/SKILL.md +0 -566
  383. package/.codex/skills/premerge/SKILL.md +0 -186
  384. package/.codex/skills/research/SKILL.md +0 -42
  385. package/.codex/skills/review/SKILL.md +0 -451
  386. package/.codex/skills/rollback/SKILL.md +0 -721
  387. package/.codex/skills/ship/SKILL.md +0 -213
  388. package/.codex/skills/sonarcloud/SKILL.md +0 -149
  389. package/.codex/skills/status/SKILL.md +0 -90
  390. package/.codex/skills/validate/SKILL.md +0 -288
  391. package/.codex/skills/verify/SKILL.md +0 -269
  392. package/.cursor/commands/dev.md +0 -342
  393. package/.cursor/commands/plan.md +0 -563
  394. package/.cursor/commands/premerge.md +0 -183
  395. package/.cursor/commands/research.md +0 -39
  396. package/.cursor/commands/review.md +0 -448
  397. package/.cursor/commands/ship.md +0 -210
  398. package/.cursor/commands/sonarcloud.md +0 -146
  399. package/.cursor/commands/status.md +0 -87
  400. package/.cursor/commands/validate.md +0 -285
  401. package/.cursor/commands/verify.md +0 -266
  402. package/.cursorrules +0 -149
  403. package/.github/prompts/premerge.prompt.md +0 -188
  404. package/.github/prompts/research.prompt.md +0 -44
  405. package/.github/prompts/rollback.prompt.md +0 -723
  406. package/.github/prompts/verify.prompt.md +0 -271
  407. package/.github/workflows/beads-to-github.yml +0 -89
  408. package/.github/workflows/github-to-beads.yml +0 -100
  409. package/.kilocode/workflows/dev.md +0 -346
  410. package/.kilocode/workflows/plan.md +0 -567
  411. package/.kilocode/workflows/premerge.md +0 -187
  412. package/.kilocode/workflows/research.md +0 -43
  413. package/.kilocode/workflows/review.md +0 -452
  414. package/.kilocode/workflows/rollback.md +0 -722
  415. package/.kilocode/workflows/ship.md +0 -214
  416. package/.kilocode/workflows/sonarcloud.md +0 -150
  417. package/.kilocode/workflows/status.md +0 -91
  418. package/.kilocode/workflows/validate.md +0 -289
  419. package/.kilocode/workflows/verify.md +0 -270
  420. package/.opencode/commands/dev.md +0 -345
  421. package/.opencode/commands/plan.md +0 -566
  422. package/.opencode/commands/premerge.md +0 -186
  423. package/.opencode/commands/research.md +0 -42
  424. package/.opencode/commands/review.md +0 -451
  425. package/.opencode/commands/rollback.md +0 -721
  426. package/.opencode/commands/ship.md +0 -213
  427. package/.opencode/commands/sonarcloud.md +0 -149
  428. package/.opencode/commands/status.md +0 -90
  429. package/.opencode/commands/validate.md +0 -288
  430. package/.opencode/commands/verify.md +0 -269
  431. package/.roo/commands/dev.md +0 -346
  432. package/.roo/commands/plan.md +0 -567
  433. package/.roo/commands/premerge.md +0 -187
  434. package/.roo/commands/research.md +0 -43
  435. package/.roo/commands/review.md +0 -452
  436. package/.roo/commands/rollback.md +0 -722
  437. package/.roo/commands/ship.md +0 -214
  438. package/.roo/commands/sonarcloud.md +0 -150
  439. package/.roo/commands/status.md +0 -91
  440. package/.roo/commands/validate.md +0 -289
  441. package/.roo/commands/verify.md +0 -270
  442. package/docs/BEADS_GITHUB_SYNC.md +0 -281
  443. package/docs/GREPTILE_SETUP.md +0 -400
  444. package/docs/MANUAL_REVIEW_GUIDE.md +0 -106
  445. package/docs/SETUP.md +0 -663
  446. package/docs/VALIDATION.md +0 -363
  447. package/lib/agents/cline.plugin.json +0 -29
  448. package/lib/agents/copilot.plugin.json +0 -24
  449. package/lib/agents/kilocode.plugin.json +0 -22
  450. package/lib/agents/opencode.plugin.json +0 -23
  451. package/lib/agents/roo.plugin.json +0 -30
  452. package/lib/beads-bootstrap.js +0 -225
  453. package/lib/beads-health-check.js +0 -188
  454. package/lib/commands/commands-reset.js +0 -147
  455. package/opencode.json +0 -67
  456. package/scripts/beads-context.test.js +0 -584
  457. package/scripts/github-beads-sync/comment.mjs +0 -64
  458. package/scripts/github-beads-sync/config.mjs +0 -148
  459. package/scripts/github-beads-sync/github-api.mjs +0 -131
  460. package/scripts/github-beads-sync/index.mjs +0 -356
  461. package/scripts/github-beads-sync/label-mapper.mjs +0 -54
  462. package/scripts/github-beads-sync/mapping.mjs +0 -132
  463. package/scripts/github-beads-sync/reverse-sync-cli.mjs +0 -31
  464. package/scripts/github-beads-sync/reverse-sync.mjs +0 -162
  465. package/scripts/github-beads-sync/run-bd.mjs +0 -161
  466. package/scripts/github-beads-sync/sanitize.mjs +0 -121
  467. package/scripts/github-beads-sync.config.json +0 -26
  468. package/scripts/sync-commands.js +0 -600
@@ -1,17 +1,22 @@
1
- # Greptile Review Handling Process
1
+ # Review Thread Handling Process
2
2
 
3
- **Purpose**: Standardized process for AI agents to systematically handle Greptile review comments.
3
+ **Purpose**: Standardized process for AI agents to systematically handle PR
4
+ review threads from **any review agent** — CodeRabbit, Qodo, Greptile, or a
5
+ human reviewer. The mechanism (GitHub review threads via GraphQL/REST) is the
6
+ same regardless of which tool or person authored the comment; the examples below
7
+ name specific tools only as illustrations.
4
8
 
5
- **Critical**: This process has been problematic for days. AI agents MUST follow these exact steps for EVERY Greptile comment.
9
+ **Critical**: Review threads left unresolved block merges. AI agents MUST follow
10
+ these exact steps for EVERY review comment, whoever authored it.
6
11
 
7
12
  ---
8
13
 
9
14
  ## Problem Background
10
15
 
11
16
  **Previous Issues:**
12
- - ❌ AI agents replied to PR with general comments instead of replying directly to each Greptile review thread
17
+ - ❌ AI agents replied to the PR with general comments instead of replying directly to each review thread
13
18
  - ❌ AI agents didn't mark conversation threads as "resolved" after fixing issues
14
- - ❌ No systematic process for tracking which Greptile comments are addressed vs pending
19
+ - ❌ No systematic process for tracking which review comments are addressed vs pending
15
20
  - ❌ Caused confusion and manual tracking overhead for maintainers
16
21
 
17
22
  **Why This Matters:**
@@ -39,28 +44,31 @@
39
44
  - Reply explains what was fixed and why
40
45
  - Resolve marks the thread as addressed
41
46
 
47
+ These two GitHub operations are author-agnostic: they work identically for a
48
+ CodeRabbit thread, a Qodo thread, a Greptile thread, or a human reviewer's thread.
49
+
42
50
  ---
43
51
 
44
52
  ## For AI Agents: Mandatory Steps
45
53
 
46
- When Greptile Quality Gate fails (score < 4/5) or when review comments exist:
54
+ When a review-agent quality gate fails or when review comments exist:
47
55
 
48
- ### Step 1: List ALL Greptile Feedback (Inline + Direct Comments)
56
+ ### Step 1: List ALL Review Feedback (Inline + Direct Comments)
49
57
 
50
- Greptile posts feedback in **two places**:
58
+ Review agents post feedback in **two places**:
51
59
  1. **Inline review threads** — attached to specific code lines (resolvable via GraphQL)
52
- 2. **Direct PR issue comments** — "Additional Comments (N)" posted as regular PR comments (reply with `gh pr comment`)
60
+ 2. **Direct PR issue comments** — summaries or "Additional Comments (N)" posted as regular PR comments (reply with `gh pr comment`)
53
61
 
54
62
  Always run `list-all` to see both:
55
63
 
56
64
  ```bash
57
- bash .claude/scripts/greptile-resolve.sh list-all <pr-number>
65
+ bash .claude/scripts/review-resolve.sh list-all <pr-number>
58
66
  ```
59
67
 
60
68
  Or just inline threads (unresolved only):
61
69
 
62
70
  ```bash
63
- bash .claude/scripts/greptile-resolve.sh list <pr-number> --unresolved
71
+ bash .claude/scripts/review-resolve.sh list <pr-number> --unresolved
64
72
  ```
65
73
 
66
74
  **Output shows:**
@@ -68,6 +76,7 @@ bash .claude/scripts/greptile-resolve.sh list <pr-number> --unresolved
68
76
  - Comment ID (for replying to inline threads)
69
77
  - File path and line number
70
78
  - Issue description
79
+ - Author (so you can see whether it came from CodeRabbit, Greptile, Qodo, a human, etc.)
71
80
  - Direct PR comment IDs and previews (reply with `gh pr comment`)
72
81
 
73
82
  **Example:**
@@ -85,7 +94,7 @@ bash .claude/scripts/greptile-resolve.sh list <pr-number> --unresolved
85
94
 
86
95
  1. **Read the comment** and understand the issue
87
96
  - Use the file path and line number to locate the code
88
- - Understand what Greptile is flagging
97
+ - Understand what the reviewer is flagging
89
98
 
90
99
  2. **Fix the issue** if the comment is valid
91
100
  - Make the necessary code changes
@@ -93,7 +102,7 @@ bash .claude/scripts/greptile-resolve.sh list <pr-number> --unresolved
93
102
 
94
103
  3. **Reply to the thread** with explanation
95
104
  ```bash
96
- bash .claude/scripts/greptile-resolve.sh reply <pr-number> <comment-id> "✅ Fixed: [description]
105
+ bash .claude/scripts/review-resolve.sh reply <pr-number> <comment-id> "✅ Fixed: [description]
97
106
 
98
107
  Changed: [what was changed]
99
108
  Reason: [why this fixes the issue]
@@ -102,14 +111,14 @@ bash .claude/scripts/greptile-resolve.sh list <pr-number> --unresolved
102
111
 
103
112
  4. **Resolve the thread**
104
113
  ```bash
105
- bash .claude/scripts/greptile-resolve.sh resolve <pr-number> <thread-id>
114
+ bash .claude/scripts/review-resolve.sh resolve <pr-number> <thread-id>
106
115
  ```
107
116
 
108
117
  5. **Track progress**: Mark comment as addressed in your notes
109
118
 
110
119
  **Alternative (all-in-one):**
111
120
  ```bash
112
- bash .claude/scripts/greptile-resolve.sh reply-and-resolve <pr-number> <comment-id> <thread-id> "✅ Fixed: [description]
121
+ bash .claude/scripts/review-resolve.sh reply-and-resolve <pr-number> <comment-id> <thread-id> "✅ Fixed: [description]
113
122
 
114
123
  Changed: [what was changed]
115
124
  Reason: [why this fixes the issue]
@@ -119,17 +128,17 @@ Commit: [commit-sha]"
119
128
  ### Step 3: Verify All Threads Resolved
120
129
 
121
130
  ```bash
122
- bash .claude/scripts/greptile-resolve.sh list <pr-number> --unresolved
131
+ bash .claude/scripts/review-resolve.sh list <pr-number> --unresolved
123
132
  ```
124
133
 
125
134
  **Should show**: "No unresolved comments" or empty list
126
135
 
127
136
  **Confirm with stats:**
128
137
  ```bash
129
- bash .claude/scripts/greptile-resolve.sh stats <pr-number>
138
+ bash .claude/scripts/review-resolve.sh stats <pr-number>
130
139
  ```
131
140
 
132
- **Should show**: "✓ All Greptile threads resolved!"
141
+ **Should show**: all tracked review threads resolved.
133
142
 
134
143
  ### Step 4: Push Changes & Poll Briefly for Re-review
135
144
 
@@ -137,10 +146,10 @@ bash .claude/scripts/greptile-resolve.sh stats <pr-number>
137
146
  git push
138
147
  ```
139
148
 
140
- **Greptile will automatically:**
149
+ **The review agent will automatically:**
141
150
  - Re-analyze the PR
142
- - Update the confidence score
143
- - Re-run the Quality Gate check
151
+ - Update any confidence/quality score
152
+ - Re-run its quality gate check
144
153
 
145
154
  ---
146
155
 
@@ -148,7 +157,7 @@ git push
148
157
 
149
158
  ```bash
150
159
  # 1. List unresolved threads
151
- $ bash .claude/scripts/greptile-resolve.sh list 24 --unresolved
160
+ $ bash .claude/scripts/review-resolve.sh list 24 --unresolved
152
161
 
153
162
  ✗ UNRESOLVED | docs/ROADMAP.md:280
154
163
  Thread ID: PRRT_kwDORErEU85tuh6I
@@ -160,7 +169,7 @@ $ git add docs/ROADMAP.md
160
169
  $ git commit -m "fix: replace Windows absolute paths with relative paths"
161
170
 
162
171
  # 3. Reply and resolve in one step
163
- $ bash .claude/scripts/greptile-resolve.sh reply-and-resolve 24 2787717459 PRRT_kwDORErEU85tuh6I \
172
+ $ bash .claude/scripts/review-resolve.sh reply-and-resolve 24 2787717459 PRRT_kwDORErEU85tuh6I \
164
173
  "✅ Fixed: Replaced Windows absolute paths with repo-relative paths
165
174
 
166
175
  Changed: C:\\Users\\...\\plans\\... → .claude/plans/*.md
@@ -171,10 +180,10 @@ Commit: abc123"
171
180
  ✅ Thread resolved successfully
172
181
 
173
182
  # 4. Verify all resolved
174
- $ bash .claude/scripts/greptile-resolve.sh stats 24
183
+ $ bash .claude/scripts/review-resolve.sh stats 24
175
184
 
176
- Greptile unresolved: 0
177
- ✓ All Greptile threads resolved!
185
+ Unresolved: 0
186
+ ✓ All review threads resolved!
178
187
 
179
188
  # 5. Push changes
180
189
  $ git push
@@ -188,7 +197,7 @@ $ git push
188
197
  - **Reply to EACH comment thread** using the script (not as separate PR comment)
189
198
  - **Mark EACH thread as resolved** after fixing using the script
190
199
  - **Track progress** (X of Y fixed) in your notes
191
- - **Poll for Greptile re-review for at most 60 seconds** after pushing fixes, then stop and hand off if it is still pending
200
+ - **Poll for re-review for at most 60 seconds** after pushing fixes, then stop and hand off if it is still pending
192
201
  - **Use comment ID for replies**, thread ID for resolving
193
202
  - **Commit fixes BEFORE replying** so you can reference commit SHA
194
203
 
@@ -204,54 +213,60 @@ $ git push
204
213
 
205
214
  ## Script Commands Reference
206
215
 
216
+ The `.claude/scripts/review-resolve.sh` helper works for review threads authored
217
+ by any tool or person. The `list-all`, `resolve-all`, and `stats` commands
218
+ additionally recognize `greptile-apps`-authored threads as a built-in convenience
219
+ (Greptile is one supported review tool); the core commands below are fully
220
+ author-agnostic.
221
+
207
222
  ### List Threads
208
223
  ```bash
209
224
  # All threads
210
- bash .claude/scripts/greptile-resolve.sh list <pr-number>
225
+ bash .claude/scripts/review-resolve.sh list <pr-number>
211
226
 
212
227
  # Only unresolved
213
- bash .claude/scripts/greptile-resolve.sh list <pr-number> --unresolved
228
+ bash .claude/scripts/review-resolve.sh list <pr-number> --unresolved
214
229
  ```
215
230
 
216
231
  ### Reply to Thread
217
232
  ```bash
218
- bash .claude/scripts/greptile-resolve.sh reply <pr-number> <comment-id> "<message>"
233
+ bash .claude/scripts/review-resolve.sh reply <pr-number> <comment-id> "<message>"
219
234
  ```
220
235
 
221
236
  ### Resolve Thread
222
237
  ```bash
223
- bash .claude/scripts/greptile-resolve.sh resolve <pr-number> <thread-id>
238
+ bash .claude/scripts/review-resolve.sh resolve <pr-number> <thread-id>
224
239
  ```
225
240
 
226
241
  ### Reply and Resolve (Recommended)
227
242
  ```bash
228
- bash .claude/scripts/greptile-resolve.sh reply-and-resolve <pr-number> <comment-id> <thread-id> "<message>"
243
+ bash .claude/scripts/review-resolve.sh reply-and-resolve <pr-number> <comment-id> <thread-id> "<message>"
229
244
  ```
230
245
 
231
246
  ### Batch Resolve (After all issues fixed)
232
247
  ```bash
233
- bash .claude/scripts/greptile-resolve.sh resolve-all <pr-number>
248
+ bash .claude/scripts/review-resolve.sh resolve-all <pr-number>
234
249
  ```
235
250
  **⚠️ Warning**: Only use after ALL issues are fixed and replied to
236
251
 
237
252
  ### Statistics
238
253
  ```bash
239
- bash .claude/scripts/greptile-resolve.sh stats <pr-number>
254
+ bash .claude/scripts/review-resolve.sh stats <pr-number>
240
255
  ```
241
256
 
242
257
  ---
243
258
 
244
259
  ## Integration with `/review` Command
245
260
 
246
- The `/review` command should now include these steps:
261
+ The `/review` command includes these steps:
247
262
 
248
263
  1. Run `/review` as usual to analyze PR feedback
249
- 2. For Greptile comments, use the script to:
264
+ 2. For review-agent comments (CodeRabbit, Qodo, Greptile, human), use the script to:
250
265
  - List unresolved threads
251
266
  - Fix each issue
252
267
  - Reply and resolve systematically
253
268
  3. Verify all threads resolved before declaring review complete
254
- 4. Push changes and poll briefly for Greptile re-review
269
+ 4. Push changes and poll briefly for re-review
255
270
 
256
271
  ---
257
272
 
@@ -269,17 +284,17 @@ The `/review` command should now include these steps:
269
284
  **Cause**: GitHub UI caching
270
285
  **Solution**: Refresh page, or check with GraphQL query
271
286
 
272
- ### Greptile score not updating after fixes
287
+ ### Review score not updating after fixes
273
288
  **Cause**: Must push commits to trigger re-analysis
274
- **Solution**: `git push`, check once immediately, and poll for up to 60 seconds. If Greptile is still pending after that, stop and wait for the user to resume later.
289
+ **Solution**: `git push`, check once immediately, and poll for up to 60 seconds. If the review agent is still pending after that, stop and wait for the user to resume later.
275
290
 
276
291
  ---
277
292
 
278
293
  ## Success Criteria
279
294
 
280
295
  **A review is complete when:**
281
- - ✅ All Greptile threads are resolved (verified with `stats` command)
296
+ - ✅ All review threads are resolved (verified with the `stats` command)
282
297
  - ✅ All threads have replies explaining fixes
283
- - ✅ Greptile Quality Gate passes (≥4/5 score)
298
+ - ✅ Any review-agent quality gate passes
284
299
  - ✅ Branch protection allows merge
285
300
  - ✅ No manual tracking needed by maintainers
@@ -1,10 +1,20 @@
1
1
  #!/bin/bash
2
- # Greptile Review Thread Resolution Tool
3
- # Uses GitHub GraphQL API to systematically resolve review threads
4
- # Uses GitHub REST API to reply to review comments
2
+ # Review Thread Resolution Tool
3
+ # Resolves GitHub PR review threads from ANY review author — CodeRabbit, Qodo,
4
+ # Greptile, or a human reviewer the mechanism is author-agnostic.
5
+ # Uses GitHub GraphQL API to systematically resolve review threads.
6
+ # Uses GitHub REST API to reply to review comments.
7
+ # Note: the `list-all`, `resolve-all`, and `stats` convenience commands additionally
8
+ # recognize `greptile-apps`-authored threads (Greptile is one supported review tool);
9
+ # the core list/reply/resolve/reply-and-resolve commands work for every author.
5
10
 
6
11
  set -e
7
12
 
13
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
14
+ if [ -f "$SCRIPT_DIR/../../scripts/bootstrap-windows-tools.sh" ]; then
15
+ source "$SCRIPT_DIR/../../scripts/bootstrap-windows-tools.sh"
16
+ fi
17
+
8
18
  # Colors for output (defined before use)
9
19
  RED='\033[0;31m'
10
20
  GREEN='\033[0;32m'
@@ -13,7 +13,7 @@ Bash(git status *), Bash(git log *), Bash(git diff *), Bash(git branch *)
13
13
  Bash(git add *), Bash(git commit *), Bash(git push *), Bash(git stash *)
14
14
  Bash(git checkout *), Bash(git switch *), Bash(git merge *), Bash(git worktree *)
15
15
  Bash(bun *), Bash(bunx *), Bash(npm *), Bash(npx *), Bash(node *)
16
- Bash(bd *), Bash(gh *), Bash(openspec *)
16
+ Bash(forge *), Bash(gh *), Bash(openspec *)
17
17
  Bash(ls *), Bash(cat *), Bash(grep *), Bash(find *), Bash(pwd *), Bash(which *)
18
18
  Bash(echo *), Bash(head *), Bash(tail *), Bash(sort *), Bash(wc *)
19
19
  Bash(mkdir *), Bash(touch *), Bash(cp *), Bash(mv *)
@@ -21,7 +21,7 @@ Bash(mkdir *), Bash(touch *), Bash(cp *), Bash(mv *)
21
21
 
22
22
  ## Confirm Before Running (prompt each time)
23
23
 
24
- <!-- git reset --hard moved from Deny to Confirm to match opencode.json "ask" policy.
24
+ <!-- git reset --hard moved from Deny to Confirm ("ask" policy).
25
25
  Rationale: agents may need it for worktree cleanup during /verify stage,
26
26
  but it should always require user confirmation since it discards uncommitted changes. -->
27
27
  ```
@@ -14,6 +14,70 @@ const fs = require("node:fs");
14
14
  const path = require("node:path");
15
15
  const readline = require("node:readline");
16
16
 
17
+ // ── Config-honest enforcement (issue eda6d866) ──────────────────────────────
18
+ // This pre-commit gate must be INERT when the TDD rail is disabled in
19
+ // .forge/config.yaml. The hook is self-contained (target projects have
20
+ // .forge/hooks/*.js but NOT lib/), so it reads the config directly. `forge gate
21
+ // disable rail.tdd_intent` writes workflow.gates['rail.tdd_intent']; the `full`
22
+ // profile writes top-level rails.tdd_intent — honor either. Missing/unparseable
23
+ // config FAILS TOWARD enforcement (returns true) so a gate the user did not
24
+ // disable is never silently dropped.
25
+ function isTddEnabled(projectRoot) {
26
+ let raw;
27
+ try {
28
+ raw = fs.readFileSync(path.join(projectRoot, ".forge", "config.yaml"), "utf8");
29
+ } catch {
30
+ return true; // no config → enforce
31
+ }
32
+ if (!raw || !raw.trim()) return true;
33
+
34
+ const railDisabled = (config) =>
35
+ isExplicitlyDisabled(config?.workflow?.gates?.["rail.tdd_intent"]) ||
36
+ isExplicitlyDisabled(config?.rails?.tdd_intent);
37
+
38
+ let YAML;
39
+ try {
40
+ YAML = require("yaml");
41
+ } catch {
42
+ // The yaml MODULE is genuinely unavailable → conservative raw-text scan for the
43
+ // disabled block. Parser presence and parse success are split so a MALFORMED file
44
+ // never reaches this fuzzy scan.
45
+ return !(rawKeyDisabled(raw, "rail.tdd_intent") || rawKeyDisabled(raw, "tdd_intent"));
46
+ }
47
+ try {
48
+ const parsed = YAML.parse(raw);
49
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return true;
50
+ return !railDisabled(parsed);
51
+ } catch {
52
+ // MALFORMED YAML (module present, parse threw) → FAIL TOWARD ENFORCEMENT (return
53
+ // true). Never fall to the raw-text scan: a broken file with a `rail.tdd_intent:
54
+ // enabled: false` fragment must not switch the gate off (issue eda6d866).
55
+ return true;
56
+ }
57
+ }
58
+
59
+ function isExplicitlyDisabled(node) {
60
+ return Boolean(node) && typeof node === "object" && node.enabled === false;
61
+ }
62
+
63
+ // Scan raw YAML for a `<key>:` block whose immediate child is `enabled: false`.
64
+ function rawKeyDisabled(raw, key) {
65
+ const lines = String(raw).split(/\r?\n/);
66
+ const keyRe = new RegExp(`^(\\s*)"?${key.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}"?\\s*:\\s*$`);
67
+ for (let i = 0; i < lines.length; i += 1) {
68
+ const m = lines[i].match(keyRe);
69
+ if (!m) continue;
70
+ const parentIndent = m[1].length;
71
+ for (let j = i + 1; j < lines.length; j += 1) {
72
+ if (!lines[j].trim()) continue;
73
+ const childIndent = lines[j].match(/^\s*/)[0].length;
74
+ if (childIndent <= parentIndent) break;
75
+ if (/^\s*enabled\s*:\s*false\s*$/.test(lines[j])) return true;
76
+ }
77
+ }
78
+ return false;
79
+ }
80
+
17
81
  // Get staged files using git diff --cached
18
82
  function getStagedFiles() {
19
83
  try {
@@ -111,6 +175,9 @@ function hasTestFile(sourceFile, stagedFiles) {
111
175
  sourceFile.replace(/^bin\//, 'test/cli/').replace(ext, `.spec${ext}`),
112
176
  sourceFile.replace(/^bin\//, 'test/bin/').replace(ext, `.test${ext}`),
113
177
  sourceFile.replace(/^bin\//, 'test/bin/').replace(ext, `.spec${ext}`),
178
+ // Workspace packages (packages/<pkg>/src/**/foo.js → packages/<pkg>/test/foo.test.js)
179
+ sourceFile.replace(/^(packages\/[^/]+)\/src\/(?:.*\/)?([^/]+)$/, `$1/test/$2`).replace(ext, `.test${ext}`),
180
+ sourceFile.replace(/^(packages\/[^/]+)\/src\/(?:.*\/)?([^/]+)$/, `$1/test/$2`).replace(ext, `.spec${ext}`),
114
181
  ];
115
182
 
116
183
  // Check if test file exists in staged files or filesystem
@@ -160,6 +227,12 @@ function promptUser(question, options) {
160
227
 
161
228
  // Main hook logic
162
229
  async function main() {
230
+ // Project root is two levels up from this installed hook (<root>/.forge/hooks/).
231
+ // When the TDD rail is disabled in config, the gate is inert — allow the commit.
232
+ if (!isTddEnabled(path.resolve(__dirname, "..", ".."))) {
233
+ process.exit(0);
234
+ }
235
+
163
236
  console.log("🔍 TDD Check: Verifying test coverage for staged files...\n");
164
237
 
165
238
  const stagedFiles = getStagedFiles();
@@ -233,8 +306,12 @@ async function main() {
233
306
  }
234
307
  }
235
308
 
236
- // Run with error handling
237
- main().catch((error) => {
238
- console.error("Error in TDD check hook:", error.message);
239
- process.exit(1);
240
- });
309
+ module.exports = { isTddEnabled };
310
+
311
+ // Run with error handling (only as a script, not when required by tests).
312
+ if (require.main === module) {
313
+ main().catch((error) => {
314
+ console.error("Error in TDD check hook:", error.message);
315
+ process.exit(1);
316
+ });
317
+ }