forge-workflow 0.0.10 → 0.1.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (454) hide show
  1. package/.claude/rules/{greptile-review-process.md → review-process.md} +56 -41
  2. package/.claude/scripts/{greptile-resolve.sh → review-resolve.sh} +13 -3
  3. package/.cursor/rules/permissions-guidance.mdc +2 -2
  4. package/.forge/hooks/check-tdd.js +3 -0
  5. package/.forge/hooks/forge-native-hook.js +245 -0
  6. package/.forge/protected-paths.yaml +157 -0
  7. package/AGENTS.md +150 -61
  8. package/CHANGELOG.md +681 -0
  9. package/CLAUDE.md +9 -118
  10. package/QUICKSTART.md +171 -0
  11. package/README.md +271 -363
  12. package/bin/forge-cmd.js +120 -9
  13. package/bin/forge-preflight.js +26 -5
  14. package/bin/forge.js +461 -489
  15. package/docs/INDEX.md +93 -0
  16. package/docs/PROJECT_DESIGN.md +685 -0
  17. package/docs/architecture/index.md +66 -0
  18. package/docs/architecture/notes/README.md +35 -0
  19. package/docs/architecture/subsystems/README.md +46 -0
  20. package/docs/forge/TOOLCHAIN.md +670 -0
  21. package/docs/forge/VALIDATION.md +82 -0
  22. package/docs/{AGENT_INSTALL_PROMPT.md → guides/AGENT_INSTALL_PROMPT.md} +3 -3
  23. package/docs/guides/BEADS_GITHUB_SYNC.md +32 -0
  24. package/docs/{ENHANCED_ONBOARDING.md → guides/ENHANCED_ONBOARDING.md} +16 -12
  25. package/docs/guides/GREPTILE_SETUP.md +46 -0
  26. package/docs/guides/MANUAL_REVIEW_GUIDE.md +58 -0
  27. package/docs/guides/MIGRATION.md +56 -0
  28. package/docs/guides/SETUP.md +118 -0
  29. package/docs/guides/SUPPORT.md +185 -0
  30. package/docs/guides/WORKFLOW_TEMPLATES.md +74 -0
  31. package/docs/guides/memory-backends.md +183 -0
  32. package/docs/reference/ADAPTERS.md +128 -0
  33. package/docs/reference/AGENT_SKILL_PARITY.md +175 -0
  34. package/docs/reference/COMMANDS.md +205 -0
  35. package/docs/reference/DECISION_DRIFT_GUARDS.md +97 -0
  36. package/docs/{EXAMPLES.md → reference/EXAMPLES.md} +7 -5
  37. package/docs/reference/FORGE_KERNEL_STORAGE_MODEL.md +135 -0
  38. package/docs/reference/HERMES_INTEGRATION.md +118 -0
  39. package/docs/reference/INSIGHTS_RECAP.md +63 -0
  40. package/docs/reference/INSTALL.md +164 -0
  41. package/docs/reference/KERNEL_TAXONOMY_VALIDATION.md +161 -0
  42. package/docs/reference/PROTECTED_PATH_MANIFEST.md +25 -0
  43. package/docs/reference/RELEASE.md +68 -0
  44. package/docs/reference/RESEARCH_TEMPLATE.md +292 -0
  45. package/docs/{ROADMAP.md → reference/ROADMAP.md} +12 -9
  46. package/docs/reference/SKILLS.md +35 -0
  47. package/docs/reference/STATUS_BOARD.md +80 -0
  48. package/docs/reference/TEMPLATES.md +106 -0
  49. package/docs/{TOOLCHAIN.md → reference/TOOLCHAIN.md} +62 -47
  50. package/docs/reference/VALIDATION.md +82 -0
  51. package/docs/reference/agent-permissions.md +169 -0
  52. package/docs/reference/beads-to-kernel-migration-ux.md +61 -0
  53. package/docs/reference/control-plane-guarantees.md +125 -0
  54. package/docs/reference/dependency-chain.md +331 -0
  55. package/docs/reference/forge-kernel-issue-command-contract.md +161 -0
  56. package/docs/reference/forge-kernel-schema.md +72 -0
  57. package/docs/reference/kernel-conflict-evaluators.md +27 -0
  58. package/docs/reference/patch-md-format.md +77 -0
  59. package/docs/reference/protected-state-surfaces.md +59 -0
  60. package/docs/reference/shepherd.md +115 -0
  61. package/docs/reference/superpowers-analysis.md +320 -0
  62. package/docs/reference/superpowers-integration-options.md +404 -0
  63. package/docs/reference/test-environment.md +519 -0
  64. package/docs/reference/upgrade-safety.md +59 -0
  65. package/lefthook.yml +18 -0
  66. package/lib/adapter-cli.js +307 -0
  67. package/lib/adapters/beads-issue-adapter.js +127 -0
  68. package/lib/adapters/beads-kernel-compat.js +1042 -0
  69. package/lib/adapters/greptile-review-adapter.js +141 -0
  70. package/lib/adapters/kernel-issue-adapter.js +101 -0
  71. package/lib/adapters/pr-state-adapter.js +484 -0
  72. package/lib/adoption-profiles.js +126 -0
  73. package/lib/agents/README.md +2 -6
  74. package/lib/agents/claude.plugin.json +3 -8
  75. package/lib/agents/codex.plugin.json +9 -1
  76. package/lib/agents/cursor.plugin.json +2 -6
  77. package/lib/agents/hermes.plugin.json +22 -0
  78. package/lib/agents-config.js +39 -1236
  79. package/lib/audit-evidence.js +282 -0
  80. package/lib/beads-setup.js +121 -0
  81. package/lib/beads-sync-scaffold.js +25 -101
  82. package/lib/codex-skills.js +51 -1
  83. package/lib/commands/_issue.js +741 -77
  84. package/lib/commands/_manifest.js +91 -0
  85. package/lib/commands/_registry.js +85 -34
  86. package/lib/commands/_resolve-command-opts.js +261 -0
  87. package/lib/commands/_serve-security.js +270 -0
  88. package/lib/commands/adapter.js +12 -0
  89. package/lib/commands/add.js +118 -0
  90. package/lib/commands/audit.js +70 -0
  91. package/lib/commands/blocked.js +5 -0
  92. package/lib/commands/board.js +64 -0
  93. package/lib/commands/claim.js +21 -2
  94. package/lib/commands/claims.js +7 -0
  95. package/lib/commands/clean.js +485 -75
  96. package/lib/commands/close.js +2 -2
  97. package/lib/commands/comment.js +5 -0
  98. package/lib/commands/control.js +148 -0
  99. package/lib/commands/create.js +2 -2
  100. package/lib/commands/dev.js +185 -7
  101. package/lib/commands/doc-gate.js +336 -0
  102. package/lib/commands/doctor.js +156 -0
  103. package/lib/commands/explain.js +15 -0
  104. package/lib/commands/export.js +237 -0
  105. package/lib/commands/gate.js +192 -0
  106. package/lib/commands/hooks.js +242 -0
  107. package/lib/commands/inbox.js +118 -0
  108. package/lib/commands/init.js +598 -0
  109. package/lib/commands/insights.js +79 -0
  110. package/lib/commands/issue.js +12 -1
  111. package/lib/commands/issues.js +17 -0
  112. package/lib/commands/lint.js +5 -0
  113. package/lib/commands/list.js +2 -2
  114. package/lib/commands/merge.js +312 -0
  115. package/lib/commands/migrate.js +523 -0
  116. package/lib/commands/new.js +12 -0
  117. package/lib/commands/options.js +241 -0
  118. package/lib/commands/orient.js +13 -0
  119. package/lib/commands/orphans.js +5 -0
  120. package/lib/commands/patch.js +67 -0
  121. package/lib/commands/plan.js +436 -24
  122. package/lib/commands/preflight.js +211 -0
  123. package/lib/commands/prime.js +13 -0
  124. package/lib/commands/push.js +69 -2
  125. package/lib/commands/ready.js +2 -2
  126. package/lib/commands/recall.js +116 -0
  127. package/lib/commands/recap.js +61 -0
  128. package/lib/commands/recommend.js +0 -1
  129. package/lib/commands/release.js +91 -0
  130. package/lib/commands/remember.js +74 -0
  131. package/lib/commands/role.js +99 -0
  132. package/lib/commands/serve.js +581 -0
  133. package/lib/commands/setup.js +838 -972
  134. package/lib/commands/shepherd.js +436 -0
  135. package/lib/commands/ship.js +23 -1
  136. package/lib/commands/show.js +2 -2
  137. package/lib/commands/stage.js +192 -0
  138. package/lib/commands/stale.js +5 -0
  139. package/lib/commands/status.js +158 -21
  140. package/lib/commands/sync.js +34 -46
  141. package/lib/commands/team.js +4 -1
  142. package/lib/commands/test.js +43 -27
  143. package/lib/commands/update.js +2 -2
  144. package/lib/commands/upgrade.js +47 -0
  145. package/lib/commands/validate.js +43 -18
  146. package/lib/commands/worktree.js +307 -100
  147. package/lib/config-writer.js +202 -0
  148. package/lib/control-plane.js +236 -0
  149. package/lib/core/runtime-graph.js +946 -0
  150. package/lib/dep-guard/keyword-ripple.js +2 -2
  151. package/lib/deprecated-sync-cleanup.js +362 -0
  152. package/lib/detect-agent.js +2 -28
  153. package/lib/detect-worktree.js +35 -9
  154. package/lib/doc-gate/declaration.js +177 -0
  155. package/lib/doc-gate/detect.js +289 -0
  156. package/lib/doc-gate/gate.js +375 -0
  157. package/lib/doc-gate/okf-config.js +128 -0
  158. package/lib/doc-gate/okf.js +429 -0
  159. package/lib/docs-command.js +1161 -6
  160. package/lib/forge-issues.js +382 -11
  161. package/lib/forge-lock.js +262 -0
  162. package/lib/gate-events.js +193 -0
  163. package/lib/global-flags.js +74 -0
  164. package/lib/greptile-match.js +7 -63
  165. package/lib/harness-capability-matrix.js +380 -0
  166. package/lib/hook-global-installer.js +347 -0
  167. package/lib/hook-renderer.js +451 -0
  168. package/lib/inbox.js +391 -0
  169. package/lib/insights.js +397 -0
  170. package/lib/issue-adapter.js +156 -0
  171. package/lib/issue-backend.js +145 -0
  172. package/lib/issue-render.js +220 -0
  173. package/lib/kernel/backing-issue.js +305 -0
  174. package/lib/kernel/broker.js +1218 -0
  175. package/lib/kernel/cli-broker-factory.js +130 -0
  176. package/lib/kernel/conflict-signal.js +82 -0
  177. package/lib/kernel/evaluators.js +195 -0
  178. package/lib/kernel/fs-class.js +495 -0
  179. package/lib/kernel/issue-command-contract.js +559 -0
  180. package/lib/kernel/issue-id-resolver.js +186 -0
  181. package/lib/kernel/lease-enforcer.js +158 -0
  182. package/lib/kernel/migrations.js +333 -0
  183. package/lib/kernel/planning-buckets-schema.js +109 -0
  184. package/lib/kernel/projection-jsonl-writer.js +450 -0
  185. package/lib/kernel/readiness-model.js +329 -0
  186. package/lib/kernel/schema.js +356 -0
  187. package/lib/kernel/sqlite-driver.js +2504 -0
  188. package/lib/kernel/taxonomy-validator.js +394 -0
  189. package/lib/lefthook-check.js +3 -2
  190. package/lib/lefthook-wiring.js +413 -0
  191. package/lib/mcp-config-renderer.js +288 -0
  192. package/lib/memory/graphiti-mcp.js +106 -0
  193. package/lib/memory/router.js +387 -0
  194. package/lib/memory/typed-api.js +102 -0
  195. package/lib/memory-digest.js +195 -0
  196. package/lib/merge-rules.js +395 -0
  197. package/lib/migrate-dry-run.js +466 -0
  198. package/lib/orientation.js +863 -0
  199. package/lib/package-manager-remediation.js +103 -0
  200. package/lib/package-root.js +381 -0
  201. package/lib/patch-intent.js +890 -0
  202. package/lib/plugin-catalog.js +3 -4
  203. package/lib/plugin-manager.js +0 -5
  204. package/lib/pr-bundle.js +186 -0
  205. package/lib/pr-monitor/differ.js +195 -0
  206. package/lib/pr-monitor/events.js +0 -0
  207. package/lib/pr-monitor/gather.js +124 -0
  208. package/lib/pr-monitor/journal.js +299 -0
  209. package/lib/pr-monitor/monitor.js +146 -0
  210. package/lib/pr-monitor/render-sticky.js +157 -0
  211. package/lib/pr-monitor/watch-lifecycle.js +95 -0
  212. package/lib/pr-monitor/watch.js +247 -0
  213. package/lib/pr-pull.js +1273 -0
  214. package/lib/pr-shepherd.js +494 -0
  215. package/lib/pr-state-validator.js +59 -0
  216. package/lib/preflight/gates.js +237 -0
  217. package/lib/preflight/runner.js +116 -0
  218. package/lib/project-discovery.js +0 -53
  219. package/lib/project-memory.js +99 -497
  220. package/lib/protected-path-manifest.js +281 -0
  221. package/lib/protected-state-surfaces.js +387 -0
  222. package/lib/release-readiness.js +2089 -0
  223. package/lib/reset.js +59 -45
  224. package/lib/review-adapter.js +68 -0
  225. package/lib/rules-sync.js +260 -0
  226. package/lib/runtime-health.js +241 -20
  227. package/lib/safety-config-renderer.js +268 -0
  228. package/lib/setup-action-log.js +1 -7
  229. package/lib/setup.js +27 -65
  230. package/lib/shell-utils.js +76 -6
  231. package/lib/skills-sync.js +330 -0
  232. package/lib/smart-status/scoring.js +17 -3
  233. package/lib/status/beads-snapshot.js +45 -2
  234. package/lib/status/presenter.js +169 -18
  235. package/lib/status/snapshot.js +186 -0
  236. package/lib/sync-backend.js +202 -0
  237. package/lib/untrusted-content.js +52 -0
  238. package/lib/upgrade-safety.js +199 -0
  239. package/lib/workflow/enforce-stage.js +296 -47
  240. package/lib/workflow/stage-transition.js +115 -0
  241. package/lib/workflow/stages.js +30 -6
  242. package/lib/workflow/state-manager.js +11 -22
  243. package/lib/workflow/state.js +23 -1
  244. package/lib/workflow-profiles.js +17 -5
  245. package/package.json +37 -35
  246. package/rules/documentation.md +19 -0
  247. package/rules/kernel-tracking.md +26 -0
  248. package/rules/security.md +22 -0
  249. package/rules/tdd.md +20 -0
  250. package/rules/workflow.md +27 -0
  251. package/scripts/auto-backing-issue.js +47 -0
  252. package/scripts/beads-context.sh +81 -57
  253. package/scripts/beads-upgrade-smoke.sh +24 -3
  254. package/scripts/bootstrap-windows-tools.sh +78 -0
  255. package/scripts/branch-protection.js +2 -3
  256. package/scripts/check-agents.js +34 -137
  257. package/scripts/commitlint.js +3 -1
  258. package/scripts/conflict-detect.sh +3 -0
  259. package/scripts/dep-guard.sh +22 -3
  260. package/scripts/file-index.sh +3 -0
  261. package/scripts/forge-team/lib/claim.sh +34 -18
  262. package/scripts/forge-team/lib/dashboard.sh +61 -86
  263. package/scripts/forge-team/lib/epic.sh +99 -263
  264. package/scripts/forge-team/lib/hooks.sh +26 -28
  265. package/scripts/forge-team/lib/identity.sh +4 -4
  266. package/scripts/forge-team/lib/sync-github.sh +49 -84
  267. package/scripts/forge-team/lib/verify.sh +93 -83
  268. package/scripts/forge-team/lib/workload.sh +41 -65
  269. package/scripts/forge-team/tests/claim.test.sh +25 -19
  270. package/scripts/forge-team/tests/dashboard.test.sh +31 -46
  271. package/scripts/forge-team/tests/epic.test.sh +52 -71
  272. package/scripts/forge-team/tests/hooks.test.sh +38 -50
  273. package/scripts/forge-team/tests/identity.test.sh +3 -3
  274. package/scripts/forge-team/tests/integration.test.sh +44 -66
  275. package/scripts/forge-team/tests/sync-github.test.sh +50 -83
  276. package/scripts/forge-team/tests/verify.test.sh +37 -46
  277. package/scripts/forge-team/tests/workflow-integration.test.sh +4 -4
  278. package/scripts/forge-team/tests/workload.test.sh +32 -66
  279. package/scripts/gen-command-manifest.js +153 -0
  280. package/scripts/gen-embedded-assets.mjs +129 -0
  281. package/scripts/install.ps1 +139 -0
  282. package/scripts/install.sh +268 -0
  283. package/scripts/lib/release-asset.mjs +84 -0
  284. package/scripts/parity-check.mjs +145 -0
  285. package/scripts/parity-check.test.mjs +58 -0
  286. package/scripts/pin-agentic-workflow-images.js +112 -0
  287. package/scripts/pr-coordinator.sh +3 -0
  288. package/scripts/preflight-sonar.eslint.config.mjs +44 -0
  289. package/scripts/preflight.sh +21 -94
  290. package/scripts/protected-state-check.js +104 -0
  291. package/scripts/smart-status.sh +60 -57
  292. package/scripts/spikes/config-race-bench.js +111 -0
  293. package/scripts/spikes/harness-capability-matrix.js +13 -0
  294. package/scripts/spikes/patch-anchor-stability-bench.js +125 -0
  295. package/scripts/spikes/protected-path-manifest.js +20 -0
  296. package/scripts/spikes/skill-auto-invoke-parity.js +292 -0
  297. package/scripts/sync-agent-skills.js +62 -0
  298. package/scripts/sync-utils.sh +3 -0
  299. package/scripts/test-ci-shard.js +13 -6
  300. package/scripts/test.js +95 -12
  301. package/skills/claim-safety/SKILL.md +102 -0
  302. package/skills/claim-safety/evals/evals.json +46 -0
  303. package/{.github/prompts/dev.prompt.md → skills/dev/SKILL.md} +44 -50
  304. package/skills/dev/evals/evals.json +50 -0
  305. package/skills/hermes-forge/SKILL.md +185 -0
  306. package/skills/hermes-forge/evals/evals.json +46 -0
  307. package/skills/issue-basics/SKILL.md +111 -0
  308. package/skills/issue-basics/evals/evals.json +46 -0
  309. package/skills/kernel/SKILL.md +166 -0
  310. package/skills/kernel/evals/evals.json +50 -0
  311. package/skills/memory/SKILL.md +102 -0
  312. package/skills/parallel-deep-research/SKILL.md +14 -11
  313. package/skills/parallel-deep-research/evals/evals.json +11 -27
  314. package/{.github/prompts/plan.prompt.md → skills/plan/SKILL.md} +132 -157
  315. package/skills/plan/evals/evals.json +42 -0
  316. package/skills/research/SKILL.md +195 -0
  317. package/skills/research/evals/evals.json +42 -0
  318. package/{.github/prompts/review.prompt.md → skills/review/SKILL.md} +98 -62
  319. package/skills/review/evals/evals.json +42 -0
  320. package/skills/rollback/SKILL.md +110 -0
  321. package/skills/rollback/evals/evals.json +46 -0
  322. package/skills/rollback/references/methods.md +204 -0
  323. package/{.cursor/commands/rollback.md → skills/rollback/references/workflow-integration.md} +10 -284
  324. package/skills/shepherd/SKILL.md +66 -0
  325. package/skills/shepherd/evals/evals.json +42 -0
  326. package/{.github/prompts/ship.prompt.md → skills/ship/SKILL.md} +81 -45
  327. package/skills/ship/evals/evals.json +42 -0
  328. package/skills/smith/SKILL.md +142 -0
  329. package/skills/smith/evals/evals.json +46 -0
  330. package/skills/smith/references/autonomy-and-gates.md +94 -0
  331. package/{.github/prompts/sonarcloud.prompt.md → skills/sonarcloud/SKILL.md} +14 -3
  332. package/skills/sonarcloud/evals/evals.json +46 -0
  333. package/skills/sonarcloud-analysis/SKILL.md +18 -13
  334. package/skills/sonarcloud-analysis/evals/evals.json +11 -15
  335. package/{.github/prompts/status.prompt.md → skills/status/SKILL.md} +20 -10
  336. package/skills/status/evals/evals.json +50 -0
  337. package/skills/triage-ready/SKILL.md +121 -0
  338. package/skills/triage-ready/evals/evals.json +42 -0
  339. package/{.github/prompts/validate.prompt.md → skills/validate/SKILL.md} +52 -29
  340. package/skills/validate/evals/evals.json +42 -0
  341. package/skills/verify/SKILL.md +299 -0
  342. package/skills/verify/evals/evals.json +50 -0
  343. package/.claude/commands/dev.md +0 -345
  344. package/.claude/commands/plan.md +0 -566
  345. package/.claude/commands/premerge.md +0 -186
  346. package/.claude/commands/research.md +0 -42
  347. package/.claude/commands/review.md +0 -451
  348. package/.claude/commands/rollback.md +0 -721
  349. package/.claude/commands/ship.md +0 -213
  350. package/.claude/commands/sonarcloud.md +0 -152
  351. package/.claude/commands/status.md +0 -90
  352. package/.claude/commands/validate.md +0 -288
  353. package/.claude/commands/verify.md +0 -269
  354. package/.claude/rules/workflow.md +0 -121
  355. package/.cline/workflows/dev.md +0 -342
  356. package/.cline/workflows/plan.md +0 -563
  357. package/.cline/workflows/premerge.md +0 -183
  358. package/.cline/workflows/research.md +0 -39
  359. package/.cline/workflows/review.md +0 -448
  360. package/.cline/workflows/rollback.md +0 -718
  361. package/.cline/workflows/ship.md +0 -210
  362. package/.cline/workflows/sonarcloud.md +0 -146
  363. package/.cline/workflows/status.md +0 -87
  364. package/.cline/workflows/validate.md +0 -285
  365. package/.cline/workflows/verify.md +0 -266
  366. package/.codex/config.toml +0 -11
  367. package/.codex/skills/dev/SKILL.md +0 -345
  368. package/.codex/skills/plan/SKILL.md +0 -566
  369. package/.codex/skills/premerge/SKILL.md +0 -186
  370. package/.codex/skills/research/SKILL.md +0 -42
  371. package/.codex/skills/review/SKILL.md +0 -451
  372. package/.codex/skills/rollback/SKILL.md +0 -721
  373. package/.codex/skills/ship/SKILL.md +0 -213
  374. package/.codex/skills/sonarcloud/SKILL.md +0 -149
  375. package/.codex/skills/status/SKILL.md +0 -90
  376. package/.codex/skills/validate/SKILL.md +0 -288
  377. package/.codex/skills/verify/SKILL.md +0 -269
  378. package/.cursor/commands/dev.md +0 -342
  379. package/.cursor/commands/plan.md +0 -563
  380. package/.cursor/commands/premerge.md +0 -183
  381. package/.cursor/commands/research.md +0 -39
  382. package/.cursor/commands/review.md +0 -448
  383. package/.cursor/commands/ship.md +0 -210
  384. package/.cursor/commands/sonarcloud.md +0 -146
  385. package/.cursor/commands/status.md +0 -87
  386. package/.cursor/commands/validate.md +0 -285
  387. package/.cursor/commands/verify.md +0 -266
  388. package/.cursorrules +0 -149
  389. package/.github/prompts/premerge.prompt.md +0 -188
  390. package/.github/prompts/research.prompt.md +0 -44
  391. package/.github/prompts/rollback.prompt.md +0 -723
  392. package/.github/prompts/verify.prompt.md +0 -271
  393. package/.github/workflows/beads-to-github.yml +0 -89
  394. package/.github/workflows/github-to-beads.yml +0 -100
  395. package/.kilocode/workflows/dev.md +0 -346
  396. package/.kilocode/workflows/plan.md +0 -567
  397. package/.kilocode/workflows/premerge.md +0 -187
  398. package/.kilocode/workflows/research.md +0 -43
  399. package/.kilocode/workflows/review.md +0 -452
  400. package/.kilocode/workflows/rollback.md +0 -722
  401. package/.kilocode/workflows/ship.md +0 -214
  402. package/.kilocode/workflows/sonarcloud.md +0 -150
  403. package/.kilocode/workflows/status.md +0 -91
  404. package/.kilocode/workflows/validate.md +0 -289
  405. package/.kilocode/workflows/verify.md +0 -270
  406. package/.opencode/commands/dev.md +0 -345
  407. package/.opencode/commands/plan.md +0 -566
  408. package/.opencode/commands/premerge.md +0 -186
  409. package/.opencode/commands/research.md +0 -42
  410. package/.opencode/commands/review.md +0 -451
  411. package/.opencode/commands/rollback.md +0 -721
  412. package/.opencode/commands/ship.md +0 -213
  413. package/.opencode/commands/sonarcloud.md +0 -149
  414. package/.opencode/commands/status.md +0 -90
  415. package/.opencode/commands/validate.md +0 -288
  416. package/.opencode/commands/verify.md +0 -269
  417. package/.roo/commands/dev.md +0 -346
  418. package/.roo/commands/plan.md +0 -567
  419. package/.roo/commands/premerge.md +0 -187
  420. package/.roo/commands/research.md +0 -43
  421. package/.roo/commands/review.md +0 -452
  422. package/.roo/commands/rollback.md +0 -722
  423. package/.roo/commands/ship.md +0 -214
  424. package/.roo/commands/sonarcloud.md +0 -150
  425. package/.roo/commands/status.md +0 -91
  426. package/.roo/commands/validate.md +0 -289
  427. package/.roo/commands/verify.md +0 -270
  428. package/docs/BEADS_GITHUB_SYNC.md +0 -281
  429. package/docs/GREPTILE_SETUP.md +0 -400
  430. package/docs/MANUAL_REVIEW_GUIDE.md +0 -106
  431. package/docs/SETUP.md +0 -663
  432. package/docs/VALIDATION.md +0 -363
  433. package/lib/agents/cline.plugin.json +0 -29
  434. package/lib/agents/copilot.plugin.json +0 -24
  435. package/lib/agents/kilocode.plugin.json +0 -22
  436. package/lib/agents/opencode.plugin.json +0 -23
  437. package/lib/agents/roo.plugin.json +0 -30
  438. package/lib/beads-bootstrap.js +0 -225
  439. package/lib/beads-health-check.js +0 -188
  440. package/lib/commands/commands-reset.js +0 -147
  441. package/opencode.json +0 -67
  442. package/scripts/beads-context.test.js +0 -584
  443. package/scripts/github-beads-sync/comment.mjs +0 -64
  444. package/scripts/github-beads-sync/config.mjs +0 -148
  445. package/scripts/github-beads-sync/github-api.mjs +0 -131
  446. package/scripts/github-beads-sync/index.mjs +0 -356
  447. package/scripts/github-beads-sync/label-mapper.mjs +0 -54
  448. package/scripts/github-beads-sync/mapping.mjs +0 -132
  449. package/scripts/github-beads-sync/reverse-sync-cli.mjs +0 -31
  450. package/scripts/github-beads-sync/reverse-sync.mjs +0 -162
  451. package/scripts/github-beads-sync/run-bd.mjs +0 -161
  452. package/scripts/github-beads-sync/sanitize.mjs +0 -121
  453. package/scripts/github-beads-sync.config.json +0 -26
  454. package/scripts/sync-commands.js +0 -600
