@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.
- package/dist/commands/action/create.js +3 -3
- package/dist/commands/action/index.js +2 -2
- package/dist/commands/action/update.js +3 -3
- package/dist/commands/agent/auth.js +1 -1
- package/dist/commands/agent/cleanup.js +6 -6
- package/dist/commands/agent/discover.js +1 -1
- package/dist/commands/agent/remove.js +4 -4
- package/dist/commands/autocomplete/setup.d.ts +2 -2
- package/dist/commands/autocomplete/setup.js +5 -5
- package/dist/commands/branch/create.js +31 -30
- package/dist/commands/category/create.js +4 -5
- package/dist/commands/category/delete.js +2 -3
- package/dist/commands/category/rename.js +2 -3
- package/dist/commands/claude.d.ts +2 -8
- package/dist/commands/claude.js +26 -26
- package/dist/commands/commit.d.ts +2 -8
- package/dist/commands/commit.js +4 -26
- package/dist/commands/config/index.d.ts +2 -10
- package/dist/commands/config/index.js +8 -34
- package/dist/commands/docker/index.d.ts +2 -2
- package/dist/commands/docker/index.js +8 -8
- package/dist/commands/epic/activate.js +9 -17
- package/dist/commands/epic/archive.js +13 -24
- package/dist/commands/epic/create.js +7 -6
- package/dist/commands/epic/delete.js +4 -5
- package/dist/commands/epic/move.js +28 -47
- package/dist/commands/epic/progress.js +10 -14
- package/dist/commands/epic/project.js +42 -59
- package/dist/commands/epic/reorder.js +25 -30
- package/dist/commands/epic/spec.d.ts +1 -0
- package/dist/commands/epic/spec.js +39 -40
- package/dist/commands/epic/ticket.d.ts +2 -0
- package/dist/commands/epic/ticket.js +63 -37
- package/dist/commands/feedback/index.d.ts +10 -0
- package/dist/commands/feedback/index.js +60 -0
- package/dist/commands/feedback/list.d.ts +12 -0
- package/dist/commands/feedback/list.js +126 -0
- package/dist/commands/feedback/submit.d.ts +16 -0
- package/dist/commands/feedback/submit.js +220 -0
- package/dist/commands/feedback/view.d.ts +15 -0
- package/dist/commands/feedback/view.js +109 -0
- package/dist/commands/gh/index.js +4 -0
- package/dist/commands/link/index.js +2 -2
- package/dist/commands/pmo/init.d.ts +2 -2
- package/dist/commands/pmo/init.js +7 -7
- package/dist/commands/project/spec.js +6 -6
- package/dist/commands/repo/create.d.ts +38 -0
- package/dist/commands/repo/create.js +283 -0
- package/dist/commands/repo/index.js +7 -0
- package/dist/commands/roadmap/add-project.js +9 -22
- package/dist/commands/roadmap/create.d.ts +0 -1
- package/dist/commands/roadmap/create.js +46 -40
- package/dist/commands/roadmap/delete.js +10 -24
- package/dist/commands/roadmap/generate.d.ts +1 -0
- package/dist/commands/roadmap/generate.js +21 -22
- package/dist/commands/roadmap/remove-project.js +14 -34
- package/dist/commands/roadmap/reorder.js +19 -26
- package/dist/commands/roadmap/update.js +27 -26
- package/dist/commands/roadmap/view.js +5 -12
- package/dist/commands/session/attach.d.ts +1 -8
- package/dist/commands/session/attach.js +93 -59
- package/dist/commands/session/health.d.ts +29 -0
- package/dist/commands/session/health.js +495 -0
- package/dist/commands/session/index.js +4 -0
- package/dist/commands/session/list.d.ts +0 -8
- package/dist/commands/session/list.js +130 -81
- package/dist/commands/spec/create.js +1 -1
- package/dist/commands/spec/edit.js +64 -35
- package/dist/commands/staff/add.d.ts +2 -2
- package/dist/commands/staff/add.js +15 -14
- package/dist/commands/staff/index.js +2 -2
- package/dist/commands/staff/remove.js +4 -4
- package/dist/commands/status/index.js +6 -7
- package/dist/commands/support/book.d.ts +10 -0
- package/dist/commands/support/book.js +54 -0
- package/dist/commands/support/discord.d.ts +10 -0
- package/dist/commands/support/discord.js +54 -0
- package/dist/commands/support/docs.d.ts +10 -0
- package/dist/commands/support/docs.js +54 -0
- package/dist/commands/support/index.d.ts +19 -0
- package/dist/commands/support/index.js +81 -0
- package/dist/commands/support/issues.d.ts +11 -0
- package/dist/commands/support/issues.js +77 -0
- package/dist/commands/support/logs.d.ts +18 -0
- package/dist/commands/support/logs.js +247 -0
- package/dist/commands/template/apply.js +10 -11
- package/dist/commands/template/create.js +18 -17
- package/dist/commands/template/index.d.ts +2 -2
- package/dist/commands/template/index.js +6 -6
- package/dist/commands/template/save.js +8 -7
- package/dist/commands/template/update.js +6 -7
- package/dist/commands/terminal/title.d.ts +2 -26
- package/dist/commands/terminal/title.js +4 -33
- package/dist/commands/theme/index.d.ts +2 -2
- package/dist/commands/theme/index.js +19 -18
- package/dist/commands/theme/set.d.ts +2 -2
- package/dist/commands/theme/set.js +5 -5
- package/dist/commands/ticket/create.js +52 -26
- package/dist/commands/ticket/delete.js +15 -13
- package/dist/commands/ticket/edit.js +59 -20
- package/dist/commands/ticket/epic.js +12 -10
- package/dist/commands/ticket/move.d.ts +7 -0
- package/dist/commands/ticket/move.js +132 -0
- package/dist/commands/ticket/project.js +11 -9
- package/dist/commands/ticket/reassign.js +23 -19
- package/dist/commands/ticket/spec.js +7 -5
- package/dist/commands/ticket/update.js +55 -53
- package/dist/commands/whoami.js +1 -0
- package/dist/commands/work/ready.js +7 -7
- package/dist/commands/work/revise.js +13 -11
- package/dist/commands/work/spawn.d.ts +1 -0
- package/dist/commands/work/spawn.js +225 -64
- package/dist/commands/work/start.d.ts +1 -0
- package/dist/commands/work/start.js +301 -173
- package/dist/hooks/init.js +4 -0
- package/dist/lib/execution/runners.js +21 -17
- package/dist/lib/execution/session-utils.d.ts +60 -0
- package/dist/lib/execution/session-utils.js +162 -0
- package/dist/lib/execution/spawner.d.ts +2 -0
- package/dist/lib/execution/spawner.js +42 -0
- package/dist/lib/flags/resolver.d.ts +2 -2
- package/dist/lib/flags/resolver.js +15 -0
- package/dist/lib/init/index.js +18 -0
- package/dist/lib/multiline-input.d.ts +63 -0
- package/dist/lib/multiline-input.js +360 -0
- package/dist/lib/pr/index.d.ts +4 -0
- package/dist/lib/pr/index.js +32 -14
- package/dist/lib/prompt-command.d.ts +3 -0
- package/dist/lib/prompt-json.d.ts +77 -6
- package/dist/lib/prompt-json.js +46 -0
- package/dist/lib/repos/git.d.ts +7 -0
- package/dist/lib/repos/git.js +20 -0
- package/oclif.manifest.json +2913 -2246
- package/package.json +1 -1
|
@@ -2,10 +2,9 @@ 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
|
-
import { shouldOutputJson, outputErrorAsJson, createMetadata, } from '../../lib/prompt-json.js';
|
|
7
|
+
import { shouldOutputJson, outputErrorAsJson, createMetadata, outputConfirmationNeededAsJson, outputExecutionResultAsJson, } from '../../lib/prompt-json.js';
|
|
9
8
|
import { FlagResolver } from '../../lib/flags/index.js';
|
|
10
9
|
import { getWorkColumnSetting, findColumnByName } from '../../lib/pmo/utils.js';
|
|
11
10
|
import { styles } from '../../lib/styles.js';
|
|
@@ -76,6 +75,7 @@ export default class WorkStart extends PMOCommand {
|
|
|
76
75
|
'<%= config.bin %> <%= command.id %> TKT-001 --mode terminal',
|
|
77
76
|
'<%= config.bin %> <%= command.id %> # Interactive mode',
|
|
78
77
|
'<%= config.bin %> <%= command.id %> --all # Spawn all backlog tickets',
|
|
78
|
+
'<%= config.bin %> <%= command.id %> TKT-001 --prompt "Add unit tests for the API" # Custom prompt',
|
|
79
79
|
];
|
|
80
80
|
static args = {
|
|
81
81
|
ticketId: Args.string({
|
|
@@ -177,6 +177,11 @@ export default class WorkStart extends PMOCommand {
|
|
|
177
177
|
description: 'Use independent git clone instead of worktree (more isolation, no real-time sync)',
|
|
178
178
|
default: false,
|
|
179
179
|
}),
|
|
180
|
+
yes: Flags.boolean({
|
|
181
|
+
char: 'y',
|
|
182
|
+
description: 'Skip confirmation prompt (for non-TTY/scripted execution)',
|
|
183
|
+
default: false,
|
|
184
|
+
}),
|
|
180
185
|
};
|
|
181
186
|
async execute() {
|
|
182
187
|
const { args, flags } = await this.parse(WorkStart);
|
|
@@ -197,6 +202,7 @@ export default class WorkStart extends PMOCommand {
|
|
|
197
202
|
}
|
|
198
203
|
// Check if JSON output mode is active
|
|
199
204
|
const jsonMode = shouldOutputJson(flags);
|
|
205
|
+
const jsonModeConfig = jsonMode ? { flags: flags, commandName: 'work start' } : null;
|
|
200
206
|
// Helper to handle errors in JSON mode
|
|
201
207
|
const handleError = (code, message) => {
|
|
202
208
|
if (jsonMode) {
|
|
@@ -252,6 +258,68 @@ export default class WorkStart extends PMOCommand {
|
|
|
252
258
|
db.close();
|
|
253
259
|
return handleError('TICKET_NOT_FOUND', `Ticket "${ticketId}" not found.`);
|
|
254
260
|
}
|
|
261
|
+
// In JSON mode with explicit flags, implement two-step confirm-then-execute protocol
|
|
262
|
+
if (jsonMode) {
|
|
263
|
+
// Check if all required flags for non-interactive execution are provided
|
|
264
|
+
const hasAction = !!(flags.action || flags.prompt);
|
|
265
|
+
const hasDisplay = !!(flags.display || flags['run-on-host']);
|
|
266
|
+
const hasPermissions = !!(flags['permission-mode'] || flags['skip-permissions']);
|
|
267
|
+
const hasAgent = !!(flags.ephemeral || flags.agent);
|
|
268
|
+
const allFlagsProvided = hasAction && hasDisplay && hasPermissions && hasAgent;
|
|
269
|
+
if (allFlagsProvided && !flags.yes) {
|
|
270
|
+
// All flags provided but no --yes: return confirmation_needed with plan
|
|
271
|
+
const metadata = createMetadata('work start', flags);
|
|
272
|
+
// Build the confirm command with --yes
|
|
273
|
+
let confirmCmd = `prlt work start ${ticketId}`;
|
|
274
|
+
if (flags.action)
|
|
275
|
+
confirmCmd += ` --action ${flags.action}`;
|
|
276
|
+
if (flags.prompt)
|
|
277
|
+
confirmCmd += ` --prompt "${flags.prompt}"`;
|
|
278
|
+
if (flags.display)
|
|
279
|
+
confirmCmd += ` --display ${flags.display}`;
|
|
280
|
+
if (flags['run-on-host'])
|
|
281
|
+
confirmCmd += ' --run-on-host';
|
|
282
|
+
if (flags['permission-mode'])
|
|
283
|
+
confirmCmd += ` --permission-mode ${flags['permission-mode']}`;
|
|
284
|
+
if (flags['skip-permissions'])
|
|
285
|
+
confirmCmd += ' --skip-permissions';
|
|
286
|
+
if (flags.ephemeral)
|
|
287
|
+
confirmCmd += ' --ephemeral';
|
|
288
|
+
if (flags.agent)
|
|
289
|
+
confirmCmd += ` --agent ${flags.agent}`;
|
|
290
|
+
if (flags.executor)
|
|
291
|
+
confirmCmd += ` --executor ${flags.executor}`;
|
|
292
|
+
if (flags.session)
|
|
293
|
+
confirmCmd += ` --session ${flags.session}`;
|
|
294
|
+
if (flags['create-pr'])
|
|
295
|
+
confirmCmd += ' --create-pr';
|
|
296
|
+
if (flags['no-pr'])
|
|
297
|
+
confirmCmd += ' --no-pr';
|
|
298
|
+
if (flags.clone)
|
|
299
|
+
confirmCmd += ' --clone';
|
|
300
|
+
if (flags.focus)
|
|
301
|
+
confirmCmd += ' --focus';
|
|
302
|
+
if (flags.force)
|
|
303
|
+
confirmCmd += ' --force';
|
|
304
|
+
confirmCmd += ' --yes';
|
|
305
|
+
const plan = {
|
|
306
|
+
ticket: {
|
|
307
|
+
id: ticket.id,
|
|
308
|
+
title: ticket.title,
|
|
309
|
+
status: ticket.statusName,
|
|
310
|
+
},
|
|
311
|
+
action: flags.action || 'custom',
|
|
312
|
+
display: flags.display || (flags['run-on-host'] ? 'host' : 'devcontainer'),
|
|
313
|
+
permissions: (flags['permission-mode'] || (flags['skip-permissions'] ? 'danger' : 'safe')),
|
|
314
|
+
agent: flags.agent || 'ephemeral',
|
|
315
|
+
};
|
|
316
|
+
db.close();
|
|
317
|
+
outputConfirmationNeededAsJson(plan, confirmCmd, `Ready to start work on ${ticketId}. Run with --yes to execute.`, metadata);
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
// If --yes is set with all flags, continue to execution (don't return)
|
|
321
|
+
// If missing flags, continue and let FlagResolver handle prompts
|
|
322
|
+
}
|
|
255
323
|
// Check if ticket is blocked by dependencies
|
|
256
324
|
const isBlocked = await this.storage.isTicketBlocked(ticketId);
|
|
257
325
|
if (isBlocked && !flags.force) {
|
|
@@ -335,15 +403,22 @@ export default class WorkStart extends PMOCommand {
|
|
|
335
403
|
let isEphemeralAgent = flags.ephemeral;
|
|
336
404
|
if (flags.ephemeral) {
|
|
337
405
|
// Create ephemeral agent on-demand
|
|
338
|
-
|
|
406
|
+
if (!jsonMode) {
|
|
407
|
+
this.log(styles.muted('Creating ephemeral agent...'));
|
|
408
|
+
}
|
|
339
409
|
const ephemeralResult = await createEphemeralAgent(workspaceInfo, {
|
|
340
410
|
skipDevcontainer: flags['run-on-host'],
|
|
341
|
-
log: (msg) =>
|
|
411
|
+
log: (msg) => {
|
|
412
|
+
if (!jsonMode)
|
|
413
|
+
this.log(msg);
|
|
414
|
+
},
|
|
342
415
|
mountMode: flags.clone ? 'clone' : 'worktree',
|
|
343
416
|
});
|
|
344
417
|
agentName = ephemeralResult.name;
|
|
345
418
|
agentWorktreePath = ephemeralResult.worktreePath;
|
|
346
|
-
|
|
419
|
+
if (!jsonMode) {
|
|
420
|
+
this.log(styles.success(`Created ephemeral agent: ${agentName}`));
|
|
421
|
+
}
|
|
347
422
|
}
|
|
348
423
|
else if (flags.agent) {
|
|
349
424
|
// Agent specified via flag
|
|
@@ -572,6 +647,11 @@ export default class WorkStart extends PMOCommand {
|
|
|
572
647
|
customPrompt = flags.prompt;
|
|
573
648
|
}
|
|
574
649
|
else if (flags.action) {
|
|
650
|
+
// Handle special "custom" action - requires --prompt flag
|
|
651
|
+
if (flags.action === 'custom') {
|
|
652
|
+
db.close();
|
|
653
|
+
this.error('--action custom requires --prompt flag.\nUsage: prlt work start TKT-001 --action custom --prompt "your custom instructions"');
|
|
654
|
+
}
|
|
575
655
|
// Specific action requested
|
|
576
656
|
selectedAction = await this.storage.getAction(flags.action);
|
|
577
657
|
if (!selectedAction) {
|
|
@@ -731,7 +811,7 @@ export default class WorkStart extends PMOCommand {
|
|
|
731
811
|
let environmentSelected = false;
|
|
732
812
|
while (!environmentSelected) {
|
|
733
813
|
// eslint-disable-next-line no-await-in-loop -- Interactive loop with retry on Docker check
|
|
734
|
-
const { selectedEnvironment } = await
|
|
814
|
+
const { selectedEnvironment } = await this.prompt([
|
|
735
815
|
{
|
|
736
816
|
type: 'list',
|
|
737
817
|
name: 'selectedEnvironment',
|
|
@@ -739,7 +819,7 @@ export default class WorkStart extends PMOCommand {
|
|
|
739
819
|
choices: envChoices,
|
|
740
820
|
default: devcontainerReady ? 'devcontainer' : 'host',
|
|
741
821
|
},
|
|
742
|
-
]);
|
|
822
|
+
], jsonModeConfig);
|
|
743
823
|
if (selectedEnvironment === 'cancel') {
|
|
744
824
|
db.close();
|
|
745
825
|
this.log(styles.muted('Cancelled.'));
|
|
@@ -806,19 +886,19 @@ export default class WorkStart extends PMOCommand {
|
|
|
806
886
|
environment = 'host';
|
|
807
887
|
// Skip to host mode prompts
|
|
808
888
|
// eslint-disable-next-line no-await-in-loop -- Follow-up prompt after user selection
|
|
809
|
-
const { selectedDisplay } = await
|
|
889
|
+
const { selectedDisplay } = await this.prompt([
|
|
810
890
|
{
|
|
811
891
|
type: 'list',
|
|
812
892
|
name: 'selectedDisplay',
|
|
813
893
|
message: 'How should the agent output be displayed?',
|
|
814
894
|
choices: [
|
|
815
|
-
{ name: '🖥️ New tab - Opens in new terminal tab (recommended)', value: 'terminal' },
|
|
816
|
-
{ name: '▶️ Foreground - Run in current terminal (blocking)', value: 'foreground' },
|
|
817
|
-
{ name: '📦 Background - Runs detached, reattach with: prlt session attach', value: 'background' },
|
|
895
|
+
{ name: '🖥️ New tab - Opens in new terminal tab (recommended)', value: 'terminal', command: `prlt work start ${ticketId} --display terminal --run-on-host --json` },
|
|
896
|
+
{ name: '▶️ Foreground - Run in current terminal (blocking)', value: 'foreground', command: `prlt work start ${ticketId} --display foreground --run-on-host --json` },
|
|
897
|
+
{ name: '📦 Background - Runs detached, reattach with: prlt session attach', value: 'background', command: `prlt work start ${ticketId} --display background --run-on-host --json` },
|
|
818
898
|
],
|
|
819
899
|
default: 'terminal',
|
|
820
900
|
},
|
|
821
|
-
]);
|
|
901
|
+
], jsonModeConfig);
|
|
822
902
|
displayMode = selectedDisplay;
|
|
823
903
|
environmentSelected = true;
|
|
824
904
|
continue;
|
|
@@ -828,19 +908,19 @@ export default class WorkStart extends PMOCommand {
|
|
|
828
908
|
environment = 'devcontainer';
|
|
829
909
|
// Pick display mode for devcontainer
|
|
830
910
|
// eslint-disable-next-line no-await-in-loop -- Follow-up prompt after selection
|
|
831
|
-
const { selectedDisplay } = await
|
|
911
|
+
const { selectedDisplay } = await this.prompt([
|
|
832
912
|
{
|
|
833
913
|
type: 'list',
|
|
834
914
|
name: 'selectedDisplay',
|
|
835
915
|
message: 'How should the agent output be displayed?',
|
|
836
916
|
choices: [
|
|
837
|
-
{ name: '🖥️ New tab - Opens in new terminal tab (recommended)', value: 'terminal' },
|
|
838
|
-
{ name: '▶️ Foreground - Run in current terminal (blocking)', value: 'foreground' },
|
|
839
|
-
{ name: '📦 Background - Runs detached, reattach with: prlt session attach', value: 'background' },
|
|
917
|
+
{ name: '🖥️ New tab - Opens in new terminal tab (recommended)', value: 'terminal', command: `prlt work start ${ticketId} --display terminal --json` },
|
|
918
|
+
{ name: '▶️ Foreground - Run in current terminal (blocking)', value: 'foreground', command: `prlt work start ${ticketId} --display foreground --json` },
|
|
919
|
+
{ name: '📦 Background - Runs detached, reattach with: prlt session attach', value: 'background', command: `prlt work start ${ticketId} --display background --json` },
|
|
840
920
|
],
|
|
841
921
|
default: 'terminal',
|
|
842
922
|
},
|
|
843
|
-
]);
|
|
923
|
+
], jsonModeConfig);
|
|
844
924
|
displayMode = selectedDisplay;
|
|
845
925
|
environment = 'devcontainer';
|
|
846
926
|
environmentSelected = true;
|
|
@@ -849,19 +929,19 @@ export default class WorkStart extends PMOCommand {
|
|
|
849
929
|
// User chose host
|
|
850
930
|
environment = 'host';
|
|
851
931
|
// eslint-disable-next-line no-await-in-loop -- Follow-up prompt after selection
|
|
852
|
-
const { selectedDisplay } = await
|
|
932
|
+
const { selectedDisplay } = await this.prompt([
|
|
853
933
|
{
|
|
854
934
|
type: 'list',
|
|
855
935
|
name: 'selectedDisplay',
|
|
856
936
|
message: 'How should the agent output be displayed?',
|
|
857
937
|
choices: [
|
|
858
|
-
{ name: '🖥️ New tab - Opens in new terminal tab (recommended)', value: 'terminal' },
|
|
859
|
-
{ name: '▶️ Foreground - Run in current terminal (blocking)', value: 'foreground' },
|
|
860
|
-
{ name: '📦 Background - Runs detached, reattach with: prlt session attach', value: 'background' },
|
|
938
|
+
{ name: '🖥️ New tab - Opens in new terminal tab (recommended)', value: 'terminal', command: `prlt work start ${ticketId} --display terminal --run-on-host --json` },
|
|
939
|
+
{ name: '▶️ Foreground - Run in current terminal (blocking)', value: 'foreground', command: `prlt work start ${ticketId} --display foreground --run-on-host --json` },
|
|
940
|
+
{ name: '📦 Background - Runs detached, reattach with: prlt session attach', value: 'background', command: `prlt work start ${ticketId} --display background --run-on-host --json` },
|
|
861
941
|
],
|
|
862
942
|
default: 'terminal',
|
|
863
943
|
},
|
|
864
|
-
]);
|
|
944
|
+
], jsonModeConfig);
|
|
865
945
|
displayMode = selectedDisplay;
|
|
866
946
|
environmentSelected = true;
|
|
867
947
|
}
|
|
@@ -918,92 +998,98 @@ export default class WorkStart extends PMOCommand {
|
|
|
918
998
|
if (environment === 'devcontainer') {
|
|
919
999
|
const hasCredentials = dockerCredentialsExist();
|
|
920
1000
|
if (!hasCredentials) {
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
this.log('');
|
|
925
|
-
// Use FlagResolver for auth action
|
|
926
|
-
const authResolver = new FlagResolver({
|
|
927
|
-
commandName: 'work start',
|
|
928
|
-
baseCommand: `prlt work start ${ticketId}`,
|
|
929
|
-
jsonMode,
|
|
930
|
-
flags: {},
|
|
931
|
-
});
|
|
932
|
-
authResolver.addPrompt({
|
|
933
|
-
flagName: 'authAction',
|
|
934
|
-
type: 'list',
|
|
935
|
-
message: 'What would you like to do?',
|
|
936
|
-
choices: () => [
|
|
937
|
-
{ name: `🔐 Run ${this.config.bin} agent auth now (one-time setup)`, value: 'auth' },
|
|
938
|
-
{ name: '💻 Switch to host environment instead', value: 'host' },
|
|
939
|
-
{ name: '⏩ Continue anyway (must run /login in first agent)', value: 'continue' },
|
|
940
|
-
{ name: '✗ Cancel', value: 'cancel' },
|
|
941
|
-
],
|
|
942
|
-
});
|
|
943
|
-
const authResult = await authResolver.resolve();
|
|
944
|
-
const authAction = authResult.authAction;
|
|
945
|
-
if (authAction === 'cancel') {
|
|
946
|
-
db.close();
|
|
947
|
-
this.log(styles.muted('Cancelled.'));
|
|
948
|
-
return;
|
|
949
|
-
}
|
|
950
|
-
if (authAction === 'host') {
|
|
951
|
-
environment = 'host';
|
|
952
|
-
this.log(styles.muted('Switched to host environment.'));
|
|
1001
|
+
// In JSON mode with --yes, continue anyway (agent can run /login)
|
|
1002
|
+
if (jsonMode && flags.yes) {
|
|
1003
|
+
// Continue without prompting - agent will need to handle auth
|
|
953
1004
|
}
|
|
954
|
-
else
|
|
1005
|
+
else {
|
|
955
1006
|
this.log('');
|
|
956
|
-
this.log(styles.
|
|
1007
|
+
this.log(styles.warning('⚠️ No Claude Code credentials found for Docker containers'));
|
|
1008
|
+
this.log(styles.muted(' Agents will fail with 401 authentication errors without credentials.'));
|
|
957
1009
|
this.log('');
|
|
958
|
-
//
|
|
959
|
-
const
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
1010
|
+
// Use FlagResolver for auth action
|
|
1011
|
+
const authResolver = new FlagResolver({
|
|
1012
|
+
commandName: 'work start',
|
|
1013
|
+
baseCommand: `prlt work start ${ticketId}`,
|
|
1014
|
+
jsonMode,
|
|
1015
|
+
flags: {},
|
|
1016
|
+
});
|
|
1017
|
+
authResolver.addPrompt({
|
|
1018
|
+
flagName: 'authAction',
|
|
1019
|
+
type: 'list',
|
|
1020
|
+
message: 'What would you like to do?',
|
|
1021
|
+
choices: () => [
|
|
1022
|
+
{ name: `🔐 Run ${this.config.bin} agent auth now (one-time setup)`, value: 'auth' },
|
|
1023
|
+
{ name: '💻 Switch to host environment instead', value: 'host' },
|
|
1024
|
+
{ name: '⏩ Continue anyway (must run /login in first agent)', value: 'continue' },
|
|
1025
|
+
{ name: '✗ Cancel', value: 'cancel' },
|
|
1026
|
+
],
|
|
1027
|
+
});
|
|
1028
|
+
const authResult = await authResolver.resolve();
|
|
1029
|
+
const authAction = authResult.authAction;
|
|
1030
|
+
if (authAction === 'cancel') {
|
|
1031
|
+
db.close();
|
|
1032
|
+
this.log(styles.muted('Cancelled.'));
|
|
1033
|
+
return;
|
|
971
1034
|
}
|
|
972
|
-
|
|
973
|
-
|
|
1035
|
+
if (authAction === 'host') {
|
|
1036
|
+
environment = 'host';
|
|
1037
|
+
this.log(styles.muted('Switched to host environment.'));
|
|
1038
|
+
}
|
|
1039
|
+
else if (authAction === 'auth') {
|
|
1040
|
+
this.log('');
|
|
1041
|
+
this.log(styles.primary(`Opening ${this.config.bin} agent auth in new tab...`));
|
|
1042
|
+
this.log('');
|
|
1043
|
+
// Open auth in a new terminal tab
|
|
1044
|
+
const authCmd = `${process.argv[1]} agent auth`;
|
|
974
1045
|
try {
|
|
975
|
-
execSync(`osascript -e '
|
|
1046
|
+
execSync(`osascript -e '
|
|
1047
|
+
tell application "iTerm"
|
|
1048
|
+
tell current window
|
|
1049
|
+
create tab with default profile
|
|
1050
|
+
tell current session
|
|
1051
|
+
write text "${authCmd}"
|
|
1052
|
+
end tell
|
|
1053
|
+
end tell
|
|
1054
|
+
end tell
|
|
1055
|
+
'`);
|
|
976
1056
|
}
|
|
977
1057
|
catch {
|
|
978
|
-
|
|
979
|
-
|
|
1058
|
+
// Fallback: try Terminal.app
|
|
1059
|
+
try {
|
|
1060
|
+
execSync(`osascript -e 'tell application "Terminal" to do script "${authCmd}"'`);
|
|
1061
|
+
}
|
|
1062
|
+
catch {
|
|
1063
|
+
this.log(styles.warning('Could not open new terminal tab.'));
|
|
1064
|
+
this.log(styles.muted(`Please run manually: ${authCmd}`));
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
this.log(styles.muted('Complete the /login flow in the new tab, then press Enter here...'));
|
|
1068
|
+
this.log('');
|
|
1069
|
+
// Wait for user to complete auth
|
|
1070
|
+
await this.prompt([{
|
|
1071
|
+
type: 'input',
|
|
1072
|
+
name: 'done',
|
|
1073
|
+
message: 'Press Enter when authentication is complete:',
|
|
1074
|
+
}]);
|
|
1075
|
+
// Check if credentials now exist
|
|
1076
|
+
if (!dockerCredentialsExist()) {
|
|
1077
|
+
this.log('');
|
|
1078
|
+
this.log(styles.warning('Authentication did not complete. No credentials found.'));
|
|
1079
|
+
db.close();
|
|
1080
|
+
return;
|
|
1081
|
+
}
|
|
1082
|
+
const info = getDockerCredentialInfo();
|
|
1083
|
+
this.log('');
|
|
1084
|
+
this.log(styles.success('✓ Credentials configured'));
|
|
1085
|
+
if (info) {
|
|
1086
|
+
this.log(styles.muted(` Subscription: ${info.subscriptionType || 'unknown'}`));
|
|
1087
|
+
this.log(styles.muted(` Expires: ${info.expiresAt.toLocaleDateString()}`));
|
|
980
1088
|
}
|
|
981
|
-
}
|
|
982
|
-
this.log(styles.muted('Complete the /login flow in the new tab, then press Enter here...'));
|
|
983
|
-
this.log('');
|
|
984
|
-
// Wait for user to complete auth
|
|
985
|
-
await inquirer.prompt([{
|
|
986
|
-
type: 'input',
|
|
987
|
-
name: 'done',
|
|
988
|
-
message: 'Press Enter when authentication is complete:',
|
|
989
|
-
}]);
|
|
990
|
-
// Check if credentials now exist
|
|
991
|
-
if (!dockerCredentialsExist()) {
|
|
992
1089
|
this.log('');
|
|
993
|
-
this.log(styles.warning('Authentication did not complete. No credentials found.'));
|
|
994
|
-
db.close();
|
|
995
|
-
return;
|
|
996
|
-
}
|
|
997
|
-
const info = getDockerCredentialInfo();
|
|
998
|
-
this.log('');
|
|
999
|
-
this.log(styles.success('✓ Credentials configured'));
|
|
1000
|
-
if (info) {
|
|
1001
|
-
this.log(styles.muted(` Subscription: ${info.subscriptionType || 'unknown'}`));
|
|
1002
|
-
this.log(styles.muted(` Expires: ${info.expiresAt.toLocaleDateString()}`));
|
|
1003
1090
|
}
|
|
1004
|
-
|
|
1091
|
+
// authAction === 'continue' falls through
|
|
1005
1092
|
}
|
|
1006
|
-
// authAction === 'continue' falls through
|
|
1007
1093
|
}
|
|
1008
1094
|
}
|
|
1009
1095
|
// Prompt for permissions mode (all environments)
|
|
@@ -1048,50 +1134,58 @@ export default class WorkStart extends PMOCommand {
|
|
|
1048
1134
|
createPR = false;
|
|
1049
1135
|
}
|
|
1050
1136
|
else if (ghAvailable) {
|
|
1051
|
-
//
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
this.log(styles.muted(` Executor: ${executor}`));
|
|
1077
|
-
// Environment info
|
|
1078
|
-
const envIcon = environment === 'devcontainer' ? '🐳' : '💻';
|
|
1079
|
-
this.log(styles.muted(` Environment: ${envIcon} ${environment}`));
|
|
1080
|
-
this.log(styles.muted(` Display: ${displayMode}`));
|
|
1081
|
-
// Permissions info
|
|
1082
|
-
if (sandboxed) {
|
|
1083
|
-
this.log(styles.success(` Permissions: 🔒 safe`));
|
|
1084
|
-
}
|
|
1085
|
-
else {
|
|
1086
|
-
this.log(styles.warning(` Permissions: ⚠️ danger (--dangerously-skip-permissions)`));
|
|
1137
|
+
// In JSON mode with --yes, default to creating PR for code-modifying actions
|
|
1138
|
+
if (jsonMode && flags.yes) {
|
|
1139
|
+
createPR = context.modifiesCode !== false;
|
|
1140
|
+
}
|
|
1141
|
+
else {
|
|
1142
|
+
// Use FlagResolver for PR choice
|
|
1143
|
+
const prResolver = new FlagResolver({
|
|
1144
|
+
commandName: 'work start',
|
|
1145
|
+
baseCommand: `prlt work start ${ticketId}`,
|
|
1146
|
+
jsonMode,
|
|
1147
|
+
flags: {},
|
|
1148
|
+
});
|
|
1149
|
+
prResolver.addPrompt({
|
|
1150
|
+
flagName: 'prChoice',
|
|
1151
|
+
type: 'list',
|
|
1152
|
+
message: 'Create a pull request when work is ready?',
|
|
1153
|
+
default: 'yes',
|
|
1154
|
+
choices: () => [
|
|
1155
|
+
{ name: '✓ Yes - Create PR when running `prlt work ready`', value: 'yes' },
|
|
1156
|
+
{ name: '✗ No - Just move ticket to review (can create PR later)', value: 'no' },
|
|
1157
|
+
],
|
|
1158
|
+
});
|
|
1159
|
+
const prResult = await prResolver.resolve();
|
|
1160
|
+
createPR = prResult.prChoice === 'yes';
|
|
1161
|
+
}
|
|
1087
1162
|
}
|
|
1088
|
-
|
|
1089
|
-
if (
|
|
1090
|
-
this.log(
|
|
1163
|
+
// Show execution info (skip in JSON mode)
|
|
1164
|
+
if (!jsonMode) {
|
|
1165
|
+
this.log('');
|
|
1166
|
+
this.log(styles.header(`🚀 Starting work: ${ticket.id}: ${ticket.title}`));
|
|
1167
|
+
this.log(styles.muted(` Agent: ${assignedAgent}`));
|
|
1168
|
+
this.log(styles.muted(` Action: ${context.actionName || 'None'}`));
|
|
1169
|
+
this.log(styles.muted(` Executor: ${executor}`));
|
|
1170
|
+
// Environment info
|
|
1171
|
+
const envIcon = environment === 'devcontainer' ? '🐳' : '💻';
|
|
1172
|
+
this.log(styles.muted(` Environment: ${envIcon} ${environment}`));
|
|
1173
|
+
this.log(styles.muted(` Display: ${displayMode}`));
|
|
1174
|
+
// Permissions info
|
|
1175
|
+
if (sandboxed) {
|
|
1176
|
+
this.log(styles.success(` Permissions: 🔒 safe`));
|
|
1177
|
+
}
|
|
1178
|
+
else {
|
|
1179
|
+
this.log(styles.warning(` Permissions: ⚠️ danger (--dangerously-skip-permissions)`));
|
|
1180
|
+
}
|
|
1181
|
+
this.log(styles.muted(` Output: ${outputMode === 'interactive' ? 'streaming (watch Claude work)' : 'print (final result only)'}`));
|
|
1182
|
+
if (ghAvailable) {
|
|
1183
|
+
this.log(styles.muted(` Create PR: ${createPR ? 'yes (when work is ready)' : 'no'}`));
|
|
1184
|
+
}
|
|
1185
|
+
this.log(styles.muted(` Worktree: ${worktreePath}`));
|
|
1186
|
+
this.log(styles.muted(` Branch: ${branch}`));
|
|
1187
|
+
this.log('');
|
|
1091
1188
|
}
|
|
1092
|
-
this.log(styles.muted(` Worktree: ${worktreePath}`));
|
|
1093
|
-
this.log(styles.muted(` Branch: ${branch}`));
|
|
1094
|
-
this.log('');
|
|
1095
1189
|
// Add createPR to context
|
|
1096
1190
|
context.createPR = createPR;
|
|
1097
1191
|
// Handle git operations
|
|
@@ -1143,14 +1237,14 @@ export default class WorkStart extends PMOCommand {
|
|
|
1143
1237
|
const branchChoice = branchResult.branchChoice;
|
|
1144
1238
|
if (branchChoice === 'enter') {
|
|
1145
1239
|
// User enters existing branch name
|
|
1146
|
-
const { enteredBranch } = await
|
|
1240
|
+
const { enteredBranch } = await this.prompt([
|
|
1147
1241
|
{
|
|
1148
1242
|
type: 'input',
|
|
1149
1243
|
name: 'enteredBranch',
|
|
1150
1244
|
message: 'Enter branch name:',
|
|
1151
1245
|
validate: (input) => input.trim() ? true : 'Branch name required',
|
|
1152
1246
|
},
|
|
1153
|
-
]);
|
|
1247
|
+
], jsonModeConfig);
|
|
1154
1248
|
finalBranch = enteredBranch.trim();
|
|
1155
1249
|
// Validate branch exists (locally or in origin)
|
|
1156
1250
|
try {
|
|
@@ -1184,18 +1278,17 @@ export default class WorkStart extends PMOCommand {
|
|
|
1184
1278
|
}
|
|
1185
1279
|
if (remoteBranches.length > 0) {
|
|
1186
1280
|
const branchChoices = [
|
|
1187
|
-
...remoteBranches.map(b => ({ name: b, value: b.replace('origin/', '') })),
|
|
1188
|
-
new
|
|
1189
|
-
{ name: 'None of these, create new branch', value: '__create__' },
|
|
1281
|
+
...remoteBranches.map(b => ({ name: b, value: b.replace('origin/', ''), command: `prlt work start ${ticketId} --json` })),
|
|
1282
|
+
{ name: '── None of these, create new branch ──', value: '__create__', command: `prlt work start ${ticketId} --json` },
|
|
1190
1283
|
];
|
|
1191
|
-
const { selectedBranch } = await
|
|
1284
|
+
const { selectedBranch } = await this.prompt([
|
|
1192
1285
|
{
|
|
1193
1286
|
type: 'list',
|
|
1194
1287
|
name: 'selectedBranch',
|
|
1195
1288
|
message: `Found ${remoteBranches.length} matching branch(es):`,
|
|
1196
1289
|
choices: branchChoices,
|
|
1197
1290
|
},
|
|
1198
|
-
]);
|
|
1291
|
+
], jsonModeConfig);
|
|
1199
1292
|
if (selectedBranch !== '__create__') {
|
|
1200
1293
|
finalBranch = selectedBranch;
|
|
1201
1294
|
// Fetch and checkout the selected branch
|
|
@@ -1279,8 +1372,10 @@ export default class WorkStart extends PMOCommand {
|
|
|
1279
1372
|
sandboxed,
|
|
1280
1373
|
branch,
|
|
1281
1374
|
});
|
|
1282
|
-
|
|
1283
|
-
|
|
1375
|
+
if (!jsonMode) {
|
|
1376
|
+
this.log(styles.muted(` Work ID: ${execution.id}`));
|
|
1377
|
+
this.log('');
|
|
1378
|
+
}
|
|
1284
1379
|
// Note: Ticket status update moved to after successful spawn (see below)
|
|
1285
1380
|
// Load execution config from database
|
|
1286
1381
|
const executionConfig = loadExecutionConfig(db);
|
|
@@ -1321,7 +1416,9 @@ export default class WorkStart extends PMOCommand {
|
|
|
1321
1416
|
executionConfig.terminal.openInBackground = false;
|
|
1322
1417
|
}
|
|
1323
1418
|
// Run execution
|
|
1324
|
-
|
|
1419
|
+
if (!jsonMode) {
|
|
1420
|
+
this.log(styles.muted('Starting agent...'));
|
|
1421
|
+
}
|
|
1325
1422
|
const sessionManager = (flags.session || 'tmux');
|
|
1326
1423
|
const result = await runExecution(environment, context, executor, executionConfig, {
|
|
1327
1424
|
host: flags['vm-host'],
|
|
@@ -1375,18 +1472,47 @@ export default class WorkStart extends PMOCommand {
|
|
|
1375
1472
|
this.warn(`Could not move ticket to "${targetColumnName}": ${moveError instanceof Error ? moveError.message : moveError}`);
|
|
1376
1473
|
}
|
|
1377
1474
|
}
|
|
1378
|
-
await autoExportToBoard(this.pmoPath, this.storage, (msg) =>
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1475
|
+
await autoExportToBoard(this.pmoPath, this.storage, (msg) => {
|
|
1476
|
+
if (!jsonMode) {
|
|
1477
|
+
this.log(styles.muted(msg));
|
|
1478
|
+
}
|
|
1479
|
+
});
|
|
1480
|
+
// Output results
|
|
1481
|
+
if (jsonMode) {
|
|
1482
|
+
// Output JSON execution result
|
|
1483
|
+
outputExecutionResultAsJson([{
|
|
1484
|
+
workId: execution.id,
|
|
1485
|
+
ticketId: ticket.id,
|
|
1486
|
+
agent: assignedAgent,
|
|
1487
|
+
sessionId: result.sessionId,
|
|
1488
|
+
containerId: result.containerId,
|
|
1489
|
+
status: 'running',
|
|
1490
|
+
}], 1, 0, createMetadata('work start', flags));
|
|
1491
|
+
}
|
|
1492
|
+
else {
|
|
1493
|
+
this.log('');
|
|
1494
|
+
this.log(styles.success(`✓ Work started (${execution.id})`));
|
|
1495
|
+
this.log('');
|
|
1496
|
+
this.log(styles.muted('Commands:'));
|
|
1497
|
+
this.log(styles.muted(` prlt work status View work status`));
|
|
1498
|
+
this.log(styles.muted(` prlt work ready ${ticketId} Mark ready for review`));
|
|
1499
|
+
this.log(styles.muted(` prlt work stop ${execution.id} Stop work`));
|
|
1500
|
+
}
|
|
1386
1501
|
}
|
|
1387
1502
|
else {
|
|
1388
1503
|
executionStorage.updateStatus(execution.id, 'failed');
|
|
1389
|
-
|
|
1504
|
+
if (jsonMode) {
|
|
1505
|
+
// Output JSON failure result
|
|
1506
|
+
outputExecutionResultAsJson([{
|
|
1507
|
+
workId: execution.id,
|
|
1508
|
+
ticketId: ticket.id,
|
|
1509
|
+
agent: assignedAgent,
|
|
1510
|
+
status: 'failed',
|
|
1511
|
+
}], 0, 1, createMetadata('work start', flags));
|
|
1512
|
+
}
|
|
1513
|
+
else {
|
|
1514
|
+
this.error(`Failed to start work: ${result.error}`);
|
|
1515
|
+
}
|
|
1390
1516
|
}
|
|
1391
1517
|
db.close();
|
|
1392
1518
|
}
|
|
@@ -1399,6 +1525,8 @@ export default class WorkStart extends PMOCommand {
|
|
|
1399
1525
|
* Run batch mode: spawn work for all unassigned backlog tickets
|
|
1400
1526
|
*/
|
|
1401
1527
|
async runBatchMode(workspaceInfo, db, executionStorage, flags) {
|
|
1528
|
+
const batchJsonMode = shouldOutputJson(flags);
|
|
1529
|
+
const batchJsonModeConfig = batchJsonMode ? { flags: flags, commandName: 'work start' } : null;
|
|
1402
1530
|
// Get all tickets and filter to backlog/unstarted (not in progress)
|
|
1403
1531
|
// Note: In batch mode, we get all tickets across all projects (pass undefined for projectId)
|
|
1404
1532
|
// eslint-disable-next-line unicorn/no-useless-undefined
|
|
@@ -1435,17 +1563,17 @@ export default class WorkStart extends PMOCommand {
|
|
|
1435
1563
|
this.log(styles.muted(`Tickets to spawn: ${backlogTickets.map(t => t.id).join(', ')}`));
|
|
1436
1564
|
this.log('');
|
|
1437
1565
|
// Confirm before batch spawning
|
|
1438
|
-
const { confirm } = await
|
|
1566
|
+
const { confirm } = await this.prompt([
|
|
1439
1567
|
{
|
|
1440
1568
|
type: 'list',
|
|
1441
1569
|
name: 'confirm',
|
|
1442
1570
|
message: `Start work on ${backlogTickets.length} tickets using ${availableAgents.length} available agents?`,
|
|
1443
1571
|
choices: [
|
|
1444
|
-
{ name: 'Yes', value: true },
|
|
1445
|
-
{ name: 'No', value: false },
|
|
1572
|
+
{ name: 'Yes', value: true, command: 'prlt work start --all --json' },
|
|
1573
|
+
{ name: 'No', value: false, command: '' },
|
|
1446
1574
|
],
|
|
1447
1575
|
},
|
|
1448
|
-
]);
|
|
1576
|
+
], batchJsonModeConfig);
|
|
1449
1577
|
if (!confirm) {
|
|
1450
1578
|
db.close();
|
|
1451
1579
|
this.log(styles.muted('Cancelled.'));
|
|
@@ -1454,18 +1582,18 @@ export default class WorkStart extends PMOCommand {
|
|
|
1454
1582
|
// Prompt for permissions mode once for all tickets (TKT-513)
|
|
1455
1583
|
let batchPermissionMode = flags['permission-mode'];
|
|
1456
1584
|
if (!batchPermissionMode) {
|
|
1457
|
-
const { permissionMode } = await
|
|
1585
|
+
const { permissionMode } = await this.prompt([
|
|
1458
1586
|
{
|
|
1459
1587
|
type: 'list',
|
|
1460
1588
|
name: 'permissionMode',
|
|
1461
1589
|
message: 'Permission mode for Claude Code:',
|
|
1462
1590
|
choices: [
|
|
1463
|
-
{ name: '⚠️ danger - Skip permission checks (faster, container provides isolation)', value: 'danger' },
|
|
1464
|
-
{ name: '🔒 safe - Requires approval for dangerous operations', value: 'safe' },
|
|
1591
|
+
{ name: '⚠️ danger - Skip permission checks (faster, container provides isolation)', value: 'danger', command: 'prlt work start --all --permission-mode danger --json' },
|
|
1592
|
+
{ name: '🔒 safe - Requires approval for dangerous operations', value: 'safe', command: 'prlt work start --all --permission-mode safe --json' },
|
|
1465
1593
|
],
|
|
1466
1594
|
default: 'danger',
|
|
1467
1595
|
},
|
|
1468
|
-
]);
|
|
1596
|
+
], batchJsonModeConfig);
|
|
1469
1597
|
batchPermissionMode = permissionMode;
|
|
1470
1598
|
}
|
|
1471
1599
|
// Check Docker credentials if any agents use devcontainers
|
|
@@ -1480,18 +1608,18 @@ export default class WorkStart extends PMOCommand {
|
|
|
1480
1608
|
this.log(styles.warning('⚠️ No Claude Code credentials found for Docker containers'));
|
|
1481
1609
|
this.log(styles.muted(' Agents will fail with 401 authentication errors without credentials.'));
|
|
1482
1610
|
this.log('');
|
|
1483
|
-
const { authAction } = await
|
|
1611
|
+
const { authAction } = await this.prompt([
|
|
1484
1612
|
{
|
|
1485
1613
|
type: 'list',
|
|
1486
1614
|
name: 'authAction',
|
|
1487
1615
|
message: 'What would you like to do?',
|
|
1488
1616
|
choices: [
|
|
1489
|
-
{ name: `🔐 Run ${this.config.bin} agent auth now (one-time setup)`, value: 'auth' },
|
|
1490
|
-
{ name: '💻 Run all agents on host instead (--run-on-host)', value: 'host' },
|
|
1491
|
-
{ name: '✗ Cancel', value: 'cancel' },
|
|
1617
|
+
{ name: `🔐 Run ${this.config.bin} agent auth now (one-time setup)`, value: 'auth', command: `${this.config.bin} agent auth` },
|
|
1618
|
+
{ name: '💻 Run all agents on host instead (--run-on-host)', value: 'host', command: 'prlt work start --all --run-on-host --json' },
|
|
1619
|
+
{ name: '✗ Cancel', value: 'cancel', command: '' },
|
|
1492
1620
|
],
|
|
1493
1621
|
},
|
|
1494
|
-
]);
|
|
1622
|
+
], batchJsonModeConfig);
|
|
1495
1623
|
if (authAction === 'cancel') {
|
|
1496
1624
|
db.close();
|
|
1497
1625
|
this.log(styles.muted('Cancelled.'));
|
|
@@ -1532,11 +1660,11 @@ export default class WorkStart extends PMOCommand {
|
|
|
1532
1660
|
this.log(styles.muted('Complete the /login flow in the new tab, then press Enter here...'));
|
|
1533
1661
|
this.log('');
|
|
1534
1662
|
// Wait for user to complete auth
|
|
1535
|
-
await
|
|
1663
|
+
await this.prompt([{
|
|
1536
1664
|
type: 'input',
|
|
1537
1665
|
name: 'done',
|
|
1538
1666
|
message: 'Press Enter when authentication is complete:',
|
|
1539
|
-
}]);
|
|
1667
|
+
}], batchJsonModeConfig);
|
|
1540
1668
|
// Check if credentials now exist
|
|
1541
1669
|
if (!dockerCredentialsExist()) {
|
|
1542
1670
|
this.log('');
|