@warpgogol/forge 5.2.4 → 5.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (568) hide show
  1. package/AGENTS.md +32 -2
  2. package/README.md +1 -1
  3. package/README.uk.md +8 -8
  4. package/bin/cli.ts +1 -0
  5. package/dist/bin/cli.js +1 -0
  6. package/dist/bin/cli.js.map +1 -1
  7. package/dist/os/adr/adr.module.d.ts.map +1 -1
  8. package/dist/os/adr/adr.module.js +8 -3
  9. package/dist/os/adr/adr.module.js.map +1 -1
  10. package/dist/os/adr/frontmatter-io.js +5 -5
  11. package/dist/os/adr/frontmatter-io.js.map +1 -1
  12. package/dist/os/adr/handlers/archive.d.ts.map +1 -1
  13. package/dist/os/adr/handlers/archive.js +10 -4
  14. package/dist/os/adr/handlers/archive.js.map +1 -1
  15. package/dist/os/adr/handlers/implement-stamp.d.ts.map +1 -1
  16. package/dist/os/adr/handlers/implement-stamp.js +10 -9
  17. package/dist/os/adr/handlers/implement-stamp.js.map +1 -1
  18. package/dist/os/adr/handlers/list-create.js +5 -5
  19. package/dist/os/adr/handlers/list-create.js.map +1 -1
  20. package/dist/os/adr/handlers/validate.js +1 -1
  21. package/dist/os/adr/handlers/validate.js.map +1 -1
  22. package/dist/os/audit/audit.module.js +3 -3
  23. package/dist/os/audit/audit.module.js.map +1 -1
  24. package/dist/os/audit/frontmatter-io.js +5 -5
  25. package/dist/os/audit/frontmatter-io.js.map +1 -1
  26. package/dist/os/audit/handlers/archive.d.ts.map +1 -1
  27. package/dist/os/audit/handlers/archive.js +10 -4
  28. package/dist/os/audit/handlers/archive.js.map +1 -1
  29. package/dist/os/compass/compass.module.d.ts.map +1 -1
  30. package/dist/os/compass/compass.module.js +17 -1
  31. package/dist/os/compass/compass.module.js.map +1 -1
  32. package/dist/os/compass/handlers/compass-audit-handler.d.ts.map +1 -1
  33. package/dist/os/compass/handlers/compass-audit-handler.js +12 -5
  34. package/dist/os/compass/handlers/compass-audit-handler.js.map +1 -1
  35. package/dist/os/compass/handlers/compass-change-summary-handler.d.ts.map +1 -1
  36. package/dist/os/compass/handlers/compass-change-summary-handler.js +3 -2
  37. package/dist/os/compass/handlers/compass-change-summary-handler.js.map +1 -1
  38. package/dist/os/compass/handlers/compass-inventory-handler.d.ts.map +1 -1
  39. package/dist/os/compass/handlers/compass-inventory-handler.js +6 -4
  40. package/dist/os/compass/handlers/compass-inventory-handler.js.map +1 -1
  41. package/dist/os/compass/handlers/compass-inventory.d.ts.map +1 -1
  42. package/dist/os/compass/handlers/compass-inventory.js +10 -8
  43. package/dist/os/compass/handlers/compass-inventory.js.map +1 -1
  44. package/dist/os/compass/handlers/compass-migrate-handler.js +1 -1
  45. package/dist/os/compass/handlers/compass-migrate-handler.js.map +1 -1
  46. package/dist/os/compass/handlers/compass-migrate.d.ts.map +1 -1
  47. package/dist/os/compass/handlers/compass-migrate.js +6 -3
  48. package/dist/os/compass/handlers/compass-migrate.js.map +1 -1
  49. package/dist/os/compass/handlers/git-revision.d.ts.map +1 -1
  50. package/dist/os/compass/handlers/git-revision.js +9 -6
  51. package/dist/os/compass/handlers/git-revision.js.map +1 -1
  52. package/dist/os/compass/handlers/resolve-scan-root.js +1 -1
  53. package/dist/os/compass/handlers/resolve-scan-root.js.map +1 -1
  54. package/dist/os/compass/handlers/summary-record.d.ts.map +1 -1
  55. package/dist/os/compass/handlers/summary-record.js +8 -4
  56. package/dist/os/compass/handlers/summary-record.js.map +1 -1
  57. package/dist/os/core/core.module.d.ts.map +1 -1
  58. package/dist/os/core/core.module.js +43 -4
  59. package/dist/os/core/core.module.js.map +1 -1
  60. package/dist/os/core/handlers/assets-helpers.d.ts.map +1 -1
  61. package/dist/os/core/handlers/assets-helpers.js +6 -3
  62. package/dist/os/core/handlers/assets-helpers.js.map +1 -1
  63. package/dist/os/core/handlers/build.js +1 -1
  64. package/dist/os/core/handlers/build.js.map +1 -1
  65. package/dist/os/core/handlers/determinism-check.d.ts.map +1 -1
  66. package/dist/os/core/handlers/determinism-check.js +10 -6
  67. package/dist/os/core/handlers/determinism-check.js.map +1 -1
  68. package/dist/os/core/handlers/dev.js +1 -1
  69. package/dist/os/core/handlers/dev.js.map +1 -1
  70. package/dist/os/core/handlers/file-size-lint.d.ts.map +1 -1
  71. package/dist/os/core/handlers/file-size-lint.js +11 -7
  72. package/dist/os/core/handlers/file-size-lint.js.map +1 -1
  73. package/dist/os/core/handlers/forge-autonomy-validate.d.ts.map +1 -1
  74. package/dist/os/core/handlers/forge-autonomy-validate.js +9 -5
  75. package/dist/os/core/handlers/forge-autonomy-validate.js.map +1 -1
  76. package/dist/os/core/handlers/knowledge-compact.js +1 -1
  77. package/dist/os/core/handlers/knowledge-compact.js.map +1 -1
  78. package/dist/os/core/handlers/package-health.js +1 -1
  79. package/dist/os/core/handlers/package-health.js.map +1 -1
  80. package/dist/os/core/handlers/pinned-check.js +2 -2
  81. package/dist/os/core/handlers/pinned-check.js.map +1 -1
  82. package/dist/os/core/handlers/pinned-init.d.ts.map +1 -1
  83. package/dist/os/core/handlers/pinned-init.js +9 -8
  84. package/dist/os/core/handlers/pinned-init.js.map +1 -1
  85. package/dist/os/core/handlers/pinned-validate.js +3 -3
  86. package/dist/os/core/handlers/pinned-validate.js.map +1 -1
  87. package/dist/os/core/handlers/profile-resolve.js +1 -1
  88. package/dist/os/core/handlers/profile-resolve.js.map +1 -1
  89. package/dist/os/core/handlers/public-surface.js +1 -1
  90. package/dist/os/core/handlers/public-surface.js.map +1 -1
  91. package/dist/os/core/handlers/release-prepare.d.ts.map +1 -1
  92. package/dist/os/core/handlers/release-prepare.js +10 -6
  93. package/dist/os/core/handlers/release-prepare.js.map +1 -1
  94. package/dist/os/core/handlers/release-publish.js +6 -6
  95. package/dist/os/core/handlers/release-publish.js.map +1 -1
  96. package/dist/os/core/handlers/validate.js +1 -1
  97. package/dist/os/core/handlers/validate.js.map +1 -1
  98. package/dist/os/exploration/exploration.module.d.ts.map +1 -1
  99. package/dist/os/exploration/exploration.module.js +1 -0
  100. package/dist/os/exploration/exploration.module.js.map +1 -1
  101. package/dist/os/exploration/frontmatter-io.js +4 -4
  102. package/dist/os/exploration/frontmatter-io.js.map +1 -1
  103. package/dist/os/exploration/handlers/archive.js +3 -3
  104. package/dist/os/exploration/handlers/archive.js.map +1 -1
  105. package/dist/os/mission/handlers/archive.d.ts.map +1 -1
  106. package/dist/os/mission/handlers/archive.js +22 -19
  107. package/dist/os/mission/handlers/archive.js.map +1 -1
  108. package/dist/os/mission/mission.module.js +3 -3
  109. package/dist/os/mission/mission.module.js.map +1 -1
  110. package/dist/os/naming/naming-convention.d.ts.map +1 -1
  111. package/dist/os/naming/naming-convention.js +7 -3
  112. package/dist/os/naming/naming-convention.js.map +1 -1
  113. package/dist/os/naming/naming.module.d.ts.map +1 -1
  114. package/dist/os/naming/naming.module.js +4 -3
  115. package/dist/os/naming/naming.module.js.map +1 -1
  116. package/dist/os/notes/notes.module.d.ts.map +1 -1
  117. package/dist/os/notes/notes.module.js +6 -3
  118. package/dist/os/notes/notes.module.js.map +1 -1
  119. package/dist/os/plan/frontmatter-io.js +5 -5
  120. package/dist/os/plan/frontmatter-io.js.map +1 -1
  121. package/dist/os/plan/handlers/archive.d.ts.map +1 -1
  122. package/dist/os/plan/handlers/archive.js +10 -4
  123. package/dist/os/plan/handlers/archive.js.map +1 -1
  124. package/dist/os/plan/plan.module.js +3 -3
  125. package/dist/os/plan/plan.module.js.map +1 -1
  126. package/dist/os/plugin/plugin.module.d.ts.map +1 -1
  127. package/dist/os/plugin/plugin.module.js +6 -3
  128. package/dist/os/plugin/plugin.module.js.map +1 -1
  129. package/dist/os/program/discovery.js +2 -2
  130. package/dist/os/program/discovery.js.map +1 -1
  131. package/dist/os/program/handlers/complete.js +1 -1
  132. package/dist/os/program/handlers/complete.js.map +1 -1
  133. package/dist/os/program/handlers/lease.js +1 -1
  134. package/dist/os/program/handlers/lease.js.map +1 -1
  135. package/dist/os/program/handlers/seal.js +1 -1
  136. package/dist/os/program/handlers/seal.js.map +1 -1
  137. package/dist/os/program/lease.js +1 -1
  138. package/dist/os/program/lease.js.map +1 -1
  139. package/dist/os/program/program.module.d.ts.map +1 -1
  140. package/dist/os/program/program.module.js +9 -3
  141. package/dist/os/program/program.module.js.map +1 -1
  142. package/dist/os/queue/index.js +1 -1
  143. package/dist/os/queue/manifest.d.ts.map +1 -1
  144. package/dist/os/queue/manifest.js +4 -8
  145. package/dist/os/queue/manifest.js.map +1 -1
  146. package/dist/os/rfc/acceptance.d.ts.map +1 -1
  147. package/dist/os/rfc/acceptance.js +10 -6
  148. package/dist/os/rfc/acceptance.js.map +1 -1
  149. package/dist/os/rfc/decision-log.d.ts.map +1 -1
  150. package/dist/os/rfc/decision-log.js +4 -3
  151. package/dist/os/rfc/decision-log.js.map +1 -1
  152. package/dist/os/rfc/dna-trace.d.ts.map +1 -1
  153. package/dist/os/rfc/dna-trace.js +7 -2
  154. package/dist/os/rfc/dna-trace.js.map +1 -1
  155. package/dist/os/rfc/frontmatter-io.js +5 -5
  156. package/dist/os/rfc/frontmatter-io.js.map +1 -1
  157. package/dist/os/rfc/handlers/archive.d.ts.map +1 -1
  158. package/dist/os/rfc/handlers/archive.js +11 -5
  159. package/dist/os/rfc/handlers/archive.js.map +1 -1
  160. package/dist/os/rfc/handlers/check.d.ts.map +1 -1
  161. package/dist/os/rfc/handlers/check.js +6 -3
  162. package/dist/os/rfc/handlers/check.js.map +1 -1
  163. package/dist/os/rfc/handlers/implement-stamp.d.ts.map +1 -1
  164. package/dist/os/rfc/handlers/implement-stamp.js +11 -10
  165. package/dist/os/rfc/handlers/implement-stamp.js.map +1 -1
  166. package/dist/os/rfc/handlers/index-graph.js +3 -3
  167. package/dist/os/rfc/handlers/index-graph.js.map +1 -1
  168. package/dist/os/rfc/handlers/lifecycle.d.ts.map +1 -1
  169. package/dist/os/rfc/handlers/lifecycle.js +6 -2
  170. package/dist/os/rfc/handlers/lifecycle.js.map +1 -1
  171. package/dist/os/rfc/handlers/list-create.d.ts.map +1 -1
  172. package/dist/os/rfc/handlers/list-create.js +7 -6
  173. package/dist/os/rfc/handlers/list-create.js.map +1 -1
  174. package/dist/os/rfc/handlers/shared.js +3 -3
  175. package/dist/os/rfc/handlers/shared.js.map +1 -1
  176. package/dist/os/rfc/handlers/supersede-propose.d.ts.map +1 -1
  177. package/dist/os/rfc/handlers/supersede-propose.js +7 -3
  178. package/dist/os/rfc/handlers/supersede-propose.js.map +1 -1
  179. package/dist/os/rfc/handlers/validate-rules.d.ts.map +1 -1
  180. package/dist/os/rfc/handlers/validate-rules.js +8 -5
  181. package/dist/os/rfc/handlers/validate-rules.js.map +1 -1
  182. package/dist/os/rfc/rfc.module.d.ts.map +1 -1
  183. package/dist/os/rfc/rfc.module.js +44 -4
  184. package/dist/os/rfc/rfc.module.js.map +1 -1
  185. package/dist/os/rfc/verification-evidence.d.ts.map +1 -1
  186. package/dist/os/rfc/verification-evidence.js +9 -5
  187. package/dist/os/rfc/verification-evidence.js.map +1 -1
  188. package/dist/os/rfc/verification-refresh.d.ts.map +1 -1
  189. package/dist/os/rfc/verification-refresh.js +4 -3
  190. package/dist/os/rfc/verification-refresh.js.map +1 -1
  191. package/dist/os/session/frontmatter-io.js +12 -12
  192. package/dist/os/session/frontmatter-io.js.map +1 -1
  193. package/dist/os/session/handlers/archive.d.ts.map +1 -1
  194. package/dist/os/session/handlers/archive.js +10 -4
  195. package/dist/os/session/handlers/archive.js.map +1 -1
  196. package/dist/os/session/handlers/metrics-aggregate.d.ts.map +1 -1
  197. package/dist/os/session/handlers/metrics-aggregate.js +9 -5
  198. package/dist/os/session/handlers/metrics-aggregate.js.map +1 -1
  199. package/dist/os/session/handlers/metrics-rfc.d.ts.map +1 -1
  200. package/dist/os/session/handlers/metrics-rfc.js +11 -8
  201. package/dist/os/session/handlers/metrics-rfc.js.map +1 -1
  202. package/dist/os/session/handlers/metrics-session.d.ts.map +1 -1
  203. package/dist/os/session/handlers/metrics-session.js +6 -3
  204. package/dist/os/session/handlers/metrics-session.js.map +1 -1
  205. package/dist/os/session/handlers/save.d.ts.map +1 -1
  206. package/dist/os/session/handlers/save.js +14 -8
  207. package/dist/os/session/handlers/save.js.map +1 -1
  208. package/dist/os/session/session.module.d.ts.map +1 -1
  209. package/dist/os/session/session.module.js +6 -0
  210. package/dist/os/session/session.module.js.map +1 -1
  211. package/dist/os/spec/live-spec-list.js +4 -4
  212. package/dist/os/spec/live-spec-list.js.map +1 -1
  213. package/dist/os/spec/live-spec-merge.js +5 -5
  214. package/dist/os/spec/live-spec-merge.js.map +1 -1
  215. package/dist/os/spec/live-spec-show.js +3 -3
  216. package/dist/os/spec/live-spec-show.js.map +1 -1
  217. package/dist/os/spec/live-spec-validate.js +4 -4
  218. package/dist/os/spec/live-spec-validate.js.map +1 -1
  219. package/dist/os/spec/spec-materialize.js +9 -9
  220. package/dist/os/spec/spec-materialize.js.map +1 -1
  221. package/dist/os/spec/spec-status.js +9 -9
  222. package/dist/os/spec/spec-status.js.map +1 -1
  223. package/dist/os/spec/spec-validate.js +7 -7
  224. package/dist/os/spec/spec-validate.js.map +1 -1
  225. package/dist/os/spec/spec.module.d.ts.map +1 -1
  226. package/dist/os/spec/spec.module.js +8 -0
  227. package/dist/os/spec/spec.module.js.map +1 -1
  228. package/dist/os/werkstatt/handlers/lock.js +16 -16
  229. package/dist/os/werkstatt/handlers/lock.js.map +1 -1
  230. package/dist/os/werkstatt/handlers/werkstatt-lock-recover.js +3 -3
  231. package/dist/os/werkstatt/handlers/werkstatt-lock-recover.js.map +1 -1
  232. package/dist/os/werkstatt/handlers/werkstatt-operation-validate.d.ts.map +1 -1
  233. package/dist/os/werkstatt/handlers/werkstatt-operation-validate.js +3 -2
  234. package/dist/os/werkstatt/handlers/werkstatt-operation-validate.js.map +1 -1
  235. package/dist/os/werkstatt/werkstatt.module.d.ts.map +1 -1
  236. package/dist/os/werkstatt/werkstatt.module.js +6 -2
  237. package/dist/os/werkstatt/werkstatt.module.js.map +1 -1
  238. package/dist/os/workflow/handlers.d.ts.map +1 -1
  239. package/dist/os/workflow/handlers.js +8 -5
  240. package/dist/os/workflow/handlers.js.map +1 -1
  241. package/dist/os/workflow/workflow.module.d.ts.map +1 -1
  242. package/dist/os/workflow/workflow.module.js +6 -3
  243. package/dist/os/workflow/workflow.module.js.map +1 -1
  244. package/dist/src/compass/contract-registry.js +1 -1
  245. package/dist/src/compass/contract-registry.js.map +1 -1
  246. package/dist/src/config/forge-config.d.ts +1 -1
  247. package/dist/src/config/forge-config.js +1 -1
  248. package/dist/src/config/forge-config.js.map +1 -1
  249. package/dist/src/knowledge/budgets.js +1 -1
  250. package/dist/src/knowledge/budgets.js.map +1 -1
  251. package/dist/src/knowledge/compact.js +1 -1
  252. package/dist/src/knowledge/compact.js.map +1 -1
  253. package/dist/src/knowledge/parse.js +1 -1
  254. package/dist/src/knowledge/parse.js.map +1 -1
  255. package/dist/src/knowledge/sync.d.ts.map +1 -1
  256. package/dist/src/knowledge/sync.js +3 -5
  257. package/dist/src/knowledge/sync.js.map +1 -1
  258. package/dist/src/migration-adapters/git-utils.js +2 -2
  259. package/dist/src/migration-adapters/git-utils.js.map +1 -1
  260. package/dist/src/migration-adapters/ignored-files.js +2 -2
  261. package/dist/src/migration-adapters/ignored-files.js.map +1 -1
  262. package/dist/src/migration-adapters/node-typescript-pnpm/index.js +1 -1
  263. package/dist/src/migration-adapters/node-typescript-pnpm/index.js.map +1 -1
  264. package/dist/src/migration-adapters/phaser-pnpm/index.js +1 -1
  265. package/dist/src/migration-adapters/phaser-pnpm/index.js.map +1 -1
  266. package/dist/src/onboarding/agents-generate.d.ts.map +1 -1
  267. package/dist/src/onboarding/agents-generate.js +60 -31
  268. package/dist/src/onboarding/agents-generate.js.map +1 -1
  269. package/dist/src/onboarding/create.d.ts.map +1 -1
  270. package/dist/src/onboarding/create.js +10 -10
  271. package/dist/src/onboarding/create.js.map +1 -1
  272. package/dist/src/onboarding/doctor.d.ts.map +1 -1
  273. package/dist/src/onboarding/doctor.js +68 -59
  274. package/dist/src/onboarding/doctor.js.map +1 -1
  275. package/dist/src/onboarding/init.d.ts.map +1 -1
  276. package/dist/src/onboarding/init.js +30 -1
  277. package/dist/src/onboarding/init.js.map +1 -1
  278. package/dist/src/onboarding/invariant-engine.js +1 -1
  279. package/dist/src/onboarding/invariant-engine.js.map +1 -1
  280. package/dist/src/onboarding/memory-compact.d.ts.map +1 -1
  281. package/dist/src/onboarding/memory-compact.js +5 -4
  282. package/dist/src/onboarding/memory-compact.js.map +1 -1
  283. package/dist/src/onboarding/memory-scaffold.js +1 -1
  284. package/dist/src/onboarding/memory-scaffold.js.map +1 -1
  285. package/dist/src/onboarding/nested-agents-generate.d.ts +4 -1
  286. package/dist/src/onboarding/nested-agents-generate.d.ts.map +1 -1
  287. package/dist/src/onboarding/nested-agents-generate.js +34 -5
  288. package/dist/src/onboarding/nested-agents-generate.js.map +1 -1
  289. package/dist/src/onboarding/nested-agents-templates.d.ts.map +1 -1
  290. package/dist/src/onboarding/nested-agents-templates.js +8 -12
  291. package/dist/src/onboarding/nested-agents-templates.js.map +1 -1
  292. package/dist/src/onboarding/npm-token-check.js +2 -2
  293. package/dist/src/onboarding/npm-token-check.js.map +1 -1
  294. package/dist/src/onboarding/prettierignore.d.ts +29 -0
  295. package/dist/src/onboarding/prettierignore.d.ts.map +1 -0
  296. package/dist/src/onboarding/prettierignore.js +231 -0
  297. package/dist/src/onboarding/prettierignore.js.map +1 -0
  298. package/dist/src/onboarding/profile-validate.d.ts.map +1 -1
  299. package/dist/src/onboarding/profile-validate.js +5 -4
  300. package/dist/src/onboarding/profile-validate.js.map +1 -1
  301. package/dist/src/onboarding/scaffold-project.d.ts.map +1 -1
  302. package/dist/src/onboarding/scaffold-project.js +35 -27
  303. package/dist/src/onboarding/scaffold-project.js.map +1 -1
  304. package/dist/src/onboarding/scaffold.js +1 -1
  305. package/dist/src/onboarding/scaffold.js.map +1 -1
  306. package/dist/src/onboarding/skill-markers.d.ts +27 -0
  307. package/dist/src/onboarding/skill-markers.d.ts.map +1 -0
  308. package/dist/src/onboarding/skill-markers.js +131 -0
  309. package/dist/src/onboarding/skill-markers.js.map +1 -0
  310. package/dist/src/onboarding/upgrade.d.ts +10 -0
  311. package/dist/src/onboarding/upgrade.d.ts.map +1 -1
  312. package/dist/src/onboarding/upgrade.js +215 -74
  313. package/dist/src/onboarding/upgrade.js.map +1 -1
  314. package/dist/src/onboarding/workspace-discovery.js +1 -1
  315. package/dist/src/onboarding/workspace-discovery.js.map +1 -1
  316. package/dist/src/pipeline-status.d.ts +6 -5
  317. package/dist/src/pipeline-status.d.ts.map +1 -1
  318. package/dist/src/pipeline-status.js +24 -19
  319. package/dist/src/pipeline-status.js.map +1 -1
  320. package/dist/src/profiles/stack-profile.js +1 -1
  321. package/dist/src/profiles/stack-profile.js.map +1 -1
  322. package/dist/src/registry.d.ts +1 -1
  323. package/dist/src/registry.d.ts.map +1 -1
  324. package/dist/src/registry.js +3 -3
  325. package/dist/src/registry.js.map +1 -1
  326. package/dist/src/skill-schema.d.ts +1 -1
  327. package/dist/src/skill-schema.d.ts.map +1 -1
  328. package/dist/src/skill-schema.js +4 -1
  329. package/dist/src/skill-schema.js.map +1 -1
  330. package/dist/src/types.d.ts +116 -0
  331. package/dist/src/types.d.ts.map +1 -1
  332. package/dist/src/utils/editable-region.d.ts +46 -0
  333. package/dist/src/utils/editable-region.d.ts.map +1 -0
  334. package/dist/src/utils/editable-region.js +125 -0
  335. package/dist/src/utils/editable-region.js.map +1 -0
  336. package/dist/src/utils/fs-idempotent.d.ts +2 -1
  337. package/dist/src/utils/fs-idempotent.d.ts.map +1 -1
  338. package/dist/src/utils/fs-idempotent.js +11 -7
  339. package/dist/src/utils/fs-idempotent.js.map +1 -1
  340. package/dist/src/utils/generated-marker.d.ts +17 -0
  341. package/dist/src/utils/generated-marker.d.ts.map +1 -1
  342. package/dist/src/utils/generated-marker.js +29 -1
  343. package/dist/src/utils/generated-marker.js.map +1 -1
  344. package/dist/src/utils/index.d.ts +3 -1
  345. package/dist/src/utils/index.d.ts.map +1 -1
  346. package/dist/src/utils/index.js +3 -1
  347. package/dist/src/utils/index.js.map +1 -1
  348. package/dist/src/utils/io.d.ts +9 -0
  349. package/dist/src/utils/io.d.ts.map +1 -0
  350. package/dist/src/utils/io.js +130 -0
  351. package/dist/src/utils/io.js.map +1 -0
  352. package/dist/src/utils/markdown-table.d.ts +21 -0
  353. package/dist/src/utils/markdown-table.d.ts.map +1 -0
  354. package/dist/src/utils/markdown-table.js +116 -0
  355. package/dist/src/utils/markdown-table.js.map +1 -0
  356. package/dist/src/utils/sync-fs.d.ts +5 -0
  357. package/dist/src/utils/sync-fs.d.ts.map +1 -0
  358. package/dist/src/utils/sync-fs.js +26 -0
  359. package/dist/src/utils/sync-fs.js.map +1 -0
  360. package/dist/src/validators/note-frontmatter-validate.js +1 -1
  361. package/dist/src/validators/note-frontmatter-validate.js.map +1 -1
  362. package/dist/src/validators/note-link-validate.js +1 -1
  363. package/dist/src/validators/note-link-validate.js.map +1 -1
  364. package/dist/src/validators/note-orphan-detect.js +1 -1
  365. package/dist/src/validators/note-orphan-detect.js.map +1 -1
  366. package/dist/src/validators/port-validate.js +1 -1
  367. package/dist/src/validators/port-validate.js.map +1 -1
  368. package/dist/src/validators/skill-validate.d.ts.map +1 -1
  369. package/dist/src/validators/skill-validate.js +34 -13
  370. package/dist/src/validators/skill-validate.js.map +1 -1
  371. package/os/adr/adr.module.ts +136 -132
  372. package/os/adr/frontmatter-io.ts +5 -5
  373. package/os/adr/handlers/archive.ts +8 -4
  374. package/os/adr/handlers/implement-stamp.ts +14 -9
  375. package/os/adr/handlers/list-create.ts +5 -5
  376. package/os/adr/handlers/validate.ts +1 -1
  377. package/os/audit/audit.module.ts +33 -34
  378. package/os/audit/frontmatter-io.ts +5 -5
  379. package/os/audit/handlers/archive.ts +8 -4
  380. package/os/compass/compass.module.ts +17 -1
  381. package/os/compass/handlers/compass-audit-handler.ts +13 -5
  382. package/os/compass/handlers/compass-change-summary-handler.ts +4 -2
  383. package/os/compass/handlers/compass-inventory-handler.ts +7 -4
  384. package/os/compass/handlers/compass-inventory.ts +11 -8
  385. package/os/compass/handlers/compass-migrate-handler.ts +1 -1
  386. package/os/compass/handlers/compass-migrate.ts +7 -3
  387. package/os/compass/handlers/git-revision.ts +11 -6
  388. package/os/compass/handlers/resolve-scan-root.ts +1 -1
  389. package/os/compass/handlers/summary-record.ts +10 -4
  390. package/os/compass/handlers/tests/compass-audit-plan.test.ts +2 -1
  391. package/os/core/core.module.ts +43 -4
  392. package/os/core/handlers/assets-helpers.ts +7 -3
  393. package/os/core/handlers/build.ts +1 -1
  394. package/os/core/handlers/determinism-check.ts +12 -6
  395. package/os/core/handlers/dev.ts +1 -1
  396. package/os/core/handlers/file-size-lint.ts +16 -9
  397. package/os/core/handlers/forge-autonomy-validate.ts +10 -5
  398. package/os/core/handlers/knowledge-compact.ts +1 -1
  399. package/os/core/handlers/package-health.ts +1 -1
  400. package/os/core/handlers/pinned-check.ts +2 -2
  401. package/os/core/handlers/pinned-init.ts +9 -8
  402. package/os/core/handlers/pinned-validate.ts +3 -3
  403. package/os/core/handlers/profile-resolve.ts +1 -1
  404. package/os/core/handlers/public-surface.ts +1 -1
  405. package/os/core/handlers/release-prepare.ts +11 -6
  406. package/os/core/handlers/release-publish.ts +6 -6
  407. package/os/core/handlers/validate.ts +1 -1
  408. package/os/exploration/exploration.module.ts +1 -0
  409. package/os/exploration/frontmatter-io.ts +4 -4
  410. package/os/exploration/handlers/archive.ts +3 -3
  411. package/os/mission/handlers/archive.ts +27 -19
  412. package/os/mission/mission.module.ts +38 -39
  413. package/os/naming/naming-convention.ts +9 -3
  414. package/os/naming/naming.module.ts +25 -25
  415. package/os/notes/notes.module.ts +87 -85
  416. package/os/plan/frontmatter-io.ts +5 -5
  417. package/os/plan/handlers/archive.ts +8 -4
  418. package/os/plan/plan.module.ts +33 -34
  419. package/os/plugin/plugin.module.ts +8 -6
  420. package/os/program/discovery.ts +2 -2
  421. package/os/program/handlers/complete.ts +1 -1
  422. package/os/program/handlers/lease.ts +1 -1
  423. package/os/program/handlers/seal.ts +1 -1
  424. package/os/program/lease.ts +1 -1
  425. package/os/program/program.module.ts +198 -193
  426. package/os/queue/index.ts +1 -1
  427. package/os/queue/manifest.ts +10 -9
  428. package/os/queue/queue-validate.test.ts +6 -15
  429. package/os/rfc/acceptance.ts +12 -6
  430. package/os/rfc/decision-log.ts +4 -3
  431. package/os/rfc/dna-trace.ts +8 -2
  432. package/os/rfc/frontmatter-io.ts +5 -5
  433. package/os/rfc/handlers/archive.ts +9 -5
  434. package/os/rfc/handlers/check.ts +5 -3
  435. package/os/rfc/handlers/implement-stamp.ts +15 -10
  436. package/os/rfc/handlers/index-graph.ts +3 -3
  437. package/os/rfc/handlers/lifecycle.ts +7 -2
  438. package/os/rfc/handlers/list-create.ts +7 -6
  439. package/os/rfc/handlers/shared.ts +3 -3
  440. package/os/rfc/handlers/supersede-propose.ts +8 -3
  441. package/os/rfc/handlers/validate-rules-rfc1006.test.ts +18 -6
  442. package/os/rfc/handlers/validate-rules.ts +10 -5
  443. package/os/rfc/rfc-create-concurrent.test.ts +11 -3
  444. package/os/rfc/rfc.module.ts +413 -374
  445. package/os/rfc/verification-evidence.ts +11 -5
  446. package/os/rfc/verification-refresh.ts +4 -3
  447. package/os/session/frontmatter-io.ts +14 -14
  448. package/os/session/handlers/archive.ts +8 -4
  449. package/os/session/handlers/metrics-aggregate.ts +34 -13
  450. package/os/session/handlers/metrics-rfc.ts +13 -8
  451. package/os/session/handlers/metrics-session.ts +7 -3
  452. package/os/session/handlers/save.ts +12 -8
  453. package/os/session/session.module.ts +6 -0
  454. package/os/spec/live-spec-list.ts +4 -4
  455. package/os/spec/live-spec-merge.ts +5 -5
  456. package/os/spec/live-spec-show.ts +3 -3
  457. package/os/spec/live-spec-validate.ts +4 -4
  458. package/os/spec/spec-materialize.ts +9 -9
  459. package/os/spec/spec-status.ts +9 -9
  460. package/os/spec/spec-validate.ts +7 -7
  461. package/os/spec/spec.module.ts +8 -0
  462. package/os/werkstatt/handlers/lock.ts +16 -16
  463. package/os/werkstatt/handlers/werkstatt-lock-recover.ts +3 -3
  464. package/os/werkstatt/handlers/werkstatt-operation-validate.ts +4 -2
  465. package/os/werkstatt/werkstatt.module.ts +8 -5
  466. package/os/workflow/handlers.ts +7 -5
  467. package/os/workflow/workflow.module.ts +45 -44
  468. package/package.json +1 -1
  469. package/skills/fo/fo-add-tests/SKILL.md +2 -2
  470. package/skills/fo/fo-architecture/SKILL.md +2 -2
  471. package/skills/fo/fo-compass-annotate/SKILL.md +2 -2
  472. package/skills/fo/fo-design-summit/SKILL.md +2 -2
  473. package/skills/fo/fo-doc-audit/SKILL.md +2 -2
  474. package/skills/fo/fo-explore/SKILL.md +2 -2
  475. package/skills/fo/fo-extract-dna/SKILL.md +2 -2
  476. package/skills/fo/fo-fix/SKILL.md +2 -2
  477. package/skills/fo/fo-handoff/SKILL.md +2 -2
  478. package/skills/fo/fo-harvest/SKILL.md +2 -2
  479. package/skills/fo/fo-idea/SKILL.md +2 -2
  480. package/skills/fo/fo-idea-audit/SKILL.md +2 -2
  481. package/skills/fo/fo-idea-create-adr/SKILL.md +3 -3
  482. package/skills/fo/fo-idea-create-rfc/SKILL.md +3 -3
  483. package/skills/fo/fo-idea-enhance/SKILL.md +2 -2
  484. package/skills/fo/fo-idea-i-just-want-to-see-the-plan/SKILL.md +2 -2
  485. package/skills/fo/fo-idea-i-just-want-to-see-the-result/SKILL.md +1 -1
  486. package/skills/fo/fo-idea-implement/SKILL.md +2 -2
  487. package/skills/fo/fo-idea-plan/SKILL.md +2 -2
  488. package/skills/fo/fo-idea-status/SKILL.md +2 -2
  489. package/skills/fo/fo-knowledge-distill/SKILL.md +2 -2
  490. package/skills/fo/fo-memory-sync/SKILL.md +2 -2
  491. package/skills/fo/fo-qa/SKILL.md +2 -2
  492. package/skills/fo/fo-review/SKILL.md +2 -2
  493. package/skills/fo/fo-session-retro/SKILL.md +2 -2
  494. package/skills/fo/fo-session-save/SKILL.md +2 -2
  495. package/skills/fo/fo-spec-ingest/SKILL.md +2 -2
  496. package/skills/fo/fo-step-commit/SKILL.md +1 -1
  497. package/skills/fo/fo-triage/SKILL.md +2 -2
  498. package/skills/meta/forge-bootstrap/SKILL.md +1 -1
  499. package/skills/meta/port-to-forge/SKILL.md +1 -1
  500. package/skills/meta/skill-create/SKILL.md +1 -1
  501. package/skills/shared/grilling/SKILL.md +1 -1
  502. package/skills/shared/grilling/learned-principles.archive.md +17 -0
  503. package/skills/shared/grilling/learned-principles.md +0 -1
  504. package/skills/shared/knowledge/learned-principles.md +6 -0
  505. package/skills/shared/my-preferences/SKILL.md +1 -1
  506. package/skills/shared/windows-ai-tooling/SKILL.md +1 -1
  507. package/skills/shared/writing-great-skills/SKILL.md +1 -1
  508. package/src/compass/contract-registry.ts +1 -1
  509. package/src/config/forge-config.ts +1 -1
  510. package/src/knowledge/__tests__/sync.test.ts +2 -7
  511. package/src/knowledge/budgets.ts +1 -1
  512. package/src/knowledge/compact.ts +1 -1
  513. package/src/knowledge/parse.ts +1 -1
  514. package/src/knowledge/sync.ts +3 -5
  515. package/src/migration-adapters/git-utils.ts +2 -2
  516. package/src/migration-adapters/ignored-files.ts +2 -2
  517. package/src/migration-adapters/node-typescript-pnpm/index.ts +1 -1
  518. package/src/migration-adapters/phaser-pnpm/index.ts +1 -1
  519. package/src/onboarding/agents-generate.ts +74 -33
  520. package/src/onboarding/create.ts +10 -10
  521. package/src/onboarding/doctor.ts +70 -55
  522. package/src/onboarding/init.ts +38 -1
  523. package/src/onboarding/invariant-engine.ts +1 -1
  524. package/src/onboarding/memory-compact.ts +5 -4
  525. package/src/onboarding/memory-scaffold.ts +1 -1
  526. package/src/onboarding/nested-agents-generate.ts +45 -4
  527. package/src/onboarding/nested-agents-templates.ts +19 -13
  528. package/src/onboarding/npm-token-check.ts +2 -2
  529. package/src/onboarding/prettierignore.ts +263 -0
  530. package/src/onboarding/profile-validate.ts +5 -4
  531. package/src/onboarding/scaffold-project.ts +38 -27
  532. package/src/onboarding/scaffold.ts +1 -1
  533. package/src/onboarding/skill-markers.ts +162 -0
  534. package/src/onboarding/templates/behavioral-layer-core.md +2 -4
  535. package/src/onboarding/upgrade.ts +285 -89
  536. package/src/onboarding/workspace-discovery.ts +1 -1
  537. package/src/pipeline-status.test.ts +1 -4
  538. package/src/pipeline-status.ts +30 -13
  539. package/src/profiles/stack-profile.ts +1 -1
  540. package/src/registry.ts +4 -4
  541. package/src/skill-schema.ts +4 -1
  542. package/src/tests/acceptance-probe-kinds.test.ts +5 -15
  543. package/src/tests/agents-generate.test.ts +6 -4
  544. package/src/tests/contract-registry.test.ts +12 -6
  545. package/src/tests/doctor-fix.test.ts +1 -4
  546. package/src/tests/doctor-nested-agents.test.ts +53 -1
  547. package/src/tests/editable-generated-region.test.ts +231 -0
  548. package/src/tests/file-size-lint.test.ts +8 -12
  549. package/src/tests/fixtures/agents-generate-business-before.txt +54 -54
  550. package/src/tests/markdown-table.test.ts +107 -0
  551. package/src/tests/prettierignore-manage.test.ts +134 -0
  552. package/src/tests/skill-agents-sync.test.ts +168 -0
  553. package/src/tests/skill-sync-marker.test.ts +134 -0
  554. package/src/tests/skill-validate.test.ts +12 -5
  555. package/src/tests/upgrade.test.ts +87 -41
  556. package/src/types.ts +123 -0
  557. package/src/utils/editable-region.ts +156 -0
  558. package/src/utils/fs-idempotent.ts +12 -6
  559. package/src/utils/generated-marker.ts +36 -2
  560. package/src/utils/index.ts +17 -0
  561. package/src/utils/io.ts +143 -0
  562. package/src/utils/markdown-table.ts +121 -0
  563. package/src/utils/sync-fs.ts +43 -0
  564. package/src/validators/note-frontmatter-validate.ts +1 -1
  565. package/src/validators/note-link-validate.ts +1 -1
  566. package/src/validators/note-orphan-detect.ts +1 -1
  567. package/src/validators/port-validate.ts +1 -1
  568. package/src/validators/skill-validate.ts +38 -13
