@warpgogol/forge 5.2.4 → 5.3.0

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 (568) hide show
  1. package/AGENTS.md +32 -2
  2. package/README.md +1 -1
  3. package/README.uk.md +8 -8
  4. package/bin/cli.ts +1 -0
  5. package/dist/bin/cli.js +1 -0
  6. package/dist/bin/cli.js.map +1 -1
  7. package/dist/os/adr/adr.module.d.ts.map +1 -1
  8. package/dist/os/adr/adr.module.js +8 -3
  9. package/dist/os/adr/adr.module.js.map +1 -1
  10. package/dist/os/adr/frontmatter-io.js +5 -5
  11. package/dist/os/adr/frontmatter-io.js.map +1 -1
  12. package/dist/os/adr/handlers/archive.d.ts.map +1 -1
  13. package/dist/os/adr/handlers/archive.js +10 -4
  14. package/dist/os/adr/handlers/archive.js.map +1 -1
  15. package/dist/os/adr/handlers/implement-stamp.d.ts.map +1 -1
  16. package/dist/os/adr/handlers/implement-stamp.js +10 -9
  17. package/dist/os/adr/handlers/implement-stamp.js.map +1 -1
  18. package/dist/os/adr/handlers/list-create.js +5 -5
  19. package/dist/os/adr/handlers/list-create.js.map +1 -1
  20. package/dist/os/adr/handlers/validate.js +1 -1
  21. package/dist/os/adr/handlers/validate.js.map +1 -1
  22. package/dist/os/audit/audit.module.js +3 -3
  23. package/dist/os/audit/audit.module.js.map +1 -1
  24. package/dist/os/audit/frontmatter-io.js +5 -5
  25. package/dist/os/audit/frontmatter-io.js.map +1 -1
  26. package/dist/os/audit/handlers/archive.d.ts.map +1 -1
  27. package/dist/os/audit/handlers/archive.js +10 -4
  28. package/dist/os/audit/handlers/archive.js.map +1 -1
  29. package/dist/os/compass/compass.module.d.ts.map +1 -1
  30. package/dist/os/compass/compass.module.js +17 -1
  31. package/dist/os/compass/compass.module.js.map +1 -1
  32. package/dist/os/compass/handlers/compass-audit-handler.d.ts.map +1 -1
  33. package/dist/os/compass/handlers/compass-audit-handler.js +12 -5
  34. package/dist/os/compass/handlers/compass-audit-handler.js.map +1 -1
  35. package/dist/os/compass/handlers/compass-change-summary-handler.d.ts.map +1 -1
  36. package/dist/os/compass/handlers/compass-change-summary-handler.js +3 -2
  37. package/dist/os/compass/handlers/compass-change-summary-handler.js.map +1 -1
  38. package/dist/os/compass/handlers/compass-inventory-handler.d.ts.map +1 -1
  39. package/dist/os/compass/handlers/compass-inventory-handler.js +6 -4
  40. package/dist/os/compass/handlers/compass-inventory-handler.js.map +1 -1
  41. package/dist/os/compass/handlers/compass-inventory.d.ts.map +1 -1
  42. package/dist/os/compass/handlers/compass-inventory.js +10 -8
  43. package/dist/os/compass/handlers/compass-inventory.js.map +1 -1
  44. package/dist/os/compass/handlers/compass-migrate-handler.js +1 -1
  45. package/dist/os/compass/handlers/compass-migrate-handler.js.map +1 -1
  46. package/dist/os/compass/handlers/compass-migrate.d.ts.map +1 -1
  47. package/dist/os/compass/handlers/compass-migrate.js +6 -3
  48. package/dist/os/compass/handlers/compass-migrate.js.map +1 -1
  49. package/dist/os/compass/handlers/git-revision.d.ts.map +1 -1
  50. package/dist/os/compass/handlers/git-revision.js +9 -6
  51. package/dist/os/compass/handlers/git-revision.js.map +1 -1
  52. package/dist/os/compass/handlers/resolve-scan-root.js +1 -1
  53. package/dist/os/compass/handlers/resolve-scan-root.js.map +1 -1
  54. package/dist/os/compass/handlers/summary-record.d.ts.map +1 -1
  55. package/dist/os/compass/handlers/summary-record.js +8 -4
  56. package/dist/os/compass/handlers/summary-record.js.map +1 -1
  57. package/dist/os/core/core.module.d.ts.map +1 -1
  58. package/dist/os/core/core.module.js +43 -4
  59. package/dist/os/core/core.module.js.map +1 -1
  60. package/dist/os/core/handlers/assets-helpers.d.ts.map +1 -1
  61. package/dist/os/core/handlers/assets-helpers.js +6 -3
  62. package/dist/os/core/handlers/assets-helpers.js.map +1 -1
  63. package/dist/os/core/handlers/build.js +1 -1
  64. package/dist/os/core/handlers/build.js.map +1 -1
  65. package/dist/os/core/handlers/determinism-check.d.ts.map +1 -1
  66. package/dist/os/core/handlers/determinism-check.js +10 -6
  67. package/dist/os/core/handlers/determinism-check.js.map +1 -1
  68. package/dist/os/core/handlers/dev.js +1 -1
  69. package/dist/os/core/handlers/dev.js.map +1 -1
  70. package/dist/os/core/handlers/file-size-lint.d.ts.map +1 -1
  71. package/dist/os/core/handlers/file-size-lint.js +11 -7
  72. package/dist/os/core/handlers/file-size-lint.js.map +1 -1
  73. package/dist/os/core/handlers/forge-autonomy-validate.d.ts.map +1 -1
  74. package/dist/os/core/handlers/forge-autonomy-validate.js +9 -5
  75. package/dist/os/core/handlers/forge-autonomy-validate.js.map +1 -1
  76. package/dist/os/core/handlers/knowledge-compact.js +1 -1
  77. package/dist/os/core/handlers/knowledge-compact.js.map +1 -1
  78. package/dist/os/core/handlers/package-health.js +1 -1
  79. package/dist/os/core/handlers/package-health.js.map +1 -1
  80. package/dist/os/core/handlers/pinned-check.js +2 -2
  81. package/dist/os/core/handlers/pinned-check.js.map +1 -1
  82. package/dist/os/core/handlers/pinned-init.d.ts.map +1 -1
  83. package/dist/os/core/handlers/pinned-init.js +9 -8
  84. package/dist/os/core/handlers/pinned-init.js.map +1 -1
  85. package/dist/os/core/handlers/pinned-validate.js +3 -3
  86. package/dist/os/core/handlers/pinned-validate.js.map +1 -1
  87. package/dist/os/core/handlers/profile-resolve.js +1 -1
  88. package/dist/os/core/handlers/profile-resolve.js.map +1 -1
  89. package/dist/os/core/handlers/public-surface.js +1 -1
  90. package/dist/os/core/handlers/public-surface.js.map +1 -1
  91. package/dist/os/core/handlers/release-prepare.d.ts.map +1 -1
  92. package/dist/os/core/handlers/release-prepare.js +10 -6
  93. package/dist/os/core/handlers/release-prepare.js.map +1 -1
  94. package/dist/os/core/handlers/release-publish.js +6 -6
  95. package/dist/os/core/handlers/release-publish.js.map +1 -1
  96. package/dist/os/core/handlers/validate.js +1 -1
  97. package/dist/os/core/handlers/validate.js.map +1 -1
  98. package/dist/os/exploration/exploration.module.d.ts.map +1 -1
  99. package/dist/os/exploration/exploration.module.js +1 -0
  100. package/dist/os/exploration/exploration.module.js.map +1 -1
  101. package/dist/os/exploration/frontmatter-io.js +4 -4
  102. package/dist/os/exploration/frontmatter-io.js.map +1 -1
  103. package/dist/os/exploration/handlers/archive.js +3 -3
  104. package/dist/os/exploration/handlers/archive.js.map +1 -1
  105. package/dist/os/mission/handlers/archive.d.ts.map +1 -1
  106. package/dist/os/mission/handlers/archive.js +22 -19
  107. package/dist/os/mission/handlers/archive.js.map +1 -1
  108. package/dist/os/mission/mission.module.js +3 -3
  109. package/dist/os/mission/mission.module.js.map +1 -1
  110. package/dist/os/naming/naming-convention.d.ts.map +1 -1
  111. package/dist/os/naming/naming-convention.js +7 -3
  112. package/dist/os/naming/naming-convention.js.map +1 -1
  113. package/dist/os/naming/naming.module.d.ts.map +1 -1
  114. package/dist/os/naming/naming.module.js +4 -3
  115. package/dist/os/naming/naming.module.js.map +1 -1
  116. package/dist/os/notes/notes.module.d.ts.map +1 -1
  117. package/dist/os/notes/notes.module.js +6 -3
  118. package/dist/os/notes/notes.module.js.map +1 -1
  119. package/dist/os/plan/frontmatter-io.js +5 -5
  120. package/dist/os/plan/frontmatter-io.js.map +1 -1
  121. package/dist/os/plan/handlers/archive.d.ts.map +1 -1
  122. package/dist/os/plan/handlers/archive.js +10 -4
  123. package/dist/os/plan/handlers/archive.js.map +1 -1
  124. package/dist/os/plan/plan.module.js +3 -3
  125. package/dist/os/plan/plan.module.js.map +1 -1
  126. package/dist/os/plugin/plugin.module.d.ts.map +1 -1
  127. package/dist/os/plugin/plugin.module.js +6 -3
  128. package/dist/os/plugin/plugin.module.js.map +1 -1
  129. package/dist/os/program/discovery.js +2 -2
  130. package/dist/os/program/discovery.js.map +1 -1
  131. package/dist/os/program/handlers/complete.js +1 -1
  132. package/dist/os/program/handlers/complete.js.map +1 -1
  133. package/dist/os/program/handlers/lease.js +1 -1
  134. package/dist/os/program/handlers/lease.js.map +1 -1
  135. package/dist/os/program/handlers/seal.js +1 -1
  136. package/dist/os/program/handlers/seal.js.map +1 -1
  137. package/dist/os/program/lease.js +1 -1
  138. package/dist/os/program/lease.js.map +1 -1
  139. package/dist/os/program/program.module.d.ts.map +1 -1
  140. package/dist/os/program/program.module.js +9 -3
  141. package/dist/os/program/program.module.js.map +1 -1
  142. package/dist/os/queue/index.js +1 -1
  143. package/dist/os/queue/manifest.d.ts.map +1 -1
  144. package/dist/os/queue/manifest.js +4 -8
  145. package/dist/os/queue/manifest.js.map +1 -1
  146. package/dist/os/rfc/acceptance.d.ts.map +1 -1
  147. package/dist/os/rfc/acceptance.js +10 -6
  148. package/dist/os/rfc/acceptance.js.map +1 -1
  149. package/dist/os/rfc/decision-log.d.ts.map +1 -1
  150. package/dist/os/rfc/decision-log.js +4 -3
  151. package/dist/os/rfc/decision-log.js.map +1 -1
  152. package/dist/os/rfc/dna-trace.d.ts.map +1 -1
  153. package/dist/os/rfc/dna-trace.js +7 -2
  154. package/dist/os/rfc/dna-trace.js.map +1 -1
  155. package/dist/os/rfc/frontmatter-io.js +5 -5
  156. package/dist/os/rfc/frontmatter-io.js.map +1 -1
  157. package/dist/os/rfc/handlers/archive.d.ts.map +1 -1
  158. package/dist/os/rfc/handlers/archive.js +11 -5
  159. package/dist/os/rfc/handlers/archive.js.map +1 -1
  160. package/dist/os/rfc/handlers/check.d.ts.map +1 -1
  161. package/dist/os/rfc/handlers/check.js +6 -3
  162. package/dist/os/rfc/handlers/check.js.map +1 -1
  163. package/dist/os/rfc/handlers/implement-stamp.d.ts.map +1 -1
  164. package/dist/os/rfc/handlers/implement-stamp.js +11 -10
  165. package/dist/os/rfc/handlers/implement-stamp.js.map +1 -1
  166. package/dist/os/rfc/handlers/index-graph.js +3 -3
  167. package/dist/os/rfc/handlers/index-graph.js.map +1 -1
  168. package/dist/os/rfc/handlers/lifecycle.d.ts.map +1 -1
  169. package/dist/os/rfc/handlers/lifecycle.js +6 -2
  170. package/dist/os/rfc/handlers/lifecycle.js.map +1 -1
  171. package/dist/os/rfc/handlers/list-create.d.ts.map +1 -1
  172. package/dist/os/rfc/handlers/list-create.js +7 -6
  173. package/dist/os/rfc/handlers/list-create.js.map +1 -1
  174. package/dist/os/rfc/handlers/shared.js +3 -3
  175. package/dist/os/rfc/handlers/shared.js.map +1 -1
  176. package/dist/os/rfc/handlers/supersede-propose.d.ts.map +1 -1
  177. package/dist/os/rfc/handlers/supersede-propose.js +7 -3
  178. package/dist/os/rfc/handlers/supersede-propose.js.map +1 -1
  179. package/dist/os/rfc/handlers/validate-rules.d.ts.map +1 -1
  180. package/dist/os/rfc/handlers/validate-rules.js +8 -5
  181. package/dist/os/rfc/handlers/validate-rules.js.map +1 -1
  182. package/dist/os/rfc/rfc.module.d.ts.map +1 -1
  183. package/dist/os/rfc/rfc.module.js +44 -4
  184. package/dist/os/rfc/rfc.module.js.map +1 -1
  185. package/dist/os/rfc/verification-evidence.d.ts.map +1 -1
  186. package/dist/os/rfc/verification-evidence.js +9 -5
  187. package/dist/os/rfc/verification-evidence.js.map +1 -1
  188. package/dist/os/rfc/verification-refresh.d.ts.map +1 -1
  189. package/dist/os/rfc/verification-refresh.js +4 -3
  190. package/dist/os/rfc/verification-refresh.js.map +1 -1
  191. package/dist/os/session/frontmatter-io.js +12 -12
  192. package/dist/os/session/frontmatter-io.js.map +1 -1
  193. package/dist/os/session/handlers/archive.d.ts.map +1 -1
  194. package/dist/os/session/handlers/archive.js +10 -4
  195. package/dist/os/session/handlers/archive.js.map +1 -1
  196. package/dist/os/session/handlers/metrics-aggregate.d.ts.map +1 -1
  197. package/dist/os/session/handlers/metrics-aggregate.js +9 -5
  198. package/dist/os/session/handlers/metrics-aggregate.js.map +1 -1
  199. package/dist/os/session/handlers/metrics-rfc.d.ts.map +1 -1
  200. package/dist/os/session/handlers/metrics-rfc.js +11 -8
  201. package/dist/os/session/handlers/metrics-rfc.js.map +1 -1
  202. package/dist/os/session/handlers/metrics-session.d.ts.map +1 -1
  203. package/dist/os/session/handlers/metrics-session.js +6 -3
  204. package/dist/os/session/handlers/metrics-session.js.map +1 -1
  205. package/dist/os/session/handlers/save.d.ts.map +1 -1
  206. package/dist/os/session/handlers/save.js +14 -8
  207. package/dist/os/session/handlers/save.js.map +1 -1
  208. package/dist/os/session/session.module.d.ts.map +1 -1
  209. package/dist/os/session/session.module.js +6 -0
  210. package/dist/os/session/session.module.js.map +1 -1
  211. package/dist/os/spec/live-spec-list.js +4 -4
  212. package/dist/os/spec/live-spec-list.js.map +1 -1
  213. package/dist/os/spec/live-spec-merge.js +5 -5
  214. package/dist/os/spec/live-spec-merge.js.map +1 -1
  215. package/dist/os/spec/live-spec-show.js +3 -3
  216. package/dist/os/spec/live-spec-show.js.map +1 -1
  217. package/dist/os/spec/live-spec-validate.js +4 -4
  218. package/dist/os/spec/live-spec-validate.js.map +1 -1
  219. package/dist/os/spec/spec-materialize.js +9 -9
  220. package/dist/os/spec/spec-materialize.js.map +1 -1
  221. package/dist/os/spec/spec-status.js +9 -9
  222. package/dist/os/spec/spec-status.js.map +1 -1
  223. package/dist/os/spec/spec-validate.js +7 -7
  224. package/dist/os/spec/spec-validate.js.map +1 -1
  225. package/dist/os/spec/spec.module.d.ts.map +1 -1
  226. package/dist/os/spec/spec.module.js +8 -0
  227. package/dist/os/spec/spec.module.js.map +1 -1
  228. package/dist/os/werkstatt/handlers/lock.js +16 -16
  229. package/dist/os/werkstatt/handlers/lock.js.map +1 -1
  230. package/dist/os/werkstatt/handlers/werkstatt-lock-recover.js +3 -3
  231. package/dist/os/werkstatt/handlers/werkstatt-lock-recover.js.map +1 -1
  232. package/dist/os/werkstatt/handlers/werkstatt-operation-validate.d.ts.map +1 -1
  233. package/dist/os/werkstatt/handlers/werkstatt-operation-validate.js +3 -2
  234. package/dist/os/werkstatt/handlers/werkstatt-operation-validate.js.map +1 -1
  235. package/dist/os/werkstatt/werkstatt.module.d.ts.map +1 -1
  236. package/dist/os/werkstatt/werkstatt.module.js +6 -2
  237. package/dist/os/werkstatt/werkstatt.module.js.map +1 -1
  238. package/dist/os/workflow/handlers.d.ts.map +1 -1
  239. package/dist/os/workflow/handlers.js +8 -5
  240. package/dist/os/workflow/handlers.js.map +1 -1
  241. package/dist/os/workflow/workflow.module.d.ts.map +1 -1
  242. package/dist/os/workflow/workflow.module.js +6 -3
  243. package/dist/os/workflow/workflow.module.js.map +1 -1
  244. package/dist/src/compass/contract-registry.js +1 -1
  245. package/dist/src/compass/contract-registry.js.map +1 -1
  246. package/dist/src/config/forge-config.d.ts +1 -1
  247. package/dist/src/config/forge-config.js +1 -1
  248. package/dist/src/config/forge-config.js.map +1 -1
  249. package/dist/src/knowledge/budgets.js +1 -1
  250. package/dist/src/knowledge/budgets.js.map +1 -1
  251. package/dist/src/knowledge/compact.js +1 -1
  252. package/dist/src/knowledge/compact.js.map +1 -1
  253. package/dist/src/knowledge/parse.js +1 -1
  254. package/dist/src/knowledge/parse.js.map +1 -1
  255. package/dist/src/knowledge/sync.d.ts.map +1 -1
  256. package/dist/src/knowledge/sync.js +3 -5
  257. package/dist/src/knowledge/sync.js.map +1 -1
  258. package/dist/src/migration-adapters/git-utils.js +2 -2
  259. package/dist/src/migration-adapters/git-utils.js.map +1 -1
  260. package/dist/src/migration-adapters/ignored-files.js +2 -2
  261. package/dist/src/migration-adapters/ignored-files.js.map +1 -1
  262. package/dist/src/migration-adapters/node-typescript-pnpm/index.js +1 -1
  263. package/dist/src/migration-adapters/node-typescript-pnpm/index.js.map +1 -1
  264. package/dist/src/migration-adapters/phaser-pnpm/index.js +1 -1
  265. package/dist/src/migration-adapters/phaser-pnpm/index.js.map +1 -1
  266. package/dist/src/onboarding/agents-generate.d.ts.map +1 -1
  267. package/dist/src/onboarding/agents-generate.js +60 -31
  268. package/dist/src/onboarding/agents-generate.js.map +1 -1
  269. package/dist/src/onboarding/create.d.ts.map +1 -1
  270. package/dist/src/onboarding/create.js +10 -10
  271. package/dist/src/onboarding/create.js.map +1 -1
  272. package/dist/src/onboarding/doctor.d.ts.map +1 -1
  273. package/dist/src/onboarding/doctor.js +68 -59
  274. package/dist/src/onboarding/doctor.js.map +1 -1
  275. package/dist/src/onboarding/init.d.ts.map +1 -1
  276. package/dist/src/onboarding/init.js +30 -1
  277. package/dist/src/onboarding/init.js.map +1 -1
  278. package/dist/src/onboarding/invariant-engine.js +1 -1
  279. package/dist/src/onboarding/invariant-engine.js.map +1 -1
  280. package/dist/src/onboarding/memory-compact.d.ts.map +1 -1
  281. package/dist/src/onboarding/memory-compact.js +5 -4
  282. package/dist/src/onboarding/memory-compact.js.map +1 -1
  283. package/dist/src/onboarding/memory-scaffold.js +1 -1
  284. package/dist/src/onboarding/memory-scaffold.js.map +1 -1
  285. package/dist/src/onboarding/nested-agents-generate.d.ts +4 -1
  286. package/dist/src/onboarding/nested-agents-generate.d.ts.map +1 -1
  287. package/dist/src/onboarding/nested-agents-generate.js +34 -5
  288. package/dist/src/onboarding/nested-agents-generate.js.map +1 -1
  289. package/dist/src/onboarding/nested-agents-templates.d.ts.map +1 -1
  290. package/dist/src/onboarding/nested-agents-templates.js +8 -12
  291. package/dist/src/onboarding/nested-agents-templates.js.map +1 -1
  292. package/dist/src/onboarding/npm-token-check.js +2 -2
  293. package/dist/src/onboarding/npm-token-check.js.map +1 -1
  294. package/dist/src/onboarding/prettierignore.d.ts +29 -0
  295. package/dist/src/onboarding/prettierignore.d.ts.map +1 -0
  296. package/dist/src/onboarding/prettierignore.js +231 -0
  297. package/dist/src/onboarding/prettierignore.js.map +1 -0
  298. package/dist/src/onboarding/profile-validate.d.ts.map +1 -1
  299. package/dist/src/onboarding/profile-validate.js +5 -4
  300. package/dist/src/onboarding/profile-validate.js.map +1 -1
  301. package/dist/src/onboarding/scaffold-project.d.ts.map +1 -1
  302. package/dist/src/onboarding/scaffold-project.js +35 -27
  303. package/dist/src/onboarding/scaffold-project.js.map +1 -1
  304. package/dist/src/onboarding/scaffold.js +1 -1
  305. package/dist/src/onboarding/scaffold.js.map +1 -1
  306. package/dist/src/onboarding/skill-markers.d.ts +27 -0
  307. package/dist/src/onboarding/skill-markers.d.ts.map +1 -0
  308. package/dist/src/onboarding/skill-markers.js +131 -0
  309. package/dist/src/onboarding/skill-markers.js.map +1 -0
  310. package/dist/src/onboarding/upgrade.d.ts +10 -0
  311. package/dist/src/onboarding/upgrade.d.ts.map +1 -1
  312. package/dist/src/onboarding/upgrade.js +215 -74
  313. package/dist/src/onboarding/upgrade.js.map +1 -1
  314. package/dist/src/onboarding/workspace-discovery.js +1 -1
  315. package/dist/src/onboarding/workspace-discovery.js.map +1 -1
  316. package/dist/src/pipeline-status.d.ts +6 -5
  317. package/dist/src/pipeline-status.d.ts.map +1 -1
  318. package/dist/src/pipeline-status.js +24 -19
  319. package/dist/src/pipeline-status.js.map +1 -1
  320. package/dist/src/profiles/stack-profile.js +1 -1
  321. package/dist/src/profiles/stack-profile.js.map +1 -1
  322. package/dist/src/registry.d.ts +1 -1
  323. package/dist/src/registry.d.ts.map +1 -1
  324. package/dist/src/registry.js +3 -3
  325. package/dist/src/registry.js.map +1 -1
  326. package/dist/src/skill-schema.d.ts +1 -1
  327. package/dist/src/skill-schema.d.ts.map +1 -1
  328. package/dist/src/skill-schema.js +4 -1
  329. package/dist/src/skill-schema.js.map +1 -1
  330. package/dist/src/types.d.ts +116 -0
  331. package/dist/src/types.d.ts.map +1 -1
  332. package/dist/src/utils/editable-region.d.ts +46 -0
  333. package/dist/src/utils/editable-region.d.ts.map +1 -0
  334. package/dist/src/utils/editable-region.js +125 -0
  335. package/dist/src/utils/editable-region.js.map +1 -0
  336. package/dist/src/utils/fs-idempotent.d.ts +2 -1
  337. package/dist/src/utils/fs-idempotent.d.ts.map +1 -1
  338. package/dist/src/utils/fs-idempotent.js +11 -7
  339. package/dist/src/utils/fs-idempotent.js.map +1 -1
  340. package/dist/src/utils/generated-marker.d.ts +17 -0
  341. package/dist/src/utils/generated-marker.d.ts.map +1 -1
  342. package/dist/src/utils/generated-marker.js +29 -1
  343. package/dist/src/utils/generated-marker.js.map +1 -1
  344. package/dist/src/utils/index.d.ts +3 -1
  345. package/dist/src/utils/index.d.ts.map +1 -1
  346. package/dist/src/utils/index.js +3 -1
  347. package/dist/src/utils/index.js.map +1 -1
  348. package/dist/src/utils/io.d.ts +9 -0
  349. package/dist/src/utils/io.d.ts.map +1 -0
  350. package/dist/src/utils/io.js +130 -0
  351. package/dist/src/utils/io.js.map +1 -0
  352. package/dist/src/utils/markdown-table.d.ts +21 -0
  353. package/dist/src/utils/markdown-table.d.ts.map +1 -0
  354. package/dist/src/utils/markdown-table.js +116 -0
  355. package/dist/src/utils/markdown-table.js.map +1 -0
  356. package/dist/src/utils/sync-fs.d.ts +5 -0
  357. package/dist/src/utils/sync-fs.d.ts.map +1 -0
  358. package/dist/src/utils/sync-fs.js +26 -0
  359. package/dist/src/utils/sync-fs.js.map +1 -0
  360. package/dist/src/validators/note-frontmatter-validate.js +1 -1
  361. package/dist/src/validators/note-frontmatter-validate.js.map +1 -1
  362. package/dist/src/validators/note-link-validate.js +1 -1
  363. package/dist/src/validators/note-link-validate.js.map +1 -1
  364. package/dist/src/validators/note-orphan-detect.js +1 -1
  365. package/dist/src/validators/note-orphan-detect.js.map +1 -1
  366. package/dist/src/validators/port-validate.js +1 -1
  367. package/dist/src/validators/port-validate.js.map +1 -1
  368. package/dist/src/validators/skill-validate.d.ts.map +1 -1
  369. package/dist/src/validators/skill-validate.js +34 -13
  370. package/dist/src/validators/skill-validate.js.map +1 -1
  371. package/os/adr/adr.module.ts +136 -132
  372. package/os/adr/frontmatter-io.ts +5 -5
  373. package/os/adr/handlers/archive.ts +8 -4
  374. package/os/adr/handlers/implement-stamp.ts +14 -9
  375. package/os/adr/handlers/list-create.ts +5 -5
  376. package/os/adr/handlers/validate.ts +1 -1
  377. package/os/audit/audit.module.ts +33 -34
  378. package/os/audit/frontmatter-io.ts +5 -5
  379. package/os/audit/handlers/archive.ts +8 -4
  380. package/os/compass/compass.module.ts +17 -1
  381. package/os/compass/handlers/compass-audit-handler.ts +13 -5
  382. package/os/compass/handlers/compass-change-summary-handler.ts +4 -2
  383. package/os/compass/handlers/compass-inventory-handler.ts +7 -4
  384. package/os/compass/handlers/compass-inventory.ts +11 -8
  385. package/os/compass/handlers/compass-migrate-handler.ts +1 -1
  386. package/os/compass/handlers/compass-migrate.ts +7 -3
  387. package/os/compass/handlers/git-revision.ts +11 -6
  388. package/os/compass/handlers/resolve-scan-root.ts +1 -1
  389. package/os/compass/handlers/summary-record.ts +10 -4
  390. package/os/compass/handlers/tests/compass-audit-plan.test.ts +2 -1
  391. package/os/core/core.module.ts +43 -4
  392. package/os/core/handlers/assets-helpers.ts +7 -3
  393. package/os/core/handlers/build.ts +1 -1
  394. package/os/core/handlers/determinism-check.ts +12 -6
  395. package/os/core/handlers/dev.ts +1 -1
  396. package/os/core/handlers/file-size-lint.ts +16 -9
  397. package/os/core/handlers/forge-autonomy-validate.ts +10 -5
  398. package/os/core/handlers/knowledge-compact.ts +1 -1
  399. package/os/core/handlers/package-health.ts +1 -1
  400. package/os/core/handlers/pinned-check.ts +2 -2
  401. package/os/core/handlers/pinned-init.ts +9 -8
  402. package/os/core/handlers/pinned-validate.ts +3 -3
  403. package/os/core/handlers/profile-resolve.ts +1 -1
  404. package/os/core/handlers/public-surface.ts +1 -1
  405. package/os/core/handlers/release-prepare.ts +11 -6
  406. package/os/core/handlers/release-publish.ts +6 -6
  407. package/os/core/handlers/validate.ts +1 -1
  408. package/os/exploration/exploration.module.ts +1 -0
  409. package/os/exploration/frontmatter-io.ts +4 -4
  410. package/os/exploration/handlers/archive.ts +3 -3
  411. package/os/mission/handlers/archive.ts +27 -19
  412. package/os/mission/mission.module.ts +38 -39
  413. package/os/naming/naming-convention.ts +9 -3
  414. package/os/naming/naming.module.ts +25 -25
  415. package/os/notes/notes.module.ts +87 -85
  416. package/os/plan/frontmatter-io.ts +5 -5
  417. package/os/plan/handlers/archive.ts +8 -4
  418. package/os/plan/plan.module.ts +33 -34
  419. package/os/plugin/plugin.module.ts +8 -6
  420. package/os/program/discovery.ts +2 -2
  421. package/os/program/handlers/complete.ts +1 -1
  422. package/os/program/handlers/lease.ts +1 -1
  423. package/os/program/handlers/seal.ts +1 -1
  424. package/os/program/lease.ts +1 -1
  425. package/os/program/program.module.ts +198 -193
  426. package/os/queue/index.ts +1 -1
  427. package/os/queue/manifest.ts +10 -9
  428. package/os/queue/queue-validate.test.ts +6 -15
  429. package/os/rfc/acceptance.ts +12 -6
  430. package/os/rfc/decision-log.ts +4 -3
  431. package/os/rfc/dna-trace.ts +8 -2
  432. package/os/rfc/frontmatter-io.ts +5 -5
  433. package/os/rfc/handlers/archive.ts +9 -5
  434. package/os/rfc/handlers/check.ts +5 -3
  435. package/os/rfc/handlers/implement-stamp.ts +15 -10
  436. package/os/rfc/handlers/index-graph.ts +3 -3
  437. package/os/rfc/handlers/lifecycle.ts +7 -2
  438. package/os/rfc/handlers/list-create.ts +7 -6
  439. package/os/rfc/handlers/shared.ts +3 -3
  440. package/os/rfc/handlers/supersede-propose.ts +8 -3
  441. package/os/rfc/handlers/validate-rules-rfc1006.test.ts +18 -6
  442. package/os/rfc/handlers/validate-rules.ts +10 -5
  443. package/os/rfc/rfc-create-concurrent.test.ts +11 -3
  444. package/os/rfc/rfc.module.ts +413 -374
  445. package/os/rfc/verification-evidence.ts +11 -5
  446. package/os/rfc/verification-refresh.ts +4 -3
  447. package/os/session/frontmatter-io.ts +14 -14
  448. package/os/session/handlers/archive.ts +8 -4
  449. package/os/session/handlers/metrics-aggregate.ts +34 -13
  450. package/os/session/handlers/metrics-rfc.ts +13 -8
  451. package/os/session/handlers/metrics-session.ts +7 -3
  452. package/os/session/handlers/save.ts +12 -8
  453. package/os/session/session.module.ts +6 -0
  454. package/os/spec/live-spec-list.ts +4 -4
  455. package/os/spec/live-spec-merge.ts +5 -5
  456. package/os/spec/live-spec-show.ts +3 -3
  457. package/os/spec/live-spec-validate.ts +4 -4
  458. package/os/spec/spec-materialize.ts +9 -9
  459. package/os/spec/spec-status.ts +9 -9
  460. package/os/spec/spec-validate.ts +7 -7
  461. package/os/spec/spec.module.ts +8 -0
  462. package/os/werkstatt/handlers/lock.ts +16 -16
  463. package/os/werkstatt/handlers/werkstatt-lock-recover.ts +3 -3
  464. package/os/werkstatt/handlers/werkstatt-operation-validate.ts +4 -2
  465. package/os/werkstatt/werkstatt.module.ts +8 -5
  466. package/os/workflow/handlers.ts +7 -5
  467. package/os/workflow/workflow.module.ts +45 -44
  468. package/package.json +1 -1
  469. package/skills/fo/fo-add-tests/SKILL.md +2 -2
  470. package/skills/fo/fo-architecture/SKILL.md +2 -2
  471. package/skills/fo/fo-compass-annotate/SKILL.md +2 -2
  472. package/skills/fo/fo-design-summit/SKILL.md +2 -2
  473. package/skills/fo/fo-doc-audit/SKILL.md +2 -2
  474. package/skills/fo/fo-explore/SKILL.md +2 -2
  475. package/skills/fo/fo-extract-dna/SKILL.md +2 -2
  476. package/skills/fo/fo-fix/SKILL.md +2 -2
  477. package/skills/fo/fo-handoff/SKILL.md +2 -2
  478. package/skills/fo/fo-harvest/SKILL.md +2 -2
  479. package/skills/fo/fo-idea/SKILL.md +2 -2
  480. package/skills/fo/fo-idea-audit/SKILL.md +2 -2
  481. package/skills/fo/fo-idea-create-adr/SKILL.md +3 -3
  482. package/skills/fo/fo-idea-create-rfc/SKILL.md +3 -3
  483. package/skills/fo/fo-idea-enhance/SKILL.md +2 -2
  484. package/skills/fo/fo-idea-i-just-want-to-see-the-plan/SKILL.md +2 -2
  485. package/skills/fo/fo-idea-i-just-want-to-see-the-result/SKILL.md +1 -1
  486. package/skills/fo/fo-idea-implement/SKILL.md +2 -2
  487. package/skills/fo/fo-idea-plan/SKILL.md +2 -2
  488. package/skills/fo/fo-idea-status/SKILL.md +2 -2
  489. package/skills/fo/fo-knowledge-distill/SKILL.md +2 -2
  490. package/skills/fo/fo-memory-sync/SKILL.md +2 -2
  491. package/skills/fo/fo-qa/SKILL.md +2 -2
  492. package/skills/fo/fo-review/SKILL.md +2 -2
  493. package/skills/fo/fo-session-retro/SKILL.md +2 -2
  494. package/skills/fo/fo-session-save/SKILL.md +2 -2
  495. package/skills/fo/fo-spec-ingest/SKILL.md +2 -2
  496. package/skills/fo/fo-step-commit/SKILL.md +1 -1
  497. package/skills/fo/fo-triage/SKILL.md +2 -2
  498. package/skills/meta/forge-bootstrap/SKILL.md +1 -1
  499. package/skills/meta/port-to-forge/SKILL.md +1 -1
  500. package/skills/meta/skill-create/SKILL.md +1 -1
  501. package/skills/shared/grilling/SKILL.md +1 -1
  502. package/skills/shared/grilling/learned-principles.archive.md +17 -0
  503. package/skills/shared/grilling/learned-principles.md +0 -1
  504. package/skills/shared/knowledge/learned-principles.md +6 -0
  505. package/skills/shared/my-preferences/SKILL.md +1 -1
  506. package/skills/shared/windows-ai-tooling/SKILL.md +1 -1
  507. package/skills/shared/writing-great-skills/SKILL.md +1 -1
  508. package/src/compass/contract-registry.ts +1 -1
  509. package/src/config/forge-config.ts +1 -1
  510. package/src/knowledge/__tests__/sync.test.ts +2 -7
  511. package/src/knowledge/budgets.ts +1 -1
  512. package/src/knowledge/compact.ts +1 -1
  513. package/src/knowledge/parse.ts +1 -1
  514. package/src/knowledge/sync.ts +3 -5
  515. package/src/migration-adapters/git-utils.ts +2 -2
  516. package/src/migration-adapters/ignored-files.ts +2 -2
  517. package/src/migration-adapters/node-typescript-pnpm/index.ts +1 -1
  518. package/src/migration-adapters/phaser-pnpm/index.ts +1 -1
  519. package/src/onboarding/agents-generate.ts +74 -33
  520. package/src/onboarding/create.ts +10 -10
  521. package/src/onboarding/doctor.ts +70 -55
  522. package/src/onboarding/init.ts +38 -1
  523. package/src/onboarding/invariant-engine.ts +1 -1
  524. package/src/onboarding/memory-compact.ts +5 -4
  525. package/src/onboarding/memory-scaffold.ts +1 -1
  526. package/src/onboarding/nested-agents-generate.ts +45 -4
  527. package/src/onboarding/nested-agents-templates.ts +19 -13
  528. package/src/onboarding/npm-token-check.ts +2 -2
  529. package/src/onboarding/prettierignore.ts +263 -0
  530. package/src/onboarding/profile-validate.ts +5 -4
  531. package/src/onboarding/scaffold-project.ts +38 -27
  532. package/src/onboarding/scaffold.ts +1 -1
  533. package/src/onboarding/skill-markers.ts +162 -0
  534. package/src/onboarding/templates/behavioral-layer-core.md +2 -4
  535. package/src/onboarding/upgrade.ts +285 -89
  536. package/src/onboarding/workspace-discovery.ts +1 -1
  537. package/src/pipeline-status.test.ts +1 -4
  538. package/src/pipeline-status.ts +30 -13
  539. package/src/profiles/stack-profile.ts +1 -1
  540. package/src/registry.ts +4 -4
  541. package/src/skill-schema.ts +4 -1
  542. package/src/tests/acceptance-probe-kinds.test.ts +5 -15
  543. package/src/tests/agents-generate.test.ts +6 -4
  544. package/src/tests/contract-registry.test.ts +12 -6
  545. package/src/tests/doctor-fix.test.ts +1 -4
  546. package/src/tests/doctor-nested-agents.test.ts +53 -1
  547. package/src/tests/editable-generated-region.test.ts +231 -0
  548. package/src/tests/file-size-lint.test.ts +8 -12
  549. package/src/tests/fixtures/agents-generate-business-before.txt +54 -54
  550. package/src/tests/markdown-table.test.ts +107 -0
  551. package/src/tests/prettierignore-manage.test.ts +134 -0
  552. package/src/tests/skill-agents-sync.test.ts +168 -0
  553. package/src/tests/skill-sync-marker.test.ts +134 -0
  554. package/src/tests/skill-validate.test.ts +12 -5
  555. package/src/tests/upgrade.test.ts +87 -41
  556. package/src/types.ts +123 -0
  557. package/src/utils/editable-region.ts +156 -0
  558. package/src/utils/fs-idempotent.ts +12 -6
  559. package/src/utils/generated-marker.ts +36 -2
  560. package/src/utils/index.ts +17 -0
  561. package/src/utils/io.ts +143 -0
  562. package/src/utils/markdown-table.ts +121 -0
  563. package/src/utils/sync-fs.ts +43 -0
  564. package/src/validators/note-frontmatter-validate.ts +1 -1
  565. package/src/validators/note-link-validate.ts +1 -1
  566. package/src/validators/note-orphan-detect.ts +1 -1
  567. package/src/validators/port-validate.ts +1 -1
  568. package/src/validators/skill-validate.ts +38 -13