@@ -10,7 +10,7 @@ TEST_TMP=""
10
10
  setup() {
11
11
  mkdir -p /c/tmp/forge-team-integ
12
12
  TEST_TMP="$(mktemp -d /c/tmp/forge-team-integ/run.XXXXXX)"
13
- mkdir -p "$TEST_TMP/.beads" "$TEST_TMP/mock"
13
+ mkdir -p "$TEST_TMP/.forge" "$TEST_TMP/mock"
14
14
  export TEAM_MAP_ROOT="$TEST_TMP"
15
15
  }
16
16
 
@@ -18,7 +18,7 @@ teardown() {
18
18
  rm -rf "$TEST_TMP"
19
19
  unset TEAM_MAP_ROOT || true
20
20
  unset GH_CMD || true
21
- unset BD_CMD || true
21
+ unset FORGE_CMD || true
22
22
  }
23
23
 
24
24
  assert_exit_code() {
@@ -64,32 +64,25 @@ esac
64
64
  MOCK
65
65
  chmod +x "$TEST_TMP/mock/gh"
66
66
 
67
- cat > "$TEST_TMP/mock/bd" << 'MOCK'
67
+ cat > "$TEST_TMP/mock/forge" << 'MOCK'
68
68
  #!/usr/bin/env bash
69
69
  case "$*" in
70
- *"list --status=open,in_progress"*)
71
- echo "forge-t1 · Test Task 1"
72
- echo " forge-t2 · Test Task 2" ;;
73
- *"show forge-t1"*)
74
- echo "◐ forge-t1 · Test Task 1 [● P2 · IN_PROGRESS]"
75
- echo "Owner: testdev"
76
- echo "Updated: 2026-03-27T10:00:00Z" ;;
77
- *"show forge-t2"*)
78
- echo "○ forge-t2 · Test Task 2 [● P3 · OPEN]"
79
- echo "Owner: testdev"
80
- echo "Updated: 2026-03-27T09:00:00Z" ;;
70
+ *"issue list"*"--status=in_progress"*)
71
+ printf '{"data":{"issues":[{"id":"forge-t1","title":"Test Task 1","status":"in_progress","assignee":"testdev","updated_at":"2026-03-27T10:00:00Z","dependencies":[]}]}}\n' ;;
72
+ *"issue list"*"--status=open"*)
73
+ printf '{"data":{"issues":[{"id":"forge-t2","title":"Test Task 2","status":"open","assignee":"testdev","updated_at":"2026-03-27T09:00:00Z","dependencies":[]}]}}\n' ;;
81
74
  *) exit 0 ;;
