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,202 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * @module config-writer
5
+ *
6
+ * Sparse read-modify-write for the ONE schema-validated config surface,
7
+ * `.forge/config.yaml` (the file `lib/core/runtime-graph.js` reads via
8
+ * `loadRuntimeGraphConfig`). This is the single missing primitive behind the
9
+ * `forge gate` / `forge role` verbs: create-or-update the file, set/remove one
10
+ * nested key, and preserve every other key untouched.
11
+ *
12
+ * Design: docs/work/2026-07-04-kernel-native-skills/extensibility-architecture.md
13
+ * (§9 "the sparse writer"). This is NOT a generalization of the legacy
14
+ * `.forge/adapters.json` review writer — that path stays where it is.
15
+ *
16
+ * Key paths are ARRAYS of segments, not dotted strings, because real keys
17
+ * contain dots (e.g. the gate id `gate.plan-exit`). Splitting on `.` would
18
+ * corrupt them, so callers pass `['workflow', 'gates', 'gate.plan-exit',
19
+ * 'enabled']`.
20
+ */
21
+
22
+ const fs = require('node:fs');
23
+ const path = require('node:path');
24
+ const YAML = require('yaml');
25
+ const { getPackageRoot } = require('./package-root');
26
+
27
+ /** Root of the installed Forge package (ships the canonical `skills/` dir). */
28
+ const PACKAGE_ROOT = path.join(__dirname, '..');
29
+
30
+ const CONFIG_RELATIVE = path.join('.forge', 'config.yaml');
31
+
32
+ function getConfigPath(projectRoot = process.cwd()) {
33
+ return path.join(projectRoot, '.forge', 'config.yaml');
34
+ }
35
+
36
+ function assertKeyPath(keyPath) {
37
+ if (!Array.isArray(keyPath) || keyPath.length === 0
38
+ || keyPath.some(seg => typeof seg !== 'string' || seg === '')) {
39
+ throw new Error('config-writer: keyPath must be a non-empty array of non-empty string segments.');
40
+ }
41
+ }
42
+
43
+ /** Load the raw config object (or `{}` if the file is absent/empty). */
44
+ function loadRawConfig(projectRoot = process.cwd()) {
45
+ const configPath = getConfigPath(projectRoot);
46
+ if (!fs.existsSync(configPath)) return {};
47
+ const raw = fs.readFileSync(configPath, 'utf8');
48
+ if (raw.trim() === '') return {};
49
+ const parsed = YAML.parse(raw);
50
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
51
+ throw new Error(`${CONFIG_RELATIVE} root must be an object.`);
52
+ }
53
+ return parsed;
54
+ }
55
+
56
+ function writeRawConfig(projectRoot, config) {
57
+ const configPath = getConfigPath(projectRoot);
58
+ fs.mkdirSync(path.dirname(configPath), { recursive: true });
59
+ fs.writeFileSync(configPath, YAML.stringify(config));
60
+ return configPath;
61
+ }
62
+
63
+ /**
64
+ * Set a nested key to `value`, creating intermediate objects as needed and
65
+ * preserving all sibling keys. Creates `.forge/config.yaml` if absent.
66
+ *
67
+ * @param {string} projectRoot
68
+ * @param {string[]} keyPath - Segments, e.g. ['roles', 'plan', 'skill'].
69
+ * @param {*} value
70
+ * @returns {{config: object, configPath: string}}
71
+ */
72
+ function setConfigOverride(projectRoot, keyPath, value) {
73
+ assertKeyPath(keyPath);
74
+ const config = loadRawConfig(projectRoot);
75
+ let node = config;
76
+ for (let i = 0; i < keyPath.length - 1; i += 1) {
77
+ const key = keyPath[i];
78
+ if (!node[key] || typeof node[key] !== 'object' || Array.isArray(node[key])) {
79
+ node[key] = {};
80
+ }
81
+ node = node[key];
82
+ }
83
+ node[keyPath[keyPath.length - 1]] = value;
84
+ return { config, configPath: writeRawConfig(projectRoot, config) };
85
+ }
86
+
87
+ /**
88
+ * Remove a nested key (a "reset" to the profile/default). Prunes ancestor
89
+ * objects that become empty so the surface stays sparse. No-op if the key is
90
+ * absent or the file does not exist.
91
+ *
92
+ * @param {string} projectRoot
93
+ * @param {string[]} keyPath
94
+ * @returns {{config: object, configPath: string, removed: boolean}}
95
+ */
96
+ function removeConfigOverride(projectRoot, keyPath) {
97
+ assertKeyPath(keyPath);
98
+ const configPath = getConfigPath(projectRoot);
99
+ if (!fs.existsSync(configPath)) {
100
+ return { config: {}, configPath, removed: false };
101
+ }
102
+ const config = loadRawConfig(projectRoot);
103
+ const chain = [config];
104
+ let node = config;
105
+ for (let i = 0; i < keyPath.length - 1; i += 1) {
106
+ const key = keyPath[i];
107
+ if (!node[key] || typeof node[key] !== 'object' || Array.isArray(node[key])) {
108
+ return { config, configPath, removed: false };
109
+ }
110
+ node = node[key];
111
+ chain.push(node);
112
+ }
113
+ const leaf = keyPath[keyPath.length - 1];
114
+ if (!Object.hasOwn(node, leaf)) {
115
+ return { config, configPath, removed: false };
116
+ }
117
+ delete node[leaf];
118
+ // Prune now-empty ancestor objects, deepest first.
119
+ for (let i = chain.length - 1; i > 0; i -= 1) {
120
+ if (Object.keys(chain[i]).length === 0) {
121
+ delete chain[i - 1][keyPath[i - 1]];
122
+ } else {
123
+ break;
124
+ }
125
+ }
126
+ return { config, configPath: writeRawConfig(projectRoot, config), removed: true };
127
+ }
128
+
129
+ /** Project-local skill dirs (highest precedence), independent of any extraction. */
130
+ function localSkillSearchDirs(projectRoot = process.cwd()) {
131
+ return [path.join(projectRoot, '.skills'), path.join(projectRoot, 'skills')];
132
+ }
133
+
134
+ /**
135
+ * The packaged (shipped-default) skills dir — resolved LAZILY and NON-throwing.
136
+ * In a compiled binary this triggers asset extraction, so it must only run after
137
+ * the project-local dirs miss (and must never abort skill resolution if assets
138
+ * cannot be resolved). Returns null if unavailable.
139
+ */
140
+ function packagedSkillsDir() {
141
+ try {
142
+ return path.join(getPackageRoot(PACKAGE_ROOT), 'skills');
143
+ } catch {
144
+ return null;
145
+ }
146
+ }
147
+
148
+ /**
149
+ * Directories searched (in precedence order) when resolving a skill name.
150
+ * Mirrors the skills-sync precedence: `.skills/` shadow wins over canonical
151
+ * `skills/`, then the installed package's shipped defaults (resolved lazily).
152
+ */
153
+ function skillSearchDirs(projectRoot = process.cwd()) {
154
+ const dirs = localSkillSearchDirs(projectRoot);
155
+ const packaged = packagedSkillsDir();
156
+ if (packaged) dirs.push(packaged);
157
+ return dirs;
158
+ }
159
+
160
+ /**
161
+ * Resolve a skill NAME to a real `SKILL.md` via `.skills/ > skills/`
162
+ * precedence. Returns null if no such skill exists — the `forge role` verb
163
+ * uses this for write-time validation so an unresolvable skill errors before
164
+ * anything is written (never mid-run).
165
+ *
166
+ * @param {string} projectRoot
167
+ * @param {string} name
168
+ * @returns {{name: string, dir: string, path: string}|null}
169
+ */
170
+ function resolveSkill(projectRoot, name) {
171
+ if (typeof name !== 'string' || name === ''
172
+ || name.includes('/') || name.includes('\\') || name.includes('\0')
173
+ || name === '.' || name === '..') {
174
+ return null;
175
+ }
176
+ // Check project-local dirs FIRST — these never trigger extraction, so a
177
+ // project-local skill resolves without touching the packaged fallback.
178
+ for (const dir of localSkillSearchDirs(projectRoot)) {
179
+ const skillMd = path.join(dir, name, 'SKILL.md');
180
+ if (fs.existsSync(skillMd)) {
181
+ return { name, dir, path: skillMd };
182
+ }
183
+ }
184
+ // Only now resolve the packaged fallback (lazy, non-throwing).
185
+ const packaged = packagedSkillsDir();
186
+ if (packaged) {
187
+ const skillMd = path.join(packaged, name, 'SKILL.md');
188
+ if (fs.existsSync(skillMd)) {
189
+ return { name, dir: packaged, path: skillMd };
190
+ }
191
+ }
192
+ return null;
193
+ }
194
+
195
+ module.exports = {
196
+ getConfigPath,
197
+ loadRawConfig,
198
+ setConfigOverride,
199
+ removeConfigOverride,
200
+ resolveSkill,
201
+ skillSearchDirs,
202
+ };
@@ -0,0 +1,236 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * @module control-plane
5
+ *
6
+ * The single source of truth for the **control-plane guarantee matrix**
7
+ * (docs/reference/control-plane-guarantees.md): it classifies each control
8
+ * surface, names its enforcement-locus, derives the tri-state label, renders the
9
+ * honest read badge, and resolves a `forge control` write-intent into the ONE
10
+ * resolver-enforced field — `workflow.gates.<id>.enabled`.
11
+ *
12
+ * Why this module exists: the cockpit uses a tri-state vocabulary
13
+ * (`mandatory` / `optional` / `permission`), but that vocabulary is only
14
+ * meaningful where Forge can actually DENY at run time — on gates and rails. On
15
+ * MCP servers, rules, and skills there is no run-time deny; "mandatory" there
16
+ * would mean nothing more than *the file is present*. This module draws that
17
+ * line so the UI and the `forge control` command never sell enforcement Forge
18
+ * cannot deliver. Pure + dependency-free so it is trivially testable and shared
19
+ * by the command, `forge options`, and any dashboard snapshot.
20
+ */
21
+
22
+ /** The closed set of human gates — satisfied by a `gate.approved` kernel EVENT. */
23
+ const HUMAN_GATE_IDS = new Set(['gate.intent', 'gate.plan-approval', 'gate.merge']);
24
+
25
+ const CONTROLLABLE_SURFACES = new Set(['gate', 'human-gate', 'rail']);
26
+
27
+ const GUARANTEE_DOC = 'docs/reference/control-plane-guarantees.md';
28
+
29
+ const VALID_STATES = new Set(['mandatory', 'optional', 'permission']);
30
+
31
+ /**
32
+ * Classify a control id into its surface. The id namespaces are disjoint, so a
33
+ * prefix match is unambiguous; the three human gates are singled out because
34
+ * their enforcement-locus (a human approval event) differs from ordinary gates.
35
+ *
36
+ * @param {string} id
37
+ * @returns {'gate'|'human-gate'|'rail'|'mcp'|'rule'|'skill'|'unknown'}
38
+ */
39
+ function classifySurface(id) {
40
+ if (typeof id !== 'string') return 'unknown';
41
+ if (HUMAN_GATE_IDS.has(id)) return 'human-gate';
42
+ if (id.startsWith('gate.')) return 'gate';
43
+ if (id.startsWith('rail.')) return 'rail';
44
+ if (id.startsWith('mcp.')) return 'mcp';
45
+ if (id.startsWith('rule.')) return 'rule';
46
+ if (id.startsWith('skill.')) return 'skill';
47
+ return 'unknown';
48
+ }
49
+
50
+ /**
51
+ * True only for surfaces `forge control` can CONFIGURE (gates + rails).
52
+ *
53
+ * NOTE: "controllable" means CLI-configurable, NOT runtime-enforced — the two are
54
+ * deliberately separate. Configuring one of these writes a declared flag; whether
55
+ * anything actually denies on it is a distinct question answered by
56
+ * `enforcementLocus` (today: nothing does). See docs/reference/control-plane-guarantees.md.
57
+ */
58
+ function isControllable(id) {
59
+ return CONTROLLABLE_SURFACES.has(classifySurface(id));
60
+ }
61
+
62
+ /**
63
+ * The honest enforcement-locus — WHERE and WHETHER Forge actually consumes this
64
+ * flag TODAY (as of 2026-07-15). This deliberately does NOT claim `run-time-deny`
65
+ * for the configurable gates/rails, because an adversarial grep of every consumer
66
+ * of the resolved graph found NONE that denies on `workflow.gates.<id>.enabled`:
67
+ *
68
+ * - stage-exit gates + rails: no runtime consumer reads their `.enabled` to
69
+ * refuse. `enforce-stage.js` enforces stage ORDER + kernel COMPLETION, which
70
+ * is independent of these flags. → "registry — declared, not yet enforced".
71
+ * - `gate.issue_verify`: consumed by lib/commands/_issue.js, but WARN-ONLY —
72
+ * a mismatch prints a warning and never overturns the write's `ok`.
73
+ * - human gates: the `forge gate approve`/`check` primitives are real and
74
+ * deny-CAPABLE, but no chokepoint auto-invokes `forge gate check`, so nothing
75
+ * denies on them yet. → "deny-on-check (no chokepoint yet)".
76
+ *
77
+ * Real enforcement today lives elsewhere and is independent of these flags: the
78
+ * B3 lefthook TDD pre-commit hook, B2 fail-closed `validate`/`preflight`, and
79
+ * `enforce-stage` order+completion. See docs/reference/control-plane-guarantees.md.
80
+ *
81
+ * @param {string} id
82
+ */
83
+ function enforcementLocus(id) {
84
+ const surface = classifySurface(id);
85
+ if (surface === 'human-gate') {
86
+ return 'deny-on-check (deny-capable via forge gate check; no chokepoint invokes it yet)';
87
+ }
88
+ if (id === 'gate.issue_verify') {
89
+ return 'run-time verify (warn-only, never denies)';
90
+ }
91
+ if (surface === 'gate' || surface === 'rail') {
92
+ return 'registry — declared, not yet enforced';
93
+ }
94
+ // mcp / rule / skill / unknown — presence written into harness config only.
95
+ return 'render-time presence-only';
96
+ }
97
+
98
+ /**
99
+ * Derive the tri-state label from the resolver-enforced fields, so state is
100
+ * never stored twice (single source of truth = `enabled`).
101
+ *
102
+ * @param {{id: string, enabled?: boolean}} primitive
103
+ * @returns {'mandatory'|'optional'|'permission'|null} null for advisory surfaces.
104
+ */
105
+ function deriveState(primitive) {
106
+ const surface = classifySurface(primitive.id);
107
+ if (!CONTROLLABLE_SURFACES.has(surface)) return null;
108
+ const enabled = primitive.enabled !== false;
109
+ if (surface === 'human-gate') return enabled ? 'permission' : 'optional';
110
+ return enabled ? 'mandatory' : 'optional';
111
+ }
112
+
113
+ /**
114
+ * The read-view badge: reflects the HONEST wiring status TODAY, never the
115
+ * author's intent, so the UI can never imply enforcement a surface lacks.
116
+ * `ENFORCED` is reserved strictly for a wired runtime deny — a set that is
117
+ * EMPTY today for these configurable flags, so this function never returns it.
118
+ * A `locked` primitive appends a `LOCKED` marker (it cannot be lowered).
119
+ *
120
+ * @param {{id: string, enabled?: boolean, locked?: boolean}} primitive
121
+ * @returns {string}
122
+ */
123
+ function badgeFor(primitive) {
124
+ const surface = classifySurface(primitive.id);
125
+ if (!CONTROLLABLE_SURFACES.has(surface)) return 'PRESENT (advisory)';
126
+
127
+ const enabled = primitive.enabled !== false;
128
+ let badge;
129
+ if (!enabled) {
130
+ badge = 'OFF (optional)';
131
+ } else if (surface === 'human-gate') {
132
+ // Deny-capable via `forge gate check`, but no chokepoint invokes it yet.
133
+ badge = 'DENY-ON-CHECK';
134
+ } else if (primitive.id === 'gate.issue_verify') {
135
+ // Consumed by _issue.js, but warn-only — never overturns a write.
136
+ badge = 'VERIFY (warn-only)';
137
+ } else {
138
+ // stage-exit gates + rails: declared in the registry, no runtime consumer.
139
+ badge = 'DECLARED (no runtime consumer yet)';
140
+ }
141
+ return primitive.locked === true ? `${badge} · LOCKED` : badge;
142
+ }
143
+
144
+ /**
145
+ * The full read record for a primitive — everything a read view / badge needs.
146
+ *
147
+ * @param {{id: string, enabled?: boolean, locked?: boolean}} primitive
148
+ */
149
+ function describeControl(primitive) {
150
+ const surface = classifySurface(primitive.id);
151
+ return {
152
+ id: primitive.id,
153
+ surface,
154
+ controllable: CONTROLLABLE_SURFACES.has(surface),
155
+ state: deriveState(primitive),
156
+ locus: enforcementLocus(primitive.id),
157
+ badge: badgeFor(primitive),
158
+ locked: primitive.locked === true,
159
+ };
160
+ }
161
+
162
+ /**
163
+ * Resolve a `forge control <id> <state>` write-intent into the enabled boolean
164
+ * for `workflow.gates.<id>.enabled` — or an honest refusal. This is the guard
165
+ * that keeps the tri-state vocabulary from over-promising:
166
+ *
167
+ * - advisory surfaces (mcp/rule/skill/unknown) → refused (presence-only).
168
+ * - `permission` is valid ONLY for human gates; elsewhere it has no path.
169
+ * - `mandatory` on a human gate → refused, directed to `permission`.
170
+ * - `optional` on a `locked` primitive → refused (cannot be lowered).
171
+ *
172
+ * @param {{id: string, locked?: boolean}} primitive
173
+ * @param {string} state - requested tri-state
174
+ * @returns {{ok: true, enabled: boolean}|{ok: false, error: string}}
175
+ */
176
+ function planControl(primitive, state) {
177
+ const surface = classifySurface(primitive.id);
178
+
179
+ if (!CONTROLLABLE_SURFACES.has(surface)) {
180
+ return {
181
+ ok: false,
182
+ error: `${primitive.id} is presence-only, not enforceable — Forge has no `
183
+ + `run-time deny for this surface. It stays read-only in the cockpit `
184
+ + `(badge PRESENT (advisory)). See ${GUARANTEE_DOC}.`,
185
+ };
186
+ }
187
+
188
+ if (!VALID_STATES.has(state)) {
189
+ return {
190
+ ok: false,
191
+ error: `Unknown state '${state}'. Use one of: mandatory, optional, permission.`,
192
+ };
193
+ }
194
+
195
+ const isHuman = surface === 'human-gate';
196
+
197
+ if (state === 'permission' && !isHuman) {
198
+ return {
199
+ ok: false,
200
+ error: `'permission' applies only to a human gate `
201
+ + `(${[...HUMAN_GATE_IDS].join(', ')}); ${primitive.id} enforces evidence, `
202
+ + `not approval. Use 'mandatory' or 'optional'. See ${GUARANTEE_DOC}.`,
203
+ };
204
+ }
205
+
206
+ if (state === 'mandatory' && isHuman) {
207
+ return {
208
+ ok: false,
209
+ error: `${primitive.id} is a human gate — it blocks until a human approval `
210
+ + `event, so use 'permission' (not 'mandatory'). See ${GUARANTEE_DOC}.`,
211
+ };
212
+ }
213
+
214
+ if (state === 'optional' && primitive.locked === true) {
215
+ return {
216
+ ok: false,
217
+ error: `Cannot lower locked ${surface} '${primitive.id}' to optional.`,
218
+ };
219
+ }
220
+
221
+ // mandatory / permission → enabled; optional → disabled. Written to the ONE
222
+ // field the resolver honors, so enforcement is genuine.
223
+ return { ok: true, enabled: state !== 'optional' };
224
+ }
225
+
226
+ module.exports = {
227
+ HUMAN_GATE_IDS,
228
+ GUARANTEE_DOC,
229
+ classifySurface,
230
+ isControllable,
231
+ enforcementLocus,
232
+ deriveState,
233
+ badgeFor,
234
+ describeControl,
235
+ planControl,
236
+ };