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,288 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Per-harness MCP config renderer.
5
+ *
6
+ * Renders a GENERIC MCP server descriptor into each harness's native MCP config,
7
+ * using read → merge → write (idempotent, preserves user/other servers). This
8
+ * replaces the old skip-if-exists behavior in setup, which silently refused to
9
+ * add a server whenever a config file already existed.
10
+ *
11
+ * Frozen descriptor interface (consumers build this shape; this module never
12
+ * references any specific server):
13
+ *
14
+ * {
15
+ * name: string, // server key
16
+ * transport: 'stdio' | 'http', // launch transport
17
+ * command: string, // executable (stdio) / launcher
18
+ * args: string[], // command arguments
19
+ * envRefs: Record<string, string>, // env var REFERENCES ('${VAR}') — never secrets
20
+ * }
21
+ *
22
+ * `envRefs` values MUST be `${VAR}` reference strings; literal secrets are rejected.
23
+ * Each harness expands them per its own semantics:
24
+ *
25
+ * - Claude : `.mcp.json` (JSON `mcpServers` map)
26
+ * - Cursor : `.cursor/mcp.json` (JSON `mcpServers` map)
27
+ * - Codex : `.codex/config.toml` (TOML `[mcp_servers.<name>]` tables)
28
+ *
29
+ * Dependency-free (no TOML lib) so it runs under `bun test` and the release gates.
30
+ *
31
+ * @module mcp-config-renderer
32
+ */
33
+
34
+ const fs = require('node:fs');
35
+ const path = require('node:path');
36
+
37
+ const HARNESS_MCP_FILES = {
38
+ claude: '.mcp.json',
39
+ cursor: '.cursor/mcp.json',
40
+ codex: '.codex/config.toml',
41
+ };
42
+
43
+ const ENV_REF_PATTERN = /^\$\{[A-Za-z_][A-Za-z0-9_]*\}$/;
44
+
45
+ /** Thrown when an existing config file cannot be parsed — signals "do not overwrite". */
46
+ class McpConfigParseError extends Error {
47
+ constructor(message, cause) {
48
+ super(message);
49
+ this.name = 'McpConfigParseError';
50
+ this.cause = cause;
51
+ }
52
+ }
53
+
54
+ /**
55
+ * Validate + normalize a generic MCP server descriptor.
56
+ * @param {object} d
57
+ * @returns {{ name, transport, command, args, url, envRefs }}
58
+ */
59
+ // MCP server names key an object entry and are written into JSON/TOML config, so
60
+ // restrict them to a safe identifier charset (no dots/quotes/whitespace that could
61
+ // break the TOML table header `[mcp_servers.<name>]` or collide on merge).
62
+ const MCP_NAME_PATTERN = /^[A-Za-z0-9_-]+$/;
63
+
64
+ // Extracted so validateDescriptor stays under the cognitive-complexity gate.
65
+ function validateEnvRefs(rawEnvRefs) {
66
+ const envRefs = rawEnvRefs && typeof rawEnvRefs === 'object' ? rawEnvRefs : {};
67
+ for (const [key, value] of Object.entries(envRefs)) {
68
+ if (typeof value !== 'string' || !ENV_REF_PATTERN.test(value)) {
69
+ throw new Error(
70
+ `MCP descriptor.envRefs.${key} must be a '\${VAR}' reference string, not a literal value`,
71
+ );
72
+ }
73
+ }
74
+ return envRefs;
75
+ }
76
+
77
+ function validateDescriptor(d) {
78
+ if (!d || typeof d !== 'object') {
79
+ throw new Error('MCP descriptor must be an object');
80
+ }
81
+ if (!d.name || typeof d.name !== 'string') {
82
+ throw new Error('MCP descriptor.name is required');
83
+ }
84
+ if (!MCP_NAME_PATTERN.test(d.name)) {
85
+ throw new Error(`MCP descriptor.name must match ${MCP_NAME_PATTERN} (got '${d.name}')`);
86
+ }
87
+ const transport = d.transport || 'stdio';
88
+ if (transport !== 'stdio' && transport !== 'http') {
89
+ throw new Error(`MCP descriptor.transport must be 'stdio' or 'http' (got ${transport})`);
90
+ }
91
+ const command = typeof d.command === 'string' ? d.command : '';
92
+ const args = Array.isArray(d.args) ? d.args.map(String) : [];
93
+ const url = typeof d.url === 'string' ? d.url : '';
94
+ // stdio launches a process (command/args); http connects to a url. Enforce the
95
+ // field each transport needs so the frozen descriptor can represent both.
96
+ if (transport === 'http' && !url) {
97
+ throw new Error("MCP descriptor.url is required for transport 'http'");
98
+ }
99
+ if (transport === 'stdio' && !command) {
100
+ throw new Error("MCP descriptor.command is required for transport 'stdio'");
101
+ }
102
+ const envRefs = validateEnvRefs(d.envRefs);
103
+ return { name: d.name, transport, command, args, url, envRefs };
104
+ }
105
+
106
+ /** Build the JSON server entry (Claude + Cursor share the `mcpServers` schema). */
107
+ function toJsonServerEntry(descriptor) {
108
+ const d = validateDescriptor(descriptor);
109
+ const entry = {};
110
+ if (d.transport === 'http') {
111
+ entry.type = 'http';
112
+ entry.url = d.url;
113
+ } else {
114
+ if (d.command) entry.command = d.command;
115
+ if (d.args.length) entry.args = d.args;
116
+ }
117
+ if (Object.keys(d.envRefs).length) entry.env = { ...d.envRefs };
118
+ return entry;
119
+ }
120
+
121
+ /**
122
+ * Merge descriptors into an existing JSON MCP config string (read → merge → write).
123
+ * Preserves every server not named in `descriptors`.
124
+ * @param {string} existingText
125
+ * @param {object[]} descriptors
126
+ * @returns {string}
127
+ */
128
+ function mergeJsonMcp(existingText, descriptors) {
129
+ let obj = {};
130
+ if (existingText && existingText.trim()) {
131
+ try {
132
+ obj = JSON.parse(existingText);
133
+ } catch (err) {
134
+ // DATA-LOSS GUARD: never silently discard a populated-but-unparseable config
135
+ // (e.g. Cursor JSONC with comments/trailing commas). Signal the caller so it
136
+ // can back up and skip instead of overwriting the user's servers.
137
+ throw new McpConfigParseError('existing MCP config is not valid JSON', err);
138
+ }
139
+ }
140
+ if (!obj || typeof obj !== 'object' || Array.isArray(obj)) obj = {};
141
+ if (!obj.mcpServers || typeof obj.mcpServers !== 'object') obj.mcpServers = {};
142
+ for (const descriptor of descriptors) {
143
+ const d = validateDescriptor(descriptor);
144
+ obj.mcpServers[d.name] = toJsonServerEntry(d);
145
+ }
146
+ return JSON.stringify(obj, null, 2) + '\n';
147
+ }
148
+
149
+ function tomlString(value) {
150
+ return '"' + String(value).replace(/\\/g, '\\\\').replace(/"/g, '\\"') + '"';
151
+ }
152
+
153
+ function tomlArray(values) {
154
+ return '[' + values.map(tomlString).join(', ') + ']';
155
+ }
156
+
157
+ /** Render a single Codex `[mcp_servers.<name>]` TOML block (+ optional env table). */
158
+ function renderCodexServerBlock(descriptor) {
159
+ const d = validateDescriptor(descriptor);
160
+ const lines = [`[mcp_servers.${d.name}]`];
161
+ if (d.transport === 'http') {
162
+ lines.push(`url = ${tomlString(d.url)}`);
163
+ lines.push('transport = "http"');
164
+ } else {
165
+ if (d.command) lines.push(`command = ${tomlString(d.command)}`);
166
+ lines.push(`args = ${tomlArray(d.args)}`);
167
+ }
168
+ let block = lines.join('\n') + '\n';
169
+ const envKeys = Object.keys(d.envRefs);
170
+ if (envKeys.length) {
171
+ block += `\n[mcp_servers.${d.name}.env]\n`;
172
+ for (const key of envKeys) {
173
+ block += `${key} = ${tomlString(d.envRefs[key])}\n`;
174
+ }
175
+ }
176
+ return block;
177
+ }
178
+
179
+ /** Remove a TOML section (header line through the line before the next `[section]`). */
180
+ function stripTomlSection(text, header) {
181
+ const lines = String(text).split('\n');
182
+ const out = [];
183
+ let skipping = false;
184
+ for (const line of lines) {
185
+ const isHeader = line.trimStart().startsWith('[');
186
+ if (isHeader) {
187
+ if (line.trim() === header) {
188
+ skipping = true;
189
+ continue;
190
+ }
191
+ skipping = false;
192
+ }
193
+ if (!skipping) out.push(line);
194
+ }
195
+ return out.join('\n');
196
+ }
197
+
198
+ /**
199
+ * Merge descriptors into an existing Codex `config.toml` string (read → merge →
200
+ * write). Only the targeted `[mcp_servers.<name>]` (+ `.env`) sections are
201
+ * replaced; all other config is preserved. Idempotent.
202
+ * @param {string} existingText
203
+ * @param {object[]} descriptors
204
+ * @returns {string}
205
+ */
206
+ function mergeCodexToml(existingText, descriptors) {
207
+ let text = existingText || '';
208
+ for (const descriptor of descriptors) {
209
+ const d = validateDescriptor(descriptor);
210
+ text = stripTomlSection(text, `[mcp_servers.${d.name}]`);
211
+ text = stripTomlSection(text, `[mcp_servers.${d.name}.env]`);
212
+ }
213
+ const preamble = text.replace(/\s+$/, '');
214
+ let result = preamble ? preamble + '\n\n' : '';
215
+ result += descriptors.map(renderCodexServerBlock).join('\n');
216
+ return result.replace(/\n{3,}/g, '\n\n').replace(/\s+$/, '') + '\n';
217
+ }
218
+
219
+ /**
220
+ * Copy `filePath` to a stable `<file>.bak` (then numbered `.bak.1`, `.2`, …) so a
221
+ * repeated back-up never clobbers an earlier snapshot. Mirrors the AGENTS.md
222
+ * markerless-backup behavior in lib/commands/setup.js.
223
+ * @param {string} filePath
224
+ * @returns {string} the backup path written
225
+ */
226
+ function backupFile(filePath) {
227
+ let backupPath = `${filePath}.bak`;
228
+ if (fs.existsSync(backupPath)) {
229
+ let suffix = 1;
230
+ while (fs.existsSync(`${filePath}.bak.${suffix}`)) suffix += 1;
231
+ backupPath = `${filePath}.bak.${suffix}`;
232
+ }
233
+ fs.copyFileSync(filePath, backupPath);
234
+ return backupPath;
235
+ }
236
+
237
+ /**
238
+ * Render (merge) MCP descriptors into one harness's native config on disk.
239
+ * Read → merge → write. If the existing file cannot be parsed, it is BACKED UP and
240
+ * left untouched (never overwritten) to avoid destroying user-defined servers.
241
+ *
242
+ * @param {object} params
243
+ * @param {'claude'|'cursor'|'codex'} params.harness
244
+ * @param {string} params.targetRoot - Project root.
245
+ * @param {object[]} params.descriptors - Generic MCP server descriptors.
246
+ * @returns {{ file: string, existed: boolean, skipped: boolean, backup?: string }}
247
+ */
248
+ function renderMcpConfig({ harness, targetRoot, descriptors }) {
249
+ const rel = HARNESS_MCP_FILES[harness];
250
+ if (!rel) throw new Error(`Unknown MCP harness: ${harness}`);
251
+ const filePath = path.join(targetRoot, rel);
252
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
253
+ const existed = fs.existsSync(filePath);
254
+ const existing = existed ? fs.readFileSync(filePath, 'utf-8') : '';
255
+
256
+ let merged;
257
+ try {
258
+ merged = harness === 'codex'
259
+ ? mergeCodexToml(existing, descriptors)
260
+ : mergeJsonMcp(existing, descriptors);
261
+ } catch (err) {
262
+ if (err instanceof McpConfigParseError && existed) {
263
+ const backup = backupFile(filePath);
264
+ console.warn(
265
+ ` ⚠ ${rel} is not valid JSON (comments/trailing commas?) — left untouched to ` +
266
+ `avoid data loss. Backed up to ${path.basename(backup)}; add the MCP server manually.`,
267
+ );
268
+ return { file: filePath, existed, skipped: true, backup };
269
+ }
270
+ throw err;
271
+ }
272
+
273
+ fs.writeFileSync(filePath, merged, 'utf-8');
274
+ return { file: filePath, existed, skipped: false };
275
+ }
276
+
277
+ module.exports = {
278
+ HARNESS_MCP_FILES,
279
+ McpConfigParseError,
280
+ validateDescriptor,
281
+ toJsonServerEntry,
282
+ mergeJsonMcp,
283
+ renderCodexServerBlock,
284
+ mergeCodexToml,
285
+ stripTomlSection,
286
+ backupFile,
287
+ renderMcpConfig,
288
+ };
@@ -0,0 +1,106 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * @module memory/graphiti-mcp
5
+ *
6
+ * DATA-ONLY descriptor for the `graphiti-memory` MCP server. This module does
7
+ * NOT write any file — it defines the harness-agnostic server descriptor shape
8
+ * so a per-harness MCP renderer can materialize it into the right place for
9
+ * each agent. `forge setup` does this today for Claude (`.mcp.json`) and Cursor
10
+ * (`.cursor/mcp.json`) via `lib/mcp-config-renderer.js` when the memory backend
11
+ * resolves to `graphiti`. Forge never speaks to Graphiti at runtime; agents
12
+ * do, over MCP.
13
+ *
14
+ * LOCKED interface (consumed by the parity agent's MCP renderer):
15
+ * { name, transport: 'stdio'|'http', command, args, envRefs }
16
+ * `envRefs` values are ALWAYS `${VAR}` reference strings — never literal keys or
17
+ * secrets — because each harness expands them differently and nothing sensitive
18
+ * may be baked into committed config.
19
+ *
20
+ * Design: docs/work/2026-07-06-graphiti-memory/research.md §1.7 / §2.2. The entry
21
+ * shape matches the Graphiti MCP server README (stdio transport, `uv run`).
22
+ */
23
+
24
+ /**
25
+ * Documented recommended defaults for a fresh opt-in (FalkorDB + OpenAI-compatible).
26
+ *
27
+ * CONSUMED TODAY by `buildGraphitiServerDescriptor`: `transport`, `command`,
28
+ * `mcpServerPath`, `graphDb`, `apiKeyEnv`.
29
+ *
30
+ * RESERVED for the fast-follow MCP wiring (the per-harness renderer that turns
31
+ * this descriptor into concrete env values) — `dbUri`, `neo4jUri`, `llmProvider`,
32
+ * `model`, `groupId` have NO EFFECT until then: the descriptor emits `${VAR}`
33
+ * references, not these literal values. They are kept here (and documented) so
34
+ * the shape is stable when the renderer lands; setting them now is a no-op.
35
+ */
36
+ const DEFAULTS = Object.freeze({
37
+ transport: 'stdio', // 'stdio' | 'http' (consumed)
38
+ command: 'uv', // (consumed)
39
+ mcpServerPath: './graphiti/mcp_server', // (consumed)
40
+ graphDb: 'falkordb', // 'falkordb' | 'falkordb-lite' | 'neo4j' (consumed)
41
+ apiKeyEnv: 'OPENAI_API_KEY', // (consumed — emitted as ${OPENAI_API_KEY})
42
+ // --- reserved (no effect until the fast-follow MCP renderer) ---
43
+ dbUri: 'redis://localhost:6379', // documented default for the FalkorDB path
44
+ neo4jUri: 'bolt://localhost:7687',
45
+ llmProvider: 'openai',
46
+ model: 'gpt-5.5',
47
+ groupId: 'forge',
48
+ });
49
+
50
+ const SERVER_NAME = 'graphiti-memory';
51
+
52
+ /** Build a `${VAR}` reference string. */
53
+ function ref(name) {
54
+ return `\${${name}}`;
55
+ }
56
+
57
+ /**
58
+ * Build the harness-agnostic Graphiti MCP server descriptor.
59
+ *
60
+ * @param {object} [config] - Partial override of DEFAULTS (graphDb, apiKeyEnv,
61
+ * mcpServerPath, transport, ...). Concrete secret/URI VALUES are never placed
62
+ * here — only which env vars the server needs, as `${VAR}` references.
63
+ * @returns {{ name: string, transport: string, command: string, args: string[], envRefs: Object<string,string> }}
64
+ */
65
+ function buildGraphitiServerDescriptor(config = {}) {
66
+ const c = { ...DEFAULTS, ...config };
67
+
68
+ const args = [
69
+ 'run',
70
+ '--isolated',
71
+ '--directory',
72
+ c.mcpServerPath,
73
+ '--project',
74
+ '.',
75
+ 'main.py',
76
+ '--transport',
77
+ c.transport,
78
+ ];
79
+
80
+ const envRefs = {};
81
+ if (c.graphDb === 'neo4j') {
82
+ envRefs.NEO4J_URI = ref('NEO4J_URI');
83
+ envRefs.NEO4J_USER = ref('NEO4J_USER');
84
+ envRefs.NEO4J_PASSWORD = ref('NEO4J_PASSWORD');
85
+ } else {
86
+ envRefs.FALKORDB_URI = ref('FALKORDB_URI');
87
+ }
88
+ // LLM key referenced by env-var NAME only — never inlined.
89
+ envRefs[c.apiKeyEnv] = ref(c.apiKeyEnv);
90
+ envRefs.MODEL_NAME = ref('MODEL_NAME');
91
+ envRefs.GROUP_ID = ref('GRAPHITI_GROUP_ID');
92
+
93
+ return {
94
+ name: SERVER_NAME,
95
+ transport: c.transport,
96
+ command: c.command,
97
+ args,
98
+ envRefs,
99
+ };
100
+ }
101
+
102
+ module.exports = {
103
+ DEFAULTS,
104
+ SERVER_NAME,
105
+ buildGraphitiServerDescriptor,
106
+ };