@seanmars/tospec 0.23.0 → 0.26.0-beta

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 (358) hide show
  1. package/CHANGELOG.md +281 -0
  2. package/README.md +27 -9
  3. package/assets/claude-mod/tospec-dashboard/.claude-plugin/plugin.json +7 -0
  4. package/assets/claude-mod/tospec-dashboard/hooks/hooks.json +1 -0
  5. package/assets/claude-mod/tospec-dashboard/hooks/register.ts +695 -0
  6. package/assets/claude-mod/tospec-dashboard/tests/register.test.ts +448 -0
  7. package/assets/claude-mod/tospec-dashboard/types/index.d.ts +8 -0
  8. package/assets/dashboard/app.js +218 -1180
  9. package/assets/dashboard/index.html +31 -22
  10. package/assets/dashboard/lib/charts.js +355 -0
  11. package/assets/dashboard/lib/derive.js +375 -0
  12. package/assets/dashboard/lib/dom.js +121 -0
  13. package/assets/dashboard/lib/routes.js +52 -0
  14. package/assets/dashboard/lib/store.js +326 -0
  15. package/assets/dashboard/style.css +3103 -664
  16. package/assets/dashboard/views/alerts.js +170 -0
  17. package/assets/dashboard/views/change.js +234 -0
  18. package/assets/dashboard/views/docs.js +214 -0
  19. package/assets/dashboard/views/home.js +357 -0
  20. package/assets/dashboard/views/project.js +168 -0
  21. package/assets/dashboard/views/session.js +270 -0
  22. package/assets/dashboard/views/sidebar.js +131 -0
  23. package/dist/cli/index.d.ts.map +1 -1
  24. package/dist/cli/index.js +116 -102
  25. package/dist/cli/index.js.map +1 -1
  26. package/dist/commands/config.d.ts.map +1 -1
  27. package/dist/commands/config.js +213 -100
  28. package/dist/commands/config.js.map +1 -1
  29. package/dist/commands/dashboard-relay.d.ts +11 -0
  30. package/dist/commands/dashboard-relay.d.ts.map +1 -0
  31. package/dist/commands/dashboard-relay.js +88 -0
  32. package/dist/commands/dashboard-relay.js.map +1 -0
  33. package/dist/commands/dashboard.d.ts +69 -100
  34. package/dist/commands/dashboard.d.ts.map +1 -1
  35. package/dist/commands/dashboard.js +420 -598
  36. package/dist/commands/dashboard.js.map +1 -1
  37. package/dist/commands/decision.d.ts +38 -1
  38. package/dist/commands/decision.d.ts.map +1 -1
  39. package/dist/commands/decision.js +303 -27
  40. package/dist/commands/decision.js.map +1 -1
  41. package/dist/commands/metrics.d.ts +3 -4
  42. package/dist/commands/metrics.d.ts.map +1 -1
  43. package/dist/commands/metrics.js +3 -5
  44. package/dist/commands/metrics.js.map +1 -1
  45. package/dist/commands/shared-output.d.ts +24 -0
  46. package/dist/commands/shared-output.d.ts.map +1 -1
  47. package/dist/commands/shared-output.js +21 -2
  48. package/dist/commands/shared-output.js.map +1 -1
  49. package/dist/commands/show.d.ts.map +1 -1
  50. package/dist/commands/show.js +12 -9
  51. package/dist/commands/show.js.map +1 -1
  52. package/dist/commands/validate.d.ts +19 -0
  53. package/dist/commands/validate.d.ts.map +1 -1
  54. package/dist/commands/validate.js +243 -64
  55. package/dist/commands/validate.js.map +1 -1
  56. package/dist/commands/workflow/instructions.d.ts +7 -1
  57. package/dist/commands/workflow/instructions.d.ts.map +1 -1
  58. package/dist/commands/workflow/instructions.js +299 -81
  59. package/dist/commands/workflow/instructions.js.map +1 -1
  60. package/dist/commands/workflow/new-change.d.ts.map +1 -1
  61. package/dist/commands/workflow/new-change.js +26 -17
  62. package/dist/commands/workflow/new-change.js.map +1 -1
  63. package/dist/commands/workflow/prompt-escape.d.ts +25 -0
  64. package/dist/commands/workflow/prompt-escape.d.ts.map +1 -0
  65. package/dist/commands/workflow/prompt-escape.js +62 -0
  66. package/dist/commands/workflow/prompt-escape.js.map +1 -0
  67. package/dist/commands/workflow/schemas.d.ts.map +1 -1
  68. package/dist/commands/workflow/schemas.js +34 -16
  69. package/dist/commands/workflow/schemas.js.map +1 -1
  70. package/dist/commands/workflow/shared.d.ts +46 -10
  71. package/dist/commands/workflow/shared.d.ts.map +1 -1
  72. package/dist/commands/workflow/shared.js +66 -30
  73. package/dist/commands/workflow/shared.js.map +1 -1
  74. package/dist/commands/workflow/status.d.ts +5 -2
  75. package/dist/commands/workflow/status.d.ts.map +1 -1
  76. package/dist/commands/workflow/status.js +62 -28
  77. package/dist/commands/workflow/status.js.map +1 -1
  78. package/dist/core/archive.d.ts +38 -0
  79. package/dist/core/archive.d.ts.map +1 -1
  80. package/dist/core/archive.js +492 -75
  81. package/dist/core/archive.js.map +1 -1
  82. package/dist/core/artifact-graph/index.d.ts +2 -2
  83. package/dist/core/artifact-graph/index.d.ts.map +1 -1
  84. package/dist/core/artifact-graph/index.js +2 -2
  85. package/dist/core/artifact-graph/index.js.map +1 -1
  86. package/dist/core/artifact-graph/instruction-loader.d.ts +8 -0
  87. package/dist/core/artifact-graph/instruction-loader.d.ts.map +1 -1
  88. package/dist/core/artifact-graph/instruction-loader.js +58 -36
  89. package/dist/core/artifact-graph/instruction-loader.js.map +1 -1
  90. package/dist/core/artifact-graph/resolver.d.ts +39 -12
  91. package/dist/core/artifact-graph/resolver.d.ts.map +1 -1
  92. package/dist/core/artifact-graph/resolver.js +82 -36
  93. package/dist/core/artifact-graph/resolver.js.map +1 -1
  94. package/dist/core/artifact-graph/schema.d.ts +24 -0
  95. package/dist/core/artifact-graph/schema.d.ts.map +1 -1
  96. package/dist/core/artifact-graph/schema.js +32 -1
  97. package/dist/core/artifact-graph/schema.js.map +1 -1
  98. package/dist/core/artifact-graph/stub-detection.d.ts +10 -2
  99. package/dist/core/artifact-graph/stub-detection.d.ts.map +1 -1
  100. package/dist/core/artifact-graph/stub-detection.js +18 -11
  101. package/dist/core/artifact-graph/stub-detection.js.map +1 -1
  102. package/dist/core/artifact-graph/types.d.ts +2 -2
  103. package/dist/core/artifact-graph/types.d.ts.map +1 -1
  104. package/dist/core/artifact-graph/types.js +10 -1
  105. package/dist/core/artifact-graph/types.js.map +1 -1
  106. package/dist/core/change-metadata/schema.d.ts.map +1 -1
  107. package/dist/core/change-metadata/schema.js +18 -4
  108. package/dist/core/change-metadata/schema.js.map +1 -1
  109. package/dist/core/change-presenter.d.ts.map +1 -1
  110. package/dist/core/change-presenter.js +13 -8
  111. package/dist/core/change-presenter.js.map +1 -1
  112. package/dist/core/change-status-policy.d.ts.map +1 -1
  113. package/dist/core/change-status-policy.js +3 -1
  114. package/dist/core/change-status-policy.js.map +1 -1
  115. package/dist/core/codex-metrics.d.ts +1 -1
  116. package/dist/core/codex-metrics.js +1 -1
  117. package/dist/core/config-schema.d.ts +8 -0
  118. package/dist/core/config-schema.d.ts.map +1 -1
  119. package/dist/core/config-schema.js +10 -0
  120. package/dist/core/config-schema.js.map +1 -1
  121. package/dist/core/dashboard-activity.d.ts +4 -4
  122. package/dist/core/dashboard-activity.js +4 -4
  123. package/dist/core/dashboard-data.d.ts +11 -5
  124. package/dist/core/dashboard-data.d.ts.map +1 -1
  125. package/dist/core/dashboard-data.js +54 -28
  126. package/dist/core/dashboard-data.js.map +1 -1
  127. package/dist/core/dashboard-hub.d.ts +258 -0
  128. package/dist/core/dashboard-hub.d.ts.map +1 -0
  129. package/dist/core/dashboard-hub.js +655 -0
  130. package/dist/core/dashboard-hub.js.map +1 -0
  131. package/dist/core/dashboard-routes.d.ts +57 -0
  132. package/dist/core/dashboard-routes.d.ts.map +1 -0
  133. package/dist/core/dashboard-routes.js +398 -0
  134. package/dist/core/dashboard-routes.js.map +1 -0
  135. package/dist/core/global-config.d.ts +71 -2
  136. package/dist/core/global-config.d.ts.map +1 -1
  137. package/dist/core/global-config.js +149 -4
  138. package/dist/core/global-config.js.map +1 -1
  139. package/dist/core/id.d.ts +9 -0
  140. package/dist/core/id.d.ts.map +1 -1
  141. package/dist/core/id.js +37 -0
  142. package/dist/core/id.js.map +1 -1
  143. package/dist/core/init.d.ts +9 -2
  144. package/dist/core/init.d.ts.map +1 -1
  145. package/dist/core/init.js +119 -33
  146. package/dist/core/init.js.map +1 -1
  147. package/dist/core/list.d.ts.map +1 -1
  148. package/dist/core/list.js +69 -45
  149. package/dist/core/list.js.map +1 -1
  150. package/dist/core/local-server.d.ts +10 -3
  151. package/dist/core/local-server.d.ts.map +1 -1
  152. package/dist/core/local-server.js +25 -5
  153. package/dist/core/local-server.js.map +1 -1
  154. package/dist/core/markdown-render.d.ts.map +1 -1
  155. package/dist/core/markdown-render.js +7 -2
  156. package/dist/core/markdown-render.js.map +1 -1
  157. package/dist/core/migrate.d.ts +24 -2
  158. package/dist/core/migrate.d.ts.map +1 -1
  159. package/dist/core/migrate.js +335 -59
  160. package/dist/core/migrate.js.map +1 -1
  161. package/dist/core/parsers/change-parser.d.ts +20 -1
  162. package/dist/core/parsers/change-parser.d.ts.map +1 -1
  163. package/dist/core/parsers/change-parser.js +76 -73
  164. package/dist/core/parsers/change-parser.js.map +1 -1
  165. package/dist/core/parsers/markdown-parser.d.ts +24 -0
  166. package/dist/core/parsers/markdown-parser.d.ts.map +1 -1
  167. package/dist/core/parsers/markdown-parser.js +65 -10
  168. package/dist/core/parsers/markdown-parser.js.map +1 -1
  169. package/dist/core/parsers/requirement-blocks.d.ts +127 -6
  170. package/dist/core/parsers/requirement-blocks.d.ts.map +1 -1
  171. package/dist/core/parsers/requirement-blocks.js +349 -56
  172. package/dist/core/parsers/requirement-blocks.js.map +1 -1
  173. package/dist/core/parsers/requirement-text.d.ts +25 -1
  174. package/dist/core/parsers/requirement-text.d.ts.map +1 -1
  175. package/dist/core/parsers/requirement-text.js +62 -6
  176. package/dist/core/parsers/requirement-text.js.map +1 -1
  177. package/dist/core/parsers/spec-structure.d.ts.map +1 -1
  178. package/dist/core/parsers/spec-structure.js +36 -24
  179. package/dist/core/parsers/spec-structure.js.map +1 -1
  180. package/dist/core/project-config.d.ts +9 -2
  181. package/dist/core/project-config.d.ts.map +1 -1
  182. package/dist/core/project-config.js +30 -7
  183. package/dist/core/project-config.js.map +1 -1
  184. package/dist/core/project-layout.d.ts +26 -0
  185. package/dist/core/project-layout.d.ts.map +1 -1
  186. package/dist/core/project-layout.js +51 -1
  187. package/dist/core/project-layout.js.map +1 -1
  188. package/dist/core/schema-names.d.ts +17 -0
  189. package/dist/core/schema-names.d.ts.map +1 -1
  190. package/dist/core/schema-names.js +24 -0
  191. package/dist/core/schema-names.js.map +1 -1
  192. package/dist/core/shared/dashboard-mod.d.ts +24 -0
  193. package/dist/core/shared/dashboard-mod.d.ts.map +1 -0
  194. package/dist/core/shared/dashboard-mod.js +44 -0
  195. package/dist/core/shared/dashboard-mod.js.map +1 -0
  196. package/dist/core/shared/index.d.ts +2 -1
  197. package/dist/core/shared/index.d.ts.map +1 -1
  198. package/dist/core/shared/index.js +2 -1
  199. package/dist/core/shared/index.js.map +1 -1
  200. package/dist/core/shared/rules-generation.d.ts +12 -0
  201. package/dist/core/shared/rules-generation.d.ts.map +1 -1
  202. package/dist/core/shared/rules-generation.js +26 -2
  203. package/dist/core/shared/rules-generation.js.map +1 -1
  204. package/dist/core/shared/skill-generation.d.ts +7 -0
  205. package/dist/core/shared/skill-generation.d.ts.map +1 -1
  206. package/dist/core/shared/skill-generation.js +19 -0
  207. package/dist/core/shared/skill-generation.js.map +1 -1
  208. package/dist/core/shared/tool-detection.d.ts +10 -1
  209. package/dist/core/shared/tool-detection.d.ts.map +1 -1
  210. package/dist/core/shared/tool-detection.js +37 -6
  211. package/dist/core/shared/tool-detection.js.map +1 -1
  212. package/dist/core/spec-presenter.d.ts.map +1 -1
  213. package/dist/core/spec-presenter.js +23 -1
  214. package/dist/core/spec-presenter.js.map +1 -1
  215. package/dist/core/specs-apply.d.ts +98 -1
  216. package/dist/core/specs-apply.d.ts.map +1 -1
  217. package/dist/core/specs-apply.js +426 -63
  218. package/dist/core/specs-apply.js.map +1 -1
  219. package/dist/core/templates/fragments/change-diff.d.ts +37 -0
  220. package/dist/core/templates/fragments/change-diff.d.ts.map +1 -0
  221. package/dist/core/templates/fragments/change-diff.js +37 -0
  222. package/dist/core/templates/fragments/change-diff.js.map +1 -0
  223. package/dist/core/templates/fragments/sync-fail.d.ts +8 -0
  224. package/dist/core/templates/fragments/sync-fail.d.ts.map +1 -0
  225. package/dist/core/templates/fragments/sync-fail.js +8 -0
  226. package/dist/core/templates/fragments/sync-fail.js.map +1 -0
  227. package/dist/core/templates/fragments/validate.d.ts +14 -1
  228. package/dist/core/templates/fragments/validate.d.ts.map +1 -1
  229. package/dist/core/templates/fragments/validate.js +14 -1
  230. package/dist/core/templates/fragments/validate.js.map +1 -1
  231. package/dist/core/templates/fragments/verify.d.ts +2 -2
  232. package/dist/core/templates/fragments/verify.d.ts.map +1 -1
  233. package/dist/core/templates/fragments/verify.js +8 -5
  234. package/dist/core/templates/fragments/verify.js.map +1 -1
  235. package/dist/core/templates/workflows/apply.d.ts +1 -1
  236. package/dist/core/templates/workflows/apply.d.ts.map +1 -1
  237. package/dist/core/templates/workflows/apply.js +29 -10
  238. package/dist/core/templates/workflows/apply.js.map +1 -1
  239. package/dist/core/templates/workflows/archive.d.ts.map +1 -1
  240. package/dist/core/templates/workflows/archive.js +27 -9
  241. package/dist/core/templates/workflows/archive.js.map +1 -1
  242. package/dist/core/templates/workflows/decision.d.ts.map +1 -1
  243. package/dist/core/templates/workflows/decision.js +10 -4
  244. package/dist/core/templates/workflows/decision.js.map +1 -1
  245. package/dist/core/templates/workflows/explore.d.ts +2 -2
  246. package/dist/core/templates/workflows/explore.d.ts.map +1 -1
  247. package/dist/core/templates/workflows/explore.js +7 -3
  248. package/dist/core/templates/workflows/explore.js.map +1 -1
  249. package/dist/core/templates/workflows/grill.d.ts +2 -2
  250. package/dist/core/templates/workflows/grill.d.ts.map +1 -1
  251. package/dist/core/templates/workflows/grill.js +5 -4
  252. package/dist/core/templates/workflows/grill.js.map +1 -1
  253. package/dist/core/templates/workflows/issue.d.ts.map +1 -1
  254. package/dist/core/templates/workflows/issue.js +9 -3
  255. package/dist/core/templates/workflows/issue.js.map +1 -1
  256. package/dist/core/templates/workflows/propose.d.ts.map +1 -1
  257. package/dist/core/templates/workflows/propose.js +4 -1
  258. package/dist/core/templates/workflows/propose.js.map +1 -1
  259. package/dist/core/templates/workflows/sync.d.ts.map +1 -1
  260. package/dist/core/templates/workflows/sync.js +25 -11
  261. package/dist/core/templates/workflows/sync.js.map +1 -1
  262. package/dist/core/templates/workflows/update.d.ts.map +1 -1
  263. package/dist/core/templates/workflows/update.js +17 -10
  264. package/dist/core/templates/workflows/update.js.map +1 -1
  265. package/dist/core/update.d.ts +5 -0
  266. package/dist/core/update.d.ts.map +1 -1
  267. package/dist/core/update.js +69 -29
  268. package/dist/core/update.js.map +1 -1
  269. package/dist/core/validation/constants.d.ts +7 -1
  270. package/dist/core/validation/constants.d.ts.map +1 -1
  271. package/dist/core/validation/constants.js +16 -2
  272. package/dist/core/validation/constants.js.map +1 -1
  273. package/dist/core/validation/purpose-placeholder.d.ts.map +1 -1
  274. package/dist/core/validation/purpose-placeholder.js +35 -11
  275. package/dist/core/validation/purpose-placeholder.js.map +1 -1
  276. package/dist/core/validation/section-validator.d.ts +7 -0
  277. package/dist/core/validation/section-validator.d.ts.map +1 -1
  278. package/dist/core/validation/section-validator.js +22 -2
  279. package/dist/core/validation/section-validator.js.map +1 -1
  280. package/dist/core/validation/sister-changes.d.ts +93 -0
  281. package/dist/core/validation/sister-changes.d.ts.map +1 -0
  282. package/dist/core/validation/sister-changes.js +180 -0
  283. package/dist/core/validation/sister-changes.js.map +1 -0
  284. package/dist/core/validation/task-markers.d.ts +9 -0
  285. package/dist/core/validation/task-markers.d.ts.map +1 -0
  286. package/dist/core/validation/task-markers.js +71 -0
  287. package/dist/core/validation/task-markers.js.map +1 -0
  288. package/dist/core/validation/types.d.ts +58 -0
  289. package/dist/core/validation/types.d.ts.map +1 -1
  290. package/dist/core/validation/types.js +22 -0
  291. package/dist/core/validation/types.js.map +1 -1
  292. package/dist/core/validation/validator.d.ts +79 -2
  293. package/dist/core/validation/validator.d.ts.map +1 -1
  294. package/dist/core/validation/validator.js +565 -84
  295. package/dist/core/validation/validator.js.map +1 -1
  296. package/dist/utils/change-metadata.d.ts +62 -5
  297. package/dist/utils/change-metadata.d.ts.map +1 -1
  298. package/dist/utils/change-metadata.js +193 -31
  299. package/dist/utils/change-metadata.js.map +1 -1
  300. package/dist/utils/change-utils.d.ts +21 -0
  301. package/dist/utils/change-utils.d.ts.map +1 -1
  302. package/dist/utils/change-utils.js +168 -53
  303. package/dist/utils/change-utils.js.map +1 -1
  304. package/dist/utils/command-line.d.ts +11 -0
  305. package/dist/utils/command-line.d.ts.map +1 -0
  306. package/dist/utils/command-line.js +43 -0
  307. package/dist/utils/command-line.js.map +1 -0
  308. package/dist/utils/display-width.d.ts +10 -0
  309. package/dist/utils/display-width.d.ts.map +1 -0
  310. package/dist/utils/display-width.js +15 -0
  311. package/dist/utils/display-width.js.map +1 -0
  312. package/dist/utils/file-system.d.ts +16 -0
  313. package/dist/utils/file-system.d.ts.map +1 -1
  314. package/dist/utils/file-system.js +49 -2
  315. package/dist/utils/file-system.js.map +1 -1
  316. package/dist/utils/frontmatter.d.ts.map +1 -1
  317. package/dist/utils/frontmatter.js +11 -5
  318. package/dist/utils/frontmatter.js.map +1 -1
  319. package/dist/utils/interactive.d.ts.map +1 -1
  320. package/dist/utils/interactive.js +3 -1
  321. package/dist/utils/interactive.js.map +1 -1
  322. package/dist/utils/item-discovery.d.ts +3 -2
  323. package/dist/utils/item-discovery.d.ts.map +1 -1
  324. package/dist/utils/item-discovery.js +34 -16
  325. package/dist/utils/item-discovery.js.map +1 -1
  326. package/dist/utils/link.d.ts +0 -1
  327. package/dist/utils/link.d.ts.map +1 -1
  328. package/dist/utils/link.js +0 -1
  329. package/dist/utils/link.js.map +1 -1
  330. package/dist/utils/match.d.ts.map +1 -1
  331. package/dist/utils/match.js +10 -1
  332. package/dist/utils/match.js.map +1 -1
  333. package/dist/utils/option-flags.d.ts +9 -0
  334. package/dist/utils/option-flags.d.ts.map +1 -0
  335. package/dist/utils/option-flags.js +12 -0
  336. package/dist/utils/option-flags.js.map +1 -0
  337. package/dist/utils/sentence.d.ts +9 -0
  338. package/dist/utils/sentence.d.ts.map +1 -0
  339. package/dist/utils/sentence.js +12 -0
  340. package/dist/utils/sentence.js.map +1 -0
  341. package/dist/utils/spec-files.d.ts +84 -1
  342. package/dist/utils/spec-files.d.ts.map +1 -1
  343. package/dist/utils/spec-files.js +192 -3
  344. package/dist/utils/spec-files.js.map +1 -1
  345. package/dist/utils/task-progress.d.ts.map +1 -1
  346. package/dist/utils/task-progress.js +32 -9
  347. package/dist/utils/task-progress.js.map +1 -1
  348. package/dist/utils/timestamp.d.ts +27 -0
  349. package/dist/utils/timestamp.d.ts.map +1 -1
  350. package/dist/utils/timestamp.js +37 -0
  351. package/dist/utils/timestamp.js.map +1 -1
  352. package/package.json +6 -2
  353. package/schemas/decision/templates/decision.md +2 -2
  354. package/schemas/issue/schema.yaml +12 -6
  355. package/schemas/issue/templates/task.md +1 -1
  356. package/schemas/sdd/schema.yaml +21 -10
  357. package/schemas/sdd/templates/proposal.md +1 -1
  358. package/assets/dashboard/chart.umd.js +0 -14