82
75
  esac
83
76
  MOCK
84
- chmod +x "$TEST_TMP/mock/bd"
77
+ chmod +x "$TEST_TMP/mock/forge"
85
78
 
86
- export GH_CMD="$TEST_TMP/mock/gh" BD_CMD="$TEST_TMP/mock/bd"
79
+ export GH_CMD="$TEST_TMP/mock/gh" FORGE_CMD="$TEST_TMP/mock/forge"
87
80
 
88
81
  # Run identity auto-detect in subshell to avoid readonly clashes
89
82
  local id_rc
90
83
  bash -c '
91
84
  set -euo pipefail
92
- export GH_CMD="'"$TEST_TMP"'/mock/gh" BD_CMD="'"$TEST_TMP"'/mock/bd" TEAM_MAP_ROOT="'"$TEST_TMP"'"
85
+ export GH_CMD="'"$TEST_TMP"'/mock/gh" FORGE_CMD="'"$TEST_TMP"'/mock/forge" TEAM_MAP_ROOT="'"$TEST_TMP"'"
93
86
  source "'"$SCRIPT_DIR"'/lib/identity.sh"
94
87
  _GITHUB_USER_CACHE=""
95
88
  auto_detect_identity
@@ -98,7 +91,7 @@ MOCK
98
91
 
