@proletariat/cli 0.3.16 → 0.3.18

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 (338) hide show
  1. package/dist/commands/action/create.d.ts +1 -0
  2. package/dist/commands/action/create.js +74 -38
  3. package/dist/commands/action/delete.d.ts +1 -0
  4. package/dist/commands/action/delete.js +23 -24
  5. package/dist/commands/action/index.d.ts +1 -0
  6. package/dist/commands/action/index.js +5 -10
  7. package/dist/commands/action/list.d.ts +1 -0
  8. package/dist/commands/action/list.js +3 -1
  9. package/dist/commands/action/run.d.ts +1 -0
  10. package/dist/commands/action/run.js +44 -32
  11. package/dist/commands/action/show.d.ts +2 -0
  12. package/dist/commands/action/update.d.ts +1 -0
  13. package/dist/commands/action/update.js +80 -39
  14. package/dist/commands/agent/auth.d.ts +2 -0
  15. package/dist/commands/agent/auth.js +44 -3
  16. package/dist/commands/agent/discover.d.ts +2 -0
  17. package/dist/commands/agent/discover.js +35 -3
  18. package/dist/commands/agent/index.d.ts +1 -0
  19. package/dist/commands/agent/index.js +25 -45
  20. package/dist/commands/agent/list.d.ts +8 -3
  21. package/dist/commands/agent/list.js +16 -29
  22. package/dist/commands/agent/login.d.ts +1 -0
  23. package/dist/commands/agent/login.js +14 -32
  24. package/dist/commands/agent/rebuild.d.ts +1 -0
  25. package/dist/commands/agent/rebuild.js +2 -2
  26. package/dist/commands/agent/remove.d.ts +17 -0
  27. package/dist/commands/agent/remove.js +144 -0
  28. package/dist/commands/agent/restart.d.ts +1 -0
  29. package/dist/commands/agent/restart.js +2 -2
  30. package/dist/commands/agent/shell.d.ts +1 -0
  31. package/dist/commands/agent/shell.js +63 -76
  32. package/dist/commands/agent/staff/add.d.ts +1 -0
  33. package/dist/commands/agent/staff/add.js +7 -1
  34. package/dist/commands/agent/staff/index.d.ts +1 -0
  35. package/dist/commands/agent/staff/index.js +5 -4
  36. package/dist/commands/agent/staff/remove.d.ts +1 -0
  37. package/dist/commands/agent/status.d.ts +1 -0
  38. package/dist/commands/agent/status.js +11 -23
  39. package/dist/commands/agent/temp/cleanup.d.ts +1 -0
  40. package/dist/commands/agent/temp/index.d.ts +1 -0
  41. package/dist/commands/agent/temp/index.js +4 -3
  42. package/dist/commands/agent/themes/index.d.ts +1 -0
  43. package/dist/commands/agent/themes/index.js +9 -3
  44. package/dist/commands/agent/themes/set.d.ts +1 -0
  45. package/dist/commands/agent/themes/set.js +7 -1
  46. package/dist/commands/agent/visit.d.ts +1 -0
  47. package/dist/commands/agent/visit.js +11 -23
  48. package/dist/commands/autocomplete/setup.d.ts +11 -0
  49. package/dist/commands/autocomplete/setup.js +113 -8
  50. package/dist/commands/board/index.d.ts +4 -0
  51. package/dist/commands/board/index.js +32 -30
  52. package/dist/commands/board/watch.d.ts +2 -0
  53. package/dist/commands/branch/create.d.ts +1 -0
  54. package/dist/commands/branch/create.js +33 -41
  55. package/dist/commands/branch/index.d.ts +1 -0
  56. package/dist/commands/branch/list.d.ts +2 -0
  57. package/dist/commands/branch/validate.d.ts +2 -0
  58. package/dist/commands/branch/where.d.ts +1 -0
  59. package/dist/commands/claude.d.ts +6 -0
  60. package/dist/commands/claude.js +166 -116
  61. package/dist/commands/commit.d.ts +6 -0
  62. package/dist/commands/commit.js +68 -73
  63. package/dist/commands/config/index.d.ts +13 -0
  64. package/dist/commands/config/index.js +142 -98
  65. package/dist/commands/docker/clean.d.ts +2 -1
  66. package/dist/commands/docker/clean.js +20 -29
  67. package/dist/commands/docker/index.d.ts +1 -0
  68. package/dist/commands/docker/index.js +37 -41
  69. package/dist/commands/docker/prune.d.ts +2 -1
  70. package/dist/commands/docker/prune.js +20 -27
  71. package/dist/commands/docker/restart.d.ts +2 -1
  72. package/dist/commands/docker/restart.js +20 -29
  73. package/dist/commands/docker/stop.d.ts +2 -1
  74. package/dist/commands/docker/stop.js +20 -29
  75. package/dist/commands/epic/activate.d.ts +1 -0
  76. package/dist/commands/epic/archive.d.ts +1 -0
  77. package/dist/commands/epic/create.d.ts +1 -0
  78. package/dist/commands/epic/index.d.ts +1 -0
  79. package/dist/commands/epic/link/block.d.ts +1 -0
  80. package/dist/commands/epic/link/duplicates.d.ts +1 -0
  81. package/dist/commands/epic/link/index.d.ts +1 -0
  82. package/dist/commands/epic/link/relates.d.ts +1 -0
  83. package/dist/commands/epic/link/remove.d.ts +1 -0
  84. package/dist/commands/epic/list.d.ts +2 -0
  85. package/dist/commands/epic/move.d.ts +1 -0
  86. package/dist/commands/epic/progress.d.ts +1 -0
  87. package/dist/commands/epic/project.d.ts +1 -0
  88. package/dist/commands/epic/reorder.d.ts +1 -0
  89. package/dist/commands/epic/spec.d.ts +1 -0
  90. package/dist/commands/epic/ticket.d.ts +1 -0
  91. package/dist/commands/epic/view.d.ts +1 -0
  92. package/dist/commands/execution/index.d.ts +1 -0
  93. package/dist/commands/execution/index.js +9 -25
  94. package/dist/commands/execution/list.d.ts +2 -0
  95. package/dist/commands/execution/logs.d.ts +1 -0
  96. package/dist/commands/execution/logs.js +6 -16
  97. package/dist/commands/execution/stop.d.ts +1 -0
  98. package/dist/commands/execution/stop.js +4 -15
  99. package/dist/commands/gh/index.d.ts +1 -0
  100. package/dist/commands/gh/index.js +27 -27
  101. package/dist/commands/gh/login.d.ts +4 -0
  102. package/dist/commands/gh/login.js +31 -0
  103. package/dist/commands/gh/status.d.ts +4 -0
  104. package/dist/commands/gh/status.js +27 -4
  105. package/dist/commands/gh/token.d.ts +4 -0
  106. package/dist/commands/gh/token.js +49 -5
  107. package/dist/commands/phase/create.d.ts +1 -1
  108. package/dist/commands/phase/create.js +116 -74
  109. package/dist/commands/phase/delete.d.ts +1 -0
  110. package/dist/commands/phase/delete.js +23 -22
  111. package/dist/commands/phase/list.d.ts +1 -0
  112. package/dist/commands/phase/list.js +3 -5
  113. package/dist/commands/phase/move.d.ts +1 -0
  114. package/dist/commands/phase/move.js +39 -39
  115. package/dist/commands/phase/template/apply.d.ts +1 -0
  116. package/dist/commands/phase/template/create.d.ts +2 -0
  117. package/dist/commands/phase/template/delete.d.ts +1 -0
  118. package/dist/commands/phase/template/index.d.ts +1 -0
  119. package/dist/commands/phase/template/list.d.ts +1 -0
  120. package/dist/commands/phase/template/update.d.ts +2 -0
  121. package/dist/commands/phase/update.d.ts +1 -1
  122. package/dist/commands/phase/update.js +89 -55
  123. package/dist/commands/pmo/init.d.ts +2 -0
  124. package/dist/commands/pmo/init.js +84 -22
  125. package/dist/commands/pr/create.d.ts +12 -3
  126. package/dist/commands/pr/create.js +130 -147
  127. package/dist/commands/pr/index.d.ts +6 -3
  128. package/dist/commands/pr/index.js +41 -39
  129. package/dist/commands/pr/link.d.ts +7 -3
  130. package/dist/commands/pr/link.js +126 -150
  131. package/dist/commands/pr/status.d.ts +6 -3
  132. package/dist/commands/pr/status.js +101 -126
  133. package/dist/commands/project/archive.d.ts +1 -0
  134. package/dist/commands/project/archive.js +15 -20
  135. package/dist/commands/project/create.d.ts +1 -0
  136. package/dist/commands/project/create.js +13 -5
  137. package/dist/commands/project/delete.d.ts +1 -0
  138. package/dist/commands/project/delete.js +14 -28
  139. package/dist/commands/project/index.d.ts +1 -0
  140. package/dist/commands/project/index.js +0 -5
  141. package/dist/commands/project/list.d.ts +2 -0
  142. package/dist/commands/project/list.js +21 -3
  143. package/dist/commands/project/spec.d.ts +1 -0
  144. package/dist/commands/project/spec.js +17 -23
  145. package/dist/commands/project/unarchive.d.ts +2 -0
  146. package/dist/commands/project/unarchive.js +21 -2
  147. package/dist/commands/project/view.d.ts +1 -0
  148. package/dist/commands/project/view.js +34 -22
  149. package/dist/commands/repo/add.d.ts +2 -0
  150. package/dist/commands/repo/add.js +44 -1
  151. package/dist/commands/repo/index.d.ts +1 -0
  152. package/dist/commands/repo/index.js +20 -38
  153. package/dist/commands/repo/list.d.ts +2 -0
  154. package/dist/commands/repo/remove.d.ts +1 -0
  155. package/dist/commands/repo/remove.js +45 -63
  156. package/dist/commands/repo/view.d.ts +2 -0
  157. package/dist/commands/repo/view.js +30 -5
  158. package/dist/commands/roadmap/add-project.d.ts +1 -0
  159. package/dist/commands/roadmap/create.d.ts +1 -0
  160. package/dist/commands/roadmap/delete.d.ts +1 -0
  161. package/dist/commands/roadmap/generate.d.ts +1 -0
  162. package/dist/commands/roadmap/index.d.ts +1 -0
  163. package/dist/commands/roadmap/list.d.ts +2 -0
  164. package/dist/commands/roadmap/remove-project.d.ts +1 -0
  165. package/dist/commands/roadmap/reorder.d.ts +1 -0
  166. package/dist/commands/roadmap/update.d.ts +1 -0
  167. package/dist/commands/roadmap/view.d.ts +1 -0
  168. package/dist/commands/session/attach.d.ts +1 -0
  169. package/dist/commands/session/index.d.ts +1 -0
  170. package/dist/commands/session/index.js +8 -25
  171. package/dist/commands/session/list.d.ts +2 -0
  172. package/dist/commands/spec/create.d.ts +1 -1
  173. package/dist/commands/spec/create.js +64 -65
  174. package/dist/commands/spec/index.d.ts +1 -0
  175. package/dist/commands/spec/index.js +36 -22
  176. package/dist/commands/spec/link/depends.d.ts +1 -0
  177. package/dist/commands/spec/link/depends.js +6 -6
  178. package/dist/commands/spec/link/duplicates.d.ts +1 -0
  179. package/dist/commands/spec/link/duplicates.js +6 -6
  180. package/dist/commands/spec/link/index.d.ts +2 -1
  181. package/dist/commands/spec/link/index.js +0 -4
  182. package/dist/commands/spec/link/relates.d.ts +1 -0
  183. package/dist/commands/spec/link/relates.js +6 -6
  184. package/dist/commands/spec/link/remove.d.ts +2 -1
  185. package/dist/commands/spec/link/remove.js +6 -6
  186. package/dist/commands/spec/list.d.ts +2 -0
  187. package/dist/commands/spec/list.js +25 -0
  188. package/dist/commands/spec/plan.d.ts +2 -1
  189. package/dist/commands/spec/plan.js +19 -26
  190. package/dist/commands/spec/ticket.d.ts +2 -1
  191. package/dist/commands/spec/ticket.js +48 -34
  192. package/dist/commands/spec/view.d.ts +2 -1
  193. package/dist/commands/spec/view.js +25 -16
  194. package/dist/commands/status/create.d.ts +1 -1
  195. package/dist/commands/status/create.js +80 -64
  196. package/dist/commands/status/delete.d.ts +2 -1
  197. package/dist/commands/status/delete.js +26 -22
  198. package/dist/commands/status/index.d.ts +1 -0
  199. package/dist/commands/status/index.js +26 -19
  200. package/dist/commands/status/list.d.ts +1 -0
  201. package/dist/commands/status/list.js +12 -7
  202. package/dist/commands/status/move.d.ts +2 -1
  203. package/dist/commands/status/move.js +62 -61
  204. package/dist/commands/status/update.d.ts +2 -2
  205. package/dist/commands/status/update.js +110 -77
  206. package/dist/commands/template/delete.d.ts +1 -0
  207. package/dist/commands/template/delete.js +47 -48
  208. package/dist/commands/template/index.d.ts +1 -0
  209. package/dist/commands/template/index.js +26 -33
  210. package/dist/commands/template/list.d.ts +1 -0
  211. package/dist/commands/template/phase/create.d.ts +1 -0
  212. package/dist/commands/template/phase/create.js +6 -0
  213. package/dist/commands/template/phase/index.d.ts +1 -0
  214. package/dist/commands/template/phase/index.js +27 -26
  215. package/dist/commands/template/phase/update.d.ts +1 -0
  216. package/dist/commands/template/phase/update.js +6 -0
  217. package/dist/commands/template/ticket/index.d.ts +1 -0
  218. package/dist/commands/template/ticket/index.js +27 -26
  219. package/dist/commands/template/ticket/save.d.ts +1 -0
  220. package/dist/commands/template/ticket/save.js +6 -0
  221. package/dist/commands/terminal/title.d.ts +26 -0
  222. package/dist/commands/terminal/title.js +37 -3
  223. package/dist/commands/ticket/bulk.d.ts +1 -0
  224. package/dist/commands/ticket/complete.d.ts +1 -0
  225. package/dist/commands/ticket/complete.js +18 -14
  226. package/dist/commands/ticket/create.d.ts +1 -0
  227. package/dist/commands/ticket/create.js +45 -41
  228. package/dist/commands/ticket/delete.d.ts +1 -0
  229. package/dist/commands/ticket/delete.js +1 -1
  230. package/dist/commands/ticket/edit.d.ts +1 -0
  231. package/dist/commands/ticket/edit.js +1 -1
  232. package/dist/commands/ticket/epic.d.ts +1 -0
  233. package/dist/commands/ticket/epic.js +2 -2
  234. package/dist/commands/ticket/index.d.ts +1 -0
  235. package/dist/commands/ticket/link/block.d.ts +1 -0
  236. package/dist/commands/ticket/link/block.js +1 -1
  237. package/dist/commands/ticket/link/duplicates.d.ts +1 -0
  238. package/dist/commands/ticket/link/duplicates.js +1 -1
  239. package/dist/commands/ticket/link/index.d.ts +1 -0
  240. package/dist/commands/ticket/link/index.js +9 -8
  241. package/dist/commands/ticket/link/relates.d.ts +1 -0
  242. package/dist/commands/ticket/link/relates.js +1 -1
  243. package/dist/commands/ticket/link/remove.d.ts +1 -0
  244. package/dist/commands/ticket/link/remove.js +1 -1
  245. package/dist/commands/ticket/list.d.ts +2 -0
  246. package/dist/commands/ticket/move.d.ts +1 -0
  247. package/dist/commands/ticket/move.js +27 -19
  248. package/dist/commands/ticket/project.d.ts +1 -0
  249. package/dist/commands/ticket/project.js +3 -3
  250. package/dist/commands/ticket/reassign.d.ts +1 -0
  251. package/dist/commands/ticket/reassign.js +1 -1
  252. package/dist/commands/ticket/spec.d.ts +1 -0
  253. package/dist/commands/ticket/spec.js +3 -3
  254. package/dist/commands/ticket/status.d.ts +1 -0
  255. package/dist/commands/ticket/status.js +1 -1
  256. package/dist/commands/ticket/template/apply.d.ts +1 -0
  257. package/dist/commands/ticket/template/create.d.ts +2 -0
  258. package/dist/commands/ticket/template/delete.d.ts +1 -0
  259. package/dist/commands/ticket/template/index.d.ts +1 -0
  260. package/dist/commands/ticket/template/list.d.ts +1 -0
  261. package/dist/commands/ticket/template/save.d.ts +2 -0
  262. package/dist/commands/ticket/update.d.ts +1 -0
  263. package/dist/commands/ticket/update.js +1 -1
  264. package/dist/commands/ticket/view.d.ts +1 -0
  265. package/dist/commands/ticket/view.js +1 -1
  266. package/dist/commands/work/complete.d.ts +1 -0
  267. package/dist/commands/work/index.d.ts +1 -0
  268. package/dist/commands/work/ready.d.ts +1 -0
  269. package/dist/commands/work/revise.d.ts +1 -0
  270. package/dist/commands/work/spawn-all.d.ts +2 -0
  271. package/dist/commands/work/spawn-all.js +11 -4
  272. package/dist/commands/work/spawn.d.ts +1 -0
  273. package/dist/commands/work/spawn.js +261 -166
  274. package/dist/commands/work/start.d.ts +1 -0
  275. package/dist/commands/work/start.js +270 -189
  276. package/dist/commands/work/watch.d.ts +1 -0
  277. package/dist/commands/work/watch.js +63 -58
  278. package/dist/commands/workflow/create.d.ts +1 -0
  279. package/dist/commands/workflow/create.js +2 -4
  280. package/dist/commands/workflow/delete.d.ts +1 -0
  281. package/dist/commands/workflow/delete.js +21 -33
  282. package/dist/commands/workflow/index.d.ts +1 -0
  283. package/dist/commands/workflow/list.d.ts +1 -0
  284. package/dist/commands/workflow/list.js +3 -6
  285. package/dist/commands/workflow/switch.d.ts +2 -0
  286. package/dist/commands/workflow/switch.js +46 -21
  287. package/dist/commands/workflow/view.d.ts +1 -0
  288. package/dist/commands/workflow/view.js +18 -27
  289. package/dist/commands/workspace/remove.d.ts +2 -2
  290. package/dist/commands/workspace/remove.js +16 -21
  291. package/dist/commands/workspace/use.d.ts +2 -2
  292. package/dist/commands/workspace/use.js +12 -18
  293. package/dist/lib/agents/commands.d.ts +1 -1
  294. package/dist/lib/agents/commands.js +4 -4
  295. package/dist/lib/database/drizzle-schema.d.ts +5009 -0
  296. package/dist/lib/database/drizzle-schema.js +699 -0
  297. package/dist/lib/database/drizzle.d.ts +29 -0
  298. package/dist/lib/database/drizzle.js +37 -0
  299. package/dist/lib/database/index.d.ts +1 -0
  300. package/dist/lib/database/index.js +1 -1
  301. package/dist/lib/execution/config.d.ts +6 -0
  302. package/dist/lib/execution/config.js +31 -13
  303. package/dist/lib/execution/devcontainer.js +13 -7
  304. package/dist/lib/execution/runners.js +24 -7
  305. package/dist/lib/execution/spawner.js +19 -0
  306. package/dist/lib/flags/index.d.ts +4 -0
  307. package/dist/lib/flags/index.js +4 -0
  308. package/dist/lib/flags/resolver.d.ts +224 -0
  309. package/dist/lib/flags/resolver.js +313 -0
  310. package/dist/lib/pmo/base-command.d.ts +53 -3
  311. package/dist/lib/pmo/base-command.js +92 -13
  312. package/dist/lib/pmo/find-pmo.d.ts +1 -1
  313. package/dist/lib/pmo/find-pmo.js +4 -4
  314. package/dist/lib/pmo/index.d.ts +1 -1
  315. package/dist/lib/pmo/index.js +1 -1
  316. package/dist/lib/pmo/storage/helpers.js +2 -1
  317. package/dist/lib/pmo/storage/index.d.ts +9 -0
  318. package/dist/lib/pmo/storage/index.js +14 -0
  319. package/dist/lib/pmo/storage/projects.d.ts +28 -13
  320. package/dist/lib/pmo/storage/projects.js +110 -34
  321. package/dist/lib/pmo/storage/roadmaps.d.ts +2 -0
  322. package/dist/lib/pmo/storage/roadmaps.js +182 -111
  323. package/dist/lib/pmo/storage/specs.js +13 -16
  324. package/dist/lib/pmo/storage/subtasks.js +17 -2
  325. package/dist/lib/pmo/storage/tickets.d.ts +12 -2
  326. package/dist/lib/pmo/storage/tickets.js +63 -5
  327. package/dist/lib/pmo/storage/types.d.ts +7 -3
  328. package/dist/lib/pmo/storage/views.d.ts +12 -1
  329. package/dist/lib/pmo/storage/views.js +61 -6
  330. package/dist/lib/prompt-command.d.ts +90 -0
  331. package/dist/lib/prompt-command.js +102 -0
  332. package/dist/lib/prompt-json.d.ts +34 -4
  333. package/dist/lib/prompt-json.js +35 -3
  334. package/dist/lib/repos/index.js +15 -15
  335. package/dist/lib/workspace.d.ts +4 -3
  336. package/dist/lib/workspace.js +3 -3
  337. package/oclif.manifest.json +4610 -2997
  338. package/package.json +13 -5
