@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,9 +1,8 @@
1
1
  import { Flags, Args } from '@oclif/core';
2
- import inquirer from 'inquirer';
3
2
  import { PMOCommand, pmoBaseFlags } from '../../lib/pmo/index.js';
4
3
  import { styles } from '../../lib/styles.js';
5
4
  import { slugify } from '../../lib/pmo/utils.js';
6
- import { shouldOutputJson, outputPromptAsJson, createMetadata, buildFormPromptConfig, } from '../../lib/prompt-json.js';
5
+ import { shouldOutputJson } from '../../lib/prompt-json.js';
7
6
  export default class RoadmapCreate extends PMOCommand {
8
7
  static description = 'Create a new roadmap';
9
8
  static examples = [
@@ -54,26 +53,46 @@ export default class RoadmapCreate extends PMOCommand {
54
53
  const jsonMode = shouldOutputJson(flags);
55
54
  let roadmapData;
56
55
  if (flags.interactive || (!args.name && !flags.name)) {
57
- const fields = [
58
- { type: 'input', name: 'name', message: 'Roadmap name:', default: flags.name },
59
- { type: 'input', name: 'id', message: 'Roadmap ID (leave blank to auto-generate):' },
60
- { type: 'input', name: 'description', message: 'Description (optional):', default: flags.description },
61
- {
56
+ const jsonModeConfig = jsonMode ? { flags, commandName: 'roadmap create' } : null;
57
+ // Prompt for name - in JSON mode, outputs prompt and exits; agent re-runs with --name flag
58
+ const { name } = await this.prompt([{
59
+ type: 'input',
60
+ name: 'name',
61
+ message: 'Roadmap name:',
62
+ default: flags.name,
63
+ validate: (input) => (typeof input === 'string' && input.length > 0) || 'Name is required',
64
+ }], jsonModeConfig);
65
+ // Prompt for id
66
+ const { id } = await this.prompt([{
67
+ type: 'input',
68
+ name: 'id',
69
+ message: 'Roadmap ID (leave blank to auto-generate):',
70
+ default: `roadmap-${slugify(name)}`,
71
+ }], jsonModeConfig);
72
+ // Prompt for description
73
+ const { description } = await this.prompt([{
74
+ type: 'input',
75
+ name: 'description',
76
+ message: 'Description (optional):',
77
+ default: flags.description,
78
+ }], jsonModeConfig);
79
+ // Prompt for isDefault
80
+ const { isDefault } = await this.prompt([{
62
81
  type: 'list',
63
82
  name: 'isDefault',
64
83
  message: 'Set as default roadmap?',
65
84
  choices: [
66
- { name: 'No', value: 'false' },
67
- { name: 'Yes', value: 'true' },
85
+ { name: 'No', value: 'false', command: `prlt roadmap create --name "${name}" --json` },
86
+ { name: 'Yes', value: 'true', command: `prlt roadmap create --name "${name}" --default --json` },
68
87
  ],
69
88
  default: flags.default ? 'true' : 'false',
70
- },
71
- ];
72
- if (jsonMode) {
73
- outputPromptAsJson(buildFormPromptConfig(fields), createMetadata('roadmap create', flags));
74
- return;
75
- }
76
- roadmapData = await this.promptRoadmapData(fields);
89
+ }], jsonModeConfig);
90
+ roadmapData = {
91
+ name,
92
+ id: id || undefined,
93
+ description: description || undefined,
94
+ isDefault: isDefault === 'true',
95
+ };
77
96
  }
78
97
  else {
79
98
  roadmapData = {
@@ -113,22 +132,26 @@ export default class RoadmapCreate extends PMOCommand {
113
132
  const projects = await this.storage.listProjects({ isArchived: false });
114
133
  if (projects.length > 0) {
115
134
  this.log('');
116
- const { addProjects } = await inquirer.prompt([{
135
+ const { addProjects } = await this.prompt([{
117
136
  type: 'list',
118
137
  name: 'addProjects',
119
138
  message: 'Add projects to this roadmap now?',
120
139
  choices: [
121
- { name: 'Yes', value: true },
122
- { name: 'No, I\'ll add them later', value: false },
140
+ { name: 'Yes', value: true, command: `prlt roadmap add-project "${roadmap.id}" --json` },
141
+ { name: 'No, I\'ll add them later', value: false, command: '' },
123
142
  ],
124
- }]);
143
+ }], null);
125
144
  if (addProjects) {
126
- const { selectedProjects } = await inquirer.prompt([{
145
+ const { selectedProjects } = await this.prompt([{
127
146
  type: 'checkbox',
128
147
  name: 'selectedProjects',
129
148
  message: 'Select projects to include:',
130
- choices: projects.map(p => ({ name: p.name, value: p.id })),
131
- }]);
149
+ choices: projects.map(p => ({
150
+ name: p.name,
151
+ value: p.id,
152
+ command: `prlt roadmap add-project "${roadmap.id}" "${p.id}" --json`,
153
+ })),
154
+ }], null);
132
155
  for (const projectId of selectedProjects) {
133
156
  // eslint-disable-next-line no-await-in-loop -- Sequential updates
134
157
  await this.storage.addProjectToRoadmap(roadmap.id, projectId);
@@ -143,21 +166,4 @@ export default class RoadmapCreate extends PMOCommand {
143
166
  this.log(styles.muted(` prlt roadmap add-project ${roadmap.id}`));
144
167
  this.log(styles.muted(` prlt roadmap generate ${roadmap.id}`));
145
168
  }
146
- async promptRoadmapData(fields) {
147
- const answers = await inquirer.prompt(fields.map(field => ({
148
- ...field,
149
- validate: field.name === 'name'
150
- ? ((input) => input.length > 0 || 'Name is required')
151
- : undefined,
152
- default: field.name === 'id'
153
- ? ((answers) => `roadmap-${slugify(answers.name)}`)
154
- : field.default,
155
- })));
156
- return {
157
- name: answers.name,
158
- id: answers.id || undefined,
159
- description: answers.description || undefined,
160
- isDefault: answers.isDefault === true || answers.isDefault === 'true',
161
- };
162
- }
163
169
  }
@@ -1,8 +1,7 @@
1
1
  import { Args, Flags } from '@oclif/core';
2
- import inquirer from 'inquirer';
3
2
  import { PMOCommand, pmoBaseFlags } from '../../lib/pmo/index.js';
4
3
  import { styles } from '../../lib/styles.js';
5
- import { shouldOutputJson, outputPromptAsJson, outputErrorAsJson, createMetadata, buildPromptConfig, } from '../../lib/prompt-json.js';
4
+ import { shouldOutputJson, outputErrorAsJson, createMetadata, } from '../../lib/prompt-json.js';
6
5
  export default class RoadmapDelete extends PMOCommand {
7
6
  static description = 'Delete a roadmap';
8
7
  static examples = [
@@ -47,23 +46,17 @@ export default class RoadmapDelete extends PMOCommand {
47
46
  }
48
47
  this.error('No roadmaps found.');
49
48
  }
50
- if (jsonMode) {
51
- const choices = roadmaps.map(r => ({
52
- name: `${r.name}${r.isDefault ? ' (default)' : ''}`,
53
- value: r.id,
54
- }));
55
- outputPromptAsJson(buildPromptConfig('list', 'id', 'Select roadmap to delete:', choices), createMetadata('roadmap delete', flags));
56
- return;
57
- }
58
- const { selected } = await inquirer.prompt([{
49
+ const jsonModeConfig = jsonMode ? { flags, commandName: 'roadmap delete' } : null;
50
+ const { selected } = await this.prompt([{
59
51
  type: 'list',
60
52
  name: 'selected',
61
53
  message: 'Select roadmap to delete:',
62
54
  choices: roadmaps.map(r => ({
63
55
  name: `${r.name}${r.isDefault ? ' (default)' : ''}`,
64
56
  value: r.id,
57
+ command: `prlt roadmap delete "${r.id}" --json`,
65
58
  })),
66
- }]);
59
+ }], jsonModeConfig);
67
60
  roadmapId = selected;
68
61
  }
69
62
  const roadmap = await this.storage.getRoadmap(roadmapId);
@@ -87,23 +80,16 @@ export default class RoadmapDelete extends PMOCommand {
87
80
  // Confirm deletion
88
81
  if (!flags.force) {
89
82
  const message = `Delete roadmap "${roadmap.name}"${projects.length > 0 ? ` (contains ${projects.length} project reference${projects.length > 1 ? 's' : ''})` : ''}?`;
90
- if (jsonMode) {
91
- const confirmChoices = [
92
- { name: 'No, cancel', value: 'false' },
93
- { name: 'Yes, delete', value: 'true' },
94
- ];
95
- outputPromptAsJson(buildPromptConfig('list', 'confirmed', message, confirmChoices), createMetadata('roadmap delete', flags));
96
- return;
97
- }
98
- const { confirm } = await inquirer.prompt([{
83
+ const confirmJsonModeConfig = jsonMode ? { flags, commandName: 'roadmap delete' } : null;
84
+ const { confirm } = await this.prompt([{
99
85
  type: 'list',
100
86
  name: 'confirm',
101
87
  message,
102
88
  choices: [
103
- { name: 'No, cancel', value: false },
104
- { name: 'Yes, delete', value: true },
89
+ { name: 'No, cancel', value: false, command: '' },
90
+ { name: 'Yes, delete', value: true, command: `prlt roadmap delete "${roadmapId}" --force --json` },
105
91
  ],
106
- }]);
92
+ }], confirmJsonModeConfig);
107
93
  if (!confirm) {
108
94
  this.log(styles.muted('Cancelled.'));
109
95
  return;
@@ -8,6 +8,7 @@ export default class RoadmapGenerate extends PMOCommand {
8
8
  static flags: {
9
9
  all: import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
10
  output: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
+ 'exclude-done': import("@oclif/core/interfaces").BooleanFlag<boolean>;
11
12
  json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
12
13
  project: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
13
14
  };
@@ -1,12 +1,11 @@
1
1
  import { Args, Flags } from '@oclif/core';
2
2
  import * as fs from 'node:fs';
3
3
  import * as path from 'node:path';
4
- import inquirer from 'inquirer';
5
4
  import { PMOCommand, pmoBaseFlags } from '../../lib/pmo/index.js';
6
5
  import { styles } from '../../lib/styles.js';
7
6
  import { slugify } from '../../lib/pmo/utils.js';
8
7
  import { normalizePriority, PRIORITIES } from '../../lib/pmo/types.js';
9
- import { shouldOutputJson, outputPromptAsJson, outputErrorAsJson, createMetadata, buildPromptConfig, } from '../../lib/prompt-json.js';
8
+ import { shouldOutputJson, outputErrorAsJson, createMetadata, } from '../../lib/prompt-json.js';
10
9
  export default class RoadmapGenerate extends PMOCommand {
11
10
  static description = 'Generate roadmap markdown file';
12
11
  static examples = [
@@ -30,6 +29,10 @@ export default class RoadmapGenerate extends PMOCommand {
30
29
  char: 'o',
31
30
  description: 'Output directory (default: {pmoPath}/roadmaps)',
32
31
  }),
32
+ 'exclude-done': Flags.boolean({
33
+ description: 'Exclude completed tickets from roadmap',
34
+ default: false,
35
+ }),
33
36
  json: Flags.boolean({
34
37
  char: 'm',
35
38
  aliases: ['machine'],
@@ -55,7 +58,7 @@ export default class RoadmapGenerate extends PMOCommand {
55
58
  }
56
59
  for (const roadmap of roadmaps) {
57
60
  // eslint-disable-next-line no-await-in-loop -- Sequential generation with user feedback
58
- await this.generateRoadmap(roadmap.id, outputDir);
61
+ await this.generateRoadmap(roadmap.id, outputDir, flags['exclude-done']);
59
62
  }
60
63
  this.log(styles.success(`\nGenerated ${roadmaps.length} roadmap(s) to ${outputDir}`));
61
64
  return;
@@ -71,28 +74,22 @@ export default class RoadmapGenerate extends PMOCommand {
71
74
  }
72
75
  this.error('No roadmaps found. Create one with: prlt roadmap create');
73
76
  }
74
- if (jsonMode) {
75
- const choices = roadmaps.map(r => ({
76
- name: `${r.name}${r.isDefault ? ' (default)' : ''}`,
77
- value: r.id,
78
- }));
79
- outputPromptAsJson(buildPromptConfig('list', 'id', 'Select roadmap to generate:', choices), createMetadata('roadmap generate', flags));
80
- return;
81
- }
82
- const { selected } = await inquirer.prompt([{
77
+ const jsonModeConfig = jsonMode ? { flags, commandName: 'roadmap generate' } : null;
78
+ const { selected } = await this.prompt([{
83
79
  type: 'list',
84
80
  name: 'selected',
85
81
  message: 'Select roadmap to generate:',
86
82
  choices: roadmaps.map(r => ({
87
83
  name: `${r.name}${r.isDefault ? ' (default)' : ''}`,
88
84
  value: r.id,
85
+ command: `prlt roadmap generate "${r.id}" --json`,
89
86
  })),
90
- }]);
87
+ }], jsonModeConfig);
91
88
  roadmapId = selected;
92
89
  }
93
- await this.generateRoadmap(roadmapId, outputDir);
90
+ await this.generateRoadmap(roadmapId, outputDir, flags['exclude-done']);
94
91
  }
95
- async generateRoadmap(roadmapId, outputDir) {
92
+ async generateRoadmap(roadmapId, outputDir, excludeDone = false) {
96
93
  const roadmap = await this.storage.getRoadmap(roadmapId);
97
94
  if (!roadmap) {
98
95
  this.error(`Roadmap not found: ${roadmapId}`);
@@ -124,13 +121,17 @@ export default class RoadmapGenerate extends PMOCommand {
124
121
  }
125
122
  lines.push(`## ${i + 1}. ${displayName}`);
126
123
  lines.push('');
124
+ // Filter tickets based on excludeDone flag
125
+ const filteredTickets = excludeDone
126
+ ? tickets.filter(t => t.statusCategory !== 'completed')
127
+ : tickets;
127
128
  // Group tickets by priority
128
129
  const ticketsByPriority = new Map();
129
130
  for (const priority of PRIORITIES) {
130
131
  ticketsByPriority.set(priority, []);
131
132
  }
132
133
  ticketsByPriority.set('unset', []);
133
- for (const ticket of tickets) {
134
+ for (const ticket of filteredTickets) {
134
135
  const normalizedPriority = normalizePriority(ticket.priority) || 'unset';
135
136
  const group = ticketsByPriority.get(normalizedPriority) || ticketsByPriority.get('unset');
136
137
  group.push(ticket);
@@ -140,16 +141,15 @@ export default class RoadmapGenerate extends PMOCommand {
140
141
  'started': 1,
141
142
  'unstarted': 2,
142
143
  'backlog': 3,
143
- 'completed': 4,
144
- 'canceled': 5,
145
- 'triage': 6,
144
+ 'triage': 4,
146
145
  };
146
+ // Output active tickets by priority
147
147
  for (const [priority, priorityTickets] of ticketsByPriority) {
148
148
  if (priorityTickets.length === 0)
149
149
  continue;
150
150
  priorityTickets.sort((a, b) => {
151
- const catA = categoryOrder[a.statusCategory || 'backlog'] || 6;
152
- const catB = categoryOrder[b.statusCategory || 'backlog'] || 6;
151
+ const catA = categoryOrder[a.statusCategory || 'backlog'] || 5;
152
+ const catB = categoryOrder[b.statusCategory || 'backlog'] || 5;
153
153
  if (catA !== catB)
154
154
  return catA - catB;
155
155
  return a.id.localeCompare(b.id);
@@ -158,7 +158,6 @@ export default class RoadmapGenerate extends PMOCommand {
158
158
  const priorityLabel = priority === 'unset' ? 'Unset Priority' : `${priority} - ${this.getPriorityLabel(priority)}`;
159
159
  lines.push(`### ${priorityLabel} (${priorityTickets.length} ticket${priorityTickets.length > 1 ? 's' : ''})`);
160
160
  lines.push('');
161
- // Table header
162
161
  lines.push('| Ticket | Title | Status | Category | Description |');
163
162
  lines.push('| ------ | ----- | ------ | -------- | ----------- |');
164
163
  for (const ticket of priorityTickets) {
@@ -1,8 +1,7 @@
1
1
  import { Args, Flags } from '@oclif/core';
2
- import inquirer from 'inquirer';
3
2
  import { PMOCommand, pmoBaseFlags } from '../../lib/pmo/index.js';
4
3
  import { styles } from '../../lib/styles.js';
5
- import { shouldOutputJson, outputPromptAsJson, outputErrorAsJson, createMetadata, buildPromptConfig, } from '../../lib/prompt-json.js';
4
+ import { shouldOutputJson, outputErrorAsJson, createMetadata, } from '../../lib/prompt-json.js';
6
5
  export default class RoadmapRemoveProject extends PMOCommand {
7
6
  static description = 'Remove a project from a roadmap';
8
7
  static examples = [
@@ -51,23 +50,17 @@ export default class RoadmapRemoveProject extends PMOCommand {
51
50
  }
52
51
  this.error('No roadmaps found');
53
52
  }
54
- if (jsonMode) {
55
- const choices = roadmaps.map(r => ({
56
- name: `${r.name}${r.isDefault ? ' (default)' : ''}`,
57
- value: r.id,
58
- }));
59
- outputPromptAsJson(buildPromptConfig('list', 'roadmap', 'Select roadmap:', choices), createMetadata('roadmap remove-project', flags));
60
- return;
61
- }
62
- const { selected } = await inquirer.prompt([{
53
+ const jsonModeConfig = jsonMode ? { flags, commandName: 'roadmap remove-project' } : null;
54
+ const { selected } = await this.prompt([{
63
55
  type: 'list',
64
56
  name: 'selected',
65
57
  message: 'Select roadmap:',
66
58
  choices: roadmaps.map(r => ({
67
59
  name: `${r.name}${r.isDefault ? ' (default)' : ''}`,
68
60
  value: r.id,
61
+ command: `prlt roadmap remove-project "${r.id}" --json`,
69
62
  })),
70
- }]);
63
+ }], jsonModeConfig);
71
64
  roadmapId = selected;
72
65
  }
73
66
  const roadmap = await this.storage.getRoadmap(roadmapId);
@@ -90,23 +83,17 @@ export default class RoadmapRemoveProject extends PMOCommand {
90
83
  // Select project
91
84
  let projectId = args.project;
92
85
  if (!projectId) {
93
- if (jsonMode) {
94
- const choices = projects.map((p, i) => ({
95
- name: `${i + 1}. ${p.name}`,
96
- value: p.id,
97
- }));
98
- outputPromptAsJson(buildPromptConfig('list', 'project', 'Select project to remove:', choices), createMetadata('roadmap remove-project', flags));
99
- return;
100
- }
101
- const { selected } = await inquirer.prompt([{
86
+ const projectJsonModeConfig = jsonMode ? { flags, commandName: 'roadmap remove-project' } : null;
87
+ const { selected } = await this.prompt([{
102
88
  type: 'list',
103
89
  name: 'selected',
104
90
  message: 'Select project to remove:',
105
91
  choices: projects.map((p, i) => ({
106
92
  name: `${i + 1}. ${p.name}`,
107
93
  value: p.id,
94
+ command: `prlt roadmap remove-project "${roadmapId}" "${p.id}" --json`,
108
95
  })),
109
- }]);
96
+ }], projectJsonModeConfig);
110
97
  projectId = selected;
111
98
  }
112
99
  // Verify project is in roadmap
@@ -121,23 +108,16 @@ export default class RoadmapRemoveProject extends PMOCommand {
121
108
  // Confirm removal
122
109
  if (!flags.force) {
123
110
  const message = `Remove "${project.name}" from "${roadmap.name}"?`;
124
- if (jsonMode) {
125
- const confirmChoices = [
126
- { name: 'No, cancel', value: 'false' },
127
- { name: 'Yes, remove', value: 'true' },
128
- ];
129
- outputPromptAsJson(buildPromptConfig('list', 'confirmed', message, confirmChoices), createMetadata('roadmap remove-project', flags));
130
- return;
131
- }
132
- const { confirm } = await inquirer.prompt([{
111
+ const confirmJsonModeConfig = jsonMode ? { flags, commandName: 'roadmap remove-project' } : null;
112
+ const { confirm } = await this.prompt([{
133
113
  type: 'list',
134
114
  name: 'confirm',
135
115
  message,
136
116
  choices: [
137
- { name: 'No, cancel', value: false },
138
- { name: 'Yes, remove', value: true },
117
+ { name: 'No, cancel', value: false, command: '' },
118
+ { name: 'Yes, remove', value: true, command: `prlt roadmap remove-project "${roadmapId}" "${projectId}" --force --json` },
139
119
  ],
140
- }]);
120
+ }], confirmJsonModeConfig);
141
121
  if (!confirm) {
142
122
  this.log(styles.muted('Cancelled.'));
143
123
  return;
@@ -1,8 +1,7 @@
1
1
  import { Args, Flags } from '@oclif/core';
2
- import inquirer from 'inquirer';
3
2
  import { PMOCommand, pmoBaseFlags } from '../../lib/pmo/index.js';
4
3
  import { styles } from '../../lib/styles.js';
5
- import { shouldOutputJson, outputPromptAsJson, outputErrorAsJson, createMetadata, buildPromptConfig, } from '../../lib/prompt-json.js';
4
+ import { shouldOutputJson, outputErrorAsJson, createMetadata, } from '../../lib/prompt-json.js';
6
5
  export default class RoadmapReorder extends PMOCommand {
7
6
  static description = 'Reorder projects in a roadmap';
8
7
  static examples = [
@@ -49,23 +48,17 @@ export default class RoadmapReorder extends PMOCommand {
49
48
  }
50
49
  this.error('No roadmaps found');
51
50
  }
52
- if (jsonMode) {
53
- const choices = roadmaps.map(r => ({
54
- name: `${r.name}${r.isDefault ? ' (default)' : ''}`,
55
- value: r.id,
56
- }));
57
- outputPromptAsJson(buildPromptConfig('list', 'roadmap', 'Select roadmap:', choices), createMetadata('roadmap reorder', flags));
58
- return;
59
- }
60
- const { selected } = await inquirer.prompt([{
51
+ const jsonModeConfig = jsonMode ? { flags, commandName: 'roadmap reorder' } : null;
52
+ const { selected } = await this.prompt([{
61
53
  type: 'list',
62
54
  name: 'selected',
63
55
  message: 'Select roadmap:',
64
56
  choices: roadmaps.map(r => ({
65
57
  name: `${r.name}${r.isDefault ? ' (default)' : ''}`,
66
58
  value: r.id,
59
+ command: `prlt roadmap reorder "${r.id}" --json`,
67
60
  })),
68
- }]);
61
+ }], jsonModeConfig);
69
62
  roadmapId = selected;
70
63
  }
71
64
  const roadmap = await this.storage.getRoadmap(roadmapId);
@@ -107,46 +100,46 @@ export default class RoadmapReorder extends PMOCommand {
107
100
  }
108
101
  this.log('');
109
102
  // Prompt to select project to move
110
- if (jsonMode) {
111
- const choices = projects.map((p, i) => ({
112
- name: `${i + 1}. ${p.name}`,
113
- value: p.id,
114
- }));
115
- outputPromptAsJson(buildPromptConfig('list', 'project', 'Select project to move:', choices), createMetadata('roadmap reorder', flags));
116
- return;
117
- }
118
- const { projectToMove } = await inquirer.prompt([{
103
+ const projectJsonModeConfig = jsonMode ? { flags, commandName: 'roadmap reorder' } : null;
104
+ const { projectToMove } = await this.prompt([{
119
105
  type: 'list',
120
106
  name: 'projectToMove',
121
107
  message: 'Select project to move:',
122
108
  choices: projects.map((p, i) => ({
123
109
  name: `${i + 1}. ${p.name}`,
124
110
  value: p.id,
111
+ command: `prlt roadmap reorder "${roadmapId}" --project "${p.id}" --json`,
125
112
  })),
126
- }]);
113
+ }], projectJsonModeConfig);
127
114
  const project = projects.find(p => p.id === projectToMove);
128
115
  const currentPosition = projects.findIndex(p => p.id === projectToMove);
129
116
  // Generate position choices
130
117
  const positionChoices = projects.map((p, i) => {
131
118
  if (i === currentPosition) {
132
- return { name: `${i + 1}. ${p.name} (current position)`, value: i, disabled: true };
119
+ return { name: `${i + 1}. ${p.name} (current position)`, value: i, disabled: true, command: '' };
133
120
  }
134
121
  const label = i < currentPosition ? `Move before ${i + 1}. ${p.name}` : `Move after ${i}. ${projects[i - 1]?.name || ''}`;
135
- return { name: `Position ${i + 1}: ${label}`, value: i };
122
+ return {
123
+ name: `Position ${i + 1}: ${label}`,
124
+ value: i,
125
+ command: `prlt roadmap reorder "${roadmapId}" --project "${projectToMove}" --position ${i} --json`,
126
+ };
136
127
  }).filter(c => !c.disabled);
137
128
  // Add "move to end" option if not already at the end
138
129
  if (currentPosition !== projects.length - 1) {
139
130
  positionChoices.push({
140
131
  name: `Position ${projects.length}: Move to end`,
141
132
  value: projects.length - 1,
133
+ command: `prlt roadmap reorder "${roadmapId}" --project "${projectToMove}" --position ${projects.length - 1} --json`,
142
134
  });
143
135
  }
144
- const { newPosition } = await inquirer.prompt([{
136
+ const positionJsonModeConfig = jsonMode ? { flags, commandName: 'roadmap reorder' } : null;
137
+ const { newPosition } = await this.prompt([{
145
138
  type: 'list',
146
139
  name: 'newPosition',
147
140
  message: `Move "${project.name}" to which position?`,
148
141
  choices: positionChoices,
149
- }]);
142
+ }], positionJsonModeConfig);
150
143
  await this.storage.reorderRoadmapProject(roadmapId, projectToMove, newPosition);
151
144
  // Show new order
152
145
  projects = await this.storage.listRoadmapProjects(roadmapId);
@@ -1,8 +1,7 @@
1
1
  import { Args, Flags } from '@oclif/core';
2
- import inquirer from 'inquirer';
3
2
  import { PMOCommand, pmoBaseFlags } from '../../lib/pmo/index.js';
4
3
  import { styles } from '../../lib/styles.js';
5
- import { shouldOutputJson, outputPromptAsJson, outputErrorAsJson, createMetadata, buildPromptConfig, buildFormPromptConfig, } from '../../lib/prompt-json.js';
4
+ import { shouldOutputJson, outputErrorAsJson, createMetadata, } from '../../lib/prompt-json.js';
6
5
  export default class RoadmapUpdate extends PMOCommand {
7
6
  static description = 'Update a roadmap';
8
7
  static examples = [
@@ -53,23 +52,17 @@ export default class RoadmapUpdate extends PMOCommand {
53
52
  }
54
53
  this.error('No roadmaps found. Create one with: prlt roadmap create');
55
54
  }
56
- if (jsonMode) {
57
- const choices = roadmaps.map(r => ({
58
- name: `${r.name}${r.isDefault ? ' (default)' : ''}`,
59
- value: r.id,
60
- }));
61
- outputPromptAsJson(buildPromptConfig('list', 'id', 'Select roadmap to update:', choices), createMetadata('roadmap update', flags));
62
- return;
63
- }
64
- const { selected } = await inquirer.prompt([{
55
+ const jsonModeConfig = jsonMode ? { flags, commandName: 'roadmap update' } : null;
56
+ const { selected } = await this.prompt([{
65
57
  type: 'list',
66
58
  name: 'selected',
67
59
  message: 'Select roadmap to update:',
68
60
  choices: roadmaps.map(r => ({
69
61
  name: `${r.name}${r.isDefault ? ' (default)' : ''}`,
70
62
  value: r.id,
63
+ command: `prlt roadmap update "${r.id}" --json`,
71
64
  })),
72
- }]);
65
+ }], jsonModeConfig);
73
66
  roadmapId = selected;
74
67
  }
75
68
  const roadmap = await this.storage.getRoadmap(roadmapId);
@@ -83,25 +76,33 @@ export default class RoadmapUpdate extends PMOCommand {
83
76
  // If no flags provided, prompt for updates
84
77
  const hasUpdateFlags = flags.name !== undefined || flags.description !== undefined || flags.default !== undefined;
85
78
  if (!hasUpdateFlags) {
86
- const fields = [
87
- { type: 'input', name: 'name', message: 'New name (leave blank to keep current):', default: roadmap.name },
88
- { type: 'input', name: 'description', message: 'New description (leave blank to keep current):', default: roadmap.description || '' },
89
- {
79
+ const formJsonModeConfig = jsonMode ? { flags, commandName: 'roadmap update' } : null;
80
+ // Prompt for name - in JSON mode, outputs prompt and exits; agent re-runs with --name flag
81
+ const { name } = await this.prompt([{
82
+ type: 'input',
83
+ name: 'name',
84
+ message: 'New name (leave blank to keep current):',
85
+ default: roadmap.name,
86
+ }], formJsonModeConfig);
87
+ // Prompt for description
88
+ const { description } = await this.prompt([{
89
+ type: 'input',
90
+ name: 'description',
91
+ message: 'New description (leave blank to keep current):',
92
+ default: roadmap.description || '',
93
+ }], formJsonModeConfig);
94
+ // Prompt for isDefault
95
+ const { isDefault } = await this.prompt([{
90
96
  type: 'list',
91
97
  name: 'isDefault',
92
98
  message: 'Set as default roadmap?',
93
99
  choices: [
94
- { name: 'No change', value: 'no-change' },
95
- { name: 'Yes', value: 'yes' },
96
- { name: 'No', value: 'no' },
100
+ { name: 'No change', value: 'no-change', command: '' },
101
+ { name: 'Yes', value: 'yes', command: `prlt roadmap update "${roadmapId}" --default --json` },
102
+ { name: 'No', value: 'no', command: `prlt roadmap update "${roadmapId}" --no-default --json` },
97
103
  ],
98
- },
99
- ];
100
- if (jsonMode) {
101
- outputPromptAsJson(buildFormPromptConfig(fields), createMetadata('roadmap update', flags));
102
- return;
103
- }
104
- const answers = await inquirer.prompt(fields);
104
+ }], formJsonModeConfig);
105
+ const answers = { name, description, isDefault };
105
106
  const changes = {};
106
107
  if (answers.name && answers.name !== roadmap.name) {
107
108
  changes.name = answers.name;
@@ -1,8 +1,7 @@
1
1
  import { Args, Flags } from '@oclif/core';
2
- import inquirer from 'inquirer';
3
2
  import { PMOCommand, pmoBaseFlags } from '../../lib/pmo/index.js';
4
3
  import { styles } from '../../lib/styles.js';
5
- import { shouldOutputJson, outputPromptAsJson, outputErrorAsJson, createMetadata, buildPromptConfig, } from '../../lib/prompt-json.js';
4
+ import { shouldOutputJson, outputErrorAsJson, createMetadata, } from '../../lib/prompt-json.js';
6
5
  export default class RoadmapView extends PMOCommand {
7
6
  static description = 'View roadmap details and its projects';
8
7
  static examples = [
@@ -40,23 +39,17 @@ export default class RoadmapView extends PMOCommand {
40
39
  }
41
40
  this.error('No roadmaps found. Create one with: prlt roadmap create');
42
41
  }
43
- if (jsonMode) {
44
- const choices = roadmaps.map(r => ({
45
- name: `${r.name}${r.isDefault ? ' (default)' : ''}`,
46
- value: r.id,
47
- }));
48
- outputPromptAsJson(buildPromptConfig('list', 'id', 'Select roadmap to view:', choices), createMetadata('roadmap view', flags));
49
- return;
50
- }
51
- const { selected } = await inquirer.prompt([{
42
+ const jsonModeConfig = jsonMode ? { flags, commandName: 'roadmap view' } : null;
43
+ const { selected } = await this.prompt([{
52
44
  type: 'list',
53
45
  name: 'selected',
54
46
  message: 'Select roadmap to view:',
55
47
  choices: roadmaps.map(r => ({
56
48
  name: `${r.name}${r.isDefault ? ' (default)' : ''}`,
57
49
  value: r.id,
50
+ command: `prlt roadmap view "${r.id}" --json`,
58
51
  })),
59
- }]);
52
+ }], jsonModeConfig);
60
53
  roadmapId = selected;
61
54
  }
62
55
  const roadmap = await this.storage.getRoadmap(roadmapId);