@proletariat/cli 0.3.21 → 0.3.22

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 (333) hide show
  1. package/dist/commands/action/create.d.ts +0 -1
  2. package/dist/commands/action/delete.d.ts +0 -1
  3. package/dist/commands/action/index.d.ts +0 -1
  4. package/dist/commands/action/list.d.ts +0 -1
  5. package/dist/commands/action/list.js +2 -0
  6. package/dist/commands/action/run.d.ts +0 -1
  7. package/dist/commands/action/show.d.ts +0 -1
  8. package/dist/commands/action/update.d.ts +0 -1
  9. package/dist/commands/agent/auth.d.ts +0 -1
  10. package/dist/commands/agent/auth.js +3 -7
  11. package/dist/commands/agent/discover.d.ts +0 -1
  12. package/dist/commands/agent/discover.js +3 -7
  13. package/dist/commands/agent/index.d.ts +0 -1
  14. package/dist/commands/agent/index.js +2 -0
  15. package/dist/commands/agent/list.d.ts +0 -1
  16. package/dist/commands/agent/list.js +30 -1
  17. package/dist/commands/agent/login.d.ts +0 -1
  18. package/dist/commands/agent/login.js +2 -0
  19. package/dist/commands/agent/rebuild.d.ts +0 -1
  20. package/dist/commands/agent/rebuild.js +2 -0
  21. package/dist/commands/agent/remove.d.ts +0 -1
  22. package/dist/commands/agent/remove.js +2 -0
  23. package/dist/commands/agent/restart.d.ts +0 -1
  24. package/dist/commands/agent/restart.js +2 -0
  25. package/dist/commands/agent/shell.d.ts +0 -1
  26. package/dist/commands/agent/shell.js +2 -0
  27. package/dist/commands/agent/staff/add.d.ts +0 -1
  28. package/dist/commands/agent/staff/add.js +3 -7
  29. package/dist/commands/agent/staff/index.d.ts +0 -1
  30. package/dist/commands/agent/staff/index.js +2 -0
  31. package/dist/commands/agent/staff/remove.d.ts +0 -1
  32. package/dist/commands/agent/staff/remove.js +2 -0
  33. package/dist/commands/agent/status.d.ts +0 -1
  34. package/dist/commands/agent/status.js +2 -0
  35. package/dist/commands/agent/temp/cleanup.d.ts +0 -1
  36. package/dist/commands/agent/temp/cleanup.js +2 -0
  37. package/dist/commands/agent/temp/index.d.ts +0 -1
  38. package/dist/commands/agent/temp/index.js +2 -0
  39. package/dist/commands/agent/themes/index.d.ts +0 -1
  40. package/dist/commands/agent/themes/index.js +3 -7
  41. package/dist/commands/agent/themes/set.d.ts +0 -1
  42. package/dist/commands/agent/themes/set.js +3 -7
  43. package/dist/commands/agent/visit.d.ts +0 -1
  44. package/dist/commands/agent/visit.js +2 -0
  45. package/dist/commands/autocomplete/setup.d.ts +0 -1
  46. package/dist/commands/board/index.d.ts +0 -1
  47. package/dist/commands/board/view.d.ts +0 -1
  48. package/dist/commands/board/watch.d.ts +0 -1
  49. package/dist/commands/branch/create.d.ts +0 -1
  50. package/dist/commands/branch/create.js +2 -0
  51. package/dist/commands/branch/index.d.ts +0 -1
  52. package/dist/commands/branch/index.js +2 -0
  53. package/dist/commands/branch/list.d.ts +0 -1
  54. package/dist/commands/branch/validate.d.ts +0 -1
  55. package/dist/commands/branch/where.d.ts +0 -1
  56. package/dist/commands/branch/where.js +2 -0
  57. package/dist/commands/category/create.d.ts +18 -0
  58. package/dist/commands/category/create.js +108 -0
  59. package/dist/commands/category/delete.d.ts +17 -0
  60. package/dist/commands/category/delete.js +103 -0
  61. package/dist/commands/category/index.d.ts +15 -0
  62. package/dist/commands/category/index.js +87 -0
  63. package/dist/commands/category/list.d.ts +17 -0
  64. package/dist/commands/category/list.js +85 -0
  65. package/dist/commands/category/rename.d.ts +18 -0
  66. package/dist/commands/category/rename.js +127 -0
  67. package/dist/commands/claude.js +2 -0
  68. package/dist/commands/commit.js +2 -0
  69. package/dist/commands/config/index.js +2 -0
  70. package/dist/commands/docker/clean.d.ts +0 -1
  71. package/dist/commands/docker/index.d.ts +0 -1
  72. package/dist/commands/docker/prune.d.ts +0 -1
  73. package/dist/commands/docker/restart.d.ts +0 -1
  74. package/dist/commands/docker/stop.d.ts +0 -1
  75. package/dist/commands/epic/activate.d.ts +0 -1
  76. package/dist/commands/epic/activate.js +2 -0
  77. package/dist/commands/epic/archive.d.ts +0 -1
  78. package/dist/commands/epic/archive.js +2 -0
  79. package/dist/commands/epic/create.d.ts +0 -1
  80. package/dist/commands/epic/create.js +3 -1
  81. package/dist/commands/epic/delete.d.ts +14 -0
  82. package/dist/commands/epic/delete.js +129 -0
  83. package/dist/commands/epic/index.d.ts +0 -1
  84. package/dist/commands/epic/index.js +6 -0
  85. package/dist/commands/epic/link/block.d.ts +0 -1
  86. package/dist/commands/epic/link/block.js +2 -0
  87. package/dist/commands/epic/link/duplicates.d.ts +0 -1
  88. package/dist/commands/epic/link/duplicates.js +2 -0
  89. package/dist/commands/epic/link/index.d.ts +0 -1
  90. package/dist/commands/epic/link/index.js +2 -0
  91. package/dist/commands/epic/link/relates.d.ts +0 -1
  92. package/dist/commands/epic/link/relates.js +2 -0
  93. package/dist/commands/epic/link/remove.d.ts +0 -1
  94. package/dist/commands/epic/link/remove.js +2 -0
  95. package/dist/commands/epic/list.d.ts +0 -1
  96. package/dist/commands/epic/move.d.ts +0 -1
  97. package/dist/commands/epic/move.js +2 -0
  98. package/dist/commands/epic/progress.d.ts +0 -1
  99. package/dist/commands/epic/progress.js +2 -0
  100. package/dist/commands/epic/project.d.ts +0 -1
  101. package/dist/commands/epic/project.js +2 -0
  102. package/dist/commands/epic/reorder.d.ts +0 -1
  103. package/dist/commands/epic/reorder.js +2 -0
  104. package/dist/commands/epic/spec.d.ts +0 -1
  105. package/dist/commands/epic/spec.js +2 -0
  106. package/dist/commands/epic/ticket.d.ts +0 -1
  107. package/dist/commands/epic/ticket.js +2 -0
  108. package/dist/commands/epic/view.d.ts +0 -1
  109. package/dist/commands/epic/view.js +2 -0
  110. package/dist/commands/execution/config.d.ts +0 -1
  111. package/dist/commands/execution/config.js +2 -0
  112. package/dist/commands/execution/index.d.ts +0 -1
  113. package/dist/commands/execution/index.js +3 -1
  114. package/dist/commands/execution/list.d.ts +0 -1
  115. package/dist/commands/execution/logs.d.ts +0 -1
  116. package/dist/commands/execution/logs.js +3 -1
  117. package/dist/commands/execution/stop.d.ts +0 -1
  118. package/dist/commands/execution/stop.js +3 -1
  119. package/dist/commands/execution/view.d.ts +0 -1
  120. package/dist/commands/execution/view.js +3 -1
  121. package/dist/commands/gh/index.d.ts +0 -1
  122. package/dist/commands/gh/login.d.ts +0 -1
  123. package/dist/commands/gh/status.d.ts +0 -1
  124. package/dist/commands/gh/token.d.ts +0 -1
  125. package/dist/commands/init.js +2 -0
  126. package/dist/commands/phase/create.d.ts +0 -1
  127. package/dist/commands/phase/create.js +1 -2
  128. package/dist/commands/phase/delete.d.ts +0 -1
  129. package/dist/commands/phase/delete.js +1 -1
  130. package/dist/commands/phase/list.d.ts +0 -1
  131. package/dist/commands/phase/move.d.ts +0 -1
  132. package/dist/commands/phase/move.js +2 -2
  133. package/dist/commands/phase/template/apply.d.ts +0 -1
  134. package/dist/commands/phase/template/apply.js +2 -0
  135. package/dist/commands/phase/template/create.d.ts +0 -1
  136. package/dist/commands/phase/template/create.js +0 -1
  137. package/dist/commands/phase/template/delete.d.ts +0 -1
  138. package/dist/commands/phase/template/delete.js +2 -0
  139. package/dist/commands/phase/template/index.d.ts +0 -1
  140. package/dist/commands/phase/template/index.js +2 -0
  141. package/dist/commands/phase/template/list.d.ts +0 -1
  142. package/dist/commands/phase/template/list.js +2 -0
  143. package/dist/commands/phase/template/update.d.ts +0 -1
  144. package/dist/commands/phase/update.d.ts +0 -1
  145. package/dist/commands/phase/update.js +2 -2
  146. package/dist/commands/pmo/init.js +2 -0
  147. package/dist/commands/pr/create.d.ts +0 -1
  148. package/dist/commands/pr/index.d.ts +0 -1
  149. package/dist/commands/pr/link.d.ts +0 -1
  150. package/dist/commands/pr/list.d.ts +0 -1
  151. package/dist/commands/pr/status.d.ts +0 -1
  152. package/dist/commands/project/archive.d.ts +0 -1
  153. package/dist/commands/project/create.d.ts +0 -1
  154. package/dist/commands/project/delete.d.ts +0 -1
  155. package/dist/commands/project/index.d.ts +0 -1
  156. package/dist/commands/project/list.d.ts +0 -1
  157. package/dist/commands/project/spec.d.ts +0 -1
  158. package/dist/commands/project/unarchive.d.ts +0 -1
  159. package/dist/commands/project/update.d.ts +0 -1
  160. package/dist/commands/project/view.d.ts +0 -1
  161. package/dist/commands/repo/add.d.ts +0 -1
  162. package/dist/commands/repo/add.js +2 -0
  163. package/dist/commands/repo/index.d.ts +0 -1
  164. package/dist/commands/repo/list.d.ts +0 -1
  165. package/dist/commands/repo/remove.d.ts +0 -1
  166. package/dist/commands/repo/view.d.ts +0 -1
  167. package/dist/commands/roadmap/add-project.d.ts +0 -1
  168. package/dist/commands/roadmap/add-project.js +2 -0
  169. package/dist/commands/roadmap/create.d.ts +0 -1
  170. package/dist/commands/roadmap/create.js +2 -0
  171. package/dist/commands/roadmap/delete.d.ts +0 -1
  172. package/dist/commands/roadmap/delete.js +12 -1
  173. package/dist/commands/roadmap/generate.d.ts +0 -1
  174. package/dist/commands/roadmap/generate.js +2 -0
  175. package/dist/commands/roadmap/index.d.ts +0 -1
  176. package/dist/commands/roadmap/index.js +2 -0
  177. package/dist/commands/roadmap/list.d.ts +0 -1
  178. package/dist/commands/roadmap/remove-project.d.ts +0 -1
  179. package/dist/commands/roadmap/remove-project.js +2 -0
  180. package/dist/commands/roadmap/reorder.d.ts +0 -1
  181. package/dist/commands/roadmap/reorder.js +2 -0
  182. package/dist/commands/roadmap/update.d.ts +0 -1
  183. package/dist/commands/roadmap/update.js +2 -0
  184. package/dist/commands/roadmap/view.d.ts +0 -1
  185. package/dist/commands/roadmap/view.js +2 -0
  186. package/dist/commands/session/attach.d.ts +0 -1
  187. package/dist/commands/session/attach.js +9 -0
  188. package/dist/commands/session/index.d.ts +0 -1
  189. package/dist/commands/session/index.js +2 -0
  190. package/dist/commands/session/list.d.ts +0 -1
  191. package/dist/commands/spec/create.d.ts +0 -1
  192. package/dist/commands/spec/create.js +1 -1
  193. package/dist/commands/spec/delete.d.ts +0 -1
  194. package/dist/commands/spec/edit.d.ts +0 -1
  195. package/dist/commands/spec/index.d.ts +0 -1
  196. package/dist/commands/spec/link/depends.d.ts +0 -1
  197. package/dist/commands/spec/link/duplicates.d.ts +0 -1
  198. package/dist/commands/spec/link/index.d.ts +0 -1
  199. package/dist/commands/spec/link/relates.d.ts +0 -1
  200. package/dist/commands/spec/link/remove.d.ts +0 -1
  201. package/dist/commands/spec/list.d.ts +0 -1
  202. package/dist/commands/spec/plan.d.ts +0 -1
  203. package/dist/commands/spec/ticket.d.ts +0 -3
  204. package/dist/commands/spec/ticket.js +7 -38
  205. package/dist/commands/spec/view.d.ts +0 -1
  206. package/dist/commands/status/category.d.ts +14 -0
  207. package/dist/commands/status/category.js +63 -0
  208. package/dist/commands/status/create.d.ts +0 -1
  209. package/dist/commands/status/create.js +1 -1
  210. package/dist/commands/status/delete.d.ts +0 -1
  211. package/dist/commands/status/index.d.ts +0 -1
  212. package/dist/commands/status/list.d.ts +0 -1
  213. package/dist/commands/status/move.d.ts +0 -1
  214. package/dist/commands/status/update.d.ts +0 -1
  215. package/dist/commands/template/delete.d.ts +0 -1
  216. package/dist/commands/template/delete.js +2 -0
  217. package/dist/commands/template/index.d.ts +0 -1
  218. package/dist/commands/template/list.d.ts +0 -1
  219. package/dist/commands/template/list.js +2 -0
  220. package/dist/commands/template/phase/apply.js +2 -0
  221. package/dist/commands/template/phase/create.d.ts +0 -1
  222. package/dist/commands/template/phase/create.js +3 -9
  223. package/dist/commands/template/phase/delete.js +2 -0
  224. package/dist/commands/template/phase/index.d.ts +0 -1
  225. package/dist/commands/template/phase/list.js +2 -0
  226. package/dist/commands/template/phase/update.js +2 -0
  227. package/dist/commands/template/ticket/apply.js +2 -0
  228. package/dist/commands/template/ticket/create.js +2 -0
  229. package/dist/commands/template/ticket/delete.js +2 -0
  230. package/dist/commands/template/ticket/index.d.ts +0 -1
  231. package/dist/commands/template/ticket/list.js +2 -0
  232. package/dist/commands/template/ticket/save.d.ts +0 -1
  233. package/dist/commands/template/ticket/save.js +0 -6
  234. package/dist/commands/terminal/title.d.ts +0 -1
  235. package/dist/commands/ticket/bulk.d.ts +0 -1
  236. package/dist/commands/ticket/bulk.js +2 -0
  237. package/dist/commands/ticket/category.d.ts +14 -0
  238. package/dist/commands/ticket/category.js +63 -0
  239. package/dist/commands/ticket/complete.d.ts +0 -1
  240. package/dist/commands/ticket/complete.js +2 -0
  241. package/dist/commands/ticket/create.d.ts +0 -1
  242. package/dist/commands/ticket/create.js +6 -4
  243. package/dist/commands/ticket/delete.d.ts +0 -1
  244. package/dist/commands/ticket/delete.js +2 -0
  245. package/dist/commands/ticket/edit.d.ts +0 -1
  246. package/dist/commands/ticket/edit.js +4 -2
  247. package/dist/commands/ticket/epic.d.ts +0 -1
  248. package/dist/commands/ticket/epic.js +2 -0
  249. package/dist/commands/ticket/index.d.ts +0 -1
  250. package/dist/commands/ticket/index.js +2 -0
  251. package/dist/commands/ticket/link/block.d.ts +0 -1
  252. package/dist/commands/ticket/link/block.js +2 -0
  253. package/dist/commands/ticket/link/duplicates.d.ts +0 -1
  254. package/dist/commands/ticket/link/duplicates.js +2 -0
  255. package/dist/commands/ticket/link/index.d.ts +0 -1
  256. package/dist/commands/ticket/link/index.js +2 -0
  257. package/dist/commands/ticket/link/relates.d.ts +0 -1
  258. package/dist/commands/ticket/link/relates.js +2 -0
  259. package/dist/commands/ticket/link/remove.d.ts +0 -1
  260. package/dist/commands/ticket/link/remove.js +2 -0
  261. package/dist/commands/ticket/list.d.ts +0 -1
  262. package/dist/commands/ticket/move.d.ts +0 -1
  263. package/dist/commands/ticket/move.js +2 -0
  264. package/dist/commands/ticket/project.d.ts +0 -1
  265. package/dist/commands/ticket/project.js +2 -0
  266. package/dist/commands/ticket/reassign.d.ts +0 -1
  267. package/dist/commands/ticket/reassign.js +29 -0
  268. package/dist/commands/ticket/spec.d.ts +0 -1
  269. package/dist/commands/ticket/spec.js +2 -0
  270. package/dist/commands/ticket/status.d.ts +0 -1
  271. package/dist/commands/ticket/status.js +2 -0
  272. package/dist/commands/ticket/template/apply.d.ts +0 -1
  273. package/dist/commands/ticket/template/apply.js +2 -0
  274. package/dist/commands/ticket/template/create.d.ts +0 -1
  275. package/dist/commands/ticket/template/create.js +4 -2
  276. package/dist/commands/ticket/template/delete.d.ts +0 -1
  277. package/dist/commands/ticket/template/delete.js +2 -0
  278. package/dist/commands/ticket/template/index.d.ts +0 -1
  279. package/dist/commands/ticket/template/index.js +2 -0
  280. package/dist/commands/ticket/template/list.d.ts +0 -1
  281. package/dist/commands/ticket/template/list.js +2 -0
  282. package/dist/commands/ticket/template/save.d.ts +0 -1
  283. package/dist/commands/ticket/template/save.js +2 -0
  284. package/dist/commands/ticket/update.d.ts +0 -1
  285. package/dist/commands/ticket/update.js +2 -0
  286. package/dist/commands/ticket/view.d.ts +0 -1
  287. package/dist/commands/ticket/view.js +2 -0
  288. package/dist/commands/work/complete.d.ts +0 -1
  289. package/dist/commands/work/complete.js +2 -0
  290. package/dist/commands/work/index.d.ts +0 -1
  291. package/dist/commands/work/index.js +2 -0
  292. package/dist/commands/work/ready.d.ts +1 -2
  293. package/dist/commands/work/ready.js +11 -5
  294. package/dist/commands/work/revise.d.ts +0 -1
  295. package/dist/commands/work/revise.js +3 -1
  296. package/dist/commands/work/spawn-all.d.ts +0 -1
  297. package/dist/commands/work/spawn-all.js +2 -0
  298. package/dist/commands/work/spawn.d.ts +0 -1
  299. package/dist/commands/work/spawn.js +2 -0
  300. package/dist/commands/work/start.d.ts +0 -1
  301. package/dist/commands/work/start.js +6 -0
  302. package/dist/commands/work/watch.d.ts +0 -1
  303. package/dist/commands/work/watch.js +3 -1
  304. package/dist/commands/workflow/create.d.ts +0 -1
  305. package/dist/commands/workflow/delete.d.ts +0 -1
  306. package/dist/commands/workflow/index.d.ts +0 -1
  307. package/dist/commands/workflow/index.js +2 -0
  308. package/dist/commands/workflow/list.d.ts +0 -1
  309. package/dist/commands/workflow/switch.d.ts +0 -1
  310. package/dist/commands/workflow/view.d.ts +0 -1
  311. package/dist/commands/workspace/list.js +2 -0
  312. package/dist/commands/workspace/prune.d.ts +13 -0
  313. package/dist/commands/workspace/prune.js +186 -0
  314. package/dist/commands/workspace/remove.js +2 -0
  315. package/dist/commands/workspace/use.js +2 -0
  316. package/dist/lib/pmo/base-command.d.ts +2 -4
  317. package/dist/lib/pmo/base-command.js +8 -10
  318. package/dist/lib/pmo/schema.d.ts +2 -0
  319. package/dist/lib/pmo/schema.js +17 -0
  320. package/dist/lib/pmo/storage/base.d.ts +4 -0
  321. package/dist/lib/pmo/storage/base.js +31 -0
  322. package/dist/lib/pmo/storage/categories.d.ts +50 -0
  323. package/dist/lib/pmo/storage/categories.js +205 -0
  324. package/dist/lib/pmo/storage/index.d.ts +14 -1
  325. package/dist/lib/pmo/storage/index.js +35 -1
  326. package/dist/lib/pmo/storage/tickets.d.ts +5 -0
  327. package/dist/lib/pmo/storage/tickets.js +31 -3
  328. package/dist/lib/pmo/storage/types.d.ts +10 -0
  329. package/dist/lib/pmo/types.d.ts +25 -0
  330. package/dist/lib/prompt-json.d.ts +10 -16
  331. package/dist/lib/prompt-json.js +8 -16
  332. package/oclif.manifest.json +4283 -4345
  333. package/package.json +1 -1
