@proletariat/cli 0.3.16 → 0.3.18

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 (338) hide show
  1. package/dist/commands/action/create.d.ts +1 -0
  2. package/dist/commands/action/create.js +74 -38
  3. package/dist/commands/action/delete.d.ts +1 -0
  4. package/dist/commands/action/delete.js +23 -24
  5. package/dist/commands/action/index.d.ts +1 -0
  6. package/dist/commands/action/index.js +5 -10
  7. package/dist/commands/action/list.d.ts +1 -0
  8. package/dist/commands/action/list.js +3 -1
  9. package/dist/commands/action/run.d.ts +1 -0
  10. package/dist/commands/action/run.js +44 -32
  11. package/dist/commands/action/show.d.ts +2 -0
  12. package/dist/commands/action/update.d.ts +1 -0
  13. package/dist/commands/action/update.js +80 -39
  14. package/dist/commands/agent/auth.d.ts +2 -0
  15. package/dist/commands/agent/auth.js +44 -3
  16. package/dist/commands/agent/discover.d.ts +2 -0
  17. package/dist/commands/agent/discover.js +35 -3
  18. package/dist/commands/agent/index.d.ts +1 -0
  19. package/dist/commands/agent/index.js +25 -45
  20. package/dist/commands/agent/list.d.ts +8 -3
  21. package/dist/commands/agent/list.js +16 -29
  22. package/dist/commands/agent/login.d.ts +1 -0
  23. package/dist/commands/agent/login.js +14 -32
  24. package/dist/commands/agent/rebuild.d.ts +1 -0
  25. package/dist/commands/agent/rebuild.js +2 -2
  26. package/dist/commands/agent/remove.d.ts +17 -0
  27. package/dist/commands/agent/remove.js +144 -0
  28. package/dist/commands/agent/restart.d.ts +1 -0
  29. package/dist/commands/agent/restart.js +2 -2
  30. package/dist/commands/agent/shell.d.ts +1 -0
  31. package/dist/commands/agent/shell.js +63 -76
  32. package/dist/commands/agent/staff/add.d.ts +1 -0
  33. package/dist/commands/agent/staff/add.js +7 -1
  34. package/dist/commands/agent/staff/index.d.ts +1 -0
  35. package/dist/commands/agent/staff/index.js +5 -4
  36. package/dist/commands/agent/staff/remove.d.ts +1 -0
  37. package/dist/commands/agent/status.d.ts +1 -0
  38. package/dist/commands/agent/status.js +11 -23
  39. package/dist/commands/agent/temp/cleanup.d.ts +1 -0
  40. package/dist/commands/agent/temp/index.d.ts +1 -0
  41. package/dist/commands/agent/temp/index.js +4 -3
  42. package/dist/commands/agent/themes/index.d.ts +1 -0
  43. package/dist/commands/agent/themes/index.js +9 -3
  44. package/dist/commands/agent/themes/set.d.ts +1 -0
  45. package/dist/commands/agent/themes/set.js +7 -1
  46. package/dist/commands/agent/visit.d.ts +1 -0
  47. package/dist/commands/agent/visit.js +11 -23
  48. package/dist/commands/autocomplete/setup.d.ts +11 -0
  49. package/dist/commands/autocomplete/setup.js +113 -8
  50. package/dist/commands/board/index.d.ts +4 -0
  51. package/dist/commands/board/index.js +32 -30
  52. package/dist/commands/board/watch.d.ts +2 -0
  53. package/dist/commands/branch/create.d.ts +1 -0
  54. package/dist/commands/branch/create.js +33 -41
  55. package/dist/commands/branch/index.d.ts +1 -0
  56. package/dist/commands/branch/list.d.ts +2 -0
  57. package/dist/commands/branch/validate.d.ts +2 -0
  58. package/dist/commands/branch/where.d.ts +1 -0
  59. package/dist/commands/claude.d.ts +6 -0
  60. package/dist/commands/claude.js +166 -116
  61. package/dist/commands/commit.d.ts +6 -0
  62. package/dist/commands/commit.js +68 -73
  63. package/dist/commands/config/index.d.ts +13 -0
  64. package/dist/commands/config/index.js +142 -98
  65. package/dist/commands/docker/clean.d.ts +2 -1
  66. package/dist/commands/docker/clean.js +20 -29
  67. package/dist/commands/docker/index.d.ts +1 -0
  68. package/dist/commands/docker/index.js +37 -41
  69. package/dist/commands/docker/prune.d.ts +2 -1
  70. package/dist/commands/docker/prune.js +20 -27
  71. package/dist/commands/docker/restart.d.ts +2 -1
  72. package/dist/commands/docker/restart.js +20 -29
  73. package/dist/commands/docker/stop.d.ts +2 -1
  74. package/dist/commands/docker/stop.js +20 -29
  75. package/dist/commands/epic/activate.d.ts +1 -0
  76. package/dist/commands/epic/archive.d.ts +1 -0
  77. package/dist/commands/epic/create.d.ts +1 -0
  78. package/dist/commands/epic/index.d.ts +1 -0
  79. package/dist/commands/epic/link/block.d.ts +1 -0
  80. package/dist/commands/epic/link/duplicates.d.ts +1 -0
  81. package/dist/commands/epic/link/index.d.ts +1 -0
  82. package/dist/commands/epic/link/relates.d.ts +1 -0
  83. package/dist/commands/epic/link/remove.d.ts +1 -0
  84. package/dist/commands/epic/list.d.ts +2 -0
  85. package/dist/commands/epic/move.d.ts +1 -0
  86. package/dist/commands/epic/progress.d.ts +1 -0
  87. package/dist/commands/epic/project.d.ts +1 -0
  88. package/dist/commands/epic/reorder.d.ts +1 -0
  89. package/dist/commands/epic/spec.d.ts +1 -0
  90. package/dist/commands/epic/ticket.d.ts +1 -0
  91. package/dist/commands/epic/view.d.ts +1 -0
  92. package/dist/commands/execution/index.d.ts +1 -0
  93. package/dist/commands/execution/index.js +9 -25
  94. package/dist/commands/execution/list.d.ts +2 -0
  95. package/dist/commands/execution/logs.d.ts +1 -0
  96. package/dist/commands/execution/logs.js +6 -16
  97. package/dist/commands/execution/stop.d.ts +1 -0
  98. package/dist/commands/execution/stop.js +4 -15
  99. package/dist/commands/gh/index.d.ts +1 -0
  100. package/dist/commands/gh/index.js +27 -27
  101. package/dist/commands/gh/login.d.ts +4 -0
  102. package/dist/commands/gh/login.js +31 -0
  103. package/dist/commands/gh/status.d.ts +4 -0
  104. package/dist/commands/gh/status.js +27 -4
  105. package/dist/commands/gh/token.d.ts +4 -0
  106. package/dist/commands/gh/token.js +49 -5
  107. package/dist/commands/phase/create.d.ts +1 -1
  108. package/dist/commands/phase/create.js +116 -74
  109. package/dist/commands/phase/delete.d.ts +1 -0
  110. package/dist/commands/phase/delete.js +23 -22
  111. package/dist/commands/phase/list.d.ts +1 -0
  112. package/dist/commands/phase/list.js +3 -5
  113. package/dist/commands/phase/move.d.ts +1 -0
  114. package/dist/commands/phase/move.js +39 -39
  115. package/dist/commands/phase/template/apply.d.ts +1 -0
  116. package/dist/commands/phase/template/create.d.ts +2 -0
  117. package/dist/commands/phase/template/delete.d.ts +1 -0
  118. package/dist/commands/phase/template/index.d.ts +1 -0
  119. package/dist/commands/phase/template/list.d.ts +1 -0
  120. package/dist/commands/phase/template/update.d.ts +2 -0
  121. package/dist/commands/phase/update.d.ts +1 -1
  122. package/dist/commands/phase/update.js +89 -55
  123. package/dist/commands/pmo/init.d.ts +2 -0
  124. package/dist/commands/pmo/init.js +84 -22
  125. package/dist/commands/pr/create.d.ts +12 -3
  126. package/dist/commands/pr/create.js +130 -147
  127. package/dist/commands/pr/index.d.ts +6 -3
  128. package/dist/commands/pr/index.js +41 -39
  129. package/dist/commands/pr/link.d.ts +7 -3
  130. package/dist/commands/pr/link.js +126 -150
  131. package/dist/commands/pr/status.d.ts +6 -3
  132. package/dist/commands/pr/status.js +101 -126
  133. package/dist/commands/project/archive.d.ts +1 -0
  134. package/dist/commands/project/archive.js +15 -20
  135. package/dist/commands/project/create.d.ts +1 -0
  136. package/dist/commands/project/create.js +13 -5
  137. package/dist/commands/project/delete.d.ts +1 -0
  138. package/dist/commands/project/delete.js +14 -28
  139. package/dist/commands/project/index.d.ts +1 -0
  140. package/dist/commands/project/index.js +0 -5
  141. package/dist/commands/project/list.d.ts +2 -0
  142. package/dist/commands/project/list.js +21 -3
  143. package/dist/commands/project/spec.d.ts +1 -0
  144. package/dist/commands/project/spec.js +17 -23
  145. package/dist/commands/project/unarchive.d.ts +2 -0
  146. package/dist/commands/project/unarchive.js +21 -2
  147. package/dist/commands/project/view.d.ts +1 -0
  148. package/dist/commands/project/view.js +34 -22
  149. package/dist/commands/repo/add.d.ts +2 -0
  150. package/dist/commands/repo/add.js +44 -1
  151. package/dist/commands/repo/index.d.ts +1 -0
  152. package/dist/commands/repo/index.js +20 -38
  153. package/dist/commands/repo/list.d.ts +2 -0
  154. package/dist/commands/repo/remove.d.ts +1 -0
  155. package/dist/commands/repo/remove.js +45 -63
  156. package/dist/commands/repo/view.d.ts +2 -0
  157. package/dist/commands/repo/view.js +30 -5
  158. package/dist/commands/roadmap/add-project.d.ts +1 -0
  159. package/dist/commands/roadmap/create.d.ts +1 -0
  160. package/dist/commands/roadmap/delete.d.ts +1 -0
  161. package/dist/commands/roadmap/generate.d.ts +1 -0
  162. package/dist/commands/roadmap/index.d.ts +1 -0
  163. package/dist/commands/roadmap/list.d.ts +2 -0
  164. package/dist/commands/roadmap/remove-project.d.ts +1 -0
  165. package/dist/commands/roadmap/reorder.d.ts +1 -0
  166. package/dist/commands/roadmap/update.d.ts +1 -0
  167. package/dist/commands/roadmap/view.d.ts +1 -0
  168. package/dist/commands/session/attach.d.ts +1 -0
  169. package/dist/commands/session/index.d.ts +1 -0
  170. package/dist/commands/session/index.js +8 -25
  171. package/dist/commands/session/list.d.ts +2 -0
  172. package/dist/commands/spec/create.d.ts +1 -1
  173. package/dist/commands/spec/create.js +64 -65
  174. package/dist/commands/spec/index.d.ts +1 -0
  175. package/dist/commands/spec/index.js +36 -22
  176. package/dist/commands/spec/link/depends.d.ts +1 -0
  177. package/dist/commands/spec/link/depends.js +6 -6
  178. package/dist/commands/spec/link/duplicates.d.ts +1 -0
  179. package/dist/commands/spec/link/duplicates.js +6 -6
  180. package/dist/commands/spec/link/index.d.ts +2 -1
  181. package/dist/commands/spec/link/index.js +0 -4
  182. package/dist/commands/spec/link/relates.d.ts +1 -0
  183. package/dist/commands/spec/link/relates.js +6 -6
  184. package/dist/commands/spec/link/remove.d.ts +2 -1
  185. package/dist/commands/spec/link/remove.js +6 -6
  186. package/dist/commands/spec/list.d.ts +2 -0
  187. package/dist/commands/spec/list.js +25 -0
  188. package/dist/commands/spec/plan.d.ts +2 -1
  189. package/dist/commands/spec/plan.js +19 -26
  190. package/dist/commands/spec/ticket.d.ts +2 -1
  191. package/dist/commands/spec/ticket.js +48 -34
  192. package/dist/commands/spec/view.d.ts +2 -1
  193. package/dist/commands/spec/view.js +25 -16
  194. package/dist/commands/status/create.d.ts +1 -1
  195. package/dist/commands/status/create.js +80 -64
  196. package/dist/commands/status/delete.d.ts +2 -1
  197. package/dist/commands/status/delete.js +26 -22
  198. package/dist/commands/status/index.d.ts +1 -0
  199. package/dist/commands/status/index.js +26 -19
  200. package/dist/commands/status/list.d.ts +1 -0
  201. package/dist/commands/status/list.js +12 -7
  202. package/dist/commands/status/move.d.ts +2 -1
  203. package/dist/commands/status/move.js +62 -61
  204. package/dist/commands/status/update.d.ts +2 -2
  205. package/dist/commands/status/update.js +110 -77
  206. package/dist/commands/template/delete.d.ts +1 -0
  207. package/dist/commands/template/delete.js +47 -48
  208. package/dist/commands/template/index.d.ts +1 -0
  209. package/dist/commands/template/index.js +26 -33
  210. package/dist/commands/template/list.d.ts +1 -0
  211. package/dist/commands/template/phase/create.d.ts +1 -0
  212. package/dist/commands/template/phase/create.js +6 -0
  213. package/dist/commands/template/phase/index.d.ts +1 -0
  214. package/dist/commands/template/phase/index.js +27 -26
  215. package/dist/commands/template/phase/update.d.ts +1 -0
  216. package/dist/commands/template/phase/update.js +6 -0
  217. package/dist/commands/template/ticket/index.d.ts +1 -0
  218. package/dist/commands/template/ticket/index.js +27 -26
  219. package/dist/commands/template/ticket/save.d.ts +1 -0
  220. package/dist/commands/template/ticket/save.js +6 -0
  221. package/dist/commands/terminal/title.d.ts +26 -0
  222. package/dist/commands/terminal/title.js +37 -3
  223. package/dist/commands/ticket/bulk.d.ts +1 -0
  224. package/dist/commands/ticket/complete.d.ts +1 -0
  225. package/dist/commands/ticket/complete.js +18 -14
  226. package/dist/commands/ticket/create.d.ts +1 -0
  227. package/dist/commands/ticket/create.js +45 -41
  228. package/dist/commands/ticket/delete.d.ts +1 -0
  229. package/dist/commands/ticket/delete.js +1 -1
  230. package/dist/commands/ticket/edit.d.ts +1 -0
  231. package/dist/commands/ticket/edit.js +1 -1
  232. package/dist/commands/ticket/epic.d.ts +1 -0
  233. package/dist/commands/ticket/epic.js +2 -2
  234. package/dist/commands/ticket/index.d.ts +1 -0
  235. package/dist/commands/ticket/link/block.d.ts +1 -0
  236. package/dist/commands/ticket/link/block.js +1 -1
  237. package/dist/commands/ticket/link/duplicates.d.ts +1 -0
  238. package/dist/commands/ticket/link/duplicates.js +1 -1
  239. package/dist/commands/ticket/link/index.d.ts +1 -0
  240. package/dist/commands/ticket/link/index.js +9 -8
  241. package/dist/commands/ticket/link/relates.d.ts +1 -0
  242. package/dist/commands/ticket/link/relates.js +1 -1
  243. package/dist/commands/ticket/link/remove.d.ts +1 -0
  244. package/dist/commands/ticket/link/remove.js +1 -1
  245. package/dist/commands/ticket/list.d.ts +2 -0
  246. package/dist/commands/ticket/move.d.ts +1 -0
  247. package/dist/commands/ticket/move.js +27 -19
  248. package/dist/commands/ticket/project.d.ts +1 -0
  249. package/dist/commands/ticket/project.js +3 -3
  250. package/dist/commands/ticket/reassign.d.ts +1 -0
  251. package/dist/commands/ticket/reassign.js +1 -1
  252. package/dist/commands/ticket/spec.d.ts +1 -0
  253. package/dist/commands/ticket/spec.js +3 -3
  254. package/dist/commands/ticket/status.d.ts +1 -0
  255. package/dist/commands/ticket/status.js +1 -1
  256. package/dist/commands/ticket/template/apply.d.ts +1 -0
  257. package/dist/commands/ticket/template/create.d.ts +2 -0
  258. package/dist/commands/ticket/template/delete.d.ts +1 -0
  259. package/dist/commands/ticket/template/index.d.ts +1 -0
  260. package/dist/commands/ticket/template/list.d.ts +1 -0
  261. package/dist/commands/ticket/template/save.d.ts +2 -0
  262. package/dist/commands/ticket/update.d.ts +1 -0
  263. package/dist/commands/ticket/update.js +1 -1
  264. package/dist/commands/ticket/view.d.ts +1 -0
  265. package/dist/commands/ticket/view.js +1 -1
  266. package/dist/commands/work/complete.d.ts +1 -0
  267. package/dist/commands/work/index.d.ts +1 -0
  268. package/dist/commands/work/ready.d.ts +1 -0
  269. package/dist/commands/work/revise.d.ts +1 -0
  270. package/dist/commands/work/spawn-all.d.ts +2 -0
  271. package/dist/commands/work/spawn-all.js +11 -4
  272. package/dist/commands/work/spawn.d.ts +1 -0
  273. package/dist/commands/work/spawn.js +261 -166
  274. package/dist/commands/work/start.d.ts +1 -0
  275. package/dist/commands/work/start.js +270 -189
  276. package/dist/commands/work/watch.d.ts +1 -0
  277. package/dist/commands/work/watch.js +63 -58
  278. package/dist/commands/workflow/create.d.ts +1 -0
  279. package/dist/commands/workflow/create.js +2 -4
  280. package/dist/commands/workflow/delete.d.ts +1 -0
  281. package/dist/commands/workflow/delete.js +21 -33
  282. package/dist/commands/workflow/index.d.ts +1 -0
  283. package/dist/commands/workflow/list.d.ts +1 -0
  284. package/dist/commands/workflow/list.js +3 -6
  285. package/dist/commands/workflow/switch.d.ts +2 -0
  286. package/dist/commands/workflow/switch.js +46 -21
  287. package/dist/commands/workflow/view.d.ts +1 -0
  288. package/dist/commands/workflow/view.js +18 -27
  289. package/dist/commands/workspace/remove.d.ts +2 -2
  290. package/dist/commands/workspace/remove.js +16 -21
  291. package/dist/commands/workspace/use.d.ts +2 -2
  292. package/dist/commands/workspace/use.js +12 -18
  293. package/dist/lib/agents/commands.d.ts +1 -1
  294. package/dist/lib/agents/commands.js +4 -4
  295. package/dist/lib/database/drizzle-schema.d.ts +5009 -0
  296. package/dist/lib/database/drizzle-schema.js +699 -0
  297. package/dist/lib/database/drizzle.d.ts +29 -0
  298. package/dist/lib/database/drizzle.js +37 -0
  299. package/dist/lib/database/index.d.ts +1 -0
  300. package/dist/lib/database/index.js +1 -1
  301. package/dist/lib/execution/config.d.ts +6 -0
  302. package/dist/lib/execution/config.js +31 -13
  303. package/dist/lib/execution/devcontainer.js +13 -7
  304. package/dist/lib/execution/runners.js +24 -7
  305. package/dist/lib/execution/spawner.js +19 -0
  306. package/dist/lib/flags/index.d.ts +4 -0
  307. package/dist/lib/flags/index.js +4 -0
  308. package/dist/lib/flags/resolver.d.ts +224 -0
  309. package/dist/lib/flags/resolver.js +313 -0
  310. package/dist/lib/pmo/base-command.d.ts +53 -3
  311. package/dist/lib/pmo/base-command.js +92 -13
  312. package/dist/lib/pmo/find-pmo.d.ts +1 -1
  313. package/dist/lib/pmo/find-pmo.js +4 -4
  314. package/dist/lib/pmo/index.d.ts +1 -1
  315. package/dist/lib/pmo/index.js +1 -1
  316. package/dist/lib/pmo/storage/helpers.js +2 -1
  317. package/dist/lib/pmo/storage/index.d.ts +9 -0
  318. package/dist/lib/pmo/storage/index.js +14 -0
  319. package/dist/lib/pmo/storage/projects.d.ts +28 -13
  320. package/dist/lib/pmo/storage/projects.js +110 -34
  321. package/dist/lib/pmo/storage/roadmaps.d.ts +2 -0
  322. package/dist/lib/pmo/storage/roadmaps.js +182 -111
  323. package/dist/lib/pmo/storage/specs.js +13 -16
  324. package/dist/lib/pmo/storage/subtasks.js +17 -2
  325. package/dist/lib/pmo/storage/tickets.d.ts +12 -2
  326. package/dist/lib/pmo/storage/tickets.js +63 -5
  327. package/dist/lib/pmo/storage/types.d.ts +7 -3
  328. package/dist/lib/pmo/storage/views.d.ts +12 -1
  329. package/dist/lib/pmo/storage/views.js +61 -6
  330. package/dist/lib/prompt-command.d.ts +90 -0
  331. package/dist/lib/prompt-command.js +102 -0
  332. package/dist/lib/prompt-json.d.ts +34 -4
  333. package/dist/lib/prompt-json.js +35 -3
  334. package/dist/lib/repos/index.js +15 -15
  335. package/dist/lib/workspace.d.ts +4 -3
  336. package/dist/lib/workspace.js +3 -3
  337. package/oclif.manifest.json +4610 -2997
  338. package/package.json +13 -5
