@proletariat/cli 0.3.105 → 0.3.110

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 (240) 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 +126 -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.d.ts +8 -0
  168. package/dist/lib/orchestrate/actions.js +339 -88
  169. package/dist/lib/orchestrate/actions.js.map +1 -1
  170. package/dist/lib/orchestrate/config-loader.js +9 -35
  171. package/dist/lib/orchestrate/config-loader.js.map +1 -1
  172. package/dist/lib/orchestrate/engine.d.ts +53 -1
  173. package/dist/lib/orchestrate/engine.js +74 -3
  174. package/dist/lib/orchestrate/engine.js.map +1 -1
  175. package/dist/lib/orchestrate/escalation.d.ts +87 -0
  176. package/dist/lib/orchestrate/escalation.js +63 -0
  177. package/dist/lib/orchestrate/escalation.js.map +1 -0
  178. package/dist/lib/orchestrate/index.d.ts +2 -0
  179. package/dist/lib/orchestrate/index.js +1 -0
  180. package/dist/lib/orchestrate/index.js.map +1 -1
  181. package/dist/lib/orchestrate/llm-agent.d.ts +101 -0
  182. package/dist/lib/orchestrate/llm-agent.js +295 -0
  183. package/dist/lib/orchestrate/llm-agent.js.map +1 -0
  184. package/dist/lib/orchestrate/presets.d.ts +4 -3
  185. package/dist/lib/orchestrate/presets.js +13 -8
  186. package/dist/lib/orchestrate/presets.js.map +1 -1
  187. package/dist/lib/orchestrate/prompt-chain.d.ts +166 -0
  188. package/dist/lib/orchestrate/prompt-chain.js +308 -0
  189. package/dist/lib/orchestrate/prompt-chain.js.map +1 -0
  190. package/dist/lib/orchestrate/types.d.ts +7 -1
  191. package/dist/lib/orchestrate/types.js +1 -0
  192. package/dist/lib/orchestrate/types.js.map +1 -1
  193. package/dist/lib/pmo/base-command.js +1 -1
  194. package/dist/lib/pmo/base-command.js.map +1 -1
  195. package/dist/lib/pmo/find-pmo.d.ts +8 -0
  196. package/dist/lib/pmo/find-pmo.js +63 -2
  197. package/dist/lib/pmo/find-pmo.js.map +1 -1
  198. package/dist/lib/pmo/index.d.ts +1 -1
  199. package/dist/lib/pmo/index.js +1 -1
  200. package/dist/lib/pmo/index.js.map +1 -1
  201. package/dist/lib/pmo/pmo-context.js +1 -1
  202. package/dist/lib/pmo/pmo-context.js.map +1 -1
  203. package/dist/lib/pmo/storage/index.js +2 -1
  204. package/dist/lib/pmo/storage/index.js.map +1 -1
  205. package/dist/lib/pr/index.d.ts +32 -0
  206. package/dist/lib/pr/index.js +45 -0
  207. package/dist/lib/pr/index.js.map +1 -1
  208. package/dist/lib/prompt-command.d.ts +61 -1
  209. package/dist/lib/prompt-command.js +167 -1
  210. package/dist/lib/prompt-command.js.map +1 -1
  211. package/dist/lib/prompt-json.d.ts +129 -2
  212. package/dist/lib/prompt-json.js +157 -0
  213. package/dist/lib/prompt-json.js.map +1 -1
  214. package/dist/lib/registry/index.js +0 -1
  215. package/dist/lib/registry/index.js.map +1 -1
  216. package/dist/lib/runtime-command.d.ts +3 -1
  217. package/dist/lib/runtime-command.js +4 -2
  218. package/dist/lib/runtime-command.js.map +1 -1
  219. package/dist/lib/signal-handler.d.ts +8 -0
  220. package/dist/lib/signal-handler.js +33 -0
  221. package/dist/lib/signal-handler.js.map +1 -1
  222. package/dist/lib/themes.js +8 -1
  223. package/dist/lib/themes.js.map +1 -1
  224. package/dist/lib/work-lifecycle/container-cleanup-hook.d.ts +17 -7
  225. package/dist/lib/work-lifecycle/container-cleanup-hook.js +64 -11
  226. package/dist/lib/work-lifecycle/container-cleanup-hook.js.map +1 -1
  227. package/dist/lib/work-lifecycle/hooks/executor.d.ts +22 -2
  228. package/dist/lib/work-lifecycle/hooks/executor.js +46 -8
  229. package/dist/lib/work-lifecycle/hooks/executor.js.map +1 -1
  230. package/dist/lib/work-lifecycle/hooks/manager.d.ts +62 -3
  231. package/dist/lib/work-lifecycle/hooks/manager.js +285 -4
  232. package/dist/lib/work-lifecycle/hooks/manager.js.map +1 -1
  233. package/dist/lib/work-lifecycle/hooks/types.d.ts +36 -5
  234. package/dist/lib/work-lifecycle/hooks/types.js +1 -1
  235. package/dist/lib/work-lifecycle/hooks/types.js.map +1 -1
  236. package/dist/lib/workspace-resolution.d.ts +73 -0
  237. package/dist/lib/workspace-resolution.js +188 -0
  238. package/dist/lib/workspace-resolution.js.map +1 -0
  239. package/oclif.manifest.json +1787 -1099
  240. 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;
