forge-workflow 0.0.10 → 0.1.0-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (468) hide show
  1. package/.claude/rules/{greptile-review-process.md → review-process.md} +56 -41
  2. package/.claude/scripts/{greptile-resolve.sh → review-resolve.sh} +13 -3
  3. package/.cursor/rules/permissions-guidance.mdc +2 -2
  4. package/.forge/hooks/check-tdd.js +82 -5
  5. package/.forge/hooks/forge-native-hook.js +431 -0
  6. package/.forge/protected-paths.yaml +157 -0
  7. package/AGENTS.md +151 -61
  8. package/CHANGELOG.md +709 -0
  9. package/CLAUDE.md +9 -118
  10. package/QUICKSTART.md +175 -0
  11. package/README.md +275 -365
  12. package/bin/forge-cmd.js +120 -9
  13. package/bin/forge-preflight.js +26 -5
  14. package/bin/forge.js +532 -489
  15. package/docs/INDEX.md +93 -0
  16. package/docs/PROJECT_DESIGN.md +685 -0
  17. package/docs/architecture/index.md +66 -0
  18. package/docs/architecture/notes/README.md +35 -0
  19. package/docs/architecture/subsystems/README.md +46 -0
  20. package/docs/forge/TOOLCHAIN.md +670 -0
  21. package/docs/forge/VALIDATION.md +82 -0
  22. package/docs/{AGENT_INSTALL_PROMPT.md → guides/AGENT_INSTALL_PROMPT.md} +3 -3
  23. package/docs/guides/BEADS_GITHUB_SYNC.md +32 -0
  24. package/docs/{ENHANCED_ONBOARDING.md → guides/ENHANCED_ONBOARDING.md} +16 -12
  25. package/docs/guides/GREPTILE_SETUP.md +46 -0
  26. package/docs/guides/MANUAL_REVIEW_GUIDE.md +58 -0
  27. package/docs/guides/MIGRATION.md +56 -0
  28. package/docs/guides/SETUP.md +121 -0
  29. package/docs/guides/SUPPORT.md +190 -0
  30. package/docs/guides/WORKFLOW_TEMPLATES.md +74 -0
  31. package/docs/guides/memory-backends.md +183 -0
  32. package/docs/reference/ADAPTERS.md +128 -0
  33. package/docs/reference/AGENT_SKILL_PARITY.md +175 -0
  34. package/docs/reference/COMMANDS.md +214 -0
  35. package/docs/reference/DECISION_DRIFT_GUARDS.md +97 -0
  36. package/docs/{EXAMPLES.md → reference/EXAMPLES.md} +7 -5
  37. package/docs/reference/FORGE_KERNEL_STORAGE_MODEL.md +135 -0
  38. package/docs/reference/HERMES_INTEGRATION.md +118 -0
  39. package/docs/reference/INSIGHTS_RECAP.md +63 -0
  40. package/docs/reference/INSTALL.md +164 -0
  41. package/docs/reference/KERNEL_TAXONOMY_VALIDATION.md +161 -0
  42. package/docs/reference/PROTECTED_PATH_MANIFEST.md +25 -0
  43. package/docs/reference/RELEASE.md +68 -0
  44. package/docs/reference/RESEARCH_TEMPLATE.md +292 -0
  45. package/docs/{ROADMAP.md → reference/ROADMAP.md} +12 -9
  46. package/docs/reference/SKILLS.md +35 -0
  47. package/docs/reference/STATUS_BOARD.md +80 -0
  48. package/docs/reference/TEMPLATES.md +106 -0
  49. package/docs/{TOOLCHAIN.md → reference/TOOLCHAIN.md} +62 -47
  50. package/docs/reference/VALIDATION.md +82 -0
  51. package/docs/reference/agent-permissions.md +169 -0
  52. package/docs/reference/beads-to-kernel-migration-ux.md +61 -0
  53. package/docs/reference/control-plane-guarantees.md +125 -0
  54. package/docs/reference/dependency-chain.md +331 -0
  55. package/docs/reference/forge-kernel-issue-command-contract.md +161 -0
  56. package/docs/reference/forge-kernel-schema.md +72 -0
  57. package/docs/reference/kernel-conflict-evaluators.md +27 -0
  58. package/docs/reference/patch-md-format.md +77 -0
  59. package/docs/reference/protected-state-surfaces.md +59 -0
  60. package/docs/reference/shepherd.md +155 -0
  61. package/docs/reference/superpowers-analysis.md +320 -0
  62. package/docs/reference/superpowers-integration-options.md +404 -0
  63. package/docs/reference/test-environment.md +519 -0
  64. package/docs/reference/upgrade-safety.md +59 -0
  65. package/lefthook.yml +18 -0
  66. package/lib/activation/ensure-forge-home.js +135 -0
  67. package/lib/adapter-cli.js +307 -0
  68. package/lib/adapters/beads-issue-adapter.js +127 -0
  69. package/lib/adapters/beads-kernel-compat.js +1109 -0
  70. package/lib/adapters/greptile-review-adapter.js +141 -0
  71. package/lib/adapters/kernel-issue-adapter.js +101 -0
  72. package/lib/adapters/pr-state-adapter.js +484 -0
  73. package/lib/adoption-profiles.js +139 -0
  74. package/lib/agents/README.md +2 -6
  75. package/lib/agents/claude.plugin.json +3 -8
  76. package/lib/agents/codex.plugin.json +9 -1
  77. package/lib/agents/cursor.plugin.json +2 -6
  78. package/lib/agents/hermes.plugin.json +22 -0
  79. package/lib/agents-config.js +39 -1236
  80. package/lib/audit-evidence.js +282 -0
  81. package/lib/beads-detect.js +60 -0
  82. package/lib/beads-nudge.js +91 -0
  83. package/lib/beads-setup.js +121 -0
  84. package/lib/beads-sync-scaffold.js +25 -101
  85. package/lib/codex-skills.js +51 -1
  86. package/lib/commands/_aliases.js +248 -0
  87. package/lib/commands/_issue.js +780 -77
  88. package/lib/commands/_manifest.js +93 -0
  89. package/lib/commands/_registry.js +99 -34
  90. package/lib/commands/_resolve-command-opts.js +230 -0
  91. package/lib/commands/_serve-security.js +270 -0
  92. package/lib/commands/adapter.js +12 -0
  93. package/lib/commands/add.js +118 -0
  94. package/lib/commands/audit.js +70 -0
  95. package/lib/commands/blocked.js +5 -0
  96. package/lib/commands/board.js +64 -0
  97. package/lib/commands/claim.js +21 -2
  98. package/lib/commands/claims.js +7 -0
  99. package/lib/commands/clean.js +485 -75
  100. package/lib/commands/close.js +2 -2
  101. package/lib/commands/comment.js +5 -0
  102. package/lib/commands/control.js +148 -0
  103. package/lib/commands/create.js +2 -2
  104. package/lib/commands/dev.js +185 -7
  105. package/lib/commands/doc-gate.js +336 -0
  106. package/lib/commands/doctor.js +156 -0
  107. package/lib/commands/explain.js +15 -0
  108. package/lib/commands/export.js +237 -0
  109. package/lib/commands/gate.js +209 -0
  110. package/lib/commands/hooks.js +377 -0
  111. package/lib/commands/inbox.js +118 -0
  112. package/lib/commands/init.js +604 -0
  113. package/lib/commands/insights.js +79 -0
  114. package/lib/commands/issue.js +12 -1
  115. package/lib/commands/issues.js +17 -0
  116. package/lib/commands/lint.js +5 -0
  117. package/lib/commands/list.js +2 -2
  118. package/lib/commands/memory.js +81 -0
  119. package/lib/commands/merge.js +312 -0
  120. package/lib/commands/migrate.js +362 -0
  121. package/lib/commands/new.js +12 -0
  122. package/lib/commands/options.js +241 -0
  123. package/lib/commands/orient.js +13 -0
  124. package/lib/commands/orphans.js +5 -0
  125. package/lib/commands/patch.js +67 -0
  126. package/lib/commands/plan.js +481 -29
  127. package/lib/commands/pr.js +88 -0
  128. package/lib/commands/preflight.js +211 -0
  129. package/lib/commands/prime.js +13 -0
  130. package/lib/commands/push.js +135 -2
  131. package/lib/commands/ready.js +2 -2
  132. package/lib/commands/recall.js +171 -0
  133. package/lib/commands/recap.js +75 -0
  134. package/lib/commands/recommend.js +0 -1
  135. package/lib/commands/release.js +104 -0
  136. package/lib/commands/remember.js +140 -0
  137. package/lib/commands/role.js +99 -0
  138. package/lib/commands/serve.js +581 -0
  139. package/lib/commands/setup.js +900 -971
  140. package/lib/commands/shepherd.js +501 -0
  141. package/lib/commands/ship.js +59 -1
  142. package/lib/commands/show.js +2 -2
  143. package/lib/commands/stage.js +192 -0
  144. package/lib/commands/stale.js +5 -0
  145. package/lib/commands/status.js +158 -21
  146. package/lib/commands/sync.js +34 -46
  147. package/lib/commands/team.js +4 -1
  148. package/lib/commands/test.js +43 -27
  149. package/lib/commands/update.js +2 -2
  150. package/lib/commands/upgrade.js +47 -0
  151. package/lib/commands/validate.js +43 -18
  152. package/lib/commands/worktree.js +362 -99
  153. package/lib/config-writer.js +202 -0
  154. package/lib/control-plane.js +236 -0
  155. package/lib/core/runtime-graph.js +977 -0
  156. package/lib/dep-guard/keyword-ripple.js +2 -2
  157. package/lib/deprecated-sync-cleanup.js +362 -0
  158. package/lib/detect-agent.js +2 -28
  159. package/lib/detect-worktree.js +35 -9
  160. package/lib/doc-gate/declaration.js +177 -0
  161. package/lib/doc-gate/detect.js +289 -0
  162. package/lib/doc-gate/gate.js +375 -0
  163. package/lib/doc-gate/okf-config.js +128 -0
  164. package/lib/doc-gate/okf.js +429 -0
  165. package/lib/docs-command.js +1161 -6
  166. package/lib/forge-issues.js +382 -11
  167. package/lib/forge-lock.js +262 -0
  168. package/lib/gate-events.js +192 -0
  169. package/lib/global-flags.js +104 -0
  170. package/lib/greptile-match.js +7 -63
  171. package/lib/grounding/context-events.js +230 -0
  172. package/lib/grounding/read-first.js +112 -0
  173. package/lib/harness-capability-matrix.js +380 -0
  174. package/lib/hook-global-installer.js +347 -0
  175. package/lib/hook-renderer.js +541 -0
  176. package/lib/inbox.js +391 -0
  177. package/lib/insights.js +397 -0
  178. package/lib/issue-adapter.js +156 -0
  179. package/lib/issue-backend.js +145 -0
  180. package/lib/issue-render.js +220 -0
  181. package/lib/kernel/backing-issue.js +311 -0
  182. package/lib/kernel/broker.js +1218 -0
  183. package/lib/kernel/cli-broker-factory.js +130 -0
  184. package/lib/kernel/conflict-signal.js +82 -0
  185. package/lib/kernel/evaluators.js +195 -0
  186. package/lib/kernel/fs-class.js +495 -0
  187. package/lib/kernel/issue-command-contract.js +559 -0
  188. package/lib/kernel/issue-id-resolver.js +186 -0
  189. package/lib/kernel/lease-enforcer.js +158 -0
  190. package/lib/kernel/migrations.js +333 -0
  191. package/lib/kernel/owned-kernel.js +43 -0
  192. package/lib/kernel/planning-buckets-schema.js +109 -0
  193. package/lib/kernel/projection-jsonl-writer.js +450 -0
  194. package/lib/kernel/readiness-model.js +329 -0
  195. package/lib/kernel/schema.js +356 -0
  196. package/lib/kernel/sqlite-driver.js +2540 -0
  197. package/lib/kernel/taxonomy-validator.js +394 -0
  198. package/lib/lefthook-check.js +3 -2
  199. package/lib/lefthook-wiring.js +413 -0
  200. package/lib/mcp-config-renderer.js +288 -0
  201. package/lib/memory/graphiti-mcp.js +106 -0
  202. package/lib/memory/router.js +387 -0
  203. package/lib/memory/typed-api.js +102 -0
  204. package/lib/memory-digest.js +195 -0
  205. package/lib/merge-rules.js +395 -0
  206. package/lib/migrate-dry-run.js +466 -0
  207. package/lib/orientation.js +863 -0
  208. package/lib/package-manager-remediation.js +103 -0
  209. package/lib/package-root.js +381 -0
  210. package/lib/patch-intent.js +890 -0
  211. package/lib/plugin-catalog.js +3 -4
  212. package/lib/plugin-manager.js +0 -5
  213. package/lib/pr-bundle.js +186 -0
  214. package/lib/pr-monitor/auto-actions.js +175 -0
  215. package/lib/pr-monitor/differ.js +195 -0
  216. package/lib/pr-monitor/digest.js +206 -0
  217. package/lib/pr-monitor/events.js +0 -0
  218. package/lib/pr-monitor/gather.js +124 -0
  219. package/lib/pr-monitor/journal.js +299 -0
  220. package/lib/pr-monitor/monitor.js +146 -0
  221. package/lib/pr-monitor/render-sticky.js +192 -0
  222. package/lib/pr-monitor/upsert-sticky.js +169 -0
  223. package/lib/pr-monitor/watch-lifecycle.js +95 -0
  224. package/lib/pr-monitor/watch.js +247 -0
  225. package/lib/pr-pull.js +1314 -0
  226. package/lib/pr-shepherd.js +494 -0
  227. package/lib/pr-state-validator.js +59 -0
  228. package/lib/preflight/gates.js +237 -0
  229. package/lib/preflight/runner.js +116 -0
  230. package/lib/project-discovery.js +0 -53
  231. package/lib/project-memory.js +99 -497
  232. package/lib/protected-path-manifest.js +281 -0
  233. package/lib/protected-state-surfaces.js +387 -0
  234. package/lib/release-readiness.js +2105 -0
  235. package/lib/reset.js +59 -45
  236. package/lib/review-adapter.js +68 -0
  237. package/lib/rules-sync.js +260 -0
  238. package/lib/runtime-health.js +241 -20
  239. package/lib/safety-config-renderer.js +268 -0
  240. package/lib/setup-action-log.js +1 -7
  241. package/lib/setup.js +27 -65
  242. package/lib/shell-utils.js +76 -6
  243. package/lib/skills-sync.js +330 -0
  244. package/lib/smart-status/scoring.js +17 -3
  245. package/lib/status/beads-snapshot.js +45 -2
  246. package/lib/status/presenter.js +169 -18
  247. package/lib/status/snapshot.js +186 -0
  248. package/lib/sync-backend.js +202 -0
  249. package/lib/untrusted-content.js +52 -0
  250. package/lib/upgrade-safety.js +251 -0
  251. package/lib/workflow/enforce-stage.js +351 -45
  252. package/lib/workflow/stage-transition.js +115 -0
  253. package/lib/workflow/stages.js +30 -6
  254. package/lib/workflow/state-manager.js +11 -22
  255. package/lib/workflow/state.js +23 -1
  256. package/lib/workflow-profiles.js +17 -5
  257. package/package.json +37 -35
  258. package/rules/documentation.md +19 -0
  259. package/rules/kernel-tracking.md +26 -0
  260. package/rules/security.md +22 -0
  261. package/rules/tdd.md +20 -0
  262. package/rules/workflow.md +27 -0
  263. package/scripts/auto-backing-issue.js +47 -0
  264. package/scripts/beads-context.sh +81 -57
  265. package/scripts/beads-upgrade-smoke.sh +24 -3
  266. package/scripts/bootstrap-windows-tools.sh +78 -0
  267. package/scripts/branch-protection.js +2 -3
  268. package/scripts/check-agents.js +34 -137
  269. package/scripts/commitlint.js +3 -1
  270. package/scripts/conflict-detect.sh +3 -0
  271. package/scripts/dep-guard.sh +22 -3
  272. package/scripts/file-index.sh +3 -0
  273. package/scripts/forge-team/lib/claim.sh +34 -18
  274. package/scripts/forge-team/lib/dashboard.sh +61 -86
  275. package/scripts/forge-team/lib/epic.sh +99 -263
  276. package/scripts/forge-team/lib/hooks.sh +26 -28
  277. package/scripts/forge-team/lib/identity.sh +4 -4
  278. package/scripts/forge-team/lib/sync-github.sh +49 -84
  279. package/scripts/forge-team/lib/verify.sh +93 -83
  280. package/scripts/forge-team/lib/workload.sh +41 -65
  281. package/scripts/forge-team/tests/claim.test.sh +25 -19
  282. package/scripts/forge-team/tests/dashboard.test.sh +31 -46
  283. package/scripts/forge-team/tests/epic.test.sh +52 -71
  284. package/scripts/forge-team/tests/hooks.test.sh +38 -50
  285. package/scripts/forge-team/tests/identity.test.sh +3 -3
  286. package/scripts/forge-team/tests/integration.test.sh +44 -66
  287. package/scripts/forge-team/tests/sync-github.test.sh +50 -83
  288. package/scripts/forge-team/tests/verify.test.sh +37 -46
  289. package/scripts/forge-team/tests/workflow-integration.test.sh +4 -4
  290. package/scripts/forge-team/tests/workload.test.sh +32 -66
  291. package/scripts/gen-command-manifest.js +153 -0
  292. package/scripts/gen-embedded-assets.mjs +129 -0
  293. package/scripts/install.ps1 +139 -0
  294. package/scripts/install.sh +268 -0
  295. package/scripts/lib/release-asset.mjs +84 -0
  296. package/scripts/parity-check.mjs +145 -0
  297. package/scripts/parity-check.test.mjs +58 -0
  298. package/scripts/pin-agentic-workflow-images.js +112 -0
  299. package/scripts/pr-auto-actions.js +93 -0
  300. package/scripts/pr-coordinator.sh +3 -0
  301. package/scripts/pr-verdict-label.js +50 -0
  302. package/scripts/preflight-sonar.eslint.config.mjs +44 -0
  303. package/scripts/preflight.sh +21 -94
  304. package/scripts/protected-state-check.js +104 -0
  305. package/scripts/smart-status.sh +60 -57
  306. package/scripts/spikes/config-race-bench.js +111 -0
  307. package/scripts/spikes/harness-capability-matrix.js +13 -0
  308. package/scripts/spikes/patch-anchor-stability-bench.js +125 -0
  309. package/scripts/spikes/protected-path-manifest.js +20 -0
  310. package/scripts/spikes/skill-auto-invoke-parity.js +292 -0
  311. package/scripts/sync-agent-skills.js +62 -0
  312. package/scripts/sync-utils.sh +3 -0
  313. package/scripts/test-ci-shard.js +13 -6
  314. package/scripts/test.js +95 -12
  315. package/skills/claim-safety/SKILL.md +102 -0
  316. package/skills/claim-safety/evals/evals.json +46 -0
  317. package/{.github/prompts/dev.prompt.md → skills/dev/SKILL.md} +44 -50
  318. package/skills/dev/evals/evals.json +50 -0
  319. package/skills/hermes-forge/SKILL.md +185 -0
  320. package/skills/hermes-forge/evals/evals.json +46 -0
  321. package/skills/issue-basics/SKILL.md +111 -0
  322. package/skills/issue-basics/evals/evals.json +46 -0
  323. package/skills/kernel/SKILL.md +166 -0
  324. package/skills/kernel/evals/evals.json +50 -0
  325. package/skills/memory/SKILL.md +102 -0
  326. package/skills/parallel-deep-research/SKILL.md +14 -11
  327. package/skills/parallel-deep-research/evals/evals.json +11 -27
  328. package/{.github/prompts/plan.prompt.md → skills/plan/SKILL.md} +132 -157
  329. package/skills/plan/evals/evals.json +42 -0
  330. package/skills/research/SKILL.md +195 -0
  331. package/skills/research/evals/evals.json +42 -0
  332. package/{.github/prompts/review.prompt.md → skills/review/SKILL.md} +98 -62
  333. package/skills/review/evals/evals.json +42 -0
  334. package/skills/rollback/SKILL.md +110 -0
  335. package/skills/rollback/evals/evals.json +46 -0
  336. package/skills/rollback/references/methods.md +204 -0
  337. package/{.cursor/commands/rollback.md → skills/rollback/references/workflow-integration.md} +10 -284
  338. package/skills/shepherd/SKILL.md +66 -0
  339. package/skills/shepherd/evals/evals.json +42 -0
  340. package/{.github/prompts/ship.prompt.md → skills/ship/SKILL.md} +81 -45
  341. package/skills/ship/evals/evals.json +42 -0
  342. package/skills/smith/SKILL.md +142 -0
  343. package/skills/smith/evals/evals.json +46 -0
  344. package/skills/smith/references/autonomy-and-gates.md +94 -0
  345. package/{.github/prompts/sonarcloud.prompt.md → skills/sonarcloud/SKILL.md} +14 -3
  346. package/skills/sonarcloud/evals/evals.json +46 -0
  347. package/skills/sonarcloud-analysis/SKILL.md +18 -13
  348. package/skills/sonarcloud-analysis/evals/evals.json +11 -15
  349. package/{.github/prompts/status.prompt.md → skills/status/SKILL.md} +20 -10
  350. package/skills/status/evals/evals.json +50 -0
  351. package/skills/triage-ready/SKILL.md +121 -0
  352. package/skills/triage-ready/evals/evals.json +42 -0
  353. package/{.github/prompts/validate.prompt.md → skills/validate/SKILL.md} +52 -29
  354. package/skills/validate/evals/evals.json +42 -0
  355. package/skills/verify/SKILL.md +299 -0
  356. package/skills/verify/evals/evals.json +50 -0
  357. package/.claude/commands/dev.md +0 -345
  358. package/.claude/commands/plan.md +0 -566
  359. package/.claude/commands/premerge.md +0 -186
  360. package/.claude/commands/research.md +0 -42
  361. package/.claude/commands/review.md +0 -451
  362. package/.claude/commands/rollback.md +0 -721
  363. package/.claude/commands/ship.md +0 -213
  364. package/.claude/commands/sonarcloud.md +0 -152
  365. package/.claude/commands/status.md +0 -90
  366. package/.claude/commands/validate.md +0 -288
  367. package/.claude/commands/verify.md +0 -269
  368. package/.claude/rules/workflow.md +0 -121
  369. package/.cline/workflows/dev.md +0 -342
  370. package/.cline/workflows/plan.md +0 -563
  371. package/.cline/workflows/premerge.md +0 -183
  372. package/.cline/workflows/research.md +0 -39
  373. package/.cline/workflows/review.md +0 -448
  374. package/.cline/workflows/rollback.md +0 -718
  375. package/.cline/workflows/ship.md +0 -210
  376. package/.cline/workflows/sonarcloud.md +0 -146
  377. package/.cline/workflows/status.md +0 -87
  378. package/.cline/workflows/validate.md +0 -285
  379. package/.cline/workflows/verify.md +0 -266
  380. package/.codex/config.toml +0 -11
  381. package/.codex/skills/dev/SKILL.md +0 -345
  382. package/.codex/skills/plan/SKILL.md +0 -566
  383. package/.codex/skills/premerge/SKILL.md +0 -186
  384. package/.codex/skills/research/SKILL.md +0 -42
  385. package/.codex/skills/review/SKILL.md +0 -451
  386. package/.codex/skills/rollback/SKILL.md +0 -721
  387. package/.codex/skills/ship/SKILL.md +0 -213
  388. package/.codex/skills/sonarcloud/SKILL.md +0 -149
  389. package/.codex/skills/status/SKILL.md +0 -90
  390. package/.codex/skills/validate/SKILL.md +0 -288
  391. package/.codex/skills/verify/SKILL.md +0 -269
  392. package/.cursor/commands/dev.md +0 -342
  393. package/.cursor/commands/plan.md +0 -563
  394. package/.cursor/commands/premerge.md +0 -183
  395. package/.cursor/commands/research.md +0 -39
  396. package/.cursor/commands/review.md +0 -448
  397. package/.cursor/commands/ship.md +0 -210
  398. package/.cursor/commands/sonarcloud.md +0 -146
  399. package/.cursor/commands/status.md +0 -87
  400. package/.cursor/commands/validate.md +0 -285
  401. package/.cursor/commands/verify.md +0 -266
  402. package/.cursorrules +0 -149
  403. package/.github/prompts/premerge.prompt.md +0 -188
  404. package/.github/prompts/research.prompt.md +0 -44
  405. package/.github/prompts/rollback.prompt.md +0 -723
  406. package/.github/prompts/verify.prompt.md +0 -271
  407. package/.github/workflows/beads-to-github.yml +0 -89
  408. package/.github/workflows/github-to-beads.yml +0 -100
  409. package/.kilocode/workflows/dev.md +0 -346
  410. package/.kilocode/workflows/plan.md +0 -567
  411. package/.kilocode/workflows/premerge.md +0 -187
  412. package/.kilocode/workflows/research.md +0 -43
  413. package/.kilocode/workflows/review.md +0 -452
  414. package/.kilocode/workflows/rollback.md +0 -722
  415. package/.kilocode/workflows/ship.md +0 -214
  416. package/.kilocode/workflows/sonarcloud.md +0 -150
  417. package/.kilocode/workflows/status.md +0 -91
  418. package/.kilocode/workflows/validate.md +0 -289
  419. package/.kilocode/workflows/verify.md +0 -270
  420. package/.opencode/commands/dev.md +0 -345
  421. package/.opencode/commands/plan.md +0 -566
  422. package/.opencode/commands/premerge.md +0 -186
  423. package/.opencode/commands/research.md +0 -42
  424. package/.opencode/commands/review.md +0 -451
  425. package/.opencode/commands/rollback.md +0 -721
  426. package/.opencode/commands/ship.md +0 -213
  427. package/.opencode/commands/sonarcloud.md +0 -149
  428. package/.opencode/commands/status.md +0 -90
  429. package/.opencode/commands/validate.md +0 -288
  430. package/.opencode/commands/verify.md +0 -269
  431. package/.roo/commands/dev.md +0 -346
  432. package/.roo/commands/plan.md +0 -567
  433. package/.roo/commands/premerge.md +0 -187
  434. package/.roo/commands/research.md +0 -43
  435. package/.roo/commands/review.md +0 -452
  436. package/.roo/commands/rollback.md +0 -722
  437. package/.roo/commands/ship.md +0 -214
  438. package/.roo/commands/sonarcloud.md +0 -150
  439. package/.roo/commands/status.md +0 -91
  440. package/.roo/commands/validate.md +0 -289
  441. package/.roo/commands/verify.md +0 -270
  442. package/docs/BEADS_GITHUB_SYNC.md +0 -281
  443. package/docs/GREPTILE_SETUP.md +0 -400
  444. package/docs/MANUAL_REVIEW_GUIDE.md +0 -106
  445. package/docs/SETUP.md +0 -663
  446. package/docs/VALIDATION.md +0 -363
  447. package/lib/agents/cline.plugin.json +0 -29
  448. package/lib/agents/copilot.plugin.json +0 -24
  449. package/lib/agents/kilocode.plugin.json +0 -22
  450. package/lib/agents/opencode.plugin.json +0 -23
  451. package/lib/agents/roo.plugin.json +0 -30
  452. package/lib/beads-bootstrap.js +0 -225
  453. package/lib/beads-health-check.js +0 -188
  454. package/lib/commands/commands-reset.js +0 -147
  455. package/opencode.json +0 -67
  456. package/scripts/beads-context.test.js +0 -584
  457. package/scripts/github-beads-sync/comment.mjs +0 -64
  458. package/scripts/github-beads-sync/config.mjs +0 -148
  459. package/scripts/github-beads-sync/github-api.mjs +0 -131
  460. package/scripts/github-beads-sync/index.mjs +0 -356
  461. package/scripts/github-beads-sync/label-mapper.mjs +0 -54
  462. package/scripts/github-beads-sync/mapping.mjs +0 -132
  463. package/scripts/github-beads-sync/reverse-sync-cli.mjs +0 -31
  464. package/scripts/github-beads-sync/reverse-sync.mjs +0 -162
  465. package/scripts/github-beads-sync/run-bd.mjs +0 -161
  466. package/scripts/github-beads-sync/sanitize.mjs +0 -121
  467. package/scripts/github-beads-sync.config.json +0 -26
  468. package/scripts/sync-commands.js +0 -600
@@ -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