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
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env bash
2
- # dep-guard.sh Dependency-guard helper for pre-change impact analysis.
2
+ # dep-guard.sh -- Dependency-guard helper for pre-change impact analysis.
3
3
  #
4
4
  # Subcommands:
5
5
  # find-consumers <file-path> Find files that import/require a given module
@@ -14,9 +14,29 @@ set -euo pipefail
14
14
 
15
15
  # Source shared sanitize library
16
16
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
17
+ if [[ -f "$SCRIPT_DIR/bootstrap-windows-tools.sh" ]]; then
18
+ source "$SCRIPT_DIR/bootstrap-windows-tools.sh"
19
+ fi
20
+ NODE_CMD="${NODE_CMD:-node}"
17
21
  source "$SCRIPT_DIR/lib/sanitize.sh"
18
22
 
19
- # ── Helpers ──────────────────────────────────────────────────────────────
23
+ node_script_path() {
24
+ case "$1" in
25
+ /[A-Za-z]/*)
26
+ _drive="$(printf '%s' "${1:1:1}" | tr '[:lower:]' '[:upper:]')"
27
+ printf '%s:/%s\n' "$_drive" "${1:3}"
28
+ ;;
29
+ *)
30
+ if command -v cygpath >/dev/null 2>&1; then
31
+ cygpath -m "$1"
32
+ else
33
+ printf '%s\n' "$1"
34
+ fi
35
+ ;;
36
+ esac
37
+ }
38
+
39
+ # ---- Helpers ----------------------------------------------------------------
20
40
 
21
41
  usage() {
22
42
  cat >&2 <<'EOF'
@@ -212,90 +232,28 @@ extract_task_file_from_design() {
212
232
  }
213
233
 
214
234
  run_phase3_analyzer() {
215
- local current_json_file="$1"
216
- local open_json_file="$2"
217
- local in_progress_json_file="$3"
235
+ local current_json="$1"
236
+ local open_json="$2"
237
+ local in_progress_json="$3"
218
238
  local task_file="$4"
219
239
  local repository_root="$5"
220
240
  local analyzer_script="${DEP_GUARD_ANALYZE_SCRIPT:-scripts/dep-guard-analyze.js}"
221
241
 
222
- node "$analyzer_script" \
223
- "$current_json_file" \
224
- "$open_json_file" \
225
- "$in_progress_json_file" \
226
- "$task_file" \
227
- "$repository_root"
242
+ printf '{"currentIssue":%s,"openIssues":%s,"inProgressIssues":%s,"taskFile":%s,"repositoryRoot":%s}' \
243
+ "$current_json" \
244
+ "${open_json:-[]}" \
245
+ "${in_progress_json:-[]}" \
246
+ "$(printf '%s' "$task_file" | jq -R '.')" \
247
+ "$(printf '%s' "$repository_root" | jq -R '.')" \
248
+ | "$NODE_CMD" "$(node_script_path "$analyzer_script")" --stdin
228
249
  }
229
250
 
230
251
  render_phase3_review() {
231
- local analysis_file="$1"
232
-
233
- node - "$analysis_file" <<'NODE'
234
- const fs = require('node:fs');
235
-
236
- const analysisPath = process.argv[2];
237
- const analysis = JSON.parse(fs.readFileSync(analysisPath, 'utf8'));
238
- const detectorCategories = Object.entries(analysis.scores ?? {})
239
- .filter(([name, score]) => name !== 'rubric' && Number(score) > 0)
240
- .map(([name]) => name);
241
-
242
- const lines = [
243
- '',
244
- `Structured dependency review for ${analysis.currentIssue.id}...`,
245
- '',
246
- ];
247
-
248
- if (!Array.isArray(analysis.issues) || analysis.issues.length === 0) {
249
- lines.push('No conflicts detected');
250
- process.stdout.write(`${lines.join('\n')}\n`);
251
- process.exit(0);
252
- }
253
-
254
- const seenPairs = new Set();
255
- for (const finding of analysis.issues) {
256
- const key = `${analysis.currentIssue.id}->${finding.targetIssueId}`;
257
- if (seenPairs.has(key)) {
258
- continue;
259
- }
260
- seenPairs.add(key);
261
- lines.push(`Issue pair: ${analysis.currentIssue.id} -> ${finding.targetIssueId}`);
262
- }
263
-
264
- lines.push(`Rubric score: ${analysis.scores?.rubric ?? 0}`);
265
- lines.push(
266
- `Confidence: ${(analysis.confidence?.score ?? 0).toFixed(2)}${
267
- analysis.confidence?.belowThreshold ? ' (below 70% threshold)' : ''
268
- }`,
269
- );
270
- lines.push(`Detector categories: ${detectorCategories.join(', ') || 'none'}`);
271
- lines.push(`Needs user decision: ${analysis.needsUserDecision ? 'yes' : 'no'}`);
272
-
273
- if (Array.isArray(analysis.detectorConflicts) && analysis.detectorConflicts.length > 0) {
274
- lines.push('Conflicts:');
275
- for (const conflict of analysis.detectorConflicts) {
276
- lines.push(` - ${conflict}`);
277
- }
278
- }
279
-
280
- if (Array.isArray(analysis.proposals) && analysis.proposals.length > 0) {
281
- lines.push('');
282
- lines.push('Proposed dependency updates:');
283
- for (const proposal of analysis.proposals) {
284
- lines.push(` - ${proposal.dependentIssueId} depends on ${proposal.dependsOnIssueId}`);
285
- if (Array.isArray(proposal.pros) && proposal.pros.length > 0) {
286
- lines.push(` Pros: ${proposal.pros.join('; ')}`);
287
- }
288
- if (Array.isArray(proposal.cons) && proposal.cons.length > 0) {
289
- lines.push(` Cons: ${proposal.cons.join('; ')}`);
290
- }
291
- }
292
- }
293
-
294
- process.stdout.write(`${lines.join('\n')}\n`);
295
- NODE
252
+ local renderer_script="${DEP_GUARD_RENDER_SCRIPT:-scripts/dep-guard-render-review.js}"
253
+ "$NODE_CMD" "$(node_script_path "$renderer_script")"
296
254
  }
297
255
 
298
- # ── Subcommands ──────────────────────────────────────────────────────────
256
+ # ---- Subcommands ------------------------------------------------------------
299
257
 
300
258
  cmd_find_consumers() {
301
259
  if [[ $# -lt 1 || -z "$1" ]]; then
@@ -343,11 +301,11 @@ cmd_check_ripple_keyword_v1() {
343
301
  local issue_id
344
302
  issue_id="$(sanitize "$1")"
345
303
 
346
- # ── Step 1: Validate issue exists ──────────────────────────────────────
304
+ # ---- Step 1: Validate issue exists ----------------------------------------
347
305
  local src_json
348
306
  src_json="$(bd_show_json "$issue_id")"
349
307
 
350
- # ── Step 2: Extract source title ───────────────────────────────────────
308
+ # ---- Step 2: Extract source title ----------------------------------------
351
309
  local src_title=""
352
310
  if command -v jq &>/dev/null; then
353
311
  src_title="$(printf '%s' "$src_json" | jq -r '.title // ""' 2>/dev/null)" || true
@@ -358,15 +316,15 @@ cmd_check_ripple_keyword_v1() {
358
316
  fi
359
317
 
360
318
  if [[ -z "$src_title" ]]; then
361
- echo "⚠️ Warning: could not extract title for ${issue_id} ripple check skipped" >&2
319
+ echo "Warning: could not extract title for ${issue_id} - ripple check skipped" >&2
362
320
  return 0
363
321
  fi
364
322
 
365
323
  echo ""
366
- printf '%s\n' "📋 Ripple check for ${issue_id}..."
324
+ printf '%s\n' "Ripple check for ${issue_id}..."
367
325
  echo ""
368
326
 
369
- # ── Step 3: Collect active issues ──────────────────────────────────────
327
+ # ---- Step 3: Collect active issues ---------------------------------------
370
328
  # Run bd list for open and in_progress separately, combine results
371
329
  local list_output=""
372
330
  local open_list=""
@@ -390,122 +348,24 @@ cmd_check_ripple_keyword_v1() {
390
348
  fi
391
349
 
392
350
  if [[ -z "$list_output" ]]; then
393
- echo "⚠️ Warning: could not fetch active issue list ripple check skipped" >&2
351
+ echo "Warning: could not fetch active issue list - ripple check skipped" >&2
394
352
  return 0
395
353
  fi
396
354
 
397
- # ── Step 4: Parse each active issue (excluding source) ─────────────────
398
- # Format: forge-xxx [P2] [feature] - Title of the issue
399
- # forge-yyy [P1] [task] - Another issue title
400
- local overlap_count=0
401
- local overlap_report=""
402
-
403
- # Stop words to exclude from keyword matching
404
- local stop_words=" the a an and or is in to for of with on at by from add fix update implement create remove delete make use get set run test check all this that it be as not no but if do we they are was were been have has had will would could should may can each every both also into than then when where which what how why who its new first last same other "
405
-
406
- # Tokenize source title: lowercase, split on non-alpha, filter stop words + short terms
407
- local src_terms=""
408
- src_terms="$(printf '%s' "$src_title" | tr '[:upper:]' '[:lower:]' | tr -cs '[:alpha:]' '\n' | sort -u)"
409
-
410
- # Filter source terms
411
- local filtered_src_terms=""
412
- while IFS= read -r term; do
413
- [[ -z "$term" ]] && continue
414
- # Skip terms < 3 characters
415
- [[ ${#term} -lt 3 ]] && continue
416
- # Skip stop words
417
- if [[ "$stop_words" == *" ${term} "* ]]; then
418
- continue
419
- fi
420
- filtered_src_terms="${filtered_src_terms} ${term}"
421
- done <<< "$src_terms"
422
-
423
- # Process each line in list_output
424
- while IFS= read -r line; do
425
- [[ -z "$line" ]] && continue
426
-
427
- # Extract issue ID (forge-xxx pattern)
428
- local cand_id=""
429
- cand_id="$(printf '%s' "$line" | grep -oE 'forge-[a-zA-Z0-9]+(\.[a-zA-Z0-9]+)*' | head -1)" || continue
430
- [[ -z "$cand_id" ]] && continue
431
-
432
- # Skip the source issue itself
433
- [[ "$cand_id" == "$issue_id" ]] && continue
434
-
435
- # Extract status symbol and map to label
436
- local cand_status="open"
437
- if printf '%s' "$line" | grep -q '◐'; then
438
- cand_status="in_progress"
439
- fi
440
-
441
- # Extract priority (P1, P2, P3, etc.)
442
- local cand_priority=""
443
- cand_priority="$(printf '%s' "$line" | grep -oE 'P[0-9]+' | head -1)" || true
444
- [[ -z "$cand_priority" ]] && cand_priority="P2"
445
-
446
- # Extract title (everything after " - ")
447
- local cand_title=""
448
- cand_title="$(printf '%s' "$line" | sed 's/^[^]]*\] [^]]*\] - //')" || continue
449
- [[ -z "$cand_title" ]] && continue
450
-
451
- # Tokenize candidate title
452
- local cand_terms=""
453
- cand_terms="$(printf '%s' "$cand_title" | tr '[:upper:]' '[:lower:]' | tr -cs '[:alpha:]' '\n' | sort -u)"
454
-
455
- # Filter candidate terms
456
- local filtered_cand_terms=""
457
- while IFS= read -r term; do
458
- [[ -z "$term" ]] && continue
459
- [[ ${#term} -lt 3 ]] && continue
460
- if [[ "$stop_words" == *" ${term} "* ]]; then
461
- continue
462
- fi
463
- filtered_cand_terms="${filtered_cand_terms} ${term}"
464
- done <<< "$cand_terms"
465
-
466
- # ── Step 6: Find shared meaningful terms ───────────────────────────────
467
- local shared_terms=""
468
- local shared_count=0
469
- for src_t in $filtered_src_terms; do
470
- for cand_t in $filtered_cand_terms; do
471
- if [[ "$src_t" == "$cand_t" ]]; then
472
- if [[ -z "$shared_terms" ]]; then
473
- shared_terms="\"${src_t}\""
474
- else
475
- shared_terms="${shared_terms}, \"${src_t}\""
476
- fi
477
- shared_count=$((shared_count + 1))
478
- break
479
- fi
480
- done
481
- done
482
-
483
- # ── Step 7: Report if >= 2 shared terms ────────────────────────────────
484
- if [[ $shared_count -ge 2 ]]; then
485
- overlap_count=$((overlap_count + 1))
486
- overlap_report="${overlap_report} ${cand_id} (${cand_status}, ${cand_priority}): \"${cand_title}\""$'\n'
487
- overlap_report="${overlap_report} Overlap: keyword match — ${shared_terms}"$'\n'
488
- overlap_report="${overlap_report} Confidence: LOW (keyword only, no contract data)"$'\n'
489
- overlap_report="${overlap_report}"$'\n'
490
- overlap_report="${overlap_report} Options:"$'\n'
491
- overlap_report="${overlap_report} (a) Add dependency: bd dep add ${issue_id} ${cand_id}"$'\n'
492
- overlap_report="${overlap_report} (b) Proceed — no real conflict"$'\n'
493
- overlap_report="${overlap_report} (c) Investigate: bd show ${cand_id}"$'\n'
494
- overlap_report="${overlap_report}"$'\n'
495
- fi
496
-
497
- done <<< "$list_output"
498
-
499
- # ── Step 8: Output final report ──────────────────────────────────────
500
- if [[ $overlap_count -gt 0 ]]; then
501
- printf '%s\n' "⚠️ Potential overlap with ${overlap_count} issue(s):"
502
- echo ""
503
- printf '%s' "$overlap_report"
504
- else
505
- printf '%s\n' "✅ No conflicts detected"
355
+ # ---- Step 4: Parse each active issue (excluding source) ------------------
356
+ # Format: - forge-xxx [P2] [feature] - Title of the issue
357
+ # - forge-yyy [P1] [task] - Another issue title
358
+ if ! command -v "$NODE_CMD" >/dev/null 2>&1; then
359
+ echo "Error: ${NODE_CMD} is required but not found." >&2
360
+ exit 1
506
361
  fi
507
362
 
363
+ ISSUE_ID="$issue_id" \
364
+ SOURCE_TITLE="$src_title" \
365
+ LIST_OUTPUT="$list_output" \
366
+ "$NODE_CMD" "$(node_script_path "$SCRIPT_DIR/dep-guard-keyword-ripple.js")"
508
367
  return 0
368
+
509
369
  }
510
370
 
511
371
  cmd_check_ripple() {
@@ -529,7 +389,7 @@ cmd_check_ripple() {
529
389
  fi
530
390
 
531
391
  if [[ -z "$src_title" ]]; then
532
- echo "⚠️ Warning: could not extract title for ${issue_id} ripple check skipped" >&2
392
+ echo "Warning: could not extract title for ${issue_id} - ripple check skipped" >&2
533
393
  return 0
534
394
  fi
535
395
 
@@ -544,7 +404,7 @@ cmd_check_ripple() {
544
404
  local task_file=""
545
405
  task_file="$(extract_task_file_from_design "$design_text" || true)"
546
406
  if [[ -z "$task_file" || ! -f "$task_file" ]]; then
547
- echo "⚠️ Structured analyzer unavailable, falling back to keyword-only ripple check." >&2
407
+ echo "Warning: structured analyzer unavailable, falling back to keyword-only ripple check." >&2
548
408
  cmd_check_ripple_keyword_v1 "$issue_id"
549
409
  return 0
550
410
  fi
@@ -555,51 +415,23 @@ cmd_check_ripple() {
555
415
  in_progress_json="$(${BD_CMD:-bd} list --status=in_progress --json 2>/dev/null)" || true
556
416
 
557
417
  if [[ -z "$open_json" && -z "$in_progress_json" ]]; then
558
- echo "⚠️ Warning: could not fetch active issue list ripple check skipped" >&2
418
+ echo "Warning: could not fetch active issue list - ripple check skipped" >&2
559
419
  return 0
560
420
  fi
561
421
 
562
- local tmp_dir
563
- tmp_dir="$(mktemp -d)"
564
- # On Windows/Git Bash, normalize to a mixed-mode path so both bash file I/O
565
- # and Node.js resolve to the same physical location (cygpath -m → C:/...).
566
- # Preserve the original POSIX path if conversion fails or returns empty.
567
- if command -v cygpath &>/dev/null; then
568
- local mixed_tmp_dir
569
- mixed_tmp_dir="$(cygpath -m "$tmp_dir" 2>/dev/null)" || true
570
- if [[ -n "$mixed_tmp_dir" && -d "$mixed_tmp_dir" ]]; then
571
- tmp_dir="$mixed_tmp_dir"
572
- fi
573
- fi
574
- trap 'rm -rf "$tmp_dir"' RETURN
575
-
576
- printf '%s' "$src_json" > "${tmp_dir}/current.json"
577
- printf '%s' "${open_json:-[]}" > "${tmp_dir}/open.json"
578
- printf '%s' "${in_progress_json:-[]}" > "${tmp_dir}/in-progress.json"
579
422
 
580
423
  local repository_root="${DEP_GUARD_REPOSITORY_ROOT:-$PWD}"
581
424
  if run_phase3_analyzer \
582
- "${tmp_dir}/current.json" \
583
- "${tmp_dir}/open.json" \
584
- "${tmp_dir}/in-progress.json" \
425
+ "$src_json" \
426
+ "${open_json:-[]}" \
427
+ "${in_progress_json:-[]}" \
585
428
  "$task_file" \
586
429
  "$repository_root" \
587
- > "${tmp_dir}/analysis.json" 2> "${tmp_dir}/analysis.err"; then
588
- if render_phase3_review "${tmp_dir}/analysis.json"; then
589
- trap - RETURN
590
- rm -rf "$tmp_dir"
591
- return 0
592
- fi
593
- echo "⚠️ Phase 3 review rendering failed — falling back to keyword-only ripple check." >&2
594
- else
595
- echo "⚠️ Structured analyzer unavailable, falling back to keyword-only ripple check." >&2
596
- if [[ -s "${tmp_dir}/analysis.err" ]]; then
597
- cat "${tmp_dir}/analysis.err" >&2
598
- fi
430
+ | render_phase3_review; then
431
+ return 0
599
432
  fi
600
433
 
601
- trap - RETURN
602
- rm -rf "$tmp_dir"
434
+ echo "Warning: structured analyzer unavailable, falling back to keyword-only ripple check." >&2
603
435
  cmd_check_ripple_keyword_v1 "$issue_id"
604
436
  }
605
437
 
@@ -624,7 +456,7 @@ cmd_apply_decision() {
624
456
  die "Failed to add dependency ${dependent_issue} -> ${depends_on_issue}"
625
457
  }
626
458
 
627
- # Check for cycles use exit code as primary signal
459
+ # Check for cycles -- use exit code as primary signal
628
460
  if ! ${BD_CMD:-bd} dep cycles &>/dev/null; then
629
461
  rollback_dependency "$dependent_issue" "$depends_on_issue"
630
462
  die "Cycle detected for ${dependent_issue} -> ${depends_on_issue}"
@@ -722,7 +554,7 @@ cmd_extract_contracts() {
722
554
  local all_contracts=""
723
555
 
724
556
  while IFS= read -r line || [[ -n "$line" ]]; do
725
- # New task block flush previous
557
+ # New task block -- flush previous
726
558
  if [[ "$line" =~ ^##\ Task ]]; then
727
559
  local _emitted
728
560
  _emitted="$(emit_contracts "$current_files" "$current_what")"
@@ -777,7 +609,7 @@ cmd_extract_contracts() {
777
609
  printf '%s\n' "$contracts"
778
610
  }
779
611
 
780
- # ── Main dispatcher ──────────────────────────────────────────────────────
612
+ # ---- Main dispatcher --------------------------------------------------------
781
613
 
782
614
  if [[ $# -lt 1 ]]; then
783
615
  usage
@@ -21,6 +21,9 @@ fi
21
21
 
22
22
  # Source shared libraries
23
23
  _FI_SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
24
+ if [[ -f "$_FI_SCRIPT_DIR/bootstrap-windows-tools.sh" ]]; then
25
+ source "$_FI_SCRIPT_DIR/bootstrap-windows-tools.sh"
26
+ fi
24
27
  source "$_FI_SCRIPT_DIR/lib/sanitize.sh"
25
28
  if [[ -f "$_FI_SCRIPT_DIR/lib/jsonl-lock.sh" ]]; then
26
29
  source "$_FI_SCRIPT_DIR/lib/jsonl-lock.sh"
@@ -10,8 +10,8 @@
10
10
  # forge_team_claim — Top-level dispatcher entry point
11
11
  #
12
12
  # Env overrides (for testing):
13
- # GH_CMD — Path to gh binary
14
- # BD_CMD — Path to bd binary
13
+ # GH_CMD — Path to gh binary
14
+ # FORGE_CMD — Path to forge binary
15
15
  #
16
16
  # This file does NOT set errexit/pipefail — callers manage their own shell options.
17
17
 
@@ -61,16 +61,22 @@ _claim_prompt() {
61
61
  fi
62
62
  }
63
63
 
64
- # _get_github_issue_number <beads-id>
65
- # Extracts github_issue:N from bd show output. Returns number or empty.
64
+ # _get_github_issue_number <issue-id>
65
+ # Extracts the GitHub issue number from the issue's github_issue:<n> label.
66
+ # Returns the number or empty.
66
67
  _get_github_issue_number() {
67
- local beads_id="$1"
68
- local bd_cmd="${BD_CMD:-bd}"
69
- local bd_output
70
- bd_output="$("$bd_cmd" show "$beads_id" 2>/dev/null)" || return 1
68
+ local issue_id="$1"
69
+ local forge_cmd="${FORGE_CMD:-forge}"
70
+ local show_output
71
+ show_output="$("$forge_cmd" issue show "$issue_id" --json 2>/dev/null)" || return 1
71
72
 
72
73
  local issue_num
73
- issue_num="$(printf '%s' "$bd_output" | grep -oP 'github_issue:\K[0-9]+' || true)"
74
+ issue_num="$(printf '%s' "$show_output" | jq -r '
75
+ (.data.issue // .data // {})
76
+ | (.labels // [])
77
+ | map(select(startswith("github_issue:")))
78
+ | (.[0] // "")
79
+ | ltrimstr("github_issue:")' 2>/dev/null)"
74
80
  if [[ -z "$issue_num" ]]; then
75
81
  return 1
76
82
  fi
@@ -90,7 +96,7 @@ _get_github_assignee() {
90
96
  # _claim_lock_dir — Returns the path to the claim lock directory
91
97
  _claim_lock_dir() {
92
98
  local root="${TEAM_MAP_ROOT:-.}"
93
- printf '%s' "$root/.beads"
99
+ printf '%s' "$root/.forge"
94
100
  }
95
101
 
96
102
  # ── Public API ───────────────────────────────────────────────────────────
@@ -149,7 +155,7 @@ claim_with_lock() {
149
155
  fi
150
156
 
151
157
  local gh_cmd="${GH_CMD:-gh}"
152
- local bd_cmd="${BD_CMD:-bd}"
158
+ local forge_cmd="${FORGE_CMD:-forge}"
153
159
  local lock_dir
154
160
  lock_dir="$(_claim_lock_dir)"
155
161
  mkdir -p "$lock_dir"
@@ -186,8 +192,13 @@ claim_with_lock() {
186
192
  exit 1
187
193
  fi
188
194
  fi
189
- # Claim on both Beads and GitHub
190
- "$bd_cmd" update "$beads_id" --claim >/dev/null 2>&1 || true
195
+ # Claim on both the Forge issue backend and GitHub. The Forge claim is the
196
+ # authoritative backend update, so a failure must abort (exit the flock
197
+ # subshell non-zero); the GitHub assignee edit stays best-effort.
198
+ "$forge_cmd" issue claim "$beads_id" >/dev/null 2>&1 || {
199
+ _claim_error "Failed to claim $beads_id in Forge"
200
+ exit 1
201
+ }
191
202
  "$gh_cmd" issue edit "$issue_num" --add-assignee "$current_user" >/dev/null 2>&1 || true
192
203
  ) 200>"$lock_file"
193
204
  local subshell_rc=$?
@@ -215,8 +226,13 @@ claim_with_lock() {
215
226
  return 1
216
227
  fi
217
228
  fi
218
- # Claim on both Beads and GitHub
219
- "$bd_cmd" update "$beads_id" --claim >/dev/null 2>&1 || true
229
+ # Claim on both the Forge issue backend and GitHub. The Forge claim is the
230
+ # authoritative backend update, so a failure must abort (return non-zero so
231
+ # the RETURN trap releases the lock); the GitHub assignee edit stays best-effort.
232
+ "$forge_cmd" issue claim "$beads_id" >/dev/null 2>&1 || {
233
+ _claim_error "Failed to claim $beads_id in Forge"
234
+ return 1
235
+ }
220
236
  "$gh_cmd" issue edit "$issue_num" --add-assignee "$current_user" >/dev/null 2>&1 || true
221
237
  fi
222
238
 
@@ -234,13 +250,13 @@ forge_team_claim() {
234
250
  return 1
235
251
  fi
236
252
 
237
- local bd_cmd="${BD_CMD:-bd}"
253
+ local forge_cmd="${FORGE_CMD:-forge}"
238
254
 
239
255
  if [[ "$force_flag" == "--force" ]]; then
240
256
  # Skip pre-claim check, claim directly (pass --force to skip lock re-check too)
241
257
  claim_with_lock "$beads_id" "--force" || return 1
242
- # Log override via bd comments
243
- "$bd_cmd" comments add "$beads_id" "Force-claimed by $(get_github_user 2>/dev/null || echo 'unknown')" >/dev/null 2>&1 || true
258
+ # Log the override as an issue comment
259
+ "$forge_cmd" issue comment "$beads_id" "Force-claimed by $(get_github_user 2>/dev/null || echo 'unknown')" >/dev/null 2>&1 || true
244
260
  _claim_info "$beads_id force-claimed successfully"
245
261
  return 0
246
262
  fi