@@ -843,7 +891,9 @@ export default class WorkStart extends PMOCommand {
843
891
  baseCommand: `prlt work start ${ticketId}`,
844
892
  jsonMode,
845
893
  flags: {},
894
+ accumulatedFlags: getAccumulatedFlags(flags),
846
895
  });
896
+ const jsonBaseBlocked = buildJsonBase(ticketId, flags);
847
897
  blockedResolver.addPrompt({
848
898
  flagName: 'startAnyway',
849
899
  type: 'list',
@@ -853,6 +903,11 @@ export default class WorkStart extends PMOCommand {
853
903
  { name: 'No, cancel', value: 'no' },
854
904
  { name: 'Yes, start despite blockers', value: 'yes' },
855
905
  ],
906
+ getCommand: (value) => {
907
+ if (value === 'yes')
908
+ return `${jsonBaseBlocked} --force --json`;
909
+ return '';
910
+ },
856
911
  });
857
912
  const blockedResult = await blockedResolver.resolve();
858
913
  if (blockedResult.startAnyway !== 'yes') {
@@ -873,10 +928,11 @@ export default class WorkStart extends PMOCommand {
873
928
  commandName: 'work start',
874
929
  baseCommand: `prlt work start ${ticketId}`,
875
930
  jsonMode,
876
- flags: flags['session-action'] ? { sessionAction: flags['session-action'] } : {},
931
+ flags: flags['session-action'] ? { 'session-action': flags['session-action'] } : {},
932
+ accumulatedFlags: getAccumulatedFlags(flags),
877
933
  });
