@codewalla_india/openspec 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (356) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +225 -0
  3. package/bin/openspec.js +5 -0
  4. package/dist/cli/index.d.ts +10 -0
  5. package/dist/cli/index.js +548 -0
  6. package/dist/commands/change.d.ts +39 -0
  7. package/dist/commands/change.js +279 -0
  8. package/dist/commands/completion.d.ts +72 -0
  9. package/dist/commands/completion.js +264 -0
  10. package/dist/commands/config.d.ts +36 -0
  11. package/dist/commands/config.js +552 -0
  12. package/dist/commands/context.d.ts +3 -0
  13. package/dist/commands/context.js +155 -0
  14. package/dist/commands/doctor.d.ts +8 -0
  15. package/dist/commands/doctor.js +163 -0
  16. package/dist/commands/feedback.d.ts +9 -0
  17. package/dist/commands/feedback.js +183 -0
  18. package/dist/commands/schema.d.ts +6 -0
  19. package/dist/commands/schema.js +869 -0
  20. package/dist/commands/shared-gather.d.ts +14 -0
  21. package/dist/commands/shared-gather.js +31 -0
  22. package/dist/commands/shared-output.d.ts +18 -0
  23. package/dist/commands/shared-output.js +61 -0
  24. package/dist/commands/show.d.ts +19 -0
  25. package/dist/commands/show.js +177 -0
  26. package/dist/commands/spec.d.ts +19 -0
  27. package/dist/commands/spec.js +236 -0
  28. package/dist/commands/store.d.ts +3 -0
  29. package/dist/commands/store.js +547 -0
  30. package/dist/commands/validate.d.ts +26 -0
  31. package/dist/commands/validate.js +330 -0
  32. package/dist/commands/workflow/index.d.ts +17 -0
  33. package/dist/commands/workflow/index.js +12 -0
  34. package/dist/commands/workflow/instructions.d.ts +45 -0
  35. package/dist/commands/workflow/instructions.js +500 -0
  36. package/dist/commands/workflow/new-change.d.ts +20 -0
  37. package/dist/commands/workflow/new-change.js +106 -0
  38. package/dist/commands/workflow/schemas.d.ts +10 -0
  39. package/dist/commands/workflow/schemas.js +34 -0
  40. package/dist/commands/workflow/shared.d.ts +84 -0
  41. package/dist/commands/workflow/shared.js +133 -0
  42. package/dist/commands/workflow/status.d.ts +16 -0
  43. package/dist/commands/workflow/status.js +92 -0
  44. package/dist/commands/workflow/templates.d.ts +16 -0
  45. package/dist/commands/workflow/templates.js +69 -0
  46. package/dist/commands/workset-input.d.ts +19 -0
  47. package/dist/commands/workset-input.js +112 -0
  48. package/dist/commands/workset-prompts.d.ts +12 -0
  49. package/dist/commands/workset-prompts.js +143 -0
  50. package/dist/commands/workset.d.ts +25 -0
  51. package/dist/commands/workset.js +446 -0
  52. package/dist/core/archive.d.ts +22 -0
  53. package/dist/core/archive.js +471 -0
  54. package/dist/core/artifact-graph/graph.d.ts +56 -0
  55. package/dist/core/artifact-graph/graph.js +141 -0
  56. package/dist/core/artifact-graph/index.d.ts +9 -0
  57. package/dist/core/artifact-graph/index.js +14 -0
  58. package/dist/core/artifact-graph/instruction-loader.d.ts +188 -0
  59. package/dist/core/artifact-graph/instruction-loader.js +233 -0
  60. package/dist/core/artifact-graph/outputs.d.ts +14 -0
  61. package/dist/core/artifact-graph/outputs.js +39 -0
  62. package/dist/core/artifact-graph/resolver.d.ts +81 -0
  63. package/dist/core/artifact-graph/resolver.js +257 -0
  64. package/dist/core/artifact-graph/schema.d.ts +13 -0
  65. package/dist/core/artifact-graph/schema.js +108 -0
  66. package/dist/core/artifact-graph/state.d.ts +12 -0
  67. package/dist/core/artifact-graph/state.js +31 -0
  68. package/dist/core/artifact-graph/types.d.ts +40 -0
  69. package/dist/core/artifact-graph/types.js +29 -0
  70. package/dist/core/available-tools.d.ts +17 -0
  71. package/dist/core/available-tools.js +43 -0
  72. package/dist/core/change-metadata/index.d.ts +2 -0
  73. package/dist/core/change-metadata/index.js +2 -0
  74. package/dist/core/change-metadata/schema.d.ts +19 -0
  75. package/dist/core/change-metadata/schema.js +30 -0
  76. package/dist/core/change-status-policy.d.ts +37 -0
  77. package/dist/core/change-status-policy.js +35 -0
  78. package/dist/core/command-generation/adapters/amazon-q.d.ts +13 -0
  79. package/dist/core/command-generation/adapters/amazon-q.js +26 -0
  80. package/dist/core/command-generation/adapters/antigravity.d.ts +13 -0
  81. package/dist/core/command-generation/adapters/antigravity.js +26 -0
  82. package/dist/core/command-generation/adapters/auggie.d.ts +13 -0
  83. package/dist/core/command-generation/adapters/auggie.js +27 -0
  84. package/dist/core/command-generation/adapters/bob.d.ts +14 -0
  85. package/dist/core/command-generation/adapters/bob.js +32 -0
  86. package/dist/core/command-generation/adapters/claude.d.ts +13 -0
  87. package/dist/core/command-generation/adapters/claude.js +37 -0
  88. package/dist/core/command-generation/adapters/cline.d.ts +14 -0
  89. package/dist/core/command-generation/adapters/cline.js +27 -0
  90. package/dist/core/command-generation/adapters/codebuddy.d.ts +13 -0
  91. package/dist/core/command-generation/adapters/codebuddy.js +28 -0
  92. package/dist/core/command-generation/adapters/codex.d.ts +16 -0
  93. package/dist/core/command-generation/adapters/codex.js +39 -0
  94. package/dist/core/command-generation/adapters/continue.d.ts +13 -0
  95. package/dist/core/command-generation/adapters/continue.js +28 -0
  96. package/dist/core/command-generation/adapters/costrict.d.ts +13 -0
  97. package/dist/core/command-generation/adapters/costrict.js +27 -0
  98. package/dist/core/command-generation/adapters/crush.d.ts +13 -0
  99. package/dist/core/command-generation/adapters/crush.js +30 -0
  100. package/dist/core/command-generation/adapters/cursor.d.ts +14 -0
  101. package/dist/core/command-generation/adapters/cursor.js +31 -0
  102. package/dist/core/command-generation/adapters/factory.d.ts +13 -0
  103. package/dist/core/command-generation/adapters/factory.js +27 -0
  104. package/dist/core/command-generation/adapters/gemini.d.ts +13 -0
  105. package/dist/core/command-generation/adapters/gemini.js +26 -0
  106. package/dist/core/command-generation/adapters/github-copilot.d.ts +13 -0
  107. package/dist/core/command-generation/adapters/github-copilot.js +26 -0
  108. package/dist/core/command-generation/adapters/iflow.d.ts +13 -0
  109. package/dist/core/command-generation/adapters/iflow.js +29 -0
  110. package/dist/core/command-generation/adapters/index.d.ts +32 -0
  111. package/dist/core/command-generation/adapters/index.js +32 -0
  112. package/dist/core/command-generation/adapters/junie.d.ts +13 -0
  113. package/dist/core/command-generation/adapters/junie.js +26 -0
  114. package/dist/core/command-generation/adapters/kilocode.d.ts +14 -0
  115. package/dist/core/command-generation/adapters/kilocode.js +23 -0
  116. package/dist/core/command-generation/adapters/kiro.d.ts +13 -0
  117. package/dist/core/command-generation/adapters/kiro.js +26 -0
  118. package/dist/core/command-generation/adapters/lingma.d.ts +13 -0
  119. package/dist/core/command-generation/adapters/lingma.js +30 -0
  120. package/dist/core/command-generation/adapters/opencode.d.ts +13 -0
  121. package/dist/core/command-generation/adapters/opencode.js +29 -0
  122. package/dist/core/command-generation/adapters/pi.d.ts +18 -0
  123. package/dist/core/command-generation/adapters/pi.js +42 -0
  124. package/dist/core/command-generation/adapters/qoder.d.ts +13 -0
  125. package/dist/core/command-generation/adapters/qoder.js +30 -0
  126. package/dist/core/command-generation/adapters/qwen.d.ts +13 -0
  127. package/dist/core/command-generation/adapters/qwen.js +26 -0
  128. package/dist/core/command-generation/adapters/roocode.d.ts +14 -0
  129. package/dist/core/command-generation/adapters/roocode.js +27 -0
  130. package/dist/core/command-generation/adapters/windsurf.d.ts +14 -0
  131. package/dist/core/command-generation/adapters/windsurf.js +38 -0
  132. package/dist/core/command-generation/generator.d.ts +21 -0
  133. package/dist/core/command-generation/generator.js +27 -0
  134. package/dist/core/command-generation/index.d.ts +22 -0
  135. package/dist/core/command-generation/index.js +24 -0
  136. package/dist/core/command-generation/registry.d.ts +36 -0
  137. package/dist/core/command-generation/registry.js +98 -0
  138. package/dist/core/command-generation/types.d.ts +56 -0
  139. package/dist/core/command-generation/types.js +8 -0
  140. package/dist/core/command-generation/yaml.d.ts +22 -0
  141. package/dist/core/command-generation/yaml.js +38 -0
  142. package/dist/core/completions/command-registry.d.ts +3 -0
  143. package/dist/core/completions/command-registry.js +778 -0
  144. package/dist/core/completions/completion-provider.d.ts +71 -0
  145. package/dist/core/completions/completion-provider.js +129 -0
  146. package/dist/core/completions/factory.d.ts +64 -0
  147. package/dist/core/completions/factory.js +75 -0
  148. package/dist/core/completions/generators/bash-generator.d.ts +35 -0
  149. package/dist/core/completions/generators/bash-generator.js +230 -0
  150. package/dist/core/completions/generators/fish-generator.d.ts +32 -0
  151. package/dist/core/completions/generators/fish-generator.js +160 -0
  152. package/dist/core/completions/generators/powershell-generator.d.ts +36 -0
  153. package/dist/core/completions/generators/powershell-generator.js +266 -0
  154. package/dist/core/completions/generators/zsh-generator.d.ts +47 -0
  155. package/dist/core/completions/generators/zsh-generator.js +276 -0
  156. package/dist/core/completions/installers/bash-installer.d.ts +87 -0
  157. package/dist/core/completions/installers/bash-installer.js +321 -0
  158. package/dist/core/completions/installers/fish-installer.d.ts +43 -0
  159. package/dist/core/completions/installers/fish-installer.js +151 -0
  160. package/dist/core/completions/installers/powershell-installer.d.ts +102 -0
  161. package/dist/core/completions/installers/powershell-installer.js +415 -0
  162. package/dist/core/completions/installers/zsh-installer.d.ts +117 -0
  163. package/dist/core/completions/installers/zsh-installer.js +424 -0
  164. package/dist/core/completions/shared-flags.d.ts +13 -0
  165. package/dist/core/completions/shared-flags.js +33 -0
  166. package/dist/core/completions/templates/bash-templates.d.ts +6 -0
  167. package/dist/core/completions/templates/bash-templates.js +30 -0
  168. package/dist/core/completions/templates/fish-templates.d.ts +7 -0
  169. package/dist/core/completions/templates/fish-templates.js +45 -0
  170. package/dist/core/completions/templates/powershell-templates.d.ts +6 -0
  171. package/dist/core/completions/templates/powershell-templates.js +34 -0
  172. package/dist/core/completions/templates/zsh-templates.d.ts +6 -0
  173. package/dist/core/completions/templates/zsh-templates.js +45 -0
  174. package/dist/core/completions/types.d.ts +101 -0
  175. package/dist/core/completions/types.js +2 -0
  176. package/dist/core/comprehension/config.d.ts +20 -0
  177. package/dist/core/comprehension/config.js +23 -0
  178. package/dist/core/comprehension/fingerprint.d.ts +5 -0
  179. package/dist/core/comprehension/fingerprint.js +25 -0
  180. package/dist/core/comprehension/index.d.ts +49 -0
  181. package/dist/core/comprehension/index.js +78 -0
  182. package/dist/core/comprehension/pass-record.d.ts +29 -0
  183. package/dist/core/comprehension/pass-record.js +64 -0
  184. package/dist/core/comprehension/stats.d.ts +18 -0
  185. package/dist/core/comprehension/stats.js +41 -0
  186. package/dist/core/config-prompts.d.ts +9 -0
  187. package/dist/core/config-prompts.js +34 -0
  188. package/dist/core/config-schema.d.ts +87 -0
  189. package/dist/core/config-schema.js +239 -0
  190. package/dist/core/config.d.ts +18 -0
  191. package/dist/core/config.js +39 -0
  192. package/dist/core/converters/json-converter.d.ts +6 -0
  193. package/dist/core/converters/json-converter.js +51 -0
  194. package/dist/core/file-state.d.ts +36 -0
  195. package/dist/core/file-state.js +112 -0
  196. package/dist/core/global-config.d.ts +51 -0
  197. package/dist/core/global-config.js +124 -0
  198. package/dist/core/id.d.ts +17 -0
  199. package/dist/core/id.js +30 -0
  200. package/dist/core/index.d.ts +6 -0
  201. package/dist/core/index.js +7 -0
  202. package/dist/core/init.d.ts +37 -0
  203. package/dist/core/init.js +613 -0
  204. package/dist/core/legacy-cleanup.d.ts +162 -0
  205. package/dist/core/legacy-cleanup.js +514 -0
  206. package/dist/core/list.d.ts +11 -0
  207. package/dist/core/list.js +185 -0
  208. package/dist/core/migration.d.ts +23 -0
  209. package/dist/core/migration.js +108 -0
  210. package/dist/core/openers.d.ts +77 -0
  211. package/dist/core/openers.js +251 -0
  212. package/dist/core/openspec-root.d.ts +45 -0
  213. package/dist/core/openspec-root.js +192 -0
  214. package/dist/core/parsers/change-parser.d.ts +13 -0
  215. package/dist/core/parsers/change-parser.js +197 -0
  216. package/dist/core/parsers/markdown-parser.d.ts +26 -0
  217. package/dist/core/parsers/markdown-parser.js +227 -0
  218. package/dist/core/parsers/requirement-blocks.d.ts +37 -0
  219. package/dist/core/parsers/requirement-blocks.js +201 -0
  220. package/dist/core/parsers/spec-structure.d.ts +9 -0
  221. package/dist/core/parsers/spec-structure.js +88 -0
  222. package/dist/core/planning-home.d.ts +16 -0
  223. package/dist/core/planning-home.js +67 -0
  224. package/dist/core/profile-sync-drift.d.ts +38 -0
  225. package/dist/core/profile-sync-drift.js +200 -0
  226. package/dist/core/profiles.d.ts +26 -0
  227. package/dist/core/profiles.js +40 -0
  228. package/dist/core/project-config.d.ts +120 -0
  229. package/dist/core/project-config.js +406 -0
  230. package/dist/core/references.d.ts +63 -0
  231. package/dist/core/references.js +310 -0
  232. package/dist/core/relationship-health.d.ts +65 -0
  233. package/dist/core/relationship-health.js +64 -0
  234. package/dist/core/root-selection.d.ts +122 -0
  235. package/dist/core/root-selection.js +337 -0
  236. package/dist/core/schemas/base.schema.d.ts +13 -0
  237. package/dist/core/schemas/base.schema.js +13 -0
  238. package/dist/core/schemas/change.schema.d.ts +73 -0
  239. package/dist/core/schemas/change.schema.js +31 -0
  240. package/dist/core/schemas/index.d.ts +4 -0
  241. package/dist/core/schemas/index.js +4 -0
  242. package/dist/core/schemas/spec.schema.d.ts +18 -0
  243. package/dist/core/schemas/spec.schema.js +15 -0
  244. package/dist/core/shared/index.d.ts +8 -0
  245. package/dist/core/shared/index.js +8 -0
  246. package/dist/core/shared/skill-generation.d.ts +49 -0
  247. package/dist/core/shared/skill-generation.js +96 -0
  248. package/dist/core/shared/tool-detection.d.ts +71 -0
  249. package/dist/core/shared/tool-detection.js +158 -0
  250. package/dist/core/specs-apply.d.ts +78 -0
  251. package/dist/core/specs-apply.js +394 -0
  252. package/dist/core/store/errors.d.ts +20 -0
  253. package/dist/core/store/errors.js +22 -0
  254. package/dist/core/store/foundation.d.ts +56 -0
  255. package/dist/core/store/foundation.js +251 -0
  256. package/dist/core/store/git.d.ts +23 -0
  257. package/dist/core/store/git.js +137 -0
  258. package/dist/core/store/index.d.ts +5 -0
  259. package/dist/core/store/index.js +5 -0
  260. package/dist/core/store/operations.d.ts +114 -0
  261. package/dist/core/store/operations.js +783 -0
  262. package/dist/core/store/registry.d.ts +58 -0
  263. package/dist/core/store/registry.js +275 -0
  264. package/dist/core/styles/palette.d.ts +7 -0
  265. package/dist/core/styles/palette.js +8 -0
  266. package/dist/core/templates/index.d.ts +8 -0
  267. package/dist/core/templates/index.js +9 -0
  268. package/dist/core/templates/skill-templates.d.ts +19 -0
  269. package/dist/core/templates/skill-templates.js +18 -0
  270. package/dist/core/templates/types.d.ts +19 -0
  271. package/dist/core/templates/types.js +5 -0
  272. package/dist/core/templates/workflows/apply-change.d.ts +10 -0
  273. package/dist/core/templates/workflows/apply-change.js +337 -0
  274. package/dist/core/templates/workflows/archive-change.d.ts +10 -0
  275. package/dist/core/templates/workflows/archive-change.js +278 -0
  276. package/dist/core/templates/workflows/bulk-archive-change.d.ts +10 -0
  277. package/dist/core/templates/workflows/bulk-archive-change.js +493 -0
  278. package/dist/core/templates/workflows/comprehension-guidance.d.ts +9 -0
  279. package/dist/core/templates/workflows/comprehension-guidance.js +58 -0
  280. package/dist/core/templates/workflows/continue-change.d.ts +10 -0
  281. package/dist/core/templates/workflows/continue-change.js +239 -0
  282. package/dist/core/templates/workflows/explore.d.ts +10 -0
  283. package/dist/core/templates/workflows/explore.js +464 -0
  284. package/dist/core/templates/workflows/feedback.d.ts +9 -0
  285. package/dist/core/templates/workflows/feedback.js +108 -0
  286. package/dist/core/templates/workflows/ff-change.d.ts +10 -0
  287. package/dist/core/templates/workflows/ff-change.js +205 -0
  288. package/dist/core/templates/workflows/mcp-guidance.d.ts +13 -0
  289. package/dist/core/templates/workflows/mcp-guidance.js +116 -0
  290. package/dist/core/templates/workflows/new-change.d.ts +10 -0
  291. package/dist/core/templates/workflows/new-change.js +148 -0
  292. package/dist/core/templates/workflows/onboard.d.ts +10 -0
  293. package/dist/core/templates/workflows/onboard.js +566 -0
  294. package/dist/core/templates/workflows/propose.d.ts +10 -0
  295. package/dist/core/templates/workflows/propose.js +228 -0
  296. package/dist/core/templates/workflows/store-selection.d.ts +8 -0
  297. package/dist/core/templates/workflows/store-selection.js +8 -0
  298. package/dist/core/templates/workflows/sync-specs.d.ts +10 -0
  299. package/dist/core/templates/workflows/sync-specs.js +291 -0
  300. package/dist/core/templates/workflows/verify-change.d.ts +10 -0
  301. package/dist/core/templates/workflows/verify-change.js +346 -0
  302. package/dist/core/update.d.ts +82 -0
  303. package/dist/core/update.js +557 -0
  304. package/dist/core/validation/constants.d.ts +34 -0
  305. package/dist/core/validation/constants.js +40 -0
  306. package/dist/core/validation/types.d.ts +18 -0
  307. package/dist/core/validation/types.js +2 -0
  308. package/dist/core/validation/validator.d.ts +44 -0
  309. package/dist/core/validation/validator.js +435 -0
  310. package/dist/core/view.d.ts +8 -0
  311. package/dist/core/view.js +168 -0
  312. package/dist/core/working-set.d.ts +47 -0
  313. package/dist/core/working-set.js +43 -0
  314. package/dist/core/worksets.d.ts +75 -0
  315. package/dist/core/worksets.js +245 -0
  316. package/dist/core/zod-issues.d.ts +4 -0
  317. package/dist/core/zod-issues.js +10 -0
  318. package/dist/index.d.ts +3 -0
  319. package/dist/index.js +3 -0
  320. package/dist/prompts/searchable-multi-select.d.ts +28 -0
  321. package/dist/prompts/searchable-multi-select.js +159 -0
  322. package/dist/telemetry/config.d.ts +38 -0
  323. package/dist/telemetry/config.js +136 -0
  324. package/dist/telemetry/index.d.ts +31 -0
  325. package/dist/telemetry/index.js +164 -0
  326. package/dist/ui/ascii-patterns.d.ts +16 -0
  327. package/dist/ui/ascii-patterns.js +133 -0
  328. package/dist/ui/welcome-screen.d.ts +10 -0
  329. package/dist/ui/welcome-screen.js +146 -0
  330. package/dist/utils/change-metadata.d.ts +55 -0
  331. package/dist/utils/change-metadata.js +141 -0
  332. package/dist/utils/change-utils.d.ts +71 -0
  333. package/dist/utils/change-utils.js +138 -0
  334. package/dist/utils/command-references.d.ts +18 -0
  335. package/dist/utils/command-references.js +20 -0
  336. package/dist/utils/file-system.d.ts +41 -0
  337. package/dist/utils/file-system.js +320 -0
  338. package/dist/utils/index.d.ts +6 -0
  339. package/dist/utils/index.js +9 -0
  340. package/dist/utils/interactive.d.ts +18 -0
  341. package/dist/utils/interactive.js +21 -0
  342. package/dist/utils/item-discovery.d.ts +4 -0
  343. package/dist/utils/item-discovery.js +72 -0
  344. package/dist/utils/match.d.ts +3 -0
  345. package/dist/utils/match.js +22 -0
  346. package/dist/utils/shell-detection.d.ts +20 -0
  347. package/dist/utils/shell-detection.js +41 -0
  348. package/dist/utils/task-progress.d.ts +8 -0
  349. package/dist/utils/task-progress.js +36 -0
  350. package/package.json +84 -0
  351. package/schemas/spec-driven/schema.yaml +153 -0
  352. package/schemas/spec-driven/templates/design.md +19 -0
  353. package/schemas/spec-driven/templates/proposal.md +23 -0
  354. package/schemas/spec-driven/templates/spec.md +8 -0
  355. package/schemas/spec-driven/templates/tasks.md +9 -0
  356. package/scripts/postinstall.js +83 -0
