@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,18 @@
|
|
|
1
|
+
import { PMOCommand } from '../../../lib/pmo/index.js';
|
|
2
|
+
export default class SpecLinkDepends extends PMOCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static args: {
|
|
6
|
+
spec: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
7
|
+
target: 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
|
+
protected getPMOOptions(): {
|
|
15
|
+
promptIfMultiple: boolean;
|
|
16
|
+
};
|
|
17
|
+
execute(): Promise<void>;
|
|
18
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
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, outputErrorAsJson, createMetadata, buildPromptConfig, } from '../../../lib/prompt-json.js';
|
|
5
|
+
export default class SpecLinkDepends extends PMOCommand {
|
|
6
|
+
static description = 'Add a dependency between specs';
|
|
7
|
+
static examples = [
|
|
8
|
+
'<%= config.bin %> <%= command.id %> SPEC-001 SPEC-002',
|
|
9
|
+
'<%= config.bin %> <%= command.id %> SPEC-001 --machine',
|
|
10
|
+
];
|
|
11
|
+
static args = {
|
|
12
|
+
spec: Args.string({
|
|
13
|
+
description: 'Source spec ID (the one that depends on another)',
|
|
14
|
+
required: true,
|
|
15
|
+
}),
|
|
16
|
+
target: Args.string({
|
|
17
|
+
description: 'Target spec ID (the one depended upon)',
|
|
18
|
+
required: false,
|
|
19
|
+
}),
|
|
20
|
+
};
|
|
21
|
+
static flags = {
|
|
22
|
+
...pmoBaseFlags,
|
|
23
|
+
};
|
|
24
|
+
getPMOOptions() {
|
|
25
|
+
return { promptIfMultiple: false };
|
|
26
|
+
}
|
|
27
|
+
async execute() {
|
|
28
|
+
const { args, flags } = await this.parse(SpecLinkDepends);
|
|
29
|
+
const jsonMode = shouldOutputJson(flags);
|
|
30
|
+
const handleError = (code, message) => {
|
|
31
|
+
if (jsonMode) {
|
|
32
|
+
outputErrorAsJson(code, message, createMetadata('spec link depends', flags));
|
|
33
|
+
this.exit(1);
|
|
34
|
+
}
|
|
35
|
+
this.error(message);
|
|
36
|
+
};
|
|
37
|
+
// Verify source spec exists
|
|
38
|
+
const sourceSpec = await this.storage.getSpec(args.spec);
|
|
39
|
+
if (!sourceSpec) {
|
|
40
|
+
return handleError('SPEC_NOT_FOUND', `Spec not found: ${args.spec}`);
|
|
41
|
+
}
|
|
42
|
+
// If target not provided, prompt for selection
|
|
43
|
+
if (!args.target) {
|
|
44
|
+
const specs = await this.storage.listSpecs();
|
|
45
|
+
const otherSpecs = specs.filter(s => s.id !== args.spec);
|
|
46
|
+
if (otherSpecs.length === 0) {
|
|
47
|
+
return handleError('NO_SPECS', 'No other specs to select as dependency.');
|
|
48
|
+
}
|
|
49
|
+
const choices = otherSpecs.map(s => ({
|
|
50
|
+
name: `${s.id} - ${s.title}`,
|
|
51
|
+
value: s.id,
|
|
52
|
+
command: `prlt spec link depends ${args.spec} ${s.id} --json`,
|
|
53
|
+
}));
|
|
54
|
+
const message = `Select spec that ${args.spec} depends on:`;
|
|
55
|
+
if (jsonMode) {
|
|
56
|
+
outputPromptAsJson(buildPromptConfig('list', 'target', message, choices), createMetadata('spec link depends', flags));
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
const { selected } = await this.prompt([{
|
|
60
|
+
type: 'list',
|
|
61
|
+
name: 'selected',
|
|
62
|
+
message,
|
|
63
|
+
choices,
|
|
64
|
+
}], null);
|
|
65
|
+
args.target = selected;
|
|
66
|
+
}
|
|
67
|
+
// Verify target spec exists
|
|
68
|
+
const targetSpec = await this.storage.getSpec(args.target);
|
|
69
|
+
if (!targetSpec) {
|
|
70
|
+
return handleError('TARGET_NOT_FOUND', `Spec not found: ${args.target}`);
|
|
71
|
+
}
|
|
72
|
+
// Create the dependency
|
|
73
|
+
try {
|
|
74
|
+
await this.storage.createSpecDependency(args.spec, args.target, 'depends_on');
|
|
75
|
+
this.log(styles.success(`\n${args.spec} now depends on ${args.target}`));
|
|
76
|
+
this.log(styles.muted(` ${sourceSpec.title}`));
|
|
77
|
+
this.log(styles.muted(` depends on: ${targetSpec.title}`));
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
if (error instanceof Error && error.message.includes('already exists')) {
|
|
81
|
+
return handleError('ALREADY_EXISTS', 'Dependency already exists.');
|
|
82
|
+
}
|
|
83
|
+
throw error;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { PMOCommand } from '../../../lib/pmo/index.js';
|
|
2
|
+
export default class SpecLink extends PMOCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static args: {
|
|
6
|
+
spec: 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
|
+
protected getPMOOptions(): {
|
|
14
|
+
promptIfMultiple: boolean;
|
|
15
|
+
};
|
|
16
|
+
execute(): Promise<void>;
|
|
17
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
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 SpecLink extends PMOCommand {
|
|
6
|
+
static description = 'Manage links (dependencies) for a spec';
|
|
7
|
+
static examples = [
|
|
8
|
+
'<%= config.bin %> <%= command.id %>',
|
|
9
|
+
'<%= config.bin %> <%= command.id %> SPEC-001',
|
|
10
|
+
'<%= config.bin %> <%= command.id %> --machine',
|
|
11
|
+
];
|
|
12
|
+
static args = {
|
|
13
|
+
spec: Args.string({
|
|
14
|
+
description: 'Spec ID',
|
|
15
|
+
required: false,
|
|
16
|
+
}),
|
|
17
|
+
};
|
|
18
|
+
static flags = {
|
|
19
|
+
...pmoBaseFlags,
|
|
20
|
+
};
|
|
21
|
+
getPMOOptions() {
|
|
22
|
+
return { promptIfMultiple: false };
|
|
23
|
+
}
|
|
24
|
+
async execute() {
|
|
25
|
+
const { args, flags } = await this.parse(SpecLink);
|
|
26
|
+
const jsonMode = shouldOutputJson(flags);
|
|
27
|
+
// If no spec ID provided, prompt for selection
|
|
28
|
+
if (!args.spec) {
|
|
29
|
+
const specs = await this.storage.listSpecs();
|
|
30
|
+
if (specs.length === 0) {
|
|
31
|
+
this.log(styles.muted('No specs found.'));
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
const choices = specs.map(s => ({
|
|
35
|
+
name: `${s.id} - ${s.title}`,
|
|
36
|
+
value: s.id,
|
|
37
|
+
command: `prlt spec link ${s.id} --machine`,
|
|
38
|
+
}));
|
|
39
|
+
const message = 'Select a spec to manage links:';
|
|
40
|
+
if (jsonMode) {
|
|
41
|
+
outputPromptAsJson(buildPromptConfig('list', 'id', message, choices), createMetadata('spec link', flags));
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
const { selected } = await this.prompt([{
|
|
45
|
+
type: 'list',
|
|
46
|
+
name: 'selected',
|
|
47
|
+
message,
|
|
48
|
+
choices,
|
|
49
|
+
}], null);
|
|
50
|
+
args.spec = selected;
|
|
51
|
+
}
|
|
52
|
+
const spec = await this.storage.getSpec(args.spec);
|
|
53
|
+
if (!spec) {
|
|
54
|
+
this.error(`Spec not found: ${args.spec}`);
|
|
55
|
+
}
|
|
56
|
+
// Show link actions submenu
|
|
57
|
+
const menuChoices = [
|
|
58
|
+
{ name: 'Add dependency', value: 'depends', command: `prlt spec link depends ${args.spec} --machine` },
|
|
59
|
+
{ name: 'Remove dependency', value: 'remove', command: `prlt spec link remove ${args.spec} --machine` },
|
|
60
|
+
{ name: 'Cancel', value: 'cancel', command: '' },
|
|
61
|
+
];
|
|
62
|
+
const message = `Manage links for ${args.spec}: ${spec.title}`;
|
|
63
|
+
if (jsonMode) {
|
|
64
|
+
outputPromptAsJson(buildPromptConfig('list', 'action', message, menuChoices), createMetadata('spec 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 'depends': {
|
|
79
|
+
const { default: DependsCommand } = await import('./depends.js');
|
|
80
|
+
const cmd = new DependsCommand([args.spec], this.config);
|
|
81
|
+
await cmd.run();
|
|
82
|
+
break;
|
|
83
|
+
}
|
|
84
|
+
case 'remove': {
|
|
85
|
+
const { default: RemoveCommand } = await import('./remove.js');
|
|
86
|
+
const cmd = new RemoveCommand([args.spec], this.config);
|
|
87
|
+
await cmd.run();
|
|
88
|
+
break;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { PMOCommand } from '../../../lib/pmo/index.js';
|
|
2
|
+
export default class SpecLinkRemove extends PMOCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static args: {
|
|
6
|
+
spec: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
7
|
+
target: 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
|
+
protected getPMOOptions(): {
|
|
15
|
+
promptIfMultiple: boolean;
|
|
16
|
+
};
|
|
17
|
+
execute(): Promise<void>;
|
|
18
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
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, outputErrorAsJson, createMetadata, buildPromptConfig, } from '../../../lib/prompt-json.js';
|
|
5
|
+
export default class SpecLinkRemove extends PMOCommand {
|
|
6
|
+
static description = 'Remove a dependency between specs';
|
|
7
|
+
static examples = [
|
|
8
|
+
'<%= config.bin %> <%= command.id %> SPEC-001 SPEC-002',
|
|
9
|
+
'<%= config.bin %> <%= command.id %> SPEC-001 --machine',
|
|
10
|
+
];
|
|
11
|
+
static args = {
|
|
12
|
+
spec: Args.string({
|
|
13
|
+
description: 'Source spec ID',
|
|
14
|
+
required: true,
|
|
15
|
+
}),
|
|
16
|
+
target: Args.string({
|
|
17
|
+
description: 'Target spec ID to remove dependency from',
|
|
18
|
+
required: false,
|
|
19
|
+
}),
|
|
20
|
+
};
|
|
21
|
+
static flags = {
|
|
22
|
+
...pmoBaseFlags,
|
|
23
|
+
};
|
|
24
|
+
getPMOOptions() {
|
|
25
|
+
return { promptIfMultiple: false };
|
|
26
|
+
}
|
|
27
|
+
async execute() {
|
|
28
|
+
const { args, flags } = await this.parse(SpecLinkRemove);
|
|
29
|
+
const jsonMode = shouldOutputJson(flags);
|
|
30
|
+
const handleError = (code, message) => {
|
|
31
|
+
if (jsonMode) {
|
|
32
|
+
outputErrorAsJson(code, message, createMetadata('spec link remove', flags));
|
|
33
|
+
this.exit(1);
|
|
34
|
+
}
|
|
35
|
+
this.error(message);
|
|
36
|
+
};
|
|
37
|
+
// Verify source spec exists
|
|
38
|
+
const sourceSpec = await this.storage.getSpec(args.spec);
|
|
39
|
+
if (!sourceSpec) {
|
|
40
|
+
return handleError('SPEC_NOT_FOUND', `Spec not found: ${args.spec}`);
|
|
41
|
+
}
|
|
42
|
+
// If target not provided, show existing dependencies for selection
|
|
43
|
+
if (!args.target) {
|
|
44
|
+
const dependencies = await this.storage.listSpecDependencies(args.spec);
|
|
45
|
+
if (dependencies.length === 0) {
|
|
46
|
+
if (jsonMode) {
|
|
47
|
+
outputErrorAsJson('NO_DEPENDENCIES', `No dependencies found for ${args.spec}.`, createMetadata('spec link remove', flags));
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
this.log(styles.muted(`No dependencies found for ${args.spec}.`));
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
// Get spec details for dependency targets
|
|
54
|
+
const choices = [];
|
|
55
|
+
for (const dep of dependencies) {
|
|
56
|
+
// eslint-disable-next-line no-await-in-loop
|
|
57
|
+
const targetSpec = await this.storage.getSpec(dep.dependsOnSpecId);
|
|
58
|
+
const name = targetSpec ? `${dep.dependsOnSpecId} - ${targetSpec.title} (${dep.dependencyType})` : `${dep.dependsOnSpecId} (${dep.dependencyType})`;
|
|
59
|
+
choices.push({
|
|
60
|
+
name,
|
|
61
|
+
value: dep.dependsOnSpecId,
|
|
62
|
+
command: `prlt spec link remove ${args.spec} ${dep.dependsOnSpecId} --json`,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
const message = `Select dependency to remove from ${args.spec}:`;
|
|
66
|
+
if (jsonMode) {
|
|
67
|
+
outputPromptAsJson(buildPromptConfig('list', 'target', message, choices), createMetadata('spec link remove', flags));
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
const { selected } = await this.prompt([{
|
|
71
|
+
type: 'list',
|
|
72
|
+
name: 'selected',
|
|
73
|
+
message,
|
|
74
|
+
choices,
|
|
75
|
+
}], null);
|
|
76
|
+
args.target = selected;
|
|
77
|
+
}
|
|
78
|
+
// Remove the dependency
|
|
79
|
+
try {
|
|
80
|
+
await this.storage.deleteSpecDependency(args.spec, args.target);
|
|
81
|
+
this.log(styles.success(`\nRemoved dependency: ${args.spec} no longer depends on ${args.target}`));
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
if (error instanceof Error && error.message.includes('not found')) {
|
|
85
|
+
return handleError('NOT_FOUND', `Dependency not found between ${args.spec} and ${args.target}`);
|
|
86
|
+
}
|
|
87
|
+
throw error;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
@@ -83,6 +83,35 @@ export default class SpecView extends PMOCommand {
|
|
|
83
83
|
// Get dependencies
|
|
84
84
|
const dependencies = await this.storage.getSpecDependencies(spec.id);
|
|
85
85
|
const dependents = await this.storage.getSpecDependents(spec.id);
|
|
86
|
+
// JSON output mode
|
|
87
|
+
if (jsonMode) {
|
|
88
|
+
this.log(JSON.stringify({
|
|
89
|
+
success: true,
|
|
90
|
+
spec: {
|
|
91
|
+
id: spec.id,
|
|
92
|
+
title: spec.title,
|
|
93
|
+
status: spec.status,
|
|
94
|
+
type: spec.type,
|
|
95
|
+
problem: spec.problem,
|
|
96
|
+
solution: spec.solution,
|
|
97
|
+
decisions: spec.decisions,
|
|
98
|
+
notNow: spec.notNow,
|
|
99
|
+
uiUx: spec.uiUx,
|
|
100
|
+
acceptanceCriteria: spec.acceptanceCriteria,
|
|
101
|
+
openQuestions: spec.openQuestions,
|
|
102
|
+
requirementsFunctional: spec.requirementsFunctional,
|
|
103
|
+
requirementsTechnical: spec.requirementsTechnical,
|
|
104
|
+
context: spec.context,
|
|
105
|
+
tags: spec.tags,
|
|
106
|
+
createdAt: spec.createdAt.toISOString(),
|
|
107
|
+
updatedAt: spec.updatedAt.toISOString(),
|
|
108
|
+
dependencies: dependencies.map(d => ({ id: d.id, title: d.title, status: d.status })),
|
|
109
|
+
dependents: dependents.map(d => ({ id: d.id, title: d.title, status: d.status })),
|
|
110
|
+
tickets: tickets.map(t => ({ id: t.id, title: t.title, status: t.status })),
|
|
111
|
+
},
|
|
112
|
+
}, null, 2));
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
86
115
|
// Display spec info
|
|
87
116
|
this.log(styles.title(`\n📄 ${spec.title}`));
|
|
88
117
|
this.log(styles.muted('═'.repeat(60)));
|
|
@@ -210,8 +210,8 @@ export default class SupportLogs extends PMOCommand {
|
|
|
210
210
|
copyToClipboard(text) {
|
|
211
211
|
const platform = process.platform;
|
|
212
212
|
// Strip ANSI codes for clipboard
|
|
213
|
-
//
|
|
214
|
-
const plainText = text.replace(/\
|
|
213
|
+
// eslint-disable-next-line no-control-regex -- intentional ANSI escape code stripping
|
|
214
|
+
const plainText = text.replace(/\u001B\[[0-9;]*m/g, '');
|
|
215
215
|
try {
|
|
216
216
|
if (platform === 'darwin') {
|
|
217
217
|
execSync('pbcopy', { input: plainText, encoding: 'utf-8' });
|
|
@@ -135,10 +135,10 @@ export default class TemplateApply extends PMOCommand {
|
|
|
135
135
|
let title = flags.title || template.titlePattern || '';
|
|
136
136
|
let column = flags.column || columns[0];
|
|
137
137
|
let priority = flags.priority || template.defaultPriority;
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
138
|
+
const category = flags.category || template.defaultCategory;
|
|
139
|
+
const assignee = flags.assignee || template.defaultAssignee;
|
|
140
|
+
const owner = flags.owner || template.defaultOwner;
|
|
141
|
+
const description = flags.description || template.descriptionTemplate;
|
|
142
142
|
const labels = template.defaultLabels;
|
|
143
143
|
// Interactive mode
|
|
144
144
|
if (flags.interactive || !title) {
|
|
@@ -182,6 +182,7 @@ export default class TemplateApply extends PMOCommand {
|
|
|
182
182
|
// Add subtasks
|
|
183
183
|
if (!flags['no-subtasks'] && template.suggestedSubtasks.length > 0) {
|
|
184
184
|
for (const subtask of template.suggestedSubtasks) {
|
|
185
|
+
// eslint-disable-next-line no-await-in-loop
|
|
185
186
|
await this.storage.addSubtask(ticket.id, subtask.title);
|
|
186
187
|
}
|
|
187
188
|
}
|
|
@@ -135,7 +135,7 @@ export default class TemplateCreate extends PMOCommand {
|
|
|
135
135
|
}
|
|
136
136
|
// Get optional values
|
|
137
137
|
let description = flags.description;
|
|
138
|
-
|
|
138
|
+
const titlePattern = flags['title-pattern'];
|
|
139
139
|
let priority = flags.priority;
|
|
140
140
|
let category = flags.category;
|
|
141
141
|
const subtasks = flags.subtask || [];
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Flags } from '@oclif/core';
|
|
2
2
|
import { PMOCommand, pmoBaseFlags } from '../../lib/pmo/index.js';
|
|
3
|
+
import { shouldOutputJson } from '../../lib/prompt-json.js';
|
|
3
4
|
import { styles } from '../../lib/styles.js';
|
|
4
5
|
export default class TemplateList extends PMOCommand {
|
|
5
6
|
static description = 'List all templates (ticket and phase)';
|
|
@@ -44,7 +45,7 @@ export default class TemplateList extends PMOCommand {
|
|
|
44
45
|
showTicket ? this.storage.listTicketTemplates(builtinFilter) : Promise.resolve([]),
|
|
45
46
|
showPhase ? this.storage.listPhaseTemplates(builtinFilter) : Promise.resolve([]),
|
|
46
47
|
]);
|
|
47
|
-
if (flags
|
|
48
|
+
if (shouldOutputJson(flags)) {
|
|
48
49
|
const result = {};
|
|
49
50
|
if (showTicket)
|
|
50
51
|
result.ticket = ticketTemplates;
|
|
@@ -2,6 +2,10 @@ import { Command } from '@oclif/core';
|
|
|
2
2
|
export default class ThemeAddNames extends Command {
|
|
3
3
|
static description: string;
|
|
4
4
|
static examples: string[];
|
|
5
|
+
static flags: {
|
|
6
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
7
|
+
machine: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
8
|
+
};
|
|
5
9
|
static args: {
|
|
6
10
|
theme: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
7
11
|
names: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
@@ -3,12 +3,17 @@ import chalk from 'chalk';
|
|
|
3
3
|
import { getWorkspaceInfo } from '../../lib/agents/commands.js';
|
|
4
4
|
import { isValidAgentName, normalizeAgentName } from '../../lib/themes.js';
|
|
5
5
|
import { getTheme, addThemeNames, getThemeNames } from '../../lib/database/index.js';
|
|
6
|
+
import { machineOutputFlags } from '../../lib/pmo/index.js';
|
|
7
|
+
import { shouldOutputJson } from '../../lib/prompt-json.js';
|
|
6
8
|
export default class ThemeAddNames extends Command {
|
|
7
9
|
static description = 'Add names to a theme';
|
|
8
10
|
static examples = [
|
|
9
11
|
'<%= config.bin %> <%= command.id %> greek-gods zeus athena poseidon',
|
|
10
12
|
'<%= config.bin %> <%= command.id %> my-theme agent-a agent-b',
|
|
11
13
|
];
|
|
14
|
+
static flags = {
|
|
15
|
+
...machineOutputFlags,
|
|
16
|
+
};
|
|
12
17
|
static args = {
|
|
13
18
|
theme: Args.string({
|
|
14
19
|
description: 'Theme ID',
|
|
@@ -21,7 +26,8 @@ export default class ThemeAddNames extends Command {
|
|
|
21
26
|
};
|
|
22
27
|
static strict = false; // Allow multiple name arguments
|
|
23
28
|
async run() {
|
|
24
|
-
const { args, argv } = await this.parse(ThemeAddNames);
|
|
29
|
+
const { args, argv, flags } = await this.parse(ThemeAddNames);
|
|
30
|
+
const jsonMode = shouldOutputJson(flags);
|
|
25
31
|
try {
|
|
26
32
|
const workspaceInfo = getWorkspaceInfo();
|
|
27
33
|
// Validate theme exists
|
|
@@ -60,6 +66,10 @@ export default class ThemeAddNames extends Command {
|
|
|
60
66
|
addThemeNames(workspaceInfo.path, theme.id, validNames);
|
|
61
67
|
// Get updated count
|
|
62
68
|
const allNames = getThemeNames(workspaceInfo.path, theme.id);
|
|
69
|
+
if (jsonMode) {
|
|
70
|
+
this.log(JSON.stringify({ type: 'success', result: { theme: args.theme, added: validNames, totalNames: allNames.length } }, null, 2));
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
63
73
|
this.log(chalk.green(`\n Added ${validNames.length} name(s) to ${theme.display_name}:`));
|
|
64
74
|
this.log(chalk.gray(` ${validNames.join(', ')}`));
|
|
65
75
|
this.log(chalk.gray(`\n Theme now has ${allNames.length} names total.`));
|
|
@@ -8,6 +8,8 @@ export default class ThemeCreate extends Command {
|
|
|
8
8
|
static flags: {
|
|
9
9
|
description: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
10
|
'display-name': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
12
|
+
machine: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
11
13
|
};
|
|
12
14
|
run(): Promise<void>;
|
|
13
15
|
}
|
|
@@ -2,6 +2,8 @@ import { Command, Args, Flags } from '@oclif/core';
|
|
|
2
2
|
import chalk from 'chalk';
|
|
3
3
|
import { getWorkspaceInfo } from '../../lib/agents/commands.js';
|
|
4
4
|
import { createTheme, getTheme } from '../../lib/database/index.js';
|
|
5
|
+
import { machineOutputFlags } from '../../lib/pmo/index.js';
|
|
6
|
+
import { shouldOutputJson } from '../../lib/prompt-json.js';
|
|
5
7
|
export default class ThemeCreate extends Command {
|
|
6
8
|
static description = 'Create a custom agent theme';
|
|
7
9
|
static examples = [
|
|
@@ -16,6 +18,7 @@ export default class ThemeCreate extends Command {
|
|
|
16
18
|
}),
|
|
17
19
|
};
|
|
18
20
|
static flags = {
|
|
21
|
+
...machineOutputFlags,
|
|
19
22
|
description: Flags.string({
|
|
20
23
|
char: 'd',
|
|
21
24
|
description: 'Theme description',
|
|
@@ -26,6 +29,7 @@ export default class ThemeCreate extends Command {
|
|
|
26
29
|
};
|
|
27
30
|
async run() {
|
|
28
31
|
const { args, flags } = await this.parse(ThemeCreate);
|
|
32
|
+
const jsonMode = shouldOutputJson(flags);
|
|
29
33
|
try {
|
|
30
34
|
const workspaceInfo = getWorkspaceInfo();
|
|
31
35
|
// Validate theme name format
|
|
@@ -51,6 +55,10 @@ export default class ThemeCreate extends Command {
|
|
|
51
55
|
description: flags.description,
|
|
52
56
|
builtin: false,
|
|
53
57
|
});
|
|
58
|
+
if (jsonMode) {
|
|
59
|
+
this.log(JSON.stringify({ type: 'success', result: { id: theme.id, displayName: theme.display_name, description: theme.description } }, null, 2));
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
54
62
|
this.log(chalk.green(`\n Created theme: ${theme.display_name}`));
|
|
55
63
|
this.log(chalk.gray(` ID: ${theme.id}`));
|
|
56
64
|
if (theme.description) {
|
|
@@ -45,7 +45,7 @@ export default class TicketBulk extends PMOCommand {
|
|
|
45
45
|
const choice = menuChoices.find(c => c.value === value);
|
|
46
46
|
return { name: choice.emoji ? `${choice.emoji} ${choice.name}` : choice.name, value: choice.value };
|
|
47
47
|
};
|
|
48
|
-
const { action } = await
|
|
48
|
+
const { action } = await this.prompt([{
|
|
49
49
|
type: 'list',
|
|
50
50
|
name: 'action',
|
|
51
51
|
message: 'What would you like to do?',
|
|
@@ -64,7 +64,7 @@ export default class TicketBulk extends PMOCommand {
|
|
|
64
64
|
new inquirer.Separator(),
|
|
65
65
|
withEmoji('cancel'),
|
|
66
66
|
]
|
|
67
|
-
}]);
|
|
67
|
+
}], null);
|
|
68
68
|
if (action === 'cancel') {
|
|
69
69
|
this.log(styles.muted('Operation cancelled.'));
|
|
70
70
|
return;
|
|
@@ -98,11 +98,11 @@ export default class TicketComplete extends PMOCommand {
|
|
|
98
98
|
}
|
|
99
99
|
async executeBulk(incompleteTickets, doneColumnName, flags) {
|
|
100
100
|
// Only show header in interactive mode
|
|
101
|
-
if (!(flags
|
|
101
|
+
if (!shouldOutputJson(flags)) {
|
|
102
102
|
this.log(styles.emphasis('✅ Complete Multiple Tickets\n'));
|
|
103
103
|
}
|
|
104
104
|
// Agent mode config for prompts
|
|
105
|
-
const jsonModeConfig = (flags
|
|
105
|
+
const jsonModeConfig = shouldOutputJson(flags) ? { flags, commandName: 'ticket complete --bulk' } : null;
|
|
106
106
|
// Select tickets to complete (now agent-compatible!)
|
|
107
107
|
const { selectedTickets } = await this.prompt([{
|
|
108
108
|
type: 'checkbox',
|
|
@@ -284,6 +284,27 @@ export default class TicketCreate extends PMOCommand {
|
|
|
284
284
|
updateEpicTicketsSection(this.pmoPath, ticketData.epicId, epic.status, ticketInfos, projectId);
|
|
285
285
|
}
|
|
286
286
|
}
|
|
287
|
+
// JSON output mode - match MCP tool response shape
|
|
288
|
+
if (jsonMode) {
|
|
289
|
+
this.log(JSON.stringify({
|
|
290
|
+
success: true,
|
|
291
|
+
ticket: {
|
|
292
|
+
id: ticket.id,
|
|
293
|
+
title: ticket.title,
|
|
294
|
+
priority: ticket.priority,
|
|
295
|
+
category: ticket.category,
|
|
296
|
+
statusName: ticket.statusName,
|
|
297
|
+
statusCategory: ticket.statusCategory,
|
|
298
|
+
projectId: ticket.projectId,
|
|
299
|
+
assignee: ticket.assignee,
|
|
300
|
+
owner: ticket.owner,
|
|
301
|
+
branch: ticket.branch,
|
|
302
|
+
epicId: ticket.epicId,
|
|
303
|
+
position: ticket.position,
|
|
304
|
+
},
|
|
305
|
+
}, null, 2));
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
287
308
|
this.log(styles.success(`\n✅ Created ticket ${styles.emphasis(ticket.id)} in project ${styles.emphasis(projectName)}`));
|
|
288
309
|
if (template) {
|
|
289
310
|
this.log(styles.muted(` Template: ${template.name}`));
|
|
@@ -103,6 +103,14 @@ export default class TicketDelete extends PMOCommand {
|
|
|
103
103
|
await this.storage.deleteTicket(ticketId);
|
|
104
104
|
// Auto-export to board.md after write
|
|
105
105
|
await autoExportToBoard(this.pmoPath, this.storage, (msg) => this.log(styles.muted(msg)));
|
|
106
|
+
// JSON output mode - match MCP tool response shape
|
|
107
|
+
if (jsonMode) {
|
|
108
|
+
this.log(JSON.stringify({
|
|
109
|
+
success: true,
|
|
110
|
+
message: `Deleted ${ticketId}`,
|
|
111
|
+
}, null, 2));
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
106
114
|
this.log(styles.success(`\n✅ Ticket ${styles.emphasis(ticketId)} deleted`));
|
|
107
115
|
this.log(styles.muted(' Removed from database and board'));
|
|
108
116
|
}
|
|
@@ -227,6 +227,31 @@ export default class TicketEdit extends PMOCommand {
|
|
|
227
227
|
const updatedTicket = await this.storage.updateTicket(ticketId, updates);
|
|
228
228
|
// Auto-export to board.md
|
|
229
229
|
await autoExportToBoard(this.pmoPath, this.storage, (msg) => this.log(styles.muted(msg)));
|
|
230
|
+
// JSON output mode - match MCP tool response shape
|
|
231
|
+
if (jsonMode) {
|
|
232
|
+
// Re-fetch to get latest state including subtasks/AC changes
|
|
233
|
+
const finalTicket = (subtasksChanged || acChanged)
|
|
234
|
+
? await this.storage.getTicket(ticketId) ?? updatedTicket
|
|
235
|
+
: updatedTicket;
|
|
236
|
+
this.log(JSON.stringify({
|
|
237
|
+
success: true,
|
|
238
|
+
ticket: {
|
|
239
|
+
id: finalTicket.id,
|
|
240
|
+
title: finalTicket.title,
|
|
241
|
+
priority: finalTicket.priority,
|
|
242
|
+
category: finalTicket.category,
|
|
243
|
+
statusName: finalTicket.statusName,
|
|
244
|
+
statusCategory: finalTicket.statusCategory,
|
|
245
|
+
projectId: finalTicket.projectId,
|
|
246
|
+
assignee: finalTicket.assignee,
|
|
247
|
+
owner: finalTicket.owner,
|
|
248
|
+
branch: finalTicket.branch,
|
|
249
|
+
epicId: finalTicket.epicId,
|
|
250
|
+
position: finalTicket.position,
|
|
251
|
+
},
|
|
252
|
+
}, null, 2));
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
230
255
|
// Display updated ticket
|
|
231
256
|
this.log(styles.success(`\n✅ Updated ticket ${styles.emphasis(updatedTicket.id)}`));
|
|
232
257
|
const changedFields = [];
|
|
@@ -41,7 +41,7 @@ export default class Ticket extends PMOCommand {
|
|
|
41
41
|
return;
|
|
42
42
|
}
|
|
43
43
|
// Show interactive menu
|
|
44
|
-
const { action } = await
|
|
44
|
+
const { action } = await this.prompt([{
|
|
45
45
|
type: 'list',
|
|
46
46
|
name: 'action',
|
|
47
47
|
message: '🎫 ' + message,
|
|
@@ -52,7 +52,7 @@ export default class Ticket extends PMOCommand {
|
|
|
52
52
|
menuChoices[12],
|
|
53
53
|
menuChoices[13],
|
|
54
54
|
],
|
|
55
|
-
}]);
|
|
55
|
+
}], null);
|
|
56
56
|
if (action === 'cancel') {
|
|
57
57
|
return;
|
|
58
58
|
}
|