@proletariat/cli 0.3.20 → 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 (352) 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 +4 -2
  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 +1 -1
  22. package/dist/commands/agent/remove.js +38 -28
  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 +4 -2
  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 +4 -2
  33. package/dist/commands/agent/status.d.ts +0 -1
  34. package/dist/commands/agent/status.js +4 -2
  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/add-names.d.ts +1 -0
  40. package/dist/commands/agent/themes/add-names.js +5 -1
  41. package/dist/commands/agent/themes/index.d.ts +0 -1
  42. package/dist/commands/agent/themes/index.js +3 -7
  43. package/dist/commands/agent/themes/set.d.ts +0 -1
  44. package/dist/commands/agent/themes/set.js +3 -7
  45. package/dist/commands/agent/visit.d.ts +0 -1
  46. package/dist/commands/agent/visit.js +4 -2
  47. package/dist/commands/autocomplete/setup.d.ts +0 -1
  48. package/dist/commands/board/index.d.ts +0 -1
  49. package/dist/commands/board/view.d.ts +0 -1
  50. package/dist/commands/board/watch.d.ts +0 -1
  51. package/dist/commands/branch/create.d.ts +0 -1
  52. package/dist/commands/branch/create.js +2 -0
  53. package/dist/commands/branch/index.d.ts +0 -1
  54. package/dist/commands/branch/index.js +2 -0
  55. package/dist/commands/branch/list.d.ts +0 -1
  56. package/dist/commands/branch/validate.d.ts +0 -1
  57. package/dist/commands/branch/where.d.ts +0 -1
  58. package/dist/commands/branch/where.js +2 -0
  59. package/dist/commands/category/create.d.ts +18 -0
  60. package/dist/commands/category/create.js +108 -0
  61. package/dist/commands/category/delete.d.ts +17 -0
  62. package/dist/commands/category/delete.js +103 -0
  63. package/dist/commands/category/index.d.ts +15 -0
  64. package/dist/commands/category/index.js +87 -0
  65. package/dist/commands/category/list.d.ts +17 -0
  66. package/dist/commands/category/list.js +85 -0
  67. package/dist/commands/category/rename.d.ts +18 -0
  68. package/dist/commands/category/rename.js +127 -0
  69. package/dist/commands/claude.js +2 -0
  70. package/dist/commands/commit.js +2 -0
  71. package/dist/commands/config/index.js +2 -0
  72. package/dist/commands/docker/clean.d.ts +0 -1
  73. package/dist/commands/docker/index.d.ts +0 -1
  74. package/dist/commands/docker/prune.d.ts +0 -1
  75. package/dist/commands/docker/restart.d.ts +0 -1
  76. package/dist/commands/docker/stop.d.ts +0 -1
  77. package/dist/commands/epic/activate.d.ts +0 -1
  78. package/dist/commands/epic/activate.js +2 -0
  79. package/dist/commands/epic/archive.d.ts +0 -1
  80. package/dist/commands/epic/archive.js +2 -0
  81. package/dist/commands/epic/create.d.ts +0 -1
  82. package/dist/commands/epic/create.js +3 -1
  83. package/dist/commands/epic/delete.d.ts +14 -0
  84. package/dist/commands/epic/delete.js +129 -0
  85. package/dist/commands/epic/index.d.ts +0 -1
  86. package/dist/commands/epic/index.js +6 -0
  87. package/dist/commands/epic/link/block.d.ts +0 -1
  88. package/dist/commands/epic/link/block.js +2 -0
  89. package/dist/commands/epic/link/duplicates.d.ts +0 -1
  90. package/dist/commands/epic/link/duplicates.js +2 -0
  91. package/dist/commands/epic/link/index.d.ts +0 -1
  92. package/dist/commands/epic/link/index.js +19 -0
  93. package/dist/commands/epic/link/relates.d.ts +0 -1
  94. package/dist/commands/epic/link/relates.js +2 -0
  95. package/dist/commands/epic/link/remove.d.ts +0 -1
  96. package/dist/commands/epic/link/remove.js +2 -0
  97. package/dist/commands/epic/list.d.ts +0 -1
  98. package/dist/commands/epic/move.d.ts +0 -1
  99. package/dist/commands/epic/move.js +2 -0
  100. package/dist/commands/epic/progress.d.ts +0 -1
  101. package/dist/commands/epic/progress.js +2 -0
  102. package/dist/commands/epic/project.d.ts +0 -1
  103. package/dist/commands/epic/project.js +2 -0
  104. package/dist/commands/epic/reorder.d.ts +0 -1
  105. package/dist/commands/epic/reorder.js +2 -0
  106. package/dist/commands/epic/spec.d.ts +0 -1
  107. package/dist/commands/epic/spec.js +2 -0
  108. package/dist/commands/epic/ticket.d.ts +0 -1
  109. package/dist/commands/epic/ticket.js +2 -0
  110. package/dist/commands/epic/view.d.ts +0 -1
  111. package/dist/commands/epic/view.js +2 -0
  112. package/dist/commands/execution/config.d.ts +0 -1
  113. package/dist/commands/execution/config.js +24 -0
  114. package/dist/commands/execution/index.d.ts +0 -1
  115. package/dist/commands/execution/index.js +3 -1
  116. package/dist/commands/execution/kill.d.ts +3 -0
  117. package/dist/commands/execution/kill.js +1 -0
  118. package/dist/commands/execution/list.d.ts +0 -1
  119. package/dist/commands/execution/list.js +5 -4
  120. package/dist/commands/execution/logs.d.ts +0 -1
  121. package/dist/commands/execution/logs.js +4 -1
  122. package/dist/commands/execution/stop.d.ts +0 -1
  123. package/dist/commands/execution/stop.js +3 -1
  124. package/dist/commands/execution/view.d.ts +0 -1
  125. package/dist/commands/execution/view.js +3 -1
  126. package/dist/commands/gh/index.d.ts +0 -1
  127. package/dist/commands/gh/login.d.ts +0 -1
  128. package/dist/commands/gh/status.d.ts +0 -1
  129. package/dist/commands/gh/token.d.ts +0 -1
  130. package/dist/commands/init.js +2 -0
  131. package/dist/commands/phase/create.d.ts +0 -1
  132. package/dist/commands/phase/create.js +1 -2
  133. package/dist/commands/phase/delete.d.ts +0 -1
  134. package/dist/commands/phase/delete.js +1 -1
  135. package/dist/commands/phase/list.d.ts +0 -1
  136. package/dist/commands/phase/move.d.ts +0 -1
  137. package/dist/commands/phase/move.js +10 -2
  138. package/dist/commands/phase/template/apply.d.ts +0 -1
  139. package/dist/commands/phase/template/apply.js +4 -2
  140. package/dist/commands/phase/template/create.d.ts +0 -1
  141. package/dist/commands/phase/template/create.js +6 -7
  142. package/dist/commands/phase/template/delete.d.ts +0 -1
  143. package/dist/commands/phase/template/delete.js +2 -0
  144. package/dist/commands/phase/template/index.d.ts +0 -1
  145. package/dist/commands/phase/template/index.js +2 -0
  146. package/dist/commands/phase/template/list.d.ts +0 -1
  147. package/dist/commands/phase/template/list.js +3 -1
  148. package/dist/commands/phase/template/update.d.ts +0 -1
  149. package/dist/commands/phase/update.d.ts +0 -1
  150. package/dist/commands/phase/update.js +2 -2
  151. package/dist/commands/pmo/init.js +2 -0
  152. package/dist/commands/pr/create.d.ts +0 -1
  153. package/dist/commands/pr/index.d.ts +0 -1
  154. package/dist/commands/pr/link.d.ts +0 -1
  155. package/dist/commands/pr/list.d.ts +0 -1
  156. package/dist/commands/pr/status.d.ts +0 -1
  157. package/dist/commands/project/archive.d.ts +0 -1
  158. package/dist/commands/project/create.d.ts +0 -1
  159. package/dist/commands/project/delete.d.ts +0 -1
  160. package/dist/commands/project/index.d.ts +0 -1
  161. package/dist/commands/project/list.d.ts +0 -1
  162. package/dist/commands/project/spec.d.ts +0 -1
  163. package/dist/commands/project/unarchive.d.ts +0 -1
  164. package/dist/commands/project/update.d.ts +0 -1
  165. package/dist/commands/project/view.d.ts +0 -1
  166. package/dist/commands/repo/add.d.ts +0 -1
  167. package/dist/commands/repo/add.js +2 -0
  168. package/dist/commands/repo/index.d.ts +0 -1
  169. package/dist/commands/repo/list.d.ts +0 -1
  170. package/dist/commands/repo/remove.d.ts +0 -1
  171. package/dist/commands/repo/view.d.ts +0 -1
  172. package/dist/commands/roadmap/add-project.d.ts +0 -1
  173. package/dist/commands/roadmap/add-project.js +2 -0
  174. package/dist/commands/roadmap/create.d.ts +0 -1
  175. package/dist/commands/roadmap/create.js +2 -0
  176. package/dist/commands/roadmap/delete.d.ts +0 -1
  177. package/dist/commands/roadmap/delete.js +12 -1
  178. package/dist/commands/roadmap/generate.d.ts +0 -1
  179. package/dist/commands/roadmap/generate.js +2 -0
  180. package/dist/commands/roadmap/index.d.ts +0 -1
  181. package/dist/commands/roadmap/index.js +2 -0
  182. package/dist/commands/roadmap/list.d.ts +0 -1
  183. package/dist/commands/roadmap/remove-project.d.ts +0 -1
  184. package/dist/commands/roadmap/remove-project.js +2 -0
  185. package/dist/commands/roadmap/reorder.d.ts +0 -1
  186. package/dist/commands/roadmap/reorder.js +2 -0
  187. package/dist/commands/roadmap/update.d.ts +0 -1
  188. package/dist/commands/roadmap/update.js +2 -0
  189. package/dist/commands/roadmap/view.d.ts +0 -1
  190. package/dist/commands/roadmap/view.js +2 -0
  191. package/dist/commands/session/attach.d.ts +0 -1
  192. package/dist/commands/session/attach.js +9 -0
  193. package/dist/commands/session/index.d.ts +0 -1
  194. package/dist/commands/session/index.js +2 -0
  195. package/dist/commands/session/list.d.ts +0 -1
  196. package/dist/commands/spec/create.d.ts +0 -1
  197. package/dist/commands/spec/create.js +1 -1
  198. package/dist/commands/spec/delete.d.ts +0 -1
  199. package/dist/commands/spec/edit.d.ts +0 -1
  200. package/dist/commands/spec/index.d.ts +0 -1
  201. package/dist/commands/spec/link/depends.d.ts +0 -1
  202. package/dist/commands/spec/link/duplicates.d.ts +0 -1
  203. package/dist/commands/spec/link/index.d.ts +0 -1
  204. package/dist/commands/spec/link/relates.d.ts +0 -1
  205. package/dist/commands/spec/link/remove.d.ts +0 -1
  206. package/dist/commands/spec/list.d.ts +0 -1
  207. package/dist/commands/spec/plan.d.ts +0 -1
  208. package/dist/commands/spec/ticket.d.ts +0 -3
  209. package/dist/commands/spec/ticket.js +7 -38
  210. package/dist/commands/spec/view.d.ts +0 -1
  211. package/dist/commands/status/category.d.ts +14 -0
  212. package/dist/commands/status/category.js +63 -0
  213. package/dist/commands/status/create.d.ts +0 -1
  214. package/dist/commands/status/create.js +1 -1
  215. package/dist/commands/status/delete.d.ts +0 -1
  216. package/dist/commands/status/index.d.ts +0 -1
  217. package/dist/commands/status/list.d.ts +0 -1
  218. package/dist/commands/status/list.js +5 -3
  219. package/dist/commands/status/move.d.ts +0 -1
  220. package/dist/commands/status/update.d.ts +0 -1
  221. package/dist/commands/template/delete.d.ts +0 -1
  222. package/dist/commands/template/delete.js +2 -0
  223. package/dist/commands/template/index.d.ts +0 -1
  224. package/dist/commands/template/list.d.ts +0 -1
  225. package/dist/commands/template/list.js +2 -0
  226. package/dist/commands/template/phase/apply.js +2 -0
  227. package/dist/commands/template/phase/create.d.ts +0 -1
  228. package/dist/commands/template/phase/create.js +3 -9
  229. package/dist/commands/template/phase/delete.js +2 -0
  230. package/dist/commands/template/phase/index.d.ts +0 -1
  231. package/dist/commands/template/phase/index.js +4 -4
  232. package/dist/commands/template/phase/list.js +2 -0
  233. package/dist/commands/template/phase/update.js +2 -0
  234. package/dist/commands/template/ticket/apply.js +2 -0
  235. package/dist/commands/template/ticket/create.js +2 -0
  236. package/dist/commands/template/ticket/delete.d.ts +1 -1
  237. package/dist/commands/template/ticket/delete.js +6 -2
  238. package/dist/commands/template/ticket/index.d.ts +0 -1
  239. package/dist/commands/template/ticket/list.js +2 -0
  240. package/dist/commands/template/ticket/save.d.ts +0 -1
  241. package/dist/commands/template/ticket/save.js +0 -6
  242. package/dist/commands/terminal/title.d.ts +0 -1
  243. package/dist/commands/ticket/bulk.d.ts +0 -1
  244. package/dist/commands/ticket/bulk.js +2 -0
  245. package/dist/commands/ticket/category.d.ts +14 -0
  246. package/dist/commands/ticket/category.js +63 -0
  247. package/dist/commands/ticket/complete.d.ts +0 -1
  248. package/dist/commands/ticket/complete.js +2 -0
  249. package/dist/commands/ticket/create.d.ts +0 -1
  250. package/dist/commands/ticket/create.js +7 -5
  251. package/dist/commands/ticket/delete.d.ts +0 -1
  252. package/dist/commands/ticket/delete.js +2 -0
  253. package/dist/commands/ticket/edit.d.ts +0 -1
  254. package/dist/commands/ticket/edit.js +5 -3
  255. package/dist/commands/ticket/epic.d.ts +0 -1
  256. package/dist/commands/ticket/epic.js +2 -0
  257. package/dist/commands/ticket/index.d.ts +0 -1
  258. package/dist/commands/ticket/index.js +2 -0
  259. package/dist/commands/ticket/link/block.d.ts +0 -1
  260. package/dist/commands/ticket/link/block.js +2 -0
  261. package/dist/commands/ticket/link/duplicates.d.ts +0 -1
  262. package/dist/commands/ticket/link/duplicates.js +2 -0
  263. package/dist/commands/ticket/link/index.d.ts +0 -1
  264. package/dist/commands/ticket/link/index.js +2 -0
  265. package/dist/commands/ticket/link/relates.d.ts +0 -1
  266. package/dist/commands/ticket/link/relates.js +2 -0
  267. package/dist/commands/ticket/link/remove.d.ts +0 -1
  268. package/dist/commands/ticket/link/remove.js +2 -0
  269. package/dist/commands/ticket/list.d.ts +2 -1
  270. package/dist/commands/ticket/list.js +39 -2
  271. package/dist/commands/ticket/move.d.ts +0 -1
  272. package/dist/commands/ticket/move.js +2 -0
  273. package/dist/commands/ticket/project.d.ts +0 -1
  274. package/dist/commands/ticket/project.js +2 -0
  275. package/dist/commands/ticket/reassign.d.ts +0 -1
  276. package/dist/commands/ticket/reassign.js +29 -0
  277. package/dist/commands/ticket/spec.d.ts +0 -1
  278. package/dist/commands/ticket/spec.js +2 -0
  279. package/dist/commands/ticket/status.d.ts +0 -1
  280. package/dist/commands/ticket/status.js +2 -0
  281. package/dist/commands/ticket/template/apply.d.ts +0 -1
  282. package/dist/commands/ticket/template/apply.js +2 -0
  283. package/dist/commands/ticket/template/create.d.ts +0 -1
  284. package/dist/commands/ticket/template/create.js +4 -2
  285. package/dist/commands/ticket/template/delete.d.ts +0 -1
  286. package/dist/commands/ticket/template/delete.js +2 -0
  287. package/dist/commands/ticket/template/index.d.ts +0 -1
  288. package/dist/commands/ticket/template/index.js +2 -0
  289. package/dist/commands/ticket/template/list.d.ts +0 -1
  290. package/dist/commands/ticket/template/list.js +2 -0
  291. package/dist/commands/ticket/template/save.d.ts +0 -1
  292. package/dist/commands/ticket/template/save.js +2 -0
  293. package/dist/commands/ticket/update.d.ts +0 -1
  294. package/dist/commands/ticket/update.js +4 -2
  295. package/dist/commands/ticket/view.d.ts +0 -1
  296. package/dist/commands/ticket/view.js +2 -0
  297. package/dist/commands/work/complete.d.ts +0 -1
  298. package/dist/commands/work/complete.js +2 -0
  299. package/dist/commands/work/index.d.ts +0 -1
  300. package/dist/commands/work/index.js +2 -0
  301. package/dist/commands/work/ready.d.ts +1 -2
  302. package/dist/commands/work/ready.js +11 -5
  303. package/dist/commands/work/revise.d.ts +0 -1
  304. package/dist/commands/work/revise.js +3 -1
  305. package/dist/commands/work/spawn-all.d.ts +0 -1
  306. package/dist/commands/work/spawn-all.js +2 -0
  307. package/dist/commands/work/spawn.d.ts +0 -1
  308. package/dist/commands/work/spawn.js +34 -8
  309. package/dist/commands/work/start.d.ts +0 -1
  310. package/dist/commands/work/start.js +6 -0
  311. package/dist/commands/work/watch.d.ts +0 -1
  312. package/dist/commands/work/watch.js +5 -1
  313. package/dist/commands/workflow/create.d.ts +0 -1
  314. package/dist/commands/workflow/delete.d.ts +0 -1
  315. package/dist/commands/workflow/index.d.ts +0 -1
  316. package/dist/commands/workflow/index.js +2 -0
  317. package/dist/commands/workflow/list.d.ts +0 -1
  318. package/dist/commands/workflow/switch.d.ts +0 -1
  319. package/dist/commands/workflow/view.d.ts +0 -1
  320. package/dist/commands/workspace/list.js +2 -0
  321. package/dist/commands/workspace/prune.d.ts +13 -0
  322. package/dist/commands/workspace/prune.js +186 -0
  323. package/dist/commands/workspace/remove.js +2 -0
  324. package/dist/commands/workspace/use.js +2 -0
  325. package/dist/lib/agents/commands.d.ts +7 -0
  326. package/dist/lib/agents/commands.js +11 -0
  327. package/dist/lib/execution/runners.js +1 -2
  328. package/dist/lib/pmo/base-command.d.ts +2 -4
  329. package/dist/lib/pmo/base-command.js +8 -10
  330. package/dist/lib/pmo/schema.d.ts +2 -0
  331. package/dist/lib/pmo/schema.js +17 -0
  332. package/dist/lib/pmo/storage/base.d.ts +4 -0
  333. package/dist/lib/pmo/storage/base.js +31 -0
  334. package/dist/lib/pmo/storage/categories.d.ts +50 -0
  335. package/dist/lib/pmo/storage/categories.js +205 -0
  336. package/dist/lib/pmo/storage/epics.js +20 -10
  337. package/dist/lib/pmo/storage/helpers.d.ts +10 -0
  338. package/dist/lib/pmo/storage/helpers.js +59 -1
  339. package/dist/lib/pmo/storage/index.d.ts +14 -1
  340. package/dist/lib/pmo/storage/index.js +35 -1
  341. package/dist/lib/pmo/storage/projects.js +20 -8
  342. package/dist/lib/pmo/storage/specs.js +23 -13
  343. package/dist/lib/pmo/storage/statuses.js +39 -18
  344. package/dist/lib/pmo/storage/subtasks.js +19 -8
  345. package/dist/lib/pmo/storage/tickets.d.ts +5 -0
  346. package/dist/lib/pmo/storage/tickets.js +57 -17
  347. package/dist/lib/pmo/storage/types.d.ts +10 -0
  348. package/dist/lib/pmo/types.d.ts +25 -0
  349. package/dist/lib/prompt-json.d.ts +10 -16
  350. package/dist/lib/prompt-json.js +8 -16
  351. package/oclif.manifest.json +3831 -3864
  352. package/package.json +1 -1