@@ -2,7 +2,9 @@ import * as fs from 'node:fs';
2
2
  import * as path from 'node:path';
3
3
  import { fileURLToPath } from 'node:url';
4
4
  import { getGlobalConfigDir, getLegacyDataDir } from '../global-config.js';
5
- import { parseSchema, SchemaValidationError } from './schema.js';
5
+ import { findSchemaWarnings, parseSchema, SchemaValidationError } from './schema.js';
6
+ import { isChangeSchema } from '../schema-names.js';
7
+ import { isDirectoryEntry } from '../../utils/file-system.js';
6
8
  export class SchemaLoadError extends Error {
7
9
  schemaPath;
8
10
  cause;
@@ -39,25 +41,6 @@ function getLegacySchemasDir() {
39
41
  export function getProjectSchemasDir(projectRoot) {
40
42
  return path.join(projectRoot, 'tospec', 'schemas');
41
43
  }
42
- /**
43
- * True for real directories and for symlinks pointing at one. `Dirent`'s
44
- * `isDirectory()` reports the raw entry type, so a symlinked schema dir needs
45
- * the `statSync` dereference below.
46
- */
47
- export function isSchemaDir(parentDir, entry) {
48
- if (entry.isDirectory()) {
49
- return true;
50
- }
51
- if (entry.isSymbolicLink()) {
52
- try {
53
- return fs.statSync(path.join(parentDir, entry.name)).isDirectory();
54
- }
55
- catch {
56
- return false;
57
- }
58
- }
59
- return false;
60
- }
61
44
  /**
62
45
  * Identity of a file's current contents, for cache invalidation. Null when the
63
46
  * file cannot be stat'd, which disables caching for that path rather than
@@ -108,9 +91,24 @@ function scanSchemaDir(dir) {
108
91
  return [];
109
92
  return fs
110
93
  .readdirSync(dir, { withFileTypes: true })
111
- .filter((entry) => isSchemaDir(dir, entry) && fs.existsSync(path.join(dir, entry.name, 'schema.yaml')))
94
+ .filter((entry) => isDirectoryEntry(dir, entry) && fs.existsSync(path.join(dir, entry.name, 'schema.yaml')))
112
95
  .map((entry) => entry.name);
113
96
  }
97
+ /**
98
+ * A schema name is one directory inside a layer. `path.join` reads `../x` or
99
+ * `a/b` as a walk out of that layer, so `--schema ../../elsewhere/evil` (or the
100
+ * same value in `tospec/config.yaml`) loaded a schema from outside all three.
101
+ * `readdir` never yields `/`, `\`, `.` or `..`, so no listed schema is refused.
102
+ */
103
+ export function isSchemaName(name) {
104
+ return name !== '' && name !== '.' && name !== '..' && !/[\\/]/u.test(name);
105
+ }
106
+ /** @throws Error when `name` is a path rather than a schema name. */
107
+ export function assertSchemaName(name) {
108
+ if (!isSchemaName(name)) {
109
+ throw new Error(`Schema '${name}' is a path, not a schema name. Use the name of a schema directory; tospec schemas lists them.`);
110
+ }
111
+ }
114
112
  /**
115
113
  * The directory holding `<name>/schema.yaml` and the layer it came from, or
116
114
  * null when no layer has one. Project-local wins over the user override, which
@@ -122,6 +120,9 @@ function scanSchemaDir(dir) {
122
120
  * won" is what explains a file the winning layer does not have.
123
121
  */
124
122
  export function getSchemaDirWithSource(name, projectRoot) {
123
+ // The floor under every lookup, for a caller that skips assertSchemaName.
124
+ if (!isSchemaName(name))
125
+ return null;
125
126
  // Highest precedence first: project overrides user overrides package.
126
127
  for (const { dir, source } of schemaSources(projectRoot).reverse()) {
127
128
  const candidate = path.join(dir, name);
@@ -131,6 +132,42 @@ export function getSchemaDirWithSource(name, projectRoot) {
131
132
  }
132
133
  return null;
133
134
  }
135
+ /**
136
+ * The layer `name` would resolve from once the winning layer's directory is
137
+ * removed, or null when no lower layer has one. A broken override hides that
138
+ * layer from the list entirely, so this is how its fix can still say what
139
+ * deleting the override restores without a second entry in the JSON contract.
140
+ */
141
+ export function getShadowedSchemaSource(name, projectRoot) {
142
+ // Deduplicated by path: with XDG_DATA_HOME=~/.local/share the user and legacy
143
+ // entries are one directory, which counted a user-only schema as shadowing
144
+ // itself.
145
+ const seen = new Set();
146
+ const layers = schemaSources(projectRoot)
147
+ .reverse()
148
+ .filter(({ dir }) => {
149
+ const key = path.resolve(dir);
150
+ if (seen.has(key))
151
+ return false;
152
+ seen.add(key);
153
+ return fs.existsSync(path.join(dir, name, 'schema.yaml'));
154
+ });
155
+ return layers[1]?.source ?? null;
156
+ }
157
+ const SCHEMA_SOURCE_LABELS = { project: 'project', user: 'user override', package: 'package' };
158
+ /**
159
+ * The fix for a schema.yaml that does not load, shared by `schemas` and by the
160
+ * commands that read a change running under it. A broken override shadows the
161
+ * lower layer's schema, which `schemas` no longer lists, so removing the
162
+ * directory has to be named as the way back to it. "Its directory", not "the
163
+ * directory": next to a change, the bare phrase reads as the change's own.
164
+ */
165
+ export function unreadableSchemaFix(name, projectRoot) {
166
+ const fallback = getShadowedSchemaSource(name, projectRoot);
167
+ if (fallback === null)
168
+ return `Fix ${name}'s schema.yaml, or remove its directory.`;
169
+ return `Fix ${name}'s schema.yaml, or remove its directory to use the ${SCHEMA_SOURCE_LABELS[fallback]} schema of that name.`;
170
+ }
134
171
  /** As `getSchemaDirWithSource`, for callers that only need the path. */
135
172
  export function getSchemaDir(name, projectRoot) {
136
173
  return getSchemaDirWithSource(name, projectRoot)?.dir ?? null;
@@ -141,12 +178,24 @@ export function getSchemaDir(name, projectRoot) {
141
178
  * @throws SchemaLoadError when the file cannot be read or does not parse.
142
179
  */
143
180
  export function resolveSchema(name, projectRoot) {
181
+ return resolveSchemaOffering(name, projectRoot, () => true);
182
+ }
183
+ /**
184
+ * `resolveSchema` for the schema a change runs under. Only the "Available"
185
+ * list differs: a change whose name came from `tospec/config.yaml` and does not
186
+ * exist was offered `decision`, which no change may use.
187
+ */
188
+ export function resolveChangeSchema(name, projectRoot) {
189
+ return resolveSchemaOffering(name, projectRoot, isChangeSchema);
190
+ }
191
+ function resolveSchemaOffering(name, projectRoot, offered) {
144
192
  const normalizedName = name.replace(/\.ya?ml$/, '');
193
+ assertSchemaName(normalizedName);
145
194
  const schemaDir = getSchemaDir(normalizedName, projectRoot);
146
195
  if (!schemaDir) {
147
196
  // Loadable, not merely present: a name whose schema.yaml does not parse is
148
197
  // a choice that cannot work.
149
- const availableSchemas = listLoadableSchemas(projectRoot);
198
+ const availableSchemas = listLoadableSchemas(projectRoot).filter(offered);
150
199
  throw new Error(`Schema '${normalizedName}' not found. Available schemas: ${availableSchemas.join(', ')}`);
151
200
  }
152
201
  const schemaPath = path.join(schemaDir, 'schema.yaml');
@@ -204,39 +253,36 @@ export function listLoadableSchemas(projectRoot) {
204
253
  * Every schema with its description and artifact list, for agent skills that
205
254
  * present a schema choice.
206
255
  *
207
- * A schema that fails to parse is reported with `error` set, but only when no
208
- * lower-precedence layer supplies a working schema of that name — a broken
209
- * project override must not hide the package schema it shadows.
256
+ * A schema that fails to parse is reported with `error` set, even when a lower
257
+ * layer has a working schema of that name. Resolution picks the highest layer
258
+ * whose schema.yaml exists and does not fall back past one that fails to parse,
259
+ * so listing the layer below as working would advertise a schema every command
260
+ * then refuses.
210
261
  */
211
262
  export function listSchemasWithInfo(projectRoot) {
212
263
  const schemas = [];
213
264
  const seenNames = new Set();
214
- // Keyed by name so the highest-precedence failure is the one reported, and a
215
- // later success removes it.
216
- const broken = new Map();
217
265
  // Highest precedence first, so an overridden schema is skipped rather than
218
- // replaced. A schema that fails to parse is not marked seen — the next source
219
- // down still gets a chance to supply it.
266
+ // replaced — broken or not, the way `getSchemaDirWithSource` chooses.
220
267
  for (const { dir, source } of schemaSources(projectRoot).reverse()) {
221
268
  for (const name of scanSchemaDir(dir)) {
222
269
  if (seenNames.has(name))
223
270
  continue;
271
+ seenNames.add(name);
224
272
  try {
225
273
  const schema = parseSchema(fs.readFileSync(path.join(dir, name, 'schema.yaml'), 'utf-8'));
274
+ const warnings = findSchemaWarnings(schema);
226
275
  schemas.push({
227
276
  name,
228
277
  description: schema.description || '',
229
278
  artifacts: schema.artifacts.map((a) => a.id),
230
279
  source,
231
280
  path: path.join(dir, name),
281
+ ...(warnings.length ? { warnings } : {}),
232
282
  });
233
- seenNames.add(name);
234
- broken.delete(name);
235
283
  }
236
284
  catch (error) {
237
- if (broken.has(name))
238
- continue;
239
- broken.set(name, {
285
+ schemas.push({
240
286
  name,
241
287
  description: '',
242
288
  artifacts: [],
@@ -247,7 +293,7 @@ export function listSchemasWithInfo(projectRoot) {
247
293
  }
248
294
  }
249
295
  }
250
- return [...schemas, ...broken.values()].sort((a, b) => a.name.localeCompare(b.name));
296
+ return schemas.sort((a, b) => a.name.localeCompare(b.name));
251
297
  }
252
298
  /**
253
299
  * Union of every artifact ID across every available schema.
@@ -1 +1 @@
1
- {"version":3,"file":"resolver.js","sourceRoot":"","sources":["../../../src/core/artifact-graph/resolver.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"resolver.js","sourceRoot":"","sources":["../../../src/core/artifact-graph/resolver.ts"],"names":[],"mappings":"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"}
@@ -4,4 +4,28 @@ export declare class SchemaValidationError extends Error {
4
4
  }
5
5
  export declare function loadSchema(filePath: string): SchemaYaml;
6
6
  export declare function parseSchema(yamlContent: string): SchemaYaml;
7
+ /**
8
+ * Every code `findSchemaWarnings` can emit. A batch command uses it to print a
9
+ * schema's warning once rather than once per change on that schema; a
10
+ * per-change diagnostic such as `skip_specs_invalid` must not be folded that way.
11
+ */
12
+ export declare const SCHEMA_WARNING_CODES: ReadonlySet<string>;
13
+ /** A schema problem that still loads: reported alongside the command's output. */
14
+ export interface SchemaWarning {
15
+ code: string;
16
+ message: string;
17
+ fix: string;
18
+ }
19
+ /**
20
+ * Problems that leave the schema usable but make some command misreport.
21
+ *
22
+ * `apply.tracks` selects the tracked artifact by its `generates` value. One that
23
+ * matches no artifact made task progress fall back to `tasks.md`, so apply said
24
+ * "The TODO.md file is missing" while TODO.md sat in the change. A warning, not
25
+ * a load error: the schema's other workflows still work, and refusing to load it
26
+ * would break every change already on it. Reading `tracks` as a literal path
27
+ * instead was rejected: that is a second resolution rule `list`, the dashboard
28
+ * and the archive gate would not share.
29
+ */
30
+ export declare function findSchemaWarnings(schema: SchemaYaml): SchemaWarning[];
7
31
  //# sourceMappingURL=schema.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/core/artifact-graph/schema.ts"],"names":[],"mappings":"AAEA,OAAO,EAAoB,KAAK,UAAU,EAAiB,MAAM,YAAY,CAAC;AAE9E,qBAAa,qBAAsB,SAAQ,KAAK;IAC9C,YAAY,OAAO,EAAE,MAAM,EAG1B;CACF;AAED,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,CAEvD;AAED,wBAAgB,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,UAAU,CAmB3D"}
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/core/artifact-graph/schema.ts"],"names":[],"mappings":"AAEA,OAAO,EAAoB,KAAK,UAAU,EAAiB,MAAM,YAAY,CAAC;AAE9E,qBAAa,qBAAsB,SAAQ,KAAK;IAC9C,YAAY,OAAO,EAAE,MAAM,EAG1B;CACF;AAED,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,CAEvD;AAED,wBAAgB,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,UAAU,CAmB3D;AAED;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,EAAE,WAAW,CAAC,MAAM,CAAwC,CAAC;AAE9F,kFAAkF;AAClF,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,UAAU,GAAG,aAAa,EAAE,CAWtE"}
@@ -26,10 +26,41 @@ export function parseSchema(yamlContent) {
26
26
  validateApplyReferences(schema);
27
27
  return schema;
28
28
  }
29
+ /**
30
+ * Every code `findSchemaWarnings` can emit. A batch command uses it to print a
31
+ * schema's warning once rather than once per change on that schema; a
32
+ * per-change diagnostic such as `skip_specs_invalid` must not be folded that way.
33
+ */
34
+ export const SCHEMA_WARNING_CODES = new Set(['schema_tracks_unmatched']);
35
+ /**
36
+ * Problems that leave the schema usable but make some command misreport.
37
+ *
38
+ * `apply.tracks` selects the tracked artifact by its `generates` value. One that
39
+ * matches no artifact made task progress fall back to `tasks.md`, so apply said
40
+ * "The TODO.md file is missing" while TODO.md sat in the change. A warning, not
41
+ * a load error: the schema's other workflows still work, and refusing to load it
42
+ * would break every change already on it. Reading `tracks` as a literal path
43
+ * instead was rejected: that is a second resolution rule `list`, the dashboard
44
+ * and the archive gate would not share.
45
+ */
46
+ export function findSchemaWarnings(schema) {
47
+ const tracks = schema.apply?.tracks;
48
+ if (tracks == null || schema.artifacts.some((a) => a.generates === tracks))
49
+ return [];
50
+ const generates = schema.artifacts.map((a) => `'${a.generates}'`).join(', ');
51
+ return [
52
+ {
53
+ code: 'schema_tracks_unmatched',
54
+ message: `Schema '${schema.name}': apply.tracks '${tracks}' matches no artifact's generates value, so task progress falls back to tasks.md.`,
55
+ fix: `Set apply.tracks to the generates value of the artifact that holds the tasks (one of: ${generates}).`,
56
+ },
57
+ ];
58
+ }
29
59
  /**
30
60
  * `tracks` is not checked alongside `requires`: it names a file inside the
31
61
  * change directory, not an artifact id, and that file legitimately does not
32
- * exist until the change is scaffolded.
62
+ * exist until the change is scaffolded. Whether it names an artifact's output
63
+ * is `findSchemaWarnings`'s concern.
33
64
  */
34
65
  function validateApplyReferences(schema) {
35
66
  if (!schema.apply)
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/core/artifact-graph/schema.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/core/artifact-graph/schema.ts"],"names":[],"mappings":"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"}
@@ -1,12 +1,20 @@
1
1
  /**
2
2
  * The one definition of "this artifact file is still the template": empty,
3
- * whitespace-only, or byte-identical to it.
3
+ * whitespace-only, or identical to it once BOM and line endings are set aside.
4
4
  *
5
- * Shared by `status` and `validate`, which must agree: a change of verbatim
5
+ * Shared by `status`, `validate` and `instructions apply` (through
6
+ * `loadChangeContext`), which must agree: a change of verbatim
6
7
  * templates would otherwise pass the last gate before archive.
7
8
  *
8
9
  * Cheap on purpose. A deeper "headings replaced, placeholders left" analysis
9
10
  * belongs to the section rules in `validation/section-validator.ts`.
10
11
  */
11
12
  export declare function isStubArtifactFile(file: string, schemaName: string, templatePath: string, projectRoot: string): boolean;
13
+ /**
14
+ * Which kind of stub the file is, or null when it is not one. Kept apart for
15
+ * the wording only: calling an empty file "the unfilled template" sends the
16
+ * reader to compare it against a template it never held.
17
+ */
18
+ export type StubKind = 'empty' | 'template';
19
+ export declare function detectStubArtifact(file: string, schemaName: string, templatePath: string, projectRoot: string): StubKind | null;
12
20
  //# sourceMappingURL=stub-detection.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"stub-detection.d.ts","sourceRoot":"","sources":["../../../src/core/artifact-graph/stub-detection.ts"],"names":[],"mappings":"AAIA;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,MAAM,GAClB,OAAO,CAqBT"}
1
+ {"version":3,"file":"stub-detection.d.ts","sourceRoot":"","sources":["../../../src/core/artifact-graph/stub-detection.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,MAAM,GAClB,OAAO,CAET;AAED;;;;GAIG;AACH,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,UAAU,CAAC;AAE5C,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,MAAM,GAClB,QAAQ,GAAG,IAAI,CAwBjB"}
@@ -1,39 +1,46 @@
1
1
  import * as fs from 'fs';
2
- import { stripBom } from '../parsers/requirement-text.js';
2
+ import { normalizeDocument } from '../parsers/requirement-text.js';
3
3
  import { loadTemplate } from './instruction-loader.js';
4
4
  /**
5
5
  * The one definition of "this artifact file is still the template": empty,
6
- * whitespace-only, or byte-identical to it.
6
+ * whitespace-only, or identical to it once BOM and line endings are set aside.
7
7
  *
8
- * Shared by `status` and `validate`, which must agree: a change of verbatim
8
+ * Shared by `status`, `validate` and `instructions apply` (through
9
+ * `loadChangeContext`), which must agree: a change of verbatim
9
10
  * templates would otherwise pass the last gate before archive.
10
11
  *
11
12
  * Cheap on purpose. A deeper "headings replaced, placeholders left" analysis
12
13
  * belongs to the section rules in `validation/section-validator.ts`.
13
14
  */
14
15
  export function isStubArtifactFile(file, schemaName, templatePath, projectRoot) {
16
+ return detectStubArtifact(file, schemaName, templatePath, projectRoot) !== null;
17
+ }
18
+ export function detectStubArtifact(file, schemaName, templatePath, projectRoot) {
15
19
  let content;
16
20
  try {
17
21
  content = fs.readFileSync(file, 'utf-8');
18
22
  }
19
23
  catch {
20
24
  // Unreadable is not stub: callers report the read failure on its own terms.
21
- return false;
25
+ return null;
22
26
  }
23
27
  if (content.trim().length === 0)
24
- return true;
28
+ return 'empty';
25
29
  let template;
26
30
  try {
27
31
  template = loadTemplate(schemaName, templatePath, projectRoot);
28
32
  }
29
33
  catch {
30
34
  // No template to compare against — say nothing rather than guess.
31
- return false;
35
+ return null;
32
36
  }
33
- // Compared BOM-free: this is a byte-identity test, so opening the untouched
34
- // template in a Windows editor and saving it would otherwise make a verbatim
35
- // stub look edited — inverting the gate, which exists to stop exactly that
36
- // file reaching archive. The template ships from the package and never has one.
37
- return stripBom(content) === template;
37
+ // Compared BOM-free and LF-only on both sides: this is an identity test, so
38
+ // opening the untouched template in a Windows editor and saving it (which
39
+ // adds a BOM, or turns every newline into CRLF) would otherwise make a
40
+ // verbatim stub look edited — inverting the gate, which exists to stop
41
+ // exactly that file reaching archive. The template side is normalized too:
42
+ // a project override, or a checkout with `core.autocrlf`, can be CRLF while
43
+ // the agent writes its copy with LF.
44
+ return normalizeDocument(content) === normalizeDocument(template) ? 'template' : null;
38
45
  }
39
46
  //# sourceMappingURL=stub-detection.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"stub-detection.js","sourceRoot":"","sources":["../../../src/core/artifact-graph/stub-detection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAEvD;;;;;;;;;GASG;AACH,MAAM,UAAU,kBAAkB,CAChC,IAAY,EACZ,UAAkB,EAClB,YAAoB,EACpB,WAAmB;IAEnB,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACH,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC3C,CAAC;IAAC,MAAM,CAAC;QACP,4EAA4E;QAC5E,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAC7C,IAAI,QAAgB,CAAC;IACrB,IAAI,CAAC;QACH,QAAQ,GAAG,YAAY,CAAC,UAAU,EAAE,YAAY,EAAE,WAAW,CAAC,CAAC;IACjE,CAAC;IAAC,MAAM,CAAC;QACP,kEAAkE;QAClE,OAAO,KAAK,CAAC;IACf,CAAC;IACD,4EAA4E;IAC5E,6EAA6E;IAC7E,2EAA2E;IAC3E,gFAAgF;IAChF,OAAO,QAAQ,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC;AACxC,CAAC"}
1
+ {"version":3,"file":"stub-detection.js","sourceRoot":"","sources":["../../../src/core/artifact-graph/stub-detection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAEvD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,kBAAkB,CAChC,IAAY,EACZ,UAAkB,EAClB,YAAoB,EACpB,WAAmB;IAEnB,OAAO,kBAAkB,CAAC,IAAI,EAAE,UAAU,EAAE,YAAY,EAAE,WAAW,CAAC,KAAK,IAAI,CAAC;AAClF,CAAC;AASD,MAAM,UAAU,kBAAkB,CAChC,IAAY,EACZ,UAAkB,EAClB,YAAoB,EACpB,WAAmB;IAEnB,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACH,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC3C,CAAC;IAAC,MAAM,CAAC;QACP,4EAA4E;QAC5E,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,OAAO,CAAC;IAChD,IAAI,QAAgB,CAAC;IACrB,IAAI,CAAC;QACH,QAAQ,GAAG,YAAY,CAAC,UAAU,EAAE,YAAY,EAAE,WAAW,CAAC,CAAC;IACjE,CAAC;IAAC,MAAM,CAAC;QACP,kEAAkE;QAClE,OAAO,IAAI,CAAC;IACd,CAAC;IACD,4EAA4E;IAC5E,0EAA0E;IAC1E,uEAAuE;IACvE,uEAAuE;IACvE,2EAA2E;IAC3E,4EAA4E;IAC5E,qCAAqC;IACrC,OAAO,iBAAiB,CAAC,OAAO,CAAC,KAAK,iBAAiB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC;AACxF,CAAC"}
@@ -20,7 +20,7 @@ export declare const ArtifactSchema: z.ZodObject<{
20
20
  }, z.core.$strip>;
21
21
  export declare const ApplyPhaseSchema: z.ZodObject<{
22
22
  requires: z.ZodArray<z.ZodString>;
23
- tracks: z.ZodOptional<z.ZodNullable<z.ZodString>>;
23
+ tracks: z.ZodPipe<z.ZodOptional<z.ZodNullable<z.ZodString>>, z.ZodTransform<string | null | undefined, string | null | undefined>>;
24
24
  instruction: z.ZodOptional<z.ZodString>;
25
25
  }, z.core.$strip>;
26
26
  export declare const SchemaYamlSchema: z.ZodObject<{
@@ -43,7 +43,7 @@ export declare const SchemaYamlSchema: z.ZodObject<{
43
43
  }, z.core.$strip>>;
44
44
  apply: z.ZodOptional<z.ZodObject<{
45
45
  requires: z.ZodArray<z.ZodString>;
46
- tracks: z.ZodOptional<z.ZodNullable<z.ZodString>>;
46
+ tracks: z.ZodPipe<z.ZodOptional<z.ZodNullable<z.ZodString>>, z.ZodTransform<string | null | undefined, string | null | undefined>>;
47
47
  instruction: z.ZodOptional<z.ZodString>;
48
48
  }, z.core.$strip>>;
49
49
  }, z.core.$strip>;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/core/artifact-graph/types.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,eAAO,MAAM,wBAAwB;;;;iBAMnC,CAAC;AA4CH,eAAO,MAAM,cAAc;;;;;;;;;;;;;iBASzB,CAAC;AAEH,eAAO,MAAM,gBAAgB;;;;iBAM3B,CAAC;AAEH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;iBAM3B,CAAC;AAEH,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AACtD,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAC1E,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC1D,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D,6CAA6C;AAC7C,MAAM,MAAM,YAAY,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC;AAEvC,MAAM,WAAW,gBAAgB;IAC/B,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CAChC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/core/artifact-graph/types.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,eAAO,MAAM,wBAAwB;;;;iBAMnC,CAAC;AA4CH,eAAO,MAAM,cAAc;;;;;;;;;;;;;iBASzB,CAAC;AAEH,eAAO,MAAM,gBAAgB;;;;iBAe3B,CAAC;AAEH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;iBAM3B,CAAC;AAEH,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AACtD,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAC1E,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC1D,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D,6CAA6C;AAC7C,MAAM,MAAM,YAAY,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC;AAEvC,MAAM,WAAW,gBAAgB;IAC/B,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CAChC"}
@@ -60,7 +60,16 @@ export const ApplyPhaseSchema = z.object({
60
60
  /** Artifact IDs that must exist before apply is available. */
61
61
  requires: z.array(z.string()).min(1, { error: 'At least one required artifact' }),
62
62
  /** Change-relative path to the file holding progress checkboxes; null for none. */
63
- tracks: z.string().nullable().optional(),
63
+ // '' becomes null here, once, because readers split on it: apply tested the
64
+ // value for truthiness and saw "no tracks", while task progress and
65
+ // findSchemaWarnings tested `!= null` and saw a filename matching nothing,
66
+ // so list and archive counted tasks.md and the warning claimed that fallback.
67
+ // An empty filename names no file, so "none" is the only reading all agree on.
68
+ tracks: z
69
+ .string()
70
+ .nullable()
71
+ .optional()
72
+ .transform((value) => (value === '' ? null : value)),
64
73
  instruction: z.string().optional(),
65
74
  });
66
75
  export const SchemaYamlSchema = z.object({
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/core/artifact-graph/types.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,wEAAwE;AACxE,8EAA8E;AAC9E,gCAAgC;AAChC,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC/C,gBAAgB,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IACjD,gBAAgB,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IAC9D,kEAAkE;IAClE,sEAAsE;IACtE,gBAAgB,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;CAC/D,CAAC,CAAC;AAEH;;;;;;;;;;;GAWG;AACH,MAAM,uBAAuB,GAAG,CAAC;KAC9B,MAAM,EAAE;KACR,GAAG,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,6BAA6B,EAAE,CAAC;KAChD,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;IACvE,KAAK,EAAE,qFAAqF;CAC7F,CAAC;KACD,MAAM,CACL,CAAC,KAAK,EAAE,EAAE,CACR,CAAC,KAAK;KACH,KAAK,CAAC,OAAO,CAAC;KACd,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,KAAK,IAAI,CAAC,EACxC,EAAE,KAAK,EAAE,4EAA4E,EAAE,CACxF,CAAC;AAEJ;;;;;GAKG;AACH,MAAM,0BAA0B,GAAG,CAAC;KACjC,MAAM,EAAE;KACR,GAAG,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,4BAA4B,EAAE,CAAC;KAC/C,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;IACvE,KAAK,EAAE,kGAAkG;CAC1G,CAAC;KACD,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,KAAK,IAAI,CAAC,EAAE;IAC5E,KAAK,EAAE,yFAAyF;CACjG,CAAC,CAAC;AAEL,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC;IACrC,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,yBAAyB,EAAE,CAAC;IAC3D,SAAS,EAAE,uBAAuB;IAClC,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;IACvB,QAAQ,EAAE,0BAA0B;IACpC,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAClC,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IACzC,QAAQ,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;IACpC,UAAU,EAAE,wBAAwB,CAAC,QAAQ,EAAE;CAChD,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IACvC,8DAA8D;IAC9D,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,gCAAgC,EAAE,CAAC;IACjF,mFAAmF;IACnF,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IACxC,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CACnC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IACvC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,yBAAyB,EAAE,CAAC;IAC7D,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,oCAAoC,EAAE,CAAC;IACnF,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAClC,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,gCAAgC,EAAE,CAAC;IACtF,KAAK,EAAE,gBAAgB,CAAC,QAAQ,EAAE;CACnC,CAAC,CAAC"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/core/artifact-graph/types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/core/change-metadata/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,eAAO,MAAM,oBAAoB;;;;;;;;;;iBAwB/B,CAAC;AAEH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC"}
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/core/change-metadata/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,eAAO,MAAM,oBAAoB;;;;;;;;;;iBAsC/B,CAAC;AAEH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import { z } from 'zod';
2
+ import { CREATED_PATTERN, parseCreated } from '../../utils/timestamp.js';
2
3
  // Per-change metadata schema. The schema field is validated against available
3
4
  // workflow schemas when metadata is read or written.
4
5
  export const ChangeMetadataSchema = z.object({
@@ -8,10 +9,21 @@ export const ChangeMetadataSchema = z.object({
8
9
  // the file exists or not: take the project default.
9
10
  schema: z.string().min(1, { message: 'schema must be a non-empty string' }).optional(),
10
11
  type: z.enum(['requirement', 'issue']).optional(),
12
+ // `new change` writes the local datetime; the day alone is what changes
13
+ // made before it recorded, and it stays valid so they keep reading.
14
+ // The pattern alone let `2026-02-30` through: validate called it valid, and
15
+ // the only check that refused it was sister ordering, which read it as "no
16
+ // order" without saying why. `abort` keeps a misspelled value to the format
17
+ // message instead of also claiming it names no real moment. No `;` in the
18
+ // messages: describeMetadataIssues joins one field's issue to the next's with it.
11
19
  created: z
12
20
  .string()
13
- .regex(/^\d{4}-\d{2}-\d{2}$/, {
14
- message: 'created must be YYYY-MM-DD format',
21
+ .regex(CREATED_PATTERN, {
22
+ message: 'created must be YYYY-MM-DDTHH:mm:ss (local time) or YYYY-MM-DD format',
23
+ abort: true,
24
+ })
25
+ .refine((value) => parseCreated(value) !== null, {
26
+ message: 'created names a date or time that does not exist (e.g. 2026-02-30 or T25:00:00): use a real YYYY-MM-DDTHH:mm:ss (local time) or YYYY-MM-DD',
15
27
  })
16
28
  .optional(),
17
29
  goal: z.string().min(1).optional(),
@@ -19,8 +31,10 @@ export const ChangeMetadataSchema = z.object({
19
31
  // "20260722_161825-topic.md" under tospec/decisions/. Optional so existing
20
32
  // metadata files without the field stay valid; absent means none.
21
33
  decisions: z.array(z.string().min(1)).optional(),
22
- // Declares that this change intentionally has no behavioral effect, waiving
23
- // the "at least one delta" rule. A property of the change, not archive's
34
+ // Records the user's decision that this change needs no delta spec, waiving
35
+ // the "at least one delta" rule; set only on the user's word, and a spec
36
+ // file beside it is a contradiction validate refuses, not a delta the waiver
37
+ // hides. A property of the change, not archive's
24
38
  // one-shot --skip-specs flag: letting the flag imply this would make
25
39
  // `tospec validate` answer differently depending on how archive was last run.
26
40
  // Read via readSkipSpecsMarker, which reports a non-boolean value as an error.
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/core/change-metadata/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,8EAA8E;AAC9E,qDAAqD;AACrD,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3C,8EAA8E;IAC9E,6EAA6E;IAC7E,4EAA4E;IAC5E,oDAAoD;IACpD,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,mCAAmC,EAAE,CAAC,CAAC,QAAQ,EAAE;IACtF,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE;IACjD,OAAO,EAAE,CAAC;SACP,MAAM,EAAE;SACR,KAAK,CAAC,qBAAqB,EAAE;QAC5B,OAAO,EAAE,mCAAmC;KAC7C,CAAC;SACD,QAAQ,EAAE;IACb,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IAClC,qDAAqD;IACrD,2EAA2E;IAC3E,kEAAkE;IAClE,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IAChD,4EAA4E;IAC5E,yEAAyE;IACzE,qEAAqE;IACrE,8EAA8E;IAC9E,+EAA+E;IAC/E,UAAU,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;CACnC,CAAC,CAAC"}
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/core/change-metadata/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAEzE,8EAA8E;AAC9E,qDAAqD;AACrD,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3C,8EAA8E;IAC9E,6EAA6E;IAC7E,4EAA4E;IAC5E,oDAAoD;IACpD,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,mCAAmC,EAAE,CAAC,CAAC,QAAQ,EAAE;IACtF,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE;IACjD,wEAAwE;IACxE,oEAAoE;IACpE,4EAA4E;IAC5E,2EAA2E;IAC3E,4EAA4E;IAC5E,0EAA0E;IAC1E,kFAAkF;IAClF,OAAO,EAAE,CAAC;SACP,MAAM,EAAE;SACR,KAAK,CAAC,eAAe,EAAE;QACtB,OAAO,EAAE,uEAAuE;QAChF,KAAK,EAAE,IAAI;KACZ,CAAC;SACD,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE;QAC/C,OAAO,EACL,4IAA4I;KAC/I,CAAC;SACD,QAAQ,EAAE;IACb,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IAClC,qDAAqD;IACrD,2EAA2E;IAC3E,kEAAkE;IAClE,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IAChD,4EAA4E;IAC5E,yEAAyE;IACzE,6EAA6E;IAC7E,iDAAiD;IACjD,qEAAqE;IACrE,8EAA8E;IAC9E,+EAA+E;IAC/E,UAAU,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;CACnC,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"change-presenter.d.ts","sourceRoot":"","sources":["../../src/core/change-presenter.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AA6BtD,qBAAa,eAAe;IAC1B,OAAO,CAAC,SAAS,CAAgB;IACjC,OAAO,CAAC,QAAQ,CAAC,CAAS;IAI1B,YAAY,QAAQ,CAAC,EAAE,MAAM,EAG5B;IAED,OAAO,CAAC,cAAc;IAMtB,OAAO,CAAC,YAAY;IAIpB;;;;;OAKG;IACG,IAAI,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,OAAO,CAAC;QAAC,gBAAgB,CAAC,EAAE,OAAO,CAAC;QAAC,UAAU,CAAC,EAAE,OAAO,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAC;QAAC,aAAa,CAAC,EAAE,OAAO,CAAC;QAAC,UAAU,CAAC,EAAE,UAAU,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAiF/L;IAED;;;;;OAKG;IACH,OAAO,CAAC,gBAAgB;IAaxB;;;;iBAIa,SAKC,gBAAgB;IAkB9B;;;;;OAKG;YACW,gBAAgB;IA2F9B;;;;;OAKG;YACW,qBAAqB;IAiCnC,8EAA8E;YAChE,aAAa;IAe3B,OAAO,CAAC,aAAa;YAsDP,UAAU;IASxB,OAAO,CAAC,YAAY;CASrB"}
1
+ {"version":3,"file":"change-presenter.d.ts","sourceRoot":"","sources":["../../src/core/change-presenter.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AA8BtD,qBAAa,eAAe;IAC1B,OAAO,CAAC,SAAS,CAAgB;IACjC,OAAO,CAAC,QAAQ,CAAC,CAAS;IAI1B,YAAY,QAAQ,CAAC,EAAE,MAAM,EAG5B;IAED,OAAO,CAAC,cAAc;IAMtB,OAAO,CAAC,YAAY;IAIpB;;;;;OAKG;IACG,IAAI,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,OAAO,CAAC;QAAC,gBAAgB,CAAC,EAAE,OAAO,CAAC;QAAC,UAAU,CAAC,EAAE,OAAO,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAC;QAAC,aAAa,CAAC,EAAE,OAAO,CAAC;QAAC,UAAU,CAAC,EAAE,UAAU,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAmF/L;IAED;;;;;OAKG;IACH,OAAO,CAAC,gBAAgB;IAaxB;;;;iBAIa,SAKC,gBAAgB;IAkB9B;;;;;OAKG;YACW,gBAAgB;IA2F9B;;;;;OAKG;YACW,qBAAqB;IAiCnC,8EAA8E;YAChE,aAAa;IAe3B,OAAO,CAAC,aAAa;YAsDP,UAAU;IASxB,OAAO,CAAC,YAAY;CAWrB"}
@@ -10,7 +10,8 @@ import { findSpecUpdates } from './specs-apply.js';
10
10
  import { resolveSchemaForChange } from '../utils/change-metadata.js';
11
11
  import { resolveSchema } from './artifact-graph/index.js';
12
12
  import { foldRequirementName, parseDeltaSpec } from './parsers/requirement-blocks.js';
13
- import { stripBom } from './parsers/requirement-text.js';
13
+ import { stripClosingHashes } from './parsers/requirement-text.js';
14
+ import { MarkdownParser } from './parsers/markdown-parser.js';
14
15
  import { buildRenameMap, diffRequirementBlock, extractRequirementBlock, } from '../utils/requirement-diff.js';
15
16
  export class ChangePresenter {
16
17
  converter;
@@ -73,6 +74,11 @@ export class ChangePresenter {
73
74
  if (!primaryPath || !(await this.fileExists(primaryPath))) {
74
75
  throw new Error(`Change "${changeName}" not found (no main artifact in ${changeDir}, no ticket in tospec/tickets/)`);
75
76
  }
77
+ // Both modes: printed in the --json branch only, a human run accepted the
78
+ // deprecated flag with no word. stderr, so --json stdout stays one document.
79
+ if (options?.requirementsOnly) {
80
+ console.error('Warning: Flag --requirements-only is deprecated; use --deltas-only instead.');
81
+ }
76
82
  if (options?.json) {
77
83
  const parser = new ChangeParser('', changeDir);
78
84
  let deltas = await parser.parseDeltaSpecs(path.join(changeDir, 'specs'));
@@ -86,9 +92,6 @@ export class ChangePresenter {
86
92
  // No inline deltas — proposal is prose only, which is fine.
87
93
  }
88
94
  }
89
- if (options.requirementsOnly) {
90
- console.error('Flag --requirements-only is deprecated; use --deltas-only instead.');
91
- }
92
95
  if (options.diff) {
93
96
  await this.enrichDeltasWithDiffs(deltas, changeDir);
94
97
  }
@@ -357,10 +360,12 @@ ${body}`;
357
360
  const fmTitle = frontmatterString(content, 'title')?.trim();
358
361
  if (fmTitle)
359
362
  return fmTitle;
360
- // `frontmatterString` strips the BOM itself; this fallback reads the raw
361
- // text, where a BOM sits between `^` and the `#` of a first-line H1.
362
- const match = stripBom(content).match(/^#\s+(?:Change:\s+)?(.+)$/im);
363
- return match ? match[1].trim() : changeName;
363
+ // The H1 as `decision` reads one: through the parser, so a fenced `# x` is
364
+ // no title, and without the closing `#` run. A local regex kept that run,
365
+ // so `# Use X ##` titled the change `Use X ##`.
366
+ const h1 = new MarkdownParser(content).getSections().find((section) => section.level === 1);
367
+ const title = h1 ? stripClosingHashes(h1.title).replace(/^Change:\s+/i, '') : '';
368
+ return title || changeName;
364
369
  }
365
370
  }
366
371
  //# sourceMappingURL=change-presenter.js.map