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,237 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Gate composition + real sub-runners for `forge preflight`.
5
+ *
6
+ * Each real runner takes an injectable `spawn` (defaults to spawnSync) so the
7
+ * composition and the runners are unit-testable without touching the shell.
8
+ * The four gates give DETERMINISTIC-GATE PARITY with CI on the blast radius of
9
+ * a change, without the slow full matrix:
10
+ *
11
+ * 1. lint — eslint --max-warnings 0 on changed files (or all with --all)
12
+ * 2. drift — skills-mirror + registry-sync + agentic-workflow structural asserts
13
+ * 3. sonar — eslint-plugin-sonarjs (cognitive-complexity=15 + parity rules)
14
+ * 4. affected — only the tests mapped from the changed files
15
+ *
16
+ * @module preflight/gates
17
+ */
18
+
19
+ const path = require('node:path');
20
+ const { spawnSync } = require('node:child_process');
21
+ const { execFileSync } = require('node:child_process');
22
+ const nodeFs = require('node:fs');
23
+ const { getAffectedTestFiles } = require('../commands/test');
24
+
25
+ const IS_WINDOWS = process.platform === 'win32';
26
+
27
+ /** Filter a changed-file list down to the JS files eslint should look at. */
28
+ function lintableFiles(files) {
29
+ if (!Array.isArray(files)) return [];
30
+ return files.filter((f) => /\.(mjs|cjs|js)$/.test(f) && !f.includes('node_modules'));
31
+ }
32
+
33
+ /** Short, bounded summary for a spawn result. */
34
+ function statusSummary(result, okMsg, failMsg) {
35
+ return result && result.status === 0
36
+ ? { ok: true, summary: okMsg }
37
+ : { ok: false, summary: failMsg };
38
+ }
39
+
40
+ /**
41
+ * Gate 1 — ESLint on the change blast radius (or the whole tree with --all).
42
+ * `files === null` means "lint everything" (`eslint .`).
43
+ */
44
+ function runEslint(files, { projectRoot, spawn = spawnSync } = {}) {
45
+ const lintAll = files === null;
46
+ const targets = lintAll ? ['.'] : lintableFiles(files);
47
+ if (targets.length === 0) {
48
+ return { ok: true, summary: 'no changed JS files' };
49
+ }
50
+ const result = spawn(
51
+ 'npx',
52
+ ['eslint', '--max-warnings', '0', ...targets],
53
+ { cwd: projectRoot, stdio: 'inherit', shell: IS_WINDOWS },
54
+ );
55
+ return statusSummary(
56
+ result,
57
+ lintAll ? 'whole tree clean' : `${targets.length} changed file(s) clean`,
58
+ 'eslint reported errors/warnings',
59
+ );
60
+ }
61
+
62
+ /**
63
+ * Gate 2 — deterministic structural asserts that CI enforces:
64
+ * - skills mirror drift (test/structural/skills-sync-drift.test.js)
65
+ * - SUBCOMMANDS<->ISSUE_COMMANDS registry sync (test/commands/_resolve-command-opts.test.js)
66
+ * - committed agentic-workflow mirror (scripts/sync-agentic-workflow.js --check)
67
+ */
68
+ function runStructural({ projectRoot, spawn = spawnSync, fs = nodeFs } = {}) {
69
+ const exists = (rel) => {
70
+ try {
71
+ return fs.existsSync(path.join(projectRoot, rel));
72
+ } catch {
73
+ return false;
74
+ }
75
+ };
76
+
77
+ // These are Forge's OWN internal structural asserts. A consumer repo does not
78
+ // contain them and can NEVER satisfy them, so only run the ones that actually
79
+ // exist in this project. If none do, the gate is not applicable here — report
80
+ // an explicit SKIP rather than a false pass or an impossible failure.
81
+ const structuralTests = [
82
+ 'test/structural/skills-sync-drift.test.js',
83
+ 'test/commands/_resolve-command-opts.test.js',
84
+ ].filter(exists);
85
+ const agenticScript = 'scripts/sync-agentic-workflow.js';
86
+ const hasAgentic = exists(agenticScript);
87
+
88
+ if (structuralTests.length === 0 && !hasAgentic) {
89
+ return {
90
+ ok: true,
91
+ skipped: true,
92
+ summary: 'no Forge-internal structural checks in this repo (consumer context)',
93
+ };
94
+ }
95
+
96
+ if (structuralTests.length > 0) {
97
+ const bun = spawn(
98
+ 'bun',
99
+ ['test', '--timeout', '15000', ...structuralTests],
100
+ { cwd: projectRoot, stdio: 'inherit', shell: IS_WINDOWS },
101
+ );
102
+ if (!bun || bun.status !== 0) {
103
+ return { ok: false, summary: 'skills-mirror / registry-sync asserts failed' };
104
+ }
105
+ }
106
+
107
+ if (!hasAgentic) {
108
+ return { ok: true, summary: 'skills + registry in sync (no agentic-workflow mirror here)' };
109
+ }
110
+
111
+ const agentic = spawn(
112
+ 'node',
113
+ [agenticScript, '--check'],
114
+ { cwd: projectRoot, stdio: 'inherit', shell: IS_WINDOWS },
115
+ );
116
+ return statusSummary(
117
+ agentic,
118
+ 'skills + registry + agentic-workflow in sync',
119
+ 'agentic-workflow mirror drift (run: node scripts/sync-agentic-workflow.js)',
120
+ );
121
+ }
122
+
123
+ /**
124
+ * Gate 3 — SonarCloud parity via eslint-plugin-sonarjs, using an isolated flat
125
+ * config (cognitive-complexity pinned to 15 + the parity rules) so it never
126
+ * merges with the repo's main eslint config.
127
+ * `files === null` means "scan everything" (whole-tree `--all` mode) — mirrors
128
+ * runEslint so `--all` never leaves sonar as a vacuous "no changed files" pass.
129
+ */
130
+ function runSonar(files, { projectRoot, spawn = spawnSync } = {}) {
131
+ const scanAll = files === null;
132
+ const targets = scanAll ? ['.'] : lintableFiles(files);
133
+ if (targets.length === 0) {
134
+ return { ok: true, summary: 'no changed JS files' };
135
+ }
136
+ const config = path.join(projectRoot, 'scripts', 'preflight-sonar.eslint.config.mjs');
137
+ const result = spawn(
138
+ 'npx',
139
+ ['eslint', '--no-config-lookup', '--config', config, '--max-warnings', '0', ...targets],
140
+ { cwd: projectRoot, stdio: 'inherit', shell: IS_WINDOWS },
141
+ );
142
+ return statusSummary(
143
+ result,
144
+ scanAll ? 'sonarjs clean (whole tree)' : `sonarjs clean (${targets.length} file(s))`,
145
+ 'sonarjs parity violations (e.g. cognitive-complexity > 15)',
146
+ );
147
+ }
148
+
149
+ /**
150
+ * Gate 4 — run ONLY the tests mapped from the changed files (reuses the
151
+ * pre-push affected-test mapping). No affected tests → fast-lane pass.
152
+ */
153
+ function runAffectedTests({
154
+ projectRoot,
155
+ changedFiles: _changedFiles,
156
+ spawn = spawnSync,
157
+ resolveTests,
158
+ } = {}) {
159
+ const resolver = typeof resolveTests === 'function'
160
+ ? resolveTests
161
+ // strict:true so a failed `git diff` THROWS here instead of returning [] —
162
+ // otherwise a git error would masquerade as "no affected tests" (fast-lane
163
+ // green), a fail-OPEN. The catch below turns that throw into a closed gate.
164
+ : () => getAffectedTestFiles(projectRoot, execFileSync, nodeFs, { strict: true });
165
+ let targets;
166
+ try {
167
+ targets = resolver() || [];
168
+ } catch (err) {
169
+ // A resolver ERROR must NOT masquerade as "no affected tests" (green).
170
+ // We could not determine what to run, so fail closed — never a vacuous pass.
171
+ const reason = err && err.message ? err.message : String(err);
172
+ return { ok: false, summary: `affected-test resolution failed — fail-closed (${reason})` };
173
+ }
174
+ if (targets.length === 0) {
175
+ return { ok: true, summary: 'no affected tests resolved (fast lane)' };
176
+ }
177
+ const result = spawn(
178
+ 'bun',
179
+ ['test', '--timeout', '15000', ...targets],
180
+ { cwd: projectRoot, stdio: 'inherit', shell: IS_WINDOWS },
181
+ );
182
+ return statusSummary(
183
+ result,
184
+ `${targets.length} affected test file(s) passed`,
185
+ 'affected tests failed',
186
+ );
187
+ }
188
+
189
+ /**
190
+ * Compose the ordered gate list. Each gate delegates to a sub-runner that can
191
+ * be injected via `deps` for testing; defaults wire the real runners above.
192
+ *
193
+ * @param {Object} args
194
+ * @param {string} args.projectRoot
195
+ * @param {string[]} args.changedFiles
196
+ * @param {boolean} [args.runAll] - lint/scan whole tree instead of changed files
197
+ * @param {Object} [args.deps] - { eslint, structural, sonar, affected }
198
+ * @returns {{ name: string, run: () => Promise<{ok:boolean, summary?:string}> }[]}
199
+ */
200
+ function buildGates({ projectRoot, changedFiles = [], runAll = false, deps = {} }) {
201
+ const eslint = deps.eslint || ((files) => runEslint(files, { projectRoot }));
202
+ const structural = deps.structural || (() => runStructural({ projectRoot }));
203
+ const sonar = deps.sonar || ((files) => runSonar(files, { projectRoot }));
204
+ const affected = deps.affected || (() => runAffectedTests({ projectRoot, changedFiles }));
205
+
206
+ // Under --all, scope BOTH lint and sonar to the whole tree (null). Otherwise
207
+ // sonar would receive changedFiles=[] and report a vacuous "no changed files"
208
+ // pass while lint scanned everything — a fail-open hole on the remedy path.
209
+ const scanTargets = runAll ? null : changedFiles;
210
+
211
+ // Affected-tests maps from the change set, which is empty under --all. Running
212
+ // the WHOLE suite here defeats preflight's fast purpose (and hangs on Windows),
213
+ // so mark it explicitly not-run — never a vacuous green. CI runs the full suite.
214
+ const affectedGate = runAll
215
+ ? async () => ({
216
+ ok: true,
217
+ skipped: true,
218
+ summary: 'whole-tree mode (--all): affected-test mapping N/A — run the full suite (CI does)',
219
+ })
220
+ : async () => affected();
221
+
222
+ return [
223
+ { name: 'lint', run: async () => eslint(scanTargets) },
224
+ { name: 'drift/registry/mirror', run: async () => structural() },
225
+ { name: 'sonar (cognitive-complexity=15)', run: async () => sonar(scanTargets) },
226
+ { name: 'affected-tests', run: affectedGate },
227
+ ];
228
+ }
229
+
230
+ module.exports = {
231
+ buildGates,
232
+ lintableFiles,
233
+ runEslint,
234
+ runStructural,
235
+ runSonar,
236
+ runAffectedTests,
237
+ };
@@ -0,0 +1,116 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Fast-fail gate runner for `forge preflight`.
5
+ *
6
+ * Executes an ordered list of gates one at a time. The first gate to fail
7
+ * short-circuits the run: every later gate is reported as `skipped` and never
8
+ * executed. This keeps preflight FAST — an agent fixes the first broken gate
9
+ * and re-runs rather than waiting for the whole matrix.
10
+ *
11
+ * A gate is `{ name: string, run: () => Promise<{ ok: boolean, summary?: string }> }`.
12
+ * The sub-runner behind each `run` is injected by the composer (see gates.js),
13
+ * so this module stays pure and trivially testable.
14
+ *
15
+ * @module preflight/runner
16
+ */
17
+
18
+ /**
19
+ * @typedef {Object} GateOutcome
20
+ * @property {boolean} ok - Whether the gate passed.
21
+ * @property {string} [summary] - Short human-readable result line.
22
+ *
23
+ * @typedef {Object} Gate
24
+ * @property {string} name
25
+ * @property {() => Promise<GateOutcome>} run
26
+ *
27
+ * @typedef {Object} GateResult
28
+ * @property {string} name
29
+ * @property {boolean|null} ok - true/false, or null when skipped.
30
+ * @property {boolean} skipped
31
+ * @property {string} summary
32
+ * @property {number} [durationMs]
33
+ */
34
+
35
+ /**
36
+ * Execute a single gate, normalizing thrown errors into a failed outcome.
37
+ *
38
+ * @param {Gate} gate
39
+ * @returns {Promise<GateResult>}
40
+ */
41
+ async function executeGate(gate) {
42
+ const started = Date.now();
43
+ let outcome;
44
+ try {
45
+ outcome = await gate.run();
46
+ } catch (err) {
47
+ const message = err && err.message ? err.message : String(err);
48
+ outcome = { ok: false, summary: `error: ${message}` };
49
+ }
50
+ const durationMs = Date.now() - started;
51
+ const skipped = !!outcome?.skipped;
52
+ // A skipped gate is a pass-through: it is neither a pass nor a failure, so it
53
+ // must never short-circuit later gates (see runGates fast-fail). BUT a skip
54
+ // must never MASK an explicit failure — a gate that reports {ok:false} has
55
+ // failed regardless of a skipped flag, so it stays failed and short-circuits.
56
+ const explicitOk = !!outcome?.ok;
57
+ const ok = skipped ? outcome?.ok !== false : explicitOk;
58
+ // Contract: an explicit ok:false can never normalize to a pass. Guards against
59
+ // a future edit reintroducing the skip-masks-failure bug (4b73b6bf).
60
+ if (outcome && outcome.ok === false && ok === true) {
61
+ throw new Error('executeGate contract violation: skipped must not override an explicit ok:false');
62
+ }
63
+ return {
64
+ name: gate.name,
65
+ ok,
66
+ skipped,
67
+ summary: outcome?.summary || '',
68
+ durationMs,
69
+ };
70
+ }
71
+
72
+ /** Live-log label for a gate result — SKIP must never read as PASS. */
73
+ function gateLogMark(result) {
74
+ if (result.skipped) return 'SKIP';
75
+ return result.ok ? 'PASS' : 'FAIL';
76
+ }
77
+
78
+ /**
79
+ * Run gates in order, fast-failing at the first failure.
80
+ *
81
+ * @param {Gate[]} gates
82
+ * @param {{ log?: (line: string) => void }} [options]
83
+ * @returns {Promise<{ ok: boolean, results: GateResult[], failedIndex: number }>}
84
+ */
85
+ async function runGates(gates, options = {}) {
86
+ const log = typeof options.log === 'function' ? options.log : () => {};
87
+ const results = [];
88
+ let ok = true;
89
+ let failedIndex = -1;
90
+
91
+ for (const gate of gates) {
92
+ if (!ok) {
93
+ results.push({
94
+ name: gate.name,
95
+ ok: null,
96
+ skipped: true,
97
+ summary: 'skipped (earlier gate failed)',
98
+ });
99
+ continue;
100
+ }
101
+
102
+ const result = await executeGate(gate);
103
+ results.push(result);
104
+ const suffix = result.summary ? ` — ${result.summary}` : '';
105
+ log(`${gateLogMark(result)} ${gate.name}${suffix}`);
106
+
107
+ if (!result.ok) {
108
+ ok = false;
109
+ failedIndex = results.length - 1;
110
+ }
111
+ }
112
+
113
+ return { ok, results, failedIndex };
114
+ }
115
+
116
+ module.exports = { runGates };
@@ -263,16 +263,6 @@ async function detectInstalledAgents(projectPath) {
263
263
  }