@@ -31,7 +31,10 @@ function mockContext(workspaceRoot: string): ForgeRuntimeContext {
31
31
  };
32
32
  }
33
33
 
34
- function input(flags: Record<string, unknown> = {}): { argv: string[]; flags: Record<string, unknown> } {
34
+ function input(flags: Record<string, unknown> = {}): {
35
+ argv: string[];
36
+ flags: Record<string, unknown>;
37
+ } {
35
38
  return { argv: [], flags };
36
39
  }
37
40
 
@@ -108,16 +111,10 @@ describe("runFileSizeLint (RFC-1088, command-level)", () => {
108
111
  const big = Array.from({ length: 700 }, (_, i) => `const x${i} = ${i};`).join("\n");
109
112
  await writeFile(join(tempDir, "packages", "some-pkg", "src", "big.ts"), big, "utf8");
110
113
 
111
- const result = await runFileSizeLint(
112
- input({ "write-baseline": true }),
113
- mockContext(tempDir),
114
- );
114
+ const result = await runFileSizeLint(input({ "write-baseline": true }), mockContext(tempDir));
115
115
  expect(result.exitCode ?? 0).toBe(0);
116
116
 
117
- const baselineRaw = await readFile(
118
- join(tempDir, "file-size-lint.baseline.yaml"),
119
- "utf8",
120
- );
117
+ const baselineRaw = await readFile(join(tempDir, "file-size-lint.baseline.yaml"), "utf8");
121
118
  expect(baselineRaw).toContain("schemaVersion");
122
119
  expect(baselineRaw).toContain("threshold: 600");
123
120
  expect(baselineRaw).toContain("big.ts");
@@ -155,9 +152,8 @@ describe("runFileSizeLint (RFC-1088, command-level)", () => {
155
152
  const result = await runFileSizeLint(input(), mockContext(tempDir));
156
153
  expect(result.exitCode ?? 0).toBe(0);
157
154
 
158
- const diagnostics = (
159
- result.data as { diagnostics: Array<{ ruleId: string; message: string }> }
160
- ).diagnostics;
155
+ const diagnostics = (result.data as { diagnostics: Array<{ ruleId: string; message: string }> })
156
+ .diagnostics;
161
157
  const hit = diagnostics.find((d) => d.ruleId === "SIZE-01");
162
158
  expect(hit).toBeDefined();
163
159
  expect(hit!.message).toContain("grew from the baselined 700 to 800");
@@ -35,76 +35,76 @@
35
35
 
36
36
  ## Skills
37
37
 
38
- | Name | Category | Invocation | Concerns |
39
- | --- | --- | --- | --- |
40
- | fo-add-tests | fo | user | code-mutation |
41
- | fo-architecture | fo | user | document-only |
42
- | fo-compass-annotate | fo | user | content-mutation |
43
- | fo-design-summit | fo | user | document-only |
44
- | fo-doc-audit | fo | user | document-only |
45
- | fo-explore | fo | user | document-only |
46
- | fo-extract-dna | fo | user | document-only |
47
- | fo-fix | fo | user | code-mutation |
48
- | fo-handoff | fo | user | document-only |
49
- | fo-harvest | fo | user | code-mutation |
50
- | fo-idea | fo | user | document-only |
51
- | fo-idea-audit | fo | user | read-only |
52
- | fo-idea-create-adr | fo | user | document-only |
53
- | fo-idea-create-rfc | fo | user | document-only |
54
- | fo-idea-enhance | fo | user | document-only |
55
- | fo-idea-i-just-want-to-see-the-plan | fo | user | document-only |
56
- | fo-idea-i-just-want-to-see-the-result | fo | user | code-mutation |
57
- | fo-idea-implement | fo | user | code-mutation |
58
- | fo-idea-plan | fo | user | document-only |
59
- | fo-idea-status | fo | user | read-only |
60
- | fo-knowledge-distill | fo | user | document-only |
61
- | fo-memory-sync | fo | user | content-mutation |
62
- | fo-qa | fo | user | document-only |
63
- | fo-review | fo | user | read-only |
64
- | fo-session-retro | fo | user | document-only |
65
- | fo-session-save | fo | user | document-only |
66
- | fo-spec-ingest | fo | user | document-only |
67
- | fo-step-commit | fo | model | code-mutation |
68
- | fo-triage | fo | user | document-only |
69
- | forge-bootstrap | meta | user | content-mutation |
70
- | grilling | shared | user | read-only |
71
- | my-preferences | shared | user | document-only |
72
- | port-to-forge | meta | user | code-mutation |
73
- | skill-create | meta | user | document-only |
74
- | windows-ai-tooling | shared | user | code-mutation |
75
- | writing-great-skills | shared | user | read-only |
38
+ | Name | Category | Invocation | Concerns |
39
+ | ------------------------------------- | -------- | ---------- | ---------------- |
40
+ | fo-add-tests | fo | user | code-mutation |
41
+ | fo-architecture | fo | user | document-only |
42
+ | fo-compass-annotate | fo | user | content-mutation |
43
+ | fo-design-summit | fo | user | document-only |
44
+ | fo-doc-audit | fo | user | document-only |
45
+ | fo-explore | fo | user | document-only |
46
+ | fo-extract-dna | fo | user | document-only |
47
+ | fo-fix | fo | user | code-mutation |
48
+ | fo-handoff | fo | user | document-only |
49
+ | fo-harvest | fo | user | code-mutation |
50
+ | fo-idea | fo | user | document-only |
51
+ | fo-idea-audit | fo | user | read-only |
52
+ | fo-idea-create-adr | fo | user | document-only |
53
+ | fo-idea-create-rfc | fo | user | document-only |
54
+ | fo-idea-enhance | fo | user | document-only |
55
+ | fo-idea-i-just-want-to-see-the-plan | fo | user | document-only |
56
+ | fo-idea-i-just-want-to-see-the-result | fo | user | code-mutation |
57
+ | fo-idea-implement | fo | user | code-mutation |
58
+ | fo-idea-plan | fo | user | document-only |
59
+ | fo-idea-status | fo | user | read-only |
60
+ | fo-knowledge-distill | fo | user | document-only |
61
+ | fo-memory-sync | fo | user | content-mutation |
62
+ | fo-qa | fo | user | document-only |
63
+ | fo-review | fo | user | read-only |
64
+ | fo-session-retro | fo | user | document-only |
65
+ | fo-session-save | fo | user | document-only |
66
+ | fo-spec-ingest | fo | user | document-only |
67
+ | fo-step-commit | fo | model | code-mutation |
68
+ | fo-triage | fo | user | document-only |
69
+ | forge-bootstrap | meta | user | content-mutation |
70
+ | grilling | shared | user | read-only |
71
+ | my-preferences | shared | user | document-only |
72
+ | port-to-forge | meta | user | code-mutation |
73
+ | skill-create | meta | user | document-only |
74
+ | windows-ai-tooling | shared | user | code-mutation |
75
+ | writing-great-skills | shared | user | read-only |
76
76
 
77
77
  ## Capabilities
78
78
 
79
79
  Bindings resolved from `forge.yaml`:
80
80
 
81
- | Key | Status | Value |
82
- | --- | --- | --- |
83
- | commands.validateRfc | resolved | `pnpm exec forge rfc.validate` |
84
- | commands.validateAdr | resolved | `pnpm exec forge adr.validate` |
85
- | commands.typecheck | absent | — |
86
- | commands.test | absent | — |
87
- | commands.scopedBuild | absent | — |
81
+ | Key | Status | Value |
82
+ | --------------------- | -------- | ------------------------------- |
83
+ | commands.validateRfc | resolved | `pnpm exec forge rfc.validate` |
84
+ | commands.validateAdr | resolved | `pnpm exec forge adr.validate` |
85
+ | commands.typecheck | absent | — |
86
+ | commands.test | absent | — |
87
+ | commands.scopedBuild | absent | — |
88
88
  | commands.specValidate | resolved | `pnpm exec forge spec.validate` |
89
- | commands.sessionSave | resolved | `pnpm exec forge session.save` |
90
- | paths.invariantsFile | resolved | `docs/architecture-dna.md` |
91
- | paths.reviewsDir | resolved | `docs/reviews` |
92
- | paths.handoffsDir | resolved | `docs/handoffs` |
93
- | paths.sessionsDir | resolved | `docs/sessions` |
94
- | paths.compassDocs | resolved | `docs/requirements.xml` |
89
+ | commands.sessionSave | resolved | `pnpm exec forge session.save` |
90
+ | paths.invariantsFile | resolved | `docs/architecture-dna.md` |
91
+ | paths.reviewsDir | resolved | `docs/reviews` |
92
+ | paths.handoffsDir | resolved | `docs/handoffs` |
93
+ | paths.sessionsDir | resolved | `docs/sessions` |
94
+ | paths.compassDocs | resolved | `docs/requirements.xml` |
95
95
 
96
96
  <!-- forge:begin behavioral-layer -->
97
97
 
98
98
  ## Behavioral layer
99
99
 
100
- This section defines the agent's core behavioral contract. It is generated from skill `triggers` and fixed policy text. The agent MUST follow these behaviors in every session.
100
+ This section defines the agent's core behavioral contract. It is generated from skill `triggerPhrases` and fixed policy text. The agent MUST follow these behaviors in every session.
101
101
 
102
102
  ### Intent-to-skill routing
103
103
 
104
- When the operator expresses an intent in natural language, the agent routes to the matching skill. The routing table is generated from `triggers` fields in skill frontmatter.
104
+ When the operator expresses an intent in natural language, the agent routes to the matching skill. The routing table is generated from `triggerPhrases` fields in skill frontmatter.
105
105
 
106
106
  | Operator says something like | Skill |
107
- | --- | --- |
107
+ | ---------------------------- | ----- |
108
108
 
109
109
  The agent uses judgment to calibrate routing — minor edits (typo fixes, small CSS changes) do not require skill invocation, while significant changes (new features, architectural decisions) do.
110
110
 
@@ -0,0 +1,107 @@
1
+ /*
2
+ <MODULE_CONTRACT>
3
+ <purpose>Unit tests for alignMarkdownTable + parseMarkdownTable (RFC-1154):
4
+ prettier-normal emission, separator dash-padding, escaped-pipe literals,
5
+ idempotency, and a regression guard over forge emission surfaces.</purpose>
6
+ </MODULE_CONTRACT>
7
+ <CHANGE_SUMMARY>
8
+ <item>RFC-1154: initial table-emitter tests + compact-separator regression guard.</item>
9
+ </CHANGE_SUMMARY>
10
+ */
11
+
12
+ import { test, expect } from "vitest";
13
+ import { readdirSync, readFileSync, statSync } from "node:fs";
14
+ import { join } from "node:path";
15
+ import { alignMarkdownTable, parseMarkdownTable } from "../utils/markdown-table.ts";
16
+
17
+ test("aligns cells and pads separator with dashes to column width", () => {
18
+ const out = alignMarkdownTable(
19
+ ["Name", "Value"],
20
+ [
21
+ ["long-name-here", "x"],
22
+ ["a", "b"],
23
+ ],
24
+ );
25
+ expect(out).toBe(
26
+ [
27
+ "| Name | Value |",
28
+ "| -------------- | ----- |",
29
+ "| long-name-here | x |",
30
+ "| a | b |",
31
+ ].join("\n"),
32
+ );
33
+ });
34
+
35
+ test("minimum column width is 3 even for short cells", () => {
36
+ const out = alignMarkdownTable(["a", "b"], [["1", "2"]]);
37
+ expect(out).toBe("| a | b |\n| --- | --- |\n| 1 | 2 |");
38
+ });
39
+
40
+ test("escaped pipe inside a cell is a literal, not a delimiter", () => {
41
+ const out = alignMarkdownTable(["Pattern", "Meaning"], [["a \\| b", "or"]]);
42
+ const lines = out.split("\n");
43
+ expect(lines[0]).toBe("| Pattern | Meaning |");
44
+ expect(lines[1]).toBe("| ------- | ------- |");
45
+ expect(lines[2]).toBe("| a \\| b | or |");
46
+ });
47
+
48
+ test("rows shorter or longer than headers extend the column set", () => {
49
+ const out = alignMarkdownTable(["A"], [["x", "extra"]]);
50
+ expect(out.split("\n")[0]).toBe("| A | |");
51
+ expect(out.split("\n")[2]).toBe("| x | extra |");
52
+ });
53
+
54
+ test("empty input emits empty string", () => {
55
+ expect(alignMarkdownTable([], [])).toBe("");
56
+ });
57
+
58
+ test("AC-5: re-aligning emitted output is byte-identical", () => {
59
+ const once = alignMarkdownTable(
60
+ ["Name", "Category", "Concerns"],
61
+ [
62
+ ["fo-idea", "fo", "classification"],
63
+ ["wg-mission", "wg", "lifecycle"],
64
+ ],
65
+ );
66
+ const parsed = parseMarkdownTable(once);
67
+ expect(parsed).not.toBeNull();
68
+ const twice = alignMarkdownTable(parsed!.headers, parsed!.rows);
69
+ expect(twice, "align(parse(emit)) must be byte-stable — check separator width math").toBe(once);
70
+ });
71
+
72
+ test("parseMarkdownTable returns null for non-table input", () => {
73
+ expect(parseMarkdownTable("just prose\nno table here")).toBeNull();
74
+ expect(parseMarkdownTable("| a |\nno separator")).toBeNull();
75
+ });
76
+
77
+ test("parseMarkdownTable splits on unescaped pipes only", () => {
78
+ const parsed = parseMarkdownTable("| a \\| b | c |\n| --- | --- |\n| 1 | 2 |");
79
+ expect(parsed).not.toBeNull();
80
+ expect(parsed!.headers).toEqual(["a \\| b", "c"]);
81
+ });
82
+
83
+ test("regression guard: no forge emitter emits a compact '| --- |' separator", () => {
84
+ const srcDir = join(import.meta.dirname, "..");
85
+ const offenders: string[] = [];
86
+ const walk = (dir: string) => {
87
+ for (const entry of readdirSync(dir)) {
88
+ const full = join(dir, entry);
89
+ if (statSync(full).isDirectory()) {
90
+ if (entry === "tests" || entry === "__tests__") continue;
91
+ walk(full);
92
+ continue;
93
+ }
94
+ if (!entry.endsWith(".ts")) continue;
95
+ const content = readFileSync(full, "utf8");
96
+ // Flag compact separator literals — all tables must route through
97
+ // alignMarkdownTable. The aligner itself lives in utils/markdown-table.ts.
98
+ if (full.endsWith("markdown-table.ts")) continue;
99
+ if (/\| -{2,} \|/.test(content)) offenders.push(full);
100
+ }
101
+ };
102
+ walk(srcDir);
103
+ expect(
104
+ offenders,
105
+ "compact '| --- |' table literals found — route through alignMarkdownTable",
106
+ ).toEqual([]);
107
+ });
@@ -0,0 +1,134 @@
1
+ /*
2
+ <MODULE_CONTRACT>
3
+ <purpose>Unit tests for the RFC-1154 managed .prettierignore block:
4
+ root-only prettier detection, delimited-block reconcile preserving operator
5
+ content, marker-driven skill entries, and the skipped contract for
6
+ prettier-free consumers.</purpose>
7
+ </MODULE_CONTRACT>
8
+ <CHANGE_SUMMARY>
9
+ <item>RFC-1154: initial prettierignore plan/apply tests.</item>
10
+ </CHANGE_SUMMARY>
11
+ */
12
+
13
+ import { test, expect, beforeEach, afterEach } from "vitest";
14
+ import { mkdtemp, rm, writeFile, mkdir, readFile } from "node:fs/promises";
15
+ import { existsSync } from "node:fs";
16
+ import { tmpdir } from "node:os";
17
+ import { join } from "node:path";
18
+ import {
19
+ planPrettierignore,
20
+ applyPrettierignore,
21
+ reconcilePrettierignoreContent,
22
+ PRETTIERIGNORE_BLOCK_BEGIN,
23
+ PRETTIERIGNORE_BLOCK_END,
24
+ } from "../onboarding/prettierignore.ts";
25
+ import { SKILL_MARKER_FILE } from "../onboarding/skill-markers.ts";
26
+
27
+ let tmpDir: string;
28
+
29
+ beforeEach(async () => {
30
+ tmpDir = await mkdtemp(join(tmpdir(), "prettierignore-"));
31
+ });
32
+
33
+ afterEach(async () => {
34
+ await rm(tmpDir, { recursive: true, force: true });
35
+ });
36
+
37
+ async function withPrettier(root: string): Promise<void> {
38
+ await writeFile(join(root, ".prettierrc"), "{}\n");
39
+ }
40
+
41
+ test("detects prettier via root .prettierrc", async () => {
42
+ await withPrettier(tmpDir);
43
+ const plan = await planPrettierignore(tmpDir);
44
+ expect(plan.applies).toBe(true);
45
+ });
46
+
47
+ test("detects prettier via package.json prettier key", async () => {
48
+ await writeFile(join(tmpDir, "package.json"), JSON.stringify({ prettier: {} }));
49
+ const plan = await planPrettierignore(tmpDir);
50
+ expect(plan.applies).toBe(true);
51
+ });
52
+
53
+ test("detects prettier via prettier devDependency", async () => {
54
+ await writeFile(
55
+ join(tmpDir, "package.json"),
56
+ JSON.stringify({ devDependencies: { prettier: "^3" } }),
57
+ );
58
+ const plan = await planPrettierignore(tmpDir);
59
+ expect(plan.applies).toBe(true);
60
+ });
61
+
62
+ test("detects prettier via existing .prettierignore alone", async () => {
63
+ await writeFile(join(tmpDir, ".prettierignore"), "dist/\n");
64
+ const plan = await planPrettierignore(tmpDir);
65
+ expect(plan.applies).toBe(true);
66
+ });
67
+
68
+ test("AC-4: no prettier markers — plan does not apply, apply writes nothing", async () => {
69
+ const plan = await planPrettierignore(tmpDir);
70
+ expect(plan.applies).toBe(false);
71
+ const result = await applyPrettierignore(tmpDir, plan);
72
+ expect(result).toBe("skipped");
73
+ expect(existsSync(join(tmpDir, ".prettierignore"))).toBe(false);
74
+ });
75
+
76
+ test("AC-2: block contains generated.yaml glob, sessions, metrics, queues entries", async () => {
77
+ await withPrettier(tmpDir);
78
+ const plan = await planPrettierignore(tmpDir);
79
+ const result = await applyPrettierignore(tmpDir, plan);
80
+ expect(result).toBe("written");
81
+ const content = await readFile(join(tmpDir, ".prettierignore"), "utf8");
82
+ expect(content).toContain(PRETTIERIGNORE_BLOCK_BEGIN);
83
+ expect(content).toContain("**/*.generated.yaml");
84
+ expect(content).toContain("docs/sessions/");
85
+ expect(content).toContain("docs/metrics/");
86
+ expect(content).toContain("docs/queues/session-*.yaml");
87
+ expect(content).toContain(PRETTIERIGNORE_BLOCK_END);
88
+ });
89
+
90
+ test("skill entries enumerate only marker-carrying dirs (AC-9)", async () => {
91
+ await withPrettier(tmpDir);
92
+ const skillsDir = join(tmpDir, ".agents", "skills");
93
+ await mkdir(join(skillsDir, "fo-idea"), { recursive: true });
94
+ await writeFile(join(skillsDir, "fo-idea", SKILL_MARKER_FILE), '{"files":["SKILL.md"]}');
95
+ await mkdir(join(skillsDir, "my-own-skill"), { recursive: true }); // unmarked — consumer-owned
96
+
97
+ const plan = await planPrettierignore(tmpDir);
98
+ expect(plan.entries).toContain(".agents/skills/fo-idea/");
99
+ expect(plan.entries).not.toContain(".agents/skills/my-own-skill/");
100
+ });
101
+
102
+ test("reconcile preserves operator content outside the block", async () => {
103
+ const existing = `dist/\nnode_modules/\n${PRETTIERIGNORE_BLOCK_BEGIN}\nold-entry/\n${PRETTIERIGNORE_BLOCK_END}\ncustom/\n`;
104
+ const { next, changed } = reconcilePrettierignoreContent(existing, ["a/", "b/"]);
105
+ expect(changed).toBe("updated");
106
+ expect(next).toContain("dist/\nnode_modules/\n");
107
+ expect(next).toContain("custom/\n");
108
+ expect(next).not.toContain("old-entry/");
109
+ expect(next).toContain("a/\nb/");
110
+ });
111
+
112
+ test("unbalanced markers treat the file as operator-owned and append a fresh block", async () => {
113
+ const existing = `dist/\n${PRETTIERIGNORE_BLOCK_BEGIN}\nstray/\n`; // no END marker
114
+ const { next, changed } = reconcilePrettierignoreContent(existing, ["x/"]);
115
+ expect(changed).toBe("updated");
116
+ expect(next).toContain("dist/\n");
117
+ // Original content preserved verbatim — forge does not merge into a
118
+ // corrupted region; a fresh block is appended.
119
+ expect(next.indexOf(PRETTIERIGNORE_BLOCK_BEGIN)).toBeLessThan(
120
+ next.lastIndexOf(PRETTIERIGNORE_BLOCK_BEGIN),
121
+ );
122
+ });
123
+
124
+ test("repeated apply is idempotent", async () => {
125
+ await withPrettier(tmpDir);
126
+ await writeFile(join(tmpDir, ".prettierignore"), "dist/\n");
127
+ const plan = await planPrettierignore(tmpDir);
128
+ const first = await applyPrettierignore(tmpDir, plan);
129
+ expect(first).toBe("updated");
130
+ const second = await applyPrettierignore(tmpDir, await planPrettierignore(tmpDir));
131
+ expect(second, "second apply must be unchanged — check reconcile block boundaries").toBe(
132
+ "unchanged",
133
+ );
134
+ });
@@ -0,0 +1,168 @@
1
+ /*
2
+ <MODULE_CONTRACT>
3
+ <purpose>CI gate: every forge/pack skill source must be fully propagated to
4
+ `.agents/skills/` (IDE discovery copy written by forge.init/forge.upgrade).
5
+ SKILL.md syncs verbatim; declared knowledge files follow the append-only
6
+ syncKnowledgeFile contract — in the canonical repo a resync must be a no-op,
7
+ otherwise source and copy have drifted apart.</purpose>
8
+ <non-goals>
9
+ <item>Do not validate skill content/schema — forge.skill.validate owns that.</item>
10
+ <item>Do not flag unmarked dirs — a missing .forge-managed marker means
11
+ consumer-owned (RFC-1154), e.g. `_shared/`.</item>
12
+ </non-goals>
13
+ <KEY_DECISIONS>
14
+ <item>planKnowledgeSync is reused so the gate encodes the exact merge
15
+ semantics of the syncer — only "unchanged" is a pass; "merged" (source has
16
+ entries the copy lacks), "copied" (copy missing), and "skipped"
17
+ (non-mergeable divergence = hand-edited copy) all fail.</item>
18
+ <item>Runs on the real repo — this is a drift gate, not a fixture test.</item>
19
+ </KEY_DECISIONS>
20
+ <CHANGE_SUMMARY>
21
+ <item>Initial version — covers FORGE_SKILLS, declared pack skills
22
+ (discoverPackSkills), and the shared-knowledge layer.</item>
23
+ </CHANGE_SUMMARY>
24
+ */
25
+
26
+ import fs from "node:fs";
27
+ import path from "node:path";
28
+ import { describe, expect, it } from "vitest";
29
+
30
+ import { loadForgeConfig } from "../config/forge-config.ts";
31
+ import { planKnowledgeSync } from "../knowledge/index.ts";
32
+ import { FORGE_SKILLS, discoverPackSkills } from "../registry.ts";
33
+
34
+ const forgeRoot = path.resolve(import.meta.dirname, "../..");
35
+ const workspaceRoot = path.resolve(import.meta.dirname, "../../../..");
36
+
37
+ interface SkillSource {
38
+ name: string;
39
+ srcDir: string;
40
+ knowledge: string[];
41
+ }
42
+
43
+ function collectSkillSources(): SkillSource[] {
44
+ const sources: SkillSource[] = [];
45
+ for (const skill of FORGE_SKILLS) {
46
+ sources.push({
47
+ name: skill.name,
48
+ srcDir: path.dirname(path.join(forgeRoot, skill.path)),
49
+ knowledge: skill.knowledge ?? [],
50
+ });
51
+ }
52
+ const config = loadForgeConfig(workspaceRoot);
53
+ for (const skill of discoverPackSkills(workspaceRoot, config)) {
54
+ sources.push({
55
+ name: skill.name,
56
+ srcDir: path.dirname(path.join(workspaceRoot, skill.dir, skill.path)),
57
+ knowledge: skill.knowledge ?? [],
58
+ });
59
+ }
60
+ return sources;
61
+ }
62
+
63
+ // Skipped in the standalone package repo — the gate needs a forge-managed
64
+ // workspace root (forge.yaml + synced skillsDir), which only exists for the
65
+ // monorepo and consumer projects, not for the published forge source tree.
66
+ const hasForgeWorkspace = fs.existsSync(path.join(workspaceRoot, "forge.yaml"));
67
+ describe.runIf(hasForgeWorkspace)(
68
+ ".agents/skills sync gate (forge.init/forge.upgrade parity)",
69
+ () => {
70
+ // describe callbacks still run during collection even when runIf is false,
71
+ // so initializers must tolerate the absent forge.yaml themselves.
72
+ const config = hasForgeWorkspace ? loadForgeConfig(workspaceRoot) : null;
73
+ const skillsDir = config ? path.join(workspaceRoot, config.paths.skillsDir) : "";
74
+ const sources = config ? collectSkillSources() : [];
75
+
76
+ it("every forge + pack skill has a synced copy in .agents/skills/", () => {
77
+ const missing = sources
78
+ .filter((s) => !fs.existsSync(path.join(skillsDir, s.name, "SKILL.md")))
79
+ .map((s) => `${s.name} (src ${path.relative(workspaceRoot, s.srcDir)})`);
80
+ expect(
81
+ missing,
82
+ `skills never synced — run \`forge init\`/\`forge upgrade\` to populate ${path.relative(workspaceRoot, skillsDir)}`,
83
+ ).toEqual([]);
84
+ });
85
+
86
+ it("SKILL.md copies are byte-identical to their sources", () => {
87
+ const drifted: string[] = [];
88
+ for (const s of sources) {
89
+ const src = path.join(s.srcDir, "SKILL.md");
90
+ const dest = path.join(skillsDir, s.name, "SKILL.md");
91
+ if (!fs.existsSync(dest)) continue; // reported by the presence test
92
+ if (fs.readFileSync(src, "utf8") !== fs.readFileSync(dest, "utf8")) {
93
+ drifted.push(s.name);
94
+ }
95
+ }
96
+ expect(
97
+ drifted,
98
+ "SKILL.md drift — edit the pack source and re-sync, never edit .agents/skills/ directly",
99
+ ).toEqual([]);
100
+ });
101
+
102
+ it("declared knowledge files are in sync (append-only merge would be a no-op)", () => {
103
+ const stale: string[] = [];
104
+ for (const s of sources) {
105
+ for (const kf of s.knowledge) {
106
+ const src = path.join(s.srcDir, kf);
107
+ const dest = path.join(skillsDir, s.name, kf);
108
+ if (!fs.existsSync(src)) {
109
+ stale.push(`${s.name}/${kf} — declared but missing in source`);
110
+ continue;
111
+ }
112
+ if (!fs.existsSync(dest)) {
113
+ stale.push(`${s.name}/${kf} — missing in .agents/skills (run forge upgrade)`);
114
+ continue;
115
+ }
116
+ const plan = planKnowledgeSync(src, dest);
117
+ if (plan.action === "merged") {
118
+ stale.push(`${s.name}/${kf} — source has entries the copy lacks`);
119
+ } else if (plan.action === "skipped") {
120
+ stale.push(`${s.name}/${kf} — copy diverged non-mergeably (hand-edited .agents copy)`);
121
+ }
122
+ }
123
+ }
124
+ expect(stale).toEqual([]);
125
+ });
126
+
127
+ it("undeclared aux files in the copy still match their sources", () => {
128
+ // The syncer writes SKILL.md + declared knowledge files only. Aux files
129
+ // (references, templates, placeholder dirs) that exist in BOTH trees are
130
+ // hand-copied and silently diverge — a same-named pair must stay identical,
131
+ // and a copy-only orphan can never resync.
132
+ const flagged: string[] = [];
133
+ for (const s of sources) {
134
+ const destDir = path.join(skillsDir, s.name);
135
+ if (!fs.existsSync(destDir)) continue;
136
+ const declared = new Set(["SKILL.md", ".forge-managed", ...s.knowledge]);
137
+ for (const entry of fs.readdirSync(destDir)) {
138
+ if (declared.has(entry)) continue;
139
+ const srcEntry = path.join(s.srcDir, entry);
140
+ const destEntry = path.join(destDir, entry);
141
+ if (fs.statSync(destEntry).isDirectory()) {
142
+ if (!fs.existsSync(srcEntry))
143
+ flagged.push(`${s.name}/${entry}/ — dir absent in source`);
144
+ continue;
145
+ }
146
+ if (!fs.existsSync(srcEntry)) {
147
+ flagged.push(`${s.name}/${entry} — absent in source, copy can never resync`);
148
+ } else if (fs.readFileSync(srcEntry, "utf8") !== fs.readFileSync(destEntry, "utf8")) {
149
+ flagged.push(`${s.name}/${entry} — diverged from source`);
150
+ }
151
+ }
152
+ }
153
+ expect(
154
+ flagged,
155
+ "aux-file drift — declare aux files via `knowledge:` in SKILL.md or keep copies identical to source",
156
+ ).toEqual([]);
157
+ });
158
+
159
+ it("shared-knowledge layer is synced", () => {
160
+ const src = path.join(forgeRoot, "skills", "shared", "knowledge", "learned-principles.md");
161
+ const dest = path.join(skillsDir, "shared-knowledge", "learned-principles.md");
162
+ if (!fs.existsSync(src)) return; // layer absent — nothing to gate
163
+ expect(fs.existsSync(dest), "shared-knowledge/learned-principles.md not synced").toBe(true);
164
+ const plan = planKnowledgeSync(src, dest);
165
+ expect(plan.action, `shared-knowledge drift (sync action: ${plan.action})`).toBe("unchanged");
166
+ });
167
+ },
168
+ );