@warpgogol/forge 5.2.3 → 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 (584) hide show
  1. package/AGENTS.md +34 -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 +57 -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 +10 -1
  247. package/dist/src/config/forge-config.d.ts.map +1 -1
  248. package/dist/src/config/forge-config.js +8 -1
  249. package/dist/src/config/forge-config.js.map +1 -1
  250. package/dist/src/knowledge/budgets.js +1 -1
  251. package/dist/src/knowledge/budgets.js.map +1 -1
  252. package/dist/src/knowledge/compact.js +1 -1
  253. package/dist/src/knowledge/compact.js.map +1 -1
  254. package/dist/src/knowledge/parse.js +1 -1
  255. package/dist/src/knowledge/parse.js.map +1 -1
  256. package/dist/src/knowledge/sync.d.ts.map +1 -1
  257. package/dist/src/knowledge/sync.js +3 -5
  258. package/dist/src/knowledge/sync.js.map +1 -1
  259. package/dist/src/migration-adapters/git-utils.js +2 -2
  260. package/dist/src/migration-adapters/git-utils.js.map +1 -1
  261. package/dist/src/migration-adapters/ignored-files.js +2 -2
  262. package/dist/src/migration-adapters/ignored-files.js.map +1 -1
  263. package/dist/src/migration-adapters/node-typescript-pnpm/index.js +1 -1
  264. package/dist/src/migration-adapters/node-typescript-pnpm/index.js.map +1 -1
  265. package/dist/src/migration-adapters/phaser-pnpm/index.js +1 -1
  266. package/dist/src/migration-adapters/phaser-pnpm/index.js.map +1 -1
  267. package/dist/src/onboarding/agents-generate.d.ts +2 -0
  268. package/dist/src/onboarding/agents-generate.d.ts.map +1 -1
  269. package/dist/src/onboarding/agents-generate.js +73 -48
  270. package/dist/src/onboarding/agents-generate.js.map +1 -1
  271. package/dist/src/onboarding/create.d.ts.map +1 -1
  272. package/dist/src/onboarding/create.js +10 -10
  273. package/dist/src/onboarding/create.js.map +1 -1
  274. package/dist/src/onboarding/doctor.d.ts +6 -0
  275. package/dist/src/onboarding/doctor.d.ts.map +1 -1
  276. package/dist/src/onboarding/doctor.js +179 -61
  277. package/dist/src/onboarding/doctor.js.map +1 -1
  278. package/dist/src/onboarding/init.d.ts.map +1 -1
  279. package/dist/src/onboarding/init.js +30 -1
  280. package/dist/src/onboarding/init.js.map +1 -1
  281. package/dist/src/onboarding/invariant-engine.js +1 -1
  282. package/dist/src/onboarding/invariant-engine.js.map +1 -1
  283. package/dist/src/onboarding/memory-compact.d.ts +22 -0
  284. package/dist/src/onboarding/memory-compact.d.ts.map +1 -0
  285. package/dist/src/onboarding/memory-compact.js +148 -0
  286. package/dist/src/onboarding/memory-compact.js.map +1 -0
  287. package/dist/src/onboarding/memory-scaffold.d.ts +1 -0
  288. package/dist/src/onboarding/memory-scaffold.d.ts.map +1 -1
  289. package/dist/src/onboarding/memory-scaffold.js +2 -2
  290. package/dist/src/onboarding/memory-scaffold.js.map +1 -1
  291. package/dist/src/onboarding/nested-agents-generate.d.ts +4 -1
  292. package/dist/src/onboarding/nested-agents-generate.d.ts.map +1 -1
  293. package/dist/src/onboarding/nested-agents-generate.js +35 -6
  294. package/dist/src/onboarding/nested-agents-generate.js.map +1 -1
  295. package/dist/src/onboarding/nested-agents-templates.d.ts.map +1 -1
  296. package/dist/src/onboarding/nested-agents-templates.js +8 -12
  297. package/dist/src/onboarding/nested-agents-templates.js.map +1 -1
  298. package/dist/src/onboarding/npm-token-check.js +2 -2
  299. package/dist/src/onboarding/npm-token-check.js.map +1 -1
  300. package/dist/src/onboarding/prettierignore.d.ts +29 -0
  301. package/dist/src/onboarding/prettierignore.d.ts.map +1 -0
  302. package/dist/src/onboarding/prettierignore.js +231 -0
  303. package/dist/src/onboarding/prettierignore.js.map +1 -0
  304. package/dist/src/onboarding/profile-validate.d.ts.map +1 -1
  305. package/dist/src/onboarding/profile-validate.js +5 -4
  306. package/dist/src/onboarding/profile-validate.js.map +1 -1
  307. package/dist/src/onboarding/scaffold-project.d.ts.map +1 -1
  308. package/dist/src/onboarding/scaffold-project.js +35 -27
  309. package/dist/src/onboarding/scaffold-project.js.map +1 -1
  310. package/dist/src/onboarding/scaffold.js +1 -1
  311. package/dist/src/onboarding/scaffold.js.map +1 -1
  312. package/dist/src/onboarding/skill-markers.d.ts +27 -0
  313. package/dist/src/onboarding/skill-markers.d.ts.map +1 -0
  314. package/dist/src/onboarding/skill-markers.js +131 -0
  315. package/dist/src/onboarding/skill-markers.js.map +1 -0
  316. package/dist/src/onboarding/upgrade.d.ts +10 -0
  317. package/dist/src/onboarding/upgrade.d.ts.map +1 -1
  318. package/dist/src/onboarding/upgrade.js +215 -74
  319. package/dist/src/onboarding/upgrade.js.map +1 -1
  320. package/dist/src/onboarding/workspace-discovery.d.ts +1 -1
  321. package/dist/src/onboarding/workspace-discovery.d.ts.map +1 -1
  322. package/dist/src/onboarding/workspace-discovery.js +15 -3
  323. package/dist/src/onboarding/workspace-discovery.js.map +1 -1
  324. package/dist/src/pipeline-status.d.ts +6 -5
  325. package/dist/src/pipeline-status.d.ts.map +1 -1
  326. package/dist/src/pipeline-status.js +24 -19
  327. package/dist/src/pipeline-status.js.map +1 -1
  328. package/dist/src/profiles/stack-profile.js +1 -1
  329. package/dist/src/profiles/stack-profile.js.map +1 -1
  330. package/dist/src/registry.d.ts +1 -1
  331. package/dist/src/registry.d.ts.map +1 -1
  332. package/dist/src/registry.js +3 -3
  333. package/dist/src/registry.js.map +1 -1
  334. package/dist/src/skill-schema.d.ts +1 -1
  335. package/dist/src/skill-schema.d.ts.map +1 -1
  336. package/dist/src/skill-schema.js +4 -1
  337. package/dist/src/skill-schema.js.map +1 -1
  338. package/dist/src/types.d.ts +116 -0
  339. package/dist/src/types.d.ts.map +1 -1
  340. package/dist/src/utils/editable-region.d.ts +46 -0
  341. package/dist/src/utils/editable-region.d.ts.map +1 -0
  342. package/dist/src/utils/editable-region.js +125 -0
  343. package/dist/src/utils/editable-region.js.map +1 -0
  344. package/dist/src/utils/fs-idempotent.d.ts +2 -1
  345. package/dist/src/utils/fs-idempotent.d.ts.map +1 -1
  346. package/dist/src/utils/fs-idempotent.js +11 -7
  347. package/dist/src/utils/fs-idempotent.js.map +1 -1
  348. package/dist/src/utils/generated-marker.d.ts +17 -0
  349. package/dist/src/utils/generated-marker.d.ts.map +1 -1
  350. package/dist/src/utils/generated-marker.js +29 -1
  351. package/dist/src/utils/generated-marker.js.map +1 -1
  352. package/dist/src/utils/index.d.ts +3 -1
  353. package/dist/src/utils/index.d.ts.map +1 -1
  354. package/dist/src/utils/index.js +3 -1
  355. package/dist/src/utils/index.js.map +1 -1
  356. package/dist/src/utils/io.d.ts +9 -0
  357. package/dist/src/utils/io.d.ts.map +1 -0
  358. package/dist/src/utils/io.js +130 -0
  359. package/dist/src/utils/io.js.map +1 -0
  360. package/dist/src/utils/markdown-table.d.ts +21 -0
  361. package/dist/src/utils/markdown-table.d.ts.map +1 -0
  362. package/dist/src/utils/markdown-table.js +116 -0
  363. package/dist/src/utils/markdown-table.js.map +1 -0
  364. package/dist/src/utils/sync-fs.d.ts +5 -0
  365. package/dist/src/utils/sync-fs.d.ts.map +1 -0
  366. package/dist/src/utils/sync-fs.js +26 -0
  367. package/dist/src/utils/sync-fs.js.map +1 -0
  368. package/dist/src/validators/note-frontmatter-validate.js +1 -1
  369. package/dist/src/validators/note-frontmatter-validate.js.map +1 -1
  370. package/dist/src/validators/note-link-validate.js +1 -1
  371. package/dist/src/validators/note-link-validate.js.map +1 -1
  372. package/dist/src/validators/note-orphan-detect.js +1 -1
  373. package/dist/src/validators/note-orphan-detect.js.map +1 -1
  374. package/dist/src/validators/port-validate.js +1 -1
  375. package/dist/src/validators/port-validate.js.map +1 -1
  376. package/dist/src/validators/skill-validate.d.ts.map +1 -1
  377. package/dist/src/validators/skill-validate.js +34 -13
  378. package/dist/src/validators/skill-validate.js.map +1 -1
  379. package/docs/reference/forge-yaml.md +12 -0
  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 -9
  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 +58 -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.ts +27 -19
  421. package/os/mission/mission.module.ts +38 -39
  422. package/os/naming/naming-convention.ts +9 -3
  423. package/os/naming/naming.module.ts +25 -25
  424. package/os/notes/notes.module.ts +87 -85
  425. package/os/plan/frontmatter-io.ts +5 -5
  426. package/os/plan/handlers/archive.ts +8 -4
  427. package/os/plan/plan.module.ts +33 -34
  428. package/os/plugin/plugin.module.ts +8 -6
  429. package/os/program/discovery.ts +2 -2
  430. package/os/program/handlers/complete.ts +1 -1
  431. package/os/program/handlers/lease.ts +1 -1
  432. package/os/program/handlers/seal.ts +1 -1
  433. package/os/program/lease.ts +1 -1
  434. package/os/program/program.module.ts +198 -193
  435. package/os/queue/index.ts +1 -1
  436. package/os/queue/manifest.ts +10 -9
  437. package/os/queue/queue-validate.test.ts +6 -15
  438. package/os/rfc/acceptance.ts +12 -6
  439. package/os/rfc/decision-log.ts +4 -3
  440. package/os/rfc/dna-trace.ts +8 -2
  441. package/os/rfc/frontmatter-io.ts +5 -5
  442. package/os/rfc/handlers/archive.ts +9 -5
  443. package/os/rfc/handlers/check.ts +5 -3
  444. package/os/rfc/handlers/implement-stamp.ts +15 -10
  445. package/os/rfc/handlers/index-graph.ts +3 -3
  446. package/os/rfc/handlers/lifecycle.ts +7 -2
  447. package/os/rfc/handlers/list-create.ts +7 -6
  448. package/os/rfc/handlers/shared.ts +3 -3
  449. package/os/rfc/handlers/supersede-propose.ts +8 -3
  450. package/os/rfc/handlers/validate-rules-rfc1006.test.ts +18 -6
  451. package/os/rfc/handlers/validate-rules.ts +10 -5
  452. package/os/rfc/rfc-create-concurrent.test.ts +11 -3
  453. package/os/rfc/rfc.module.ts +413 -374
  454. package/os/rfc/verification-evidence.ts +11 -5
  455. package/os/rfc/verification-refresh.ts +4 -3
  456. package/os/session/frontmatter-io.ts +14 -14
  457. package/os/session/handlers/archive.ts +8 -4
  458. package/os/session/handlers/metrics-aggregate.ts +34 -13
  459. package/os/session/handlers/metrics-rfc.ts +13 -8
  460. package/os/session/handlers/metrics-session.ts +7 -3
  461. package/os/session/handlers/save.ts +12 -8
  462. package/os/session/session.module.ts +6 -0
  463. package/os/spec/live-spec-list.ts +4 -4
  464. package/os/spec/live-spec-merge.ts +5 -5
  465. package/os/spec/live-spec-show.ts +3 -3
  466. package/os/spec/live-spec-validate.ts +4 -4
  467. package/os/spec/spec-materialize.ts +9 -9
  468. package/os/spec/spec-status.ts +9 -9
  469. package/os/spec/spec-validate.ts +7 -7
  470. package/os/spec/spec.module.ts +8 -0
  471. package/os/werkstatt/handlers/lock.ts +16 -16
  472. package/os/werkstatt/handlers/werkstatt-lock-recover.ts +3 -3
  473. package/os/werkstatt/handlers/werkstatt-operation-validate.ts +4 -2
  474. package/os/werkstatt/werkstatt.module.ts +8 -5
  475. package/os/workflow/handlers.ts +7 -5
  476. package/os/workflow/workflow.module.ts +45 -44
  477. package/package.json +1 -1
  478. package/profiles/forge-shell.yaml +3 -0
  479. package/profiles/godot-game.yaml +3 -0
  480. package/profiles/phaser-game.yaml +3 -0
  481. package/profiles/site-workshop.yaml +567 -564
  482. package/skills/fo/fo-add-tests/SKILL.md +2 -2
  483. package/skills/fo/fo-architecture/SKILL.md +2 -2
  484. package/skills/fo/fo-compass-annotate/SKILL.md +2 -2
  485. package/skills/fo/fo-design-summit/SKILL.md +2 -2
  486. package/skills/fo/fo-doc-audit/SKILL.md +2 -2
  487. package/skills/fo/fo-explore/SKILL.md +2 -2
  488. package/skills/fo/fo-extract-dna/SKILL.md +2 -2
  489. package/skills/fo/fo-fix/SKILL.md +2 -2
  490. package/skills/fo/fo-handoff/SKILL.md +2 -2
  491. package/skills/fo/fo-harvest/SKILL.md +2 -2
  492. package/skills/fo/fo-idea/SKILL.md +2 -2
  493. package/skills/fo/fo-idea-audit/SKILL.md +2 -2
  494. package/skills/fo/fo-idea-create-adr/SKILL.md +3 -3
  495. package/skills/fo/fo-idea-create-rfc/SKILL.md +3 -3
  496. package/skills/fo/fo-idea-enhance/SKILL.md +2 -2
  497. package/skills/fo/fo-idea-i-just-want-to-see-the-plan/SKILL.md +2 -2
  498. package/skills/fo/fo-idea-i-just-want-to-see-the-result/SKILL.md +1 -1
  499. package/skills/fo/fo-idea-implement/SKILL.md +2 -2
  500. package/skills/fo/fo-idea-plan/SKILL.md +2 -2
  501. package/skills/fo/fo-idea-status/SKILL.md +2 -2
  502. package/skills/fo/fo-knowledge-distill/SKILL.md +2 -2
  503. package/skills/fo/fo-memory-sync/SKILL.md +2 -2
  504. package/skills/fo/fo-qa/SKILL.md +2 -2
  505. package/skills/fo/fo-review/SKILL.md +2 -2
  506. package/skills/fo/fo-session-retro/SKILL.md +2 -2
  507. package/skills/fo/fo-session-save/SKILL.md +2 -2
  508. package/skills/fo/fo-spec-ingest/SKILL.md +2 -2
  509. package/skills/fo/fo-step-commit/SKILL.md +1 -1
  510. package/skills/fo/fo-triage/SKILL.md +2 -2
  511. package/skills/meta/forge-bootstrap/SKILL.md +1 -1
  512. package/skills/meta/port-to-forge/SKILL.md +1 -1
  513. package/skills/meta/skill-create/SKILL.md +1 -1
  514. package/skills/shared/grilling/SKILL.md +1 -1
  515. package/skills/shared/grilling/learned-principles.archive.md +17 -0
  516. package/skills/shared/grilling/learned-principles.md +0 -1
  517. package/skills/shared/knowledge/learned-principles.md +6 -0
  518. package/skills/shared/my-preferences/SKILL.md +1 -1
  519. package/skills/shared/windows-ai-tooling/SKILL.md +1 -1
  520. package/skills/shared/writing-great-skills/SKILL.md +1 -1
  521. package/src/compass/contract-registry.ts +1 -1
  522. package/src/config/forge-config.ts +12 -1
  523. package/src/knowledge/__tests__/sync.test.ts +2 -7
  524. package/src/knowledge/budgets.ts +1 -1
  525. package/src/knowledge/compact.ts +1 -1
  526. package/src/knowledge/parse.ts +1 -1
  527. package/src/knowledge/sync.ts +3 -5
  528. package/src/migration-adapters/git-utils.ts +2 -2
  529. package/src/migration-adapters/ignored-files.ts +2 -2
  530. package/src/migration-adapters/node-typescript-pnpm/index.ts +1 -1
  531. package/src/migration-adapters/phaser-pnpm/index.ts +1 -1
  532. package/src/onboarding/agents-generate.ts +91 -50
  533. package/src/onboarding/create.ts +10 -10
  534. package/src/onboarding/doctor.ts +199 -59
  535. package/src/onboarding/init.ts +38 -1
  536. package/src/onboarding/invariant-engine.ts +1 -1
  537. package/src/onboarding/memory-compact.ts +189 -0
  538. package/src/onboarding/memory-scaffold.ts +2 -2
  539. package/src/onboarding/nested-agents-generate.ts +50 -5
  540. package/src/onboarding/nested-agents-templates.ts +19 -13
  541. package/src/onboarding/npm-token-check.ts +2 -2
  542. package/src/onboarding/prettierignore.ts +263 -0
  543. package/src/onboarding/profile-validate.ts +5 -4
  544. package/src/onboarding/scaffold-project.ts +38 -27
  545. package/src/onboarding/scaffold.ts +1 -1
  546. package/src/onboarding/skill-markers.ts +162 -0
  547. package/src/onboarding/templates/behavioral-layer-core.md +2 -4
  548. package/src/onboarding/upgrade.ts +285 -89
  549. package/src/onboarding/workspace-discovery.ts +16 -2
  550. package/src/pipeline-status.test.ts +1 -4
  551. package/src/pipeline-status.ts +30 -13
  552. package/src/profiles/stack-profile.ts +1 -1
  553. package/src/registry.ts +4 -4
  554. package/src/skill-schema.ts +4 -1
  555. package/src/tests/acceptance-probe-kinds.test.ts +5 -15
  556. package/src/tests/agents-generate.test.ts +32 -7
  557. package/src/tests/contract-registry.test.ts +12 -6
  558. package/src/tests/doctor-dist-freshness.test.ts +110 -0
  559. package/src/tests/doctor-fix.test.ts +142 -0
  560. package/src/tests/doctor-nested-agents.test.ts +160 -0
  561. package/src/tests/editable-generated-region.test.ts +231 -0
  562. package/src/tests/file-size-lint.test.ts +8 -12
  563. package/src/tests/fixtures/agents-generate-business-before.txt +54 -54
  564. package/src/tests/markdown-table.test.ts +107 -0
  565. package/src/tests/memory-compact.test.ts +143 -0
  566. package/src/tests/prettierignore-manage.test.ts +134 -0
  567. package/src/tests/skill-agents-sync.test.ts +168 -0
  568. package/src/tests/skill-sync-marker.test.ts +134 -0
  569. package/src/tests/skill-validate.test.ts +12 -5
  570. package/src/tests/upgrade.test.ts +87 -41
  571. package/src/tests/workspace-discovery.test.ts +28 -0
  572. package/src/types.ts +123 -0
  573. package/src/utils/editable-region.ts +156 -0
  574. package/src/utils/fs-idempotent.ts +12 -6
  575. package/src/utils/generated-marker.ts +36 -2
  576. package/src/utils/index.ts +17 -0
  577. package/src/utils/io.ts +143 -0
  578. package/src/utils/markdown-table.ts +121 -0
  579. package/src/utils/sync-fs.ts +43 -0
  580. package/src/validators/note-frontmatter-validate.ts +1 -1
  581. package/src/validators/note-link-validate.ts +1 -1
  582. package/src/validators/note-orphan-detect.ts +1 -1
  583. package/src/validators/port-validate.ts +1 -1
  584. package/src/validators/skill-validate.ts +38 -13
