@proletariat/cli 0.3.104 → 0.3.109

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 (227) hide show
  1. package/dist/commands/agent/cleanup.js +13 -1
  2. package/dist/commands/agent/cleanup.js.map +1 -1
  3. package/dist/commands/claude/index.js +2 -2
  4. package/dist/commands/claude/index.js.map +1 -1
  5. package/dist/commands/feedback/list.js +4 -9
  6. package/dist/commands/feedback/list.js.map +1 -1
  7. package/dist/commands/feedback/submit.js +4 -9
  8. package/dist/commands/feedback/submit.js.map +1 -1
  9. package/dist/commands/feedback/view.js +4 -9
  10. package/dist/commands/feedback/view.js.map +1 -1
  11. package/dist/commands/gc.d.ts +1 -0
  12. package/dist/commands/gc.js +34 -1
  13. package/dist/commands/gc.js.map +1 -1
  14. package/dist/commands/notify/connect.d.ts +34 -0
  15. package/dist/commands/notify/connect.js +166 -0
  16. package/dist/commands/notify/connect.js.map +1 -0
  17. package/dist/commands/notify/disconnect.d.ts +16 -0
  18. package/dist/commands/notify/disconnect.js +45 -0
  19. package/dist/commands/notify/disconnect.js.map +1 -0
  20. package/dist/commands/notify/list.d.ts +15 -0
  21. package/dist/commands/notify/list.js +101 -0
  22. package/dist/commands/notify/list.js.map +1 -0
  23. package/dist/commands/notify/rules/add.d.ts +26 -0
  24. package/dist/commands/notify/rules/add.js +95 -0
  25. package/dist/commands/notify/rules/add.js.map +1 -0
  26. package/dist/commands/notify/rules/list.d.ts +14 -0
  27. package/dist/commands/notify/rules/list.js +82 -0
  28. package/dist/commands/notify/rules/list.js.map +1 -0
  29. package/dist/commands/notify/rules/remove.d.ts +16 -0
  30. package/dist/commands/notify/rules/remove.js +44 -0
  31. package/dist/commands/notify/rules/remove.js.map +1 -0
  32. package/dist/commands/notify/test.d.ts +16 -0
  33. package/dist/commands/notify/test.js +63 -0
  34. package/dist/commands/notify/test.js.map +1 -0
  35. package/dist/commands/orchestrate/index.js +11 -6
  36. package/dist/commands/orchestrate/index.js.map +1 -1
  37. package/dist/commands/orchestrate/machine.d.ts +29 -0
  38. package/dist/commands/orchestrate/machine.js +230 -0
  39. package/dist/commands/orchestrate/machine.js.map +1 -0
  40. package/dist/commands/pr/checks.js +4 -8
  41. package/dist/commands/pr/checks.js.map +1 -1
  42. package/dist/commands/pr/close.js +4 -8
  43. package/dist/commands/pr/close.js.map +1 -1
  44. package/dist/commands/pr/create.js +4 -8
  45. package/dist/commands/pr/create.js.map +1 -1
  46. package/dist/commands/pr/index.js +1 -1
  47. package/dist/commands/pr/index.js.map +1 -1
  48. package/dist/commands/pr/link.js +4 -8
  49. package/dist/commands/pr/link.js.map +1 -1
  50. package/dist/commands/pr/list.js +5 -9
  51. package/dist/commands/pr/list.js.map +1 -1
  52. package/dist/commands/pr/merge.d.ts +5 -0
  53. package/dist/commands/pr/merge.js +35 -11
  54. package/dist/commands/pr/merge.js.map +1 -1
  55. package/dist/commands/pr/status.js +5 -4
  56. package/dist/commands/pr/status.js.map +1 -1
  57. package/dist/commands/qa/index.js +2 -2
  58. package/dist/commands/qa/index.js.map +1 -1
  59. package/dist/commands/repo/create.js +4 -8
  60. package/dist/commands/repo/create.js.map +1 -1
  61. package/dist/commands/session/list.js +81 -41
  62. package/dist/commands/session/list.js.map +1 -1
  63. package/dist/commands/session/poke.d.ts +1 -11
  64. package/dist/commands/session/poke.js +20 -78
  65. package/dist/commands/session/poke.js.map +1 -1
  66. package/dist/commands/session/prune.js +3 -0
  67. package/dist/commands/session/prune.js.map +1 -1
  68. package/dist/commands/ticket/move.d.ts +12 -0
  69. package/dist/commands/ticket/move.js +75 -2
  70. package/dist/commands/ticket/move.js.map +1 -1
  71. package/dist/commands/work/drop.js +2 -2
  72. package/dist/commands/work/drop.js.map +1 -1
  73. package/dist/commands/work/ready.js +3 -3
  74. package/dist/commands/work/ready.js.map +1 -1
  75. package/dist/commands/work/rebase.js +4 -8
  76. package/dist/commands/work/rebase.js.map +1 -1
  77. package/dist/commands/work/run.d.ts +58 -0
  78. package/dist/commands/work/run.js +411 -0
  79. package/dist/commands/work/run.js.map +1 -0
  80. package/dist/commands/work/ship.d.ts +6 -0
  81. package/dist/commands/work/ship.js +93 -51
  82. package/dist/commands/work/ship.js.map +1 -1
  83. package/dist/commands/work/start.d.ts +1 -0
  84. package/dist/commands/work/start.js +127 -13
  85. package/dist/commands/work/start.js.map +1 -1
  86. package/dist/lib/agents/commands.d.ts +6 -0
  87. package/dist/lib/agents/commands.js +55 -2
  88. package/dist/lib/agents/commands.js.map +1 -1
  89. package/dist/lib/database/credential-store.js +2 -3
  90. package/dist/lib/database/credential-store.js.map +1 -1
  91. package/dist/lib/database/db-safety.d.ts +25 -0
  92. package/dist/lib/database/db-safety.js +35 -0
  93. package/dist/lib/database/db-safety.js.map +1 -1
  94. package/dist/lib/database/driver.js +6 -12
  95. package/dist/lib/database/driver.js.map +1 -1
  96. package/dist/lib/database/drizzle-schema.d.ts +3 -3
  97. package/dist/lib/database/drizzle.js +3 -3
  98. package/dist/lib/database/drizzle.js.map +1 -1
  99. package/dist/lib/database/index.d.ts +1 -1
  100. package/dist/lib/database/index.js +1 -1
  101. package/dist/lib/database/index.js.map +1 -1
  102. package/dist/lib/database/migrations/0021_notification_system.d.ts +2 -0
  103. package/dist/lib/database/migrations/0021_notification_system.js +39 -0
  104. package/dist/lib/database/migrations/0021_notification_system.js.map +1 -0
  105. package/dist/lib/database/migrations/0022_hook_mode_tiers.d.ts +11 -0
  106. package/dist/lib/database/migrations/0022_hook_mode_tiers.js +53 -0
  107. package/dist/lib/database/migrations/0022_hook_mode_tiers.js.map +1 -0
  108. package/dist/lib/database/migrations/index.js +4 -0
  109. package/dist/lib/database/migrations/index.js.map +1 -1
  110. package/dist/lib/database/pmo-bootstrap.js +6 -2
  111. package/dist/lib/database/pmo-bootstrap.js.map +1 -1
  112. package/dist/lib/database/workspace.js +5 -13
  113. package/dist/lib/database/workspace.js.map +1 -1
  114. package/dist/lib/events/emitting-runner.js +10 -0
  115. package/dist/lib/events/emitting-runner.js.map +1 -1
  116. package/dist/lib/execution/cc-version.d.ts +62 -0
  117. package/dist/lib/execution/cc-version.js +103 -0
  118. package/dist/lib/execution/cc-version.js.map +1 -0
  119. package/dist/lib/execution/devcontainer.js +2 -1
  120. package/dist/lib/execution/devcontainer.js.map +1 -1
  121. package/dist/lib/execution/runners/devcontainer.js +4 -1
  122. package/dist/lib/execution/runners/devcontainer.js.map +1 -1
  123. package/dist/lib/execution/runners/docker-management.js +10 -46
  124. package/dist/lib/execution/runners/docker-management.js.map +1 -1
  125. package/dist/lib/execution/runners/orchestrator.js +13 -39
  126. package/dist/lib/execution/runners/orchestrator.js.map +1 -1
  127. package/dist/lib/execution/session-utils.d.ts +88 -1
  128. package/dist/lib/execution/session-utils.js +120 -46
  129. package/dist/lib/execution/session-utils.js.map +1 -1
  130. package/dist/lib/execution/storage.js +20 -2
  131. package/dist/lib/execution/storage.js.map +1 -1
  132. package/dist/lib/flags/resolver.d.ts +8 -1
  133. package/dist/lib/flags/resolver.js +35 -2
  134. package/dist/lib/flags/resolver.js.map +1 -1
  135. package/dist/lib/gc/cascade.d.ts +99 -0
  136. package/dist/lib/gc/cascade.js +357 -0
  137. package/dist/lib/gc/cascade.js.map +1 -0
  138. package/dist/lib/gc/config.d.ts +69 -0
  139. package/dist/lib/gc/config.js +134 -0
  140. package/dist/lib/gc/config.js.map +1 -0
  141. package/dist/lib/gc/index.d.ts +36 -0
  142. package/dist/lib/gc/index.js +209 -1
  143. package/dist/lib/gc/index.js.map +1 -1
  144. package/dist/lib/init/index.js +10 -1
  145. package/dist/lib/init/index.js.map +1 -1
  146. package/dist/lib/machine-db.d.ts +144 -0
  147. package/dist/lib/machine-db.js +338 -0
  148. package/dist/lib/machine-db.js.map +1 -0
  149. package/dist/lib/machine-orchestrator.d.ts +35 -0
  150. package/dist/lib/machine-orchestrator.js +139 -0
  151. package/dist/lib/machine-orchestrator.js.map +1 -0
  152. package/dist/lib/notifications/dispatcher.d.ts +29 -0
  153. package/dist/lib/notifications/dispatcher.js +281 -0
  154. package/dist/lib/notifications/dispatcher.js.map +1 -0
  155. package/dist/lib/notifications/index.d.ts +13 -0
  156. package/dist/lib/notifications/index.js +18 -0
  157. package/dist/lib/notifications/index.js.map +1 -0
  158. package/dist/lib/notifications/manager.d.ts +46 -0
  159. package/dist/lib/notifications/manager.js +200 -0
  160. package/dist/lib/notifications/manager.js.map +1 -0
  161. package/dist/lib/notifications/storage.d.ts +60 -0
  162. package/dist/lib/notifications/storage.js +182 -0
  163. package/dist/lib/notifications/storage.js.map +1 -0
  164. package/dist/lib/notifications/types.d.ts +126 -0
  165. package/dist/lib/notifications/types.js +16 -0
  166. package/dist/lib/notifications/types.js.map +1 -0
  167. package/dist/lib/orchestrate/actions.js +182 -3
  168. package/dist/lib/orchestrate/actions.js.map +1 -1
  169. package/dist/lib/orchestrate/config-loader.js +9 -35
  170. package/dist/lib/orchestrate/config-loader.js.map +1 -1
  171. package/dist/lib/orchestrate/engine.d.ts +53 -1
  172. package/dist/lib/orchestrate/engine.js +74 -3
  173. package/dist/lib/orchestrate/engine.js.map +1 -1
  174. package/dist/lib/orchestrate/escalation.d.ts +87 -0
  175. package/dist/lib/orchestrate/escalation.js +63 -0
  176. package/dist/lib/orchestrate/escalation.js.map +1 -0
  177. package/dist/lib/orchestrate/index.d.ts +2 -0
  178. package/dist/lib/orchestrate/index.js +1 -0
  179. package/dist/lib/orchestrate/index.js.map +1 -1
  180. package/dist/lib/orchestrate/llm-agent.d.ts +101 -0
  181. package/dist/lib/orchestrate/llm-agent.js +295 -0
  182. package/dist/lib/orchestrate/llm-agent.js.map +1 -0
  183. package/dist/lib/orchestrate/presets.d.ts +4 -3
  184. package/dist/lib/orchestrate/presets.js +13 -8
  185. package/dist/lib/orchestrate/presets.js.map +1 -1
  186. package/dist/lib/orchestrate/types.d.ts +7 -1
  187. package/dist/lib/orchestrate/types.js +1 -0
  188. package/dist/lib/orchestrate/types.js.map +1 -1
  189. package/dist/lib/pmo/base-command.js +1 -1
  190. package/dist/lib/pmo/base-command.js.map +1 -1
  191. package/dist/lib/pmo/find-pmo.d.ts +8 -0
  192. package/dist/lib/pmo/find-pmo.js +63 -2
  193. package/dist/lib/pmo/find-pmo.js.map +1 -1
  194. package/dist/lib/pmo/index.d.ts +1 -1
  195. package/dist/lib/pmo/index.js +1 -1
  196. package/dist/lib/pmo/index.js.map +1 -1
  197. package/dist/lib/pmo/pmo-context.js +1 -1
  198. package/dist/lib/pmo/pmo-context.js.map +1 -1
  199. package/dist/lib/pmo/storage/index.js +2 -1
  200. package/dist/lib/pmo/storage/index.js.map +1 -1
  201. package/dist/lib/pr/index.d.ts +32 -0
  202. package/dist/lib/pr/index.js +45 -0
  203. package/dist/lib/pr/index.js.map +1 -1
  204. package/dist/lib/registry/index.js +0 -1
  205. package/dist/lib/registry/index.js.map +1 -1
  206. package/dist/lib/signal-handler.d.ts +8 -0
  207. package/dist/lib/signal-handler.js +33 -0
  208. package/dist/lib/signal-handler.js.map +1 -1
  209. package/dist/lib/themes.js +8 -1
  210. package/dist/lib/themes.js.map +1 -1
  211. package/dist/lib/work-lifecycle/container-cleanup-hook.d.ts +17 -7
  212. package/dist/lib/work-lifecycle/container-cleanup-hook.js +64 -11
  213. package/dist/lib/work-lifecycle/container-cleanup-hook.js.map +1 -1
  214. package/dist/lib/work-lifecycle/hooks/executor.d.ts +22 -2
  215. package/dist/lib/work-lifecycle/hooks/executor.js +46 -8
  216. package/dist/lib/work-lifecycle/hooks/executor.js.map +1 -1
  217. package/dist/lib/work-lifecycle/hooks/manager.d.ts +62 -3
  218. package/dist/lib/work-lifecycle/hooks/manager.js +285 -4
  219. package/dist/lib/work-lifecycle/hooks/manager.js.map +1 -1
  220. package/dist/lib/work-lifecycle/hooks/types.d.ts +36 -5
  221. package/dist/lib/work-lifecycle/hooks/types.js +1 -1
  222. package/dist/lib/work-lifecycle/hooks/types.js.map +1 -1
  223. package/dist/lib/workspace-resolution.d.ts +73 -0
  224. package/dist/lib/workspace-resolution.js +188 -0
  225. package/dist/lib/workspace-resolution.js.map +1 -0
  226. package/oclif.manifest.json +1309 -621
  227. package/package.json +1 -1
