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,347 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Opt-in GLOBAL-config native hook installer for the two harnesses whose hook
5
+ * surface lives in home-directory config, which project `forge setup`
6
+ * intentionally never writes (kernel issue 66dd5a1f, epics 90f2f631 + 1390e1d1):
7
+ *
8
+ * - Codex : `$CODEX_HOME/config.toml` (default `~/.codex/config.toml`) — the
9
+ * `[[hooks.PreToolUse]]` groups rendered by renderCodexHooksToml.
10
+ * - Hermes : `~/.hermes/config.yaml` — the `hooks:`/`pre_tool_call:` shell-hook
11
+ * entries rendered by renderHermesHooksYaml.
12
+ *
13
+ * CONSENT-GUARDED: this module only runs from `forge hooks install --global`
14
+ * (lib/commands/hooks.js), never from project setup. Same discipline as
15
+ * lib/hook-renderer.js / lib/mcp-config-renderer.js: read → MERGE → write,
16
+ * idempotent via the `forge-native-hook.js` marker, unparseable-for-merging
17
+ * existing config → backed up (backupFile) + skipped, never overwritten.
18
+ *
19
+ * ADAPTER-PATH RESOLUTION (why a project-relative command works in global config):
20
+ * the rendered commands invoke `node .forge/hooks/forge-native-hook.js ...`
21
+ * RELATIVE to the harness's working directory. Codex and Hermes execute hook
22
+ * commands from the workspace root (S7/S16 in lib/harness-capability-matrix.js),
23
+ * so inside any Forge-initialized project the command resolves to THAT project's
24
+ * installed adapter. In a directory without `.forge/hooks/forge-native-hook.js`
25
+ * (a non-Forge project), node exits non-zero WITHOUT emitting a deny decision on
26
+ * stdout — both harnesses only block on an explicit decision payload, so the
27
+ * hook fails OPEN and Forge enforcement simply does not apply there.
28
+ *
29
+ * Dependency-free (no TOML/YAML lib): the mergers are conservative line-based
30
+ * block editors that refuse (HookConfigParseError) any existing shape they
31
+ * cannot merge into without risking corruption.
32
+ *
33
+ * @module hook-global-installer
34
+ */
35
+
36
+ const fs = require('node:fs');
37
+ const os = require('node:os');
38
+ const path = require('node:path');
39
+
40
+ const {
41
+ FORGE_HOOK_CONTRACT,
42
+ FORGE_HOOK_MARKER,
43
+ HookConfigParseError,
44
+ renderCodexHooksToml,
45
+ renderHermesHooksYaml,
46
+ } = require('./hook-renderer');
47
+ const { backupFile } = require('./mcp-config-renderer');
48
+ const { resolveCodexHome } = require('./codex-skills');
49
+
50
+ /** The harnesses whose native hooks live in GLOBAL (home-dir) config. */
51
+ const GLOBAL_HOOK_HARNESSES = ['codex', 'hermes'];
52
+
53
+ /**
54
+ * Resolve the global hook config file for a harness.
55
+ * Codex honors $CODEX_HOME (same resolution as lib/codex-skills.js / #311).
56
+ * @param {'codex'|'hermes'} harness
57
+ * @param {{ env?: object, homeDir?: string }} [options]
58
+ * @returns {string} absolute config file path
59
+ */
60
+ function resolveGlobalHookFile(harness, options = {}) {
61
+ if (harness === 'codex') {
62
+ return path.join(resolveCodexHome(options), 'config.toml');
63
+ }
64
+ if (harness === 'hermes') {
65
+ return path.join(options.homeDir || os.homedir(), '.hermes', 'config.yaml');
66
+ }
67
+ throw new Error(`Harness '${harness}' has no global hook config surface`);
68
+ }
69
+
70
+ function normalizedTomlHeader(line) {
71
+ return line.trim().replace(/\s+/g, '');
72
+ }
73
+
74
+ /**
75
+ * Remove Forge-owned `[[hooks.PreToolUse]]` groups (a group = the PreToolUse
76
+ * header segment plus its immediately-following `[[hooks.PreToolUse.hooks]]`
77
+ * segments) whose lines carry the forge-native-hook.js marker. Everything else
78
+ * — user tables, comments, user hook groups — is preserved verbatim.
79
+ */
80
+ function stripForgeCodexHookGroups(text) {
81
+ const lines = String(text).split('\n');
82
+ const segments = [];
83
+ let current = { header: null, lines: [] };
84
+ for (const line of lines) {
85
+ if (line.trim().startsWith('[')) {
86
+ segments.push(current);
87
+ current = { header: normalizedTomlHeader(line), lines: [line] };
88
+ } else {
89
+ current.lines.push(line);
90
+ }
91
+ }
92
+ segments.push(current);
93
+
94
+ const out = [];
95
+ for (let i = 0; i < segments.length; i += 1) {
96
+ const seg = segments[i];
97
+ if (seg.header === '[[hooks.PreToolUse]]') {
98
+ const group = [seg];
99
+ let j = i + 1;
100
+ while (j < segments.length && segments[j].header === '[[hooks.PreToolUse.hooks]]') {
101
+ group.push(segments[j]);
102
+ j += 1;
103
+ }
104
+ const forgeOwned = group.some(s => s.lines.some(l => l.includes(FORGE_HOOK_MARKER)));
105
+ if (!forgeOwned) {
106
+ for (const s of group) out.push(...s.lines);
107
+ }
108
+ i = j - 1;
109
+ } else {
110
+ out.push(...seg.lines);
111
+ }
112
+ }
113
+ return out.join('\n');
114
+ }
115
+
116
+ /** True when the `[hooks]` table section assigns PreToolUse as a plain key. */
117
+ function hooksTableAssignsPreToolUse(text) {
118
+ const lines = String(text).split('\n');
119
+ let inHooksTable = false;
120
+ for (const line of lines) {
121
+ const trimmed = line.trim();
122
+ if (trimmed.startsWith('[')) {
123
+ inHooksTable = normalizedTomlHeader(line) === '[hooks]';
124
+ continue;
125
+ }
126
+ if (inHooksTable && /^PreToolUse\s*=/.test(trimmed)) return true;
127
+ }
128
+ return false;
129
+ }
130
+
131
+ /**
132
+ * Merge Forge's `[[hooks.PreToolUse]]` groups into an existing Codex global
133
+ * `config.toml` string. Preserves ALL existing user config (idempotent via the
134
+ * forge-native-hook.js marker). TOML permits re-opening an array-of-tables
135
+ * later in the document, so appending fresh Forge groups after the preserved
136
+ * content is always valid — UNLESS `hooks.PreToolUse` already exists in a
137
+ * non-array shape, which is refused with HookConfigParseError (never corrupt).
138
+ * @param {string} existingText
139
+ * @param {object} [contract]
140
+ * @returns {string}
141
+ */
142
+ function mergeCodexGlobalConfigToml(existingText, contract = FORGE_HOOK_CONTRACT) {
143
+ const text = String(existingText || '');
144
+ const hasPlainPreToolUseTable = text
145
+ .split('\n')
146
+ .some(line => normalizedTomlHeader(line) === '[hooks.PreToolUse]');
147
+ if (hasPlainPreToolUseTable || hooksTableAssignsPreToolUse(text)) {
148
+ throw new HookConfigParseError(
149
+ 'existing config defines hooks.PreToolUse in a non-array shape; appending '
150
+ + '[[hooks.PreToolUse]] would corrupt the file',
151
+ );
152
+ }
153
+
154
+ const preamble = stripForgeCodexHookGroups(text).replace(/\s+$/, '');
155
+ const rendered = renderCodexHooksToml(contract);
156
+ const result = (preamble ? preamble + '\n\n' : '') + rendered;
157
+ return result.replace(/\n{3,}/g, '\n\n').replace(/\s+$/, '') + '\n';
158
+ }
159
+
160
+ /** The rendered Hermes pre_tool_call list items, re-indented to `itemIndent` spaces. */
161
+ function hermesForgeItems(contract, itemIndent) {
162
+ // renderHermesHooksYaml emits `hooks:\n pre_tool_call:\n` then item lines at a
163
+ // 4-space base indent; strip the first two lines and re-base the indentation.
164
+ const rendered = renderHermesHooksYaml(contract).split('\n');
165
+ return rendered
166
+ .slice(2)
167
+ .filter(line => line.trim().length > 0)
168
+ .map(line => ' '.repeat(itemIndent) + line.slice(4));
169
+ }
170
+
171
+ /** Split a YAML block-sequence body into items (each starting at a `- ` line). */
172
+ function splitYamlListItems(lines) {
173
+ const items = [];
174
+ let current = null;
175
+ for (const line of lines) {
176
+ if (/^\s*- /.test(line)) {
177
+ if (current) items.push(current);
178
+ current = [line];
179
+ } else if (current) {
180
+ current.push(line);
181
+ } else {
182
+ // Content before the first `- ` item (comments/blank lines) — keep as its own chunk.
183
+ items.push([line]);
184
+ }
185
+ }
186
+ if (current) items.push(current);
187
+ return items;
188
+ }
189
+
190
+ /**
191
+ * Merge Forge's `pre_tool_call` shell-hook entries into an existing Hermes
192
+ * global `config.yaml` string. Preserves all user keys, the user's own hook
193
+ * entries, and other hook events; replaces only Forge-owned entries
194
+ * (idempotent via the forge-native-hook.js marker). Shapes it cannot merge
195
+ * without risking corruption (tabs, inline `hooks:`/`pre_tool_call:` values)
196
+ * are refused with HookConfigParseError so the caller backs up + skips.
197
+ * @param {string} existingText
198
+ * @param {object} [contract]
199
+ * @returns {string}
200
+ */
201
+ function mergeHermesGlobalConfigYaml(existingText, contract = FORGE_HOOK_CONTRACT) {
202
+ const text = String(existingText || '');
203
+ if (!text.trim()) return renderHermesHooksYaml(contract);
204
+ if (text.includes('\t')) {
205
+ throw new HookConfigParseError('existing Hermes config contains tabs — cannot merge safely');
206
+ }
207
+
208
+ const lines = text.split('\n');
209
+ const inlineHooks = lines.some(l => /^hooks:\s*[^\s#]/.test(l));
210
+ if (inlineHooks) {
211
+ throw new HookConfigParseError(
212
+ 'existing `hooks:` key has an inline value Forge cannot merge into',
213
+ );
214
+ }
215
+
216
+ const hooksIdx = lines.findIndex(l => /^hooks:\s*(#.*)?$/.test(l));
217
+ if (hooksIdx === -1) {
218
+ const base = text.replace(/\s+$/, '');
219
+ return base + '\n\n' + renderHermesHooksYaml(contract);
220
+ }
221
+
222
+ // The hooks block spans until the next non-blank line at column 0.
223
+ let hooksEnd = hooksIdx + 1;
224
+ while (hooksEnd < lines.length && !(lines[hooksEnd] && /^\S/.test(lines[hooksEnd]))) {
225
+ hooksEnd += 1;
226
+ }
227
+ const block = lines.slice(hooksIdx + 1, hooksEnd);
228
+
229
+ const preToolRel = block.findIndex(l => /^\s+pre_tool_call:\s*(#.*)?$/.test(l));
230
+ const inlinePreTool = block.some(l => /^\s+pre_tool_call:\s*[^\s#]/.test(l));
231
+ if (inlinePreTool) {
232
+ throw new HookConfigParseError(
233
+ 'existing `pre_tool_call:` key has an inline value Forge cannot merge into',
234
+ );
235
+ }
236
+
237
+ let newBlock;
238
+ if (preToolRel === -1) {
239
+ // No pre_tool_call event yet — append ours at the end of the hooks block.
240
+ newBlock = [...block, ' pre_tool_call:', ...hermesForgeItems(contract, 4)];
241
+ } else {
242
+ const keyIndent = (block[preToolRel].match(/^\s*/) || [''])[0].length;
243
+ // The pre_tool_call sub-block spans until the next non-blank line indented
244
+ // at or shallower than the key itself.
245
+ let subEnd = preToolRel + 1;
246
+ while (subEnd < block.length) {
247
+ const line = block[subEnd];
248
+ if (line.trim() && (line.match(/^\s*/) || [''])[0].length <= keyIndent) break;
249
+ subEnd += 1;
250
+ }
251
+ const subBody = block.slice(preToolRel + 1, subEnd);
252
+ const kept = splitYamlListItems(subBody)
253
+ .filter(item => !item.some(l => l.includes(FORGE_HOOK_MARKER)))
254
+ .flat();
255
+ const firstItem = subBody.find(l => /^\s*- /.test(l));
256
+ const itemIndent = firstItem ? (firstItem.match(/^\s*/) || [''])[0].length : keyIndent + 2;
257
+ newBlock = [
258
+ ...block.slice(0, preToolRel + 1),
259
+ ...kept,
260
+ ...hermesForgeItems(contract, itemIndent),
261
+ ...block.slice(subEnd),
262
+ ];
263
+ }
264
+
265
+ const merged = [...lines.slice(0, hooksIdx + 1), ...newBlock, ...lines.slice(hooksEnd)];
266
+ return merged.join('\n').replace(/\n{3,}/g, '\n\n').replace(/\s+$/, '') + '\n';
267
+ }
268
+
269
+ const GLOBAL_MERGERS = {
270
+ codex: mergeCodexGlobalConfigToml,
271
+ hermes: mergeHermesGlobalConfigYaml,
272
+ };
273
+
274
+ /** The Forge hook block a harness's global config receives (for consent output). */
275
+ function renderGlobalHookBlock(harness, contract = FORGE_HOOK_CONTRACT) {
276
+ if (harness === 'codex') return renderCodexHooksToml(contract);
277
+ if (harness === 'hermes') return renderHermesHooksYaml(contract);
278
+ throw new Error(`Harness '${harness}' has no global hook config surface`);
279
+ }
280
+
281
+ /**
282
+ * Install (merge) Forge's native hooks into the GLOBAL configs of the given
283
+ * harnesses. Read → merge → write; dry-run returns previews without touching
284
+ * disk (no writes, no directories, no backups). Unmergeable existing config is
285
+ * backed up (backupFile) and skipped — never overwritten.
286
+ *
287
+ * @param {object} [params]
288
+ * @param {string[]} [params.harnesses] - subset of GLOBAL_HOOK_HARNESSES
289
+ * @param {boolean} [params.dryRun]
290
+ * @param {object} [params.env] - env override (CODEX_HOME resolution / tests)
291
+ * @param {string} [params.homeDir] - home-dir override (tests)
292
+ * @param {object} [params.contract]
293
+ * @returns {Array<{ harness: string, file: string, existed: boolean, wrote: boolean,
294
+ * skipped: boolean, changed?: boolean, dryRun?: boolean,
295
+ * preview?: string, backup?: string, reason?: string }>}
296
+ */
297
+ function installGlobalHooks({
298
+ harnesses = GLOBAL_HOOK_HARNESSES,
299
+ dryRun = false,
300
+ env,
301
+ homeDir,
302
+ contract = FORGE_HOOK_CONTRACT,
303
+ } = {}) {
304
+ return harnesses.map((harness) => {
305
+ const merge = GLOBAL_MERGERS[harness];
306
+ if (!merge) throw new Error(`Harness '${harness}' has no global hook config surface`);
307
+
308
+ const file = resolveGlobalHookFile(harness, { env, homeDir });
309
+ const existed = fs.existsSync(file);
310
+ const existing = existed ? fs.readFileSync(file, 'utf-8') : '';
311
+
312
+ let merged;
313
+ try {
314
+ merged = merge(existing, contract);
315
+ } catch (err) {
316
+ if (err instanceof HookConfigParseError) {
317
+ const result = {
318
+ harness, file, existed, wrote: false, skipped: true, reason: err.message,
319
+ };
320
+ if (dryRun) return { ...result, dryRun: true };
321
+ if (existed) result.backup = backupFile(file);
322
+ return result;
323
+ }
324
+ throw err;
325
+ }
326
+
327
+ const changed = merged !== existing;
328
+ if (dryRun) {
329
+ return {
330
+ harness, file, existed, wrote: false, skipped: false,
331
+ changed, dryRun: true, preview: merged,
332
+ };
333
+ }
334
+ fs.mkdirSync(path.dirname(file), { recursive: true });
335
+ if (changed) fs.writeFileSync(file, merged, 'utf-8');
336
+ return { harness, file, existed, wrote: true, skipped: false, changed };
337
+ });
338
+ }
339
+
340
+ module.exports = {
341
+ GLOBAL_HOOK_HARNESSES,
342
+ resolveGlobalHookFile,
343
+ mergeCodexGlobalConfigToml,
344
+ mergeHermesGlobalConfigYaml,
345
+ renderGlobalHookBlock,
346
+ installGlobalHooks,
347
+ };