@@ -0,0 +1,18 @@
1
+ import { PMOCommand } from '../../lib/pmo/index.js';
2
+ export default class CategoryCreate extends PMOCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ static args: {
6
+ name: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
7
+ };
8
+ static flags: {
9
+ type: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
10
+ description: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
+ json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
12
+ project: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
13
+ };
14
+ protected getPMOOptions(): {
15
+ promptIfMultiple: boolean;
16
+ };
17
+ execute(): Promise<void>;
18
+ }
@@ -0,0 +1,108 @@
1
+ import { Args, Flags } from '@oclif/core';
2
+ import inquirer from 'inquirer';
3
+ import { PMOCommand, pmoBaseFlags } from '../../lib/pmo/index.js';
4
+ import { styles } from '../../lib/styles.js';
5
+ import { shouldOutputJson, outputPromptAsJson, buildPromptConfig, createMetadata } from '../../lib/prompt-json.js';
6
+ export default class CategoryCreate extends PMOCommand {
7
+ static description = 'Create a new category';
8
+ static examples = [
9
+ '<%= config.bin %> <%= command.id %> --type ticket spike',
10
+ '<%= config.bin %> <%= command.id %> --type ticket spike --description "Research or investigation task"',
11
+ '<%= config.bin %> <%= command.id %> --type status reviewing',
12
+ ];
13
+ static args = {
14
+ name: Args.string({
15
+ description: 'Name of the new category',
16
+ }),
17
+ };
18
+ static flags = {
19
+ ...pmoBaseFlags,
20
+ type: Flags.string({
21
+ char: 't',
22
+ description: 'Category type',
23
+ options: ['ticket', 'status'],
24
+ required: true,
25
+ }),
26
+ description: Flags.string({
27
+ char: 'd',
28
+ description: 'Description of the category',
29
+ }),
30
+ json: Flags.boolean({
31
+ description: 'Output prompt configuration as JSON (for AI agents/scripts)',
32
+ default: false,
33
+ }),
34
+ };
35
+ getPMOOptions() {
36
+ return { promptIfMultiple: false };
37
+ }
38
+ async execute() {
39
+ const { args, flags } = await this.parse(CategoryCreate);
40
+ const categoryType = flags.type;
41
+ const jsonMode = shouldOutputJson(flags);
42
+ let name = args.name;
43
+ let description = flags.description;
44
+ // Prompt for name if not provided
45
+ if (!name) {
46
+ const message = `Enter ${categoryType} category name:`;
47
+ const choices = [
48
+ { name: 'Enter category name', value: 'input' },
49
+ ];
50
+ if (jsonMode) {
51
+ outputPromptAsJson(buildPromptConfig('input', 'name', message, choices), createMetadata('category create', flags));
52
+ return;
53
+ }
54
+ const { categoryName } = await inquirer.prompt([{
55
+ type: 'input',
56
+ name: 'categoryName',
57
+ message,
58
+ validate: (input) => {
59
+ if (!input.trim())
60
+ return 'Category name is required';
61
+ if (!/^[a-z][a-z0-9-]*$/.test(input.trim())) {
62
+ return 'Category name must start with a letter and contain only lowercase letters, numbers, and hyphens';
63
+ }
64
+ return true;
65
+ },
66
+ }]);
67
+ name = categoryName;
68
+ }
69
+ // At this point name should be defined
70
+ if (!name) {
71
+ this.error('Category name is required');
72
+ }
73
+ // Validate name format
74
+ if (!/^[a-z][a-z0-9-]*$/.test(name)) {
75
+ this.error('Category name must start with a letter and contain only lowercase letters, numbers, and hyphens');
76
+ }
77
+ // Prompt for description if not provided
78
+ if (!description && !jsonMode) {
79
+ const { categoryDescription } = await inquirer.prompt([{
80
+ type: 'input',
81
+ name: 'categoryDescription',
82
+ message: 'Description (optional):',
83
+ }]);
84
+ description = categoryDescription || undefined;
85
+ }
86
+ try {
87
+ const category = await this.storage.createCategory({
88
+ name: name,
89
+ type: categoryType,
90
+ description,
91
+ });
92
+ this.log(`\n${styles.success('Category created successfully!')}`);
93
+ this.log(` Name: ${styles.emphasis(category.name)}`);
94
+ this.log(` Type: ${category.type}`);
95
+ this.log(` ID: ${category.id}`);
96
+ if (category.description) {
97
+ this.log(` Description: ${category.description}`);
98
+ }
99
+ this.log('');
100
+ }
101
+ catch (error) {
102
+ if (error instanceof Error) {
103
+ this.error(error.message);
104
+ }
105
+ throw error;
106
+ }
107
+ }
108
+ }
@@ -0,0 +1,17 @@
1
+ import { PMOCommand } from '../../lib/pmo/index.js';
2
+ export default class CategoryDelete extends PMOCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ static args: {
6
+ name: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
7
+ };
8
+ static flags: {
9
+ type: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
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
+ }
@@ -0,0 +1,103 @@
1
+ import { Args, Flags } from '@oclif/core';
2
+ import inquirer from 'inquirer';
3
+ import { PMOCommand, pmoBaseFlags } from '../../lib/pmo/index.js';
4
+ import { styles } from '../../lib/styles.js';
5
+ import { shouldOutputJson, outputPromptAsJson, buildPromptConfig, createMetadata } from '../../lib/prompt-json.js';
6
+ export default class CategoryDelete extends PMOCommand {
7
+ static description = 'Delete a category (custom categories only)';
8
+ static examples = [
9
+ '<%= config.bin %> <%= command.id %> --type ticket spike',
10
+ '<%= config.bin %> <%= command.id %> --type status reviewing',
11
+ ];
12
+ static args = {
13
+ name: Args.string({
14
+ description: 'Name of the category to delete',
15
+ }),
16
+ };
17
+ static flags = {
18
+ ...pmoBaseFlags,
19
+ type: Flags.string({
20
+ char: 't',
21
+ description: 'Category type',
22
+ options: ['ticket', 'status'],
23
+ required: true,
24
+ }),
25
+ json: Flags.boolean({
26
+ description: 'Output prompt configuration as JSON (for AI agents/scripts)',
27
+ default: false,
28
+ }),
29
+ };
30
+ getPMOOptions() {
31
+ return { promptIfMultiple: false };
32
+ }
33
+ async execute() {
34
+ const { args, flags } = await this.parse(CategoryDelete);
35
+ const categoryType = flags.type;
36
+ const jsonMode = shouldOutputJson(flags);
37
+ let name = args.name;
38
+ // Get custom categories for selection
39
+ const customCategories = await this.storage.listCategories({ type: categoryType, isBuiltin: false });
40
+ if (customCategories.length === 0) {
41
+ this.log(styles.muted('\nNo custom categories to delete. Built-in categories cannot be deleted.'));
42
+ return;
43
+ }
44
+ // Prompt for category if not provided
45
+ if (!name) {
46
+ const message = 'Select category to delete:';
47
+ const choices = customCategories.map(c => ({
48
+ name: c.name + (c.description ? ` - ${c.description}` : ''),
49
+ value: c.name,
50
+ }));
51
+ if (jsonMode) {
52
+ outputPromptAsJson(buildPromptConfig('list', 'name', message, choices), createMetadata('category delete', flags));
53
+ return;
54
+ }
55
+ const result = await this.selectFromList({
56
+ message,
57
+ items: customCategories,
58
+ getName: (c) => c.name + (c.description ? ` - ${c.description}` : ''),
59
+ getValue: (c) => c.name,
60
+ getCommand: (c) => `prlt category delete --type ${categoryType} ${c.name}`,
61
+ allowCancel: true,
62
+ });
63
+ if (!result) {
64
+ return;
65
+ }
66
+ name = result;
67
+ }
68
+ // Find the category
69
+ const category = await this.storage.getCategoryByName(name, categoryType);
70
+ if (!category) {
71
+ this.error(`Category "${name}" not found for type "${categoryType}"`);
72
+ }
73
+ if (category.isBuiltin) {
74
+ this.error(`Cannot delete built-in category "${name}"`);
75
+ }
76
+ // Confirm deletion
77
+ if (!jsonMode) {
78
+ const { confirmed } = await inquirer.prompt([{
79
+ type: 'list',
80
+ name: 'confirmed',
81
+ message: `Are you sure you want to delete category "${name}"?`,
82
+ choices: [
83
+ { name: 'Yes, delete it', value: true },
84
+ { name: 'No, cancel', value: false },
85
+ ],
86
+ }]);
87
+ if (!confirmed) {
88
+ this.log(styles.muted('Deletion cancelled.'));
89
+ return;
90
+ }
91
+ }
92
+ try {
93
+ await this.storage.deleteCategory(category.id);
94
+ this.log(`\n${styles.success(`Category "${name}" deleted successfully.`)}`);
95
+ }
96
+ catch (error) {
97
+ if (error instanceof Error) {
98
+ this.error(error.message);
99
+ }
100
+ throw error;
101
+ }
102
+ }
103
+ }
@@ -0,0 +1,15 @@
1
+ import { PMOCommand } from '../../lib/pmo/index.js';
2
+ export default class CategoryIndex extends PMOCommand {
3
+ static description: string;
4
+ static aliases: string[];
5
+ static examples: string[];
6
+ static flags: {
7
+ type: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
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
+ }
@@ -0,0 +1,87 @@
1
+ import { Flags } from '@oclif/core';
2
+ import { PMOCommand, pmoBaseFlags } from '../../lib/pmo/index.js';
3
+ import { shouldOutputJson } from '../../lib/prompt-json.js';
4
+ export default class CategoryIndex extends PMOCommand {
5
+ static description = 'Interactive menu for category operations (ticket and status categories)';
6
+ static aliases = ['categories'];
7
+ static examples = [
8
+ '<%= config.bin %> <%= command.id %>',
9
+ '<%= config.bin %> <%= command.id %> --type ticket',
10
+ '<%= config.bin %> <%= command.id %> --type status',
11
+ ];
12
+ static flags = {
13
+ ...pmoBaseFlags,
14
+ type: Flags.string({
15
+ char: 't',
16
+ description: 'Category type to manage',
17
+ options: ['ticket', 'status'],
18
+ }),
19
+ json: Flags.boolean({
20
+ description: 'Output prompt configuration as JSON (for AI agents/scripts)',
21
+ default: false,
22
+ }),
23
+ };
24
+ getPMOOptions() {
25
+ return { promptIfMultiple: false };
26
+ }
27
+ async execute() {
28
+ const { flags } = await this.parse(CategoryIndex);
29
+ // Check if JSON output mode is active
30
+ const jsonMode = shouldOutputJson(flags);
31
+ // First, determine the category type
32
+ let categoryType = flags.type;
33
+ if (!categoryType) {
34
+ const typeChoices = [
35
+ { id: 'ticket', name: 'Ticket Categories (feature, bug, etc.)', command: 'prlt category --type ticket' },
36
+ { id: 'status', name: 'Status Categories (backlog, started, etc.)', command: 'prlt category --type status' },
37
+ { id: 'cancel', name: 'Cancel', command: '' },
38
+ ];
39
+ const selectedType = await this.selectFromList({
40
+ message: '📁 Which category type would you like to manage?',
41
+ items: typeChoices,
42
+ getName: (c) => c.name,
43
+ getValue: (c) => c.id,
44
+ getCommand: (c) => c.command,
45
+ jsonMode: jsonMode ? { flags, commandName: 'category' } : null,
46
+ });
47
+ if (selectedType === 'cancel' || !selectedType) {
48
+ return;
49
+ }
50
+ categoryType = selectedType;
51
+ }
52
+ // Now show the action menu
53
+ const menuChoices = [
54
+ { id: 'list', name: 'List all categories', command: `prlt category list --type ${categoryType}` },
55
+ { id: 'create', name: 'Create new category', command: `prlt category create --type ${categoryType} --json` },
56
+ { id: 'rename', name: 'Rename category', command: `prlt category rename --type ${categoryType} --json` },
57
+ { id: 'delete', name: 'Delete category', command: `prlt category delete --type ${categoryType} --json` },
58
+ { id: 'cancel', name: 'Cancel', command: '' },
59
+ ];
60
+ const action = await this.selectFromList({
61
+ message: `📁 ${categoryType.charAt(0).toUpperCase() + categoryType.slice(1)} Categories - What would you like to do?`,
62
+ items: menuChoices,
63
+ getName: (c) => c.name,
64
+ getValue: (c) => c.id,
65
+ getCommand: (c) => c.command,
66
+ jsonMode: jsonMode ? { flags: { ...flags, type: categoryType }, commandName: 'category' } : null,
67
+ });
68
+ if (action === 'cancel' || !action) {
69
+ return;
70
+ }
71
+ // Run the selected subcommand
72
+ switch (action) {
73
+ case 'list':
74
+ await this.config.runCommand('category:list', ['--type', categoryType]);
75
+ break;
76
+ case 'create':
77
+ await this.config.runCommand('category:create', ['--type', categoryType]);
78
+ break;
79
+ case 'rename':
80
+ await this.config.runCommand('category:rename', ['--type', categoryType]);
81
+ break;
82
+ case 'delete':
83
+ await this.config.runCommand('category:delete', ['--type', categoryType]);
84
+ break;
85
+ }
86
+ }
87
+ }
@@ -0,0 +1,17 @@
1
+ import { PMOCommand } from '../../lib/pmo/index.js';
2
+ export default class CategoryList extends PMOCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ type: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
7
+ builtin: import("@oclif/core/interfaces").BooleanFlag<boolean>;
8
+ custom: import("@oclif/core/interfaces").BooleanFlag<boolean>;
9
+ json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
+ project: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
+ };
12
+ protected getPMOOptions(): {
13
+ promptIfMultiple: boolean;
14
+ };
15
+ execute(): Promise<void>;
16
+ private printCategory;
17
+ }
@@ -0,0 +1,85 @@
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 CategoryList extends PMOCommand {
5
+ static description = 'List categories for ticket or status types';
6
+ static examples = [
7
+ '<%= config.bin %> <%= command.id %> --type ticket',
8
+ '<%= config.bin %> <%= command.id %> --type status',
9
+ '<%= config.bin %> <%= command.id %> --type ticket --builtin',
10
+ '<%= config.bin %> <%= command.id %> --type ticket --json',
11
+ ];
12
+ static flags = {
13
+ ...pmoBaseFlags,
14
+ type: Flags.string({
15
+ char: 't',
16
+ description: 'Category type to list',
17
+ options: ['ticket', 'status'],
18
+ required: true,
19
+ }),
20
+ builtin: Flags.boolean({
21
+ description: 'Show only built-in categories',
22
+ exclusive: ['custom'],
23
+ }),
24
+ custom: Flags.boolean({
25
+ description: 'Show only custom categories',
26
+ exclusive: ['builtin'],
27
+ }),
28
+ json: Flags.boolean({
29
+ description: 'Output as JSON',
30
+ default: false,
31
+ }),
32
+ };
33
+ getPMOOptions() {
34
+ return { promptIfMultiple: false };
35
+ }
36
+ async execute() {
37
+ const { flags } = await this.parse(CategoryList);
38
+ const categoryType = flags.type;
39
+ let filter = { type: categoryType };
40
+ if (flags.builtin)
41
+ filter.isBuiltin = true;
42
+ if (flags.custom)
43
+ filter.isBuiltin = false;
44
+ const categories = await this.storage.listCategories(filter);
45
+ if (flags.json) {
46
+ this.log(JSON.stringify(categories, null, 2));
47
+ return;
48
+ }
49
+ if (categories.length === 0) {
50
+ this.log(styles.muted(`\nNo ${categoryType} categories found.`));
51
+ this.log(styles.muted(`Create one: prlt category create --type ${categoryType}`));
52
+ return;
53
+ }
54
+ const typeLabel = categoryType === 'ticket' ? 'Ticket' : 'Status';
55
+ this.log(`\n📁 ${styles.emphasis(`${typeLabel} Categories`)}`);
56
+ this.log('═'.repeat(60));
57
+ // Group by builtin vs custom
58
+ const builtinCategories = categories.filter(c => c.isBuiltin);
59
+ const customCategories = categories.filter(c => !c.isBuiltin);
60
+ if (builtinCategories.length > 0 && !flags.custom) {
61
+ this.log(`\n${styles.emphasis('Built-in Categories')}`);
62
+ this.log('─'.repeat(40));
63
+ for (const category of builtinCategories) {
64
+ this.printCategory(category);
65
+ }
66
+ }
67
+ if (customCategories.length > 0 && !flags.builtin) {
68
+ this.log(`\n${styles.emphasis('Custom Categories')}`);
69
+ this.log('─'.repeat(40));
70
+ for (const category of customCategories) {
71
+ this.printCategory(category);
72
+ }
73
+ }
74
+ this.log('');
75
+ this.log(styles.muted(`Create new: prlt category create --type ${categoryType} <name>`));
76
+ this.log('');
77
+ }
78
+ printCategory(category) {
79
+ const builtinBadge = category.isBuiltin ? '' : ' [custom]';
80
+ this.log(` ${styles.emphasis(category.name)} ${styles.muted(`(${category.id})`)}${builtinBadge}`);
81
+ if (category.description) {
82
+ this.log(` ${styles.muted(category.description)}`);
83
+ }
84
+ }
85
+ }
@@ -0,0 +1,18 @@
1
+ import { PMOCommand } from '../../lib/pmo/index.js';
2
+ export default class CategoryRename extends PMOCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ static args: {
6
+ oldName: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
7
+ newName: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
8
+ };
9
+ static flags: {
10
+ type: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
11
+ json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
12
+ project: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
13
+ };
14
+ protected getPMOOptions(): {
15
+ promptIfMultiple: boolean;
16
+ };
17
+ execute(): Promise<void>;
18
+ }
@@ -0,0 +1,127 @@
1
+ import { Args, Flags } from '@oclif/core';
2
+ import inquirer from 'inquirer';
3
+ import { PMOCommand, pmoBaseFlags } from '../../lib/pmo/index.js';
4
+ import { styles } from '../../lib/styles.js';
5
+ import { shouldOutputJson, outputPromptAsJson, buildPromptConfig, createMetadata } from '../../lib/prompt-json.js';
6
+ export default class CategoryRename extends PMOCommand {
7
+ static description = 'Rename a category (custom categories only)';
8
+ static examples = [
9
+ '<%= config.bin %> <%= command.id %> --type ticket spike investigation',
10
+ '<%= config.bin %> <%= command.id %> --type status reviewing in-review',
11
+ ];
12
+ static args = {
13
+ oldName: Args.string({
14
+ description: 'Current name of the category',
15
+ }),
16
+ newName: Args.string({
17
+ description: 'New name for the category',
18
+ }),
19
+ };
20
+ static flags = {
21
+ ...pmoBaseFlags,
22
+ type: Flags.string({
23
+ char: 't',
24
+ description: 'Category type',
25
+ options: ['ticket', 'status'],
26
+ required: true,
27
+ }),
28
+ json: Flags.boolean({
29
+ description: 'Output prompt configuration as JSON (for AI agents/scripts)',
30
+ default: false,
31
+ }),
32
+ };
33
+ getPMOOptions() {
34
+ return { promptIfMultiple: false };
35
+ }
36
+ async execute() {
37
+ const { args, flags } = await this.parse(CategoryRename);
38
+ const categoryType = flags.type;
39
+ const jsonMode = shouldOutputJson(flags);
40
+ let oldName = args.oldName;
41
+ let newName = args.newName;
42
+ // Get custom categories for selection
43
+ const customCategories = await this.storage.listCategories({ type: categoryType, isBuiltin: false });
44
+ if (customCategories.length === 0) {
45
+ this.log(styles.muted('\nNo custom categories to rename. Built-in categories cannot be renamed.'));
46
+ return;
47
+ }
48
+ // Prompt for category if not provided
49
+ if (!oldName) {
50
+ const message = 'Select category to rename:';
51
+ const choices = customCategories.map(c => ({
52
+ name: c.name + (c.description ? ` - ${c.description}` : ''),
53
+ value: c.name,
54
+ }));
55
+ if (jsonMode) {
56
+ outputPromptAsJson(buildPromptConfig('list', 'oldName', message, choices), createMetadata('category rename', flags));
57
+ return;
58
+ }
59
+ const result = await this.selectFromList({
60
+ message,
61
+ items: customCategories,
62
+ getName: (c) => c.name + (c.description ? ` - ${c.description}` : ''),
63
+ getValue: (c) => c.name,
64
+ getCommand: (c) => `prlt category rename --type ${categoryType} ${c.name}`,
65
+ allowCancel: true,
66
+ });
67
+ if (!result) {
68
+ return;
69
+ }
70
+ oldName = result;
71
+ }
72
+ // Find the category
73
+ const category = await this.storage.getCategoryByName(oldName, categoryType);
74
+ if (!category) {
75
+ this.error(`Category "${oldName}" not found for type "${categoryType}"`);
76
+ }
77
+ if (category.isBuiltin) {
78
+ this.error(`Cannot rename built-in category "${oldName}"`);
79
+ }
80
+ // Prompt for new name if not provided
81
+ if (!newName) {
82
+ const message = `Enter new name for "${oldName}":`;
83
+ if (jsonMode) {
84
+ outputPromptAsJson(buildPromptConfig('input', 'newName', message, []), createMetadata('category rename', { ...flags, oldName }));
85
+ return;
86
+ }
87
+ const { categoryNewName } = await inquirer.prompt([{
88
+ type: 'input',
89
+ name: 'categoryNewName',
90
+ message,
91
+ validate: (input) => {
92
+ if (!input.trim())
93
+ return 'New name is required';
94
+ if (!/^[a-z][a-z0-9-]*$/.test(input.trim())) {
95
+ return 'Category name must start with a letter and contain only lowercase letters, numbers, and hyphens';
96
+ }
97
+ return true;
98
+ },
99
+ }]);
100
+ newName = categoryNewName;
101
+ }
102
+ // At this point newName and oldName should be defined
103
+ if (!newName) {
104
+ this.error('New name is required');
105
+ }
106
+ if (!oldName) {
107
+ this.error('Old name is required');
108
+ }
109
+ // Validate new name format
110
+ if (!/^[a-z][a-z0-9-]*$/.test(newName)) {
111
+ this.error('Category name must start with a letter and contain only lowercase letters, numbers, and hyphens');
112
+ }
113
+ try {
114
+ const updatedCategory = await this.storage.renameCategory(category.id, newName);
115
+ this.log(`\n${styles.success(`Category renamed successfully!`)}`);
116
+ this.log(` Old name: ${oldName}`);
117
+ this.log(` New name: ${styles.emphasis(updatedCategory.name)}`);
118
+ this.log('');
119
+ }
120
+ catch (error) {
121
+ if (error instanceof Error) {
122
+ this.error(error.message);
123
+ }
124
+ throw error;
125
+ }
126
+ }
127
+ }
@@ -50,6 +50,8 @@ export default class Claude extends Command {
50
50
  ];
