@proletariat/cli 0.3.24 → 0.3.26

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 (134) hide show
  1. package/dist/commands/action/create.js +3 -3
  2. package/dist/commands/action/index.js +2 -2
  3. package/dist/commands/action/update.js +3 -3
  4. package/dist/commands/agent/auth.js +1 -1
  5. package/dist/commands/agent/cleanup.js +6 -6
  6. package/dist/commands/agent/discover.js +1 -1
  7. package/dist/commands/agent/remove.js +4 -4
  8. package/dist/commands/autocomplete/setup.d.ts +2 -2
  9. package/dist/commands/autocomplete/setup.js +5 -5
  10. package/dist/commands/branch/create.js +31 -30
  11. package/dist/commands/category/create.js +4 -5
  12. package/dist/commands/category/delete.js +2 -3
  13. package/dist/commands/category/rename.js +2 -3
  14. package/dist/commands/claude.d.ts +2 -8
  15. package/dist/commands/claude.js +26 -26
  16. package/dist/commands/commit.d.ts +2 -8
  17. package/dist/commands/commit.js +4 -26
  18. package/dist/commands/config/index.d.ts +2 -10
  19. package/dist/commands/config/index.js +8 -34
  20. package/dist/commands/docker/index.d.ts +2 -2
  21. package/dist/commands/docker/index.js +8 -8
  22. package/dist/commands/epic/activate.js +9 -17
  23. package/dist/commands/epic/archive.js +13 -24
  24. package/dist/commands/epic/create.js +7 -6
  25. package/dist/commands/epic/delete.js +4 -5
  26. package/dist/commands/epic/move.js +28 -47
  27. package/dist/commands/epic/progress.js +10 -14
  28. package/dist/commands/epic/project.js +42 -59
  29. package/dist/commands/epic/reorder.js +25 -30
  30. package/dist/commands/epic/spec.d.ts +1 -0
  31. package/dist/commands/epic/spec.js +39 -40
  32. package/dist/commands/epic/ticket.d.ts +2 -0
  33. package/dist/commands/epic/ticket.js +63 -37
  34. package/dist/commands/feedback/index.d.ts +10 -0
  35. package/dist/commands/feedback/index.js +60 -0
  36. package/dist/commands/feedback/list.d.ts +12 -0
  37. package/dist/commands/feedback/list.js +126 -0
  38. package/dist/commands/feedback/submit.d.ts +16 -0
  39. package/dist/commands/feedback/submit.js +220 -0
  40. package/dist/commands/feedback/view.d.ts +15 -0
  41. package/dist/commands/feedback/view.js +109 -0
  42. package/dist/commands/gh/index.js +4 -0
  43. package/dist/commands/link/index.js +2 -2
  44. package/dist/commands/pmo/init.d.ts +2 -2
  45. package/dist/commands/pmo/init.js +7 -7
  46. package/dist/commands/project/spec.js +6 -6
  47. package/dist/commands/repo/create.d.ts +38 -0
  48. package/dist/commands/repo/create.js +283 -0
  49. package/dist/commands/repo/index.js +7 -0
  50. package/dist/commands/roadmap/add-project.js +9 -22
  51. package/dist/commands/roadmap/create.d.ts +0 -1
  52. package/dist/commands/roadmap/create.js +46 -40
  53. package/dist/commands/roadmap/delete.js +10 -24
  54. package/dist/commands/roadmap/generate.d.ts +1 -0
  55. package/dist/commands/roadmap/generate.js +21 -22
  56. package/dist/commands/roadmap/remove-project.js +14 -34
  57. package/dist/commands/roadmap/reorder.js +19 -26
  58. package/dist/commands/roadmap/update.js +27 -26
  59. package/dist/commands/roadmap/view.js +5 -12
  60. package/dist/commands/session/attach.d.ts +1 -8
  61. package/dist/commands/session/attach.js +93 -59
  62. package/dist/commands/session/health.d.ts +29 -0
  63. package/dist/commands/session/health.js +495 -0
  64. package/dist/commands/session/index.js +4 -0
  65. package/dist/commands/session/list.d.ts +0 -8
  66. package/dist/commands/session/list.js +130 -81
  67. package/dist/commands/spec/create.js +1 -1
  68. package/dist/commands/spec/edit.js +64 -35
  69. package/dist/commands/staff/add.d.ts +2 -2
  70. package/dist/commands/staff/add.js +15 -14
  71. package/dist/commands/staff/index.js +2 -2
  72. package/dist/commands/staff/remove.js +4 -4
  73. package/dist/commands/status/index.js +6 -7
  74. package/dist/commands/support/book.d.ts +10 -0
  75. package/dist/commands/support/book.js +54 -0
  76. package/dist/commands/support/discord.d.ts +10 -0
  77. package/dist/commands/support/discord.js +54 -0
  78. package/dist/commands/support/docs.d.ts +10 -0
  79. package/dist/commands/support/docs.js +54 -0
  80. package/dist/commands/support/index.d.ts +19 -0
  81. package/dist/commands/support/index.js +81 -0
  82. package/dist/commands/support/issues.d.ts +11 -0
  83. package/dist/commands/support/issues.js +77 -0
  84. package/dist/commands/support/logs.d.ts +18 -0
  85. package/dist/commands/support/logs.js +247 -0
  86. package/dist/commands/template/apply.js +10 -11
  87. package/dist/commands/template/create.js +18 -17
  88. package/dist/commands/template/index.d.ts +2 -2
  89. package/dist/commands/template/index.js +6 -6
  90. package/dist/commands/template/save.js +8 -7
  91. package/dist/commands/template/update.js +6 -7
  92. package/dist/commands/terminal/title.d.ts +2 -26
  93. package/dist/commands/terminal/title.js +4 -33
  94. package/dist/commands/theme/index.d.ts +2 -2
  95. package/dist/commands/theme/index.js +19 -18
  96. package/dist/commands/theme/set.d.ts +2 -2
  97. package/dist/commands/theme/set.js +5 -5
  98. package/dist/commands/ticket/create.js +52 -26
  99. package/dist/commands/ticket/delete.js +15 -13
  100. package/dist/commands/ticket/edit.js +59 -20
  101. package/dist/commands/ticket/epic.js +12 -10
  102. package/dist/commands/ticket/move.d.ts +7 -0
  103. package/dist/commands/ticket/move.js +132 -0
  104. package/dist/commands/ticket/project.js +11 -9
  105. package/dist/commands/ticket/reassign.js +23 -19
  106. package/dist/commands/ticket/spec.js +7 -5
  107. package/dist/commands/ticket/update.js +55 -53
  108. package/dist/commands/whoami.js +1 -0
  109. package/dist/commands/work/ready.js +7 -7
  110. package/dist/commands/work/revise.js +13 -11
  111. package/dist/commands/work/spawn.d.ts +1 -0
  112. package/dist/commands/work/spawn.js +225 -64
  113. package/dist/commands/work/start.d.ts +1 -0
  114. package/dist/commands/work/start.js +301 -173
  115. package/dist/hooks/init.js +4 -0
  116. package/dist/lib/execution/runners.js +21 -17
  117. package/dist/lib/execution/session-utils.d.ts +60 -0
  118. package/dist/lib/execution/session-utils.js +162 -0
  119. package/dist/lib/execution/spawner.d.ts +2 -0
  120. package/dist/lib/execution/spawner.js +42 -0
  121. package/dist/lib/flags/resolver.d.ts +2 -2
  122. package/dist/lib/flags/resolver.js +15 -0
  123. package/dist/lib/init/index.js +18 -0
  124. package/dist/lib/multiline-input.d.ts +63 -0
  125. package/dist/lib/multiline-input.js +360 -0
  126. package/dist/lib/pr/index.d.ts +4 -0
  127. package/dist/lib/pr/index.js +32 -14
  128. package/dist/lib/prompt-command.d.ts +3 -0
  129. package/dist/lib/prompt-json.d.ts +77 -6
  130. package/dist/lib/prompt-json.js +46 -0
  131. package/dist/lib/repos/git.d.ts +7 -0
  132. package/dist/lib/repos/git.js +20 -0
  133. package/oclif.manifest.json +2913 -2246
  134. package/package.json +1 -1