@@ -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, outputSuccessAsJson, createMetadata, } from '../../lib/prompt-json.js';
6
5
  export default class ProjectArchive extends PMOCommand {
7
6
  static description = 'Archive a project (hide from default views)';
8
7
  static examples = [
@@ -22,10 +21,6 @@ export default class ProjectArchive extends PMOCommand {
22
21
  description: 'Skip confirmation',
23
22
  default: false,
24
23
  }),
25
- json: Flags.boolean({
26
- description: 'Output prompt configuration as JSON (for AI agents/scripts)',
27
- default: false,
28
- }),
29
24
  };
30
25
  getPMOOptions() {
31
26
  return { promptIfMultiple: false };
@@ -48,34 +43,34 @@ export default class ProjectArchive extends PMOCommand {
48
43
  }
49
44
  if (project.isArchived) {
50
45
  if (jsonMode) {
51
- outputErrorAsJson('ALREADY_ARCHIVED', `Project "${project.name}" is already archived.`, createMetadata('project archive', flags));
46
+ outputSuccessAsJson({ projectId: project.id, projectName: project.name, alreadyArchived: true }, createMetadata('project archive', flags));
52
47
  return;
53
48
  }
54
49
  this.log(styles.muted(`Project "${project.name}" is already archived.`));
55
50
  return;
56
51
  }
52
+ // Agent mode config for prompts
53
+ const agentConfig = jsonMode ? { flags, commandName: 'project archive' } : null;
57
54
  if (!flags.force) {
58
- // In JSON mode, output confirmation prompt
59
- if (jsonMode) {
60
- const confirmChoices = [
61
- { name: 'No', value: 'false' },
62
- { name: 'Yes', value: 'true' },
63
- ];
64
- outputPromptAsJson(buildPromptConfig('list', 'confirmed', `Archive project "${project.name}"? It will be hidden from default views.`, confirmChoices), createMetadata('project archive', flags));
65
- return;
66
- }
67
- const { confirm } = await inquirer.prompt([{
68
- type: 'confirm',
55
+ const { confirm } = await this.prompt([{
56
+ type: 'list',
69
57
  name: 'confirm',
70
58
  message: `Archive project "${project.name}"? It will be hidden from default views.`,
71
- default: false,
72
- }]);
59
+ choices: [
60
+ { name: 'No', value: false, command: '' },
61
+ { name: 'Yes', value: true, command: `prlt project archive ${args.id} --force --json` },
62
+ ],
63
+ }], agentConfig);
73
64
  if (!confirm) {
74
65
  this.log(styles.muted('Cancelled.'));
75
66
  return;
76
67
  }
77
68
  }
78
69
  await this.storage.archiveProject(args.id);
70
+ if (jsonMode) {
71
+ outputSuccessAsJson({ projectId: project.id, projectName: project.name, archived: true }, createMetadata('project archive', flags));
72
+ return;
73
+ }
79
74
  this.log(styles.success(`\nArchived project "${project.name}"`));
80
75
  this.log(styles.muted('View archived projects: prlt project list --archived'));
81
76
  this.log(styles.muted('Unarchive: prlt project unarchive ' + args.id));
@@ -11,6 +11,7 @@ export default class ProjectCreate extends PMOCommand {
11
11
  description: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
12
12
  template: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
13
13
  interactive: import("@oclif/core/interfaces").BooleanFlag<boolean>;
14
+ machine: import("@oclif/core/interfaces").BooleanFlag<boolean>;
14
15
  json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
15
16
  project: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
16
17
  };
@@ -5,7 +5,7 @@ import inquirer from 'inquirer';
5
5
  import { createBoardContent, createSpecFolders, PMOCommand, pmoBaseFlags, BUILTIN_TEMPLATES } from '../../lib/pmo/index.js';
6
6
  import { styles } from '../../lib/styles.js';
7
7
  import { slugify } from '../../lib/pmo/utils.js';
8
- import { shouldOutputJson, outputPromptAsJson, createMetadata, buildFormPromptConfig, } from '../../lib/prompt-json.js';
8
+ import { shouldOutputJson, outputPromptAsJson, outputSuccessAsJson, createMetadata, buildFormPromptConfig, } from '../../lib/prompt-json.js';
9
9
  // Build template options dynamically from shared definitions
10
10
  const TEMPLATE_IDS = BUILTIN_TEMPLATES.map(t => t.id);
11
11
  export default class ProjectCreate extends PMOCommand {
@@ -45,10 +45,6 @@ export default class ProjectCreate extends PMOCommand {
45
45
  description: 'Interactive mode',
46
46
  default: false,
47
47
  }),
48
- json: Flags.boolean({
49
- description: 'Output prompt configuration as JSON (for AI agents/scripts)',
50
- default: false,
51
- }),
52
48
  };