878
934
  sessionResolver.addPrompt({
879
- flagName: 'sessionAction',
935
+ flagName: 'session-action',
880
936
  type: 'list',
881
937
  message: 'What would you like to do?',
882
938
  choices: () => [
@@ -887,7 +943,7 @@ export default class WorkStart extends PMOCommand {
887
943
  ],
888
944
  });
889
945
  const sessionResult = await sessionResolver.resolve();
890
- const sessionAction = sessionResult.sessionAction;
946
+ const sessionAction = sessionResult['session-action'];
891
947
  if (sessionAction === 'cancel') {
892
948
  db.close();
893
949
  this.log(styles.muted('Cancelled.'));
@@ -1033,11 +1089,13 @@ export default class WorkStart extends PMOCommand {
1033
1089
  agentChoiceList.push({ name: `${a.name} (working on ${ticketIds})`, value: a.name, disabled: true });
1034
1090
  }
1035
1091
  // Use FlagResolver for agent selection
1092
+ const jsonBaseAgent = buildJsonBase(ticketId, flags);
1036
1093
  const agentResolver = new FlagResolver({
1037
1094
  commandName: 'work start',
1038
1095
  baseCommand: `prlt work start ${ticketId}`,
1039
1096
  jsonMode,
1040
1097
  flags: {},
1098
+ accumulatedFlags: getAccumulatedFlags(flags),
1041
1099
  });
1042
1100
  agentResolver.addPrompt({
1043
1101
  flagName: 'selectedAgent',
@@ -1045,6 +1103,11 @@ export default class WorkStart extends PMOCommand {
1045
1103
  message: `Select agent for ${ticketId}:`,
1046
1104
  default: '__ephemeral__',
1047
1105
  choices: () => agentChoiceList,
1106
+ getCommand: (value) => {
1107
+ if (value === '__ephemeral__')
1108
+ return `${jsonBaseAgent} --ephemeral --json`;
1109
+ return `${jsonBaseAgent} --agent "${value}" --json`;
1110
+ },
1048
1111
  });
1049
1112
  const agentResult = await agentResolver.resolve();
1050
1113
  const selectedAgent = agentResult.selectedAgent;
@@ -1151,11 +1214,13 @@ export default class WorkStart extends PMOCommand {
1151
1214
  this.log('');
1152
1215
  }
1153
1216
  // Use FlagResolver for unsaved work action
1217
+ const jsonBaseUnsaved = buildJsonBase(ticketId, flags);
1154
1218
  const unsavedResolver = new FlagResolver({
1155
1219
  commandName: 'work start',
1156
1220
  baseCommand: `prlt work start ${ticketId}`,
1157
1221
  jsonMode,
1158
1222
  flags: {},
1223
+ accumulatedFlags: getAccumulatedFlags(flags),
1159
1224
  });
1160
1225
  unsavedResolver.addPrompt({
1161
1226
  flagName: 'unsavedAction',
@@ -1166,6 +1231,12 @@ export default class WorkStart extends PMOCommand {
1166
1231
  { name: 'Continue anyway (existing work may conflict)', value: 'continue' },
1167
1232
  { name: 'Cancel', value: 'cancel' },
1168
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
+ },
1169
1240
  });
1170
1241
  const unsavedResult = await unsavedResolver.resolve();
1171
1242
  const action = unsavedResult.unsavedAction;
@@ -1262,12 +1333,13 @@ export default class WorkStart extends PMOCommand {
1262
1333
  // Check if agent has devcontainer config
1263
1334
  const hasDevcontainer = hasDevcontainerConfig(agentDir);
1264
1335
  // Use devcontainer by default if available, unless --run-on-host is set
1265
- 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';
1266
1338
  // Determine execution environment and display mode
1267
1339
  let environment = 'host';
1268
1340
  let displayMode = 'terminal';
1269
1341
  let permissionMode = 'danger';
1270
- if (hasDevcontainer && !flags.display && !flags['run-on-host']) {
1342
+ if (hasDevcontainer && !flags.display && !flags['run-on-host'] && !flags.environment) {
1271
1343
  // Agent has devcontainer - prompt for environment choice
1272
1344
  const devcontainerLabel = '🐳 devcontainer (isolated, recommended)';
1273
1345
  const envChoices = [
@@ -1277,11 +1349,13 @@ export default class WorkStart extends PMOCommand {
1277
1349
  ];
1278
1350
  // In JSON mode, use FlagResolver (outputs prompt and exits)
1279
1351
  if (jsonMode) {
1352
+ const jsonBaseEnv = buildJsonBase(ticketId, flags);
1280
1353
  const envResolver = new FlagResolver({
1281
1354
  commandName: 'work start',
1282
1355
  baseCommand: `prlt work start ${ticketId}`,
1283
1356
  jsonMode,
1284
1357
  flags: {},
1358
+ accumulatedFlags: getAccumulatedFlags(flags),
1285
1359
  });
1286
1360
  envResolver.addPrompt({
1287
1361
  flagName: 'environment',
@@ -1290,13 +1364,12 @@ export default class WorkStart extends PMOCommand {
1290
1364
  default: 'devcontainer',
1291
1365
  choices: () => envChoices,
1292
1366
  getCommand: (value) => {
1293
- const base = `prlt work start ${ticketId}`;
1294
1367
  if (value === 'host')
1295
- return `${base} --run-on-host --json`;
1368
+ return `${jsonBaseEnv} --run-on-host --json`;
1296
1369
  if (value === 'cancel')
1297
1370
  return '';
1298
- // devcontainer is the default when available
1299
- return `${base} --json`;
1371
+ // Explicit --environment devcontainer so the command advances past this prompt
1372
+ return `${jsonBaseEnv} --environment devcontainer --json`;
1300
1373
  },
1301
1374
  });
1302
1375
  await envResolver.resolve();
@@ -1343,11 +1416,13 @@ export default class WorkStart extends PMOCommand {
1343
1416
  if (!isGitHubTokenAvailable()) {
1344
1417
  const tokenMessage = 'GitHub token not found. Git push may fail. Continue without token?';
1345
1418
  // Use FlagResolver for token action prompt
1419
+ const jsonBaseToken = buildJsonBase(ticketId, flags);
1346
1420
  const tokenResolver = new FlagResolver({
1347
1421
  commandName: 'work start',
1348
1422
  baseCommand: `prlt work start ${ticketId}`,
1349
1423
  jsonMode,
1350
1424
  flags: {},
1425
+ accumulatedFlags: getAccumulatedFlags(flags),
1351
1426
  });
1352
1427
  tokenResolver.addPrompt({
1353
1428
  flagName: 'tokenAction',
@@ -1359,6 +1434,14 @@ export default class WorkStart extends PMOCommand {
1359
1434
  { name: 'No, let me run gh auth login first', value: 'cancel' },
1360
1435
  { name: 'Switch to host mode instead', value: 'host' },
1361
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
+ },
1362
1445
  });
1363
1446
  // In JSON mode, this will output prompt and exit
1364
1447
  // In interactive mode, show warning first then prompt
@@ -1469,9 +1552,10 @@ export default class WorkStart extends PMOCommand {
1469
1552
  baseCommand: `prlt work start ${ticketId}`,
1470
1553
  jsonMode,
1471
1554
  flags: {},
1555
+ accumulatedFlags: getAccumulatedFlags(flags),
1472
1556
  });
1473
1557
  displayResolver.addPrompt({
1474
- flagName: 'selectedMode',
1558
+ flagName: 'display',
1475
1559
  type: 'list',
1476
1560
  message: warningMsg,
1477
1561
  default: 'terminal',
@@ -1482,7 +1566,7 @@ export default class WorkStart extends PMOCommand {
1482
1566
  ],
1483
1567
  });
1484
1568
  const displayResult = await displayResolver.resolve();
1485
- displayMode = displayResult.selectedMode;
1569
+ displayMode = displayResult.display;
1486
1570
  }
1487
1571
  }
1488
1572
  const executor = flags.executor || DEFAULT_EXECUTION_CONFIG.defaultExecutor;
@@ -1513,17 +1597,24 @@ export default class WorkStart extends PMOCommand {
1513
1597
  { name: '✗ Cancel', value: 'cancel' },
1514
1598
  ];
1515
1599
  const dockerMessage = 'Docker is not running. What would you like to do?';
1600
+ const jsonBaseDocker = buildJsonBase(ticketId, flags);
1516
1601
  const dockerResolver = new FlagResolver({
1517
1602
  commandName: 'work start',
1518
1603
  baseCommand: `prlt work start ${ticketId}`,
1519
1604
  jsonMode,
1520
1605
  flags: {},
1606
+ accumulatedFlags: getAccumulatedFlags(flags),
1521
1607
  });
1522
1608
  dockerResolver.addPrompt({
1523
1609
  flagName: 'dockerAction',
1524
1610
  type: 'list',
1525
1611
  message: dockerMessage,
1526
1612
  choices: () => dockerChoices,
1613
+ getCommand: (value) => {
1614
+ if (value === 'host')
1615
+ return `${jsonBaseDocker} --run-on-host --json`;
1616
+ return '';
1617
+ },
1527
1618
  });
1528
1619
  const dockerResult = await dockerResolver.resolve();
1529
1620
  const dockerAction = dockerResult.dockerAction;
@@ -1601,17 +1692,29 @@ export default class WorkStart extends PMOCommand {
1601
1692
  }
1602
1693
  authChoices.push({ name: '💻 Switch to host environment instead', value: 'host' }, { name: '✗ Cancel', value: 'cancel' });
1603
1694
  // Use FlagResolver for auth method selection
1695
+ const jsonBaseAuth = buildJsonBase(ticketId, flags);
1604
1696
  const authResolver = new FlagResolver({
1605
1697
  commandName: 'work start',
1606
1698
  baseCommand: `prlt work start ${ticketId}`,
1607
1699
  jsonMode,
1608
1700
  flags: {},
1701
+ accumulatedFlags: getAccumulatedFlags(flags),
1609
1702
  });
1610
1703
  authResolver.addPrompt({
1611
1704
  flagName: 'authAction',
1612
1705
  type: 'list',
1613
1706
  message: 'How should the agent authenticate with Claude?',
1614
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
+ },
1615
1718
  });
1616
1719
  const authResult = await authResolver.resolve();
1617
1720
  const authAction = authResult.authAction;
@@ -1695,6 +1798,7 @@ export default class WorkStart extends PMOCommand {
1695
1798
  baseCommand: `prlt work start ${ticketId}`,
1696
1799
  jsonMode,
1697
1800
  flags: {},
1801
+ accumulatedFlags: getAccumulatedFlags(flags),
1698
1802
  });
1699
1803
  saveResolver.addPrompt({
1700
1804
  flagName: 'saveDefault',
@@ -1743,6 +1847,7 @@ export default class WorkStart extends PMOCommand {
1743
1847
  baseCommand: `prlt work start ${ticketId}`,
1744
1848
  jsonMode,
1745
1849
  flags: { 'permission-mode': flags['permission-mode'] },
1850
+ accumulatedFlags: getAccumulatedFlags(flags),
1746
1851
  });
1747
1852
  const executorName = getExecutorDisplayName(executor);
1748
1853
  permissionResolver.addPrompt({
@@ -1791,11 +1896,13 @@ export default class WorkStart extends PMOCommand {
1791
1896
  }
1792
1897
  else {
1793
1898
  // Use FlagResolver for PR choice
1899
+ const jsonBasePr = buildJsonBase(ticketId, flags);
1794
1900
  const prResolver = new FlagResolver({
1795
1901
  commandName: 'work start',
1796
1902
  baseCommand: `prlt work start ${ticketId}`,
1797
1903
  jsonMode,
1798
1904
  flags: {},
1905
+ accumulatedFlags: getAccumulatedFlags(flags),
1799
1906
  });
1800
1907
  prResolver.addPrompt({
1801
1908
  flagName: 'prChoice',
@@ -1806,6 +1913,11 @@ export default class WorkStart extends PMOCommand {
1806
1913
  { name: '✓ Yes - Create PR when running `prlt work ready`', value: 'yes' },
1807
1914
  { name: '✗ No - Just move ticket to review (can create PR later)', value: 'no' },
1808
1915
  ],
1916
+ getCommand: (value) => {
1917
+ if (value === 'yes')
1918
+ return `${jsonBasePr} --create-pr --json`;
1919
+ return `${jsonBasePr} --json`;
1920
+ },
1809
1921
  });
1810
1922
  const prResult = await prResolver.resolve();
1811
1923
  createPR = prResult.prChoice === 'yes';
@@ -1918,8 +2030,9 @@ export default class WorkStart extends PMOCommand {
1918
2030
  // Ticket already has a branch linked - just use it
1919
2031
  this.log(styles.muted(`Using existing branch: ${branch}`));
1920
2032
  }
1921
- else if (flags.action || flags.force) {
1922
- // 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
1923
2036
  finalBranch = branch;
1924
2037
  this.log(styles.muted(`Branch: ${finalBranch}`));
1925
2038
  }