@@ -21,8 +21,8 @@ Sweep batch 4: 73 Compass headers on headerless engine files (certification, com
21
21
  </CHANGE_SUMMARY>
22
22
  */
23
23
 
24
- import fs from "node:fs/promises";
25
- import { exec } from "node:child_process";
24
+ import { ambientIo as fs } from "../../../src/utils/io.ts";
25
+ import { exec } from "../../../src/utils/sync-fs.ts";
26
26
  import { promisify } from "node:util";
27
27
  import path from "node:path";
28
28
  import type {
@@ -141,7 +141,7 @@ async function appendAuditLog(
141
141
  ): Promise<void> {
142
142
  const logPath = path.join(repoRoot, AUDIT_LOG_PATH);
143
143
  const line = JSON.stringify(entry) + "\n";
144
- await fs.appendFile(logPath, line, "utf8");
144
+ await fs.appendFile(logPath, line);
145
145
  }
146
146
 
147
147
  export async function runPinnedValidate(
@@ -11,7 +11,7 @@
11
11
  </CHANGE_SUMMARY>
12
12
  */
13
13
 
14
- import fs from "node:fs";
14
+ import * as fs from "../../../src/utils/sync-fs.ts";
15
15
  import path from "node:path";
16
16
  import { parse as parseYaml } from "yaml";
17
17
  import { resolveForgeRoot } from "../../../src/config/forge-config.ts";
@@ -13,7 +13,7 @@
13
13
  </CHANGE_SUMMARY>
14
14
  */
15
15
 
16
- import fs from "node:fs";
16
+ import * as fs from "../../../src/utils/sync-fs.ts";
17
17
  import path from "node:path";
18
18
  import type {
19
19
  ForgeCommandInput,
@@ -14,8 +14,8 @@
14
14
  </CHANGE_SUMMARY>
15
15
  */
16
16
 
17
- import { readFile, copyFile, mkdir, stat } from "node:fs/promises";
18
17
  import { join, basename } from "node:path";
18
+ import { ambientIo, resolveIo } from "../../../src/utils/io.ts";
19
19
  import { createHash } from "node:crypto";
20
20
  import type {
21
21
  ForgeCommandInput,
@@ -27,6 +27,10 @@ import { loadWorkspaceDeps } from "../../werkstatt/handlers/workspace-deps.ts";
27
27
  import { writeFileIfChanged } from "../../../src/utils/fs-idempotent.ts";
28
28
  import type { ProfileRelease } from "../../../src/profiles/profile-schema.ts";
29
29
 
30
+ // Ambient default for helper fns without a context param — handlers override
31
+ // with `const io = resolveIo(context.io)` inside their own scope.
32
+ const io = ambientIo;
33
+
30
34
  export interface ReleaseManifest {
31
35
  schemaVersion: string;
32
36
  releaseId: string;
@@ -58,7 +62,7 @@ function generateReleaseId(profileId: string, shortHash: string): string {
58
62
 
59
63
  async function readVersionFromPackageJson(workspaceRoot: string): Promise<string> {
60
64
  try {
61
- const raw = await readFile(join(workspaceRoot, "package.json"), "utf8");
65
+ const raw = await io.readFile(join(workspaceRoot, "package.json"));
62
66
  const pkg = JSON.parse(raw) as { version?: string };
63
67
  return pkg.version ?? "0.0.0";
64
68
  } catch {
@@ -79,7 +83,7 @@ async function findBuiltArtifacts(
79
83
  if (!isGlob) {
80
84
  const fullPath = join(workspaceRoot, produceOutput);
81
85
  try {
82
- const _s = await stat(fullPath);
86
+ const _s = await io.stat(fullPath);
83
87
  return [fullPath];
84
88
  } catch {
85
89
  return [];
@@ -110,6 +114,7 @@ export async function runReleasePrepare(
110
114
  input: ForgeCommandInput,
111
115
  context: ForgeRuntimeContext,
112
116
  ): Promise<ForgeCommandResult<ForgeReleasePrepareResult>> {
117
+ const io = resolveIo(context.io);
113
118
  const { workspaceRoot, logger } = context;
114
119
  const { dryRun, profileIdOverride } = resolveLifecycleFlags(input, context);
115
120
 
@@ -212,7 +217,7 @@ export async function runReleasePrepare(
212
217
  if (!dryRun) {
213
218
  const { byteHashFile } = await loadWorkspaceDeps();
214
219
  hash = await byteHashFile(builtFile);
215
- const stats = await stat(builtFile);
220
+ const stats = await io.stat(builtFile);
216
221
  size = stats.size;
217
222
  allHashes += hash;
218
223
  }
@@ -268,12 +273,12 @@ export async function runReleasePrepare(
268
273
  };
269
274
  }
270
275
 
271
- await mkdir(releaseDir, { recursive: true });
276
+ await io.mkdir(releaseDir);
272
277
 
273
278
  for (const a of manifestArtifacts) {
274
279
  const srcPath = join(workspaceRoot, a.path);
275
280
  const dstPath = join(releaseDir, basename(a.path));
276
- await copyFile(srcPath, dstPath);
281
+ await io.copyFile(srcPath, dstPath);
277
282
  }
278
283
 
279
284
  const manifestPath = join(releaseDir, releaseConfig.manifestName);
@@ -14,8 +14,8 @@
14
14
  </CHANGE_SUMMARY>
15
15
  */
16
16
 
17
- import { readFile, copyFile, mkdir } from "node:fs/promises";
18
17
  import { join, basename } from "node:path";
18
+ import { resolveIo } from "../../../src/utils/io.ts";
19
19
  import type {
20
20
  ForgeCommandInput,
21
21
  ForgeCommandResult,
@@ -46,6 +46,7 @@ export async function runReleasePublish(
46
46
  input: ForgeCommandInput,
47
47
  context: ForgeRuntimeContext,
48
48
  ): Promise<ForgeCommandResult<ForgeReleasePublishResult>> {
49
+ const io = resolveIo(context.io);
49
50
  const { workspaceRoot, logger } = context;
50
51
  const { dryRun, profileIdOverride } = resolveLifecycleFlags(input, context);
51
52
 
@@ -87,7 +88,7 @@ export async function runReleasePublish(
87
88
 
88
89
  let manifest: ReleaseManifest;
89
90
  try {
90
- const raw = await readFile(manifestPath, "utf8");
91
+ const raw = await io.readFile(manifestPath);
91
92
  manifest = JSON.parse(raw) as ReleaseManifest;
92
93
  } catch {
93
94
  return {
@@ -155,15 +156,14 @@ export async function runReleasePublish(
155
156
 
156
157
  if (target === "local") {
157
158
  const publishedDir = join(releaseDir, "published");
158
- await mkdir(publishedDir, { recursive: true });
159
+ await io.mkdir(publishedDir);
159
160
  for (const f of filesToPublish) {
160
161
  const dst = join(publishedDir, basename(f));
161
- await copyFile(f, dst);
162
+ await io.copyFile(f, dst);
162
163
  publishedFiles.push({ path: f, targetPath: dst });
163
164
  }
164
165
  } else if (target === "r2" || target === "s3") {
165
166
  const { S3Client, PutObjectCommand } = await import("@aws-sdk/client-s3");
166
- const { readFile: fsReadFile } = await import("node:fs/promises");
167
167
 
168
168
  const endpoint =
169
169
  target === "r2"
@@ -185,7 +185,7 @@ export async function runReleasePublish(
185
185
 
186
186
  for (const f of filesToPublish) {
187
187
  const key = prefix ? `${prefix}/${basename(f)}` : basename(f);
188
- const body = await fsReadFile(f);
188
+ const body = await io.readFile(f);
189
189
  await client.send(
190
190
  new PutObjectCommand({
191
191
  Bucket: bucket,
@@ -18,7 +18,7 @@ Sweep batch 4: 73 Compass headers on headerless engine files (certification, com
18
18
  </CHANGE_SUMMARY>
19
19
  */
20
20
 
21
- import { exec } from "node:child_process";
21
+ import { exec } from "../../../src/utils/sync-fs.ts";
22
22
  import { promisify } from "node:util";
23
23
  import type {
24
24
  ForgeCommandInput,
@@ -74,6 +74,7 @@ export async function createForgeExplorationModule(): Promise<ForgeModule> {
74
74
  scope: "workspace",
75
75
  mutatesState: true,
76
76
  writes: ["docs/explorations/*.md"],
77
+ generates: [],
77
78
  reads: ["docs/explorations/*.md"],
78
79
  cacheable: false,
79
80
  flags: {
@@ -13,7 +13,7 @@ their YAML frontmatter without validating the shape.
13
13
  </CHANGE_SUMMARY>
14
14
  */
15
15
 
16
- import fs from "node:fs/promises";
16
+ import { ambientIo as fs } from "../../src/utils/io.ts";
17
17
  import path from "node:path";
18
18
  import YAML from "yaml";
19
19
  import { EXPLORATION_DIR } from "./types.ts";
@@ -38,9 +38,9 @@ export async function listExplorationFiles(explorationsDirPath: string): Promise
38
38
  const results: string[] = [];
39
39
 
40
40
  try {
41
- const entries = await fs.readdir(explorationsDirPath, { withFileTypes: true });
41
+ const entries = await fs.readdir(explorationsDirPath);
42
42
  for (const entry of entries) {
43
- if (entry.isFile() && entry.name.endsWith(".md") && entry.name !== "README.md") {
43
+ if (entry.isFile && entry.name.endsWith(".md") && entry.name !== "README.md") {
44
44
  results.push(entry.name);
45
45
  }
46
46
  }
@@ -57,7 +57,7 @@ export async function readAndParseExplorationNote(
57
57
  ): Promise<{ fileName: string; parsed: ParsedExplorationNote } | undefined> {
58
58
  try {
59
59
  const filePath = path.join(explorationsDirPath, fileName);
60
- const content = await fs.readFile(filePath, "utf-8");
60
+ const content = await fs.readFile(filePath);
61
61
  return { fileName, parsed: parseExplorationFile(content) };
62
62
  } catch {
63
63
  return undefined;
@@ -10,7 +10,7 @@
10
10
  </CHANGE_SUMMARY>
11
11
  */
12
12
 
13
- import fs from "node:fs/promises";
13
+ import { ambientIo as fs } from "../../../src/utils/io.ts";
14
14
  import path from "node:path";
15
15
  import type {
16
16
  ForgeCommandInput,
@@ -110,7 +110,7 @@ export async function runExplorationArchive(
110
110
  related,
111
111
  };
112
112
  const updatedContent = serializeExplorationNote(updatedFrontmatter, result.parsed.body);
113
- await fs.writeFile(filePath, updatedContent, "utf-8");
113
+ await fs.writeFile(filePath, updatedContent);
114
114
  }
115
115
  if (outputFormat === "pretty") {
116
116
  logger.info(`Exploration note ${slug} is already archived (no-op).`);
@@ -136,7 +136,7 @@ export async function runExplorationArchive(
136
136
  };
137
137
 
138
138
  const updatedContent = serializeExplorationNote(updatedFrontmatter, result.parsed.body);
139
- await fs.writeFile(filePath, updatedContent, "utf-8");
139
+ await fs.writeFile(filePath, updatedContent);
140
140
 
141
141
  if (outputFormat === "pretty") {
142
142
  logger.success(`Archived exploration note: ${slug} (${previousStatus} → archived)`);
@@ -26,10 +26,10 @@ Sweep batch 2: real KEY_DECISIONS on 10 files, expanded purposes (CONTRACT-02/PU
26
26
  </CHANGE_SUMMARY>
27
27
  */
28
28
 
29
- import fs from "node:fs/promises";
30
- import { existsSync } from "node:fs";
29
+ import { ambientIo as fs } from "../../../src/utils/io.ts";
30
+ import { existsSync, lstatSync } from "../../../src/utils/sync-fs.ts";
31
31
  import path from "node:path";
32
- import { execSync } from "node:child_process";
32
+ import { execSync } from "../../../src/utils/sync-fs.ts";
33
33
  import { parse as parseYaml } from "yaml";
34
34
  import type {
35
35
  ForgeCommandInput,
@@ -61,7 +61,7 @@ async function cleanServiceFolders(workpieceDir: string): Promise<string[]> {
61
61
  for (const folder of SERVICE_FOLDERS) {
62
62
  const target = path.join(workpieceDir, folder);
63
63
  if (existsSync(target)) {
64
- await fs.rm(target, { recursive: true, force: true });
64
+ await fs.rm(target);
65
65
  removed.push(folder);
66
66
  }
67
67
  }
@@ -76,7 +76,7 @@ function isCacheEntry(name: string): boolean {
76
76
  async function readMissionReleaseId(missionDir: string): Promise<string | null> {
77
77
  const manifestPath = path.join(missionDir, "mission.yaml");
78
78
  try {
79
- const raw = await fs.readFile(manifestPath, "utf8");
79
+ const raw = await fs.readFile(manifestPath);
80
80
  const parsed = parseYaml(raw) as Record<string, unknown>;
81
81
  const releaseId = parsed?.releaseId;
82
82
  if (typeof releaseId === "string" && releaseId.trim()) return releaseId.trim();
@@ -89,7 +89,7 @@ async function readMissionReleaseId(missionDir: string): Promise<string | null>
89
89
  async function readMissionState(missionDir: string): Promise<string | null> {
90
90
  const manifestPath = path.join(missionDir, "mission.yaml");
91
91
  try {
92
- const raw = await fs.readFile(manifestPath, "utf8");
92
+ const raw = await fs.readFile(manifestPath);
93
93
  const parsed = parseYaml(raw) as Record<string, unknown>;
94
94
  const state = parsed?.state;
95
95
  if (typeof state === "string") return state.trim();
@@ -106,7 +106,7 @@ async function readMissionState(missionDir: string): Promise<string | null> {
106
106
  const workpieceDir = path.join(missionDir, "workpiece");
107
107
  if (existsSync(workpieceDir)) {
108
108
  const entries = await fs.readdir(workpieceDir);
109
- const nonCacheEntries = entries.filter((e) => !isCacheEntry(e));
109
+ const nonCacheEntries = entries.filter((e) => !isCacheEntry(e.name));
110
110
  if (nonCacheEntries.length === 0) {
111
111
  return "closed";
112
112
  }
@@ -125,17 +125,17 @@ async function isOrphanedRemnant(missionDir: string): Promise<boolean> {
125
125
  if (!existsSync(workpieceDir)) return true;
126
126
 
127
127
  const entries = await fs.readdir(workpieceDir);
128
- const nonCacheEntries = entries.filter((e) => !isCacheEntry(e));
128
+ const nonCacheEntries = entries.filter((e) => !isCacheEntry(e.name));
129
129
  return nonCacheEntries.length === 0;
130
130
  }
131
131
 
132
132
  // RFC-0982: Check if a mission directory has non-cache content (source files,
133
133
  // configs, etc.) that warrants manual inspection rather than auto-cleanup.
134
134
  async function hasNonCacheContent(missionDir: string): Promise<boolean> {
135
- const entries = await fs.readdir(missionDir, { withFileTypes: true });
135
+ const entries = await fs.readdir(missionDir);
136
136
  for (const entry of entries) {
137
137
  if (entry.name === "workpiece") continue;
138
- if (entry.isDirectory() && isCacheEntry(entry.name)) {
138
+ if (entry.isDirectory && isCacheEntry(entry.name)) {
139
139
  continue;
140
140
  }
141
141
  // Any file or non-cache directory at mission root is content
@@ -146,7 +146,7 @@ async function hasNonCacheContent(missionDir: string): Promise<boolean> {
146
146
  const workpieceDir = path.join(missionDir, "workpiece");
147
147
  if (existsSync(workpieceDir)) {
148
148
  const wpEntries = await fs.readdir(workpieceDir);
149
- const nonCacheEntries = wpEntries.filter((e) => !isCacheEntry(e));
149
+ const nonCacheEntries = wpEntries.filter((e) => !isCacheEntry(e.name));
150
150
  if (nonCacheEntries.length > 0) return true;
151
151
  }
152
152
 
@@ -176,7 +176,7 @@ async function moveMissionDir(
176
176
 
177
177
  if (!dryRun) {
178
178
  if (targetParentDir) {
179
- await fs.mkdir(targetParentDir, { recursive: true });
179
+ await fs.mkdir(targetParentDir);
180
180
  }
181
181
 
182
182
  // RFC-0801: Clean service folders from workpiece before move.
@@ -271,14 +271,17 @@ export async function runMissionArchive(
271
271
  }
272
272
 
273
273
  // Phase 1: Scan missions/ for terminal-state missions to move into archive
274
- const rootEntries = await fs.readdir(missionsPath, { withFileTypes: true });
274
+ const rootEntries = await fs.readdir(missionsPath);
275
275
 
276
276
  // Stale symlink cleanup: IDEs or file watchers may recreate symlinks to
277
277
  // archived mission directories after mission.archive has moved them.
278
278
  // These symlinks break pnpm workspace resolution and mission number derivation.
279
279
  // Trash them before they can cause downstream issues.
280
280
  for (const e of rootEntries) {
281
- if (e.isSymbolicLink() && e.name !== ARCHIVE_DIR_NAME) {
281
+ if (
282
+ lstatSync(path.join(missionsPath, e.name)).isSymbolicLink() &&
283
+ e.name !== ARCHIVE_DIR_NAME
284
+ ) {
282
285
  const symlinkPath = path.join(missionsPath, e.name);
283
286
  const sourceRel = `${MISSIONS_DIR}/${e.name}`;
284
287
  if (!dryRun) {
@@ -296,7 +299,12 @@ export async function runMissionArchive(
296
299
  }
297
300
 
298
301
  const rootDirs = rootEntries
299
- .filter((e) => e.isDirectory() && !e.isSymbolicLink() && e.name !== ARCHIVE_DIR_NAME)
302
+ .filter(
303
+ (e) =>
304
+ e.isDirectory &&
305
+ !lstatSync(path.join(missionsPath, e.name)).isSymbolicLink() &&
306
+ e.name !== ARCHIVE_DIR_NAME,
307
+ )
300
308
  .map((e) => e.name);
301
309
 
302
310
  for (const missionId of rootDirs) {
@@ -410,13 +418,13 @@ export async function runMissionArchive(
410
418
  // Phase 2: Scan missions/archive/<state>/ for non-terminal missions to move back
411
419
  const archivePath = path.join(missionsPath, ARCHIVE_DIR_NAME);
412
420
  if (existsSync(archivePath)) {
413
- const stateDirs = await fs.readdir(archivePath, { withFileTypes: true });
414
- const stateDirNames = stateDirs.filter((e) => e.isDirectory()).map((e) => e.name);
421
+ const stateDirs = await fs.readdir(archivePath);
422
+ const stateDirNames = stateDirs.filter((e) => e.isDirectory).map((e) => e.name);
415
423
 
416
424
  for (const stateDirName of stateDirNames) {
417
425
  const stateDirPath = path.join(archivePath, stateDirName);
418
- const archivedMissions = await fs.readdir(stateDirPath, { withFileTypes: true });
419
- const archivedDirNames = archivedMissions.filter((e) => e.isDirectory()).map((e) => e.name);
426
+ const archivedMissions = await fs.readdir(stateDirPath);
427
+ const archivedDirNames = archivedMissions.filter((e) => e.isDirectory).map((e) => e.name);
420
428
 
421
429
  for (const missionId of archivedDirNames) {
422
430
  const archivedMissionDir = path.join(stateDirPath, missionId);
@@ -14,47 +14,46 @@
14
14
  import type { ForgeModule } from "../../src/forge-module.ts";
15
15
 
16
16
  export async function createForgeMissionModule(): Promise<ForgeModule> {
17
- const { runMissionArchive } = await import("./handlers/archive.ts");
17
+ const { runMissionArchive } = await import("./handlers/archive.ts");
18
18
  return {
19
- name: "forge-mission",
20
- version: "0.1.0",
21
- runtime: "autonomous",
19
+ name: "forge-mission",
20
+ version: "0.1.0",
21
+ runtime: "autonomous",
22
22
  declarations: [],
23
- commands: [
24
- {
25
- name: "mission.archive",
26
- description:
27
- "Move terminal-state mission directories (state: closed or aborted in " +
28
- "mission.yaml) into missions/archive/<state>/<missionId>/ subdirectories. " +
29
- "Bidirectional: moves open missions found in archive subdirectories back " +
30
- "to missions/. Use --dry-run to preview. Use --status to filter to a " +
31
- "single terminal status (closed, aborted). " +
32
- "Prefer the docs.archive umbrella command unless you need to archive only missions.",
33
- scope: "workspace",
34
- mutatesState: true,
35
- writes: ["missions/*", "missions/archive/**"],
36
- reads: ["missions/**"],
37
- cacheable: false,
38
- flags: {
39
- "dry-run": {
40
- kind: "boolean",
41
- description: "Preview what would be moved without touching the filesystem.",
42
- },
43
- status: {
44
- kind: "string",
45
- description: "Filter to a single terminal status (closed, aborted).",
46
- },
47
- "clean-orphans": {
48
- kind: "boolean",
49
- description:
50
- "Trash orphaned directories (no mission.yaml, only cache files) instead of archiving them.",
23
+ commands: [
24
+ {
25
+ name: "mission.archive",
26
+ description:
27
+ "Move terminal-state mission directories (state: closed or aborted in " +
28
+ "mission.yaml) into missions/archive/<state>/<missionId>/ subdirectories. " +
29
+ "Bidirectional: moves open missions found in archive subdirectories back " +
30
+ "to missions/. Use --dry-run to preview. Use --status to filter to a " +
31
+ "single terminal status (closed, aborted). " +
32
+ "Prefer the docs.archive umbrella command unless you need to archive only missions.",
33
+ scope: "workspace",
34
+ mutatesState: true,
35
+ writes: ["missions/*", "missions/archive/**"],
36
+ generates: [],
37
+ reads: ["missions/**"],
38
+ cacheable: false,
39
+ flags: {
40
+ "dry-run": {
41
+ kind: "boolean",
42
+ description: "Preview what would be moved without touching the filesystem.",
43
+ },
44
+ status: {
45
+ kind: "string",
46
+ description: "Filter to a single terminal status (closed, aborted).",
47
+ },
48
+ "clean-orphans": {
49
+ kind: "boolean",
50
+ description:
51
+ "Trash orphaned directories (no mission.yaml, only cache files) instead of archiving them.",
52
+ },
51
53
  },
54
+ execute: runMissionArchive,
52
55
  },
53
- execute: runMissionArchive,
54
- }
55
- ],
56
- pipelines: [
57
-
58
- ]};
56
+ ],
57
+ pipelines: [],
58
+ };
59
59
  }
60
- ;
@@ -13,9 +13,14 @@ uses kebab-case (lowercase letters, digits, hyphens only), with documented exemp
13
13
  */
14
14
 
15
15
  import { basename, join, relative } from "node:path";
16
- import { readFile } from "node:fs/promises";
17
- import { readdirSync, type Dirent } from "node:fs";
16
+ import { ambientIo, resolveIo } from "../../src/utils/io.ts";
17
+
18
+ import { readdirSync, type Dirent } from "../../src/utils/sync-fs.ts";
18
19
  import { collectFiles } from "../../src/utils/fs.ts";
20
+
21
+ // Ambient default for helper fns without a context param — handlers override
22
+ // with `const io = resolveIo(context.io)` inside their own scope.
23
+ const io = ambientIo;
19
24
  import type {
20
25
  ForgeCommandInput,
21
26
  ForgeCommandResult,
@@ -168,7 +173,7 @@ function hasNamingViolation(fileName: string): boolean {
168
173
  async function readSimpleIgnorePatterns(filePath: string): Promise<Set<string>> {
169
174
  const patterns = new Set<string>();
170
175
  try {
171
- const content = await readFile(filePath, "utf8");
176
+ const content = await io.readFile(filePath);
172
177
  for (const rawLine of content.split("\n")) {
173
178
  const line = rawLine.trim();
174
179
  if (!line || line.startsWith("#")) continue;
@@ -270,6 +275,7 @@ export async function runNamingConventionLint(
270
275
  unknownTopLevelDirs?: string[];
271
276
  }>
272
277
  > {
278
+ const _io = resolveIo(context.io);
273
279
  const workspaceRoot = context.workspaceRoot;
274
280
  const includeIgnored = input.flags["include-ignored"] === true;
275
281
 
@@ -7,39 +7,39 @@
7
7
  </MODULE_CONTRACT>
8
8
  <CHANGE_SUMMARY>
9
9
  <item>RFC-0374: initial forgeNamingModule registering naming.convention.lint.</item>
10
+ <item>RFC-1173: declare mutatesState on all kernel commands — collectDeclarationDiagnostics emits error-severity MUTATES-STATE-DECLARED, command.manifest.validate is the blocking consumer in packages.check, sweep declares the flag on every command definition (factories hardcode false for read-only check specs)</item>
10
11
  </CHANGE_SUMMARY>
11
12
  */
12
13
 
13
14
  import type { ForgeModule } from "../../src/forge-module.ts";
14
15
 
15
16
  export async function createForgeNamingModule(): Promise<ForgeModule> {
16
- const { runNamingConventionLint } = await import("./naming-convention.ts");
17
+ const { runNamingConventionLint } = await import("./naming-convention.ts");
17
18
  return {
18
- name: "forge-naming",
19
- version: "0.1.0",
20
- runtime: "autonomous",
19
+ name: "forge-naming",
20
+ version: "0.1.0",
21
+ runtime: "autonomous",
21
22
  declarations: [],
22
- commands: [
23
- {
24
- name: "naming.convention.lint",
25
- contract: "naming",
26
- rules: [],
27
- description:
28
- "Validate all filenames use kebab-case (no underscores) across registered workspace roots.",
29
- scope: "workspace",
30
- supportsAllSites: true,
31
- flags: {
32
- "include-ignored": {
33
- kind: "boolean",
34
- description: "Also scan files ignored by .gitignore or .windsurfignore.",
23
+ commands: [
24
+ {
25
+ name: "naming.convention.lint",
26
+ mutatesState: false,
27
+ contract: "naming",
28
+ rules: [],
29
+ description:
30
+ "Validate all filenames use kebab-case (no underscores) across registered workspace roots.",
31
+ scope: "workspace",
32
+ supportsAllSites: true,
33
+ flags: {
34
+ "include-ignored": {
35
+ kind: "boolean",
36
+ description: "Also scan files ignored by .gitignore or .windsurfignore.",
37
+ },
35
38
  },
39
+ reads: ["packages/**/*.{ts,tsx}", "apps/**/*.{ts,tsx}", "services/**/*.{ts,tsx}"],
40
+ execute: runNamingConventionLint,
36
41
  },
37
- reads: ["packages/**/*.{ts,tsx}", "apps/**/*.{ts,tsx}", "services/**/*.{ts,tsx}"],
38
- execute: runNamingConventionLint,
39
- }
40
- ],
41
- pipelines: [
42
-
43
- ]};
42
+ ],
43
+ pipelines: [],
44
+ };
44
45
  }
45
- ;