99
92
  # Check team map has entry
100
93
  local map_content
101
- map_content="$(cat "$TEST_TMP/.beads/team-map.jsonl" 2>/dev/null || echo "")"
94
+ map_content="$(cat "$TEST_TMP/.forge/team-map.jsonl" 2>/dev/null || echo "")"
102
95
  assert_contains "team map has testdev" "testdev" "$map_content"
103
96
 
104
97
  # Workload shows issues
@@ -125,26 +118,19 @@ esac
125
118
  MOCK
126
119
  chmod +x "$TEST_TMP/mock/gh"
127
120
 
128
- cat > "$TEST_TMP/mock/bd" << 'MOCK'
121
+ cat > "$TEST_TMP/mock/forge" << 'MOCK'
129
122
  #!/usr/bin/env bash
130
123
  case "$*" in
131
- *"list --status=open,in_progress"*)
132
- echo "forge-aa · Task A"
133
- echo " forge-bb · Task B" ;;
134
- *"show forge-aa"*)
135
- echo "◐ forge-aa · Task A [● P2 · IN_PROGRESS]"
136
- echo "Owner: dev-a"
137
- echo "Updated: 2026-03-27T10:00:00Z" ;;
138
- *"show forge-bb"*)
139
- echo "○ forge-bb · Task B [● P3 · OPEN]"
140
- echo "Owner: dev-b"
141
- echo "Updated: 2026-03-27T09:00:00Z" ;;
124
+ *"issue list"*"--status=in_progress"*)
125
+ printf '{"data":{"issues":[{"id":"forge-aa","title":"Task A","status":"in_progress","assignee":"dev-a","updated_at":"2026-03-27T10:00:00Z","dependencies":[]}]}}\n' ;;
126
+ *"issue list"*"--status=open"*)
127
+ printf '{"data":{"issues":[{"id":"forge-bb","title":"Task B","status":"open","assignee":"dev-b","updated_at":"2026-03-27T09:00:00Z","dependencies":[]}]}}\n' ;;
142
128
  *) exit 0 ;;