@@ -5,6 +5,7 @@ import { randomUUID } from 'node:crypto';
5
5
  import { PMO_TABLES } from '../schema.js';
6
6
  import { PMOError } from '../types.js';
7
7
  import { slugify } from '../utils.js';
8
+ import { wrapSqliteError } from './helpers.js';
8
9
  const T = PMO_TABLES;
9
10
  export class SubtaskStorage {
10
11
  ctx;
@@ -42,10 +43,15 @@ export class SubtaskStorage {
42
43
  id = `${baseId}-${counter}`;
43
44
  }
44
45
  const position = maxPos.max_pos + 1;
45
- this.ctx.db.prepare(`
46
- INSERT INTO ${T.subtasks} (id, ticket_id, title, done, position)
47
- VALUES (?, ?, ?, 0, ?)
48
- `).run(id, ticketId, title, position);
46
+ try {
47
+ this.ctx.db.prepare(`
48
+ INSERT INTO ${T.subtasks} (id, ticket_id, title, done, position)
49
+ VALUES (?, ?, ?, 0, ?)
50
+ `).run(id, ticketId, title, position);
51
+ }
52
+ catch (err) {
53
+ wrapSqliteError('Subtask', 'create', err);
54
+ }
49
55
  // Update ticket timestamp
50
56
  this.ctx.db.prepare(`
51
57
  UPDATE ${T.tickets} SET updated_at = ? WHERE id = ?
@@ -139,10 +145,15 @@ export class AcceptanceCriteriaStorage {
139
145
  // Use UUID to guarantee uniqueness even when multiple ACs are added in the same millisecond
140
146
  const id = `ac-${randomUUID()}`;
141
147
  const position = maxPos.max_pos + 1;
142
- this.ctx.db.prepare(`
143
- INSERT INTO ${T.ticket_acceptance_criteria} (id, ticket_id, criterion, verifiable, verified, position)
144
- VALUES (?, ?, ?, 1, 0, ?)
145
- `).run(id, ticketId, criterion, position);
148
+ try {
149
+ this.ctx.db.prepare(`
150
+ INSERT INTO ${T.ticket_acceptance_criteria} (id, ticket_id, criterion, verifiable, verified, position)
151
+ VALUES (?, ?, ?, 1, 0, ?)
152
+ `).run(id, ticketId, criterion, position);
153
+ }
154
+ catch (err) {
155
+ wrapSqliteError('Acceptance criterion', 'create', err);
156
+ }
146
157
  this.ctx.db.prepare(`
147
158
  UPDATE ${T.tickets} SET updated_at = ? WHERE id = ?
148
159
  `).run(Date.now(), ticketId);
@@ -8,6 +8,11 @@ import { StorageContext } from './types.js';
8
8
  export declare class TicketStorage {
9
9
  private ctx;
10
10
  constructor(ctx: StorageContext);
11
+ /**
12
+ * Validate a category against the DB.
13
+ * Returns the valid category name if found, throws error if invalid.
14
+ */
15
+ private validateCategory;
11
16
  /**
12
17
  * Resolve a project identifier to its actual ID.
13
18
  * Tries multiple strategies:
@@ -6,13 +6,34 @@
6
6
  import { PMO_TABLES } from '../schema.js';
7
7
  import { PMOError } from '../types.js';
8
8
  import { slugify, generateEntityId } from '../utils.js';
9
- import { rowToTicket } from './helpers.js';
9
+ import { rowToTicket, wrapSqliteError } from './helpers.js';
10
10
  const T = PMO_TABLES;
11
11
  export class TicketStorage {
12
12
  ctx;
13
13
  constructor(ctx) {
14
14
  this.ctx = ctx;
15
15
  }
16
+ /**
17
+ * Validate a category against the DB.
18
+ * Returns the valid category name if found, throws error if invalid.
19
+ */
20
+ async validateCategory(category) {
21
+ if (!category)
22
+ return null;
23
+ // Check if category exists in DB for ticket type
24
+ const row = this.ctx.db.prepare(`
25
+ SELECT name FROM ${T.categories} WHERE LOWER(name) = LOWER(?) AND type = 'ticket'
26
+ `).get(category);
27
+ if (!row) {
28
+ // Get valid categories for error message
29
+ const validCategories = this.ctx.db.prepare(`
30
+ SELECT name FROM ${T.categories} WHERE type = 'ticket' ORDER BY position
31
+ `).all();
32
+ const validNames = validCategories.map(c => c.name).join(', ');
33
+ throw new PMOError('INVALID', `Invalid category "${category}". Valid categories: ${validNames}`);
34
+ }
35
+ return row.name;
36
+ }
16
37
  /**
17
38
  * Resolve a project identifier to its actual ID.
18
39
  * Tries multiple strategies:
@@ -71,6 +92,8 @@ export class TicketStorage {
71
92
  const title = ticket.title || 'Untitled';
72
93
  const now = Date.now();
73
94
  const specId = ticket.specId || null;
95
+ // Validate category against DB
96
+ const validatedCategory = await this.validateCategory(ticket.category);
74
97
  // Get status_id from project's workflow
75
98
  let statusId = ticket.statusId;
76
99
  // Get the project's workflow
@@ -126,14 +149,19 @@ export class TicketStorage {
126
149
  }
127
150
  // Insert ticket
128
151
  const labels = ticket.labels || [];
129
- this.ctx.db.prepare(`
130
- INSERT INTO ${T.tickets} (
131
- id, project_id, title, description, priority, category,
132
- status_id, owner, assignee, spec_id, epic_id, labels,
133
- created_at, updated_at, last_synced_from_spec, last_synced_from_board
134
- )
135
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
136
- `).run(id, projectId, title, ticket.description || null, ticket.priority || null, ticket.category || null, statusId, ticket.owner || null, ticket.assignee || null, specId, ticket.epicId || null, JSON.stringify(labels), now, now, ticket.lastSyncedFromSpec || null, ticket.lastSyncedFromBoard || null);
152
+ try {
153
+ this.ctx.db.prepare(`
154
+ INSERT INTO ${T.tickets} (
155
+ id, project_id, title, description, priority, category,
156
+ status_id, owner, assignee, spec_id, epic_id, labels,
157
+ created_at, updated_at, last_synced_from_spec, last_synced_from_board
158
+ )
159
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
160
+ `).run(id, projectId, title, ticket.description || null, ticket.priority || null, validatedCategory, statusId, ticket.owner || null, ticket.assignee || null, specId, ticket.epicId || null, JSON.stringify(labels), now, now, ticket.lastSyncedFromSpec || null, ticket.lastSyncedFromBoard || null);
161
+ }
162
+ catch (err) {
163
+ wrapSqliteError('Ticket', 'create', err);
164
+ }
137
165
  // Insert subtasks
138
166
  if (ticket.subtasks && ticket.subtasks.length > 0) {
139
167
  const insertSubtask = this.ctx.db.prepare(`
@@ -191,6 +219,11 @@ export class TicketStorage {
191
219
  if (!existing) {
192
220
  throw new PMOError('NOT_FOUND', `Ticket not found: ${id}`, id);
193
221
  }
222
+ // Validate category if being updated
223
+ let validatedCategory;
224
+ if (changes.category !== undefined) {
225
+ validatedCategory = await this.validateCategory(changes.category);
226
+ }
194
227
  const updates = [];
195
228
  const params = [];
196
229
  if (changes.title !== undefined) {
@@ -205,9 +238,9 @@ export class TicketStorage {
205
238
  updates.push('priority = ?');
206
239
  params.push(changes.priority);
207
240
  }
208
- if (changes.category !== undefined) {
241
+ if (validatedCategory !== undefined) {
209
242
  updates.push('category = ?');
210
- params.push(changes.category);
243
+ params.push(validatedCategory);
211
244
  }
212
245
  if (changes.statusId !== undefined) {
213
246
  updates.push('status_id = ?');
@@ -335,12 +368,19 @@ export class TicketStorage {
335
368
  }
336
369
  // Delete ticket (by ID only, since IDs are globally unique)
337
370
  // Related data (subtasks, metadata) are deleted via CASCADE
338
- const result = this.ctx.db.prepare(`
339
- DELETE FROM ${T.tickets}
340
- WHERE id = ?
341
- `).run(id);
342
- if (result.changes === 0) {
343
- throw new PMOError('NOT_FOUND', `Ticket not found: ${id}`, id);
371
+ try {
372
+ const result = this.ctx.db.prepare(`
373
+ DELETE FROM ${T.tickets}
374
+ WHERE id = ?
375
+ `).run(id);
376
+ if (result.changes === 0) {
377
+ throw new PMOError('NOT_FOUND', `Ticket not found: ${id}`, id);
378
+ }
379
+ }
380
+ catch (err) {
381
+ if (err instanceof PMOError)
382
+ throw err;
383
+ wrapSqliteError('Ticket', 'delete', err);
344
384
  }
345
385
  // Update board timestamp for the ticket's project
346
386
  this.updateProjectTimestamp(ticketProjectId);
@@ -216,3 +216,13 @@ export interface RoadmapProjectRow {
216
216
  position: number;
217
217
  created_at: string;
218
218
  }
219
+ export interface CategoryRow {
220
+ id: string;
221
+ name: string;
222
+ type: string;
223
+ description: string | null;
224
+ color: string | null;
225
+ position: number;
226
+ is_builtin: number;
227
+ created_at: string;
228
+ }
@@ -83,6 +83,31 @@ export declare const LEGACY_PRIORITY_MAP: Record<LegacyPriority, Priority>;
83
83
  */
84
84
  export declare const TICKET_CATEGORIES: readonly ["feature", "bug", "refactor", "docs", "test", "chore", "performance", "ci", "build", "security", "database", "release"];
85
85
  export type TicketCategory = typeof TICKET_CATEGORIES[number];
86
+ /**
87
+ * Category types (ticket vs status).
88
+ */
89
+ export type CategoryType = 'ticket' | 'status';
90
+ /**
91
+ * Category record for ticket or status classification.
92
+ */
93
+ export interface Category {
94
+ id: string;
95
+ name: string;
96
+ type: CategoryType;
97
+ description?: string;
98
+ color?: string;
99
+ position: number;
100
+ isBuiltin: boolean;
101
+ createdAt: Date;
102
+ }
103
+ /**
104
+ * Filter options for listing categories.
105
+ */
106
+ export interface CategoryFilter {
107
+ type?: CategoryType;
108
+ isBuiltin?: boolean;
109
+ search?: string;
110
+ }
86
111
  /**
87
112
  * Check if a string is a valid Priority value.
88
113
  */
@@ -128,20 +128,17 @@ export interface ErrorJsonOutput {
128
128
  */
129
129
  export type JsonOutput = PromptJsonOutput | SuccessJsonOutput | ErrorJsonOutput;
130
130
  /**
131
- * Flags interface for JSON mode detection (legacy)
132
- * @deprecated Use MachineOutputFlags instead
131
+ * Flags interface for JSON mode detection
133
132
  */
134
133
  export interface JsonFlags {
135
134
  json?: boolean;
136
135
  }
137
136
  /**
138
137
  * Flags interface for machine-readable output mode detection
139
- * Supports both new --machine format and legacy --json boolean
138
+ * --json is the primary flag, -m/--machine are aliases that set json=true
140
139
  */
141
140
  export interface MachineOutputFlags {
142
- /** New format: --machine (enables machine-readable JSON output for AI agents) */
143
- machine?: boolean;
144
- /** Legacy format: --json (deprecated, use --machine instead) */
141
+ /** Primary JSON output flag. -m and --machine are aliases to this flag */
145
142
  json?: boolean;
146
143
  }
147
144
  /**
@@ -154,16 +151,13 @@ export declare function isNonTTY(): boolean;
154
151
  * Determine if JSON output mode is active (for AI agents)
155
152
  *
156
153
  * Returns true if:
157
- * - The --machine flag is explicitly set
158
- * - The --json flag is explicitly set
154
+ * - The --json flag is set (or -m/--machine aliases)
159
155
  * - The environment is non-TTY (piped output)
160
156
  *
161
157
  * @param flags - Command flags object
162
158
  * @returns true if JSON mode should be used
163
159
  */
164
- export declare function shouldOutputJson(flags: JsonFlags & {
165
- machine?: boolean;
166
- }): boolean;
160
+ export declare function shouldOutputJson(flags: JsonFlags): boolean;
167
161
  /**
168
162
  * Alias for shouldOutputJson - clearer name for agent-focused code
169
163
  */
@@ -172,8 +166,7 @@ export declare const isAgentMode: typeof shouldOutputJson;
172
166
  * Determine if machine-readable output mode is active (for AI agents/scripts)
173
167
  *
174
168
  * Returns true if:
175
- * - The --machine flag is set
176
- * - The --json flag is explicitly set (legacy support)
169
+ * - The --json flag is set (or -m/--machine aliases)
177
170
  * - The environment is non-TTY (piped output)
178
171
  *
179
172
  * @param flags - Command flags object
@@ -200,15 +193,16 @@ export declare function createMetadata(command: string, flags: Record<string, un
200
193
  */
201
194
  export declare function outputPromptAsJson(config: PromptConfig, metadata: OutputMetadata): never;
202
195
  /**
203
- * Output success result as JSON
196
+ * Output success result as JSON and exit
204
197
  *
205
198
  * Use this when all required data was provided via flags
206
- * and no prompt is needed.
199
+ * and no prompt is needed. Exits with EXIT_SUCCESS (0) to signal
200
+ * successful command completion.
207
201
  *
208
202
  * @param result - Command-specific result data
209
203
  * @param metadata - Command metadata
210
204
  */
211
- export declare function outputSuccessAsJson(result: Record<string, unknown>, metadata: OutputMetadata): void;
205
+ export declare function outputSuccessAsJson(result: Record<string, unknown>, metadata: OutputMetadata): never;
212
206
  /**
213
207
  * Output error as JSON and exit
214
208
  *
@@ -41,19 +41,14 @@ export function isNonTTY() {
41
41
  * Determine if JSON output mode is active (for AI agents)
42
42
  *
43
43
  * Returns true if:
44
- * - The --machine flag is explicitly set
45
- * - The --json flag is explicitly set
44
+ * - The --json flag is set (or -m/--machine aliases)
46
45
  * - The environment is non-TTY (piped output)
47
46
  *
48
47
  * @param flags - Command flags object
49
48
  * @returns true if JSON mode should be used
50
49
  */
51
50
  export function shouldOutputJson(flags) {
52
- // New --machine flag
53
- if (flags.machine === true) {
54
- return true;
55
- }
56
- // Legacy --json flag
51
+ // --json flag (includes -m and --machine aliases)
57
52
  if (flags.json === true) {
58
53
  return true;
59
54
  }
@@ -68,19 +63,14 @@ export const isAgentMode = shouldOutputJson;
68
63
  * Determine if machine-readable output mode is active (for AI agents/scripts)
69
64
  *
70
65
  * Returns true if:
71
- * - The --machine flag is set
72
- * - The --json flag is explicitly set (legacy support)
66
+ * - The --json flag is set (or -m/--machine aliases)
73
67
  * - The environment is non-TTY (piped output)
74
68
  *
75
69
  * @param flags - Command flags object
76
70
  * @returns true if machine-readable output mode should be used
77
71
  */
78
72
  export function isMachineOutput(flags) {
79
- // New --machine flag takes precedence
80
- if (flags.machine === true) {
81
- return true;
82
- }
83
- // Legacy --json flag support
73
+ // --json flag (includes -m and --machine aliases)
84
74
  if (flags.json === true) {
85
75
  return true;
86
76
  }
@@ -128,10 +118,11 @@ export function outputPromptAsJson(config, metadata) {
128
118
  process.exit(EXIT_NEEDS_INPUT);
129
119
  }
130
120
  /**
131
- * Output success result as JSON
121
+ * Output success result as JSON and exit
132
122
  *
133
123
  * Use this when all required data was provided via flags
134
- * and no prompt is needed.
124
+ * and no prompt is needed. Exits with EXIT_SUCCESS (0) to signal
125
+ * successful command completion.
135
126
  *
136
127
  * @param result - Command-specific result data
137
128
  * @param metadata - Command metadata
@@ -144,6 +135,7 @@ export function outputSuccessAsJson(result, metadata) {
144
135
  metadata,
145
136
  };
146
137
  console.log(JSON.stringify(output, null, 2));
138
+ process.exit(EXIT_SUCCESS);
147
139
  }
148
140
  /**
149
141
  * Output error as JSON and exit