51
51
  static flags = {
52
52
  json: Flags.boolean({
53
+ char: 'm',
54
+ aliases: ['machine'],
53
55
  description: 'Output prompt configuration as JSON (for AI agents/scripts)',
54
56
  default: false,
55
57
  }),
@@ -191,6 +191,8 @@ export default class Commit extends Command {
191
191
  default: false,
192
192
  }),
193
193
  json: Flags.boolean({
194
+ char: 'm',
195
+ aliases: ['machine'],
194
196
  description: 'Output prompt configuration as JSON (for AI agents/scripts)',
195
197
  default: false,
196
198
  }),
@@ -18,6 +18,8 @@ export default class Config extends Command {
18
18
  ];
19
19
  static flags = {
20
20
  json: Flags.boolean({
21
+ char: 'm',
22
+ aliases: ['machine'],
21
23
  description: 'Output configuration as JSON (for AI agents/scripts)',
22
24
  default: false,
23
25
  }),
@@ -3,7 +3,6 @@ export default class DockerClean extends Command {
3
3
  static description: string;
4
4
  static examples: string[];
5
5
  static flags: {
6
- machine: import("@oclif/core/interfaces").BooleanFlag<boolean>;
7
6
  json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
8
7
  force: import("@oclif/core/interfaces").BooleanFlag<boolean>;
9
8
  'dry-run': import("@oclif/core/interfaces").BooleanFlag<boolean>;
@@ -3,7 +3,6 @@ export default class Docker extends Command {
3
3
  static description: string;
4
4
  static examples: string[];
5
5
  static flags: {
6
- machine: import("@oclif/core/interfaces").BooleanFlag<boolean>;
7
6
  json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
8
7
  };
9
8
  run(): Promise<void>;
@@ -3,7 +3,6 @@ export default class DockerPrune extends Command {
3
3
  static description: string;
4
4
  static examples: string[];
5
5
  static flags: {
6
- machine: import("@oclif/core/interfaces").BooleanFlag<boolean>;
7
6
  json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
8
7
  force: import("@oclif/core/interfaces").BooleanFlag<boolean>;
9
8
  'dry-run': import("@oclif/core/interfaces").BooleanFlag<boolean>;