143
129
  esac
144
130
  MOCK
145
- chmod +x "$TEST_TMP/mock/bd"
131
+ chmod +x "$TEST_TMP/mock/forge"
146
132
 
147
- export GH_CMD="$TEST_TMP/mock/gh" BD_CMD="$TEST_TMP/mock/bd"
133
+ export GH_CMD="$TEST_TMP/mock/gh" FORGE_CMD="$TEST_TMP/mock/forge"
148
134
 
149
135
  local output rc
150
136
  output="$(bash "$FORGE_TEAM" workload 2>&1)" && rc=$? || rc=$?
@@ -173,23 +159,24 @@ esac
173
159
  MOCK
174
160
  chmod +x "$TEST_TMP/mock/gh"
175
161
 
176
- cat > "$TEST_TMP/mock/bd" << 'MOCK'
162
+ cat > "$TEST_TMP/mock/forge" << 'MOCK'
177
163
  #!/usr/bin/env bash
178
164
  case "$*" in
179
- *"show forge-claimed"*) echo "○ forge-claimed · Claimed [● P2 · OPEN] [github_issue:42]" ;;
165
+ *"issue show forge-claimed"*)
166
+ printf '{"data":{"issue":{"id":"forge-claimed","title":"Claimed","status":"open","labels":["github_issue:42"]}}}\n' ;;
180
167
  *) exit 0 ;;
181
168
  esac
182
169
  MOCK
183
- chmod +x "$TEST_TMP/mock/bd"
170
+ chmod +x "$TEST_TMP/mock/forge"
184
171
 
185
- export GH_CMD="$TEST_TMP/mock/gh" BD_CMD="$TEST_TMP/mock/bd"
172
+ export GH_CMD="$TEST_TMP/mock/gh" FORGE_CMD="$TEST_TMP/mock/forge"
186
173
 
187
174
  # Run in subshell to avoid readonly clashes from re-sourcing
188
175
  local output rc
189
176
  output="$(
190
177
  bash -c '
191
178
  set -euo pipefail
192
- export GH_CMD="'"$TEST_TMP"'/mock/gh" BD_CMD="'"$TEST_TMP"'/mock/bd" TEAM_MAP_ROOT="'"$TEST_TMP"'"
179
+ export GH_CMD="'"$TEST_TMP"'/mock/gh" FORGE_CMD="'"$TEST_TMP"'/mock/forge" TEAM_MAP_ROOT="'"$TEST_TMP"'"
193
180
  source "'"$SCRIPT_DIR"'/lib/claim.sh"
194
181
  _GITHUB_USER_CACHE=""
195
182
  pre_claim_check "forge-claimed" 2>&1
@@ -217,24 +204,22 @@ esac
217
204
  MOCK
218
205
  chmod +x "$TEST_TMP/mock/gh"
219
206
 
220
- cat > "$TEST_TMP/mock/bd" << 'MOCK'
207
+ cat > "$TEST_TMP/mock/forge" << 'MOCK'
221
208
  #!/usr/bin/env bash
222
209
  case "$*" in
223
- *"list --status=open,in_progress"*)
224
- echo "forge-orphan · Orphan Task" ;;
225
- *"show forge-orphan"*)
226
- echo "○ forge-orphan · Orphan Task [ P3 · OPEN]"
227
- echo "Owner: testdev"
228
- echo "Updated: 2026-03-27T10:00:00Z" ;;
210
+ *"issue list"*"--status=open"*)
211
+ printf '{"data":{"issues":[{"id":"forge-orphan","title":"Orphan Task","status":"open","assignee":"testdev","updated_at":"2026-03-27T10:00:00Z","labels":[],"dependencies":[]}]}}\n' ;;
212
+ *"issue list"*"--status=in_progress"*)
213
+ printf '{"data":{"issues":[]}}\n' ;;
229
214
  *) exit 0 ;;
230
215
  esac
231
216
  MOCK
232
- chmod +x "$TEST_TMP/mock/bd"
217
+ chmod +x "$TEST_TMP/mock/forge"
233
218
 
234
- export GH_CMD="$TEST_TMP/mock/gh" BD_CMD="$TEST_TMP/mock/bd"
219
+ export GH_CMD="$TEST_TMP/mock/gh" FORGE_CMD="$TEST_TMP/mock/forge"
235
220
 
236
221
  # Seed team map so identity check passes
237
- echo '{"github":"testdev","display_name":"testdev","updated_at":"2026-03-27T10:00:00Z","is_bot":false}' > "$TEST_TMP/.beads/team-map.jsonl"
222
+ echo '{"github":"testdev","display_name":"testdev","updated_at":"2026-03-27T10:00:00Z","is_bot":false}' > "$TEST_TMP/.forge/team-map.jsonl"
238
223
 
239
224
  local output rc
240
225
  output="$(bash "$FORGE_TEAM" verify 2>&1)" && rc=$? || rc=$?
@@ -261,19 +246,19 @@ esac
261
246
  MOCK
262
247
  chmod +x "$TEST_TMP/mock/gh"
263
248
 
264
- cat > "$TEST_TMP/mock/bd" << 'MOCK'
249
+ cat > "$TEST_TMP/mock/forge" << 'MOCK'
265
250
  #!/usr/bin/env bash
266
251
  case "$*" in
267
- *"list"*) echo "" ;;
252
+ *"issue list"*) printf '{"data":{"issues":[]}}\n' ;;
268
253
  *) exit 0 ;;
269
254
  esac
270
255
  MOCK
271
- chmod +x "$TEST_TMP/mock/bd"
256
+ chmod +x "$TEST_TMP/mock/forge"
272
257
 
