@seanmars/tospec 0.19.0-beta.0 → 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 (431) hide show
  1. package/CHANGELOG.md +578 -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/metrics/app.js +22 -0
  6. package/assets/metrics/style.css +8 -0
  7. package/assets/rules/tospec/decision.md +3 -0
  8. package/assets/rules/tospec/single-source-of-truth.md +19 -0
  9. package/dist/cli/index.d.ts.map +1 -1
  10. package/dist/cli/index.js +266 -82
  11. package/dist/cli/index.js.map +1 -1
  12. package/dist/commands/config.d.ts +9 -17
  13. package/dist/commands/config.d.ts.map +1 -1
  14. package/dist/commands/config.js +374 -95
  15. package/dist/commands/config.js.map +1 -1
  16. package/dist/commands/dashboard.d.ts +64 -81
  17. package/dist/commands/dashboard.d.ts.map +1 -1
  18. package/dist/commands/dashboard.js +350 -218
  19. package/dist/commands/dashboard.js.map +1 -1
  20. package/dist/commands/decision.d.ts +41 -19
  21. package/dist/commands/decision.d.ts.map +1 -1
  22. package/dist/commands/decision.js +400 -70
  23. package/dist/commands/decision.js.map +1 -1
  24. package/dist/commands/metrics.d.ts +34 -48
  25. package/dist/commands/metrics.d.ts.map +1 -1
  26. package/dist/commands/metrics.js +74 -84
  27. package/dist/commands/metrics.js.map +1 -1
  28. package/dist/commands/shared-output.d.ts +24 -10
  29. package/dist/commands/shared-output.d.ts.map +1 -1
  30. package/dist/commands/shared-output.js +62 -11
  31. package/dist/commands/shared-output.js.map +1 -1
  32. package/dist/commands/show.d.ts +7 -0
  33. package/dist/commands/show.d.ts.map +1 -1
  34. package/dist/commands/show.js +39 -8
  35. package/dist/commands/show.js.map +1 -1
  36. package/dist/commands/validate.d.ts +47 -30
  37. package/dist/commands/validate.d.ts.map +1 -1
  38. package/dist/commands/validate.js +282 -108
  39. package/dist/commands/validate.js.map +1 -1
  40. package/dist/commands/workflow/index.d.ts +6 -10
  41. package/dist/commands/workflow/index.d.ts.map +1 -1
  42. package/dist/commands/workflow/index.js +6 -10
  43. package/dist/commands/workflow/index.js.map +1 -1
  44. package/dist/commands/workflow/instructions.d.ts +21 -8
  45. package/dist/commands/workflow/instructions.d.ts.map +1 -1
  46. package/dist/commands/workflow/instructions.js +254 -95
  47. package/dist/commands/workflow/instructions.js.map +1 -1
  48. package/dist/commands/workflow/new-change.d.ts +4 -5
  49. package/dist/commands/workflow/new-change.d.ts.map +1 -1
  50. package/dist/commands/workflow/new-change.js +90 -25
  51. package/dist/commands/workflow/new-change.js.map +1 -1
  52. package/dist/commands/workflow/schemas.d.ts +3 -5
  53. package/dist/commands/workflow/schemas.d.ts.map +1 -1
  54. package/dist/commands/workflow/schemas.js +37 -11
  55. package/dist/commands/workflow/schemas.js.map +1 -1
  56. package/dist/commands/workflow/shared.d.ts +48 -21
  57. package/dist/commands/workflow/shared.d.ts.map +1 -1
  58. package/dist/commands/workflow/shared.js +36 -33
  59. package/dist/commands/workflow/shared.js.map +1 -1
  60. package/dist/commands/workflow/status.d.ts +10 -6
  61. package/dist/commands/workflow/status.d.ts.map +1 -1
  62. package/dist/commands/workflow/status.js +84 -42
  63. package/dist/commands/workflow/status.js.map +1 -1
  64. package/dist/commands/workflow/templates.d.ts +10 -3
  65. package/dist/commands/workflow/templates.d.ts.map +1 -1
  66. package/dist/commands/workflow/templates.js +39 -40
  67. package/dist/commands/workflow/templates.js.map +1 -1
  68. package/dist/core/archive.d.ts +26 -21
  69. package/dist/core/archive.d.ts.map +1 -1
  70. package/dist/core/archive.js +415 -201
  71. package/dist/core/archive.js.map +1 -1
  72. package/dist/core/artifact-graph/graph.d.ts +29 -36
  73. package/dist/core/artifact-graph/graph.d.ts.map +1 -1
  74. package/dist/core/artifact-graph/graph.js +50 -58
  75. package/dist/core/artifact-graph/graph.js.map +1 -1
  76. package/dist/core/artifact-graph/index.d.ts +2 -2
  77. package/dist/core/artifact-graph/index.d.ts.map +1 -1
  78. package/dist/core/artifact-graph/index.js +2 -2
  79. package/dist/core/artifact-graph/index.js.map +1 -1
  80. package/dist/core/artifact-graph/instruction-loader.d.ts +105 -100
  81. package/dist/core/artifact-graph/instruction-loader.d.ts.map +1 -1
  82. package/dist/core/artifact-graph/instruction-loader.js +176 -110
  83. package/dist/core/artifact-graph/instruction-loader.js.map +1 -1
  84. package/dist/core/artifact-graph/outputs.d.ts +13 -6
  85. package/dist/core/artifact-graph/outputs.d.ts.map +1 -1
  86. package/dist/core/artifact-graph/outputs.js +146 -8
  87. package/dist/core/artifact-graph/outputs.js.map +1 -1
  88. package/dist/core/artifact-graph/resolver.d.ts +44 -63
  89. package/dist/core/artifact-graph/resolver.d.ts.map +1 -1
  90. package/dist/core/artifact-graph/resolver.js +85 -86
  91. package/dist/core/artifact-graph/resolver.js.map +1 -1
  92. package/dist/core/artifact-graph/schema.d.ts +0 -6
  93. package/dist/core/artifact-graph/schema.d.ts.map +1 -1
  94. package/dist/core/artifact-graph/schema.js +7 -32
  95. package/dist/core/artifact-graph/schema.js.map +1 -1
  96. package/dist/core/artifact-graph/state.d.ts +1 -8
  97. package/dist/core/artifact-graph/state.d.ts.map +1 -1
  98. package/dist/core/artifact-graph/state.js +2 -17
  99. package/dist/core/artifact-graph/state.js.map +1 -1
  100. package/dist/core/artifact-graph/stub-detection.d.ts +12 -0
  101. package/dist/core/artifact-graph/stub-detection.d.ts.map +1 -0
  102. package/dist/core/artifact-graph/stub-detection.js +39 -0
  103. package/dist/core/artifact-graph/stub-detection.js.map +1 -0
  104. package/dist/core/artifact-graph/types.d.ts +4 -0
  105. package/dist/core/artifact-graph/types.d.ts.map +1 -1
  106. package/dist/core/artifact-graph/types.js +30 -10
  107. package/dist/core/artifact-graph/types.js.map +1 -1
  108. package/dist/core/available-tools.d.ts +3 -12
  109. package/dist/core/available-tools.d.ts.map +1 -1
  110. package/dist/core/available-tools.js +4 -13
  111. package/dist/core/available-tools.js.map +1 -1
  112. package/dist/core/change-metadata/schema.d.ts +1 -1
  113. package/dist/core/change-metadata/schema.d.ts.map +1 -1
  114. package/dist/core/change-metadata/schema.js +10 -7
  115. package/dist/core/change-metadata/schema.js.map +1 -1
  116. package/dist/core/change-presenter.d.ts +23 -18
  117. package/dist/core/change-presenter.d.ts.map +1 -1
  118. package/dist/core/change-presenter.js +102 -43
  119. package/dist/core/change-presenter.js.map +1 -1
  120. package/dist/core/change-status-policy.d.ts +8 -1
  121. package/dist/core/change-status-policy.d.ts.map +1 -1
  122. package/dist/core/change-status-policy.js +25 -1
  123. package/dist/core/change-status-policy.js.map +1 -1
  124. package/dist/core/codex-metrics.d.ts +25 -45
  125. package/dist/core/codex-metrics.d.ts.map +1 -1
  126. package/dist/core/codex-metrics.js +44 -88
  127. package/dist/core/codex-metrics.js.map +1 -1
  128. package/dist/core/codex-residue.d.ts +22 -0
  129. package/dist/core/codex-residue.d.ts.map +1 -0
  130. package/dist/core/codex-residue.js +61 -0
  131. package/dist/core/codex-residue.js.map +1 -0
  132. package/dist/core/command-generation/adapters/claude.d.ts +2 -9
  133. package/dist/core/command-generation/adapters/claude.d.ts.map +1 -1
  134. package/dist/core/command-generation/adapters/claude.js +2 -12
  135. package/dist/core/command-generation/adapters/claude.js.map +1 -1
  136. package/dist/core/command-generation/adapters/index.d.ts +1 -9
  137. package/dist/core/command-generation/adapters/index.d.ts.map +1 -1
  138. package/dist/core/command-generation/adapters/index.js +1 -9
  139. package/dist/core/command-generation/adapters/index.js.map +1 -1
  140. package/dist/core/command-generation/generator.d.ts +0 -17
  141. package/dist/core/command-generation/generator.d.ts.map +1 -1
  142. package/dist/core/command-generation/generator.js +0 -17
  143. package/dist/core/command-generation/generator.js.map +1 -1
  144. package/dist/core/command-generation/index.d.ts +2 -5
  145. package/dist/core/command-generation/index.d.ts.map +1 -1
  146. package/dist/core/command-generation/index.js +0 -9
  147. package/dist/core/command-generation/index.js.map +1 -1
  148. package/dist/core/command-generation/types.d.ts +10 -36
  149. package/dist/core/command-generation/types.d.ts.map +1 -1
  150. package/dist/core/command-generation/types.js +0 -6
  151. package/dist/core/command-generation/types.js.map +1 -1
  152. package/dist/core/command-generation/yaml.d.ts +3 -18
  153. package/dist/core/command-generation/yaml.d.ts.map +1 -1
  154. package/dist/core/command-generation/yaml.js +5 -23
  155. package/dist/core/command-generation/yaml.js.map +1 -1
  156. package/dist/core/config-prompts.d.ts +2 -4
  157. package/dist/core/config-prompts.d.ts.map +1 -1
  158. package/dist/core/config-prompts.js +2 -7
  159. package/dist/core/config-prompts.js.map +1 -1
  160. package/dist/core/config-schema.d.ts +8 -53
  161. package/dist/core/config-schema.d.ts.map +1 -1
  162. package/dist/core/config-schema.js +49 -62
  163. package/dist/core/config-schema.js.map +1 -1
  164. package/dist/core/config.d.ts +56 -0
  165. package/dist/core/config.d.ts.map +1 -1
  166. package/dist/core/config.js +73 -2
  167. package/dist/core/config.js.map +1 -1
  168. package/dist/core/converters/json-converter.d.ts.map +1 -1
  169. package/dist/core/dashboard-activity.d.ts +7 -9
  170. package/dist/core/dashboard-activity.d.ts.map +1 -1
  171. package/dist/core/dashboard-activity.js +26 -24
  172. package/dist/core/dashboard-activity.js.map +1 -1
  173. package/dist/core/dashboard-data.d.ts +40 -22
  174. package/dist/core/dashboard-data.d.ts.map +1 -1
  175. package/dist/core/dashboard-data.js +84 -68
  176. package/dist/core/dashboard-data.js.map +1 -1
  177. package/dist/core/global-config.d.ts +24 -53
  178. package/dist/core/global-config.d.ts.map +1 -1
  179. package/dist/core/global-config.js +43 -62
  180. package/dist/core/global-config.js.map +1 -1
  181. package/dist/core/init.d.ts +29 -11
  182. package/dist/core/init.d.ts.map +1 -1
  183. package/dist/core/init.js +232 -164
  184. package/dist/core/init.js.map +1 -1
  185. package/dist/core/list.d.ts +1 -1
  186. package/dist/core/list.d.ts.map +1 -1
  187. package/dist/core/list.js +121 -28
  188. package/dist/core/list.js.map +1 -1
  189. package/dist/core/local-server.d.ts +63 -39
  190. package/dist/core/local-server.d.ts.map +1 -1
  191. package/dist/core/local-server.js +99 -53
  192. package/dist/core/local-server.js.map +1 -1
  193. package/dist/core/markdown-render.d.ts +25 -0
  194. package/dist/core/markdown-render.d.ts.map +1 -0
  195. package/dist/core/markdown-render.js +94 -0
  196. package/dist/core/markdown-render.js.map +1 -0
  197. package/dist/core/migrate.d.ts +32 -15
  198. package/dist/core/migrate.d.ts.map +1 -1
  199. package/dist/core/migrate.js +220 -108
  200. package/dist/core/migrate.js.map +1 -1
  201. package/dist/core/parsers/change-parser.d.ts +7 -10
  202. package/dist/core/parsers/change-parser.d.ts.map +1 -1
  203. package/dist/core/parsers/change-parser.js +48 -56
  204. package/dist/core/parsers/change-parser.js.map +1 -1
  205. package/dist/core/parsers/markdown-parser.d.ts +8 -9
  206. package/dist/core/parsers/markdown-parser.d.ts.map +1 -1
  207. package/dist/core/parsers/markdown-parser.js +31 -22
  208. package/dist/core/parsers/markdown-parser.js.map +1 -1
  209. package/dist/core/parsers/requirement-blocks.d.ts +53 -11
  210. package/dist/core/parsers/requirement-blocks.d.ts.map +1 -1
  211. package/dist/core/parsers/requirement-blocks.js +200 -60
  212. package/dist/core/parsers/requirement-blocks.js.map +1 -1
  213. package/dist/core/parsers/requirement-text.d.ts +73 -79
  214. package/dist/core/parsers/requirement-text.d.ts.map +1 -1
  215. package/dist/core/parsers/requirement-text.js +137 -79
  216. package/dist/core/parsers/requirement-text.js.map +1 -1
  217. package/dist/core/parsers/spec-structure.d.ts +1 -1
  218. package/dist/core/parsers/spec-structure.d.ts.map +1 -1
  219. package/dist/core/parsers/spec-structure.js +30 -3
  220. package/dist/core/parsers/spec-structure.js.map +1 -1
  221. package/dist/core/planning-home.js.map +1 -1
  222. package/dist/core/profiles.d.ts +3 -10
  223. package/dist/core/profiles.d.ts.map +1 -1
  224. package/dist/core/profiles.js +5 -12
  225. package/dist/core/profiles.js.map +1 -1
  226. package/dist/core/project-config.d.ts +43 -44
  227. package/dist/core/project-config.d.ts.map +1 -1
  228. package/dist/core/project-config.js +107 -82
  229. package/dist/core/project-config.js.map +1 -1
  230. package/dist/core/project-layout.d.ts +10 -18
  231. package/dist/core/project-layout.d.ts.map +1 -1
  232. package/dist/core/project-layout.js +16 -26
  233. package/dist/core/project-layout.js.map +1 -1
  234. package/dist/core/root-selection.d.ts +11 -7
  235. package/dist/core/root-selection.d.ts.map +1 -1
  236. package/dist/core/root-selection.js +7 -8
  237. package/dist/core/root-selection.js.map +1 -1
  238. package/dist/core/rules.d.ts +10 -0
  239. package/dist/core/rules.d.ts.map +1 -0
  240. package/dist/core/rules.js +43 -0
  241. package/dist/core/rules.js.map +1 -0
  242. package/dist/core/schema-names.d.ts +16 -0
  243. package/dist/core/schema-names.d.ts.map +1 -0
  244. package/dist/core/schema-names.js +16 -0
  245. package/dist/core/schema-names.js.map +1 -0
  246. package/dist/core/schemas/base.schema.d.ts +3 -0
  247. package/dist/core/schemas/base.schema.d.ts.map +1 -1
  248. package/dist/core/schemas/base.schema.js +22 -6
  249. package/dist/core/schemas/base.schema.js.map +1 -1
  250. package/dist/core/schemas/change.schema.d.ts +16 -0
  251. package/dist/core/schemas/change.schema.d.ts.map +1 -1
  252. package/dist/core/schemas/change.schema.js +41 -10
  253. package/dist/core/schemas/change.schema.js.map +1 -1
  254. package/dist/core/schemas/spec.schema.d.ts +2 -0
  255. package/dist/core/schemas/spec.schema.d.ts.map +1 -1
  256. package/dist/core/shared/index.d.ts +3 -8
  257. package/dist/core/shared/index.d.ts.map +1 -1
  258. package/dist/core/shared/index.js +3 -8
  259. package/dist/core/shared/index.js.map +1 -1
  260. package/dist/core/shared/rules-generation.d.ts +27 -8
  261. package/dist/core/shared/rules-generation.d.ts.map +1 -1
  262. package/dist/core/shared/rules-generation.js +151 -16
  263. package/dist/core/shared/rules-generation.js.map +1 -1
  264. package/dist/core/shared/skill-generation.d.ts +38 -53
  265. package/dist/core/shared/skill-generation.d.ts.map +1 -1
  266. package/dist/core/shared/skill-generation.js +82 -51
  267. package/dist/core/shared/skill-generation.js.map +1 -1
  268. package/dist/core/shared/tool-detection.d.ts +40 -62
  269. package/dist/core/shared/tool-detection.d.ts.map +1 -1
  270. package/dist/core/shared/tool-detection.js +88 -80
  271. package/dist/core/shared/tool-detection.js.map +1 -1
  272. package/dist/core/skill-metrics.d.ts +36 -63
  273. package/dist/core/skill-metrics.d.ts.map +1 -1
  274. package/dist/core/skill-metrics.js +34 -73
  275. package/dist/core/skill-metrics.js.map +1 -1
  276. package/dist/core/spec-presenter.d.ts.map +1 -1
  277. package/dist/core/spec-presenter.js +6 -6
  278. package/dist/core/spec-presenter.js.map +1 -1
  279. package/dist/core/specs-apply.d.ts +24 -23
  280. package/dist/core/specs-apply.d.ts.map +1 -1
  281. package/dist/core/specs-apply.js +188 -173
  282. package/dist/core/specs-apply.js.map +1 -1
  283. package/dist/core/templates/fragments/interview.d.ts +2 -6
  284. package/dist/core/templates/fragments/interview.d.ts.map +1 -1
  285. package/dist/core/templates/fragments/interview.js +2 -6
  286. package/dist/core/templates/fragments/interview.js.map +1 -1
  287. package/dist/core/templates/fragments/next-step.d.ts +4 -8
  288. package/dist/core/templates/fragments/next-step.d.ts.map +1 -1
  289. package/dist/core/templates/fragments/next-step.js +4 -8
  290. package/dist/core/templates/fragments/next-step.js.map +1 -1
  291. package/dist/core/templates/fragments/verify.d.ts +9 -12
  292. package/dist/core/templates/fragments/verify.d.ts.map +1 -1
  293. package/dist/core/templates/fragments/verify.js +9 -12
  294. package/dist/core/templates/fragments/verify.js.map +1 -1
  295. package/dist/core/templates/index.d.ts +0 -6
  296. package/dist/core/templates/index.d.ts.map +1 -1
  297. package/dist/core/templates/index.js +0 -7
  298. package/dist/core/templates/index.js.map +1 -1
  299. package/dist/core/templates/skill-templates.d.ts +1 -5
  300. package/dist/core/templates/skill-templates.d.ts.map +1 -1
  301. package/dist/core/templates/skill-templates.js +0 -5
  302. package/dist/core/templates/skill-templates.js.map +1 -1
  303. package/dist/core/templates/types.d.ts +3 -7
  304. package/dist/core/templates/types.d.ts.map +1 -1
  305. package/dist/core/templates/types.js +0 -3
  306. package/dist/core/templates/types.js.map +1 -1
  307. package/dist/core/templates/workflows/apply.d.ts +3 -9
  308. package/dist/core/templates/workflows/apply.d.ts.map +1 -1
  309. package/dist/core/templates/workflows/apply.js +9 -12
  310. package/dist/core/templates/workflows/apply.js.map +1 -1
  311. package/dist/core/templates/workflows/archive.d.ts +0 -6
  312. package/dist/core/templates/workflows/archive.d.ts.map +1 -1
  313. package/dist/core/templates/workflows/archive.js +7 -5
  314. package/dist/core/templates/workflows/archive.js.map +1 -1
  315. package/dist/core/templates/workflows/decision.js +4 -4
  316. package/dist/core/templates/workflows/decision.js.map +1 -1
  317. package/dist/core/templates/workflows/explore.js +1 -1
  318. package/dist/core/templates/workflows/grill.d.ts.map +1 -1
  319. package/dist/core/templates/workflows/grill.js +0 -2
  320. package/dist/core/templates/workflows/grill.js.map +1 -1
  321. package/dist/core/templates/workflows/issue.d.ts +0 -6
  322. package/dist/core/templates/workflows/issue.d.ts.map +1 -1
  323. package/dist/core/templates/workflows/issue.js +3 -0
  324. package/dist/core/templates/workflows/issue.js.map +1 -1
  325. package/dist/core/templates/workflows/propose.d.ts +0 -6
  326. package/dist/core/templates/workflows/propose.d.ts.map +1 -1
  327. package/dist/core/templates/workflows/propose.js +0 -1
  328. package/dist/core/templates/workflows/propose.js.map +1 -1
  329. package/dist/core/templates/workflows/sync.d.ts +2 -8
  330. package/dist/core/templates/workflows/sync.d.ts.map +1 -1
  331. package/dist/core/templates/workflows/sync.js +2 -2
  332. package/dist/core/templates/workflows/sync.js.map +1 -1
  333. package/dist/core/templates/workflows/update.d.ts +0 -6
  334. package/dist/core/templates/workflows/update.d.ts.map +1 -1
  335. package/dist/core/templates/workflows/update.js.map +1 -1
  336. package/dist/core/update.d.ts +26 -21
  337. package/dist/core/update.d.ts.map +1 -1
  338. package/dist/core/update.js +165 -116
  339. package/dist/core/update.js.map +1 -1
  340. package/dist/core/user-state-migration.d.ts +13 -15
  341. package/dist/core/user-state-migration.d.ts.map +1 -1
  342. package/dist/core/user-state-migration.js +16 -20
  343. package/dist/core/user-state-migration.js.map +1 -1
  344. package/dist/core/validation/constants.d.ts +19 -25
  345. package/dist/core/validation/constants.d.ts.map +1 -1
  346. package/dist/core/validation/constants.js +25 -20
  347. package/dist/core/validation/constants.js.map +1 -1
  348. package/dist/core/validation/prose-length.d.ts +15 -0
  349. package/dist/core/validation/prose-length.d.ts.map +1 -0
  350. package/dist/core/validation/prose-length.js +29 -0
  351. package/dist/core/validation/prose-length.js.map +1 -0
  352. package/dist/core/validation/purpose-placeholder.d.ts +9 -16
  353. package/dist/core/validation/purpose-placeholder.d.ts.map +1 -1
  354. package/dist/core/validation/purpose-placeholder.js +30 -44
  355. package/dist/core/validation/purpose-placeholder.js.map +1 -1
  356. package/dist/core/validation/section-validator.d.ts +4 -4
  357. package/dist/core/validation/section-validator.d.ts.map +1 -1
  358. package/dist/core/validation/section-validator.js +43 -7
  359. package/dist/core/validation/section-validator.js.map +1 -1
  360. package/dist/core/validation/task-numbering.d.ts +6 -3
  361. package/dist/core/validation/task-numbering.d.ts.map +1 -1
  362. package/dist/core/validation/task-numbering.js +23 -11
  363. package/dist/core/validation/task-numbering.js.map +1 -1
  364. package/dist/core/validation/types.d.ts +18 -0
  365. package/dist/core/validation/types.d.ts.map +1 -1
  366. package/dist/core/validation/types.js +12 -1
  367. package/dist/core/validation/types.js.map +1 -1
  368. package/dist/core/validation/validator.d.ts +50 -51
  369. package/dist/core/validation/validator.d.ts.map +1 -1
  370. package/dist/core/validation/validator.js +486 -263
  371. package/dist/core/validation/validator.js.map +1 -1
  372. package/dist/prompts/searchable-multi-select.d.ts +3 -8
  373. package/dist/prompts/searchable-multi-select.d.ts.map +1 -1
  374. package/dist/prompts/searchable-multi-select.js +16 -39
  375. package/dist/prompts/searchable-multi-select.js.map +1 -1
  376. package/dist/utils/change-metadata.d.ts +11 -50
  377. package/dist/utils/change-metadata.d.ts.map +1 -1
  378. package/dist/utils/change-metadata.js +48 -67
  379. package/dist/utils/change-metadata.js.map +1 -1
  380. package/dist/utils/change-utils.d.ts +31 -54
  381. package/dist/utils/change-utils.d.ts.map +1 -1
  382. package/dist/utils/change-utils.js +143 -100
  383. package/dist/utils/change-utils.js.map +1 -1
  384. package/dist/utils/file-lock.d.ts +39 -0
  385. package/dist/utils/file-lock.d.ts.map +1 -0
  386. package/dist/utils/file-lock.js +149 -0
  387. package/dist/utils/file-lock.js.map +1 -0
  388. package/dist/utils/file-system.d.ts +12 -32
  389. package/dist/utils/file-system.d.ts.map +1 -1
  390. package/dist/utils/file-system.js +16 -40
  391. package/dist/utils/file-system.js.map +1 -1
  392. package/dist/utils/frontmatter.d.ts +7 -11
  393. package/dist/utils/frontmatter.d.ts.map +1 -1
  394. package/dist/utils/frontmatter.js +11 -11
  395. package/dist/utils/frontmatter.js.map +1 -1
  396. package/dist/utils/interactive.d.ts +4 -9
  397. package/dist/utils/interactive.d.ts.map +1 -1
  398. package/dist/utils/interactive.js +2 -4
  399. package/dist/utils/interactive.js.map +1 -1
  400. package/dist/utils/item-discovery.d.ts +15 -10
  401. package/dist/utils/item-discovery.d.ts.map +1 -1
  402. package/dist/utils/item-discovery.js +42 -47
  403. package/dist/utils/item-discovery.js.map +1 -1
  404. package/dist/utils/link.d.ts +13 -4
  405. package/dist/utils/link.d.ts.map +1 -1
  406. package/dist/utils/link.js +13 -4
  407. package/dist/utils/link.js.map +1 -1
  408. package/dist/utils/match.js.map +1 -1
  409. package/dist/utils/requirement-diff.d.ts +13 -23
  410. package/dist/utils/requirement-diff.d.ts.map +1 -1
  411. package/dist/utils/requirement-diff.js +13 -23
  412. package/dist/utils/requirement-diff.js.map +1 -1
  413. package/dist/utils/spec-files.d.ts +10 -11
  414. package/dist/utils/spec-files.d.ts.map +1 -1
  415. package/dist/utils/spec-files.js +31 -22
  416. package/dist/utils/spec-files.js.map +1 -1
  417. package/dist/utils/task-progress.d.ts +11 -9
  418. package/dist/utils/task-progress.d.ts.map +1 -1
  419. package/dist/utils/task-progress.js +53 -32
  420. package/dist/utils/task-progress.js.map +1 -1
  421. package/dist/utils/timestamp.d.ts +5 -8
  422. package/dist/utils/timestamp.d.ts.map +1 -1
  423. package/dist/utils/timestamp.js +5 -8
  424. package/dist/utils/timestamp.js.map +1 -1
  425. package/package.json +9 -10
  426. package/schemas/decision/templates/decision.md +3 -1
  427. package/schemas/decision/templates/index.md +2 -2
  428. package/schemas/issue/schema.yaml +11 -2
  429. package/schemas/issue/templates/spec.md +37 -3
  430. package/schemas/sdd/schema.yaml +24 -1
  431. package/schemas/sdd/templates/spec.md +37 -3
