@proletariat/cli 0.3.34 → 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 +15 -3
- package/dist/commands/agent/auth.js +136 -15
- package/dist/commands/agent/index.js +11 -2
- package/dist/commands/agent/list.js +16 -7
- package/dist/commands/agent/staff/add.d.ts +1 -0
- package/dist/commands/agent/staff/add.js +1 -0
- package/dist/commands/agent/staff/index.d.ts +15 -0
- package/dist/commands/agent/staff/index.js +83 -0
- package/dist/commands/agent/staff/list.d.ts +1 -0
- package/dist/commands/agent/staff/list.js +1 -0
- package/dist/commands/agent/staff/remove.d.ts +1 -0
- package/dist/commands/agent/staff/remove.js +1 -0
- package/dist/commands/agent/status.js +32 -4
- package/dist/commands/agent/themes/add-names.d.ts +1 -0
- package/dist/commands/agent/themes/add-names.js +1 -0
- package/dist/commands/agent/themes/create.d.ts +1 -0
- package/dist/commands/agent/themes/create.js +1 -0
- package/dist/commands/agent/themes/index.d.ts +10 -0
- package/dist/commands/agent/themes/index.js +144 -0
- package/dist/commands/agent/themes/list.d.ts +1 -0
- package/dist/commands/agent/themes/list.js +1 -0
- package/dist/commands/agent/themes/set.d.ts +1 -0
- package/dist/commands/agent/themes/set.js +1 -0
- package/dist/commands/agents/themes/add-names.d.ts +1 -0
- package/dist/commands/agents/themes/add-names.js +1 -0
- package/dist/commands/agents/themes/create.d.ts +1 -0
- package/dist/commands/agents/themes/create.js +1 -0
- package/dist/commands/agents/themes/list.d.ts +1 -0
- package/dist/commands/agents/themes/list.js +1 -0
- 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.d.ts +20 -0
- package/dist/commands/label/create.js +57 -0
- package/dist/commands/label/delete.d.ts +17 -0
- package/dist/commands/label/delete.js +32 -0
- package/dist/commands/label/group/create.d.ts +20 -0
- package/dist/commands/label/group/create.js +55 -0
- package/dist/commands/label/group/list.d.ts +14 -0
- package/dist/commands/label/group/list.js +52 -0
- package/dist/commands/label/index.d.ts +15 -0
- package/dist/commands/label/index.js +58 -0
- package/dist/commands/label/list.d.ts +16 -0
- package/dist/commands/label/list.js +83 -0
- package/dist/commands/link/list.js +3 -2
- package/dist/commands/mcp-server.js +27 -1
- package/dist/commands/phase/template/apply.d.ts +26 -0
- package/dist/commands/phase/template/apply.js +14 -0
- package/dist/commands/phase/template/create.d.ts +23 -0
- package/dist/commands/phase/template/create.js +14 -0
- package/dist/commands/phase/template/delete.d.ts +18 -0
- package/dist/commands/phase/template/delete.js +61 -0
- package/dist/commands/phase/template/list.d.ts +17 -0
- package/dist/commands/phase/template/list.js +89 -0
- package/dist/commands/phase/template/update.d.ts +1 -0
- package/dist/commands/phase/template/update.js +1 -0
- package/dist/commands/priority/add.js +1 -1
- package/dist/commands/project/create.js +3 -4
- package/dist/commands/project/update.js +5 -8
- package/dist/commands/pull.js +24 -0
- package/dist/commands/roadmap/generate.js +1 -2
- package/dist/commands/session/create.d.ts +19 -0
- package/dist/commands/session/create.js +102 -0
- package/dist/commands/session/health.js +2 -21
- 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/link/depends.d.ts +18 -0
- package/dist/commands/spec/link/depends.js +86 -0
- package/dist/commands/spec/link/index.d.ts +17 -0
- package/dist/commands/spec/link/index.js +92 -0
- package/dist/commands/spec/link/remove.d.ts +18 -0
- package/dist/commands/spec/link/remove.js +90 -0
- package/dist/commands/spec/view.js +29 -0
- package/dist/commands/support/logs.js +2 -2
- package/dist/commands/template/apply.js +5 -4
- package/dist/commands/template/create.js +1 -1
- 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/link/block.d.ts +15 -0
- package/dist/commands/ticket/link/block.js +95 -0
- package/dist/commands/ticket/link/index.d.ts +14 -0
- package/dist/commands/ticket/link/index.js +96 -0
- package/dist/commands/ticket/list.d.ts +1 -0
- package/dist/commands/ticket/list.js +6 -0
- package/dist/commands/ticket/move.js +25 -2
- package/dist/commands/ticket/resolve.js +4 -5
- package/dist/commands/ticket/show.d.ts +13 -0
- package/dist/commands/ticket/show.js +16 -0
- package/dist/commands/ticket/template/apply.d.ts +26 -0
- package/dist/commands/ticket/template/apply.js +14 -0
- package/dist/commands/ticket/template/delete.d.ts +18 -0
- package/dist/commands/ticket/template/delete.js +61 -0
- package/dist/commands/ticket/template/list.d.ts +17 -0
- package/dist/commands/ticket/template/list.js +78 -0
- package/dist/commands/ticket/template/save.d.ts +17 -0
- package/dist/commands/ticket/template/save.js +97 -0
- package/dist/commands/ticket/view.js +30 -0
- package/dist/commands/work/index.js +4 -0
- package/dist/commands/work/ready.js +17 -0
- package/dist/commands/work/resolve.js +1 -1
- package/dist/commands/work/spawn.js +4 -4
- package/dist/commands/work/start.d.ts +1 -0
- package/dist/commands/work/start.js +203 -93
- 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/database/index.d.ts +1 -1
- package/dist/lib/database/index.js +20 -0
- package/dist/lib/execution/config.d.ts +15 -1
- package/dist/lib/execution/config.js +28 -0
- package/dist/lib/execution/devcontainer.js +3 -1
- package/dist/lib/execution/runners.d.ts +18 -2
- package/dist/lib/execution/runners.js +71 -29
- 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 +3 -0
- package/dist/lib/flags/resolver.js +1 -0
- package/dist/lib/mcp/helpers.d.ts +1 -2
- package/dist/lib/mcp/tools/board.js +4 -6
- package/dist/lib/mcp/tools/cli-passthrough.js +25 -6
- package/dist/lib/mcp/tools/diet.js +1 -0
- 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/label.d.ts +6 -0
- package/dist/lib/mcp/tools/label.js +338 -0
- package/dist/lib/mcp/tools/spec.js +1 -1
- package/dist/lib/mcp/tools/ticket.js +57 -19
- package/dist/lib/mcp/tools/work.js +96 -6
- package/dist/lib/mcp/types.d.ts +10 -0
- package/dist/lib/multiline-input.js +8 -19
- package/dist/lib/pmo/base-command.d.ts +0 -1
- package/dist/lib/pmo/base-command.js +4 -5
- package/dist/lib/pmo/schema.d.ts +6 -0
- package/dist/lib/pmo/schema.js +44 -0
- package/dist/lib/pmo/storage/actions.js +1 -1
- package/dist/lib/pmo/storage/base.d.ts +6 -0
- package/dist/lib/pmo/storage/base.js +311 -52
- package/dist/lib/pmo/storage/index.d.ts +23 -1
- package/dist/lib/pmo/storage/index.js +59 -1
- package/dist/lib/pmo/storage/labels.d.ts +55 -0
- package/dist/lib/pmo/storage/labels.js +346 -0
- package/dist/lib/pmo/storage/tickets.js +17 -0
- package/dist/lib/pmo/storage/types.d.ts +25 -0
- package/dist/lib/pmo/types.d.ts +44 -0
- package/dist/lib/pmo/utils.js +1 -1
- 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 +6399 -3799
- package/package.json +1 -1
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { Flags } from '@oclif/core';
|
|
2
|
+
import * as path from 'node:path';
|
|
3
|
+
import * as fs from 'node:fs';
|
|
4
|
+
import Database from 'better-sqlite3';
|
|
5
|
+
import { PromptCommand } from '../../lib/prompt-command.js';
|
|
6
|
+
import { machineOutputFlags } from '../../lib/pmo/index.js';
|
|
7
|
+
import { findHQRoot } from '../../lib/workspace.js';
|
|
8
|
+
import { getWorkspaceInfo } from '../../lib/agents/commands.js';
|
|
9
|
+
import { shouldOutputJson, outputErrorAsJson, outputSuccessAsJson, createMetadata, } from '../../lib/prompt-json.js';
|
|
10
|
+
import { styles } from '../../lib/styles.js';
|
|
11
|
+
import { DEFAULT_EXECUTION_CONFIG, } from '../../lib/execution/types.js';
|
|
12
|
+
import { runExecution } from '../../lib/execution/runners.js';
|
|
13
|
+
import { loadExecutionConfig, getTerminalApp, promptTerminalPreference, getShell, promptShellPreference, hasTerminalPreference, hasShellPreference, } from '../../lib/execution/config.js';
|
|
14
|
+
export default class Open extends PromptCommand {
|
|
15
|
+
static description = 'Open Claude Code in a new terminal tab (side-by-side workflow)';
|
|
16
|
+
static examples = [
|
|
17
|
+
'<%= config.bin %> <%= command.id %>',
|
|
18
|
+
'<%= config.bin %> <%= command.id %> --agent altman',
|
|
19
|
+
'<%= config.bin %> <%= command.id %> --directory /path/to/project',
|
|
20
|
+
'<%= config.bin %> <%= command.id %> --prompt "help me debug the auth flow"',
|
|
21
|
+
];
|
|
22
|
+
static flags = {
|
|
23
|
+
...machineOutputFlags,
|
|
24
|
+
agent: Flags.string({
|
|
25
|
+
char: 'a',
|
|
26
|
+
description: 'Open in an agent\'s workspace directory',
|
|
27
|
+
}),
|
|
28
|
+
directory: Flags.string({
|
|
29
|
+
char: 'C',
|
|
30
|
+
description: 'Directory to open in (default: current directory)',
|
|
31
|
+
}),
|
|
32
|
+
prompt: Flags.string({
|
|
33
|
+
char: 'p',
|
|
34
|
+
description: 'Initial prompt for Claude Code',
|
|
35
|
+
}),
|
|
36
|
+
};
|
|
37
|
+
async run() {
|
|
38
|
+
const { flags } = await this.parse(Open);
|
|
39
|
+
const jsonMode = shouldOutputJson(flags);
|
|
40
|
+
// Resolve the target directory
|
|
41
|
+
let workDir;
|
|
42
|
+
let label;
|
|
43
|
+
if (flags.agent) {
|
|
44
|
+
// Resolve agent workspace directory
|
|
45
|
+
let workspaceInfo;
|
|
46
|
+
try {
|
|
47
|
+
workspaceInfo = getWorkspaceInfo();
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
if (jsonMode) {
|
|
51
|
+
outputErrorAsJson('NO_WORKSPACE', 'Not in an HQ or workspace. --agent requires an HQ.', createMetadata('open', flags));
|
|
52
|
+
}
|
|
53
|
+
this.error('Not in an HQ or workspace. --agent requires an HQ.');
|
|
54
|
+
}
|
|
55
|
+
const agent = workspaceInfo.agents.find(a => a.name === flags.agent);
|
|
56
|
+
if (!agent) {
|
|
57
|
+
const available = workspaceInfo.agents.map(a => a.name).join(', ');
|
|
58
|
+
const msg = `Agent "${flags.agent}" not found. Available: ${available || 'none'}`;
|
|
59
|
+
if (jsonMode) {
|
|
60
|
+
outputErrorAsJson('AGENT_NOT_FOUND', msg, createMetadata('open', flags));
|
|
61
|
+
}
|
|
62
|
+
this.error(msg);
|
|
63
|
+
}
|
|
64
|
+
workDir = agent.type === 'ephemeral'
|
|
65
|
+
? path.join(workspaceInfo.path, 'agents', workspaceInfo.ephemeralAgentsDir, flags.agent)
|
|
66
|
+
: path.join(workspaceInfo.path, 'agents', workspaceInfo.persistentAgentsDir, flags.agent);
|
|
67
|
+
label = flags.agent;
|
|
68
|
+
}
|
|
69
|
+
else if (flags.directory) {
|
|
70
|
+
workDir = path.resolve(flags.directory);
|
|
71
|
+
label = path.basename(workDir);
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
workDir = process.cwd();
|
|
75
|
+
label = path.basename(workDir);
|
|
76
|
+
}
|
|
77
|
+
// Validate directory exists
|
|
78
|
+
if (!fs.existsSync(workDir)) {
|
|
79
|
+
if (jsonMode) {
|
|
80
|
+
outputErrorAsJson('DIRECTORY_NOT_FOUND', `Directory not found: ${workDir}`, createMetadata('open', flags));
|
|
81
|
+
}
|
|
82
|
+
this.error(`Directory not found: ${workDir}`);
|
|
83
|
+
}
|
|
84
|
+
// Build execution context
|
|
85
|
+
const sessionName = `open-${label}`;
|
|
86
|
+
const context = {
|
|
87
|
+
ticketId: 'OPEN',
|
|
88
|
+
ticketTitle: `Open: ${label}`,
|
|
89
|
+
agentName: label,
|
|
90
|
+
agentDir: workDir,
|
|
91
|
+
worktreePath: workDir,
|
|
92
|
+
branch: 'main',
|
|
93
|
+
actionName: 'open',
|
|
94
|
+
actionPrompt: flags.prompt,
|
|
95
|
+
modifiesCode: false,
|
|
96
|
+
};
|
|
97
|
+
// Try to find HQ for execution config, fall back to home dir config
|
|
98
|
+
const hqPath = findHQRoot(workDir);
|
|
99
|
+
if (hqPath) {
|
|
100
|
+
context.hqPath = hqPath;
|
|
101
|
+
}
|
|
102
|
+
// Load execution config
|
|
103
|
+
const executionConfig = { ...DEFAULT_EXECUTION_CONFIG };
|
|
104
|
+
executionConfig.outputMode = 'interactive';
|
|
105
|
+
executionConfig.sandboxed = false; // Default to dangerously-skip-permissions for quick open
|
|
106
|
+
// Try to load saved preferences from workspace DB or home dir
|
|
107
|
+
const dbPath = hqPath
|
|
108
|
+
? path.join(hqPath, '.proletariat', 'workspace.db')
|
|
109
|
+
: path.join(process.env.HOME || '', '.proletariat', 'adhoc.db');
|
|
110
|
+
let db = null;
|
|
111
|
+
try {
|
|
112
|
+
if (fs.existsSync(dbPath)) {
|
|
113
|
+
db = new Database(dbPath);
|
|
114
|
+
const savedConfig = loadExecutionConfig(db);
|
|
115
|
+
executionConfig.terminal = savedConfig.terminal;
|
|
116
|
+
executionConfig.shell = savedConfig.shell;
|
|
117
|
+
executionConfig.tmux = savedConfig.tmux;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
// Ignore config loading errors, use defaults
|
|
122
|
+
}
|
|
123
|
+
// If no terminal preference saved, prompt for it (first run only)
|
|
124
|
+
if (!jsonMode && db) {
|
|
125
|
+
if (!hasTerminalPreference(db)) {
|
|
126
|
+
executionConfig.terminal.app = await promptTerminalPreference(db);
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
executionConfig.terminal.app = await getTerminalApp(db);
|
|
130
|
+
}
|
|
131
|
+
if (!hasShellPreference(db)) {
|
|
132
|
+
executionConfig.shell = await promptShellPreference(db);
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
executionConfig.shell = await getShell(db);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
if (db) {
|
|
139
|
+
db.close();
|
|
140
|
+
}
|
|
141
|
+
// Show what we're doing
|
|
142
|
+
if (!jsonMode) {
|
|
143
|
+
this.log('');
|
|
144
|
+
this.log(styles.muted(` Opening Claude Code in new tab...`));
|
|
145
|
+
this.log(styles.muted(` Directory: ${workDir}`));
|
|
146
|
+
if (flags.prompt) {
|
|
147
|
+
this.log(styles.muted(` Prompt: "${flags.prompt.substring(0, 60)}${flags.prompt.length > 60 ? '...' : ''}"`));
|
|
148
|
+
}
|
|
149
|
+
this.log('');
|
|
150
|
+
}
|
|
151
|
+
// Launch Claude Code in a new terminal tab
|
|
152
|
+
const result = await runExecution('host', context, 'claude-code', executionConfig, {
|
|
153
|
+
displayMode: 'terminal',
|
|
154
|
+
});
|
|
155
|
+
if (result.success) {
|
|
156
|
+
if (jsonMode) {
|
|
157
|
+
outputSuccessAsJson({
|
|
158
|
+
directory: workDir,
|
|
159
|
+
sessionId: result.sessionId,
|
|
160
|
+
sessionName,
|
|
161
|
+
}, createMetadata('open', flags));
|
|
162
|
+
}
|
|
163
|
+
this.log(styles.success(`✓ Claude Code opened in new tab`));
|
|
164
|
+
if (result.sessionId) {
|
|
165
|
+
this.log(styles.muted(` Session: ${result.sessionId}`));
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
if (jsonMode) {
|
|
170
|
+
outputErrorAsJson('EXECUTION_FAILED', `Failed to open: ${result.error}`, createMetadata('open', flags));
|
|
171
|
+
}
|
|
172
|
+
this.error(`Failed to open: ${result.error}`);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
package/dist/commands/diet.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, saveDietConfig, parseDietString, formatDietConfig, } from '../lib/pmo/diet.js';
|
|
5
6
|
export default class Diet extends PMOCommand {
|
|
@@ -23,6 +24,7 @@ export default class Diet extends PMOCommand {
|
|
|
23
24
|
};
|
|
24
25
|
async execute() {
|
|
25
26
|
const { flags } = await this.parse(Diet);
|
|
27
|
+
const jsonMode = shouldOutputJson(flags);
|
|
26
28
|
const projectId = await this.requireProject();
|
|
27
29
|
const db = this.storage.getDatabase();
|
|
28
30
|
// Handle --set
|
|
@@ -30,7 +32,12 @@ export default class Diet extends PMOCommand {
|
|
|
30
32
|
try {
|
|
31
33
|
const newConfig = parseDietString(flags.set);
|
|
32
34
|
saveDietConfig(db, newConfig);
|
|
33
|
-
|
|
35
|
+
if (jsonMode) {
|
|
36
|
+
this.log(JSON.stringify({ type: 'success', result: { action: 'set', diet: newConfig } }, null, 2));
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
this.log(styles.success(`Diet updated: ${formatDietConfig(newConfig)}`));
|
|
40
|
+
}
|
|
34
41
|
}
|
|
35
42
|
catch (error) {
|
|
36
43
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -42,12 +49,21 @@ export default class Diet extends PMOCommand {
|
|
|
42
49
|
if (flags.reset) {
|
|
43
50
|
const { DEFAULT_DIET_CONFIG } = await import('../lib/pmo/diet.js');
|
|
44
51
|
saveDietConfig(db, DEFAULT_DIET_CONFIG);
|
|
45
|
-
|
|
52
|
+
if (jsonMode) {
|
|
53
|
+
this.log(JSON.stringify({ type: 'success', result: { action: 'reset', diet: DEFAULT_DIET_CONFIG } }, null, 2));
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
this.log(styles.success(`Diet reset to defaults: ${formatDietConfig(DEFAULT_DIET_CONFIG)}`));
|
|
57
|
+
}
|
|
46
58
|
return;
|
|
47
59
|
}
|
|
48
60
|
// Show diet report
|
|
49
61
|
const dietConfig = loadDietConfig(db);
|
|
50
62
|
const report = await this.buildDietReport(projectId, dietConfig);
|
|
63
|
+
if (jsonMode) {
|
|
64
|
+
this.log(JSON.stringify({ type: 'success', result: { diet: dietConfig, report } }, null, 2));
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
51
67
|
this.displayDietReport(report, dietConfig);
|
|
52
68
|
}
|
|
53
69
|
/**
|
|
@@ -8,6 +8,7 @@ import { ExecutionStorage } from '../../lib/execution/storage.js';
|
|
|
8
8
|
import { isDockerRunning } from '../../lib/execution/runners.js';
|
|
9
9
|
import { resolveContainerId } from '../../lib/docker/resolve.js';
|
|
10
10
|
import { machineOutputFlags } from '../../lib/pmo/index.js';
|
|
11
|
+
import { shouldOutputJson } from '../../lib/prompt-json.js';
|
|
11
12
|
export default class DockerLogs extends Command {
|
|
12
13
|
static description = 'View logs from a container (by execution ID, agent name, or container ID)';
|
|
13
14
|
static examples = [
|
|
@@ -42,6 +43,7 @@ export default class DockerLogs extends Command {
|
|
|
42
43
|
};
|
|
43
44
|
async run() {
|
|
44
45
|
const { args, flags } = await this.parse(DockerLogs);
|
|
46
|
+
const jsonMode = shouldOutputJson(flags);
|
|
45
47
|
if (!isDockerRunning()) {
|
|
46
48
|
this.error('Docker is not running. Start Docker Desktop or the Docker daemon first.');
|
|
47
49
|
}
|
|
@@ -81,9 +83,11 @@ export default class DockerLogs extends Command {
|
|
|
81
83
|
dockerArgs.push('--timestamps');
|
|
82
84
|
}
|
|
83
85
|
dockerArgs.push(result.containerId);
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
86
|
+
if (!jsonMode) {
|
|
87
|
+
this.log(`\n${styles.header(`Logs for ${result.displayName}`)}`);
|
|
88
|
+
this.log(styles.muted(`Container: ${result.containerId}`));
|
|
89
|
+
this.log('─'.repeat(60) + '\n');
|
|
90
|
+
}
|
|
87
91
|
db.close();
|
|
88
92
|
if (flags.follow) {
|
|
89
93
|
// Stream logs
|
|
@@ -8,6 +8,7 @@ import { ExecutionStorage } from '../../lib/execution/storage.js';
|
|
|
8
8
|
import { isDockerRunning } from '../../lib/execution/runners.js';
|
|
9
9
|
import { resolveContainerId, isContainerRunning } from '../../lib/docker/resolve.js';
|
|
10
10
|
import { machineOutputFlags } from '../../lib/pmo/index.js';
|
|
11
|
+
import { shouldOutputJson } from '../../lib/prompt-json.js';
|
|
11
12
|
export default class DockerShell extends Command {
|
|
12
13
|
static description = 'Open a shell in a running container (by execution ID, agent name, or container ID)';
|
|
13
14
|
static examples = [
|
|
@@ -39,6 +40,11 @@ export default class DockerShell extends Command {
|
|
|
39
40
|
};
|
|
40
41
|
async run() {
|
|
41
42
|
const { args, flags } = await this.parse(DockerShell);
|
|
43
|
+
if (shouldOutputJson(flags)) {
|
|
44
|
+
this.log(JSON.stringify({ type: 'error', error: { code: 'REQUIRES_TTY', message: 'docker shell requires an interactive terminal' } }));
|
|
45
|
+
this.exit(1);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
42
48
|
if (!isDockerRunning()) {
|
|
43
49
|
this.error('Docker is not running. Start Docker Desktop or the Docker daemon first.');
|
|
44
50
|
}
|
|
@@ -8,6 +8,7 @@ import { ExecutionStorage } from '../../lib/execution/storage.js';
|
|
|
8
8
|
import { isDockerRunning } from '../../lib/execution/runners.js';
|
|
9
9
|
import { resolveContainerId, isContainerRunning, sanitizeContainerId } from '../../lib/docker/resolve.js';
|
|
10
10
|
import { machineOutputFlags } from '../../lib/pmo/index.js';
|
|
11
|
+
import { shouldOutputJson } from '../../lib/prompt-json.js';
|
|
11
12
|
export default class DockerStart extends Command {
|
|
12
13
|
static description = 'Start a stopped container (by execution ID, agent name, or container ID)';
|
|
13
14
|
static examples = [
|
|
@@ -31,6 +32,7 @@ export default class DockerStart extends Command {
|
|
|
31
32
|
};
|
|
32
33
|
async run() {
|
|
33
34
|
const { args, flags } = await this.parse(DockerStart);
|
|
35
|
+
const jsonMode = shouldOutputJson(flags);
|
|
34
36
|
if (!isDockerRunning()) {
|
|
35
37
|
this.error('Docker is not running. Start Docker Desktop or the Docker daemon first.');
|
|
36
38
|
}
|
|
@@ -60,15 +62,24 @@ export default class DockerStart extends Command {
|
|
|
60
62
|
}
|
|
61
63
|
// Check if container is already running
|
|
62
64
|
if (isContainerRunning(result.containerId)) {
|
|
65
|
+
if (jsonMode) {
|
|
66
|
+
this.log(JSON.stringify({ type: 'success', result: { containerId: result.containerId, displayName: result.displayName, executionId: result.executionId, status: 'already_running' } }, null, 2));
|
|
67
|
+
db.close();
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
63
70
|
this.log(`\n${styles.warning(`Container ${result.displayName} is already running`)}\n`);
|
|
64
71
|
db.close();
|
|
65
72
|
return;
|
|
66
73
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
74
|
+
if (!jsonMode) {
|
|
75
|
+
this.log(`\n${styles.header('Start Container')}`);
|
|
76
|
+
this.log(styles.muted(`Target: ${result.displayName}`));
|
|
77
|
+
this.log(styles.muted(`Container: ${result.containerId.substring(0, 12)}\n`));
|
|
78
|
+
}
|
|
70
79
|
// Start container
|
|
71
|
-
|
|
80
|
+
if (!jsonMode) {
|
|
81
|
+
this.log(styles.muted('Starting container...'));
|
|
82
|
+
}
|
|
72
83
|
try {
|
|
73
84
|
const attachFlag = flags.attach ? '-a' : '';
|
|
74
85
|
const safeId = sanitizeContainerId(result.containerId);
|
|
@@ -79,6 +90,11 @@ export default class DockerStart extends Command {
|
|
|
79
90
|
if (result.executionId) {
|
|
80
91
|
executionStorage.updateStatus(result.executionId, 'running');
|
|
81
92
|
}
|
|
93
|
+
if (jsonMode) {
|
|
94
|
+
this.log(JSON.stringify({ type: 'success', result: { containerId: result.containerId, displayName: result.displayName, executionId: result.executionId, status: 'started' } }, null, 2));
|
|
95
|
+
db.close();
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
82
98
|
this.log(`${styles.success('Container started successfully')}\n`);
|
|
83
99
|
}
|
|
84
100
|
catch (error) {
|
|
@@ -2,6 +2,10 @@ import { Command } from '@oclif/core';
|
|
|
2
2
|
export default class DockerSync extends Command {
|
|
3
3
|
static description: string;
|
|
4
4
|
static examples: string[];
|
|
5
|
+
static flags: {
|
|
6
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
7
|
+
machine: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
8
|
+
};
|
|
5
9
|
run(): Promise<void>;
|
|
6
10
|
/**
|
|
7
11
|
* Get raw container info from Docker
|
|
@@ -7,12 +7,19 @@ import { getWorkspaceInfo } from '../../lib/agents/commands.js';
|
|
|
7
7
|
import { ContainerStorage } from '../../lib/execution/storage.js';
|
|
8
8
|
import { isDockerRunning } from '../../lib/execution/runners.js';
|
|
9
9
|
import { visualPadEnd } from '../../lib/string-utils.js';
|
|
10
|
+
import { shouldOutputJson } from '../../lib/prompt-json.js';
|
|
11
|
+
import { machineOutputFlags } from '../../lib/pmo/index.js';
|
|
10
12
|
export default class DockerSync extends Command {
|
|
11
13
|
static description = 'Sync container status from Docker into the database';
|
|
12
14
|
static examples = [
|
|
13
15
|
'<%= config.bin %> <%= command.id %>',
|
|
14
16
|
];
|
|
17
|
+
static flags = {
|
|
18
|
+
...machineOutputFlags,
|
|
19
|
+
};
|
|
15
20
|
async run() {
|
|
21
|
+
const { flags } = await this.parse(DockerSync);
|
|
22
|
+
const jsonMode = shouldOutputJson(flags);
|
|
16
23
|
if (!isDockerRunning()) {
|
|
17
24
|
this.error('Docker is not running. Start Docker Desktop or the Docker daemon first.');
|
|
18
25
|
}
|
|
@@ -37,8 +44,10 @@ export default class DockerSync extends Command {
|
|
|
37
44
|
const containerStorage = new ContainerStorage(db);
|
|
38
45
|
// Get devcontainers from Docker
|
|
39
46
|
const dockerContainers = this.getDockerContainers();
|
|
40
|
-
|
|
41
|
-
|
|
47
|
+
if (!jsonMode) {
|
|
48
|
+
this.log(`\n${styles.header('Syncing Containers')}`);
|
|
49
|
+
this.log(styles.muted(`Found ${dockerContainers.length} devcontainers in Docker\n`));
|
|
50
|
+
}
|
|
42
51
|
// Add agent name from image (only used for new containers)
|
|
43
52
|
const containersWithAgent = dockerContainers.map(c => ({
|
|
44
53
|
...c,
|
|
@@ -46,6 +55,25 @@ export default class DockerSync extends Command {
|
|
|
46
55
|
}));
|
|
47
56
|
// Sync with database
|
|
48
57
|
const result = containerStorage.syncFromDocker(containersWithAgent);
|
|
58
|
+
if (jsonMode) {
|
|
59
|
+
const containers = containerStorage.listContainers({ limit: 20 });
|
|
60
|
+
this.log(JSON.stringify({
|
|
61
|
+
type: 'success',
|
|
62
|
+
result: {
|
|
63
|
+
added: result.added,
|
|
64
|
+
updated: result.updated,
|
|
65
|
+
removed: result.removed,
|
|
66
|
+
containers: containers.map(c => ({
|
|
67
|
+
id: c.id,
|
|
68
|
+
agentName: c.agentName,
|
|
69
|
+
status: c.status,
|
|
70
|
+
dockerId: c.dockerId,
|
|
71
|
+
})),
|
|
72
|
+
},
|
|
73
|
+
}, null, 2));
|
|
74
|
+
db.close();
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
49
77
|
this.log(styles.success('✓ Sync complete'));
|
|
50
78
|
this.log(styles.muted(` Added: ${result.added}`));
|
|
51
79
|
this.log(styles.muted(` Updated: ${result.updated}`));
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import EpicView from './view.js';
|
|
2
|
+
export default class EpicShow extends EpicView {
|
|
3
|
+
static description: string;
|
|
4
|
+
static hidden: boolean;
|
|
5
|
+
static args: {
|
|
6
|
+
id: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
7
|
+
};
|
|
8
|
+
static flags: {
|
|
9
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
|
+
machine: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
11
|
+
project: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Args } from '@oclif/core';
|
|
2
|
+
import { pmoBaseFlags } from '../../lib/pmo/index.js';
|
|
3
|
+
import EpicView from './view.js';
|
|
4
|
+
export default class EpicShow extends EpicView {
|
|
5
|
+
static description = 'View epic details and linked tickets (alias for epic view)';
|
|
6
|
+
static hidden = true;
|
|
7
|
+
static args = {
|
|
8
|
+
id: Args.string({
|
|
9
|
+
description: 'Epic ID',
|
|
10
|
+
required: false,
|
|
11
|
+
}),
|
|
12
|
+
};
|
|
13
|
+
static flags = {
|
|
14
|
+
...pmoBaseFlags,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
@@ -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
|
|
@@ -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',
|