@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,15 @@
|
|
|
1
|
+
import { PMOCommand } from '../../../lib/pmo/index.js';
|
|
2
|
+
export default class TicketLinkBlock extends PMOCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static args: {
|
|
6
|
+
ticket: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
7
|
+
blocker: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
8
|
+
};
|
|
9
|
+
static flags: {
|
|
10
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
11
|
+
machine: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
12
|
+
project: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
13
|
+
};
|
|
14
|
+
execute(): Promise<void>;
|
|
15
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { Args } from '@oclif/core';
|
|
2
|
+
import { autoExportToBoard, PMOCommand, pmoBaseFlags } from '../../../lib/pmo/index.js';
|
|
3
|
+
import { styles } from '../../../lib/styles.js';
|
|
4
|
+
import { shouldOutputJson, outputPromptAsJson, outputSuccessAsJson, outputErrorAsJson, createMetadata, buildPromptConfig, } from '../../../lib/prompt-json.js';
|
|
5
|
+
export default class TicketLinkBlock extends PMOCommand {
|
|
6
|
+
static description = 'Add a blocking dependency to a ticket';
|
|
7
|
+
static examples = [
|
|
8
|
+
'<%= config.bin %> <%= command.id %> TKT-001',
|
|
9
|
+
'<%= config.bin %> <%= command.id %> TKT-001 TKT-002',
|
|
10
|
+
'<%= config.bin %> <%= command.id %> TKT-001 --json',
|
|
11
|
+
];
|
|
12
|
+
static args = {
|
|
13
|
+
ticket: Args.string({
|
|
14
|
+
description: 'Ticket that will be blocked',
|
|
15
|
+
required: true,
|
|
16
|
+
}),
|
|
17
|
+
blocker: Args.string({
|
|
18
|
+
description: 'Ticket that blocks (the blocker)',
|
|
19
|
+
required: false,
|
|
20
|
+
}),
|
|
21
|
+
};
|
|
22
|
+
static flags = {
|
|
23
|
+
...pmoBaseFlags,
|
|
24
|
+
};
|
|
25
|
+
async execute() {
|
|
26
|
+
const { args, flags } = await this.parse(TicketLinkBlock);
|
|
27
|
+
const jsonMode = shouldOutputJson(flags);
|
|
28
|
+
const projectId = await this.requireProject();
|
|
29
|
+
const handleError = (code, message) => {
|
|
30
|
+
if (jsonMode) {
|
|
31
|
+
outputErrorAsJson(code, message, createMetadata('ticket link block', flags));
|
|
32
|
+
this.exit(1);
|
|
33
|
+
}
|
|
34
|
+
this.error(message);
|
|
35
|
+
};
|
|
36
|
+
// Verify the target ticket exists
|
|
37
|
+
const ticket = await this.storage.getTicket(args.ticket);
|
|
38
|
+
if (!ticket) {
|
|
39
|
+
return handleError('TICKET_NOT_FOUND', `Ticket not found: ${args.ticket}`);
|
|
40
|
+
}
|
|
41
|
+
// If blocker not provided, prompt for selection
|
|
42
|
+
if (!args.blocker) {
|
|
43
|
+
const tickets = await this.storage.listTickets(projectId);
|
|
44
|
+
const otherTickets = tickets.filter(t => t.id !== args.ticket);
|
|
45
|
+
if (otherTickets.length === 0) {
|
|
46
|
+
return handleError('NO_TICKETS', 'No other tickets to select as blocker.');
|
|
47
|
+
}
|
|
48
|
+
const projectFlag = flags.project ? ` -P ${flags.project}` : '';
|
|
49
|
+
const choices = otherTickets.map(t => ({
|
|
50
|
+
name: `${t.id} - ${t.title}`,
|
|
51
|
+
value: t.id,
|
|
52
|
+
command: `prlt ticket link block ${args.ticket} ${t.id}${projectFlag} --json`,
|
|
53
|
+
}));
|
|
54
|
+
const message = `Select ticket that blocks ${args.ticket}:`;
|
|
55
|
+
if (jsonMode) {
|
|
56
|
+
outputPromptAsJson(buildPromptConfig('list', 'blocker', message, choices), createMetadata('ticket link block', flags));
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
const { selected } = await this.prompt([{
|
|
60
|
+
type: 'list',
|
|
61
|
+
name: 'selected',
|
|
62
|
+
message,
|
|
63
|
+
choices,
|
|
64
|
+
}], null);
|
|
65
|
+
args.blocker = selected;
|
|
66
|
+
}
|
|
67
|
+
// Verify blocker exists
|
|
68
|
+
const blockerTicket = await this.storage.getTicket(args.blocker);
|
|
69
|
+
if (!blockerTicket) {
|
|
70
|
+
return handleError('BLOCKER_NOT_FOUND', `Blocker ticket not found: ${args.blocker}`);
|
|
71
|
+
}
|
|
72
|
+
// Create the blocking dependency
|
|
73
|
+
try {
|
|
74
|
+
await this.storage.createTicketDependency(args.ticket, args.blocker, 'blocks');
|
|
75
|
+
await autoExportToBoard(this.pmoPath, this.storage, (msg) => this.log(styles.muted(msg)));
|
|
76
|
+
if (jsonMode) {
|
|
77
|
+
outputSuccessAsJson({
|
|
78
|
+
ticketId: args.ticket,
|
|
79
|
+
blockerId: args.blocker,
|
|
80
|
+
type: 'blocks',
|
|
81
|
+
}, createMetadata('ticket link block', flags));
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
this.log(styles.success(`\n${args.ticket} is now blocked by ${args.blocker}`));
|
|
85
|
+
this.log(styles.muted(` ${ticket.title}`));
|
|
86
|
+
this.log(styles.muted(` blocked by: ${blockerTicket.title}`));
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
if (error instanceof Error && error.message.includes('already exists')) {
|
|
90
|
+
return handleError('ALREADY_EXISTS', 'Blocking dependency already exists.');
|
|
91
|
+
}
|
|
92
|
+
throw error;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { PMOCommand } from '../../../lib/pmo/index.js';
|
|
2
|
+
export default class TicketLink extends PMOCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static args: {
|
|
6
|
+
ticket: 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
|
+
execute(): Promise<void>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { Args } from '@oclif/core';
|
|
2
|
+
import { PMOCommand, pmoBaseFlags } from '../../../lib/pmo/index.js';
|
|
3
|
+
import { styles } from '../../../lib/styles.js';
|
|
4
|
+
import { shouldOutputJson, outputPromptAsJson, createMetadata, buildPromptConfig, } from '../../../lib/prompt-json.js';
|
|
5
|
+
export default class TicketLink extends PMOCommand {
|
|
6
|
+
static description = 'Manage links (dependencies) for a ticket';
|
|
7
|
+
static examples = [
|
|
8
|
+
'<%= config.bin %> <%= command.id %>',
|
|
9
|
+
'<%= config.bin %> <%= command.id %> TKT-001',
|
|
10
|
+
'<%= config.bin %> <%= command.id %> TKT-001 --json',
|
|
11
|
+
];
|
|
12
|
+
static args = {
|
|
13
|
+
ticket: Args.string({
|
|
14
|
+
description: 'Ticket ID',
|
|
15
|
+
required: false,
|
|
16
|
+
}),
|
|
17
|
+
};
|
|
18
|
+
static flags = {
|
|
19
|
+
...pmoBaseFlags,
|
|
20
|
+
};
|
|
21
|
+
async execute() {
|
|
22
|
+
const { args, flags } = await this.parse(TicketLink);
|
|
23
|
+
const jsonMode = shouldOutputJson(flags);
|
|
24
|
+
const projectId = await this.requireProject();
|
|
25
|
+
// If no ticket ID provided, prompt for selection
|
|
26
|
+
if (!args.ticket) {
|
|
27
|
+
const tickets = await this.storage.listTickets(projectId);
|
|
28
|
+
if (tickets.length === 0) {
|
|
29
|
+
this.log(styles.muted('No tickets found.'));
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
const choices = tickets.map(t => ({
|
|
33
|
+
name: `${t.id} - ${t.title}`,
|
|
34
|
+
value: t.id,
|
|
35
|
+
command: `prlt ticket link ${t.id}${flags.project ? ` -P ${flags.project}` : ''} --json`,
|
|
36
|
+
}));
|
|
37
|
+
const message = 'Select a ticket to manage links:';
|
|
38
|
+
if (jsonMode) {
|
|
39
|
+
outputPromptAsJson(buildPromptConfig('list', 'ticket', message, choices), createMetadata('ticket link', flags));
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const { selected } = await this.prompt([{
|
|
43
|
+
type: 'list',
|
|
44
|
+
name: 'selected',
|
|
45
|
+
message,
|
|
46
|
+
choices,
|
|
47
|
+
}], null);
|
|
48
|
+
args.ticket = selected;
|
|
49
|
+
}
|
|
50
|
+
const ticket = await this.storage.getTicket(args.ticket);
|
|
51
|
+
if (!ticket) {
|
|
52
|
+
this.error(`Ticket not found: ${args.ticket}`);
|
|
53
|
+
}
|
|
54
|
+
// Show link actions submenu
|
|
55
|
+
const projectFlag = flags.project ? ` -P ${flags.project}` : '';
|
|
56
|
+
const menuChoices = [
|
|
57
|
+
{ name: 'Add blocker', value: 'block', command: `prlt ticket link block ${args.ticket}${projectFlag} --json` },
|
|
58
|
+
{ name: 'View links', value: 'view', command: `prlt link list ${args.ticket}${projectFlag} --json` },
|
|
59
|
+
{ name: 'Remove link', value: 'remove', command: `prlt link remove ${args.ticket}${projectFlag} --json` },
|
|
60
|
+
{ name: 'Cancel', value: 'cancel', command: '' },
|
|
61
|
+
];
|
|
62
|
+
const message = `Manage links for ${args.ticket}: ${ticket.title}`;
|
|
63
|
+
if (jsonMode) {
|
|
64
|
+
outputPromptAsJson(buildPromptConfig('list', 'action', message, menuChoices), createMetadata('ticket link', flags));
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
const { action } = await this.prompt([{
|
|
68
|
+
type: 'list',
|
|
69
|
+
name: 'action',
|
|
70
|
+
message,
|
|
71
|
+
choices: menuChoices,
|
|
72
|
+
}], null);
|
|
73
|
+
if (action === 'cancel') {
|
|
74
|
+
this.log(styles.muted('Cancelled.'));
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
switch (action) {
|
|
78
|
+
case 'block': {
|
|
79
|
+
const { default: BlockCommand } = await import('./block.js');
|
|
80
|
+
const cmd = new BlockCommand([args.ticket, ...(flags.project ? ['-P', flags.project] : [])], this.config);
|
|
81
|
+
await cmd.run();
|
|
82
|
+
break;
|
|
83
|
+
}
|
|
84
|
+
case 'view': {
|
|
85
|
+
const { default: LinkListCommand } = await import('../../link/list.js');
|
|
86
|
+
const cmd = new LinkListCommand([args.ticket, ...(flags.project ? ['-P', flags.project] : [])], this.config);
|
|
87
|
+
await cmd.run();
|
|
88
|
+
break;
|
|
89
|
+
}
|
|
90
|
+
case 'remove': {
|
|
91
|
+
this.log(styles.muted('Use: prlt link remove <from> <to>'));
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
@@ -11,6 +11,7 @@ export default class TicketList extends Command {
|
|
|
11
11
|
search: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
12
|
format: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
13
13
|
all: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
14
|
+
label: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
14
15
|
'group-by': import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
15
16
|
limit: import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
16
17
|
offset: import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
@@ -55,6 +55,9 @@ export default class TicketList extends Command {
|
|
|
55
55
|
description: 'Show tickets across all projects',
|
|
56
56
|
default: false,
|
|
57
57
|
}),
|
|
58
|
+
label: Flags.string({
|
|
59
|
+
description: 'Filter by label name',
|
|
60
|
+
}),
|
|
58
61
|
'group-by': Flags.string({
|
|
59
62
|
char: 'g',
|
|
60
63
|
description: 'Group tickets by field',
|
|
@@ -106,6 +109,9 @@ export default class TicketList extends Command {
|
|
|
106
109
|
if (flags.search) {
|
|
107
110
|
filter.search = flags.search;
|
|
108
111
|
}
|
|
112
|
+
if (flags.label) {
|
|
113
|
+
filter.label = flags.label;
|
|
114
|
+
}
|
|
109
115
|
// Determine projectId for the query
|
|
110
116
|
const projectId = flags.all ? undefined : (filter.projectId || undefined);
|
|
111
117
|
// Validate project if specified (not in --all mode)
|
|
@@ -3,6 +3,7 @@ import { autoExportToBoard, PMOCommand, pmoBaseFlags, } from '../../lib/pmo/inde
|
|
|
3
3
|
import { PMOError } from '../../lib/pmo/types.js';
|
|
4
4
|
import { styles } from '../../lib/styles.js';
|
|
5
5
|
import { shouldOutputJson, outputErrorAsJson, createMetadata, } from '../../lib/prompt-json.js';
|
|
6
|
+
import { formatTicket } from '../../lib/mcp/helpers.js';
|
|
6
7
|
export default class TicketMove extends PMOCommand {
|
|
7
8
|
static description = 'Move ticket(s) to a different column';
|
|
8
9
|
static examples = [
|
|
@@ -195,6 +196,14 @@ export default class TicketMove extends PMOCommand {
|
|
|
195
196
|
const moved = await this.storage.moveTicket(projectId, ticketId, targetColumn, flags.position);
|
|
196
197
|
// Auto-export to board.md after write
|
|
197
198
|
await autoExportToBoard(this.pmoPath, this.storage, (msg) => this.log(styles.muted(msg)));
|
|
199
|
+
// JSON output mode - match MCP tool response shape
|
|
200
|
+
if (jsonMode) {
|
|
201
|
+
this.log(JSON.stringify({
|
|
202
|
+
success: true,
|
|
203
|
+
ticket: formatTicket(moved),
|
|
204
|
+
}, null, 2));
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
198
207
|
this.log(styles.success(`\n✅ Moved ticket ${styles.emphasis(moved.id)}`));
|
|
199
208
|
if (targetColumn !== ticket.statusName) {
|
|
200
209
|
this.log(styles.muted(` From: ${ticket.statusName}`));
|
|
@@ -206,7 +215,7 @@ export default class TicketMove extends PMOCommand {
|
|
|
206
215
|
}
|
|
207
216
|
async executeBulk(allTickets, flags, projectId) {
|
|
208
217
|
// Only show header in interactive mode
|
|
209
|
-
if (!(flags
|
|
218
|
+
if (!shouldOutputJson(flags)) {
|
|
210
219
|
this.log(styles.emphasis('📦 Move Multiple Tickets\n'));
|
|
211
220
|
}
|
|
212
221
|
// Get columns
|
|
@@ -216,7 +225,7 @@ export default class TicketMove extends PMOCommand {
|
|
|
216
225
|
}
|
|
217
226
|
const columns = board.columns.map(col => col.name);
|
|
218
227
|
// Agent mode config for prompts
|
|
219
|
-
const jsonModeConfig = (flags
|
|
228
|
+
const jsonModeConfig = shouldOutputJson(flags) ? { flags, commandName: 'ticket move --bulk' } : null;
|
|
220
229
|
// Select tickets to move (now agent-compatible!)
|
|
221
230
|
const { selectedTickets } = await this.prompt([{
|
|
222
231
|
type: 'checkbox',
|
|
@@ -328,6 +337,13 @@ export default class TicketMove extends PMOCommand {
|
|
|
328
337
|
// Refresh ticket to get updated status
|
|
329
338
|
const updatedTicket = await this.storage.getTicket(ticketId);
|
|
330
339
|
await autoExportToBoard(this.pmoPath, this.storage, (msg) => this.log(styles.muted(msg)));
|
|
340
|
+
if (jsonMode && updatedTicket) {
|
|
341
|
+
this.log(JSON.stringify({
|
|
342
|
+
success: true,
|
|
343
|
+
ticket: formatTicket(updatedTicket),
|
|
344
|
+
}, null, 2));
|
|
345
|
+
return;
|
|
346
|
+
}
|
|
331
347
|
this.log(styles.success(`\n✅ Moved ticket ${styles.emphasis(ticketId)} to project ${styles.emphasis(targetProject.id)}`));
|
|
332
348
|
this.log(styles.muted(` From project: ${sourceProjectId}`));
|
|
333
349
|
this.log(styles.muted(` To project: ${targetProject.id}`));
|
|
@@ -345,6 +361,13 @@ export default class TicketMove extends PMOCommand {
|
|
|
345
361
|
}
|
|
346
362
|
}
|
|
347
363
|
await autoExportToBoard(this.pmoPath, this.storage, (msg) => this.log(styles.muted(msg)));
|
|
364
|
+
if (jsonMode) {
|
|
365
|
+
this.log(JSON.stringify({
|
|
366
|
+
success: true,
|
|
367
|
+
ticket: formatTicket(movedTicket),
|
|
368
|
+
}, null, 2));
|
|
369
|
+
return;
|
|
370
|
+
}
|
|
348
371
|
this.log(styles.success(`\n✅ Moved ticket ${styles.emphasis(ticketId)} to project ${styles.emphasis(targetProject.id)}`));
|
|
349
372
|
this.log(styles.muted(` From project: ${sourceProjectId}`));
|
|
350
373
|
this.log(styles.muted(` To project: ${targetProject.id}`));
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { Args, Flags } from '@oclif/core';
|
|
2
|
-
import inquirer from 'inquirer';
|
|
3
2
|
import { autoExportToBoard, PMOCommand, pmoBaseFlags } from '../../lib/pmo/index.js';
|
|
4
3
|
import { styles } from '../../lib/styles.js';
|
|
5
4
|
import { shouldOutputJson, outputErrorAsJson, outputSuccessAsJson, createMetadata, } from '../../lib/prompt-json.js';
|
|
@@ -137,7 +136,7 @@ export default class TicketResolve extends PMOCommand {
|
|
|
137
136
|
}),
|
|
138
137
|
};
|
|
139
138
|
async execute() {
|
|
140
|
-
const {
|
|
139
|
+
const { flags, argv } = await this.parse(TicketResolve);
|
|
141
140
|
const projectId = flags.project;
|
|
142
141
|
const jsonMode = shouldOutputJson(flags);
|
|
143
142
|
const handleError = (code, message) => {
|
|
@@ -223,18 +222,18 @@ export default class TicketResolve extends PMOCommand {
|
|
|
223
222
|
for (const question of unanswered) {
|
|
224
223
|
this.log(styles.emphasis(` Q${question.number}: ${question.text}`));
|
|
225
224
|
// eslint-disable-next-line no-await-in-loop
|
|
226
|
-
const { answer } = await
|
|
225
|
+
const { answer } = await this.prompt([
|
|
227
226
|
{
|
|
228
227
|
type: 'input',
|
|
229
228
|
name: 'answer',
|
|
230
229
|
message: ` A${question.number}:`,
|
|
231
230
|
validate: (input) => {
|
|
232
|
-
if (!input.trim())
|
|
231
|
+
if (!String(input).trim())
|
|
233
232
|
return 'Please provide an answer (or type "skip" to skip)';
|
|
234
233
|
return true;
|
|
235
234
|
},
|
|
236
235
|
},
|
|
237
|
-
]);
|
|
236
|
+
], null);
|
|
238
237
|
if (answer.toLowerCase() === 'cancel') {
|
|
239
238
|
cancelled = true;
|
|
240
239
|
this.log(styles.warning('\nResolution cancelled.'));
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import TicketView from './view.js';
|
|
2
|
+
export default class TicketShow extends TicketView {
|
|
3
|
+
static description: string;
|
|
4
|
+
static hidden: boolean;
|
|
5
|
+
static args: {
|
|
6
|
+
ticketId: 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 TicketView from './view.js';
|
|
4
|
+
export default class TicketShow extends TicketView {
|
|
5
|
+
static description = 'View detailed ticket information (alias for ticket view)';
|
|
6
|
+
static hidden = true;
|
|
7
|
+
static args = {
|
|
8
|
+
ticketId: Args.string({
|
|
9
|
+
description: 'Ticket ID to view - prompts with dropdown if not provided',
|
|
10
|
+
required: false,
|
|
11
|
+
}),
|
|
12
|
+
};
|
|
13
|
+
static flags = {
|
|
14
|
+
...pmoBaseFlags,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import TemplateApply from '../../template/apply.js';
|
|
2
|
+
export default class TicketTemplateApply extends TemplateApply {
|
|
3
|
+
static description: string;
|
|
4
|
+
static args: {
|
|
5
|
+
template: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
6
|
+
};
|
|
7
|
+
static flags: {
|
|
8
|
+
type: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
9
|
+
title: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
|
+
column: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
|
+
priority: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
|
+
category: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
13
|
+
assignee: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
14
|
+
owner: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
15
|
+
description: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
16
|
+
epic: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
17
|
+
'no-subtasks': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
18
|
+
interactive: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
19
|
+
force: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
20
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
21
|
+
machine: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
22
|
+
project: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
23
|
+
};
|
|
24
|
+
static examples: string[];
|
|
25
|
+
run(): Promise<void>;
|
|
26
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import TemplateApply from '../../template/apply.js';
|
|
2
|
+
export default class TicketTemplateApply extends TemplateApply {
|
|
3
|
+
static description = 'Apply a ticket template to create a new ticket';
|
|
4
|
+
static args = TemplateApply.args;
|
|
5
|
+
static flags = TemplateApply.flags;
|
|
6
|
+
static examples = TemplateApply.examples;
|
|
7
|
+
async run() {
|
|
8
|
+
const argv = this.argv;
|
|
9
|
+
if (!argv.includes('--type') && !argv.includes('-t')) {
|
|
10
|
+
argv.push('--type', 'ticket');
|
|
11
|
+
}
|
|
12
|
+
return super.run();
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { PMOCommand } from '../../../lib/pmo/index.js';
|
|
2
|
+
export default class TicketTemplateDelete extends PMOCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static args: {
|
|
6
|
+
id: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
7
|
+
};
|
|
8
|
+
static flags: {
|
|
9
|
+
force: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
11
|
+
machine: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
12
|
+
project: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
13
|
+
};
|
|
14
|
+
protected getPMOOptions(): {
|
|
15
|
+
promptIfMultiple: boolean;
|
|
16
|
+
};
|
|
17
|
+
execute(): Promise<void>;
|
|
18
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { Args, Flags } from '@oclif/core';
|
|
2
|
+
import { PMOCommand, pmoBaseFlags } from '../../../lib/pmo/index.js';
|
|
3
|
+
import { styles } from '../../../lib/styles.js';
|
|
4
|
+
import { shouldOutputJson, outputErrorAsJson, createMetadata, } from '../../../lib/prompt-json.js';
|
|
5
|
+
export default class TicketTemplateDelete extends PMOCommand {
|
|
6
|
+
static description = 'Delete a ticket template';
|
|
7
|
+
static examples = [
|
|
8
|
+
'<%= config.bin %> <%= command.id %> my-template --force',
|
|
9
|
+
];
|
|
10
|
+
static args = {
|
|
11
|
+
id: Args.string({
|
|
12
|
+
description: 'Template ID to delete',
|
|
13
|
+
required: true,
|
|
14
|
+
}),
|
|
15
|
+
};
|
|
16
|
+
static flags = {
|
|
17
|
+
...pmoBaseFlags,
|
|
18
|
+
force: Flags.boolean({
|
|
19
|
+
char: 'f',
|
|
20
|
+
description: 'Skip confirmation',
|
|
21
|
+
default: false,
|
|
22
|
+
}),
|
|
23
|
+
};
|
|
24
|
+
getPMOOptions() {
|
|
25
|
+
return { promptIfMultiple: false };
|
|
26
|
+
}
|
|
27
|
+
async execute() {
|
|
28
|
+
const { args, flags } = await this.parse(TicketTemplateDelete);
|
|
29
|
+
const jsonMode = shouldOutputJson(flags);
|
|
30
|
+
const handleError = (code, message) => {
|
|
31
|
+
if (jsonMode) {
|
|
32
|
+
outputErrorAsJson(code, message, createMetadata('ticket template delete', flags));
|
|
33
|
+
}
|
|
34
|
+
this.error(message);
|
|
35
|
+
};
|
|
36
|
+
const template = await this.storage.getTicketTemplate(args.id);
|
|
37
|
+
if (!template) {
|
|
38
|
+
return handleError('NOT_FOUND', `Ticket template not found: ${args.id}`);
|
|
39
|
+
}
|
|
40
|
+
if (template.isBuiltin) {
|
|
41
|
+
return handleError('BUILTIN', `Cannot delete built-in template "${template.name}".`);
|
|
42
|
+
}
|
|
43
|
+
if (!flags.force) {
|
|
44
|
+
const { confirm } = await this.prompt([{
|
|
45
|
+
type: 'list',
|
|
46
|
+
name: 'confirm',
|
|
47
|
+
message: `Delete ticket template "${template.name}"?`,
|
|
48
|
+
choices: [
|
|
49
|
+
{ name: 'No', value: false },
|
|
50
|
+
{ name: 'Yes', value: true },
|
|
51
|
+
],
|
|
52
|
+
}], jsonMode ? { flags, commandName: 'ticket template delete' } : null);
|
|
53
|
+
if (!confirm) {
|
|
54
|
+
this.log(styles.muted('Cancelled.'));
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
await this.storage.deleteTicketTemplate(args.id);
|
|
59
|
+
this.log(styles.success(`\nDeleted template "${template.name}"`));
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { PMOCommand } from '../../../lib/pmo/index.js';
|
|
2
|
+
export default class TicketTemplateList extends PMOCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static flags: {
|
|
6
|
+
builtin: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
7
|
+
custom: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
8
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
9
|
+
machine: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
|
+
project: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
|
+
};
|
|
12
|
+
protected getPMOOptions(): {
|
|
13
|
+
promptIfMultiple: boolean;
|
|
14
|
+
};
|
|
15
|
+
execute(): Promise<void>;
|
|
16
|
+
private printTemplate;
|
|
17
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { Flags } from '@oclif/core';
|
|
2
|
+
import { PMOCommand, pmoBaseFlags } from '../../../lib/pmo/index.js';
|
|
3
|
+
import { shouldOutputJson } from '../../../lib/prompt-json.js';
|
|
4
|
+
import { styles } from '../../../lib/styles.js';
|
|
5
|
+
export default class TicketTemplateList extends PMOCommand {
|
|
6
|
+
static description = 'List ticket templates';
|
|
7
|
+
static examples = [
|
|
8
|
+
'<%= config.bin %> <%= command.id %>',
|
|
9
|
+
'<%= config.bin %> <%= command.id %> --builtin',
|
|
10
|
+
'<%= config.bin %> <%= command.id %> --json',
|
|
11
|
+
];
|
|
12
|
+
static flags = {
|
|
13
|
+
...pmoBaseFlags,
|
|
14
|
+
builtin: Flags.boolean({
|
|
15
|
+
description: 'Show only built-in templates',
|
|
16
|
+
exclusive: ['custom'],
|
|
17
|
+
}),
|
|
18
|
+
custom: Flags.boolean({
|
|
19
|
+
description: 'Show only custom templates',
|
|
20
|
+
exclusive: ['builtin'],
|
|
21
|
+
}),
|
|
22
|
+
};
|
|
23
|
+
getPMOOptions() {
|
|
24
|
+
return { promptIfMultiple: false };
|
|
25
|
+
}
|
|
26
|
+
async execute() {
|
|
27
|
+
const { flags } = await this.parse(TicketTemplateList);
|
|
28
|
+
let builtinFilter;
|
|
29
|
+
if (flags.builtin)
|
|
30
|
+
builtinFilter = { isBuiltin: true };
|
|
31
|
+
if (flags.custom)
|
|
32
|
+
builtinFilter = { isBuiltin: false };
|
|
33
|
+
const templates = await this.storage.listTicketTemplates(builtinFilter);
|
|
34
|
+
if (shouldOutputJson(flags)) {
|
|
35
|
+
this.log(JSON.stringify(templates, null, 2));
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
if (templates.length === 0) {
|
|
39
|
+
this.log(styles.muted('\nNo ticket templates found.'));
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
this.log(`\n${styles.emphasis('Ticket Templates')}`);
|
|
43
|
+
this.log('═'.repeat(60));
|
|
44
|
+
const builtinTemplates = templates.filter(t => t.isBuiltin);
|
|
45
|
+
const customTemplates = templates.filter(t => !t.isBuiltin);
|
|
46
|
+
if (builtinTemplates.length > 0 && !flags.custom) {
|
|
47
|
+
this.log(`\n${styles.emphasis('Built-in Templates')}`);
|
|
48
|
+
this.log('─'.repeat(40));
|
|
49
|
+
for (const template of builtinTemplates) {
|
|
50
|
+
this.printTemplate(template);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
if (customTemplates.length > 0 && !flags.builtin) {
|
|
54
|
+
this.log(`\n${styles.emphasis('Custom Templates')}`);
|
|
55
|
+
this.log('─'.repeat(40));
|
|
56
|
+
for (const template of customTemplates) {
|
|
57
|
+
this.printTemplate(template);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
this.log('');
|
|
61
|
+
}
|
|
62
|
+
printTemplate(template) {
|
|
63
|
+
this.log(` ${styles.emphasis(template.name)} ${styles.muted(`(${template.id})`)}`);
|
|
64
|
+
if (template.description) {
|
|
65
|
+
this.log(` ${styles.muted(template.description)}`);
|
|
66
|
+
}
|
|
67
|
+
const details = [];
|
|
68
|
+
if (template.defaultPriority)
|
|
69
|
+
details.push(`Priority: ${template.defaultPriority}`);
|
|
70
|
+
if (template.defaultCategory)
|
|
71
|
+
details.push(`Category: ${template.defaultCategory}`);
|
|
72
|
+
if (template.suggestedSubtasks.length > 0)
|
|
73
|
+
details.push(`Subtasks: ${template.suggestedSubtasks.length}`);
|
|
74
|
+
if (details.length > 0) {
|
|
75
|
+
this.log(` ${styles.muted(details.join(' | '))}`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { PMOCommand } from '../../../lib/pmo/index.js';
|
|
2
|
+
export default class TicketTemplateSave extends PMOCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static args: {
|
|
6
|
+
ticket: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
7
|
+
name: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
8
|
+
};
|
|
9
|
+
static flags: {
|
|
10
|
+
'template-name': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
|
+
description: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
13
|
+
machine: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
14
|
+
project: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
15
|
+
};
|
|
16
|
+
execute(): Promise<void>;
|
|
17
|
+
}
|