@proletariat/cli 0.3.17 → 0.3.19

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 (340) hide show
  1. package/LICENSE +21 -0
  2. package/bin/dev.js +0 -0
  3. package/dist/commands/action/create.d.ts +1 -0
  4. package/dist/commands/action/create.js +74 -38
  5. package/dist/commands/action/delete.d.ts +1 -0
  6. package/dist/commands/action/delete.js +23 -24
  7. package/dist/commands/action/index.d.ts +1 -0
  8. package/dist/commands/action/index.js +5 -10
  9. package/dist/commands/action/list.d.ts +1 -0
  10. package/dist/commands/action/list.js +3 -1
  11. package/dist/commands/action/run.d.ts +1 -0
  12. package/dist/commands/action/run.js +44 -32
  13. package/dist/commands/action/show.d.ts +2 -0
  14. package/dist/commands/action/update.d.ts +1 -0
  15. package/dist/commands/action/update.js +80 -39
  16. package/dist/commands/agent/auth.d.ts +2 -0
  17. package/dist/commands/agent/auth.js +44 -3
  18. package/dist/commands/agent/discover.d.ts +2 -0
  19. package/dist/commands/agent/discover.js +35 -3
  20. package/dist/commands/agent/index.d.ts +1 -0
  21. package/dist/commands/agent/index.js +25 -45
  22. package/dist/commands/agent/list.d.ts +8 -3
  23. package/dist/commands/agent/list.js +16 -29
  24. package/dist/commands/agent/login.d.ts +1 -0
  25. package/dist/commands/agent/login.js +14 -32
  26. package/dist/commands/agent/rebuild.d.ts +1 -0
  27. package/dist/commands/agent/rebuild.js +2 -2
  28. package/dist/commands/agent/remove.d.ts +17 -0
  29. package/dist/commands/agent/remove.js +144 -0
  30. package/dist/commands/agent/restart.d.ts +1 -0
  31. package/dist/commands/agent/restart.js +2 -2
  32. package/dist/commands/agent/shell.d.ts +1 -0
  33. package/dist/commands/agent/shell.js +63 -76
  34. package/dist/commands/agent/staff/add.d.ts +1 -0
  35. package/dist/commands/agent/staff/add.js +7 -1
  36. package/dist/commands/agent/staff/index.d.ts +1 -0
  37. package/dist/commands/agent/staff/index.js +5 -4
  38. package/dist/commands/agent/staff/remove.d.ts +1 -0
  39. package/dist/commands/agent/status.d.ts +1 -0
  40. package/dist/commands/agent/status.js +11 -23
  41. package/dist/commands/agent/temp/cleanup.d.ts +1 -0
  42. package/dist/commands/agent/temp/index.d.ts +1 -0
  43. package/dist/commands/agent/temp/index.js +4 -3
  44. package/dist/commands/agent/themes/index.d.ts +1 -0
  45. package/dist/commands/agent/themes/index.js +9 -3
  46. package/dist/commands/agent/themes/set.d.ts +1 -0
  47. package/dist/commands/agent/themes/set.js +7 -1
  48. package/dist/commands/agent/visit.d.ts +1 -0
  49. package/dist/commands/agent/visit.js +11 -23
  50. package/dist/commands/autocomplete/setup.d.ts +11 -0
  51. package/dist/commands/autocomplete/setup.js +113 -8
  52. package/dist/commands/board/index.d.ts +4 -0
  53. package/dist/commands/board/index.js +32 -30
  54. package/dist/commands/board/watch.d.ts +2 -0
  55. package/dist/commands/branch/create.d.ts +1 -0
  56. package/dist/commands/branch/create.js +33 -41
  57. package/dist/commands/branch/index.d.ts +1 -0
  58. package/dist/commands/branch/list.d.ts +2 -0
  59. package/dist/commands/branch/validate.d.ts +2 -0
  60. package/dist/commands/branch/where.d.ts +1 -0
  61. package/dist/commands/claude.d.ts +6 -0
  62. package/dist/commands/claude.js +166 -116
  63. package/dist/commands/commit.d.ts +6 -0
  64. package/dist/commands/commit.js +68 -73
  65. package/dist/commands/config/index.d.ts +13 -0
  66. package/dist/commands/config/index.js +142 -98
  67. package/dist/commands/docker/clean.d.ts +2 -1
  68. package/dist/commands/docker/clean.js +20 -29
  69. package/dist/commands/docker/index.d.ts +1 -0
  70. package/dist/commands/docker/index.js +37 -41
  71. package/dist/commands/docker/prune.d.ts +2 -1
  72. package/dist/commands/docker/prune.js +20 -27
  73. package/dist/commands/docker/restart.d.ts +2 -1
  74. package/dist/commands/docker/restart.js +20 -29
  75. package/dist/commands/docker/stop.d.ts +2 -1
  76. package/dist/commands/docker/stop.js +20 -29
  77. package/dist/commands/epic/activate.d.ts +1 -0
  78. package/dist/commands/epic/archive.d.ts +1 -0
  79. package/dist/commands/epic/create.d.ts +1 -0
  80. package/dist/commands/epic/index.d.ts +1 -0
  81. package/dist/commands/epic/link/block.d.ts +1 -0
  82. package/dist/commands/epic/link/duplicates.d.ts +1 -0
  83. package/dist/commands/epic/link/index.d.ts +1 -0
  84. package/dist/commands/epic/link/relates.d.ts +1 -0
  85. package/dist/commands/epic/link/remove.d.ts +1 -0
  86. package/dist/commands/epic/list.d.ts +2 -0
  87. package/dist/commands/epic/move.d.ts +1 -0
  88. package/dist/commands/epic/progress.d.ts +1 -0
  89. package/dist/commands/epic/project.d.ts +1 -0
  90. package/dist/commands/epic/reorder.d.ts +1 -0
  91. package/dist/commands/epic/spec.d.ts +1 -0
  92. package/dist/commands/epic/ticket.d.ts +1 -0
  93. package/dist/commands/epic/view.d.ts +1 -0
  94. package/dist/commands/execution/index.d.ts +1 -0
  95. package/dist/commands/execution/index.js +9 -25
  96. package/dist/commands/execution/list.d.ts +2 -0
  97. package/dist/commands/execution/logs.d.ts +1 -0
  98. package/dist/commands/execution/logs.js +6 -16
  99. package/dist/commands/execution/stop.d.ts +1 -0
  100. package/dist/commands/execution/stop.js +4 -15
  101. package/dist/commands/gh/index.d.ts +1 -0
  102. package/dist/commands/gh/index.js +27 -27
  103. package/dist/commands/gh/login.d.ts +4 -0
  104. package/dist/commands/gh/login.js +31 -0
  105. package/dist/commands/gh/status.d.ts +4 -0
  106. package/dist/commands/gh/status.js +27 -4
  107. package/dist/commands/gh/token.d.ts +4 -0
  108. package/dist/commands/gh/token.js +49 -5
  109. package/dist/commands/phase/create.d.ts +1 -1
  110. package/dist/commands/phase/create.js +116 -74
  111. package/dist/commands/phase/delete.d.ts +1 -0
  112. package/dist/commands/phase/delete.js +23 -22
  113. package/dist/commands/phase/list.d.ts +1 -0
  114. package/dist/commands/phase/list.js +3 -5
  115. package/dist/commands/phase/move.d.ts +1 -0
  116. package/dist/commands/phase/move.js +39 -39
  117. package/dist/commands/phase/template/apply.d.ts +1 -0
  118. package/dist/commands/phase/template/create.d.ts +2 -0
  119. package/dist/commands/phase/template/delete.d.ts +1 -0
  120. package/dist/commands/phase/template/index.d.ts +1 -0
  121. package/dist/commands/phase/template/list.d.ts +1 -0
  122. package/dist/commands/phase/template/update.d.ts +2 -0
  123. package/dist/commands/phase/update.d.ts +1 -1
  124. package/dist/commands/phase/update.js +89 -55
  125. package/dist/commands/pmo/init.d.ts +2 -0
  126. package/dist/commands/pmo/init.js +84 -22
  127. package/dist/commands/pr/create.d.ts +12 -3
  128. package/dist/commands/pr/create.js +130 -147
  129. package/dist/commands/pr/index.d.ts +6 -3
  130. package/dist/commands/pr/index.js +41 -39
  131. package/dist/commands/pr/link.d.ts +7 -3
  132. package/dist/commands/pr/link.js +126 -150
  133. package/dist/commands/pr/status.d.ts +6 -3
  134. package/dist/commands/pr/status.js +101 -126
  135. package/dist/commands/project/archive.d.ts +1 -0
  136. package/dist/commands/project/archive.js +15 -20
  137. package/dist/commands/project/create.d.ts +1 -0
  138. package/dist/commands/project/create.js +13 -5
  139. package/dist/commands/project/delete.d.ts +1 -0
  140. package/dist/commands/project/delete.js +14 -28
  141. package/dist/commands/project/index.d.ts +1 -0
  142. package/dist/commands/project/index.js +0 -5
  143. package/dist/commands/project/list.d.ts +2 -0
  144. package/dist/commands/project/list.js +21 -3
  145. package/dist/commands/project/spec.d.ts +1 -0
  146. package/dist/commands/project/spec.js +17 -23
  147. package/dist/commands/project/unarchive.d.ts +2 -0
  148. package/dist/commands/project/unarchive.js +21 -2
  149. package/dist/commands/project/view.d.ts +1 -0
  150. package/dist/commands/project/view.js +34 -22
  151. package/dist/commands/repo/add.d.ts +2 -0
  152. package/dist/commands/repo/add.js +44 -1
  153. package/dist/commands/repo/index.d.ts +1 -0
  154. package/dist/commands/repo/index.js +20 -38
  155. package/dist/commands/repo/list.d.ts +2 -0
  156. package/dist/commands/repo/remove.d.ts +1 -0
  157. package/dist/commands/repo/remove.js +45 -63
  158. package/dist/commands/repo/view.d.ts +2 -0
  159. package/dist/commands/repo/view.js +30 -5
  160. package/dist/commands/roadmap/add-project.d.ts +1 -0
  161. package/dist/commands/roadmap/create.d.ts +1 -0
  162. package/dist/commands/roadmap/delete.d.ts +1 -0
  163. package/dist/commands/roadmap/generate.d.ts +1 -0
  164. package/dist/commands/roadmap/index.d.ts +1 -0
  165. package/dist/commands/roadmap/list.d.ts +2 -0
  166. package/dist/commands/roadmap/remove-project.d.ts +1 -0
  167. package/dist/commands/roadmap/reorder.d.ts +1 -0
  168. package/dist/commands/roadmap/update.d.ts +1 -0
  169. package/dist/commands/roadmap/view.d.ts +1 -0
  170. package/dist/commands/session/attach.d.ts +1 -0
  171. package/dist/commands/session/index.d.ts +1 -0
  172. package/dist/commands/session/index.js +8 -25
  173. package/dist/commands/session/list.d.ts +2 -0
  174. package/dist/commands/spec/create.d.ts +1 -1
  175. package/dist/commands/spec/create.js +64 -65
  176. package/dist/commands/spec/index.d.ts +1 -0
  177. package/dist/commands/spec/index.js +36 -22
  178. package/dist/commands/spec/link/depends.d.ts +1 -0
  179. package/dist/commands/spec/link/depends.js +6 -6
  180. package/dist/commands/spec/link/duplicates.d.ts +1 -0
  181. package/dist/commands/spec/link/duplicates.js +6 -6
  182. package/dist/commands/spec/link/index.d.ts +2 -1
  183. package/dist/commands/spec/link/index.js +0 -4
  184. package/dist/commands/spec/link/relates.d.ts +1 -0
  185. package/dist/commands/spec/link/relates.js +6 -6
  186. package/dist/commands/spec/link/remove.d.ts +2 -1
  187. package/dist/commands/spec/link/remove.js +6 -6
  188. package/dist/commands/spec/list.d.ts +2 -0
  189. package/dist/commands/spec/list.js +25 -0
  190. package/dist/commands/spec/plan.d.ts +2 -1
  191. package/dist/commands/spec/plan.js +19 -26
  192. package/dist/commands/spec/ticket.d.ts +2 -1
  193. package/dist/commands/spec/ticket.js +48 -34
  194. package/dist/commands/spec/view.d.ts +2 -1
  195. package/dist/commands/spec/view.js +25 -16
  196. package/dist/commands/status/create.d.ts +1 -1
  197. package/dist/commands/status/create.js +80 -64
  198. package/dist/commands/status/delete.d.ts +2 -1
  199. package/dist/commands/status/delete.js +26 -22
  200. package/dist/commands/status/index.d.ts +1 -0
  201. package/dist/commands/status/index.js +26 -19
  202. package/dist/commands/status/list.d.ts +1 -0
  203. package/dist/commands/status/list.js +12 -7
  204. package/dist/commands/status/move.d.ts +2 -1
  205. package/dist/commands/status/move.js +62 -61
  206. package/dist/commands/status/update.d.ts +2 -2
  207. package/dist/commands/status/update.js +110 -77
  208. package/dist/commands/template/delete.d.ts +1 -0
  209. package/dist/commands/template/delete.js +47 -48
  210. package/dist/commands/template/index.d.ts +1 -0
  211. package/dist/commands/template/index.js +26 -33
  212. package/dist/commands/template/list.d.ts +1 -0
  213. package/dist/commands/template/phase/create.d.ts +1 -0
  214. package/dist/commands/template/phase/create.js +6 -0
  215. package/dist/commands/template/phase/index.d.ts +1 -0
  216. package/dist/commands/template/phase/index.js +27 -26
  217. package/dist/commands/template/phase/update.d.ts +1 -0
  218. package/dist/commands/template/phase/update.js +6 -0
  219. package/dist/commands/template/ticket/index.d.ts +1 -0
  220. package/dist/commands/template/ticket/index.js +27 -26
  221. package/dist/commands/template/ticket/save.d.ts +1 -0
  222. package/dist/commands/template/ticket/save.js +6 -0
  223. package/dist/commands/terminal/title.d.ts +26 -0
  224. package/dist/commands/terminal/title.js +37 -3
  225. package/dist/commands/ticket/bulk.d.ts +1 -0
  226. package/dist/commands/ticket/complete.d.ts +1 -0
  227. package/dist/commands/ticket/complete.js +18 -14
  228. package/dist/commands/ticket/create.d.ts +1 -0
  229. package/dist/commands/ticket/create.js +45 -41
  230. package/dist/commands/ticket/delete.d.ts +1 -0
  231. package/dist/commands/ticket/delete.js +1 -1
  232. package/dist/commands/ticket/edit.d.ts +1 -0
  233. package/dist/commands/ticket/edit.js +1 -1
  234. package/dist/commands/ticket/epic.d.ts +1 -0
  235. package/dist/commands/ticket/epic.js +2 -2
  236. package/dist/commands/ticket/index.d.ts +1 -0
  237. package/dist/commands/ticket/link/block.d.ts +1 -0
  238. package/dist/commands/ticket/link/block.js +1 -1
  239. package/dist/commands/ticket/link/duplicates.d.ts +1 -0
  240. package/dist/commands/ticket/link/duplicates.js +1 -1
  241. package/dist/commands/ticket/link/index.d.ts +1 -0
  242. package/dist/commands/ticket/link/index.js +9 -8
  243. package/dist/commands/ticket/link/relates.d.ts +1 -0
  244. package/dist/commands/ticket/link/relates.js +1 -1
  245. package/dist/commands/ticket/link/remove.d.ts +1 -0
  246. package/dist/commands/ticket/link/remove.js +1 -1
  247. package/dist/commands/ticket/list.d.ts +2 -0
  248. package/dist/commands/ticket/move.d.ts +1 -0
  249. package/dist/commands/ticket/move.js +27 -19
  250. package/dist/commands/ticket/project.d.ts +1 -0
  251. package/dist/commands/ticket/project.js +3 -3
  252. package/dist/commands/ticket/reassign.d.ts +1 -0
  253. package/dist/commands/ticket/reassign.js +1 -1
  254. package/dist/commands/ticket/spec.d.ts +1 -0
  255. package/dist/commands/ticket/spec.js +3 -3
  256. package/dist/commands/ticket/status.d.ts +1 -0
  257. package/dist/commands/ticket/status.js +1 -1
  258. package/dist/commands/ticket/template/apply.d.ts +1 -0
  259. package/dist/commands/ticket/template/create.d.ts +2 -0
  260. package/dist/commands/ticket/template/delete.d.ts +1 -0
  261. package/dist/commands/ticket/template/index.d.ts +1 -0
  262. package/dist/commands/ticket/template/list.d.ts +1 -0
  263. package/dist/commands/ticket/template/save.d.ts +2 -0
  264. package/dist/commands/ticket/update.d.ts +1 -0
  265. package/dist/commands/ticket/update.js +1 -1
  266. package/dist/commands/ticket/view.d.ts +1 -0
  267. package/dist/commands/ticket/view.js +1 -1
  268. package/dist/commands/work/complete.d.ts +1 -0
  269. package/dist/commands/work/index.d.ts +1 -0
  270. package/dist/commands/work/ready.d.ts +1 -0
  271. package/dist/commands/work/revise.d.ts +1 -0
  272. package/dist/commands/work/spawn-all.d.ts +2 -0
  273. package/dist/commands/work/spawn-all.js +11 -4
  274. package/dist/commands/work/spawn.d.ts +1 -0
  275. package/dist/commands/work/spawn.js +261 -166
  276. package/dist/commands/work/start.d.ts +1 -0
  277. package/dist/commands/work/start.js +270 -189
  278. package/dist/commands/work/watch.d.ts +1 -0
  279. package/dist/commands/work/watch.js +63 -58
  280. package/dist/commands/workflow/create.d.ts +1 -0
  281. package/dist/commands/workflow/create.js +2 -4
  282. package/dist/commands/workflow/delete.d.ts +1 -0
  283. package/dist/commands/workflow/delete.js +21 -33
  284. package/dist/commands/workflow/index.d.ts +1 -0
  285. package/dist/commands/workflow/list.d.ts +1 -0
  286. package/dist/commands/workflow/list.js +3 -6
  287. package/dist/commands/workflow/switch.d.ts +2 -0
  288. package/dist/commands/workflow/switch.js +46 -21
  289. package/dist/commands/workflow/view.d.ts +1 -0
  290. package/dist/commands/workflow/view.js +18 -27
  291. package/dist/commands/workspace/remove.d.ts +2 -2
  292. package/dist/commands/workspace/remove.js +16 -21
  293. package/dist/commands/workspace/use.d.ts +2 -2
  294. package/dist/commands/workspace/use.js +12 -18
  295. package/dist/lib/agents/commands.d.ts +1 -1
  296. package/dist/lib/agents/commands.js +4 -4
  297. package/dist/lib/database/drizzle-schema.d.ts +5009 -0
  298. package/dist/lib/database/drizzle-schema.js +699 -0
  299. package/dist/lib/database/drizzle.d.ts +29 -0
  300. package/dist/lib/database/drizzle.js +37 -0
  301. package/dist/lib/database/index.d.ts +1 -0
  302. package/dist/lib/database/index.js +1 -1
  303. package/dist/lib/execution/config.d.ts +6 -0
  304. package/dist/lib/execution/config.js +31 -13
  305. package/dist/lib/execution/devcontainer.js +12 -6
  306. package/dist/lib/execution/runners.js +13 -7
  307. package/dist/lib/execution/spawner.js +19 -0
  308. package/dist/lib/flags/index.d.ts +4 -0
  309. package/dist/lib/flags/index.js +4 -0
  310. package/dist/lib/flags/resolver.d.ts +224 -0
  311. package/dist/lib/flags/resolver.js +313 -0
  312. package/dist/lib/pmo/base-command.d.ts +53 -3
  313. package/dist/lib/pmo/base-command.js +92 -13
  314. package/dist/lib/pmo/find-pmo.d.ts +1 -1
  315. package/dist/lib/pmo/find-pmo.js +4 -4
  316. package/dist/lib/pmo/index.d.ts +1 -1
  317. package/dist/lib/pmo/index.js +1 -1
  318. package/dist/lib/pmo/storage/helpers.js +2 -1
  319. package/dist/lib/pmo/storage/index.d.ts +9 -0
  320. package/dist/lib/pmo/storage/index.js +14 -0
  321. package/dist/lib/pmo/storage/projects.d.ts +28 -13
  322. package/dist/lib/pmo/storage/projects.js +110 -34
  323. package/dist/lib/pmo/storage/roadmaps.d.ts +2 -0
  324. package/dist/lib/pmo/storage/roadmaps.js +182 -111
  325. package/dist/lib/pmo/storage/specs.js +13 -16
  326. package/dist/lib/pmo/storage/subtasks.js +17 -2
  327. package/dist/lib/pmo/storage/tickets.d.ts +12 -2
  328. package/dist/lib/pmo/storage/tickets.js +63 -5
  329. package/dist/lib/pmo/storage/types.d.ts +7 -3
  330. package/dist/lib/pmo/storage/views.d.ts +12 -1
  331. package/dist/lib/pmo/storage/views.js +61 -6
  332. package/dist/lib/prompt-command.d.ts +90 -0
  333. package/dist/lib/prompt-command.js +102 -0
  334. package/dist/lib/prompt-json.d.ts +34 -4
  335. package/dist/lib/prompt-json.js +35 -3
  336. package/dist/lib/repos/index.js +15 -15
  337. package/dist/lib/workspace.d.ts +4 -3
  338. package/dist/lib/workspace.js +3 -3
  339. package/oclif.manifest.json +4193 -2580
  340. package/package.json +9 -6