273
- export GH_CMD="$TEST_TMP/mock/gh" BD_CMD="$TEST_TMP/mock/bd"
258
+ export GH_CMD="$TEST_TMP/mock/gh" FORGE_CMD="$TEST_TMP/mock/forge"
274
259
 
275
260
  # Seed team map so identity check passes
276
- echo '{"github":"testdev","display_name":"testdev","updated_at":"2026-03-27T10:00:00Z","is_bot":false}' > "$TEST_TMP/.beads/team-map.jsonl"
261
+ echo '{"github":"testdev","display_name":"testdev","updated_at":"2026-03-27T10:00:00Z","is_bot":false}' > "$TEST_TMP/.forge/team-map.jsonl"
277
262
 
278
263
  # No mapping file — all GitHub issues should be orphans
279
264
  local output rc
@@ -299,26 +284,19 @@ esac
299
284
  MOCK
300
285
  chmod +x "$TEST_TMP/mock/gh"
301
286
 
302
- cat > "$TEST_TMP/mock/bd" << 'MOCK'
287
+ cat > "$TEST_TMP/mock/forge" << 'MOCK'
303
288
  #!/usr/bin/env bash
304
289
  case "$*" in
305
- *"list --status=open,in_progress"*)
306
- echo "forge-bot1 · Bot Task"
307
- echo " forge-real · Real Task" ;;
308
- *"show forge-bot1"*)
309
- echo "○ forge-bot1 · Bot Task [● P4 · OPEN]"
310
- echo "Owner: dependabot[bot]"
311
- echo "Updated: 2026-03-27T10:00:00Z" ;;
312
- *"show forge-real"*)
313
- echo "◐ forge-real · Real Task [● P2 · IN_PROGRESS]"
314
- echo "Owner: testdev"
315
- echo "Updated: 2026-03-27T10:00:00Z" ;;
290
+ *"issue list"*"--status=in_progress"*)
291
+ printf '{"data":{"issues":[{"id":"forge-real","title":"Real Task","status":"in_progress","assignee":"testdev","updated_at":"2026-03-27T10:00:00Z","dependencies":[]}]}}\n' ;;
292
+ *"issue list"*"--status=open"*)
293
+ printf '{"data":{"issues":[{"id":"forge-bot1","title":"Bot Task","status":"open","assignee":"dependabot[bot]","updated_at":"2026-03-27T10:00:00Z","dependencies":[]}]}}\n' ;;
316
294
  *) exit 0 ;;
317
295
  esac
318
296
  MOCK
319
- chmod +x "$TEST_TMP/mock/bd"
297
+ chmod +x "$TEST_TMP/mock/forge"
320
298
 
321
- export GH_CMD="$TEST_TMP/mock/gh" BD_CMD="$TEST_TMP/mock/bd"
299
+ export GH_CMD="$TEST_TMP/mock/gh" FORGE_CMD="$TEST_TMP/mock/forge"
322
300
 
323
301
  local output rc
324
302
  output="$(bash "$FORGE_TEAM" workload 2>&1)" && rc=$? || rc=$?
@@ -29,43 +29,31 @@ exit 1
29
29
  MOCK
30
30
  chmod +x "$mock_dir/gh"
31
31
 
32
- cat > "$mock_dir/bd" << 'MOCK'
32
+ # Mock forge: `issue show --json` carries the github_issue:<n> association as a
33
+ # label; `issue update --label` records it. Args are logged for assertions.
34
+ cat > "$mock_dir/forge" << 'MOCK'
33
35
  #!/usr/bin/env bash
34
36
  echo "$*" >> "$LOG_FILE"
35
- case "$1" in
36
- show)
37
- if [[ "${3:-}" == "--json" ]]; then
38
- cat <<'JSON'
39
- {"id":"beads-001","github":{"number":42,"nodeId":"I_kwDOForge42","url":"https://github.com/test/repo/issues/42"},"shared":{"title":"Test Issue"}}
40
- JSON
41
- else
42
- echo "o $2 - Test Issue"
43
- echo "Title: Test Issue"
44
- fi
37
+ case "$1 $2" in
38
+ "issue show")
39
+ printf '{"data":{"issue":{"id":"beads-001","title":"Test Issue","labels":["github_issue:42"]}}}\n'
45
40
  ;;
46
- set-state) echo "State set" ;;
41
+ "issue update") echo "Updated" ;;
47
42
  esac
48
43
  MOCK
49
- chmod +x "$mock_dir/bd"
44
+ chmod +x "$mock_dir/forge"
50
45
 
51
- cat > "$mock_dir/bd-no-gh" << 'MOCK'
46
+ cat > "$mock_dir/forge-no-gh" << 'MOCK'
52
47
  #!/usr/bin/env bash
53
48
  echo "$*" >> "$LOG_FILE"
54
- case "$1" in
55
- show)
56
- if [[ "${3:-}" == "--json" ]]; then
57
- cat <<'JSON'
58
- {"id":"beads-999","shared":{"title":"Test Issue"}}
59
- JSON
60
- else
61
- echo "o $2 - Test Issue"
62
- echo "Title: Test Issue"
63
- fi
49
+ case "$1 $2" in
50
+ "issue show")
51
+ printf '{"data":{"issue":{"id":"beads-999","title":"Test Issue","labels":[]}}}\n'
64
52
  ;;
65
- set-state) echo "State set" ;;
53
+ "issue update") echo "Updated" ;;
66
54
  esac
67
55
  MOCK
68
- chmod +x "$mock_dir/bd-no-gh"
56
+ chmod +x "$mock_dir/forge-no-gh"
69
57
 
70
58
  cat > "$portable_bin/grep" << 'MOCK'
71
59
  #!/usr/bin/env bash
@@ -83,7 +71,7 @@ chmod +x "$portable_bin/grep"
83
71
 
84
72
  export LOG_FILE="$log_file"
85
73
  export GH_CMD="$mock_dir/gh"
86
- export BD_CMD="$mock_dir/bd"
74
+ export FORGE_CMD="$mock_dir/forge"
87
75
  export TEAM_MAP_ROOT="$TEST_TMP"
88
76
  mapping_file="$TEAM_MAP_ROOT/.github/beads-mapping.json"
89
77
 
@@ -145,8 +133,8 @@ log_contents="$(cat "$log_file")"
145
133
  assert_contains "gh issue create called" "issue create" "$log_contents"
146
134
  assert_contains "title includes Test Issue" "Test Issue" "$log_contents"
147
135
  assert_contains "body includes beads-001" "beads-001" "$log_contents"
148
- assert_contains "sync create writes legacy github_issue state" "github_issue=42" "$log_contents"
149
- assert_contains "sync create calls set-state for hook compatibility" "set-state" "$log_contents"
136
+ assert_contains "sync create writes github_issue label" "github_issue:42" "$log_contents"
137
+ assert_contains "sync create calls issue update for the label" "issue update" "$log_contents"
150
138
  assert_contains "sync create persists mapping entry" '"42": "beads-001"' "$(cat "$mapping_file")"
151
139
 
152
140
  echo
@@ -211,10 +199,10 @@ cat > "$mapping_file" << 'JSON'
211
199
  "77": "beads-999"
212
200
  }
213
201
  JSON
214
- export BD_CMD="$mock_dir/bd-no-gh"
202
+ export FORGE_CMD="$mock_dir/forge-no-gh"
215
203
  result="$(_get_github_issue_number "beads-999")"
216
204
  assert_eq "mapping fallback returns issue number 77" "77" "$result"
217
- export BD_CMD="$mock_dir/bd"
205
+ export FORGE_CMD="$mock_dir/forge"
218
206
 
219
207
  echo
220
208
  echo "== Test 8: Mapping fallback returns newest issue number =="
@@ -225,69 +213,54 @@ cat > "$mapping_file" << 'JSON'
225
213
  "88": "beads-other"
226
214
  }
227
215
  JSON
228
- export BD_CMD="$mock_dir/bd-no-gh"
216
+ export FORGE_CMD="$mock_dir/forge-no-gh"
229
217
  result="$(_get_github_issue_number "beads-999")"
