@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.
Files changed (235) hide show
  1. package/dist/commands/action/create.js +4 -4
  2. package/dist/commands/action/update.js +3 -3
  3. package/dist/commands/agent/{temp/cleanup.d.ts → cleanup.d.ts} +1 -1
  4. package/dist/commands/agent/{temp/cleanup.js → cleanup.js} +4 -4
  5. package/dist/commands/agent/index.js +8 -8
  6. package/dist/commands/branch/create.js +2 -2
  7. package/dist/commands/epic/activate.js +9 -17
  8. package/dist/commands/epic/archive.js +13 -24
  9. package/dist/commands/epic/create.d.ts +1 -0
  10. package/dist/commands/epic/create.js +46 -8
  11. package/dist/commands/epic/index.js +2 -2
  12. package/dist/commands/epic/move.js +28 -47
  13. package/dist/commands/epic/progress.js +10 -14
  14. package/dist/commands/epic/project.js +42 -59
  15. package/dist/commands/epic/reorder.js +25 -30
  16. package/dist/commands/epic/spec.d.ts +1 -0
  17. package/dist/commands/epic/spec.js +39 -40
  18. package/dist/commands/epic/ticket.d.ts +2 -0
  19. package/dist/commands/epic/ticket.js +63 -37
  20. package/dist/commands/feedback/index.d.ts +10 -0
  21. package/dist/commands/feedback/index.js +60 -0
  22. package/dist/commands/feedback/list.d.ts +12 -0
  23. package/dist/commands/feedback/list.js +126 -0
  24. package/dist/commands/feedback/submit.d.ts +16 -0
  25. package/dist/commands/feedback/submit.js +220 -0
  26. package/dist/commands/{template/phase/delete.d.ts → feedback/view.d.ts} +7 -5
  27. package/dist/commands/feedback/view.js +109 -0
  28. package/dist/commands/gh/index.js +4 -0
  29. package/dist/commands/{epic/link/remove.d.ts → link/create.d.ts} +6 -7
  30. package/dist/commands/link/create.js +141 -0
  31. package/dist/commands/{epic/link/relates.d.ts → link/index.d.ts} +4 -5
  32. package/dist/commands/link/index.js +87 -0
  33. package/dist/commands/{epic/link/duplicates.d.ts → link/list.d.ts} +7 -4
  34. package/dist/commands/link/list.js +182 -0
  35. package/dist/commands/{spec/link → link}/remove.d.ts +4 -5
  36. package/dist/commands/link/remove.js +120 -0
  37. package/dist/commands/mcp-server.d.ts +22 -0
  38. package/dist/commands/mcp-server.js +98 -0
  39. package/dist/commands/phase/create.js +1 -1
  40. package/dist/commands/project/create.d.ts +1 -0
  41. package/dist/commands/project/create.js +38 -4
  42. package/dist/commands/repo/create.d.ts +38 -0
  43. package/dist/commands/repo/create.js +283 -0
  44. package/dist/commands/repo/index.js +7 -0
  45. package/dist/commands/roadmap/add-project.js +9 -22
  46. package/dist/commands/roadmap/create.d.ts +0 -1
  47. package/dist/commands/roadmap/create.js +46 -40
  48. package/dist/commands/roadmap/delete.js +10 -24
  49. package/dist/commands/roadmap/generate.d.ts +1 -0
  50. package/dist/commands/roadmap/generate.js +21 -22
  51. package/dist/commands/roadmap/remove-project.js +14 -34
  52. package/dist/commands/roadmap/reorder.js +19 -26
  53. package/dist/commands/roadmap/update.js +27 -26
  54. package/dist/commands/roadmap/view.js +5 -12
  55. package/dist/commands/session/attach.d.ts +1 -8
  56. package/dist/commands/session/attach.js +93 -59
  57. package/dist/commands/session/list.d.ts +0 -8
  58. package/dist/commands/session/list.js +130 -81
  59. package/dist/commands/spec/create.d.ts +1 -0
  60. package/dist/commands/spec/create.js +44 -3
  61. package/dist/commands/spec/edit.js +63 -33
  62. package/dist/commands/spec/index.js +2 -2
  63. package/dist/commands/{agent/staff → staff}/add.js +10 -10
  64. package/dist/commands/{agent/staff → staff}/index.d.ts +1 -1
  65. package/dist/commands/{agent/staff → staff}/index.js +7 -7
  66. package/dist/commands/{agent/staff → staff}/list.js +3 -3
  67. package/dist/commands/{agent/staff → staff}/remove.d.ts +1 -1
  68. package/dist/commands/{agent/staff → staff}/remove.js +8 -8
  69. package/dist/commands/{template/phase/index.d.ts → support/book.d.ts} +2 -2
  70. package/dist/commands/support/book.js +54 -0
  71. package/dist/commands/{template/ticket/index.d.ts → support/discord.d.ts} +2 -2
  72. package/dist/commands/support/discord.js +54 -0
  73. package/dist/commands/support/docs.d.ts +10 -0
  74. package/dist/commands/support/docs.js +54 -0
  75. package/dist/commands/support/index.d.ts +19 -0
  76. package/dist/commands/support/index.js +81 -0
  77. package/dist/commands/support/issues.d.ts +11 -0
  78. package/dist/commands/support/issues.js +77 -0
  79. package/dist/commands/support/logs.d.ts +18 -0
  80. package/dist/commands/support/logs.js +247 -0
  81. package/dist/commands/{ticket/template → template}/apply.d.ts +8 -6
  82. package/dist/commands/template/apply.js +262 -0
  83. package/dist/commands/{ticket/template → template}/create.d.ts +5 -6
  84. package/dist/commands/template/create.js +238 -0
  85. package/dist/commands/template/index.js +48 -36
  86. package/dist/commands/{ticket/template → template}/save.d.ts +2 -2
  87. package/dist/commands/template/save.js +104 -0
  88. package/dist/commands/{phase/template → template}/update.d.ts +2 -2
  89. package/dist/commands/template/update.js +99 -0
  90. package/dist/commands/{agent/themes → theme}/add-names.d.ts +1 -1
  91. package/dist/commands/{agent/themes → theme}/add-names.js +6 -6
  92. package/dist/commands/{agent/themes → theme}/create.d.ts +1 -1
  93. package/dist/commands/{agent/themes → theme}/create.js +5 -5
  94. package/dist/commands/{agent/themes → theme}/index.d.ts +1 -1
  95. package/dist/commands/{agent/themes → theme}/index.js +10 -10
  96. package/dist/commands/{agent/themes → theme}/list.d.ts +1 -1
  97. package/dist/commands/{agent/themes → theme}/list.js +5 -5
  98. package/dist/commands/{agent/themes → theme}/set.d.ts +1 -1
  99. package/dist/commands/{agent/themes → theme}/set.js +7 -7
  100. package/dist/commands/ticket/create.d.ts +1 -0
  101. package/dist/commands/ticket/create.js +75 -15
  102. package/dist/commands/ticket/edit.js +44 -13
  103. package/dist/commands/ticket/index.js +6 -6
  104. package/dist/commands/ticket/move.d.ts +7 -0
  105. package/dist/commands/ticket/move.js +132 -0
  106. package/dist/commands/work/spawn.d.ts +1 -0
  107. package/dist/commands/work/spawn.js +72 -8
  108. package/dist/commands/work/start.js +6 -0
  109. package/dist/lib/execution/runners.js +21 -17
  110. package/dist/lib/execution/session-utils.d.ts +60 -0
  111. package/dist/lib/execution/session-utils.js +162 -0
  112. package/dist/lib/execution/spawner.d.ts +2 -0
  113. package/dist/lib/execution/spawner.js +42 -0
  114. package/dist/lib/flags/resolver.d.ts +2 -2
  115. package/dist/lib/flags/resolver.js +15 -0
  116. package/dist/lib/init/index.js +18 -0
  117. package/dist/lib/mcp/helpers.d.ts +43 -0
  118. package/dist/lib/mcp/helpers.js +57 -0
  119. package/dist/lib/mcp/index.d.ts +6 -0
  120. package/dist/lib/mcp/index.js +6 -0
  121. package/dist/lib/mcp/tools/action.d.ts +6 -0
  122. package/dist/lib/mcp/tools/action.js +88 -0
  123. package/dist/lib/mcp/tools/board.d.ts +6 -0
  124. package/dist/lib/mcp/tools/board.js +139 -0
  125. package/dist/lib/mcp/tools/category.d.ts +6 -0
  126. package/dist/lib/mcp/tools/category.js +84 -0
  127. package/dist/lib/mcp/tools/cli-passthrough.d.ts +15 -0
  128. package/dist/lib/mcp/tools/cli-passthrough.js +333 -0
  129. package/dist/lib/mcp/tools/epic.d.ts +6 -0
  130. package/dist/lib/mcp/tools/epic.js +178 -0
  131. package/dist/lib/mcp/tools/index.d.ts +18 -0
  132. package/dist/lib/mcp/tools/index.js +19 -0
  133. package/dist/lib/mcp/tools/phase.d.ts +6 -0
  134. package/dist/lib/mcp/tools/phase.js +131 -0
  135. package/dist/lib/mcp/tools/project.d.ts +6 -0
  136. package/dist/lib/mcp/tools/project.js +196 -0
  137. package/dist/lib/mcp/tools/roadmap.d.ts +6 -0
  138. package/dist/lib/mcp/tools/roadmap.js +123 -0
  139. package/dist/lib/mcp/tools/spec.d.ts +6 -0
  140. package/dist/lib/mcp/tools/spec.js +196 -0
  141. package/dist/lib/mcp/tools/status.d.ts +6 -0
  142. package/dist/lib/mcp/tools/status.js +109 -0
  143. package/dist/lib/mcp/tools/template.d.ts +6 -0
  144. package/dist/lib/mcp/tools/template.js +107 -0
  145. package/dist/lib/mcp/tools/ticket.d.ts +6 -0
  146. package/dist/lib/mcp/tools/ticket.js +393 -0
  147. package/dist/lib/mcp/tools/view.d.ts +6 -0
  148. package/dist/lib/mcp/tools/view.js +76 -0
  149. package/dist/lib/mcp/tools/work.d.ts +6 -0
  150. package/dist/lib/mcp/tools/work.js +132 -0
  151. package/dist/lib/mcp/tools/workflow.d.ts +6 -0
  152. package/dist/lib/mcp/tools/workflow.js +95 -0
  153. package/dist/lib/mcp/types.d.ts +17 -0
  154. package/dist/lib/mcp/types.js +4 -0
  155. package/dist/lib/multiline-input.d.ts +63 -0
  156. package/dist/lib/multiline-input.js +360 -0
  157. package/dist/lib/prompt-json.d.ts +57 -6
  158. package/dist/lib/prompt-json.js +45 -0
  159. package/dist/lib/repos/git.d.ts +7 -0
  160. package/dist/lib/repos/git.js +20 -0
  161. package/oclif.manifest.json +3690 -4995
  162. package/package.json +6 -4
  163. package/dist/commands/agent/temp/index.d.ts +0 -14
  164. package/dist/commands/agent/temp/index.js +0 -85
  165. package/dist/commands/agent/temp/list.d.ts +0 -7
  166. package/dist/commands/agent/temp/list.js +0 -108
  167. package/dist/commands/epic/link/block.d.ts +0 -14
  168. package/dist/commands/epic/link/block.js +0 -81
  169. package/dist/commands/epic/link/duplicates.js +0 -68
  170. package/dist/commands/epic/link/index.d.ts +0 -19
  171. package/dist/commands/epic/link/index.js +0 -272
  172. package/dist/commands/epic/link/relates.js +0 -68
  173. package/dist/commands/epic/link/remove.js +0 -93
  174. package/dist/commands/phase/template/apply.d.ts +0 -17
  175. package/dist/commands/phase/template/apply.js +0 -108
  176. package/dist/commands/phase/template/create.d.ts +0 -17
  177. package/dist/commands/phase/template/create.js +0 -104
  178. package/dist/commands/phase/template/delete.d.ts +0 -17
  179. package/dist/commands/phase/template/delete.js +0 -100
  180. package/dist/commands/phase/template/index.d.ts +0 -15
  181. package/dist/commands/phase/template/index.js +0 -130
  182. package/dist/commands/phase/template/list.d.ts +0 -16
  183. package/dist/commands/phase/template/list.js +0 -97
  184. package/dist/commands/phase/template/update.js +0 -89
  185. package/dist/commands/spec/link/depends.d.ts +0 -14
  186. package/dist/commands/spec/link/depends.js +0 -64
  187. package/dist/commands/spec/link/duplicates.d.ts +0 -14
  188. package/dist/commands/spec/link/duplicates.js +0 -63
  189. package/dist/commands/spec/link/index.d.ts +0 -19
  190. package/dist/commands/spec/link/index.js +0 -207
  191. package/dist/commands/spec/link/relates.d.ts +0 -14
  192. package/dist/commands/spec/link/relates.js +0 -63
  193. package/dist/commands/spec/link/remove.js +0 -96
  194. package/dist/commands/template/phase/apply.d.ts +0 -14
  195. package/dist/commands/template/phase/apply.js +0 -43
  196. package/dist/commands/template/phase/create.d.ts +0 -13
  197. package/dist/commands/template/phase/create.js +0 -38
  198. package/dist/commands/template/phase/delete.js +0 -36
  199. package/dist/commands/template/phase/index.js +0 -63
  200. package/dist/commands/template/phase/list.d.ts +0 -11
  201. package/dist/commands/template/phase/list.js +0 -36
  202. package/dist/commands/template/phase/update.d.ts +0 -14
  203. package/dist/commands/template/phase/update.js +0 -43
  204. package/dist/commands/template/ticket/apply.d.ts +0 -17
  205. package/dist/commands/template/ticket/apply.js +0 -60
  206. package/dist/commands/template/ticket/create.d.ts +0 -20
  207. package/dist/commands/template/ticket/create.js +0 -89
  208. package/dist/commands/template/ticket/delete.d.ts +0 -13
  209. package/dist/commands/template/ticket/delete.js +0 -38
  210. package/dist/commands/template/ticket/index.js +0 -63
  211. package/dist/commands/template/ticket/list.d.ts +0 -11
  212. package/dist/commands/template/ticket/list.js +0 -36
  213. package/dist/commands/template/ticket/save.d.ts +0 -15
  214. package/dist/commands/template/ticket/save.js +0 -46
  215. package/dist/commands/ticket/link/block.d.ts +0 -14
  216. package/dist/commands/ticket/link/block.js +0 -96
  217. package/dist/commands/ticket/link/duplicates.d.ts +0 -14
  218. package/dist/commands/ticket/link/duplicates.js +0 -95
  219. package/dist/commands/ticket/link/index.d.ts +0 -19
  220. package/dist/commands/ticket/link/index.js +0 -256
  221. package/dist/commands/ticket/link/relates.d.ts +0 -14
  222. package/dist/commands/ticket/link/relates.js +0 -95
  223. package/dist/commands/ticket/link/remove.d.ts +0 -16
  224. package/dist/commands/ticket/link/remove.js +0 -132
  225. package/dist/commands/ticket/template/apply.js +0 -252
  226. package/dist/commands/ticket/template/create.js +0 -386
  227. package/dist/commands/ticket/template/delete.d.ts +0 -17
  228. package/dist/commands/ticket/template/delete.js +0 -94
  229. package/dist/commands/ticket/template/index.d.ts +0 -15
  230. package/dist/commands/ticket/template/index.js +0 -120
  231. package/dist/commands/ticket/template/list.d.ts +0 -16
  232. package/dist/commands/ticket/template/list.js +0 -112
  233. package/dist/commands/ticket/template/save.js +0 -163
  234. /package/dist/commands/{agent/staff → staff}/add.d.ts +0 -0
  235. /package/dist/commands/{agent/staff → staff}/list.d.ts +0 -0