264
264
  ]
265
265
  },
266
- {
267
- name: 'copilot',
268
- checks: [
269
- // .github/copilot-instructions.md
270
- async () => {
271
- const copilotFile = path.join(projectPath, '.github', 'copilot-instructions.md');
272
- return fs.existsSync(copilotFile);
273
- }
274
- ]
275
- },
276
266
  {
277
267
  name: 'cursor',
278
268
  checks: [
@@ -283,39 +273,6 @@ async function detectInstalledAgents(projectPath) {
283
273
  }
284
274
  ]
285
275
  },
286
- {
287
- name: 'cline',
288
- checks: [
289
- async () => fs.existsSync(path.join(projectPath, '.clinerules')),
290
- async () => {
291
- const clineDir = path.join(projectPath, '.cline');
292
- return fs.existsSync(clineDir) && (await fs.promises.stat(clineDir)).isDirectory();
293
- }
294
- ]
295
- },
296
- {
297
- name: 'kilocode',
298
- checks: [
299
- async () => {
300
- const kilocodeDir = path.join(projectPath, '.kilocode');
301
- return fs.existsSync(kilocodeDir) && (await fs.promises.stat(kilocodeDir)).isDirectory();
302
- },
303
- async () => fs.existsSync(path.join(projectPath, '.kilocode', 'workflows', 'forge-workflow.md')),
304
- async () => fs.existsSync(path.join(projectPath, '.kilocode', 'rules', 'workflow.md')),
305
- async () => fs.existsSync(path.join(projectPath, '.kilocode', 'skills', 'forge-workflow', 'SKILL.md'))
306
- ]
307
- },
308
- {
309
- name: 'roo',
310
- checks: [
311
- async () => fs.existsSync(path.join(projectPath, '.roorules')),
312
- async () => {
313
- const rooDir = path.join(projectPath, '.roo');
314
- return fs.existsSync(rooDir) && (await fs.promises.stat(rooDir)).isDirectory();
315
- },
316
- async () => fs.existsSync(path.join(projectPath, '.roo', 'rules'))
317
- ]
318
- },
319
276
  {
320
277
  name: 'codex',
321
278
  checks: [
@@ -325,16 +282,6 @@ async function detectInstalledAgents(projectPath) {
325
282
  return fs.existsSync(codexDir) && (await fs.promises.stat(codexDir)).isDirectory();
326
283
  }
327
284
  ]
328
- },
329
- {
330
- name: 'opencode',
331
- checks: [
332
- // opencode.json file
333
- async () => {
334
- const opencodeJson = path.join(projectPath, 'opencode.json');
335
- return fs.existsSync(opencodeJson);
336
- }
337
- ]
338
285
  }
339
286
  ];
340
287