@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,29 @@
1
+ /**
2
+ * Drizzle ORM Database Connection
3
+ *
4
+ * This module provides type-safe database connections using Drizzle ORM
5
+ * with better-sqlite3 as the underlying driver.
6
+ */
7
+ import { BetterSQLite3Database } from 'drizzle-orm/better-sqlite3';
8
+ import Database from 'better-sqlite3';
9
+ import * as schema from './drizzle-schema.js';
10
+ export type DrizzleDB = BetterSQLite3Database<typeof schema>;
11
+ /**
12
+ * Create a Drizzle database connection from an existing better-sqlite3 database.
13
+ * This allows gradual migration by wrapping existing database connections.
14
+ */
15
+ export declare function createDrizzleConnection(db: Database.Database): DrizzleDB;
16
+ /**
17
+ * Create a new Drizzle database connection from a file path.
18
+ * Configures pragmas for optimal performance and reliability.
19
+ */
20
+ export declare function openDrizzleDatabase(dbPath: string): {
21
+ db: DrizzleDB;
22
+ sqliteDb: Database.Database;
23
+ };
24
+ /**
25
+ * Close a Drizzle database connection.
26
+ * Since Drizzle wraps better-sqlite3, we need to close the underlying connection.
27
+ */
28
+ export declare function closeDrizzleDatabase(sqliteDb: Database.Database): void;
29
+ export * from './drizzle-schema.js';
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Drizzle ORM Database Connection
3
+ *
4
+ * This module provides type-safe database connections using Drizzle ORM
5
+ * with better-sqlite3 as the underlying driver.
6
+ */
7
+ import { drizzle } from 'drizzle-orm/better-sqlite3';
8
+ import Database from 'better-sqlite3';
9
+ import * as schema from './drizzle-schema.js';
10
+ /**
11
+ * Create a Drizzle database connection from an existing better-sqlite3 database.
12
+ * This allows gradual migration by wrapping existing database connections.
13
+ */
14
+ export function createDrizzleConnection(db) {
15
+ return drizzle(db, { schema });
16
+ }
17
+ /**
18
+ * Create a new Drizzle database connection from a file path.
19
+ * Configures pragmas for optimal performance and reliability.
20
+ */
21
+ export function openDrizzleDatabase(dbPath) {
22
+ const sqliteDb = new Database(dbPath);
23
+ // Configure pragmas
24
+ sqliteDb.pragma('foreign_keys = ON');
25
+ sqliteDb.pragma('busy_timeout = 5000'); // Wait up to 5 seconds if database is locked
26
+ const db = drizzle(sqliteDb, { schema });
27
+ return { db, sqliteDb };
28
+ }
29
+ /**
30
+ * Close a Drizzle database connection.
31
+ * Since Drizzle wraps better-sqlite3, we need to close the underlying connection.
32
+ */
33
+ export function closeDrizzleDatabase(sqliteDb) {
34
+ sqliteDb.close();
35
+ }
36
+ // Re-export schema for convenience
37
+ export * from './drizzle-schema.js';
@@ -52,6 +52,7 @@ export interface AgentWorktree {
52
52
  is_clean: boolean;
53
53
  last_checked?: string;
54
54
  }