230
218
  assert_eq "mapping fallback returns newest matching issue number" "91" "$result"
231
- export BD_CMD="$mock_dir/bd"
219
+ export FORGE_CMD="$mock_dir/forge"
232
220
 
233
221
  echo
234
222
  echo "== Test 9: Missing canonical GitHub number =="
235
223
  rm -f "$mapping_file"
236
- export BD_CMD="$mock_dir/bd-no-gh"
224
+ export FORGE_CMD="$mock_dir/forge-no-gh"
237
225
  rc=0
238
226
  result="$(_get_github_issue_number "beads-999" 2>/dev/null)" || rc=$?
239
227
  assert_exit "returns error when no canonical github number" 1 "$rc"
240
- export BD_CMD="$mock_dir/bd"
228
+ export FORGE_CMD="$mock_dir/forge"
241
229
 
242
230
  echo
243
- echo "== Test 10: Legacy github_issue state fallback =="
244
- cat > "$mock_dir/bd-legacy" << 'MOCK'
231
+ echo "== Test 10: github_issue label lookup =="
232
+ cat > "$mock_dir/forge-legacy" << 'MOCK'
245
233
  #!/usr/bin/env bash
246
234
  echo "$*" >> "$LOG_FILE"
247
- case "$1" in
248
- show)
249
- if [[ "${3:-}" == "--json" ]]; then
250
- cat <<'JSON'
251
- {"id":"beads-legacy","github_issue":43,"shared":{"title":"Legacy Issue"}}
252
- JSON
253
- else
254
- echo "o $2 - Legacy Issue"
255
- echo "github_issue:43"
256
- echo "Title: Legacy Issue"
257
- fi
235
+ case "$1 $2" in
236
+ "issue show")
237
+ printf '{"data":{"issue":{"id":"beads-legacy","title":"Legacy Issue","labels":["github_issue:43"]}}}\n'
258
238
  ;;
259
- set-state) echo "State set" ;;
239
+ "issue update") echo "Updated" ;;
260
240
  esac
261
241
  MOCK
262
- chmod +x "$mock_dir/bd-legacy"
263
- export BD_CMD="$mock_dir/bd-legacy"
242
+ chmod +x "$mock_dir/forge-legacy"
243
+ export FORGE_CMD="$mock_dir/forge-legacy"
264
244
  rc=0
265
245
  result="$(_get_github_issue_number "beads-legacy" 2>/dev/null)" || rc=$?
266
246
  assert_exit "legacy github_issue exits successfully" 0 "$rc"
267
247
  assert_eq "legacy github_issue returns number" "43" "$result"
268
- export BD_CMD="$mock_dir/bd"
248
+ export FORGE_CMD="$mock_dir/forge"
269
249
 
270
250
  echo
271
251
  echo "== Test 11: Injection in title sanitized =="
272
- cat > "$mock_dir/bd-inject" << 'MOCK'
252
+ cat > "$mock_dir/forge-inject" << 'MOCK'
273
253
  #!/usr/bin/env bash
274
254
  echo "$*" >> "$LOG_FILE"
275
- case "$1" in
276
- show)
277
- if [[ "${3:-}" == "--json" ]]; then
278
- cat <<'JSON'
279
- {"id":"beads-inject","github":{"number":99,"url":"https://github.com/test/repo/issues/99"},"shared":{"title":"Evil $(rm -rf /) Issue"}}
280
- JSON
281
- else
282
- echo 'o beads-inject - Evil $(rm -rf /) Issue'
283
- echo 'Title: Evil $(rm -rf /) Issue'
284
- fi
255
+ case "$1 $2" in
256
+ "issue show")
257
+ printf '{"data":{"issue":{"id":"beads-inject","title":"Evil $(rm -rf /) Issue","labels":["github_issue:99"]}}}\n'
285
258
  ;;
286
- set-state) echo "State set" ;;
259
+ "issue update") echo "Updated" ;;
287
260
  esac
288
261
  MOCK
289
- chmod +x "$mock_dir/bd-inject"
290
- export BD_CMD="$mock_dir/bd-inject"
262
+ chmod +x "$mock_dir/forge-inject"
263
+ export FORGE_CMD="$mock_dir/forge-inject"
291
264
  > "$log_file"
292
265
  rc=0
293
266
  sync_issue_create "beads-inject" || rc=$?
@@ -300,7 +273,7 @@ else
300
273
  PASS=$((PASS + 1))
301
274
  echo " PASS: injection sanitized - no \$\(rm in gh call"
302
275
  fi
303
- export BD_CMD="$mock_dir/bd"
276
+ export FORGE_CMD="$mock_dir/forge"
304
277
 
305
278
  echo
306
279
  echo "== Test 11: sync_issue_create without grep -P =="
@@ -314,32 +287,26 @@ assert_contains "gh issue create called without PCRE grep" "issue create" "$log_
314
287
  export PATH="$ORIGINAL_PATH"
315
288
 
316
289
  echo
317
- echo "== Test 12: sync_issue_create with summary-only bd show =="
318
- cat > "$mock_dir/bd-summary-only" << 'MOCK'
290
+ echo "== Test 12: sync_issue_create reads title from issue show JSON =="
291
+ cat > "$mock_dir/forge-summary-only" << 'MOCK'
319
292
  #!/usr/bin/env bash
320
293
  echo "$*" >> "$LOG_FILE"
321
- case "$1" in
322
- show)
323
- if [[ "${3:-}" == "--json" ]]; then
324
- cat <<'JSON'
325
- {"id":"beads-summary","github":{"number":77,"url":"https://github.com/test/repo/issues/77"},"shared":{"title":"Summary Only Title"}}
326
- JSON
327
- else
328
- echo "o $2 - Summary Only Title"
329
- fi
294
+ case "$1 $2" in
295
+ "issue show")
296
+ printf '{"data":{"issue":{"id":"beads-summary","title":"Summary Only Title","labels":["github_issue:77"]}}}\n'
330
297
  ;;
331
- set-state) echo "State set" ;;
298
+ "issue update") echo "Updated" ;;
332
299
  esac
333
300
  MOCK
334
- chmod +x "$mock_dir/bd-summary-only"
335
- export BD_CMD="$mock_dir/bd-summary-only"
301
+ chmod +x "$mock_dir/forge-summary-only"
302
+ export FORGE_CMD="$mock_dir/forge-summary-only"
336
303
  > "$log_file"
337
304
  rc=0
338
305
  sync_issue_create "beads-summary" || rc=$?
339
- assert_exit "sync_issue_create works with summary-only bd show" 0 "$rc"
306
+ assert_exit "sync_issue_create works with title from issue show JSON" 0 "$rc"
340
307
  log_contents="$(cat "$log_file")"
341
308
  assert_contains "summary-only title is passed to gh issue create" "Summary Only Title" "$log_contents"
342
- export BD_CMD="$mock_dir/bd"
309
+ export FORGE_CMD="$mock_dir/forge"
343
310
 
344
311
  echo
345
312
  echo "Results: $PASS passed, $FAIL failed"
@@ -7,7 +7,7 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
7
7
  TEST_TMP="$(mktemp -d)"
8
8
  trap 'rm -rf "$TEST_TMP"' EXIT
9
9
 
10
- # Override TEAM_MAP_ROOT so tests don't touch real .beads/
10
+ # Override TEAM_MAP_ROOT so tests don't touch real .forge/
11
11
  export TEAM_MAP_ROOT="$TEST_TMP"
12
12
 
13
13
  # ── Create mock directories ────────────────────────────────────────────
@@ -66,47 +66,34 @@ exit 1
66
66
  MOCK
67
67
  chmod +x "$mock_dir/gh-noauth"
68
68
 
