@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
@@ -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";
@@ -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
  });
@@ -10,7 +10,7 @@ routing table, conditional extended layer, markers, and idempotency (RFC-0548, R
10
10
  */
11
11
 
12
12
  import { test, expect, beforeEach, afterEach } from "vitest";
13
- import { mkdtemp, rm, writeFile, mkdir, readFile } from "node:fs/promises";
13
+ import { mkdtemp, rm, writeFile, mkdir, readFile, symlink } from "node:fs/promises";
14
14
  import { existsSync } from "node:fs";
15
15
  import { tmpdir } from "node:os";
16
16
  import { join } from "node:path";
@@ -102,11 +102,33 @@ 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
  });
109
110
 
111
+ test("agents-generate populates routing table rows in consumer layout (no packages/forge)", async () => {
112
+ await makeForgeYaml(tempDir);
113
+ // Consumer install: the package lives under node_modules — skills ship inside
114
+ // it. A symlinked node_modules/@warpgogol/forge mimics the npm layout.
115
+ const consumerPkg = join(tempDir, "node_modules", "@warpgogol", "forge");
116
+ await mkdir(join(consumerPkg, ".."), { recursive: true });
117
+ await symlink(FORGE_ROOT, consumerPkg, "junction");
118
+
119
+ // forgeRoot undefined → extraction must resolve via the consumer layout.
120
+ const result = await runAgentsGenerate(
121
+ { argv: [], flags: {} },
122
+ { ...makeContext(tempDir), forgeRoot: undefined },
123
+ );
124
+ expect(result.exitCode).toBe(0);
125
+
126
+ const agentsMd = await readFile(join(tempDir, "AGENTS.md"), "utf8");
127
+ // A quoted trigger phrase appears only in routing-table rows — the Skills
128
+ // table contains bare skill names, so this probes extraction end-to-end.
129
+ expect(agentsMd).toContain('"show RFC and ADR status"');
130
+ });
131
+
110
132
  test("agents-generate includes fixed policy text sections", async () => {
111
133
  await makeForgeYaml(tempDir);
112
134
  const result = await runAgentsGenerate({ argv: [], flags: {} }, makeContext(tempDir));
@@ -427,9 +449,10 @@ test("agents-generate nested renders entry points from exports map", async () =>
427
449
 
428
450
  const nested = await readFile(join(tempDir, "packages", "my-pkg", "AGENTS.md"), "utf8");
429
451
  expect(nested).toContain("## Entry points");
430
- expect(nested).toContain("| `@test/my-pkg` | `./src/index.ts` |");
431
- expect(nested).toContain("| `@test/my-pkg/port` | `./src/port.ts` |");
432
- expect(nested).toContain("| `@test/my-pkg/client` | `./src/client.ts` |");
452
+ // RFC-1154: cells are padded to column width — match via regex
453
+ expect(nested).toMatch(/\| `@test\/my-pkg` +\| `\.\/src\/index\.ts` +\|/);
454
+ expect(nested).toMatch(/\| `@test\/my-pkg\/port` +\| `\.\/src\/port\.ts` +\|/);
455
+ expect(nested).toMatch(/\| `@test\/my-pkg\/client` +\| `\.\/src\/client\.ts` +\|/);
433
456
  });
434
457
 
435
458
  test("agents-generate nested separates workspace and external dependencies", async () => {
@@ -0,0 +1,169 @@
1
+ /*
2
+ <MODULE_CONTRACT>
3
+ <purpose>Unit tests for src/cli-flags.ts — schema-driven argv-to-flags
4
+ resolution for the standalone forge CLI (strict KERNEL-FLAG-01/02/03 and
5
+ KERNEL-ARG-01 diagnostics, legacy heuristic path for schema-less commands).</purpose>
6
+ <non-goals>
7
+ <item>Do not test bin/cli.ts dispatch — these tests cover pure functions only.</item>
8
+ </non-goals>
9
+ </MODULE_CONTRACT>
10
+ <CHANGE_SUMMARY>
11
+ <item>Initial cli-flags resolution tests — covers the `forge rfc.validate --id` crash regression (value-less declared string flag must produce KERNEL-FLAG-02, not a boolean).</item>
12
+ </CHANGE_SUMMARY>
13
+ */
14
+
15
+ import { describe, expect, test } from "vitest";
16
+ import { parseCliArgs, resolveCliFlags } from "../cli-flags.ts";
17
+ import type { ForgeCommandDefinition, ForgeFlagSpec } from "../types.ts";
18
+
19
+ function command(flags?: Record<string, ForgeFlagSpec>): ForgeCommandDefinition {
20
+ return {
21
+ name: "test.command",
22
+ description: "test command",
23
+ scope: "workspace",
24
+ flags,
25
+ execute: () => {},
26
+ };
27
+ }
28
+
29
+ const errorRuleIds = (diagnostics: { ruleId: string; severity: string }[]) =>
30
+ diagnostics.filter((d) => d.severity === "error").map((d) => d.ruleId);
31
+
32
+ describe("resolveCliFlags — strict (schema-carrying) path", () => {
33
+ const rfcValidate = command({
34
+ id: { kind: "string", description: "Target a single RFC by id." },
35
+ });
36
+
37
+ test("value-less declared string flag errors with KERNEL-FLAG-02 instead of becoming `true`", () => {
38
+ const { flags, diagnostics } = resolveCliFlags(["--id"], rfcValidate);
39
+ expect(flags["id"]).toBeUndefined();
40
+ expect(errorRuleIds(diagnostics)).toEqual(["KERNEL-FLAG-02"]);
41
+ expect(diagnostics[0]!.message).toContain('Flag "--id"');
42
+ expect(diagnostics[0]!.message).toContain('"test.command"');
43
+ });
44
+
45
+ test("value-less declared string flag before another flag still errors", () => {
46
+ const { flags, diagnostics } = resolveCliFlags(["--id", "--json"], rfcValidate);
47
+ expect(flags["id"]).toBeUndefined();
48
+ expect(flags["json"]).toBe(true);
49
+ expect(errorRuleIds(diagnostics)).toEqual(["KERNEL-FLAG-02"]);
50
+ });
51
+
52
+ test("--id <value> and --id=<value> resolve to the string", () => {
53
+ for (const argv of [["--id", "RFC-0609"], ["--id=RFC-0609"]]) {
54
+ const { flags, diagnostics } = resolveCliFlags(argv, rfcValidate);
55
+ expect(flags["id"]).toBe("RFC-0609");
56
+ expect(errorRuleIds(diagnostics)).toEqual([]);
57
+ }
58
+ });
59
+
60
+ test("repeated single-value string flag errors instead of promoting to an array", () => {
61
+ const { flags, diagnostics } = resolveCliFlags(["--id", "RFC-1", "--id", "RFC-2"], rfcValidate);
62
+ expect(errorRuleIds(diagnostics)).toEqual(["KERNEL-FLAG-02"]);
63
+ expect(diagnostics[0]!.message).toContain("single value");
64
+ expect(flags["id"]).toEqual(["RFC-1", "RFC-2"]);
65
+ });
66
+
67
+ test("unknown flag errors with KERNEL-FLAG-01 listing valid flags", () => {
68
+ const { diagnostics } = resolveCliFlags(["--idd"], rfcValidate);
69
+ expect(errorRuleIds(diagnostics)).toEqual(["KERNEL-FLAG-01"]);
70
+ expect(diagnostics[0]!.message).toContain("id");
71
+ });
72
+
73
+ test("unknown flag followed by a bare token also flags the token as positional", () => {
74
+ const { diagnostics } = resolveCliFlags(["--idd", "RFC-1"], rfcValidate);
75
+ expect(errorRuleIds(diagnostics)).toEqual(["KERNEL-FLAG-01", "KERNEL-ARG-01"]);
76
+ });
77
+
78
+ test("required flag missing errors with KERNEL-FLAG-03", () => {
79
+ const cmd = command({
80
+ name: { kind: "string", required: true, description: "Required name." },
81
+ });
82
+ const { diagnostics } = resolveCliFlags([], cmd);
83
+ expect(errorRuleIds(diagnostics)).toEqual(["KERNEL-FLAG-03"]);
84
+ });
85
+
86
+ test("declared default applies when flag absent", () => {
87
+ const cmd = command({
88
+ mode: { kind: "string", default: "all", description: "Mode." },
89
+ });
90
+ const { flags, diagnostics } = resolveCliFlags([], cmd);
91
+ expect(flags["mode"]).toBe("all");
92
+ expect(errorRuleIds(diagnostics)).toEqual([]);
93
+ });
94
+
95
+ test("positional token errors with KERNEL-ARG-01", () => {
96
+ const { diagnostics } = resolveCliFlags(["RFC-0609"], rfcValidate);
97
+ expect(errorRuleIds(diagnostics)).toEqual(["KERNEL-ARG-01"]);
98
+ });
99
+
100
+ test("tokens after -- are positional errors", () => {
101
+ const { diagnostics } = resolveCliFlags(["--id", "RFC-1", "--", "extra"], rfcValidate);
102
+ expect(errorRuleIds(diagnostics)).toEqual(["KERNEL-ARG-01"]);
103
+ });
104
+
105
+ test("universal flags accepted on commands with empty schema", () => {
106
+ const { flags, diagnostics } = resolveCliFlags(
107
+ ["--json", "--dry-run", "--help", "--site", "x"],
108
+ command({}),
109
+ );
110
+ expect(flags["json"]).toBe(true);
111
+ expect(flags["dry-run"]).toBe(true);
112
+ expect(flags["help"]).toBe(true);
113
+ expect(flags["site"]).toBe("x");
114
+ expect(errorRuleIds(diagnostics)).toEqual([]);
115
+ });
116
+
117
+ test("universal boolean does not swallow the next flag's token", () => {
118
+ const cmd = command({ fix: { kind: "boolean", description: "Fix." } });
119
+ const { flags, diagnostics } = resolveCliFlags(["--json", "--fix"], cmd);
120
+ expect(flags["json"]).toBe(true);
121
+ expect(flags["fix"]).toBe(true);
122
+ expect(errorRuleIds(diagnostics)).toEqual([]);
123
+ });
124
+
125
+ test("--flag=false on a declared boolean resolves to false", () => {
126
+ const cmd = command({ fix: { kind: "boolean", description: "Fix." } });
127
+ const { flags, diagnostics } = resolveCliFlags(["--fix=false"], cmd);
128
+ expect(flags["fix"]).toBe(false);
129
+ expect(errorRuleIds(diagnostics)).toEqual([]);
130
+ });
131
+
132
+ test("string[] flag collects repeated values", () => {
133
+ const cmd = command({
134
+ files: { kind: "string[]", description: "Files." },
135
+ });
136
+ const { flags, diagnostics } = resolveCliFlags(["--files", "a", "--files", "b"], cmd);
137
+ expect(flags["files"]).toEqual(["a", "b"]);
138
+ expect(errorRuleIds(diagnostics)).toEqual([]);
139
+ });
140
+ });
141
+
142
+ describe("resolveCliFlags — legacy (schema-less) path", () => {
143
+ const schemaLess = command(undefined);
144
+
145
+ test("unknown flags still parse heuristically", () => {
146
+ const { flags, diagnostics } = resolveCliFlags(["--anything", "v"], schemaLess);
147
+ expect(flags["anything"]).toBe("v");
148
+ expect(errorRuleIds(diagnostics)).toEqual([]);
149
+ });
150
+
151
+ test("known boolean switches do not consume the next token", () => {
152
+ const { flags } = resolveCliFlags(["--json", "v"], schemaLess);
153
+ expect(flags["json"]).toBe(true);
154
+ });
155
+
156
+ test("positional token errors with KERNEL-ARG-01", () => {
157
+ const { diagnostics } = resolveCliFlags(["positional"], schemaLess);
158
+ expect(errorRuleIds(diagnostics)).toEqual(["KERNEL-ARG-01"]);
159
+ });
160
+ });
161
+
162
+ describe("parseCliArgs", () => {
163
+ test("--key=value and --key value forms both resolve", () => {
164
+ const { flags } = parseCliArgs(["--a=1", "--b", "2", "--json"]);
165
+ expect(flags["a"]).toBe("1");
166
+ expect(flags["b"]).toBe("2");
167
+ expect(flags["json"]).toBe(true);
168
+ });
169
+ });
@@ -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 = {
@@ -83,10 +83,7 @@ test("doctor --fix regenerates stale nested AGENTS.md and subsequent run passes"
83
83
  expect(fixEntry).toBeDefined();
84
84
  expect(fixEntry!.action).toBe("fixed");
85
85
 
86
- const regenerated = await readFile(
87
- join(tempDir, "packages", "my-pkg", "AGENTS.md"),
88
- "utf8",
89
- );
86
+ const regenerated = await readFile(join(tempDir, "packages", "my-pkg", "AGENTS.md"), "utf8");
90
87
  expect(regenerated).toContain("`@test/my-pkg` — Agent Guide");
91
88
  expect(regenerated).not.toContain("Old content");
92
89
 
@@ -9,10 +9,13 @@ workspace discovery exclusions via bindings.workspaces.skipDirs (RFC-1150).</pur
9
9
  */
10
10
 
11
11
  import { test, expect, beforeEach, afterEach } from "vitest";
12
- import { mkdtemp, rm, mkdir, writeFile } from "node:fs/promises";
12
+ import { mkdtemp, rm, mkdir, writeFile, appendFile } from "node:fs/promises";
13
13
  import { tmpdir } from "node:os";
14
14
  import { join } from "node:path";
15
15
  import { runDoctor } from "../onboarding/doctor.ts";
16
+ import { generateNestedAgentsMd } from "../onboarding/nested-agents-generate.ts";
17
+ import { buildGeneratedHeader } from "../utils/index.ts";
18
+ import { loadForgeConfig } from "../config/forge-config.ts";
16
19
  import type { ForgeCommandInput, ForgeRuntimeContext } from "../types.ts";
17
20
 
18
21
  let tempDir: string;
@@ -106,3 +109,52 @@ test("nested-AGENTS.md check reports artifact dir as missing without skipDirs",
106
109
  expect(check).toBeDefined();
107
110
  expect(check!.message).toContain("builds");
108
111
  });
112
+
113
+ // RFC-1153: boundary-aware staleness -----------------------------------------
114
+
115
+ test("AC-8: custom content below the forge:custom boundary reports in-sync, not stale", async () => {
116
+ await writeFile(join(tempDir, "forge.yaml"), forgeYaml([]), "utf8");
117
+ await mkdir(join(tempDir, "packages", "pkg"), { recursive: true });
118
+ await writeFile(join(tempDir, "packages", "pkg", "package.json"), '{"name":"pkg"}', "utf8");
119
+
120
+ const config = loadForgeConfig(tempDir);
121
+ await generateNestedAgentsMd(tempDir, config, false);
122
+
123
+ // Operator appends a custom section below the marker
124
+ await appendFile(
125
+ join(tempDir, "packages", "pkg", "AGENTS.md"),
126
+ "\n## Custom rules\n\n- workspace-specific note\n",
127
+ "utf8",
128
+ );
129
+
130
+ const input: ForgeCommandInput = { argv: [], flags: {} };
131
+ const result = await runDoctor(input, makeContext());
132
+
133
+ const check = result.data!.checks.find((c) => c.name === "nested-AGENTS.md");
134
+ expect(check).toBeDefined();
135
+ expect(
136
+ check!.message,
137
+ "Below-boundary divergence must not count as stale — merge(expected, actual) compares only the head",
138
+ ).not.toContain("stale");
139
+ });
140
+
141
+ test("AC-6: divergent file without a resolvable boundary reports unmapped-customization", async () => {
142
+ await writeFile(join(tempDir, "forge.yaml"), forgeYaml([]), "utf8");
143
+ await mkdir(join(tempDir, "packages", "legacy"), { recursive: true });
144
+ await writeFile(join(tempDir, "packages", "legacy", "package.json"), '{"name":"legacy"}', "utf8");
145
+ // Marker-bearing (isGenerated) file that diverges and lacks footer/forge:custom
146
+ await writeFile(
147
+ join(tempDir, "packages", "legacy", "AGENTS.md"),
148
+ `${buildGeneratedHeader({ filePath: "AGENTS.md", ownerCommand: "forge.agents.generate", editable: true })}\n# Hand-maintained\n\ndivergent body\n`,
149
+ "utf8",
150
+ );
151
+
152
+ const input: ForgeCommandInput = { argv: [], flags: {} };
153
+ const result = await runDoctor(input, makeContext());
154
+
155
+ const check = result.data!.checks.find((c) => c.name === "nested-AGENTS.md");
156
+ expect(check).toBeDefined();
157
+ expect(check!.status).toBe("warn");
158
+ expect(check!.message).toContain("unmapped-customization");
159
+ expect(check!.message).not.toContain("stale");
160
+ });