@proletariat/cli 0.3.35 → 0.3.40
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/README.md +37 -2
- package/bin/dev.js +0 -0
- package/dist/commands/agent/auth.d.ts +12 -2
- package/dist/commands/agent/auth.js +128 -4
- package/dist/commands/agent/list.js +16 -7
- package/dist/commands/agent/status.js +32 -4
- package/dist/commands/board/watch.js +6 -0
- package/dist/commands/branch/list.d.ts +1 -0
- package/dist/commands/branch/list.js +43 -12
- package/dist/commands/branch/where.js +9 -19
- package/dist/commands/category/list.d.ts +2 -1
- package/dist/commands/category/list.js +38 -13
- package/dist/commands/{claude.d.ts → claude/index.d.ts} +1 -1
- package/dist/commands/{claude.js → claude/index.js} +12 -12
- package/dist/commands/claude/open.d.ts +13 -0
- package/dist/commands/claude/open.js +175 -0
- package/dist/commands/diet.js +18 -2
- package/dist/commands/docker/logs.js +7 -3
- package/dist/commands/docker/shell.js +6 -0
- package/dist/commands/docker/start.js +20 -4
- package/dist/commands/docker/sync.d.ts +4 -0
- package/dist/commands/docker/sync.js +30 -2
- package/dist/commands/epic/show.d.ts +13 -0
- package/dist/commands/epic/show.js +16 -0
- package/dist/commands/epic/ticket.js +7 -24
- package/dist/commands/epic/view.js +27 -0
- package/dist/commands/execution/config.d.ts +0 -4
- package/dist/commands/execution/config.js +14 -46
- package/dist/commands/execution/index.js +2 -1
- package/dist/commands/execution/logs.js +7 -1
- package/dist/commands/execution/stop.js +2 -1
- package/dist/commands/execution/view.js +30 -26
- package/dist/commands/init.js +2 -19
- package/dist/commands/label/create.js +2 -1
- package/dist/commands/label/delete.js +2 -1
- package/dist/commands/label/group/create.js +2 -1
- package/dist/commands/label/group/list.js +2 -1
- package/dist/commands/label/list.js +2 -1
- package/dist/commands/mcp-server.js +27 -1
- package/dist/commands/phase/template/list.js +2 -1
- package/dist/commands/pmo/init.js +12 -40
- package/dist/commands/project/create.js +3 -4
- package/dist/commands/project/update.js +5 -6
- package/dist/commands/pull.js +24 -0
- package/dist/commands/qa/index.d.ts +54 -0
- package/dist/commands/qa/index.js +762 -0
- package/dist/commands/repo/view.js +2 -8
- package/dist/commands/session/attach.js +4 -4
- package/dist/commands/session/create.d.ts +19 -0
- package/dist/commands/session/create.js +102 -0
- package/dist/commands/session/health.js +4 -23
- package/dist/commands/session/index.js +14 -1
- package/dist/commands/session/list.js +9 -8
- package/dist/commands/session/peek.d.ts +38 -0
- package/dist/commands/session/peek.js +316 -0
- package/dist/commands/session/poke.d.ts +27 -0
- package/dist/commands/session/poke.js +219 -0
- package/dist/commands/spec/view.js +29 -0
- package/dist/commands/template/list.js +2 -1
- package/dist/commands/theme/add-names.d.ts +4 -0
- package/dist/commands/theme/add-names.js +11 -1
- package/dist/commands/theme/create.d.ts +2 -0
- package/dist/commands/theme/create.js +8 -0
- package/dist/commands/ticket/bulk.js +2 -2
- package/dist/commands/ticket/complete.js +2 -2
- package/dist/commands/ticket/create.js +21 -0
- package/dist/commands/ticket/delete.js +8 -0
- package/dist/commands/ticket/edit.js +25 -0
- package/dist/commands/ticket/epic.js +17 -43
- package/dist/commands/ticket/index.js +2 -2
- package/dist/commands/ticket/move.js +25 -2
- package/dist/commands/ticket/resolve.js +3 -4
- package/dist/commands/ticket/show.d.ts +13 -0
- package/dist/commands/ticket/show.js +16 -0
- package/dist/commands/ticket/template/list.js +2 -1
- package/dist/commands/ticket/view.d.ts +0 -1
- package/dist/commands/ticket/view.js +30 -1
- package/dist/commands/work/index.js +4 -0
- package/dist/commands/work/spawn-all.js +1 -1
- package/dist/commands/work/spawn.js +15 -4
- package/dist/commands/work/start.js +186 -103
- package/dist/commands/work/status.d.ts +14 -0
- package/dist/commands/work/status.js +60 -0
- package/dist/commands/work/watch.js +1 -1
- package/dist/commands/workflow/index.js +2 -1
- package/dist/commands/workflow/show.d.ts +13 -0
- package/dist/commands/workflow/show.js +16 -0
- package/dist/commands/workspace/add.js +15 -0
- package/dist/commands/workspace/list.js +2 -1
- package/dist/commands/workspace/prune.js +7 -7
- package/dist/hooks/init.js +10 -2
- package/dist/lib/agents/commands.d.ts +5 -0
- package/dist/lib/agents/commands.js +143 -97
- package/dist/lib/branch/index.d.ts +1 -0
- package/dist/lib/database/drizzle-schema.d.ts +465 -0
- package/dist/lib/database/drizzle-schema.js +53 -0
- package/dist/lib/database/index.d.ts +47 -1
- package/dist/lib/database/index.js +138 -20
- package/dist/lib/execution/config.d.ts +15 -1
- package/dist/lib/execution/config.js +28 -0
- package/dist/lib/execution/runners.d.ts +45 -0
- package/dist/lib/execution/runners.js +187 -26
- package/dist/lib/execution/session-utils.d.ts +16 -1
- package/dist/lib/execution/session-utils.js +71 -4
- package/dist/lib/execution/spawner.js +15 -2
- package/dist/lib/execution/storage.d.ts +6 -1
- package/dist/lib/execution/storage.js +35 -5
- package/dist/lib/execution/types.d.ts +3 -0
- package/dist/lib/mcp/tools/board.js +4 -6
- package/dist/lib/mcp/tools/cli-passthrough.js +25 -6
- package/dist/lib/mcp/tools/epic.js +8 -3
- package/dist/lib/mcp/tools/index.d.ts +1 -0
- package/dist/lib/mcp/tools/index.js +1 -0
- package/dist/lib/mcp/tools/spec.js +1 -1
- package/dist/lib/mcp/tools/ticket.js +11 -9
- package/dist/lib/mcp/tools/tmux.d.ts +16 -0
- package/dist/lib/mcp/tools/tmux.js +182 -0
- package/dist/lib/mcp/tools/work.js +148 -6
- package/dist/lib/mcp/types.d.ts +10 -0
- package/dist/lib/multiline-input.js +2 -1
- package/dist/lib/pmo/base-command.js +4 -4
- package/dist/lib/pmo/schema.d.ts +1 -1
- package/dist/lib/pmo/schema.js +1 -0
- package/dist/lib/pmo/storage/actions.js +1 -1
- package/dist/lib/pmo/storage/base.js +402 -50
- package/dist/lib/pmo/storage/dependencies.d.ts +1 -0
- package/dist/lib/pmo/storage/dependencies.js +11 -3
- package/dist/lib/pmo/storage/epics.js +1 -1
- package/dist/lib/pmo/storage/helpers.d.ts +4 -4
- package/dist/lib/pmo/storage/helpers.js +36 -26
- package/dist/lib/pmo/storage/projects.d.ts +2 -0
- package/dist/lib/pmo/storage/projects.js +207 -119
- package/dist/lib/pmo/storage/specs.d.ts +2 -0
- package/dist/lib/pmo/storage/specs.js +274 -188
- package/dist/lib/pmo/storage/tickets.d.ts +2 -0
- package/dist/lib/pmo/storage/tickets.js +350 -290
- package/dist/lib/pmo/storage/types.d.ts +1 -0
- package/dist/lib/pmo/storage/views.d.ts +2 -0
- package/dist/lib/pmo/storage/views.js +183 -130
- package/dist/lib/prompt-command.d.ts +20 -0
- package/dist/lib/prompt-command.js +38 -2
- package/dist/lib/prompt-json.d.ts +41 -4
- package/dist/lib/prompt-json.js +138 -7
- package/dist/lib/styles.d.ts +37 -0
- package/dist/lib/styles.js +73 -0
- package/oclif.manifest.json +4046 -3385
- package/package.json +11 -6
- package/LICENSE +0 -190
|
@@ -76,6 +76,33 @@ export default class EpicView extends PMOCommand {
|
|
|
76
76
|
specTitle = spec?.title;
|
|
77
77
|
}
|
|
78
78
|
const projectName = await this.getProjectName(projectId);
|
|
79
|
+
// JSON output mode
|
|
80
|
+
if (jsonMode) {
|
|
81
|
+
this.log(JSON.stringify({
|
|
82
|
+
success: true,
|
|
83
|
+
epic: {
|
|
84
|
+
id: epic.id,
|
|
85
|
+
title: epic.title,
|
|
86
|
+
status: epic.status,
|
|
87
|
+
description: epic.description,
|
|
88
|
+
projectId,
|
|
89
|
+
specId: epic.specId,
|
|
90
|
+
createdAt: epic.createdAt.toISOString(),
|
|
91
|
+
updatedAt: epic.updatedAt?.toISOString(),
|
|
92
|
+
ticketCount: tickets.length,
|
|
93
|
+
doneCount: doneTickets,
|
|
94
|
+
progress: percent,
|
|
95
|
+
tickets: tickets.map((t) => ({
|
|
96
|
+
id: t.id,
|
|
97
|
+
title: t.title,
|
|
98
|
+
statusName: t.statusName,
|
|
99
|
+
statusCategory: t.statusCategory,
|
|
100
|
+
priority: t.priority,
|
|
101
|
+
})),
|
|
102
|
+
},
|
|
103
|
+
}, null, 2));
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
79
106
|
this.log(`\n🎯 Epic: ${styles.emphasis(epic.id)} - ${epic.title}`);
|
|
80
107
|
this.log('═'.repeat(55));
|
|
81
108
|
this.log(`ID: ${epic.id}`);
|
|
@@ -13,10 +13,6 @@ export default class ExecutionConfig extends PMOCommand {
|
|
|
13
13
|
protected getPMOOptions(): {
|
|
14
14
|
promptIfMultiple: boolean;
|
|
15
15
|
};
|
|
16
|
-
/**
|
|
17
|
-
* Prompt wrapper - drop-in replacement for inquirer.prompt
|
|
18
|
-
*/
|
|
19
|
-
private promptUser;
|
|
20
16
|
execute(): Promise<void>;
|
|
21
17
|
/**
|
|
22
18
|
* Handle a specific setting's sub-prompt
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { Flags } from '@oclif/core';
|
|
2
|
-
import * as path from 'node:path';
|
|
3
|
-
import Database from 'better-sqlite3';
|
|
4
2
|
import inquirer from 'inquirer';
|
|
5
3
|
import { PMOCommand, pmoBaseFlags } from '../../lib/pmo/index.js';
|
|
6
4
|
import { styles } from '../../lib/styles.js';
|
|
7
5
|
import { getWorkspaceInfo } from '../../lib/agents/commands.js';
|
|
6
|
+
import { openWorkspaceDatabase } from '../../lib/database/index.js';
|
|
8
7
|
import { loadExecutionConfig, saveTerminalApp, saveTerminalOpenInBackground, saveTmuxControlMode, saveShell, saveExecutionSetting, } from '../../lib/execution/config.js';
|
|
9
|
-
import { shouldOutputJson,
|
|
8
|
+
import { shouldOutputJson, outputSuccessAsJson, outputErrorAsJson, createMetadata, } from '../../lib/prompt-json.js';
|
|
10
9
|
export default class ExecutionConfig extends PMOCommand {
|
|
11
10
|
static description = 'View and update execution preferences';
|
|
12
11
|
static examples = [
|
|
@@ -37,28 +36,6 @@ export default class ExecutionConfig extends PMOCommand {
|
|
|
37
36
|
getPMOOptions() {
|
|
38
37
|
return { promptIfMultiple: false };
|
|
39
38
|
}
|
|
40
|
-
/**
|
|
41
|
-
* Prompt wrapper - drop-in replacement for inquirer.prompt
|
|
42
|
-
*/
|
|
43
|
-
async promptUser(questions, jsonModeConfig) {
|
|
44
|
-
if (jsonModeConfig && isAgentMode(jsonModeConfig.flags)) {
|
|
45
|
-
const firstQuestion = questions[0];
|
|
46
|
-
if (firstQuestion) {
|
|
47
|
-
const choices = firstQuestion.choices
|
|
48
|
-
? normalizeChoices(firstQuestion.choices)
|
|
49
|
-
: undefined;
|
|
50
|
-
outputPromptAsJson({
|
|
51
|
-
type: firstQuestion.type,
|
|
52
|
-
name: firstQuestion.name,
|
|
53
|
-
message: firstQuestion.message,
|
|
54
|
-
choices,
|
|
55
|
-
default: firstQuestion.default,
|
|
56
|
-
}, createMetadata(jsonModeConfig.commandName, jsonModeConfig.flags));
|
|
57
|
-
}
|
|
58
|
-
return {};
|
|
59
|
-
}
|
|
60
|
-
return inquirer.prompt(questions);
|
|
61
|
-
}
|
|
62
39
|
async execute() {
|
|
63
40
|
const { flags } = await this.parse(ExecutionConfig);
|
|
64
41
|
const jsonMode = shouldOutputJson(flags);
|
|
@@ -76,8 +53,7 @@ export default class ExecutionConfig extends PMOCommand {
|
|
|
76
53
|
this.error('Not in a workspace. Run "prlt init" first.');
|
|
77
54
|
}
|
|
78
55
|
// Open database
|
|
79
|
-
const
|
|
80
|
-
const db = new Database(dbPath);
|
|
56
|
+
const db = openWorkspaceDatabase(workspaceInfo.path);
|
|
81
57
|
try {
|
|
82
58
|
// Load current config
|
|
83
59
|
const config = loadExecutionConfig(db);
|
|
@@ -101,7 +77,7 @@ export default class ExecutionConfig extends PMOCommand {
|
|
|
101
77
|
return;
|
|
102
78
|
}
|
|
103
79
|
// Handle --list or --json flag without --setting (just show config)
|
|
104
|
-
if ((flags.list || (flags
|
|
80
|
+
if ((flags.list || shouldOutputJson(flags)) && !flags.setting) {
|
|
105
81
|
if (jsonMode) {
|
|
106
82
|
outputSuccessAsJson({
|
|
107
83
|
terminal: {
|
|
@@ -161,7 +137,7 @@ export default class ExecutionConfig extends PMOCommand {
|
|
|
161
137
|
{ name: `Shell: ${config.shell}`, value: 'shell', command: 'prlt execution config --setting shell --json' },
|
|
162
138
|
{ name: `Tmux Control Mode: ${config.tmux.controlMode}`, value: 'tmux.controlMode', command: 'prlt execution config --setting tmux.controlMode --json' },
|
|
163
139
|
];
|
|
164
|
-
const { setting } = await this.
|
|
140
|
+
const { setting } = await this.prompt([
|
|
165
141
|
{
|
|
166
142
|
type: 'list',
|
|
167
143
|
name: 'setting',
|
|
@@ -205,7 +181,7 @@ export default class ExecutionConfig extends PMOCommand {
|
|
|
205
181
|
{ name: 'docker - Run in a Docker container', value: 'docker', command: 'prlt execution config --set "defaultEnvironment docker" --json' },
|
|
206
182
|
{ name: 'vm - Run on a remote VM', value: 'vm', command: 'prlt execution config --set "defaultEnvironment vm" --json' },
|
|
207
183
|
];
|
|
208
|
-
const { newEnv } = await this.
|
|
184
|
+
const { newEnv } = await this.prompt([
|
|
209
185
|
{
|
|
210
186
|
type: 'list',
|
|
211
187
|
name: 'newEnv',
|
|
@@ -223,7 +199,7 @@ export default class ExecutionConfig extends PMOCommand {
|
|
|
223
199
|
{ name: 'interactive - Watch Claude work in real-time (streaming UI)', value: 'interactive', command: 'prlt execution config --set "outputMode interactive" --json' },
|
|
224
200
|
{ name: 'print - Show final result only (better for logs)', value: 'print', command: 'prlt execution config --set "outputMode print" --json' },
|
|
225
201
|
];
|
|
226
|
-
const { newOutput } = await this.
|
|
202
|
+
const { newOutput } = await this.prompt([
|
|
227
203
|
{
|
|
228
204
|
type: 'list',
|
|
229
205
|
name: 'newOutput',
|
|
@@ -241,7 +217,7 @@ export default class ExecutionConfig extends PMOCommand {
|
|
|
241
217
|
{ name: 'safe - Requires approval for dangerous operations (recommended)', value: 'true', command: 'prlt execution config --set "sandboxed true" --json' },
|
|
242
218
|
{ name: 'danger - Skip permission checks (--dangerously-skip-permissions)', value: 'false', command: 'prlt execution config --set "sandboxed false" --json' },
|
|
243
219
|
];
|
|
244
|
-
const { newPerm } = await this.
|
|
220
|
+
const { newPerm } = await this.prompt([
|
|
245
221
|
{
|
|
246
222
|
type: 'list',
|
|
247
223
|
name: 'newPerm',
|
|
@@ -265,7 +241,7 @@ export default class ExecutionConfig extends PMOCommand {
|
|
|
265
241
|
{ name: 'Warp', value: 'Warp', command: 'prlt execution config --set "terminal.app Warp" --json' },
|
|
266
242
|
{ name: 'tmux', value: 'tmux', command: 'prlt execution config --set "terminal.app tmux" --json' },
|
|
267
243
|
];
|
|
268
|
-
const { newApp } = await this.
|
|
244
|
+
const { newApp } = await this.prompt([
|
|
269
245
|
{
|
|
270
246
|
type: 'list',
|
|
271
247
|
name: 'newApp',
|
|
@@ -283,7 +259,7 @@ export default class ExecutionConfig extends PMOCommand {
|
|
|
283
259
|
{ name: 'Yes - Open tabs in background (don\'t steal focus)', value: 'true', command: 'prlt execution config --set "terminal.openInBackground true" --json' },
|
|
284
260
|
{ name: 'No - Bring terminal to foreground when opening tabs', value: 'false', command: 'prlt execution config --set "terminal.openInBackground false" --json' },
|
|
285
261
|
];
|
|
286
|
-
const { openInBg } = await this.
|
|
262
|
+
const { openInBg } = await this.prompt([
|
|
287
263
|
{
|
|
288
264
|
type: 'list',
|
|
289
265
|
name: 'openInBg',
|
|
@@ -302,7 +278,7 @@ export default class ExecutionConfig extends PMOCommand {
|
|
|
302
278
|
{ name: 'bash', value: 'bash', command: 'prlt execution config --set "shell bash" --json' },
|
|
303
279
|
{ name: 'fish', value: 'fish', command: 'prlt execution config --set "shell fish" --json' },
|
|
304
280
|
];
|
|
305
|
-
const { newShell } = await this.
|
|
281
|
+
const { newShell } = await this.prompt([
|
|
306
282
|
{
|
|
307
283
|
type: 'list',
|
|
308
284
|
name: 'newShell',
|
|
@@ -320,7 +296,7 @@ export default class ExecutionConfig extends PMOCommand {
|
|
|
320
296
|
{ name: 'Yes - Use tmux -CC for native iTerm integration', value: 'true', command: 'prlt execution config --set "tmux.controlMode true" --json' },
|
|
321
297
|
{ name: 'No - Standard tmux interface', value: 'false', command: 'prlt execution config --set "tmux.controlMode false" --json' },
|
|
322
298
|
];
|
|
323
|
-
const { controlMode } = await this.
|
|
299
|
+
const { controlMode } = await this.prompt([
|
|
324
300
|
{
|
|
325
301
|
type: 'list',
|
|
326
302
|
name: 'controlMode',
|
|
@@ -410,20 +386,12 @@ export default class ExecutionConfig extends PMOCommand {
|
|
|
410
386
|
* Save output mode to workspace settings
|
|
411
387
|
*/
|
|
412
388
|
setOutputMode(db, mode) {
|
|
413
|
-
db
|
|
414
|
-
INSERT INTO workspace_settings (key, value)
|
|
415
|
-
VALUES (?, ?)
|
|
416
|
-
ON CONFLICT(key) DO UPDATE SET value = excluded.value
|
|
417
|
-
`).run('execution.output_mode', mode);
|
|
389
|
+
saveExecutionSetting(db, 'outputMode', mode);
|
|
418
390
|
}
|
|
419
391
|
/**
|
|
420
392
|
* Save sandboxed preference to workspace settings
|
|
421
393
|
*/
|
|
422
394
|
setSandboxed(db, sandboxed) {
|
|
423
|
-
db.
|
|
424
|
-
INSERT INTO workspace_settings (key, value)
|
|
425
|
-
VALUES (?, ?)
|
|
426
|
-
ON CONFLICT(key) DO UPDATE SET value = excluded.value
|
|
427
|
-
`).run('execution.sandboxed', sandboxed.toString());
|
|
395
|
+
saveExecutionSetting(db, 'sandboxed', sandboxed.toString());
|
|
428
396
|
}
|
|
429
397
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import inquirer from 'inquirer';
|
|
2
2
|
import { PMOCommand, pmoBaseFlags } from '../../lib/pmo/index.js';
|
|
3
|
+
import { shouldOutputJson } from '../../lib/prompt-json.js';
|
|
3
4
|
export default class Execution extends PMOCommand {
|
|
4
5
|
static description = 'Single execution operations (view, logs, stop)';
|
|
5
6
|
static examples = [
|
|
@@ -16,7 +17,7 @@ export default class Execution extends PMOCommand {
|
|
|
16
17
|
}
|
|
17
18
|
async execute() {
|
|
18
19
|
const { flags } = await this.parse(Execution);
|
|
19
|
-
const jsonModeConfig = (flags
|
|
20
|
+
const jsonModeConfig = shouldOutputJson(flags) ? { flags, commandName: 'execution' } : null;
|
|
20
21
|
const { action } = await this.prompt([
|
|
21
22
|
{
|
|
22
23
|
type: 'list',
|
|
@@ -66,7 +66,7 @@ export default class ExecutionLogs extends PMOCommand {
|
|
|
66
66
|
}
|
|
67
67
|
this.error('No executions found.');
|
|
68
68
|
}
|
|
69
|
-
const jsonModeConfig = (flags
|
|
69
|
+
const jsonModeConfig = shouldOutputJson(flags) ? { flags, commandName: 'execution logs' } : null;
|
|
70
70
|
const { selectedId } = await this.prompt([
|
|
71
71
|
{
|
|
72
72
|
type: 'list',
|
|
@@ -90,6 +90,12 @@ export default class ExecutionLogs extends PMOCommand {
|
|
|
90
90
|
if (!execution.logPath) {
|
|
91
91
|
this.log(styles.muted(`\nNo log file for execution ${execId}`));
|
|
92
92
|
this.log(styles.muted(`Environment: ${execution.environment}`));
|
|
93
|
+
// Show error message if available (TKT-1082)
|
|
94
|
+
if (execution.errorMessage) {
|
|
95
|
+
this.log('');
|
|
96
|
+
this.log(styles.error('Error:'));
|
|
97
|
+
this.log(styles.error(` ${execution.errorMessage}`));
|
|
98
|
+
}
|
|
93
99
|
if (execution.sessionId) {
|
|
94
100
|
this.log('');
|
|
95
101
|
this.log(styles.muted('View in tmux:'));
|
|
@@ -7,6 +7,7 @@ import { getWorkspaceInfo } from '../../lib/agents/commands.js';
|
|
|
7
7
|
import { ExecutionStorage } from '../../lib/execution/storage.js';
|
|
8
8
|
import { isDockerRunning } from '../../lib/execution/runners.js';
|
|
9
9
|
import { PMOCommand, pmoBaseFlags } from '../../lib/pmo/index.js';
|
|
10
|
+
import { shouldOutputJson } from '../../lib/prompt-json.js';
|
|
10
11
|
export default class ExecutionStop extends PMOCommand {
|
|
11
12
|
static description = 'Stop running execution(s)';
|
|
12
13
|
static examples = [
|
|
@@ -133,7 +134,7 @@ export default class ExecutionStop extends PMOCommand {
|
|
|
133
134
|
this.log(styles.muted('\nNo running executions found.\n'));
|
|
134
135
|
return;
|
|
135
136
|
}
|
|
136
|
-
const jsonModeConfig = (flags
|
|
137
|
+
const jsonModeConfig = shouldOutputJson(flags) ? { flags: flags, commandName: 'execution stop' } : null;
|
|
137
138
|
const { selectedId } = await this.prompt([
|
|
138
139
|
{
|
|
139
140
|
type: 'list',
|
|
@@ -6,7 +6,7 @@ import { styles } from '../../lib/styles.js';
|
|
|
6
6
|
import { getWorkspaceInfo } from '../../lib/agents/commands.js';
|
|
7
7
|
import { ExecutionStorage } from '../../lib/execution/storage.js';
|
|
8
8
|
import { PMOCommand, pmoBaseFlags } from '../../lib/pmo/index.js';
|
|
9
|
-
import { outputErrorAsJson, createMetadata, shouldOutputJson, } from '../../lib/prompt-json.js';
|
|
9
|
+
import { outputErrorAsJson, outputSuccessAsJson, createMetadata, shouldOutputJson, } from '../../lib/prompt-json.js';
|
|
10
10
|
export default class ExecutionView extends PMOCommand {
|
|
11
11
|
static description = 'View details of a specific execution';
|
|
12
12
|
static examples = [
|
|
@@ -63,7 +63,7 @@ export default class ExecutionView extends PMOCommand {
|
|
|
63
63
|
this.log(styles.muted('\nNo executions found.\n'));
|
|
64
64
|
return;
|
|
65
65
|
}
|
|
66
|
-
const jsonModeConfig = (flags
|
|
66
|
+
const jsonModeConfig = shouldOutputJson(flags) ? { flags, commandName: 'execution view' } : null;
|
|
67
67
|
const { selectedId } = await this.prompt([
|
|
68
68
|
{
|
|
69
69
|
type: 'list',
|
|
@@ -85,30 +85,27 @@ export default class ExecutionView extends PMOCommand {
|
|
|
85
85
|
}
|
|
86
86
|
// If JSON mode with ID provided, output the execution data as JSON
|
|
87
87
|
if (jsonMode && args.id) {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
metadata: createMetadata('execution view', flags),
|
|
110
|
-
}, null, 2));
|
|
111
|
-
return;
|
|
88
|
+
db.close();
|
|
89
|
+
outputSuccessAsJson({
|
|
90
|
+
id: execution.id,
|
|
91
|
+
ticketId: execution.ticketId,
|
|
92
|
+
agentName: execution.agentName,
|
|
93
|
+
executor: execution.executor,
|
|
94
|
+
environment: execution.environment,
|
|
95
|
+
displayMode: execution.displayMode,
|
|
96
|
+
sandboxed: execution.sandboxed,
|
|
97
|
+
status: execution.status,
|
|
98
|
+
branch: execution.branch || null,
|
|
99
|
+
pid: execution.pid || null,
|
|
100
|
+
containerId: execution.containerId || null,
|
|
101
|
+
sessionId: execution.sessionId || null,
|
|
102
|
+
host: execution.host || null,
|
|
103
|
+
logPath: execution.logPath || null,
|
|
104
|
+
startedAt: execution.startedAt.toISOString(),
|
|
105
|
+
completedAt: execution.completedAt?.toISOString() || null,
|
|
106
|
+
exitCode: execution.exitCode ?? null,
|
|
107
|
+
errorMessage: execution.errorMessage || null,
|
|
108
|
+
}, createMetadata('execution view', flags));
|
|
112
109
|
}
|
|
113
110
|
// Display execution details
|
|
114
111
|
this.log('');
|
|
@@ -164,6 +161,13 @@ export default class ExecutionView extends PMOCommand {
|
|
|
164
161
|
this.log(`${styles.muted('Exit Code:')} ${exitStyle(execution.exitCode.toString())}`);
|
|
165
162
|
}
|
|
166
163
|
this.log('');
|
|
164
|
+
// Error details (TKT-1082)
|
|
165
|
+
if (execution.errorMessage) {
|
|
166
|
+
this.log(styles.header('Error'));
|
|
167
|
+
this.log('─'.repeat(40));
|
|
168
|
+
this.log(styles.error(execution.errorMessage));
|
|
169
|
+
this.log('');
|
|
170
|
+
}
|
|
167
171
|
// Logs summary
|
|
168
172
|
if (execution.logPath) {
|
|
169
173
|
this.log(styles.header('Logs'));
|
package/dist/commands/init.js
CHANGED
|
@@ -6,6 +6,7 @@ import { promptForHQName, promptForHQLocation, initializeHQ, showNextSteps, vali
|
|
|
6
6
|
import { promptForAgentsWithTheme } from '../lib/agents/index.js';
|
|
7
7
|
import { promptForRepositories } from '../lib/repos/index.js';
|
|
8
8
|
import { promptForPMOSetup, machineOutputFlags } from '../lib/pmo/index.js';
|
|
9
|
+
import { shouldOutputJson } from '../lib/prompt-json.js';
|
|
9
10
|
export default class Init extends Command {
|
|
10
11
|
static description = 'Initialize an HQ (headquarters) for managing repositories, agents, and projects';
|
|
11
12
|
static examples = [
|
|
@@ -41,27 +42,9 @@ export default class Init extends Command {
|
|
|
41
42
|
};
|
|
42
43
|
async run() {
|
|
43
44
|
const { flags } = await this.parse(Init);
|
|
44
|
-
if (flags
|
|
45
|
+
if (shouldOutputJson(flags)) {
|
|
45
46
|
await this.runAgentMode(flags);
|
|
46
47
|
}
|
|
47
|
-
else if (!process.stdin.isTTY) {
|
|
48
|
-
// Non-interactive environment (likely an AI agent)
|
|
49
|
-
// Output guidance as JSON
|
|
50
|
-
this.outputJson({
|
|
51
|
-
success: false,
|
|
52
|
-
error: 'Interactive mode requires a TTY. Use --json flag for agent mode.',
|
|
53
|
-
hint: 'Run: prlt init --json --name <hq-name> [--path <path>] [--agents a1,a2] [--no-pmo]',
|
|
54
|
-
flags: {
|
|
55
|
-
'--json': 'Enable agent mode with JSON output',
|
|
56
|
-
'--name, -n': 'HQ name (required)',
|
|
57
|
-
'--path, -p': 'HQ path (defaults to ./{name}-hq)',
|
|
58
|
-
'--agents, -a': 'Comma-separated agent names',
|
|
59
|
-
'--repos, -r': 'Comma-separated repo paths',
|
|
60
|
-
'--pmo/--no-pmo': 'Include PMO (default: true)',
|
|
61
|
-
},
|
|
62
|
-
});
|
|
63
|
-
this.exit(1);
|
|
64
|
-
}
|
|
65
48
|
else {
|
|
66
49
|
await this.runHumanMode();
|
|
67
50
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Args, Flags } from '@oclif/core';
|
|
2
2
|
import { PMOCommand, pmoBaseFlags } from '../../lib/pmo/index.js';
|
|
3
|
+
import { shouldOutputJson } from '../../lib/prompt-json.js';
|
|
3
4
|
import { styles } from '../../lib/styles.js';
|
|
4
5
|
export default class LabelCreate extends PMOCommand {
|
|
5
6
|
static description = 'Create a new label';
|
|
@@ -40,7 +41,7 @@ export default class LabelCreate extends PMOCommand {
|
|
|
40
41
|
description: flags.description,
|
|
41
42
|
groupId: flags.group,
|
|
42
43
|
});
|
|
43
|
-
if (flags
|
|
44
|
+
if (shouldOutputJson(flags)) {
|
|
44
45
|
this.log(JSON.stringify(label, null, 2));
|
|
45
46
|
return;
|
|
46
47
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Args } from '@oclif/core';
|
|
2
2
|
import { PMOCommand, pmoBaseFlags } from '../../lib/pmo/index.js';
|
|
3
|
+
import { shouldOutputJson } from '../../lib/prompt-json.js';
|
|
3
4
|
import { styles } from '../../lib/styles.js';
|
|
4
5
|
export default class LabelDelete extends PMOCommand {
|
|
5
6
|
static description = 'Delete a label (removes from all tickets)';
|
|
@@ -21,7 +22,7 @@ export default class LabelDelete extends PMOCommand {
|
|
|
21
22
|
async execute() {
|
|
22
23
|
const { args, flags } = await this.parse(LabelDelete);
|
|
23
24
|
await this.storage.deleteLabel(args.id);
|
|
24
|
-
if (flags
|
|
25
|
+
if (shouldOutputJson(flags)) {
|
|
25
26
|
this.log(JSON.stringify({ success: true, deleted: args.id }));
|
|
26
27
|
return;
|
|
27
28
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Args, Flags } from '@oclif/core';
|
|
2
2
|
import { PMOCommand, pmoBaseFlags } from '../../../lib/pmo/index.js';
|
|
3
|
+
import { shouldOutputJson } from '../../../lib/prompt-json.js';
|
|
3
4
|
import { styles } from '../../../lib/styles.js';
|
|
4
5
|
export default class LabelGroupCreate extends PMOCommand {
|
|
5
6
|
static description = 'Create a new label group';
|
|
@@ -41,7 +42,7 @@ export default class LabelGroupCreate extends PMOCommand {
|
|
|
41
42
|
isExclusive: flags.exclusive,
|
|
42
43
|
isRequired: flags.required,
|
|
43
44
|
});
|
|
44
|
-
if (flags
|
|
45
|
+
if (shouldOutputJson(flags)) {
|
|
45
46
|
this.log(JSON.stringify(group, null, 2));
|
|
46
47
|
return;
|
|
47
48
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Flags } from '@oclif/core';
|
|
2
2
|
import { PMOCommand, pmoBaseFlags } from '../../../lib/pmo/index.js';
|
|
3
|
+
import { shouldOutputJson } from '../../../lib/prompt-json.js';
|
|
3
4
|
import { styles } from '../../../lib/styles.js';
|
|
4
5
|
export default class LabelGroupList extends PMOCommand {
|
|
5
6
|
static description = 'List label groups';
|
|
@@ -20,7 +21,7 @@ export default class LabelGroupList extends PMOCommand {
|
|
|
20
21
|
async execute() {
|
|
21
22
|
const { flags } = await this.parse(LabelGroupList);
|
|
22
23
|
const groups = await this.storage.listLabelGroups();
|
|
23
|
-
if (flags
|
|
24
|
+
if (shouldOutputJson(flags)) {
|
|
24
25
|
this.log(JSON.stringify(groups, null, 2));
|
|
25
26
|
return;
|
|
26
27
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Flags } from '@oclif/core';
|
|
2
2
|
import { PMOCommand, pmoBaseFlags } from '../../lib/pmo/index.js';
|
|
3
|
+
import { shouldOutputJson } from '../../lib/prompt-json.js';
|
|
3
4
|
import { styles } from '../../lib/styles.js';
|
|
4
5
|
export default class LabelList extends PMOCommand {
|
|
5
6
|
static description = 'List labels, optionally filtered by group';
|
|
@@ -27,7 +28,7 @@ export default class LabelList extends PMOCommand {
|
|
|
27
28
|
const labels = await this.storage.listLabels({
|
|
28
29
|
groupId: flags.group,
|
|
29
30
|
});
|
|
30
|
-
if (flags
|
|
31
|
+
if (shouldOutputJson(flags)) {
|
|
31
32
|
this.log(JSON.stringify(labels, null, 2));
|
|
32
33
|
return;
|
|
33
34
|
}
|
|
@@ -18,8 +18,11 @@ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
|
18
18
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
19
19
|
import { execSync } from 'node:child_process';
|
|
20
20
|
import * as path from 'node:path';
|
|
21
|
+
import Database from 'better-sqlite3';
|
|
21
22
|
import { getPMOContext } from '../lib/pmo/pmo-context.js';
|
|
22
|
-
import {
|
|
23
|
+
import { getWorkspaceInfo } from '../lib/agents/commands.js';
|
|
24
|
+
import { ExecutionStorage } from '../lib/execution/storage.js';
|
|
25
|
+
import { registerTicketTools, registerProjectTools, registerBoardTools, registerSpecTools, registerEpicTools, registerWorkTools, registerWorkflowTools, registerStatusTools, registerPhaseTools, registerActionTools, registerRoadmapTools, registerCategoryTools, registerTemplateTools, registerViewTools, registerDietTools, registerLabelTools, registerTmuxTools, registerAgentTools, registerDockerTools, registerRepoTools, registerBranchTools, registerGitHubTools, registerInitTools, registerUtilityTools, } from '../lib/mcp/index.js';
|
|
23
26
|
export default class McpServerCommand extends Command {
|
|
24
27
|
static description = 'Start MCP server for AI agent integration (exposes all prlt commands as tools)';
|
|
25
28
|
static hidden = true;
|
|
@@ -38,6 +41,25 @@ export default class McpServerCommand extends Command {
|
|
|
38
41
|
name: 'prlt',
|
|
39
42
|
version: this.config.version,
|
|
40
43
|
});
|
|
44
|
+
// Try to initialize workspace context for execution support
|
|
45
|
+
let workspaceContext = null;
|
|
46
|
+
try {
|
|
47
|
+
const workspaceInfo = getWorkspaceInfo();
|
|
48
|
+
if (workspaceInfo && pmoContext) {
|
|
49
|
+
const dbPath = path.join(workspaceInfo.path, '.proletariat', 'workspace.db');
|
|
50
|
+
const db = new Database(dbPath);
|
|
51
|
+
const executionStorage = new ExecutionStorage(db);
|
|
52
|
+
workspaceContext = {
|
|
53
|
+
workspaceInfo,
|
|
54
|
+
executionStorage,
|
|
55
|
+
db,
|
|
56
|
+
pmoPath: pmoContext.pmoPath,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
// Not in a workspace — workspace context will be null
|
|
62
|
+
}
|
|
41
63
|
// Create tool context
|
|
42
64
|
const ctx = {
|
|
43
65
|
get storage() {
|
|
@@ -68,6 +90,9 @@ export default class McpServerCommand extends Command {
|
|
|
68
90
|
throw error;
|
|
69
91
|
}
|
|
70
92
|
},
|
|
93
|
+
getWorkspaceContext: workspaceContext
|
|
94
|
+
? () => workspaceContext
|
|
95
|
+
: undefined,
|
|
71
96
|
};
|
|
72
97
|
// Register all tool categories
|
|
73
98
|
registerTicketTools(server, ctx);
|
|
@@ -86,6 +111,7 @@ export default class McpServerCommand extends Command {
|
|
|
86
111
|
registerViewTools(server, ctx);
|
|
87
112
|
registerDietTools(server, ctx);
|
|
88
113
|
registerLabelTools(server, ctx);
|
|
114
|
+
registerTmuxTools(server, ctx);
|
|
89
115
|
registerAgentTools(server, ctx);
|
|
90
116
|
registerDockerTools(server, ctx);
|
|
91
117
|
registerRepoTools(server, ctx);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Flags } from '@oclif/core';
|
|
2
2
|
import { PMOCommand, pmoBaseFlags } from '../../../lib/pmo/index.js';
|
|
3
|
+
import { shouldOutputJson } from '../../../lib/prompt-json.js';
|
|
3
4
|
import { styles } from '../../../lib/styles.js';
|
|
4
5
|
export default class PhaseTemplateList extends PMOCommand {
|
|
5
6
|
static description = 'List phase templates';
|
|
@@ -30,7 +31,7 @@ export default class PhaseTemplateList extends PMOCommand {
|
|
|
30
31
|
if (flags.custom)
|
|
31
32
|
builtinFilter = { isBuiltin: false };
|
|
32
33
|
const templates = await this.storage.listPhaseTemplates(builtinFilter);
|
|
33
|
-
if (flags
|
|
34
|
+
if (shouldOutputJson(flags)) {
|
|
34
35
|
this.log(JSON.stringify(templates, null, 2));
|
|
35
36
|
return;
|
|
36
37
|
}
|
|
@@ -4,7 +4,7 @@ import * as path from 'node:path';
|
|
|
4
4
|
import { execSync } from 'node:child_process';
|
|
5
5
|
import chalk from 'chalk';
|
|
6
6
|
import { PromptCommand } from '../../lib/prompt-command.js';
|
|
7
|
-
import
|
|
7
|
+
import { checkPMOExists, getPMOSetting, dropPMOTables } from '../../lib/database/index.js';
|
|
8
8
|
import { SQLiteStorage, getColumnsForTemplate, createPMO, promptForPMOLocation, promptForBoardTemplate, promptForBoardName, promptForCustomColumns, determinePMOPath, getPickerTemplates, machineOutputFlags, } from '../../lib/pmo/index.js';
|
|
9
9
|
import { styles } from '../../lib/styles.js';
|
|
10
10
|
import { isGHInstalled, isGHAuthenticated, getGHUsername, isGHTokenInEnv } from '../../lib/pr/index.js';
|
|
@@ -56,17 +56,10 @@ export default class PMOInit extends PromptCommand {
|
|
|
56
56
|
const dbPath = path.join(hqRoot, '.proletariat', 'workspace.db');
|
|
57
57
|
if (fs.existsSync(dbPath)) {
|
|
58
58
|
try {
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
// Get counts
|
|
64
|
-
const projectCountResult = db.prepare('SELECT COUNT(*) as count FROM pmo_projects').get();
|
|
65
|
-
const ticketCountResult = db.prepare('SELECT COUNT(*) as count FROM pmo_tickets').get();
|
|
66
|
-
projectCount = projectCountResult.count;
|
|
67
|
-
ticketCount = ticketCountResult.count;
|
|
68
|
-
}
|
|
69
|
-
db.close();
|
|
59
|
+
const pmoStatus = checkPMOExists(dbPath);
|
|
60
|
+
existingPMO = pmoStatus.exists;
|
|
61
|
+
projectCount = pmoStatus.projectCount;
|
|
62
|
+
ticketCount = pmoStatus.ticketCount;
|
|
70
63
|
}
|
|
71
64
|
catch (error) {
|
|
72
65
|
// Log error for debugging
|
|
@@ -243,16 +236,9 @@ export default class PMOInit extends PromptCommand {
|
|
|
243
236
|
// Find PMO location from database
|
|
244
237
|
const dbPath = path.join(hqRoot, '.proletariat', 'workspace.db');
|
|
245
238
|
let pmoPath = path.join(hqRoot, 'pmo'); // Default fallback
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
if (result) {
|
|
250
|
-
pmoPath = result.value;
|
|
251
|
-
}
|
|
252
|
-
db.close();
|
|
253
|
-
}
|
|
254
|
-
catch {
|
|
255
|
-
// Use default if table doesn't exist
|
|
239
|
+
const savedPmoPath = getPMOSetting(dbPath, 'pmo_path');
|
|
240
|
+
if (savedPmoPath) {
|
|
241
|
+
pmoPath = savedPmoPath;
|
|
256
242
|
}
|
|
257
243
|
// Define choices once, use for both JSON and interactive modes
|
|
258
244
|
const actionChoices = [
|
|
@@ -336,30 +322,16 @@ export default class PMOInit extends PromptCommand {
|
|
|
336
322
|
const dbPath = path.join(hqRoot, '.proletariat', 'workspace.db');
|
|
337
323
|
let pmoPath = path.join(hqRoot, 'pmo'); // Default fallback
|
|
338
324
|
if (fs.existsSync(dbPath)) {
|
|
339
|
-
const db = new Database(dbPath);
|
|
340
325
|
// Get PMO path from database before deleting
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
pmoPath = result.value;
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
catch {
|
|
348
|
-
// Ignore - table might not exist, use default
|
|
326
|
+
const savedPmoPath = getPMOSetting(dbPath, 'pmo_path');
|
|
327
|
+
if (savedPmoPath) {
|
|
328
|
+
pmoPath = savedPmoPath;
|
|
349
329
|
}
|
|
350
330
|
// Drop all pmo_* tables
|
|
351
331
|
const tables = ['pmo_ticket_specs', 'pmo_ticket_metadata', 'pmo_subtasks', 'pmo_tickets',
|
|
352
332
|
'pmo_columns', 'pmo_specs', 'pmo_epics', 'pmo_projects',
|
|
353
333
|
'pmo_initiatives', 'pmo_ticket_assignments', 'pmo_cache_metadata', 'pmo_settings'];
|
|
354
|
-
|
|
355
|
-
try {
|
|
356
|
-
db.prepare(`DROP TABLE IF EXISTS ${table}`).run();
|
|
357
|
-
}
|
|
358
|
-
catch {
|
|
359
|
-
// Ignore errors - table might not exist
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
db.close();
|
|
334
|
+
dropPMOTables(dbPath, tables);
|
|
363
335
|
this.log(chalk.green(' ✓ Dropped database tables'));
|
|
364
336
|
}
|
|
365
337
|
// Delete pmo/ directory (using path from database or default)
|