@warpgogol/forge 5.2.4 → 5.3.1

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 (590) hide show
  1. package/README.md +1 -1
  2. package/README.uk.md +8 -8
  3. package/bin/cli.ts +25 -33
  4. package/dist/bin/cli.js +21 -32
  5. package/dist/bin/cli.js.map +1 -1
  6. package/dist/os/adr/adr.module.d.ts.map +1 -1
  7. package/dist/os/adr/adr.module.js +8 -3
  8. package/dist/os/adr/adr.module.js.map +1 -1
  9. package/dist/os/adr/frontmatter-io.js +5 -5
  10. package/dist/os/adr/frontmatter-io.js.map +1 -1
  11. package/dist/os/adr/handlers/archive.d.ts.map +1 -1
  12. package/dist/os/adr/handlers/archive.js +10 -4
  13. package/dist/os/adr/handlers/archive.js.map +1 -1
  14. package/dist/os/adr/handlers/implement-stamp.d.ts.map +1 -1
  15. package/dist/os/adr/handlers/implement-stamp.js +10 -10
  16. package/dist/os/adr/handlers/implement-stamp.js.map +1 -1
  17. package/dist/os/adr/handlers/list-create.js +5 -5
  18. package/dist/os/adr/handlers/list-create.js.map +1 -1
  19. package/dist/os/adr/handlers/validate.js +1 -1
  20. package/dist/os/adr/handlers/validate.js.map +1 -1
  21. package/dist/os/audit/audit.module.js +3 -3
  22. package/dist/os/audit/audit.module.js.map +1 -1
  23. package/dist/os/audit/frontmatter-io.js +5 -5
  24. package/dist/os/audit/frontmatter-io.js.map +1 -1
  25. package/dist/os/audit/handlers/archive.d.ts.map +1 -1
  26. package/dist/os/audit/handlers/archive.js +10 -4
  27. package/dist/os/audit/handlers/archive.js.map +1 -1
  28. package/dist/os/compass/compass.module.d.ts.map +1 -1
  29. package/dist/os/compass/compass.module.js +17 -1
  30. package/dist/os/compass/compass.module.js.map +1 -1
  31. package/dist/os/compass/handlers/compass-audit-handler.d.ts.map +1 -1
  32. package/dist/os/compass/handlers/compass-audit-handler.js +12 -5
  33. package/dist/os/compass/handlers/compass-audit-handler.js.map +1 -1
  34. package/dist/os/compass/handlers/compass-change-summary-handler.d.ts.map +1 -1
  35. package/dist/os/compass/handlers/compass-change-summary-handler.js +3 -2
  36. package/dist/os/compass/handlers/compass-change-summary-handler.js.map +1 -1
  37. package/dist/os/compass/handlers/compass-inventory-handler.d.ts.map +1 -1
  38. package/dist/os/compass/handlers/compass-inventory-handler.js +6 -4
  39. package/dist/os/compass/handlers/compass-inventory-handler.js.map +1 -1
  40. package/dist/os/compass/handlers/compass-inventory.d.ts.map +1 -1
  41. package/dist/os/compass/handlers/compass-inventory.js +10 -8
  42. package/dist/os/compass/handlers/compass-inventory.js.map +1 -1
  43. package/dist/os/compass/handlers/compass-migrate-handler.js +1 -1
  44. package/dist/os/compass/handlers/compass-migrate-handler.js.map +1 -1
  45. package/dist/os/compass/handlers/compass-migrate.d.ts.map +1 -1
  46. package/dist/os/compass/handlers/compass-migrate.js +6 -3
  47. package/dist/os/compass/handlers/compass-migrate.js.map +1 -1
  48. package/dist/os/compass/handlers/git-revision.d.ts.map +1 -1
  49. package/dist/os/compass/handlers/git-revision.js +9 -6
  50. package/dist/os/compass/handlers/git-revision.js.map +1 -1
  51. package/dist/os/compass/handlers/resolve-scan-root.js +1 -1
  52. package/dist/os/compass/handlers/resolve-scan-root.js.map +1 -1
  53. package/dist/os/compass/handlers/summary-record.d.ts.map +1 -1
  54. package/dist/os/compass/handlers/summary-record.js +8 -4
  55. package/dist/os/compass/handlers/summary-record.js.map +1 -1
  56. package/dist/os/core/core.module.d.ts.map +1 -1
  57. package/dist/os/core/core.module.js +43 -4
  58. package/dist/os/core/core.module.js.map +1 -1
  59. package/dist/os/core/handlers/assets-helpers.d.ts.map +1 -1
  60. package/dist/os/core/handlers/assets-helpers.js +6 -3
  61. package/dist/os/core/handlers/assets-helpers.js.map +1 -1
  62. package/dist/os/core/handlers/build.js +1 -1
  63. package/dist/os/core/handlers/build.js.map +1 -1
  64. package/dist/os/core/handlers/determinism-check.d.ts.map +1 -1
  65. package/dist/os/core/handlers/determinism-check.js +10 -6
  66. package/dist/os/core/handlers/determinism-check.js.map +1 -1
  67. package/dist/os/core/handlers/dev.js +1 -1
  68. package/dist/os/core/handlers/dev.js.map +1 -1
  69. package/dist/os/core/handlers/file-size-lint.d.ts.map +1 -1
  70. package/dist/os/core/handlers/file-size-lint.js +11 -7
  71. package/dist/os/core/handlers/file-size-lint.js.map +1 -1
  72. package/dist/os/core/handlers/forge-autonomy-validate.d.ts.map +1 -1
  73. package/dist/os/core/handlers/forge-autonomy-validate.js +9 -5
  74. package/dist/os/core/handlers/forge-autonomy-validate.js.map +1 -1
  75. package/dist/os/core/handlers/knowledge-compact.js +1 -1
  76. package/dist/os/core/handlers/knowledge-compact.js.map +1 -1
  77. package/dist/os/core/handlers/package-health.js +1 -1
  78. package/dist/os/core/handlers/package-health.js.map +1 -1
  79. package/dist/os/core/handlers/pinned-check.js +2 -2
  80. package/dist/os/core/handlers/pinned-check.js.map +1 -1
  81. package/dist/os/core/handlers/pinned-init.d.ts.map +1 -1
  82. package/dist/os/core/handlers/pinned-init.js +9 -8
  83. package/dist/os/core/handlers/pinned-init.js.map +1 -1
  84. package/dist/os/core/handlers/pinned-validate.js +3 -3
  85. package/dist/os/core/handlers/pinned-validate.js.map +1 -1
  86. package/dist/os/core/handlers/profile-resolve.js +1 -1
  87. package/dist/os/core/handlers/profile-resolve.js.map +1 -1
  88. package/dist/os/core/handlers/public-surface.js +1 -1
  89. package/dist/os/core/handlers/public-surface.js.map +1 -1
  90. package/dist/os/core/handlers/release-prepare.d.ts.map +1 -1
  91. package/dist/os/core/handlers/release-prepare.js +10 -6
  92. package/dist/os/core/handlers/release-prepare.js.map +1 -1
  93. package/dist/os/core/handlers/release-publish.js +6 -6
  94. package/dist/os/core/handlers/release-publish.js.map +1 -1
  95. package/dist/os/core/handlers/validate.js +1 -1
  96. package/dist/os/core/handlers/validate.js.map +1 -1
  97. package/dist/os/exploration/exploration.module.d.ts.map +1 -1
  98. package/dist/os/exploration/exploration.module.js +1 -0
  99. package/dist/os/exploration/exploration.module.js.map +1 -1
  100. package/dist/os/exploration/frontmatter-io.js +4 -4
  101. package/dist/os/exploration/frontmatter-io.js.map +1 -1
  102. package/dist/os/exploration/handlers/archive.js +3 -3
  103. package/dist/os/exploration/handlers/archive.js.map +1 -1
  104. package/dist/os/mission/handlers/archive.d.ts.map +1 -1
  105. package/dist/os/mission/handlers/archive.js +44 -23
  106. package/dist/os/mission/handlers/archive.js.map +1 -1
  107. package/dist/os/mission/mission.module.js +3 -3
  108. package/dist/os/mission/mission.module.js.map +1 -1
  109. package/dist/os/naming/naming-convention.d.ts.map +1 -1
  110. package/dist/os/naming/naming-convention.js +7 -3
  111. package/dist/os/naming/naming-convention.js.map +1 -1
  112. package/dist/os/naming/naming.module.d.ts.map +1 -1
  113. package/dist/os/naming/naming.module.js +4 -3
  114. package/dist/os/naming/naming.module.js.map +1 -1
  115. package/dist/os/notes/notes.module.d.ts.map +1 -1
  116. package/dist/os/notes/notes.module.js +6 -3
  117. package/dist/os/notes/notes.module.js.map +1 -1
  118. package/dist/os/plan/frontmatter-io.js +5 -5
  119. package/dist/os/plan/frontmatter-io.js.map +1 -1
  120. package/dist/os/plan/handlers/archive.d.ts.map +1 -1
  121. package/dist/os/plan/handlers/archive.js +10 -4
  122. package/dist/os/plan/handlers/archive.js.map +1 -1
  123. package/dist/os/plan/plan.module.js +3 -3
  124. package/dist/os/plan/plan.module.js.map +1 -1
  125. package/dist/os/plugin/plugin.module.d.ts.map +1 -1
  126. package/dist/os/plugin/plugin.module.js +6 -3
  127. package/dist/os/plugin/plugin.module.js.map +1 -1
  128. package/dist/os/program/discovery.js +2 -2
  129. package/dist/os/program/discovery.js.map +1 -1
  130. package/dist/os/program/handlers/complete.js +1 -1
  131. package/dist/os/program/handlers/complete.js.map +1 -1
  132. package/dist/os/program/handlers/lease.js +1 -1
  133. package/dist/os/program/handlers/lease.js.map +1 -1
  134. package/dist/os/program/handlers/seal.js +1 -1
  135. package/dist/os/program/handlers/seal.js.map +1 -1
  136. package/dist/os/program/lease.js +1 -1
  137. package/dist/os/program/lease.js.map +1 -1
  138. package/dist/os/program/program.module.d.ts.map +1 -1
  139. package/dist/os/program/program.module.js +9 -3
  140. package/dist/os/program/program.module.js.map +1 -1
  141. package/dist/os/queue/index.js +1 -1
  142. package/dist/os/queue/manifest.d.ts.map +1 -1
  143. package/dist/os/queue/manifest.js +4 -8
  144. package/dist/os/queue/manifest.js.map +1 -1
  145. package/dist/os/rfc/acceptance.d.ts.map +1 -1
  146. package/dist/os/rfc/acceptance.js +10 -6
  147. package/dist/os/rfc/acceptance.js.map +1 -1
  148. package/dist/os/rfc/decision-log.d.ts.map +1 -1
  149. package/dist/os/rfc/decision-log.js +4 -3
  150. package/dist/os/rfc/decision-log.js.map +1 -1
  151. package/dist/os/rfc/dna-trace.d.ts.map +1 -1
  152. package/dist/os/rfc/dna-trace.js +7 -2
  153. package/dist/os/rfc/dna-trace.js.map +1 -1
  154. package/dist/os/rfc/frontmatter-io.js +5 -5
  155. package/dist/os/rfc/frontmatter-io.js.map +1 -1
  156. package/dist/os/rfc/handlers/archive.d.ts.map +1 -1
  157. package/dist/os/rfc/handlers/archive.js +11 -5
  158. package/dist/os/rfc/handlers/archive.js.map +1 -1
  159. package/dist/os/rfc/handlers/check.d.ts.map +1 -1
  160. package/dist/os/rfc/handlers/check.js +6 -3
  161. package/dist/os/rfc/handlers/check.js.map +1 -1
  162. package/dist/os/rfc/handlers/implement-stamp.d.ts.map +1 -1
  163. package/dist/os/rfc/handlers/implement-stamp.js +11 -10
  164. package/dist/os/rfc/handlers/implement-stamp.js.map +1 -1
  165. package/dist/os/rfc/handlers/index-graph.js +3 -3
  166. package/dist/os/rfc/handlers/index-graph.js.map +1 -1
  167. package/dist/os/rfc/handlers/lifecycle.d.ts.map +1 -1
  168. package/dist/os/rfc/handlers/lifecycle.js +6 -2
  169. package/dist/os/rfc/handlers/lifecycle.js.map +1 -1
  170. package/dist/os/rfc/handlers/list-create.d.ts.map +1 -1
  171. package/dist/os/rfc/handlers/list-create.js +7 -6
  172. package/dist/os/rfc/handlers/list-create.js.map +1 -1
  173. package/dist/os/rfc/handlers/shared.js +3 -3
  174. package/dist/os/rfc/handlers/shared.js.map +1 -1
  175. package/dist/os/rfc/handlers/supersede-propose.d.ts.map +1 -1
  176. package/dist/os/rfc/handlers/supersede-propose.js +7 -3
  177. package/dist/os/rfc/handlers/supersede-propose.js.map +1 -1
  178. package/dist/os/rfc/handlers/validate-rules.d.ts.map +1 -1
  179. package/dist/os/rfc/handlers/validate-rules.js +8 -5
  180. package/dist/os/rfc/handlers/validate-rules.js.map +1 -1
  181. package/dist/os/rfc/handlers/validate.d.ts.map +1 -1
  182. package/dist/os/rfc/handlers/validate.js +6 -1
  183. package/dist/os/rfc/handlers/validate.js.map +1 -1
  184. package/dist/os/rfc/rfc.module.d.ts.map +1 -1
  185. package/dist/os/rfc/rfc.module.js +44 -4
  186. package/dist/os/rfc/rfc.module.js.map +1 -1
  187. package/dist/os/rfc/verification-evidence.d.ts.map +1 -1
  188. package/dist/os/rfc/verification-evidence.js +9 -5
  189. package/dist/os/rfc/verification-evidence.js.map +1 -1
  190. package/dist/os/rfc/verification-refresh.d.ts.map +1 -1
  191. package/dist/os/rfc/verification-refresh.js +4 -3
  192. package/dist/os/rfc/verification-refresh.js.map +1 -1
  193. package/dist/os/session/frontmatter-io.js +12 -12
  194. package/dist/os/session/frontmatter-io.js.map +1 -1
  195. package/dist/os/session/handlers/archive.d.ts.map +1 -1
  196. package/dist/os/session/handlers/archive.js +10 -4
  197. package/dist/os/session/handlers/archive.js.map +1 -1
  198. package/dist/os/session/handlers/metrics-aggregate.d.ts.map +1 -1
  199. package/dist/os/session/handlers/metrics-aggregate.js +9 -5
  200. package/dist/os/session/handlers/metrics-aggregate.js.map +1 -1
  201. package/dist/os/session/handlers/metrics-rfc.d.ts.map +1 -1
  202. package/dist/os/session/handlers/metrics-rfc.js +11 -8
  203. package/dist/os/session/handlers/metrics-rfc.js.map +1 -1
  204. package/dist/os/session/handlers/metrics-session.d.ts.map +1 -1
  205. package/dist/os/session/handlers/metrics-session.js +6 -3
  206. package/dist/os/session/handlers/metrics-session.js.map +1 -1
  207. package/dist/os/session/handlers/save.d.ts.map +1 -1
  208. package/dist/os/session/handlers/save.js +14 -8
  209. package/dist/os/session/handlers/save.js.map +1 -1
  210. package/dist/os/session/session.module.d.ts.map +1 -1
  211. package/dist/os/session/session.module.js +6 -0
  212. package/dist/os/session/session.module.js.map +1 -1
  213. package/dist/os/spec/live-spec-list.js +4 -4
  214. package/dist/os/spec/live-spec-list.js.map +1 -1
  215. package/dist/os/spec/live-spec-merge.js +5 -5
  216. package/dist/os/spec/live-spec-merge.js.map +1 -1
  217. package/dist/os/spec/live-spec-show.js +3 -3
  218. package/dist/os/spec/live-spec-show.js.map +1 -1
  219. package/dist/os/spec/live-spec-validate.js +4 -4
  220. package/dist/os/spec/live-spec-validate.js.map +1 -1
  221. package/dist/os/spec/spec-materialize.js +9 -9
  222. package/dist/os/spec/spec-materialize.js.map +1 -1
  223. package/dist/os/spec/spec-status.js +9 -9
  224. package/dist/os/spec/spec-status.js.map +1 -1
  225. package/dist/os/spec/spec-validate.js +7 -7
  226. package/dist/os/spec/spec-validate.js.map +1 -1
  227. package/dist/os/spec/spec.module.d.ts.map +1 -1
  228. package/dist/os/spec/spec.module.js +8 -0
  229. package/dist/os/spec/spec.module.js.map +1 -1
  230. package/dist/os/werkstatt/handlers/lock.js +16 -16
  231. package/dist/os/werkstatt/handlers/lock.js.map +1 -1
  232. package/dist/os/werkstatt/handlers/werkstatt-lock-recover.js +3 -3
  233. package/dist/os/werkstatt/handlers/werkstatt-lock-recover.js.map +1 -1
  234. package/dist/os/werkstatt/handlers/werkstatt-operation-validate.d.ts.map +1 -1
  235. package/dist/os/werkstatt/handlers/werkstatt-operation-validate.js +3 -2
  236. package/dist/os/werkstatt/handlers/werkstatt-operation-validate.js.map +1 -1
  237. package/dist/os/werkstatt/handlers/workspace-deps.d.ts.map +1 -1
  238. package/dist/os/werkstatt/handlers/workspace-deps.js +0 -1
  239. package/dist/os/werkstatt/handlers/workspace-deps.js.map +1 -1
  240. package/dist/os/werkstatt/werkstatt.module.d.ts.map +1 -1
  241. package/dist/os/werkstatt/werkstatt.module.js +6 -2
  242. package/dist/os/werkstatt/werkstatt.module.js.map +1 -1
  243. package/dist/os/workflow/handlers.d.ts.map +1 -1
  244. package/dist/os/workflow/handlers.js +8 -5
  245. package/dist/os/workflow/handlers.js.map +1 -1
  246. package/dist/os/workflow/workflow.module.d.ts.map +1 -1
  247. package/dist/os/workflow/workflow.module.js +6 -3
  248. package/dist/os/workflow/workflow.module.js.map +1 -1
  249. package/dist/src/cli-flags.d.ts +28 -0
  250. package/dist/src/cli-flags.d.ts.map +1 -0
  251. package/dist/src/cli-flags.js +232 -0
  252. package/dist/src/cli-flags.js.map +1 -0
  253. package/dist/src/compass/contract-registry.js +1 -1
  254. package/dist/src/compass/contract-registry.js.map +1 -1
  255. package/dist/src/config/forge-config.d.ts +1 -1
  256. package/dist/src/config/forge-config.js +1 -1
  257. package/dist/src/config/forge-config.js.map +1 -1
  258. package/dist/src/knowledge/budgets.js +1 -1
  259. package/dist/src/knowledge/budgets.js.map +1 -1
  260. package/dist/src/knowledge/compact.js +1 -1
  261. package/dist/src/knowledge/compact.js.map +1 -1
  262. package/dist/src/knowledge/parse.js +1 -1
  263. package/dist/src/knowledge/parse.js.map +1 -1
  264. package/dist/src/knowledge/sync.d.ts.map +1 -1
  265. package/dist/src/knowledge/sync.js +3 -5
  266. package/dist/src/knowledge/sync.js.map +1 -1
  267. package/dist/src/migration-adapters/git-utils.js +2 -2
  268. package/dist/src/migration-adapters/git-utils.js.map +1 -1
  269. package/dist/src/migration-adapters/ignored-files.js +2 -2
  270. package/dist/src/migration-adapters/ignored-files.js.map +1 -1
  271. package/dist/src/migration-adapters/node-typescript-pnpm/index.js +1 -1
  272. package/dist/src/migration-adapters/node-typescript-pnpm/index.js.map +1 -1
  273. package/dist/src/migration-adapters/phaser-pnpm/index.js +1 -1
  274. package/dist/src/migration-adapters/phaser-pnpm/index.js.map +1 -1
  275. package/dist/src/onboarding/agents-generate.d.ts.map +1 -1
  276. package/dist/src/onboarding/agents-generate.js +76 -34
  277. package/dist/src/onboarding/agents-generate.js.map +1 -1
  278. package/dist/src/onboarding/create.d.ts.map +1 -1
  279. package/dist/src/onboarding/create.js +10 -10
  280. package/dist/src/onboarding/create.js.map +1 -1
  281. package/dist/src/onboarding/doctor.d.ts.map +1 -1
  282. package/dist/src/onboarding/doctor.js +68 -59
  283. package/dist/src/onboarding/doctor.js.map +1 -1
  284. package/dist/src/onboarding/init.d.ts.map +1 -1
  285. package/dist/src/onboarding/init.js +30 -1
  286. package/dist/src/onboarding/init.js.map +1 -1
  287. package/dist/src/onboarding/invariant-engine.js +1 -1
  288. package/dist/src/onboarding/invariant-engine.js.map +1 -1
  289. package/dist/src/onboarding/memory-compact.d.ts.map +1 -1
  290. package/dist/src/onboarding/memory-compact.js +5 -4
  291. package/dist/src/onboarding/memory-compact.js.map +1 -1
  292. package/dist/src/onboarding/memory-scaffold.js +1 -1
  293. package/dist/src/onboarding/memory-scaffold.js.map +1 -1
  294. package/dist/src/onboarding/nested-agents-generate.d.ts +4 -1
  295. package/dist/src/onboarding/nested-agents-generate.d.ts.map +1 -1
  296. package/dist/src/onboarding/nested-agents-generate.js +34 -5
  297. package/dist/src/onboarding/nested-agents-generate.js.map +1 -1
  298. package/dist/src/onboarding/nested-agents-templates.d.ts.map +1 -1
  299. package/dist/src/onboarding/nested-agents-templates.js +8 -12
  300. package/dist/src/onboarding/nested-agents-templates.js.map +1 -1
  301. package/dist/src/onboarding/npm-token-check.js +2 -2
  302. package/dist/src/onboarding/npm-token-check.js.map +1 -1
  303. package/dist/src/onboarding/prettierignore.d.ts +29 -0
  304. package/dist/src/onboarding/prettierignore.d.ts.map +1 -0
  305. package/dist/src/onboarding/prettierignore.js +231 -0
  306. package/dist/src/onboarding/prettierignore.js.map +1 -0
  307. package/dist/src/onboarding/profile-validate.d.ts.map +1 -1
  308. package/dist/src/onboarding/profile-validate.js +5 -4
  309. package/dist/src/onboarding/profile-validate.js.map +1 -1
  310. package/dist/src/onboarding/scaffold-project.d.ts.map +1 -1
  311. package/dist/src/onboarding/scaffold-project.js +35 -27
  312. package/dist/src/onboarding/scaffold-project.js.map +1 -1
  313. package/dist/src/onboarding/scaffold.js +1 -1
  314. package/dist/src/onboarding/scaffold.js.map +1 -1
  315. package/dist/src/onboarding/skill-markers.d.ts +27 -0
  316. package/dist/src/onboarding/skill-markers.d.ts.map +1 -0
  317. package/dist/src/onboarding/skill-markers.js +131 -0
  318. package/dist/src/onboarding/skill-markers.js.map +1 -0
  319. package/dist/src/onboarding/upgrade.d.ts +10 -0
  320. package/dist/src/onboarding/upgrade.d.ts.map +1 -1
  321. package/dist/src/onboarding/upgrade.js +215 -74
  322. package/dist/src/onboarding/upgrade.js.map +1 -1
  323. package/dist/src/onboarding/workspace-discovery.js +1 -1
  324. package/dist/src/onboarding/workspace-discovery.js.map +1 -1
  325. package/dist/src/pipeline-status.d.ts +6 -5
  326. package/dist/src/pipeline-status.d.ts.map +1 -1
  327. package/dist/src/pipeline-status.js +24 -19
  328. package/dist/src/pipeline-status.js.map +1 -1
  329. package/dist/src/profiles/stack-profile.js +1 -1
  330. package/dist/src/profiles/stack-profile.js.map +1 -1
  331. package/dist/src/registry.d.ts +1 -1
  332. package/dist/src/registry.d.ts.map +1 -1
  333. package/dist/src/registry.js +3 -3
  334. package/dist/src/registry.js.map +1 -1
  335. package/dist/src/skill-schema.d.ts +1 -1
  336. package/dist/src/skill-schema.d.ts.map +1 -1
  337. package/dist/src/skill-schema.js +4 -1
  338. package/dist/src/skill-schema.js.map +1 -1
  339. package/dist/src/types.d.ts +116 -0
  340. package/dist/src/types.d.ts.map +1 -1
  341. package/dist/src/utils/editable-region.d.ts +46 -0
  342. package/dist/src/utils/editable-region.d.ts.map +1 -0
  343. package/dist/src/utils/editable-region.js +125 -0
  344. package/dist/src/utils/editable-region.js.map +1 -0
  345. package/dist/src/utils/fs-idempotent.d.ts +2 -1
  346. package/dist/src/utils/fs-idempotent.d.ts.map +1 -1
  347. package/dist/src/utils/fs-idempotent.js +11 -7
  348. package/dist/src/utils/fs-idempotent.js.map +1 -1
  349. package/dist/src/utils/generated-marker.d.ts +17 -0
  350. package/dist/src/utils/generated-marker.d.ts.map +1 -1
  351. package/dist/src/utils/generated-marker.js +29 -1
  352. package/dist/src/utils/generated-marker.js.map +1 -1
  353. package/dist/src/utils/index.d.ts +3 -1
  354. package/dist/src/utils/index.d.ts.map +1 -1
  355. package/dist/src/utils/index.js +3 -1
  356. package/dist/src/utils/index.js.map +1 -1
  357. package/dist/src/utils/io.d.ts +9 -0
  358. package/dist/src/utils/io.d.ts.map +1 -0
  359. package/dist/src/utils/io.js +130 -0
  360. package/dist/src/utils/io.js.map +1 -0
  361. package/dist/src/utils/markdown-table.d.ts +21 -0
  362. package/dist/src/utils/markdown-table.d.ts.map +1 -0
  363. package/dist/src/utils/markdown-table.js +116 -0
  364. package/dist/src/utils/markdown-table.js.map +1 -0
  365. package/dist/src/utils/sync-fs.d.ts +5 -0
  366. package/dist/src/utils/sync-fs.d.ts.map +1 -0
  367. package/dist/src/utils/sync-fs.js +26 -0
  368. package/dist/src/utils/sync-fs.js.map +1 -0
  369. package/dist/src/validators/note-frontmatter-validate.js +1 -1
  370. package/dist/src/validators/note-frontmatter-validate.js.map +1 -1
  371. package/dist/src/validators/note-link-validate.js +1 -1
  372. package/dist/src/validators/note-link-validate.js.map +1 -1
  373. package/dist/src/validators/note-orphan-detect.js +1 -1
  374. package/dist/src/validators/note-orphan-detect.js.map +1 -1
  375. package/dist/src/validators/port-validate.js +1 -1
  376. package/dist/src/validators/port-validate.js.map +1 -1
  377. package/dist/src/validators/skill-validate.d.ts.map +1 -1
  378. package/dist/src/validators/skill-validate.js +34 -13
  379. package/dist/src/validators/skill-validate.js.map +1 -1
  380. package/os/adr/adr.module.ts +136 -132
  381. package/os/adr/frontmatter-io.ts +5 -5
  382. package/os/adr/handlers/archive.ts +8 -4
  383. package/os/adr/handlers/implement-stamp.ts +14 -10
  384. package/os/adr/handlers/list-create.ts +5 -5
  385. package/os/adr/handlers/validate.ts +1 -1
  386. package/os/audit/audit.module.ts +33 -34
  387. package/os/audit/frontmatter-io.ts +5 -5
  388. package/os/audit/handlers/archive.ts +8 -4
  389. package/os/compass/compass.module.ts +17 -1
  390. package/os/compass/handlers/compass-audit-handler.ts +13 -5
  391. package/os/compass/handlers/compass-change-summary-handler.ts +4 -2
  392. package/os/compass/handlers/compass-inventory-handler.ts +7 -4
  393. package/os/compass/handlers/compass-inventory.ts +11 -8
  394. package/os/compass/handlers/compass-migrate-handler.ts +1 -1
  395. package/os/compass/handlers/compass-migrate.ts +7 -3
  396. package/os/compass/handlers/git-revision.ts +11 -6
  397. package/os/compass/handlers/resolve-scan-root.ts +1 -1
  398. package/os/compass/handlers/summary-record.ts +10 -4
  399. package/os/compass/handlers/tests/compass-audit-plan.test.ts +2 -1
  400. package/os/core/core.module.ts +43 -4
  401. package/os/core/handlers/assets-helpers.ts +7 -3
  402. package/os/core/handlers/build.ts +1 -1
  403. package/os/core/handlers/determinism-check.ts +12 -6
  404. package/os/core/handlers/dev.ts +1 -1
  405. package/os/core/handlers/file-size-lint.ts +16 -9
  406. package/os/core/handlers/forge-autonomy-validate.ts +10 -5
  407. package/os/core/handlers/knowledge-compact.ts +1 -1
  408. package/os/core/handlers/package-health.ts +1 -1
  409. package/os/core/handlers/pinned-check.ts +2 -2
  410. package/os/core/handlers/pinned-init.ts +9 -8
  411. package/os/core/handlers/pinned-validate.ts +3 -3
  412. package/os/core/handlers/profile-resolve.ts +1 -1
  413. package/os/core/handlers/public-surface.ts +1 -1
  414. package/os/core/handlers/release-prepare.ts +11 -6
  415. package/os/core/handlers/release-publish.ts +6 -6
  416. package/os/core/handlers/validate.ts +1 -1
  417. package/os/exploration/exploration.module.ts +1 -0
  418. package/os/exploration/frontmatter-io.ts +4 -4
  419. package/os/exploration/handlers/archive.ts +3 -3
  420. package/os/mission/handlers/archive.test.ts +38 -1
  421. package/os/mission/handlers/archive.ts +54 -23
  422. package/os/mission/mission.module.ts +38 -39
  423. package/os/naming/naming-convention.ts +9 -3
  424. package/os/naming/naming.module.ts +25 -25
  425. package/os/notes/notes.module.ts +87 -85
  426. package/os/plan/frontmatter-io.ts +5 -5
  427. package/os/plan/handlers/archive.ts +8 -4
  428. package/os/plan/plan.module.ts +33 -34
  429. package/os/plugin/plugin.module.ts +8 -6
  430. package/os/program/discovery.ts +2 -2
  431. package/os/program/handlers/complete.ts +1 -1
  432. package/os/program/handlers/lease.ts +1 -1
  433. package/os/program/handlers/seal.ts +1 -1
  434. package/os/program/lease.ts +1 -1
  435. package/os/program/program.module.ts +198 -193
  436. package/os/queue/index.ts +1 -1
  437. package/os/queue/manifest.ts +10 -9
  438. package/os/queue/queue-validate.test.ts +6 -15
  439. package/os/rfc/acceptance.ts +12 -6
  440. package/os/rfc/decision-log.ts +4 -3
  441. package/os/rfc/dna-trace.ts +8 -2
  442. package/os/rfc/frontmatter-io.ts +5 -5
  443. package/os/rfc/handlers/archive.ts +9 -5
  444. package/os/rfc/handlers/check.ts +5 -3
  445. package/os/rfc/handlers/implement-stamp.ts +15 -10
  446. package/os/rfc/handlers/index-graph.ts +3 -3
  447. package/os/rfc/handlers/lifecycle.ts +7 -2
  448. package/os/rfc/handlers/list-create.ts +7 -6
  449. package/os/rfc/handlers/shared.ts +3 -3
  450. package/os/rfc/handlers/supersede-propose.ts +8 -3
  451. package/os/rfc/handlers/validate-rules-rfc1006.test.ts +18 -6
  452. package/os/rfc/handlers/validate-rules.ts +10 -5
  453. package/os/rfc/handlers/validate.test.ts +71 -0
  454. package/os/rfc/handlers/validate.ts +6 -1
  455. package/os/rfc/rfc-create-concurrent.test.ts +11 -3
  456. package/os/rfc/rfc.module.ts +413 -374
  457. package/os/rfc/verification-evidence.ts +11 -5
  458. package/os/rfc/verification-refresh.ts +4 -3
  459. package/os/session/frontmatter-io.ts +14 -14
  460. package/os/session/handlers/archive.ts +8 -4
  461. package/os/session/handlers/metrics-aggregate.ts +34 -13
  462. package/os/session/handlers/metrics-rfc.ts +13 -8
  463. package/os/session/handlers/metrics-session.ts +7 -3
  464. package/os/session/handlers/save.ts +12 -8
  465. package/os/session/session.module.ts +6 -0
  466. package/os/spec/live-spec-list.ts +4 -4
  467. package/os/spec/live-spec-merge.ts +5 -5
  468. package/os/spec/live-spec-show.ts +3 -3
  469. package/os/spec/live-spec-validate.ts +4 -4
  470. package/os/spec/spec-materialize.ts +9 -9
  471. package/os/spec/spec-status.ts +9 -9
  472. package/os/spec/spec-validate.ts +7 -7
  473. package/os/spec/spec.module.ts +8 -0
  474. package/os/werkstatt/handlers/lock.ts +16 -16
  475. package/os/werkstatt/handlers/werkstatt-lock-recover.ts +3 -3
  476. package/os/werkstatt/handlers/werkstatt-operation-validate.ts +4 -2
  477. package/os/werkstatt/handlers/workspace-deps.ts +0 -1
  478. package/os/werkstatt/werkstatt.module.ts +8 -5
  479. package/os/workflow/handlers.ts +7 -5
  480. package/os/workflow/workflow.module.ts +45 -44
  481. package/package.json +1 -1
  482. package/profiles/forge-shell.yaml +1 -1
  483. package/profiles/godot-game.yaml +1 -1
  484. package/profiles/knowledge.yaml +1 -1
  485. package/profiles/phaser-game.yaml +1 -1
  486. package/profiles/site-workshop.yaml +1 -1
  487. package/profiles/typescript.yaml +1 -1
  488. package/skills/fo/fo-add-tests/SKILL.md +2 -2
  489. package/skills/fo/fo-architecture/SKILL.md +2 -2
  490. package/skills/fo/fo-compass-annotate/SKILL.md +2 -2
  491. package/skills/fo/fo-design-summit/SKILL.md +2 -2
  492. package/skills/fo/fo-doc-audit/SKILL.md +2 -2
  493. package/skills/fo/fo-explore/SKILL.md +2 -2
  494. package/skills/fo/fo-extract-dna/SKILL.md +2 -2
  495. package/skills/fo/fo-fix/SKILL.md +2 -2
  496. package/skills/fo/fo-handoff/SKILL.md +2 -2
  497. package/skills/fo/fo-harvest/SKILL.md +2 -2
  498. package/skills/fo/fo-idea/SKILL.md +2 -2
  499. package/skills/fo/fo-idea-audit/SKILL.md +2 -2
  500. package/skills/fo/fo-idea-create-adr/SKILL.md +3 -3
  501. package/skills/fo/fo-idea-create-rfc/SKILL.md +3 -3
  502. package/skills/fo/fo-idea-enhance/SKILL.md +2 -2
  503. package/skills/fo/fo-idea-i-just-want-to-see-the-plan/SKILL.md +2 -2
  504. package/skills/fo/fo-idea-i-just-want-to-see-the-result/SKILL.md +1 -1
  505. package/skills/fo/fo-idea-implement/SKILL.md +2 -2
  506. package/skills/fo/fo-idea-plan/SKILL.md +2 -2
  507. package/skills/fo/fo-idea-status/SKILL.md +2 -2
  508. package/skills/fo/fo-knowledge-distill/SKILL.md +2 -2
  509. package/skills/fo/fo-memory-sync/SKILL.md +2 -2
  510. package/skills/fo/fo-qa/SKILL.md +2 -2
  511. package/skills/fo/fo-review/SKILL.md +2 -2
  512. package/skills/fo/fo-session-retro/SKILL.md +2 -2
  513. package/skills/fo/fo-session-save/SKILL.md +2 -2
  514. package/skills/fo/fo-spec-ingest/SKILL.md +2 -2
  515. package/skills/fo/fo-step-commit/SKILL.md +1 -1
  516. package/skills/fo/fo-triage/SKILL.md +2 -2
  517. package/skills/meta/forge-bootstrap/SKILL.md +1 -1
  518. package/skills/meta/port-to-forge/SKILL.md +1 -1
  519. package/skills/meta/skill-create/SKILL.md +1 -1
  520. package/skills/shared/grilling/SKILL.md +1 -1
  521. package/skills/shared/grilling/learned-principles.archive.md +17 -0
  522. package/skills/shared/grilling/learned-principles.md +0 -1
  523. package/skills/shared/knowledge/learned-principles.md +6 -0
  524. package/skills/shared/my-preferences/SKILL.md +1 -1
  525. package/skills/shared/windows-ai-tooling/SKILL.md +1 -1
  526. package/skills/shared/writing-great-skills/SKILL.md +1 -1
  527. package/src/cli-flags.ts +285 -0
  528. package/src/compass/contract-registry.ts +1 -1
  529. package/src/config/forge-config.ts +1 -1
  530. package/src/knowledge/__tests__/sync.test.ts +2 -7
  531. package/src/knowledge/budgets.ts +1 -1
  532. package/src/knowledge/compact.ts +1 -1
  533. package/src/knowledge/parse.ts +1 -1
  534. package/src/knowledge/sync.ts +3 -5
  535. package/src/migration-adapters/git-utils.ts +2 -2
  536. package/src/migration-adapters/ignored-files.ts +2 -2
  537. package/src/migration-adapters/node-typescript-pnpm/index.ts +1 -1
  538. package/src/migration-adapters/phaser-pnpm/index.ts +1 -1
  539. package/src/onboarding/agents-generate.ts +92 -36
  540. package/src/onboarding/create.ts +10 -10
  541. package/src/onboarding/doctor.ts +70 -55
  542. package/src/onboarding/init.ts +38 -1
  543. package/src/onboarding/invariant-engine.ts +1 -1
  544. package/src/onboarding/memory-compact.ts +5 -4
  545. package/src/onboarding/memory-scaffold.ts +1 -1
  546. package/src/onboarding/nested-agents-generate.ts +45 -4
  547. package/src/onboarding/nested-agents-templates.ts +19 -13
  548. package/src/onboarding/npm-token-check.ts +2 -2
  549. package/src/onboarding/prettierignore.ts +263 -0
  550. package/src/onboarding/profile-validate.ts +5 -4
  551. package/src/onboarding/scaffold-project.ts +38 -27
  552. package/src/onboarding/scaffold.ts +1 -1
  553. package/src/onboarding/skill-markers.ts +162 -0
  554. package/src/onboarding/templates/behavioral-layer-core.md +2 -4
  555. package/src/onboarding/upgrade.ts +285 -89
  556. package/src/onboarding/workspace-discovery.ts +1 -1
  557. package/src/pipeline-status.test.ts +1 -4
  558. package/src/pipeline-status.ts +30 -13
  559. package/src/profiles/stack-profile.ts +1 -1
  560. package/src/registry.ts +4 -4
  561. package/src/skill-schema.ts +4 -1
  562. package/src/tests/acceptance-probe-kinds.test.ts +5 -15
  563. package/src/tests/agents-generate.test.ts +28 -5
  564. package/src/tests/cli-flags.test.ts +169 -0
  565. package/src/tests/contract-registry.test.ts +12 -6
  566. package/src/tests/doctor-fix.test.ts +1 -4
  567. package/src/tests/doctor-nested-agents.test.ts +53 -1
  568. package/src/tests/editable-generated-region.test.ts +231 -0
  569. package/src/tests/file-size-lint.test.ts +8 -12
  570. package/src/tests/fixtures/agents-generate-business-before.txt +85 -56
  571. package/src/tests/markdown-table.test.ts +107 -0
  572. package/src/tests/prettierignore-manage.test.ts +134 -0
  573. package/src/tests/skill-agents-sync.test.ts +168 -0
  574. package/src/tests/skill-sync-marker.test.ts +134 -0
  575. package/src/tests/skill-validate.test.ts +12 -5
  576. package/src/tests/upgrade.test.ts +87 -41
  577. package/src/types.ts +123 -0
  578. package/src/utils/editable-region.ts +156 -0
  579. package/src/utils/fs-idempotent.ts +12 -6
  580. package/src/utils/generated-marker.ts +36 -2
  581. package/src/utils/index.ts +17 -0
  582. package/src/utils/io.ts +143 -0
  583. package/src/utils/markdown-table.ts +121 -0
  584. package/src/utils/sync-fs.ts +43 -0
  585. package/src/validators/note-frontmatter-validate.ts +1 -1
  586. package/src/validators/note-link-validate.ts +1 -1
  587. package/src/validators/note-orphan-detect.ts +1 -1
  588. package/src/validators/port-validate.ts +1 -1
  589. package/src/validators/skill-validate.ts +38 -13
  590. package/AGENTS.md +0 -502
