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
@@ -3,6 +3,7 @@
3
3
  const fs = require('node:fs');
4
4
  const path = require('node:path');
5
5
  const { execFileSync } = require('node:child_process');
6
+ const { cleanupDeprecatedSyncFiles } = require('./deprecated-sync-cleanup');
6
7
 
7
8
  const DEFAULT_BEADS_VERSION = '1.0.0';
8
9
 
@@ -141,119 +142,41 @@ function templateWorkflows(workflowDir, branch, beadsVersion, createdFiles = [])
141
142
  }
142
143
  }
143
144
 
144
- /**
145
- * @typedef {Object} ScaffoldResult
146
- * @property {string[]} filesCreated - Relative paths of files written (new or overwritten)
147
- * @property {string[]} filesSkipped - Relative paths of files that already existed and were preserved
148
- */
145
+ function cleanupDeprecatedBeadsSync(projectRoot, options = {}) {
146
+ return cleanupDeprecatedSyncFiles(projectRoot, options);
147
+ }
149
148
 
150
149
  /**
151
- * Copy a single file from src to dest, creating parent directories as needed.
152
- *
153
- * @param {string} src - Absolute source path
154
- * @param {string} dest - Absolute destination path
155
- * @returns {void}
150
+ * @typedef {Object} ScaffoldResult
151
+ * @property {string[]} filesCreated - Always empty; retained for deprecated API compatibility.
152
+ * @property {string[]} filesSkipped - Always empty; retained for deprecated API compatibility.
153
+ * @property {string[]} filesRemoved - Relative paths of deprecated generated sync files removed.
154
+ * @property {boolean} deprecated - Indicates the legacy scaffold path is deprecated.
155
+ * @property {string} message - Deprecation guidance for future sync direction.
156
156
  */
157
- function copyFileWithDirs(src, dest) {
158
- fs.mkdirSync(path.dirname(dest), { recursive: true });
159
- fs.copyFileSync(src, dest);
160
- }
161
157
 
162
158
  /**
163
- * Scaffold Beads sync workflows and scripts to the user's project.
159
+ * Deprecated compatibility shim for removed Beads/GitHub sync scaffolding.
164
160
  *
165
- * Copies workflow templates, sync modules, config, and mapping stub into
166
- * the project's `.github/` tree from the forge package source.
161
+ * Performs cleanup of generated legacy sync artifacts only. User-owned files
162
+ * at matching paths are preserved unless their content matches known generated
163
+ * templates.
167
164
  *
168
165
  * @param {string} projectRoot - Absolute path to the user's project root
169
166
  * @param {string} packageDir - Absolute path to the forge package install location
170
167
  * @param {Object} [_options={}] - Reserved for future options
171
- * @returns {ScaffoldResult}
168
+ * @returns {ScaffoldResult} Deprecated cleanup result.
172
169
  */
