@proletariat/cli 0.3.23 → 0.3.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/action/create.js +4 -4
- package/dist/commands/action/update.js +3 -3
- package/dist/commands/agent/{temp/cleanup.d.ts → cleanup.d.ts} +1 -1
- package/dist/commands/agent/{temp/cleanup.js → cleanup.js} +4 -4
- package/dist/commands/agent/index.js +8 -8
- package/dist/commands/branch/create.js +2 -2
- package/dist/commands/epic/activate.js +9 -17
- package/dist/commands/epic/archive.js +13 -24
- package/dist/commands/epic/create.d.ts +1 -0
- package/dist/commands/epic/create.js +46 -8
- package/dist/commands/epic/index.js +2 -2
- package/dist/commands/epic/move.js +28 -47
- package/dist/commands/epic/progress.js +10 -14
- package/dist/commands/epic/project.js +42 -59
- package/dist/commands/epic/reorder.js +25 -30
- package/dist/commands/epic/spec.d.ts +1 -0
- package/dist/commands/epic/spec.js +39 -40
- package/dist/commands/epic/ticket.d.ts +2 -0
- package/dist/commands/epic/ticket.js +63 -37
- package/dist/commands/feedback/index.d.ts +10 -0
- package/dist/commands/feedback/index.js +60 -0
- package/dist/commands/feedback/list.d.ts +12 -0
- package/dist/commands/feedback/list.js +126 -0
- package/dist/commands/feedback/submit.d.ts +16 -0
- package/dist/commands/feedback/submit.js +220 -0
- package/dist/commands/{template/phase/delete.d.ts → feedback/view.d.ts} +7 -5
- package/dist/commands/feedback/view.js +109 -0
- package/dist/commands/gh/index.js +4 -0
- package/dist/commands/{epic/link/remove.d.ts → link/create.d.ts} +6 -7
- package/dist/commands/link/create.js +141 -0
- package/dist/commands/{epic/link/relates.d.ts → link/index.d.ts} +4 -5
- package/dist/commands/link/index.js +87 -0
- package/dist/commands/{epic/link/duplicates.d.ts → link/list.d.ts} +7 -4
- package/dist/commands/link/list.js +182 -0
- package/dist/commands/{spec/link → link}/remove.d.ts +4 -5
- package/dist/commands/link/remove.js +120 -0
- package/dist/commands/mcp-server.d.ts +22 -0
- package/dist/commands/mcp-server.js +98 -0
- package/dist/commands/phase/create.js +1 -1
- package/dist/commands/project/create.d.ts +1 -0
- package/dist/commands/project/create.js +38 -4
- package/dist/commands/repo/create.d.ts +38 -0
- package/dist/commands/repo/create.js +283 -0
- package/dist/commands/repo/index.js +7 -0
- package/dist/commands/roadmap/add-project.js +9 -22
- package/dist/commands/roadmap/create.d.ts +0 -1
- package/dist/commands/roadmap/create.js +46 -40
- package/dist/commands/roadmap/delete.js +10 -24
- package/dist/commands/roadmap/generate.d.ts +1 -0
- package/dist/commands/roadmap/generate.js +21 -22
- package/dist/commands/roadmap/remove-project.js +14 -34
- package/dist/commands/roadmap/reorder.js +19 -26
- package/dist/commands/roadmap/update.js +27 -26
- package/dist/commands/roadmap/view.js +5 -12
- package/dist/commands/session/attach.d.ts +1 -8
- package/dist/commands/session/attach.js +93 -59
- package/dist/commands/session/list.d.ts +0 -8
- package/dist/commands/session/list.js +130 -81
- package/dist/commands/spec/create.d.ts +1 -0
- package/dist/commands/spec/create.js +44 -3
- package/dist/commands/spec/edit.js +63 -33
- package/dist/commands/spec/index.js +2 -2
- package/dist/commands/{agent/staff → staff}/add.js +10 -10
- package/dist/commands/{agent/staff → staff}/index.d.ts +1 -1
- package/dist/commands/{agent/staff → staff}/index.js +7 -7
- package/dist/commands/{agent/staff → staff}/list.js +3 -3
- package/dist/commands/{agent/staff → staff}/remove.d.ts +1 -1
- package/dist/commands/{agent/staff → staff}/remove.js +8 -8
- package/dist/commands/{template/phase/index.d.ts → support/book.d.ts} +2 -2
- package/dist/commands/support/book.js +54 -0
- package/dist/commands/{template/ticket/index.d.ts → support/discord.d.ts} +2 -2
- package/dist/commands/support/discord.js +54 -0
- package/dist/commands/support/docs.d.ts +10 -0
- package/dist/commands/support/docs.js +54 -0
- package/dist/commands/support/index.d.ts +19 -0
- package/dist/commands/support/index.js +81 -0
- package/dist/commands/support/issues.d.ts +11 -0
- package/dist/commands/support/issues.js +77 -0
- package/dist/commands/support/logs.d.ts +18 -0
- package/dist/commands/support/logs.js +247 -0
- package/dist/commands/{ticket/template → template}/apply.d.ts +8 -6
- package/dist/commands/template/apply.js +262 -0
- package/dist/commands/{ticket/template → template}/create.d.ts +5 -6
- package/dist/commands/template/create.js +238 -0
- package/dist/commands/template/index.js +48 -36
- package/dist/commands/{ticket/template → template}/save.d.ts +2 -2
- package/dist/commands/template/save.js +104 -0
- package/dist/commands/{phase/template → template}/update.d.ts +2 -2
- package/dist/commands/template/update.js +99 -0
- package/dist/commands/{agent/themes → theme}/add-names.d.ts +1 -1
- package/dist/commands/{agent/themes → theme}/add-names.js +6 -6
- package/dist/commands/{agent/themes → theme}/create.d.ts +1 -1
- package/dist/commands/{agent/themes → theme}/create.js +5 -5
- package/dist/commands/{agent/themes → theme}/index.d.ts +1 -1
- package/dist/commands/{agent/themes → theme}/index.js +10 -10
- package/dist/commands/{agent/themes → theme}/list.d.ts +1 -1
- package/dist/commands/{agent/themes → theme}/list.js +5 -5
- package/dist/commands/{agent/themes → theme}/set.d.ts +1 -1
- package/dist/commands/{agent/themes → theme}/set.js +7 -7
- package/dist/commands/ticket/create.d.ts +1 -0
- package/dist/commands/ticket/create.js +75 -15
- package/dist/commands/ticket/edit.js +44 -13
- package/dist/commands/ticket/index.js +6 -6
- package/dist/commands/ticket/move.d.ts +7 -0
- package/dist/commands/ticket/move.js +132 -0
- package/dist/commands/work/spawn.d.ts +1 -0
- package/dist/commands/work/spawn.js +72 -8
- package/dist/commands/work/start.js +6 -0
- package/dist/lib/execution/runners.js +21 -17
- package/dist/lib/execution/session-utils.d.ts +60 -0
- package/dist/lib/execution/session-utils.js +162 -0
- package/dist/lib/execution/spawner.d.ts +2 -0
- package/dist/lib/execution/spawner.js +42 -0
- package/dist/lib/flags/resolver.d.ts +2 -2
- package/dist/lib/flags/resolver.js +15 -0
- package/dist/lib/init/index.js +18 -0
- package/dist/lib/mcp/helpers.d.ts +43 -0
- package/dist/lib/mcp/helpers.js +57 -0
- package/dist/lib/mcp/index.d.ts +6 -0
- package/dist/lib/mcp/index.js +6 -0
- package/dist/lib/mcp/tools/action.d.ts +6 -0
- package/dist/lib/mcp/tools/action.js +88 -0
- package/dist/lib/mcp/tools/board.d.ts +6 -0
- package/dist/lib/mcp/tools/board.js +139 -0
- package/dist/lib/mcp/tools/category.d.ts +6 -0
- package/dist/lib/mcp/tools/category.js +84 -0
- package/dist/lib/mcp/tools/cli-passthrough.d.ts +15 -0
- package/dist/lib/mcp/tools/cli-passthrough.js +333 -0
- package/dist/lib/mcp/tools/epic.d.ts +6 -0
- package/dist/lib/mcp/tools/epic.js +178 -0
- package/dist/lib/mcp/tools/index.d.ts +18 -0
- package/dist/lib/mcp/tools/index.js +19 -0
- package/dist/lib/mcp/tools/phase.d.ts +6 -0
- package/dist/lib/mcp/tools/phase.js +131 -0
- package/dist/lib/mcp/tools/project.d.ts +6 -0
- package/dist/lib/mcp/tools/project.js +196 -0
- package/dist/lib/mcp/tools/roadmap.d.ts +6 -0
- package/dist/lib/mcp/tools/roadmap.js +123 -0
- package/dist/lib/mcp/tools/spec.d.ts +6 -0
- package/dist/lib/mcp/tools/spec.js +196 -0
- package/dist/lib/mcp/tools/status.d.ts +6 -0
- package/dist/lib/mcp/tools/status.js +109 -0
- package/dist/lib/mcp/tools/template.d.ts +6 -0
- package/dist/lib/mcp/tools/template.js +107 -0
- package/dist/lib/mcp/tools/ticket.d.ts +6 -0
- package/dist/lib/mcp/tools/ticket.js +393 -0
- package/dist/lib/mcp/tools/view.d.ts +6 -0
- package/dist/lib/mcp/tools/view.js +76 -0
- package/dist/lib/mcp/tools/work.d.ts +6 -0
- package/dist/lib/mcp/tools/work.js +132 -0
- package/dist/lib/mcp/tools/workflow.d.ts +6 -0
- package/dist/lib/mcp/tools/workflow.js +95 -0
- package/dist/lib/mcp/types.d.ts +17 -0
- package/dist/lib/mcp/types.js +4 -0
- package/dist/lib/multiline-input.d.ts +63 -0
- package/dist/lib/multiline-input.js +360 -0
- package/dist/lib/prompt-json.d.ts +57 -6
- package/dist/lib/prompt-json.js +45 -0
- package/dist/lib/repos/git.d.ts +7 -0
- package/dist/lib/repos/git.js +20 -0
- package/oclif.manifest.json +3690 -4995
- package/package.json +6 -4
- package/dist/commands/agent/temp/index.d.ts +0 -14
- package/dist/commands/agent/temp/index.js +0 -85
- package/dist/commands/agent/temp/list.d.ts +0 -7
- package/dist/commands/agent/temp/list.js +0 -108
- package/dist/commands/epic/link/block.d.ts +0 -14
- package/dist/commands/epic/link/block.js +0 -81
- package/dist/commands/epic/link/duplicates.js +0 -68
- package/dist/commands/epic/link/index.d.ts +0 -19
- package/dist/commands/epic/link/index.js +0 -272
- package/dist/commands/epic/link/relates.js +0 -68
- package/dist/commands/epic/link/remove.js +0 -93
- package/dist/commands/phase/template/apply.d.ts +0 -17
- package/dist/commands/phase/template/apply.js +0 -108
- package/dist/commands/phase/template/create.d.ts +0 -17
- package/dist/commands/phase/template/create.js +0 -104
- package/dist/commands/phase/template/delete.d.ts +0 -17
- package/dist/commands/phase/template/delete.js +0 -100
- package/dist/commands/phase/template/index.d.ts +0 -15
- package/dist/commands/phase/template/index.js +0 -130
- package/dist/commands/phase/template/list.d.ts +0 -16
- package/dist/commands/phase/template/list.js +0 -97
- package/dist/commands/phase/template/update.js +0 -89
- package/dist/commands/spec/link/depends.d.ts +0 -14
- package/dist/commands/spec/link/depends.js +0 -64
- package/dist/commands/spec/link/duplicates.d.ts +0 -14
- package/dist/commands/spec/link/duplicates.js +0 -63
- package/dist/commands/spec/link/index.d.ts +0 -19
- package/dist/commands/spec/link/index.js +0 -207
- package/dist/commands/spec/link/relates.d.ts +0 -14
- package/dist/commands/spec/link/relates.js +0 -63
- package/dist/commands/spec/link/remove.js +0 -96
- package/dist/commands/template/phase/apply.d.ts +0 -14
- package/dist/commands/template/phase/apply.js +0 -43
- package/dist/commands/template/phase/create.d.ts +0 -13
- package/dist/commands/template/phase/create.js +0 -38
- package/dist/commands/template/phase/delete.js +0 -36
- package/dist/commands/template/phase/index.js +0 -63
- package/dist/commands/template/phase/list.d.ts +0 -11
- package/dist/commands/template/phase/list.js +0 -36
- package/dist/commands/template/phase/update.d.ts +0 -14
- package/dist/commands/template/phase/update.js +0 -43
- package/dist/commands/template/ticket/apply.d.ts +0 -17
- package/dist/commands/template/ticket/apply.js +0 -60
- package/dist/commands/template/ticket/create.d.ts +0 -20
- package/dist/commands/template/ticket/create.js +0 -89
- package/dist/commands/template/ticket/delete.d.ts +0 -13
- package/dist/commands/template/ticket/delete.js +0 -38
- package/dist/commands/template/ticket/index.js +0 -63
- package/dist/commands/template/ticket/list.d.ts +0 -11
- package/dist/commands/template/ticket/list.js +0 -36
- package/dist/commands/template/ticket/save.d.ts +0 -15
- package/dist/commands/template/ticket/save.js +0 -46
- package/dist/commands/ticket/link/block.d.ts +0 -14
- package/dist/commands/ticket/link/block.js +0 -96
- package/dist/commands/ticket/link/duplicates.d.ts +0 -14
- package/dist/commands/ticket/link/duplicates.js +0 -95
- package/dist/commands/ticket/link/index.d.ts +0 -19
- package/dist/commands/ticket/link/index.js +0 -256
- package/dist/commands/ticket/link/relates.d.ts +0 -14
- package/dist/commands/ticket/link/relates.js +0 -95
- package/dist/commands/ticket/link/remove.d.ts +0 -16
- package/dist/commands/ticket/link/remove.js +0 -132
- package/dist/commands/ticket/template/apply.js +0 -252
- package/dist/commands/ticket/template/create.js +0 -386
- package/dist/commands/ticket/template/delete.d.ts +0 -17
- package/dist/commands/ticket/template/delete.js +0 -94
- package/dist/commands/ticket/template/index.d.ts +0 -15
- package/dist/commands/ticket/template/index.js +0 -120
- package/dist/commands/ticket/template/list.d.ts +0 -16
- package/dist/commands/ticket/template/list.js +0 -112
- package/dist/commands/ticket/template/save.js +0 -163
- /package/dist/commands/{agent/staff → staff}/add.d.ts +0 -0
- /package/dist/commands/{agent/staff → staff}/list.d.ts +0 -0
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import { Args } from '@oclif/core';
|
|
2
|
-
import inquirer from 'inquirer';
|
|
3
|
-
import { PMOCommand, pmoBaseFlags } from '../../../lib/pmo/index.js';
|
|
4
|
-
import { styles } from '../../../lib/styles.js';
|
|
5
|
-
import { shouldOutputJson, outputPromptAsJson, outputErrorAsJson, createMetadata, buildPromptConfig, } from '../../../lib/prompt-json.js';
|
|
6
|
-
export default class SpecLinkDuplicates extends PMOCommand {
|
|
7
|
-
static description = 'Mark a spec as duplicate of another';
|
|
8
|
-
static examples = ['<%= config.bin %> <%= command.id %> my-feature other-spec'];
|
|
9
|
-
static args = {
|
|
10
|
-
id: Args.string({ description: 'Duplicate spec ID', required: true }),
|
|
11
|
-
original: Args.string({ description: 'Original spec ID', required: false }),
|
|
12
|
-
};
|
|
13
|
-
static flags = {
|
|
14
|
-
...pmoBaseFlags,
|
|
15
|
-
};
|
|
16
|
-
async execute() {
|
|
17
|
-
const { args, flags } = await this.parse(SpecLinkDuplicates);
|
|
18
|
-
// Check if JSON output mode is active
|
|
19
|
-
const jsonMode = shouldOutputJson(flags);
|
|
20
|
-
// Helper to handle errors in JSON mode
|
|
21
|
-
const handleError = (code, message) => {
|
|
22
|
-
if (jsonMode) {
|
|
23
|
-
outputErrorAsJson(code, message, createMetadata('spec link duplicates', flags));
|
|
24
|
-
this.exit(1);
|
|
25
|
-
}
|
|
26
|
-
this.error(message);
|
|
27
|
-
};
|
|
28
|
-
const spec = await this.storage.getSpec(args.id);
|
|
29
|
-
if (!spec)
|
|
30
|
-
return handleError('SPEC_NOT_FOUND', `Spec not found: ${args.id}`);
|
|
31
|
-
let originalId = args.original;
|
|
32
|
-
if (!originalId) {
|
|
33
|
-
const allSpecs = await this.storage.listSpecs();
|
|
34
|
-
const otherSpecs = allSpecs.filter(s => s.id !== args.id);
|
|
35
|
-
if (otherSpecs.length === 0) {
|
|
36
|
-
if (jsonMode) {
|
|
37
|
-
outputErrorAsJson('NO_OTHER_SPECS', 'No other specs.', createMetadata('spec link duplicates', flags));
|
|
38
|
-
return;
|
|
39
|
-
}
|
|
40
|
-
this.log(styles.muted('\nNo other specs.'));
|
|
41
|
-
return;
|
|
42
|
-
}
|
|
43
|
-
// In JSON mode, output spec selection prompt
|
|
44
|
-
if (jsonMode) {
|
|
45
|
-
const specChoices = otherSpecs.map(s => ({
|
|
46
|
-
name: `${s.id} - ${s.title}`,
|
|
47
|
-
value: s.id,
|
|
48
|
-
command: `prlt spec link duplicates ${args.id} ${s.id} --json`,
|
|
49
|
-
}));
|
|
50
|
-
outputPromptAsJson(buildPromptConfig('list', 'original', `Select the original spec (${args.id} is a duplicate of):`, specChoices), createMetadata('spec link duplicates', flags));
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
const { selected } = await inquirer.prompt([{ type: 'list', name: 'selected', message: `Select the original spec (${args.id} is a duplicate of):`,
|
|
54
|
-
choices: otherSpecs.map(s => ({ name: `${s.id} - ${s.title}`, value: s.id })) }]);
|
|
55
|
-
originalId = selected;
|
|
56
|
-
}
|
|
57
|
-
const originalSpec = await this.storage.getSpec(originalId);
|
|
58
|
-
if (!originalSpec)
|
|
59
|
-
this.error(`Spec not found: ${originalId}`);
|
|
60
|
-
await this.storage.createSpecDependency(args.id, originalId, 'duplicates');
|
|
61
|
-
this.log(styles.success(`\n✅ ${styles.emphasis(args.id)} duplicates ${styles.emphasis(originalId)}`));
|
|
62
|
-
}
|
|
63
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
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
|
-
id: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
7
|
-
};
|
|
8
|
-
static flags: {
|
|
9
|
-
depends: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
|
-
relates: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
|
-
duplicates: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
|
-
all: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
13
|
-
json: 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
|
-
private addDependency;
|
|
18
|
-
private viewDependencies;
|
|
19
|
-
}
|
|
@@ -1,207 +0,0 @@
|
|
|
1
|
-
import { Args, Flags } from '@oclif/core';
|
|
2
|
-
import inquirer from 'inquirer';
|
|
3
|
-
import { PMOCommand, pmoBaseFlags } from '../../../lib/pmo/index.js';
|
|
4
|
-
import { styles } from '../../../lib/styles.js';
|
|
5
|
-
import { shouldOutputJson, outputPromptAsJson, outputErrorAsJson, createMetadata, buildPromptConfig, } from '../../../lib/prompt-json.js';
|
|
6
|
-
export default class SpecLink extends PMOCommand {
|
|
7
|
-
static description = 'Manage spec dependencies (links)';
|
|
8
|
-
static examples = [
|
|
9
|
-
'<%= config.bin %> <%= command.id %> my-feature # List dependencies',
|
|
10
|
-
'<%= config.bin %> <%= command.id %> my-feature --depends other-spec # my-feature depends on other-spec',
|
|
11
|
-
'<%= config.bin %> <%= command.id %> my-feature --relates other-spec # my-feature relates to other-spec',
|
|
12
|
-
'<%= config.bin %> <%= command.id %> my-feature --duplicates other-spec',
|
|
13
|
-
'<%= config.bin %> <%= command.id %> my-feature --all # Show all links',
|
|
14
|
-
];
|
|
15
|
-
static args = {
|
|
16
|
-
id: Args.string({ description: 'Spec ID', required: false }),
|
|
17
|
-
};
|
|
18
|
-
static flags = {
|
|
19
|
-
...pmoBaseFlags,
|
|
20
|
-
depends: Flags.string({ char: 'd', description: 'Add depends_on dependency' }),
|
|
21
|
-
relates: Flags.string({ char: 'r', description: 'Add relates_to dependency' }),
|
|
22
|
-
duplicates: Flags.string({ description: 'Add duplicates dependency' }),
|
|
23
|
-
all: Flags.boolean({ char: 'a', description: 'Show all dependencies', default: false }),
|
|
24
|
-
};
|
|
25
|
-
async execute() {
|
|
26
|
-
const { args, flags } = await this.parse(SpecLink);
|
|
27
|
-
// Check if JSON output mode is active
|
|
28
|
-
const jsonMode = shouldOutputJson(flags);
|
|
29
|
-
let specId = args.id;
|
|
30
|
-
if (!specId) {
|
|
31
|
-
const specs = await this.storage.listSpecs();
|
|
32
|
-
if (specs.length === 0) {
|
|
33
|
-
if (jsonMode) {
|
|
34
|
-
outputErrorAsJson('NO_SPECS', 'No specs found.', createMetadata('spec link', flags));
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
this.log(styles.muted('\nNo specs found.'));
|
|
38
|
-
return;
|
|
39
|
-
}
|
|
40
|
-
// In JSON mode, output spec selection prompt
|
|
41
|
-
if (jsonMode) {
|
|
42
|
-
const specChoices = specs.map(s => ({ name: `${s.id} - ${s.title}`, value: s.id }));
|
|
43
|
-
outputPromptAsJson(buildPromptConfig('list', 'id', 'Select spec to manage dependencies:', specChoices), createMetadata('spec link', flags));
|
|
44
|
-
return;
|
|
45
|
-
}
|
|
46
|
-
const { selected } = await inquirer.prompt([{
|
|
47
|
-
type: 'list',
|
|
48
|
-
name: 'selected',
|
|
49
|
-
message: 'Select spec to manage dependencies:',
|
|
50
|
-
choices: specs.map(s => ({ name: `${s.id} - ${s.title}`, value: s.id })),
|
|
51
|
-
}]);
|
|
52
|
-
specId = selected;
|
|
53
|
-
}
|
|
54
|
-
const spec = await this.storage.getSpec(specId);
|
|
55
|
-
if (!spec)
|
|
56
|
-
this.error(`Spec not found: ${specId}`);
|
|
57
|
-
// If a dependency flag is provided, add the dependency directly
|
|
58
|
-
if (flags.depends || flags.relates || flags.duplicates) {
|
|
59
|
-
const targetId = flags.depends || flags.relates || flags.duplicates;
|
|
60
|
-
const dependencyType = flags.depends ? 'depends_on' :
|
|
61
|
-
flags.relates ? 'relates_to' : 'duplicates';
|
|
62
|
-
await this.addDependency(specId, targetId, dependencyType, spec.title);
|
|
63
|
-
return;
|
|
64
|
-
}
|
|
65
|
-
// Interactive mode: show menu in a loop
|
|
66
|
-
let continueLoop = true;
|
|
67
|
-
while (continueLoop) {
|
|
68
|
-
// eslint-disable-next-line no-await-in-loop -- Interactive user loop
|
|
69
|
-
const allSpecs = await this.storage.listSpecs();
|
|
70
|
-
const otherSpecs = allSpecs.filter(s => s.id !== specId);
|
|
71
|
-
// eslint-disable-next-line no-await-in-loop -- Interactive user prompt
|
|
72
|
-
const { action } = await inquirer.prompt([{
|
|
73
|
-
type: 'list',
|
|
74
|
-
name: 'action',
|
|
75
|
-
message: `Dependencies for ${spec.id}:`,
|
|
76
|
-
choices: [
|
|
77
|
-
{ name: 'View dependencies', value: 'view' },
|
|
78
|
-
{ name: 'Add depends_on dependency', value: 'depends_on' },
|
|
79
|
-
{ name: 'Add relates_to dependency', value: 'relates_to' },
|
|
80
|
-
{ name: 'Add duplicates dependency', value: 'duplicates' },
|
|
81
|
-
new inquirer.Separator(),
|
|
82
|
-
{ name: 'Remove dependency', value: 'remove' },
|
|
83
|
-
{ name: 'Done', value: 'done' },
|
|
84
|
-
],
|
|
85
|
-
}]);
|
|
86
|
-
if (action === 'done') {
|
|
87
|
-
continueLoop = false;
|
|
88
|
-
continue;
|
|
89
|
-
}
|
|
90
|
-
if (action === 'view') {
|
|
91
|
-
// eslint-disable-next-line no-await-in-loop -- User action handling
|
|
92
|
-
await this.viewDependencies(specId, spec, flags.all);
|
|
93
|
-
continue;
|
|
94
|
-
}
|
|
95
|
-
if (action === 'remove') {
|
|
96
|
-
// eslint-disable-next-line no-await-in-loop -- User action handling
|
|
97
|
-
const dependencies = await this.storage.listSpecDependencies(specId);
|
|
98
|
-
if (dependencies.length === 0) {
|
|
99
|
-
this.log(styles.muted('\nNo dependencies to remove.'));
|
|
100
|
-
continue;
|
|
101
|
-
}
|
|
102
|
-
// eslint-disable-next-line no-await-in-loop -- Building choices for current interaction
|
|
103
|
-
const choices = await Promise.all(dependencies.map(async (dep) => {
|
|
104
|
-
const depSpec = await this.storage.getSpec(dep.dependsOnSpecId);
|
|
105
|
-
return {
|
|
106
|
-
name: `${dep.dependsOnSpecId} - ${depSpec?.title || 'Unknown'} (${dep.dependencyType})`,
|
|
107
|
-
value: { targetId: dep.dependsOnSpecId, type: dep.dependencyType }
|
|
108
|
-
};
|
|
109
|
-
}));
|
|
110
|
-
// eslint-disable-next-line no-await-in-loop -- User selection prompt
|
|
111
|
-
const { selected } = await inquirer.prompt([{
|
|
112
|
-
type: 'list',
|
|
113
|
-
name: 'selected',
|
|
114
|
-
message: 'Select dependency to remove:',
|
|
115
|
-
choices,
|
|
116
|
-
}]);
|
|
117
|
-
// eslint-disable-next-line no-await-in-loop -- Action after user selection
|
|
118
|
-
await this.storage.deleteSpecDependency(specId, selected.targetId, selected.type);
|
|
119
|
-
this.log(styles.success(`\n✅ Removed dependency: ${specId} → ${selected.targetId}`));
|
|
120
|
-
continue;
|
|
121
|
-
}
|
|
122
|
-
// Add dependency
|
|
123
|
-
if (otherSpecs.length === 0) {
|
|
124
|
-
this.log(styles.muted('\nNo other specs to link to.'));
|
|
125
|
-
continue;
|
|
126
|
-
}
|
|
127
|
-
// eslint-disable-next-line no-await-in-loop -- User selection prompt
|
|
128
|
-
const { targetId } = await inquirer.prompt([{
|
|
129
|
-
type: 'list',
|
|
130
|
-
name: 'targetId',
|
|
131
|
-
message: `Select spec that ${specId} ${action === 'depends_on' ? 'depends on' : action === 'relates_to' ? 'relates to' : 'duplicates'}:`,
|
|
132
|
-
choices: otherSpecs.map(s => ({ name: `${s.id} - ${s.title}`, value: s.id })),
|
|
133
|
-
}]);
|
|
134
|
-
// eslint-disable-next-line no-await-in-loop -- Action after user selection
|
|
135
|
-
await this.addDependency(specId, targetId, action, spec.title);
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
async addDependency(specId, targetId, dependencyType, specTitle) {
|
|
139
|
-
const targetSpec = await this.storage.getSpec(targetId);
|
|
140
|
-
if (!targetSpec) {
|
|
141
|
-
this.error(`Spec not found: ${targetId}`);
|
|
142
|
-
}
|
|
143
|
-
try {
|
|
144
|
-
await this.storage.createSpecDependency(specId, targetId, dependencyType);
|
|
145
|
-
const typeLabel = dependencyType === 'depends_on' ? 'depends on' :
|
|
146
|
-
dependencyType === 'relates_to' ? 'relates to' : 'duplicates';
|
|
147
|
-
this.log(styles.success(`\n✅ ${styles.emphasis(specId)} ${typeLabel} ${styles.emphasis(targetId)}`));
|
|
148
|
-
this.log(styles.muted(` ${specTitle}`));
|
|
149
|
-
this.log(styles.muted(` ${typeLabel} ${targetSpec.title}`));
|
|
150
|
-
}
|
|
151
|
-
catch (error) {
|
|
152
|
-
if (error instanceof Error) {
|
|
153
|
-
if (error.message.includes('already exists')) {
|
|
154
|
-
this.error('Dependency already exists');
|
|
155
|
-
}
|
|
156
|
-
if (error.message.includes('self-dependency')) {
|
|
157
|
-
this.error('Cannot create self-dependency');
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
throw error;
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
async viewDependencies(specId, spec, showAll) {
|
|
164
|
-
const dependencies = await this.storage.listSpecDependencies(specId);
|
|
165
|
-
this.log(`\n${styles.emphasis(spec.id)}: ${spec.title}`);
|
|
166
|
-
const dependsOn = dependencies.filter(d => d.dependencyType === 'depends_on');
|
|
167
|
-
if (dependsOn.length > 0) {
|
|
168
|
-
this.log(styles.muted('\n Depends on:'));
|
|
169
|
-
// Fetch all dependency specs in parallel
|
|
170
|
-
const depSpecs = await Promise.all(dependsOn.map(dep => this.storage.getSpec(dep.dependsOnSpecId)));
|
|
171
|
-
for (const depSpec of depSpecs) {
|
|
172
|
-
if (depSpec)
|
|
173
|
-
this.log(` - ${depSpec.id}: ${depSpec.title}`);
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
const otherDeps = dependencies.filter(d => d.dependencyType !== 'depends_on');
|
|
177
|
-
if (otherDeps.length > 0) {
|
|
178
|
-
this.log(styles.muted('\n Related:'));
|
|
179
|
-
// Fetch all related specs in parallel
|
|
180
|
-
const relatedSpecs = await Promise.all(otherDeps.map(async (dep) => ({ dep, spec: await this.storage.getSpec(dep.dependsOnSpecId) })));
|
|
181
|
-
for (const { dep, spec: relatedSpec } of relatedSpecs) {
|
|
182
|
-
if (relatedSpec)
|
|
183
|
-
this.log(` - ${dep.dependencyType}: ${relatedSpec.id} - ${relatedSpec.title}`);
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
if (showAll) {
|
|
187
|
-
const allSpecs = await this.storage.listSpecs();
|
|
188
|
-
// Find all specs that depend on this spec in parallel
|
|
189
|
-
const dependedByResults = await Promise.all(allSpecs
|
|
190
|
-
.filter(otherSpec => otherSpec.id !== specId)
|
|
191
|
-
.map(async (otherSpec) => {
|
|
192
|
-
const otherDeps = await this.storage.listSpecDependencies(otherSpec.id);
|
|
193
|
-
const dep = otherDeps.find(d => d.dependsOnSpecId === specId);
|
|
194
|
-
return dep ? { spec: otherSpec, type: dep.dependencyType } : null;
|
|
195
|
-
}));
|
|
196
|
-
const dependedBy = dependedByResults.filter((d) => d !== null);
|
|
197
|
-
if (dependedBy.length > 0) {
|
|
198
|
-
this.log(styles.muted('\n Depended by:'));
|
|
199
|
-
for (const item of dependedBy)
|
|
200
|
-
this.log(` - ${item.spec.id}: ${item.spec.title} (${item.type})`);
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
if (dependencies.length === 0)
|
|
204
|
-
this.log(styles.muted('\n No dependencies.'));
|
|
205
|
-
this.log('');
|
|
206
|
-
}
|
|
207
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { PMOCommand } from '../../../lib/pmo/index.js';
|
|
2
|
-
export default class SpecLinkRelates 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
|
-
target: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
8
|
-
};
|
|
9
|
-
static flags: {
|
|
10
|
-
json: 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
|
-
}
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import { Args } from '@oclif/core';
|
|
2
|
-
import inquirer from 'inquirer';
|
|
3
|
-
import { PMOCommand, pmoBaseFlags } from '../../../lib/pmo/index.js';
|
|
4
|
-
import { styles } from '../../../lib/styles.js';
|
|
5
|
-
import { shouldOutputJson, outputPromptAsJson, outputErrorAsJson, createMetadata, buildPromptConfig, } from '../../../lib/prompt-json.js';
|
|
6
|
-
export default class SpecLinkRelates extends PMOCommand {
|
|
7
|
-
static description = 'Add a relates_to dependency (informational link)';
|
|
8
|
-
static examples = ['<%= config.bin %> <%= command.id %> my-feature other-spec'];
|
|
9
|
-
static args = {
|
|
10
|
-
id: Args.string({ description: 'Spec ID', required: true }),
|
|
11
|
-
target: Args.string({ description: 'Related spec ID', required: false }),
|
|
12
|
-
};
|
|
13
|
-
static flags = {
|
|
14
|
-
...pmoBaseFlags,
|
|
15
|
-
};
|
|
16
|
-
async execute() {
|
|
17
|
-
const { args, flags } = await this.parse(SpecLinkRelates);
|
|
18
|
-
// Check if JSON output mode is active
|
|
19
|
-
const jsonMode = shouldOutputJson(flags);
|
|
20
|
-
// Helper to handle errors in JSON mode
|
|
21
|
-
const handleError = (code, message) => {
|
|
22
|
-
if (jsonMode) {
|
|
23
|
-
outputErrorAsJson(code, message, createMetadata('spec link relates', flags));
|
|
24
|
-
this.exit(1);
|
|
25
|
-
}
|
|
26
|
-
this.error(message);
|
|
27
|
-
};
|
|
28
|
-
const spec = await this.storage.getSpec(args.id);
|
|
29
|
-
if (!spec)
|
|
30
|
-
return handleError('SPEC_NOT_FOUND', `Spec not found: ${args.id}`);
|
|
31
|
-
let targetId = args.target;
|
|
32
|
-
if (!targetId) {
|
|
33
|
-
const allSpecs = await this.storage.listSpecs();
|
|
34
|
-
const otherSpecs = allSpecs.filter(s => s.id !== args.id);
|
|
35
|
-
if (otherSpecs.length === 0) {
|
|
36
|
-
if (jsonMode) {
|
|
37
|
-
outputErrorAsJson('NO_OTHER_SPECS', 'No other specs.', createMetadata('spec link relates', flags));
|
|
38
|
-
return;
|
|
39
|
-
}
|
|
40
|
-
this.log(styles.muted('\nNo other specs.'));
|
|
41
|
-
return;
|
|
42
|
-
}
|
|
43
|
-
// In JSON mode, output spec selection prompt
|
|
44
|
-
if (jsonMode) {
|
|
45
|
-
const specChoices = otherSpecs.map(s => ({
|
|
46
|
-
name: `${s.id} - ${s.title}`,
|
|
47
|
-
value: s.id,
|
|
48
|
-
command: `prlt spec link relates ${args.id} ${s.id} --json`,
|
|
49
|
-
}));
|
|
50
|
-
outputPromptAsJson(buildPromptConfig('list', 'target', `Select spec that ${args.id} relates to:`, specChoices), createMetadata('spec link relates', flags));
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
const { selected } = await inquirer.prompt([{ type: 'list', name: 'selected', message: `Select spec that ${args.id} relates to:`,
|
|
54
|
-
choices: otherSpecs.map(s => ({ name: `${s.id} - ${s.title}`, value: s.id })) }]);
|
|
55
|
-
targetId = selected;
|
|
56
|
-
}
|
|
57
|
-
const targetSpec = await this.storage.getSpec(targetId);
|
|
58
|
-
if (!targetSpec)
|
|
59
|
-
this.error(`Spec not found: ${targetId}`);
|
|
60
|
-
await this.storage.createSpecDependency(args.id, targetId, 'relates_to');
|
|
61
|
-
this.log(styles.success(`\n✅ ${styles.emphasis(args.id)} relates to ${styles.emphasis(targetId)}`));
|
|
62
|
-
}
|
|
63
|
-
}
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import { Args, Flags } from '@oclif/core';
|
|
2
|
-
import inquirer from 'inquirer';
|
|
3
|
-
import { PMOCommand, pmoBaseFlags } from '../../../lib/pmo/index.js';
|
|
4
|
-
import { styles } from '../../../lib/styles.js';
|
|
5
|
-
import { shouldOutputJson, outputPromptAsJson, outputErrorAsJson, createMetadata, buildPromptConfig, } from '../../../lib/prompt-json.js';
|
|
6
|
-
export default class SpecLinkRemove extends PMOCommand {
|
|
7
|
-
static description = 'Remove a dependency from a spec';
|
|
8
|
-
static examples = [
|
|
9
|
-
'<%= config.bin %> <%= command.id %> my-feature other-spec',
|
|
10
|
-
'<%= config.bin %> <%= command.id %> my-feature --all',
|
|
11
|
-
];
|
|
12
|
-
static args = {
|
|
13
|
-
id: Args.string({ description: 'Spec ID', required: true }),
|
|
14
|
-
target: Args.string({ description: 'Target spec ID to unlink', required: false }),
|
|
15
|
-
};
|
|
16
|
-
static flags = {
|
|
17
|
-
...pmoBaseFlags,
|
|
18
|
-
type: Flags.string({ char: 't', description: 'Dependency type', options: ['depends_on', 'relates_to', 'duplicates'] }),
|
|
19
|
-
all: Flags.boolean({ char: 'a', description: 'Remove all dependencies', default: false }),
|
|
20
|
-
};
|
|
21
|
-
async execute() {
|
|
22
|
-
const { args, flags } = await this.parse(SpecLinkRemove);
|
|
23
|
-
// Check if JSON output mode is active
|
|
24
|
-
const jsonMode = shouldOutputJson(flags);
|
|
25
|
-
// Helper to handle errors in JSON mode
|
|
26
|
-
const handleError = (code, message) => {
|
|
27
|
-
if (jsonMode) {
|
|
28
|
-
outputErrorAsJson(code, message, createMetadata('spec link remove', flags));
|
|
29
|
-
this.exit(1);
|
|
30
|
-
}
|
|
31
|
-
this.error(message);
|
|
32
|
-
};
|
|
33
|
-
const spec = await this.storage.getSpec(args.id);
|
|
34
|
-
if (!spec)
|
|
35
|
-
return handleError('SPEC_NOT_FOUND', `Spec not found: ${args.id}`);
|
|
36
|
-
const dependencies = await this.storage.listSpecDependencies(args.id);
|
|
37
|
-
if (dependencies.length === 0) {
|
|
38
|
-
if (jsonMode) {
|
|
39
|
-
outputErrorAsJson('NO_DEPENDENCIES', `Spec ${args.id} has no dependencies.`, createMetadata('spec link remove', flags));
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
this.log(styles.muted(`\nSpec ${args.id} has no dependencies.`));
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
|
-
if (flags.all) {
|
|
46
|
-
// In JSON mode, output confirmation prompt
|
|
47
|
-
if (jsonMode) {
|
|
48
|
-
const confirmChoices = [
|
|
49
|
-
{ name: 'No', value: 'false' },
|
|
50
|
-
{ name: 'Yes', value: 'true' },
|
|
51
|
-
];
|
|
52
|
-
outputPromptAsJson(buildPromptConfig('list', 'confirmed', `Remove all ${dependencies.length} dependencies?`, confirmChoices), createMetadata('spec link remove', flags));
|
|
53
|
-
return;
|
|
54
|
-
}
|
|
55
|
-
const { confirmed } = await inquirer.prompt([{
|
|
56
|
-
type: 'list',
|
|
57
|
-
name: 'confirmed',
|
|
58
|
-
message: `Remove all ${dependencies.length} dependencies?`,
|
|
59
|
-
choices: [
|
|
60
|
-
{ name: 'No', value: false },
|
|
61
|
-
{ name: 'Yes', value: true },
|
|
62
|
-
],
|
|
63
|
-
}]);
|
|
64
|
-
if (!confirmed) {
|
|
65
|
-
this.log(styles.muted('\nCancelled.'));
|
|
66
|
-
return;
|
|
67
|
-
}
|
|
68
|
-
// Delete sequentially for data integrity
|
|
69
|
-
// eslint-disable-next-line no-await-in-loop
|
|
70
|
-
for (const dep of dependencies)
|
|
71
|
-
await this.storage.deleteSpecDependency(args.id, dep.dependsOnSpecId, dep.dependencyType);
|
|
72
|
-
this.log(styles.success(`\n✅ Removed ${dependencies.length} dependencies from ${args.id}`));
|
|
73
|
-
return;
|
|
74
|
-
}
|
|
75
|
-
let targetId = args.target;
|
|
76
|
-
if (!targetId) {
|
|
77
|
-
const choices = await Promise.all(dependencies.map(async (dep) => {
|
|
78
|
-
const depSpec = await this.storage.getSpec(dep.dependsOnSpecId);
|
|
79
|
-
return { name: `${dep.dependsOnSpecId} - ${depSpec?.title || 'Unknown'} (${dep.dependencyType})`, value: dep.dependsOnSpecId };
|
|
80
|
-
}));
|
|
81
|
-
// In JSON mode, output dependency selection prompt with command fields
|
|
82
|
-
if (jsonMode) {
|
|
83
|
-
const choicesWithCommands = choices.map(c => ({
|
|
84
|
-
...c,
|
|
85
|
-
command: `prlt spec link remove ${args.id} ${c.value} --json`,
|
|
86
|
-
}));
|
|
87
|
-
outputPromptAsJson(buildPromptConfig('list', 'target', 'Select dependency to remove:', choicesWithCommands), createMetadata('spec link remove', flags));
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
90
|
-
const { selected } = await inquirer.prompt([{ type: 'list', name: 'selected', message: 'Select dependency to remove:', choices }]);
|
|
91
|
-
targetId = selected;
|
|
92
|
-
}
|
|
93
|
-
await this.storage.deleteSpecDependency(args.id, targetId, flags.type);
|
|
94
|
-
this.log(styles.success(`\n✅ Removed dependency: ${args.id} → ${targetId}`));
|
|
95
|
-
}
|
|
96
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { Command } from '@oclif/core';
|
|
2
|
-
export default class TemplatePhaseApply extends Command {
|
|
3
|
-
static description: string;
|
|
4
|
-
static examples: string[];
|
|
5
|
-
static args: {
|
|
6
|
-
template: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
7
|
-
};
|
|
8
|
-
static flags: {
|
|
9
|
-
project: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
|
-
force: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
11
|
-
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
12
|
-
};
|
|
13
|
-
run(): Promise<void>;
|
|
14
|
-
}
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { Args, Command, Flags } from '@oclif/core';
|
|
2
|
-
export default class TemplatePhaseApply extends Command {
|
|
3
|
-
static description = 'Apply a phase template to a project';
|
|
4
|
-
static examples = [
|
|
5
|
-
'<%= config.bin %> <%= command.id %> agile',
|
|
6
|
-
'<%= config.bin %> <%= command.id %> waterfall --project my-project',
|
|
7
|
-
'<%= config.bin %> <%= command.id %> agile --force',
|
|
8
|
-
];
|
|
9
|
-
static args = {
|
|
10
|
-
template: Args.string({
|
|
11
|
-
description: 'Phase template ID to apply',
|
|
12
|
-
required: true,
|
|
13
|
-
}),
|
|
14
|
-
};
|
|
15
|
-
static flags = {
|
|
16
|
-
project: Flags.string({
|
|
17
|
-
char: 'p',
|
|
18
|
-
description: 'Project ID or name',
|
|
19
|
-
}),
|
|
20
|
-
force: Flags.boolean({
|
|
21
|
-
char: 'f',
|
|
22
|
-
description: 'Skip confirmation prompt (will replace existing phases)',
|
|
23
|
-
default: false,
|
|
24
|
-
}),
|
|
25
|
-
json: Flags.boolean({
|
|
26
|
-
char: 'm',
|
|
27
|
-
aliases: ['machine'],
|
|
28
|
-
description: 'Output prompt configuration as JSON (for AI agents/scripts)',
|
|
29
|
-
default: false,
|
|
30
|
-
}),
|
|
31
|
-
};
|
|
32
|
-
async run() {
|
|
33
|
-
const { args, flags } = await this.parse(TemplatePhaseApply);
|
|
34
|
-
const cmdArgs = [args.template];
|
|
35
|
-
if (flags.project)
|
|
36
|
-
cmdArgs.push('--project', flags.project);
|
|
37
|
-
if (flags.force)
|
|
38
|
-
cmdArgs.push('--force');
|
|
39
|
-
if (flags.json)
|
|
40
|
-
cmdArgs.push('--json');
|
|
41
|
-
await this.config.runCommand('phase:template:apply', cmdArgs);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { Command } from '@oclif/core';
|
|
2
|
-
export default class TemplatePhaseCreate extends Command {
|
|
3
|
-
static description: string;
|
|
4
|
-
static examples: string[];
|
|
5
|
-
static args: {
|
|
6
|
-
name: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
7
|
-
};
|
|
8
|
-
static flags: {
|
|
9
|
-
description: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
|
-
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
11
|
-
};
|
|
12
|
-
run(): Promise<void>;
|
|
13
|
-
}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { Args, Command, Flags } from '@oclif/core';
|
|
2
|
-
export default class TemplatePhaseCreate extends Command {
|
|
3
|
-
static description = 'Create a new phase template';
|
|
4
|
-
static examples = [
|
|
5
|
-
'<%= config.bin %> <%= command.id %> "My Phases"',
|
|
6
|
-
'<%= config.bin %> <%= command.id %> "Sprint Phases" --description "Agile sprint phases"',
|
|
7
|
-
'<%= config.bin %> <%= command.id %> "My Phases" --description "Custom phases" --json',
|
|
8
|
-
];
|
|
9
|
-
static args = {
|
|
10
|
-
name: Args.string({
|
|
11
|
-
description: 'Name for the new template',
|
|
12
|
-
required: false,
|
|
13
|
-
}),
|
|
14
|
-
};
|
|
15
|
-
static flags = {
|
|
16
|
-
description: Flags.string({
|
|
17
|
-
char: 'd',
|
|
18
|
-
description: 'Template description',
|
|
19
|
-
}),
|
|
20
|
-
json: Flags.boolean({
|
|
21
|
-
char: 'm',
|
|
22
|
-
aliases: ['machine'],
|
|
23
|
-
description: 'Output as JSON for AI agents/scripts',
|
|
24
|
-
default: false,
|
|
25
|
-
}),
|
|
26
|
-
};
|
|
27
|
-
async run() {
|
|
28
|
-
const { args, flags } = await this.parse(TemplatePhaseCreate);
|
|
29
|
-
const cmdArgs = [];
|
|
30
|
-
if (args.name)
|
|
31
|
-
cmdArgs.push(args.name);
|
|
32
|
-
if (flags.description)
|
|
33
|
-
cmdArgs.push('--description', flags.description);
|
|
34
|
-
if (flags.json)
|
|
35
|
-
cmdArgs.push('--json');
|
|
36
|
-
await this.config.runCommand('phase:template:create', cmdArgs);
|
|
37
|
-
}
|
|
38
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { Args, Command, Flags } from '@oclif/core';
|
|
2
|
-
export default class TemplatePhaseDelete extends Command {
|
|
3
|
-
static description = 'Delete a phase template';
|
|
4
|
-
static examples = [
|
|
5
|
-
'<%= config.bin %> <%= command.id %> my-template',
|
|
6
|
-
'<%= config.bin %> <%= command.id %> my-template --force',
|
|
7
|
-
];
|
|
8
|
-
static args = {
|
|
9
|
-
id: Args.string({
|
|
10
|
-
description: 'Template ID to delete',
|
|
11
|
-
required: true,
|
|
12
|
-
}),
|
|
13
|
-
};
|
|
14
|
-
static flags = {
|
|
15
|
-
force: Flags.boolean({
|
|
16
|
-
char: 'f',
|
|
17
|
-
description: 'Skip confirmation',
|
|
18
|
-
default: false,
|
|
19
|
-
}),
|
|
20
|
-
json: Flags.boolean({
|
|
21
|
-
char: 'm',
|
|
22
|
-
aliases: ['machine'],
|
|
23
|
-
description: 'Output prompt configuration as JSON (for AI agents/scripts)',
|
|
24
|
-
default: false,
|
|
25
|
-
}),
|
|
26
|
-
};
|
|
27
|
-
async run() {
|
|
28
|
-
const { args, flags } = await this.parse(TemplatePhaseDelete);
|
|
29
|
-
const cmdArgs = [args.id];
|
|
30
|
-
if (flags.force)
|
|
31
|
-
cmdArgs.push('--force');
|
|
32
|
-
if (flags.json)
|
|
33
|
-
cmdArgs.push('--json');
|
|
34
|
-
await this.config.runCommand('phase:template:delete', cmdArgs);
|
|
35
|
-
}
|
|
36
|
-
}
|