@@ -1,104 +0,0 @@
1
- import { Flags, Args } from '@oclif/core';
2
- import { PMOCommand, pmoBaseFlags } from '../../../lib/pmo/index.js';
3
- import { styles } from '../../../lib/styles.js';
4
- import { shouldOutputJson, outputSuccessAsJson, createMetadata } from '../../../lib/prompt-json.js';
5
- import { FlagResolver } from '../../../lib/flags/index.js';
6
- export default class PhaseTemplateCreate extends PMOCommand {
7
- static description = 'Create a new phase template from current workspace phases';
8
- static examples = [
9
- '<%= config.bin %> <%= command.id %> "My Custom Phases"',
10
- '<%= config.bin %> <%= command.id %> "Enterprise" --description "Enterprise project lifecycle"',
11
- '<%= config.bin %> <%= command.id %> "My Phases" --description "Custom phases" --json',
12
- ];
13
- static args = {
14
- name: Args.string({
15
- description: 'Name for the new template',
16
- required: false,
17
- }),
18
- };
19
- static flags = {
20
- ...pmoBaseFlags,
21
- description: Flags.string({
22
- char: 'd',
23
- description: 'Template description',
24
- }),
25
- };
26
- getPMOOptions() {
27
- return { promptIfMultiple: false };
28
- }
29
- async execute() {
30
- const { args, flags } = await this.parse(PhaseTemplateCreate);
31
- // Check if JSON output mode is active
32
- const jsonMode = shouldOutputJson(flags);
33
- // Build base command with positional arg if name provided
34
- const baseCmd = args.name
35
- ? `prlt template phase create "${args.name}"`
36
- : 'prlt template phase create';
37
- // Use FlagResolver for unified JSON mode and interactive handling
38
- const resolver = new FlagResolver({
39
- commandName: 'phase template create',
40
- baseCommand: baseCmd,
41
- jsonMode,
42
- flags: {
43
- description: flags.description,
44
- json: flags.json,
45
- },
46
- args: { name: args.name },
47
- });
48
- // Name prompt - required (only if not provided as positional arg)
49
- if (!args.name) {
50
- resolver.addPrompt({
51
- flagName: 'name',
52
- type: 'input',
53
- message: 'Template name:',
54
- validate: (value) => value.length > 0 || 'Name is required',
55
- context: {
56
- hint: 'Provide name with: prlt template phase create "Template Name"',
57
- example: 'prlt template phase create "My Phases" --description "Custom phases"',
58
- },
59
- // For input prompts, the agent will re-run with the positional arg
60
- getCommand: (value) => `prlt template phase create "${value}" --json`,
61
- });
62
- }
63
- // Description prompt - optional (only in interactive mode without --json)
64
- if (!jsonMode && args.name && flags.description === undefined) {
65
- resolver.addPrompt({
66
- flagName: 'description',
67
- type: 'input',
68
- message: 'Description (optional):',
69
- });
70
- }
71
- // Resolve missing flags
72
- const resolved = await resolver.resolve();
73
- // Get name from args or resolved (for interactive mode)
74
- const templateName = args.name || resolved.name;
75
- // Validate required fields
76
- if (!templateName) {
77
- this.error('Name is required. Provide as positional argument: prlt template phase create "Template Name"');
78
- }
79
- // Get description from flags or resolved
80
- const description = flags.description ?? resolved.description ?? undefined;
81
- const template = await this.storage.savePhaseTemplate(templateName, description);
82
- // Output as JSON in machine mode
83
- if (jsonMode) {
84
- outputSuccessAsJson({
85
- id: template.id,
86
- name: template.name,
87
- description: template.description,
88
- phasesCount: template.phases.length,
89
- phases: template.phases.map(p => ({
90
- name: p.name,
91
- category: p.category,
92
- isDefault: p.isDefault,
93
- })),
94
- }, createMetadata('phase template create', flags));
95
- return;
96
- }
97
- this.log(styles.success(`\nCreated phase template "${styles.emphasis(template.name)}" (${template.id})`));
98
- this.log(styles.muted(`Saved ${template.phases.length} phases:`));
99
- for (const phase of template.phases) {
100
- const defaultBadge = phase.isDefault ? ' (default)' : '';
101
- this.log(styles.muted(` • ${phase.name} [${phase.category}]${defaultBadge}`));
102
- }
103
- }
104
- }
@@ -1,17 +0,0 @@
1
- import { PMOCommand } from '../../../lib/pmo/index.js';
2
- export default class PhaseTemplateDelete 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
- force: import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
- json: 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
- }
@@ -1,100 +0,0 @@
1
- import { Flags, 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 PhaseTemplateDelete extends PMOCommand {
7
- static description = 'Delete a phase template';
8
- static examples = [
9
- '<%= config.bin %> <%= command.id %> my-custom-template',
10
- '<%= config.bin %> <%= command.id %> my-template --force',
11
- ];
12
- static args = {
13
- id: Args.string({
14
- description: 'Template ID to delete',
15
- required: false,
16
- }),
17
- };
18
- static flags = {
19
- ...pmoBaseFlags,
20
- force: Flags.boolean({
21
- char: 'f',
22
- description: 'Skip confirmation',
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
- getPMOOptions() {
33
- return { promptIfMultiple: false };
34
- }
35
- async execute() {
36
- const { args, flags } = await this.parse(PhaseTemplateDelete);
37
- // Check if JSON output mode is active
38
- const jsonMode = shouldOutputJson(flags);
39
- // Helper to handle errors in JSON mode
40
- const handleError = (code, message) => {
41
- if (jsonMode) {
42
- outputErrorAsJson(code, message, createMetadata('phase template delete', flags));
43
- this.exit(1);
44
- }
45
- this.error(message);
46
- };
47
- // Get template - prompt for selection if not provided
48
- let templateId = args.id;
49
- if (!templateId) {
50
- const templates = await this.storage.listPhaseTemplates();
51
- const deletableTemplates = templates.filter(t => !t.isBuiltin);
52
- if (deletableTemplates.length === 0) {
53
- return handleError('NO_TEMPLATES', `No deletable phase templates found (built-in templates cannot be deleted).`);
54
- }
55
- const { selectedTemplate } = await inquirer.prompt([{
56
- type: 'list',
57
- name: 'selectedTemplate',
58
- message: 'Select a template to delete:',
59
- choices: deletableTemplates.map(t => ({
60
- name: `${t.name}${t.description ? ` - ${t.description}` : ''}`,
61
- value: t.id,
62
- })),
63
- }]);
64
- templateId = selectedTemplate;
65
- }
66
- // Verify template exists
67
- const template = await this.storage.getPhaseTemplate(templateId);
68
- if (!template) {
69
- return handleError('TEMPLATE_NOT_FOUND', `Phase template not found: ${templateId}`);
70
- }
71
- if (template.isBuiltin) {
72
- return handleError('CANNOT_DELETE_BUILTIN', 'Cannot delete built-in templates');
73
- }
74
- if (!flags.force) {
75
- // In JSON mode, output confirmation prompt
76
- if (jsonMode) {
77
- const confirmChoices = [
78
- { name: 'No', value: 'false' },
79
- { name: 'Yes', value: 'true' },
80
- ];
81
- outputPromptAsJson(buildPromptConfig('list', 'confirmed', `Delete phase template "${template.name}"?`, confirmChoices), createMetadata('phase template delete', flags));
82
- return;
83
- }
84
- const { confirm } = await inquirer.prompt([
85
- {
86
- type: 'confirm',
87
- name: 'confirm',
88
- message: `Delete phase template "${template.name}"?`,
89
- default: false,
90
- },
91
- ]);
92
- if (!confirm) {
93
- this.log(styles.muted('Cancelled'));
94
- return;
95
- }
96
- }
97
- await this.storage.deletePhaseTemplate(templateId);
98
- this.log(styles.success(`\nDeleted phase template "${template.name}"`));
99
- }
100
- }
@@ -1,15 +0,0 @@
1
- import { PMOCommand } from '../../../lib/pmo/index.js';
2
- export default class PhaseTemplateMenu extends PMOCommand {
3
- static description: string;
4
- static aliases: string[];
5
- static examples: string[];
6
- static flags: {
7
- json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
8
- project: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
9
- };
10
- protected getPMOOptions(): {
11
- promptIfMultiple: boolean;
12
- };
13
- execute(): Promise<void>;
14
- private selectTemplate;
15
- }
@@ -1,130 +0,0 @@
1
- import { Flags } from '@oclif/core';
2
- import inquirer from 'inquirer';
3
- import { PMOCommand, pmoBaseFlags } from '../../../lib/pmo/index.js';
4
- import { shouldOutputJson, outputPromptAsJson, createMetadata, buildPromptConfig, } from '../../../lib/prompt-json.js';
5
- export default class PhaseTemplateMenu extends PMOCommand {
6
- static description = 'Interactive menu for project phase template operations';
7
- static aliases = ['phase:templates'];
8
- static examples = [
9
- '<%= config.bin %> <%= command.id %>',
10
- ];
11
- static flags = {
12
- ...pmoBaseFlags,
13
- json: Flags.boolean({
14
- char: 'm',
15
- aliases: ['machine'],
16
- description: 'Output prompt configuration as JSON (for AI agents/scripts)',
17
- default: false,
18
- }),
19
- };
20
- getPMOOptions() {
21
- return { promptIfMultiple: false };
22
- }
23
- async execute() {
24
- const { flags } = await this.parse(PhaseTemplateMenu);
25
- // Check if JSON output mode is active
26
- const jsonMode = shouldOutputJson(flags);
27
- // Define choices once, use for both JSON and interactive modes
28
- const menuChoices = [
29
- { name: 'List available templates', value: 'list' },
30
- { name: 'Apply template to workspace', value: 'apply' },
31
- { name: 'Save current phases as template', value: 'create' },
32
- { name: 'Update template', value: 'update' },
33
- { name: 'Delete template', value: 'delete' },
34
- { name: 'Cancel', value: 'cancel' },
35
- ];
36
- const message = 'Phase Templates - What would you like to do?';
37
- // In JSON mode, output menu prompt
38
- if (jsonMode) {
39
- outputPromptAsJson(buildPromptConfig('list', 'action', message, menuChoices), createMetadata('phase template', flags));
40
- return;
41
- }
42
- {
43
- // Show interactive menu
44
- const { action } = await inquirer.prompt([{
45
- type: 'list',
46
- name: 'action',
47
- message: '📊 ' + message,
48
- choices: [
49
- ...menuChoices.slice(0, 3),
50
- new inquirer.Separator('──────────────'),
51
- ...menuChoices.slice(3),
52
- ],
53
- }]);
54
- if (action === 'cancel') {
55
- return;
56
- }
57
- // Run the selected subcommand
58
- switch (action) {
59
- case 'list':
60
- await this.config.runCommand('phase:template:list', []);
61
- break;
62
- case 'apply': {
63
- const templateId = await this.selectTemplate(this.storage, 'Select template to apply:');
64
- if (templateId) {
65
- await this.config.runCommand('phase:template:apply', [templateId]);
66
- }
67
- break;
68
- }
69
- case 'create': {
70
- const { name } = await inquirer.prompt([{
71
- type: 'input',
72
- name: 'name',
73
- message: 'Template name:',
74
- validate: (input) => input.length > 0 || 'Name is required',
75
- }]);
76
- await this.config.runCommand('phase:template:create', [name]);
77
- break;
78
- }
79
- case 'update': {
80
- const customTemplates = (await this.storage.listPhaseTemplates()).filter(t => !t.isBuiltin);
81
- if (customTemplates.length === 0) {
82
- this.log('No custom templates to update. Built-in templates cannot be modified.');
83
- return;
84
- }
85
- const templateId = await this.selectTemplate(this.storage, 'Select template to update:', true);
86
- if (templateId) {
87
- await this.config.runCommand('phase:template:update', [templateId]);
88
- }
89
- break;
90
- }
91
- case 'delete': {
92
- const customTemplates = (await this.storage.listPhaseTemplates()).filter(t => !t.isBuiltin);
93
- if (customTemplates.length === 0) {
94
- this.log('No custom templates to delete. Built-in templates cannot be deleted.');
95
- return;
96
- }
97
- const templateId = await this.selectTemplate(this.storage, 'Select template to delete:', true);
98
- if (templateId) {
99
- await this.config.runCommand('phase:template:delete', [templateId]);
100
- }
101
- break;
102
- }
103
- }
104
- }
105
- }
106
- async selectTemplate(storage, message, customOnly = false) {
107
- let templates = await storage.listPhaseTemplates();
108
- if (customOnly) {
109
- templates = templates.filter(t => !t.isBuiltin);
110
- }
111
- if (templates.length === 0) {
112
- this.log('No templates found.');
113
- return null;
114
- }
115
- const { selected } = await inquirer.prompt([{
116
- type: 'list',
117
- name: 'selected',
118
- message,
119
- choices: [
120
- ...templates.map(t => ({
121
- name: `${t.name} (${t.id})${t.isBuiltin ? '' : ' [custom]'}`,
122
- value: t.id,
123
- })),
124
- new inquirer.Separator(),
125
- { name: 'Cancel', value: null },
126
- ],
127
- }]);
128
- return selected;
129
- }
130
- }
@@ -1,16 +0,0 @@
1
- import { PMOCommand } from '../../../lib/pmo/index.js';
2
- export default class PhaseTemplateList 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
- project: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
10
- };
11
- protected getPMOOptions(): {
12
- promptIfMultiple: boolean;
13
- };
14
- execute(): Promise<void>;
15
- private printTemplate;
16
- }
@@ -1,97 +0,0 @@
1
- import { Flags } from '@oclif/core';
2
- import { PMOCommand, pmoBaseFlags } from '../../../lib/pmo/index.js';
3
- import { styles } from '../../../lib/styles.js';
4
- export default class PhaseTemplateList extends PMOCommand {
5
- static description = 'List available phase templates';
6
- static examples = [
7
- '<%= config.bin %> <%= command.id %>',
8
- '<%= config.bin %> <%= command.id %> --builtin # Only built-in templates',
9
- '<%= config.bin %> <%= command.id %> --custom # Only custom templates',
10
- ];
11
- static flags = {
12
- ...pmoBaseFlags,
13
- builtin: Flags.boolean({
14
- description: 'Show only built-in templates',
15
- exclusive: ['custom'],
16
- }),
17
- custom: Flags.boolean({
18
- description: 'Show only custom templates',
19
- exclusive: ['builtin'],
20
- }),
21
- json: Flags.boolean({
22
- char: 'm',
23
- aliases: ['machine'],
24
- description: 'Output as JSON',
25
- default: false,
26
- }),
27
- };
28
- getPMOOptions() {
29
- return { promptIfMultiple: false };
30
- }
31
- async execute() {
32
- const { flags } = await this.parse(PhaseTemplateList);
33
- let filter;
34
- if (flags.builtin)
35
- filter = { isBuiltin: true };
36
- if (flags.custom)
37
- filter = { isBuiltin: false };
38
- const templates = await this.storage.listPhaseTemplates(filter);
39
- if (flags.json) {
40
- this.log(JSON.stringify(templates, null, 2));
41
- return;
42
- }
43
- if (templates.length === 0) {
44
- this.log(styles.muted('\nNo phase templates found.'));
45
- return;
46
- }
47
- this.log(`\n📋 ${styles.emphasis('Phase Templates')}`);
48
- this.log('═'.repeat(60));
49
- // Group by builtin vs custom
50
- const builtinTemplates = templates.filter(t => t.isBuiltin);
51
- const customTemplates = templates.filter(t => !t.isBuiltin);
52
- if (builtinTemplates.length > 0 && !flags.custom) {
53
- this.log(`\n${styles.emphasis('Built-in Templates')}`);
54
- this.log('─'.repeat(40));
55
- for (const template of builtinTemplates) {
56
- this.printTemplate(template);
57
- }
58
- }
59
- if (customTemplates.length > 0 && !flags.builtin) {
60
- this.log(`\n${styles.emphasis('Custom Templates')}`);
61
- this.log('─'.repeat(40));
62
- for (const template of customTemplates) {
63
- this.printTemplate(template);
64
- }
65
- }
66
- this.log('');
67
- this.log(styles.muted('Apply a template: prlt template phase apply <template-id>'));
68
- this.log('');
69
- }
70
- printTemplate(template) {
71
- this.log(`\n ${styles.emphasis(template.name)} ${styles.muted(`(${template.id})`)}`);
72
- if (template.description) {
73
- this.log(` ${styles.muted(template.description)}`);
74
- }
75
- // Group phases by category for display
76
- const categoryEmoji = {
77
- triage: '📬',
78
- backlog: '📥',
79
- unstarted: '📋',
80
- started: '🚀',
81
- completed: '✅',
82
- canceled: '🚫',
83
- };
84
- const phasesByCategory = new Map();
85
- for (const phase of template.phases) {
86
- const existing = phasesByCategory.get(phase.category) || [];
87
- existing.push(phase.name);
88
- phasesByCategory.set(phase.category, existing);
89
- }
90
- const phaseParts = [];
91
- for (const [category, names] of phasesByCategory) {
92
- const emoji = categoryEmoji[category];
93
- phaseParts.push(`${emoji} ${names.join(', ')}`);
94
- }
95
- this.log(` ${styles.muted(phaseParts.join(' → '))}`);
96
- }
97
- }
@@ -1,89 +0,0 @@
1
- import { Flags, 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
- export default class PhaseTemplateUpdate extends PMOCommand {
6
- static description = 'Update a phase template';
7
- static examples = [
8
- '<%= config.bin %> <%= command.id %> my-template --name "New Name"',
9
- '<%= config.bin %> <%= command.id %> my-template --description "Updated description"',
10
- ];
11
- static args = {
12
- id: Args.string({
13
- description: 'Template ID to update',
14
- required: false,
15
- }),
16
- };
17
- static flags = {
18
- ...pmoBaseFlags,
19
- name: Flags.string({
20
- char: 'n',
21
- description: 'New template name',
22
- }),
23
- description: Flags.string({
24
- char: 'd',
25
- description: 'New template description',
26
- }),
27
- };
28
- getPMOOptions() {
29
- return { promptIfMultiple: false };
30
- }
31
- async execute() {
32
- const { args, flags } = await this.parse(PhaseTemplateUpdate);
33
- // Get template ID - prompt for selection if not provided
34
- let templateId = args.id;
35
- if (!templateId) {
36
- const templates = await this.storage.listPhaseTemplates();
37
- const editableTemplates = templates.filter(t => !t.isBuiltin);
38
- if (editableTemplates.length === 0) {
39
- this.error('No editable phase templates found (built-in templates cannot be updated).');
40
- }
41
- const { selectedTemplate } = await inquirer.prompt([{
42
- type: 'list',
43
- name: 'selectedTemplate',
44
- message: 'Select a template to update:',
45
- choices: editableTemplates.map(t => ({
46
- name: `${t.name}${t.description ? ` - ${t.description}` : ''}`,
47
- value: t.id,
48
- })),
49
- }]);
50
- templateId = selectedTemplate;
51
- }
52
- // If no flags provided, prompt for what to update
53
- let newName = flags.name;
54
- let newDescription = flags.description;
55
- if (!newName && newDescription === undefined) {
56
- const { updateName } = await inquirer.prompt([{
57
- type: 'input',
58
- name: 'updateName',
59
- message: 'New name (leave empty to keep current):',
60
- }]);
61
- if (updateName)
62
- newName = updateName;
63
- const { updateDesc } = await inquirer.prompt([{
64
- type: 'input',
65
- name: 'updateDesc',
66
- message: 'New description (leave empty to keep current):',
67
- }]);
68
- if (updateDesc)
69
- newDescription = updateDesc;
70
- if (!newName && !newDescription) {
71
- this.log(styles.muted('No changes made.'));
72
- return;
73
- }
74
- }
75
- const changes = {};
76
- if (newName)
77
- changes.name = newName;
78
- if (newDescription !== undefined)
79
- changes.description = newDescription;
80
- const template = await this.storage.updatePhaseTemplate(templateId, changes);
81
- this.log(styles.success(`\nUpdated phase template "${styles.emphasis(template.name)}"`));
82
- if (flags.name) {
83
- this.log(styles.muted(` Name: ${template.name}`));
84
- }
85
- if (flags.description !== undefined) {
86
- this.log(styles.muted(` Description: ${template.description || '(none)'}`));
87
- }
88
- }
89
- }
@@ -1,14 +0,0 @@
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
- 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,64 +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 SpecLinkDepends extends PMOCommand {
7
- static description = 'Add a depends_on dependency (spec requires another to be completed first)';
8
- static examples = ['<%= config.bin %> <%= command.id %> my-feature other-spec'];
9
- static args = {
10
- id: Args.string({ description: 'Spec ID that depends on another', required: true }),
11
- target: Args.string({ description: 'Spec ID that this spec depends on', required: false }),
12
- };
13
- static flags = {
14
- ...pmoBaseFlags,
15
- };
16
- async execute() {
17
- const { args, flags } = await this.parse(SpecLinkDepends);
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 depends', 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 depends', 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 depends ${args.id} ${s.id} --json`,
49
- }));
50
- outputPromptAsJson(buildPromptConfig('list', 'target', `Select spec that ${args.id} depends on:`, specChoices), createMetadata('spec link depends', flags));
51
- return;
52
- }
53
- const { selected } = await inquirer.prompt([{ type: 'list', name: 'selected', message: `Select spec that ${args.id} depends on:`,
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, 'depends_on');
61
- this.log(styles.success(`\n✅ ${styles.emphasis(args.id)} depends on ${styles.emphasis(targetId)}`));
62
- this.log(styles.muted(` ${spec.title} depends on: ${targetSpec.title}`));
63
- }
64
- }
@@ -1,14 +0,0 @@
1
- import { PMOCommand } from '../../../lib/pmo/index.js';
2
- export default class SpecLinkDuplicates 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
- original: 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
- }