69
- # ── Mock bd ────────────────────────────────────────────────────────────
70
- cat > "$mock_dir/bd" << 'MOCK'
69
+ # ── Mock forge (emits Kernel-shaped issue list JSON) ───────────────────
70
+ # The GitHub association lives in each issue's labels as github_issue:<n>.
71
+ # Tests drive which issues appear via FORGE_MOCK_OPEN / FORGE_MOCK_INPROGRESS
72
+ # (JSON arrays, each defaulting to []).
73
+ cat > "$mock_dir/forge" << 'MOCK'
71
74
  #!/usr/bin/env bash
72
- case "$1" in
73
- list)
74
- if [[ -n "${BD_MOCK_OUTPUT:-}" ]]; then
75
- echo "$BD_MOCK_OUTPUT"
76
- fi
77
- exit 0
78
- ;;
79
- show)
80
- case "${2:-}" in
81
- forge-aaa)
82
- echo "◐ forge-aaa · Feature A [● P2 · IN_PROGRESS]"
83
- echo "Owner: devone"
84
- if [[ -z "${BD_MOCK_NO_GITHUB_AAA:-}" ]]; then
85
- echo "State: github_issue:10"
86
- fi
87
- ;;
88
- forge-bbb)
89
- echo "○ forge-bbb · Feature B [● P2 · OPEN]"
90
- echo "Owner: devtwo"
91
- if [[ -z "${BD_MOCK_NO_GITHUB_BBB:-}" ]]; then
92
- echo "State: github_issue:20"
93
- fi
94
- ;;
95
- forge-ccc)
96
- echo "◐ forge-ccc · Feature C [● P1 · IN_PROGRESS]"
97
- echo "Owner: devone"
98
- # forge-ccc never has github_issue (for orphan tests)
99
- ;;
100
- esac
101
- exit 0
102
- ;;
103
- esac
75
+ args="$*"
76
+ if [[ "$args" == *"issue list"* ]]; then
77
+ if [[ "$args" == *"--status=open"* ]]; then
78
+ printf '{"data":{"issues":%s}}\n' "${FORGE_MOCK_OPEN:-[]}"
79
+ elif [[ "$args" == *"--status=in_progress"* ]]; then
80
+ printf '{"data":{"issues":%s}}\n' "${FORGE_MOCK_INPROGRESS:-[]}"
81
+ else
82
+ printf '{"data":{"issues":[]}}\n'
83
+ fi
84
+ exit 0
85
+ fi
104
86
  exit 0
105
87
  MOCK
106
- chmod +x "$mock_dir/bd"
88
+ chmod +x "$mock_dir/forge"
89
+
90
+ # Reusable issue fixtures (synced issues carry a github_issue:<n> label)
91
+ ccc_orphan='{"id":"forge-ccc","title":"Feature C","status":"in_progress","assignee":"devone","labels":[],"dependencies":[]}'
92
+ aaa_synced='{"id":"forge-aaa","title":"Feature A","status":"in_progress","assignee":"devone","labels":["github_issue:10"],"dependencies":[]}'
93
+ bbb_synced='{"id":"forge-bbb","title":"Feature B","status":"open","assignee":"devtwo","labels":["github_issue:20"],"dependencies":[]}'
107
94
 
108
95
  export GH_CMD="$mock_dir/gh"
109
- export BD_CMD="$mock_dir/bd"
96
+ export FORGE_CMD="$mock_dir/forge"
110
97
 
111
98
  # Source the library under test
112
99
  source "$SCRIPT_DIR/lib/agent-prompt.sh"
@@ -158,11 +145,12 @@ echo "── Test 1: All clean → exit 0 ──"
158
145
  # Setup: identity exists in team map
159
146
  unset _GITHUB_USER_CACHE
160
147
  export GH_CMD="$mock_dir/gh"
161
- export BD_CMD="$mock_dir/bd"
148
+ export FORGE_CMD="$mock_dir/forge"
162
149
  team_map_add "testuser" "Test User"
163
150
 
164
- # No beads issues, no github issues
165
- export BD_MOCK_OUTPUT=""
151
+ # No tracked issues, no github issues
152
+ export FORGE_MOCK_OPEN="[]"
153
+ export FORGE_MOCK_INPROGRESS="[]"
166
154
  export GH_MOCK_ISSUES="[]"
167
155
 
168
156
  # Create empty mapping file
@@ -194,10 +182,11 @@ echo "── Test 3: Orphan Beads issue detected ──"
194
182
 
195
183
  unset _GITHUB_USER_CACHE
196
184
  export GH_CMD="$mock_dir/gh"
197
- export BD_MOCK_OUTPUT="◐ forge-ccc · Feature C"
185
+ export FORGE_MOCK_OPEN="[]"
186
+ export FORGE_MOCK_INPROGRESS="[$ccc_orphan]"
198
187
  export GH_MOCK_ISSUES="[]"
199
188
 
200
- # forge-ccc has no github_issue state (see mock bd above)
189
+ # forge-ccc carries no github_issue label (see fixtures above)
201
190
  rc=0
202
191
  output="$(cmd_verify 2>&1)" || rc=$?
203
192
  assert_exit "orphan beads exits 1" 1 "$rc"
@@ -210,7 +199,8 @@ echo "── Test 4: Orphan GitHub issue detected ──"
210
199
 
211
200
  unset _GITHUB_USER_CACHE
212
201
  export GH_CMD="$mock_dir/gh"
213
- export BD_MOCK_OUTPUT=""
202
+ export FORGE_MOCK_OPEN="[]"
203
+ export FORGE_MOCK_INPROGRESS="[]"
214
204
  export GH_MOCK_ISSUES='[{"number":42,"title":"Some feature"},{"number":45,"title":"Another feature"}]'
215
205
 
216
206
  # Mapping file has neither #42 nor #45
@@ -231,8 +221,8 @@ unset _GITHUB_USER_CACHE
231
221
  export GH_CMD="$mock_dir/gh"
232
222
 
233
223
  # Setup: forge-aaa has github_issue:10, forge-bbb has github_issue:20
234
- export BD_MOCK_OUTPUT="◐ forge-aaa · Feature A
235
- forge-bbb · Feature B"
224
+ export FORGE_MOCK_OPEN="[$bbb_synced]"
225
+ export FORGE_MOCK_INPROGRESS="[$aaa_synced]"
236
226
 
237
227
  # Create mapping with both issues
238
228
  cat > "$TEST_TMP/.github/beads-mapping.json" << 'EOF'
@@ -300,7 +290,8 @@ echo "── Test 6: No issues at all → exit 0 ──"
300
290
 
301
291
  unset _GITHUB_USER_CACHE
302
292
  export GH_CMD="$mock_dir/gh"
303
- export BD_MOCK_OUTPUT=""
293
+ export FORGE_MOCK_OPEN="[]"
294
+ export FORGE_MOCK_INPROGRESS="[]"
304
295
  export GH_MOCK_ISSUES="[]"
305
296
  echo '{}' > "$TEST_TMP/.github/beads-mapping.json"
306
297
 
@@ -31,11 +31,11 @@ assert_contains_file "ship calls sync" "forge-team.*sync" "$SHIP"
31
31
  assert_contains_file "ship calls verify" "forge-team.*verify" "$SHIP"
32
32
 
33
33
  echo ""
34
- echo "── Sync check ──"
35
- if node "$SCRIPT_DIR/scripts/sync-commands.js" --check 2>&1 | grep -qi 'error\|drift\|mismatch'; then
36
- FAIL=$((FAIL + 1)); echo " FAIL: sync drift detected"
34
+ echo "── Skill sync check ──"
35
+ if (cd "$SCRIPT_DIR" && node -e "const r=require('./lib/skills-sync').checkSkillsSync({repoRoot:process.cwd()}); process.exit(r.inSync?0:1)"); then
36
+ PASS=$((PASS + 1)); echo " PASS: all agent skill dirs in sync"
37
37
  else
38
- PASS=$((PASS + 1)); echo " PASS: all agent dirs in sync"
38
+ FAIL=$((FAIL + 1)); echo " FAIL: skill drift detected"
39
39
  fi
40
40
 
41
41
  echo ""