@seanmars/tospec 0.19.0-beta.1 → 0.19.0-beta.13

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 (428) hide show
  1. package/CHANGELOG.md +530 -0
  2. package/README.md +71 -77
  3. package/assets/dashboard/app.js +14 -3
  4. package/assets/dashboard/style.css +7 -0
  5. package/assets/rules/tospec/decision.md +3 -0
  6. package/assets/rules/tospec/single-source-of-truth.md +19 -0
  7. package/dist/cli/index.d.ts.map +1 -1
  8. package/dist/cli/index.js +254 -83
  9. package/dist/cli/index.js.map +1 -1
  10. package/dist/commands/config.d.ts +9 -17
  11. package/dist/commands/config.d.ts.map +1 -1
  12. package/dist/commands/config.js +374 -98
  13. package/dist/commands/config.js.map +1 -1
  14. package/dist/commands/dashboard.d.ts +64 -81
  15. package/dist/commands/dashboard.d.ts.map +1 -1
  16. package/dist/commands/dashboard.js +346 -230
  17. package/dist/commands/dashboard.js.map +1 -1
  18. package/dist/commands/decision.d.ts +41 -19
  19. package/dist/commands/decision.d.ts.map +1 -1
  20. package/dist/commands/decision.js +400 -70
  21. package/dist/commands/decision.js.map +1 -1
  22. package/dist/commands/metrics.d.ts +28 -51
  23. package/dist/commands/metrics.d.ts.map +1 -1
  24. package/dist/commands/metrics.js +69 -85
  25. package/dist/commands/metrics.js.map +1 -1
  26. package/dist/commands/shared-output.d.ts +18 -21
  27. package/dist/commands/shared-output.d.ts.map +1 -1
  28. package/dist/commands/shared-output.js +49 -23
  29. package/dist/commands/shared-output.js.map +1 -1
  30. package/dist/commands/show.d.ts +7 -0
  31. package/dist/commands/show.d.ts.map +1 -1
  32. package/dist/commands/show.js +39 -8
  33. package/dist/commands/show.js.map +1 -1
  34. package/dist/commands/validate.d.ts +47 -30
  35. package/dist/commands/validate.d.ts.map +1 -1
  36. package/dist/commands/validate.js +282 -108
  37. package/dist/commands/validate.js.map +1 -1
  38. package/dist/commands/workflow/index.d.ts +6 -10
  39. package/dist/commands/workflow/index.d.ts.map +1 -1
  40. package/dist/commands/workflow/index.js +6 -10
  41. package/dist/commands/workflow/index.js.map +1 -1
  42. package/dist/commands/workflow/instructions.d.ts +21 -8
  43. package/dist/commands/workflow/instructions.d.ts.map +1 -1
  44. package/dist/commands/workflow/instructions.js +254 -95
  45. package/dist/commands/workflow/instructions.js.map +1 -1
  46. package/dist/commands/workflow/new-change.d.ts +4 -5
  47. package/dist/commands/workflow/new-change.d.ts.map +1 -1
  48. package/dist/commands/workflow/new-change.js +90 -25
  49. package/dist/commands/workflow/new-change.js.map +1 -1
  50. package/dist/commands/workflow/schemas.d.ts +3 -5
  51. package/dist/commands/workflow/schemas.d.ts.map +1 -1
  52. package/dist/commands/workflow/schemas.js +37 -11
  53. package/dist/commands/workflow/schemas.js.map +1 -1
  54. package/dist/commands/workflow/shared.d.ts +48 -21
  55. package/dist/commands/workflow/shared.d.ts.map +1 -1
  56. package/dist/commands/workflow/shared.js +36 -33
  57. package/dist/commands/workflow/shared.js.map +1 -1
  58. package/dist/commands/workflow/status.d.ts +10 -6
  59. package/dist/commands/workflow/status.d.ts.map +1 -1
  60. package/dist/commands/workflow/status.js +84 -42
  61. package/dist/commands/workflow/status.js.map +1 -1
  62. package/dist/commands/workflow/templates.d.ts +10 -3
  63. package/dist/commands/workflow/templates.d.ts.map +1 -1
  64. package/dist/commands/workflow/templates.js +39 -40
  65. package/dist/commands/workflow/templates.js.map +1 -1
  66. package/dist/core/archive.d.ts +26 -21
  67. package/dist/core/archive.d.ts.map +1 -1
  68. package/dist/core/archive.js +386 -205
  69. package/dist/core/archive.js.map +1 -1
  70. package/dist/core/artifact-graph/graph.d.ts +29 -36
  71. package/dist/core/artifact-graph/graph.d.ts.map +1 -1
  72. package/dist/core/artifact-graph/graph.js +50 -58
  73. package/dist/core/artifact-graph/graph.js.map +1 -1
  74. package/dist/core/artifact-graph/index.d.ts +1 -1
  75. package/dist/core/artifact-graph/index.d.ts.map +1 -1
  76. package/dist/core/artifact-graph/index.js +1 -1
  77. package/dist/core/artifact-graph/index.js.map +1 -1
  78. package/dist/core/artifact-graph/instruction-loader.d.ts +105 -100
  79. package/dist/core/artifact-graph/instruction-loader.d.ts.map +1 -1
  80. package/dist/core/artifact-graph/instruction-loader.js +176 -110
  81. package/dist/core/artifact-graph/instruction-loader.js.map +1 -1
  82. package/dist/core/artifact-graph/outputs.d.ts +11 -14
  83. package/dist/core/artifact-graph/outputs.d.ts.map +1 -1
  84. package/dist/core/artifact-graph/outputs.js +47 -29
  85. package/dist/core/artifact-graph/outputs.js.map +1 -1
  86. package/dist/core/artifact-graph/resolver.d.ts +44 -63
  87. package/dist/core/artifact-graph/resolver.d.ts.map +1 -1
  88. package/dist/core/artifact-graph/resolver.js +85 -86
  89. package/dist/core/artifact-graph/resolver.js.map +1 -1
  90. package/dist/core/artifact-graph/schema.d.ts +0 -6
  91. package/dist/core/artifact-graph/schema.d.ts.map +1 -1
  92. package/dist/core/artifact-graph/schema.js +7 -32
  93. package/dist/core/artifact-graph/schema.js.map +1 -1
  94. package/dist/core/artifact-graph/state.d.ts +1 -8
  95. package/dist/core/artifact-graph/state.d.ts.map +1 -1
  96. package/dist/core/artifact-graph/state.js +2 -17
  97. package/dist/core/artifact-graph/state.js.map +1 -1
  98. package/dist/core/artifact-graph/stub-detection.d.ts +12 -0
  99. package/dist/core/artifact-graph/stub-detection.d.ts.map +1 -0
  100. package/dist/core/artifact-graph/stub-detection.js +39 -0
  101. package/dist/core/artifact-graph/stub-detection.js.map +1 -0
  102. package/dist/core/artifact-graph/types.d.ts +4 -0
  103. package/dist/core/artifact-graph/types.d.ts.map +1 -1
  104. package/dist/core/artifact-graph/types.js +30 -10
  105. package/dist/core/artifact-graph/types.js.map +1 -1
  106. package/dist/core/available-tools.d.ts +3 -12
  107. package/dist/core/available-tools.d.ts.map +1 -1
  108. package/dist/core/available-tools.js +4 -13
  109. package/dist/core/available-tools.js.map +1 -1
  110. package/dist/core/change-metadata/schema.d.ts +1 -1
  111. package/dist/core/change-metadata/schema.d.ts.map +1 -1
  112. package/dist/core/change-metadata/schema.js +10 -7
  113. package/dist/core/change-metadata/schema.js.map +1 -1
  114. package/dist/core/change-presenter.d.ts +23 -18
  115. package/dist/core/change-presenter.d.ts.map +1 -1
  116. package/dist/core/change-presenter.js +102 -43
  117. package/dist/core/change-presenter.js.map +1 -1
  118. package/dist/core/change-status-policy.d.ts +8 -1
  119. package/dist/core/change-status-policy.d.ts.map +1 -1
  120. package/dist/core/change-status-policy.js +25 -1
  121. package/dist/core/change-status-policy.js.map +1 -1
  122. package/dist/core/codex-metrics.d.ts +25 -45
  123. package/dist/core/codex-metrics.d.ts.map +1 -1
  124. package/dist/core/codex-metrics.js +44 -88
  125. package/dist/core/codex-metrics.js.map +1 -1
  126. package/dist/core/codex-residue.d.ts +22 -0
  127. package/dist/core/codex-residue.d.ts.map +1 -0
  128. package/dist/core/codex-residue.js +61 -0
  129. package/dist/core/codex-residue.js.map +1 -0
  130. package/dist/core/command-generation/adapters/claude.d.ts +2 -9
  131. package/dist/core/command-generation/adapters/claude.d.ts.map +1 -1
  132. package/dist/core/command-generation/adapters/claude.js +2 -12
  133. package/dist/core/command-generation/adapters/claude.js.map +1 -1
  134. package/dist/core/command-generation/adapters/index.d.ts +1 -9
  135. package/dist/core/command-generation/adapters/index.d.ts.map +1 -1
  136. package/dist/core/command-generation/adapters/index.js +1 -9
  137. package/dist/core/command-generation/adapters/index.js.map +1 -1
  138. package/dist/core/command-generation/generator.d.ts +0 -17
  139. package/dist/core/command-generation/generator.d.ts.map +1 -1
  140. package/dist/core/command-generation/generator.js +0 -17
  141. package/dist/core/command-generation/generator.js.map +1 -1
  142. package/dist/core/command-generation/index.d.ts +2 -5
  143. package/dist/core/command-generation/index.d.ts.map +1 -1
  144. package/dist/core/command-generation/index.js +0 -9
  145. package/dist/core/command-generation/index.js.map +1 -1
  146. package/dist/core/command-generation/types.d.ts +10 -36
  147. package/dist/core/command-generation/types.d.ts.map +1 -1
  148. package/dist/core/command-generation/types.js +0 -6
  149. package/dist/core/command-generation/types.js.map +1 -1
  150. package/dist/core/command-generation/yaml.d.ts +3 -18
  151. package/dist/core/command-generation/yaml.d.ts.map +1 -1
  152. package/dist/core/command-generation/yaml.js +5 -23
  153. package/dist/core/command-generation/yaml.js.map +1 -1
  154. package/dist/core/config-prompts.d.ts +2 -4
  155. package/dist/core/config-prompts.d.ts.map +1 -1
  156. package/dist/core/config-prompts.js +2 -7
  157. package/dist/core/config-prompts.js.map +1 -1
  158. package/dist/core/config-schema.d.ts +8 -53
  159. package/dist/core/config-schema.d.ts.map +1 -1
  160. package/dist/core/config-schema.js +49 -62
  161. package/dist/core/config-schema.js.map +1 -1
  162. package/dist/core/config.d.ts +56 -0
  163. package/dist/core/config.d.ts.map +1 -1
  164. package/dist/core/config.js +73 -2
  165. package/dist/core/config.js.map +1 -1
  166. package/dist/core/converters/json-converter.d.ts.map +1 -1
  167. package/dist/core/dashboard-activity.d.ts +7 -9
  168. package/dist/core/dashboard-activity.d.ts.map +1 -1
  169. package/dist/core/dashboard-activity.js +26 -24
  170. package/dist/core/dashboard-activity.js.map +1 -1
  171. package/dist/core/dashboard-data.d.ts +40 -22
  172. package/dist/core/dashboard-data.d.ts.map +1 -1
  173. package/dist/core/dashboard-data.js +62 -70
  174. package/dist/core/dashboard-data.js.map +1 -1
  175. package/dist/core/global-config.d.ts +24 -53
  176. package/dist/core/global-config.d.ts.map +1 -1
  177. package/dist/core/global-config.js +38 -67
  178. package/dist/core/global-config.js.map +1 -1
  179. package/dist/core/init.d.ts +29 -11
  180. package/dist/core/init.d.ts.map +1 -1
  181. package/dist/core/init.js +232 -164
  182. package/dist/core/init.js.map +1 -1
  183. package/dist/core/list.d.ts +1 -1
  184. package/dist/core/list.d.ts.map +1 -1
  185. package/dist/core/list.js +121 -28
  186. package/dist/core/list.js.map +1 -1
  187. package/dist/core/local-server.d.ts +60 -50
  188. package/dist/core/local-server.d.ts.map +1 -1
  189. package/dist/core/local-server.js +94 -66
  190. package/dist/core/local-server.js.map +1 -1
  191. package/dist/core/markdown-render.d.ts +25 -0
  192. package/dist/core/markdown-render.d.ts.map +1 -0
  193. package/dist/core/markdown-render.js +94 -0
  194. package/dist/core/markdown-render.js.map +1 -0
  195. package/dist/core/migrate.d.ts +32 -15
  196. package/dist/core/migrate.d.ts.map +1 -1
  197. package/dist/core/migrate.js +220 -108
  198. package/dist/core/migrate.js.map +1 -1
  199. package/dist/core/parsers/change-parser.d.ts +7 -10
  200. package/dist/core/parsers/change-parser.d.ts.map +1 -1
  201. package/dist/core/parsers/change-parser.js +48 -56
  202. package/dist/core/parsers/change-parser.js.map +1 -1
  203. package/dist/core/parsers/markdown-parser.d.ts +8 -9
  204. package/dist/core/parsers/markdown-parser.d.ts.map +1 -1
  205. package/dist/core/parsers/markdown-parser.js +31 -22
  206. package/dist/core/parsers/markdown-parser.js.map +1 -1
  207. package/dist/core/parsers/requirement-blocks.d.ts +43 -15
  208. package/dist/core/parsers/requirement-blocks.d.ts.map +1 -1
  209. package/dist/core/parsers/requirement-blocks.js +169 -54
  210. package/dist/core/parsers/requirement-blocks.js.map +1 -1
  211. package/dist/core/parsers/requirement-text.d.ts +73 -79
  212. package/dist/core/parsers/requirement-text.d.ts.map +1 -1
  213. package/dist/core/parsers/requirement-text.js +137 -79
  214. package/dist/core/parsers/requirement-text.js.map +1 -1
  215. package/dist/core/parsers/spec-structure.d.ts.map +1 -1
  216. package/dist/core/parsers/spec-structure.js +10 -6
  217. package/dist/core/parsers/spec-structure.js.map +1 -1
  218. package/dist/core/planning-home.js.map +1 -1
  219. package/dist/core/profiles.d.ts +3 -10
  220. package/dist/core/profiles.d.ts.map +1 -1
  221. package/dist/core/profiles.js +5 -12
  222. package/dist/core/profiles.js.map +1 -1
  223. package/dist/core/project-config.d.ts +43 -44
  224. package/dist/core/project-config.d.ts.map +1 -1
  225. package/dist/core/project-config.js +107 -82
  226. package/dist/core/project-config.js.map +1 -1
  227. package/dist/core/project-layout.d.ts +10 -18
  228. package/dist/core/project-layout.d.ts.map +1 -1
  229. package/dist/core/project-layout.js +16 -26
  230. package/dist/core/project-layout.js.map +1 -1
  231. package/dist/core/root-selection.d.ts +11 -7
  232. package/dist/core/root-selection.d.ts.map +1 -1
  233. package/dist/core/root-selection.js +7 -8
  234. package/dist/core/root-selection.js.map +1 -1
  235. package/dist/core/rules.d.ts +10 -0
  236. package/dist/core/rules.d.ts.map +1 -0
  237. package/dist/core/rules.js +43 -0
  238. package/dist/core/rules.js.map +1 -0
  239. package/dist/core/schema-names.d.ts +16 -0
  240. package/dist/core/schema-names.d.ts.map +1 -0
  241. package/dist/core/schema-names.js +16 -0
  242. package/dist/core/schema-names.js.map +1 -0
  243. package/dist/core/schemas/base.schema.d.ts +3 -0
  244. package/dist/core/schemas/base.schema.d.ts.map +1 -1
  245. package/dist/core/schemas/base.schema.js +22 -6
  246. package/dist/core/schemas/base.schema.js.map +1 -1
  247. package/dist/core/schemas/change.schema.d.ts +16 -0
  248. package/dist/core/schemas/change.schema.d.ts.map +1 -1
  249. package/dist/core/schemas/change.schema.js +41 -10
  250. package/dist/core/schemas/change.schema.js.map +1 -1
  251. package/dist/core/schemas/spec.schema.d.ts +2 -0
  252. package/dist/core/schemas/spec.schema.d.ts.map +1 -1
  253. package/dist/core/shared/index.d.ts +3 -8
  254. package/dist/core/shared/index.d.ts.map +1 -1
  255. package/dist/core/shared/index.js +3 -8
  256. package/dist/core/shared/index.js.map +1 -1
  257. package/dist/core/shared/rules-generation.d.ts +27 -8
  258. package/dist/core/shared/rules-generation.d.ts.map +1 -1
  259. package/dist/core/shared/rules-generation.js +151 -16
  260. package/dist/core/shared/rules-generation.js.map +1 -1
  261. package/dist/core/shared/skill-generation.d.ts +38 -53
  262. package/dist/core/shared/skill-generation.d.ts.map +1 -1
  263. package/dist/core/shared/skill-generation.js +82 -51
  264. package/dist/core/shared/skill-generation.js.map +1 -1
  265. package/dist/core/shared/tool-detection.d.ts +40 -62
  266. package/dist/core/shared/tool-detection.d.ts.map +1 -1
  267. package/dist/core/shared/tool-detection.js +88 -80
  268. package/dist/core/shared/tool-detection.js.map +1 -1
  269. package/dist/core/skill-metrics.d.ts +36 -63
  270. package/dist/core/skill-metrics.d.ts.map +1 -1
  271. package/dist/core/skill-metrics.js +34 -73
  272. package/dist/core/skill-metrics.js.map +1 -1
  273. package/dist/core/spec-presenter.d.ts.map +1 -1
  274. package/dist/core/spec-presenter.js +6 -6
  275. package/dist/core/spec-presenter.js.map +1 -1
  276. package/dist/core/specs-apply.d.ts +22 -23
  277. package/dist/core/specs-apply.d.ts.map +1 -1
  278. package/dist/core/specs-apply.js +166 -193
  279. package/dist/core/specs-apply.js.map +1 -1
  280. package/dist/core/templates/fragments/interview.d.ts +2 -6
  281. package/dist/core/templates/fragments/interview.d.ts.map +1 -1
  282. package/dist/core/templates/fragments/interview.js +2 -6
  283. package/dist/core/templates/fragments/interview.js.map +1 -1
  284. package/dist/core/templates/fragments/next-step.d.ts +4 -8
  285. package/dist/core/templates/fragments/next-step.d.ts.map +1 -1
  286. package/dist/core/templates/fragments/next-step.js +4 -8
  287. package/dist/core/templates/fragments/next-step.js.map +1 -1
  288. package/dist/core/templates/fragments/verify.d.ts +9 -12
  289. package/dist/core/templates/fragments/verify.d.ts.map +1 -1
  290. package/dist/core/templates/fragments/verify.js +9 -12
  291. package/dist/core/templates/fragments/verify.js.map +1 -1
  292. package/dist/core/templates/index.d.ts +0 -6
  293. package/dist/core/templates/index.d.ts.map +1 -1
  294. package/dist/core/templates/index.js +0 -7
  295. package/dist/core/templates/index.js.map +1 -1
  296. package/dist/core/templates/skill-templates.d.ts +1 -5
  297. package/dist/core/templates/skill-templates.d.ts.map +1 -1
  298. package/dist/core/templates/skill-templates.js +0 -5
  299. package/dist/core/templates/skill-templates.js.map +1 -1
  300. package/dist/core/templates/types.d.ts +3 -7
  301. package/dist/core/templates/types.d.ts.map +1 -1
  302. package/dist/core/templates/types.js +0 -3
  303. package/dist/core/templates/types.js.map +1 -1
  304. package/dist/core/templates/workflows/apply.d.ts +3 -9
  305. package/dist/core/templates/workflows/apply.d.ts.map +1 -1
  306. package/dist/core/templates/workflows/apply.js +9 -12
  307. package/dist/core/templates/workflows/apply.js.map +1 -1
  308. package/dist/core/templates/workflows/archive.d.ts +0 -6
  309. package/dist/core/templates/workflows/archive.d.ts.map +1 -1
  310. package/dist/core/templates/workflows/archive.js +7 -5
  311. package/dist/core/templates/workflows/archive.js.map +1 -1
  312. package/dist/core/templates/workflows/decision.js +4 -4
  313. package/dist/core/templates/workflows/decision.js.map +1 -1
  314. package/dist/core/templates/workflows/explore.js +1 -1
  315. package/dist/core/templates/workflows/grill.d.ts.map +1 -1
  316. package/dist/core/templates/workflows/grill.js +0 -2
  317. package/dist/core/templates/workflows/grill.js.map +1 -1
  318. package/dist/core/templates/workflows/issue.d.ts +0 -6
  319. package/dist/core/templates/workflows/issue.d.ts.map +1 -1
  320. package/dist/core/templates/workflows/issue.js +3 -0
  321. package/dist/core/templates/workflows/issue.js.map +1 -1
  322. package/dist/core/templates/workflows/propose.d.ts +0 -6
  323. package/dist/core/templates/workflows/propose.d.ts.map +1 -1
  324. package/dist/core/templates/workflows/propose.js +0 -1
  325. package/dist/core/templates/workflows/propose.js.map +1 -1
  326. package/dist/core/templates/workflows/sync.d.ts +2 -8
  327. package/dist/core/templates/workflows/sync.d.ts.map +1 -1
  328. package/dist/core/templates/workflows/sync.js +2 -2
  329. package/dist/core/templates/workflows/sync.js.map +1 -1
  330. package/dist/core/templates/workflows/update.d.ts +0 -6
  331. package/dist/core/templates/workflows/update.d.ts.map +1 -1
  332. package/dist/core/templates/workflows/update.js.map +1 -1
  333. package/dist/core/update.d.ts +26 -21
  334. package/dist/core/update.d.ts.map +1 -1
  335. package/dist/core/update.js +165 -116
  336. package/dist/core/update.js.map +1 -1
  337. package/dist/core/user-state-migration.d.ts +13 -15
  338. package/dist/core/user-state-migration.d.ts.map +1 -1
  339. package/dist/core/user-state-migration.js +16 -20
  340. package/dist/core/user-state-migration.js.map +1 -1
  341. package/dist/core/validation/constants.d.ts +19 -25
  342. package/dist/core/validation/constants.d.ts.map +1 -1
  343. package/dist/core/validation/constants.js +25 -20
  344. package/dist/core/validation/constants.js.map +1 -1
  345. package/dist/core/validation/prose-length.d.ts +15 -0
  346. package/dist/core/validation/prose-length.d.ts.map +1 -0
  347. package/dist/core/validation/prose-length.js +29 -0
  348. package/dist/core/validation/prose-length.js.map +1 -0
  349. package/dist/core/validation/purpose-placeholder.d.ts +9 -16
  350. package/dist/core/validation/purpose-placeholder.d.ts.map +1 -1
  351. package/dist/core/validation/purpose-placeholder.js +30 -44
  352. package/dist/core/validation/purpose-placeholder.js.map +1 -1
  353. package/dist/core/validation/section-validator.d.ts +4 -4
  354. package/dist/core/validation/section-validator.d.ts.map +1 -1
  355. package/dist/core/validation/section-validator.js +43 -7
  356. package/dist/core/validation/section-validator.js.map +1 -1
  357. package/dist/core/validation/task-numbering.d.ts +6 -3
  358. package/dist/core/validation/task-numbering.d.ts.map +1 -1
  359. package/dist/core/validation/task-numbering.js +23 -11
  360. package/dist/core/validation/task-numbering.js.map +1 -1
  361. package/dist/core/validation/types.d.ts +18 -0
  362. package/dist/core/validation/types.d.ts.map +1 -1
  363. package/dist/core/validation/types.js +12 -1
  364. package/dist/core/validation/types.js.map +1 -1
  365. package/dist/core/validation/validator.d.ts +50 -51
  366. package/dist/core/validation/validator.d.ts.map +1 -1
  367. package/dist/core/validation/validator.js +478 -269
  368. package/dist/core/validation/validator.js.map +1 -1
  369. package/dist/prompts/searchable-multi-select.d.ts +3 -8
  370. package/dist/prompts/searchable-multi-select.d.ts.map +1 -1
  371. package/dist/prompts/searchable-multi-select.js +16 -39
  372. package/dist/prompts/searchable-multi-select.js.map +1 -1
  373. package/dist/utils/change-metadata.d.ts +11 -50
  374. package/dist/utils/change-metadata.d.ts.map +1 -1
  375. package/dist/utils/change-metadata.js +48 -67
  376. package/dist/utils/change-metadata.js.map +1 -1
  377. package/dist/utils/change-utils.d.ts +31 -54
  378. package/dist/utils/change-utils.d.ts.map +1 -1
  379. package/dist/utils/change-utils.js +143 -100
  380. package/dist/utils/change-utils.js.map +1 -1
  381. package/dist/utils/file-lock.d.ts +39 -0
  382. package/dist/utils/file-lock.d.ts.map +1 -0
  383. package/dist/utils/file-lock.js +149 -0
  384. package/dist/utils/file-lock.js.map +1 -0
  385. package/dist/utils/file-system.d.ts +12 -32
  386. package/dist/utils/file-system.d.ts.map +1 -1
  387. package/dist/utils/file-system.js +16 -40
  388. package/dist/utils/file-system.js.map +1 -1
  389. package/dist/utils/frontmatter.d.ts +7 -11
  390. package/dist/utils/frontmatter.d.ts.map +1 -1
  391. package/dist/utils/frontmatter.js +11 -11
  392. package/dist/utils/frontmatter.js.map +1 -1
  393. package/dist/utils/interactive.d.ts +4 -9
  394. package/dist/utils/interactive.d.ts.map +1 -1
  395. package/dist/utils/interactive.js +2 -4
  396. package/dist/utils/interactive.js.map +1 -1
  397. package/dist/utils/item-discovery.d.ts +15 -10
  398. package/dist/utils/item-discovery.d.ts.map +1 -1
  399. package/dist/utils/item-discovery.js +42 -47
  400. package/dist/utils/item-discovery.js.map +1 -1
  401. package/dist/utils/link.d.ts +13 -4
  402. package/dist/utils/link.d.ts.map +1 -1
  403. package/dist/utils/link.js +13 -4
  404. package/dist/utils/link.js.map +1 -1
  405. package/dist/utils/match.js.map +1 -1
  406. package/dist/utils/requirement-diff.d.ts +13 -23
  407. package/dist/utils/requirement-diff.d.ts.map +1 -1
  408. package/dist/utils/requirement-diff.js +13 -23
  409. package/dist/utils/requirement-diff.js.map +1 -1
  410. package/dist/utils/spec-files.d.ts +10 -11
  411. package/dist/utils/spec-files.d.ts.map +1 -1
  412. package/dist/utils/spec-files.js +31 -22
  413. package/dist/utils/spec-files.js.map +1 -1
  414. package/dist/utils/task-progress.d.ts +11 -9
  415. package/dist/utils/task-progress.d.ts.map +1 -1
  416. package/dist/utils/task-progress.js +53 -32
  417. package/dist/utils/task-progress.js.map +1 -1
  418. package/dist/utils/timestamp.d.ts +5 -8
  419. package/dist/utils/timestamp.d.ts.map +1 -1
  420. package/dist/utils/timestamp.js +5 -8
  421. package/dist/utils/timestamp.js.map +1 -1
  422. package/package.json +9 -10
  423. package/schemas/decision/templates/decision.md +3 -1
  424. package/schemas/decision/templates/index.md +2 -2
  425. package/schemas/issue/schema.yaml +11 -2
  426. package/schemas/issue/templates/spec.md +37 -3
  427. package/schemas/sdd/schema.yaml +24 -1
  428. package/schemas/sdd/templates/spec.md +37 -3
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Schema names the command layer keys behaviour on. Kept out of any command
3
+ * module: `workflow/shared.ts` needs the decision name to refuse it for `new
4
+ * change`, and `decision.ts` needs the default schema to complete a root — with
5
+ * the constants living in those two files, each imported the other and the
6
+ * ESM cycle left one of them reading `undefined` depending on entry order.
7
+ */
8
+ /** The schema `new change` and `templates` fall back to. */
9
+ export declare const DEFAULT_SCHEMA = "sdd";
10
+ /**
11
+ * Backs the ADR writer, not the change graph: a change created against it
12
+ * lands under `tospec/changes/` where `decision list` never sees it, so `new
13
+ * change` refuses it by name.
14
+ */
15
+ export declare const DECISION_SCHEMA_NAME = "decision";
16
+ //# sourceMappingURL=schema-names.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-names.d.ts","sourceRoot":"","sources":["../../src/core/schema-names.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,4DAA4D;AAC5D,eAAO,MAAM,cAAc,QAAQ,CAAC;AAEpC;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,aAAa,CAAC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Schema names the command layer keys behaviour on. Kept out of any command
3
+ * module: `workflow/shared.ts` needs the decision name to refuse it for `new
4
+ * change`, and `decision.ts` needs the default schema to complete a root — with
5
+ * the constants living in those two files, each imported the other and the
6
+ * ESM cycle left one of them reading `undefined` depending on entry order.
7
+ */
8
+ /** The schema `new change` and `templates` fall back to. */
9
+ export const DEFAULT_SCHEMA = 'sdd';
10
+ /**
11
+ * Backs the ADR writer, not the change graph: a change created against it
12
+ * lands under `tospec/changes/` where `decision list` never sees it, so `new
13
+ * change` refuses it by name.
14
+ */
15
+ export const DECISION_SCHEMA_NAME = 'decision';
16
+ //# sourceMappingURL=schema-names.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-names.js","sourceRoot":"","sources":["../../src/core/schema-names.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,4DAA4D;AAC5D,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,CAAC;AAEpC;;;;GAIG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,UAAU,CAAC"}
@@ -1,10 +1,13 @@
1
1
  import { z } from 'zod';
