@proletariat/cli 0.3.35 → 0.3.36
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/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 +3 -2
- 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/view.js +27 -0
- package/dist/commands/execution/config.d.ts +0 -4
- package/dist/commands/execution/config.js +10 -32
- package/dist/commands/execution/index.js +2 -1
- package/dist/commands/execution/logs.js +1 -1
- package/dist/commands/execution/stop.js +2 -1
- package/dist/commands/execution/view.js +22 -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 +25 -0
- package/dist/commands/phase/template/list.js +2 -1
- 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/session/create.d.ts +19 -0
- package/dist/commands/session/create.js +102 -0
- package/dist/commands/session/health.js +1 -20
- package/dist/commands/session/index.js +14 -1
- package/dist/commands/session/list.js +26 -7
- 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/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/start.js +169 -94
- package/dist/commands/work/status.d.ts +14 -0
- package/dist/commands/work/status.js +60 -0
- 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 +5 -5
- package/dist/lib/branch/index.d.ts +1 -0
- package/dist/lib/execution/config.d.ts +15 -1
- package/dist/lib/execution/config.js +28 -0
- package/dist/lib/execution/runners.d.ts +11 -0
- package/dist/lib/execution/runners.js +53 -19
- package/dist/lib/execution/session-utils.d.ts +11 -1
- package/dist/lib/execution/session-utils.js +26 -1
- package/dist/lib/execution/storage.d.ts +5 -0
- package/dist/lib/execution/storage.js +18 -3
- package/dist/lib/execution/types.d.ts +2 -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/spec.js +1 -1
- package/dist/lib/mcp/tools/ticket.js +11 -9
- package/dist/lib/mcp/tools/work.js +96 -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/storage/actions.js +1 -1
- package/dist/lib/pmo/storage/base.js +195 -50
- package/dist/lib/pmo/storage/types.d.ts +1 -0
- package/dist/lib/prompt-command.d.ts +20 -0
- package/dist/lib/prompt-command.js +38 -2
- package/dist/lib/prompt-json.d.ts +36 -4
- package/dist/lib/prompt-json.js +129 -7
- package/dist/lib/styles.d.ts +37 -0
- package/dist/lib/styles.js +73 -0
- package/oclif.manifest.json +3259 -2701
- package/package.json +1 -1
|
@@ -6,7 +6,7 @@ import { PMOCommand, pmoBaseFlags } from '../../lib/pmo/index.js';
|
|
|
6
6
|
import { styles } from '../../lib/styles.js';
|
|
7
7
|
import { getWorkspaceInfo } from '../../lib/agents/commands.js';
|
|
8
8
|
import { loadExecutionConfig, saveTerminalApp, saveTerminalOpenInBackground, saveTmuxControlMode, saveShell, saveExecutionSetting, } from '../../lib/execution/config.js';
|
|
9
|
-
import { shouldOutputJson,
|
|
9
|
+
import { shouldOutputJson, outputSuccessAsJson, outputErrorAsJson, createMetadata, } from '../../lib/prompt-json.js';
|
|
10
10
|
export default class ExecutionConfig extends PMOCommand {
|
|
11
11
|
static description = 'View and update execution preferences';
|
|
12
12
|
static examples = [
|
|
@@ -37,28 +37,6 @@ export default class ExecutionConfig extends PMOCommand {
|
|
|
37
37
|
getPMOOptions() {
|
|
38
38
|
return { promptIfMultiple: false };
|
|
39
39
|
}
|
|
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
40
|
async execute() {
|
|
63
41
|
const { flags } = await this.parse(ExecutionConfig);
|
|
64
42
|
const jsonMode = shouldOutputJson(flags);
|
|
@@ -101,7 +79,7 @@ export default class ExecutionConfig extends PMOCommand {
|
|
|
101
79
|
return;
|
|
102
80
|
}
|
|
103
81
|
// Handle --list or --json flag without --setting (just show config)
|
|
104
|
-
if ((flags.list || (flags
|
|
82
|
+
if ((flags.list || shouldOutputJson(flags)) && !flags.setting) {
|
|
105
83
|
if (jsonMode) {
|
|
106
84
|
outputSuccessAsJson({
|
|
107
85
|
terminal: {
|
|
@@ -161,7 +139,7 @@ export default class ExecutionConfig extends PMOCommand {
|
|
|
161
139
|
{ name: `Shell: ${config.shell}`, value: 'shell', command: 'prlt execution config --setting shell --json' },
|
|
162
140
|
{ name: `Tmux Control Mode: ${config.tmux.controlMode}`, value: 'tmux.controlMode', command: 'prlt execution config --setting tmux.controlMode --json' },
|
|
163
141
|
];
|
|
164
|
-
const { setting } = await this.
|
|
142
|
+
const { setting } = await this.prompt([
|
|
165
143
|
{
|
|
166
144
|
type: 'list',
|
|
167
145
|
name: 'setting',
|
|
@@ -205,7 +183,7 @@ export default class ExecutionConfig extends PMOCommand {
|
|
|
205
183
|
{ name: 'docker - Run in a Docker container', value: 'docker', command: 'prlt execution config --set "defaultEnvironment docker" --json' },
|
|
206
184
|
{ name: 'vm - Run on a remote VM', value: 'vm', command: 'prlt execution config --set "defaultEnvironment vm" --json' },
|
|
207
185
|
];
|
|
208
|
-
const { newEnv } = await this.
|
|
186
|
+
const { newEnv } = await this.prompt([
|
|
209
187
|
{
|
|
210
188
|
type: 'list',
|
|
211
189
|
name: 'newEnv',
|
|
@@ -223,7 +201,7 @@ export default class ExecutionConfig extends PMOCommand {
|
|
|
223
201
|
{ name: 'interactive - Watch Claude work in real-time (streaming UI)', value: 'interactive', command: 'prlt execution config --set "outputMode interactive" --json' },
|
|
224
202
|
{ name: 'print - Show final result only (better for logs)', value: 'print', command: 'prlt execution config --set "outputMode print" --json' },
|
|
225
203
|
];
|
|
226
|
-
const { newOutput } = await this.
|
|
204
|
+
const { newOutput } = await this.prompt([
|
|
227
205
|
{
|
|
228
206
|
type: 'list',
|
|
229
207
|
name: 'newOutput',
|
|
@@ -241,7 +219,7 @@ export default class ExecutionConfig extends PMOCommand {
|
|
|
241
219
|
{ name: 'safe - Requires approval for dangerous operations (recommended)', value: 'true', command: 'prlt execution config --set "sandboxed true" --json' },
|
|
242
220
|
{ name: 'danger - Skip permission checks (--dangerously-skip-permissions)', value: 'false', command: 'prlt execution config --set "sandboxed false" --json' },
|
|
243
221
|
];
|
|
244
|
-
const { newPerm } = await this.
|
|
222
|
+
const { newPerm } = await this.prompt([
|
|
245
223
|
{
|
|
246
224
|
type: 'list',
|
|
247
225
|
name: 'newPerm',
|
|
@@ -265,7 +243,7 @@ export default class ExecutionConfig extends PMOCommand {
|
|
|
265
243
|
{ name: 'Warp', value: 'Warp', command: 'prlt execution config --set "terminal.app Warp" --json' },
|
|
266
244
|
{ name: 'tmux', value: 'tmux', command: 'prlt execution config --set "terminal.app tmux" --json' },
|
|
267
245
|
];
|
|
268
|
-
const { newApp } = await this.
|
|
246
|
+
const { newApp } = await this.prompt([
|
|
269
247
|
{
|
|
270
248
|
type: 'list',
|
|
271
249
|
name: 'newApp',
|
|
@@ -283,7 +261,7 @@ export default class ExecutionConfig extends PMOCommand {
|
|
|
283
261
|
{ name: 'Yes - Open tabs in background (don\'t steal focus)', value: 'true', command: 'prlt execution config --set "terminal.openInBackground true" --json' },
|
|
284
262
|
{ name: 'No - Bring terminal to foreground when opening tabs', value: 'false', command: 'prlt execution config --set "terminal.openInBackground false" --json' },
|
|
285
263
|
];
|
|
286
|
-
const { openInBg } = await this.
|
|
264
|
+
const { openInBg } = await this.prompt([
|
|
287
265
|
{
|
|
288
266
|
type: 'list',
|
|
289
267
|
name: 'openInBg',
|
|
@@ -302,7 +280,7 @@ export default class ExecutionConfig extends PMOCommand {
|
|
|
302
280
|
{ name: 'bash', value: 'bash', command: 'prlt execution config --set "shell bash" --json' },
|
|
303
281
|
{ name: 'fish', value: 'fish', command: 'prlt execution config --set "shell fish" --json' },
|
|
304
282
|
];
|
|
305
|
-
const { newShell } = await this.
|
|
283
|
+
const { newShell } = await this.prompt([
|
|
306
284
|
{
|
|
307
285
|
type: 'list',
|
|
308
286
|
name: 'newShell',
|
|
@@ -320,7 +298,7 @@ export default class ExecutionConfig extends PMOCommand {
|
|
|
320
298
|
{ name: 'Yes - Use tmux -CC for native iTerm integration', value: 'true', command: 'prlt execution config --set "tmux.controlMode true" --json' },
|
|
321
299
|
{ name: 'No - Standard tmux interface', value: 'false', command: 'prlt execution config --set "tmux.controlMode false" --json' },
|
|
322
300
|
];
|
|
323
|
-
const { controlMode } = await this.
|
|
301
|
+
const { controlMode } = await this.prompt([
|
|
324
302
|
{
|
|
325
303
|
type: 'list',
|
|
326
304
|
name: 'controlMode',
|
|
@@ -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',
|
|
@@ -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,26 @@ 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
|
+
}, createMetadata('execution view', flags));
|
|
112
108
|
}
|
|
113
109
|
// Display execution details
|
|
114
110
|
this.log('');
|
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,7 +18,10 @@ 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';
|
|
23
|
+
import { getWorkspaceInfo } from '../lib/agents/commands.js';
|
|
24
|
+
import { ExecutionStorage } from '../lib/execution/storage.js';
|
|
22
25
|
import { registerTicketTools, registerProjectTools, registerBoardTools, registerSpecTools, registerEpicTools, registerWorkTools, registerWorkflowTools, registerStatusTools, registerPhaseTools, registerActionTools, registerRoadmapTools, registerCategoryTools, registerTemplateTools, registerViewTools, registerDietTools, registerLabelTools, 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)';
|
|
@@ -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);
|
|
@@ -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
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Flags, Args } from '@oclif/core';
|
|
2
2
|
import * as fs from 'node:fs';
|
|
3
3
|
import * as path from 'node:path';
|
|
4
|
-
import inquirer from 'inquirer';
|
|
5
4
|
import { createBoardContent, createSpecFolders, PMOCommand, pmoBaseFlags, BUILTIN_TEMPLATES } from '../../lib/pmo/index.js';
|
|
6
5
|
import { styles } from '../../lib/styles.js';
|
|
7
6
|
import { slugify } from '../../lib/pmo/utils.js';
|
|
@@ -164,16 +163,16 @@ export default class ProjectCreate extends PMOCommand {
|
|
|
164
163
|
}
|
|
165
164
|
async promptProjectData(fields) {
|
|
166
165
|
// Build inquirer prompts from fields, adding validators and dynamic defaults
|
|
167
|
-
const answers = await
|
|
166
|
+
const answers = await this.prompt(fields.map(field => ({
|
|
168
167
|
...field,
|
|
169
168
|
validate: field.name === 'name'
|
|
170
|
-
? ((input) => input.length > 0 || 'Name is required')
|
|
169
|
+
? ((input) => String(input).length > 0 || 'Name is required')
|
|
171
170
|
: undefined,
|
|
172
171
|
// Dynamic default for id based on name
|
|
173
172
|
default: field.name === 'id'
|
|
174
173
|
? ((answers) => slugify(answers.name))
|
|
175
174
|
: field.default,
|
|
176
|
-
})));
|
|
175
|
+
})), null);
|
|
177
176
|
return {
|
|
178
177
|
name: answers.name,
|
|
179
178
|
id: answers.id || undefined,
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { Args, Flags } from '@oclif/core';
|
|
2
|
-
import inquirer from 'inquirer';
|
|
3
2
|
import { PMOCommand, pmoBaseFlags } from '../../lib/pmo/index.js';
|
|
4
3
|
import { styles } from '../../lib/styles.js';
|
|
5
4
|
import { shouldOutputJson, outputPromptAsJson, outputErrorAsJson, outputSuccessAsJson, createMetadata, buildFormPromptConfig, } from '../../lib/prompt-json.js';
|
|
@@ -66,12 +65,12 @@ export default class ProjectUpdate extends PMOCommand {
|
|
|
66
65
|
}, createMetadata('project update', flags));
|
|
67
66
|
return;
|
|
68
67
|
}
|
|
69
|
-
const { selectedProjectId } = await
|
|
68
|
+
const { selectedProjectId } = await this.prompt([{
|
|
70
69
|
type: 'list',
|
|
71
70
|
name: 'selectedProjectId',
|
|
72
71
|
message: 'Select project to update:',
|
|
73
72
|
choices: projectChoices,
|
|
74
|
-
}]);
|
|
73
|
+
}], null);
|
|
75
74
|
projectId = selectedProjectId;
|
|
76
75
|
}
|
|
77
76
|
// Get the project
|
|
@@ -103,12 +102,12 @@ export default class ProjectUpdate extends PMOCommand {
|
|
|
103
102
|
outputPromptAsJson(buildFormPromptConfig(fields), createMetadata('project update', flags));
|
|
104
103
|
return;
|
|
105
104
|
}
|
|
106
|
-
const answers = await
|
|
105
|
+
const answers = await this.prompt(fields.map(field => ({
|
|
107
106
|
...field,
|
|
108
107
|
validate: field.name === 'name'
|
|
109
|
-
? ((input) => input.length > 0 || 'Name is required')
|
|
108
|
+
? ((input) => String(input).length > 0 || 'Name is required')
|
|
110
109
|
: undefined,
|
|
111
|
-
})));
|
|
110
|
+
})), null);
|
|
112
111
|
newName = answers.name;
|
|
113
112
|
newDescription = answers.description;
|
|
114
113
|
}
|
package/dist/commands/pull.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Flags } from '@oclif/core';
|
|
2
2
|
import { PMOCommand, pmoBaseFlags } from '../lib/pmo/base-command.js';
|
|
3
|
+
import { shouldOutputJson } from '../lib/prompt-json.js';
|
|
3
4
|
import { styles, divider } from '../lib/styles.js';
|
|
4
5
|
import { loadDietConfig, formatDietConfig, } from '../lib/pmo/diet.js';
|
|
5
6
|
export default class Pull extends PMOCommand {
|
|
@@ -26,6 +27,7 @@ export default class Pull extends PMOCommand {
|
|
|
26
27
|
};
|
|
27
28
|
async execute() {
|
|
28
29
|
const { flags } = await this.parse(Pull);
|
|
30
|
+
const jsonMode = shouldOutputJson(flags);
|
|
29
31
|
const projectId = await this.requireProject();
|
|
30
32
|
const count = flags.count;
|
|
31
33
|
const dryRun = flags['dry-run'];
|
|
@@ -60,6 +62,28 @@ export default class Pull extends PMOCommand {
|
|
|
60
62
|
const existingReadyTickets = await this.storage.listTickets(projectId, { statusCategory: 'unstarted' });
|
|
61
63
|
// Run the pull algorithm
|
|
62
64
|
const result = await this.runPullAlgorithm(allBacklogTickets, existingReadyTickets, dietConfig, count);
|
|
65
|
+
// JSON output path
|
|
66
|
+
if (jsonMode) {
|
|
67
|
+
this.log(JSON.stringify({
|
|
68
|
+
type: 'success',
|
|
69
|
+
result: {
|
|
70
|
+
dryRun,
|
|
71
|
+
pulled: result.pulled,
|
|
72
|
+
skippedBlocked: result.skippedBlocked,
|
|
73
|
+
skippedCeiling: result.skippedCeiling,
|
|
74
|
+
totalCandidates: result.totalCandidates,
|
|
75
|
+
targetStatus: targetStatus.name,
|
|
76
|
+
}
|
|
77
|
+
}, null, 2));
|
|
78
|
+
// Still move tickets if not dry-run
|
|
79
|
+
if (!dryRun && result.pulled.length > 0) {
|
|
80
|
+
for (const ticket of result.pulled) {
|
|
81
|
+
// eslint-disable-next-line no-await-in-loop -- Sequential moves to maintain ordering
|
|
82
|
+
await this.storage.moveTicket(projectId, ticket.id, targetStatus.name);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
63
87
|
// Display results
|
|
64
88
|
this.displayPullResults(result, dietConfig, targetStatus, dryRun);
|
|
65
89
|
// Move tickets if not dry-run
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { PMOCommand } from '../../lib/pmo/index.js';
|
|
2
|
+
export default class SessionCreate extends PMOCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static args: {
|
|
6
|
+
name: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
7
|
+
};
|
|
8
|
+
static flags: {
|
|
9
|
+
command: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
|
+
detach: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
11
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
12
|
+
machine: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
13
|
+
project: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
14
|
+
};
|
|
15
|
+
protected getPMOOptions(): {
|
|
16
|
+
promptIfMultiple: boolean;
|
|
17
|
+
};
|
|
18
|
+
execute(): Promise<void>;
|
|
19
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { Args, Flags } from '@oclif/core';
|
|
2
|
+
import { execSync } from 'node:child_process';
|
|
3
|
+
import { styles } from '../../lib/styles.js';
|
|
4
|
+
import { PMOCommand, pmoBaseFlags } from '../../lib/pmo/index.js';
|
|
5
|
+
import { shouldOutputJson, outputSuccessAsJson, outputErrorAsJson, createMetadata, } from '../../lib/prompt-json.js';
|
|
6
|
+
export default class SessionCreate extends PMOCommand {
|
|
7
|
+
static description = 'Create a new tmux session';
|
|
8
|
+
static examples = [
|
|
9
|
+
'<%= config.bin %> <%= command.id %> my-session',
|
|
10
|
+
'<%= config.bin %> <%= command.id %> my-session --command "npm run dev"',
|
|
11
|
+
'<%= config.bin %> <%= command.id %> my-session --detach',
|
|
12
|
+
];
|
|
13
|
+
static args = {
|
|
14
|
+
name: Args.string({
|
|
15
|
+
description: 'Name for the new tmux session',
|
|
16
|
+
required: true,
|
|
17
|
+
}),
|
|
18
|
+
};
|
|
19
|
+
static flags = {
|
|
20
|
+
...pmoBaseFlags,
|
|
21
|
+
command: Flags.string({
|
|
22
|
+
char: 'c',
|
|
23
|
+
description: 'Initial command to run in the session',
|
|
24
|
+
}),
|
|
25
|
+
detach: Flags.boolean({
|
|
26
|
+
char: 'd',
|
|
27
|
+
description: 'Create session in detached mode (do not attach)',
|
|
28
|
+
default: false,
|
|
29
|
+
}),
|
|
30
|
+
};
|
|
31
|
+
getPMOOptions() {
|
|
32
|
+
return { promptIfMultiple: false };
|
|
33
|
+
}
|
|
34
|
+
async execute() {
|
|
35
|
+
const { args, flags } = await this.parse(SessionCreate);
|
|
36
|
+
const jsonMode = shouldOutputJson(flags);
|
|
37
|
+
const sessionName = args.name;
|
|
38
|
+
// Check if tmux is available
|
|
39
|
+
try {
|
|
40
|
+
execSync('which tmux', { stdio: 'pipe' });
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
if (jsonMode) {
|
|
44
|
+
outputErrorAsJson('TMUX_NOT_FOUND', 'tmux is not installed or not in PATH.', createMetadata('session create', flags));
|
|
45
|
+
}
|
|
46
|
+
this.error('tmux is not installed or not in PATH.');
|
|
47
|
+
}
|
|
48
|
+
// Check if a session with this name already exists
|
|
49
|
+
try {
|
|
50
|
+
execSync(`tmux has-session -t "${sessionName}" 2>/dev/null`, { stdio: 'pipe' });
|
|
51
|
+
// If we get here, session exists
|
|
52
|
+
if (jsonMode) {
|
|
53
|
+
outputErrorAsJson('SESSION_EXISTS', `A tmux session named "${sessionName}" already exists.`, createMetadata('session create', flags));
|
|
54
|
+
}
|
|
55
|
+
this.error(`A tmux session named "${sessionName}" already exists.`);
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
// Session doesn't exist, good to proceed
|
|
59
|
+
}
|
|
60
|
+
// Build the tmux new-session command
|
|
61
|
+
const tmuxArgs = ['tmux', 'new-session'];
|
|
62
|
+
// Always use detached mode for creation, then attach if needed
|
|
63
|
+
tmuxArgs.push('-d');
|
|
64
|
+
tmuxArgs.push('-s', `"${sessionName}"`);
|
|
65
|
+
if (flags.command) {
|
|
66
|
+
tmuxArgs.push(`"${flags.command}"`);
|
|
67
|
+
}
|
|
68
|
+
try {
|
|
69
|
+
execSync(tmuxArgs.join(' '), { stdio: 'pipe' });
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
const message = `Failed to create tmux session "${sessionName}": ${error instanceof Error ? error.message : error}`;
|
|
73
|
+
if (jsonMode) {
|
|
74
|
+
outputErrorAsJson('CREATE_FAILED', message, createMetadata('session create', flags));
|
|
75
|
+
}
|
|
76
|
+
this.error(message);
|
|
77
|
+
}
|
|
78
|
+
if (jsonMode) {
|
|
79
|
+
outputSuccessAsJson({
|
|
80
|
+
sessionName,
|
|
81
|
+
detached: flags.detach,
|
|
82
|
+
command: flags.command || null,
|
|
83
|
+
}, createMetadata('session create', flags));
|
|
84
|
+
}
|
|
85
|
+
this.log('');
|
|
86
|
+
this.log(styles.success(`Created tmux session: ${sessionName}`));
|
|
87
|
+
if (!flags.detach) {
|
|
88
|
+
this.log(styles.info(`Attaching to session: ${sessionName}`));
|
|
89
|
+
try {
|
|
90
|
+
execSync(`tmux attach -t "${sessionName}"`, { stdio: 'inherit' });
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
this.log(styles.muted(`Session "${sessionName}" is running in detached mode.`));
|
|
94
|
+
this.log(styles.muted(`Attach with: tmux attach -t "${sessionName}"`));
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
this.log(styles.muted(`Attach with: prlt session attach ${sessionName}`));
|
|
99
|
+
}
|
|
100
|
+
this.log('');
|
|
101
|
+
}
|
|
102
|
+
}
|