@@ -0,0 +1,500 @@
1
+ /**
2
+ * Instructions Command
3
+ *
4
+ * Generates enriched instructions for creating artifacts or applying tasks.
5
+ * Includes both artifact instructions and apply instructions.
6
+ */
7
+ import ora from 'ora';
8
+ import path from 'path';
9
+ import * as fs from 'fs';
10
+ import { loadChangeContext, generateInstructions, resolveSchema, resolveArtifactOutputs, } from '../../core/artifact-graph/index.js';
11
+ import { getChangeDir, resolveCurrentPlanningHomeSync, } from '../../core/planning-home.js';
12
+ import { resolveRootForCommand, withStoreFlag, toPlanningHome, toRootOutput, } from '../../core/root-selection.js';
13
+ import { assembleReferenceIndex, renderReferencedStoresBlock, renderReferencedStoresSection, } from '../../core/references.js';
14
+ import { readRegistrySnapshot } from '../../core/store/registry.js';
15
+ import { readProjectConfig } from '../../core/project-config.js';
16
+ import { checkComprehensionGate, ComprehensionPassError, recordComprehensionPass, } from '../../core/comprehension/index.js';
17
+ import { validateChangeExists, validateSchemaExists, } from './shared.js';
18
+ // -----------------------------------------------------------------------------
19
+ // Artifact Instructions Command
20
+ // -----------------------------------------------------------------------------
21
+ /**
22
+ * Reads the resolved root's config once, assembles the referenced-store
23
+ * index when references are declared, and resolves the config path for
24
+ * fix text. Shared by both instruction surfaces.
25
+ */
26
+ async function loadRootConfigContext(root) {
27
+ // readProjectConfig never throws: missing/unparseable configs are null.
28
+ const projectConfig = readProjectConfig(root.path);
29
+ // One registry read serves every relationship consumer in this
30
+ // output so it never carries a torn snapshot.
31
+ const snapshot = await readRegistrySnapshot();
32
+ const registryEntries = snapshot.entries;
33
+ const declared = projectConfig?.references ?? [];
34
+ const index = declared.length > 0
35
+ ? await assembleReferenceIndex({ references: declared, resolvedRoot: root, registryEntries })
36
+ : [];
37
+ // Omitted, not empty: an index emptied by self-reference omission must
38
+ // look identical to an undeclared one in JSON.
39
+ return {
40
+ projectConfig,
41
+ references: index.length > 0 ? index : undefined,
42
+ };
43
+ }
44
+ export async function instructionsCommand(artifactId, options) {
45
+ // Resolve (and banner) before the spinner starts so stderr stays readable.
46
+ const root = await resolveRootForCommand(options, { json: options.json });
47
+ if (!root) {
48
+ return;
49
+ }
50
+ const spinner = options.json ? undefined : ora('Generating instructions...').start();
51
+ try {
52
+ const planningHome = toPlanningHome(root);
53
+ const projectRoot = root.path;
54
+ const changeName = await validateChangeExists(options.change, projectRoot, root.changesDir, { newChangeHint: withStoreFlag(root, 'openspec new change <name>') });
55
+ // Validate schema if explicitly provided
56
+ if (options.schema) {
57
+ validateSchemaExists(options.schema, projectRoot);
58
+ }
59
+ // loadChangeContext will auto-detect schema from metadata if not provided
60
+ const context = loadChangeContext(projectRoot, changeName, options.schema, {
61
+ changeDir: getChangeDir(planningHome, changeName),
62
+ planningHome,
63
+ });
64
+ if (!artifactId) {
65
+ spinner?.stop();
66
+ const validIds = context.graph.getAllArtifacts().map((a) => a.id);
67
+ throw new Error(`Missing required argument <artifact>. Valid artifacts:\n ${validIds.join('\n ')}`);
68
+ }
69
+ const artifact = context.graph.getArtifact(artifactId);
70
+ if (!artifact) {
71
+ spinner?.stop();
72
+ const validIds = context.graph.getAllArtifacts().map((a) => a.id);
73
+ throw new Error(`Artifact '${artifactId}' not found in schema '${context.schemaName}'. Valid artifacts:\n ${validIds.join('\n ')}`);
74
+ }
75
+ const { projectConfig, references } = await loadRootConfigContext(root);
76
+ const instructions = generateInstructions(context, artifactId, projectRoot, {
77
+ projectConfig,
78
+ references,
79
+ });
80
+ const isBlocked = instructions.dependencies.some((d) => !d.done);
81
+ spinner?.stop();
82
+ if (options.json) {
83
+ console.log(JSON.stringify({ ...instructions, root: toRootOutput(root) }, null, 2));
84
+ return;
85
+ }
86
+ printInstructionsText(instructions, isBlocked);
87
+ }
88
+ catch (error) {
89
+ spinner?.stop();
90
+ throw error;
91
+ }
92
+ }
93
+ export function printInstructionsText(instructions, isBlocked) {
94
+ const { artifactId, changeName, schemaName, changeDir, resolvedOutputPath, description, instruction, context, rules, template, dependencies, unlocks, } = instructions;
95
+ // Opening tag
96
+ console.log(`<artifact id="${artifactId}" change="${changeName}" schema="${schemaName}">`);
97
+ console.log();
98
+ // Warning for blocked artifacts
99
+ if (isBlocked) {
100
+ const missing = dependencies.filter((d) => !d.done).map((d) => d.id);
101
+ console.log('<warning>');
102
+ console.log('This artifact has unmet dependencies. Complete them first or proceed with caution.');
103
+ console.log(`Missing: ${missing.join(', ')}`);
104
+ console.log('</warning>');
105
+ console.log();
106
+ }
107
+ // Task directive
108
+ console.log('<task>');
109
+ console.log(`Create the ${artifactId} artifact for change "${changeName}".`);
110
+ console.log(description);
111
+ console.log('</task>');
112
+ console.log();
113
+ // Project context (AI constraint - do not include in output)
114
+ if (context) {
115
+ console.log('<project_context>');
116
+ console.log('<!-- This is background information for you. Do NOT include this in your output. -->');
117
+ console.log(context);
118
+ console.log('</project_context>');
119
+ console.log();
120
+ }
121
+ // Referenced-store index (read-only upstream context)
122
+ if (instructions.references && instructions.references.length > 0) {
123
+ console.log(renderReferencedStoresBlock(instructions.references));
124
+ console.log();
125
+ }
126
+ // Rules (AI constraint - do not include in output)
127
+ if (rules && rules.length > 0) {
128
+ console.log('<rules>');
129
+ console.log('<!-- These are constraints for you to follow. Do NOT include this in your output. -->');
130
+ for (const rule of rules) {
131
+ console.log(`- ${rule}`);
132
+ }
133
+ console.log('</rules>');
134
+ console.log();
135
+ }
136
+ // Dependencies (files to read for context)
137
+ if (dependencies.length > 0) {
138
+ console.log('<dependencies>');
139
+ console.log('Read these files for context before creating this artifact:');
140
+ console.log();
141
+ for (const dep of dependencies) {
142
+ const status = dep.done ? 'done' : 'missing';
143
+ const fullPath = path.join(changeDir, dep.path);
144
+ console.log(`<dependency id="${dep.id}" status="${status}">`);
145
+ console.log(` <path>${fullPath}</path>`);
146
+ console.log(` <description>${dep.description}</description>`);
147
+ console.log('</dependency>');
148
+ }
149
+ console.log('</dependencies>');
150
+ console.log();
151
+ }
152
+ // Output location
153
+ console.log('<output>');
154
+ console.log(`Write to: ${resolvedOutputPath}`);
155
+ console.log('</output>');
156
+ console.log();
157
+ // Instruction (guidance)
158
+ if (instruction) {
159
+ console.log('<instruction>');
160
+ console.log(instruction.trim());
161
+ console.log('</instruction>');
162
+ console.log();
163
+ }
164
+ // Template
165
+ console.log('<template>');
166
+ console.log('<!-- Use this as the structure for your output file. Fill in the sections. -->');
167
+ console.log(template.trim());
168
+ console.log('</template>');
169
+ console.log();
170
+ // Success criteria placeholder
171
+ console.log('<success_criteria>');
172
+ console.log('<!-- To be defined in schema validation rules -->');
173
+ console.log('</success_criteria>');
174
+ console.log();
175
+ // Unlocks
176
+ if (unlocks.length > 0) {
177
+ console.log('<unlocks>');
178
+ console.log(`Completing this artifact enables: ${unlocks.join(', ')}`);
179
+ console.log('</unlocks>');
180
+ console.log();
181
+ }
182
+ // Closing tag
183
+ console.log('</artifact>');
184
+ }
185
+ // -----------------------------------------------------------------------------
186
+ // Apply Instructions Command
187
+ // -----------------------------------------------------------------------------
188
+ /**
189
+ * Parses tasks.md content and extracts task items with their completion status.
190
+ */
191
+ function parseTasksFile(content) {
192
+ const tasks = [];
193
+ const lines = content.split('\n');
194
+ let taskIndex = 0;
195
+ for (const line of lines) {
196
+ // Match checkbox patterns: - [ ] or - [x] or - [X]
197
+ const checkboxMatch = line.match(/^[-*]\s*\[([ xX])\]\s*(.+)\s*$/);
198
+ if (checkboxMatch) {
199
+ taskIndex++;
200
+ const done = checkboxMatch[1].toLowerCase() === 'x';
201
+ const description = checkboxMatch[2].trim();
202
+ tasks.push({
203
+ id: `${taskIndex}`,
204
+ description,
205
+ done,
206
+ });
207
+ }
208
+ }
209
+ return tasks;
210
+ }
211
+ /**
212
+ * Generates apply instructions for implementing tasks from a change.
213
+ * Schema-aware: reads apply phase configuration from schema to determine
214
+ * required artifacts, tracking file, and instruction.
215
+ */
216
+ export async function generateApplyInstructions(projectRoot, changeName, schemaName, options = {}) {
217
+ const planningHome = options.planningHome ?? resolveCurrentPlanningHomeSync({ startPath: projectRoot });
218
+ const references = options.references;
219
+ // loadChangeContext will auto-detect schema from metadata if not provided
220
+ const context = loadChangeContext(projectRoot, changeName, schemaName, {
221
+ changeDir: getChangeDir(planningHome, changeName),
222
+ planningHome,
223
+ });
224
+ const changeDir = context.changeDir;
225
+ // Get the full schema to access the apply phase configuration
226
+ const schema = resolveSchema(context.schemaName, projectRoot);
227
+ const applyConfig = schema.apply;
228
+ // Determine required artifacts and tracking file from schema
229
+ // Fallback: if no apply block, require all artifacts
230
+ const requiredArtifactIds = applyConfig?.requires ?? schema.artifacts.map((a) => a.id);
231
+ const tracksFile = applyConfig?.tracks ?? null;
232
+ const schemaInstruction = applyConfig?.instruction ?? null;
233
+ // Check which required artifacts are missing
234
+ const missingArtifacts = [];
235
+ for (const artifactId of requiredArtifactIds) {
236
+ const artifact = schema.artifacts.find((a) => a.id === artifactId);
237
+ if (artifact && resolveArtifactOutputs(changeDir, artifact.generates).length === 0) {
238
+ missingArtifacts.push(artifactId);
239
+ }
240
+ }
241
+ // Build context files from all existing artifacts in schema
242
+ const contextFiles = {};
243
+ for (const artifact of schema.artifacts) {
244
+ const outputs = resolveArtifactOutputs(changeDir, artifact.generates);
245
+ if (outputs.length > 0) {
246
+ contextFiles[artifact.id] = outputs;
247
+ }
248
+ }
249
+ // Parse tasks if tracking file exists
250
+ let tasks = [];
251
+ let tracksFileExists = false;
252
+ if (tracksFile) {
253
+ const tracksPath = path.join(changeDir, tracksFile);
254
+ tracksFileExists = fs.existsSync(tracksPath);
255
+ if (tracksFileExists) {
256
+ const tasksContent = await fs.promises.readFile(tracksPath, 'utf-8');
257
+ tasks = parseTasksFile(tasksContent);
258
+ }
259
+ }
260
+ // Calculate progress
261
+ const total = tasks.length;
262
+ const complete = tasks.filter((t) => t.done).length;
263
+ const remaining = total - complete;
264
+ // Determine state and instruction
265
+ let state;
266
+ let instruction;
267
+ if (missingArtifacts.length > 0) {
268
+ state = 'blocked';
269
+ instruction = `Cannot apply this change yet. Missing artifacts: ${missingArtifacts.join(', ')}.\nUse the openspec-continue-change skill to create the missing artifacts first.`;
270
+ }
271
+ else if (tracksFile && !tracksFileExists) {
272
+ // Tracking file configured but doesn't exist yet
273
+ const tracksFilename = path.basename(tracksFile);
274
+ state = 'blocked';
275
+ instruction = `The ${tracksFilename} file is missing and must be created.\nUse openspec-continue-change to generate the tracking file.`;
276
+ }
277
+ else if (tracksFile && tracksFileExists && total === 0) {
278
+ // Tracking file exists but contains no tasks
279
+ const tracksFilename = path.basename(tracksFile);
280
+ state = 'blocked';
281
+ instruction = `The ${tracksFilename} file exists but contains no tasks.\nAdd tasks to ${tracksFilename} or regenerate it with openspec-continue-change.`;
282
+ }
283
+ else if (tracksFile && remaining === 0 && total > 0) {
284
+ state = 'all_done';
285
+ instruction = 'All tasks are complete! This change is ready to be archived.\nConsider running tests and reviewing the changes before archiving.';
286
+ }
287
+ else if (!tracksFile) {
288
+ // No tracking file configured in schema - ready to apply
289
+ state = 'ready';
290
+ instruction = schemaInstruction?.trim() ?? 'All required artifacts complete. Proceed with implementation.';
291
+ }
292
+ else {
293
+ state = 'ready';
294
+ instruction = schemaInstruction?.trim() ?? 'Read context files, work through pending tasks, mark complete as you go.\nPause if you hit blockers or need clarification.';
295
+ }
296
+ let missingComprehension;
297
+ let comprehension;
298
+ if (state === 'ready') {
299
+ const specPaths = contextFiles.specs ?? [];
300
+ const tasksPath = tracksFile && tracksFileExists ? path.join(changeDir, tracksFile) : null;
301
+ const pendingTaskCount = tasks.filter((task) => !task.done).length;
302
+ const gate = checkComprehensionGate(changeDir, specPaths, options.projectConfig ?? readProjectConfig(projectRoot), { tasksPath, pendingTaskCount });
303
+ if (gate.active && !gate.passed && gate.info) {
304
+ state = 'blocked';
305
+ missingComprehension = true;
306
+ comprehension = gate.info;
307
+ instruction = `Complete the comprehension quiz in /opsx:apply before implementation (score ≥ ${gate.info.thresholdPercent}% on specs and tasks).`;
308
+ }
309
+ else if (gate.active && gate.info) {
310
+ comprehension = gate.info;
311
+ }
312
+ }
313
+ return {
314
+ changeName,
315
+ changeDir,
316
+ schemaName: context.schemaName,
317
+ contextFiles,
318
+ progress: { total, complete, remaining },
319
+ tasks,
320
+ state,
321
+ missingArtifacts: missingArtifacts.length > 0 ? missingArtifacts : undefined,
322
+ missingComprehension,
323
+ comprehension,
324
+ instruction,
325
+ ...(references !== undefined ? { references } : {}),
326
+ };
327
+ }
328
+ export async function applyInstructionsCommand(options) {
329
+ // Resolve (and banner) before the spinner starts so stderr stays readable.
330
+ const root = await resolveRootForCommand(options, { json: options.json });
331
+ if (!root) {
332
+ return;
333
+ }
334
+ const spinner = options.json ? undefined : ora('Generating apply instructions...').start();
335
+ try {
336
+ const planningHome = toPlanningHome(root);
337
+ const projectRoot = root.path;
338
+ const changeName = await validateChangeExists(options.change, projectRoot, root.changesDir, { newChangeHint: withStoreFlag(root, 'openspec new change <name>') });
339
+ // Validate schema if explicitly provided
340
+ if (options.schema) {
341
+ validateSchemaExists(options.schema, projectRoot);
342
+ }
343
+ const { projectConfig, references } = await loadRootConfigContext(root);
344
+ if (options.recordComprehensionPass) {
345
+ if (options.score === undefined) {
346
+ spinner?.stop();
347
+ throw new Error('--score is required with --record-comprehension-pass');
348
+ }
349
+ const context = loadChangeContext(projectRoot, changeName, options.schema, {
350
+ changeDir: getChangeDir(planningHome, changeName),
351
+ planningHome,
352
+ });
353
+ const changeDir = context.changeDir;
354
+ const schema = resolveSchema(context.schemaName, projectRoot);
355
+ const specPaths = [];
356
+ const specsArtifact = schema.artifacts.find((a) => a.id === 'specs');
357
+ if (specsArtifact) {
358
+ specPaths.push(...resolveArtifactOutputs(changeDir, specsArtifact.generates));
359
+ }
360
+ const tracksFile = schema.apply?.tracks ?? null;
361
+ const tasksPath = tracksFile ? path.join(changeDir, tracksFile) : null;
362
+ try {
363
+ const record = recordComprehensionPass({
364
+ changeDir,
365
+ specPaths,
366
+ tasksPath,
367
+ projectConfig,
368
+ scorePercent: options.score,
369
+ attempt: options.attempt ?? 1,
370
+ questionCount: options.questionCount ?? 0,
371
+ });
372
+ spinner?.stop();
373
+ if (options.json) {
374
+ const instructions = await generateApplyInstructions(projectRoot, changeName, options.schema, {
375
+ planningHome,
376
+ references,
377
+ projectConfig,
378
+ });
379
+ console.log(JSON.stringify({
380
+ recorded: true,
381
+ comprehensionPass: record,
382
+ ...instructions,
383
+ root: toRootOutput(root),
384
+ }, null, 2));
385
+ return;
386
+ }
387
+ console.log(`Comprehension pass recorded (${record.score_percent}%).`);
388
+ const instructions = await generateApplyInstructions(projectRoot, changeName, options.schema, {
389
+ planningHome,
390
+ references,
391
+ projectConfig,
392
+ });
393
+ printApplyInstructionsText(instructions);
394
+ return;
395
+ }
396
+ catch (error) {
397
+ spinner?.stop();
398
+ if (error instanceof ComprehensionPassError) {
399
+ if (options.json) {
400
+ console.log(JSON.stringify({
401
+ recorded: false,
402
+ status: [
403
+ {
404
+ severity: 'error',
405
+ code: 'comprehension_score_below_threshold',
406
+ message: error.message,
407
+ },
408
+ ],
409
+ root: toRootOutput(root),
410
+ }, null, 2));
411
+ process.exitCode = 1;
412
+ return;
413
+ }
414
+ }
415
+ throw error;
416
+ }
417
+ }
418
+ // generateApplyInstructions uses loadChangeContext which auto-detects schema
419
+ const instructions = await generateApplyInstructions(projectRoot, changeName, options.schema, {
420
+ planningHome,
421
+ references,
422
+ projectConfig,
423
+ });
424
+ spinner?.stop();
425
+ if (options.json) {
426
+ console.log(JSON.stringify({ ...instructions, root: toRootOutput(root) }, null, 2));
427
+ return;
428
+ }
429
+ printApplyInstructionsText(instructions);
430
+ }
431
+ catch (error) {
432
+ spinner?.stop();
433
+ throw error;
434
+ }
435
+ }
436
+ export function printApplyInstructionsText(instructions) {
437
+ const { changeName, schemaName, contextFiles, progress, tasks, state, missingArtifacts, missingComprehension, comprehension, instruction, } = instructions;
438
+ console.log(`## Apply: ${changeName}`);
439
+ console.log(`Schema: ${schemaName}`);
440
+ console.log();
441
+ if (instructions.references && instructions.references.length > 0) {
442
+ console.log(renderReferencedStoresSection(instructions.references));
443
+ console.log();
444
+ }
445
+ // Warning for blocked state
446
+ if (state === 'blocked' && missingArtifacts) {
447
+ console.log('### ⚠️ Blocked');
448
+ console.log();
449
+ console.log(`Missing artifacts: ${missingArtifacts.join(', ')}`);
450
+ console.log('Use the openspec-continue-change skill to create these first.');
451
+ console.log();
452
+ }
453
+ if (state === 'blocked' && missingComprehension && comprehension) {
454
+ console.log('### ⚠️ Comprehension Required');
455
+ console.log();
456
+ console.log(`Pass the spec and task comprehension quiz (score ≥ ${comprehension.thresholdPercent}%) before implementation.`);
457
+ console.log(`Questions: ${comprehension.questionCount}`);
458
+ console.log(`Specs: ${comprehension.requirementCount} requirements, ${comprehension.scenarioCount} scenarios; Tasks: ${comprehension.pendingTaskCount} pending`);
459
+ if (comprehension.bestScorePercent !== undefined) {
460
+ console.log(`Previous score: ${comprehension.bestScorePercent}% (specs changed — retake required)`);
461
+ }
462
+ console.log('Complete the quiz via /opsx:apply.');
463
+ console.log();
464
+ }
465
+ // Context files (dynamically from schema)
466
+ const contextFileEntries = Object.entries(contextFiles);
467
+ if (contextFileEntries.length > 0) {
468
+ console.log('### Context Files');
469
+ for (const [artifactId, filePaths] of contextFileEntries) {
470
+ for (const filePath of filePaths) {
471
+ console.log(`- ${artifactId}: ${filePath}`);
472
+ }
473
+ }
474
+ console.log();
475
+ }
476
+ // Progress (only show if we have tracking)
477
+ if (progress.total > 0 || tasks.length > 0) {
478
+ console.log('### Progress');
479
+ if (state === 'all_done') {
480
+ console.log(`${progress.complete}/${progress.total} complete ✓`);
481
+ }
482
+ else {
483
+ console.log(`${progress.complete}/${progress.total} complete`);
484
+ }
485
+ console.log();
486
+ }
487
+ // Tasks
488
+ if (tasks.length > 0) {
489
+ console.log('### Tasks');
490
+ for (const task of tasks) {
491
+ const checkbox = task.done ? '[x]' : '[ ]';
492
+ console.log(`- ${checkbox} ${task.description}`);
493
+ }
494
+ console.log();
495
+ }
496
+ // Instruction
497
+ console.log('### Instruction');
498
+ console.log(instruction);
499
+ }
500
+ //# sourceMappingURL=instructions.js.map
@@ -0,0 +1,20 @@
1
+ /**
2
+ * New Change Command
3
+ *
4
+ * Creates a new change directory with optional description and schema in the
5
+ * resolved OpenSpec root. `--store <id>` selects a registered store's
6
+ * root; initiative linking and workspace affected areas are no longer part of
7
+ * this command.
8
+ */
9
+ export interface NewChangeOptions {
10
+ description?: string;
11
+ goal?: string;
12
+ schema?: string;
13
+ store?: string;
14
+ storePath?: string;
15
+ initiative?: string;
16
+ areas?: string;
17
+ json?: boolean;
18
+ }
19
+ export declare function newChangeCommand(name: string | undefined, options: NewChangeOptions): Promise<void>;
20
+ //# sourceMappingURL=new-change.d.ts.map
@@ -0,0 +1,106 @@
1
+ /**
2
+ * New Change Command
3
+ *
4
+ * Creates a new change directory with optional description and schema in the
5
+ * resolved OpenSpec root. `--store <id>` selects a registered store's
6
+ * root; initiative linking and workspace affected areas are no longer part of
7
+ * this command.
8
+ */
9
+ import ora from 'ora';
10
+ import path from 'path';
11
+ import { createChange, validateChangeName } from '../../utils/change-utils.js';
12
+ import { formatChangeLocation } from '../../core/planning-home.js';
13
+ import { resolveRootForCommand, RootSelectionError, toPlanningHome, toRootOutput, withStoreFlag, isStoreSelectedRoot, } from '../../core/root-selection.js';
14
+ import { printJson, statusFromError, validateSchemaExists } from './shared.js';
15
+ // -----------------------------------------------------------------------------
16
+ // Command Implementation
17
+ // -----------------------------------------------------------------------------
18
+ function assertRemovedOptionsAbsent(options) {
19
+ if (options.initiative !== undefined) {
20
+ throw new RootSelectionError('--initiative is no longer supported. Normal changes no longer attach to initiatives; --store <id> selects the OpenSpec root.', 'initiative_option_removed', { target: 'change.options' });
21
+ }
22
+ if (options.areas !== undefined) {
23
+ throw new RootSelectionError('--areas is no longer supported. Workspace affected areas are not part of the normal OpenSpec root path.', 'areas_option_removed', { target: 'change.options' });
24
+ }
25
+ }
26
+ function printCreatedChangeHuman(payload, root) {
27
+ // A relative path is only honest when the root is where the user
28
+ // stands; a distant ancestor root gets the absolute path.
29
+ const location = !isStoreSelectedRoot(root) && root.path === process.cwd()
30
+ ? formatChangeLocation(toPlanningHome(root), payload.change.id)
31
+ : payload.change.path;
32
+ console.log(`Created change '${payload.change.id}' at ${location}/`);
33
+ console.log(`Schema: ${payload.change.schema}`);
34
+ console.log(`Next: ${withStoreFlag(root, `openspec status --change ${payload.change.id}`)}`);
35
+ }
36
+ export async function newChangeCommand(name, options) {
37
+ const spinner = options.json ? undefined : ora();
38
+ try {
39
+ if (!name) {
40
+ throw new Error('Missing required argument <name>');
41
+ }
42
+ const validation = validateChangeName(name);
43
+ if (!validation.valid) {
44
+ throw new Error(validation.error);
45
+ }
46
+ assertRemovedOptionsAbsent(options);
47
+ const root = await resolveRootForCommand(options, {
48
+ json: options.json,
49
+ failurePayload: { change: null },
50
+ });
51
+ if (!root) {
52
+ return;
53
+ }
54
+ const projectRoot = root.path;
55
+ // Validate schema if provided
56
+ if (options.schema) {
57
+ validateSchemaExists(options.schema, projectRoot);
58
+ }
59
+ const resolvedSchema = options.schema ?? root.defaultSchema;
60
+ if (spinner) {
61
+ spinner.start(`Creating change '${name}' with schema '${resolvedSchema}'...`);
62
+ }
63
+ const result = await createChange(projectRoot, name, {
64
+ schema: options.schema,
65
+ defaultSchema: root.defaultSchema,
66
+ changesDir: root.changesDir,
67
+ metadata: {
68
+ ...(options.goal ? { goal: options.goal } : {}),
69
+ },
70
+ });
71
+ // If description provided, create README.md with description
72
+ if (options.description) {
73
+ const { promises: fs } = await import('fs');
74
+ const readmePath = path.join(result.changeDir, 'README.md');
75
+ await fs.writeFile(readmePath, `# ${name}\n\n${options.description}\n`, 'utf-8');
76
+ }
77
+ const payload = {
78
+ change: {
79
+ id: name,
80
+ path: result.changeDir,
81
+ metadataPath: path.join(result.changeDir, '.openspec.yaml'),
82
+ schema: result.schema,
83
+ },
84
+ root: toRootOutput(root),
85
+ };
86
+ if (options.json) {
87
+ printJson(payload);
88
+ return;
89
+ }
90
+ spinner?.stop();
91
+ printCreatedChangeHuman(payload, root);
92
+ }
93
+ catch (error) {
94
+ spinner?.stop();
95
+ if (options.json) {
96
+ printJson({
97
+ change: null,
98
+ status: [statusFromError(error)],
99
+ });
100
+ process.exitCode = 1;
101
+ return;
102
+ }
103
+ throw error;
104
+ }
105
+ }
106
+ //# sourceMappingURL=new-change.js.map
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Schemas Command
3
+ *
4
+ * Lists available workflow schemas with descriptions.
5
+ */
6
+ export interface SchemasOptions {
7
+ json?: boolean;
8
+ }
9
+ export declare function schemasCommand(options: SchemasOptions): Promise<void>;
10
+ //# sourceMappingURL=schemas.d.ts.map
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Schemas Command
3
+ *
4
+ * Lists available workflow schemas with descriptions.
5
+ */
6
+ import chalk from 'chalk';
7
+ import { listSchemasWithInfo } from '../../core/artifact-graph/index.js';
8
+ // -----------------------------------------------------------------------------
9
+ // Command Implementation
10
+ // -----------------------------------------------------------------------------
11
+ export async function schemasCommand(options) {
12
+ const projectRoot = process.cwd();
13
+ const schemas = listSchemasWithInfo(projectRoot);
14
+ if (options.json) {
15
+ console.log(JSON.stringify(schemas, null, 2));
16
+ return;
17
+ }
18
+ console.log('Available schemas:');
19
+ console.log();
20
+ for (const schema of schemas) {
21
+ let sourceLabel = '';
22
+ if (schema.source === 'project') {
23
+ sourceLabel = chalk.cyan(' (project)');
24
+ }
25
+ else if (schema.source === 'user') {
26
+ sourceLabel = chalk.dim(' (user override)');
27
+ }
28
+ console.log(` ${chalk.bold(schema.name)}${sourceLabel}`);
29
+ console.log(` ${schema.description}`);
30
+ console.log(` Artifacts: ${schema.artifacts.join(' → ')}`);
31
+ console.log();
32
+ }
33
+ }
34
+ //# sourceMappingURL=schemas.js.map