@@ -1,14 +1,6 @@
1
- /**
2
- * Command Adapters Index
3
- *
4
- * Re-exports the tool command adapters tospec ships (claude only).
5
- */
6
1
  import { claudeAdapter } from './claude.js';
7
2
  export { claudeAdapter };
8
- /**
9
- * The adapter registry. Adding a tool means adding it here — callers resolve by
10
- * `toolId` rather than testing the tool name, so no generation code changes.
11
- */
3
+ /** Adding a tool means adding it here; callers resolve by `toolId`. */
12
4
  export const COMMAND_ADAPTERS = [claudeAdapter];
13
5
  export function findCommandAdapter(toolId) {
14
6
  return COMMAND_ADAPTERS.find((adapter) => adapter.toolId === toolId);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/core/command-generation/adapters/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EAAE,aAAa,EAAE,CAAC;AAEzB;;;GAGG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAkC,CAAC,aAAa,CAAC,CAAC;AAE/E,MAAM,UAAU,kBAAkB,CAAC,MAAc;IAC/C,OAAO,gBAAgB,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC;AACvE,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/core/command-generation/adapters/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EAAE,aAAa,EAAE,CAAC;AAEzB,uEAAuE;AACvE,MAAM,CAAC,MAAM,gBAAgB,GAAkC,CAAC,aAAa,CAAC,CAAC;AAE/E,MAAM,UAAU,kBAAkB,CAAC,MAAc;IAC/C,OAAO,gBAAgB,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC;AACvE,CAAC"}
@@ -1,21 +1,4 @@
1
- /**
2
- * Command Generator
3
- *
4
- * Functions for generating command files using tool adapters.
5
- */
6
1
  import type { CommandContent, ToolCommandAdapter, GeneratedCommand } from './types.js';
7
- /**
8
- * Generate a single command file using the provided adapter.
9
- * @param content - The tool-agnostic command content
10
- * @param adapter - The tool-specific adapter
11
- * @returns Generated command with path and file content
12
- */
13
2
  export declare function generateCommand(content: CommandContent, adapter: ToolCommandAdapter): GeneratedCommand;
14
- /**
15
- * Generate multiple command files using the provided adapter.
16
- * @param contents - Array of tool-agnostic command contents
17
- * @param adapter - The tool-specific adapter
18
- * @returns Array of generated commands with paths and file contents
19
- */
20
3
  export declare function generateCommands(contents: CommandContent[], adapter: ToolCommandAdapter): GeneratedCommand[];
21
4
  //# sourceMappingURL=generator.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../../src/core/command-generation/generator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEvF;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,cAAc,EACvB,OAAO,EAAE,kBAAkB,GAC1B,gBAAgB,CAKlB;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,cAAc,EAAE,EAC1B,OAAO,EAAE,kBAAkB,GAC1B,gBAAgB,EAAE,CAEpB"}
1
+ {"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../../src/core/command-generation/generator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEvF,wBAAgB,eAAe,CAC7B,OAAO,EAAE,cAAc,EACvB,OAAO,EAAE,kBAAkB,GAC1B,gBAAgB,CAKlB;AAED,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,cAAc,EAAE,EAC1B,OAAO,EAAE,kBAAkB,GAC1B,gBAAgB,EAAE,CAEpB"}
@@ -1,26 +1,9 @@
1
- /**
2
- * Command Generator
3
- *
4
- * Functions for generating command files using tool adapters.
5
- */
6
- /**
7
- * Generate a single command file using the provided adapter.
8
- * @param content - The tool-agnostic command content
9
- * @param adapter - The tool-specific adapter
10
- * @returns Generated command with path and file content
11
- */
12
1
  export function generateCommand(content, adapter) {
13
2
  return {
14
3
  path: adapter.getFilePath(content.id),
15
4
  fileContent: adapter.formatFile(content),
16
5
  };
17
6
  }
18
- /**
19
- * Generate multiple command files using the provided adapter.
20
- * @param contents - Array of tool-agnostic command contents
21
- * @param adapter - The tool-specific adapter
22
- * @returns Array of generated commands with paths and file contents
23
- */
24
7
  export function generateCommands(contents, adapter) {
25
8
  return contents.map((content) => generateCommand(content, adapter));
26
9
  }
@@ -1 +1 @@
1
- {"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../src/core/command-generation/generator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAC7B,OAAuB,EACvB,OAA2B;IAE3B,OAAO;QACL,IAAI,EAAE,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC;QACrC,WAAW,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC;KACzC,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAC9B,QAA0B,EAC1B,OAA2B;IAE3B,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,eAAe,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;AACtE,CAAC"}
1
+ {"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../src/core/command-generation/generator.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,eAAe,CAC7B,OAAuB,EACvB,OAA2B;IAE3B,OAAO;QACL,IAAI,EAAE,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC;QACrC,WAAW,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC;KACzC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC9B,QAA0B,EAC1B,OAA2B;IAE3B,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,eAAe,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;AACtE,CAAC"}
@@ -1,9 +1,6 @@
1
1
  /**
2
- * Command Generation Module
3
- *
4
- * Generic command generation with a tool adapter. Claude Code is the only
5
- * shipped adapter today; add a tool by writing an adapter in adapters/ and
6
- * registering it in COMMAND_ADAPTERS — callers resolve it by toolId.
2
+ * Command generation through a tool adapter. Claude Code is the only shipped
3
+ * one; add a tool by writing an adapter and registering it in COMMAND_ADAPTERS.
7
4
  */
8
5
  export type { CommandContent, ToolCommandAdapter, GeneratedCommand, } from './types.js';
9
6
  export { generateCommand, generateCommands } from './generator.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/command-generation/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,YAAY,EACV,cAAc,EACd,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAGnE,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/command-generation/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,YAAY,EACV,cAAc,EACd,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAEnE,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC"}
@@ -1,12 +1,3 @@
1
- /**
2
- * Command Generation Module
3
- *
4
- * Generic command generation with a tool adapter. Claude Code is the only
5
- * shipped adapter today; add a tool by writing an adapter in adapters/ and
6
- * registering it in COMMAND_ADAPTERS — callers resolve it by toolId.
7
- */
8
- // Generator functions
9
1
  export { generateCommand, generateCommands } from './generator.js';
10
- // Adapters
11
2
  export { claudeAdapter, COMMAND_ADAPTERS, findCommandAdapter } from './adapters/index.js';
12
3
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/command-generation/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AASH,sBAAsB;AACtB,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAEnE,WAAW;AACX,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/command-generation/index.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAEnE,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC"}
@@ -1,56 +1,30 @@
1
- /**
2
- * Command Generation Types
3
- *
4
- * Tool-agnostic interfaces for command generation.
5
- * These types separate "what to generate" from "how to format it".
6
- */
7
- /**
8
- * Tool-agnostic command data.
9
- * Represents the content of a command without any tool-specific formatting.
10
- */
1
+ /** A command's content, before any tool-specific formatting. */
11
2
  export interface CommandContent {
12
- /** Command identifier (e.g., 'explore', 'apply', 'new') */
3
+ /** e.g. 'explore', 'apply', 'new'. */
13
4
  id: string;
14
- /** Human-readable name (e.g., 'Tospec Explore') */
15
5
  name: string;
16
- /** Brief description of command purpose */
17
6
  description: string;
18
- /** Grouping category (e.g., 'Workflow') */
7
+ /** Grouping category, e.g. 'Workflow'. */
19
8
  category: string;
20
- /** Array of tag strings */
21
9
  tags: string[];
22
- /** The command instruction content (body text) */
10
+ /** The command instruction text. */
23
11
  body: string;
24
12
  }
25
- /**
26
- * Per-tool formatting strategy.
27
- * Each AI tool implements this interface to handle its specific file path
28
- * and frontmatter format requirements.
29
- */
13
+ /** Per-tool formatting strategy: where the file goes and how it is framed. */
30
14
  export interface ToolCommandAdapter {
31
- /** Tool identifier matching AIToolOption.value (e.g., 'claude', 'cursor') */
15
+ /** Matches AIToolOption.value, e.g. 'claude'. */
32
16
  toolId: string;
33
17
  /**
34
- * Returns the file path for a command.
35
- * @param commandId - The command identifier (e.g., 'explore')
36
- * @returns Path from project root (e.g., '.claude/commands/tosx/explore.md').
37
- * May be absolute for tools with global-scoped prompts (e.g., Codex).
18
+ * Path from the project root, e.g. '.claude/commands/tosx/explore.md'. May be
19
+ * absolute for a tool with global-scoped prompts.
38
20
  */
39
21
  getFilePath(commandId: string): string;
40
- /**
41
- * Formats the complete file content including frontmatter.
42
- * @param content - The tool-agnostic command content
43
- * @returns Complete file content ready to write
44
- */
22
+ /** The complete file, frontmatter included. */
45
23
  formatFile(content: CommandContent): string;
46
24
  }
47
- /**
48
- * Result of generating a command file.
49
- */
50
25
  export interface GeneratedCommand {
51
- /** File path from project root, or absolute for global-scoped tools */
26
+ /** From the project root, or absolute for global-scoped tools. */
52
27
  path: string;
53
- /** Complete file content (frontmatter + body) */
54
28
  fileContent: string;
55
29
  }
56
30
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/core/command-generation/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,2DAA2D;IAC3D,EAAE,EAAE,MAAM,CAAC;IACX,mDAAmD;IACnD,IAAI,EAAE,MAAM,CAAC;IACb,2CAA2C;IAC3C,WAAW,EAAE,MAAM,CAAC;IACpB,2CAA2C;IAC3C,QAAQ,EAAE,MAAM,CAAC;IACjB,2BAA2B;IAC3B,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,kDAAkD;IAClD,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,6EAA6E;IAC7E,MAAM,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC;IACvC;;;;OAIG;IACH,UAAU,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,CAAC;CAC7C;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,uEAAuE;IACvE,IAAI,EAAE,MAAM,CAAC;IACb,iDAAiD;IACjD,WAAW,EAAE,MAAM,CAAC;CACrB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/core/command-generation/types.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAChE,MAAM,WAAW,cAAc;IAC7B,sCAAsC;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,0CAA0C;IAC1C,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,oCAAoC;IACpC,IAAI,EAAE,MAAM,CAAC;CACd;AAED,8EAA8E;AAC9E,MAAM,WAAW,kBAAkB;IACjC,iDAAiD;IACjD,MAAM,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC;IACvC,+CAA+C;IAC/C,UAAU,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,CAAC;CAC7C;AAED,MAAM,WAAW,gBAAgB;IAC/B,kEAAkE;IAClE,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB"}
@@ -1,8 +1,2 @@
1
- /**
2
- * Command Generation Types
3
- *
4
- * Tool-agnostic interfaces for command generation.
5
- * These types separate "what to generate" from "how to format it".
6
- */
7
1
  export {};
8
2
  //# sourceMappingURL=types.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/core/command-generation/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/core/command-generation/types.ts"],"names":[],"mappings":""}
@@ -1,22 +1,7 @@
1
1
  /**
2
- * Shared YAML frontmatter helpers for command adapters.
3
- *
4
- * Several tool adapters emit YAML frontmatter and need to escape
5
- * user-facing strings (name, description, category, tags) so the
6
- * generated file stays valid YAML. This module centralizes that logic
7
- * so the behavior is identical across adapters and fixed in one place.
8
- */
9
- /**
10
- * Escapes a string value for safe YAML output.
11
- *
12
- * Quotes the value with double quotes when it contains characters that
13
- * carry special meaning in YAML (or leading/trailing whitespace), and
14
- * escapes the characters that are not representable verbatim inside a
15
- * double-quoted scalar: backslash, double quote, line feed and carriage
16
- * return. Values without special characters are returned unquoted.
17
- *
18
- * @param value - The raw string to embed in YAML frontmatter.
19
- * @returns The value, double-quoted and escaped when necessary.
2
+ * Double-quotes and escapes a frontmatter value when it carries YAML-special
3
+ * characters or edge whitespace; returns it unquoted otherwise. Shared by every
4
+ * adapter so the escaping cannot differ between them.
20
5
  */
21
6
  export declare function escapeYamlValue(value: string): string;
22
7
  //# sourceMappingURL=yaml.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"yaml.d.ts","sourceRoot":"","sources":["../../../src/core/command-generation/yaml.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAgBrD"}
1
+ {"version":3,"file":"yaml.d.ts","sourceRoot":"","sources":["../../../src/core/command-generation/yaml.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAarD"}
@@ -1,31 +1,13 @@
1
1
  /**
2
- * Shared YAML frontmatter helpers for command adapters.
3
- *
4
- * Several tool adapters emit YAML frontmatter and need to escape
5
- * user-facing strings (name, description, category, tags) so the
6
- * generated file stays valid YAML. This module centralizes that logic
7
- * so the behavior is identical across adapters and fixed in one place.
8
- */
9
- /**
10
- * Escapes a string value for safe YAML output.
11
- *
12
- * Quotes the value with double quotes when it contains characters that
13
- * carry special meaning in YAML (or leading/trailing whitespace), and
14
- * escapes the characters that are not representable verbatim inside a
15
- * double-quoted scalar: backslash, double quote, line feed and carriage
16
- * return. Values without special characters are returned unquoted.
17
- *
18
- * @param value - The raw string to embed in YAML frontmatter.
19
- * @returns The value, double-quoted and escaped when necessary.
2
+ * Double-quotes and escapes a frontmatter value when it carries YAML-special
3
+ * characters or edge whitespace; returns it unquoted otherwise. Shared by every
4
+ * adapter so the escaping cannot differ between them.
20
5
  */
21
6
  export function escapeYamlValue(value) {
22
- // Check if value needs quoting (contains special YAML characters or starts/ends with whitespace)
23
7
  const needsQuoting = /[:\n\r#{}[\],&*!|>'"%@`]|^\s|\s$/.test(value);
24
8
  if (needsQuoting) {
25
- // Use double quotes and escape characters that are not safe to emit
26
- // verbatim inside a double-quoted YAML scalar. Carriage returns must be
27
- // escaped too: a literal CR inside double quotes is subject to YAML line
28
- // folding/normalization and would silently corrupt the round-tripped value.
9
+ // CR too: a literal one inside double quotes is subject to YAML line
10
+ // folding and corrupts the round-tripped value.
29
11
  const escaped = value
30
12
  .replace(/\\/g, '\\\\')
31
13
  .replace(/"/g, '\\"')
@@ -1 +1 @@
1
- {"version":3,"file":"yaml.js","sourceRoot":"","sources":["../../../src/core/command-generation/yaml.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,eAAe,CAAC,KAAa;IAC3C,iGAAiG;IACjG,MAAM,YAAY,GAAG,kCAAkC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACpE,IAAI,YAAY,EAAE,CAAC;QACjB,oEAAoE;QACpE,wEAAwE;QACxE,yEAAyE;QACzE,4EAA4E;QAC5E,MAAM,OAAO,GAAG,KAAK;aAClB,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC;aACtB,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC;aACpB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC;aACrB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QACzB,OAAO,IAAI,OAAO,GAAG,CAAC;IACxB,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
1
+ {"version":3,"file":"yaml.js","sourceRoot":"","sources":["../../../src/core/command-generation/yaml.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,KAAa;IAC3C,MAAM,YAAY,GAAG,kCAAkC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACpE,IAAI,YAAY,EAAE,CAAC;QACjB,qEAAqE;QACrE,gDAAgD;QAChD,MAAM,OAAO,GAAG,KAAK;aAClB,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC;aACtB,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC;aACpB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC;aACrB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QACzB,OAAO,IAAI,OAAO,GAAG,CAAC;IACxB,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -1,9 +1,7 @@
1
1
  import type { ProjectConfig } from './project-config.js';
2
2
  /**
3
- * Serialize config to YAML string with helpful comments.
4
- *
5
- * @param config - Partial config object (schema required, context/rules optional)
6
- * @returns YAML string ready to write to file
3
+ * A starter config.yaml: the `schema` value plus commented-out examples of
4
+ * `context` and `rules`. Only `schema` is read from `config`.
7
5
  */
8
6
  export declare function serializeConfig(config: Partial<ProjectConfig>): string;
9
7
  //# sourceMappingURL=config-prompts.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config-prompts.d.ts","sourceRoot":"","sources":["../../src/core/config-prompts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,MAAM,CA8BtE"}
1
+ {"version":3,"file":"config-prompts.d.ts","sourceRoot":"","sources":["../../src/core/config-prompts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,MAAM,CA2BtE"}
@@ -1,15 +1,11 @@
1
1
  /**
2
- * Serialize config to YAML string with helpful comments.
3
- *
4
- * @param config - Partial config object (schema required, context/rules optional)
5
- * @returns YAML string ready to write to file
2
+ * A starter config.yaml: the `schema` value plus commented-out examples of
3
+ * `context` and `rules`. Only `schema` is read from `config`.
6
4
  */
7
5
  export function serializeConfig(config) {
8
6
  const lines = [];
9
- // Schema (required)
10
7
  lines.push(`schema: ${config.schema}`);
11
8
  lines.push('');
12
- // Context section with comments
13
9
  lines.push('# Project context (optional)');
14
10
  lines.push('# This is shown to AI when creating artifacts.');
15
11
  lines.push('# Add your tech stack, conventions, style guides, domain knowledge, etc.');
@@ -19,7 +15,6 @@ export function serializeConfig(config) {
19
15
  lines.push('# We use conventional commits');
20
16
  lines.push('# Domain: e-commerce platform');
21
17
  lines.push('');
22
- // Rules section with comments
23
18
  lines.push('# Per-artifact rules (optional)');
24
19
  lines.push('# Add custom rules for specific artifacts.');
25
20
  lines.push('# Example:');
@@ -1 +1 @@
1
- {"version":3,"file":"config-prompts.js","sourceRoot":"","sources":["../../src/core/config-prompts.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,MAA8B;IAC5D,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,oBAAoB;IACpB,KAAK,CAAC,IAAI,CAAC,WAAW,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IACvC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,gCAAgC;IAChC,KAAK,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;IAC3C,KAAK,CAAC,IAAI,CAAC,gDAAgD,CAAC,CAAC;IAC7D,KAAK,CAAC,IAAI,CAAC,0EAA0E,CAAC,CAAC;IACvF,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACzB,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IAC7B,KAAK,CAAC,IAAI,CAAC,8CAA8C,CAAC,CAAC;IAC3D,KAAK,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC;IAChD,KAAK,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC;IAChD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,8BAA8B;IAC9B,KAAK,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;IAC9C,KAAK,CAAC,IAAI,CAAC,4CAA4C,CAAC,CAAC;IACzD,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACzB,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACzB,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;IAC9B,KAAK,CAAC,IAAI,CAAC,0CAA0C,CAAC,CAAC;IACvD,KAAK,CAAC,IAAI,CAAC,gDAAgD,CAAC,CAAC;IAC7D,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,kDAAkD,CAAC,CAAC;IAE/D,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AACjC,CAAC"}
1
+ {"version":3,"file":"config-prompts.js","sourceRoot":"","sources":["../../src/core/config-prompts.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,MAA8B;IAC5D,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,KAAK,CAAC,IAAI,CAAC,WAAW,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IACvC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,KAAK,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;IAC3C,KAAK,CAAC,IAAI,CAAC,gDAAgD,CAAC,CAAC;IAC7D,KAAK,CAAC,IAAI,CAAC,0EAA0E,CAAC,CAAC;IACvF,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACzB,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IAC7B,KAAK,CAAC,IAAI,CAAC,8CAA8C,CAAC,CAAC;IAC3D,KAAK,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC;IAChD,KAAK,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC;IAChD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,KAAK,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;IAC9C,KAAK,CAAC,IAAI,CAAC,4CAA4C,CAAC,CAAC;IACzD,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACzB,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACzB,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;IAC9B,KAAK,CAAC,IAAI,CAAC,0CAA0C,CAAC,CAAC;IACvD,KAAK,CAAC,IAAI,CAAC,gDAAgD,CAAC,CAAC;IAC7D,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,kDAAkD,CAAC,CAAC;IAE/D,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AACjC,CAAC"}
@@ -1,8 +1,5 @@
1
1
  import { z } from 'zod';
2
- /**
3
- * Zod schema for global Tospec configuration.
4
- * Uses passthrough() to preserve unknown fields for forward compatibility.
5
- */
2
+ /** passthrough() preserves unknown fields, for forward compatibility. */
6
3
  export declare const GlobalConfigSchema: z.ZodObject<{
7
4
  profile: z.ZodDefault<z.ZodOptional<z.ZodEnum<{
8
5
  core: "core";
@@ -11,67 +8,25 @@ export declare const GlobalConfigSchema: z.ZodObject<{
11
8
  workflows: z.ZodOptional<z.ZodArray<z.ZodString>>;
12
9
  }, z.core.$loose>;
13
10
  export type GlobalConfigType = z.infer<typeof GlobalConfigSchema>;
14
- /**
15
- * Default configuration values.
16
- */
17
11
  export declare const DEFAULT_CONFIG: GlobalConfigType;
18
12
  /**
19
13
  * True when a dot-notation key path contains a prototype-reaching segment.
20
- * Callers that bypass key validation (e.g. --allow-unknown) still must not
21
- * bypass this.
14
+ * `--allow-unknown` relaxes key validation, never this.
22
15
  */
23
16
  export declare function hasUnsafeKeySegment(path: string): boolean;
24
- /**
25
- * Validate a config key path for CLI set operations.
26
- * Unknown top-level keys are rejected unless explicitly allowed by the caller.
27
- */
17
+ /** Unknown top-level keys are rejected unless the caller allows them. */
28
18
  export declare function validateConfigKeyPath(path: string): {
29
19
  valid: boolean;
30
20
  reason?: string;
31
21
  };
32
- /**
33
- * Get a nested value from an object using dot notation.
34
- *
35
- * @param obj - The object to access
36
- * @param path - Dot-separated path (e.g., "featureFlags.someFlag")
37
- * @returns The value at the path, or undefined if not found
38
- */
22
+ /** Reads `obj` at a dot-separated path, e.g. "featureFlags.someFlag". */
39
23
  export declare function getNestedValue(obj: Record<string, unknown>, path: string): unknown;
40
- /**
41
- * Set a nested value in an object using dot notation.
42
- * Creates intermediate objects as needed.
43
- *
44
- * @param obj - The object to modify (mutated in place)
45
- * @param path - Dot-separated path (e.g., "featureFlags.someFlag")
46
- * @param value - The value to set
47
- */
24
+ /** Writes `obj` at a dot-separated path, creating intermediate objects. */
48
25
  export declare function setNestedValue(obj: Record<string, unknown>, path: string, value: unknown): void;
49
- /**
50
- * Delete a nested value from an object using dot notation.
51
- *
52
- * @param obj - The object to modify (mutated in place)
53
- * @param path - Dot-separated path (e.g., "featureFlags.someFlag")
54
- * @returns true if the key existed and was deleted, false otherwise
55
- */
26
+ /** Deletes `obj`'s value at a dot-separated path; false when it was absent. */
56
27
  export declare function deleteNestedValue(obj: Record<string, unknown>, path: string): boolean;
57
- /**
58
- * Coerce a string value to its appropriate type.
59
- * - "true" / "false" -> boolean
60
- * - Numeric strings -> number
61
- * - JSON arrays/objects -> parsed containers
62
- * - Everything else -> string
63
- *
64
- * @param value - The string value to coerce
65
- * @param forceString - If true, always return the value as a string
66
- * @returns The coerced value
67
- */
68
- export declare function coerceValue(value: string, forceString?: boolean): string | number | boolean | unknown[] | Record<string, unknown>;
69
- /**
70
- * Validate a configuration object against the schema.
71
- *
72
- * @param config - The configuration to validate
73
- * @returns Validation result with success status and optional error message
74
- */
28
+ /** Reads a CLI string as a boolean, number, JSON container, list, or string. */
29
+ export declare function coerceValue(value: string, forceString?: boolean, key?: string): string | number | boolean | unknown[] | Record<string, unknown>;
75
30
  export declare function validateConfig(config: unknown): {
76
31
  success: boolean;
77
32
  error?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"config-schema.d.ts","sourceRoot":"","sources":["../../src/core/config-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;GAGG;AACH,eAAO,MAAM,kBAAkB;;;;;;iBAUf,CAAC;AAEjB,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAElE;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,gBAE5B,CAAC;AAcF;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAsBvF;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAkBlF;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAwB/F;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAyBrF;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,MAAM,EACb,WAAW,GAAE,OAAe,GAC3B,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAyBjE;AA2BD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,OAAO,GAAG;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAYpF"}
1
+ {"version":3,"file":"config-schema.d.ts","sourceRoot":"","sources":["../../src/core/config-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,yEAAyE;AACzE,eAAO,MAAM,kBAAkB;;;;;;iBAUf,CAAC;AAEjB,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAElE,eAAO,MAAM,cAAc,EAAE,gBAE5B,CAAC;AAcF;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED,yEAAyE;AACzE,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAsBvF;AAED,yEAAyE;AACzE,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAkBlF;AAED,2EAA2E;AAC3E,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAwB/F;AAED,+EAA+E;AAC/E,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAqCrF;AAkBD,gFAAgF;AAChF,wBAAgB,WAAW,CACzB,KAAK,EAAE,MAAM,EACb,WAAW,GAAE,OAAe,EAC5B,GAAG,CAAC,EAAE,MAAM,GACX,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAkCjE;AA2BD,wBAAgB,cAAc,CAAC,MAAM,EAAE,OAAO,GAAG;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAWpF"}
@@ -1,8 +1,5 @@
1
1
  import { z } from 'zod';
2
- /**
3
- * Zod schema for global Tospec configuration.
4
- * Uses passthrough() to preserve unknown fields for forward compatibility.
5
- */
2
+ /** passthrough() preserves unknown fields, for forward compatibility. */
6
3
  export const GlobalConfigSchema = z
7
4
  .object({
8
5
  profile: z
@@ -14,9 +11,6 @@ export const GlobalConfigSchema = z
14
11
  .optional(),
15
12
  })
16
13
  .passthrough();
17
- /**
18
- * Default configuration values.
19
- */
20
14
  export const DEFAULT_CONFIG = {
21
15
  profile: 'core',
22
16
  };
@@ -31,16 +25,12 @@ function hasUnsafeSegment(keys) {
31
25
  }
32
26
  /**
33
27
  * True when a dot-notation key path contains a prototype-reaching segment.
34
- * Callers that bypass key validation (e.g. --allow-unknown) still must not
35
- * bypass this.
28
+ * `--allow-unknown` relaxes key validation, never this.
36
29
  */
37
30
  export function hasUnsafeKeySegment(path) {
38
31
  return hasUnsafeSegment(path.split('.'));
39
32
  }
40
- /**
41
- * Validate a config key path for CLI set operations.
42
- * Unknown top-level keys are rejected unless explicitly allowed by the caller.
43
- */
33
+ /** Unknown top-level keys are rejected unless the caller allows them. */
44
34
  export function validateConfigKeyPath(path) {
45
35
  const rawKeys = path.split('.');
46
36
  if (rawKeys.length === 0 || rawKeys.some((key) => key.trim() === '')) {
@@ -59,13 +49,7 @@ export function validateConfigKeyPath(path) {
59
49
  }
60
50
  return { valid: true };
61
51
  }
62
- /**
63
- * Get a nested value from an object using dot notation.
64
- *
65
- * @param obj - The object to access
66
- * @param path - Dot-separated path (e.g., "featureFlags.someFlag")
67
- * @returns The value at the path, or undefined if not found
68
- */
52
+ /** Reads `obj` at a dot-separated path, e.g. "featureFlags.someFlag". */
69
53
  export function getNestedValue(obj, path) {
70
54
  const keys = path.split('.');
71
55
  if (hasUnsafeSegment(keys)) {
@@ -83,19 +67,12 @@ export function getNestedValue(obj, path) {
83
67
  }
84
68
  return current;
85
69
  }
86
- /**
87
- * Set a nested value in an object using dot notation.
88
- * Creates intermediate objects as needed.
89
- *
90
- * @param obj - The object to modify (mutated in place)
91
- * @param path - Dot-separated path (e.g., "featureFlags.someFlag")
92
- * @param value - The value to set
93
- */
70
+ /** Writes `obj` at a dot-separated path, creating intermediate objects. */
94
71
  export function setNestedValue(obj, path, value) {
95
72
  const keys = path.split('.');
96
- // Compared literally rather than through a helper, so the guard is plain to a
97
- // reader and to static analysis. Checked for the whole path before anything is
98
- // written, so a rejected key never leaves half-created objects behind.
73
+ // Compared literally rather than through a helper, so the guard is plain to
74
+ // static analysis. Checked for the whole path before anything is written, so
75
+ // a rejected key leaves no half-created objects.
99
76
  for (const key of keys) {
100
77
  if (key === '__proto__' || key === 'constructor' || key === 'prototype') {
101
78
  return;
@@ -112,13 +89,7 @@ export function setNestedValue(obj, path, value) {
112
89
  const lastKey = keys[keys.length - 1];
113
90
  current[lastKey] = value;
114
91
  }
115
- /**
116
- * Delete a nested value from an object using dot notation.
117
- *
118
- * @param obj - The object to modify (mutated in place)
119
- * @param path - Dot-separated path (e.g., "featureFlags.someFlag")
120
- * @returns true if the key existed and was deleted, false otherwise
121
- */
92
+ /** Deletes `obj`'s value at a dot-separated path; false when it was absent. */
122
93
  export function deleteNestedValue(obj, path) {
123
94
  const keys = path.split('.');
124
95
  for (const key of keys) {
@@ -127,43 +98,57 @@ export function deleteNestedValue(obj, path) {
127
98
  }
128
99
  }
129
100
  let current = obj;
101
+ // Every container on the way down, so emptied parents can be pruned after
102
+ // the leaf goes: `unset foo.bar` used to leave `foo: {}` behind, a key
103
+ // `config list` then showed as if the user had set it.
104
+ const trail = [];
130
105
  for (let i = 0; i < keys.length - 1; i++) {
131
106
  const key = keys[i];
132
107
  if (current[key] === undefined || current[key] === null || typeof current[key] !== 'object') {
133
108
  return false;
134
109
  }
110
+ trail.push({ parent: current, key });
135
111
  current = current[key];
136
112
  }
137
113
  const lastKey = keys[keys.length - 1];
138
- if (lastKey in current) {
139
- delete current[lastKey];
140
- return true;
114
+ if (!(lastKey in current)) {
115
+ return false;
116
+ }
117
+ delete current[lastKey];
118
+ for (let i = trail.length - 1; i >= 0; i--) {
119
+ const { parent, key } = trail[i];
120
+ const container = parent[key];
121
+ if (Object.keys(container).length > 0)
122
+ break;
123
+ delete parent[key];
141
124
  }
142
- return false;
125
+ return true;
143
126
  }
144
127
  /**
145
- * Coerce a string value to its appropriate type.
146
- * - "true" / "false" -> boolean
147
- * - Numeric strings -> number
148
- * - JSON arrays/objects -> parsed containers
149
- * - Everything else -> string
150
- *
151
- * @param value - The string value to coerce
152
- * @param forceString - If true, always return the value as a string
153
- * @returns The coerced value
128
+ * Config keys whose value is a list. Splitting on commas cannot be decided from
129
+ * the value alone — a string key such as `context` may legitimately contain
130
+ * them — so the decision is keyed on the field, read from the same schema that
131
+ * validates the result.
154
132
  */
155
- export function coerceValue(value, forceString = false) {
133
+ const ARRAY_VALUED_KEYS = new Set(Object.entries(GlobalConfigSchema.shape)
134
+ .filter(([, field]) => {
135
+ // Unwrap `.optional()` to reach the array underneath.
136
+ const inner = field instanceof z.ZodOptional ? field.unwrap() : field;
137
+ return inner instanceof z.ZodArray;
138
+ })
139
+ .map(([name]) => name));
140
+ /** Reads a CLI string as a boolean, number, JSON container, list, or string. */
141
+ export function coerceValue(value, forceString = false, key) {
156
142
  if (forceString) {
157
143
  return value;
158
144
  }
159
- // Boolean coercion
160
145
  if (value === 'true') {
161
146
  return true;
162
147
  }
163
148
  if (value === 'false') {
164
149
  return false;
165
150
  }
166
- // Number coercion - must be a valid finite number
151
+ // Finite numbers only; `''`, `'NaN'` and `'Infinity'` stay strings.
167
152
  const num = Number(value);
168
153
  if (!isNaN(num) && isFinite(num) && value.trim() !== '') {
169
154
  return num;
@@ -172,6 +157,15 @@ export function coerceValue(value, forceString = false) {
172
157
  if (jsonContainer !== undefined) {
173
158
  return jsonContainer;
174
159
  }
160
+ // `--tools a,b,c` already reads this way, so requiring a JSON array would make
161
+ // the syntax the CLI teaches elsewhere fail with a type error. JSON is tried
162
+ // first, so an explicit array literal still wins and `--string` opts out.
163
+ if (key !== undefined && ARRAY_VALUED_KEYS.has(key)) {
164
+ return value
165
+ .split(',')
166
+ .map((entry) => entry.trim())
167
+ .filter(Boolean);
168
+ }
175
169
  return value;
176
170
  }
177
171
  function parseJsonContainer(value) {
@@ -195,12 +189,6 @@ function parseJsonContainer(value) {
195
189
  }
196
190
  return undefined;
197
191
  }
198
- /**
199
- * Validate a configuration object against the schema.
200
- *
201
- * @param config - The configuration to validate
202
- * @returns Validation result with success status and optional error message
203
- */
204
192
  export function validateConfig(config) {
205
193
  try {
206
194
  GlobalConfigSchema.parse(config);
@@ -208,8 +196,7 @@ export function validateConfig(config) {
208
196
  }
209
197
  catch (error) {
210
198
  if (error instanceof z.ZodError) {
211
- const zodError = error;
212
- const messages = zodError.issues.map((e) => `${e.path.join('.')}: ${e.message}`);
199
+ const messages = error.issues.map((e) => `${e.path.join('.')}: ${e.message}`);
213
200
  return { success: false, error: messages.join('; ') };
214
201
  }
215
202
  return { success: false, error: 'Unknown validation error' };