173
170
  function scaffoldBeadsSync(projectRoot, packageDir, _options = {}) {
174
- /** @type {string[]} */
175
- const filesCreated = [];
176
- /** @type {string[]} */
177
- const filesSkipped = [];
178
-
179
- const githubDir = path.join(projectRoot, '.github');
180
-
181
- // --- Step a: Copy workflow templates ---
182
- const workflowNames = ['github-to-beads.yml', 'beads-to-github.yml'];
183
- const srcWorkflowsDir = path.join(packageDir, '.github', 'workflows');
184
-
185
- for (const name of workflowNames) {
186
- const src = path.join(srcWorkflowsDir, name);
187
- const relPath = `.github/workflows/${name}`;
188
- const dest = path.join(projectRoot, '.github', 'workflows', name);
189
-
190
- if (!fs.existsSync(src)) continue;
191
- if (fs.existsSync(dest)) {
192
- filesSkipped.push(relPath);
193
- } else {
194
- copyFileWithDirs(src, dest);
195
- filesCreated.push(relPath);
196
- }
197
- }
198
-
199
- // --- Step b: Copy sync modules ---
200
- const srcSyncDir = path.join(packageDir, 'scripts', 'github-beads-sync');
201
- const destSyncDir = path.join(githubDir, 'scripts', 'beads-sync');
202
-
203
- if (fs.existsSync(srcSyncDir)) {
204
- const entries = fs.readdirSync(srcSyncDir);
205
- for (const entry of entries) {
206
- const srcFile = path.join(srcSyncDir, entry);
207
- const stat = fs.statSync(srcFile);
208
- if (stat.isFile()) {
209
- const relPath = `.github/scripts/beads-sync/${entry}`;
210
- const dest = path.join(destSyncDir, entry);
211
- if (fs.existsSync(dest)) {
212
- filesSkipped.push(relPath);
213
- } else {
214
- copyFileWithDirs(srcFile, dest);
215
- filesCreated.push(relPath);
216
- }
217
- }
218
- }
219
- }
220
-
221
- // --- Step c: Create beads-sync-config.json ---
222
- const configRelPath = '.github/beads-sync-config.json';
223
- const configDest = path.join(githubDir, 'beads-sync-config.json');
224
- const srcConfig = path.join(packageDir, 'scripts', 'github-beads-sync.config.json');
225
-
226
- if (fs.existsSync(configDest)) {
227
- filesSkipped.push(configRelPath);
228
- } else if (fs.existsSync(srcConfig)) {
229
- copyFileWithDirs(srcConfig, configDest);
230
- filesCreated.push(configRelPath);
231
- } else {
232
- // Create a sensible default config
233
- const defaultConfig = {
234
- defaultType: 'task',
235
- defaultPriority: 2,
236
- mapAssignee: true,
237
- publicRepoGate: 'none'
238
- };
239
- fs.mkdirSync(path.dirname(configDest), { recursive: true });
240
- fs.writeFileSync(configDest, JSON.stringify(defaultConfig, null, 2) + '\n');
241
- filesCreated.push(configRelPath);
242
- }
243
-
244
- // --- Step d: Create beads-mapping.json if not exists ---
245
- const mappingRelPath = '.github/beads-mapping.json';
246
- const mappingDest = path.join(githubDir, 'beads-mapping.json');
247
-
248
- if (fs.existsSync(mappingDest)) {
249
- filesSkipped.push(mappingRelPath);
250
- } else {
251
- fs.mkdirSync(path.dirname(mappingDest), { recursive: true });
252
- fs.writeFileSync(mappingDest, '{}');
253
- filesCreated.push(mappingRelPath);
254
- }
255
-
256
- return { filesCreated, filesSkipped };
171
+ const cleanup = cleanupDeprecatedBeadsSync(projectRoot, { packageDir });
172
+
173
+ return {
174
+ filesCreated: [],
175
+ filesSkipped: [],
176
+ filesRemoved: cleanup.removed,
177
+ deprecated: true,
178
+ message: 'Beads GitHub sync scaffolding is deprecated; future GitHub issue sync must use Forge Kernel/server authority.'
179
+ };
257
180
  }
258
181
 