@@ -112,6 +112,46 @@ function mergeAllowlists(actionDomains, flagValue) {
112
112
  function isIssueSource(value) {
113
113
  return value === 'linear' || value === 'jira' || value === 'asana' || value === 'shortcut' || value === 'trello';
114
114
  }
115
+ /**
116
+ * Extract explicitly-set flags for JSON mode command chaining.
117
+ * Filters out defaults (false/undefined) and the json flag itself.
118
+ * Used as accumulatedFlags so buildCommand includes prior resolver results.
119
+ */
120
+ function getAccumulatedFlags(flags) {
121
+ const result = {};
122
+ for (const [key, val] of Object.entries(flags)) {
123
+ if (key === 'json' || val === undefined || val === false)
124
+ continue;
125
+ result[key] = val;
126
+ }
127
+ return result;
128
+ }
129
+ /**
130
+ * Build a base command string with all explicitly-set flags for JSON mode chaining.
131
+ * Used by getCommand callbacks to include accumulated flags from prior prompts.
132
+ */
133
+ function buildJsonBase(ticketId, flags) {
134
+ let cmd = `prlt work start ${ticketId}`;
135
+ for (const [key, val] of Object.entries(flags)) {
136
+ if (key === 'json' || val === undefined || val === false)
137
+ continue;
138
+ if (typeof val === 'boolean') {
139
+ cmd += ` --${key}`;
140
+ }
141
+ else if (typeof val === 'string') {
142
+ cmd += ` --${key} "${val}"`;
143
+ }
144
+ else if (Array.isArray(val)) {
145
+ for (const item of val) {
146
+ cmd += ` --${key} "${item}"`;
147
+ }
148
+ }
149
+ else {
150
+ cmd += ` --${key} ${val}`;
151
+ }
152
+ }
153
+ return cmd;
154
+ }
115
155
  function buildExternalMetadata(envelope) {
116
156
  switch (envelope.source.name) {
117
157
  case 'jira': return buildJiraMetadata(envelope);
@@ -329,6 +369,10 @@ export default class WorkStart extends PMOCommand {
329
369
  description: 'Validate environment and prerequisites without actually spawning an agent',
330
370
  default: false,
331
371
  }),
372
+ environment: Flags.string({
373
+ description: 'Execution environment (devcontainer or host). Use to bypass the environment selection prompt.',
374
+ options: ['devcontainer', 'host'],
375
+ }),
332
376
  };
333
377
  async findLinkedTicketByEnvelope(_projectId, envelope) {
334
378
  // Ticket lives in the provider (Linear, etc.) — look it up directly, no local PMO scan
@@ -471,6 +515,10 @@ export default class WorkStart extends PMOCommand {
471
515
  if (flags['skip-permissions']) {
472
516
  flags['permission-mode'] = 'danger';
473
517
  }
518
+ // Handle --environment flag: normalize to --run-on-host for host mode
519
+ if (flags.environment === 'host') {
520
+ flags['run-on-host'] = true;
521
+ }
474
522
  // Check if JSON output mode is active
475
523
  const jsonMode = shouldOutputJson(flags);
476
524
  const jsonModeConfig = jsonMode ? { flags: flags, commandName: 'work start' } : null;
@@ -614,6 +662,7 @@ export default class WorkStart extends PMOCommand {
614
662
  await autoExportToBoard(this.pmoPath, this.storage);
615
663
  }
616
664
  else if (existingLinkedTicket) {
665
+ envelopeTicket = existingLinkedTicket;
617
666
  // Existing PMO ticket found — use it (backward compat)
618
667
  linkedTicket = existingLinkedTicket;
619
668
  }
@@ -842,7 +891,9 @@ export default class WorkStart extends PMOCommand {
842
891
  baseCommand: `prlt work start ${ticketId}`,
843
892
  jsonMode,
844
893
  flags: {},
894
+ accumulatedFlags: getAccumulatedFlags(flags),
845
895
  });
896
+ const jsonBaseBlocked = buildJsonBase(ticketId, flags);
846
897
  blockedResolver.addPrompt({
847
898
  flagName: 'startAnyway',
848
899
  type: 'list',
@@ -852,6 +903,11 @@ export default class WorkStart extends PMOCommand {
852
903
  { name: 'No, cancel', value: 'no' },
853
904
  { name: 'Yes, start despite blockers', value: 'yes' },
854
905
  ],
906
+ getCommand: (value) => {
907
+ if (value === 'yes')
908
+ return `${jsonBaseBlocked} --force --json`;
909
+ return '';
910
+ },
855
911
  });
856
912
  const blockedResult = await blockedResolver.resolve();
857
913
  if (blockedResult.startAnyway !== 'yes') {
@@ -872,10 +928,11 @@ export default class WorkStart extends PMOCommand {
872
928
  commandName: 'work start',
873
929
  baseCommand: `prlt work start ${ticketId}`,
874
930
  jsonMode,
875
- flags: flags['session-action'] ? { sessionAction: flags['session-action'] } : {},
931
+ flags: flags['session-action'] ? { 'session-action': flags['session-action'] } : {},
932
+ accumulatedFlags: getAccumulatedFlags(flags),
876
933
  });
877
934
  sessionResolver.addPrompt({
878
- flagName: 'sessionAction',
935
+ flagName: 'session-action',
879
936
  type: 'list',
880
937
  message: 'What would you like to do?',
881
938
  choices: () => [
@@ -886,7 +943,7 @@ export default class WorkStart extends PMOCommand {
886
943
  ],
887
944
  });
888
945
  const sessionResult = await sessionResolver.resolve();
889
- const sessionAction = sessionResult.sessionAction;
946
+ const sessionAction = sessionResult['session-action'];
890
947
  if (sessionAction === 'cancel') {
891
948
  db.close();
892
949
  this.log(styles.muted('Cancelled.'));
@@ -1032,11 +1089,13 @@ export default class WorkStart extends PMOCommand {
1032
1089
  agentChoiceList.push({ name: `${a.name} (working on ${ticketIds})`, value: a.name, disabled: true });
1033
1090
  }
1034
1091
  // Use FlagResolver for agent selection
1092
+ const jsonBaseAgent = buildJsonBase(ticketId, flags);
1035
1093
  const agentResolver = new FlagResolver({
1036
1094
  commandName: 'work start',
1037
1095
  baseCommand: `prlt work start ${ticketId}`,
1038
1096
  jsonMode,
1039
1097
  flags: {},
1098
+ accumulatedFlags: getAccumulatedFlags(flags),
1040
1099
  });
1041
1100
  agentResolver.addPrompt({
1042
1101
  flagName: 'selectedAgent',
@@ -1044,6 +1103,11 @@ export default class WorkStart extends PMOCommand {
1044
1103
  message: `Select agent for ${ticketId}:`,
1045
1104
  default: '__ephemeral__',
1046
1105
  choices: () => agentChoiceList,
1106
+ getCommand: (value) => {
1107
+ if (value === '__ephemeral__')
1108
+ return `${jsonBaseAgent} --ephemeral --json`;
1109
+ return `${jsonBaseAgent} --agent "${value}" --json`;
1110
+ },
1047
1111
  });
1048
1112
  const agentResult = await agentResolver.resolve();
1049
1113
  const selectedAgent = agentResult.selectedAgent;
@@ -1150,11 +1214,13 @@ export default class WorkStart extends PMOCommand {
1150
1214
  this.log('');
1151
1215
  }
1152
1216
  // Use FlagResolver for unsaved work action
1217
+ const jsonBaseUnsaved = buildJsonBase(ticketId, flags);
1153
1218
  const unsavedResolver = new FlagResolver({
1154
1219
  commandName: 'work start',
1155
1220
  baseCommand: `prlt work start ${ticketId}`,
1156
1221
  jsonMode,
1157
1222
  flags: {},
1223
+ accumulatedFlags: getAccumulatedFlags(flags),
1158
1224
  });
1159
1225
  unsavedResolver.addPrompt({
1160
1226
  flagName: 'unsavedAction',
@@ -1165,6 +1231,12 @@ export default class WorkStart extends PMOCommand {
1165
1231
  { name: 'Continue anyway (existing work may conflict)', value: 'continue' },
1166
1232
  { name: 'Cancel', value: 'cancel' },
1167
1233
  ],
1234
+ getCommand: (value) => {
1235
+ if (value === 'cancel')
1236
+ return '';
1237
+ // Both 'push' and 'continue' advance; use --force to skip re-prompt
1238
+ return `${jsonBaseUnsaved} --force --json`;
1239
+ },
1168
1240
  });
1169
1241
  const unsavedResult = await unsavedResolver.resolve();
1170
1242
  const action = unsavedResult.unsavedAction;
@@ -1261,12 +1333,13 @@ export default class WorkStart extends PMOCommand {
1261
1333
  // Check if agent has devcontainer config
1262
1334
  const hasDevcontainer = hasDevcontainerConfig(agentDir);
1263
1335
  // Use devcontainer by default if available, unless --run-on-host is set
1264
- const useDevcontainer = hasDevcontainer && !flags['run-on-host'];
1336
+ // --environment devcontainer explicitly requests devcontainer mode
1337
+ const useDevcontainer = (hasDevcontainer && !flags['run-on-host']) || flags.environment === 'devcontainer';
1265
1338
  // Determine execution environment and display mode
1266
1339
  let environment = 'host';
1267
1340
  let displayMode = 'terminal';
1268
1341
  let permissionMode = 'danger';
1269
- if (hasDevcontainer && !flags.display && !flags['run-on-host']) {
1342
+ if (hasDevcontainer && !flags.display && !flags['run-on-host'] && !flags.environment) {
1270
1343
  // Agent has devcontainer - prompt for environment choice
1271
1344
  const devcontainerLabel = '🐳 devcontainer (isolated, recommended)';
1272
1345
  const envChoices = [
@@ -1276,11 +1349,13 @@ export default class WorkStart extends PMOCommand {
1276
1349
  ];
1277
1350
  // In JSON mode, use FlagResolver (outputs prompt and exits)
1278
1351
  if (jsonMode) {
1352
+ const jsonBaseEnv = buildJsonBase(ticketId, flags);
1279
1353
  const envResolver = new FlagResolver({
1280
1354
  commandName: 'work start',
1281
1355
  baseCommand: `prlt work start ${ticketId}`,
1282
1356
  jsonMode,
1283
1357
  flags: {},
1358
+ accumulatedFlags: getAccumulatedFlags(flags),
1284
1359
  });
1285
1360
  envResolver.addPrompt({
1286
1361
  flagName: 'environment',
@@ -1289,13 +1364,12 @@ export default class WorkStart extends PMOCommand {
1289
1364
  default: 'devcontainer',
1290
1365
  choices: () => envChoices,
1291
1366
  getCommand: (value) => {
1292
- const base = `prlt work start ${ticketId}`;
1293
1367
  if (value === 'host')
1294
- return `${base} --run-on-host --json`;
1368
+ return `${jsonBaseEnv} --run-on-host --json`;
1295
1369
  if (value === 'cancel')
1296
1370
  return '';
1297
- // devcontainer is the default when available
1298
- return `${base} --json`;
1371
+ // Explicit --environment devcontainer so the command advances past this prompt
1372
+ return `${jsonBaseEnv} --environment devcontainer --json`;
1299
1373
  },
1300
1374
  });
1301
1375
  await envResolver.resolve();
@@ -1342,11 +1416,13 @@ export default class WorkStart extends PMOCommand {
1342
1416
  if (!isGitHubTokenAvailable()) {
1343
1417
  const tokenMessage = 'GitHub token not found. Git push may fail. Continue without token?';
1344
1418
  // Use FlagResolver for token action prompt
1419
+ const jsonBaseToken = buildJsonBase(ticketId, flags);
1345
1420
  const tokenResolver = new FlagResolver({
1346
1421
  commandName: 'work start',
1347
1422
  baseCommand: `prlt work start ${ticketId}`,
1348
1423
  jsonMode,
1349
1424
  flags: {},
1425
+ accumulatedFlags: getAccumulatedFlags(flags),
1350
1426
  });
1351
1427
  tokenResolver.addPrompt({
1352
1428
  flagName: 'tokenAction',
@@ -1358,6 +1434,14 @@ export default class WorkStart extends PMOCommand {
1358
1434
  { name: 'No, let me run gh auth login first', value: 'cancel' },
1359
1435
  { name: 'Switch to host mode instead', value: 'host' },
1360
1436
  ],
1437
+ getCommand: (value) => {
1438
+ if (value === 'cancel')
1439
+ return '';
1440
+ if (value === 'host')
1441
+ return `${jsonBaseToken} --run-on-host --json`;
1442
+ // 'continue' — re-run with environment devcontainer explicit
1443
+ return `${jsonBaseToken} --environment devcontainer --json`;
1444
+ },
1361
1445
  });
1362
1446
  // In JSON mode, this will output prompt and exit
1363
1447
  // In interactive mode, show warning first then prompt
@@ -1468,9 +1552,10 @@ export default class WorkStart extends PMOCommand {
1468
1552
  baseCommand: `prlt work start ${ticketId}`,
1469
1553
  jsonMode,
1470
1554
  flags: {},
1555
+ accumulatedFlags: getAccumulatedFlags(flags),
1471
1556
  });
1472
1557
  displayResolver.addPrompt({
1473
- flagName: 'selectedMode',
1558
+ flagName: 'display',
1474
1559
  type: 'list',
1475
1560
  message: warningMsg,
1476
1561
  default: 'terminal',
@@ -1481,7 +1566,7 @@ export default class WorkStart extends PMOCommand {
1481
1566
  ],
1482
1567
  });
1483
1568
  const displayResult = await displayResolver.resolve();
1484
- displayMode = displayResult.selectedMode;
1569
+ displayMode = displayResult.display;
1485
1570
  }
1486
1571
  }
1487
1572
  const executor = flags.executor || DEFAULT_EXECUTION_CONFIG.defaultExecutor;
@@ -1512,17 +1597,24 @@ export default class WorkStart extends PMOCommand {
1512
1597
  { name: '✗ Cancel', value: 'cancel' },
1513
1598
  ];
1514
1599
  const dockerMessage = 'Docker is not running. What would you like to do?';
1600
+ const jsonBaseDocker = buildJsonBase(ticketId, flags);
1515
1601
  const dockerResolver = new FlagResolver({
1516
1602
  commandName: 'work start',
1517
1603
  baseCommand: `prlt work start ${ticketId}`,
1518
1604
  jsonMode,
1519
1605
  flags: {},
1606
+ accumulatedFlags: getAccumulatedFlags(flags),
1520
1607
  });
1521
1608
  dockerResolver.addPrompt({
1522
1609
  flagName: 'dockerAction',
1523
1610
  type: 'list',
1524
1611
  message: dockerMessage,
1525
1612
  choices: () => dockerChoices,
1613
+ getCommand: (value) => {
1614
+ if (value === 'host')
1615
+ return `${jsonBaseDocker} --run-on-host --json`;
1616
+ return '';
1617
+ },
1526
1618
  });
1527
1619
  const dockerResult = await dockerResolver.resolve();
1528
1620
  const dockerAction = dockerResult.dockerAction;
@@ -1600,17 +1692,29 @@ export default class WorkStart extends PMOCommand {
1600
1692
  }
1601
1693
  authChoices.push({ name: '💻 Switch to host environment instead', value: 'host' }, { name: '✗ Cancel', value: 'cancel' });
1602
1694
  // Use FlagResolver for auth method selection
1695
+ const jsonBaseAuth = buildJsonBase(ticketId, flags);
1603
1696
  const authResolver = new FlagResolver({
1604
1697
  commandName: 'work start',
1605
1698
  baseCommand: `prlt work start ${ticketId}`,
1606
1699
  jsonMode,
1607
1700
  flags: {},
1701
+ accumulatedFlags: getAccumulatedFlags(flags),
1608
1702
  });
1609
1703
  authResolver.addPrompt({
1610
1704
  flagName: 'authAction',
1611
1705
  type: 'list',
1612
1706
  message: 'How should the agent authenticate with Claude?',
1613
1707
  choices: () => authChoices,
1708
+ getCommand: (value) => {
1709
+ if (value === 'apikey')
1710
+ return `${jsonBaseAuth} --use-api-key --json`;
1711
+ if (value === 'host')
1712
+ return `${jsonBaseAuth} --run-on-host --json`;
1713
+ if (value === 'cancel')
1714
+ return '';
1715
+ // oauth — re-run with environment devcontainer (requires interactive auth flow)
1716
+ return `${jsonBaseAuth} --environment devcontainer --json`;
1717
+ },
1614
1718
  });
1615
1719
  const authResult = await authResolver.resolve();
1616
1720
  const authAction = authResult.authAction;
@@ -1694,6 +1798,7 @@ export default class WorkStart extends PMOCommand {
1694
1798
  baseCommand: `prlt work start ${ticketId}`,
1695
1799
  jsonMode,
1696
1800
  flags: {},
1801
+ accumulatedFlags: getAccumulatedFlags(flags),
1697
1802
  });
1698
1803
  saveResolver.addPrompt({
1699
1804
  flagName: 'saveDefault',
@@ -1742,6 +1847,7 @@ export default class WorkStart extends PMOCommand {
1742
1847
  baseCommand: `prlt work start ${ticketId}`,
1743
1848
  jsonMode,
1744
1849
  flags: { 'permission-mode': flags['permission-mode'] },
1850
+ accumulatedFlags: getAccumulatedFlags(flags),
1745
1851
  });
1746
1852
  const executorName = getExecutorDisplayName(executor);
1747
1853
  permissionResolver.addPrompt({
@@ -1790,11 +1896,13 @@ export default class WorkStart extends PMOCommand {
1790
1896
  }
1791
1897
  else {
1792
1898
  // Use FlagResolver for PR choice
1899
+ const jsonBasePr = buildJsonBase(ticketId, flags);
1793
1900
  const prResolver = new FlagResolver({
1794
1901
  commandName: 'work start',
1795
1902
  baseCommand: `prlt work start ${ticketId}`,
1796
1903
  jsonMode,
1797
1904
  flags: {},
1905
+ accumulatedFlags: getAccumulatedFlags(flags),
1798
1906
  });
1799
1907
  prResolver.addPrompt({
1800
1908
  flagName: 'prChoice',
@@ -1805,6 +1913,11 @@ export default class WorkStart extends PMOCommand {
1805
1913
  { name: '✓ Yes - Create PR when running `prlt work ready`', value: 'yes' },
1806
1914
  { name: '✗ No - Just move ticket to review (can create PR later)', value: 'no' },
1807
1915
  ],
1916
+ getCommand: (value) => {
1917
+ if (value === 'yes')
1918
+ return `${jsonBasePr} --create-pr --json`;
1919
+ return `${jsonBasePr} --json`;
1920
+ },
1808
1921
  });
1809
1922
  const prResult = await prResolver.resolve();
1810
1923
  createPR = prResult.prChoice === 'yes';
@@ -1917,8 +2030,9 @@ export default class WorkStart extends PMOCommand {
1917
2030
  // Ticket already has a branch linked - just use it
1918
2031
  this.log(styles.muted(`Using existing branch: ${branch}`));
1919
2032
  }
1920
- else if (flags.action || flags.force) {
1921
- // Non-interactive mode (spawned from batch command) - auto-create branch
2033
+ else if (flags.action || flags.force || jsonMode) {
2034
+ // Non-interactive / JSON mode - auto-create branch
2035
+ // JSON mode agents can't interactively enter branch names
1922
2036
  finalBranch = branch;
1923
2037
  this.log(styles.muted(`Branch: ${finalBranch}`));
1924
2038
  }