2
2
  export declare const ScenarioSchema: z.ZodObject<{
3
+ name: z.ZodOptional<z.ZodString>;
3
4
  rawText: z.ZodString;
4
5
  }, z.core.$strip>;
5
6
  export declare const RequirementSchema: z.ZodObject<{
7
+ name: z.ZodOptional<z.ZodString>;
6
8
  text: z.ZodString;
7
9
  scenarios: z.ZodArray<z.ZodObject<{
10
+ name: z.ZodOptional<z.ZodString>;
8
11
  rawText: z.ZodString;
9
12
  }, z.core.$strip>>;
10
13
  }, z.core.$strip>;
@@ -1 +1 @@
1
- {"version":3,"file":"base.schema.d.ts","sourceRoot":"","sources":["../../../src/core/schemas/base.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,eAAO,MAAM,cAAc;;iBAEzB,CAAC;AAEH,eAAO,MAAM,iBAAiB;;;;;iBAW5B,CAAC;AAEH,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AACtD,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC"}
1
+ {"version":3,"file":"base.schema.d.ts","sourceRoot":"","sources":["../../../src/core/schemas/base.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,eAAO,MAAM,cAAc;;;iBASzB,CAAC;AAEH,eAAO,MAAM,iBAAiB;;;;;;;iBAoB5B,CAAC;AAEH,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AACtD,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC"}
@@ -1,15 +1,31 @@
1
1
  import { z } from 'zod';
2
2
  import { VALIDATION_MESSAGES } from '../validation/constants.js';
3
3
  export const ScenarioSchema = z.object({
4
+ /**
5
+ * The `#### Scenario: <name>` heading text, without the `Scenario:` prefix.
6
+ *
7
+ * Optional only so a hand-built Scenario in a test or a future caller does
8
+ * not have to invent one; every parsed scenario carries it.
9
+ */
10
+ name: z.string().optional(),
4
11
  rawText: z.string().min(1, VALIDATION_MESSAGES.SCENARIO_EMPTY),
5
12
  });
6
13
  export const RequirementSchema = z.object({
7
- // SHALL/MUST body-keyword enforcement lives in the imperative validator
8
- // (Validator.applySpecRules), not here: the parser collapses the requirement
9
- // header into `text`, so a Zod refine on `text` cannot tell "keyword in header
10
- // only" from "keyword in body" and emits a misleading generic error. The
11
- // validator recovers the header and emits the targeted hint for both the
12
- // main-spec and change-delta paths (#1156).
14
+ /**
15
+ * The `### Requirement: <name>` heading text, without the `Requirement:`
16
+ * prefix.
17
+ *
18
+ * Carried rather than discarded: a MODIFIED, REMOVED or RENAMED delta must
19
+ * reproduce the header exactly and archive hard-fails on a mismatch, so
20
+ * `show --json` has to report it.
21
+ *
22
+ * Optional in the schema so a hand-built Requirement need not supply one;
23
+ * every parsed requirement carries it.
24
+ */
25
+ name: z.string().optional(),
26
+ // SHALL/MUST body-keyword enforcement lives in Validator.applySpecRules: the
27
+ // parser collapses the requirement header into `text`, so a Zod refine here
28
+ // cannot tell "keyword in header only" from "keyword in body".
13
29
  text: z.string()
14
30
  .min(1, VALIDATION_MESSAGES.REQUIREMENT_EMPTY),
15
31
  scenarios: z.array(ScenarioSchema)
@@ -1 +1 @@
1
- {"version":3,"file":"base.schema.js","sourceRoot":"","sources":["../../../src/core/schemas/base.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAEjE,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC;IACrC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,mBAAmB,CAAC,cAAc,CAAC;CAC/D,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,wEAAwE;IACxE,6EAA6E;IAC7E,+EAA+E;IAC/E,yEAAyE;IACzE,yEAAyE;IACzE,4CAA4C;IAC5C,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;SACb,GAAG,CAAC,CAAC,EAAE,mBAAmB,CAAC,iBAAiB,CAAC;IAChD,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,cAAc,CAAC;SAC/B,GAAG,CAAC,CAAC,EAAE,mBAAmB,CAAC,wBAAwB,CAAC;CACxD,CAAC,CAAC"}
1
+ {"version":3,"file":"base.schema.js","sourceRoot":"","sources":["../../../src/core/schemas/base.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAEjE,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC;IACrC;;;;;OAKG;IACH,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC3B,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,mBAAmB,CAAC,cAAc,CAAC;CAC/D,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC;;;;;;;;;;OAUG;IACH,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC3B,6EAA6E;IAC7E,4EAA4E;IAC5E,+DAA+D;IAC/D,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;SACb,GAAG,CAAC,CAAC,EAAE,mBAAmB,CAAC,iBAAiB,CAAC;IAChD,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,cAAc,CAAC;SAC/B,GAAG,CAAC,CAAC,EAAE,mBAAmB,CAAC,wBAAwB,CAAC;CACxD,CAAC,CAAC"}
@@ -15,14 +15,18 @@ export declare const DeltaSchema: z.ZodObject<{
15
15
  }>;
16
16
  description: z.ZodString;
17
17
  requirement: z.ZodOptional<z.ZodObject<{
18
+ name: z.ZodOptional<z.ZodString>;
18
19
  text: z.ZodString;
19
20
  scenarios: z.ZodArray<z.ZodObject<{
21
+ name: z.ZodOptional<z.ZodString>;
20
22
  rawText: z.ZodString;
21
23
  }, z.core.$strip>>;
22
24
  }, z.core.$strip>>;
23
25
  requirements: z.ZodOptional<z.ZodArray<z.ZodObject<{
26
+ name: z.ZodOptional<z.ZodString>;
24
27
  text: z.ZodString;
25
28
  scenarios: z.ZodArray<z.ZodObject<{
29
+ name: z.ZodOptional<z.ZodString>;
26
30
  rawText: z.ZodString;
27
31
  }, z.core.$strip>>;
28
32
  }, z.core.$strip>>>;
@@ -31,6 +35,14 @@ export declare const DeltaSchema: z.ZodObject<{
31
35
  to: z.ZodString;
32
36
  }, z.core.$strip>>;
33
37
  }, z.core.$strip>;
38
+ /**
39
+ * The *shape* of a parsed change — what `ChangeParser` returns and what `Change`
40
+ * is inferred from — not where a change's rules live. Those are in
41
+ * `schemas/<name>/schema.yaml` (read by `validateSections`) and
42
+ * `validateChangeDeltaSpecs`.
43
+ *
44
+ * Keep it that way: nothing in `src/` runs a rule added here.
45
+ */
34
46
  export declare const ChangeSchema: z.ZodObject<{
35
47
  name: z.ZodString;
36
48
  why: z.ZodString;
@@ -45,14 +57,18 @@ export declare const ChangeSchema: z.ZodObject<{
45
57
  }>;
46
58
  description: z.ZodString;
47
59
  requirement: z.ZodOptional<z.ZodObject<{
60
+ name: z.ZodOptional<z.ZodString>;
48
61
  text: z.ZodString;
49
62
  scenarios: z.ZodArray<z.ZodObject<{
63
+ name: z.ZodOptional<z.ZodString>;
50
64
  rawText: z.ZodString;
51
65
  }, z.core.$strip>>;
52
66
  }, z.core.$strip>>;
53
67
  requirements: z.ZodOptional<z.ZodArray<z.ZodObject<{
68
+ name: z.ZodOptional<z.ZodString>;
54
69
  text: z.ZodString;
55
70
  scenarios: z.ZodArray<z.ZodObject<{
71
+ name: z.ZodOptional<z.ZodString>;
56
72
  rawText: z.ZodString;
57
73
  }, z.core.$strip>>;
58
74
  }, z.core.$strip>>>;
@@ -1 +1 @@
1
- {"version":3,"file":"change.schema.d.ts","sourceRoot":"","sources":["../../../src/core/schemas/change.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AASxB,eAAO,MAAM,kBAAkB;;;;;EAAsD,CAAC;AAEtF,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;iBAUtB,CAAC;AAEH,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAcvB,CAAC;AAEH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAChE,MAAM,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AAChD,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC"}
1
+ {"version":3,"file":"change.schema.d.ts","sourceRoot":"","sources":["../../../src/core/schemas/change.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,eAAO,MAAM,kBAAkB;;;;;EAAsD,CAAC;AAatF,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA0BtB,CAAC;AAEH;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAUvB,CAAC;AAEH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAChE,MAAM,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AAChD,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC"}
@@ -1,27 +1,58 @@
1
1
  import { z } from 'zod';
2
- import { RequirementSchema } from './base.schema.js';
3
- import { MIN_WHY_SECTION_LENGTH, MAX_WHY_SECTION_LENGTH, MAX_DELTAS_PER_CHANGE, VALIDATION_MESSAGES } from '../validation/constants.js';
2
+ import { RequirementSchema, ScenarioSchema } from './base.schema.js';
3
+ import { VALIDATION_MESSAGES } from '../validation/constants.js';
4
4
  export const DeltaOperationType = z.enum(['ADDED', 'MODIFIED', 'REMOVED', 'RENAMED']);
5
+ /**
6
+ * A requirement as a delta carries it. Identical to RequirementSchema except
7
+ * that the scenario list may be empty, because a REMOVED entry names a
8
+ * requirement that is going away: the canonical form for it is a bullet with
9
+ * Reason/Migration fields, which has no scenarios to restate. The min-1 rule
10
+ * still applies to every other operation — see the refinement below.
11
+ */
12
+ const DeltaRequirementSchema = RequirementSchema.extend({
13
+ scenarios: z.array(ScenarioSchema),
14
+ });
5
15
  export const DeltaSchema = z.object({
6
16
  spec: z.string().min(1, VALIDATION_MESSAGES.DELTA_SPEC_EMPTY),
7
17
  operation: DeltaOperationType,
8
18
  description: z.string().min(1, VALIDATION_MESSAGES.DELTA_DESCRIPTION_EMPTY),
9
- requirement: RequirementSchema.optional(),
10
- requirements: z.array(RequirementSchema).optional(),
19
+ requirement: DeltaRequirementSchema.optional(),
20
+ requirements: z.array(DeltaRequirementSchema).optional(),
11
21
  rename: z.object({
12
22
  from: z.string(),
13
23
  to: z.string(),
14
24
  }).optional(),
25
+ }).superRefine((delta, ctx) => {
26
+ // Scenario-less requirements are only legal on a REMOVED delta. Enforced here
27
+ // rather than on the field so every operation keeps one shape.
28
+ if (delta.operation === 'REMOVED')
29
+ return;
30
+ const reject = (path) => ctx.addIssue({
31
+ code: z.ZodIssueCode.custom,
32
+ message: VALIDATION_MESSAGES.REQUIREMENT_NO_SCENARIOS,
33
+ path,
34
+ });
35
+ if (delta.requirement && delta.requirement.scenarios.length === 0) {
36
+ reject(['requirement', 'scenarios']);
37
+ }
38
+ delta.requirements?.forEach((requirement, index) => {
39
+ if (requirement.scenarios.length === 0)
40
+ reject(['requirements', index, 'scenarios']);
41
+ });
15
42
  });
43
+ /**
44
+ * The *shape* of a parsed change — what `ChangeParser` returns and what `Change`
45
+ * is inferred from — not where a change's rules live. Those are in
46
+ * `schemas/<name>/schema.yaml` (read by `validateSections`) and
47
+ * `validateChangeDeltaSpecs`.
48
+ *
49
+ * Keep it that way: nothing in `src/` runs a rule added here.
50
+ */
16
51
  export const ChangeSchema = z.object({
17
52
  name: z.string().min(1, VALIDATION_MESSAGES.CHANGE_NAME_EMPTY),
18
- why: z.string()
19
- .min(MIN_WHY_SECTION_LENGTH, VALIDATION_MESSAGES.CHANGE_WHY_TOO_SHORT)
20
- .max(MAX_WHY_SECTION_LENGTH, VALIDATION_MESSAGES.CHANGE_WHY_TOO_LONG),
53
+ why: z.string(),
21
54
  whatChanges: z.string().min(1, VALIDATION_MESSAGES.CHANGE_WHAT_EMPTY),
22
- deltas: z.array(DeltaSchema)
23
- .min(1, VALIDATION_MESSAGES.CHANGE_NO_DELTAS)
24
- .max(MAX_DELTAS_PER_CHANGE, VALIDATION_MESSAGES.CHANGE_TOO_MANY_DELTAS),
55
+ deltas: z.array(DeltaSchema),
25
56
  metadata: z.object({
26
57
  version: z.string().default('1.0.0'),
27
58
  format: z.literal('tospec-change'),
@@ -1 +1 @@
1
- {"version":3,"file":"change.schema.js","sourceRoot":"","sources":["../../../src/core/schemas/change.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EACL,sBAAsB,EACtB,sBAAsB,EACtB,qBAAqB,EACrB,mBAAmB,EACpB,MAAM,4BAA4B,CAAC;AAEpC,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC;AAEtF,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC;IAClC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,mBAAmB,CAAC,gBAAgB,CAAC;IAC7D,SAAS,EAAE,kBAAkB;IAC7B,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,mBAAmB,CAAC,uBAAuB,CAAC;IAC3E,WAAW,EAAE,iBAAiB,CAAC,QAAQ,EAAE;IACzC,YAAY,EAAE,CAAC,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,QAAQ,EAAE;IACnD,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;QAChB,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;KACf,CAAC,CAAC,QAAQ,EAAE;CACd,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC;IACnC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,mBAAmB,CAAC,iBAAiB,CAAC;IAC9D,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE;SACZ,GAAG,CAAC,sBAAsB,EAAE,mBAAmB,CAAC,oBAAoB,CAAC;SACrE,GAAG,CAAC,sBAAsB,EAAE,mBAAmB,CAAC,mBAAmB,CAAC;IACvE,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,mBAAmB,CAAC,iBAAiB,CAAC;IACrE,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC;SACzB,GAAG,CAAC,CAAC,EAAE,mBAAmB,CAAC,gBAAgB,CAAC;SAC5C,GAAG,CAAC,qBAAqB,EAAE,mBAAmB,CAAC,sBAAsB,CAAC;IACzE,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC;QACjB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC;QACpC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,eAAe,CAAC;QAClC,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;KAClC,CAAC,CAAC,QAAQ,EAAE;CACd,CAAC,CAAC"}
1
+ {"version":3,"file":"change.schema.js","sourceRoot":"","sources":["../../../src/core/schemas/change.schema.ts"],"names":[],"mappings":"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"}
@@ -3,8 +3,10 @@ export declare const SpecSchema: z.ZodObject<{
3
3
  name: z.ZodString;
4
4
  overview: z.ZodString;
5
5
  requirements: z.ZodArray<z.ZodObject<{
6
+ name: z.ZodOptional<z.ZodString>;
6
7
  text: z.ZodString;
7
8
  scenarios: z.ZodArray<z.ZodObject<{
9
+ name: z.ZodOptional<z.ZodString>;
8
10
  rawText: z.ZodString;
9
11
  }, z.core.$strip>>;
10
12
  }, z.core.$strip>>;
@@ -1 +1 @@
1
- {"version":3,"file":"spec.schema.d.ts","sourceRoot":"","sources":["../../../src/core/schemas/spec.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,eAAO,MAAM,UAAU;;;;;;;;;;;;;;iBAUrB,CAAC;AAEH,MAAM,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC"}
1
+ {"version":3,"file":"spec.schema.d.ts","sourceRoot":"","sources":["../../../src/core/schemas/spec.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;iBAUrB,CAAC;AAEH,MAAM,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC"}
@@ -1,9 +1,4 @@
1
- /**
2
- * Shared Utilities
3
- *
4
- * Common code shared between init and update commands.
5
- */
6
- export { SKILL_NAMES, LEGACY_SKILL_DIRS, type ToolSkillStatus, type ToolVersionStatus, removeLegacySkillDirs, removeLegacyToolSkillLayout, getToolsWithSkillsDir, getToolSkillStatus, getToolStates, extractGeneratedByVersion, getToolVersionStatus, getConfiguredTools, } from './tool-detection.js';
7
- export { type SkillTemplateEntry, type CommandTemplateEntry, getSkillTemplates, getCommandTemplates, getCommandContents, generateSkillContent, writeSkillDir, writeToolCommands, } from './skill-generation.js';
8
- export { writeToolRules } from './rules-generation.js';
1
+ export { SKILL_NAMES, LEGACY_SKILL_DIRS, type ToolSkillStatus, type ToolVersionStatus, removeLegacySkillDirs, removeUnselectedSkillDirs, removeLegacyToolSkillLayout, getToolsWithSkillsDir, getToolSkillStatus, getToolStates, extractGeneratedByVersion, getToolVersionStatus, getConfiguredTools, } from './tool-detection.js';
2
+ export { type SkillTemplateEntry, type CommandTemplateEntry, type WorkflowReferenceGap, getSkillTemplates, getCommandTemplates, getCommandContents, generateSkillContent, writeSkillDir, writeToolCommands, findWorkflowReferenceGaps, describeWorkflowReferenceGaps, } from './skill-generation.js';
3
+ export { planWorkflowRules, writeWorkflowRules } from './rules-generation.js';
9
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/shared/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,WAAW,EACX,iBAAiB,EACjB,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,qBAAqB,EACrB,2BAA2B,EAC3B,qBAAqB,EACrB,kBAAkB,EAClB,aAAa,EACb,yBAAyB,EACzB,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EACzB,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,oBAAoB,EACpB,aAAa,EACb,iBAAiB,GAClB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/shared/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,iBAAiB,EACjB,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,qBAAqB,EACrB,yBAAyB,EACzB,2BAA2B,EAC3B,qBAAqB,EACrB,kBAAkB,EAClB,aAAa,EACb,yBAAyB,EACzB,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EACzB,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,oBAAoB,EACpB,aAAa,EACb,iBAAiB,EACjB,yBAAyB,EACzB,6BAA6B,GAC9B,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC"}
@@ -1,9 +1,4 @@
1
- /**
2
- * Shared Utilities
3
- *
4
- * Common code shared between init and update commands.
5
- */
6
- export { SKILL_NAMES, LEGACY_SKILL_DIRS, removeLegacySkillDirs, removeLegacyToolSkillLayout, getToolsWithSkillsDir, getToolSkillStatus, getToolStates, extractGeneratedByVersion, getToolVersionStatus, getConfiguredTools, } from './tool-detection.js';
7
- export { getSkillTemplates, getCommandTemplates, getCommandContents, generateSkillContent, writeSkillDir, writeToolCommands, } from './skill-generation.js';
8
- export { writeToolRules } from './rules-generation.js';
1
+ export { SKILL_NAMES, LEGACY_SKILL_DIRS, removeLegacySkillDirs, removeUnselectedSkillDirs, removeLegacyToolSkillLayout, getToolsWithSkillsDir, getToolSkillStatus, getToolStates, extractGeneratedByVersion, getToolVersionStatus, getConfiguredTools, } from './tool-detection.js';
2
+ export { getSkillTemplates, getCommandTemplates, getCommandContents, generateSkillContent, writeSkillDir, writeToolCommands, findWorkflowReferenceGaps, describeWorkflowReferenceGaps, } from './skill-generation.js';
3
+ export { planWorkflowRules, writeWorkflowRules } from './rules-generation.js';
9
4
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/shared/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,WAAW,EACX,iBAAiB,EAGjB,qBAAqB,EACrB,2BAA2B,EAC3B,qBAAqB,EACrB,kBAAkB,EAClB,aAAa,EACb,yBAAyB,EACzB,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAGL,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,oBAAoB,EACpB,aAAa,EACb,iBAAiB,GAClB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/shared/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,iBAAiB,EAGjB,qBAAqB,EACrB,yBAAyB,EACzB,2BAA2B,EAC3B,qBAAqB,EACrB,kBAAkB,EAClB,aAAa,EACb,yBAAyB,EACzB,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAIL,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,oBAAoB,EACpB,aAAa,EACb,iBAAiB,EACjB,yBAAyB,EACzB,6BAA6B,GAC9B,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC"}
@@ -1,11 +1,30 @@
1
1
  /**
2
- * Rules Generation
3
- *
4
- * Writes static tospec rule files into an agent's `rules/` directory.
5
- * Unlike skills, rules are fixed, tospec-owned content, so there is no
6
- * canonical `.agents/` source-of-truth or hard-linking — a plain write into
7
- * each selected tool's dir is enough (init regenerates it on demand).
2
+ * Every rule document tospec writes is managed the same way: a shipped Markdown
3
+ * template, wrapped in a hash-stamped marker, planned read-only before any
4
+ * project write, and refused rather than overwritten once somebody has edited
5
+ * it. Without the marker there is no way to tell a generated file from an
6
+ * edited one, and `tospec init` silently loses the edit.
8
7
  */
9
- /** Write tospec rule files into `<projectPath>/<agentBaseDir>/rules/` for one tool. */
10
- export declare function writeToolRules(projectPath: string, agentBaseDir: string): Promise<void>;
8
+ export interface WorkflowRulePlan {
9
+ toolId: string;
10
+ /** Which managed rule this entry writes; distinguishes a tool's entries. */
11
+ rule: string;
12
+ destination: string;
13
+ content: string;
14
+ action: 'created' | 'updated' | 'unchanged';
15
+ /**
16
+ * A copy under the previous misspelled filename to delete after the write.
17
+ * Absent unless one is there and is verifiably tospec-generated.
18
+ */
19
+ retire?: string;
20
+ }
21
+ /** Read every target before allowing any project mutation. */
22
+ export declare function planWorkflowRules(projectPath: string, toolIds: string[]): Promise<WorkflowRulePlan[]>;
23
+ /**
24
+ * Call only after the complete plan passed preflight. `silent` suppresses the
25
+ * progress prose for a `--json` caller, whose stdout must stay one document.
26
+ */
27
+ export declare function writeWorkflowRules(plan: WorkflowRulePlan[], options?: {
28
+ silent?: boolean;
29
+ }): Promise<void>;
11
30
  //# sourceMappingURL=rules-generation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"rules-generation.d.ts","sourceRoot":"","sources":["../../../src/core/shared/rules-generation.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAsBH,uFAAuF;AACvF,wBAAsB,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAK7F"}
1
+ {"version":3,"file":"rules-generation.d.ts","sourceRoot":"","sources":["../../../src/core/shared/rules-generation.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAoEH,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,4EAA4E;IAC5E,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,WAAW,CAAC;IAC5C;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAuCD,8DAA8D;AAC9D,wBAAsB,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAkE3G;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,gBAAgB,EAAE,EACxB,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GACjC,OAAO,CAAC,IAAI,CAAC,CAsBf"}
@@ -1,27 +1,162 @@
1
1
  /**
2
- * Rules Generation
3
- *
4
- * Writes static tospec rule files into an agent's `rules/` directory.
5
- * Unlike skills, rules are fixed, tospec-owned content, so there is no
6
- * canonical `.agents/` source-of-truth or hard-linking — a plain write into
7
- * each selected tool's dir is enough (init regenerates it on demand).
2
+ * Every rule document tospec writes is managed the same way: a shipped Markdown
3
+ * template, wrapped in a hash-stamped marker, planned read-only before any
4
+ * project write, and refused rather than overwritten once somebody has edited
5
+ * it. Without the marker there is no way to tell a generated file from an
6
+ * edited one, and `tospec init` silently loses the edit.
8
7
  */
9
8
  import path from 'node:path';
9
+ import { promises as fs } from 'node:fs';
10
+ import { createHash } from 'node:crypto';
11
+ import { AI_TOOLS, CODEX_TARGET_ID, DECISION_RULE_FILENAME, LEGACY_WORKFLOW_RULE_FILENAME, TOOL_RULES_SUBDIR, WORKFLOW_RULE_FILENAME, } from '../config.js';
10
12
  import { FileSystemUtils } from '../../utils/file-system.js';
11
- // Trailing newline intentional.
12
- const DECISION_RULE = `# Decision
13
+ /**
14
+ * The exact text the init-only writer produced. Kept verbatim rather than
15
+ * regenerated from the template: its only job is to recognise files already on
16
+ * disk, so it must not follow a change to the shipped body.
17
+ */
18
+ const UNMARKED_DECISION_RULE = `# Decision
13
19
 
14
20
  Any material decision reached during discussion must be recorded with /tospec-decision, which creates a decision file and captures the relevant decision details.
15
21
  `;
16
- // Single entry today; the array keeps adding a rule a one-line change.
17
- const RULE_FILES = [
18
- { relPath: path.join('tospec', 'decision.md'), content: DECISION_RULE },
22
+ const MANAGED_RULES = [
23
+ {
24
+ filename: WORKFLOW_RULE_FILENAME,
25
+ slug: 'single-source-of-truth',
26
+ templateUrl: new URL('../../../assets/rules/tospec/single-source-of-truth.md', import.meta.url),
27
+ // Carries the same `sourc` typo as the filename it was written beside.
28
+ legacySlugs: ['single-sourc-of-truth'],
29
+ legacyFilename: LEGACY_WORKFLOW_RULE_FILENAME,
30
+ },
31
+ {
32
+ filename: DECISION_RULE_FILENAME,
33
+ slug: 'decision',
34
+ templateUrl: new URL('../../../assets/rules/tospec/decision.md', import.meta.url),
35
+ unmarkedLegacyBodies: [UNMARKED_DECISION_RULE],
36
+ },
19
37
  ];
20
- /** Write tospec rule files into `<projectPath>/<agentBaseDir>/rules/` for one tool. */
21
- export async function writeToolRules(projectPath, agentBaseDir) {
22
- for (const rule of RULE_FILES) {
23
- const dest = path.join(projectPath, agentBaseDir, 'rules', rule.relPath);
24
- await FileSystemUtils.writeFile(dest, rule.content); // auto-creates parent dirs
38
+ function normalizeNewlines(content) {
39
+ return content.replace(/\r\n/g, '\n');
40
+ }
41
+ function bodyHash(body) {
42
+ return createHash('sha256').update(body, 'utf8').digest('hex');
43
+ }
44
+ const managedDocumentPattern = (slug) => new RegExp(`^<!-- tospec:${slug}:v1 sha256=([a-f0-9]{64}) -->\\n([\\s\\S]*\\n)<!-- \\/tospec:${slug} -->\\n$`);
45
+ /**
46
+ * Whether the file is an untouched tospec-generated rule document. Every slug
47
+ * this rule has ever used is accepted, as is any unmarked body a previous tospec
48
+ * wrote: refusing either turns a routine `tospec update` into a rule conflict
49
+ * for every project predating the change.
50
+ */
51
+ function isIntactDocument(rule, content) {
52
+ if (rule.unmarkedLegacyBodies?.some((body) => content === body))
53
+ return true;
54
+ return [rule.slug, ...(rule.legacySlugs ?? [])].some((slug) => {
55
+ const match = managedDocumentPattern(slug).exec(content);
56
+ // A dedicated file has exactly one frame; text outside it is somebody's.
57
+ return match !== null && match[0] === content
58
+ && !match[2].includes(`<!-- tospec:${slug}:`)
59
+ && !match[2].includes(`<!-- /tospec:${slug} -->`)
60
+ && bodyHash(match[2]) === match[1];
61
+ });
62
+ }
63
+ function planAction(previous, content) {
64
+ if (previous === undefined)
65
+ return 'created';
66
+ if (previous === content)
67
+ return 'unchanged';
68
+ return 'updated';
69
+ }
70
+ /** Read every target before allowing any project mutation. */
71
+ export async function planWorkflowRules(projectPath, toolIds) {
72
+ if (toolIds.length === 0)
73
+ return [];
74
+ const contents = new Map();
75
+ for (const rule of MANAGED_RULES) {
76
+ const body = normalizeNewlines(await fs.readFile(rule.templateUrl, 'utf8')).replace(/\n*$/, '\n');
77
+ contents.set(rule.filename, `<!-- tospec:${rule.slug}:v1 sha256=${bodyHash(body)} -->\n${body}<!-- /tospec:${rule.slug} -->\n`);
78
+ }
79
+ const plan = [];
80
+ const conflicts = [];
81
+ const readIfPresent = async (file) => {
82
+ try {
83
+ return normalizeNewlines(await fs.readFile(file, 'utf8'));
84
+ }
85
+ catch (error) {
86
+ if (error.code !== 'ENOENT')
87
+ throw error;
88
+ return undefined;
89
+ }
90
+ };
91
+ for (const toolId of toolIds) {
92
+ const tool = AI_TOOLS.find((tool) => tool.value === toolId);
93
+ if (!tool?.skillsDir)
94
+ throw new Error(`Unknown rule target: ${toolId}`);
95
+ const rulesDir = path.join(projectPath, tool.skillsDir, ...TOOL_RULES_SUBDIR);
96
+ for (const rule of MANAGED_RULES) {
97
+ const content = contents.get(rule.filename);
98
+ const destination = path.join(rulesDir, rule.filename);
99
+ const previous = await readIfPresent(destination);
100
+ if (previous !== undefined && !isIntactDocument(rule, previous)) {
101
+ conflicts.push(destination);
102
+ }
103
+ let retire;
104
+ if (rule.legacyFilename) {
105
+ const legacy = path.join(rulesDir, rule.legacyFilename);
106
+ const legacyPrevious = await readIfPresent(legacy);
107
+ if (legacyPrevious !== undefined) {
108
+ // An edited copy under the old name is reported, not deleted: the
109
+ // rename is tospec's housekeeping, not a reason to drop notes. Named
110
+ // as the old spelling, because a user who never typed that filename
111
+ // cannot otherwise tell why an "old" file blocks the run.
112
+ if (isIntactDocument(rule, legacyPrevious))
113
+ retire = legacy;
114
+ else {
115
+ conflicts.push(`${legacy} (previous filename of ${rule.filename}; tospec would have renamed it had it not been edited)`);
116
+ }
117
+ }
118
+ }
119
+ plan.push({
120
+ toolId,
121
+ rule: rule.filename,
122
+ destination,
123
+ content,
124
+ action: planAction(previous, content),
125
+ ...(retire ? { retire } : {}),
126
+ });
127
+ }
128
+ }
129
+ if (conflicts.length > 0) {
130
+ throw new Error(`Workflow rule conflict:\n${conflicts.join('\n')}\nPreserve your edits, remove the conflicting generated files, then rerun. Force does not bypass rule conflicts.`);
131
+ }
132
+ return plan;
133
+ }
134
+ /**
135
+ * Call only after the complete plan passed preflight. `silent` suppresses the
136
+ * progress prose for a `--json` caller, whose stdout must stay one document.
137
+ */
138
+ export async function writeWorkflowRules(plan, options = {}) {
139
+ const say = (line) => {
140
+ if (!options.silent)
141
+ console.log(line);
142
+ };
143
+ for (const entry of plan) {
144
+ if (entry.action !== 'unchanged') {
145
+ await FileSystemUtils.writeFile(entry.destination, entry.content);
146
+ }
147
+ say(`Rules ${entry.action}: ${entry.destination}`);
148
+ // After the write, never before: a failure between the two would leave the
149
+ // project with no rule document at all.
150
+ if (entry.retire) {
151
+ await fs.rm(entry.retire, { force: true });
152
+ say(`Rules removed (renamed): ${entry.retire}`);
153
+ }
154
+ }
155
+ // Codex reads AGENTS.md and skill files, never project Markdown under rules/,
156
+ // so the relocated file has no loading path there. Said out loud, or the
157
+ // limitation is silent.
158
+ if (plan.some((entry) => entry.toolId === CODEX_TARGET_ID)) {
159
+ say('Codex: rule documents are reference material; configure loading yourself. Markdown files in .agents/rules/ are not automatically loaded as instructions — Codex takes its text guidance from AGENTS.md and skill files.');
25
160
  }
26
161
  }
27
162
  //# sourceMappingURL=rules-generation.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"rules-generation.js","sourceRoot":"","sources":["../../../src/core/shared/rules-generation.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAE7D,gCAAgC;AAChC,MAAM,aAAa,GAAG;;;CAGrB,CAAC;AAQF,uEAAuE;AACvE,MAAM,UAAU,GAAe;IAC7B,EAAE,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,aAAa,CAAC,EAAE,OAAO,EAAE,aAAa,EAAE;CACxE,CAAC;AAEF,uFAAuF;AACvF,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,WAAmB,EAAE,YAAoB;IAC5E,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;QAC9B,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,YAAY,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QACzE,MAAM,eAAe,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,2BAA2B;IAClF,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"rules-generation.js","sourceRoot":"","sources":["../../../src/core/shared/rules-generation.ts"],"names":[],"mappings":"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"}