@@ -5,7 +5,8 @@ import { execSync } from 'node:child_process';
5
5
  import inquirer from 'inquirer';
6
6
  import Database from 'better-sqlite3';
7
7
  import { PMOCommand, pmoBaseFlags, autoExportToBoard } from '../../lib/pmo/index.js';
8
- import { shouldOutputJson, outputPromptAsJson, outputErrorAsJson, createMetadata, buildPromptConfig, } from '../../lib/prompt-json.js';
8
+ import { shouldOutputJson, outputErrorAsJson, createMetadata, } from '../../lib/prompt-json.js';
9
+ import { FlagResolver } from '../../lib/flags/index.js';
9
10
  import { getWorkColumnSetting, findColumnByName } from '../../lib/pmo/utils.js';
10
11
  import { styles } from '../../lib/styles.js';
11
12
  import { getWorkspaceInfo, createEphemeralAgent, getTicketTmuxSession, killTmuxSession, } from '../../lib/agents/commands.js';
@@ -256,19 +257,25 @@ export default class WorkStart extends PMOCommand {
256
257
  this.log(styles.muted(` - ${blocker.id}: ${blocker.title} (${blocker.status})`));
257
258
  }
258
259
  this.log('');
259
- const { startAnyway } = await inquirer.prompt([
260
- {
261
- type: 'list',
262
- name: 'startAnyway',
263
- message: 'Start anyway?',
264
- choices: [
265
- { name: 'No, cancel', value: false },
266
- { name: 'Yes, start despite blockers', value: true },
267
- ],
268
- default: false,
269
- },
270
- ]);
271
- if (!startAnyway) {
260
+ // Use FlagResolver for blocked ticket confirmation
261
+ const blockedResolver = new FlagResolver({
262
+ commandName: 'work start',
263
+ baseCommand: `prlt work start ${ticketId}`,
264
+ jsonMode,
265
+ flags: {},
266
+ });
267
+ blockedResolver.addPrompt({
268
+ flagName: 'startAnyway',
269
+ type: 'list',
270
+ message: 'Start anyway?',
271
+ default: 'no',
272
+ choices: () => [
273
+ { name: 'No, cancel', value: 'no' },
274
+ { name: 'Yes, start despite blockers', value: 'yes' },
275
+ ],
276
+ });
277
+ const blockedResult = await blockedResolver.resolve();
278
+ if (blockedResult.startAnyway !== 'yes') {
272
279
  db.close();
273
280
  this.log(styles.muted('Cancelled.'));
274
281
  return;
@@ -279,19 +286,26 @@ export default class WorkStart extends PMOCommand {
279
286
  if (existingSession && !flags.force) {
280
287
  this.log('');
281
288
  this.log(styles.warning(`Ticket ${ticketId} has an active tmux session (${existingSession.agent})`));
282
- const { sessionAction } = await inquirer.prompt([
283
- {
284
- type: 'list',
285
- name: 'sessionAction',
286
- message: 'What would you like to do?',
287
- choices: [
288
- { name: 'Attach to existing session', value: 'attach' },
289
- { name: 'Spawn new agent (keeps existing session)', value: 'spawn' },
290
- { name: 'Kill session and respawn', value: 'kill' },
291
- { name: 'Cancel', value: 'cancel' },
292
- ],
293
- },
294
- ]);
289
+ // Use FlagResolver for session action
290
+ const sessionResolver = new FlagResolver({
291
+ commandName: 'work start',
292
+ baseCommand: `prlt work start ${ticketId}`,
293
+ jsonMode,
294
+ flags: {},
295
+ });
296
+ sessionResolver.addPrompt({
297
+ flagName: 'sessionAction',
298
+ type: 'list',
299
+ message: 'What would you like to do?',
300
+ choices: () => [
301
+ { name: 'Attach to existing session', value: 'attach' },
302
+ { name: 'Spawn new agent (keeps existing session)', value: 'spawn' },
303
+ { name: 'Kill session and respawn', value: 'kill' },
304
+ { name: 'Cancel', value: 'cancel' },
305
+ ],
306
+ });
307
+ const sessionResult = await sessionResolver.resolve();
308
+ const sessionAction = sessionResult.sessionAction;
295
309
  if (sessionAction === 'cancel') {
296
310
  db.close();
297
311
  this.log(styles.muted('Cancelled.'));
@@ -351,36 +365,36 @@ export default class WorkStart extends PMOCommand {
351
365
  busyAgentNames.add(agent.name);
352
366
  }
353
367
  }
354
- // Prompt to assign an agent
355
- const agentChoices = [];
356
- // Add ephemeral option first
357
- agentChoices.push({ name: 'Create new ephemeral agent (recommended)', value: '__ephemeral__' });
358
- agentChoices.push(new inquirer.Separator());
359
- // Only show staff agents that exist on disk
368
+ // Build agent choices
360
369
  const availableAgents = activeStaffAgents.filter(a => !busyAgentNames.has(a.name));
361
370
  const busyAgents = activeStaffAgents.filter(a => busyAgentNames.has(a.name));
362
- if (availableAgents.length > 0) {
363
- agentChoices.push(new inquirer.Separator('── Available Staff Agents ──'));
364
- for (const a of availableAgents) {
365
- agentChoices.push({ name: a.name, value: a.name });
366
- }
371
+ const agentChoiceList = [
372
+ { name: 'Create new ephemeral agent (recommended)', value: '__ephemeral__' },
373
+ ];
374
+ for (const a of availableAgents) {
375
+ agentChoiceList.push({ name: a.name, value: a.name });
367
376
  }
368
- if (busyAgents.length > 0) {
369
- agentChoices.push(new inquirer.Separator('── Busy (already working) ──'));
370
- for (const a of busyAgents) {
371
- const runningExecs = executionStorage.getAgentRunningExecutions(a.name);
372
- const ticketIds = runningExecs.map(e => e.ticketId).join(', ');
373
- agentChoices.push({ name: `${a.name} (working on ${ticketIds})`, value: a.name, disabled: 'busy' });
374
- }
377
+ for (const a of busyAgents) {
378
+ const runningExecs = executionStorage.getAgentRunningExecutions(a.name);
379
+ const ticketIds = runningExecs.map(e => e.ticketId).join(', ');
380
+ agentChoiceList.push({ name: `${a.name} (working on ${ticketIds})`, value: a.name, disabled: true });
375
381
  }
376
- const { selectedAgent } = await inquirer.prompt([
377
- {
378
- type: 'list',
379
- name: 'selectedAgent',
380
- message: `Select agent for ${ticketId}:`,
381
- choices: agentChoices,
382
- },
383
- ]);
382
+ // Use FlagResolver for agent selection
383
+ const agentResolver = new FlagResolver({
384
+ commandName: 'work start',
385
+ baseCommand: `prlt work start ${ticketId}`,
386
+ jsonMode,
387
+ flags: {},
388
+ });
389
+ agentResolver.addPrompt({
390
+ flagName: 'selectedAgent',
391
+ type: 'list',
392
+ message: `Select agent for ${ticketId}:`,
393
+ default: '__ephemeral__',
394
+ choices: () => agentChoiceList,
395
+ });
396
+ const agentResult = await agentResolver.resolve();
397
+ const selectedAgent = agentResult.selectedAgent;
384
398
  if (selectedAgent === '__ephemeral__') {
385
399
  // Create ephemeral agent
386
400
  this.log(styles.muted('Creating ephemeral agent...'));
@@ -478,18 +492,25 @@ export default class WorkStart extends PMOCommand {
478
492
  }
479
493
  }
480
494
  this.log('');
481
- const { action } = await inquirer.prompt([
482
- {
483
- type: 'list',
484
- name: 'action',
485
- message: 'How would you like to proceed?',
486
- choices: [
487
- { name: 'Push existing work and continue', value: 'push' },
488
- { name: 'Continue anyway (existing work may conflict)', value: 'continue' },
489
- { name: 'Cancel', value: 'cancel' },
490
- ],
491
- },
492
- ]);
495
+ // Use FlagResolver for unsaved work action
496
+ const unsavedResolver = new FlagResolver({
497
+ commandName: 'work start',
498
+ baseCommand: `prlt work start ${ticketId}`,
499
+ jsonMode,
500
+ flags: {},
501
+ });
502
+ unsavedResolver.addPrompt({
503
+ flagName: 'unsavedAction',
504
+ type: 'list',
505
+ message: 'How would you like to proceed?',
506
+ choices: () => [
507
+ { name: 'Push existing work and continue', value: 'push' },
508
+ { name: 'Continue anyway (existing work may conflict)', value: 'continue' },
509
+ { name: 'Cancel', value: 'cancel' },
510
+ ],
511
+ });
512
+ const unsavedResult = await unsavedResolver.resolve();
513
+ const action = unsavedResult.unsavedAction;
493
514
  if (action === 'cancel') {
494
515
  db.close();
495
516
  this.log(styles.muted('Cancelled.'));
@@ -562,43 +583,48 @@ export default class WorkStart extends PMOCommand {
562
583
  // Get all actions for selection
563
584
  const allActions = await this.storage.listActions();
564
585
  // Build choices with suggested action at top
565
- const actionChoices = [];
586
+ const actionChoiceList = [];
566
587
  if (suggestedAction) {
567
- actionChoices.push({
588
+ actionChoiceList.push({
568
589
  name: `${suggestedAction.name} - ${suggestedAction.description || 'Suggested for ' + currentCategory} (Recommended)`,
569
590
  value: suggestedAction.id,
570
591
  });
571
- actionChoices.push(new inquirer.Separator('── Other Actions ──'));
572
592
  }
573
593
  for (const action of allActions) {
574
594
  if (suggestedAction && action.id === suggestedAction.id)
575
595
  continue;
576
- actionChoices.push({
596
+ actionChoiceList.push({
577
597
  name: `${action.name}${action.description ? ' - ' + action.description : ''}`,
578
598
  value: action.id,
579
599
  });
580
600
  }
581
- actionChoices.push(new inquirer.Separator('── Custom ──'));
582
- actionChoices.push({ name: 'Custom prompt...', value: '__custom__' });
583
- actionChoices.push({ name: 'Ad-hoc session - unstructured exploration/debugging', value: '__adhoc__' });
584
- const { selectedActionId } = await inquirer.prompt([
585
- {
586
- type: 'list',
587
- name: 'selectedActionId',
588
- message: `What should the agent do with ${ticket.id}?`,
589
- choices: actionChoices,
590
- },
591
- ]);
601
+ actionChoiceList.push({ name: 'Custom prompt...', value: '__custom__' });
602
+ actionChoiceList.push({ name: 'Ad-hoc session - unstructured exploration/debugging', value: '__adhoc__' });
603
+ // Use FlagResolver for action selection
604
+ const actionResolver = new FlagResolver({
605
+ commandName: 'work start',
606
+ baseCommand: `prlt work start ${ticketId}`,
607
+ jsonMode,
608
+ flags: {},
609
+ });
610
+ actionResolver.addPrompt({
611
+ flagName: 'selectedActionId',
612
+ type: 'list',
613
+ message: `What should the agent do with ${ticket.id}?`,
614
+ default: suggestedAction?.id,
615
+ choices: () => actionChoiceList,
616
+ });
617
+ actionResolver.addPrompt({
618
+ flagName: 'customInput',
619
+ type: 'input',
620
+ message: 'Enter custom prompt:',
621
+ when: (ctx) => ctx.flags.selectedActionId === '__custom__',
622
+ validate: (value) => value.trim() ? true : 'Prompt cannot be empty',
623
+ });
624
+ const actionResult = await actionResolver.resolve();
625
+ const selectedActionId = actionResult.selectedActionId;
592
626
  if (selectedActionId === '__custom__') {
593
- const { customInput } = await inquirer.prompt([
594
- {
595
- type: 'input',
596
- name: 'customInput',
597
- message: 'Enter custom prompt:',
598
- validate: (input) => input.trim() ? true : 'Prompt cannot be empty',
599
- },
600
- ]);
601
- customPrompt = customInput.trim();
627
+ customPrompt = actionResult.customInput.trim();
602
628
  }
603
629
  else if (selectedActionId === '__adhoc__') {
604
630
  // Ad-hoc session - no specific action, just launch Claude for exploration
@@ -613,7 +639,7 @@ export default class WorkStart extends PMOCommand {
613
639
  createdAt: new Date(),
614
640
  };
615
641
  }
616
- else {
642
+ else if (selectedActionId) {
617
643
  selectedAction = await this.storage.getAction(selectedActionId);
618
644
  }
619
645
  }
@@ -670,6 +696,31 @@ export default class WorkStart extends PMOCommand {
670
696
  missing.push('devcontainer CLI');
671
697
  devcontainerLabel = `🐳 devcontainer (requires: ${missing.join(', ')})`;
672
698
  }
699
+ const envChoices = [
700
+ { name: devcontainerLabel, value: 'devcontainer', disabled: !devcontainerReady },
701
+ { name: '💻 host (runs directly on your machine)', value: 'host' },
702
+ { name: '✗ cancel', value: 'cancel' },
703
+ ];
704
+ // In JSON mode, use FlagResolver (outputs prompt and exits)
705
+ if (jsonMode) {
706
+ const envResolver = new FlagResolver({
707
+ commandName: 'work start',
708
+ baseCommand: `prlt work start ${ticketId}`,
709
+ jsonMode,
710
+ flags: {},
711
+ });
712
+ envResolver.addPrompt({
713
+ flagName: 'selectedEnvironment',
714
+ type: 'list',
715
+ message: 'Where should the agent run?',
716
+ default: devcontainerReady ? 'devcontainer' : 'host',
717
+ choices: () => envChoices,
718
+ });
719
+ await envResolver.resolve();
720
+ // FlagResolver exits in JSON mode, so we never reach here
721
+ db.close();
722
+ return;
723
+ }
673
724
  // Loop to allow re-selection if Docker isn't running
674
725
  let environmentSelected = false;
675
726
  while (!environmentSelected) {
@@ -679,11 +730,7 @@ export default class WorkStart extends PMOCommand {
679
730
  type: 'list',
680
731
  name: 'selectedEnvironment',
681
732
  message: 'Where should the agent run?',
682
- choices: [
683
- { name: devcontainerLabel, value: 'devcontainer', disabled: !devcontainerReady },
684
- { name: '💻 host (runs directly on your machine)', value: 'host' },
685
- { name: '✗ cancel', value: 'cancel' },
686
- ],
733
+ choices: envChoices,
687
734
  default: devcontainerReady ? 'devcontainer' : 'host',
688
735
  },
689
736
  ]);
@@ -713,32 +760,37 @@ export default class WorkStart extends PMOCommand {
713
760
  }
714
761
  // Check GitHub token is available for git push operations
715
762
  if (!isGitHubTokenAvailable()) {
716
- const tokenChoices = [
717
- { name: 'Yes, continue anyway (git push may fail)', value: 'continue' },
718
- { name: 'No, let me run gh auth login first', value: 'cancel' },
719
- { name: 'Switch to host mode instead', value: 'host' },
720
- ];
721
763
  const tokenMessage = 'GitHub token not found. Git push may fail. Continue without token?';
722
- if (jsonMode) {
723
- outputPromptAsJson(buildPromptConfig('list', 'tokenAction', tokenMessage, tokenChoices), createMetadata('work start', flags));
724
- db.close();
725
- return;
764
+ // Use FlagResolver for token action prompt
765
+ const tokenResolver = new FlagResolver({
766
+ commandName: 'work start',
767
+ baseCommand: `prlt work start ${ticketId}`,
768
+ jsonMode,
769
+ flags: {},
770
+ });
771
+ tokenResolver.addPrompt({
772
+ flagName: 'tokenAction',
773
+ type: 'list',
774
+ message: tokenMessage,
775
+ default: 'continue',
776
+ choices: () => [
777
+ { name: 'Yes, continue anyway (git push may fail)', value: 'continue' },
778
+ { name: 'No, let me run gh auth login first', value: 'cancel' },
779
+ { name: 'Switch to host mode instead', value: 'host' },
780
+ ],
781
+ });
782
+ // In JSON mode, this will output prompt and exit
783
+ // In interactive mode, show warning first then prompt
784
+ if (!jsonMode) {
785
+ this.log('');
786
+ this.warn('GitHub token not found.\n' +
787
+ 'Git push operations may fail inside the container.\n' +
788
+ 'Run `gh auth login` to authenticate, or continue without token.');
789
+ this.log('');
726
790
  }
727
- this.log('');
728
- this.warn('GitHub token not found.\n' +
729
- 'Git push operations may fail inside the container.\n' +
730
- 'Run `gh auth login` to authenticate, or continue without token.');
731
- this.log('');
732
791
  // eslint-disable-next-line no-await-in-loop -- Interactive user prompt in loop
733
- const { tokenAction } = await inquirer.prompt([
734
- {
735
- type: 'list',
736
- name: 'tokenAction',
737
- message: tokenMessage,
738
- choices: tokenChoices,
739
- default: 'continue',
740
- },
741
- ]);
792
+ const resolved = await tokenResolver.resolve();
793
+ const tokenAction = resolved.tokenAction;
742
794
  if (tokenAction === 'cancel') {
743
795
  db.close();
744
796
  this.log(styles.muted('Run `gh auth login` and try again.'));
@@ -830,20 +882,26 @@ export default class WorkStart extends PMOCommand {
830
882
  const warningMsg = flags['run-on-host']
831
883
  ? 'Select display mode (--run-on-host: bypassing devcontainer):'
832
884
  : 'Select display mode (no devcontainer - running on host):';
833
- const { selectedMode } = await inquirer.prompt([
834
- {
835
- type: 'list',
836
- name: 'selectedMode',
837
- message: warningMsg,
838
- choices: [
839
- { name: '🖥️ New tab - Opens in new terminal tab (recommended)', value: 'terminal' },
840
- { name: '▶️ Foreground - Run in current terminal (blocking)', value: 'foreground' },
841
- { name: '📦 Background - Runs detached, reattach with: prlt session attach', value: 'background' },
842
- ],
843
- default: 'terminal',
844
- },
845
- ]);
846
- displayMode = selectedMode;
885
+ // Use FlagResolver for display mode selection
886
+ const displayResolver = new FlagResolver({
887
+ commandName: 'work start',
888
+ baseCommand: `prlt work start ${ticketId}`,
889
+ jsonMode,
890
+ flags: {},
891
+ });
892
+ displayResolver.addPrompt({
893
+ flagName: 'selectedMode',
894
+ type: 'list',
895
+ message: warningMsg,
896
+ default: 'terminal',
897
+ choices: () => [
898
+ { name: '🖥️ New tab - Opens in new terminal tab (recommended)', value: 'terminal' },
899
+ { name: '▶️ Foreground - Run in current terminal (blocking)', value: 'foreground' },
900
+ { name: '📦 Background - Runs detached, reattach with: prlt session attach', value: 'background' },
901
+ ],
902
+ });
903
+ const displayResult = await displayResolver.resolve();
904
+ displayMode = displayResult.selectedMode;
847
905
  }
848
906
  }
849
907
  const executor = flags.executor || DEFAULT_EXECUTION_CONFIG.defaultExecutor;
@@ -858,19 +916,26 @@ export default class WorkStart extends PMOCommand {
858
916
  this.log(styles.warning('⚠️ No Claude Code credentials found for Docker containers'));
859
917
  this.log(styles.muted(' Agents will fail with 401 authentication errors without credentials.'));
860
918
  this.log('');
861
- const { authAction } = await inquirer.prompt([
862
- {
863
- type: 'list',
864
- name: 'authAction',
865
- message: 'What would you like to do?',
866
- choices: [
867
- { name: `🔐 Run ${this.config.bin} agent auth now (one-time setup)`, value: 'auth' },
868
- { name: '💻 Switch to host environment instead', value: 'host' },
869
- { name: '⏩ Continue anyway (must run /login in first agent)', value: 'continue' },
870
- { name: '✗ Cancel', value: 'cancel' },
871
- ],
872
- },
873
- ]);
919
+ // Use FlagResolver for auth action
920
+ const authResolver = new FlagResolver({
921
+ commandName: 'work start',
922
+ baseCommand: `prlt work start ${ticketId}`,
923
+ jsonMode,
924
+ flags: {},
925
+ });
926
+ authResolver.addPrompt({
927
+ flagName: 'authAction',
928
+ type: 'list',
929
+ message: 'What would you like to do?',
930
+ choices: () => [
931
+ { name: `🔐 Run ${this.config.bin} agent auth now (one-time setup)`, value: 'auth' },
932
+ { name: '💻 Switch to host environment instead', value: 'host' },
933
+ { name: '⏩ Continue anyway (must run /login in first agent)', value: 'continue' },
934
+ { name: '✗ Cancel', value: 'cancel' },
935
+ ],
936
+ });
937
+ const authResult = await authResolver.resolve();
938
+ const authAction = authResult.authAction;
874
939
  if (authAction === 'cancel') {
875
940
  db.close();
876
941
  this.log(styles.muted('Cancelled.'));
@@ -936,7 +1001,7 @@ export default class WorkStart extends PMOCommand {
936
1001
  }
937
1002
  }
938
1003
  // Prompt for permissions mode (all environments)
939
- // Skip prompt if --permission-mode flag is set
1004
+ // Use FlagResolver to handle both JSON mode and interactive prompts consistently
940
1005
  if (flags['permission-mode']) {
941
1006
  sandboxed = flags['permission-mode'] === 'safe';
942
1007
  }
@@ -944,24 +1009,26 @@ export default class WorkStart extends PMOCommand {
944
1009
  const containerNote = environment === 'devcontainer'
945
1010
  ? ' (container provides additional isolation)'
946
1011
  : '';
947
- const permissionChoices = [
948
- { name: '⚠️ danger - Skip permission checks (faster, container provides isolation)', value: 'danger', command: `prlt work start ${ticketId} --skip-permissions` },
949
- { name: '🔒 safe - Requires approval for dangerous operations', value: 'safe' },
950
- ];
951
- // Handle JSON mode
952
- if (jsonMode) {
953
- outputPromptAsJson(buildPromptConfig('list', 'permissionMode', `Permission mode for Claude Code${containerNote}:`, permissionChoices, 'danger'), createMetadata('work start', flags));
954
- }
955
- const { permissionMode } = await inquirer.prompt([
956
- {
957
- type: 'list',
958
- name: 'permissionMode',
959
- message: `Permission mode for Claude Code${containerNote}:`,
960
- choices: permissionChoices,
961
- default: 'danger',
962
- },
963
- ]);
964
- sandboxed = permissionMode === 'safe';
1012
+ // Create resolver for permission-mode flag
1013
+ const permissionResolver = new FlagResolver({
1014
+ commandName: 'work start',
1015
+ baseCommand: `prlt work start ${ticketId}`,
1016
+ jsonMode,
1017
+ flags: { 'permission-mode': flags['permission-mode'] },
1018
+ });
1019
+ permissionResolver.addPrompt({
1020
+ flagName: 'permission-mode',
1021
+ type: 'list',
1022
+ message: `Permission mode for Claude Code${containerNote}:`,
1023
+ default: 'danger',
1024
+ choices: () => [
1025
+ { name: '⚠️ danger - Skip permission checks (faster, container provides isolation)', value: 'danger' },
1026
+ { name: '🔒 safe - Requires approval for dangerous operations', value: 'safe' },
1027
+ ],
1028
+ when: (ctx) => !ctx.flags['permission-mode'],
1029
+ });
1030
+ const resolvedPermission = await permissionResolver.resolve();
1031
+ sandboxed = resolvedPermission['permission-mode'] === 'safe';
965
1032
  }
966
1033
  // Prompt for PR creation when work is complete
967
1034
  // Only show if gh CLI is available and authenticated
@@ -975,19 +1042,25 @@ export default class WorkStart extends PMOCommand {
975
1042
  createPR = false;
976
1043
  }
977
1044
  else if (ghAvailable) {
978
- const { prChoice } = await inquirer.prompt([
979
- {
980
- type: 'list',
981
- name: 'prChoice',
982
- message: 'Create a pull request when work is ready?',
983
- choices: [
984
- { name: '✓ Yes - Create PR when running `prlt work ready`', value: 'yes' },
985
- { name: '✗ No - Just move ticket to review (can create PR later)', value: 'no' },
986
- ],
987
- default: 'yes',
988
- },
989
- ]);
990
- createPR = prChoice === 'yes';
1045
+ // Use FlagResolver for PR choice
1046
+ const prResolver = new FlagResolver({
1047
+ commandName: 'work start',
1048
+ baseCommand: `prlt work start ${ticketId}`,
1049
+ jsonMode,
1050
+ flags: {},
1051
+ });
1052
+ prResolver.addPrompt({
1053
+ flagName: 'prChoice',
1054
+ type: 'list',
1055
+ message: 'Create a pull request when work is ready?',
1056
+ default: 'yes',
1057
+ choices: () => [
1058
+ { name: '✓ Yes - Create PR when running `prlt work ready`', value: 'yes' },
1059
+ { name: '✗ No - Just move ticket to review (can create PR later)', value: 'no' },
1060
+ ],
1061
+ });
1062
+ const prResult = await prResolver.resolve();
1063
+ createPR = prResult.prChoice === 'yes';
991
1064
  }
992
1065
  // Show execution info
993
1066
  this.log('');
@@ -1042,18 +1115,26 @@ export default class WorkStart extends PMOCommand {
1042
1115
  }
1043
1116
  else {
1044
1117
  // No branch in DB - ask user if one already exists
1045
- const { branchChoice } = await inquirer.prompt([
1046
- {
1047
- type: 'list',
1048
- name: 'branchChoice',
1049
- message: `Does a branch already exist for ${ticket.id}?`,
1050
- choices: [
1051
- { name: 'No, create new branch (Recommended)', value: 'create' },
1052
- { name: 'Yes, I\'ll enter the branch name', value: 'enter' },
1053
- { name: 'Search for matching branches', value: 'search' },
1054
- ],
1055
- },
1056
- ]);
1118
+ // Use FlagResolver for branch choice
1119
+ const branchResolver = new FlagResolver({
1120
+ commandName: 'work start',
1121
+ baseCommand: `prlt work start ${ticketId}`,
1122
+ jsonMode,
1123
+ flags: {},
1124
+ });
1125
+ branchResolver.addPrompt({
1126
+ flagName: 'branchChoice',
1127
+ type: 'list',
1128
+ message: `Does a branch already exist for ${ticket.id}?`,
1129
+ default: 'create',
1130
+ choices: () => [
1131
+ { name: 'No, create new branch (Recommended)', value: 'create' },
1132
+ { name: 'Yes, I\'ll enter the branch name', value: 'enter' },
1133
+ { name: 'Search for matching branches', value: 'search' },
1134
+ ],
1135
+ });
1136
+ const branchResult = await branchResolver.resolve();
1137
+ const branchChoice = branchResult.branchChoice;
1057
1138
  if (branchChoice === 'enter') {
1058
1139
  // User enters existing branch name
1059
1140
  const { enteredBranch } = await inquirer.prompt([
@@ -13,6 +13,7 @@ export default class WorkWatch extends PMOCommand {
13
13
  mode: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
14
14
  'skip-permissions': import("@oclif/core/interfaces").BooleanFlag<boolean>;
15
15
  'create-pr': import("@oclif/core/interfaces").BooleanFlag<boolean>;
16
+ machine: import("@oclif/core/interfaces").BooleanFlag<boolean>;
16
17
  project: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
17
18
  };
18
19
  private isRunning;