259
182
  module.exports = {
@@ -261,5 +184,6 @@ module.exports = {
261
184
  detectDefaultBranch,
262
185
  detectBeadsVersion,
263
186
  templateWorkflows,
187
+ cleanupDeprecatedBeadsSync,
264
188
  scaffoldBeadsSync,
265
189
  };
@@ -2,6 +2,19 @@ const fs = require('node:fs');
2
2
  const os = require('node:os');
3
3
  const path = require('node:path');
4
4
 
5
+ const { populateAgentSkills } = require('./skills-sync');
6
+
7
+ /**
8
+ * Codex's documented repo-local skill discovery directory, relative to a project
9
+ * root. Codex scans `.agents/skills/<name>/SKILL.md` from the current working
10
+ * directory up to the repo root (developers.openai.com/codex/skills). Unlike the
11
+ * GLOBAL `$CODEX_HOME/skills` install, this surface is COMMITTED to the repo (kept
12
+ * byte-identical to the canonical `skills/` source by a pre-commit sync hook and
13
+ * the drift gate), so a teammate who clones the repo WITHOUT running `forge setup`
14
+ * still gets the Forge skills/stages auto-discovered.
15
+ */
16
+ const CODEX_REPO_SKILLS_DIR = '.agents/skills';
17
+
5
18
  function injectForgeAdapter(content, commandName) {
6
19
  const adapter = [
7
20
  '> Forge stage adapter',
@@ -20,7 +33,10 @@ function injectForgeAdapter(content, commandName) {
20
33
  }
21
34
 
22
35
  function listCodexSkillEntries(sourceRoot) {
23
- const skillsDir = path.join(sourceRoot, '.codex', 'skills');
36
+ // Read from the canonical `skills/` source (single source of truth) rather than
37
+ // a committed `.codex/skills` mirror. The GLOBAL `$CODEX_HOME/skills` install is
38
+ // generated from these entries with the stage adapter injected below.
39
+ const skillsDir = path.join(sourceRoot, 'skills');
24
40
 
25
41
  if (!fs.existsSync(skillsDir)) {
26
42
  return [];
@@ -94,10 +110,44 @@ function buildCodexSkillInstallPlan(sourceRoot, options = {}) {
94
110
  }));
95
111
  }
96
112
 
113
+ /**
114
+ * Absolute path to a project's repo-local Codex skill discovery dir.
115
+ *
116
+ * @param {string} projectRoot - The project/repo root.
117
+ * @returns {string} `<projectRoot>/.agents/skills`.
118
+ */
119
+ function resolveCodexRepoSkillsDir(projectRoot) {
120
+ return path.join(projectRoot, '.agents', 'skills');
121
+ }
122
+
123
+ /**
124
+ * Generate the repo-local Codex skill discovery mirror (`.agents/skills`) from
125
+ * the canonical `skills/` source.
126
+ *
127
+ * Content matches the other harness mirrors byte-for-byte (raw canonical — the
128
+ * `$CODEX_HOME` stage adapter is NOT injected here) so the skills-sync drift gate
129
+ * can enforce it, and so repo-local discovery reaches parity with the
130
+ * `.claude/skills` / `.cursor/skills` discovery surfaces.
131
+ *
132
+ * @param {object} params
133
+ * @param {string} params.sourceRoot - Root containing the canonical `skills/` dir.
134
+ * @param {string} params.projectRoot - Target project/repo root.
135
+ * @param {boolean} [params.clean=false] - Remove stale canonical-managed dirs first.
136
+ * @returns {{targetSkillsDir: string, written: string[]}}
137
+ */
138
+ function populateCodexRepoSkills({ sourceRoot, projectRoot, clean = false }) {
139
+ const targetSkillsDir = resolveCodexRepoSkillsDir(projectRoot);
140
+ const { written } = populateAgentSkills({ sourceRoot, targetSkillsDir, clean });
141
+ return { targetSkillsDir, written };
142
+ }
143
+
97
144
  module.exports = {
145
+ CODEX_REPO_SKILLS_DIR,
98
146
  buildCodexSkillInstallPlan,
99
147
  formatCodexSkillsInstallDir,
100
148
  listCodexSkillEntries,
149
+ populateCodexRepoSkills,
101
150
  resolveCodexHome,
151
+ resolveCodexRepoSkillsDir,
102
152
  resolveCodexSkillsInstallDir,
103
153
  };
@@ -0,0 +1,248 @@
1
+ /**
2
+ * Command Aliases — declarative back-compat alias map.
3
+ *
4
+ * Generalises the former hardcoded `ISSUE_ALIAS_COMMANDS` allowlist (bin/forge.js)
5
+ * into a single declarative source of truth for command-surface unification
6
+ * (kernel issue 33d1a906, epic eea186fa). Each entry maps a bare top-level alias
7
+ * to the canonical `<noun> <sub>` form it stands in for, plus two flags:
8
+ *
9
+ * { canonical: 'issue create', visible: false, deprecated?: true }
10
+ *
11
+ * - `canonical` — the canonical noun+subcommand this alias resolves to.
12
+ * - `visible` — true → routable AND shown in `forge --help`;
13
+ * false → routable but hidden from help (back-compat only).
14
+ * - `deprecated` — optional; when true, using the alias emits a one-line hint
15
+ * to STDERR, but ONLY when `FORGE_DEPRECATION_WARNINGS` is set.
16
+ * Aliases are NEVER removed or broken (docker still ships
17
+ * `docker pull`).
18
+ *
19
+ * P0 SCOPE: seeds ONLY the existing issue aliases migrated verbatim from
20
+ * `ISSUE_ALIAS_COMMANDS` (all hidden, none deprecated) so behaviour is identical.
21
+ * No new noun mappings are added here — those land in later phases. The bare
22
+ * files (create.js, update.js, …) still exist and remain the routed handlers, so
23
+ * `resolveDispatch` is a strict no-op for the seed set (its first clause skips any
24
+ * name that is still a registered command).
25
+ *
26
+ * Files starting with `_` are excluded from command auto-discovery (see
27
+ * `_registry.js`), so this module is never mistaken for a command itself.
28
+ *
29
+ * @module _aliases
30
+ */
31
+
32
+ /**
33
+ * @typedef {Object} AliasDescriptor
34
+ * @property {string} canonical - Canonical `<noun> <sub>` form the alias resolves to.
35
+ * @property {boolean} visible - Whether the alias appears in `forge --help`.
36
+ * @property {boolean} [deprecated] - Whether using the alias emits an opt-in hint.
37
+ */
38
+
39
+ /** @type {Object<string, AliasDescriptor>} */
40
+ const ALIASES = {
41
+ create: { canonical: 'issue create', visible: false },
42
+ update: { canonical: 'issue update', visible: false },
43
+ claim: { canonical: 'issue claim', visible: false },
44
+ close: { canonical: 'issue close', visible: false },
45
+ show: { canonical: 'issue show', visible: false },
46
+ list: { canonical: 'issue list', visible: false },
47
+ ready: { canonical: 'issue ready', visible: false },
48
+ blocked: { canonical: 'issue blocked', visible: false },
49
+ stale: { canonical: 'issue stale', visible: false },
50
+ orphans: { canonical: 'issue orphans', visible: false },
51
+ lint: { canonical: 'issue lint', visible: false },
52
+ claims: { canonical: 'issue claims', visible: false },
53
+ // `issues` is the plural convenience form of `issue list`.
54
+ issues: { canonical: 'issue list', visible: false },
55
+
56
+ // P1 (kernel issue febf7690) — memory noun shortcuts. The `memory` noun
57
+ // (add/recall/search/insights) shipped in PR #392 (issue 25362344); P1 wires the
58
+ // bare verbs as VISIBLE back-compat shortcuts of the canonical `memory <sub>`
59
+ // form. The canonical WRITE verb is `memory add` (there is NO `save`). These stay
60
+ // registered command files (remember.js/recall.js/insights.js), so resolveDispatch
61
+ // is a strict no-op for them and bare-verb dispatch stays byte-identical; the
62
+ // entries exist to document the mapping and drive the `forge --help` Shortcuts
63
+ // block. They are deliberately NOT issue-backend flag-passthrough aliases (see
64
+ // passthroughAliasNames) so global flags (`-p`, `--help`, `--all`) still parse
65
+ // exactly as they did for the standalone commands.
66
+ remember: { canonical: 'memory add', visible: true },
67
+ recall: { canonical: 'memory recall', visible: true },
68
+ insights: { canonical: 'memory insights', visible: true },
69
+
70
+ // P2 (kernel issue 6ab3f30c) — the `pr` noun (ship/preflight/shepherd/merge) plus
71
+ // folding doc-gate under the existing `gate` noun. `pr ship` is the canonical
72
+ // PR-creation form, but bare `ship` stays a VISIBLE shortcut (hot workflow verb,
73
+ // zero keystroke loss); `preflight` is likewise VISIBLE. shepherd/merge/doc-gate
74
+ // are less-hot, so they stay HIDDEN back-compat aliases. Every one keeps its own
75
+ // registered command file (ship.js/preflight.js/shepherd.js/merge.js/doc-gate.js),
76
+ // so resolveDispatch is a strict no-op for them and bare-verb dispatch stays
77
+ // byte-identical — the entries document the mapping and drive the `forge --help`
78
+ // Shortcuts block. Their canonical is a `pr `/`gate ` form (NOT `issue `), so
79
+ // passthroughAliasNames() excludes them and their global flags (`--pull`,
80
+ // `--json`, `--bundle`, `--all`, `-h`) parse exactly as the standalone commands'.
81
+ ship: { canonical: 'pr ship', visible: true },
82
+ preflight: { canonical: 'pr preflight', visible: true },
83
+ shepherd: { canonical: 'pr shepherd', visible: false },
84
+ merge: { canonical: 'pr merge', visible: false },
85
+ 'doc-gate': { canonical: 'gate doc', visible: false },
86
+ };
87
+
88
+ /**
89
+ * Look up an alias descriptor by bare name.
90
+ * @param {string} name
91
+ * @returns {AliasDescriptor|undefined}
92
+ */
93
+ function resolveAlias(name) {
94
+ return Object.prototype.hasOwnProperty.call(ALIASES, name) ? ALIASES[name] : undefined;
95
+ }
96
+
97
+ /**
98
+ * @param {string} name
99
+ * @returns {boolean} true if `name` is a registered alias.
100
+ */
101
+ function isAlias(name) {
102
+ return resolveAlias(name) !== undefined;
103
+ }
104
+
105
+ /**
106
+ * All alias names. Replaces the flat `ISSUE_ALIAS_COMMANDS` array — used to skip
107
+ * global flag parsing so passthrough flags reach the handler intact.
108
+ * @returns {string[]}
109
+ */
110
+ function aliasNames() {
111
+ return Object.keys(ALIASES);
112
+ }
113
+
114
+ /**
115
+ * The subset of aliases that delegate ALL flag parsing to the issue backend
116
+ * and therefore must SKIP global flag parsing in bin/forge.js so flags like
117
+ * `--type` / `-p` / `--help` reach the handler intact. This is issue-specific:
118
+ * only issue-canonical aliases passthrough. Non-issue aliases (e.g. the P1 memory
119
+ * shortcuts) parse global flags normally — exactly as their standalone command
120
+ * files did — so their behaviour stays byte-identical after becoming aliases.
121
+ * @returns {string[]}
122
+ */
123
+ function passthroughAliasNames() {
124
+ return Object.keys(ALIASES).filter(name => ALIASES[name].canonical.startsWith('issue '));
125
+ }
126
+
127
+ /**
128
+ * Names of aliases shown in the `forge --help` Shortcuts block — visible
129
+ * back-compat shortcuts for a canonical `<noun> <sub>` form. Hidden (back-compat
130
+ * only) aliases are excluded.
131
+ * @returns {string[]}
132
+ */
133
+ function visibleAliasNames() {
134
+ return Object.keys(ALIASES).filter(name => ALIASES[name].visible === true);
135
+ }
136
+
137
+ /**
138
+ * Whether a descriptor is hidden from help. Pure predicate over the `visible`
139
+ * flag so the visible-vs-hidden distinction can be tested independent of the
140
+ * P0 seed (which is entirely hidden).
141
+ * @param {AliasDescriptor|undefined} descriptor
142
+ * @returns {boolean}
143
+ */
144
+ function isHidden(descriptor) {
145
+ return !!descriptor && descriptor.visible === false;
146
+ }
147
+
148
+ /**
149
+ * Whether the named alias is hidden from `forge --help`. Drives the help filter.
150
+ * @param {string} name
151
+ * @returns {boolean}
152
+ */
153
+ function isHiddenAlias(name) {
154
+ return isHidden(resolveAlias(name));
155
+ }
156
+
157
+ /**
158
+ * Whether the named alias is a visible (help-listed) shortcut.
159
+ * @param {string} name
160
+ * @returns {boolean}
161
+ */
162
+ function isVisibleAlias(name) {
163
+ const descriptor = resolveAlias(name);
164
+ return !!descriptor && descriptor.visible === true;
165
+ }
166
+
167
+ /**
168
+ * Render the one-line deprecation hint for an alias.
169
+ * @param {string} name
170
+ * @param {AliasDescriptor} descriptor
171
+ * @returns {string}
172
+ */
173
+ function renderHint(name, descriptor) {
174
+ return `forge ${name} is a back-compat alias; prefer 'forge ${descriptor.canonical}'`;
175
+ }
176
+
177
+ /**
178
+ * Whether a deprecation hint should be emitted: requires BOTH the opt-in env flag
179
+ * AND a descriptor explicitly marked deprecated. Default (flag unset) is silent,
180
+ * so scripted stdout is never affected.
181
+ * @param {AliasDescriptor|undefined} descriptor
182
+ * @param {Object} env
183
+ * @returns {boolean}
184
+ */
185
+ function shouldWarn(descriptor, env) {
186
+ return !!(env && env.FORGE_DEPRECATION_WARNINGS && descriptor && descriptor.deprecated);
187
+ }
188
+
189
+ /**
190
+ * Emit an opt-in deprecation hint to stderr when both gates pass. Never writes to
191
+ * stdout (would corrupt `--json`). Returns whether a hint was emitted.
192
+ * @param {string} name
193
+ * @param {{env?: Object, stderr?: {write: function}, resolve?: function}} [opts]
194
+ * @returns {boolean}
195
+ */
196
+ function maybeWarnDeprecation(name, opts = {}) {
197
+ const env = opts.env || process.env;
198
+ const stderr = opts.stderr || process.stderr;
199
+ const resolve = opts.resolve || resolveAlias;
200
+ const descriptor = resolve(name);
201
+ if (!shouldWarn(descriptor, env)) return false;
202
+ stderr.write(`${renderHint(name, descriptor)}\n`);
203
+ return true;
204
+ }
205
+
206
+ /**
207
+ * Resolve a bare command to its canonical noun handler for dispatch.
208
+ *
209
+ * A command that is still a registered command file (`isRegistered(command)` is
210
+ * true) is NEVER rewritten — dispatch stays byte-identical. Only a bare alias
211
+ * whose name is NOT a registered command resolves to `<noun> <sub>`; this
212
+ * activates when a later phase folds a bare verb into a noun handler. For the P0
213
+ * seed every alias is still registered, so this always returns `redirected:false`.
214
+ *
215
+ * @param {string} command - The bare command name (args[0]).
216
+ * @param {string[]} argv - The full argv (argv[0] is the command token).
217
+ * @param {function(string): boolean} isRegistered - Predicate: is this a live command?
218
+ * @returns {{command: string, args: string[], redirected: boolean}}
219
+ */
220
+ function resolveDispatch(command, argv, isRegistered) {
221
+ if (typeof isRegistered === 'function' && isRegistered(command)) {
222
+ return { command, args: argv, redirected: false };
223
+ }
224
+ const descriptor = resolveAlias(command);
225
+ if (!descriptor) {
226
+ return { command, args: argv, redirected: false };
227
+ }
228
+ const parts = String(descriptor.canonical).trim().split(/\s+/);
229
+ const noun = parts[0];
230
+ const rest = Array.isArray(argv) ? argv.slice(1) : [];
231
+ return { command: noun, args: [noun, ...parts.slice(1), ...rest], redirected: true };
232
+ }
233
+
234
+ module.exports = {
235
+ ALIASES,
236
+ resolveAlias,
237
+ isAlias,
238
+ aliasNames,
239
+ passthroughAliasNames,
240
+ visibleAliasNames,
241
+ isHidden,
242
+ isHiddenAlias,
243
+ isVisibleAlias,
244
+ renderHint,
245
+ shouldWarn,
246
+ maybeWarnDeprecation,
247
+ resolveDispatch,
248
+ };