@@ -1,5 +1,4 @@
1
1
  import { Args, Flags } from '@oclif/core';
2
- import inquirer from 'inquirer';
3
2
  import { PMOCommand, pmoBaseFlags, autoExportToBoard } from '../../lib/pmo/index.js';
4
3
  import { styles } from '../../lib/styles.js';
5
4
  import { shouldOutputJson, outputErrorAsJson, createMetadata, } from '../../lib/prompt-json.js';
@@ -166,6 +165,8 @@ export default class TicketProject extends PMOCommand {
166
165
  this.log(styles.muted(`\nView ticket: prlt ticket view ${ticketId}`));
167
166
  }
168
167
  async executeBulk(flags) {
168
+ const jsonMode = shouldOutputJson(flags);
169
+ const jsonModeConfig = jsonMode ? { flags: flags, commandName: 'ticket project' } : null;
169
170
  this.log(styles.emphasis('📁 Bulk Move Tickets to Project\n'));
170
171
  // Get source project ID
171
172
  const sourceProjectId = await this.requireProject();
@@ -176,7 +177,7 @@ export default class TicketProject extends PMOCommand {
176
177
  return;
177
178
  }
178
179
  // Select tickets
179
- const { selectedTickets } = await inquirer.prompt([{
180
+ const { selectedTickets } = await this.prompt([{
180
181
  type: 'checkbox',
181
182
  name: 'selectedTickets',
182
183
  message: 'Select tickets to move:',
@@ -187,7 +188,7 @@ export default class TicketProject extends PMOCommand {
187
188
  value: t.id,
188
189
  };
189
190
  }),
190
- }]);
191
+ }], jsonModeConfig);
191
192
  if (selectedTickets.length === 0) {
192
193
  this.log(styles.muted('No tickets selected.'));
193
194
  return;
@@ -201,15 +202,16 @@ export default class TicketProject extends PMOCommand {
201
202
  }
202
203
  let targetProjectId = flags.target;
203
204
  if (!targetProjectId) {
204
- const { selected } = await inquirer.prompt([{
205
+ const { selected } = await this.prompt([{
205
206
  type: 'list',
206
207
  name: 'selected',
207
208
  message: 'Select target project:',
208
209
  choices: otherProjects.map(p => ({
209
210
  name: `${p.id} - ${p.name}`,
210
211
  value: p.id,
212
+ command: `prlt ticket project --bulk --target ${p.id} --json`,
211
213
  })),
212
- }]);
214
+ }], jsonModeConfig);
213
215
  targetProjectId = selected;
214
216
  }
215
217
  // Validate target project
@@ -224,15 +226,15 @@ export default class TicketProject extends PMOCommand {
224
226
  });
