@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
@@ -0,0 +1,313 @@
1
+ /**
2
+ * FlagResolver - Unified flag resolution for human and machine interactive modes
3
+ *
4
+ * This abstraction unifies the two interaction patterns in the CLI:
5
+ * - Human interactive mode: Uses inquirer prompts, collects input, returns flags
6
+ * - Machine/JSON mode: Outputs prompt schema as JSON, exits for agent to process
7
+ *
8
+ * Both modes use the same underlying pattern: prompts PRODUCE flags.
9
+ * The execution logic only sees flags, not prompt results.
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * // Define prompts for missing flags
14
+ * const resolver = new FlagResolver({
15
+ * commandName: 'ticket create',
16
+ * baseCommand: 'prlt ticket create',
17
+ * jsonMode: shouldOutputJson(flags),
18
+ * flags,
19
+ * });
20
+ *
21
+ * // Add prompts - they execute in order, can depend on previously resolved flags
22
+ * resolver.addPrompt({
23
+ * flagName: 'column',
24
+ * type: 'list',
25
+ * message: 'Select column:',
26
+ * choices: async () => columns.map(c => ({ name: c, value: c })),
27
+ * });
28
+ *
29
+ * resolver.addPrompt({
30
+ * flagName: 'title',
31
+ * type: 'input',
32
+ * message: 'Enter title:',
33
+ * when: (ctx) => ctx.flags.column !== undefined, // Only after column is selected
34
+ * });
35
+ *
36
+ * // Resolve all missing flags
37
+ * const resolved = await resolver.resolve();
38
+ * // resolved.column and resolved.title are now guaranteed to have values
39
+ * ```
40
+ */
41
+ import inquirer from 'inquirer';
42
+ import { outputPromptAsJson, createMetadata, } from '../prompt-json.js';
43
+ /**
44
+ * FlagResolver handles unified flag resolution for both human and machine modes.
45
+ *
46
+ * Usage pattern:
47
+ * 1. Create resolver with command info and current flags
48
+ * 2. Add prompt definitions for flags that may need resolution
49
+ * 3. Call resolve() to get complete flags
50
+ *
51
+ * In JSON mode, resolve() outputs the first unresolved prompt and exits.
52
+ * In interactive mode, resolve() prompts for each unresolved flag sequentially.
53
+ */
54
+ export class FlagResolver {
55
+ prompts = [];
56
+ options;
57
+ resolvedFlags;
58
+ resolverContext;
59
+ constructor(options) {
60
+ this.options = options;
61
+ this.resolvedFlags = { ...options.flags };
62
+ this.resolverContext = {
63
+ flags: this.resolvedFlags,
64
+ args: options.args || {},
65
+ commandName: options.commandName,
66
+ baseCommand: options.baseCommand,
67
+ ...options.context,
68
+ };
69
+ }
70
+ /**
71
+ * Add a prompt definition for resolving a flag.
72
+ * Prompts are processed in the order they are added.
73
+ */
74
+ addPrompt(prompt) {
75
+ this.prompts.push(prompt);
76
+ return this;
77
+ }
78
+ /**
79
+ * Add multiple prompt definitions at once.
80
+ */
81
+ addPrompts(prompts) {
82
+ for (const prompt of prompts) {
83
+ this.prompts.push(prompt);
84
+ }
85
+ return this;
86
+ }
87
+ /**
88
+ * Update the context with additional data.
89
+ * Useful for adding computed values that prompts might need.
90
+ */
91
+ setContext(key, value) {
92
+ this.resolverContext[key] = value;
93
+ return this;
94
+ }
95
+ /**
96
+ * Get current context value
97
+ */
98
+ getContext(key) {
99
+ return this.resolverContext[key];
100
+ }
101
+ /**
102
+ * Check if a flag has a value (not undefined)
103
+ */
104
+ hasFlag(flagName) {
105
+ return this.resolvedFlags[flagName] !== undefined;
106
+ }
107
+ /**
108
+ * Get current flag value
109
+ */
110
+ getFlag(flagName) {
111
+ return this.resolvedFlags[flagName];
112
+ }
113
+ /**
114
+ * Set a flag value directly (bypasses prompting)
115
+ */
116
+ setFlag(flagName, value) {
117
+ this.resolvedFlags[flagName] = value;
118
+ this.resolverContext.flags = this.resolvedFlags;
119
+ return this;
120
+ }
121
+ /**
122
+ * Resolve all prompts and return complete flags.
123
+ *
124
+ * In JSON mode: outputs the first unresolved prompt as JSON and exits (never returns).
125
+ * In interactive mode: prompts for each unresolved flag and returns all flags.
126
+ *
127
+ * @returns The fully resolved flags
128
+ */
129
+ async resolve() {
130
+ for (const prompt of this.prompts) {
131
+ // Check if flag already has a value
132
+ const currentValue = this.resolvedFlags[prompt.flagName];
133
+ if (currentValue !== undefined) {
134
+ continue;
135
+ }
136
+ // Check conditional
137
+ if (prompt.when && !prompt.when(this.resolverContext)) {
138
+ continue;
139
+ }
140
+ // Resolve the message if it's a function
141
+ const message = typeof prompt.message === 'function'
142
+ ? prompt.message(this.resolverContext)
143
+ : prompt.message;
144
+ // Get choices if applicable
145
+ let choices;
146
+ if (prompt.choices) {
147
+ choices = await Promise.resolve(prompt.choices(this.resolverContext));
148
+ }
149
+ // Get default value
150
+ const defaultValue = typeof prompt.default === 'function'
151
+ ? prompt.default(this.resolverContext)
152
+ : prompt.default;
153
+ if (this.options.jsonMode) {
154
+ // JSON MODE: Output prompt config and exit
155
+ await this.outputJsonPrompt(prompt, message, choices, defaultValue);
156
+ // outputPromptAsJson calls process.exit, so we never reach here
157
+ }
158
+ else {
159
+ // INTERACTIVE MODE: Prompt for value
160
+ const value = await this.promptInteractive(prompt, message, choices, defaultValue);
161
+ // Transform value if needed
162
+ const finalValue = prompt.transform
163
+ ? prompt.transform(value, this.resolverContext)
164
+ : value;
165
+ // Store resolved flag
166
+ this.resolvedFlags[prompt.flagName] = finalValue;
167
+ this.resolverContext.flags = this.resolvedFlags;
168
+ }
169
+ }
170
+ return this.resolvedFlags;
171
+ }
172
+ /**
173
+ * Output prompt as JSON for machine mode
174
+ */
175
+ async outputJsonPrompt(prompt, message, choices, defaultValue) {
176
+ // Build prompt config
177
+ const config = {
178
+ type: prompt.type,
179
+ name: prompt.flagName,
180
+ message,
181
+ };
182
+ // Add choices with command field
183
+ if (choices) {
184
+ config.choices = choices.map(choice => {
185
+ const promptChoice = {
186
+ name: choice.name,
187
+ value: String(choice.value),
188
+ };
189
+ if (choice.disabled !== undefined) {
190
+ promptChoice.disabled = Boolean(choice.disabled);
191
+ }
192
+ // Generate command for this choice
193
+ if (choice.command) {
194
+ promptChoice.command = choice.command;
195
+ }
196
+ else if (!prompt.skipAutoCommand) {
197
+ // Auto-generate command
198
+ promptChoice.command = prompt.getCommand
199
+ ? prompt.getCommand(choice.value, this.resolverContext)
200
+ : this.buildCommand(prompt.flagName, choice.value);
201
+ }
202
+ return promptChoice;
203
+ });
204
+ }
205
+ // Add default value
206
+ if (defaultValue !== undefined) {
207
+ config.default = defaultValue;
208
+ }
209
+ // Add context if provided
210
+ if (prompt.context) {
211
+ config.context = typeof prompt.context === 'function'
212
+ ? prompt.context(this.resolverContext)
213
+ : prompt.context;
214
+ }
215
+ // For input prompts without choices, add helpful context
216
+ if (prompt.type === 'input' && !config.context) {
217
+ config.context = {
218
+ hint: `Provide ${prompt.flagName} with: ${this.buildCommand(prompt.flagName, '<value>')}`,
219
+ };
220
+ }
221
+ // Output and exit
222
+ outputPromptAsJson(config, createMetadata(this.options.commandName, this.options.flags));
223
+ // outputPromptAsJson calls process.exit, but TypeScript doesn't know that
224
+ // This line is never reached
225
+ throw new Error('Unreachable');
226
+ }
227
+ /**
228
+ * Prompt for value in interactive mode
229
+ */
230
+ async promptInteractive(prompt, message, choices, defaultValue) {
231
+ // Build inquirer prompt config as a single question object
232
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
233
+ const question = {
234
+ type: prompt.type,
235
+ name: prompt.flagName,
236
+ message,
237
+ default: defaultValue,
238
+ };
239
+ // Add choices for list/checkbox
240
+ if (choices) {
241
+ question.choices = choices.map(c => ({
242
+ name: c.name,
243
+ value: c.value,
244
+ disabled: c.disabled,
245
+ }));
246
+ }
247
+ // Add validation for input
248
+ if (prompt.validate) {
249
+ question.validate = (input) => {
250
+ return prompt.validate(input, this.resolverContext);
251
+ };
252
+ }
253
+ // Prompt and return value
254
+ const answers = await inquirer.prompt([question]);
255
+ return answers[prompt.flagName];
256
+ }
257
+ /**
258
+ * Build a command string for a flag value
259
+ */
260
+ buildCommand(flagName, value) {
261
+ const { baseCommand } = this.options;
262
+ // Build flags part from currently resolved flags
263
+ let cmd = baseCommand;
264
+ // Add any project flag from context
265
+ const projectId = this.resolverContext.projectId;
266
+ if (projectId && !this.resolvedFlags['project']) {
267
+ cmd += ` -P ${projectId}`;
268
+ }
269
+ // Add resolved flags (except the one we're prompting for)
270
+ for (const [key, val] of Object.entries(this.resolvedFlags)) {
271
+ if (key === flagName || val === undefined || key === 'json')
272
+ continue;
273
+ if (typeof val === 'boolean') {
274
+ if (val)
275
+ cmd += ` --${key}`;
276
+ }
277
+ else if (typeof val === 'string') {
278
+ cmd += ` --${key} "${val}"`;
279
+ }
280
+ else if (Array.isArray(val)) {
281
+ cmd += ` --${key} "${val.join(',')}"`;
282
+ }
283
+ else {
284
+ cmd += ` --${key} ${val}`;
285
+ }
286
+ }
287
+ // Add the current flag
288
+ if (typeof value === 'boolean') {
289
+ if (value)
290
+ cmd += ` --${flagName}`;
291
+ }
292
+ else if (typeof value === 'string') {
293
+ cmd += ` --${flagName} "${value}"`;
294
+ }
295
+ else if (value !== undefined) {
296
+ cmd += ` --${flagName} ${value}`;
297
+ }
298
+ // Always add --json at the end
299
+ cmd += ' --json';
300
+ return cmd;
301
+ }
302
+ }
303
+ /**
304
+ * Convenience function to create a FlagResolver from command context
305
+ */
306
+ export function createFlagResolver(options) {
307
+ return new FlagResolver(options);
308
+ }
309
+ /**
310
+ * Helper to check if we should use JSON mode
311
+ * Re-exported from prompt-json for convenience
312
+ */
313
+ export { shouldOutputJson, isMachineOutput } from '../prompt-json.js';
@@ -1,11 +1,30 @@
1
- import { Command } from '@oclif/core';
2
1
  import { type PMOContext } from './pmo-context.js';