@@ -17,8 +17,9 @@ a JSON evidence envelope to docs/rfcs/verification/<slug>.generated.yaml.
17
17
  </CHANGE_SUMMARY>
18
18
  */
19
19
 
20
- import { execFile } from "node:child_process";
21
- import { readFile, mkdir } from "node:fs/promises";
20
+ import { execFile } from "../../src/utils/sync-fs.ts";
21
+ import { ambientIo, resolveIo } from "../../src/utils/io.ts";
22
+
22
23
  import { join } from "node:path";
23
24
  import { performance } from "node:perf_hooks";
24
25
  import { byteHash } from "../../src/utils/hash.ts";
@@ -29,6 +30,10 @@ import { writeFileAtomic } from "../../src/utils/fs-atomic.ts";
29
30
  import { buildGeneratedHeader } from "../../src/utils/generated-marker.ts";
30
31
  import { stringify as yamlStringify } from "yaml";
31
32
  import { RFC_DIR } from "./types.ts";
33
+
34
+ // Ambient default for helper fns without a context param — handlers override
35
+ // with `const io = resolveIo(context.io)` inside their own scope.
36
+ const io = ambientIo;
32
37
  import type {
33
38
  AcceptanceProbe,
34
39
  RfcStatus,
@@ -74,7 +79,7 @@ export async function captureGitContext(
74
79
  export async function getKernelVersion(workspaceRoot: string): Promise<string> {
75
80
  try {
76
81
  const pkgPath = join(workspaceRoot, "packages", "os", "site-kernel", "package.json");
77
- const pkg = JSON.parse(await readFile(pkgPath, "utf-8"));
82
+ const pkg = JSON.parse(await io.readFile(pkgPath));
78
83
  return String(pkg.version ?? "unknown");
79
84
  } catch {
80
85
  return "unknown";
@@ -120,6 +125,7 @@ export async function runRfcVerificationEmit(
120
125
  input: ForgeCommandInput,
121
126
  context: ForgeRuntimeContext,
122
127
  ): Promise<ForgeCommandResult<RfcVerificationEmitResult>> {
128
+ const io = resolveIo(context.io);
123
129
  const { workspaceRoot, logger, outputFormat } = context;
124
130
  const rfcDirPath = join(workspaceRoot, RFC_DIR);
125
131
  const targetId = input.flags["id"] as string | undefined;
@@ -155,7 +161,7 @@ export async function runRfcVerificationEmit(
155
161
  }
156
162
  const kernelVersion = await getKernelVersion(workspaceRoot);
157
163
  const verificationDirAbs = join(workspaceRoot, VERIFICATION_DIR);
158
- await mkdir(verificationDirAbs, { recursive: true });
164
+ await io.mkdir(verificationDirAbs);
159
165
 
160
166
  for (const fileName of allFiles) {
161
167
  const parsedFile = await readAndParseRfc(rfcDirPath, fileName);
@@ -176,7 +182,7 @@ export async function runRfcVerificationEmit(
176
182
  const probes = acceptance as AcceptanceProbe[];
177
183
  const probeRecords: VerificationEvidenceProbeRecord[] = [];
178
184
  const rfcFilePath = join(rfcDirPath, fileName);
179
- const rfcMarkdown = await readFile(rfcFilePath, "utf-8");
185
+ const rfcMarkdown = await io.readFile(rfcFilePath);
180
186
  const emittedAt = new Date().toISOString();
181
187
 
182
188
  for (const probe of probes) {
@@ -17,8 +17,8 @@ lastRefreshedAt, replaces probes[] with fresh results. Supports --id,
17
17
  </CHANGE_SUMMARY>
18
18
  */
19
19
 
20
- import { readFile } from "node:fs/promises";
21
20
  import { join } from "node:path";
21
+ import { resolveIo } from "../../src/utils/io.ts";
22
22
  import { performance } from "node:perf_hooks";
23
23
  import { parse as yamlParse } from "yaml";
24
24
 
@@ -52,6 +52,7 @@ export async function runRfcVerificationRefresh(
52
52
  input: ForgeCommandInput,
53
53
  context: ForgeRuntimeContext,
54
54
  ): Promise<ForgeCommandResult<RfcVerificationRefreshResult>> {
55
+ const io = resolveIo(context.io);
55
56
  const { workspaceRoot, logger, outputFormat } = context;
56
57
  const rfcDirPath = join(workspaceRoot, RFC_DIR);
57
58
  const targetId = input.flags["id"] as string | undefined;
@@ -103,7 +104,7 @@ export async function runRfcVerificationRefresh(
103
104
 
104
105
  let existingEnvelope: VerificationEvidence | null = null;
105
106
  try {
106
- const raw = await readFile(evidenceAbsPath, "utf-8");
107
+ const raw = await io.readFile(evidenceAbsPath);
107
108
  const parsed = yamlParse(raw) as VerificationEvidence;
108
109
  if (parsed && typeof parsed === "object" && parsed.rfcId) {
109
110
  existingEnvelope = parsed;
@@ -126,7 +127,7 @@ export async function runRfcVerificationRefresh(
126
127
  const probes = acceptance as AcceptanceProbe[];
127
128
  const probeRecords: VerificationEvidenceProbeRecord[] = [];
128
129
  const rfcFilePath = join(rfcDirPath, fileName);
129
- const rfcMarkdown = await readFile(rfcFilePath, "utf-8");
130
+ const rfcMarkdown = await io.readFile(rfcFilePath);
130
131
  const now = new Date().toISOString();
131
132
 
132
133
  for (const probe of probes) {
@@ -14,7 +14,7 @@ subdirectories from the main file list.
14
14
  </CHANGE_SUMMARY>
15
15
  */
16
16
 
17
- import fs from "node:fs/promises";
17
+ import { ambientIo as fs } from "../../src/utils/io.ts";
18
18
  import path from "node:path";
19
19
  import YAML from "yaml";
20
20
  import { SESSION_FILE_PATTERN, SESSION_RAW_SUBDIR, SESSION_ARCHIVE_SUBDIR } from "./types.ts";
@@ -43,9 +43,9 @@ export async function listSessionFiles(sessionDirPath: string): Promise<string[]
43
43
  const results: string[] = [];
44
44
 
45
45
  async function scanDir(dirPath: string, relativePrefix: string): Promise<void> {
46
- let entries: import("node:fs").Dirent[];
46
+ let entries: Awaited<ReturnType<typeof fs.readdir>>;
47
47
  try {
48
- entries = await fs.readdir(dirPath, { withFileTypes: true });
48
+ entries = await fs.readdir(dirPath);
49
49
  } catch {
50
50
  return;
51
51
  }
@@ -54,10 +54,10 @@ export async function listSessionFiles(sessionDirPath: string): Promise<string[]
54
54
  continue;
55
55
  }
56
56
  const relativePath = relativePrefix ? `${relativePrefix}/${entry.name}` : entry.name;
57
- if (entry.isDirectory()) {
57
+ if (entry.isDirectory) {
58
58
  await scanDir(path.join(dirPath, entry.name), relativePath);
59
59
  } else if (
60
- entry.isFile() &&
60
+ entry.isFile &&
61
61
  entry.name.endsWith(".md") &&
62
62
  entry.name !== "README.md" &&
63
63
  SESSION_FILE_PATTERN.test(entry.name)
@@ -80,18 +80,18 @@ export async function listArchivedSessionFiles(sessionDirPath: string): Promise<
80
80
  const results: string[] = [];
81
81
 
82
82
  async function scanDir(dirPath: string, relativePrefix: string): Promise<void> {
83
- let entries: import("node:fs").Dirent[];
83
+ let entries: Awaited<ReturnType<typeof fs.readdir>>;
84
84
  try {
85
- entries = await fs.readdir(dirPath, { withFileTypes: true });
85
+ entries = await fs.readdir(dirPath);
86
86
  } catch {
87
87
  return;
88
88
  }
89
89
  for (const entry of entries) {
90
90
  const relativePath = relativePrefix ? `${relativePrefix}/${entry.name}` : entry.name;
91
- if (entry.isDirectory()) {
91
+ if (entry.isDirectory) {
92
92
  await scanDir(path.join(dirPath, entry.name), relativePath);
93
93
  } else if (
94
- entry.isFile() &&
94
+ entry.isFile &&
95
95
  entry.name.endsWith(".md") &&
96
96
  SESSION_FILE_PATTERN.test(entry.name)
97
97
  ) {
@@ -110,7 +110,7 @@ export async function readAndParseSession(
110
110
  ): Promise<{ fileName: string; parsed: ParsedSession } | undefined> {
111
111
  try {
112
112
  const filePath = path.join(sessionDirPath, fileName);
113
- const content = await fs.readFile(filePath, "utf-8");
113
+ const content = await fs.readFile(filePath);
114
114
  return { fileName, parsed: parseSessionFile(content) };
115
115
  } catch {
116
116
  return undefined;
@@ -125,10 +125,10 @@ export async function readAndParseSession(
125
125
  export async function listNonMarkdownSessionFiles(sessionDirPath: string): Promise<string[]> {
126
126
  const results: string[] = [];
127
127
  try {
128
- const entries = await fs.readdir(sessionDirPath, { withFileTypes: true });
128
+ const entries = await fs.readdir(sessionDirPath);
129
129
  for (const entry of entries) {
130
130
  if (
131
- entry.isFile() &&
131
+ entry.isFile &&
132
132
  !entry.name.endsWith(".md") &&
133
133
  entry.name !== ".gitkeep" &&
134
134
  entry.name !== "README.md"
@@ -150,9 +150,9 @@ export async function listRawFiles(sessionDirPath: string): Promise<string[]> {
150
150
  const rawDirPath = path.join(sessionDirPath, SESSION_RAW_SUBDIR);
151
151
  const results: string[] = [];
152
152
  try {
153
- const entries = await fs.readdir(rawDirPath, { withFileTypes: true });
153
+ const entries = await fs.readdir(rawDirPath);
154
154
  for (const entry of entries) {
155
- if (entry.isFile()) {
155
+ if (entry.isFile) {
156
156
  results.push(entry.name);
157
157
  }
158
158
  }
@@ -16,7 +16,7 @@ younger than threshold are moved back to docs/sessions/.
16
16
  </CHANGE_SUMMARY>
17
17
  */
18
18
 
19
- import fs from "node:fs/promises";
19
+ import { ambientIo as fs } from "../../../src/utils/io.ts";
20
20
  import path from "node:path";
21
21
  import {
22
22
  listSessionFiles,
@@ -131,7 +131,9 @@ export async function runSessionArchive(
131
131
  }
132
132
 
133
133
  try {
134
- await fs.access(targetPath);
134
+ await fs.exists(targetPath).then((ok) => {
135
+ if (!ok) throw Object.assign(new Error("ENOENT"), { code: "ENOENT" });
136
+ });
135
137
  skipped.push({ id, file: relFile, reason: "destination exists" });
136
138
  continue;
137
139
  } catch {
@@ -139,7 +141,7 @@ export async function runSessionArchive(
139
141
  }
140
142
 
141
143
  if (!dryRun) {
142
- await fs.mkdir(archiveDirPath, { recursive: true });
144
+ await fs.mkdir(archiveDirPath);
143
145
  try {
144
146
  await fs.rename(path.join(sessionDirPath, fileName), targetPath);
145
147
  } catch (err) {
@@ -217,7 +219,9 @@ export async function runSessionArchive(
217
219
  }
218
220
 
219
221
  try {
220
- await fs.access(targetPath);
222
+ await fs.exists(targetPath).then((ok) => {
223
+ if (!ok) throw Object.assign(new Error("ENOENT"), { code: "ENOENT" });
224
+ });
221
225
  skipped.push({ id, file: archRelFile, reason: "destination exists" });
222
226
  continue;
223
227
  } catch {
@@ -16,16 +16,30 @@ result when no metrics files exist.
16
16
  </CHANGE_SUMMARY>
17
17
  */
18
18
 
19
- import { readdir, readFile } from "node:fs/promises";
20
19
  import { join } from "node:path";
20
+ import { ambientIo, resolveIo } from "../../../src/utils/io.ts";
21
21
  import { parse as yamlParse } from "yaml";
22
22
 
23
- import { METRICS_DIR, type MetricsAggregateResult, type SkillAggregate, type RfcMetrics, type SessionMetrics } from "../types.ts";
24
- import type { ForgeCommandInput, ForgeCommandResult, ForgeRuntimeContext } from "../../../src/types.ts";
23
+ import {
24
+ METRICS_DIR,
25
+ type MetricsAggregateResult,
26
+ type SkillAggregate,
27
+ type RfcMetrics,
28
+ type SessionMetrics,
29
+ } from "../types.ts";
30
+ import type {
31
+ ForgeCommandInput,
32
+ ForgeCommandResult,
33
+ ForgeRuntimeContext,
34
+ } from "../../../src/types.ts";
35
+
36
+ // Ambient default for helper fns without a context param — handlers override
37
+ // with `const io = resolveIo(context.io)` inside their own scope.
38
+ const io = ambientIo;
25
39
 
26
40
  async function readYamlFile<T>(filePath: string): Promise<T | null> {
27
41
  try {
28
- const content = await readFile(filePath, "utf-8");
42
+ const content = await io.readFile(filePath);
29
43
  return yamlParse(content) as T;
30
44
  } catch {
31
45
  return null;
@@ -36,6 +50,7 @@ export async function runMetricsAggregate(
36
50
  input: ForgeCommandInput,
37
51
  context: ForgeRuntimeContext,
38
52
  ): Promise<ForgeCommandResult<MetricsAggregateResult>> {
53
+ const io = resolveIo(context.io);
39
54
  const { workspaceRoot, outputFormat } = context;
40
55
  const skillFilter = input.flags["skill"] as string | undefined;
41
56
  const since = input.flags["since"] as string | undefined;
@@ -48,13 +63,13 @@ export async function runMetricsAggregate(
48
63
  let sessionFiles: string[] = [];
49
64
 
50
65
  try {
51
- rfcFiles = await readdir(rfcMetricsDir);
66
+ rfcFiles = (await io.readdir(rfcMetricsDir)).map((e) => e.name);
52
67
  } catch {
53
68
  // No RFC metrics directory yet
54
69
  }
55
70
 
56
71
  try {
57
- sessionFiles = await readdir(sessionMetricsDir);
72
+ sessionFiles = (await io.readdir(sessionMetricsDir)).map((e) => e.name);
58
73
  } catch {
59
74
  // No session metrics directory yet
60
75
  }
@@ -109,11 +124,14 @@ export async function runMetricsAggregate(
109
124
  }
110
125
  >();
111
126
 
112
- function recordSkill(skill: string, data: Partial<{
113
- findings: number;
114
- fixIterations: number;
115
- durationMs: number;
116
- }>) {
127
+ function recordSkill(
128
+ skill: string,
129
+ data: Partial<{
130
+ findings: number;
131
+ fixIterations: number;
132
+ durationMs: number;
133
+ }>,
134
+ ) {
117
135
  let entry = skillData.get(skill);
118
136
  if (!entry) {
119
137
  entry = {
@@ -173,7 +191,8 @@ export async function runMetricsAggregate(
173
191
  skill,
174
192
  invocations: data.invocations,
175
193
  avgFindings: data.findingsCount > 0 ? data.findingsSum / data.findingsCount : null,
176
- avgFixIterations: data.fixIterationsCount > 0 ? data.fixIterationsSum / data.fixIterationsCount : null,
194
+ avgFixIterations:
195
+ data.fixIterationsCount > 0 ? data.fixIterationsSum / data.fixIterationsCount : null,
177
196
  avgDurationMs: data.durationCount > 0 ? data.durationSum / data.durationCount : null,
178
197
  });
179
198
  }
@@ -197,7 +216,9 @@ export async function runMetricsAggregate(
197
216
  };
198
217
 
199
218
  if (outputFormat === "pretty") {
200
- context.logger.info(`[metrics.aggregate] ${perSkill.length} skill(s), ${filteredRfcs.length} RFC(s), ${filteredSessions.length} session(s)`);
219
+ context.logger.info(
220
+ `[metrics.aggregate] ${perSkill.length} skill(s), ${filteredRfcs.length} RFC(s), ${filteredSessions.length} session(s)`,
221
+ );
201
222
  }
202
223
 
203
224
  return {
@@ -17,13 +17,18 @@ Writes to docs/metrics/rfcs/<rfc-id>.metrics.yaml via writeFileAtomic.
17
17
  </CHANGE_SUMMARY>
18
18
  */
19
19
 
20
- import { execFile } from "node:child_process";
21
- import { readFile, readdir, mkdir } from "node:fs/promises";
20
+ import { execFile } from "../../../src/utils/sync-fs.ts";
21
+ import { ambientIo } from "../../../src/utils/io.ts";
22
+
22
23
  import { join, dirname } from "node:path";
23
24
 
24
25
  import { writeFileAtomic } from "../../../src/utils/fs-atomic.ts";
25
26
  import { parse as yamlParse, stringify as yamlStringify } from "yaml";
26
27
 
28
+ // Ambient default for helper fns without a context param — handlers override
29
+ // with `const io = resolveIo(context.io)` inside their own scope.
30
+ const io = ambientIo;
31
+
27
32
  import {
28
33
  METRICS_DIR,
29
34
  type RfcMetrics,
@@ -111,7 +116,7 @@ async function findReviewReport(workspaceRoot: string, rfcId: string): Promise<s
111
116
  const reviewDir = join(workspaceRoot, "docs", "reviews", "code");
112
117
  let files: string[];
113
118
  try {
114
- files = await readdir(reviewDir, { recursive: true });
119
+ files = await io.glob("**/*", { cwd: reviewDir });
115
120
  } catch {
116
121
  return null;
117
122
  }
@@ -121,7 +126,7 @@ async function findReviewReport(workspaceRoot: string, rfcId: string): Promise<s
121
126
  if (!file.endsWith(".md")) continue;
122
127
  if (file.toLowerCase().includes(rfcLower)) {
123
128
  try {
124
- const content = await readFile(join(reviewDir, file), "utf-8");
129
+ const content = await io.readFile(join(reviewDir, file));
125
130
  return content;
126
131
  } catch {
127
132
  continue;
@@ -177,7 +182,7 @@ async function parseVerificationEvidence(
177
182
  );
178
183
  let content: string;
179
184
  try {
180
- content = await readFile(evidencePath, "utf-8");
185
+ content = await io.readFile(evidencePath);
181
186
  } catch {
182
187
  return null;
183
188
  }
@@ -208,7 +213,7 @@ async function parseAcceptanceCriteria(
208
213
  const rfcDir = join(workspaceRoot, "docs", "rfcs");
209
214
  let files: string[];
210
215
  try {
211
- files = await readdir(rfcDir);
216
+ files = (await io.readdir(rfcDir)).map((e) => e.name);
212
217
  } catch {
213
218
  return { acceptanceCriteriaTotal: 0, acceptanceCriteriaMet: 0 };
214
219
  }
@@ -223,7 +228,7 @@ async function parseAcceptanceCriteria(
223
228
 
224
229
  let content: string;
225
230
  try {
226
- content = await readFile(join(rfcDir, rfcFile), "utf-8");
231
+ content = await io.readFile(join(rfcDir, rfcFile));
227
232
  } catch {
228
233
  return { acceptanceCriteriaTotal: 0, acceptanceCriteriaMet: 0 };
229
234
  }
@@ -332,7 +337,7 @@ export async function generateRfcMetrics(
332
337
  "rfcs",
333
338
  `${rfcId.toLowerCase()}.metrics.yaml`,
334
339
  );
335
- await mkdir(dirname(metricsFilePath), { recursive: true });
340
+ await io.mkdir(dirname(metricsFilePath));
336
341
  await writeFileAtomic(metricsFilePath, yamlContent);
337
342
 
338
343
  return `${METRICS_DIR}/rfcs/${rfcId.toLowerCase()}.metrics.yaml`;
@@ -17,8 +17,8 @@ docs/metrics/sessions/<session-id>.metrics.yaml via writeFileAtomic.
17
17
  </CHANGE_SUMMARY>
18
18
  */
19
19
 
20
- import { readdir, mkdir } from "node:fs/promises";
21
20
  import { join, dirname } from "node:path";
21
+ import { ambientIo } from "../../../src/utils/io.ts";
22
22
 
23
23
  import { writeFileAtomic } from "../../../src/utils/fs-atomic.ts";
24
24
  import { stringify as yamlStringify } from "yaml";
@@ -32,6 +32,10 @@ import {
32
32
  } from "../types.ts";
33
33
  import type { AtifMessage } from "../atif-parser.ts";
34
34
 
35
+ // Ambient default for helper fns without a context param — handlers override
36
+ // with `const io = resolveIo(context.io)` inside their own scope.
37
+ const io = ambientIo;
38
+
35
39
  // ─── Skill name extraction ───────────────────────────────────────────────────
36
40
 
37
41
  const SKILL_PATTERN = /\b(fo-[a-z]+(?:-[a-z]+)*)\b/g;
@@ -116,7 +120,7 @@ async function extractDocumentRefs(
116
120
 
117
121
  let existingMetricsFiles: string[] = [];
118
122
  try {
119
- existingMetricsFiles = await readdir(metricsRfcDir);
123
+ existingMetricsFiles = (await io.readdir(metricsRfcDir)).map((e) => e.name);
120
124
  } catch {
121
125
  // No metrics directory yet
122
126
  }
@@ -203,7 +207,7 @@ export async function generateSessionMetrics(
203
207
 
204
208
  const yamlContent = yamlStringify(metrics, { lineWidth: 120 });
205
209
  const metricsFilePath = join(workspaceRoot, METRICS_DIR, "sessions", `${sessionId}.metrics.yaml`);
206
- await mkdir(dirname(metricsFilePath), { recursive: true });
210
+ await io.mkdir(dirname(metricsFilePath));
207
211
  await writeFileAtomic(metricsFilePath, yamlContent);
208
212
 
209
213
  return `${METRICS_DIR}/sessions/${sessionId}.metrics.yaml`;
@@ -22,7 +22,7 @@ Sweep batch 4: 73 Compass headers on headerless engine files (certification, com
22
22
  </CHANGE_SUMMARY>
23
23
  */
24
24
 
25
- import fs from "node:fs/promises";
25
+ import { ambientIo as fs } from "../../../src/utils/io.ts";
26
26
  import path from "node:path";
27
27
  import { createHash } from "node:crypto";
28
28
  import YAML from "yaml";
@@ -182,7 +182,9 @@ export async function runSessionSave(
182
182
  ? rawFileFlag
183
183
  : path.join(workspaceRoot, rawFileFlag);
184
184
  try {
185
- await fs.access(resolvedPath);
185
+ await fs.exists(resolvedPath).then((ok) => {
186
+ if (!ok) throw Object.assign(new Error("ENOENT"), { code: "ENOENT" });
187
+ });
186
188
  } catch {
187
189
  throw new Error(`Raw file not found: ${rawFileFlag}`);
188
190
  }
@@ -193,8 +195,8 @@ export async function runSessionSave(
193
195
  ];
194
196
  } else {
195
197
  try {
196
- const entries = await fs.readdir(rawDirPath, { withFileTypes: true });
197
- rawFiles = entries.filter((e) => e.isFile()).map((e) => e.name);
198
+ const entries = await fs.readdir(rawDirPath);
199
+ rawFiles = entries.filter((e) => e.isFile).map((e) => e.name);
198
200
  } catch {
199
201
  rawFiles = [];
200
202
  }
@@ -234,7 +236,7 @@ export async function runSessionSave(
234
236
  const rawFilePath = path.join(rawDirPath, rawFileName);
235
237
  let rawContent: string;
236
238
  try {
237
- rawContent = await fs.readFile(rawFilePath, "utf-8");
239
+ rawContent = await fs.readFile(rawFilePath);
238
240
  } catch (err) {
239
241
  if ((err as NodeJS.ErrnoException).code === "ENOENT") {
240
242
  skipped.push({ rawFile: rawFileName, reason: "already processed by another process" });
@@ -267,7 +269,9 @@ export async function runSessionSave(
267
269
  const outputRel = path.join(SESSION_DIR, outputFileName);
268
270
 
269
271
  try {
270
- await fs.access(outputPath);
272
+ await fs.exists(outputPath).then((ok) => {
273
+ if (!ok) throw Object.assign(new Error("ENOENT"), { code: "ENOENT" });
274
+ });
271
275
  skipped.push({ rawFile: rawFileName, reason: "already converted" });
272
276
  if (outputFormat === "pretty") {
273
277
  logger.info(`Skipped ${rawFileName}: already converted to ${outputRel}`);
@@ -298,8 +302,8 @@ export async function runSessionSave(
298
302
 
299
303
  let metricsPath: string | undefined;
300
304
  if (!dryRun) {
301
- await fs.mkdir(sessionDirPath, { recursive: true });
302
- await fs.writeFile(outputPath, markdown, "utf-8");
305
+ await fs.mkdir(sessionDirPath);
306
+ await fs.writeFile(outputPath, markdown);
303
307
 
304
308
  // ── RFC-1053: Generate session metrics from ATIF messages (non-fatal) ──
305
309
  try {
@@ -8,6 +8,7 @@
8
8
  <CHANGE_SUMMARY>
9
9
  <item>RFC-0537: initial forgeSessionModule registering session.save, session.archive, session.validate, session.list commands.</item>
10
10
  <item>RFC-1053: register metrics.aggregate command for skill effectiveness metrics aggregation.</item>
11
+ <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>
11
12
  </CHANGE_SUMMARY>
12
13
  */
13
14
 
@@ -35,6 +36,7 @@ export async function createForgeSessionModule(): Promise<ForgeModule> {
35
36
  scope: "workspace",
36
37
  mutatesState: true,
37
38
  writes: ["docs/sessions/*.md"],
39
+ generates: [],
38
40
  reads: ["docs/sessions/.raw/*"],
39
41
  cacheable: false,
40
42
  flags: {
@@ -65,6 +67,7 @@ export async function createForgeSessionModule(): Promise<ForgeModule> {
65
67
  scope: "workspace",
66
68
  mutatesState: true,
67
69
  writes: ["docs/sessions/*.md", "docs/sessions/archive/**"],
70
+ generates: [],
68
71
  reads: ["docs/sessions/**/*.md"],
69
72
  cacheable: false,
70
73
  flags: {
@@ -81,6 +84,7 @@ export async function createForgeSessionModule(): Promise<ForgeModule> {
81
84
  },
82
85
  {
83
86
  name: "session.validate",
87
+ mutatesState: false,
84
88
  contract: "session",
85
89
  rules: [],
86
90
  description:
@@ -98,6 +102,7 @@ export async function createForgeSessionModule(): Promise<ForgeModule> {
98
102
  },
99
103
  {
100
104
  name: "session.list",
105
+ mutatesState: false,
101
106
  description:
102
107
  "List all sessions. Filter with --date-from, --date-to, --rfc, --type flags. " +
103
108
  "Use --json for machine-readable output. Parses frontmatter on the fly. " +
@@ -127,6 +132,7 @@ export async function createForgeSessionModule(): Promise<ForgeModule> {
127
132
  },
128
133
  {
129
134
  name: "metrics.aggregate",
135
+ mutatesState: true,
130
136
  description:
131
137
  "Query and aggregate skill effectiveness metrics from docs/metrics/ files. " +
132
138
  "Returns per-skill statistics (invocations, avgFindings, avgFixIterations, avgDurationMs). " +
@@ -10,8 +10,8 @@
10
10
  </CHANGE_SUMMARY>
11
11
  */
12
12
 
13
- import fs from "node:fs/promises";
14
- import { existsSync } from "node:fs";
13
+ import { ambientIo as fs } from "../../src/utils/io.ts";
14
+ import { existsSync } from "../../src/utils/sync-fs.ts";
15
15
  import path from "node:path";
16
16
  import YAML from "yaml";
17
17
  import type {
@@ -33,11 +33,11 @@ export async function runSpecLiveList(
33
33
  const entries: SpecLiveListEntry[] = [];
34
34
 
35
35
  if (existsSync(liveSpecsDir)) {
36
- const files = await fs.readdir(liveSpecsDir);
36
+ const files = (await fs.readdir(liveSpecsDir)).map((e) => e.name);
37
37
  for (const file of files) {
38
38
  if (!file.endsWith(".md") || file === "README.md") continue;
39
39
  const filePath = path.join(liveSpecsDir, file);
40
- const content = await fs.readFile(filePath, "utf-8");
40
+ const content = await fs.readFile(filePath);
41
41
  const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
42
42
  if (!match) continue;
43
43
  const fm = (YAML.parse(match[1]!) ?? {}) as Record<string, unknown>;
@@ -14,8 +14,8 @@ headings, and writes atomically (RFC-0711).</purpose>
14
14
  </CHANGE_SUMMARY>
15
15
  */
16
16
 
17
- import fs from "node:fs/promises";
18
- import { existsSync } from "node:fs";
17
+ import { ambientIo as fs } from "../../src/utils/io.ts";
18
+ import { existsSync } from "../../src/utils/sync-fs.ts";
19
19
  import path from "node:path";
20
20
  import YAML from "yaml";
21
21
  import type {
@@ -223,7 +223,7 @@ export async function runSpecLiveMerge(
223
223
  };
224
224
  }
225
225
 
226
- const rfcContent = await fs.readFile(path.join(rfcDir, rfcFile), "utf-8");
226
+ const rfcContent = await fs.readFile(path.join(rfcDir, rfcFile));
227
227
  const parsed = parseRfcFile(rfcContent);
228
228
  const fm = parsed.frontmatter;
229
229
 
@@ -282,7 +282,7 @@ export async function runSpecLiveMerge(
282
282
 
283
283
  let existingSpec: LivingSpec | null = null;
284
284
  if (existsSync(specFilePath)) {
285
- const specContent = await fs.readFile(specFilePath, "utf-8");
285
+ const specContent = await fs.readFile(specFilePath);
286
286
  existingSpec = parseLivingSpec(specContent);
287
287
  }
288
288
 
@@ -311,7 +311,7 @@ export async function runSpecLiveMerge(
311
311
  };
312
312
 
313
313
  if (!dryRun) {
314
- await fs.mkdir(liveSpecsDir, { recursive: true });
314
+ await fs.mkdir(liveSpecsDir);
315
315
  await writeFileIfChanged(specFilePath, serializeLivingSpec(newSpec));
316
316
  }
317
317
 
@@ -10,8 +10,8 @@
10
10
  </CHANGE_SUMMARY>
11
11
  */
12
12
 
13
- import fs from "node:fs/promises";
14
- import { existsSync } from "node:fs";
13
+ import { ambientIo as fs } from "../../src/utils/io.ts";
14
+ import { existsSync } from "../../src/utils/sync-fs.ts";
15
15
  import path from "node:path";
16
16
  import YAML from "yaml";
17
17
  import type {
@@ -68,7 +68,7 @@ export async function runSpecLiveShow(
68
68
  };
69
69
  }
70
70
 
71
- const content = await fs.readFile(specFilePath, "utf-8");
71
+ const content = await fs.readFile(specFilePath);
72
72
  const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/);
73
73
  if (!match) {
74
74
  return {
@@ -11,8 +11,8 @@ with rules V-LS-01..05 (RFC-0711).</purpose>
11
11
  </CHANGE_SUMMARY>
12
12
  */
13
13
 
14
- import fs from "node:fs/promises";
15
- import { existsSync } from "node:fs";
14
+ import { ambientIo as fs } from "../../src/utils/io.ts";
15
+ import { existsSync } from "../../src/utils/sync-fs.ts";
16
16
  import path from "node:path";
17
17
  import YAML from "yaml";
18
18
  import type {
@@ -75,13 +75,13 @@ export async function runSpecLiveValidate(
75
75
  };
76
76
  }
77
77
 
78
- const files = await fs.readdir(liveSpecsDir);
78
+ const files = (await fs.readdir(liveSpecsDir)).map((e) => e.name);
79
79
  const specFiles = files.filter((f) => f.endsWith(".md") && f !== "README.md");
80
80
 
81
81
  for (const file of specFiles) {
82
82
  specsChecked++;
83
83
  const filePath = path.join(liveSpecsDir, file);
84
- const content = await fs.readFile(filePath, "utf-8");
84
+ const content = await fs.readFile(filePath);
85
85
  const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
86
86
  if (!match) {
87
87
  violations.push({ rule: "V-LS-01", message: `${file}: no valid frontmatter block`, domain: file });