@@ -15,7 +15,7 @@ workspace type (app, service, package) by content markers.</purpose>
15
15
  </CHANGE_SUMMARY>
16
16
  */
17
17
 
18
- import fs from "node:fs";
18
+ import * as fs from "../utils/sync-fs.ts";
19
19
  import path from "node:path";
20
20
  import { hasGeneratedMarker } from "../utils/index.ts";
21
21
  import type { ProfileWorkspaceType } from "../profiles/profile-schema.ts";
@@ -36,6 +36,13 @@ const SKIP_DIRS = new Set([
36
36
  ".turbo",
37
37
  ".cache",
38
38
  ".agents",
39
+ // Pipeline-managed mission workpieces and archives — their AGENTS.md is
40
+ // generated by the site pipeline, not by forge.agents.generate.
41
+ "missions",
42
+ // Test fixture workshops — not real project workspaces.
43
+ "test-fixtures",
44
+ // Stryker mutation-testing sandboxes — transient temp dirs.
45
+ ".stryker-tmp",
39
46
  ]);
40
47
 
41
48
  export function detectWorkspaceType(
@@ -110,8 +117,15 @@ function matchesWorkspaceType(dirPath: string, wt: ProfileWorkspaceType): boolea
110
117
  export function discoverWorkspaces(
111
118
  workspaceRoot: string,
112
119
  workspaceTypes?: ProfileWorkspaceType[],
120
+ extraSkipDirs?: readonly string[],
113
121
  ): WorkspaceDir[] {
114
122
  const results: WorkspaceDir[] = [];
123
+ // RFC-1150: consumer-declared exclusions (bindings.workspaces.skipDirs)
124
+ // merge over the SKIP_DIRS defaults.
125
+ const skipDirs =
126
+ extraSkipDirs && extraSkipDirs.length > 0
127
+ ? new Set([...SKIP_DIRS, ...extraSkipDirs])
128
+ : SKIP_DIRS;
115
129
 
116
130
  function scanDir(dirPath: string, depth: number): void {
117
131
  if (depth > 5) return;
@@ -125,7 +139,7 @@ export function discoverWorkspaces(
125
139
 
126
140
  for (const entry of entries) {
127
141
  if (!entry.isDirectory()) continue;
128
- if (SKIP_DIRS.has(entry.name)) continue;
142
+ if (skipDirs.has(entry.name)) continue;
129
143
 
130
144
  const childPath = path.join(dirPath, entry.name);
131
145
  const type = detectWorkspaceType(childPath, workspaceTypes);
@@ -116,10 +116,7 @@ describe("deriveQueueItemStatus — derivation matrix (RFC-1140)", () => {
116
116
 
117
117
  test("audit file only → in-progress/enhance", async () => {
118
118
  await writeRfc("RFC-1107", "status: draft\n");
119
- await fs.writeFile(
120
- path.join(tmpDir, "docs/audits/audit-rfc-1107-test.md"),
121
- "# audit\n",
122
- );
119
+ await fs.writeFile(path.join(tmpDir, "docs/audits/audit-rfc-1107-test.md"), "# audit\n");
123
120
  const r = await deriveQueueItemStatus(tmpDir, "RFC-1107");
124
121
  expect(r?.status).toBe("in-progress");
125
122
  expect(r?.pipelineStep).toBe("enhance");
@@ -25,8 +25,9 @@ Add pipeline-status.test.ts (derivation matrix, order, next selection, ADR, skip
25
25
  </CHANGE_SUMMARY>
26
26
  */
27
27
 
28
- import fs from "node:fs/promises";
29
28
  import path from "node:path";
29
+ import type { WorkspaceIO } from "./types.ts";
30
+ import { resolveIo } from "./utils/io.ts";
30
31
  import YAML from "yaml";
31
32
 
32
33
  // ---------------------------------------------------------------------------
@@ -75,10 +76,12 @@ export function parseFrontmatter(source: string): ParsedDocument {
75
76
  export async function findAuditFile(
76
77
  workspaceRoot: string,
77
78
  docId: string,
79
+ io?: WorkspaceIO,
78
80
  ): Promise<string | undefined> {
81
+ const fio = resolveIo(io);
79
82
  const auditsDir = path.join(workspaceRoot, "docs/audits");
80
83
  try {
81
- const entries = await fs.readdir(auditsDir);
84
+ const entries = (await fio.readdir(auditsDir)).map((e) => e.name);
82
85
  const prefix = `audit-${docId.toLowerCase()}`;
83
86
  const match = entries.find((e) => e.toLowerCase().startsWith(prefix) && e.endsWith(".md"));
84
87
  return match ? path.join("docs/audits", match) : undefined;
@@ -90,10 +93,12 @@ export async function findAuditFile(
90
93
  export async function findPlanFile(
91
94
  workspaceRoot: string,
92
95
  docId: string,
96
+ io?: WorkspaceIO,
93
97
  ): Promise<string | undefined> {
98
+ const fio = resolveIo(io);
94
99
  const plansDir = path.join(workspaceRoot, "docs/plans");
95
100
  try {
96
- const entries = await fs.readdir(plansDir);
101
+ const entries = (await fio.readdir(plansDir)).map((e) => e.name);
97
102
  const prefix = `plan-${docId.toLowerCase()}`;
98
103
  const match = entries.find((e) => e.toLowerCase().startsWith(prefix) && e.endsWith(".md"));
99
104
  return match ? path.join("docs/plans", match) : undefined;
@@ -122,20 +127,26 @@ async function scanForDocument(
122
127
  dirPath: string,
123
128
  relativePrefix: string,
124
129
  idLower: string,
130
+ io: WorkspaceIO,
125
131
  ): Promise<string | undefined> {
126
132
  let entries;
127
133
  try {
128
- entries = await fs.readdir(dirPath, { withFileTypes: true });
134
+ entries = await io.readdir(dirPath);
129
135
  } catch {
130
136
  return undefined;
131
137
  }
132
138
  for (const entry of entries) {
133
139
  const relativePath = relativePrefix ? `${relativePrefix}/${entry.name}` : entry.name;
134
- if (entry.isDirectory()) {
135
- const found = await scanForDocument(path.join(dirPath, entry.name), relativePath, idLower);
140
+ if (entry.isDirectory) {
141
+ const found = await scanForDocument(
142
+ path.join(dirPath, entry.name),
143
+ relativePath,
144
+ idLower,
145
+ io,
146
+ );
136
147
  if (found) return found;
137
148
  } else if (
138
- entry.isFile() &&
149
+ entry.isFile &&
139
150
  entry.name.endsWith(".md") &&
140
151
  entry.name.toLowerCase().startsWith(idLower)
141
152
  ) {
@@ -153,19 +164,21 @@ async function scanForDocument(
153
164
  export async function resolveDocument(
154
165
  workspaceRoot: string,
155
166
  docId: string,
167
+ io?: WorkspaceIO,
156
168
  ): Promise<ResolvedDocument | undefined> {
169
+ const fio = resolveIo(io);
157
170
  const idMatch = DOC_ID_PATTERN.exec(docId.trim());
158
171
  if (!idMatch) return undefined;
159
172
  const kind: QueueDocumentKind = idMatch[1]!.toUpperCase() === "ADR" ? "adr" : "rfc";
160
173
  const baseDir = kind === "adr" ? "docs/adrs" : "docs/rfcs";
161
174
  const idLower = docId.toLowerCase();
162
175
 
163
- const found = await scanForDocument(path.join(workspaceRoot, baseDir), "", idLower);
176
+ const found = await scanForDocument(path.join(workspaceRoot, baseDir), "", idLower, fio);
164
177
  if (!found) return undefined;
165
178
 
166
179
  let source: string;
167
180
  try {
168
- source = await fs.readFile(path.join(workspaceRoot, baseDir, found), "utf-8");
181
+ source = await fio.readFile(path.join(workspaceRoot, baseDir, found));
169
182
  } catch {
170
183
  return undefined;
171
184
  }
@@ -242,8 +255,10 @@ export interface QueueItemReport {
242
255
  export async function deriveQueueItemStatus(
243
256
  workspaceRoot: string,
244
257
  docId: string,
258
+ io?: WorkspaceIO,
245
259
  ): Promise<QueueItemReport | undefined> {
246
- const doc = await resolveDocument(workspaceRoot, docId);
260
+ const fio = resolveIo(io);
261
+ const doc = await resolveDocument(workspaceRoot, docId, fio);
247
262
  if (!doc) return undefined;
248
263
 
249
264
  const fm = doc.frontmatter;
@@ -268,8 +283,8 @@ export async function deriveQueueItemStatus(
268
283
  }
269
284
 
270
285
  const enhancedAt = fm["enhancedAt"] ? String(fm["enhancedAt"]) : undefined;
271
- const auditFile = await findAuditFile(workspaceRoot, doc.id);
272
- const planFile = await findPlanFile(workspaceRoot, doc.id);
286
+ const auditFile = await findAuditFile(workspaceRoot, doc.id, fio);
287
+ const planFile = await findPlanFile(workspaceRoot, doc.id, fio);
273
288
 
274
289
  const stages = computeRfcPipelineStages({
275
290
  status,
@@ -306,10 +321,12 @@ export interface QueueReport {
306
321
  export async function deriveQueueReport(
307
322
  workspaceRoot: string,
308
323
  itemIds: string[],
324
+ io?: WorkspaceIO,
309
325
  ): Promise<QueueReport> {
326
+ const fio = resolveIo(io);
310
327
  const items: QueueItemReport[] = [];
311
328
  for (const id of itemIds) {
312
- const report = await deriveQueueItemStatus(workspaceRoot, id);
329
+ const report = await deriveQueueItemStatus(workspaceRoot, id, fio);
313
330
  // Unresolvable ids are reported by the manifest validator; the resolver
314
331
  // skips them here so a partial report stays usable.
315
332
  if (report) items.push(report);
@@ -20,7 +20,7 @@ Sweep batch 2: real KEY_DECISIONS on 10 files, expanded purposes (CONTRACT-02/PU
20
20
  </CHANGE_SUMMARY>
21
21
  */
22
22
 
23
- import fs from "node:fs";
23
+ import * as fs from "../utils/sync-fs.ts";
24
24
  import path from "node:path";
25
25
  import { z } from "zod";
26
26
  import { parse as parseYaml } from "yaml";
package/src/registry.ts CHANGED
@@ -19,7 +19,7 @@ Sweep batch 2: real KEY_DECISIONS on 10 files, expanded purposes (CONTRACT-02/PU
19
19
  </CHANGE_SUMMARY>
20
20
  */
21
21
 
22
- import fs from "node:fs";
22
+ import * as fs from "./utils/sync-fs.ts";
23
23
  import path from "node:path";
24
24
  import { parse as parseYaml } from "yaml";
25
25
  import type { ForgeConfig } from "./config/forge-config.ts";
@@ -38,7 +38,7 @@ export interface ForgeSkillEntry {
38
38
  dependsOn: string[];
39
39
  path: string;
40
40
  knowledge?: string[];
41
- triggers?: string[];
41
+ triggerPhrases?: string[];
42
42
  }
43
43
 
44
44
  /**
@@ -191,9 +191,9 @@ function discoverForgeSkills(skillsRoot: string): ForgeSkillEntry[] {
191
191
  ),
192
192
  }
193
193
  : {}),
194
- ...(Array.isArray(fm["triggers"])
194
+ ...(Array.isArray(fm["triggerPhrases"])
195
195
  ? {
196
- triggers: (fm["triggers"] as unknown[]).filter(
196
+ triggerPhrases: (fm["triggerPhrases"] as unknown[]).filter(
197
197
  (v): v is string => typeof v === "string",
198
198
  ),
199
199
  }
@@ -31,7 +31,10 @@ export const skillFrontmatterSchema = z.object({
31
31
  })
32
32
  .optional(),
33
33
  knowledge: z.array(z.string()).optional(),
34
- triggers: z.array(z.string().min(5).max(100)).max(5).optional(),
34
+ // Named triggerPhrases, not triggers — agent-IDE skill loaders (Devin CLI,
35
+ // Windsurf) reserve `triggers` for invocation modes (user/model); a list of
36
+ // phrases parses to zero valid modes and the skill is dropped entirely.
37
+ triggerPhrases: z.array(z.string().min(5).max(100)).max(5).optional(),
35
38
  });
36
39
 
37
40
  export type SkillFrontmatter = z.infer<typeof skillFrontmatterSchema>;
@@ -36,17 +36,13 @@ describe("validateAcceptanceShape — test probe", () => {
36
36
  });
37
37
 
38
38
  it("rejects a test probe missing file", () => {
39
- const issues = validateAcceptanceShape([
40
- { probe: "test", expect: { exitCode: 0 } },
41
- ]);
39
+ const issues = validateAcceptanceShape([{ probe: "test", expect: { exitCode: 0 } }]);
42
40
  expect(issues).toHaveLength(1);
43
41
  expect(issues[0].message).toContain('requires a string "file"');
44
42
  });
45
43
 
46
44
  it("rejects a test probe missing expect.exitCode", () => {
47
- const issues = validateAcceptanceShape([
48
- { probe: "test", file: "src/test.ts" },
49
- ]);
45
+ const issues = validateAcceptanceShape([{ probe: "test", file: "src/test.ts" }]);
50
46
  expect(issues).toHaveLength(1);
51
47
  expect(issues[0].message).toContain("requires expect: { exitCode");
52
48
  });
@@ -108,9 +104,7 @@ describe("validateAcceptanceShape — existing probe kinds (regression)", () =>
108
104
  });
109
105
 
110
106
  it("accepts well-formed file-exists probe", () => {
111
- const issues = validateAcceptanceShape([
112
- { probe: "file-exists", path: "src/index.ts" },
113
- ]);
107
+ const issues = validateAcceptanceShape([{ probe: "file-exists", path: "src/index.ts" }]);
114
108
  expect(issues).toEqual([]);
115
109
  });
116
110
 
@@ -122,16 +116,12 @@ describe("validateAcceptanceShape — existing probe kinds (regression)", () =>
122
116
  });
123
117
 
124
118
  it("accepts well-formed command-registered probe", () => {
125
- const issues = validateAcceptanceShape([
126
- { probe: "command-registered", name: "rfc.validate" },
127
- ]);
119
+ const issues = validateAcceptanceShape([{ probe: "command-registered", name: "rfc.validate" }]);
128
120
  expect(issues).toEqual([]);
129
121
  });
130
122
 
131
123
  it("accepts well-formed page probe", () => {
132
- const issues = validateAcceptanceShape([
133
- { probe: "page", path: "/about" },
134
- ]);
124
+ const issues = validateAcceptanceShape([{ probe: "page", path: "/about" }]);
135
125
  expect(issues).toEqual([]);
136
126
  });
137
127
  });
@@ -102,7 +102,8 @@ test("agents-generate includes intent-to-skill routing table", async () => {
102
102
 
103
103
  const agentsMd = await readFile(join(tempDir, "AGENTS.md"), "utf8");
104
104
  expect(agentsMd).toContain("### Intent-to-skill routing");
105
- expect(agentsMd).toContain("| Operator says something like | Skill |");
105
+ // RFC-1154: header cells are padded to column width — match via regex
106
+ expect(agentsMd).toMatch(/\| Operator says something like +\| Skill +\|/);
106
107
  // Should contain at least one skill name from the registry
107
108
  expect(agentsMd).toContain("fo-");
108
109
  });
@@ -224,13 +225,36 @@ test("agents-generate is idempotent — running twice produces the same content"
224
225
  expect(second).toBe(first);
225
226
  });
226
227
 
227
- test("agents-generate refuses to overwrite hand-written AGENTS.md", async () => {
228
+ // RFC-1150: hand-written root guard is non-fatal — skip root, continue nested
229
+
230
+ test("agents-generate skips hand-written root and still generates nested", async () => {
228
231
  await makeForgeYaml(tempDir);
229
232
  await writeFile(join(tempDir, "AGENTS.md"), "# Hand-written\nNo marker.\n", "utf8");
233
+ await mkdir(join(tempDir, "packages", "my-pkg"), { recursive: true });
234
+ await writeFile(
235
+ join(tempDir, "packages", "my-pkg", "package.json"),
236
+ JSON.stringify({ name: "@test/my-pkg" }),
237
+ );
230
238
 
231
239
  const result = await runAgentsGenerate({ argv: [], flags: {} }, makeContext(tempDir));
232
- expect(result.exitCode).toBe(1);
233
- expect(result.data?.status).toBe("fail");
240
+ expect(result.exitCode).toBe(0);
241
+ expect(result.data?.status).toBe("pass");
242
+ expect(result.data?.rootSkipped).toBe(true);
243
+ expect(result.data?.rootSkipReason).toBe("hand-written");
244
+ expect(result.data?.skipped).toContain("AGENTS.md (hand-written)");
245
+ expect(result.data?.generated).toContain("packages/my-pkg/AGENTS.md");
246
+ });
247
+
248
+ test("agents-generate does not modify hand-written root AGENTS.md", async () => {
249
+ await makeForgeYaml(tempDir);
250
+ const original = "# Hand-written\nNo marker.\n";
251
+ await writeFile(join(tempDir, "AGENTS.md"), original, "utf8");
252
+
253
+ const result = await runAgentsGenerate({ argv: [], flags: {} }, makeContext(tempDir));
254
+ expect(result.exitCode).toBe(0);
255
+
256
+ const after = await readFile(join(tempDir, "AGENTS.md"), "utf8");
257
+ expect(after).toBe(original);
234
258
  });
235
259
 
236
260
  // RFC-0611: nested AGENTS.md generation tests
@@ -404,9 +428,10 @@ test("agents-generate nested renders entry points from exports map", async () =>
404
428
 
405
429
  const nested = await readFile(join(tempDir, "packages", "my-pkg", "AGENTS.md"), "utf8");
406
430
  expect(nested).toContain("## Entry points");
407
- expect(nested).toContain("| `@test/my-pkg` | `./src/index.ts` |");
408
- expect(nested).toContain("| `@test/my-pkg/port` | `./src/port.ts` |");
409
- expect(nested).toContain("| `@test/my-pkg/client` | `./src/client.ts` |");
431
+ // RFC-1154: cells are padded to column width — match via regex
432
+ expect(nested).toMatch(/\| `@test\/my-pkg` +\| `\.\/src\/index\.ts` +\|/);
433
+ expect(nested).toMatch(/\| `@test\/my-pkg\/port` +\| `\.\/src\/port\.ts` +\|/);
434
+ expect(nested).toMatch(/\| `@test\/my-pkg\/client` +\| `\.\/src\/client\.ts` +\|/);
410
435
  });
411
436
 
412
437
  test("agents-generate nested separates workspace and external dependencies", async () => {
@@ -41,11 +41,15 @@ describe("contract-registry (RFC-0943)", () => {
41
41
 
42
42
  describe("fileMatchesGlobs", () => {
43
43
  test("matches a simple glob pattern", () => {
44
- expect(fileMatchesGlobs("packages/my-pack/src/index.ts", ["packages/my-pack/**/*.ts"])).toBe(true);
44
+ expect(fileMatchesGlobs("packages/my-pack/src/index.ts", ["packages/my-pack/**/*.ts"])).toBe(
45
+ true,
46
+ );
45
47
  });
46
48
 
47
49
  test("does not match when glob does not match", () => {
48
- expect(fileMatchesGlobs("packages/other-pack/src/index.ts", ["packages/my-pack/**/*.ts"])).toBe(false);
50
+ expect(
51
+ fileMatchesGlobs("packages/other-pack/src/index.ts", ["packages/my-pack/**/*.ts"]),
52
+ ).toBe(false);
49
53
  });
50
54
 
51
55
  test("matches any of multiple globs", () => {
@@ -58,7 +62,9 @@ describe("contract-registry (RFC-0943)", () => {
58
62
  });
59
63
 
60
64
  test("handles dot files with dot option", () => {
61
- expect(fileMatchesGlobs("packages/my-pack/.env.example", ["packages/**/*.example"])).toBe(true);
65
+ expect(fileMatchesGlobs("packages/my-pack/.env.example", ["packages/**/*.example"])).toBe(
66
+ true,
67
+ );
62
68
  });
63
69
  });
64
70
 
@@ -86,7 +92,7 @@ describe("contract-registry (RFC-0943)", () => {
86
92
  const packDir = join(ws, "my-pack");
87
93
  writeManifest(
88
94
  packDir,
89
- "id: my-pack\nversion: 1.0.0\nextensionPoints:\n compass:\n contract:\n blocks:\n - blockId: api-contract\n requiredFor:\n - \"packages/my-pack/**/*.ts\"\n requiredTags:\n - name: endpoints\n minWords: 5\n",
95
+ 'id: my-pack\nversion: 1.0.0\nextensionPoints:\n compass:\n contract:\n blocks:\n - blockId: api-contract\n requiredFor:\n - "packages/my-pack/**/*.ts"\n requiredTags:\n - name: endpoints\n minWords: 5\n',
90
96
  );
91
97
 
92
98
  const config: ForgeConfig = {
@@ -111,11 +117,11 @@ describe("contract-registry (RFC-0943)", () => {
111
117
  try {
112
118
  writeManifest(
113
119
  join(ws, "pack-a"),
114
- "id: pack-a\nversion: 1.0.0\nextensionPoints:\n compass:\n contract:\n blocks:\n - blockId: shared-block\n requiredFor:\n - \"packages/**/*.ts\"\n",
120
+ 'id: pack-a\nversion: 1.0.0\nextensionPoints:\n compass:\n contract:\n blocks:\n - blockId: shared-block\n requiredFor:\n - "packages/**/*.ts"\n',
115
121
  );
116
122
  writeManifest(
117
123
  join(ws, "pack-b"),
118
- "id: pack-b\nversion: 1.0.0\nextensionPoints:\n compass:\n contract:\n blocks:\n - blockId: shared-block\n requiredFor:\n - \"services/**/*.ts\"\n",
124
+ 'id: pack-b\nversion: 1.0.0\nextensionPoints:\n compass:\n contract:\n blocks:\n - blockId: shared-block\n requiredFor:\n - "services/**/*.ts"\n',
119
125
  );
120
126
 
121
127
  const config: ForgeConfig = {
@@ -0,0 +1,110 @@
1
+ /*
2
+ <MODULE_CONTRACT>
3
+ <purpose>Unit tests for the dist-freshness doctor check — warns when a forge
4
+ source checkout's dist/ is older than the newest src/ file (RFC-1151).</purpose>
5
+ </MODULE_CONTRACT>
6
+ <CHANGE_SUMMARY>
7
+ <item>RFC-1151: initial dist-freshness tests.</item>
8
+ </CHANGE_SUMMARY>
9
+ */
10
+
11
+ import { test, expect, beforeEach, afterEach } from "vitest";
12
+ import { mkdtemp, rm, mkdir, writeFile, utimes } from "node:fs/promises";
13
+ import { tmpdir } from "node:os";
14
+ import { join } from "node:path";
15
+ import { runDoctor } from "../onboarding/doctor.ts";
16
+ import type { ForgeCommandInput, ForgeRuntimeContext } from "../types.ts";
17
+
18
+ let tempDir: string;
19
+
20
+ beforeEach(async () => {
21
+ tempDir = await mkdtemp(join(tmpdir(), "doctor-dist-test-"));
22
+ });
23
+
24
+ afterEach(async () => {
25
+ await rm(tempDir, { recursive: true, force: true });
26
+ });
27
+
28
+ function makeContext(): ForgeRuntimeContext {
29
+ return {
30
+ workspaceRoot: tempDir,
31
+ // forgeRoot falls back to <workspaceRoot>/packages/forge when unresolvable
32
+ forgeRoot: join(tempDir, "packages", "forge"),
33
+ logger: {
34
+ section: () => {},
35
+ success: () => {},
36
+ warn: () => {},
37
+ error: () => {},
38
+ info: () => {},
39
+ },
40
+ dryRun: false,
41
+ outputFormat: "json",
42
+ };
43
+ }
44
+
45
+ const FORGE_YAML = `schema: "forge/config@1"
46
+ project:
47
+ name: test-project
48
+ stack: []
49
+ packageManager: pnpm
50
+ paths:
51
+ rfcsDir: docs/rfcs
52
+ adrsDir: docs/adrs
53
+ plansDir: docs/plans
54
+ auditsDir: docs/audits
55
+ specsDir: docs/specs
56
+ skillsDir: .agents/skills
57
+ sessionsDir: docs/sessions
58
+ `;
59
+
60
+ async function makeForgeCheckout(srcMtime: Date, distMtime: Date): Promise<void> {
61
+ const forgeRoot = join(tempDir, "packages", "forge");
62
+ await mkdir(join(forgeRoot, "src"), { recursive: true });
63
+ await mkdir(join(forgeRoot, "dist"), { recursive: true });
64
+ await writeFile(join(forgeRoot, "package.json"), JSON.stringify({ name: "@warpgogol/forge" }));
65
+ await writeFile(join(forgeRoot, "src", "index.ts"), "export {};\n");
66
+ await writeFile(join(forgeRoot, "dist", "index.js"), "export {};\n");
67
+ await utimes(join(forgeRoot, "src", "index.ts"), srcMtime, srcMtime);
68
+ await utimes(join(forgeRoot, "dist"), distMtime, distMtime);
69
+ }
70
+
71
+ test("dist-freshness warns when dist is older than newest src file", async () => {
72
+ await writeFile(join(tempDir, "forge.yaml"), FORGE_YAML, "utf8");
73
+ const old = new Date("2026-01-01T00:00:00Z");
74
+ const recent = new Date("2026-09-01T00:00:00Z");
75
+ await makeForgeCheckout(recent, old);
76
+
77
+ const input: ForgeCommandInput = { argv: [], flags: {} };
78
+ const result = await runDoctor(input, makeContext());
79
+
80
+ const check = result.data!.checks.find((c) => c.name === "dist-freshness");
81
+ expect(check).toBeDefined();
82
+ expect(check!.status).toBe("warn");
83
+ expect(check!.message).toContain("pnpm run build");
84
+ });
85
+
86
+ test("dist-freshness passes when dist is absent (npm consumer layout)", async () => {
87
+ await writeFile(join(tempDir, "forge.yaml"), FORGE_YAML, "utf8");
88
+ // No packages/forge at all — forgeRoot fallback dir doesn't exist
89
+ const input: ForgeCommandInput = { argv: [], flags: {} };
90
+ const result = await runDoctor(input, makeContext());
91
+
92
+ const check = result.data!.checks.find((c) => c.name === "dist-freshness");
93
+ expect(check).toBeDefined();
94
+ expect(check!.status).toBe("pass");
95
+ });
96
+
97
+ test("dist-freshness passes when dist is newer than src", async () => {
98
+ await writeFile(join(tempDir, "forge.yaml"), FORGE_YAML, "utf8");
99
+ const old = new Date("2026-01-01T00:00:00Z");
100
+ const recent = new Date("2026-09-01T00:00:00Z");
101
+ await makeForgeCheckout(old, recent);
102
+
103
+ const input: ForgeCommandInput = { argv: [], flags: {} };
104
+ const result = await runDoctor(input, makeContext());
105
+
106
+ const check = result.data!.checks.find((c) => c.name === "dist-freshness");
107
+ expect(check).toBeDefined();
108
+ expect(check!.status).toBe("pass");
109
+ expect(check!.message).toContain("fresh");
110
+ });
@@ -0,0 +1,142 @@
1
+ /*
2
+ <MODULE_CONTRACT>
3
+ <purpose>Unit tests for forge doctor --fix — safe remediations for warn/fail
4
+ checks: nested-AGENTS.md regeneration and memory-layer compaction (RFC-1151).</purpose>
5
+ </MODULE_CONTRACT>
6
+ <CHANGE_SUMMARY>
7
+ <item>RFC-1151: initial doctor --fix tests.</item>
8
+ </CHANGE_SUMMARY>
9
+ */
10
+
11
+ import { test, expect, beforeEach, afterEach } from "vitest";
12
+ import { mkdtemp, rm, mkdir, writeFile, readFile } from "node:fs/promises";
13
+ import { tmpdir } from "node:os";
14
+ import { join } from "node:path";
15
+ import { runDoctor } from "../onboarding/doctor.ts";
16
+ import type { ForgeCommandInput, ForgeRuntimeContext } from "../types.ts";
17
+
18
+ let tempDir: string;
19
+
20
+ beforeEach(async () => {
21
+ tempDir = await mkdtemp(join(tmpdir(), "doctor-fix-test-"));
22
+ });
23
+
24
+ afterEach(async () => {
25
+ await rm(tempDir, { recursive: true, force: true });
26
+ });
27
+
28
+ function makeContext(dryRun = false): ForgeRuntimeContext {
29
+ return {
30
+ workspaceRoot: tempDir,
31
+ logger: {
32
+ section: () => {},
33
+ success: () => {},
34
+ warn: () => {},
35
+ error: () => {},
36
+ info: () => {},
37
+ },
38
+ dryRun,
39
+ outputFormat: "json",
40
+ };
41
+ }
42
+
43
+ const FORGE_YAML = `schema: "forge/config@1"
44
+ project:
45
+ name: test-project
46
+ stack: []
47
+ packageManager: pnpm
48
+ paths:
49
+ rfcsDir: docs/rfcs
50
+ adrsDir: docs/adrs
51
+ plansDir: docs/plans
52
+ auditsDir: docs/audits
53
+ specsDir: docs/specs
54
+ skillsDir: .agents/skills
55
+ sessionsDir: docs/sessions
56
+ `;
57
+
58
+ const GENERATED_MARKER =
59
+ "<!--\n GENERATED. Do not change this line unless the file contains project specific changes.\n-->\n";
60
+
61
+ async function makeStaleWorkspace(): Promise<void> {
62
+ await mkdir(join(tempDir, "packages", "my-pkg"), { recursive: true });
63
+ await writeFile(
64
+ join(tempDir, "packages", "my-pkg", "package.json"),
65
+ JSON.stringify({ name: "@test/my-pkg" }),
66
+ );
67
+ // Generated marker + outdated content → stale
68
+ await writeFile(
69
+ join(tempDir, "packages", "my-pkg", "AGENTS.md"),
70
+ `${GENERATED_MARKER}# Old content\n`,
71
+ "utf8",
72
+ );
73
+ }
74
+
75
+ test("doctor --fix regenerates stale nested AGENTS.md and subsequent run passes", async () => {
76
+ await writeFile(join(tempDir, "forge.yaml"), FORGE_YAML, "utf8");
77
+ await makeStaleWorkspace();
78
+
79
+ const fixInput: ForgeCommandInput = { argv: [], flags: { fix: true } };
80
+ const fixResult = await runDoctor(fixInput, makeContext());
81
+
82
+ const fixEntry = fixResult.data!.fixes?.find((f) => f.check === "nested-AGENTS.md");
83
+ expect(fixEntry).toBeDefined();
84
+ expect(fixEntry!.action).toBe("fixed");
85
+
86
+ const regenerated = await readFile(join(tempDir, "packages", "my-pkg", "AGENTS.md"), "utf8");
87
+ expect(regenerated).toContain("`@test/my-pkg` — Agent Guide");
88
+ expect(regenerated).not.toContain("Old content");
89
+
90
+ // Subsequent doctor run: nested-AGENTS.md no longer reports this file stale
91
+ const verifyResult = await runDoctor({ argv: [], flags: {} }, makeContext());
92
+ const check = verifyResult.data!.checks.find((c) => c.name === "nested-AGENTS.md");
93
+ expect(check!.message).not.toContain("my-pkg/AGENTS.md stale");
94
+ });
95
+
96
+ test("doctor --fix does not modify hand-written nested AGENTS.md", async () => {
97
+ await writeFile(join(tempDir, "forge.yaml"), FORGE_YAML, "utf8");
98
+ await mkdir(join(tempDir, "packages", "my-pkg"), { recursive: true });
99
+ await writeFile(
100
+ join(tempDir, "packages", "my-pkg", "package.json"),
101
+ JSON.stringify({ name: "@test/my-pkg" }),
102
+ );
103
+ const handwritten = "# Custom\nNo marker.\n";
104
+ await writeFile(join(tempDir, "packages", "my-pkg", "AGENTS.md"), handwritten, "utf8");
105
+
106
+ const result = await runDoctor({ argv: [], flags: { fix: true } }, makeContext());
107
+ expect(result.data!.fixes).toBeDefined();
108
+
109
+ const after = await readFile(join(tempDir, "packages", "my-pkg", "AGENTS.md"), "utf8");
110
+ expect(after).toBe(handwritten);
111
+ });
112
+
113
+ test("doctor --fix compacts over-budget MEMORY.md", async () => {
114
+ await writeFile(join(tempDir, "forge.yaml"), FORGE_YAML, "utf8");
115
+ await mkdir(join(tempDir, ".agents", "memory"), { recursive: true });
116
+ const env = Array.from({ length: 30 }, (_, i) => `- env ${i} ${"x".repeat(200)}`).join("\n");
117
+ await writeFile(
118
+ join(tempDir, ".agents", "memory", "MEMORY.md"),
119
+ `# Project Memory\n\n## Current focus\n\n- keep\n\n## Environment notes\n\n${env}\n`,
120
+ "utf8",
121
+ );
122
+
123
+ const result = await runDoctor({ argv: [], flags: { fix: true } }, makeContext());
124
+ const fixEntry = result.data!.fixes?.find((f) => f.check === "memory-layer");
125
+ expect(fixEntry).toBeDefined();
126
+ expect(fixEntry!.action).toBe("fixed");
127
+
128
+ const after = await readFile(join(tempDir, ".agents", "memory", "MEMORY.md"), "utf8");
129
+ expect(after.length).toBeLessThanOrEqual(4096);
130
+ expect(after).toContain("- keep");
131
+ });
132
+
133
+ test("doctor without --fix produces no fixes array and does not mutate", async () => {
134
+ await writeFile(join(tempDir, "forge.yaml"), FORGE_YAML, "utf8");
135
+ await makeStaleWorkspace();
136
+
137
+ const result = await runDoctor({ argv: [], flags: {} }, makeContext());
138
+ expect(result.data!.fixes).toBeUndefined();
139
+
140
+ const after = await readFile(join(tempDir, "packages", "my-pkg", "AGENTS.md"), "utf8");
141
+ expect(after).toContain("Old content");
142
+ });