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
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env bash
2
- # beads-context.sh — Helper script to manage Beads issue context
2
+ # beads-context.sh — Helper script to manage issue context
3
3
  # for the Forge 7-stage workflow.
4
4
  #
5
5
  # Subcommands:
@@ -17,6 +17,9 @@ set -euo pipefail
17
17
 
18
18
  # Source shared sanitize library
19
19
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
20
+ if [[ -f "$SCRIPT_DIR/bootstrap-windows-tools.sh" ]]; then
21
+ source "$SCRIPT_DIR/bootstrap-windows-tools.sh"
22
+ fi
20
23
  source "$SCRIPT_DIR/lib/sanitize.sh"
21
24
 
22
25
  # ── Helpers ──────────────────────────────────────────────────────────────
@@ -41,8 +44,8 @@ die() {
41
44
  exit 1
42
45
  }
43
46
 
44
- # Resolve a Windows bd.exe installation for bash-based helper flows.
45
- # This covers WSL/Git Bash cases where PowerShell can run bd.exe but bash PATH
47
+ # Resolve a Windows forge.exe installation for bash-based helper flows.
48
+ # This covers WSL/Git Bash cases where PowerShell can run forge.exe but bash PATH
46
49
  # does not include the Windows install directory.
47
50
  convert_windows_path() {
48
51
  local raw="${1%$'\r'}"
@@ -71,7 +74,7 @@ convert_windows_path() {
71
74
  printf '/mnt/%s%s' "$drive" "$rest"
72
75
  }
73
76
 
74
- is_runnable_bd_candidate() {
77
+ is_runnable_forge_candidate() {
75
78
  local candidate="${1:-}"
76
79
 
77
80
  if [[ -z "$candidate" || ! -f "$candidate" ]]; then
@@ -81,41 +84,41 @@ is_runnable_bd_candidate() {
81
84
  [[ -x "$candidate" || "$candidate" == *.exe ]]
82
85
  }
83
86
 
84
- resolve_bd_cmd() {
87
+ resolve_forge_cmd() {
85
88
  local candidate=""
86
89
  local converted=""
87
90
 
88
- if [[ -n "${BD_CMD:-}" ]]; then
89
- if [[ "${BD_CMD}" == *"/"* || "${BD_CMD}" == *"\\"* ]]; then
90
- converted="$(convert_windows_path "$BD_CMD")"
91
- if is_runnable_bd_candidate "$converted"; then
91
+ if [[ -n "${FORGE_CMD:-}" ]]; then
92
+ if [[ "${FORGE_CMD}" == *"/"* || "${FORGE_CMD}" == *"\\"* ]]; then
93
+ converted="$(convert_windows_path "$FORGE_CMD")"
94
+ if is_runnable_forge_candidate "$converted"; then
92
95
  printf '%s' "$converted"
93
96
  return 0
94
97
  fi
95
98
 
96
- is_runnable_bd_candidate "$BD_CMD" || return 1
99
+ is_runnable_forge_candidate "$FORGE_CMD" || return 1
97
100
  fi
98
- printf '%s' "$BD_CMD"
101
+ printf '%s' "$FORGE_CMD"
99
102
  return 0
100
103
  fi
101
104
 
102
- if command -v bd >/dev/null 2>&1; then
103
- printf '%s' "bd"
105
+ if command -v forge >/dev/null 2>&1; then
106
+ printf '%s' "forge"
104
107
  return 0
105
108
  fi
106
109
 
107
- if command -v bd.exe >/dev/null 2>&1; then
108
- printf '%s' "bd.exe"
110
+ if command -v forge.exe >/dev/null 2>&1; then
111
+ printf '%s' "forge.exe"
109
112
  return 0
110
113
  fi
111
114
 
112
115
  for candidate in \
113
- "$HOME/.local/bin/bd" \
114
- "$HOME/.local/bin/bd.exe" \
115
- "$HOME/.bun/bin/bd" \
116
- "$HOME/.bun/bin/bd.exe"
116
+ "$HOME/.local/bin/forge" \
117
+ "$HOME/.local/bin/forge.exe" \
118
+ "$HOME/.bun/bin/forge" \
119
+ "$HOME/.bun/bin/forge.exe"
117
120
  do
118
- if is_runnable_bd_candidate "$candidate"; then
121
+ if is_runnable_forge_candidate "$candidate"; then
119
122
  printf '%s' "$candidate"
120
123
  return 0
121
124
  fi
@@ -127,38 +130,38 @@ resolve_bd_cmd() {
127
130
  [[ -z "$candidate" ]] && continue
128
131
 
129
132
  converted="$(convert_windows_path "$candidate")"
130
- if is_runnable_bd_candidate "$converted"; then
133
+ if is_runnable_forge_candidate "$converted"; then
131
134
  printf '%s' "$converted"
132
135
  return 0
133
136
  fi
134
137
 
135
- if is_runnable_bd_candidate "$candidate"; then
138
+ if is_runnable_forge_candidate "$candidate"; then
136
139
  printf '%s' "$candidate"
137
140
  return 0
138
141
  fi
139
- done < <(where.exe bd 2>/dev/null || true)
142
+ done < <(where.exe forge 2>/dev/null || true)
140
143
  fi
141
144
 
142
145
  return 1
143
146
  }
144
147
 
145
- BD=""
148
+ FORGE=""
146
149
 
147
- get_bd_cmd() {
148
- if [[ -z "$BD" ]]; then
149
- BD="$(resolve_bd_cmd)" || die "bd is required but not found"
150
+ get_forge_cmd() {
151
+ if [[ -z "$FORGE" ]]; then
152
+ FORGE="$(resolve_forge_cmd)" || die "forge is required but not found"
150
153
  fi
151
154
 
152
- printf '%s' "$BD"
155
+ printf '%s' "$FORGE"
153
156
  }
154
157
 
155
- # Run bd update and check for errors in both exit code and output.
156
- # bd update exits 0 even for non-existent issues, so we check stdout too.
157
- bd_update() {
158
- local bd_cmd
159
- bd_cmd="$(get_bd_cmd)"
158
+ # Run forge issue update and check for errors in both exit code and output.
159
+ # The update operation exits 0 even for non-existent issues, so we check stdout too.
160
+ forge_update() {
161
+ local forge_cmd
162
+ forge_cmd="$(get_forge_cmd)"
160
163
  local output
161
- output="$("$bd_cmd" update "$@" 2>&1)"
164
+ output="$("$forge_cmd" issue update "$@" 2>&1)"
162
165
  local rc=$?
163
166
 
164
167
  if [[ $rc -ne 0 ]]; then
@@ -166,7 +169,7 @@ bd_update() {
166
169
  return 1
167
170
  fi
168
171
 
169
- # bd prints "Error resolving/updating ..." to stdout for non-existent issues
172
+ # Forge prints "Error resolving/updating ..." to stdout for non-existent issues
170
173
  # Use specific patterns to avoid false positives from data containing "error"
171
174
  if printf '%s' "$output" | grep -Eqi '^Error|Error resolving|Error updating'; then
172
175
  echo "$output" >&2
@@ -177,12 +180,12 @@ bd_update() {
177
180
  return 0
178
181
  }
179
182
 
180
- # Run bd comments add and check for errors similarly.
181
- bd_comment() {
182
- local bd_cmd
183
- bd_cmd="$(get_bd_cmd)"
183
+ # Run forge issue comment and check for errors similarly.
184
+ forge_comment() {
185
+ local forge_cmd
186
+ forge_cmd="$(get_forge_cmd)"
184
187
  local output
185
- output="$("$bd_cmd" comments add "$@" 2>&1)"
188
+ output="$("$forge_cmd" issue comment "$@" 2>&1)"
186
189
  local rc=$?
187
190
 
188
191
  if [[ $rc -ne 0 ]]; then
@@ -200,6 +203,25 @@ bd_comment() {
200
203
  return 0
201
204
  }
202
205
 
206
+ # Extract concatenated comment text from a `forge issue show --json` payload.
207
+ # Forge/issue show returns comments as an array of objects ({text:...}) — matching
208
+ # the issue-state contract in lib/workflow/state-manager.js — or, defensively, a
209
+ # raw string. jq is preferred; a grep/sed fallback captures "text" fields.
210
+ extract_comments_text() {
211
+ local json="$1"
212
+
213
+ if command -v jq &>/dev/null; then
214
+ printf '%s' "$json" | jq -r '
215
+ ((if type == "array" then .[0] else . end).comments // [])
216
+ | if type == "array" then (map(.text? // tostring) | join("\n"))
217
+ else tostring end
218
+ ' 2>/dev/null || true
219
+ return 0
220
+ fi
221
+
222
+ printf '%s' "$json" | grep -o '"text": *"[^"]*"' | sed 's/^"text": *"//;s/"$//' || true
223
+ }
224
+
203
225
  # ── Subcommands ──────────────────────────────────────────────────────────
204
226
 
205
227
  cmd_set_design() {
@@ -216,7 +238,7 @@ cmd_set_design() {
216
238
 
217
239
  local design_text="${task_count} tasks | ${task_file}"
218
240
 
219
- if ! bd_update "$issue_id" --design "$design_text" > /dev/null; then
241
+ if ! forge_update "$issue_id" --design "$design_text" > /dev/null; then
220
242
  die "Failed to set design on issue ${issue_id}"
221
243
  fi
222
244
 
@@ -233,7 +255,7 @@ cmd_set_acceptance() {
233
255
  local criteria
234
256
  criteria="$(sanitize "$2")"
235
257
 
236
- if ! bd_update "$issue_id" --acceptance "$criteria" > /dev/null; then
258
+ if ! forge_update "$issue_id" --acceptance "$criteria" > /dev/null; then
237
259
  die "Failed to set acceptance on issue ${issue_id}"
238
260
  fi
239
261
 
@@ -273,7 +295,7 @@ cmd_update_progress() {
273
295
 
274
296
  local note="Task ${task_num}/${total} done: ${title} | ${test_count} tests | ${commit_sha} | ${gate_count} gates"
275
297
 
276
- if ! bd_update "$issue_id" --append-notes "$note" > /dev/null; then
298
+ if ! forge_update "$issue_id" --append-notes "$note" > /dev/null; then
277
299
  die "Failed to update progress on issue ${issue_id}"
278
300
  fi
279
301
 
@@ -287,20 +309,20 @@ cmd_parse_progress() {
287
309
  fi
288
310
 
289
311
  local issue_id="$1"
290
- local bd_cmd
291
- bd_cmd="$(get_bd_cmd)"
312
+ local forge_cmd
313
+ forge_cmd="$(get_forge_cmd)"
292
314
 
293
315
  # Get the issue JSON — detect non-existent issues
294
316
  local json
295
- json="$("$bd_cmd" show "$issue_id" --json 2>&1)" || die "Failed to show issue ${issue_id}"
317
+ json="$("$forge_cmd" issue show "$issue_id" --json 2>&1)" || die "Failed to show issue ${issue_id}"
296
318
 
297
- # bd show may exit 0 but print an error for non-existent issues
298
- # Match specific bd error patterns, not the word "error" in data fields
319
+ # show may exit 0 but print an error for non-existent issues
320
+ # Match specific error patterns, not the word "error" in data fields
299
321
  if printf '%s' "$json" | grep -Eqi '^Error (fetching|resolving)'; then
300
322
  die "Issue not found: ${issue_id}"
301
323
  fi
302
324
 
303
- # bd show returns "[]" or empty for non-existent issues
325
+ # show returns "[]" or empty for non-existent issues
304
326
  if [[ -z "$json" || "$json" == "[]" || "$json" == "null" ]]; then
305
327
  die "Issue not found: ${issue_id}"
306
328
  fi
@@ -308,7 +330,7 @@ cmd_parse_progress() {
308
330
  # Extract notes field from JSON — prefer jq if available, fall back to grep/sed
309
331
  local notes
310
332
  if command -v jq &>/dev/null; then
311
- # Handle both array ([{...}]) and object ({...}) responses from bd show
333
+ # Handle both array ([{...}]) and object ({...}) show responses
312
334
  notes="$(printf '%s' "$json" | jq -r 'if type == "array" then .[0].notes else .notes end // empty' 2>/dev/null || true)"
313
335
  else
314
336
  notes="$(printf '%s' "$json" | grep -o '"notes": *"[^"]*"' | head -1 | sed 's/^"notes": *"//;s/"$//' || true)"
@@ -422,7 +444,7 @@ Next: ${flag_next}"
422
444
  WorkflowState: ${flag_workflow_state}"
423
445
  fi
424
446
 
425
- if ! bd_comment "$issue_id" "$comment" > /dev/null; then
447
+ if ! forge_comment "$issue_id" "$comment" > /dev/null; then
426
448
  die "Failed to record stage transition on issue ${issue_id}"
427
449
  fi
428
450
 
@@ -437,17 +459,17 @@ cmd_validate() {
437
459
 
438
460
  local issue_id="$1"
439
461
  local warnings=0
440
- local bd_cmd
441
- bd_cmd="$(get_bd_cmd)"
462
+ local forge_cmd
463
+ forge_cmd="$(get_forge_cmd)"
442
464
 
443
465
  # Get issue JSON
444
466
  local json
445
- json="$("$bd_cmd" show "$issue_id" --json 2>&1)" || {
467
+ json="$("$forge_cmd" issue show "$issue_id" --json 2>&1)" || {
446
468
  echo "Error: Failed to retrieve issue ${issue_id}" >&2
447
469
  exit 1
448
470
  }
449
471
 
450
- # Check for bd error patterns
472
+ # Check for error patterns
451
473
  if printf '%s' "$json" | grep -Eqi '^Error|Error resolving|Error fetching'; then
452
474
  echo "Error: Issue not found: ${issue_id}" >&2
453
475
  exit 1
@@ -474,9 +496,11 @@ cmd_validate() {
474
496
  warnings=$((warnings + 1))
475
497
  fi
476
498
 
477
- # Get comments to check for stage transitions
499
+ # The issue payload returned by `forge issue show --json` already includes its
500
+ # comment history, so the stage-transition checks read comments from that single
501
+ # response rather than issuing a separate comment-list query.
478
502
  local comments
479
- comments="$("$bd_cmd" comments "$issue_id" 2>/dev/null || true)"
503
+ comments="$(extract_comments_text "$json")"
480
504
 
481
505
  # Check 2: At least one stage transition exists
482
506
  local has_transition=false
@@ -1,6 +1,11 @@
1
1
  #!/usr/bin/env bash
2
2
  set -euo pipefail
3
3
 
4
+ _BEADS_UPGRADE_SMOKE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
5
+ if [[ -f "$_BEADS_UPGRADE_SMOKE_DIR/bootstrap-windows-tools.sh" ]]; then
6
+ source "$_BEADS_UPGRADE_SMOKE_DIR/bootstrap-windows-tools.sh"
7
+ fi
8
+
4
9
  BD_CMD="${BD_CMD:-bd}"
5
10
  NODE_CMD="${NODE_CMD:-node}"
6
11
  PROJECT_ROOT="${PROJECT_ROOT:-$(pwd)}"
@@ -12,6 +17,22 @@ SMOKE_RUN_ID="${BEADS_UPGRADE_SMOKE_RUN_ID:-$(date +%s)-$$}"
12
17
  PRIMARY_ISSUE_TITLE="Beads upgrade smoke primary (${SMOKE_RUN_ID})"
13
18
  DEPENDENT_ISSUE_TITLE="Beads upgrade smoke dependent (${SMOKE_RUN_ID})"
14
19
 
20
+ node_fs_path() {
21
+ case "$1" in
22
+ /[A-Za-z]/*)
23
+ _drive="$(printf '%s' "${1:1:1}" | tr '[:lower:]' '[:upper:]')"
24
+ printf '%s:/%s\n' "$_drive" "${1:3}"
25
+ ;;
26
+ *)
27
+ if command -v cygpath >/dev/null 2>&1; then
28
+ cygpath -m "$1"
29
+ else
30
+ printf '%s\n' "$1"
31
+ fi
32
+ ;;
33
+ esac
34
+ }
35
+
15
36
  mkdir -p "${ARTIFACT_DIR}"
16
37
  : > "${COMMAND_LOG_PATH}"
17
38
 
@@ -77,7 +98,7 @@ append_command() {
77
98
  stderrPath,
78
99
  };
79
100
  fs.appendFileSync(logPath, JSON.stringify(entry) + "\n");
80
- ' "${COMMAND_LOG_PATH}" "${step}" "${command_name}" "${command_text}" "${exit_code}" "${stdout_path}" "${stderr_path}"
101
+ ' "$(node_fs_path "${COMMAND_LOG_PATH}")" "${step}" "${command_name}" "${command_text}" "${exit_code}" "$(node_fs_path "${stdout_path}")" "$(node_fs_path "${stderr_path}")"
81
102
  }
82
103
 
83
104
  read_output_snippet() {
@@ -91,7 +112,7 @@ read_output_snippet() {
91
112
  const [filePath] = process.argv.slice(1);
92
113
  const text = fs.readFileSync(filePath, "utf8");
93
114
  process.stdout.write(text.slice(0, 4096));
94
- ' "${file_path}"
115
+ ' "$(node_fs_path "${file_path}")"
95
116
  }
96
117
 
97
118
  write_summary() {
@@ -126,7 +147,7 @@ write_summary() {
126
147
  artifactDir,
127
148
  };
128
149
  fs.writeFileSync(summaryPath, JSON.stringify(summary, null, 2) + "\n");
129
- ' "${COMMAND_LOG_PATH}" "${SUMMARY_PATH}" "${ok}" "${failed_step}" "${failure_message}" "${ARTIFACT_DIR}" "$(printf '%s\n' "${created_issue_ids[@]:-}" | "${NODE_CMD}" -e 'const fs=require("node:fs"); const lines=fs.readFileSync(0,"utf8").split(/\r?\n/).filter(Boolean); process.stdout.write(JSON.stringify(lines));')" "$(printf '%s\n' "${closed_issue_ids[@]:-}" | "${NODE_CMD}" -e 'const fs=require("node:fs"); const lines=fs.readFileSync(0,"utf8").split(/\r?\n/).filter(Boolean); process.stdout.write(JSON.stringify(lines));')"
150
+ ' "$(node_fs_path "${COMMAND_LOG_PATH}")" "$(node_fs_path "${SUMMARY_PATH}")" "${ok}" "${failed_step}" "${failure_message}" "$(node_fs_path "${ARTIFACT_DIR}")" "$(printf '%s\n' "${created_issue_ids[@]:-}" | "${NODE_CMD}" -e 'const fs=require("node:fs"); const lines=fs.readFileSync(0,"utf8").split(/\r?\n/).filter(Boolean); process.stdout.write(JSON.stringify(lines));')" "$(printf '%s\n' "${closed_issue_ids[@]:-}" | "${NODE_CMD}" -e 'const fs=require("node:fs"); const lines=fs.readFileSync(0,"utf8").split(/\r?\n/).filter(Boolean); process.stdout.write(JSON.stringify(lines));')"
130
151
  }
131
152
 
132
153
  run_bd_step() {
@@ -0,0 +1,78 @@
1
+ #!/usr/bin/env bash
2
+ # Shared Windows/WSL command bootstrap for bash entrypoints.
3
+
4
+ if [[ -n "${_FORGE_BOOTSTRAP_WINDOWS_TOOLS_LOADED:-}" ]]; then
5
+ return 0 2>/dev/null || exit 0
6
+ fi
7
+ _FORGE_BOOTSTRAP_WINDOWS_TOOLS_LOADED=1
8
+
9
+ _forge_to_unix_path() {
10
+ local raw="$1"
11
+ if command -v wslpath >/dev/null 2>&1; then
12
+ wslpath -u "$raw" 2>/dev/null && return 0
13
+ fi
14
+ if command -v cygpath >/dev/null 2>&1; then
15
+ cygpath -u "$raw" 2>/dev/null && return 0
16
+ fi
17
+ printf '%s\n' "$raw"
18
+ }
19
+
20
+ _forge_resolve_tool() {
21
+ local name="$1"
22
+ local found=""
23
+
24
+ found="$(command -v "$name" 2>/dev/null || true)"
25
+ if [[ -n "$found" ]]; then
26
+ printf '%s\n' "$found"
27
+ return 0
28
+ fi
29
+
30
+ if command -v where.exe >/dev/null 2>&1; then
31
+ found="$(where.exe "$name" 2>/dev/null | tr -d '\r' | head -n 1 || true)"
32
+ if [[ -n "$found" ]]; then
33
+ _forge_to_unix_path "$found"
34
+ return 0
35
+ fi
36
+ fi
37
+
38
+ return 1
39
+ }
40
+
41
+ if [[ -z "${BD_CMD:-}" ]]; then
42
+ BD_CMD="$(_forge_resolve_tool bd || true)"
43
+ fi
44
+ if [[ -n "${BD_CMD:-}" ]]; then
45
+ export BD_CMD
46
+ fi
47
+
48
+ if [[ -z "${JQ_CMD:-}" ]]; then
49
+ JQ_CMD="$(_forge_resolve_tool jq || true)"
50
+ fi
51
+ if [[ -n "${JQ_CMD:-}" ]]; then
52
+ export JQ_CMD
53
+ fi
54
+
55
+ if [[ -z "${GH_CMD:-}" ]]; then
56
+ GH_CMD="$(_forge_resolve_tool gh || true)"
57
+ fi
58
+ if [[ -n "${GH_CMD:-}" ]]; then
59
+ export GH_CMD
60
+ fi
61
+
62
+ if [[ -n "${BD_CMD:-}" ]]; then
63
+ bd() {
64
+ command "$BD_CMD" "$@"
65
+ }
66
+ fi
67
+
68
+ if [[ -n "${JQ_CMD:-}" ]]; then
69
+ jq() {
70
+ command "$JQ_CMD" "$@"
71
+ }
72
+ fi
73
+
74
+ if [[ -n "${GH_CMD:-}" ]]; then
75
+ gh() {
76
+ command "$GH_CMD" "$@"
77
+ }
78
+ fi
@@ -131,7 +131,7 @@ function main() {
131
131
  const currentBranch = getCurrentBranch();
132
132
 
133
133
  if (isProtectedBranch(currentBranch)) {
134
- // Allow beads-only commits (issue tracking metadata) to push directly
134
+ // Beads runtime metadata is local state. Do not bypass protected branches for it.
135
135
  try {
136
136
  let upstream;
137
137
  try {
@@ -150,8 +150,7 @@ function main() {
150
150
  if (changedFiles.length === 0) {
151
151
  console.error(`${YELLOW}Note: no changed files detected — nothing to bypass${RESET}`);
152
152
  } else if (changedFiles.every(f => f.startsWith('.beads/'))) {
153
- console.error(`${YELLOW}Beads-only push to '${currentBranch}' allowed${RESET}`);
154
- process.exit(0);
153
+ console.error(`${YELLOW}Beads metadata is local runtime state; protected branches do not accept .beads-only pushes.${RESET}`);
155
154
  }
156
155
  } catch (_e) {
157
156
  console.error(`${YELLOW}Note: could not detect beads-only push (upstream ref missing?) — blocking by default${RESET}`);