@proletariat/cli 0.3.23 → 0.3.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/action/create.js +4 -4
- package/dist/commands/action/update.js +3 -3
- package/dist/commands/agent/{temp/cleanup.d.ts → cleanup.d.ts} +1 -1
- package/dist/commands/agent/{temp/cleanup.js → cleanup.js} +4 -4
- package/dist/commands/agent/index.js +8 -8
- package/dist/commands/branch/create.js +2 -2
- package/dist/commands/epic/activate.js +9 -17
- package/dist/commands/epic/archive.js +13 -24
- package/dist/commands/epic/create.d.ts +1 -0
- package/dist/commands/epic/create.js +46 -8
- package/dist/commands/epic/index.js +2 -2
- package/dist/commands/epic/move.js +28 -47
- package/dist/commands/epic/progress.js +10 -14
- package/dist/commands/epic/project.js +42 -59
- package/dist/commands/epic/reorder.js +25 -30
- package/dist/commands/epic/spec.d.ts +1 -0
- package/dist/commands/epic/spec.js +39 -40
- package/dist/commands/epic/ticket.d.ts +2 -0
- package/dist/commands/epic/ticket.js +63 -37
- package/dist/commands/feedback/index.d.ts +10 -0
- package/dist/commands/feedback/index.js +60 -0
- package/dist/commands/feedback/list.d.ts +12 -0
- package/dist/commands/feedback/list.js +126 -0
- package/dist/commands/feedback/submit.d.ts +16 -0
- package/dist/commands/feedback/submit.js +220 -0
- package/dist/commands/{template/phase/delete.d.ts → feedback/view.d.ts} +7 -5
- package/dist/commands/feedback/view.js +109 -0
- package/dist/commands/gh/index.js +4 -0
- package/dist/commands/{epic/link/remove.d.ts → link/create.d.ts} +6 -7
- package/dist/commands/link/create.js +141 -0
- package/dist/commands/{epic/link/relates.d.ts → link/index.d.ts} +4 -5
- package/dist/commands/link/index.js +87 -0
- package/dist/commands/{epic/link/duplicates.d.ts → link/list.d.ts} +7 -4
- package/dist/commands/link/list.js +182 -0
- package/dist/commands/{spec/link → link}/remove.d.ts +4 -5
- package/dist/commands/link/remove.js +120 -0
- package/dist/commands/mcp-server.d.ts +22 -0
- package/dist/commands/mcp-server.js +98 -0
- package/dist/commands/phase/create.js +1 -1
- package/dist/commands/project/create.d.ts +1 -0
- package/dist/commands/project/create.js +38 -4
- package/dist/commands/repo/create.d.ts +38 -0
- package/dist/commands/repo/create.js +283 -0
- package/dist/commands/repo/index.js +7 -0
- package/dist/commands/roadmap/add-project.js +9 -22
- package/dist/commands/roadmap/create.d.ts +0 -1
- package/dist/commands/roadmap/create.js +46 -40
- package/dist/commands/roadmap/delete.js +10 -24
- package/dist/commands/roadmap/generate.d.ts +1 -0
- package/dist/commands/roadmap/generate.js +21 -22
- package/dist/commands/roadmap/remove-project.js +14 -34
- package/dist/commands/roadmap/reorder.js +19 -26
- package/dist/commands/roadmap/update.js +27 -26
- package/dist/commands/roadmap/view.js +5 -12
- package/dist/commands/session/attach.d.ts +1 -8
- package/dist/commands/session/attach.js +93 -59
- package/dist/commands/session/list.d.ts +0 -8
- package/dist/commands/session/list.js +130 -81
- package/dist/commands/spec/create.d.ts +1 -0
- package/dist/commands/spec/create.js +44 -3
- package/dist/commands/spec/edit.js +63 -33
- package/dist/commands/spec/index.js +2 -2
- package/dist/commands/{agent/staff → staff}/add.js +10 -10
- package/dist/commands/{agent/staff → staff}/index.d.ts +1 -1
- package/dist/commands/{agent/staff → staff}/index.js +7 -7
- package/dist/commands/{agent/staff → staff}/list.js +3 -3
- package/dist/commands/{agent/staff → staff}/remove.d.ts +1 -1
- package/dist/commands/{agent/staff → staff}/remove.js +8 -8
- package/dist/commands/{template/phase/index.d.ts → support/book.d.ts} +2 -2
- package/dist/commands/support/book.js +54 -0
- package/dist/commands/{template/ticket/index.d.ts → support/discord.d.ts} +2 -2
- package/dist/commands/support/discord.js +54 -0
- package/dist/commands/support/docs.d.ts +10 -0
- package/dist/commands/support/docs.js +54 -0
- package/dist/commands/support/index.d.ts +19 -0
- package/dist/commands/support/index.js +81 -0
- package/dist/commands/support/issues.d.ts +11 -0
- package/dist/commands/support/issues.js +77 -0
- package/dist/commands/support/logs.d.ts +18 -0
- package/dist/commands/support/logs.js +247 -0
- package/dist/commands/{ticket/template → template}/apply.d.ts +8 -6
- package/dist/commands/template/apply.js +262 -0
- package/dist/commands/{ticket/template → template}/create.d.ts +5 -6
- package/dist/commands/template/create.js +238 -0
- package/dist/commands/template/index.js +48 -36
- package/dist/commands/{ticket/template → template}/save.d.ts +2 -2
- package/dist/commands/template/save.js +104 -0
- package/dist/commands/{phase/template → template}/update.d.ts +2 -2
- package/dist/commands/template/update.js +99 -0
- package/dist/commands/{agent/themes → theme}/add-names.d.ts +1 -1
- package/dist/commands/{agent/themes → theme}/add-names.js +6 -6
- package/dist/commands/{agent/themes → theme}/create.d.ts +1 -1
- package/dist/commands/{agent/themes → theme}/create.js +5 -5
- package/dist/commands/{agent/themes → theme}/index.d.ts +1 -1
- package/dist/commands/{agent/themes → theme}/index.js +10 -10
- package/dist/commands/{agent/themes → theme}/list.d.ts +1 -1
- package/dist/commands/{agent/themes → theme}/list.js +5 -5
- package/dist/commands/{agent/themes → theme}/set.d.ts +1 -1
- package/dist/commands/{agent/themes → theme}/set.js +7 -7
- package/dist/commands/ticket/create.d.ts +1 -0
- package/dist/commands/ticket/create.js +75 -15
- package/dist/commands/ticket/edit.js +44 -13
- package/dist/commands/ticket/index.js +6 -6
- package/dist/commands/ticket/move.d.ts +7 -0
- package/dist/commands/ticket/move.js +132 -0
- package/dist/commands/work/spawn.d.ts +1 -0
- package/dist/commands/work/spawn.js +72 -8
- package/dist/commands/work/start.js +6 -0
- package/dist/lib/execution/runners.js +21 -17
- package/dist/lib/execution/session-utils.d.ts +60 -0
- package/dist/lib/execution/session-utils.js +162 -0
- package/dist/lib/execution/spawner.d.ts +2 -0
- package/dist/lib/execution/spawner.js +42 -0
- package/dist/lib/flags/resolver.d.ts +2 -2
- package/dist/lib/flags/resolver.js +15 -0
- package/dist/lib/init/index.js +18 -0
- package/dist/lib/mcp/helpers.d.ts +43 -0
- package/dist/lib/mcp/helpers.js +57 -0
- package/dist/lib/mcp/index.d.ts +6 -0
- package/dist/lib/mcp/index.js +6 -0
- package/dist/lib/mcp/tools/action.d.ts +6 -0
- package/dist/lib/mcp/tools/action.js +88 -0
- package/dist/lib/mcp/tools/board.d.ts +6 -0
- package/dist/lib/mcp/tools/board.js +139 -0
- package/dist/lib/mcp/tools/category.d.ts +6 -0
- package/dist/lib/mcp/tools/category.js +84 -0
- package/dist/lib/mcp/tools/cli-passthrough.d.ts +15 -0
- package/dist/lib/mcp/tools/cli-passthrough.js +333 -0
- package/dist/lib/mcp/tools/epic.d.ts +6 -0
- package/dist/lib/mcp/tools/epic.js +178 -0
- package/dist/lib/mcp/tools/index.d.ts +18 -0
- package/dist/lib/mcp/tools/index.js +19 -0
- package/dist/lib/mcp/tools/phase.d.ts +6 -0
- package/dist/lib/mcp/tools/phase.js +131 -0
- package/dist/lib/mcp/tools/project.d.ts +6 -0
- package/dist/lib/mcp/tools/project.js +196 -0
- package/dist/lib/mcp/tools/roadmap.d.ts +6 -0
- package/dist/lib/mcp/tools/roadmap.js +123 -0
- package/dist/lib/mcp/tools/spec.d.ts +6 -0
- package/dist/lib/mcp/tools/spec.js +196 -0
- package/dist/lib/mcp/tools/status.d.ts +6 -0
- package/dist/lib/mcp/tools/status.js +109 -0
- package/dist/lib/mcp/tools/template.d.ts +6 -0
- package/dist/lib/mcp/tools/template.js +107 -0
- package/dist/lib/mcp/tools/ticket.d.ts +6 -0
- package/dist/lib/mcp/tools/ticket.js +393 -0
- package/dist/lib/mcp/tools/view.d.ts +6 -0
- package/dist/lib/mcp/tools/view.js +76 -0
- package/dist/lib/mcp/tools/work.d.ts +6 -0
- package/dist/lib/mcp/tools/work.js +132 -0
- package/dist/lib/mcp/tools/workflow.d.ts +6 -0
- package/dist/lib/mcp/tools/workflow.js +95 -0
- package/dist/lib/mcp/types.d.ts +17 -0
- package/dist/lib/mcp/types.js +4 -0
- package/dist/lib/multiline-input.d.ts +63 -0
- package/dist/lib/multiline-input.js +360 -0
- package/dist/lib/prompt-json.d.ts +57 -6
- package/dist/lib/prompt-json.js +45 -0
- package/dist/lib/repos/git.d.ts +7 -0
- package/dist/lib/repos/git.js +20 -0
- package/oclif.manifest.json +3690 -4995
- package/package.json +6 -4
- package/dist/commands/agent/temp/index.d.ts +0 -14
- package/dist/commands/agent/temp/index.js +0 -85
- package/dist/commands/agent/temp/list.d.ts +0 -7
- package/dist/commands/agent/temp/list.js +0 -108
- package/dist/commands/epic/link/block.d.ts +0 -14
- package/dist/commands/epic/link/block.js +0 -81
- package/dist/commands/epic/link/duplicates.js +0 -68
- package/dist/commands/epic/link/index.d.ts +0 -19
- package/dist/commands/epic/link/index.js +0 -272
- package/dist/commands/epic/link/relates.js +0 -68
- package/dist/commands/epic/link/remove.js +0 -93
- package/dist/commands/phase/template/apply.d.ts +0 -17
- package/dist/commands/phase/template/apply.js +0 -108
- package/dist/commands/phase/template/create.d.ts +0 -17
- package/dist/commands/phase/template/create.js +0 -104
- package/dist/commands/phase/template/delete.d.ts +0 -17
- package/dist/commands/phase/template/delete.js +0 -100
- package/dist/commands/phase/template/index.d.ts +0 -15
- package/dist/commands/phase/template/index.js +0 -130
- package/dist/commands/phase/template/list.d.ts +0 -16
- package/dist/commands/phase/template/list.js +0 -97
- package/dist/commands/phase/template/update.js +0 -89
- package/dist/commands/spec/link/depends.d.ts +0 -14
- package/dist/commands/spec/link/depends.js +0 -64
- package/dist/commands/spec/link/duplicates.d.ts +0 -14
- package/dist/commands/spec/link/duplicates.js +0 -63
- package/dist/commands/spec/link/index.d.ts +0 -19
- package/dist/commands/spec/link/index.js +0 -207
- package/dist/commands/spec/link/relates.d.ts +0 -14
- package/dist/commands/spec/link/relates.js +0 -63
- package/dist/commands/spec/link/remove.js +0 -96
- package/dist/commands/template/phase/apply.d.ts +0 -14
- package/dist/commands/template/phase/apply.js +0 -43
- package/dist/commands/template/phase/create.d.ts +0 -13
- package/dist/commands/template/phase/create.js +0 -38
- package/dist/commands/template/phase/delete.js +0 -36
- package/dist/commands/template/phase/index.js +0 -63
- package/dist/commands/template/phase/list.d.ts +0 -11
- package/dist/commands/template/phase/list.js +0 -36
- package/dist/commands/template/phase/update.d.ts +0 -14
- package/dist/commands/template/phase/update.js +0 -43
- package/dist/commands/template/ticket/apply.d.ts +0 -17
- package/dist/commands/template/ticket/apply.js +0 -60
- package/dist/commands/template/ticket/create.d.ts +0 -20
- package/dist/commands/template/ticket/create.js +0 -89
- package/dist/commands/template/ticket/delete.d.ts +0 -13
- package/dist/commands/template/ticket/delete.js +0 -38
- package/dist/commands/template/ticket/index.js +0 -63
- package/dist/commands/template/ticket/list.d.ts +0 -11
- package/dist/commands/template/ticket/list.js +0 -36
- package/dist/commands/template/ticket/save.d.ts +0 -15
- package/dist/commands/template/ticket/save.js +0 -46
- package/dist/commands/ticket/link/block.d.ts +0 -14
- package/dist/commands/ticket/link/block.js +0 -96
- package/dist/commands/ticket/link/duplicates.d.ts +0 -14
- package/dist/commands/ticket/link/duplicates.js +0 -95
- package/dist/commands/ticket/link/index.d.ts +0 -19
- package/dist/commands/ticket/link/index.js +0 -256
- package/dist/commands/ticket/link/relates.d.ts +0 -14
- package/dist/commands/ticket/link/relates.js +0 -95
- package/dist/commands/ticket/link/remove.d.ts +0 -16
- package/dist/commands/ticket/link/remove.js +0 -132
- package/dist/commands/ticket/template/apply.js +0 -252
- package/dist/commands/ticket/template/create.js +0 -386
- package/dist/commands/ticket/template/delete.d.ts +0 -17
- package/dist/commands/ticket/template/delete.js +0 -94
- package/dist/commands/ticket/template/index.d.ts +0 -15
- package/dist/commands/ticket/template/index.js +0 -120
- package/dist/commands/ticket/template/list.d.ts +0 -16
- package/dist/commands/ticket/template/list.js +0 -112
- package/dist/commands/ticket/template/save.js +0 -163
- /package/dist/commands/{agent/staff → staff}/add.d.ts +0 -0
- /package/dist/commands/{agent/staff → staff}/list.d.ts +0 -0
|
@@ -21,7 +21,7 @@ export default class ActionCreate extends PMOCommand {
|
|
|
21
21
|
...pmoBaseFlags,
|
|
22
22
|
prompt: Flags.string({
|
|
23
23
|
char: 'p',
|
|
24
|
-
description: 'The prompt to send to the agent',
|
|
24
|
+
description: 'The prompt to send to the agent [required for non-interactive]',
|
|
25
25
|
}),
|
|
26
26
|
description: Flags.string({
|
|
27
27
|
char: 'd',
|
|
@@ -85,11 +85,11 @@ export default class ActionCreate extends PMOCommand {
|
|
|
85
85
|
requiredFields: ['name (as first argument)', '--prompt'],
|
|
86
86
|
},
|
|
87
87
|
});
|
|
88
|
-
// Prompt input (
|
|
88
|
+
// Prompt input (multiline for inline text input)
|
|
89
89
|
resolver.addPrompt({
|
|
90
90
|
flagName: 'prompt',
|
|
91
|
-
type: '
|
|
92
|
-
message: 'Prompt (
|
|
91
|
+
type: 'multiline',
|
|
92
|
+
message: 'Prompt (agent instructions):',
|
|
93
93
|
default: prompt || 'Enter the prompt that will be sent to the agent...',
|
|
94
94
|
when: (ctx) => !ctx.flags.prompt && ctx.flags.name !== undefined,
|
|
95
95
|
validate: (value) => value.trim() ? true : 'Prompt is required',
|
|
@@ -113,11 +113,11 @@ export default class ActionUpdate extends PMOCommand {
|
|
|
113
113
|
currentValue: existingAction.description || '',
|
|
114
114
|
},
|
|
115
115
|
});
|
|
116
|
-
// Prompt input (
|
|
116
|
+
// Prompt input (multiline)
|
|
117
117
|
resolver.addPrompt({
|
|
118
118
|
flagName: 'prompt',
|
|
119
|
-
type: '
|
|
120
|
-
message: 'Prompt (
|
|
119
|
+
type: 'multiline',
|
|
120
|
+
message: 'Prompt (agent instructions):',
|
|
121
121
|
default: existingAction.prompt,
|
|
122
122
|
when: (ctx) => ctx.flags.name !== undefined && ctx.flags.description !== undefined,
|
|
123
123
|
context: {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Args, Flags } from '@oclif/core';
|
|
2
2
|
import inquirer from 'inquirer';
|
|
3
|
-
import { colors, format } from '
|
|
4
|
-
import { getWorkspaceInfo, cleanupAgent, getCleanableAgents, getAgentTmuxSessions } from '
|
|
5
|
-
import { PMOCommand, pmoBaseFlags } from '
|
|
6
|
-
import { shouldOutputJson, outputPromptAsJson, outputErrorAsJson, outputSuccessAsJson, createMetadata, buildPromptConfig, } from '
|
|
3
|
+
import { colors, format } from '../../lib/colors.js';
|
|
4
|
+
import { getWorkspaceInfo, cleanupAgent, getCleanableAgents, getAgentTmuxSessions } from '../../lib/agents/commands.js';
|
|
5
|
+
import { PMOCommand, pmoBaseFlags } from '../../lib/pmo/index.js';
|
|
6
|
+
import { shouldOutputJson, outputPromptAsJson, outputErrorAsJson, outputSuccessAsJson, createMetadata, buildPromptConfig, } from '../../lib/prompt-json.js';
|
|
7
7
|
export default class Cleanup extends PMOCommand {
|
|
8
8
|
static description = 'Clean up agent resources (containers, directories, tmux sessions)';
|
|
9
9
|
static examples = [
|
|
@@ -10,7 +10,7 @@ export default class Agent extends PMOCommand {
|
|
|
10
10
|
'<%= config.bin %> <%= command.id %> visit tacoma',
|
|
11
11
|
'<%= config.bin %> <%= command.id %> staff add',
|
|
12
12
|
'<%= config.bin %> <%= command.id %> staff remove camry',
|
|
13
|
-
'<%= config.bin %> <%= command.id %>
|
|
13
|
+
'<%= config.bin %> <%= command.id %> cleanup --temp',
|
|
14
14
|
'<%= config.bin %> <%= command.id %> restart altman',
|
|
15
15
|
'<%= config.bin %> <%= command.id %> rebuild altman',
|
|
16
16
|
'<%= config.bin %> <%= command.id %> shell altman',
|
|
@@ -52,7 +52,7 @@ export default class Agent extends PMOCommand {
|
|
|
52
52
|
{ name: '🗑️ Remove agent', value: 'remove', command: 'prlt agent remove --machine' },
|
|
53
53
|
// Management group
|
|
54
54
|
{ name: '👔 Manage staff agents', value: 'staff', command: 'prlt agent staff --machine' },
|
|
55
|
-
{ name: '
|
|
55
|
+
{ name: '🧹 Cleanup agents', value: 'cleanup', command: 'prlt agent cleanup --machine' },
|
|
56
56
|
{ name: '🎨 Manage themes', value: 'themes', command: 'prlt agent themes --machine' },
|
|
57
57
|
// Operations group
|
|
58
58
|
{ name: '🐚 Open shell', value: 'shell', command: 'prlt agent shell --machine' },
|
|
@@ -96,20 +96,20 @@ export default class Agent extends PMOCommand {
|
|
|
96
96
|
break;
|
|
97
97
|
}
|
|
98
98
|
case 'staff': {
|
|
99
|
-
const { default: StaffCommand } = await import('
|
|
99
|
+
const { default: StaffCommand } = await import('../staff/index.js');
|
|
100
100
|
const cmd = new StaffCommand([], this.config);
|
|
101
101
|
await cmd.run();
|
|
102
102
|
break;
|
|
103
103
|
}
|
|
104
|
-
case '
|
|
105
|
-
const { default:
|
|
106
|
-
const cmd = new
|
|
104
|
+
case 'cleanup': {
|
|
105
|
+
const { default: CleanupCommand } = await import('./cleanup.js');
|
|
106
|
+
const cmd = new CleanupCommand([], this.config);
|
|
107
107
|
await cmd.run();
|
|
108
108
|
break;
|
|
109
109
|
}
|
|
110
110
|
case 'themes': {
|
|
111
|
-
const { default:
|
|
112
|
-
const cmd = new
|
|
111
|
+
const { default: ThemeCommand } = await import('../theme/index.js');
|
|
112
|
+
const cmd = new ThemeCommand([], this.config);
|
|
113
113
|
await cmd.run();
|
|
114
114
|
break;
|
|
115
115
|
}
|
|
@@ -38,7 +38,7 @@ export default class BranchCreate extends PMOCommand {
|
|
|
38
38
|
}),
|
|
39
39
|
type: Flags.string({
|
|
40
40
|
char: 't',
|
|
41
|
-
description: 'Branch type',
|
|
41
|
+
description: 'Branch type [required for non-interactive with -d]',
|
|
42
42
|
options: Object.keys(BRANCH_TYPES),
|
|
43
43
|
}),
|
|
44
44
|
owner: Flags.string({
|
|
@@ -47,7 +47,7 @@ export default class BranchCreate extends PMOCommand {
|
|
|
47
47
|
}),
|
|
48
48
|
description: Flags.string({
|
|
49
49
|
char: 'd',
|
|
50
|
-
description: 'Branch description (kebab-case)',
|
|
50
|
+
description: 'Branch description (kebab-case) [required for non-interactive with -t]',
|
|
51
51
|
}),
|
|
52
52
|
'empty-commit': Flags.boolean({
|
|
53
53
|
char: 'e',
|
|
@@ -1,9 +1,8 @@
|
|
|
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 { moveEpicFile, getRelativeEpicPath } from '../../lib/pmo/epic-files.js';
|
|
6
|
-
import { shouldOutputJson,
|
|
5
|
+
import { shouldOutputJson, outputErrorAsJson, createMetadata, } from '../../lib/prompt-json.js';
|
|
7
6
|
export default class EpicActivate extends PMOCommand {
|
|
8
7
|
static description = 'Activate a draft or archived epic';
|
|
9
8
|
static examples = [
|
|
@@ -76,26 +75,19 @@ export default class EpicActivate extends PMOCommand {
|
|
|
76
75
|
if (epic.status === 'complete') {
|
|
77
76
|
const tickets = await this.storage.getTicketsForEpic(projectId, epicId);
|
|
78
77
|
const doneTickets = tickets.filter((t) => t.status === 'done').length;
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
const confirmChoices = [
|
|
82
|
-
{ name: 'No', value: 'false' },
|
|
83
|
-
{ name: 'Yes', value: 'true' },
|
|
84
|
-
];
|
|
85
|
-
outputPromptAsJson(buildPromptConfig('list', 'confirm', `This epic was previously completed (${doneTickets}/${tickets.length} tickets done). Reactivate this epic?`, confirmChoices), createMetadata('epic activate', flags));
|
|
86
|
-
return;
|
|
78
|
+
if (!jsonMode) {
|
|
79
|
+
this.log(styles.warning(`\n⚠️ This epic was previously completed (${doneTickets}/${tickets.length} tickets done)`));
|
|
87
80
|
}
|
|
88
|
-
|
|
89
|
-
const { confirm } = await
|
|
81
|
+
const jsonModeConfig = jsonMode ? { flags, commandName: 'epic activate' } : null;
|
|
82
|
+
const { confirm } = await this.prompt([{
|
|
90
83
|
type: 'list',
|
|
91
84
|
name: 'confirm',
|
|
92
|
-
message:
|
|
85
|
+
message: `This epic was previously completed (${doneTickets}/${tickets.length} tickets done). Reactivate this epic?`,
|
|
93
86
|
choices: [
|
|
94
|
-
{ name: 'No', value: false },
|
|
95
|
-
{ name: 'Yes', value: true },
|
|
87
|
+
{ name: 'No', value: false, command: '' },
|
|
88
|
+
{ name: 'Yes', value: true, command: `prlt epic activate ${epicId} --json` },
|
|
96
89
|
],
|
|
97
|
-
|
|
98
|
-
}]);
|
|
90
|
+
}], jsonModeConfig);
|
|
99
91
|
if (!confirm) {
|
|
100
92
|
this.log(styles.muted('Cancelled.'));
|
|
101
93
|
return;
|
|
@@ -1,9 +1,8 @@
|
|
|
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 { moveEpicFile, getRelativeEpicPath } from '../../lib/pmo/epic-files.js';
|
|
6
|
-
import { shouldOutputJson,
|
|
5
|
+
import { shouldOutputJson, outputErrorAsJson, createMetadata, } from '../../lib/prompt-json.js';
|
|
7
6
|
export default class EpicArchive extends PMOCommand {
|
|
8
7
|
static description = 'Archive a completed epic';
|
|
9
8
|
static examples = [
|
|
@@ -64,19 +63,16 @@ export default class EpicArchive extends PMOCommand {
|
|
|
64
63
|
return {
|
|
65
64
|
name: `${e.id} ${e.title} (${e.status}) [${done}/${tickets.length} tickets complete]${complete ? ' ✅' : ''}`,
|
|
66
65
|
value: e.id,
|
|
66
|
+
command: `prlt epic archive ${e.id} --json`,
|
|
67
67
|
};
|
|
68
68
|
}));
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
outputPromptAsJson(buildPromptConfig('list', 'id', 'Select epic to archive:', choices), createMetadata('epic archive', flags));
|
|
72
|
-
return;
|
|
73
|
-
}
|
|
74
|
-
const { selected } = await inquirer.prompt([{
|
|
69
|
+
const jsonModeConfig = jsonMode ? { flags, commandName: 'epic archive' } : null;
|
|
70
|
+
const { selected } = await this.prompt([{
|
|
75
71
|
type: 'list',
|
|
76
72
|
name: 'selected',
|
|
77
73
|
message: 'Select epic to archive:',
|
|
78
74
|
choices,
|
|
79
|
-
}]);
|
|
75
|
+
}], jsonModeConfig);
|
|
80
76
|
epicId = selected;
|
|
81
77
|
}
|
|
82
78
|
const epic = await this.storage.getEpic(epicId);
|
|
@@ -92,26 +88,19 @@ export default class EpicArchive extends PMOCommand {
|
|
|
92
88
|
const doneTickets = tickets.filter((t) => t.status === 'done').length;
|
|
93
89
|
const allComplete = doneTickets === tickets.length;
|
|
94
90
|
if (!allComplete && !flags.force) {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
const confirmChoices = [
|
|
98
|
-
{ name: 'No', value: 'false' },
|
|
99
|
-
{ name: 'Yes', value: 'true' },
|
|
100
|
-
];
|
|
101
|
-
outputPromptAsJson(buildPromptConfig('list', 'confirm', `Not all tickets are complete (${doneTickets}/${tickets.length} done). Continue archiving anyway?`, confirmChoices), createMetadata('epic archive', flags));
|
|
102
|
-
return;
|
|
91
|
+
if (!jsonMode) {
|
|
92
|
+
this.log(styles.warning(`\n⚠️ Not all tickets are complete (${doneTickets}/${tickets.length} done)`));
|
|
103
93
|
}
|
|
104
|
-
|
|
105
|
-
const { confirm } = await
|
|
94
|
+
const jsonModeConfig = jsonMode ? { flags, commandName: 'epic archive' } : null;
|
|
95
|
+
const { confirm } = await this.prompt([{
|
|
106
96
|
type: 'list',
|
|
107
97
|
name: 'confirm',
|
|
108
|
-
message:
|
|
98
|
+
message: `Not all tickets are complete (${doneTickets}/${tickets.length} done). Continue archiving anyway?`,
|
|
109
99
|
choices: [
|
|
110
|
-
{ name: 'No', value: false },
|
|
111
|
-
{ name: 'Yes', value: true },
|
|
100
|
+
{ name: 'No', value: false, command: '' },
|
|
101
|
+
{ name: 'Yes', value: true, command: `prlt epic archive ${epicId} --force --json` },
|
|
112
102
|
],
|
|
113
|
-
|
|
114
|
-
}]);
|
|
103
|
+
}], jsonModeConfig);
|
|
115
104
|
if (!confirm) {
|
|
116
105
|
this.log(styles.muted('Cancelled.'));
|
|
117
106
|
return;
|
|
@@ -8,6 +8,7 @@ export default class EpicCreate extends PMOCommand {
|
|
|
8
8
|
description: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
9
9
|
spec: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
10
|
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
11
|
+
'dry-run': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
11
12
|
project: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
13
|
};
|
|
13
14
|
execute(): Promise<void>;
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { 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 { createEpicFile, getRelativeEpicPath } from '../../lib/pmo/epic-files.js';
|
|
6
|
-
import { shouldOutputJson, outputPromptAsJson, createMetadata, buildFormPromptConfig, } from '../../lib/prompt-json.js';
|
|
5
|
+
import { shouldOutputJson, outputPromptAsJson, outputDryRunSuccessAsJson, outputDryRunErrorsAsJson, createMetadata, buildFormPromptConfig, } from '../../lib/prompt-json.js';
|
|
7
6
|
export default class EpicCreate extends PMOCommand {
|
|
8
7
|
static description = 'Create a new epic';
|
|
9
8
|
static examples = [
|
|
@@ -11,12 +10,13 @@ export default class EpicCreate extends PMOCommand {
|
|
|
11
10
|
'<%= config.bin %> <%= command.id %> --title "User Authentication System"',
|
|
12
11
|
'<%= config.bin %> <%= command.id %> -t "API Design" --status draft',
|
|
13
12
|
'<%= config.bin %> <%= command.id %> -t "Implement Auth" --spec SPEC-001',
|
|
13
|
+
'<%= config.bin %> <%= command.id %> --title "Test" -P PROJ-001 --dry-run --json # Validate without creating',
|
|
14
14
|
];
|
|
15
15
|
static flags = {
|
|
16
16
|
...pmoBaseFlags,
|
|
17
17
|
title: Flags.string({
|
|
18
18
|
char: 't',
|
|
19
|
-
description: 'Epic title',
|
|
19
|
+
description: 'Epic title [required for non-interactive]',
|
|
20
20
|
}),
|
|
21
21
|
status: Flags.string({
|
|
22
22
|
char: 's',
|
|
@@ -37,6 +37,10 @@ export default class EpicCreate extends PMOCommand {
|
|
|
37
37
|
description: 'Output prompt configuration as JSON (for AI agents/scripts)',
|
|
38
38
|
default: false,
|
|
39
39
|
}),
|
|
40
|
+
'dry-run': Flags.boolean({
|
|
41
|
+
description: 'Validate inputs without creating epic (use with --json for structured output)',
|
|
42
|
+
default: false,
|
|
43
|
+
}),
|
|
40
44
|
};
|
|
41
45
|
async execute() {
|
|
42
46
|
const { flags } = await this.parse(EpicCreate);
|
|
@@ -76,7 +80,7 @@ export default class EpicCreate extends PMOCommand {
|
|
|
76
80
|
if (jsonMode) {
|
|
77
81
|
outputPromptAsJson(buildFormPromptConfig(fields), createMetadata('epic create', flags));
|
|
78
82
|
}
|
|
79
|
-
epicData = await this.promptEpicData(fields, specChoices.length > 1);
|
|
83
|
+
epicData = await this.promptEpicData(fields, specChoices.length > 1, jsonMode ? { flags, commandName: 'epic create' } : null);
|
|
80
84
|
}
|
|
81
85
|
else {
|
|
82
86
|
epicData = {
|
|
@@ -90,9 +94,41 @@ export default class EpicCreate extends PMOCommand {
|
|
|
90
94
|
if (epicData.specId) {
|
|
91
95
|
const spec = await this.storage.getSpec(epicData.specId);
|
|
92
96
|
if (!spec) {
|
|
97
|
+
if (flags['dry-run']) {
|
|
98
|
+
if (jsonMode) {
|
|
99
|
+
outputDryRunErrorsAsJson([{ field: 'spec', error: `Spec not found: ${epicData.specId}` }], createMetadata('epic create', flags));
|
|
100
|
+
}
|
|
101
|
+
}
|
|
93
102
|
this.error(`Spec not found: ${epicData.specId}`);
|
|
94
103
|
}
|
|
95
104
|
}
|
|
105
|
+
// Handle dry-run: show what would be created without actually creating
|
|
106
|
+
if (flags['dry-run']) {
|
|
107
|
+
const projectName = await this.getProjectName(projectId);
|
|
108
|
+
const wouldCreate = {
|
|
109
|
+
title: epicData.title,
|
|
110
|
+
project: projectId,
|
|
111
|
+
status: epicData.status,
|
|
112
|
+
...(epicData.description && { description: epicData.description }),
|
|
113
|
+
...(epicData.specId && { spec: epicData.specId }),
|
|
114
|
+
};
|
|
115
|
+
if (jsonMode) {
|
|
116
|
+
outputDryRunSuccessAsJson('epic', wouldCreate, createMetadata('epic create', flags));
|
|
117
|
+
}
|
|
118
|
+
// Human-readable dry-run output
|
|
119
|
+
this.log(styles.warning('\n[DRY RUN] Would create epic:'));
|
|
120
|
+
this.log(styles.muted(` Title: ${epicData.title}`));
|
|
121
|
+
this.log(styles.muted(` Project: ${projectName}`));
|
|
122
|
+
this.log(styles.muted(` Status: ${epicData.status}`));
|
|
123
|
+
if (epicData.description) {
|
|
124
|
+
this.log(styles.muted(` Description: ${epicData.description}`));
|
|
125
|
+
}
|
|
126
|
+
if (epicData.specId) {
|
|
127
|
+
this.log(styles.muted(` Spec: ${epicData.specId}`));
|
|
128
|
+
}
|
|
129
|
+
this.log(styles.muted('\n(No epic was created)'));
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
96
132
|
const epic = await this.storage.createEpic(projectId, {
|
|
97
133
|
title: epicData.title,
|
|
98
134
|
status: epicData.status,
|
|
@@ -120,15 +156,17 @@ export default class EpicCreate extends PMOCommand {
|
|
|
120
156
|
this.log(styles.muted(` prlt ticket create --epic ${epic.id} "Design auth flow"`));
|
|
121
157
|
this.log(styles.muted(` 3. View progress: prlt epic progress ${epic.id}`));
|
|
122
158
|
}
|
|
123
|
-
async promptEpicData(fields, hasSpecs) {
|
|
159
|
+
async promptEpicData(fields, hasSpecs, jsonModeConfig) {
|
|
124
160
|
// Build inquirer prompts from fields, adding validators and conditionals
|
|
125
|
-
const
|
|
161
|
+
const promptFields = fields
|
|
162
|
+
.filter(field => field.name !== 'specId' || hasSpecs)
|
|
163
|
+
.map(field => ({
|
|
126
164
|
...field,
|
|
127
165
|
validate: field.name === 'title'
|
|
128
166
|
? ((input) => input.trim() ? true : 'Title cannot be empty')
|
|
129
167
|
: undefined,
|
|
130
|
-
|
|
131
|
-
|
|
168
|
+
}));
|
|
169
|
+
const answers = await this.prompt(promptFields, jsonModeConfig);
|
|
132
170
|
return {
|
|
133
171
|
title: answers.title,
|
|
134
172
|
status: answers.status,
|
|
@@ -31,7 +31,7 @@ export default class Epic extends PMOCommand {
|
|
|
31
31
|
{ id: 'progress', name: 'Show progress', command: 'prlt epic progress --json' },
|
|
32
32
|
{ id: 'ticket', name: 'Assign tickets to epic', command: 'prlt epic ticket --json' },
|
|
33
33
|
{ id: 'spec', name: 'Assign spec to epic', command: 'prlt epic spec --json' },
|
|
34
|
-
{ id: 'link', name: 'Manage dependencies', command: 'prlt
|
|
34
|
+
{ id: 'link', name: 'Manage dependencies', command: 'prlt link list --json' },
|
|
35
35
|
{ id: 'archive', name: 'Archive epic (complete)', command: 'prlt epic archive --json' },
|
|
36
36
|
{ id: 'activate', name: 'Activate epic', command: 'prlt epic activate --json' },
|
|
37
37
|
{ id: 'move', name: 'Reorder epic', command: 'prlt epic move --json' },
|
|
@@ -72,7 +72,7 @@ export default class Epic extends PMOCommand {
|
|
|
72
72
|
await this.config.runCommand('epic:spec', []);
|
|
73
73
|
break;
|
|
74
74
|
case 'link':
|
|
75
|
-
await this.config.runCommand('
|
|
75
|
+
await this.config.runCommand('link', []);
|
|
76
76
|
break;
|
|
77
77
|
case 'archive':
|
|
78
78
|
await this.config.runCommand('epic:archive', []);
|
|
@@ -1,9 +1,8 @@
|
|
|
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 { moveEpicFile, getRelativeEpicPath } from '../../lib/pmo/epic-files.js';
|
|
6
|
-
import { shouldOutputJson,
|
|
5
|
+
import { shouldOutputJson, outputErrorAsJson, createMetadata, } from '../../lib/prompt-json.js';
|
|
7
6
|
const STATUS_CHOICES = [
|
|
8
7
|
{ name: 'active (currently working on)', value: 'active' },
|
|
9
8
|
{ name: 'draft (planning phase)', value: 'draft' },
|
|
@@ -75,19 +74,16 @@ export default class EpicMove extends PMOCommand {
|
|
|
75
74
|
return {
|
|
76
75
|
name: `${e.id} ${e.title} (${e.status}) [${done}/${tickets.length} complete]`,
|
|
77
76
|
value: e.id,
|
|
77
|
+
command: `prlt epic move ${e.id} --json`,
|
|
78
78
|
};
|
|
79
79
|
}));
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
outputPromptAsJson(buildPromptConfig('list', 'id', 'Select epic to move:', choices), createMetadata('epic move', flags));
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
const { selected } = await inquirer.prompt([{
|
|
80
|
+
const jsonModeConfig = jsonMode ? { flags, commandName: 'epic move' } : null;
|
|
81
|
+
const { selected } = await this.prompt([{
|
|
86
82
|
type: 'list',
|
|
87
83
|
name: 'selected',
|
|
88
84
|
message: 'Select epic to move:',
|
|
89
85
|
choices,
|
|
90
|
-
}]);
|
|
86
|
+
}], jsonModeConfig);
|
|
91
87
|
epicId = selected;
|
|
92
88
|
}
|
|
93
89
|
const epic = await this.storage.getEpic(epicId);
|
|
@@ -96,18 +92,17 @@ export default class EpicMove extends PMOCommand {
|
|
|
96
92
|
}
|
|
97
93
|
// If no status provided, prompt for selection
|
|
98
94
|
if (!targetStatus) {
|
|
99
|
-
const statusChoices = STATUS_CHOICES.filter(c => c.value !== epic.status)
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
}
|
|
105
|
-
const { selected } = await inquirer.prompt([{
|
|
95
|
+
const statusChoices = STATUS_CHOICES.filter(c => c.value !== epic.status).map(c => ({
|
|
96
|
+
...c,
|
|
97
|
+
command: `prlt epic move ${epicId} ${c.value} --json`,
|
|
98
|
+
}));
|
|
99
|
+
const jsonModeConfig = jsonMode ? { flags, commandName: 'epic move' } : null;
|
|
100
|
+
const { selected } = await this.prompt([{
|
|
106
101
|
type: 'list',
|
|
107
102
|
name: 'selected',
|
|
108
103
|
message: 'Move to which status?',
|
|
109
104
|
choices: statusChoices,
|
|
110
|
-
}]);
|
|
105
|
+
}], jsonModeConfig);
|
|
111
106
|
targetStatus = selected;
|
|
112
107
|
}
|
|
113
108
|
if (targetStatus === epic.status) {
|
|
@@ -120,26 +115,19 @@ export default class EpicMove extends PMOCommand {
|
|
|
120
115
|
const allComplete = doneTickets === tickets.length;
|
|
121
116
|
// Moving to complete - check ticket completion
|
|
122
117
|
if (targetStatus === 'complete' && !allComplete && !flags.force) {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
const confirmChoices = [
|
|
126
|
-
{ name: 'No', value: 'false' },
|
|
127
|
-
{ name: 'Yes', value: 'true' },
|
|
128
|
-
];
|
|
129
|
-
outputPromptAsJson(buildPromptConfig('list', 'confirm', `Not all tickets are complete (${doneTickets}/${tickets.length} done). Continue moving to complete anyway?`, confirmChoices), createMetadata('epic move', flags));
|
|
130
|
-
return;
|
|
118
|
+
if (!jsonMode) {
|
|
119
|
+
this.log(styles.warning(`\n⚠️ Not all tickets are complete (${doneTickets}/${tickets.length} done)`));
|
|
131
120
|
}
|
|
132
|
-
|
|
133
|
-
const { confirm } = await
|
|
121
|
+
const jsonModeConfig = jsonMode ? { flags, commandName: 'epic move' } : null;
|
|
122
|
+
const { confirm } = await this.prompt([{
|
|
134
123
|
type: 'list',
|
|
135
124
|
name: 'confirm',
|
|
136
|
-
message:
|
|
125
|
+
message: `Not all tickets are complete (${doneTickets}/${tickets.length} done). Continue moving to complete anyway?`,
|
|
137
126
|
choices: [
|
|
138
|
-
{ name: 'No', value: false },
|
|
139
|
-
{ name: 'Yes', value: true },
|
|
127
|
+
{ name: 'No', value: false, command: '' },
|
|
128
|
+
{ name: 'Yes', value: true, command: `prlt epic move ${epicId} complete --force --json` },
|
|
140
129
|
],
|
|
141
|
-
|
|
142
|
-
}]);
|
|
130
|
+
}], jsonModeConfig);
|
|
143
131
|
if (!confirm) {
|
|
144
132
|
this.log(styles.muted('Cancelled.'));
|
|
145
133
|
return;
|
|
@@ -147,26 +135,19 @@ export default class EpicMove extends PMOCommand {
|
|
|
147
135
|
}
|
|
148
136
|
// Moving to dropped - confirm cancellation
|
|
149
137
|
if (targetStatus === 'dropped' && !flags.force) {
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
const confirmChoices = [
|
|
153
|
-
{ name: 'No', value: 'false' },
|
|
154
|
-
{ name: 'Yes', value: 'true' },
|
|
155
|
-
];
|
|
156
|
-
outputPromptAsJson(buildPromptConfig('list', 'confirmDrop', 'This will mark the epic as dropped/cancelled. Continue?', confirmChoices), createMetadata('epic move', flags));
|
|
157
|
-
return;
|
|
138
|
+
if (!jsonMode) {
|
|
139
|
+
this.log(styles.warning('\n⚠️ This will mark the epic as dropped/cancelled'));
|
|
158
140
|
}
|
|
159
|
-
|
|
160
|
-
const { confirm } = await
|
|
141
|
+
const jsonModeConfig = jsonMode ? { flags, commandName: 'epic move' } : null;
|
|
142
|
+
const { confirm } = await this.prompt([{
|
|
161
143
|
type: 'list',
|
|
162
144
|
name: 'confirm',
|
|
163
|
-
message: 'Continue?',
|
|
145
|
+
message: 'This will mark the epic as dropped/cancelled. Continue?',
|
|
164
146
|
choices: [
|
|
165
|
-
{ name: 'No', value: false },
|
|
166
|
-
{ name: 'Yes', value: true },
|
|
147
|
+
{ name: 'No', value: false, command: '' },
|
|
148
|
+
{ name: 'Yes', value: true, command: `prlt epic move ${epicId} dropped --force --json` },
|
|
167
149
|
],
|
|
168
|
-
|
|
169
|
-
}]);
|
|
150
|
+
}], jsonModeConfig);
|
|
170
151
|
if (!confirm) {
|
|
171
152
|
this.log(styles.muted('Cancelled.'));
|
|
172
153
|
return;
|
|
@@ -1,9 +1,8 @@
|
|
|
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 { getRelativeEpicPath } from '../../lib/pmo/epic-files.js';
|
|
6
|
-
import { shouldOutputJson,
|
|
5
|
+
import { shouldOutputJson, outputErrorAsJson, createMetadata, } from '../../lib/prompt-json.js';
|
|
7
6
|
// Progress bar helper
|
|
8
7
|
function progressBar(percent, width = 20) {
|
|
9
8
|
const filled = Math.round((percent / 100) * width);
|
|
@@ -57,21 +56,18 @@ export default class EpicProgress extends PMOCommand {
|
|
|
57
56
|
this.log(styles.muted('\nNo epics found.'));
|
|
58
57
|
return;
|
|
59
58
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
}
|
|
66
|
-
const { selected } = await
|
|
59
|
+
const epicChoices = epics.map(e => ({
|
|
60
|
+
name: `${e.id} ${e.title} (${e.status})`,
|
|
61
|
+
value: e.id,
|
|
62
|
+
command: `prlt epic progress ${e.id} --json`,
|
|
63
|
+
}));
|
|
64
|
+
const jsonModeConfig = jsonMode ? { flags, commandName: 'epic progress' } : null;
|
|
65
|
+
const { selected } = await this.prompt([{
|
|
67
66
|
type: 'list',
|
|
68
67
|
name: 'selected',
|
|
69
68
|
message: 'Select epic to view progress:',
|
|
70
|
-
choices:
|
|
71
|
-
|
|
72
|
-
value: e.id,
|
|
73
|
-
})),
|
|
74
|
-
}]);
|
|
69
|
+
choices: epicChoices,
|
|
70
|
+
}], jsonModeConfig);
|
|
75
71
|
epicId = selected;
|
|
76
72
|
}
|
|
77
73
|
await this.showSingleProgress(projectId, epicId);
|