@proletariat/cli 0.3.23 → 0.3.24
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 +1 -1
- 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/create.d.ts +1 -0
- package/dist/commands/epic/create.js +39 -2
- package/dist/commands/epic/index.js +2 -2
- 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/spec/create.d.ts +1 -0
- package/dist/commands/spec/create.js +43 -2
- 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/{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 +54 -2
- package/dist/commands/ticket/index.js +6 -6
- package/dist/commands/work/spawn.js +1 -1
- 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/prompt-json.d.ts +52 -1
- package/dist/lib/prompt-json.js +45 -0
- package/oclif.manifest.json +3660 -5564
- 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.d.ts +0 -13
- package/dist/commands/template/phase/delete.js +0 -36
- package/dist/commands/template/phase/index.d.ts +0 -10
- 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.d.ts +0 -10
- 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
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { Command, Flags } from '@oclif/core';
|
|
2
2
|
import inquirer from 'inquirer';
|
|
3
3
|
import chalk from 'chalk';
|
|
4
|
-
import { getWorkspaceInfo } from '
|
|
5
|
-
import { ensureBuiltinThemes } from '
|
|
6
|
-
import { getThemes, getAvailableThemeNames } from '
|
|
7
|
-
import { shouldOutputJson, outputPromptAsJson, createMetadata, buildPromptConfig, } from '
|
|
8
|
-
export default class
|
|
4
|
+
import { getWorkspaceInfo } from '../../lib/agents/commands.js';
|
|
5
|
+
import { ensureBuiltinThemes } from '../../lib/themes.js';
|
|
6
|
+
import { getThemes, getAvailableThemeNames } from '../../lib/database/index.js';
|
|
7
|
+
import { shouldOutputJson, outputPromptAsJson, createMetadata, buildPromptConfig, } from '../../lib/prompt-json.js';
|
|
8
|
+
export default class Theme extends Command {
|
|
9
9
|
static description = 'Manage agent naming themes';
|
|
10
10
|
static examples = [
|
|
11
11
|
'<%= config.bin %> <%= command.id %> list',
|
|
@@ -21,15 +21,15 @@ export default class Themes extends Command {
|
|
|
21
21
|
}),
|
|
22
22
|
};
|
|
23
23
|
async run() {
|
|
24
|
-
const { flags } = await this.parse(
|
|
24
|
+
const { flags } = await this.parse(Theme);
|
|
25
25
|
// Check if JSON output mode is active
|
|
26
26
|
const jsonMode = shouldOutputJson(flags);
|
|
27
27
|
// Define choices once, use for both JSON and interactive modes
|
|
28
28
|
// Each choice includes the full command for AI agents to execute
|
|
29
29
|
const menuChoices = [
|
|
30
|
-
{ id: 'list', name: 'List themes', command: 'prlt
|
|
31
|
-
{ id: 'create', name: 'Create a new theme', command: 'prlt
|
|
32
|
-
{ id: 'add-names', name: 'Add names to a theme', command: 'prlt
|
|
30
|
+
{ id: 'list', name: 'List themes', command: 'prlt theme list --format json' },
|
|
31
|
+
{ id: 'create', name: 'Create a new theme', command: 'prlt theme create --machine' },
|
|
32
|
+
{ id: 'add-names', name: 'Add names to a theme', command: 'prlt theme add-names --machine' },
|
|
33
33
|
{ id: 'cancel', name: 'Cancel', command: '' },
|
|
34
34
|
];
|
|
35
35
|
const message = 'What would you like to do?';
|
|
@@ -39,7 +39,7 @@ export default class Themes extends Command {
|
|
|
39
39
|
name: c.name,
|
|
40
40
|
value: c.id,
|
|
41
41
|
command: c.command,
|
|
42
|
-
}))), createMetadata('
|
|
42
|
+
}))), createMetadata('theme', flags));
|
|
43
43
|
return;
|
|
44
44
|
}
|
|
45
45
|
this.log(chalk.bold('\nAgent Themes'));
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Command } from '@oclif/core';
|
|
2
2
|
import chalk from 'chalk';
|
|
3
|
-
import { getWorkspaceInfo } from '
|
|
4
|
-
import { ensureBuiltinThemes } from '
|
|
5
|
-
import { getThemes, getThemeNames, getAvailableThemeNames } from '
|
|
6
|
-
export default class
|
|
3
|
+
import { getWorkspaceInfo } from '../../lib/agents/commands.js';
|
|
4
|
+
import { ensureBuiltinThemes } from '../../lib/themes.js';
|
|
5
|
+
import { getThemes, getThemeNames, getAvailableThemeNames } from '../../lib/database/index.js';
|
|
6
|
+
export default class ThemeList extends Command {
|
|
7
7
|
static description = 'List available agent themes';
|
|
8
8
|
static examples = [
|
|
9
9
|
'<%= config.bin %> <%= command.id %>',
|
|
@@ -32,7 +32,7 @@ export default class ThemesList extends Command {
|
|
|
32
32
|
this.log(chalk.gray(` Names: ${chalk.green(availableNames.length + ' available')}, ${chalk.yellow(inUse + ' in use')}`));
|
|
33
33
|
this.log('');
|
|
34
34
|
}
|
|
35
|
-
this.log(chalk.blue('Use: prlt
|
|
35
|
+
this.log(chalk.blue('Use: prlt staff add --theme <theme-id>'));
|
|
36
36
|
}
|
|
37
37
|
catch (error) {
|
|
38
38
|
this.error(error instanceof Error ? error.message : String(error));
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { Command, Args, Flags } from '@oclif/core';
|
|
2
2
|
import chalk from 'chalk';
|
|
3
3
|
import inquirer from 'inquirer';
|
|
4
|
-
import { getWorkspaceInfo } from '
|
|
5
|
-
import { ensureBuiltinThemes } from '
|
|
6
|
-
import { getThemes, getAvailableThemeNames, setActiveTheme, getActiveTheme } from '
|
|
7
|
-
import { shouldOutputJson, outputPromptAsJson, createMetadata, buildPromptConfig, } from '
|
|
8
|
-
export default class
|
|
4
|
+
import { getWorkspaceInfo } from '../../lib/agents/commands.js';
|
|
5
|
+
import { ensureBuiltinThemes } from '../../lib/themes.js';
|
|
6
|
+
import { getThemes, getAvailableThemeNames, setActiveTheme, getActiveTheme } from '../../lib/database/index.js';
|
|
7
|
+
import { shouldOutputJson, outputPromptAsJson, createMetadata, buildPromptConfig, } from '../../lib/prompt-json.js';
|
|
8
|
+
export default class ThemeSet extends Command {
|
|
9
9
|
static description = 'Set the active theme for this workspace';
|
|
10
10
|
static examples = [
|
|
11
11
|
'<%= config.bin %> <%= command.id %> billionaires',
|
|
@@ -26,7 +26,7 @@ export default class ThemesSet extends Command {
|
|
|
26
26
|
}),
|
|
27
27
|
};
|
|
28
28
|
async run() {
|
|
29
|
-
const { args, flags } = await this.parse(
|
|
29
|
+
const { args, flags } = await this.parse(ThemeSet);
|
|
30
30
|
// Check if JSON output mode is active
|
|
31
31
|
const jsonMode = shouldOutputJson(flags);
|
|
32
32
|
try {
|
|
@@ -47,7 +47,7 @@ export default class ThemesSet extends Command {
|
|
|
47
47
|
value: t.id
|
|
48
48
|
};
|
|
49
49
|
});
|
|
50
|
-
outputPromptAsJson(buildPromptConfig('list', 'theme', 'Select theme for this workspace:', themeChoices), createMetadata('
|
|
50
|
+
outputPromptAsJson(buildPromptConfig('list', 'theme', 'Select theme for this workspace:', themeChoices), createMetadata('theme set', flags));
|
|
51
51
|
return;
|
|
52
52
|
}
|
|
53
53
|
const choices = themes.map(t => {
|
|
@@ -14,6 +14,7 @@ export default class TicketCreate extends PMOCommand {
|
|
|
14
14
|
epic: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
15
15
|
template: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
16
16
|
labels: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
17
|
+
'dry-run': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
17
18
|
project: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
18
19
|
};
|
|
19
20
|
execute(): Promise<void>;
|
|
@@ -4,7 +4,7 @@ import { autoExportToBoard, PMOCommand, pmoBaseFlags } from '../../lib/pmo/index
|
|
|
4
4
|
import { styles } from '../../lib/styles.js';
|
|
5
5
|
import { updateEpicTicketsSection } from '../../lib/pmo/epic-files.js';
|
|
6
6
|
import { PRIORITIES, PRIORITY_LABELS } from '../../lib/pmo/types.js';
|
|
7
|
-
import { shouldOutputJson, outputErrorAsJson, createMetadata, } from '../../lib/prompt-json.js';
|
|
7
|
+
import { shouldOutputJson, outputErrorAsJson, outputDryRunSuccessAsJson, outputDryRunErrorsAsJson, createMetadata, } from '../../lib/prompt-json.js';
|
|
8
8
|
import { FlagResolver } from '../../lib/flags/index.js';
|
|
9
9
|
export default class TicketCreate extends PMOCommand {
|
|
10
10
|
static description = 'Create a new ticket on the PMO board';
|
|
@@ -15,6 +15,7 @@ export default class TicketCreate extends PMOCommand {
|
|
|
15
15
|
'<%= config.bin %> <%= command.id %> --project mobile-app -t "New feature"',
|
|
16
16
|
'<%= config.bin %> <%= command.id %> --epic EPIC-001 -t "Implement auth flow"',
|
|
17
17
|
'<%= config.bin %> <%= command.id %> --json # Output column choices as JSON',
|
|
18
|
+
'<%= config.bin %> <%= command.id %> --title "Test" -P PROJ-001 --dry-run --json # Validate without creating',
|
|
18
19
|
];
|
|
19
20
|
static flags = {
|
|
20
21
|
...pmoBaseFlags,
|
|
@@ -26,7 +27,7 @@ export default class TicketCreate extends PMOCommand {
|
|
|
26
27
|
}),
|
|
27
28
|
title: Flags.string({
|
|
28
29
|
char: 't',
|
|
29
|
-
description: 'Ticket title',
|
|
30
|
+
description: 'Ticket title [required for non-interactive]',
|
|
30
31
|
}),
|
|
31
32
|
column: Flags.string({
|
|
32
33
|
char: 'c',
|
|
@@ -64,6 +65,10 @@ export default class TicketCreate extends PMOCommand {
|
|
|
64
65
|
char: 'l',
|
|
65
66
|
description: 'Labels (comma-separated)',
|
|
66
67
|
}),
|
|
68
|
+
'dry-run': Flags.boolean({
|
|
69
|
+
description: 'Validate inputs without creating ticket (use with --json for structured output)',
|
|
70
|
+
default: false,
|
|
71
|
+
}),
|
|
67
72
|
};
|
|
68
73
|
async execute() {
|
|
69
74
|
const { flags } = await this.parse(TicketCreate);
|
|
@@ -171,8 +176,55 @@ export default class TicketCreate extends PMOCommand {
|
|
|
171
176
|
}
|
|
172
177
|
// Validate status/column
|
|
173
178
|
if (!columns.includes(ticketData.statusName)) {
|
|
179
|
+
if (flags['dry-run']) {
|
|
180
|
+
if (jsonMode) {
|
|
181
|
+
outputDryRunErrorsAsJson([{ field: 'column', error: `Invalid column "${ticketData.statusName}". Available: ${columns.join(', ')}` }], createMetadata('ticket create', flags));
|
|
182
|
+
}
|
|
183
|
+
this.error(`Invalid column "${ticketData.statusName}". Available columns: ${columns.join(', ')}`);
|
|
184
|
+
}
|
|
174
185
|
this.error(`Invalid column "${ticketData.statusName}". Available columns: ${columns.join(', ')}`);
|
|
175
186
|
}
|
|
187
|
+
// Handle dry-run: show what would be created without actually creating
|
|
188
|
+
if (flags['dry-run']) {
|
|
189
|
+
const wouldCreate = {
|
|
190
|
+
title: ticketData.title,
|
|
191
|
+
project: projectId,
|
|
192
|
+
column: ticketData.statusName,
|
|
193
|
+
...(ticketData.priority && { priority: ticketData.priority }),
|
|
194
|
+
...(ticketData.category && { category: ticketData.category }),
|
|
195
|
+
...(ticketData.description && { description: ticketData.description }),
|
|
196
|
+
...(ticketData.epicId && { epic: ticketData.epicId }),
|
|
197
|
+
...(ticketData.labels && ticketData.labels.length > 0 && { labels: ticketData.labels }),
|
|
198
|
+
};
|
|
199
|
+
if (jsonMode) {
|
|
200
|
+
outputDryRunSuccessAsJson('ticket', wouldCreate, createMetadata('ticket create', flags));
|
|
201
|
+
}
|
|
202
|
+
// Human-readable dry-run output
|
|
203
|
+
this.log(styles.warning('\n[DRY RUN] Would create ticket:'));
|
|
204
|
+
this.log(styles.muted(` Title: ${ticketData.title}`));
|
|
205
|
+
this.log(styles.muted(` Project: ${projectName}`));
|
|
206
|
+
this.log(styles.muted(` Column: ${ticketData.statusName}`));
|
|
207
|
+
if (ticketData.priority) {
|
|
208
|
+
this.log(styles.muted(` Priority: ${ticketData.priority}`));
|
|
209
|
+
}
|
|
210
|
+
if (ticketData.category) {
|
|
211
|
+
this.log(styles.muted(` Category: ${ticketData.category}`));
|
|
212
|
+
}
|
|
213
|
+
if (ticketData.epicId) {
|
|
214
|
+
this.log(styles.muted(` Epic: ${ticketData.epicId}`));
|
|
215
|
+
}
|
|
216
|
+
if (ticketData.labels && ticketData.labels.length > 0) {
|
|
217
|
+
this.log(styles.muted(` Labels: ${ticketData.labels.join(', ')}`));
|
|
218
|
+
}
|
|
219
|
+
if (template) {
|
|
220
|
+
this.log(styles.muted(` Template: ${template.name}`));
|
|
221
|
+
if (template.suggestedSubtasks.length > 0) {
|
|
222
|
+
this.log(styles.muted(` Subtasks: ${template.suggestedSubtasks.length} would be created`));
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
this.log(styles.muted('\n(No ticket was created)'));
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
176
228
|
const ticket = await this.storage.createTicket(projectId, {
|
|
177
229
|
id: ticketData.id,
|
|
178
230
|
title: ticketData.title,
|
|
@@ -27,7 +27,7 @@ export default class Ticket extends PMOCommand {
|
|
|
27
27
|
// Each choice includes the full command for AI agents to execute
|
|
28
28
|
const menuChoices = [
|
|
29
29
|
{ name: 'Create new ticket', value: 'create', command: 'prlt ticket create --json' },
|
|
30
|
-
{ name: 'Create from template', value: 'template', command: 'prlt
|
|
30
|
+
{ name: 'Create from template', value: 'template', command: 'prlt template apply --type ticket --json' },
|
|
31
31
|
{ name: 'List all tickets', value: 'list', command: 'prlt ticket list --format json' },
|
|
32
32
|
{ name: 'View ticket details', value: 'view', command: 'prlt ticket view --json' },
|
|
33
33
|
{ name: 'Edit ticket', value: 'edit', command: 'prlt ticket edit --json' },
|
|
@@ -35,8 +35,8 @@ export default class Ticket extends PMOCommand {
|
|
|
35
35
|
{ name: 'Move to different project', value: 'project', command: 'prlt ticket project --json' },
|
|
36
36
|
{ name: 'Assign to epic', value: 'epic', command: 'prlt ticket epic --json' },
|
|
37
37
|
{ name: 'Assign to spec', value: 'spec', command: 'prlt ticket spec --json' },
|
|
38
|
-
{ name: 'Manage dependencies', value: 'link', command: 'prlt
|
|
39
|
-
{ name: 'Manage templates', value: 'templates', command: 'prlt
|
|
38
|
+
{ name: 'Manage dependencies', value: 'link', command: 'prlt link list --json' },
|
|
39
|
+
{ name: 'Manage templates', value: 'templates', command: 'prlt template --json' },
|
|
40
40
|
{ name: 'Delete ticket', value: 'delete', command: 'prlt ticket delete --json' },
|
|
41
41
|
{ name: 'Cancel', value: 'cancel' },
|
|
42
42
|
];
|
|
@@ -68,7 +68,7 @@ export default class Ticket extends PMOCommand {
|
|
|
68
68
|
await this.config.runCommand('ticket:create', []);
|
|
69
69
|
break;
|
|
70
70
|
case 'template':
|
|
71
|
-
await this.config.runCommand('
|
|
71
|
+
await this.config.runCommand('template:apply', ['--type', 'ticket']);
|
|
72
72
|
break;
|
|
73
73
|
case 'list':
|
|
74
74
|
await this.config.runCommand('ticket:list', []);
|
|
@@ -92,10 +92,10 @@ export default class Ticket extends PMOCommand {
|
|
|
92
92
|
await this.config.runCommand('ticket:spec', []);
|
|
93
93
|
break;
|
|
94
94
|
case 'link':
|
|
95
|
-
await this.config.runCommand('
|
|
95
|
+
await this.config.runCommand('link', []);
|
|
96
96
|
break;
|
|
97
97
|
case 'templates':
|
|
98
|
-
await this.config.runCommand('
|
|
98
|
+
await this.config.runCommand('template', []);
|
|
99
99
|
break;
|
|
100
100
|
case 'delete':
|
|
101
101
|
await this.config.runCommand('ticket:delete', []);
|
|
@@ -39,7 +39,7 @@ export default class WorkSpawn extends PMOCommand {
|
|
|
39
39
|
}),
|
|
40
40
|
column: Flags.string({
|
|
41
41
|
char: 'c',
|
|
42
|
-
description: 'Column name to spawn tickets from
|
|
42
|
+
description: 'Column name to spawn tickets from [required for non-interactive with --all]',
|
|
43
43
|
}),
|
|
44
44
|
strategy: Flags.string({
|
|
45
45
|
char: 's',
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Helper Functions
|
|
3
|
+
*/
|
|
4
|
+
import type { Ticket } from '../pmo/types.js';
|
|
5
|
+
import type { McpToolResult } from './types.js';
|
|
6
|
+
export declare function formatTicket(t: Ticket): {
|
|
7
|
+
id: string;
|
|
8
|
+
title: string;
|
|
9
|
+
priority: string | undefined;
|
|
10
|
+
category: string | undefined;
|
|
11
|
+
statusName: string | undefined;
|
|
12
|
+
statusCategory: import("../pmo/types.js").StateCategory | undefined;
|
|
13
|
+
projectId: string | undefined;
|
|
14
|
+
assignee: string | undefined;
|
|
15
|
+
owner: string | undefined;
|
|
16
|
+
branch: string | undefined;
|
|
17
|
+
epicId: string | undefined;
|
|
18
|
+
};
|
|
19
|
+
export declare function formatTicketFull(t: Ticket): {
|
|
20
|
+
description: string | undefined;
|
|
21
|
+
subtasks: import("../pmo/types.js").Subtask[];
|
|
22
|
+
labels: string[];
|
|
23
|
+
metadata: Record<string, string>;
|
|
24
|
+
blockedBy: string[] | undefined;
|
|
25
|
+
acceptanceCriteria: import("../pmo/types.js").AcceptanceCriterion[] | undefined;
|
|
26
|
+
specId: string | undefined;
|
|
27
|
+
createdAt: string;
|
|
28
|
+
updatedAt: string;
|
|
29
|
+
id: string;
|
|
30
|
+
title: string;
|
|
31
|
+
priority: string | undefined;
|
|
32
|
+
category: string | undefined;
|
|
33
|
+
statusName: string | undefined;
|
|
34
|
+
statusCategory: import("../pmo/types.js").StateCategory | undefined;
|
|
35
|
+
projectId: string | undefined;
|
|
36
|
+
assignee: string | undefined;
|
|
37
|
+
owner: string | undefined;
|
|
38
|
+
branch: string | undefined;
|
|
39
|
+
epicId: string | undefined;
|
|
40
|
+
};
|
|
41
|
+
export declare function successResponse(data: Record<string, unknown>): McpToolResult;
|
|
42
|
+
export declare function errorResponse(error: unknown): McpToolResult;
|
|
43
|
+
export declare function textResponse(text: string): McpToolResult;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Helper Functions
|
|
3
|
+
*/
|
|
4
|
+
export function formatTicket(t) {
|
|
5
|
+
return {
|
|
6
|
+
id: t.id,
|
|
7
|
+
title: t.title,
|
|
8
|
+
priority: t.priority,
|
|
9
|
+
category: t.category,
|
|
10
|
+
statusName: t.statusName,
|
|
11
|
+
statusCategory: t.statusCategory,
|
|
12
|
+
projectId: t.projectId,
|
|
13
|
+
assignee: t.assignee,
|
|
14
|
+
owner: t.owner,
|
|
15
|
+
branch: t.branch,
|
|
16
|
+
epicId: t.epicId,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
export function formatTicketFull(t) {
|
|
20
|
+
return {
|
|
21
|
+
...formatTicket(t),
|
|
22
|
+
description: t.description,
|
|
23
|
+
subtasks: t.subtasks,
|
|
24
|
+
labels: t.labels,
|
|
25
|
+
metadata: t.metadata,
|
|
26
|
+
blockedBy: t.blockedBy,
|
|
27
|
+
acceptanceCriteria: t.acceptanceCriteria,
|
|
28
|
+
specId: t.specId,
|
|
29
|
+
createdAt: t.createdAt.toISOString(),
|
|
30
|
+
updatedAt: t.updatedAt.toISOString(),
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
export function successResponse(data) {
|
|
34
|
+
return {
|
|
35
|
+
content: [{
|
|
36
|
+
type: 'text',
|
|
37
|
+
text: JSON.stringify({ success: true, ...data }, null, 2),
|
|
38
|
+
}],
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
export function errorResponse(error) {
|
|
42
|
+
return {
|
|
43
|
+
content: [{
|
|
44
|
+
type: 'text',
|
|
45
|
+
text: JSON.stringify({
|
|
46
|
+
success: false,
|
|
47
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
48
|
+
}),
|
|
49
|
+
}],
|
|
50
|
+
isError: true,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
export function textResponse(text) {
|
|
54
|
+
return {
|
|
55
|
+
content: [{ type: 'text', text }],
|
|
56
|
+
};
|
|
57
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Action Tools
|
|
3
|
+
*/
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
import { errorResponse } from '../helpers.js';
|
|
6
|
+
export function registerActionTools(server, ctx) {
|
|
7
|
+
server.tool('action_list', 'List work actions', { include_builtin: z.boolean().optional() }, async (params) => {
|
|
8
|
+
try {
|
|
9
|
+
const actions = await ctx.storage.listActions({
|
|
10
|
+
isBuiltin: params.include_builtin ? undefined : false,
|
|
11
|
+
});
|
|
12
|
+
return {
|
|
13
|
+
content: [{
|
|
14
|
+
type: 'text',
|
|
15
|
+
text: JSON.stringify({
|
|
16
|
+
success: true,
|
|
17
|
+
actions: actions.map((a) => ({
|
|
18
|
+
id: a.id,
|
|
19
|
+
name: a.name,
|
|
20
|
+
description: a.description,
|
|
21
|
+
modifiesCode: a.modifiesCode,
|
|
22
|
+
isBuiltin: a.isBuiltin,
|
|
23
|
+
})),
|
|
24
|
+
}, null, 2),
|
|
25
|
+
}],
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
catch (error) {
|
|
29
|
+
return errorResponse(error);
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
server.tool('action_show', 'Get action details', { id: z.string().describe('Action ID') }, async (params) => {
|
|
33
|
+
try {
|
|
34
|
+
const action = await ctx.storage.getAction(params.id);
|
|
35
|
+
if (!action)
|
|
36
|
+
throw new Error(`Action not found: ${params.id}`);
|
|
37
|
+
return {
|
|
38
|
+
content: [{
|
|
39
|
+
type: 'text',
|
|
40
|
+
text: JSON.stringify({ success: true, action }, null, 2),
|
|
41
|
+
}],
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
return errorResponse(error);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
server.tool('action_create', 'Create a work action', {
|
|
49
|
+
name: z.string().describe('Action name'),
|
|
50
|
+
prompt: z.string().describe('Start prompt'),
|
|
51
|
+
description: z.string().optional(),
|
|
52
|
+
end_prompt: z.string().optional(),
|
|
53
|
+
modifies_code: z.boolean().optional(),
|
|
54
|
+
}, async (params) => {
|
|
55
|
+
try {
|
|
56
|
+
const action = await ctx.storage.createAction({
|
|
57
|
+
name: params.name,
|
|
58
|
+
prompt: params.prompt,
|
|
59
|
+
description: params.description,
|
|
60
|
+
endPrompt: params.end_prompt,
|
|
61
|
+
modifiesCode: params.modifies_code ?? true,
|
|
62
|
+
});
|
|
63
|
+
return {
|
|
64
|
+
content: [{
|
|
65
|
+
type: 'text',
|
|
66
|
+
text: JSON.stringify({ success: true, action: { id: action.id, name: action.name } }, null, 2),
|
|
67
|
+
}],
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
return errorResponse(error);
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
server.tool('action_delete', 'Delete an action', { id: z.string().describe('Action ID') }, async (params) => {
|
|
75
|
+
try {
|
|
76
|
+
await ctx.storage.deleteAction(params.id);
|
|
77
|
+
return {
|
|
78
|
+
content: [{
|
|
79
|
+
type: 'text',
|
|
80
|
+
text: JSON.stringify({ success: true, message: 'Action deleted' }, null, 2),
|
|
81
|
+
}],
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
return errorResponse(error);
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Board Tools
|
|
3
|
+
*/
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
import { errorResponse } from '../helpers.js';
|
|
6
|
+
export function registerBoardTools(server, ctx) {
|
|
7
|
+
server.tool('board_show', 'Show the kanban board', { project: z.string().optional().describe('Project ID') }, async (params) => {
|
|
8
|
+
try {
|
|
9
|
+
let projectId = params.project;
|
|
10
|
+
if (!projectId) {
|
|
11
|
+
const projects = await ctx.storage.listProjects();
|
|
12
|
+
if (projects.length === 0)
|
|
13
|
+
throw new Error('No projects found');
|
|
14
|
+
projectId = projects[0].id;
|
|
15
|
+
}
|
|
16
|
+
const board = await ctx.storage.getBoard(projectId);
|
|
17
|
+
return {
|
|
18
|
+
content: [{
|
|
19
|
+
type: 'text',
|
|
20
|
+
text: JSON.stringify({
|
|
21
|
+
success: true,
|
|
22
|
+
board: {
|
|
23
|
+
id: board.id,
|
|
24
|
+
name: board.name,
|
|
25
|
+
columns: board.columns.map((col) => ({
|
|
26
|
+
name: col.name,
|
|
27
|
+
position: col.position,
|
|
28
|
+
ticketCount: col.tickets.length,
|
|
29
|
+
tickets: col.tickets.map((t) => ({
|
|
30
|
+
id: t.id,
|
|
31
|
+
title: t.title,
|
|
32
|
+
priority: t.priority,
|
|
33
|
+
assignee: t.assignee,
|
|
34
|
+
})),
|
|
35
|
+
})),
|
|
36
|
+
updatedAt: board.updatedAt.toISOString(),
|
|
37
|
+
},
|
|
38
|
+
}, null, 2),
|
|
39
|
+
}],
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
return errorResponse(error);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
server.tool('board_columns', 'Get column names for a project', { project: z.string().optional().describe('Project ID') }, async (params) => {
|
|
47
|
+
try {
|
|
48
|
+
let projectId = params.project;
|
|
49
|
+
if (!projectId) {
|
|
50
|
+
const projects = await ctx.storage.listProjects();
|
|
51
|
+
if (projects.length === 0)
|
|
52
|
+
throw new Error('No projects found');
|
|
53
|
+
projectId = projects[0].id;
|
|
54
|
+
}
|
|
55
|
+
const columns = ctx.storage.getColumnNames(projectId);
|
|
56
|
+
return {
|
|
57
|
+
content: [{
|
|
58
|
+
type: 'text',
|
|
59
|
+
text: JSON.stringify({ success: true, projectId, columns }, null, 2),
|
|
60
|
+
}],
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
return errorResponse(error);
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
server.tool('board_create_column', 'Add a new column to the board', {
|
|
68
|
+
project: z.string().describe('Project ID'),
|
|
69
|
+
name: z.string().describe('Column name'),
|
|
70
|
+
position: z.number().optional().describe('Position'),
|
|
71
|
+
}, async (params) => {
|
|
72
|
+
try {
|
|
73
|
+
const column = await ctx.storage.createColumn(params.project, params.name, params.position);
|
|
74
|
+
return {
|
|
75
|
+
content: [{
|
|
76
|
+
type: 'text',
|
|
77
|
+
text: JSON.stringify({ success: true, column: { id: column.id, name: column.name, position: column.position } }, null, 2),
|
|
78
|
+
}],
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
return errorResponse(error);
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
server.tool('board_rename_column', 'Rename a column', {
|
|
86
|
+
project: z.string().describe('Project ID'),
|
|
87
|
+
column_id: z.string().describe('Column ID'),
|
|
88
|
+
name: z.string().describe('New name'),
|
|
89
|
+
}, async (params) => {
|
|
90
|
+
try {
|
|
91
|
+
const column = await ctx.storage.renameColumn(params.project, params.column_id, params.name);
|
|
92
|
+
return {
|
|
93
|
+
content: [{
|
|
94
|
+
type: 'text',
|
|
95
|
+
text: JSON.stringify({ success: true, column: { id: column.id, name: column.name } }, null, 2),
|
|
96
|
+
}],
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
return errorResponse(error);
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
server.tool('board_move_column', 'Reorder a column', {
|
|
104
|
+
project: z.string().describe('Project ID'),
|
|
105
|
+
column_id: z.string().describe('Column ID'),
|
|
106
|
+
position: z.number().describe('New position'),
|
|
107
|
+
}, async (params) => {
|
|
108
|
+
try {
|
|
109
|
+
const column = await ctx.storage.moveColumn(params.project, params.column_id, params.position);
|
|
110
|
+
return {
|
|
111
|
+
content: [{
|
|
112
|
+
type: 'text',
|
|
113
|
+
text: JSON.stringify({ success: true, column: { id: column.id, name: column.name, position: column.position } }, null, 2),
|
|
114
|
+
}],
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
catch (error) {
|
|
118
|
+
return errorResponse(error);
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
server.tool('board_delete_column', 'Delete a column', {
|
|
122
|
+
project: z.string().describe('Project ID'),
|
|
123
|
+
column_id: z.string().describe('Column ID'),
|
|
124
|
+
cascade: z.boolean().optional().describe('Delete tickets in column'),
|
|
125
|
+
}, async (params) => {
|
|
126
|
+
try {
|
|
127
|
+
await ctx.storage.deleteColumn(params.project, params.column_id, params.cascade);
|
|
128
|
+
return {
|
|
129
|
+
content: [{
|
|
130
|
+
type: 'text',
|
|
131
|
+
text: JSON.stringify({ success: true, message: 'Column deleted' }, null, 2),
|
|
132
|
+
}],
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
catch (error) {
|
|
136
|
+
return errorResponse(error);
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
}
|