53
49
  getPMOOptions() {
54
50
  return { promptIfMultiple: false };
@@ -110,6 +106,18 @@ export default class ProjectCreate extends PMOCommand {
110
106
  const specsPath = createSpecFolders(this.pmoPath, projectId);
111
107
  // Get the statuses from the workflow (template name = workflow ID for built-in templates)
112
108
  const statuses = await this.storage.listStatuses(projectData.template);
109
+ // In JSON mode, output success with project details
110
+ if (jsonMode) {
111
+ outputSuccessAsJson({
112
+ id: project.id,
113
+ name: project.name,
114
+ template: projectData.template,
115
+ statuses: statuses.map(s => s.name),
116
+ boardPath: path.relative(process.cwd(), boardPath),
117
+ specsPath: path.relative(process.cwd(), specsPath),
118
+ }, createMetadata('project create', flags));
119
+ return;
120
+ }
113
121
  this.log(styles.success(`\nCreated project "${styles.emphasis(project.name)}"`));
114
122
  this.log(styles.muted(` ID: ${project.id}`));
115
123
  this.log(styles.muted(` Template: ${projectData.template}`));
@@ -7,6 +7,7 @@ export default class ProjectDelete extends PMOCommand {
7
7
  };
8
8
  static flags: {
9
9
  force: import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
+ machine: import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
11
  json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
11
12
  project: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
12
13
  };
@@ -1,10 +1,9 @@
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
- import { shouldOutputJson, outputPromptAsJson, outputErrorAsJson, createMetadata, buildPromptConfig, } from '../../lib/prompt-json.js';
6
+ import { shouldOutputJson, outputErrorAsJson, outputSuccessAsJson, createMetadata, } from '../../lib/prompt-json.js';
8
7
  export default class ProjectDelete extends PMOCommand {
9
8
  static description = 'Delete a project from the PMO';
10
9
  static examples = [
@@ -24,10 +23,6 @@ export default class ProjectDelete extends PMOCommand {
24
23
  description: 'Skip confirmation prompt',
25
24
  default: false,
26
25
  }),
27
- json: Flags.boolean({
28
- description: 'Output prompt configuration as JSON (for AI agents/scripts)',
29
- default: false,
30
- }),
31
26
  };
32
27
  getPMOOptions() {
33
28
  return { promptIfMultiple: false };
@@ -44,6 +39,8 @@ export default class ProjectDelete extends PMOCommand {
44
39
  }
45
40
  this.error(message);
46
41
  };
42
+ // Agent mode config for prompts
43
+ const agentConfig = jsonMode ? { flags, commandName: 'project delete' } : null;
47
44
  // Get project ID - prompt if not provided
48
45
  let projectId = args.id;
49
46
  if (!projectId) {
@@ -55,21 +52,16 @@ export default class ProjectDelete extends PMOCommand {
55
52
  if (deletableProjects.length === 0) {
56
53
  return handleError('NO_DELETABLE_PROJECTS', 'No deletable projects found. Cannot delete the default project.');
57
54
  }
58
- // In JSON mode, output project selection prompt
59
- if (jsonMode) {
60
- const projectChoices = deletableProjects.map(p => ({ name: `${p.id} - ${p.name}`, value: p.id }));
61
- outputPromptAsJson(buildPromptConfig('list', 'id', 'Select project to delete:', projectChoices), createMetadata('project delete', flags));
62
- return;
63
- }
64
- const { selectedProjectId } = await inquirer.prompt([{
55
+ const { selectedProjectId } = await this.prompt([{
65
56
  type: 'list',
66
57
  name: 'selectedProjectId',
67
58
  message: 'Select project to delete:',
68
59
  choices: deletableProjects.map(p => ({
69
60
  name: `${p.id} - ${p.name}`,
70
61
  value: p.id,
62
+ command: `prlt project delete ${p.id} --json`,
71
63
  })),
72
- }]);
64
+ }], agentConfig);
73
65
  projectId = selectedProjectId;
74
66
  }
75
67
  if (projectId === 'default') {
@@ -88,25 +80,15 @@ export default class ProjectDelete extends PMOCommand {
88
80
  const message = ticketCount > 0
89
81
  ? `Delete project "${project.name}" and its ${ticketCount} ticket(s)?`
90
82
  : `Delete project "${project.name}"?`;
91
- // In JSON mode, output confirmation prompt
92
- if (jsonMode) {
93
- const confirmChoices = [
94
- { name: 'No, cancel', value: 'false' },
95
- { name: 'Yes, delete', value: 'true' },
96
- ];
97
- outputPromptAsJson(buildPromptConfig('list', 'confirmed', message, confirmChoices), createMetadata('project delete', flags));
98
- return;
99
- }
100
- const { confirm } = await inquirer.prompt([{
83
+ const { confirm } = await this.prompt([{
101
84
  type: 'list',
102
85
  name: 'confirm',
103
86
  message,
104
87
  choices: [
105
- { name: 'No, cancel', value: false },
106
- { name: 'Yes, delete', value: true },
88
+ { name: 'No, cancel', value: false, command: '' },
89
+ { name: 'Yes, delete', value: true, command: `prlt project delete ${projectId} --force --json` },
107
90
  ],
108
- default: 0,
109
- }]);
91
+ }], agentConfig);
110
92
  if (!confirm) {
111
93
  this.log(styles.muted('Cancelled.'));
112
94
  return;
@@ -120,6 +102,10 @@ export default class ProjectDelete extends PMOCommand {
120
102
  if (fs.existsSync(projectPath)) {
121
103
  fs.rmSync(projectPath, { recursive: true, force: true });
122
104
  }
105
+ if (jsonMode) {
106
+ outputSuccessAsJson({ projectId: project.id, projectName: project.name, deleted: true, ticketsRemoved: ticketCount }, createMetadata('project delete', flags));
107
+ return;
108
+ }
123
109
  this.log(styles.success(`Deleted project "${project.name}"`));
124
110
  if (ticketCount > 0) {
125
111
  this.log(styles.muted(` (${ticketCount} ticket(s) removed)`));
@@ -3,6 +3,7 @@ export default class Project extends PMOCommand {
3
3
  static description: string;
4
4
  static examples: string[];
5
5
  static flags: {
6
+ machine: import("@oclif/core/interfaces").BooleanFlag<boolean>;
6
7
  json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
7
8
  project: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
8
9
  };
@@ -1,4 +1,3 @@
1
- import { Flags } from '@oclif/core';
2
1
  import { PMOCommand, pmoBaseFlags } from '../../lib/pmo/index.js';
3
2
  import { shouldOutputJson } from '../../lib/prompt-json.js';
4
3
  export default class Project extends PMOCommand {
@@ -8,10 +7,6 @@ export default class Project extends PMOCommand {
8
7
  ];
9
8
  static flags = {
10
9
  ...pmoBaseFlags,
11
- json: Flags.boolean({
12
- description: 'Output prompt configuration as JSON (for AI agents/scripts)',
13
- default: false,
14
- }),
15
10
  };
16
11
  getPMOOptions() {
17
12
  return { promptIfMultiple: false };
@@ -5,6 +5,8 @@ export default class ProjectList extends PMOCommand {
5
5
  static flags: {
6
6
  archived: import("@oclif/core/interfaces").BooleanFlag<boolean>;
7
7
  all: import("@oclif/core/interfaces").BooleanFlag<boolean>;
8
+ machine: import("@oclif/core/interfaces").BooleanFlag<boolean>;
9
+ json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
8
10
  project: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
9
11
  };
10
12
  protected getPMOOptions(): {
@@ -1,6 +1,7 @@
1
1
  import { Flags } from '@oclif/core';
2
2
  import { PMOCommand, pmoBaseFlags } from '../../lib/pmo/index.js';
3
3
  import { styles } from '../../lib/styles.js';
4
+ import { shouldOutputJson, outputSuccessAsJson, createMetadata, } from '../../lib/prompt-json.js';
4
5
  export default class ProjectList extends PMOCommand {
5
6
  static description = 'List all projects in the PMO';
6
7
  static examples = [
@@ -25,6 +26,8 @@ export default class ProjectList extends PMOCommand {
25
26
  }
26
27
  async execute() {
27
28
  const { flags } = await this.parse(ProjectList);
29
+ // Check if JSON output mode is active
30
+ const jsonMode = shouldOutputJson(flags);
28
31
  // Determine filter based on flags
29
32
  let isArchived;
30
33
  if (flags.archived) {
@@ -38,6 +41,24 @@ export default class ProjectList extends PMOCommand {
38
41
  // Get phases for display
39
42
  const phases = await this.storage.listPhases();
40
43
  const phaseMap = new Map(phases.map(p => [p.id, p]));
44
+ // Get ticket counts using listProjectSummaries
45
+ const summaries = await this.storage.listProjectSummaries();
46
+ const ticketCountMap = new Map(summaries.map(s => [s.id, s.ticketCount]));
47
+ // JSON mode: output structured data
48
+ if (jsonMode) {
49
+ const projectData = projects.map(p => ({
50
+ id: p.id,
51
+ name: p.name,
52
+ description: p.description,
53
+ isArchived: p.isArchived,
54
+ isDefault: p.id === 'default',
55
+ ticketCount: ticketCountMap.get(p.id) ?? 0,
56
+ phase: p.phaseId ? phaseMap.get(p.phaseId)?.name : undefined,
57
+ phaseId: p.phaseId,
58
+ }));
59
+ outputSuccessAsJson({ projects: projectData }, createMetadata('project list', flags));
60
+ return;
61
+ }
41
62
  if (projects.length === 0) {
42
63
  if (flags.archived) {
43
64
  this.log(styles.muted('No archived projects found.'));
@@ -57,9 +78,6 @@ export default class ProjectList extends PMOCommand {
57
78
  }
58
79
  const title = flags.archived ? 'Archived Projects' : flags.all ? 'All Projects' : 'Projects';
59
80
  this.log(styles.title(`\n${title}\n`));
60
- // Get ticket counts using listProjectSummaries
61
- const summaries = await this.storage.listProjectSummaries();
62
- const ticketCountMap = new Map(summaries.map(s => [s.id, s.ticketCount]));
63
81
  for (const project of projects) {
64
82
  const isDefault = project.id === 'default';
65
83
  const markers = [];
@@ -8,6 +8,7 @@ export default class ProjectSpec extends PMOCommand {
8
8
  static flags: {
9
9
  add: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
10
10
  remove: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
+ machine: 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
  };
@@ -2,7 +2,7 @@ import { Args, Flags } from '@oclif/core';
2
2
  import inquirer from 'inquirer';
3
3
  import { PMOCommand, pmoBaseFlags } from '../../lib/pmo/index.js';
4
4
  import { styles } from '../../lib/styles.js';
5
- import { shouldOutputJson, outputPromptAsJson, outputErrorAsJson, createMetadata, buildPromptConfig, } from '../../lib/prompt-json.js';
5
+ import { shouldOutputJson, outputErrorAsJson, outputSuccessAsJson, createMetadata, } from '../../lib/prompt-json.js';
6
6
  export default class ProjectSpec extends PMOCommand {
7
7
  static description = 'Manage specs associated with a project (many-to-many)';
8
8
  static examples = [
@@ -27,10 +27,6 @@ export default class ProjectSpec extends PMOCommand {
27
27
  char: 'r',
28
28
  description: 'Remove a spec from this project',
29
29
  }),
30
- json: Flags.boolean({
31
- description: 'Output prompt configuration as JSON (for AI agents/scripts)',
32
- default: false,
33
- }),
34
30
  };
35
31
  getPMOOptions() {
36
32
  return { promptIfMultiple: false };
@@ -47,6 +43,8 @@ export default class ProjectSpec extends PMOCommand {
47
43
  }
48
44
  this.error(message);
49
45
  };
46
+ // Agent mode config for prompts
47
+ const agentConfig = jsonMode ? { flags, commandName: 'project spec' } : null;
50
48
  // Get all projects
51
49
  const projects = await this.storage.listProjects();
52
50
  if (projects.length === 0) {
@@ -60,21 +58,16 @@ export default class ProjectSpec extends PMOCommand {
60
58
  let projectId = args.projectId;
61
59
  // If no project ID provided, prompt for selection
62
60
  if (!projectId) {
63
- // In JSON mode, output project selection prompt
64
- if (jsonMode) {
65
- const projectChoices = projects.map(p => ({ name: `${p.id} - ${p.name} (${p.status})`, value: p.id }));
66
- outputPromptAsJson(buildPromptConfig('list', 'projectId', 'Select project:', projectChoices), createMetadata('project spec', flags));
67
- return;
68
- }
69
- const { selected } = await inquirer.prompt([{
61
+ const { selected } = await this.prompt([{
70
62
  type: 'list',
71
63
  name: 'selected',
72
64
  message: 'Select project:',
73
65
  choices: projects.map(p => ({
74
66
  name: `${p.id} - ${p.name} (${p.status})`,
75
67
  value: p.id,
68
+ command: `prlt project spec ${p.id} --json`,
76
69
  })),
77
- }]);
70
+ }], agentConfig);
78
71
  projectId = selected;
79
72
  }
80
73
  // Validate project exists
@@ -116,16 +109,17 @@ export default class ProjectSpec extends PMOCommand {
116
109
  // In JSON mode, output the menu prompt (no loop - AI will call back)
117
110
  if (jsonMode) {
118
111
  const currentSpecs = await this.storage.getSpecsForProject(projectId);
119
- const menuChoices = [
120
- { name: 'Add spec to project', value: 'add' },
121
- { name: 'Remove spec from project', value: 'remove' },
122
- { name: 'Done', value: 'done' },
123
- ];
124
- outputPromptAsJson({
125
- ...buildPromptConfig('list', 'action', `Manage specs for ${projectId}:`, menuChoices),
126
- context: {
127
- projectId,
128
- currentSpecs: currentSpecs.map(s => ({ id: s.id, title: s.title, status: s.status })),
112
+ const allSpecs = await this.storage.listSpecs();
113
+ const currentSpecIds = new Set(currentSpecs.map(s => s.id));
114
+ const availableSpecs = allSpecs.filter(s => !currentSpecIds.has(s.id));
115
+ outputSuccessAsJson({
116
+ projectId,
117
+ projectName: project.name,
118
+ currentSpecs: currentSpecs.map(s => ({ id: s.id, title: s.title, status: s.status })),
119
+ availableSpecs: availableSpecs.map(s => ({ id: s.id, title: s.title, status: s.status })),
120
+ commands: {
121
+ addSpec: `prlt project spec ${projectId} --add <SPEC_ID> --json`,
122
+ removeSpec: `prlt project spec ${projectId} --remove <SPEC_ID> --json`,
129
123
  },
130
124
  }, createMetadata('project spec', flags));
131
125
  return;
@@ -6,6 +6,8 @@ export default class ProjectUnarchive extends PMOCommand {
6
6
  id: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
7
7
  };
8
8
  static flags: {
9
+ machine: import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
+ json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
9
11
  project: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
10
12
  };
11
13
  protected getPMOOptions(): {
@@ -1,6 +1,7 @@
1
1
  import { Args } from '@oclif/core';
2
2
  import { PMOCommand, pmoBaseFlags } from '../../lib/pmo/index.js';
3
3
  import { styles } from '../../lib/styles.js';
4
+ import { shouldOutputJson, outputSuccessAsJson, outputErrorAsJson, createMetadata, } from '../../lib/prompt-json.js';
4
5
  export default class ProjectUnarchive extends PMOCommand {
5
6
  static description = 'Unarchive a project (restore to default views)';
6
7
  static examples = [
@@ -19,16 +20,34 @@ export default class ProjectUnarchive extends PMOCommand {
19
20
  return { promptIfMultiple: false };
20
21
  }
21
22
  async execute() {
22
- const { args } = await this.parse(ProjectUnarchive);
23
+ const { args, flags } = await this.parse(ProjectUnarchive);
24
+ // Check if JSON output mode is active
25
+ const jsonMode = shouldOutputJson(flags);
26
+ // Helper to handle errors in JSON mode
27
+ const handleError = (code, message) => {
28
+ if (jsonMode) {
29
+ outputErrorAsJson(code, message, createMetadata('project unarchive', flags));
30
+ this.exit(1);
31
+ }
32
+ this.error(message);
33
+ };
23
34
  const project = await this.storage.getProject(args.id);
24
35
  if (!project) {
25
- this.error(`Project "${args.id}" not found.`);
36
+ return handleError('PROJECT_NOT_FOUND', `Project "${args.id}" not found.`);
26
37
  }
27
38
  if (!project.isArchived) {
39
+ if (jsonMode) {
40
+ outputSuccessAsJson({ projectId: project.id, projectName: project.name, alreadyUnarchived: true }, createMetadata('project unarchive', flags));
41
+ return;
42
+ }
28
43
  this.log(styles.muted(`Project "${project.name}" is not archived.`));
29
44
  return;
30
45
  }
31
46
  await this.storage.unarchiveProject(args.id);
47
+ if (jsonMode) {
48
+ outputSuccessAsJson({ projectId: project.id, projectName: project.name, unarchived: true }, createMetadata('project unarchive', flags));
49
+ return;
50
+ }
32
51
  this.log(styles.success(`\nUnarchived project "${project.name}"`));
33
52
  this.log(styles.muted('View project: prlt project view ' + args.id));
34
53
  }
@@ -6,6 +6,7 @@ export default class ProjectView extends PMOCommand {
6
6
  id: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
7
7
  };
8
8
  static flags: {
9
+ machine: import("@oclif/core/interfaces").BooleanFlag<boolean>;
9
10
  json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
11
  project: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
12
  };
@@ -1,8 +1,7 @@
1
- import { Args, Flags } from '@oclif/core';
2
- import inquirer from 'inquirer';
1
+ import { Args } from '@oclif/core';
3
2
  import { PMOCommand, pmoBaseFlags } from '../../lib/pmo/index.js';
4
3
  import { styles, getColumnStyle, getColumnEmoji, formatPriority, formatCategory } from '../../lib/styles.js';
5
- import { shouldOutputJson, outputPromptAsJson, outputErrorAsJson, createMetadata, buildPromptConfig, } from '../../lib/prompt-json.js';
4
+ import { shouldOutputJson, outputErrorAsJson, outputSuccessAsJson, createMetadata, } from '../../lib/prompt-json.js';
6
5
  export default class ProjectView extends PMOCommand {
7
6
  static description = 'View a project\'s board';
8
7
  static examples = [
@@ -17,10 +16,6 @@ export default class ProjectView extends PMOCommand {
17
16
  };
18
17
  static flags = {
19
18
  ...pmoBaseFlags,
20
- json: Flags.boolean({
21
- description: 'Output prompt configuration as JSON (for AI agents/scripts)',
22
- default: false,
23
- }),
24
19
  };
25
20
  getPMOOptions() {
26
21
  return { promptIfMultiple: false };
@@ -44,27 +39,44 @@ export default class ProjectView extends PMOCommand {
44
39
  if (projects.length === 0) {
45
40
  return handleError('NO_PROJECTS', 'No projects found. Create a project first with "prlt project create".');
46
41
  }
47
- // In JSON mode, output project selection prompt
48
- if (jsonMode) {
49
- const projectChoices = projects.map(p => ({ name: `${p.id} - ${p.name}`, value: p.id }));
50
- outputPromptAsJson(buildPromptConfig('list', 'id', 'Select project to view:', projectChoices), createMetadata('project view', flags));
51
- return;
42
+ // Use selectFromList helper (handles JSON mode automatically)
43
+ const selected = await this.selectFromList({
44
+ message: 'Select project to view:',
45
+ items: projects,
46
+ getName: (p) => `${p.id} - ${p.name}`,
47
+ getValue: (p) => p.id,
48
+ getCommand: (p) => `prlt project view ${p.id} --json`,
49
+ jsonMode: jsonMode ? { flags, commandName: 'project view' } : null,
50
+ });
51
+ if (!selected) {
52
+ return; // Cancelled or JSON mode (already exited)
52
53
  }
53
- const { selectedProjectId } = await inquirer.prompt([{
54
- type: 'list',
55
- name: 'selectedProjectId',
56
- message: 'Select project to view:',
57
- choices: projects.map(p => ({
58
- name: `${p.id} - ${p.name}`,
59
- value: p.id,
60
- })),
61
- }]);
62
- projectId = selectedProjectId;
54
+ projectId = selected;
63
55
  }
64
56
  const project = await this.storage.getProjectBoard(projectId);
65
57
  if (!project) {
66
58
  return handleError('PROJECT_NOT_FOUND', `Project "${projectId}" not found.`);
67
59
  }
60
+ // In JSON mode, output project board as structured data
61
+ if (jsonMode) {
62
+ outputSuccessAsJson({
63
+ id: project.id,
64
+ name: project.name,
65
+ columns: project.columns.map(col => ({
66
+ name: col.name,
67
+ ticketCount: col.tickets.length,
68
+ tickets: col.tickets.map(t => ({
69
+ id: t.id,
70
+ title: t.title,
71
+ priority: t.priority,
72
+ category: t.category,
73
+ subtasksDone: t.subtasks.filter((s) => s.done).length,
74
+ subtasksTotal: t.subtasks.length,
75
+ })),
76
+ })),
77
+ }, createMetadata('project view', flags));
78
+ return;
79
+ }
68
80
  this.log(styles.title(`\n${project.name}`));
69
81
  this.log(styles.muted(`Project: ${project.id}\n`));
70
82
  for (const column of project.columns) {
@@ -8,6 +8,8 @@ export default class Add extends PMOCommand {
8
8
  static flags: {
9
9
  action: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
10
10
  bulk: import("@oclif/core/interfaces").BooleanFlag<boolean>;
11
+ json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
12
+ machine: import("@oclif/core/interfaces").BooleanFlag<boolean>;
11
13
  project: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
12
14
  };
13
15
  protected getPMOOptions(): {
@@ -3,6 +3,7 @@ import { PMOCommand, pmoBaseFlags } from '../../lib/pmo/index.js';
3
3
  import { colors, format } from '../../lib/colors.js';
4
4
  import { findHQRoot, promptAddSingleRepo, promptForRepositories, addRepository } from '../../lib/repos/index.js';
5
5
  import { getWorkspaceRepositories } from '../../lib/database/index.js';
6
+ import { shouldOutputJson, outputErrorAsJson, createMetadata, } from '../../lib/prompt-json.js';
6
7
  export default class Add extends PMOCommand {
7
8
  static description = 'Add a repository to the HQ';
8
9
  static examples = [
@@ -30,19 +31,47 @@ export default class Add extends PMOCommand {
30
31
  description: 'Add multiple repositories interactively',
31
32
  default: false,
32
33
  }),
34
+ json: Flags.boolean({
35
+ description: 'Output prompt configuration as JSON (for AI agents/scripts)',
36
+ default: false,
37
+ }),
33
38
  };
34
39
  getPMOOptions() {
35
40
  return { promptIfMultiple: false };
36
41
  }
37
42
  async execute() {
38
43
  const { args, flags } = await this.parse(Add);
44
+ // Check if JSON output mode is active
45
+ const jsonMode = shouldOutputJson(flags);
46
+ // Helper to handle errors in JSON mode
47
+ const handleError = (code, message) => {
48
+ if (jsonMode) {
49
+ outputErrorAsJson(code, message, createMetadata('repo add', flags));
50
+ this.exit(1);
51
+ }
52
+ this.error(message);
53
+ };
39
54
  // Find HQ root
40
55
  const hqPath = findHQRoot();
41
56
  if (!hqPath) {
42
- this.error('Not in an HQ directory. Run "prlt init" first.');
57
+ return handleError('NOT_IN_HQ', 'Not in an HQ directory. Run "prlt init" first.');
43
58
  }
44
59
  // Bulk mode: add multiple repositories interactively
45
60
  if (flags.bulk) {
61
+ // In JSON mode, output guidance
62
+ if (jsonMode) {
63
+ const agentConfig = { flags, commandName: 'repo add --bulk' };
64
+ await this.prompt([{
65
+ type: 'list',
66
+ name: 'method',
67
+ message: 'Bulk mode requires interactive selection. Use one of these instead:',
68
+ choices: [
69
+ { name: 'Add single repository by path', value: 'path', command: 'prlt repo add <path> --json' },
70
+ { name: 'Add by Git URL', value: 'url', command: 'prlt repo add <git-url> --json' },
71
+ ],
72
+ }], agentConfig);
73
+ return;
74
+ }
46
75
  await this.executeBulk(hqPath);
47
76
  return;
48
77
  }
@@ -60,6 +89,20 @@ export default class Add extends PMOCommand {
60
89
  }
61
90
  }
62
91
  else {
92
+ // In JSON mode, output prompt for method selection
93
+ if (jsonMode) {
94
+ const agentConfig = { flags, commandName: 'repo add' };
95
+ await this.prompt([{
96
+ type: 'list',
97
+ name: 'method',
98
+ message: 'How would you like to add a repository?',
99
+ choices: [
100
+ { name: 'Enter path or Git URL', value: 'manual', command: 'prlt repo add <path> --json' },
101
+ { name: 'Search for repositories (bulk)', value: 'search', command: 'prlt repo add --bulk --json' },
102
+ ],
103
+ }], agentConfig);
104
+ return;
105
+ }
63
106
  // Interactive mode
64
107
  const result = await promptAddSingleRepo();
65
108
  if (!result) {
@@ -3,6 +3,7 @@ export default class Repo extends PMOCommand {
3
3
  static description: string;
4
4
  static examples: string[];
5
5
  static flags: {
6
+ machine: import("@oclif/core/interfaces").BooleanFlag<boolean>;
6
7
  json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
7
8
  project: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
8
9
  };