225
227
  if (ticketsWithEpics.length > 0) {
226
228
  this.log(styles.warning(`\n${ticketsWithEpics.length} ticket(s) are assigned to epics.`));
227
- const { action } = await inquirer.prompt([{
229
+ const { action } = await this.prompt([{
228
230
  type: 'list',
229
231
  name: 'action',
230
232
  message: 'How to handle epic assignments?',
231
233
  choices: [
232
- { name: 'Unlink from epics and move', value: 'unlink' },
233
- { name: 'Cancel', value: 'cancel' },
234
+ { name: 'Unlink from epics and move', value: 'unlink', command: `prlt ticket project --bulk --target ${targetProjectId} --json` },
235
+ { name: 'Cancel', value: 'cancel', command: '' },
234
236
  ],
235
- }]);
237
+ }], jsonModeConfig);
236
238
  if (action === 'cancel') {
237
239
  return;
238
240
  }
@@ -1,5 +1,4 @@
1
1
  import { Args, Flags } from '@oclif/core';
2
- import inquirer from 'inquirer';
3
2
  import { PMOCommand, pmoBaseFlags, autoExportToBoard } from '../../lib/pmo/index.js';
4
3
  import { styles } from '../../lib/styles.js';
5
4
  import { shouldOutputJson, outputErrorAsJson, createMetadata, } from '../../lib/prompt-json.js';
@@ -110,26 +109,28 @@ export default class TicketReassign extends PMOCommand {
110
109
  // Get target assignee
111
110
  let targetAssignee = args.assignee || flags.to;
112
111
  if (!targetAssignee) {
113
- const { assignee } = await inquirer.prompt([{
112
+ const jsonModeConfig = jsonMode ? { flags, commandName: 'ticket reassign' } : null;
113
+ const { assignee } = await this.prompt([{
114
114
  type: 'list',
115
115
  name: 'assignee',
116
116
  message: `Reassign ${ticketId} to:`,
117
117
  choices: [
118
- { name: 'None (unassign)', value: '__none__' },
118
+ { name: 'None (unassign)', value: '__none__', command: `prlt ticket reassign ${ticketId} none${projectId ? ` -P ${projectId}` : ''} --json` },
119
119
  ...Array.from(assignees).sort().map(a => ({
120
120
  name: a === ticket.assignee ? `${a} (current)` : a,
121
121
  value: a,
122
+ command: `prlt ticket reassign ${ticketId} ${a}${projectId ? ` -P ${projectId}` : ''} --json`,
122
123
  })),
123
- { name: '── Enter custom name ──', value: '__custom__' },
124
+ { name: '── Enter custom name ──', value: '__custom__', command: `prlt ticket reassign ${ticketId} <name>${projectId ? ` -P ${projectId}` : ''} --json` },
124
125
  ],
125
- }]);
126
+ }], jsonModeConfig);
126
127
  if (assignee === '__custom__') {
127
- const { customAssignee } = await inquirer.prompt([{
128
+ const { customAssignee } = await this.prompt([{
128
129
  type: 'input',
129
130
  name: 'customAssignee',
130
131
  message: 'Enter agent/assignee name:',
131
132
  validate: (input) => input.length > 0 || 'Name is required',
132
- }]);
133
+ }], jsonModeConfig);
133
134
  targetAssignee = customAssignee;
134
135
  }
135
136
  else if (assignee === '__none__') {
@@ -173,6 +174,7 @@ export default class TicketReassign extends PMOCommand {
173
174
  }
174
175
  }
175
176
  async executeBulk(allTickets, assigneesList, flags) {
177
+ const jsonMode = shouldOutputJson(flags);
176
178
  this.log(styles.emphasis('👤 Reassign Tickets\n'));
177
179
  // Filter tickets if --from specified
178
180
  let filteredTickets = allTickets;
@@ -189,7 +191,8 @@ export default class TicketReassign extends PMOCommand {
189
191
  return;
190
192
  }
191
193
  // Select tickets to reassign
192
- const { selectedTickets } = await inquirer.prompt([{
194
+ const jsonModeConfig = jsonMode ? { flags: flags, commandName: 'ticket reassign' } : null;
195
+ const { selectedTickets } = await this.prompt([{
193
196
  type: 'checkbox',
194
197
  name: 'selectedTickets',
195
198
  message: 'Select tickets to reassign:',
@@ -197,7 +200,7 @@ export default class TicketReassign extends PMOCommand {
197
200
  name: `${t.id} - ${t.title} [Assignee: ${t.assignee || '(none)'}]`,
198
201
  value: t.id,
199
202
  })),
200
- }]);
203
+ }], jsonModeConfig);
201
204
  if (selectedTickets.length === 0) {
202
205
  this.log(styles.muted('No tickets selected.'));
203
206
  return;
@@ -205,26 +208,27 @@ export default class TicketReassign extends PMOCommand {
205
208
  // Select target assignee
206
209
  let targetAssignee = flags.to;
207
210
  if (targetAssignee === undefined) {
208
- const { assignee } = await inquirer.prompt([{
211
+ const { assignee } = await this.prompt([{
209
212
  type: 'list',
210
213
  name: 'assignee',
211
214
  message: 'Reassign to which agent?',
212
215
  choices: [
213
- { name: 'None (unassign)', value: '__none__' },
216
+ { name: 'None (unassign)', value: '__none__', command: '' },
214
217
  ...assigneesList.sort().map(a => ({
215
218
  name: a,
216
219
  value: a,
220
+ command: `prlt ticket reassign --bulk --to ${a} --json`,
217
221
  })),
218
- { name: '── Enter custom name ──', value: '__custom__' },
222
+ { name: '── Enter custom name ──', value: '__custom__', command: '' },
219
223
  ],
220
- }]);
224
+ }], jsonModeConfig);
221
225
  if (assignee === '__custom__') {
222
- const { customAssignee } = await inquirer.prompt([{
226
+ const { customAssignee } = await this.prompt([{
223
227
  type: 'input',
224
228
  name: 'customAssignee',
225
229
  message: 'Enter agent/assignee name:',
226
230
  validate: (input) => input.length > 0 || 'Name is required',
227
- }]);
231
+ }], jsonModeConfig);
228
232
  targetAssignee = customAssignee;
229
233
  }
230
234
  else if (assignee === '__none__') {
@@ -262,16 +266,16 @@ export default class TicketReassign extends PMOCommand {
262
266
  this.log(styles.primary(` • ${ticketId}: ${ticket?.title}`));
263
267
  }
264
268
  this.log('');
265
- const { confirm } = await inquirer.prompt([{
269
+ const { confirm } = await this.prompt([{
266
270
  type: 'list',
267
271
  name: 'confirm',
268
272
  message: 'Continue?',
269
273
  choices: [
270
- { name: 'No, cancel', value: false },
271
- { name: 'Yes, reassign tickets', value: true }
274
+ { name: 'No, cancel', value: false, command: '' },
275
+ { name: 'Yes, reassign tickets', value: true, command: `prlt ticket reassign --bulk --to ${targetAssignee || 'none'} --force --json` }
272
276
  ],
273
277
  default: 0
274
- }]);
278
+ }], jsonModeConfig);
275
279
  if (!confirm) {
276
280
  this.log(styles.muted('Operation cancelled.'));
277
281
  return;
@@ -1,5 +1,4 @@
1
1
  import { Args, Flags } from '@oclif/core';
2
- import inquirer from 'inquirer';
3
2
  import { PMOCommand, pmoBaseFlags, autoExportToBoard } from '../../lib/pmo/index.js';
4
3
  import { styles } from '../../lib/styles.js';
5
4
  import { shouldOutputJson, outputErrorAsJson, createMetadata, } from '../../lib/prompt-json.js';
@@ -192,6 +191,8 @@ export default class TicketSpec extends PMOCommand {
192
191
  this.log(styles.muted(`\nView ticket: prlt ticket view ${ticketId}`));
193
192
  }
194
193
  async executeBulk(flags, projectId) {
194
+ const jsonMode = shouldOutputJson(flags);
195
+ const jsonModeConfig = jsonMode ? { flags: flags, commandName: 'ticket spec' } : null;
195
196
  this.log(styles.emphasis('📄 Bulk Assign Spec to Tickets\n'));
196
197
  // Get all tickets
197
198
  const tickets = await this.storage.listTickets(projectId);
@@ -200,7 +201,7 @@ export default class TicketSpec extends PMOCommand {
200
201
  return;
201
202
  }
202
203
  // Select tickets
203
- const { selectedTickets } = await inquirer.prompt([{
204
+ const { selectedTickets } = await this.prompt([{
204
205
  type: 'checkbox',
205
206
  name: 'selectedTickets',
206
207
  message: 'Select tickets to update:',
@@ -211,7 +212,7 @@ export default class TicketSpec extends PMOCommand {
211
212
  value: t.id,
212
213
  };
213
214
  }),
214
- }]);
215
+ }], jsonModeConfig);
215
216
  if (selectedTickets.length === 0) {
216
217
  this.log(styles.muted('No tickets selected.'));
217
218
  return;
@@ -235,15 +236,16 @@ export default class TicketSpec extends PMOCommand {
235
236
  this.log(styles.muted('\nNo specs found. Create one with: prlt spec create'));
236
237
  return;
237
238
  }
238
- const { selected } = await inquirer.prompt([{
239
+ const { selected } = await this.prompt([{
239
240
  type: 'list',
240
241
  name: 'selected',
241
242
  message: 'Select spec to assign:',
242
243
  choices: specs.map(s => ({
243
244
  name: `${s.id} - ${s.title} (${s.status})`,
244
245
  value: s.id,
246
+ command: `prlt ticket spec --bulk --spec ${s.id} --json`,
245
247
  })),
246
- }]);
248
+ }], jsonModeConfig);
247
249
  specId = selected;
248
250
  }
249
251
  // Validate spec
@@ -1,5 +1,4 @@
1
1
  import { Args, Flags } from '@oclif/core';
2
- import inquirer from 'inquirer';
3
2
  import { PMOCommand, pmoBaseFlags, autoExportToBoard } from '../../lib/pmo/index.js';
4
3
  import { PRIORITIES, PRIORITY_LABELS } from '../../lib/pmo/types.js';
5
4
  import { styles } from '../../lib/styles.js';
@@ -93,55 +92,56 @@ export default class TicketUpdate extends PMOCommand {
93
92
  let updateCategory = flags.category;
94
93
  if (!updatePriority && !updateCategory) {
95
94
  // Ask what to update
96
- const { updateType } = await inquirer.prompt([{
95
+ const jsonModeConfig = jsonMode ? { flags, commandName: 'ticket update' } : null;
96
+ const { updateType } = await this.prompt([{
97
97
  type: 'list',
98
98
  name: 'updateType',
99
99
  message: 'What would you like to update?',
100
100
  choices: [
101
- { name: 'Priority', value: 'priority' },
102
- { name: 'Category', value: 'category' },
103
- { name: 'Both', value: 'both' },
101
+ { name: 'Priority', value: 'priority', command: `prlt ticket update ${ticketId} --priority <P0|P1|P2|P3>${projectId ? ` -P ${projectId}` : ''} --json` },
102
+ { name: 'Category', value: 'category', command: `prlt ticket update ${ticketId} --category <category>${projectId ? ` -P ${projectId}` : ''} --json` },
103
+ { name: 'Both', value: 'both', command: `prlt ticket update ${ticketId} --priority <P0|P1|P2|P3> --category <category>${projectId ? ` -P ${projectId}` : ''} --json` },
104
104
  ],
105
- }]);
105
+ }], jsonModeConfig);
106
106
  if (updateType === 'priority' || updateType === 'both') {
107
- const { priority } = await inquirer.prompt([{
107
+ const { priority } = await this.prompt([{
108
108
  type: 'list',
109
109
  name: 'priority',
110
110
  message: 'Set priority to:',
111
111
  choices: [
112
- { name: `(Keep existing: ${ticket.priority || 'none'})`, value: null },
113
- ...PRIORITIES.map(p => ({ name: PRIORITY_LABELS[p], value: p })),
114
- { name: 'None (clear priority)', value: '' },
112
+ { name: `(Keep existing: ${ticket.priority || 'none'})`, value: null, command: '' },
113
+ ...PRIORITIES.map(p => ({ name: PRIORITY_LABELS[p], value: p, command: `prlt ticket update ${ticketId} --priority ${p}${projectId ? ` -P ${projectId}` : ''} --json` })),
114
+ { name: 'None (clear priority)', value: '', command: `prlt ticket update ${ticketId} --priority none${projectId ? ` -P ${projectId}` : ''} --json` },
115
115
  ],
116
- }]);
116
+ }], jsonModeConfig);
117
117
  if (priority !== null) {
118
118
  updatePriority = priority;
119
119
  }
120
120
  }
121
121
  if (updateType === 'category' || updateType === 'both') {
122
- const { categoryChoice } = await inquirer.prompt([{
122
+ const { categoryChoice } = await this.prompt([{
123
123
  type: 'list',
124
124
  name: 'categoryChoice',
125
125
  message: 'Set category to:',
126
126
  choices: [
127
- { name: `(Keep existing: ${ticket.category || 'none'})`, value: null },
128
- { name: 'feature', value: 'feature' },
129
- { name: 'bug', value: 'bug' },
130
- { name: 'refactor', value: 'refactor' },
131
- { name: 'docs', value: 'docs' },
132
- { name: 'test', value: 'test' },
133
- { name: 'chore', value: 'chore' },
134
- { name: 'None (clear category)', value: '' },
135
- { name: 'Custom...', value: '__custom__' },
127
+ { name: `(Keep existing: ${ticket.category || 'none'})`, value: null, command: '' },
128
+ { name: 'feature', value: 'feature', command: `prlt ticket update ${ticketId} --category feature${projectId ? ` -P ${projectId}` : ''} --json` },
129
+ { name: 'bug', value: 'bug', command: `prlt ticket update ${ticketId} --category bug${projectId ? ` -P ${projectId}` : ''} --json` },
130
+ { name: 'refactor', value: 'refactor', command: `prlt ticket update ${ticketId} --category refactor${projectId ? ` -P ${projectId}` : ''} --json` },
131
+ { name: 'docs', value: 'docs', command: `prlt ticket update ${ticketId} --category docs${projectId ? ` -P ${projectId}` : ''} --json` },
132
+ { name: 'test', value: 'test', command: `prlt ticket update ${ticketId} --category test${projectId ? ` -P ${projectId}` : ''} --json` },
133
+ { name: 'chore', value: 'chore', command: `prlt ticket update ${ticketId} --category chore${projectId ? ` -P ${projectId}` : ''} --json` },
134
+ { name: 'None (clear category)', value: '', command: `prlt ticket update ${ticketId} --category none${projectId ? ` -P ${projectId}` : ''} --json` },
135
+ { name: 'Custom...', value: '__custom__', command: `prlt ticket update ${ticketId} --category <category>${projectId ? ` -P ${projectId}` : ''} --json` },
136
136
  ],
137
- }]);
137
+ }], jsonModeConfig);
138
138
  if (categoryChoice === '__custom__') {
139
- const { customCategory } = await inquirer.prompt([{
139
+ const { customCategory } = await this.prompt([{
140
140
  type: 'input',
141
141
  name: 'customCategory',
142
142
  message: 'Enter custom category:',
143
143
  validate: (input) => input.length > 0 || 'Category is required',
144
- }]);
144
+ }], jsonModeConfig);
145
145
  updateCategory = customCategory;
146
146
  }
147
147
  else if (categoryChoice !== null) {
@@ -175,9 +175,11 @@ export default class TicketUpdate extends PMOCommand {
175
175
  this.log(styles.muted(` ${updates.join(', ')}`));
176
176
  }
177
177
  async executeBulk(allTickets, flags) {
178
+ const jsonMode = shouldOutputJson(flags);
179
+ const jsonModeConfig = jsonMode ? { flags: flags, commandName: 'ticket update' } : null;
178
180
  this.log(styles.emphasis('✏️ Update Multiple Tickets\n'));
179
181
  // Select tickets to update
180
- const { selectedTickets } = await inquirer.prompt([{
182
+ const { selectedTickets } = await this.prompt([{
181
183
  type: 'checkbox',
182
184
  name: 'selectedTickets',
183
185
  message: 'Select tickets to update:',
@@ -185,7 +187,7 @@ export default class TicketUpdate extends PMOCommand {
185
187
  name: `${t.id} - ${t.title} [P:${t.priority || 'none'} C:${t.category || 'none'}]`,
186
188
  value: t.id,
187
189
  })),
188
- }]);
190
+ }], jsonModeConfig);
189
191
  if (selectedTickets.length === 0) {
190
192
  this.log(styles.muted('No tickets selected.'));
191
193
  return;
@@ -195,55 +197,55 @@ export default class TicketUpdate extends PMOCommand {
195
197
  let updateCategory = flags.category;
196
198
  if (!updatePriority && !updateCategory) {
197
199
  // Ask what to update
198
- const { updateType } = await inquirer.prompt([{
200
+ const { updateType } = await this.prompt([{
199
201
  type: 'list',
200
202
  name: 'updateType',
201
203
  message: 'What would you like to update?',
202
204
  choices: [
203
- { name: 'Priority', value: 'priority' },
204
- { name: 'Category', value: 'category' },
205
- { name: 'Both', value: 'both' },
205
+ { name: 'Priority', value: 'priority', command: 'prlt ticket update --bulk --priority <P0|P1|P2|P3> --json' },
206
+ { name: 'Category', value: 'category', command: 'prlt ticket update --bulk --category <category> --json' },
207
+ { name: 'Both', value: 'both', command: 'prlt ticket update --bulk --priority <P0|P1|P2|P3> --category <category> --json' },
206
208
  ],
207
- }]);
209
+ }], jsonModeConfig);
208
210
  if (updateType === 'priority' || updateType === 'both') {
209
- const { priority } = await inquirer.prompt([{
211
+ const { priority } = await this.prompt([{
210
212
  type: 'list',
211
213
  name: 'priority',
212
214
  message: 'Set priority to:',
213
215
  choices: [
214
- { name: '(Keep existing)', value: null },
215
- ...PRIORITIES.map(p => ({ name: PRIORITY_LABELS[p], value: p })),
216
- { name: 'None (clear priority)', value: '' },
216
+ { name: '(Keep existing)', value: null, command: '' },
217
+ ...PRIORITIES.map(p => ({ name: PRIORITY_LABELS[p], value: p, command: `prlt ticket update --bulk --priority ${p} --json` })),
218
+ { name: 'None (clear priority)', value: '', command: 'prlt ticket update --bulk --priority none --json' },
217
219
  ],
218
- }]);
220
+ }], jsonModeConfig);
219
221
  if (priority !== null) {
220
222
  updatePriority = priority;
221
223
  }
222
224
  }
223
225
  if (updateType === 'category' || updateType === 'both') {
224
- const { categoryChoice } = await inquirer.prompt([{
226
+ const { categoryChoice } = await this.prompt([{
225
227
  type: 'list',
226
228
  name: 'categoryChoice',
227
229
  message: 'Set category to:',
228
230
  choices: [
229
- { name: '(Keep existing)', value: null },
230
- { name: 'feature', value: 'feature' },
231
- { name: 'bug', value: 'bug' },
232
- { name: 'refactor', value: 'refactor' },
233
- { name: 'docs', value: 'docs' },
234
- { name: 'test', value: 'test' },
235
- { name: 'chore', value: 'chore' },
236
- { name: 'None (clear category)', value: '' },
237
- { name: 'Custom...', value: '__custom__' },
231
+ { name: '(Keep existing)', value: null, command: '' },
232
+ { name: 'feature', value: 'feature', command: 'prlt ticket update --bulk --category feature --json' },
233
+ { name: 'bug', value: 'bug', command: 'prlt ticket update --bulk --category bug --json' },
234
+ { name: 'refactor', value: 'refactor', command: 'prlt ticket update --bulk --category refactor --json' },
235
+ { name: 'docs', value: 'docs', command: 'prlt ticket update --bulk --category docs --json' },
236
+ { name: 'test', value: 'test', command: 'prlt ticket update --bulk --category test --json' },
237
+ { name: 'chore', value: 'chore', command: 'prlt ticket update --bulk --category chore --json' },
238
+ { name: 'None (clear category)', value: '', command: 'prlt ticket update --bulk --category none --json' },
239
+ { name: 'Custom...', value: '__custom__', command: 'prlt ticket update --bulk --category <category> --json' },
238
240
  ],
239
- }]);
241
+ }], jsonModeConfig);
240
242
  if (categoryChoice === '__custom__') {
241
- const { customCategory } = await inquirer.prompt([{
243
+ const { customCategory } = await this.prompt([{
242
244
  type: 'input',
243
245
  name: 'customCategory',
244
246
  message: 'Enter custom category:',
245
247
  validate: (input) => input.length > 0 || 'Category is required',
246
- }]);
248
+ }], jsonModeConfig);
247
249
  updateCategory = customCategory;
248
250
  }
249
251
  else if (categoryChoice !== null) {
@@ -271,16 +273,16 @@ export default class TicketUpdate extends PMOCommand {
271
273
  this.log(styles.primary(` • ${ticketId}: ${ticket?.title}`));
272
274
  }
273
275
  this.log('');
274
- const { confirm } = await inquirer.prompt([{
276
+ const { confirm } = await this.prompt([{
275
277
  type: 'list',
276
278
  name: 'confirm',
277
279
  message: 'Continue?',
278
280
  choices: [
279
- { name: 'No, cancel', value: false },
280
- { name: 'Yes, update tickets', value: true }
281
+ { name: 'No, cancel', value: false, command: '' },
282
+ { name: 'Yes, update tickets', value: true, command: 'prlt ticket update --bulk --force --json' }
281
283
  ],
282
284
  default: 0
283
- }]);
285
+ }], jsonModeConfig);
284
286
  if (!confirm) {
285
287
  this.log(styles.muted('Operation cancelled.'));
286
288
  return;
@@ -10,6 +10,7 @@ export default class Whoami extends Command {
10
10
  '<%= config.bin %> <%= command.id %>',
11
11
  ];
12
12
  async run() {
13
+ await this.parse(Whoami);
13
14
  const isDevcontainer = process.env.DEVCONTAINER === 'true';
14
15
  const agentName = this.detectAgentName();
15
16
  const repoName = this.detectRepoName();
@@ -2,7 +2,6 @@ import { Args, Flags } from '@oclif/core';
2
2
  import * as path from 'node:path';
3
3
  import * as fs from 'node:fs';
4
4
  import Database from 'better-sqlite3';
5
- import inquirer from 'inquirer';
6
5
  import { PMOCommand, pmoBaseFlags, autoExportToBoard } from '../../lib/pmo/index.js';
7
6
  import { getWorkColumnSetting, findColumnByName } from '../../lib/pmo/utils.js';
8
7
  import { styles } from '../../lib/styles.js';
@@ -134,7 +133,8 @@ export default class WorkReady extends PMOCommand {
134
133
  }
135
134
  // Handle PR creation
136
135
  let prUrl;
137
- const shouldCreatePR = flags.pr || flags['draft-pr'] || (!flags['no-pr'] && await this.shouldOfferPRCreation());
136
+ const jsonModeConfig = jsonMode ? { flags: flags, commandName: 'work ready' } : null;
137
+ const shouldCreatePR = flags.pr || flags['draft-pr'] || (!flags['no-pr'] && await this.shouldOfferPRCreation(jsonModeConfig));
138
138
  if (shouldCreatePR) {
139
139
  // Get branch and worktree path from the execution record
140
140
  const branch = runningExecution?.branch;
@@ -191,7 +191,7 @@ export default class WorkReady extends PMOCommand {
191
191
  /**
192
192
  * Check if we should offer PR creation (gh is available, on a feature branch, etc.)
193
193
  */
194
- async shouldOfferPRCreation() {
194
+ async shouldOfferPRCreation(jsonModeConfig) {
195
195
  // Check if gh CLI is available
196
196
  if (!isGHInstalled() || !isGHAuthenticated()) {
197
197
  return false;
@@ -212,16 +212,16 @@ export default class WorkReady extends PMOCommand {
212
212
  return false;
213
213
  }
214
214
  // Prompt user
215
- const { createPR: wantPR } = await inquirer.prompt([{
215
+ const { createPR: wantPR } = await this.prompt([{
216
216
  type: 'list',
217
217
  name: 'createPR',
218
218
  message: 'Create a pull request for this work?',
219
219
  choices: [
220
- { name: 'Yes', value: true },
221
- { name: 'No', value: false },
220
+ { name: 'Yes', value: true, command: 'prlt work ready --pr --json' },
221
+ { name: 'No', value: false, command: 'prlt work ready --no-pr --json' },
222
222
  ],
223
223
  default: true,
224
- }]);
224
+ }], jsonModeConfig);
225
225
  return wantPR;
226
226
  }
227
227
  /**
@@ -2,7 +2,6 @@ import { Args, Flags } from '@oclif/core';
2
2
  import * as fs from 'node:fs';
3
3
  import * as path from 'node:path';
4
4
  import { execSync } from 'node:child_process';
5
- import inquirer from 'inquirer';
6
5
  import Database from 'better-sqlite3';
7
6
  import { PMOCommand, pmoBaseFlags, autoExportToBoard } from '../../lib/pmo/index.js';
8
7
  import { getWorkColumnSetting, findColumnByName } from '../../lib/pmo/utils.js';
@@ -122,7 +121,8 @@ export default class WorkRevise extends PMOCommand {
122
121
  this.log(styles.muted('Use "prlt work start" for new work.'));
123
122
  return;
124
123
  }
125
- const { selectedTicketId } = await inquirer.prompt([
124
+ const jsonModeConfig = jsonMode ? { flags: flags, commandName: 'work revise' } : null;
125
+ const { selectedTicketId } = await this.prompt([
126
126
  {
127
127
  type: 'list',
128
128
  name: 'selectedTicketId',
@@ -130,9 +130,10 @@ export default class WorkRevise extends PMOCommand {
130
130
  choices: reviewTickets.map((t) => ({
131
131
  name: `${t.id} - ${t.title}`,
132
132
  value: t.id,
133
+ command: `prlt work revise ${t.id} --json`,
133
134
  })),
134
135
  },
135
- ]);
136
+ ], jsonModeConfig);
136
137
  ticketId = selectedTicketId;
137
138
  }
138
139
  // Get ticket
@@ -226,20 +227,21 @@ export default class WorkRevise extends PMOCommand {
226
227
  let environment = 'host';
227
228
  let displayMode = 'terminal';
228
229
  let sandboxed = false;
230
+ const reviseJsonModeConfig = jsonMode ? { flags: flags, commandName: 'work revise' } : null;
229
231
  if (hasDevcontainer && !flags['run-on-host']) {
230
232
  environment = 'devcontainer';
231
- const { selectedDisplay } = await inquirer.prompt([
233
+ const { selectedDisplay } = await this.prompt([
232
234
  {
233
235
  type: 'list',
234
236
  name: 'selectedDisplay',
235
237
  message: 'How should the agent output be displayed?',
236
238
  choices: [
237
- { name: 'terminal - New terminal window', value: 'terminal' },
238
- { name: 'background - Runs detached, reattach with: prlt session attach', value: 'background' },
239
+ { name: 'terminal - New terminal window', value: 'terminal', command: `prlt work revise ${ticketId} --mode terminal --json` },
240
+ { name: 'background - Runs detached, reattach with: prlt session attach', value: 'background', command: `prlt work revise ${ticketId} --mode background --json` },
239
241
  ],
240
242
  default: 'terminal',
241
243
  },
242
- ]);
244
+ ], reviseJsonModeConfig);
243
245
  displayMode = selectedDisplay;
244
246
  }
245
247
  else if (flags.mode) {
@@ -247,18 +249,18 @@ export default class WorkRevise extends PMOCommand {
247
249
  displayMode = flags.mode;
248
250
  }
249
251
  // Permission mode
250
- const { permissionMode } = await inquirer.prompt([
252
+ const { permissionMode } = await this.prompt([
251
253
  {
252
254
  type: 'list',
253
255
  name: 'permissionMode',
254
256
  message: 'Permission mode for Claude Code:',
255
257
  choices: [
256
- { name: 'danger - Skip permission checks (faster for revisions)', value: 'danger' },
257
- { name: 'safe - Requires approval for dangerous operations', value: 'safe' },
258
+ { name: 'danger - Skip permission checks (faster for revisions)', value: 'danger', command: `prlt work revise ${ticketId} --json` },
259
+ { name: 'safe - Requires approval for dangerous operations', value: 'safe', command: `prlt work revise ${ticketId} --json` },
258
260
  ],
259
261
  default: 'danger',
260
262
  },
261
- ]);
263
+ ], reviseJsonModeConfig);
262
264
  sandboxed = permissionMode === 'safe';
263
265
  const executor = flags.executor || DEFAULT_EXECUTION_CONFIG.defaultExecutor;
264
266
  // Show execution info
@@ -22,6 +22,7 @@ export default class WorkSpawn extends PMOCommand {
22
22
  'create-pr': import("@oclif/core/interfaces").BooleanFlag<boolean>;
23
23
  'no-pr': import("@oclif/core/interfaces").BooleanFlag<boolean>;
24
24
  action: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
25
+ message: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
25
26
  session: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
26
27
  focus: import("@oclif/core/interfaces").BooleanFlag<boolean>;
27
28
  clone: import("@oclif/core/interfaces").BooleanFlag<boolean>;