forge-workflow 0.0.9 → 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 (479) 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 +151 -61
  8. package/CHANGELOG.md +681 -0
  9. package/CLAUDE.md +9 -106
  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 +466 -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/{TOOLCHAIN.md → forge/TOOLCHAIN.md} +56 -47
  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/reference/TOOLCHAIN.md +658 -0
  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 +225 -28
  81. package/lib/beads-sync-scaffold.js +36 -107
  82. package/lib/codex-skills.js +51 -1
  83. package/lib/commands/_issue.js +744 -70
  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 +66 -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 +22 -2
  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 +851 -979
  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 +329 -11
  140. package/lib/commands/sync.js +34 -46
  141. package/lib/commands/team.js +15 -2
  142. package/lib/commands/test.js +58 -7
  143. package/lib/commands/update.js +2 -2
  144. package/lib/commands/upgrade.js +47 -0
  145. package/lib/commands/validate.js +56 -25
  146. package/lib/commands/worktree.js +308 -128
  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 +184 -0
  151. package/lib/deprecated-sync-cleanup.js +362 -0
  152. package/lib/detect-agent.js +2 -28
  153. package/lib/detect-worktree.js +42 -17
  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 +697 -0
  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/issue-sync/authority.js +100 -0
  174. package/lib/issue-sync/github-pull.js +184 -0
  175. package/lib/issue-sync/import-primitives.js +98 -0
  176. package/lib/issue-sync/legacy-link-bridge.js +436 -0
  177. package/lib/issue-sync/link-store.js +292 -0
  178. package/lib/issue-sync/project-github.js +123 -0
  179. package/lib/issue-sync/reconcile.js +195 -0
  180. package/lib/issue-sync/schema.js +126 -0
  181. package/lib/kernel/backing-issue.js +305 -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/planning-buckets-schema.js +109 -0
  192. package/lib/kernel/projection-jsonl-writer.js +450 -0
  193. package/lib/kernel/readiness-model.js +329 -0
  194. package/lib/kernel/schema.js +356 -0
  195. package/lib/kernel/sqlite-driver.js +2504 -0
  196. package/lib/kernel/taxonomy-validator.js +394 -0
  197. package/lib/lefthook-check.js +8 -4
  198. package/lib/lefthook-wiring.js +413 -0
  199. package/lib/mcp-config-renderer.js +288 -0
  200. package/lib/memory/graphiti-mcp.js +106 -0
  201. package/lib/memory/router.js +387 -0
  202. package/lib/memory/typed-api.js +102 -0
  203. package/lib/memory-digest.js +195 -0
  204. package/lib/merge-rules.js +395 -0
  205. package/lib/migrate-dry-run.js +466 -0
  206. package/lib/orientation.js +863 -0
  207. package/lib/package-manager-remediation.js +103 -0
  208. package/lib/package-root.js +381 -0
  209. package/lib/patch-intent.js +890 -0
  210. package/lib/plugin-catalog.js +3 -4
  211. package/lib/plugin-manager.js +0 -5
  212. package/lib/pr-bundle.js +186 -0
  213. package/lib/pr-monitor/differ.js +195 -0
  214. package/lib/pr-monitor/events.js +0 -0
  215. package/lib/pr-monitor/gather.js +124 -0
  216. package/lib/pr-monitor/journal.js +299 -0
  217. package/lib/pr-monitor/monitor.js +146 -0
  218. package/lib/pr-monitor/render-sticky.js +157 -0
  219. package/lib/pr-monitor/watch-lifecycle.js +95 -0
  220. package/lib/pr-monitor/watch.js +247 -0
  221. package/lib/pr-pull.js +1273 -0
  222. package/lib/pr-shepherd.js +494 -0
  223. package/lib/pr-state-validator.js +59 -0
  224. package/lib/preflight/gates.js +237 -0
  225. package/lib/preflight/runner.js +116 -0
  226. package/lib/project-discovery.js +0 -53
  227. package/lib/project-memory.js +166 -0
  228. package/lib/protected-path-manifest.js +281 -0
  229. package/lib/protected-state-surfaces.js +387 -0
  230. package/lib/release-readiness.js +2089 -0
  231. package/lib/reset.js +59 -45
  232. package/lib/review-adapter.js +68 -0
  233. package/lib/rules-sync.js +260 -0
  234. package/lib/runtime-health.js +332 -23
  235. package/lib/safety-config-renderer.js +268 -0
  236. package/lib/setup-action-log.js +1 -7
  237. package/lib/setup.js +27 -65
  238. package/lib/shell-utils.js +76 -6
  239. package/lib/skills-sync.js +330 -0
  240. package/lib/smart-status/conflicts.js +205 -0
  241. package/lib/smart-status/scoring.js +191 -0
  242. package/lib/status/beads-snapshot.js +145 -0
  243. package/lib/status/presenter.js +216 -0
  244. package/lib/status/snapshot.js +186 -0
  245. package/lib/sync-backend.js +202 -0
  246. package/lib/untrusted-content.js +52 -0
  247. package/lib/upgrade-safety.js +199 -0
  248. package/lib/workflow/enforce-stage.js +298 -47
  249. package/lib/workflow/stage-transition.js +115 -0
  250. package/lib/workflow/stages.js +30 -6
  251. package/lib/workflow/state-manager.js +159 -14
  252. package/lib/workflow/state.js +23 -1
  253. package/lib/workflow-profiles.js +17 -5
  254. package/package.json +46 -36
  255. package/rules/documentation.md +19 -0
  256. package/rules/kernel-tracking.md +26 -0
  257. package/rules/security.md +22 -0
  258. package/rules/tdd.md +20 -0
  259. package/rules/workflow.md +27 -0
  260. package/scripts/auto-backing-issue.js +47 -0
  261. package/scripts/beads-context.sh +165 -22
  262. package/scripts/beads-migrate-to-dolt.sh +7 -0
  263. package/scripts/beads-upgrade-smoke.sh +284 -0
  264. package/scripts/behavioral-judge.sh +115 -11
  265. package/scripts/benchmark.js +349 -63
  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-analyze.js +52 -17
  272. package/scripts/dep-guard-keyword-ripple.js +29 -0
  273. package/scripts/dep-guard-render-review.js +86 -0
  274. package/scripts/dep-guard.sh +64 -232
  275. package/scripts/file-index.sh +3 -0
  276. package/scripts/forge-team/lib/claim.sh +34 -18
  277. package/scripts/forge-team/lib/dashboard.sh +61 -86
  278. package/scripts/forge-team/lib/epic.sh +99 -263
  279. package/scripts/forge-team/lib/hooks.sh +26 -28
  280. package/scripts/forge-team/lib/identity.sh +4 -4
  281. package/scripts/forge-team/lib/sync-github.sh +144 -47
  282. package/scripts/forge-team/lib/verify.sh +93 -83
  283. package/scripts/forge-team/lib/workload.sh +41 -65
  284. package/scripts/forge-team/tests/claim.test.sh +25 -19
  285. package/scripts/forge-team/tests/dashboard.test.sh +31 -46
  286. package/scripts/forge-team/tests/epic.test.sh +52 -71
  287. package/scripts/forge-team/tests/hooks.test.sh +38 -50
  288. package/scripts/forge-team/tests/identity.test.sh +3 -3
  289. package/scripts/forge-team/tests/integration.test.sh +44 -66
  290. package/scripts/forge-team/tests/sync-github.test.sh +183 -79
  291. package/scripts/forge-team/tests/verify.test.sh +37 -46
  292. package/scripts/forge-team/tests/workflow-integration.test.sh +4 -4
  293. package/scripts/forge-team/tests/workload.test.sh +32 -66
  294. package/scripts/gen-command-manifest.js +153 -0
  295. package/scripts/gen-embedded-assets.mjs +129 -0
  296. package/scripts/install.ps1 +139 -0
  297. package/scripts/install.sh +268 -0
  298. package/scripts/lib/beads-migrate-to-dolt.mjs +503 -0
  299. package/scripts/lib/release-asset.mjs +84 -0
  300. package/scripts/parity-check.mjs +145 -0
  301. package/scripts/parity-check.test.mjs +58 -0
  302. package/scripts/pin-agentic-workflow-images.js +112 -0
  303. package/scripts/pr-coordinator.sh +3 -0
  304. package/scripts/preflight-sonar.eslint.config.mjs +44 -0
  305. package/scripts/preflight.sh +108 -0
  306. package/scripts/protected-state-check.js +104 -0
  307. package/scripts/smart-status-score.js +31 -0
  308. package/scripts/smart-status-sessions.js +51 -0
  309. package/scripts/smart-status.sh +117 -369
  310. package/scripts/spikes/config-race-bench.js +111 -0
  311. package/scripts/spikes/harness-capability-matrix.js +13 -0
  312. package/scripts/spikes/patch-anchor-stability-bench.js +125 -0
  313. package/scripts/spikes/protected-path-manifest.js +20 -0
  314. package/scripts/spikes/skill-auto-invoke-parity.js +292 -0
  315. package/scripts/sync-agent-skills.js +62 -0
  316. package/scripts/sync-agentic-workflow.js +48 -0
  317. package/scripts/sync-utils.sh +3 -0
  318. package/scripts/test-ci-shard.js +251 -0
  319. package/scripts/test-dashboard.js +188 -52
  320. package/scripts/test-full-suite.js +186 -0
  321. package/scripts/test-profile.js +278 -0
  322. package/scripts/test.js +302 -28
  323. package/scripts/validate.js +143 -0
  324. package/scripts/validate.sh +18 -1
  325. package/skills/claim-safety/SKILL.md +102 -0
  326. package/skills/claim-safety/evals/evals.json +46 -0
  327. package/{.github/prompts/dev.prompt.md → skills/dev/SKILL.md} +46 -52
  328. package/skills/dev/evals/evals.json +50 -0
  329. package/skills/hermes-forge/SKILL.md +185 -0
  330. package/skills/hermes-forge/evals/evals.json +46 -0
  331. package/skills/issue-basics/SKILL.md +111 -0
  332. package/skills/issue-basics/evals/evals.json +46 -0
  333. package/skills/kernel/SKILL.md +166 -0
  334. package/skills/kernel/evals/evals.json +50 -0
  335. package/skills/memory/SKILL.md +102 -0
  336. package/skills/parallel-deep-research/SKILL.md +14 -11
  337. package/skills/parallel-deep-research/evals/evals.json +11 -27
  338. package/{.github/prompts/plan.prompt.md → skills/plan/SKILL.md} +134 -159
  339. package/skills/plan/evals/evals.json +42 -0
  340. package/skills/research/SKILL.md +195 -0
  341. package/skills/research/evals/evals.json +42 -0
  342. package/{.github/prompts/review.prompt.md → skills/review/SKILL.md} +98 -62
  343. package/skills/review/evals/evals.json +42 -0
  344. package/skills/rollback/SKILL.md +110 -0
  345. package/skills/rollback/evals/evals.json +46 -0
  346. package/skills/rollback/references/methods.md +204 -0
  347. package/{.cursor/commands/rollback.md → skills/rollback/references/workflow-integration.md} +10 -284
  348. package/skills/shepherd/SKILL.md +66 -0
  349. package/skills/shepherd/evals/evals.json +42 -0
  350. package/skills/ship/SKILL.md +251 -0
  351. package/skills/ship/evals/evals.json +42 -0
  352. package/skills/smith/SKILL.md +142 -0
  353. package/skills/smith/evals/evals.json +46 -0
  354. package/skills/smith/references/autonomy-and-gates.md +94 -0
  355. package/{.github/prompts/sonarcloud.prompt.md → skills/sonarcloud/SKILL.md} +14 -3
  356. package/skills/sonarcloud/evals/evals.json +46 -0
  357. package/skills/sonarcloud-analysis/SKILL.md +18 -13
  358. package/skills/sonarcloud-analysis/evals/evals.json +11 -15
  359. package/skills/status/SKILL.md +102 -0
  360. package/skills/status/evals/evals.json +50 -0
  361. package/skills/triage-ready/SKILL.md +121 -0
  362. package/skills/triage-ready/evals/evals.json +42 -0
  363. package/{.github/prompts/validate.prompt.md → skills/validate/SKILL.md} +52 -29
  364. package/skills/validate/evals/evals.json +42 -0
  365. package/skills/verify/SKILL.md +299 -0
  366. package/skills/verify/evals/evals.json +50 -0
  367. package/.claude/commands/dev.md +0 -345
  368. package/.claude/commands/plan.md +0 -566
  369. package/.claude/commands/premerge.md +0 -186
  370. package/.claude/commands/research.md +0 -42
  371. package/.claude/commands/review.md +0 -451
  372. package/.claude/commands/rollback.md +0 -721
  373. package/.claude/commands/ship.md +0 -213
  374. package/.claude/commands/sonarcloud.md +0 -152
  375. package/.claude/commands/status.md +0 -90
  376. package/.claude/commands/validate.md +0 -288
  377. package/.claude/commands/verify.md +0 -269
  378. package/.claude/rules/workflow.md +0 -121
  379. package/.cline/workflows/dev.md +0 -342
  380. package/.cline/workflows/plan.md +0 -563
  381. package/.cline/workflows/premerge.md +0 -183
  382. package/.cline/workflows/research.md +0 -39
  383. package/.cline/workflows/review.md +0 -448
  384. package/.cline/workflows/rollback.md +0 -718
  385. package/.cline/workflows/ship.md +0 -210
  386. package/.cline/workflows/sonarcloud.md +0 -146
  387. package/.cline/workflows/status.md +0 -87
  388. package/.cline/workflows/validate.md +0 -285
  389. package/.cline/workflows/verify.md +0 -266
  390. package/.codex/config.toml +0 -11
  391. package/.codex/skills/dev/SKILL.md +0 -345
  392. package/.codex/skills/plan/SKILL.md +0 -566
  393. package/.codex/skills/premerge/SKILL.md +0 -186
  394. package/.codex/skills/research/SKILL.md +0 -42
  395. package/.codex/skills/review/SKILL.md +0 -451
  396. package/.codex/skills/rollback/SKILL.md +0 -721
  397. package/.codex/skills/ship/SKILL.md +0 -213
  398. package/.codex/skills/sonarcloud/SKILL.md +0 -149
  399. package/.codex/skills/status/SKILL.md +0 -90
  400. package/.codex/skills/validate/SKILL.md +0 -288
  401. package/.codex/skills/verify/SKILL.md +0 -269
  402. package/.cursor/commands/dev.md +0 -342
  403. package/.cursor/commands/plan.md +0 -563
  404. package/.cursor/commands/premerge.md +0 -183
  405. package/.cursor/commands/research.md +0 -39
  406. package/.cursor/commands/review.md +0 -448
  407. package/.cursor/commands/ship.md +0 -210
  408. package/.cursor/commands/sonarcloud.md +0 -146
  409. package/.cursor/commands/status.md +0 -87
  410. package/.cursor/commands/validate.md +0 -285
  411. package/.cursor/commands/verify.md +0 -266
  412. package/.cursorrules +0 -149
  413. package/.github/prompts/premerge.prompt.md +0 -188
  414. package/.github/prompts/research.prompt.md +0 -44
  415. package/.github/prompts/rollback.prompt.md +0 -723
  416. package/.github/prompts/ship.prompt.md +0 -215
  417. package/.github/prompts/status.prompt.md +0 -92
  418. package/.github/prompts/verify.prompt.md +0 -271
  419. package/.github/workflows/beads-to-github.yml +0 -56
  420. package/.github/workflows/github-to-beads.yml +0 -97
  421. package/.kilocode/workflows/dev.md +0 -346
  422. package/.kilocode/workflows/plan.md +0 -567
  423. package/.kilocode/workflows/premerge.md +0 -187
  424. package/.kilocode/workflows/research.md +0 -43
  425. package/.kilocode/workflows/review.md +0 -452
  426. package/.kilocode/workflows/rollback.md +0 -722
  427. package/.kilocode/workflows/ship.md +0 -214
  428. package/.kilocode/workflows/sonarcloud.md +0 -150
  429. package/.kilocode/workflows/status.md +0 -91
  430. package/.kilocode/workflows/validate.md +0 -289
  431. package/.kilocode/workflows/verify.md +0 -270
  432. package/.opencode/commands/dev.md +0 -345
  433. package/.opencode/commands/plan.md +0 -566
  434. package/.opencode/commands/premerge.md +0 -186
  435. package/.opencode/commands/research.md +0 -42
  436. package/.opencode/commands/review.md +0 -451
  437. package/.opencode/commands/rollback.md +0 -721
  438. package/.opencode/commands/ship.md +0 -213
  439. package/.opencode/commands/sonarcloud.md +0 -149
  440. package/.opencode/commands/status.md +0 -90
  441. package/.opencode/commands/validate.md +0 -288
  442. package/.opencode/commands/verify.md +0 -269
  443. package/.roo/commands/dev.md +0 -346
  444. package/.roo/commands/plan.md +0 -567
  445. package/.roo/commands/premerge.md +0 -187
  446. package/.roo/commands/research.md +0 -43
  447. package/.roo/commands/review.md +0 -452
  448. package/.roo/commands/rollback.md +0 -722
  449. package/.roo/commands/ship.md +0 -214
  450. package/.roo/commands/sonarcloud.md +0 -150
  451. package/.roo/commands/status.md +0 -91
  452. package/.roo/commands/validate.md +0 -289
  453. package/.roo/commands/verify.md +0 -270
  454. package/docs/BEADS_GITHUB_SYNC.md +0 -255
  455. package/docs/GREPTILE_SETUP.md +0 -400
  456. package/docs/MANUAL_REVIEW_GUIDE.md +0 -106
  457. package/docs/SETUP.md +0 -663
  458. package/docs/VALIDATION.md +0 -363
  459. package/lib/agents/cline.plugin.json +0 -29
  460. package/lib/agents/copilot.plugin.json +0 -24
  461. package/lib/agents/kilocode.plugin.json +0 -22
  462. package/lib/agents/opencode.plugin.json +0 -23
  463. package/lib/agents/roo.plugin.json +0 -30
  464. package/lib/beads-health-check.js +0 -143
  465. package/lib/commands/commands-reset.js +0 -147
  466. package/opencode.json +0 -67
  467. package/scripts/beads-context.test.js +0 -567
  468. package/scripts/github-beads-sync/comment.mjs +0 -64
  469. package/scripts/github-beads-sync/config.mjs +0 -148
  470. package/scripts/github-beads-sync/github-api.mjs +0 -131
  471. package/scripts/github-beads-sync/index.mjs +0 -332
  472. package/scripts/github-beads-sync/label-mapper.mjs +0 -54
  473. package/scripts/github-beads-sync/mapping.mjs +0 -78
  474. package/scripts/github-beads-sync/reverse-sync-cli.mjs +0 -31
  475. package/scripts/github-beads-sync/reverse-sync.mjs +0 -138
  476. package/scripts/github-beads-sync/run-bd.mjs +0 -161
  477. package/scripts/github-beads-sync/sanitize.mjs +0 -121
  478. package/scripts/github-beads-sync.config.json +0 -26
  479. package/scripts/sync-commands.js +0 -600
