@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,143 @@
1
+ /**
2
+ * The workset command's interactive prompt flows (the compose wizard,
3
+ * the open-time tool select, the remove confirm). @inquirer is always
4
+ * imported dynamically at the call site - never at module top.
5
+ */
6
+ import * as path from 'node:path';
7
+ import { pathIsDirectory } from '../core/file-state.js';
8
+ import { listOpenerChoices, } from '../core/openers.js';
9
+ import { expandUserPath } from '../core/store/operations.js';
10
+ import { memberLabelProblem, validateWorksetName, } from '../core/worksets.js';
11
+ import { asErrorMessage } from './shared-output.js';
12
+ import { assertKnownTool, finalizeWorkset, formatMemberRows, resolveMemberFlags, } from './workset-input.js';
13
+ export async function composeInteractively(givenName, input, table) {
14
+ const prompts = await import('@inquirer/prompts');
15
+ console.log('[1/3] Name the workset');
16
+ let name;
17
+ if (givenName !== undefined) {
18
+ name = validateWorksetName(givenName);
19
+ console.log(` Workset name: ${name}`);
20
+ }
21
+ else {
22
+ name = await prompts.input({
23
+ message: 'Workset name:',
24
+ required: true,
25
+ validate(value) {
26
+ try {
27
+ validateWorksetName(value);
28
+ return true;
29
+ }
30
+ catch (error) {
31
+ return asErrorMessage(error);
32
+ }
33
+ },
34
+ });
35
+ }
36
+ // Flag-provided pieces are validated before any prompting, so a
37
+ // bad flag or tool cannot discard a finished wizard walk.
38
+ if (input.tool !== undefined) {
39
+ assertKnownTool(input.tool, table);
40
+ }
41
+ console.log('');
42
+ console.log('[2/3] Add member folders (the first one is the primary - sessions start there)');
43
+ const members = await resolveMemberFlags(input.memberFlags);
44
+ if (members.length > 0) {
45
+ finalizeWorkset(name, members, input.tool, table);
46
+ for (const member of members) {
47
+ console.log(` Added '${member.name}' (${member.path})`);
48
+ }
49
+ }
50
+ while (true) {
51
+ if (members.length > 0) {
52
+ const next = await prompts.select({
53
+ message: 'Add another folder or finish:',
54
+ choices: [
55
+ { name: 'Finish', value: 'finish' },
56
+ { name: 'Add another folder', value: 'add' },
57
+ ],
58
+ default: 'finish',
59
+ });
60
+ if (next === 'finish') {
61
+ break;
62
+ }
63
+ }
64
+ const rawPath = await prompts.input({
65
+ message: 'Folder path:',
66
+ ...(members.length === 0 ? { default: '.', prefill: 'editable' } : {}),
67
+ required: true,
68
+ async validate(value) {
69
+ const resolved = path.resolve(expandUserPath(value));
70
+ if (!(await pathIsDirectory(resolved))) {
71
+ return `'${value}' is not an existing folder`;
72
+ }
73
+ return true;
74
+ },
75
+ });
76
+ const resolvedPath = path.resolve(expandUserPath(rawPath));
77
+ let label = path.basename(resolvedPath);
78
+ const collision = members.some((member) => member.name === label);
79
+ if (memberLabelProblem(label) !== null || collision) {
80
+ label = await prompts.input({
81
+ message: 'Name this member (the folder label):',
82
+ required: true,
83
+ validate(value) {
84
+ const problem = memberLabelProblem(value);
85
+ if (problem !== null) {
86
+ return problem;
87
+ }
88
+ if (members.some((member) => member.name === value)) {
89
+ return `duplicate member name '${value}'`;
90
+ }
91
+ return true;
92
+ },
93
+ });
94
+ }
95
+ members.push({ name: label, path: resolvedPath });
96
+ console.log(` Added '${label}' (${resolvedPath})`);
97
+ }
98
+ console.log('');
99
+ console.log('[3/3] Choose your tool');
100
+ let tool = input.tool;
101
+ if (tool === undefined) {
102
+ const choices = listOpenerChoices(table);
103
+ const available = choices.filter((choice) => choice.available);
104
+ if (available.length === 0) {
105
+ console.log(' None of the known tools is on PATH; not saving a preference.');
106
+ console.log(` (Known tools: ${choices.map((choice) => `${choice.opener.id} ${choice.note ?? ''}`.trim()).join(', ')})`);
107
+ }
108
+ else {
109
+ tool = await promptToolFromChoices(available);
110
+ }
111
+ }
112
+ return finalizeWorkset(name, members, tool, table);
113
+ }
114
+ export async function promptToolFromChoices(available) {
115
+ const { select } = await import('@inquirer/prompts');
116
+ return select({
117
+ message: 'Open with:',
118
+ choices: available.map((choice) => ({
119
+ name: choice.opener.label,
120
+ value: choice.opener.id,
121
+ })),
122
+ });
123
+ }
124
+ export async function promptOpenNow(label) {
125
+ const { confirm } = await import('@inquirer/prompts');
126
+ return confirm({
127
+ message: `Open it now in ${label}?`,
128
+ default: true,
129
+ });
130
+ }
131
+ /** Prints the workset (decision 13: remove shows what it removes). */
132
+ export async function confirmRemoveInteractively(workset) {
133
+ const { confirm } = await import('@inquirer/prompts');
134
+ console.log(`Workset '${workset.name}':`);
135
+ for (const row of formatMemberRows(workset.members)) {
136
+ console.log(` ${row}`);
137
+ }
138
+ return confirm({
139
+ message: `Remove workset '${workset.name}'? (member folders are never touched)`,
140
+ default: false,
141
+ });
142
+ }
143
+ //# sourceMappingURL=workset-prompts.js.map
@@ -0,0 +1,25 @@
1
+ import type { spawn as nodeSpawn } from 'node:child_process';
2
+ import { Command } from 'commander';
3
+ import { type LaunchCommand } from '../core/openers.js';
4
+ interface LaunchResult {
5
+ code: number | null;
6
+ signal: NodeJS.Signals | null;
7
+ }
8
+ export interface LaunchOptions {
9
+ spawnFn?: typeof nodeSpawn;
10
+ }
11
+ /**
12
+ * Spawns the opener with this terminal's stdio. Resolves with the
13
+ * child's exit facts (never rejects for a nonzero exit - for a
14
+ * terminal handoff, the session is the command); rejects with
15
+ * workset_launch_failed only when the spawn itself fails. While the
16
+ * child runs, SIGINT/SIGTERM are ignored in this parent: the terminal
17
+ * delivers Ctrl-C to the child, and the parent must survive to report
18
+ * the child's real exit facts (the 128+n contract).
19
+ */
20
+ export declare function launchOpenerCommand(command: LaunchCommand, options?: LaunchOptions): Promise<LaunchResult>;
21
+ /** 130 for SIGINT, 143 for SIGTERM - the shell's 128+n convention. */
22
+ export declare function exitCodeForLaunch(result: LaunchResult): number;
23
+ export declare function registerWorksetCommand(program: Command): void;
24
+ export {};
25
+ //# sourceMappingURL=workset.d.ts.map
@@ -0,0 +1,446 @@
1
+ /**
2
+ * The `workset` command group (slice 7.1): compose, keep, and open
3
+ * personal working views. A workset is purely local and personal -
4
+ * never committed, never shared, never derived from declarations, and
5
+ * never a membership truth. Opening hands the view to the user's tool:
6
+ * editors get the generated .code-workspace; CLI agents take over this
7
+ * terminal with every member attached and no starter prompt.
8
+ */
9
+ import * as os from 'node:os';
10
+ import { createRequire } from 'node:module';
11
+ import { Option } from 'commander';
12
+ import { buildWorksetCodeWorkspaceJson, getWorkset, getWorksetCodeWorkspacePath, listWorksets, readWorksetsState, removeWorkset, updateWorksetsState, validateWorksetName, withWorkset, withWorksetsLock, worksetNotFoundError, } from '../core/worksets.js';
13
+ import { buildLaunchCommand, findOpener, isOpenerCommandAvailable, isOpenerEnabled, listOpenerChoices, mergeOpenerTable, } from '../core/openers.js';
14
+ import { pathIsDirectory, writeFileAtomically } from '../core/file-state.js';
15
+ import { getGlobalConfig, getGlobalConfigPath, } from '../core/global-config.js';
16
+ import { StoreError } from '../core/store/errors.js';
17
+ import { isInteractive } from '../utils/interactive.js';
18
+ import { asErrorMessage, emitFailure, isPromptCancellationError, printJson, } from './shared-output.js';
19
+ import { finalizeWorkset, firstInstalledAlternative, formatMemberRows, noToolInstalledError, resolveMemberFlags, toolUnavailableError, toolUnknownError, } from './workset-input.js';
20
+ import { composeInteractively, confirmRemoveInteractively, promptOpenNow, promptToolFromChoices, } from './workset-prompts.js';
21
+ import { COMMAND_REGISTRY } from '../core/completions/command-registry.js';
22
+ // cross-spawn is CJS with no types and only `workset open` needs it -
23
+ // loaded lazily so every other CLI invocation skips its module graph.
24
+ let cachedSpawn;
25
+ function defaultSpawn() {
26
+ if (cachedSpawn === undefined) {
27
+ const require = createRequire(import.meta.url);
28
+ cachedSpawn = require('cross-spawn');
29
+ }
30
+ return cachedSpawn;
31
+ }
32
+ function readOpenerTable() {
33
+ return mergeOpenerTable(getGlobalConfig().openers, getGlobalConfigPath());
34
+ }
35
+ function worksetCliOpenerDisabledError(opener, name) {
36
+ return new StoreError(`Opening a workset in ${opener.label} is temporarily disabled while CLI-agent opening is reworked. Worksets open in an IDE for now.`, 'workset_cli_opener_disabled', {
37
+ target: 'workset.tool',
38
+ fix: `Open in VS Code or Cursor: openspec workset open ${name} --tool code`,
39
+ });
40
+ }
41
+ /**
42
+ * Spawns the opener with this terminal's stdio. Resolves with the
43
+ * child's exit facts (never rejects for a nonzero exit - for a
44
+ * terminal handoff, the session is the command); rejects with
45
+ * workset_launch_failed only when the spawn itself fails. While the
46
+ * child runs, SIGINT/SIGTERM are ignored in this parent: the terminal
47
+ * delivers Ctrl-C to the child, and the parent must survive to report
48
+ * the child's real exit facts (the 128+n contract).
49
+ */
50
+ export function launchOpenerCommand(command, options = {}) {
51
+ const spawnFn = options.spawnFn ?? defaultSpawn();
52
+ return new Promise((resolve, reject) => {
53
+ const launchFailure = (error) => new StoreError(`Could not launch ${command.label}: ${asErrorMessage(error)}`, 'workset_launch_failed', {
54
+ target: 'workset.tool',
55
+ fix: `Check that '${command.executable}' runs from this terminal, or pass --tool with another installed tool.`,
56
+ });
57
+ let child;
58
+ try {
59
+ child = spawnFn(command.executable, command.args, {
60
+ cwd: command.cwd,
61
+ stdio: 'inherit',
62
+ shell: false,
63
+ });
64
+ }
65
+ catch (error) {
66
+ // Some spawn failures throw synchronously (platform-dependent);
67
+ // they are the same launch failure.
68
+ reject(launchFailure(error));
69
+ return;
70
+ }
71
+ const ignoreSignal = () => undefined;
72
+ process.on('SIGINT', ignoreSignal);
73
+ process.on('SIGTERM', ignoreSignal);
74
+ const cleanup = () => {
75
+ process.removeListener('SIGINT', ignoreSignal);
76
+ process.removeListener('SIGTERM', ignoreSignal);
77
+ };
78
+ child.on('error', (error) => {
79
+ cleanup();
80
+ reject(launchFailure(error));
81
+ });
82
+ child.on('close', (code, signal) => {
83
+ cleanup();
84
+ resolve({ code, signal });
85
+ });
86
+ });
87
+ }
88
+ /** 130 for SIGINT, 143 for SIGTERM - the shell's 128+n convention. */
89
+ export function exitCodeForLaunch(result) {
90
+ if (result.signal !== null) {
91
+ const signalNumber = os.constants.signals[result.signal];
92
+ return 128 + (signalNumber ?? 1);
93
+ }
94
+ return result.code ?? 0;
95
+ }
96
+ class WorksetCommand {
97
+ async create(name, options = {}) {
98
+ try {
99
+ const interactive = !options.json && isInteractive();
100
+ let workset;
101
+ let table;
102
+ if (interactive) {
103
+ table = readOpenerTable();
104
+ workset = await composeInteractively(name, { memberFlags: options.member ?? [], tool: options.tool }, table);
105
+ }
106
+ else {
107
+ workset = await this.composeFromFlags(name, options);
108
+ }
109
+ await updateWorksetsState((state) => withWorkset(state, workset));
110
+ if (options.json) {
111
+ printJson({ workset, status: [] });
112
+ return;
113
+ }
114
+ console.log('');
115
+ console.log(`Saved workset '${workset.name}' (${workset.members.length} member${workset.members.length === 1 ? '' : 's'}) to your machine.`);
116
+ if (interactive && workset.tool !== undefined && table !== undefined) {
117
+ const label = findOpener(table, workset.tool)?.label ?? workset.tool;
118
+ let openNow = false;
119
+ try {
120
+ openNow = await promptOpenNow(label);
121
+ }
122
+ catch (error) {
123
+ // The workset is already durably saved: Ctrl-C here declines
124
+ // the offer, it does not cancel the create.
125
+ if (!isPromptCancellationError(error)) {
126
+ throw error;
127
+ }
128
+ }
129
+ if (openNow) {
130
+ console.log('');
131
+ await this.open(workset.name, {});
132
+ return;
133
+ }
134
+ }
135
+ console.log(`Open it any time with: openspec workset open ${workset.name}`);
136
+ }
137
+ catch (error) {
138
+ emitFailure(options.json, { workset: null, status: [] }, error, 'workset_error');
139
+ }
140
+ }
141
+ async composeFromFlags(name, options) {
142
+ if (!name) {
143
+ throw new StoreError('Pass a workset name.', 'workset_name_required', {
144
+ target: 'workset.name',
145
+ fix: 'openspec workset create <name> --member <path>',
146
+ });
147
+ }
148
+ validateWorksetName(name);
149
+ const memberFlags = options.member ?? [];
150
+ if (memberFlags.length === 0) {
151
+ throw new StoreError('Pass at least one member folder.', 'workset_members_required', {
152
+ target: 'workset.member',
153
+ fix: `openspec workset create ${name} --member <path> --member <name>=<path>`,
154
+ });
155
+ }
156
+ const members = await resolveMemberFlags(memberFlags);
157
+ // The opener table is read only when a tool is actually named - a
158
+ // tool-less scripted create must not fail on unrelated config rows.
159
+ const table = options.tool !== undefined ? readOpenerTable() : [];
160
+ if (options.tool !== undefined) {
161
+ const chosen = findOpener(table, options.tool);
162
+ if (chosen !== null && !isOpenerEnabled(chosen)) {
163
+ throw worksetCliOpenerDisabledError(chosen, name);
164
+ }
165
+ }
166
+ return finalizeWorkset(name, members, options.tool, table);
167
+ }
168
+ async list(options = {}) {
169
+ try {
170
+ const state = await readWorksetsState();
171
+ const worksets = listWorksets(state);
172
+ if (options.json) {
173
+ printJson({ worksets, status: [] });
174
+ return;
175
+ }
176
+ if (worksets.length === 0) {
177
+ console.log('No worksets saved. Create one with: openspec workset create');
178
+ return;
179
+ }
180
+ // The table is consulted only to render tool labels.
181
+ const table = worksets.some((workset) => workset.tool !== undefined)
182
+ ? readOpenerTable()
183
+ : [];
184
+ for (const workset of worksets) {
185
+ const toolLabel = workset.tool !== undefined
186
+ ? ` (opens in ${findOpener(table, workset.tool)?.label ?? workset.tool})`
187
+ : '';
188
+ console.log(`${workset.name}${toolLabel}`);
189
+ for (const row of formatMemberRows(workset.members)) {
190
+ console.log(` ${row}`);
191
+ }
192
+ }
193
+ }
194
+ catch (error) {
195
+ emitFailure(options.json, { worksets: [], status: [] }, error, 'workset_error');
196
+ }
197
+ }
198
+ async open(name, options = {}) {
199
+ let prepared;
200
+ try {
201
+ if (options.json) {
202
+ throw new StoreError('workset open hands this terminal to the chosen tool and has no JSON mode.', 'workset_open_json_unsupported', {
203
+ target: 'workset.tool',
204
+ fix: 'Inspect worksets with: openspec workset list --json',
205
+ });
206
+ }
207
+ // Regenerate the derived file FIRST (under the lock), so every
208
+ // cannot-drive failure below can name an existing, current file.
209
+ prepared = await withWorksetsLock(async (state) => {
210
+ const workset = getWorkset(state, name);
211
+ if (workset === null) {
212
+ throw worksetNotFoundError(name, state);
213
+ }
214
+ const checks = await Promise.all(workset.members.map(async (member) => ({
215
+ member,
216
+ exists: await pathIsDirectory(member.path),
217
+ })));
218
+ const surviving = checks
219
+ .filter((check) => check.exists)
220
+ .map((check) => check.member);
221
+ const skipped = checks
222
+ .filter((check) => !check.exists)
223
+ .map((check) => check.member);
224
+ if (surviving.length === 0) {
225
+ throw new StoreError(`No member folder of workset '${name}' exists on this machine.`, 'workset_no_members_available', {
226
+ target: 'workset.member',
227
+ fix: `Recompose it: openspec workset remove ${name} --yes && openspec workset create ${name} --member <path>`,
228
+ });
229
+ }
230
+ const codeWorkspacePath = getWorksetCodeWorkspacePath(name);
231
+ await writeFileAtomically(codeWorkspacePath, buildWorksetCodeWorkspaceJson(surviving));
232
+ return { workset, surviving, skipped, codeWorkspacePath };
233
+ });
234
+ for (const member of prepared.skipped) {
235
+ console.error(`Skipped '${member.name}' (${member.path} is not available).`);
236
+ }
237
+ if (prepared.workset.members[0] !== prepared.surviving[0]) {
238
+ const primary = prepared.surviving[0];
239
+ console.error(`Using '${primary.name}' (${primary.path}) as the primary for this open.`);
240
+ }
241
+ const table = readOpenerTable();
242
+ const toolId = options.tool ?? prepared.workset.tool;
243
+ let opener;
244
+ if (toolId !== undefined) {
245
+ const found = findOpener(table, toolId);
246
+ if (found === null) {
247
+ throw toolUnknownError(toolId, table);
248
+ }
249
+ if (!isOpenerEnabled(found)) {
250
+ throw worksetCliOpenerDisabledError(found, name);
251
+ }
252
+ if (!isOpenerCommandAvailable(found.command)) {
253
+ throw toolUnavailableError(found, table, name);
254
+ }
255
+ opener = found;
256
+ }
257
+ else {
258
+ if (!isInteractive()) {
259
+ throw new StoreError(`Workset '${name}' has no saved tool.`, 'workset_tool_required', {
260
+ target: 'workset.tool',
261
+ fix: `openspec workset open ${name} --tool <id>`,
262
+ });
263
+ }
264
+ // The prompt offers only available openers, so the selection
265
+ // needs no second scan.
266
+ const available = listOpenerChoices(table).filter((choice) => choice.available);
267
+ if (available.length === 0) {
268
+ throw noToolInstalledError(table, name);
269
+ }
270
+ const selectedId = await promptToolFromChoices(available);
271
+ opener = available.find((choice) => choice.opener.id === selectedId).opener;
272
+ }
273
+ const launch = buildLaunchCommand(opener, {
274
+ members: prepared.surviving,
275
+ codeWorkspacePath: prepared.codeWorkspacePath,
276
+ });
277
+ if (opener.style === 'workspace-file') {
278
+ console.log(`Opening '${name}' in ${opener.label} (a window opens; this command returns).`);
279
+ }
280
+ else {
281
+ console.log(`Handing this terminal to ${opener.label} for '${name}' (the session ends when you exit).`);
282
+ }
283
+ let result;
284
+ try {
285
+ result = await launchOpenerCommand(launch);
286
+ }
287
+ catch (error) {
288
+ // Make the launch-failure fix pasteable when an alternative is
289
+ // installed (the launcher itself does not know the table).
290
+ if (error instanceof StoreError &&
291
+ error.diagnostic.code === 'workset_launch_failed') {
292
+ const alternative = firstInstalledAlternative(table, opener.id);
293
+ if (alternative !== null) {
294
+ throw new StoreError(error.message, 'workset_launch_failed', {
295
+ target: 'workset.tool',
296
+ fix: `Run: openspec workset open ${name} --tool ${alternative}`,
297
+ });
298
+ }
299
+ }
300
+ throw error;
301
+ }
302
+ const exitCode = exitCodeForLaunch(result);
303
+ if (exitCode !== 0) {
304
+ process.exitCode = exitCode;
305
+ }
306
+ }
307
+ catch (error) {
308
+ emitFailure(options.json, { status: [] }, error, 'workset_error');
309
+ // Never strand the user: once the derived file is regenerated,
310
+ // every failure (except a prompt cancellation) carries the
311
+ // manual route - the file path plus the members it contains.
312
+ if (!options.json &&
313
+ prepared !== undefined &&
314
+ !isPromptCancellationError(error)) {
315
+ console.error('Open manually:');
316
+ console.error(` Workspace file: ${prepared.codeWorkspacePath}`);
317
+ console.error(' Members:');
318
+ for (const row of formatMemberRows(prepared.surviving)) {
319
+ console.error(` ${row}`);
320
+ }
321
+ }
322
+ }
323
+ }
324
+ async remove(name, options = {}) {
325
+ try {
326
+ if (!options.yes) {
327
+ // The pre-read serves the not-found priority and the confirm
328
+ // display; the --yes path skips it (removeWorkset re-checks
329
+ // under the lock anyway).
330
+ const state = await readWorksetsState();
331
+ const workset = getWorkset(state, name);
332
+ if (workset === null) {
333
+ throw worksetNotFoundError(name, state);
334
+ }
335
+ if (options.json || !isInteractive()) {
336
+ throw new StoreError('Pass --yes to remove a workset non-interactively.', 'workset_remove_confirmation_required', {
337
+ target: 'workset.name',
338
+ fix: `openspec workset remove ${name} --yes`,
339
+ });
340
+ }
341
+ const confirmed = await confirmRemoveInteractively(workset);
342
+ if (!confirmed) {
343
+ throw new StoreError('Workset remove cancelled.', 'workset_remove_cancelled', {
344
+ target: 'workset.name',
345
+ fix: 'Rerun remove when you are ready.',
346
+ });
347
+ }
348
+ }
349
+ await removeWorkset(name);
350
+ if (options.json) {
351
+ printJson({ removed: { name }, status: [] });
352
+ return;
353
+ }
354
+ console.log(`Removed workset '${name}'. Member folders were not touched.`);
355
+ }
356
+ catch (error) {
357
+ emitFailure(options.json, { removed: null, status: [] }, error, 'workset_error');
358
+ }
359
+ }
360
+ }
361
+ function collectMember(value, previous) {
362
+ return [...previous, value];
363
+ }
364
+ export function registerWorksetCommand(program) {
365
+ const worksetCommand = new WorksetCommand();
366
+ const groupDescription = COMMAND_REGISTRY.find((entry) => entry.name === 'workset')?.description ??
367
+ 'Compose, keep, and open personal working views (purely local)';
368
+ const workset = program.command('workset').description(groupDescription);
369
+ // Parsed at the group level so `openspec workset --json` keeps the
370
+ // one-JSON-document contract instead of a raw Commander error. The
371
+ // parent option matches anywhere; actions read optsWithGlobals().
372
+ workset.addOption(new Option('--json', 'Output as JSON').hideHelp());
373
+ workset
374
+ .command('create [name]')
375
+ .description('Compose and save a named working view of folders you choose')
376
+ .option('--member <member>', 'Member folder as <path> or <name>=<path>; repeatable, first is the primary', collectMember, [])
377
+ .option('--tool <id>', 'Preferred tool to open this workset with')
378
+ .option('--json', 'Output as JSON')
379
+ .action(async (name, _options, command) => {
380
+ await worksetCommand.create(name, command.optsWithGlobals());
381
+ });
382
+ workset
383
+ .command('list')
384
+ .alias('ls')
385
+ .description('Show saved worksets with their members')
386
+ .option('--json', 'Output as JSON')
387
+ .action(async (_options, command) => {
388
+ await worksetCommand.list(command.optsWithGlobals());
389
+ });
390
+ workset
391
+ .command('open <name>')
392
+ .description('Open a saved workset in your tool (editor window or agent session)')
393
+ .option('--tool <id>', 'Open with this tool just this once')
394
+ .addOption(
395
+ // Parsed so Commander never owns the error; rejected in the
396
+ // action with one JSON document. Hidden because help should not
397
+ // advertise a mode that only rejects.
398
+ new Option('--json', 'Not supported for open').hideHelp())
399
+ .action(async (name, _options, command) => {
400
+ await worksetCommand.open(name, command.optsWithGlobals());
401
+ });
402
+ workset
403
+ .command('remove <name>')
404
+ .description('Delete a saved workset (member folders are never touched)')
405
+ .option('--yes', 'Confirm removal non-interactively')
406
+ .option('--json', 'Output as JSON')
407
+ .action(async (name, _options, command) => {
408
+ await worksetCommand.remove(name, command.optsWithGlobals());
409
+ });
410
+ const subcommandsLine = workset.commands
411
+ .map((subcommand) => {
412
+ const aliases = subcommand.aliases();
413
+ return aliases.length > 0
414
+ ? `${subcommand.name()} (${aliases.join(', ')})`
415
+ : subcommand.name();
416
+ })
417
+ .join(', ');
418
+ // One handler owns missing AND unknown subcommands: known
419
+ // subcommands dispatch above; everything else lands in this action
420
+ // (allowExcessArguments routes the unknown operand here), keeping
421
+ // the one-JSON-document contract for `--json` probes.
422
+ workset.allowExcessArguments(true);
423
+ workset.action(() => {
424
+ const attempted = workset.args.filter((operand) => !operand.startsWith('-'));
425
+ const message = attempted.length > 0
426
+ ? `Unknown command '${attempted[0]}' for 'openspec workset'. Workset subcommands: ${subcommandsLine}.`
427
+ : `Missing subcommand for 'openspec workset'. Workset subcommands: ${subcommandsLine}.`;
428
+ if (workset.opts().json) {
429
+ printJson({
430
+ status: [
431
+ {
432
+ severity: 'error',
433
+ code: 'unknown_workset_subcommand',
434
+ message,
435
+ fix: 'Run one of the workset subcommands.',
436
+ },
437
+ ],
438
+ });
439
+ }
440
+ else {
441
+ console.error(`Error: ${message}`);
442
+ }
443
+ process.exitCode = 1;
444
+ });
445
+ }
446
+ //# sourceMappingURL=workset.js.map
@@ -0,0 +1,22 @@
1
+ export interface ArchiveOptions {
2
+ yes?: boolean;
3
+ skipSpecs?: boolean;
4
+ noValidate?: boolean;
5
+ validate?: boolean;
6
+ json?: boolean;
7
+ store?: string;
8
+ storePath?: string;
9
+ }
10
+ export declare class ArchiveCommand {
11
+ execute(changeName?: string, options?: ArchiveOptions): Promise<void>;
12
+ private printJsonFailure;
13
+ /**
14
+ * Shared archive flow. In human mode (json=false) prompts and prose match
15
+ * the historical behavior and cancellations return null. In JSON mode no
16
+ * prose reaches stdout and every blocked path throws.
17
+ */
18
+ private run;
19
+ private selectChange;
20
+ private getArchiveDate;
21
+ }
22
+ //# sourceMappingURL=archive.d.ts.map