2
+ import { PromptCommand } from '../prompt-command.js';
3
3
  import { type JsonFlags } from '../prompt-json.js';
4
+ /**
5
+ * Base flags for JSON/agent mode support (legacy)
6
+ * Include these in your command's flags by spreading: ...jsonModeFlags
7
+ * @deprecated Use machineOutputFlags instead
8
+ */
9
+ export declare const jsonModeFlags: {
10
+ json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
11
+ };
12
+ /**
13
+ * Base flags for machine-readable output mode
14
+ * Include these in your command's flags by spreading: ...machineOutputFlags
15
+ * Supports both --machine (new) and --json (legacy, deprecated)
16
+ */
17
+ export declare const machineOutputFlags: {
18
+ machine: import("@oclif/core/interfaces").BooleanFlag<boolean>;
19
+ json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
20
+ };
4
21
  /**
5
22
  * Base flags shared by all PMO commands
6
- * Include these in your command's flags by spreading: ...PMOCommand.baseFlags
23
+ * Include these in your command's flags by spreading: ...pmoBaseFlags
7
24
  */
8
25
  export declare const pmoBaseFlags: {
26
+ machine: import("@oclif/core/interfaces").BooleanFlag<boolean>;
27
+ json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
9
28
  project: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
10
29
  };
11
30
  /**
@@ -43,7 +62,7 @@ export declare const pmoBaseFlags: {
43
62
  * }
44
63
  * ```
45
64
  */