55
+ export declare const CREATE_TABLES_SQL = "\n-- Core workspace metadata\nCREATE TABLE IF NOT EXISTS workspace (\n id INTEGER PRIMARY KEY CHECK (id = 1),\n type TEXT NOT NULL CHECK (type IN ('hq', 'workspace')),\n workspace_name TEXT NOT NULL,\n has_pmo BOOLEAN DEFAULT FALSE,\n active_theme_id TEXT,\n created_at TEXT NOT NULL,\n FOREIGN KEY (active_theme_id) REFERENCES agent_themes(id) ON DELETE SET NULL\n);\n\n-- Repository management\nCREATE TABLE IF NOT EXISTS repositories (\n name TEXT PRIMARY KEY,\n path TEXT NOT NULL,\n type TEXT DEFAULT 'main' CHECK (type IN ('main', 'dependency')),\n source_url TEXT,\n action TEXT CHECK (action IN ('clone', 'move', 'link')),\n added_at TEXT NOT NULL\n);\n\n-- Agent naming themes (optional)\nCREATE TABLE IF NOT EXISTS agent_themes (\n id TEXT PRIMARY KEY,\n name TEXT NOT NULL UNIQUE,\n display_name TEXT NOT NULL,\n description TEXT,\n builtin BOOLEAN DEFAULT FALSE,\n created_at TEXT NOT NULL\n);\n\n-- Names available within each theme\nCREATE TABLE IF NOT EXISTS agent_theme_names (\n theme_id TEXT NOT NULL,\n name TEXT NOT NULL,\n PRIMARY KEY (theme_id, name),\n FOREIGN KEY (theme_id) REFERENCES agent_themes(id) ON DELETE CASCADE\n);\n\n-- Agent instances in workspace\nCREATE TABLE IF NOT EXISTS agents (\n name TEXT PRIMARY KEY,\n type TEXT NOT NULL DEFAULT 'persistent' CHECK (type IN ('persistent', 'ephemeral')),\n status TEXT NOT NULL DEFAULT 'active' CHECK (status IN ('active', 'cleaned')),\n base_name TEXT,\n theme_id TEXT,\n worktree_path TEXT,\n mount_mode TEXT NOT NULL DEFAULT 'worktree' CHECK (mount_mode IN ('worktree', 'clone')),\n created_at TEXT NOT NULL,\n cleaned_at TEXT,\n FOREIGN KEY (theme_id) REFERENCES agent_themes(id) ON DELETE SET NULL\n);\n\n-- Agent-owned worktrees\nCREATE TABLE IF NOT EXISTS agent_worktrees (\n agent_name TEXT NOT NULL,\n repo_name TEXT NOT NULL,\n worktree_path TEXT NOT NULL,\n branch TEXT NOT NULL,\n created_at TEXT NOT NULL,\n PRIMARY KEY (agent_name, repo_name),\n FOREIGN KEY (agent_name) REFERENCES agents(name) ON DELETE CASCADE,\n FOREIGN KEY (repo_name) REFERENCES repositories(name) ON DELETE CASCADE\n);\n\n-- Workspace-level settings (key-value store)\nCREATE TABLE IF NOT EXISTS workspace_settings (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL\n);\n\n-- =============================================================================\n-- Indexes\n-- =============================================================================\n\nCREATE INDEX IF NOT EXISTS idx_worktrees_agent ON agent_worktrees(agent_name);\nCREATE INDEX IF NOT EXISTS idx_worktrees_repo ON agent_worktrees(repo_name);\nCREATE INDEX IF NOT EXISTS idx_theme_names_theme ON agent_theme_names(theme_id);\nCREATE INDEX IF NOT EXISTS idx_agents_theme ON agents(theme_id);\n";
55
56
  /**
56
57
  * Get the database path for a workspace
57
58
  */
@@ -3,7 +3,7 @@ import * as fs from 'node:fs';
3
3
  import * as path from 'node:path';
4
4
  import { getThemePersistentDir, isEphemeralAgentName } from '../themes.js';
5
5
  import { PMO_SCHEMA_SQL } from '../pmo/schema.js';
6
- const CREATE_TABLES_SQL = `
6
+ export const CREATE_TABLES_SQL = `
7
7
  -- Core workspace metadata
