forge-workflow 0.0.10 → 0.1.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (454) hide show
  1. package/.claude/rules/{greptile-review-process.md → review-process.md} +56 -41
  2. package/.claude/scripts/{greptile-resolve.sh → review-resolve.sh} +13 -3
  3. package/.cursor/rules/permissions-guidance.mdc +2 -2
  4. package/.forge/hooks/check-tdd.js +3 -0
  5. package/.forge/hooks/forge-native-hook.js +245 -0
  6. package/.forge/protected-paths.yaml +157 -0
  7. package/AGENTS.md +150 -61
  8. package/CHANGELOG.md +681 -0
  9. package/CLAUDE.md +9 -118
  10. package/QUICKSTART.md +171 -0
  11. package/README.md +271 -363
  12. package/bin/forge-cmd.js +120 -9
  13. package/bin/forge-preflight.js +26 -5
  14. package/bin/forge.js +461 -489
  15. package/docs/INDEX.md +93 -0
  16. package/docs/PROJECT_DESIGN.md +685 -0
  17. package/docs/architecture/index.md +66 -0
  18. package/docs/architecture/notes/README.md +35 -0
  19. package/docs/architecture/subsystems/README.md +46 -0
  20. package/docs/forge/TOOLCHAIN.md +670 -0
  21. package/docs/forge/VALIDATION.md +82 -0
  22. package/docs/{AGENT_INSTALL_PROMPT.md → guides/AGENT_INSTALL_PROMPT.md} +3 -3
  23. package/docs/guides/BEADS_GITHUB_SYNC.md +32 -0
  24. package/docs/{ENHANCED_ONBOARDING.md → guides/ENHANCED_ONBOARDING.md} +16 -12
  25. package/docs/guides/GREPTILE_SETUP.md +46 -0
  26. package/docs/guides/MANUAL_REVIEW_GUIDE.md +58 -0
  27. package/docs/guides/MIGRATION.md +56 -0
  28. package/docs/guides/SETUP.md +118 -0
  29. package/docs/guides/SUPPORT.md +185 -0
  30. package/docs/guides/WORKFLOW_TEMPLATES.md +74 -0
  31. package/docs/guides/memory-backends.md +183 -0
  32. package/docs/reference/ADAPTERS.md +128 -0
  33. package/docs/reference/AGENT_SKILL_PARITY.md +175 -0
  34. package/docs/reference/COMMANDS.md +205 -0
  35. package/docs/reference/DECISION_DRIFT_GUARDS.md +97 -0
  36. package/docs/{EXAMPLES.md → reference/EXAMPLES.md} +7 -5
  37. package/docs/reference/FORGE_KERNEL_STORAGE_MODEL.md +135 -0
  38. package/docs/reference/HERMES_INTEGRATION.md +118 -0
  39. package/docs/reference/INSIGHTS_RECAP.md +63 -0
  40. package/docs/reference/INSTALL.md +164 -0
  41. package/docs/reference/KERNEL_TAXONOMY_VALIDATION.md +161 -0
  42. package/docs/reference/PROTECTED_PATH_MANIFEST.md +25 -0
  43. package/docs/reference/RELEASE.md +68 -0
  44. package/docs/reference/RESEARCH_TEMPLATE.md +292 -0
  45. package/docs/{ROADMAP.md → reference/ROADMAP.md} +12 -9
  46. package/docs/reference/SKILLS.md +35 -0
  47. package/docs/reference/STATUS_BOARD.md +80 -0
  48. package/docs/reference/TEMPLATES.md +106 -0
  49. package/docs/{TOOLCHAIN.md → reference/TOOLCHAIN.md} +62 -47
  50. package/docs/reference/VALIDATION.md +82 -0
  51. package/docs/reference/agent-permissions.md +169 -0
  52. package/docs/reference/beads-to-kernel-migration-ux.md +61 -0
  53. package/docs/reference/control-plane-guarantees.md +125 -0
  54. package/docs/reference/dependency-chain.md +331 -0
  55. package/docs/reference/forge-kernel-issue-command-contract.md +161 -0
  56. package/docs/reference/forge-kernel-schema.md +72 -0
  57. package/docs/reference/kernel-conflict-evaluators.md +27 -0
  58. package/docs/reference/patch-md-format.md +77 -0
  59. package/docs/reference/protected-state-surfaces.md +59 -0
  60. package/docs/reference/shepherd.md +115 -0
  61. package/docs/reference/superpowers-analysis.md +320 -0
  62. package/docs/reference/superpowers-integration-options.md +404 -0
  63. package/docs/reference/test-environment.md +519 -0
  64. package/docs/reference/upgrade-safety.md +59 -0
  65. package/lefthook.yml +18 -0
  66. package/lib/adapter-cli.js +307 -0
  67. package/lib/adapters/beads-issue-adapter.js +127 -0
  68. package/lib/adapters/beads-kernel-compat.js +1042 -0
  69. package/lib/adapters/greptile-review-adapter.js +141 -0
  70. package/lib/adapters/kernel-issue-adapter.js +101 -0
  71. package/lib/adapters/pr-state-adapter.js +484 -0
  72. package/lib/adoption-profiles.js +126 -0
  73. package/lib/agents/README.md +2 -6
  74. package/lib/agents/claude.plugin.json +3 -8
  75. package/lib/agents/codex.plugin.json +9 -1
  76. package/lib/agents/cursor.plugin.json +2 -6
  77. package/lib/agents/hermes.plugin.json +22 -0
  78. package/lib/agents-config.js +39 -1236
  79. package/lib/audit-evidence.js +282 -0
  80. package/lib/beads-setup.js +121 -0
  81. package/lib/beads-sync-scaffold.js +25 -101
  82. package/lib/codex-skills.js +51 -1
  83. package/lib/commands/_issue.js +741 -77
  84. package/lib/commands/_manifest.js +91 -0
  85. package/lib/commands/_registry.js +85 -34
  86. package/lib/commands/_resolve-command-opts.js +261 -0
  87. package/lib/commands/_serve-security.js +270 -0
  88. package/lib/commands/adapter.js +12 -0
  89. package/lib/commands/add.js +118 -0
  90. package/lib/commands/audit.js +70 -0
  91. package/lib/commands/blocked.js +5 -0
  92. package/lib/commands/board.js +64 -0
  93. package/lib/commands/claim.js +21 -2
  94. package/lib/commands/claims.js +7 -0
  95. package/lib/commands/clean.js +485 -75
  96. package/lib/commands/close.js +2 -2
  97. package/lib/commands/comment.js +5 -0
  98. package/lib/commands/control.js +148 -0
  99. package/lib/commands/create.js +2 -2
  100. package/lib/commands/dev.js +185 -7
  101. package/lib/commands/doc-gate.js +336 -0
  102. package/lib/commands/doctor.js +156 -0
  103. package/lib/commands/explain.js +15 -0
  104. package/lib/commands/export.js +237 -0
  105. package/lib/commands/gate.js +192 -0
  106. package/lib/commands/hooks.js +242 -0
  107. package/lib/commands/inbox.js +118 -0
  108. package/lib/commands/init.js +598 -0
  109. package/lib/commands/insights.js +79 -0
  110. package/lib/commands/issue.js +12 -1
  111. package/lib/commands/issues.js +17 -0
  112. package/lib/commands/lint.js +5 -0
  113. package/lib/commands/list.js +2 -2
  114. package/lib/commands/merge.js +312 -0
  115. package/lib/commands/migrate.js +523 -0
  116. package/lib/commands/new.js +12 -0
  117. package/lib/commands/options.js +241 -0
  118. package/lib/commands/orient.js +13 -0
  119. package/lib/commands/orphans.js +5 -0
  120. package/lib/commands/patch.js +67 -0
  121. package/lib/commands/plan.js +436 -24
  122. package/lib/commands/preflight.js +211 -0
  123. package/lib/commands/prime.js +13 -0
  124. package/lib/commands/push.js +69 -2
  125. package/lib/commands/ready.js +2 -2
  126. package/lib/commands/recall.js +116 -0
  127. package/lib/commands/recap.js +61 -0
  128. package/lib/commands/recommend.js +0 -1
  129. package/lib/commands/release.js +91 -0
  130. package/lib/commands/remember.js +74 -0
  131. package/lib/commands/role.js +99 -0
  132. package/lib/commands/serve.js +581 -0
  133. package/lib/commands/setup.js +838 -972
  134. package/lib/commands/shepherd.js +436 -0
  135. package/lib/commands/ship.js +23 -1
  136. package/lib/commands/show.js +2 -2
  137. package/lib/commands/stage.js +192 -0
  138. package/lib/commands/stale.js +5 -0
  139. package/lib/commands/status.js +158 -21
  140. package/lib/commands/sync.js +34 -46
  141. package/lib/commands/team.js +4 -1
  142. package/lib/commands/test.js +43 -27
  143. package/lib/commands/update.js +2 -2
  144. package/lib/commands/upgrade.js +47 -0
  145. package/lib/commands/validate.js +43 -18
  146. package/lib/commands/worktree.js +307 -100
  147. package/lib/config-writer.js +202 -0
  148. package/lib/control-plane.js +236 -0
  149. package/lib/core/runtime-graph.js +946 -0
  150. package/lib/dep-guard/keyword-ripple.js +2 -2
  151. package/lib/deprecated-sync-cleanup.js +362 -0
  152. package/lib/detect-agent.js +2 -28
  153. package/lib/detect-worktree.js +35 -9
  154. package/lib/doc-gate/declaration.js +177 -0
  155. package/lib/doc-gate/detect.js +289 -0
  156. package/lib/doc-gate/gate.js +375 -0
  157. package/lib/doc-gate/okf-config.js +128 -0
  158. package/lib/doc-gate/okf.js +429 -0
  159. package/lib/docs-command.js +1161 -6
  160. package/lib/forge-issues.js +382 -11
  161. package/lib/forge-lock.js +262 -0
  162. package/lib/gate-events.js +193 -0
  163. package/lib/global-flags.js +74 -0
  164. package/lib/greptile-match.js +7 -63
  165. package/lib/harness-capability-matrix.js +380 -0
  166. package/lib/hook-global-installer.js +347 -0
  167. package/lib/hook-renderer.js +451 -0
  168. package/lib/inbox.js +391 -0
  169. package/lib/insights.js +397 -0
  170. package/lib/issue-adapter.js +156 -0
  171. package/lib/issue-backend.js +145 -0
  172. package/lib/issue-render.js +220 -0
  173. package/lib/kernel/backing-issue.js +305 -0
  174. package/lib/kernel/broker.js +1218 -0
  175. package/lib/kernel/cli-broker-factory.js +130 -0
  176. package/lib/kernel/conflict-signal.js +82 -0
  177. package/lib/kernel/evaluators.js +195 -0
  178. package/lib/kernel/fs-class.js +495 -0
  179. package/lib/kernel/issue-command-contract.js +559 -0
  180. package/lib/kernel/issue-id-resolver.js +186 -0
  181. package/lib/kernel/lease-enforcer.js +158 -0
  182. package/lib/kernel/migrations.js +333 -0
  183. package/lib/kernel/planning-buckets-schema.js +109 -0
  184. package/lib/kernel/projection-jsonl-writer.js +450 -0
  185. package/lib/kernel/readiness-model.js +329 -0
  186. package/lib/kernel/schema.js +356 -0
  187. package/lib/kernel/sqlite-driver.js +2504 -0
  188. package/lib/kernel/taxonomy-validator.js +394 -0
  189. package/lib/lefthook-check.js +3 -2
  190. package/lib/lefthook-wiring.js +413 -0
  191. package/lib/mcp-config-renderer.js +288 -0
  192. package/lib/memory/graphiti-mcp.js +106 -0
  193. package/lib/memory/router.js +387 -0
  194. package/lib/memory/typed-api.js +102 -0
  195. package/lib/memory-digest.js +195 -0
  196. package/lib/merge-rules.js +395 -0
  197. package/lib/migrate-dry-run.js +466 -0
  198. package/lib/orientation.js +863 -0
  199. package/lib/package-manager-remediation.js +103 -0
  200. package/lib/package-root.js +381 -0
  201. package/lib/patch-intent.js +890 -0
  202. package/lib/plugin-catalog.js +3 -4
  203. package/lib/plugin-manager.js +0 -5
  204. package/lib/pr-bundle.js +186 -0
  205. package/lib/pr-monitor/differ.js +195 -0
  206. package/lib/pr-monitor/events.js +0 -0
  207. package/lib/pr-monitor/gather.js +124 -0
  208. package/lib/pr-monitor/journal.js +299 -0
  209. package/lib/pr-monitor/monitor.js +146 -0
  210. package/lib/pr-monitor/render-sticky.js +157 -0
  211. package/lib/pr-monitor/watch-lifecycle.js +95 -0
  212. package/lib/pr-monitor/watch.js +247 -0
  213. package/lib/pr-pull.js +1273 -0
  214. package/lib/pr-shepherd.js +494 -0
  215. package/lib/pr-state-validator.js +59 -0
  216. package/lib/preflight/gates.js +237 -0
  217. package/lib/preflight/runner.js +116 -0
  218. package/lib/project-discovery.js +0 -53
  219. package/lib/project-memory.js +99 -497
  220. package/lib/protected-path-manifest.js +281 -0
  221. package/lib/protected-state-surfaces.js +387 -0
  222. package/lib/release-readiness.js +2089 -0
  223. package/lib/reset.js +59 -45
  224. package/lib/review-adapter.js +68 -0
  225. package/lib/rules-sync.js +260 -0
  226. package/lib/runtime-health.js +241 -20
  227. package/lib/safety-config-renderer.js +268 -0
  228. package/lib/setup-action-log.js +1 -7
  229. package/lib/setup.js +27 -65
  230. package/lib/shell-utils.js +76 -6
  231. package/lib/skills-sync.js +330 -0
  232. package/lib/smart-status/scoring.js +17 -3
  233. package/lib/status/beads-snapshot.js +45 -2
  234. package/lib/status/presenter.js +169 -18
  235. package/lib/status/snapshot.js +186 -0
  236. package/lib/sync-backend.js +202 -0
  237. package/lib/untrusted-content.js +52 -0
  238. package/lib/upgrade-safety.js +199 -0
  239. package/lib/workflow/enforce-stage.js +296 -47
  240. package/lib/workflow/stage-transition.js +115 -0
  241. package/lib/workflow/stages.js +30 -6
  242. package/lib/workflow/state-manager.js +11 -22
  243. package/lib/workflow/state.js +23 -1
  244. package/lib/workflow-profiles.js +17 -5
  245. package/package.json +37 -35
  246. package/rules/documentation.md +19 -0
  247. package/rules/kernel-tracking.md +26 -0
  248. package/rules/security.md +22 -0
  249. package/rules/tdd.md +20 -0
  250. package/rules/workflow.md +27 -0
  251. package/scripts/auto-backing-issue.js +47 -0
  252. package/scripts/beads-context.sh +81 -57
  253. package/scripts/beads-upgrade-smoke.sh +24 -3
  254. package/scripts/bootstrap-windows-tools.sh +78 -0
  255. package/scripts/branch-protection.js +2 -3
  256. package/scripts/check-agents.js +34 -137
  257. package/scripts/commitlint.js +3 -1
  258. package/scripts/conflict-detect.sh +3 -0
  259. package/scripts/dep-guard.sh +22 -3
  260. package/scripts/file-index.sh +3 -0
  261. package/scripts/forge-team/lib/claim.sh +34 -18
  262. package/scripts/forge-team/lib/dashboard.sh +61 -86
  263. package/scripts/forge-team/lib/epic.sh +99 -263
  264. package/scripts/forge-team/lib/hooks.sh +26 -28
  265. package/scripts/forge-team/lib/identity.sh +4 -4
  266. package/scripts/forge-team/lib/sync-github.sh +49 -84
  267. package/scripts/forge-team/lib/verify.sh +93 -83
  268. package/scripts/forge-team/lib/workload.sh +41 -65
  269. package/scripts/forge-team/tests/claim.test.sh +25 -19
  270. package/scripts/forge-team/tests/dashboard.test.sh +31 -46
  271. package/scripts/forge-team/tests/epic.test.sh +52 -71
  272. package/scripts/forge-team/tests/hooks.test.sh +38 -50
  273. package/scripts/forge-team/tests/identity.test.sh +3 -3
  274. package/scripts/forge-team/tests/integration.test.sh +44 -66
  275. package/scripts/forge-team/tests/sync-github.test.sh +50 -83
  276. package/scripts/forge-team/tests/verify.test.sh +37 -46
  277. package/scripts/forge-team/tests/workflow-integration.test.sh +4 -4
  278. package/scripts/forge-team/tests/workload.test.sh +32 -66
  279. package/scripts/gen-command-manifest.js +153 -0
  280. package/scripts/gen-embedded-assets.mjs +129 -0
  281. package/scripts/install.ps1 +139 -0
  282. package/scripts/install.sh +268 -0
  283. package/scripts/lib/release-asset.mjs +84 -0
  284. package/scripts/parity-check.mjs +145 -0
  285. package/scripts/parity-check.test.mjs +58 -0
  286. package/scripts/pin-agentic-workflow-images.js +112 -0
  287. package/scripts/pr-coordinator.sh +3 -0
  288. package/scripts/preflight-sonar.eslint.config.mjs +44 -0
  289. package/scripts/preflight.sh +21 -94
  290. package/scripts/protected-state-check.js +104 -0
  291. package/scripts/smart-status.sh +60 -57
  292. package/scripts/spikes/config-race-bench.js +111 -0
  293. package/scripts/spikes/harness-capability-matrix.js +13 -0
  294. package/scripts/spikes/patch-anchor-stability-bench.js +125 -0
  295. package/scripts/spikes/protected-path-manifest.js +20 -0
  296. package/scripts/spikes/skill-auto-invoke-parity.js +292 -0
  297. package/scripts/sync-agent-skills.js +62 -0
  298. package/scripts/sync-utils.sh +3 -0
  299. package/scripts/test-ci-shard.js +13 -6
  300. package/scripts/test.js +95 -12
  301. package/skills/claim-safety/SKILL.md +102 -0
  302. package/skills/claim-safety/evals/evals.json +46 -0
  303. package/{.github/prompts/dev.prompt.md → skills/dev/SKILL.md} +44 -50
  304. package/skills/dev/evals/evals.json +50 -0
  305. package/skills/hermes-forge/SKILL.md +185 -0
  306. package/skills/hermes-forge/evals/evals.json +46 -0
  307. package/skills/issue-basics/SKILL.md +111 -0
  308. package/skills/issue-basics/evals/evals.json +46 -0
  309. package/skills/kernel/SKILL.md +166 -0
  310. package/skills/kernel/evals/evals.json +50 -0
  311. package/skills/memory/SKILL.md +102 -0
  312. package/skills/parallel-deep-research/SKILL.md +14 -11
  313. package/skills/parallel-deep-research/evals/evals.json +11 -27
  314. package/{.github/prompts/plan.prompt.md → skills/plan/SKILL.md} +132 -157
  315. package/skills/plan/evals/evals.json +42 -0
  316. package/skills/research/SKILL.md +195 -0
  317. package/skills/research/evals/evals.json +42 -0
  318. package/{.github/prompts/review.prompt.md → skills/review/SKILL.md} +98 -62
  319. package/skills/review/evals/evals.json +42 -0
  320. package/skills/rollback/SKILL.md +110 -0
  321. package/skills/rollback/evals/evals.json +46 -0
  322. package/skills/rollback/references/methods.md +204 -0
  323. package/{.cursor/commands/rollback.md → skills/rollback/references/workflow-integration.md} +10 -284
  324. package/skills/shepherd/SKILL.md +66 -0
  325. package/skills/shepherd/evals/evals.json +42 -0
  326. package/{.github/prompts/ship.prompt.md → skills/ship/SKILL.md} +81 -45
  327. package/skills/ship/evals/evals.json +42 -0
  328. package/skills/smith/SKILL.md +142 -0
  329. package/skills/smith/evals/evals.json +46 -0
  330. package/skills/smith/references/autonomy-and-gates.md +94 -0
  331. package/{.github/prompts/sonarcloud.prompt.md → skills/sonarcloud/SKILL.md} +14 -3
  332. package/skills/sonarcloud/evals/evals.json +46 -0
  333. package/skills/sonarcloud-analysis/SKILL.md +18 -13
  334. package/skills/sonarcloud-analysis/evals/evals.json +11 -15
  335. package/{.github/prompts/status.prompt.md → skills/status/SKILL.md} +20 -10
  336. package/skills/status/evals/evals.json +50 -0
  337. package/skills/triage-ready/SKILL.md +121 -0
  338. package/skills/triage-ready/evals/evals.json +42 -0
  339. package/{.github/prompts/validate.prompt.md → skills/validate/SKILL.md} +52 -29
  340. package/skills/validate/evals/evals.json +42 -0
  341. package/skills/verify/SKILL.md +299 -0
  342. package/skills/verify/evals/evals.json +50 -0
  343. package/.claude/commands/dev.md +0 -345
  344. package/.claude/commands/plan.md +0 -566
  345. package/.claude/commands/premerge.md +0 -186
  346. package/.claude/commands/research.md +0 -42
  347. package/.claude/commands/review.md +0 -451
  348. package/.claude/commands/rollback.md +0 -721
  349. package/.claude/commands/ship.md +0 -213
  350. package/.claude/commands/sonarcloud.md +0 -152
  351. package/.claude/commands/status.md +0 -90
  352. package/.claude/commands/validate.md +0 -288
  353. package/.claude/commands/verify.md +0 -269
  354. package/.claude/rules/workflow.md +0 -121
  355. package/.cline/workflows/dev.md +0 -342
  356. package/.cline/workflows/plan.md +0 -563
  357. package/.cline/workflows/premerge.md +0 -183
  358. package/.cline/workflows/research.md +0 -39
  359. package/.cline/workflows/review.md +0 -448
  360. package/.cline/workflows/rollback.md +0 -718
  361. package/.cline/workflows/ship.md +0 -210
  362. package/.cline/workflows/sonarcloud.md +0 -146
  363. package/.cline/workflows/status.md +0 -87
  364. package/.cline/workflows/validate.md +0 -285
  365. package/.cline/workflows/verify.md +0 -266
  366. package/.codex/config.toml +0 -11
  367. package/.codex/skills/dev/SKILL.md +0 -345
  368. package/.codex/skills/plan/SKILL.md +0 -566
  369. package/.codex/skills/premerge/SKILL.md +0 -186
  370. package/.codex/skills/research/SKILL.md +0 -42
  371. package/.codex/skills/review/SKILL.md +0 -451
  372. package/.codex/skills/rollback/SKILL.md +0 -721
  373. package/.codex/skills/ship/SKILL.md +0 -213
  374. package/.codex/skills/sonarcloud/SKILL.md +0 -149
  375. package/.codex/skills/status/SKILL.md +0 -90
  376. package/.codex/skills/validate/SKILL.md +0 -288
  377. package/.codex/skills/verify/SKILL.md +0 -269
  378. package/.cursor/commands/dev.md +0 -342
  379. package/.cursor/commands/plan.md +0 -563
  380. package/.cursor/commands/premerge.md +0 -183
  381. package/.cursor/commands/research.md +0 -39
  382. package/.cursor/commands/review.md +0 -448
  383. package/.cursor/commands/ship.md +0 -210
  384. package/.cursor/commands/sonarcloud.md +0 -146
  385. package/.cursor/commands/status.md +0 -87
  386. package/.cursor/commands/validate.md +0 -285
  387. package/.cursor/commands/verify.md +0 -266
  388. package/.cursorrules +0 -149
  389. package/.github/prompts/premerge.prompt.md +0 -188
  390. package/.github/prompts/research.prompt.md +0 -44
  391. package/.github/prompts/rollback.prompt.md +0 -723
  392. package/.github/prompts/verify.prompt.md +0 -271
  393. package/.github/workflows/beads-to-github.yml +0 -89
  394. package/.github/workflows/github-to-beads.yml +0 -100
  395. package/.kilocode/workflows/dev.md +0 -346
  396. package/.kilocode/workflows/plan.md +0 -567
  397. package/.kilocode/workflows/premerge.md +0 -187
  398. package/.kilocode/workflows/research.md +0 -43
  399. package/.kilocode/workflows/review.md +0 -452
  400. package/.kilocode/workflows/rollback.md +0 -722
  401. package/.kilocode/workflows/ship.md +0 -214
  402. package/.kilocode/workflows/sonarcloud.md +0 -150
  403. package/.kilocode/workflows/status.md +0 -91
  404. package/.kilocode/workflows/validate.md +0 -289
  405. package/.kilocode/workflows/verify.md +0 -270
  406. package/.opencode/commands/dev.md +0 -345
  407. package/.opencode/commands/plan.md +0 -566
  408. package/.opencode/commands/premerge.md +0 -186
  409. package/.opencode/commands/research.md +0 -42
  410. package/.opencode/commands/review.md +0 -451
  411. package/.opencode/commands/rollback.md +0 -721
  412. package/.opencode/commands/ship.md +0 -213
  413. package/.opencode/commands/sonarcloud.md +0 -149
  414. package/.opencode/commands/status.md +0 -90
  415. package/.opencode/commands/validate.md +0 -288
  416. package/.opencode/commands/verify.md +0 -269
  417. package/.roo/commands/dev.md +0 -346
  418. package/.roo/commands/plan.md +0 -567
  419. package/.roo/commands/premerge.md +0 -187
  420. package/.roo/commands/research.md +0 -43
  421. package/.roo/commands/review.md +0 -452
  422. package/.roo/commands/rollback.md +0 -722
  423. package/.roo/commands/ship.md +0 -214
  424. package/.roo/commands/sonarcloud.md +0 -150
  425. package/.roo/commands/status.md +0 -91
  426. package/.roo/commands/validate.md +0 -289
  427. package/.roo/commands/verify.md +0 -270
  428. package/docs/BEADS_GITHUB_SYNC.md +0 -281
  429. package/docs/GREPTILE_SETUP.md +0 -400
  430. package/docs/MANUAL_REVIEW_GUIDE.md +0 -106
  431. package/docs/SETUP.md +0 -663
  432. package/docs/VALIDATION.md +0 -363
  433. package/lib/agents/cline.plugin.json +0 -29
  434. package/lib/agents/copilot.plugin.json +0 -24
  435. package/lib/agents/kilocode.plugin.json +0 -22
  436. package/lib/agents/opencode.plugin.json +0 -23
  437. package/lib/agents/roo.plugin.json +0 -30
  438. package/lib/beads-bootstrap.js +0 -225
  439. package/lib/beads-health-check.js +0 -188
  440. package/lib/commands/commands-reset.js +0 -147
  441. package/opencode.json +0 -67
  442. package/scripts/beads-context.test.js +0 -584
  443. package/scripts/github-beads-sync/comment.mjs +0 -64
  444. package/scripts/github-beads-sync/config.mjs +0 -148
  445. package/scripts/github-beads-sync/github-api.mjs +0 -131
  446. package/scripts/github-beads-sync/index.mjs +0 -356
  447. package/scripts/github-beads-sync/label-mapper.mjs +0 -54
  448. package/scripts/github-beads-sync/mapping.mjs +0 -132
  449. package/scripts/github-beads-sync/reverse-sync-cli.mjs +0 -31
  450. package/scripts/github-beads-sync/reverse-sync.mjs +0 -162
  451. package/scripts/github-beads-sync/run-bd.mjs +0 -161
  452. package/scripts/github-beads-sync/sanitize.mjs +0 -121
  453. package/scripts/github-beads-sync.config.json +0 -26
  454. package/scripts/sync-commands.js +0 -600