@@ -3,7 +3,7 @@ import { execSync } from 'node:child_process';
3
3
  import inquirer from 'inquirer';
4
4
  import { validateBranchName } from '../lib/branch/index.js';
5
5
  import { styles } from '../lib/styles.js';
6
- import { shouldOutputJson, outputPromptAsJson, outputErrorAsJson, createMetadata, buildPromptConfig, } from '../lib/prompt-json.js';
6
+ import { shouldOutputJson, isAgentMode, outputPromptAsJson, outputErrorAsJson, createMetadata, normalizeChoices, } from '../lib/prompt-json.js';
7
7
  /**
8
8
  * Commit message format presets.
9
9
  */
@@ -195,10 +195,33 @@ export default class Commit extends Command {
195
195
  default: false,
196
196
  }),
197
197
  };
198
+ /**
199
+ * Prompt wrapper - handles both JSON mode and interactive mode.
200
+ * In JSON mode: outputs prompt as JSON and exits.
201
+ * In interactive mode: calls inquirer.prompt normally.
202
+ */
203
+ async prompt(questions, jsonModeConfig) {
204
+ if (jsonModeConfig && isAgentMode(jsonModeConfig.flags)) {
205
+ const firstQuestion = questions[0];
206
+ if (firstQuestion) {
207
+ const choices = firstQuestion.choices ? normalizeChoices(firstQuestion.choices) : undefined;
208
+ outputPromptAsJson({
209
+ type: firstQuestion.type,
210
+ name: firstQuestion.name,
211
+ message: firstQuestion.message,
212
+ choices,
213
+ default: firstQuestion.default,
214
+ }, createMetadata(jsonModeConfig.commandName, jsonModeConfig.flags));
215
+ }
216
+ return {};
217
+ }
218
+ return inquirer.prompt(questions);
219
+ }
198
220
  async run() {
199
221
  const { args, flags } = await this.parse(Commit);
200
222
  // Check if JSON output mode is active
201
223
  const jsonMode = shouldOutputJson(flags);
224
+ const jsonModeConfig = jsonMode ? { flags: flags, commandName: 'commit' } : null;
202
225
  // Helper to handle errors in JSON mode
203
226
  const handleError = (code, message) => {
204
227
  if (jsonMode) {
@@ -267,65 +290,12 @@ export default class Commit extends Command {
267
290
  if (!hasChanges) {
268
291
  return handleError('NO_CHANGES', 'No changes to commit. Working tree is clean.');
269
292
  }
270
- // In JSON mode, output the staging action prompt first
271
- if (jsonMode) {
272
- const stagingChoicesJson = [];
273
- if (hasStaged) {
274
- stagingChoicesJson.push({
275
- name: `Commit staged only (${status.staged.length} file${status.staged.length === 1 ? '' : 's'})`,
276
- value: 'staged',
277
- });
278
- }
279
- if (hasUnstaged || hasUntracked) {
280
- const totalUnstaged = status.unstaged.length + status.untracked.length;
281
- stagingChoicesJson.push({
282
- name: `Add all & commit (${totalUnstaged} unstaged + ${status.staged.length} staged)`,
283
- value: 'all',
284
- });
285
- stagingChoicesJson.push({
286
- name: 'Select files to add...',
287
- value: 'select',
288
- });
289
- }
290
- stagingChoicesJson.push({ name: 'Cancel', value: 'cancel' });
291
- outputPromptAsJson(buildPromptConfig('list', 'stagingAction', 'What would you like to commit?', stagingChoicesJson), createMetadata('commit', flags));
292
- return;
293
- }
294
- // Build status display
295
- this.log('');
296
- if (hasStaged) {
297
- this.log(styles.success(` Staged (${status.staged.length}):`));
298
- for (const file of status.staged.slice(0, 5)) {
299
- this.log(styles.success(` ✓ ${file}`));
300
- }
301
- if (status.staged.length > 5) {
302
- this.log(styles.muted(` ... and ${status.staged.length - 5} more`));
303
- }
304
- }
305
- if (hasUnstaged) {
306
- this.log(styles.warning(` Modified (${status.unstaged.length}):`));
307
- for (const file of status.unstaged.slice(0, 5)) {
308
- this.log(styles.warning(` ○ ${file}`));
309
- }
310
- if (status.unstaged.length > 5) {
311
- this.log(styles.muted(` ... and ${status.unstaged.length - 5} more`));
312
- }
313
- }
314
- if (hasUntracked) {
315
- this.log(styles.muted(` Untracked (${status.untracked.length}):`));
316
- for (const file of status.untracked.slice(0, 5)) {
317
- this.log(styles.muted(` ? ${file}`));
318
- }
319
- if (status.untracked.length > 5) {
320
- this.log(styles.muted(` ... and ${status.untracked.length - 5} more`));
321
- }
322
- }
323
- this.log('');
324
293
  const stagingChoices = [];
325
294
  if (hasStaged) {
326
295
  stagingChoices.push({
327
296
  name: `Commit staged only (${status.staged.length} file${status.staged.length === 1 ? '' : 's'})`,
328
297
  value: 'staged',
298
+ command: 'prlt commit --json',
329
299
  });
330
300
  }
331
301
  if (hasUnstaged || hasUntracked) {
@@ -333,21 +303,55 @@ export default class Commit extends Command {
333
303
  stagingChoices.push({
334
304
  name: `Add all & commit (${totalUnstaged} unstaged + ${status.staged.length} staged)`,
335
305
  value: 'all',
306
+ command: 'prlt commit --all --json',
336
307
  });
337
308
  stagingChoices.push({
338
309
  name: 'Select files to add...',
339
310
  value: 'select',
311
+ command: 'prlt commit --stage <file> --json',
340
312
  });
341
313
  }
342
314
  stagingChoices.push({ name: 'Cancel', value: 'cancel' });
343
- const { stagingAction } = await inquirer.prompt([
315
+ // Display git status (interactive only)
316
+ if (!jsonMode) {
317
+ this.log('');
318
+ if (hasStaged) {
319
+ this.log(styles.success(` Staged (${status.staged.length}):`));
320
+ for (const file of status.staged.slice(0, 5)) {
321
+ this.log(styles.success(` ✓ ${file}`));
322
+ }
323
+ if (status.staged.length > 5) {
324
+ this.log(styles.muted(` ... and ${status.staged.length - 5} more`));
325
+ }
326
+ }
327
+ if (hasUnstaged) {
328
+ this.log(styles.warning(` Modified (${status.unstaged.length}):`));
329
+ for (const file of status.unstaged.slice(0, 5)) {
330
+ this.log(styles.warning(` ○ ${file}`));
331
+ }
332
+ if (status.unstaged.length > 5) {
333
+ this.log(styles.muted(` ... and ${status.unstaged.length - 5} more`));
334
+ }
335
+ }
336
+ if (hasUntracked) {
337
+ this.log(styles.muted(` Untracked (${status.untracked.length}):`));
338
+ for (const file of status.untracked.slice(0, 5)) {
339
+ this.log(styles.muted(` ? ${file}`));
340
+ }
341
+ if (status.untracked.length > 5) {
342
+ this.log(styles.muted(` ... and ${status.untracked.length - 5} more`));
343
+ }
344
+ }
345
+ this.log('');
346
+ }
347
+ const { stagingAction } = await this.prompt([
344
348
  {
345
349
  type: 'list',
346
350
  name: 'stagingAction',
347
351
  message: 'What would you like to commit?',
348
352
  choices: stagingChoices,
349
353
  },
350
- ]);
354
+ ], jsonModeConfig);
351
355
  if (stagingAction === 'cancel') {
352
356
  this.log(styles.muted('Cancelled.'));
353
357
  return;
@@ -359,7 +363,7 @@ export default class Commit extends Command {
359
363
  else if (stagingAction === 'select') {
360
364
  // Let user select files to stage
361
365
  const allUnstaged = [...status.unstaged, ...status.untracked];
362
- const { filesToStage } = await inquirer.prompt([
366
+ const { filesToStage } = await this.prompt([
363
367
  {
364
368
  type: 'checkbox',
365
369
  name: 'filesToStage',
@@ -370,7 +374,7 @@ export default class Commit extends Command {
370
374
  checked: false,
371
375
  })),
372
376
  },
373
- ]);
377
+ ], null);
374
378
  if (filesToStage.length > 0) {
375
379
  stageFiles(filesToStage);
376
380
  this.log(styles.success(`Staged ${filesToStage.length} file${filesToStage.length === 1 ? '' : 's'}.`));
@@ -397,13 +401,9 @@ export default class Commit extends Command {
397
401
  const formatChoices = Object.entries(COMMIT_FORMATS).map(([name, preset]) => ({
398
402
  name: `${name}${name === DEFAULT_COMMIT_FORMAT ? ' (default)' : ''} → ${preset.format(exampleCtx)}`,
399
403
  value: name,
404
+ command: `prlt commit --all --format ${name} --json`,
400
405
  }));
401
- // In JSON mode, output format selection prompt
402
- if (jsonMode) {
403
- outputPromptAsJson(buildPromptConfig('list', 'format', 'Commit format:', formatChoices), createMetadata('commit', flags));
404
- return;
405
- }
406
- const { chosenFormat } = await inquirer.prompt([
406
+ const { chosenFormat } = await this.prompt([
407
407
  {
408
408
  type: 'list',
409
409
  name: 'chosenFormat',
@@ -411,23 +411,18 @@ export default class Commit extends Command {
411
411
  choices: formatChoices,
412
412
  default: DEFAULT_COMMIT_FORMAT,
413
413
  },
414
- ]);
414
+ ], jsonModeConfig);
415
415
  selectedFormat = chosenFormat;
416
416
  }
417
- // In JSON mode with format specified, output message input prompt
418
- if (jsonMode) {
419
- outputPromptAsJson(buildPromptConfig('input', 'message', 'Commit message:', []), createMetadata('commit', flags));
420
- return;
421
- }
422
417
  // Prompt for message
423
- const { inputMessage } = await inquirer.prompt([
418
+ const { inputMessage } = await this.prompt([
424
419
  {
425
420
  type: 'input',
426
421
  name: 'inputMessage',
427
422
  message: 'Commit message:',
428
423
  validate: (input) => input.trim() ? true : 'Message cannot be empty',
429
424
  },
430
- ]);
425
+ ], jsonModeConfig);
431
426
  message = inputMessage.trim();
432
427
  }
433
428
  // Get format preset
@@ -6,7 +6,20 @@ export default class Config extends Command {
6
6
  json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
7
7
  set: import("@oclif/core/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/interfaces").CustomOptions>;
8
8
  list: import("@oclif/core/interfaces").BooleanFlag<boolean>;
9
+ setting: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
9
10
  };
11
+ /**
12
+ * Prompt wrapper - drop-in replacement for inquirer.prompt
13
+ *
14
+ * Works in BOTH modes:
15
+ * - Interactive mode: calls inquirer.prompt normally (human sees menu)
16
+ * - JSON/Agent mode: outputs prompt as structured JSON and exits
17
+ */
18
+ private promptUser;
10
19
  run(): Promise<void>;
20
+ /**
21
+ * Handle a specific setting's sub-prompt
22
+ */
23
+ private handleSettingPrompt;
11
24
  private setConfigValue;
12
25
  }
@@ -6,7 +6,7 @@ import { Command } from '@oclif/core';
6
6
  import { styles } from '../../lib/styles.js';
7
7
  import { getWorkspaceInfo } from '../../lib/agents/commands.js';
8
8
  import { loadExecutionConfig, saveTerminalApp, saveTerminalOpenInBackground, saveTmuxControlMode, saveShell, } from '../../lib/execution/config.js';
9
- import { shouldOutputJson, outputPromptAsJson, outputSuccessAsJson, outputErrorAsJson, createMetadata, buildPromptConfig, } from '../../lib/prompt-json.js';
9
+ import { shouldOutputJson, isAgentMode, outputPromptAsJson, outputSuccessAsJson, outputErrorAsJson, createMetadata, normalizeChoices, } from '../../lib/prompt-json.js';
10
10
  export default class Config extends Command {
11
11
  static description = 'View and update workspace configuration';
12
12
  static examples = [
@@ -14,6 +14,7 @@ export default class Config extends Command {
14
14
  '<%= config.bin %> <%= command.id %> --json # Output current config as JSON',
15
15
  '<%= config.bin %> <%= command.id %> --set terminal.app iTerm',
16
16
  '<%= config.bin %> <%= command.id %> --set terminal.openInBackground true',
17
+ '<%= config.bin %> <%= command.id %> --setting terminal.app --json # Show terminal app choices',
17
18
  ];
18
19
  static flags = {
19
20
  json: Flags.boolean({
@@ -30,10 +31,40 @@ export default class Config extends Command {
30
31
  description: 'List all configuration values',
31
32
  default: false,
32
33
  }),
34
+ setting: Flags.string({
35
+ description: 'Navigate to a specific setting prompt (for agent navigation)',
36
+ }),
33
37
  };
38
+ /**
39
+ * Prompt wrapper - drop-in replacement for inquirer.prompt
40
+ *
41
+ * Works in BOTH modes:
42
+ * - Interactive mode: calls inquirer.prompt normally (human sees menu)
43
+ * - JSON/Agent mode: outputs prompt as structured JSON and exits
44
+ */
45
+ async promptUser(questions, jsonModeConfig) {
46
+ if (jsonModeConfig && isAgentMode(jsonModeConfig.flags)) {
47
+ const firstQuestion = questions[0];
48
+ if (firstQuestion) {
49
+ const choices = firstQuestion.choices
50
+ ? normalizeChoices(firstQuestion.choices)
51
+ : undefined;
52
+ outputPromptAsJson({
53
+ type: firstQuestion.type,
54
+ name: firstQuestion.name,
55
+ message: firstQuestion.message,
56
+ choices,
57
+ default: firstQuestion.default,
58
+ }, createMetadata(jsonModeConfig.commandName, jsonModeConfig.flags));
59
+ }
60
+ return {};
61
+ }
62
+ return inquirer.prompt(questions);
63
+ }
34
64
  async run() {
35
65
  const { flags } = await this.parse(Config);
36
66
  const jsonMode = shouldOutputJson(flags);
67
+ const jsonModeConfig = jsonMode ? { flags, commandName: 'config' } : null;
37
68
  // Get workspace info
38
69
  let workspaceInfo;
39
70
  try {
@@ -71,8 +102,8 @@ export default class Config extends Command {
71
102
  db.close();
72
103
  return;
73
104
  }
74
- // Handle --list or --json flag (just show config)
75
- if (flags.list || flags.json) {
105
+ // Handle --list or --json flag without --setting (just show config)
106
+ if ((flags.list || flags.json) && !flags.setting) {
76
107
  if (jsonMode) {
77
108
  outputSuccessAsJson({
78
109
  terminal: {
@@ -114,24 +145,24 @@ export default class Config extends Command {
114
145
  db.close();
115
146
  return;
116
147
  }
117
- // Interactive menu
118
- const settingChoices = [
119
- { name: `Terminal App: ${config.terminal.app}`, value: 'terminal.app' },
120
- { name: `Open Tabs in Background: ${config.terminal.openInBackground}`, value: 'terminal.openInBackground' },
121
- { name: `Shell: ${config.shell}`, value: 'shell' },
122
- { name: `Tmux Control Mode (iTerm -CC): ${config.tmux.controlMode}`, value: 'tmux.controlMode' },
123
- ];
124
- const settingMessage = 'Select setting to configure:';
125
- if (jsonMode) {
126
- outputPromptAsJson(buildPromptConfig('list', 'setting', settingMessage, settingChoices), createMetadata('config', flags));
148
+ // Handle --setting flag (navigate directly to a sub-prompt)
149
+ if (flags.setting) {
150
+ await this.handleSettingPrompt(db, config, flags.setting, jsonModeConfig);
127
151
  db.close();
128
152
  return;
129
153
  }
130
- const { setting } = await inquirer.prompt([
154
+ // Interactive menu
155
+ const settingChoices = [
156
+ { name: `Terminal App: ${config.terminal.app}`, value: 'terminal.app', command: 'prlt config --setting terminal.app --json' },
157
+ { name: `Open Tabs in Background: ${config.terminal.openInBackground}`, value: 'terminal.openInBackground', command: 'prlt config --setting terminal.openInBackground --json' },
158
+ { name: `Shell: ${config.shell}`, value: 'shell', command: 'prlt config --setting shell --json' },
159
+ { name: `Tmux Control Mode (iTerm -CC): ${config.tmux.controlMode}`, value: 'tmux.controlMode', command: 'prlt config --setting tmux.controlMode --json' },
160
+ ];
161
+ const { setting } = await this.promptUser([
131
162
  {
132
163
  type: 'list',
133
164
  name: 'setting',
134
- message: settingMessage,
165
+ message: 'Select setting to configure:',
135
166
  choices: [
136
167
  new inquirer.Separator('── Terminal ──'),
137
168
  ...settingChoices.slice(0, 2),
@@ -143,93 +174,13 @@ export default class Config extends Command {
143
174
  { name: 'Exit', value: '__exit__' },
144
175
  ],
145
176
  },
146
- ]);
177
+ ], jsonModeConfig);
147
178
  if (setting === '__exit__') {
148
179
  db.close();
149
180
  return;
150
181
  }
151
- // Handle each setting
152
- switch (setting) {
153
- case 'terminal.app': {
154
- const appChoices = [
155
- { name: 'iTerm', value: 'iTerm' },
156
- { name: 'Terminal.app (macOS default)', value: 'Terminal' },
157
- { name: 'Ghostty', value: 'Ghostty' },
158
- { name: 'Alacritty', value: 'Alacritty' },
159
- { name: 'Kitty', value: 'Kitty' },
160
- { name: 'WezTerm', value: 'WezTerm' },
161
- { name: 'Warp', value: 'Warp' },
162
- { name: 'tmux', value: 'tmux' },
163
- ];
164
- const { newApp } = await inquirer.prompt([
165
- {
166
- type: 'list',
167
- name: 'newApp',
168
- message: 'Select terminal app:',
169
- choices: appChoices,
170
- default: config.terminal.app,
171
- },
172
- ]);
173
- saveTerminalApp(db, newApp);
174
- this.log(styles.success(`Terminal app set to: ${newApp}`));
175
- break;
176
- }
177
- case 'terminal.openInBackground': {
178
- const bgChoices = [
179
- { name: 'Yes - Open tabs in background (don\'t steal focus)', value: true },
180
- { name: 'No - Bring terminal to foreground when opening tabs', value: false },
181
- ];
182
- const { openInBg } = await inquirer.prompt([
183
- {
184
- type: 'list',
185
- name: 'openInBg',
186
- message: 'Open terminal tabs in background?',
187
- choices: bgChoices,
188
- default: config.terminal.openInBackground,
189
- },
190
- ]);
191
- saveTerminalOpenInBackground(db, openInBg);
192
- this.log(styles.success(`Open in background set to: ${openInBg}`));
193
- break;
194
- }
195
- case 'shell': {
196
- const shellChoices = [
197
- { name: 'zsh (macOS default)', value: 'zsh' },
198
- { name: 'bash', value: 'bash' },
199
- { name: 'fish', value: 'fish' },
200
- ];
201
- const { newShell } = await inquirer.prompt([
202
- {
203
- type: 'list',
204
- name: 'newShell',
205
- message: 'Select shell:',
206
- choices: shellChoices,
207
- default: config.shell,
208
- },
209
- ]);
210
- saveShell(db, newShell);
211
- this.log(styles.success(`Shell set to: ${newShell}`));
212
- break;
213
- }
214
- case 'tmux.controlMode': {
215
- const ccChoices = [
216
- { name: 'Yes - Use tmux -CC for native iTerm integration', value: true },
217
- { name: 'No - Standard tmux interface', value: false },
218
- ];
219
- const { controlMode } = await inquirer.prompt([
220
- {
221
- type: 'list',
222
- name: 'controlMode',
223
- message: 'Enable tmux control mode (-CC)?',
224
- choices: ccChoices,
225
- default: config.tmux.controlMode,
226
- },
227
- ]);
228
- saveTmuxControlMode(db, controlMode);
229
- this.log(styles.success(`Tmux control mode set to: ${controlMode}`));
230
- break;
231
- }
232
- }
182
+ // Handle the selected setting
183
+ await this.handleSettingPrompt(db, config, setting, jsonModeConfig);
233
184
  db.close();
234
185
  }
235
186
  catch (error) {
@@ -237,6 +188,99 @@ export default class Config extends Command {
237
188
  throw error;
238
189
  }
239
190
  }
191
+ /**
192
+ * Handle a specific setting's sub-prompt
193
+ */
194
+ async handleSettingPrompt(db, config, setting, jsonModeConfig) {
195
+ switch (setting) {
196
+ case 'terminal.app': {
197
+ const appChoices = [
198
+ { name: 'iTerm', value: 'iTerm', command: 'prlt config --set "terminal.app iTerm" --json' },
199
+ { name: 'Terminal.app (macOS default)', value: 'Terminal', command: 'prlt config --set "terminal.app Terminal" --json' },
200
+ { name: 'Ghostty', value: 'Ghostty', command: 'prlt config --set "terminal.app Ghostty" --json' },
201
+ { name: 'Alacritty', value: 'Alacritty', command: 'prlt config --set "terminal.app Alacritty" --json' },
202
+ { name: 'Kitty', value: 'Kitty', command: 'prlt config --set "terminal.app Kitty" --json' },
203
+ { name: 'WezTerm', value: 'WezTerm', command: 'prlt config --set "terminal.app WezTerm" --json' },
204
+ { name: 'Warp', value: 'Warp', command: 'prlt config --set "terminal.app Warp" --json' },
205
+ { name: 'tmux', value: 'tmux', command: 'prlt config --set "terminal.app tmux" --json' },
206
+ ];
207
+ const { newApp } = await this.promptUser([
208
+ {
209
+ type: 'list',
210
+ name: 'newApp',
211
+ message: 'Select terminal app:',
212
+ choices: appChoices,
213
+ default: config.terminal.app,
214
+ },
215
+ ], jsonModeConfig);
216
+ saveTerminalApp(db, newApp);
217
+ this.log(styles.success(`Terminal app set to: ${newApp}`));
218
+ break;
219
+ }
220
+ case 'terminal.openInBackground': {
221
+ const bgChoices = [
222
+ { name: 'Yes - Open tabs in background (don\'t steal focus)', value: 'true', command: 'prlt config --set "terminal.openInBackground true" --json' },
223
+ { name: 'No - Bring terminal to foreground when opening tabs', value: 'false', command: 'prlt config --set "terminal.openInBackground false" --json' },
224
+ ];
225
+ const { openInBg } = await this.promptUser([
226
+ {
227
+ type: 'list',
228
+ name: 'openInBg',
229
+ message: 'Open terminal tabs in background?',
230
+ choices: bgChoices,
231
+ default: String(config.terminal.openInBackground),
232
+ },
233
+ ], jsonModeConfig);
234
+ saveTerminalOpenInBackground(db, openInBg === 'true');
235
+ this.log(styles.success(`Open in background set to: ${openInBg}`));
236
+ break;
237
+ }
238
+ case 'shell': {
239
+ const shellChoices = [
240
+ { name: 'zsh (macOS default)', value: 'zsh', command: 'prlt config --set "shell zsh" --json' },
241
+ { name: 'bash', value: 'bash', command: 'prlt config --set "shell bash" --json' },
242
+ { name: 'fish', value: 'fish', command: 'prlt config --set "shell fish" --json' },
243
+ ];
244
+ const { newShell } = await this.promptUser([
245
+ {
246
+ type: 'list',
247
+ name: 'newShell',
248
+ message: 'Select shell:',
249
+ choices: shellChoices,
250
+ default: config.shell,
251
+ },
252
+ ], jsonModeConfig);
253
+ saveShell(db, newShell);
254
+ this.log(styles.success(`Shell set to: ${newShell}`));
255
+ break;
256
+ }
257
+ case 'tmux.controlMode': {
258
+ const ccChoices = [
259
+ { name: 'Yes - Use tmux -CC for native iTerm integration', value: 'true', command: 'prlt config --set "tmux.controlMode true" --json' },
260
+ { name: 'No - Standard tmux interface', value: 'false', command: 'prlt config --set "tmux.controlMode false" --json' },
261
+ ];
262
+ const { controlMode } = await this.promptUser([
263
+ {
264
+ type: 'list',
265
+ name: 'controlMode',
266
+ message: 'Enable tmux control mode (-CC)?',
267
+ choices: ccChoices,
268
+ default: String(config.tmux.controlMode),
269
+ },
270
+ ], jsonModeConfig);
271
+ saveTmuxControlMode(db, controlMode === 'true');
272
+ this.log(styles.success(`Tmux control mode set to: ${controlMode}`));
273
+ break;
274
+ }
275
+ default: {
276
+ const jsonMode = shouldOutputJson(jsonModeConfig?.flags ?? {});
277
+ if (jsonMode) {
278
+ outputErrorAsJson('UNKNOWN_SETTING', `Unknown setting: ${setting}`, createMetadata('config', jsonModeConfig?.flags ?? {}));
279
+ }
280
+ this.error(`Unknown setting: ${setting}`);
281
+ }
282
+ }
283
+ }
240
284
  setConfigValue(db, key, value, jsonMode) {
241
285
  const normalizedKey = key.toLowerCase();
242
286
  switch (normalizedKey) {
@@ -3,10 +3,11 @@ export default class DockerClean extends Command {
3
3
  static description: string;
4
4
  static examples: string[];
5
5
  static flags: {
6
+ machine: import("@oclif/core/interfaces").BooleanFlag<boolean>;
7
+ json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
6
8
  force: import("@oclif/core/interfaces").BooleanFlag<boolean>;
7
9
  'dry-run': import("@oclif/core/interfaces").BooleanFlag<boolean>;
8
10
  all: import("@oclif/core/interfaces").BooleanFlag<boolean>;
9
- json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
11
  };
11
12
  run(): Promise<void>;
12
13
  private findOrphanedContainers;
@@ -2,13 +2,13 @@ import { Command, Flags } from '@oclif/core';
2
2
  import { execSync } from 'node:child_process';
3
3
  import * as path from 'node:path';
4
4
  import Database from 'better-sqlite3';
5
- import inquirer from 'inquirer';
6
5
  import { styles } from '../../lib/styles.js';
7
6
  import { getWorkspaceInfo } from '../../lib/agents/commands.js';
8
7
  import { ExecutionStorage } from '../../lib/execution/storage.js';
9
8
  import { isDockerRunning } from '../../lib/execution/runners.js';
10
9
  import { sanitizeContainerId } from '../../lib/docker/resolve.js';
11
- import { shouldOutputJson, outputPromptAsJson, createMetadata, buildPromptConfig, } from '../../lib/prompt-json.js';
10
+ import { FlagResolver, shouldOutputJson } from '../../lib/flags/index.js';
11
+ import { machineOutputFlags } from '../../lib/pmo/base-command.js';
12
12
  export default class DockerClean extends Command {
13
13
  static description = 'Remove orphaned containers (containers without running agents)';
14
14
  static examples = [
@@ -33,10 +33,7 @@ export default class DockerClean extends Command {
33
33
  description: 'Remove all stopped devcontainers (not just orphaned)',
34
34
  default: false,
35
35
  }),
36
- json: Flags.boolean({
37
- description: 'Output prompt configuration as JSON (for AI agents/scripts)',
38
- default: false,
39
- }),
36
+ ...machineOutputFlags,
40
37
  };
41
38
  async run() {
42
39
  const { flags } = await this.parse(DockerClean);
@@ -93,29 +90,23 @@ export default class DockerClean extends Command {
93
90
  }
94
91
  // Confirm removal
95
92
  if (!flags.force) {
96
- // Check if JSON output mode is active
97
- const jsonMode = shouldOutputJson(flags);
98
- // Build choices once, use for both JSON and interactive modes
99
- const confirmChoices = [
100
- { name: 'No', value: 'false' },
101
- { name: 'Yes', value: 'true' },
102
- ];
103
- const confirmMessage = `Remove ${orphanedContainers.length} orphaned container(s)?`;
104
- // In JSON mode, output confirmation prompt
105
- if (jsonMode) {
106
- outputPromptAsJson(buildPromptConfig('list', 'confirmed', confirmMessage, confirmChoices), createMetadata('docker clean', flags));
107
- db.close();
108
- return;
109
- }
110
- const { confirm } = await inquirer.prompt([
111
- {
112
- type: 'confirm',
113
- name: 'confirm',
114
- message: confirmMessage,
115
- default: false,
116
- },
117
- ]);
118
- if (!confirm) {
93
+ const resolver = new FlagResolver({
94
+ commandName: 'docker clean',
95
+ baseCommand: 'prlt docker clean',
96
+ jsonMode: shouldOutputJson(flags),
97
+ flags,
98
+ });
99
+ resolver.addPrompt({
100
+ flagName: 'confirmed',
101
+ type: 'list',
102
+ message: `Remove ${orphanedContainers.length} orphaned container(s)?`,
103
+ choices: () => [
104
+ { name: 'Yes', value: true },
105
+ { name: 'No', value: false },
106
+ ],
107
+ });
108
+ const resolved = await resolver.resolve();
109
+ if (!resolved.confirmed) {
119
110
  this.log(`\n${styles.muted('Aborted.')}\n`);
120
111
  db.close();
121
112
  return;
@@ -3,6 +3,7 @@ export default class Docker extends Command {
3
3
  static description: string;
4
4
  static examples: string[];
5
5
  static flags: {
6
+ machine: import("@oclif/core/interfaces").BooleanFlag<boolean>;
6
7
  json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
7
8
  };
8
9
  run(): Promise<void>;