46
- export declare abstract class PMOCommand extends Command {
65
+ export declare abstract class PMOCommand extends PromptCommand {
47
66
  /**
48
67
  * PMO context with storage, pmoPath, etc.
49
68
  * Available after init() runs (before execute())
@@ -162,6 +181,37 @@ export declare abstract class PMOCommand extends Command {
162
181
  example?: string;
163
182
  } | null;
164
183
  }): Promise<string>;
184
+ /**
185
+ * Unified error handler for JSON/interactive modes.
186
+ *
187
+ * Consolidates error handling to avoid message drift between JSON and interactive modes.
188
+ * In JSON mode: outputs structured error JSON and exits
189
+ * In interactive mode: calls this.error() with the message
190
+ *
191
+ * @param code - Error code for JSON output (e.g., 'NOT_FOUND', 'DOCKER_NOT_RUNNING')
192
+ * @param message - Human-readable error message (used in both modes)
193
+ * @param options - Configuration for error handling
194
+ * @returns never - always throws or exits
195
+ *
196
+ * @example
197
+ * ```typescript
198
+ * // Instead of duplicating messages:
199
+ * // if (jsonMode) { outputErrorAsJson('CODE', 'msg', ...); }
200
+ * // this.error('msg');
201
+ *
202
+ * // Use:
203
+ * this.handleError('DOCKER_NOT_RUNNING', 'Docker is not running.', {
204
+ * jsonMode,
205
+ * commandName: 'agent auth',
206
+ * flags,
207
+ * });
208
+ * ```
209
+ */
210
+ protected handleError(code: string, message: string, options: {
211
+ jsonMode: boolean;
212
+ commandName: string;
213
+ flags: Record<string, unknown>;
214
+ }): never;
165
215
  /**
166
216
  * Override run() to delegate to execute() and ensure cleanup
167
217
  * Subclasses should implement execute() instead of run()
@@ -1,17 +1,47 @@
1
- import { Command, Flags } from '@oclif/core';
1
+ import { Flags } from '@oclif/core';
2
2
  import inquirer from 'inquirer';
3
3
  import { getPMOContext } from './pmo-context.js';
4
4
  import { styles } from '../styles.js';
5
- import { shouldOutputJson, outputPromptAsJson, createMetadata, } from '../prompt-json.js';
5
+ import { PromptCommand } from '../prompt-command.js';
6
+ import { shouldOutputJson, outputPromptAsJson, outputErrorAsJson, createMetadata, } from '../prompt-json.js';
7
+ /**
8
+ * Base flags for JSON/agent mode support (legacy)
9
+ * Include these in your command's flags by spreading: ...jsonModeFlags
10
+ * @deprecated Use machineOutputFlags instead
11
+ */
12
+ export const jsonModeFlags = {
13
+ json: Flags.boolean({
14
+ description: 'Output prompts as JSON for AI agents/scripts',
15
+ default: false,
16
+ }),
17
+ };
18
+ /**
19
+ * Base flags for machine-readable output mode
20
+ * Include these in your command's flags by spreading: ...machineOutputFlags
21
+ * Supports both --machine (new) and --json (legacy, deprecated)
22
+ */
23
+ export const machineOutputFlags = {
24
+ machine: Flags.boolean({
25
+ char: 'm',
26
+ description: 'Output as JSON for AI agents/scripts (machine-readable mode)',
27
+ default: false,
28
+ }),
29
+ json: Flags.boolean({
30
+ description: 'Output as JSON (deprecated, use --machine)',
31
+ default: false,
32
+ hidden: true, // Hide from help since it's deprecated
33
+ }),
34
+ };
6
35
  /**
7
36
  * Base flags shared by all PMO commands
8
- * Include these in your command's flags by spreading: ...PMOCommand.baseFlags
37
+ * Include these in your command's flags by spreading: ...pmoBaseFlags
9
38
  */
10
39
  export const pmoBaseFlags = {
11
40
  project: Flags.string({
12
41
  char: 'P',
13
42
  description: 'Project ID (uses first project if only one exists)',
14
43
  }),
44
+ ...machineOutputFlags,
15
45
  };
16
46
  /**
17
47
  * Base command class for PMO commands
@@ -48,7 +78,7 @@ export const pmoBaseFlags = {
48
78
  * }
49
79
  * ```
50
80
  */
51
- export class PMOCommand extends Command {
81
+ export class PMOCommand extends PromptCommand {
52
82
  /**
53
83
  * PMO context with storage, pmoPath, etc.
54
84
  * Available after init() runs (before execute())
@@ -133,19 +163,27 @@ export class PMOCommand extends Command {
133
163
  const numB = parseInt(b.name.match(/^(\d+)/)?.[1] || '999', 10);
134
164
  return numA - numB;
135
165
  });
166
+ // Auto-detect non-TTY: switch to JSON mode when no TTY present
167
+ const effectiveJsonMode = options?.jsonMode ?? (!process.stdin.isTTY
168
+ ? {
169
+ flags: { json: true },
170
+ commandName: this.id ?? 'unknown',
171
+ baseCommand: `prlt ${(this.id ?? 'unknown').replace(/:/g, ' ')}`,
172
+ }
173
+ : null);
136
174
  // If JSON mode is active, output project choices as JSON
137
- if (options?.jsonMode && shouldOutputJson(options.jsonMode.flags)) {
175
+ if (effectiveJsonMode && shouldOutputJson(effectiveJsonMode.flags)) {
138
176
  const choices = sortedProjects.map(p => ({
139
177
  name: `${p.name} (${p.id})`,
140
178
  value: p.id,
141
- command: `${options.jsonMode.baseCommand} -P ${p.id} --json`,
179
+ command: `${effectiveJsonMode.baseCommand} -P ${p.id} --json`,
142
180
  }));
143
181
  outputPromptAsJson({
144
182
  type: 'list',
145
183
  name: 'project',
146
184
  message: 'Select project:',
147
185
  choices,
148
- }, createMetadata(options.jsonMode.commandName, options.jsonMode.flags));
186
+ }, createMetadata(effectiveJsonMode.commandName, effectiveJsonMode.flags));
149
187
  // outputPromptAsJson calls process.exit, so this is unreachable
150
188
  return '';
151
189
  }
@@ -191,6 +229,10 @@ export class PMOCommand extends Command {
191
229
  */
192
230
  async selectFromList(options) {
193
231
  const { message, items, getName, getValue, getCommand, jsonMode, allowCancel = false, cancelValue, } = options;
232
+ // Auto-detect non-TTY: switch to JSON mode when no TTY present
233
+ const effectiveJsonMode = jsonMode ?? (!process.stdin.isTTY
234
+ ? { flags: { json: true }, commandName: this.id ?? 'unknown' }
235
+ : null);
194
236
  // Build choices with command field
195
237
  const choices = items.map(item => ({
196
238
  name: getName(item),
@@ -198,13 +240,13 @@ export class PMOCommand extends Command {
198
240
  command: getCommand(item),
199
241
  }));
200
242
  // Check for JSON mode
201
- if (jsonMode && shouldOutputJson(jsonMode.flags)) {
243
+ if (effectiveJsonMode && shouldOutputJson(effectiveJsonMode.flags)) {
202
244
  outputPromptAsJson({
203
245
  type: 'list',
204
246
  name: 'selection',
205
247
  message,
206
248
  choices,
207
- }, createMetadata(jsonMode.commandName, jsonMode.flags));
249
+ }, createMetadata(effectiveJsonMode.commandName, effectiveJsonMode.flags));
208
250
  // outputPromptAsJson exits, so this is unreachable
209
251
  return null;
210
252
  }
@@ -238,18 +280,22 @@ export class PMOCommand extends Command {
238
280
  */
239
281
  async promptForInput(options) {
240
282
  const { message, fieldName, defaultValue, validate, jsonMode } = options;
283
+ // Auto-detect non-TTY: switch to JSON mode when no TTY present
284
+ const effectiveJsonMode = jsonMode ?? (!process.stdin.isTTY
285
+ ? { flags: { json: true }, commandName: this.id ?? 'unknown', commandHint: '', example: undefined }
286
+ : null);
241
287
  // Check for JSON mode
242
- if (jsonMode && shouldOutputJson(jsonMode.flags)) {
288
+ if (effectiveJsonMode && shouldOutputJson(effectiveJsonMode.flags)) {
243
289
  outputPromptAsJson({
244
290
  type: 'input',
245
291
  name: fieldName,
246
292
  message,
247
293
  default: defaultValue,
248
294
  context: {
249
- hint: jsonMode.commandHint,
250
- example: jsonMode.example,
295
+ hint: effectiveJsonMode.commandHint,
296
+ example: effectiveJsonMode.example,
251
297
  },
252
- }, createMetadata(jsonMode.commandName, jsonMode.flags));
298
+ }, createMetadata(effectiveJsonMode.commandName, effectiveJsonMode.flags));
253
299
  // outputPromptAsJson exits, so this is unreachable
254
300
  return '';
255
301
  }
@@ -263,6 +309,39 @@ export class PMOCommand extends Command {
263
309
  }]);
264
310
  return value;
265
311
  }
312
+ /**
313
+ * Unified error handler for JSON/interactive modes.
314
+ *
315
+ * Consolidates error handling to avoid message drift between JSON and interactive modes.
316
+ * In JSON mode: outputs structured error JSON and exits
317
+ * In interactive mode: calls this.error() with the message
318
+ *
319
+ * @param code - Error code for JSON output (e.g., 'NOT_FOUND', 'DOCKER_NOT_RUNNING')
320
+ * @param message - Human-readable error message (used in both modes)
321
+ * @param options - Configuration for error handling
322
+ * @returns never - always throws or exits
323
+ *
324
+ * @example
325
+ * ```typescript
326
+ * // Instead of duplicating messages:
327
+ * // if (jsonMode) { outputErrorAsJson('CODE', 'msg', ...); }
328
+ * // this.error('msg');
329
+ *
330
+ * // Use:
331
+ * this.handleError('DOCKER_NOT_RUNNING', 'Docker is not running.', {
332
+ * jsonMode,
333
+ * commandName: 'agent auth',
334
+ * flags,
335
+ * });
336
+ * ```
337
+ */
338
+ handleError(code, message, options) {
339
+ if (options.jsonMode) {
340
+ outputErrorAsJson(code, message, createMetadata(options.commandName, options.flags));
341
+ this.exit(1);
342
+ }
343
+ this.error(message);
344
+ }
266
345
  /**
267
346
  * Override run() to delegate to execute() and ensure cleanup
268
347
  * Subclasses should implement execute() instead of run()
@@ -2,7 +2,7 @@
2
2
  * Find PMO directory by checking workspace.db for pmo_projects table
3
3
  *
4
4
  * Search priority:
5
- * 1. PRLT_HQ_PATH env var (ONLY when DEVCONTAINER=true - for devcontainer mounts)
5
+ * 1. PRLT_HQ_PATH env var (ONLY when DEVCONTAINER=true or PRLT_TEST_ENV=true)
6
6
  * 2. Current directory tree for HQ with PMO
7
7
  * 3. Current directory tree for standalone PMO (.pmo/)
8
8
  * 4. ~/.proletariat/config.json activeWorkspace (fallback when NOT in any workspace)
@@ -52,7 +52,7 @@ function hasPMOTables(dbPath) {
52
52
  * Find PMO directory by checking workspace.db for pmo_projects table
53
53
  *
54
54
  * Search priority:
55
- * 1. PRLT_HQ_PATH env var (ONLY when DEVCONTAINER=true - for devcontainer mounts)
55
+ * 1. PRLT_HQ_PATH env var (ONLY when DEVCONTAINER=true or PRLT_TEST_ENV=true)
56
56
  * 2. Current directory tree for HQ with PMO
57
57
  * 3. Current directory tree for standalone PMO (.pmo/)
58
58
  * 4. ~/.proletariat/config.json activeWorkspace (fallback when NOT in any workspace)
@@ -62,10 +62,10 @@ function hasPMOTables(dbPath) {
62
62
  * working in different workspaces simultaneously.
63
63
  */
64
64
  export function findPMO() {
65
- // Check PRLT_HQ_PATH environment variable (only in devcontainers)
65
+ // Check PRLT_HQ_PATH environment variable (only in devcontainers or test environments)
66
66
  const hqPath = process.env.PRLT_HQ_PATH;
67
- const isDevcontainer = process.env.DEVCONTAINER === 'true';
68
- if (hqPath && isDevcontainer) {
67
+ const allowEnvHqPath = process.env.DEVCONTAINER === 'true' || process.env.PRLT_TEST_ENV === 'true';
68
+ if (hqPath && allowEnvHqPath) {
69
69
  // In devcontainer, PMO is always mounted at /hq/pmo regardless of database value
70
70
  // (database stores relative path like "repos/proletariat/pmo" but mount is at /hq/pmo)
71
71
  return path.join(hqPath, 'pmo');
@@ -8,7 +8,7 @@ export { startWatcher, runWatcherForeground, type WatcherOptions, type WatcherIn
8
8
  export { createSpecFolders, getSpecFolderPath, getProjectPath, getProductPath, getEpicsPath, } from './create-spec-folders.js';
9
9
  export { findPMO } from './find-pmo.js';
10
10
  export { getPMOContext, type PMOContext, type GetPMOContextOptions } from './pmo-context.js';
11
- export { PMOCommand, pmoBaseFlags } from './base-command.js';
11
+ export { PMOCommand, pmoBaseFlags, jsonModeFlags, machineOutputFlags } from './base-command.js';
12
12
  export { PMO_TABLES, PMO_TABLE_SCHEMAS, PMO_INDEXES, PMO_SCHEMA_SQL, EXPECTED_TICKET_COLUMNS, validateTicketSchema, } from './schema.js';
13
13
  export { BUILTIN_TEMPLATES, getBuiltinTemplate, getPickerTemplates, getColumnsForTemplate, getColumnSettingsForTemplate, } from './templates-builtin.js';
14
14
  /**
@@ -16,7 +16,7 @@ export { startWatcher, runWatcherForeground, } from './watcher.js';
16
16
  export { createSpecFolders, getSpecFolderPath, getProjectPath, getProductPath, getEpicsPath, } from './create-spec-folders.js';
17
17
  export { findPMO } from './find-pmo.js';
18
18
  export { getPMOContext } from './pmo-context.js';
19
- export { PMOCommand, pmoBaseFlags } from './base-command.js';
19
+ export { PMOCommand, pmoBaseFlags, jsonModeFlags, machineOutputFlags } from './base-command.js';
20
20
  export { PMO_TABLES, PMO_TABLE_SCHEMAS, PMO_INDEXES, PMO_SCHEMA_SQL, EXPECTED_TICKET_COLUMNS, validateTicketSchema, } from './schema.js';
21
21
  // Re-export template utilities from shared definitions
22
22
  export { BUILTIN_TEMPLATES, getBuiltinTemplate, getPickerTemplates, getColumnsForTemplate, getColumnSettingsForTemplate, } from './templates-builtin.js';
@@ -115,7 +115,8 @@ export function rowToSpec(row) {
115
115
  status: row.status,
116
116
  type: row.type,
117
117
  tags: row.tags ? JSON.parse(row.tags) : undefined,
118
- dependsOn: row.depends_on ? JSON.parse(row.depends_on) : undefined,
118
+ // Note: dependsOn is now handled via spec_dependencies table, not inline column
119
+ dependsOn: undefined,
119
120
  problem: row.problem || undefined,
120
121
  solution: row.solution || undefined,
121
122
  decisions: row.decisions || undefined,
@@ -3,12 +3,17 @@
3
3
  *
4
4
  * This is the main facade that delegates to domain-specific storage modules.
5
5
  * Uses the unified workspace.db database with pmo_ prefixed tables.
6
+ *
7
+ * This module now supports Drizzle ORM for type-safe queries while maintaining
8
+ * backward compatibility with raw SQL queries during the migration period.
6
9
  */
7
10
  import Database from 'better-sqlite3';
11
+ import { DrizzleDB } from '../../database/drizzle.js';
8
12
  import { AcceptanceCriterion, Board, BoardConfig, BoardView, BoardViewFilter, BoardViewFilters, Column, CreateTicketInput, Epic, EpicDependency, EpicDependencyType, EpicFilter, PhaseFilter, PhaseTemplate, PhaseTemplateFilter, PMOStorage, Project, ProjectFilter, ProjectPhase, Roadmap, RoadmapFilter, RoadmapProject, Spec, SpecDependency, SpecDependencyType, SpecFilter, StateCategory, Subtask, SyncResult, SyncStatus, Ticket, TicketDependency, TicketDependencyType, TicketFilter, TicketTemplate, TicketTemplateFilter, WorkAction, WorkActionFilter, Workflow, WorkflowFilter, WorkflowStatus } from '../types.js';
9
13
  export declare class SQLiteStorage implements PMOStorage {
10
14
  readonly type: "sqlite";
11
15
  private db;
16
+ private drizzle;
12
17
  private dbPath;
13
18
  private projectStorage;
14
19
  private ticketStorage;
@@ -28,6 +33,10 @@ export declare class SQLiteStorage implements PMOStorage {
28
33
  * Get the underlying database connection.
29
34
  */
30
35
  getDatabase(): Database.Database;
36
+ /**
37
+ * Get the Drizzle ORM database connection for type-safe queries.
38
+ */
39
+ getDrizzle(): DrizzleDB;
31
40
  /**
32
41
  * Ensure PMO tables exist in the database.
33
42
  */