@@ -0,0 +1,466 @@
1
+ 'use strict';
2
+
3
+ const fs = require('node:fs');
4
+ const path = require('node:path');
5
+ const { execFileSync } = require('node:child_process');
6
+ const { buildRuntimeGraphEnvelope } = require('./core/runtime-graph');
7
+ const { WORKFLOW_STAGE_MATRIX } = require('./workflow/stages');
8
+
9
+ const EXPECTED_CLASSIFICATIONS = Object.freeze([
10
+ 'critical',
11
+ 'standard',
12
+ 'refactor',
13
+ 'simple',
14
+ 'hotfix',
15
+ 'docs',
16
+ ]);
17
+
18
+ function toPlainMatrix(matrix) {
19
+ return Object.fromEntries(
20
+ Object.entries(matrix || {}).map(([classification, stages]) => [classification, [...stages]])
21
+ );
22
+ }
23
+
24
+ function addCheck(checks, status, label, detail) {
25
+ checks.push({ status, label, detail });
26
+ }
27
+
28
+ function checkStatus(ok) {
29
+ return ok ? 'pass' : 'fail';
30
+ }
31
+
32
+ function readJsonFile(filePath) {
33
+ return JSON.parse(fs.readFileSync(filePath, 'utf8'));
34
+ }
35
+
36
+ function tryReadJsonFile(filePath) {
37
+ try {
38
+ return { ok: true, value: readJsonFile(filePath) };
39
+ } catch (error) {
40
+ return { ok: false, error };
41
+ }
42
+ }
43
+
44
+ function parseJsonl(filePath) {
45
+ const rows = [];
46
+ const errors = [];
47
+ let source;
48
+ try {
49
+ source = fs.readFileSync(filePath, 'utf8');
50
+ } catch (error) {
51
+ return {
52
+ rows,
53
+ errors: [`${path.basename(path.dirname(filePath))}/${path.basename(filePath)} ${error.message}`],
54
+ };
55
+ }
56
+ const lines = source.split(/\r?\n/);
57
+
58
+ lines.forEach((line, index) => {
59
+ if (!line.trim()) return;
60
+ try {
61
+ rows.push(JSON.parse(line));
62
+ } catch (error) {
63
+ errors.push(`${path.basename(path.dirname(filePath))}/${path.basename(filePath)}:${index + 1} ${error.message}`);
64
+ }
65
+ });
66
+
67
+ return { rows, errors };
68
+ }
69
+
70
+ function runGit(projectRoot, args) {
71
+ return execFileSync('git', args, { // NOSONAR: Forge is a local developer CLI and intentionally resolves git from PATH.
72
+ cwd: projectRoot,
73
+ encoding: 'utf8',
74
+ stdio: ['ignore', 'pipe', 'ignore'],
75
+ }).trim();
76
+ }
77
+
78
+ function getGitInfo(projectRoot) {
79
+ try {
80
+ const insideWorkTree = runGit(projectRoot, ['rev-parse', '--is-inside-work-tree']) === 'true';
81
+ if (!insideWorkTree) {
82
+ return { ok: false, detail: 'not a git work tree' };
83
+ }
84
+
85
+ const branch = runGit(projectRoot, ['branch', '--show-current']);
86
+ if (branch) {
87
+ return { ok: true, branch, detail: `branch=${branch}` };
88
+ }
89
+
90
+ const shortHead = runGit(projectRoot, ['rev-parse', '--short', 'HEAD']);
91
+ return { ok: true, branch: null, detail: `detached HEAD (${shortHead})` };
92
+ } catch (error) {
93
+ return { ok: false, detail: `not a git repository (${error.message})` };
94
+ }
95
+ }
96
+
97
+ function isForgeSourceRepo(projectRoot) {
98
+ const packagePath = path.join(projectRoot, 'package.json');
99
+ if (!fs.existsSync(packagePath)) {
100
+ return false;
101
+ }
102
+
103
+ const packageJson = tryReadJsonFile(packagePath);
104
+ if (!packageJson.ok) {
105
+ return false;
106
+ }
107
+
108
+ return packageJson.value.name === 'forge-workflow'
109
+ && fs.existsSync(path.join(projectRoot, 'docs', 'work', '2026-04-28-skeleton-pivot'));
110
+ }
111
+
112
+ function findWorkflowStageMatrix(projectRoot) {
113
+ const fixtureMatrixPath = path.join(projectRoot, '.forge', 'v2', 'workflow-stage-matrix.json');
114
+ if (fs.existsSync(fixtureMatrixPath)) {
115
+ return {
116
+ source: path.relative(projectRoot, fixtureMatrixPath),
117
+ matrix: readJsonFile(fixtureMatrixPath),
118
+ };
119
+ }
120
+
121
+ return {
122
+ source: 'lib/workflow/stages.js',
123
+ matrix: toPlainMatrix(WORKFLOW_STAGE_MATRIX),
124
+ };
125
+ }
126
+
127
+ function validateWorkflowMatrix(projectRoot, checks) {
128
+ let matrixInfo;
129
+ try {
130
+ matrixInfo = findWorkflowStageMatrix(projectRoot);
131
+ } catch (error) {
132
+ addCheck(checks, 'fail', 'WORKFLOW_STAGE_MATRIX', error.message);
133
+ return null;
134
+ }
135
+
136
+ const matrix = matrixInfo.matrix;
137
+ const failures = [];
138
+ for (const classification of EXPECTED_CLASSIFICATIONS) {
139
+ if (!Array.isArray(matrix[classification]) || matrix[classification].length === 0) {
140
+ failures.push(`missing ${classification}`);
141
+ }
142
+ }
143
+
144
+ const unknown = Object.keys(matrix).filter(classification => !EXPECTED_CLASSIFICATIONS.includes(classification));
145
+ if (unknown.length > 0) {
146
+ failures.push(`unknown classifications: ${unknown.join(', ')}`);
147
+ }
148
+
149
+ addCheck(
150
+ checks,
151
+ checkStatus(failures.length === 0),
152
+ 'WORKFLOW_STAGE_MATRIX',
153
+ failures.length === 0
154
+ ? `${Object.keys(matrix).length} classifications from ${matrixInfo.source}`
155
+ : failures.join('; ')
156
+ );
157
+
158
+ return failures.length === 0 ? matrixInfo : null;
159
+ }
160
+
161
+ function summarizeIssues(issues) {
162
+ const byStatus = {};
163
+ for (const issue of issues) {
164
+ const status = issue.status || 'unknown';
165
+ byStatus[status] = (byStatus[status] || 0) + 1;
166
+ }
167
+ return byStatus;
168
+ }
169
+
170
+ function validateBeadsState(projectRoot, checks, options = {}) {
171
+ const beadsDir = path.join(projectRoot, '.beads');
172
+ const issuesPath = path.join(beadsDir, 'issues.jsonl');
173
+ if (!fs.existsSync(beadsDir)) {
174
+ addCheck(checks, 'fail', 'Beads issue state', 'missing .beads directory');
175
+ return null;
176
+ }
177
+ if (!fs.existsSync(issuesPath)) {
178
+ addCheck(checks, 'fail', 'Beads issue state', 'missing .beads/issues.jsonl');
179
+ return null;
180
+ }
181
+
182
+ const parsed = parseJsonl(issuesPath);
183
+ const issues = parsed.rows.filter(row => row && typeof row === 'object' && row.id);
184
+ if (parsed.errors.length > 0) {
185
+ addCheck(checks, 'fail', 'Beads issue state', parsed.errors.join('; '));
186
+ return { issues, errors: parsed.errors };
187
+ }
188
+
189
+ const statusSummary = Object.entries(summarizeIssues(issues))
190
+ .sort(([left], [right]) => left.localeCompare(right))
191
+ .map(([status, count]) => `${status}=${count}`)
192
+ .join(', ');
193
+ addCheck(
194
+ checks,
195
+ checkStatus(issues.length > 0),
196
+ 'Beads issue state',
197
+ issues.length > 0 ? `${issues.length} issues parsed (${statusSummary})` : 'no issue records found'
198
+ );
199
+
200
+ const waveIssue = issues.find(issue => issue.id === 'forge-0uo0');
201
+ if (waveIssue) {
202
+ addCheck(checks, 'pass', 'Wave 0 issue forge-0uo0', `status=${waveIssue.status || 'unknown'}`);
203
+ } else if (options.requireWaveIssue) {
204
+ addCheck(checks, 'fail', 'Wave 0 issue forge-0uo0', 'missing from .beads/issues.jsonl');
205
+ }
206
+
207
+ return { issues, errors: [] };
208
+ }
209
+
210
+ function detectBeadsBackend(projectRoot) {
211
+ const configCandidates = [
212
+ path.join(projectRoot, '.beads', 'config.yaml'),
213
+ path.join(projectRoot, '.beads', 'dolt', 'config.yaml'),
214
+ ];
215
+ for (const candidate of configCandidates) {
216
+ if (!fs.existsSync(candidate)) continue;
217
+ let content;
218
+ try {
219
+ content = fs.readFileSync(candidate, 'utf8');
220
+ } catch (_error) {
221
+ continue;
222
+ }
223
+ const backendMatch = content.match(/backend:\s*([A-Za-z0-9_-]+)/);
224
+ if (backendMatch) return backendMatch[1];
225
+ }
226
+ if (fs.existsSync(path.join(projectRoot, '.beads', 'metadata.json'))) {
227
+ return 'dolt';
228
+ }
229
+ return 'unknown';
230
+ }
231
+
232
+ function renderConfigYaml(matrix, beadsBackend) {
233
+ const lines = [
234
+ '# Generated preview by forge migrate --dry-run. Do not commit this preview output.',
235
+ 'version: 3',
236
+ 'compat:',
237
+ ' v2Commands: true',
238
+ 'issueTracker:',
239
+ ' adapter: beads',
240
+ ` backend: ${beadsBackend}`,
241
+ 'workflow:',
242
+ ' source: v2 WORKFLOW_STAGE_MATRIX',
243
+ ' classifications:',
244
+ ];
245
+
246
+ for (const classification of EXPECTED_CLASSIFICATIONS) {
247
+ lines.push(` ${classification}:`, ' stages:');
248
+ for (const stage of matrix[classification] || []) {
249
+ lines.push(` - ${stage}`);
250
+ }
251
+ }
252
+
253
+ return `${lines.join('\n')}\n`;
254
+ }
255
+
256
+ function renderPatchMd() {
257
+ return [
258
+ '# Forge v3 Project Patch',
259
+ '',
260
+ 'No project overrides were inferred during the Wave 0 dry-run PoC.',
261
+ 'Add L3 overrides here after v3 config schema lands.',
262
+ '',
263
+ ].join('\n');
264
+ }
265
+
266
+ function renderForgeLock(matrix) {
267
+ return `${JSON.stringify({
268
+ version: 1,
269
+ generatedBy: 'forge migrate --dry-run',
270
+ compat: { v2Commands: true },
271
+ workflowMatrixHashInput: matrix,
272
+ extensions: [],
273
+ }, null, 2)}\n`;
274
+ }
275
+
276
+ function buildPlannedFiles(projectRoot, matrix, beadsBackend) {
277
+ return [
278
+ {
279
+ path: '.forge/config.yaml',
280
+ content: renderConfigYaml(matrix, beadsBackend),
281
+ },
282
+ {
283
+ path: '.forge/patch.md',
284
+ content: renderPatchMd(),
285
+ },
286
+ {
287
+ path: 'forge.lock',
288
+ content: renderForgeLock(matrix),
289
+ },
290
+ ].map(file => ({
291
+ ...file,
292
+ exists: fs.existsSync(path.join(projectRoot, file.path)),
293
+ }));
294
+ }
295
+
296
+ function renderFileDiff(file) {
297
+ const lines = [
298
+ `diff --git a/${file.path} b/${file.path}`,
299
+ file.exists ? `--- a/${file.path}` : '--- /dev/null',
300
+ `+++ ${file.path}`,
301
+ '@@',
302
+ ];
303
+ for (const line of file.content.replace(/\n$/, '').split('\n')) {
304
+ lines.push(`+${line}`);
305
+ }
306
+ return lines.join('\n');
307
+ }
308
+
309
+ function getFixtureCorpusModule() {
310
+ const fixtureModulePath = path.join(__dirname, '..', 'test', 'fixtures', 'v2-corpus');
311
+ if (!fs.existsSync(fixtureModulePath) && !fs.existsSync(`${fixtureModulePath}.js`)) {
312
+ return null;
313
+ }
314
+ return require(fixtureModulePath);
315
+ }
316
+
317
+ function getFixtureCorpusAvailability() {
318
+ return getFixtureCorpusModule() ? {
319
+ available: true,
320
+ note: 'run with --fixture-corpus to materialize and dry-run all v2 fixtures',
321
+ } : {
322
+ available: false,
323
+ note: 'fixture corpus not available in this install; command is ready for test/fixtures/v2-corpus when available',
324
+ };
325
+ }
326
+
327
+ function buildMigrationDryRunReport(projectRoot = process.cwd(), options = {}) {
328
+ const checks = [];
329
+ const root = path.resolve(projectRoot);
330
+ const requireWaveIssue = options.requireWaveIssue ?? isForgeSourceRepo(root);
331
+ const gitInfo = getGitInfo(root);
332
+ addCheck(checks, checkStatus(gitInfo.ok), 'Git repository', gitInfo.detail);
333
+
334
+ const beadsState = validateBeadsState(root, checks, { requireWaveIssue });
335
+ const matrixInfo = validateWorkflowMatrix(root, checks);
336
+ const beadsBackend = detectBeadsBackend(root);
337
+ addCheck(checks, 'pass', 'Beads adapter projection', `adapter=beads backend=${beadsBackend}`);
338
+
339
+ const plannedFiles = matrixInfo
340
+ ? buildPlannedFiles(root, matrixInfo.matrix, beadsBackend)
341
+ : [];
342
+ if (matrixInfo) {
343
+ addCheck(checks, 'pass', 'v3 config projection', `${plannedFiles.length} planned file(s), dry-run only`);
344
+ }
345
+
346
+ addCheck(checks, 'pass', 'Mutation guard', 'No files were written; planned changes are report-only');
347
+
348
+ const corpus = getFixtureCorpusAvailability();
349
+ let corpusRun = null;
350
+ if (options.fixtureCorpus) {
351
+ corpusRun = runV2FixtureCorpusDryRun();
352
+ }
353
+
354
+ return {
355
+ ok: checks.every(check => check.status !== 'fail'),
356
+ projectRoot: root,
357
+ branch: gitInfo.branch,
358
+ git: gitInfo,
359
+ checks,
360
+ beads: beadsState,
361
+ workflowMatrix: matrixInfo,
362
+ plannedFiles,
363
+ fixtureCorpus: corpus,
364
+ fixtureCorpusRun: corpusRun,
365
+ runtimeGraph: buildRuntimeGraphEnvelope(),
366
+ };
367
+ }
368
+
369
+ function renderFixtureCorpus(corpus, corpusRun) {
370
+ if (!corpus.available) {
371
+ return [`Fixture corpus: unavailable`, corpus.note];
372
+ }
373
+ if (!corpusRun) {
374
+ return [`Fixture corpus: available`, corpus.note];
375
+ }
376
+
377
+ const lines = ['Fixture corpus: executed'];
378
+ for (const result of corpusRun.results) {
379
+ lines.push(`[${result.ok ? 'PASS' : 'FAIL'}] ${result.name}: ${result.summary}`);
380
+ }
381
+ return lines;
382
+ }
383
+
384
+ function renderMigrationDryRunReport(report) {
385
+ const lines = [
386
+ 'Forge v2 -> v3 migration dry-run',
387
+ `Target: ${report.projectRoot}`,
388
+ `Result: ${report.ok ? 'PASS' : 'FAIL'}`,
389
+ '',
390
+ 'Validation',
391
+ ];
392
+
393
+ for (const check of report.checks) {
394
+ lines.push(`[${check.status.toUpperCase()}] ${check.label}: ${check.detail}`);
395
+ }
396
+
397
+ lines.push('', 'Planned diff');
398
+ if (report.plannedFiles.length === 0) {
399
+ lines.push('(no diff available because validation failed before config projection)');
400
+ } else {
401
+ lines.push(
402
+ ...report.plannedFiles.map(renderFileDiff).join('\n\n').split('\n')
403
+ );
404
+ }
405
+
406
+ lines.push(
407
+ '',
408
+ ...renderRuntimeGraph(report.runtimeGraph),
409
+ '',
410
+ 'Dry-run guarantee',
411
+ 'No files were written outside controlled temp fixture materialization when --fixture-corpus is used.',
412
+ '',
413
+ ...renderFixtureCorpus(report.fixtureCorpus, report.fixtureCorpusRun)
414
+ );
415
+
416
+ return `${lines.join('\n')}\n`;
417
+ }
418
+
419
+ function renderRuntimeGraph(envelope) {
420
+ if (!envelope?.graph) {
421
+ return ['Runtime graph', '(not available)'];
422
+ }
423
+
424
+ const graph = envelope.graph;
425
+ return [
426
+ 'Runtime graph',
427
+ `Schema: ${envelope.kind}@${envelope.schemaVersion}`,
428
+ `Phases: ${graph.phases.map(phase => phase.id).join(' -> ')}`,
429
+ `Actions: ${graph.actions.map(action => action.id).join(', ')}`,
430
+ `Artifacts: ${graph.artifacts.map(artifact => artifact.id).join(', ')}`,
431
+ `Evaluator regions: ${graph.evaluatorRegions.map(region => region.id).join(', ')}`,
432
+ `Gates: ${graph.gates.map(gate => gate.id).join(', ')}`,
433
+ `Evidence: ${graph.evidence.map(evidence => evidence.id).join(', ')}`,
434
+ ];
435
+ }
436
+
437
+ function runV2FixtureCorpusDryRun() {
438
+ const corpus = getFixtureCorpusModule();
439
+ if (!corpus) {
440
+ return {
441
+ available: false,
442
+ results: [],
443
+ blocker: 'fixture corpus not found at test/fixtures/v2-corpus',
444
+ };
445
+ }
446
+
447
+ const results = corpus.listFixtureNames().map((name) => {
448
+ const { repoRoot } = corpus.materializeFixture(name);
449
+ const report = buildMigrationDryRunReport(repoRoot);
450
+ const failed = report.checks.filter(check => check.status === 'fail');
451
+ return {
452
+ name,
453
+ repoRoot,
454
+ ok: report.ok,
455
+ summary: report.ok ? 'dry-run report generated' : failed.map(check => `${check.label}: ${check.detail}`).join('; '),
456
+ };
457
+ });
458
+
459
+ return { available: true, results };
460
+ }
461
+
462
+ module.exports = {
463
+ buildMigrationDryRunReport,
464
+ renderMigrationDryRunReport,
465
+ runV2FixtureCorpusDryRun,
466
+ };