@@ -0,0 +1,103 @@
1
+ /**
2
+ * package-manager-remediation.js — Detect the caller's package manager from
3
+ * lockfile presence so remediation messages (e.g. "lefthook is missing, run
4
+ * X") give the correct install command instead of hard-coding a single tool.
5
+ *
6
+ * This is deliberately separate from lib/detection-utils.js#detectPackageManager,
7
+ * which shells out to probe installed binaries and prints setup-wizard output.
8
+ * Remediation messages need a fast, side-effect-free, synchronous lookup that
9
+ * never spawns a process — it runs on every stage-gate health check.
10
+ *
11
+ * @module lib/package-manager-remediation
12
+ */
13
+
14
+ const fs = require('node:fs');
15
+ const path = require('node:path');
16
+
17
+ /**
18
+ * Ordered lockfile → package manager mapping. First match wins.
19
+ * `install` is the command to fetch already-declared dependencies.
20
+ * `addDev(pkg)` is the command to add a new dev dependency and install it.
21
+ */
22
+ const PACKAGE_MANAGERS = [
23
+ {
24
+ name: 'bun',
25
+ lockFiles: ['bun.lockb', 'bun.lock'],
26
+ install: 'bun install',
27
+ addDev: pkg => `bun add -D ${pkg} && bun install`
28
+ },
29
+ {
30
+ name: 'pnpm',
31
+ lockFiles: ['pnpm-lock.yaml'],
32
+ install: 'pnpm install',
33
+ addDev: pkg => `pnpm add -D ${pkg}`
34
+ },
35
+ {
36
+ name: 'yarn',
37
+ lockFiles: ['yarn.lock'],
38
+ install: 'yarn install',
39
+ addDev: pkg => `yarn add -D ${pkg}`
40
+ },
41
+ {
42
+ name: 'npm',
43
+ lockFiles: ['package-lock.json'],
44
+ install: 'npm install',
45
+ addDev: pkg => `npm install -D ${pkg}`
46
+ }
47
+ ];
48
+
49
+ // npm is the safest universal fallback when no lockfile is present or
50
+ // recognized — it ships with Node itself, so it is always a documented,
51
+ // reasonable default rather than assuming any particular toolchain.
52
+ const DEFAULT_MANAGER = PACKAGE_MANAGERS[PACKAGE_MANAGERS.length - 1];
53
+
54
+ /**
55
+ * Detect the package manager in use for a project from lockfile presence.
56
+ *
57
+ * @param {string} [projectRoot] - Absolute path to the project root. Falls
58
+ * back to process.cwd() when omitted or not a non-empty string.
59
+ * @returns {{ name: string, install: string, addDev: (pkg: string) => string }}
60
+ * The detected (or default) package manager descriptor.
61
+ */
62
+ function detectPackageManagerForRemediation(projectRoot) {
63
+ const root = typeof projectRoot === 'string' && projectRoot.trim()
64
+ ? projectRoot
65
+ : process.cwd();
66
+
67
+ for (const manager of PACKAGE_MANAGERS) {
68
+ const hasLockFile = manager.lockFiles.some(file =>
69
+ fs.existsSync(path.join(root, file))
70
+ );
71
+ if (hasLockFile) return manager;
72
+ }
73
+
74
+ return DEFAULT_MANAGER;
75
+ }
76
+
77
+ /**
78
+ * Get the install command for the detected package manager (e.g. when a
79
+ * dependency is already declared but not installed).
80
+ *
81
+ * @param {string} [projectRoot] - Absolute path to the project root.
82
+ * @returns {string} Install command, e.g. "npm install".
83
+ */
84
+ function getInstallCommand(projectRoot) {
85
+ return detectPackageManagerForRemediation(projectRoot).install;
86
+ }
87
+
88
+ /**
89
+ * Get the "add as dev dependency" command for the detected package manager.
90
+ *
91
+ * @param {string} [projectRoot] - Absolute path to the project root.
92
+ * @param {string} pkg - Package name to add, e.g. "lefthook".
93
+ * @returns {string} Add-dev-dependency command, e.g. "npm install -D lefthook".
94
+ */
95
+ function getAddDevCommand(projectRoot, pkg) {
96
+ return detectPackageManagerForRemediation(projectRoot).addDev(pkg);
97
+ }
98
+
99
+ module.exports = {
100
+ detectPackageManagerForRemediation,
101
+ getInstallCommand,
102
+ getAddDevCommand
103
+ };
@@ -0,0 +1,381 @@
1
+ 'use strict';
2
+
3
+ /* global FORGE_COMPILED */
4
+
5
+ /**
6
+ * @module package-root
7
+ *
8
+ * Dual-channel resolution of the Forge "package root" — the directory that ships
9
+ * the runtime assets `forge setup` (and a few runtime commands) copy into a
10
+ * target project (`skills/`, `rules/`, essential docs, `AGENTS.md`, hook scripts,
11
+ * workflow runtime scripts).
12
+ *
13
+ * Two distribution channels must both work:
14
+ *
15
+ * 1. npm / npx install → the package is a real directory on disk. The root is
16
+ * the Forge repo/package root (`lib/` → `..`). Historical path; unchanged.
17
+ *
18
+ * 2. `bun build --compile` single-file binary → there is NO package directory
19
+ * on disk. The runtime assets are embedded at compile time (Bun import
20
+ * attributes, see `scripts/gen-embedded-assets.mjs`) and this module
21
+ * materializes them into a temp directory on first use, then hands that
22
+ * directory to the existing (unchanged) copy logic. This "extract then
23
+ * delegate" keeps every downstream asset consumer working without a rewrite.
24
+ *
25
+ * Every consumer that READS a packaged asset off the package root goes through
26
+ * `getPackageRoot(diskFallback)`:
27
+ * - npm/dev: returns `diskFallback` (verified to actually contain assets).
28
+ * - compiled: returns the memoized, sentinel-guarded extraction directory.
29
+ *
30
+ * Module `require()`s that resolve code (`require(path.join(packageDir,'lib',…))`)
31
+ * are NOT asset reads and are intentionally left alone — those are handled by the
32
+ * bundler when compiling, not by this helper.
33
+ */
34
+
35
+ const fs = require('node:fs');
36
+ const path = require('node:path');
37
+ const os = require('node:os');
38
+
39
+ /** On-disk package root for the npm/dev channel: `lib/` → repo root. */
40
+ const DISK_PACKAGE_ROOT = path.resolve(__dirname, '..');
41
+
42
+ /** Filename written into the extraction dir after a fully-successful extraction. */
43
+ const SENTINEL_FILE = '.forge-assets-complete';
44
+
45
+ /**
46
+ * Asset roots that Forge reads from the package root. Directory entries are
47
+ * embedded recursively; file entries individually. The generator
48
+ * (`scripts/gen-embedded-assets.mjs`) walks exactly this list, so it is the
49
+ * single source of truth for "what ships inside the compiled binary".
50
+ *
51
+ * Kept in sync with the setup/runtime consumers (asserted by
52
+ * test/embedded-assets-drift.test.js):
53
+ * - skills/** → populateAgentSkills, listCanonicalSkills, codex skills, reset
54
+ * - rules/** → renderRulesForHarness (agents-config)
55
+ * - AGENTS.md → workflow contract copied into the project
56
+ * - .claude/scripts/** → load-env.sh, review-resolve.sh
57
+ * - .forge/hooks/** → check-tdd.js, forge-native-hook.js
58
+ * - scripts/** → WORKFLOW_RUNTIME_ASSETS (team + workflow scripts), `forge team`
59
+ *
60
+ * NOTE: the essential docs (TOOLCHAIN.md / VALIDATION.md) are intentionally NOT
61
+ * embedded — copyEssentialDocs reads `docs/<doc>` which does not exist (the files
62
+ * live under docs/reference/ + docs/forge/), so it is a no-op in BOTH channels
63
+ * today. Embedding follows the copyEssentialDocs source-path fix (deferred). Every
64
+ * root listed here MUST exist on disk — the generator fails closed if one is absent.
65
+ */
66
+ const ASSET_ROOTS = Object.freeze([
67
+ 'skills',
68
+ 'rules',
69
+ 'AGENTS.md',
70
+ '.claude/scripts',
71
+ '.forge/hooks',
72
+ 'scripts',
73
+ ]);
74
+
75
+ /**
76
+ * Compile-time signal injected by `build:binary` via `--define FORGE_COMPILED=true`.
77
+ * The `global` directive above tells ESLint the identifier exists; the `typeof`
78
+ * guard prevents a ReferenceError under node where it is never defined.
79
+ */
80
+ function isCompiledByDefine() {
81
+ try {
82
+ return typeof FORGE_COMPILED !== 'undefined' && FORGE_COMPILED === true;
83
+ } catch {
84
+ return false;
85
+ }
86
+ }
87
+
88
+ /**
89
+ * True when running inside a `bun build --compile` single-file executable that
90
+ * carries embedded assets. Primary signal is the injected `FORGE_COMPILED`
91
+ * constant; `Bun.embeddedFiles` is a runtime FALLBACK. Under `node` (npm) and a
92
+ * plain `bun test` (not compiled) both are false → the on-disk path is used.
93
+ *
94
+ * @param {*} [bun] - Bun runtime object; injectable for tests (the real
95
+ * `globalThis.Bun` is a read-only property and cannot be mocked by assignment).
96
+ */
97
+ function isCompiledBinary(bun = globalThis.Bun) {
98
+ if (isCompiledByDefine()) return true;
99
+ try {
100
+ if (!bun || bun.embeddedFiles == null) return false;
101
+ return Array.from(bun.embeddedFiles).length > 0;
102
+ } catch {
103
+ return false;
104
+ }
105
+ }
106
+
107
+ /** A directory qualifies as a real on-disk package root if it carries the core assets. */
108
+ function hasDiskAssets(dir) {
109
+ return (
110
+ !!dir &&
111
+ fs.existsSync(path.join(dir, 'skills')) &&
112
+ fs.existsSync(path.join(dir, 'AGENTS.md'))
113
+ );
114
+ }
115
+
116
+ /** Resolve a stable version tag for the extraction directory + sentinel. */
117
+ function resolveVersion() {
118
+ try {
119
+ // Literal path so the bundler embeds package.json into the binary too.
120
+ return require('../package.json').version || 'dev';
121
+ } catch {
122
+ return 'dev';
123
+ }
124
+ }
125
+
126
+ /**
127
+ * Load the compile-time embedded-asset manifest. Only ever reached inside a
128
+ * compiled binary, where the generated module is bundled at build time. The
129
+ * literal specifier lets Bun's compiler discover and embed it; the guard in
130
+ * `getPackageRoot` ensures node/npm never executes this line (the generated
131
+ * file is gitignored and absent there).
132
+ *
133
+ * @returns {{ EMBEDDED_ASSETS: Record<string,string>, EXECUTABLE_ASSETS: string[] }}
134
+ */
135
+ function loadEmbeddedManifest() {
136
+ return require('./embedded-assets.generated.mjs');
137
+ }
138
+
139
+ /**
140
+ * Split a relative path into segments for platform-correct joining. Splits on
141
+ * BOTH `/` and `\` so a backslash-separated key cannot smuggle a `..` segment
142
+ * past the traversal guard on Windows.
143
+ */
144
+ function relSegments(relPosix) {
145
+ return relPosix.split(/[/\\]/).filter(Boolean);
146
+ }
147
+
148
+ /**
149
+ * Extract every embedded asset into `destDir`, preserving relative paths and
150
+ * restoring the executable bit on scripts/hooks (files-only embedding drops
151
+ * mode). Node `fs` reads the `/$bunfs/…` embedded paths directly. Returns the
152
+ * number of files written so the caller can assert completeness.
153
+ *
154
+ * @param {string} destDir
155
+ * @param {Record<string,string>} [assets] - relPath → source path map. Defaults
156
+ * to the compile-time embedded manifest; injectable for unit tests.
157
+ * @param {string[]} [executable] - relPaths needing chmod +x. Defaults to manifest.
158
+ * @returns {number} count of files written
159
+ */
160
+ function extractEmbeddedAssets(destDir, assets, executable) {
161
+ if (!assets) {
162
+ const manifest = loadEmbeddedManifest();
163
+ assets = manifest.EMBEDDED_ASSETS;
164
+ executable = manifest.EXECUTABLE_ASSETS || [];
165
+ }
166
+ const execSet = new Set(executable || []);
167
+ let count = 0;
168
+ for (const [relPath, embeddedPath] of Object.entries(assets)) {
169
+ // Defense-in-depth: the manifest is compile-time-trusted, but never let a
170
+ // key escape destDir via traversal or an absolute path.
171
+ const segs = relSegments(relPath);
172
+ if (path.isAbsolute(relPath) || segs.includes('..') || segs.length === 0) {
173
+ throw new Error(`Refusing to extract unsafe embedded asset path: ${JSON.stringify(relPath)}`);
174
+ }
175
+ const outPath = path.join(destDir, ...segs);
176
+ fs.mkdirSync(path.dirname(outPath), { recursive: true });
177
+ // read+write (not copyFileSync): Bun's embedded `/$bunfs/…` source paths
178
+ // support readFileSync but NOT the copyfile syscall. Binary buffer copy — no
179
+ // encoding/line-ending translation. Works identically for real disk files.
180
+ fs.writeFileSync(outPath, fs.readFileSync(embeddedPath));
181
+ if (execSet.has(relPath)) {
182
+ try {
183
+ // Owner-only rwx (0o700) — this is a per-user cache dir; no group/other
184
+ // needs access. chmod is a no-op on Windows.
185
+ fs.chmodSync(outPath, 0o700);
186
+ } catch {
187
+ // Non-fatal: mode restore best-effort; the copy already succeeded.
188
+ }
189
+ }
190
+ count += 1;
191
+ }
192
+ return count;
193
+ }
194
+
195
+ /**
196
+ * Per-USER cache root for extracted assets. NOT `os.tmpdir()` — a world-writable
197
+ * shared tmp lets a local attacker pre-plant `forge-assets-<version>/` with a
198
+ * valid sentinel + malicious hook scripts that `forge setup` would then install.
199
+ * Windows: `%LOCALAPPDATA%`; POSIX: `$XDG_CACHE_HOME` or `~/.cache`. The `forge`
200
+ * dir is created `0o700` on POSIX so only the owner can populate it.
201
+ */
202
+ function userCacheRoot() {
203
+ let base;
204
+ if (process.platform === 'win32') {
205
+ base = process.env.LOCALAPPDATA || process.env.APPDATA || os.tmpdir();
206
+ } else {
207
+ base = process.env.XDG_CACHE_HOME || path.join(os.homedir(), '.cache');
208
+ }
209
+ const root = path.join(base, 'forge');
210
+ fs.mkdirSync(root, { recursive: true });
211
+ if (process.platform !== 'win32') {
212
+ try {
213
+ fs.chmodSync(root, 0o700);
214
+ } catch {
215
+ // Best-effort ownership hardening; not fatal.
216
+ }
217
+ }
218
+ return root;
219
+ }
220
+
221
+ /** True iff `dir` holds a completion sentinel matching this version. */
222
+ function isCompleteExtraction(dir, version) {
223
+ try {
224
+ const sentinel = path.join(dir, SENTINEL_FILE);
225
+ return fs.existsSync(sentinel) && fs.readFileSync(sentinel, 'utf8').trim() === version;
226
+ } catch {
227
+ return false;
228
+ }
229
+ }
230
+
231
+ /** Assert every expected relpath exists on disk under `dir` and is non-empty. */
232
+ function assertAllPresent(dir, assets) {
233
+ const missing = [];
234
+ for (const rel of Object.keys(assets)) {
235
+ const p = path.join(dir, ...relSegments(rel));
236
+ let ok = false;
237
+ try {
238
+ ok = fs.statSync(p).size > 0;
239
+ } catch {
240
+ // Missing or unreadable → counts as absent below.
241
+ }
242
+ if (!ok) missing.push(rel);
243
+ }
244
+ if (missing.length > 0) {
245
+ const sample = missing.slice(0, 10).join(', ');
246
+ throw new Error(
247
+ `Forge embedded-asset extraction incomplete: ${missing.length} file(s) missing or empty in ${dir} ` +
248
+ `(e.g. ${sample}${missing.length > 10 ? ', …' : ''}). Rebuild with \`bun run build:binary\`.`
249
+ );
250
+ }
251
+ }
252
+
253
+ let _extractedRoot = null;
254
+
255
+ /**
256
+ * Materialize embedded assets, atomically and concurrency-safely.
257
+ *
258
+ * Extraction writes into a PRIVATE `mkdtempSync` sibling dir (all files + the
259
+ * completion sentinel), then `renameSync`s it into the final version-stamped
260
+ * path in ONE atomic step. A half-written temp NEVER acquires the final name, so
261
+ * a crash mid-extraction or a second process racing us can never observe (or
262
+ * bless) a partially-populated dir — and no process ever `rmSync`es a dir another
263
+ * process is reading. If the final path already exists (another process won),
264
+ * we discard our temp and adopt theirs.
265
+ */
266
+ function ensureExtracted() {
267
+ if (_extractedRoot) return _extractedRoot;
268
+ const version = resolveVersion();
269
+ const manifest = loadEmbeddedManifest();
270
+ const cacheRoot = userCacheRoot();
271
+
272
+ // Cache identity = version + an asset-content FINGERPRINT (emitted by the
273
+ // generator). Same-version rebuilds with a changed asset set therefore land in
274
+ // a DIFFERENT dir, so a stale extraction is never silently reused.
275
+ const fp = String(manifest.ASSET_FINGERPRINT || 'nofp').slice(0, 16);
276
+ const finalDir = path.join(cacheRoot, `assets-${version}-${fp}`);
277
+
278
+ // Fast path: a completed extraction already exists — but do NOT trust the
279
+ // sentinel alone; verify the expected files are actually present + non-empty
280
+ // (a truncated/partly-deleted cache must re-extract, not be adopted).
281
+ if (isCompleteExtraction(finalDir, version)) {
282
+ try {
283
+ assertAllPresent(finalDir, manifest.EMBEDDED_ASSETS);
284
+ _extractedRoot = finalDir;
285
+ return finalDir;
286
+ } catch {
287
+ // Cache incomplete/corrupt — fall through to a fresh extraction.
288
+ }
289
+ }
290
+
291
+ const tmpDir = fs.mkdtempSync(path.join(cacheRoot, `.assets-${version}-`));
292
+ try {
293
+ extractEmbeddedAssets(tmpDir, manifest.EMBEDDED_ASSETS, manifest.EXECUTABLE_ASSETS || []);
294
+ assertAllPresent(tmpDir, manifest.EMBEDDED_ASSETS);
295
+ fs.writeFileSync(path.join(tmpDir, SENTINEL_FILE), version, 'utf8');
296
+ try {
297
+ fs.renameSync(tmpDir, finalDir);
298
+ } catch (err) {
299
+ // Another process already materialized finalDir (rename onto a non-empty
300
+ // dir fails) — discard ours and adopt theirs if it is complete.
301
+ fs.rmSync(tmpDir, { recursive: true, force: true });
302
+ if (isCompleteExtraction(finalDir, version)) {
303
+ _extractedRoot = finalDir;
304
+ return finalDir;
305
+ }
306
+ throw err;
307
+ }
308
+ } catch (err) {
309
+ try {
310
+ fs.rmSync(tmpDir, { recursive: true, force: true });
311
+ } catch {
312
+ // Best-effort cleanup of the private temp dir.
313
+ }
314
+ throw err;
315
+ }
316
+ _extractedRoot = finalDir;
317
+ return finalDir;
318
+ }
319
+
320
+ /**
321
+ * The directory to read packaged assets from, for BOTH channels.
322
+ *
323
+ * Resolution order (safe-default): a real on-disk package (npm/npx/dev) wins;
324
+ * otherwise a compiled binary extracts its embedded assets; otherwise BOTH
325
+ * channels failed and we throw loudly listing both attempts — never silently
326
+ * return an empty dir that lets setup "succeed" with nothing.
327
+ *
328
+ * @param {string} [diskFallback] - The caller's own on-disk package root.
329
+ * @returns {string}
330
+ */
331
+ function getPackageRoot(diskFallback = DISK_PACKAGE_ROOT) {
332
+ // 1. Disk channel — a real package dir that actually carries assets.
333
+ if (hasDiskAssets(diskFallback)) {
334
+ return diskFallback;
335
+ }
336
+ // 2. Embedded channel — compiled binary (or disk assets simply absent).
337
+ if (isCompiledBinary()) {
338
+ return ensureExtracted();
339
+ }
340
+ // 3. Both channels failed — fail loud, never return an asset-less dir.
341
+ throw new Error(
342
+ 'Cannot resolve Forge runtime assets. Tried:\n' +
343
+ ` 1. on-disk package root: ${diskFallback} (missing skills/ or AGENTS.md)\n` +
344
+ ' 2. embedded assets: not a compiled binary (no FORGE_COMPILED / Bun.embeddedFiles)\n' +
345
+ 'A published npm install should always satisfy (1); a single-file binary should satisfy (2).'
346
+ );
347
+ }
348
+
349
+ /**
350
+ * List the relative POSIX paths of all embedded assets (compiled binary only).
351
+ * Minimal read surface for steps 3/4; returns [] outside a compiled binary.
352
+ */
353
+ function listAssets() {
354
+ if (!isCompiledBinary()) return [];
355
+ try {
356
+ // Deterministic, locale-INDEPENDENT codepoint order (must match the generator
357
+ // so the embed set is byte-identical across cross-compile targets).
358
+ return Object.keys(loadEmbeddedManifest().EMBEDDED_ASSETS).sort((a, b) =>
359
+ a < b ? -1 : a > b ? 1 : 0
360
+ );
361
+ } catch {
362
+ return [];
363
+ }
364
+ }
365
+
366
+ /** Test-only: reset the memoized extraction directory. */
367
+ function _resetForTests() {
368
+ _extractedRoot = null;
369
+ }
370
+
371
+ module.exports = {
372
+ getPackageRoot,
373
+ isCompiledBinary,
374
+ extractEmbeddedAssets,
375
+ listAssets,
376
+ hasDiskAssets,
377
+ ASSET_ROOTS,
378
+ DISK_PACKAGE_ROOT,
379
+ SENTINEL_FILE,
380
+ _resetForTests,
381
+ };