8
8
  CREATE TABLE IF NOT EXISTS workspace (
9
9
  id INTEGER PRIMARY KEY CHECK (id = 1),
@@ -6,6 +6,7 @@
6
6
  */
7
7
  import Database from 'better-sqlite3';
8
8
  import { ExecutionConfig, TerminalApp, Shell, DisplayMode, OutputMode, ExecutionEnvironment } from './types.js';
9
+ import { type JsonFlags } from '../prompt-json.js';
9
10
  declare const CONFIG_KEYS: {
10
11
  terminalApp: string;
11
12
  terminalOpenInBackground: string;
@@ -106,6 +107,11 @@ export interface ExecutionPromptOptions {
106
107
  reconfigure?: boolean;
107
108
  /** Log function for status messages */
108
109
  log?: (msg: string) => void;
110
+ /** JSON mode configuration for AI agents */
111
+ jsonMode?: {
112
+ flags: JsonFlags & Record<string, unknown>;
113
+ commandName: string;
114
+ };
109
115
  }
110
116
  export interface ExecutionPromptResult {
111
117
  /** Execution config with terminal/shell/output settings */
@@ -7,6 +7,7 @@
7
7
  import inquirer from 'inquirer';
8
8
  import { DEFAULT_EXECUTION_CONFIG } from './types.js';
9
9
  import { isGHInstalled, isGHAuthenticated } from '../pr/index.js';
10
+ import { shouldOutputJson, outputPromptAsJson, createMetadata, buildPromptConfig, } from '../prompt-json.js';
10
11
  import { execSync } from 'node:child_process';
11
12
  const SETTINGS_TABLE = 'workspace_settings';
12
13
  // Config keys stored in workspace_settings table
@@ -342,7 +343,9 @@ export async function getShell(db) {
342
343
  * Used by work start, work spawn, and work watch commands.
343
344
  */
344
345
  export async function promptExecutionSettings(db, options) {
345
- const { displayMode, environment, log = () => { } } = options;
346
+ const { displayMode, environment, log = () => { }, jsonMode } = options;
347
+ // Check if JSON mode is active
348
+ const isJsonMode = jsonMode && shouldOutputJson(jsonMode.flags);
346
349
  // Load execution config from database
347
350
  const executionConfig = loadExecutionConfig(db);
348
351
  // If terminal display mode, ensure terminal and shell preferences are set (prompts on first use)
@@ -373,15 +376,20 @@ export async function promptExecutionSettings(db, options) {
373
376
  let outputMode = options.outputMode ?? DEFAULT_EXECUTION_CONFIG.outputMode;
374
377
  const streamingDisplayModes = ['terminal'];
375
378
  if (options.outputMode === undefined && streamingDisplayModes.includes(displayMode)) {
379
+ const outputChoices = [
380
+ { name: 'interactive - Watch Claude work in real-time (streaming UI)', value: 'interactive' },
381
+ { name: 'print - Show final result only (better for logs)', value: 'print' },
382
+ ];
383
+ // In JSON mode, output the output mode prompt
384
+ if (isJsonMode && jsonMode) {
385
+ outputPromptAsJson(buildPromptConfig('list', 'selectedOutputMode', 'How should Claude display output?', outputChoices, 'interactive'), createMetadata(jsonMode.commandName, jsonMode.flags));
386
+ }
376
387
  const { selectedOutputMode } = await inquirer.prompt([
377
388
  {
378
389
  type: 'list',
379
390
  name: 'selectedOutputMode',
380
391
  message: 'How should Claude display output?',
381
- choices: [
382
- { name: 'interactive - Watch Claude work in real-time (streaming UI)', value: 'interactive' },
383
- { name: 'print - Show final result only (better for logs)', value: 'print' },
384
- ],
392
+ choices: outputChoices,
385
393
  default: 'interactive',
386
394
  },
387
395
  ]);
@@ -394,15 +402,20 @@ export async function promptExecutionSettings(db, options) {
394
402
  const containerNote = (environment === 'devcontainer' || environment === 'docker')
395
403
  ? ' (container provides additional isolation)'
396
404
  : '';
405
+ const permissionChoices = [
406
+ { name: '🔒 safe - Requires approval for dangerous operations (recommended)', value: 'safe' },
407
+ { name: '⚠️ danger - Skip permission checks (--dangerously-skip-permissions)', value: 'danger' },
408
+ ];
409
+ // In JSON mode, output the permissions prompt
410
+ if (isJsonMode && jsonMode) {
411
+ outputPromptAsJson(buildPromptConfig('list', 'permissionMode', `Permission mode for Claude Code${containerNote}:`, permissionChoices, 'safe'), createMetadata(jsonMode.commandName, jsonMode.flags));
412
+ }
397
413
  const { permissionMode } = await inquirer.prompt([
398
414
  {
399
415
  type: 'list',
400
416
  name: 'permissionMode',
401
417
  message: `Permission mode for Claude Code${containerNote}:`,
402
- choices: [
403
- { name: '🔒 safe - Requires approval for dangerous operations (recommended)', value: 'safe' },
404
- { name: '⚠️ danger - Skip permission checks (--dangerously-skip-permissions)', value: 'danger' },
405
- ],
418
+ choices: permissionChoices,
406
419
  default: 'safe',
407
420
  },
408
421
  ]);
@@ -413,15 +426,20 @@ export async function promptExecutionSettings(db, options) {
413
426
  if (options.createPR === undefined) {
414
427
  const ghAvailable = isGHInstalled() && isGHAuthenticated();
415
428
  if (ghAvailable) {
429
+ const prChoices = [
430
+ { name: '✓ Yes - Create PR when running `prlt work ready`', value: 'yes' },
431
+ { name: '✗ No - Just move ticket to review (can create PR later)', value: 'no' },
432
+ ];
433
+ // In JSON mode, output the PR creation prompt
434
+ if (isJsonMode && jsonMode) {
435
+ outputPromptAsJson(buildPromptConfig('list', 'prChoice', 'Create a pull request when work is ready?', prChoices, 'yes'), createMetadata(jsonMode.commandName, jsonMode.flags));
436
+ }
416
437
  const { prChoice } = await inquirer.prompt([
417
438
  {
418
439
  type: 'list',
419
440
  name: 'prChoice',
420
441
  message: 'Create a pull request when work is ready?',
421
- choices: [
422
- { name: '✓ Yes - Create PR when running `prlt work ready`', value: 'yes' },
423
- { name: '✗ No - Just move ticket to review (can create PR later)', value: 'no' },
424
- ],
442
+ choices: prChoices,
425
443
  default: 'yes',
426
444
  },
427
445
  ]);
@@ -36,32 +36,37 @@ export function generateDevcontainerJson(options, config) {
36
36
  buildArgs.GITHUB_TOKEN = '${localEnv:GITHUB_TOKEN}';
37
37
  }
38
38
  // Build mounts array - parent repo mounts only needed for worktree mode
39
+ // TKT-801: Use consistency=cached to reduce grpcfuse contention on Docker Desktop.
40
+ // This helps prevent kernel panics when multiple containers mount the same paths concurrently.
39
41
  const mounts = [
40
- 'source=${localWorkspaceFolder},target=/workspace,type=bind',
42
+ 'source=${localWorkspaceFolder},target=/workspace,type=bind,consistency=cached',
41
43
  'source=claude-bash-history,target=/commandhistory,type=volume',
42
44
  'source=claude-credentials,target=/home/node/.claude,type=volume',
43
45
  // NOTE: ~/.claude.json is COPIED (not mounted) to /workspace/.claude.json
44
46
  // to avoid corruption from concurrent writes by multiple containers
45
47
  // NOTE: SSH agent socket mounting doesn't work reliably on Docker Desktop for Mac
46
48
  // So we use HTTPS + token approach instead. The token is fetched fresh at spawn time.
47
- 'source=${localEnv:PRLT_HQ_PATH}/.proletariat,target=/hq/.proletariat,type=bind',
49
+ 'source=${localEnv:PRLT_HQ_PATH}/.proletariat,target=/hq/.proletariat,type=bind,consistency=cached',
48
50
  // PMO path can be anywhere (e.g., /hq/pmo or /hq/repos/myrepo/pmo)
49
51
  // Use PRLT_PMO_PATH env var to mount the actual location to /hq/pmo
50
- 'source=${localEnv:PRLT_PMO_PATH},target=/hq/pmo,type=bind',
52
+ 'source=${localEnv:PRLT_PMO_PATH},target=/hq/pmo,type=bind,consistency=cached',
51
53
  ];
52
54
  // Only add parent repo mounts for worktree mode
53
55
  // Worktree .git files reference paths like /Users/.../repos/{repoName}/.git/worktrees/name
54
56
  // These mounts make those paths accessible inside the container at /hq/repos/{repoName}
55
57
  // Clone mode doesn't need this because each clone has its own self-contained .git directory
58
+ // NOTE: Cannot use readonly because git worktrees share the object store with parent repo.
59
+ // Commits write to parent's .git/objects/ and refs update in .git/worktrees/<name>/
56
60
  if (mountMode === 'worktree' && options.repoWorktrees) {
57
61
  for (const repoName of options.repoWorktrees) {
58
- mounts.push(`source=\${localEnv:PRLT_HQ_PATH}/repos/${repoName},target=/hq/repos/${repoName},type=bind`);
62
+ mounts.push(`source=\${localEnv:PRLT_HQ_PATH}/repos/${repoName},target=/hq/repos/${repoName},type=bind,consistency=cached`);
59
63
  }
60
64
  }
61
65
  // If using "mount" channel, mount local prlt build from PRLT_REPO_PATH
62
66
  // The setup-prlt.sh script will detect /opt/prlt and configure the wrapper
67
+ // TKT-801: Use readonly,consistency=cached to reduce grpcfuse contention
63
68
  if (useMount) {
64
- mounts.push('source=${localEnv:PRLT_REPO_PATH},target=/opt/prlt,type=bind,readonly');
69
+ mounts.push('source=${localEnv:PRLT_REPO_PATH},target=/opt/prlt,type=bind,readonly,consistency=cached');
65
70
  }
66
71
  const devcontainerJson = {
67
72
  name: `Agent: ${options.agentName}`,
@@ -470,7 +475,7 @@ if [ -d "/opt/prlt/apps/cli" ]; then
470
475
  # Install only better-sqlite3 with correct architecture
471
476
  cd "$PRLT_LOCAL"
472
477
  npm init -y > /dev/null 2>&1
473
- npm install better-sqlite3@11.6.0 --build-from-source 2>&1 || {
478
+ npm install better-sqlite3@12.6.2 --build-from-source 2>&1 || {
474
479
  echo "Warning: better-sqlite3 rebuild failed"
475
480
  }
476
481
 
@@ -601,8 +606,9 @@ export function updateDevcontainerMounts(agentDir, _repoWorktrees) {
601
606
  // Use single mount for entire workspace - includes all repos and temp files
602
607
  // NOTE: ~/.claude.json is COPIED (not mounted) to /workspace/.claude.json
603
608
  // to avoid corruption from concurrent writes by multiple containers
609
+ // TKT-801: Use consistency=cached to reduce grpcfuse contention on Docker Desktop
604
610
  devcontainerJson.mounts = [
605
- 'source=${localWorkspaceFolder},target=/workspace,type=bind',
611
+ 'source=${localWorkspaceFolder},target=/workspace,type=bind,consistency=cached',
606
612
  'source=claude-bash-history,target=/commandhistory,type=volume',
607
613
  'source=claude-credentials,target=/home/node/.claude,type=volume',
608
614
  ];
@@ -735,17 +735,23 @@ function createDockerContainer(context, containerName, imageName, config) {
735
735
  // KEY: Use a named Docker volume for Claude credentials - this is how devcontainer.json
736
736
  // was handling it. The volume persists across containers, so login once = logged in everywhere.
737
737
  // This avoids corruption from concurrent writes to host filesystem.
738
+ //
739
+ // TKT-801: Use :cached mount option to reduce grpcfuse contention on Docker Desktop.
740
+ // This improves performance and helps prevent kernel panics when multiple containers
741
+ // mount the same paths concurrently.
738
742
  const mounts = [
739
743
  // Agent workspace
740
- `-v "${context.agentDir}:/workspace"`,
741
- // HQ .proletariat directory (for database access)
742
- ...(context.hqPath ? [`-v "${context.hqPath}/.proletariat:/hq/.proletariat"`] : []),
743
- // PMO path
744
- ...(context.pmoPath ? [`-v "${context.pmoPath}:/hq/pmo"`] : []),
745
- // Mount parent repos for git worktree resolution
744
+ `-v "${context.agentDir}:/workspace:cached"`,
745
+ // HQ .proletariat directory (for database access) - use :cached to reduce contention
746
+ ...(context.hqPath ? [`-v "${context.hqPath}/.proletariat:/hq/.proletariat:cached"`] : []),
747
+ // PMO path - use :cached to reduce contention
748
+ ...(context.pmoPath ? [`-v "${context.pmoPath}:/hq/pmo:cached"`] : []),
749
+ // Mount parent repos for git worktree resolution - use :cached to reduce contention
750
+ // NOTE: Cannot use :ro because git worktrees share the object store with parent repo.
751
+ // Commits write to parent's .git/objects/ and refs update in .git/worktrees/<name>/
746
752
  // Worktree .git files reference paths like /Users/.../repos/{repoName}/.git/worktrees/name
747
753
  // These mounts make those paths accessible inside the container at /hq/repos/{repoName}
748
- ...(context.repoWorktrees || []).map(repoName => `-v "${context.hqPath}/repos/${repoName}:/hq/repos/${repoName}"`),
754
+ ...(context.repoWorktrees || []).map(repoName => `-v "${context.hqPath}/repos/${repoName}:/hq/repos/${repoName}:cached"`),
749
755
  // Claude credentials - shared named volume (login once, all containers share)
750
756
  `-v "claude-credentials:/home/node/.claude"`,
751
757
  ];
@@ -814,6 +820,17 @@ function runContainerSetup(containerId, sandboxed = true) {
814
820
  console.debug(`[runners:docker] Container setup scripts failed:`, error);
815
821
  // Continue - setup might partially work
816
822
  }
823
+ // Configure pnpm to use container-local store to prevent contention
824
+ // Multiple agents sharing the same pnpm store causes hangs and ERR_PNPM errors (TKT-718)
825
+ // Each container gets its own store at /tmp/pnpm-store for reliability
826
+ try {
827
+ execSync(`docker exec ${containerId} pnpm config set store-dir /tmp/pnpm-store`, { stdio: 'pipe' });
828
+ console.debug(`[runners:docker] Configured pnpm store-dir to /tmp/pnpm-store`);
829
+ }
830
+ catch (error) {
831
+ console.debug(`[runners:docker] Failed to configure pnpm store (pnpm may not be installed):`, error);
832
+ // Non-fatal - pnpm may not be installed in all containers
833
+ }
817
834
  // Copy Claude settings file (.claude.json) from host to container
818
835
  // This is needed for Claude Code to recognize settings and bypass prompts
819
836
  // Note: Auth tokens are in the claude-credentials volume at /home/node/.claude/.credentials.json
@@ -77,6 +77,16 @@ function findBaseBranchInContainer(containerId, containerRepoPath, candidates =
77
77
  return 'HEAD';
78
78
  }
79
79
  // =============================================================================
80
+ // Constants
81
+ // =============================================================================
82
+ /**
83
+ * Delay between container spawns to prevent Docker kernel panics (TKT-801).
84
+ * When spawning multiple agents simultaneously, Docker Desktop on Apple Silicon
85
+ * can hit kernel panics in grpcfuse (file sharing layer) due to spinlock
86
+ * contention when all agents mount the same shared volumes concurrently.
87
+ */
88
+ const SPAWN_STAGGER_DELAY_MS = 2000;
89
+ // =============================================================================
80
90
  // Agent Selection
81
91
  // =============================================================================
82
92
  /**
@@ -517,6 +527,15 @@ export async function spawnForColumn(projectId, columnName, storage, executionSt
517
527
  roundRobinState.lastIndex = -1;
518
528
  }
519
529
  }
530
+ // Staggered spawn delay to prevent Docker kernel panics (TKT-801)
531
+ // When spawning multiple containers, add delay between spawns to avoid
532
+ // mount storms that cause spinlock contention in Docker's grpcfuse layer
533
+ const remainingTickets = ticketsToProcess.length - (ticketsToProcess.indexOf(ticket) + 1);
534
+ if (remainingTickets > 0 && availableAgents.length > 0) {
535
+ log(`Waiting ${SPAWN_STAGGER_DELAY_MS / 1000}s before next spawn (${remainingTickets} remaining)...`);
536
+ // eslint-disable-next-line no-await-in-loop -- Intentional staggered delay for Docker stability
537
+ await new Promise(resolve => setTimeout(resolve, SPAWN_STAGGER_DELAY_MS));
538
+ }
520
539
  }
521
540
  else {
522
541
  result.failed.push(spawnResult);
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Flag resolution utilities for unified human/machine interactive modes
3
+ */
4
+ export { FlagResolver, createFlagResolver, shouldOutputJson, isMachineOutput, type FlagResolverOptions, type PromptDefinition, type ResolverChoice, type ResolverContext, type ResolveResult, } from './resolver.js';
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Flag resolution utilities for unified human/machine interactive modes
3
+ */
4
+ export { FlagResolver, createFlagResolver, shouldOutputJson, isMachineOutput, } from './resolver.js';
@@ -0,0 +1,224 @@
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
+ /**
42
+ * Context available during prompt resolution
43
+ */
44
+ export interface ResolverContext<TFlags = Record<string, unknown>> {
45
+ /** Currently resolved flags (includes original flags + newly resolved) */
46
+ flags: TFlags;
47
+ /** Command args */
48
+ args: Record<string, unknown>;
49
+ /** Command name for metadata */
50
+ commandName: string;
51
+ /** Base command for building follow-up commands (e.g., "prlt ticket create") */
52
+ baseCommand: string;
53
+ /** Project ID if available */
54
+ projectId?: string;
55
+ /** Any additional custom context */
56
+ [key: string]: unknown;
57
+ }
58
+ /**
59
+ * Choice item for list/checkbox prompts
60
+ */
61
+ export interface ResolverChoice<T = string> {
62
+ /** Display text */
63
+ name: string;
64
+ /** Value returned when selected */
65
+ value: T;
66
+ /** Whether this choice is disabled */
67
+ disabled?: boolean | string;
68
+ /** Full CLI command for this choice (for JSON mode) - if not provided, auto-generated */
69
+ command?: string;
70
+ }
71
+ /**
72
+ * Definition for a single prompt that resolves a flag
73
+ */
74
+ export interface PromptDefinition<TValue = unknown, TFlags = Record<string, unknown>> {
75
+ /** The flag name this prompt resolves (e.g., 'column', 'title') */
76
+ flagName: string;
77
+ /** Prompt type */
78
+ type: 'list' | 'checkbox' | 'input' | 'confirm' | 'editor';
79
+ /** User-facing prompt message */
80
+ message: string | ((ctx: ResolverContext<TFlags>) => string);
81
+ /**
82
+ * Get choices for list/checkbox prompts.
83
+ * Can be async to fetch dynamic data.
84
+ */
85
+ choices?: (ctx: ResolverContext<TFlags>) => Promise<ResolverChoice<TValue>[]> | ResolverChoice<TValue>[];
86
+ /**
87
+ * Default value for the prompt.
88
+ * Can be a function to compute based on context.
89
+ */
90
+ default?: TValue | ((ctx: ResolverContext<TFlags>) => TValue | undefined);
91
+ /**
92
+ * Validation function for input prompts.
93
+ * Return true if valid, or error message string if invalid.
94
+ */
95
+ validate?: (value: TValue, ctx: ResolverContext<TFlags>) => boolean | string;
96
+ /**
97
+ * Conditional function - prompt is skipped if this returns false.
98
+ * Use for prompts that depend on other flags.
99
+ */
100
+ when?: (ctx: ResolverContext<TFlags>) => boolean;
101
+ /**
102
+ * Transform the flag value before storing.
103
+ * Useful for parsing/formatting.
104
+ */
105
+ transform?: (value: TValue, ctx: ResolverContext<TFlags>) => unknown;
106
+ /**
107
+ * For JSON mode: additional context to include in the prompt output.
108
+ * Useful for providing hints, examples, etc.
109
+ */
110
+ context?: Record<string, unknown> | ((ctx: ResolverContext<TFlags>) => Record<string, unknown>);
111
+ /**
112
+ * For JSON mode: generate the command string for a specific choice.
113
+ * If not provided, auto-generates based on flagName and value.
114
+ */
115
+ getCommand?: (value: TValue, ctx: ResolverContext<TFlags>) => string;
116
+ /**
117
+ * Skip auto-generating commands for choices (useful when choices already have custom commands)
118
+ */
119
+ skipAutoCommand?: boolean;
120
+ }
121
+ /**
122
+ * Options for creating a FlagResolver
123
+ */
124
+ export interface FlagResolverOptions<TFlags extends Record<string, unknown>> {
125
+ /** Command name for metadata (e.g., "ticket create") */
126
+ commandName: string;
127
+ /** Base command for building commands (e.g., "prlt ticket create") */
128
+ baseCommand: string;
129
+ /** Whether JSON mode is active */
130
+ jsonMode: boolean;
131
+ /** Initial flags from CLI parsing */
132
+ flags: Partial<TFlags>;
133
+ /** Command args */
134
+ args?: Record<string, unknown>;
135
+ /** Additional custom context */
136
+ context?: Record<string, unknown>;
137
+ }
138
+ /**
139
+ * Result of flag resolution
140
+ */
141
+ export interface ResolveResult<TFlags> {
142
+ /** The fully resolved flags */
143
+ flags: TFlags;
144
+ /** Whether all required prompts were resolved (false if user cancelled) */
145
+ complete: boolean;
146
+ }
147
+ /**
148
+ * FlagResolver handles unified flag resolution for both human and machine modes.
149
+ *
150
+ * Usage pattern:
151
+ * 1. Create resolver with command info and current flags
152
+ * 2. Add prompt definitions for flags that may need resolution
153
+ * 3. Call resolve() to get complete flags
154
+ *
155
+ * In JSON mode, resolve() outputs the first unresolved prompt and exits.
156
+ * In interactive mode, resolve() prompts for each unresolved flag sequentially.
157
+ */
158
+ export declare class FlagResolver<TFlags extends Record<string, unknown> = Record<string, unknown>> {
159
+ private prompts;
160
+ private options;
161
+ private resolvedFlags;
162
+ private resolverContext;
163
+ constructor(options: FlagResolverOptions<TFlags>);
164
+ /**
165
+ * Add a prompt definition for resolving a flag.
166
+ * Prompts are processed in the order they are added.
167
+ */
168
+ addPrompt<TValue = unknown>(prompt: PromptDefinition<TValue, TFlags>): this;
169
+ /**
170
+ * Add multiple prompt definitions at once.
171
+ */
172
+ addPrompts(prompts: PromptDefinition<unknown, TFlags>[]): this;
173
+ /**
174
+ * Update the context with additional data.
175
+ * Useful for adding computed values that prompts might need.
176
+ */
177
+ setContext(key: string, value: unknown): this;
178
+ /**
179
+ * Get current context value
180
+ */
181
+ getContext<T = unknown>(key: string): T | undefined;
182
+ /**
183
+ * Check if a flag has a value (not undefined)
184
+ */
185
+ hasFlag(flagName: keyof TFlags): boolean;
186
+ /**
187
+ * Get current flag value
188
+ */
189
+ getFlag<K extends keyof TFlags>(flagName: K): TFlags[K] | undefined;
190
+ /**
191
+ * Set a flag value directly (bypasses prompting)
192
+ */
193
+ setFlag<K extends keyof TFlags>(flagName: K, value: TFlags[K]): this;
194
+ /**
195
+ * Resolve all prompts and return complete flags.
196
+ *
197
+ * In JSON mode: outputs the first unresolved prompt as JSON and exits (never returns).
198
+ * In interactive mode: prompts for each unresolved flag and returns all flags.
199
+ *
200
+ * @returns The fully resolved flags
201
+ */
202
+ resolve(): Promise<TFlags>;
203
+ /**
204
+ * Output prompt as JSON for machine mode
205
+ */
206
+ private outputJsonPrompt;
207
+ /**
208
+ * Prompt for value in interactive mode
209
+ */
210
+ private promptInteractive;
211
+ /**
212
+ * Build a command string for a flag value
213
+ */
214
+ private buildCommand;
215
+ }
216
+ /**
217
+ * Convenience function to create a FlagResolver from command context
218
+ */
219
+ export declare function createFlagResolver<TFlags extends Record<string, unknown>>(options: FlagResolverOptions<TFlags>): FlagResolver<TFlags>;
220
+ /**
221
+ * Helper to check if we should use JSON mode
222
+ * Re-exported from prompt-json for convenience
223
+ */
224
+ export { shouldOutputJson, isMachineOutput } from '../prompt-json.js';