@proletariat/cli 0.3.95 → 0.3.97

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 (260) hide show
  1. package/dist/commands/config/index.js +1 -1
  2. package/dist/commands/config/index.js.map +1 -1
  3. package/dist/commands/db/repair.js +160 -35
  4. package/dist/commands/db/repair.js.map +1 -1
  5. package/dist/commands/gc.d.ts +14 -0
  6. package/dist/commands/gc.js +208 -0
  7. package/dist/commands/gc.js.map +1 -0
  8. package/dist/commands/linear/connect.d.ts +5 -0
  9. package/dist/commands/linear/connect.js +84 -0
  10. package/dist/commands/linear/connect.js.map +1 -1
  11. package/dist/commands/pr/merge.js +1 -1
  12. package/dist/commands/pr/merge.js.map +1 -1
  13. package/dist/commands/session/attach.d.ts +3 -3
  14. package/dist/commands/session/attach.js +37 -79
  15. package/dist/commands/session/attach.js.map +1 -1
  16. package/dist/commands/session/exec.js +1 -1
  17. package/dist/commands/session/exec.js.map +1 -1
  18. package/dist/commands/session/health.js +1 -1
  19. package/dist/commands/session/health.js.map +1 -1
  20. package/dist/commands/session/inspect.js +1 -1
  21. package/dist/commands/session/inspect.js.map +1 -1
  22. package/dist/commands/session/list.d.ts +1 -0
  23. package/dist/commands/session/list.js +111 -78
  24. package/dist/commands/session/list.js.map +1 -1
  25. package/dist/commands/session/peek.js +1 -1
  26. package/dist/commands/session/peek.js.map +1 -1
  27. package/dist/commands/session/poke.js +1 -1
  28. package/dist/commands/session/poke.js.map +1 -1
  29. package/dist/commands/session/prune.js +50 -11
  30. package/dist/commands/session/prune.js.map +1 -1
  31. package/dist/commands/session/restart.js +1 -1
  32. package/dist/commands/session/restart.js.map +1 -1
  33. package/dist/commands/session/watch.d.ts +1 -0
  34. package/dist/commands/session/watch.js +46 -2
  35. package/dist/commands/session/watch.js.map +1 -1
  36. package/dist/commands/{action → sync}/index.d.ts +2 -6
  37. package/dist/commands/sync/index.js +68 -0
  38. package/dist/commands/sync/index.js.map +1 -0
  39. package/dist/commands/sync/pause.d.ts +10 -0
  40. package/dist/commands/sync/pause.js +35 -0
  41. package/dist/commands/sync/pause.js.map +1 -0
  42. package/dist/commands/sync/queue.d.ts +10 -0
  43. package/dist/commands/sync/queue.js +106 -0
  44. package/dist/commands/sync/queue.js.map +1 -0
  45. package/dist/commands/sync/resume.d.ts +10 -0
  46. package/dist/commands/sync/resume.js +34 -0
  47. package/dist/commands/sync/resume.js.map +1 -0
  48. package/dist/commands/sync/start.d.ts +11 -0
  49. package/dist/commands/sync/start.js +73 -0
  50. package/dist/commands/sync/start.js.map +1 -0
  51. package/dist/commands/sync/status.d.ts +10 -0
  52. package/dist/commands/sync/status.js +40 -0
  53. package/dist/commands/sync/status.js.map +1 -0
  54. package/dist/commands/sync/stop.d.ts +10 -0
  55. package/dist/commands/sync/stop.js +39 -0
  56. package/dist/commands/sync/stop.js.map +1 -0
  57. package/dist/commands/ticket/create.js +1 -1
  58. package/dist/commands/ticket/create.js.map +1 -1
  59. package/dist/commands/ticket/edit.js +1 -1
  60. package/dist/commands/ticket/edit.js.map +1 -1
  61. package/dist/commands/ticket/list.js +1 -1
  62. package/dist/commands/ticket/list.js.map +1 -1
  63. package/dist/commands/ticket/update.js +1 -1
  64. package/dist/commands/ticket/update.js.map +1 -1
  65. package/dist/commands/work/complete.d.ts +1 -0
  66. package/dist/commands/work/complete.js +27 -25
  67. package/dist/commands/work/complete.js.map +1 -1
  68. package/dist/commands/work/drop.d.ts +14 -0
  69. package/dist/commands/work/drop.js +215 -0
  70. package/dist/commands/work/drop.js.map +1 -0
  71. package/dist/commands/work/ready.d.ts +1 -0
  72. package/dist/commands/work/ready.js +26 -25
  73. package/dist/commands/work/ready.js.map +1 -1
  74. package/dist/commands/work/resolve.js +1 -1
  75. package/dist/commands/work/resolve.js.map +1 -1
  76. package/dist/commands/work/ship.d.ts +1 -0
  77. package/dist/commands/work/ship.js +33 -32
  78. package/dist/commands/work/ship.js.map +1 -1
  79. package/dist/commands/work/start.d.ts +2 -0
  80. package/dist/commands/work/start.js +172 -125
  81. package/dist/commands/work/start.js.map +1 -1
  82. package/dist/commands/work/stop.d.ts +1 -0
  83. package/dist/commands/work/stop.js +40 -0
  84. package/dist/commands/work/stop.js.map +1 -1
  85. package/dist/lib/agents/commands.js +7 -5
  86. package/dist/lib/agents/commands.js.map +1 -1
  87. package/dist/lib/dashboard/data.js +1 -1
  88. package/dist/lib/dashboard/data.js.map +1 -1
  89. package/dist/lib/database/db-safety.d.ts +22 -0
  90. package/dist/lib/database/db-safety.js +91 -4
  91. package/dist/lib/database/db-safety.js.map +1 -1
  92. package/dist/lib/database/drizzle-schema.d.ts +17 -0
  93. package/dist/lib/database/drizzle-schema.js +1 -0
  94. package/dist/lib/database/drizzle-schema.js.map +1 -1
  95. package/dist/lib/database/index.d.ts +1 -1
  96. package/dist/lib/database/index.js +1 -1
  97. package/dist/lib/database/index.js.map +1 -1
  98. package/dist/lib/database/migrations/0017_drop_agent_work_fk.d.ts +13 -0
  99. package/dist/lib/database/migrations/0017_drop_agent_work_fk.js +85 -0
  100. package/dist/lib/database/migrations/0017_drop_agent_work_fk.js.map +1 -0
  101. package/dist/lib/database/migrations/0018_create_ticket_refs.d.ts +11 -0
  102. package/dist/lib/database/migrations/0018_create_ticket_refs.js +40 -0
  103. package/dist/lib/database/migrations/0018_create_ticket_refs.js.map +1 -0
  104. package/dist/lib/database/migrations/0019_gc_artifact_cleanup.d.ts +9 -0
  105. package/dist/lib/database/migrations/0019_gc_artifact_cleanup.js +23 -0
  106. package/dist/lib/database/migrations/0019_gc_artifact_cleanup.js.map +1 -0
  107. package/dist/lib/database/migrations/0020_transition_map.d.ts +2 -0
  108. package/dist/lib/database/migrations/0020_transition_map.js +27 -0
  109. package/dist/lib/database/migrations/0020_transition_map.js.map +1 -0
  110. package/dist/lib/database/migrations/index.js +8 -0
  111. package/dist/lib/database/migrations/index.js.map +1 -1
  112. package/dist/lib/execution/config.d.ts +10 -0
  113. package/dist/lib/execution/config.js +24 -0
  114. package/dist/lib/execution/config.js.map +1 -1
  115. package/dist/lib/execution/devcontainer.js +1 -1
  116. package/dist/lib/execution/devcontainer.js.map +1 -1
  117. package/dist/lib/execution/preflight.d.ts +51 -0
  118. package/dist/lib/execution/preflight.js +278 -0
  119. package/dist/lib/execution/preflight.js.map +1 -0
  120. package/dist/lib/execution/runners/docker-management.d.ts +9 -0
  121. package/dist/lib/execution/runners/docker-management.js +14 -3
  122. package/dist/lib/execution/runners/docker-management.js.map +1 -1
  123. package/dist/lib/execution/runners/prompt-builder.d.ts +6 -0
  124. package/dist/lib/execution/runners/prompt-builder.js +53 -10
  125. package/dist/lib/execution/runners/prompt-builder.js.map +1 -1
  126. package/dist/lib/execution/runners/shared.d.ts +1 -1
  127. package/dist/lib/execution/runners/shared.js +1 -1
  128. package/dist/lib/execution/runners/shared.js.map +1 -1
  129. package/dist/lib/execution/session-utils.d.ts +39 -0
  130. package/dist/lib/execution/session-utils.js +111 -0
  131. package/dist/lib/execution/session-utils.js.map +1 -1
  132. package/dist/lib/execution/spawner.d.ts +11 -1
  133. package/dist/lib/execution/spawner.js +46 -17
  134. package/dist/lib/execution/spawner.js.map +1 -1
  135. package/dist/lib/execution/storage.js +2 -1
  136. package/dist/lib/execution/storage.js.map +1 -1
  137. package/dist/lib/execution/ticket-refs.d.ts +71 -0
  138. package/dist/lib/execution/ticket-refs.js +125 -0
  139. package/dist/lib/execution/ticket-refs.js.map +1 -0
  140. package/dist/lib/execution/types.d.ts +7 -2
  141. package/dist/lib/execution/types.js +5 -3
  142. package/dist/lib/execution/types.js.map +1 -1
  143. package/dist/lib/external-issues/utils.d.ts +25 -0
  144. package/dist/lib/external-issues/utils.js +32 -0
  145. package/dist/lib/external-issues/utils.js.map +1 -0
  146. package/dist/lib/gc/index.d.ts +179 -0
  147. package/dist/lib/gc/index.js +655 -0
  148. package/dist/lib/gc/index.js.map +1 -0
  149. package/dist/lib/mcp/tools/action.js +1 -1
  150. package/dist/lib/mcp/tools/action.js.map +1 -1
  151. package/dist/lib/mcp/tools/ticket.js +1 -1
  152. package/dist/lib/mcp/tools/ticket.js.map +1 -1
  153. package/dist/lib/orchestrate/actions.js +30 -0
  154. package/dist/lib/orchestrate/actions.js.map +1 -1
  155. package/dist/lib/orchestrate/poller.js +3 -3
  156. package/dist/lib/orchestrate/poller.js.map +1 -1
  157. package/dist/lib/orchestrate/presets.js +2 -1
  158. package/dist/lib/orchestrate/presets.js.map +1 -1
  159. package/dist/lib/orchestrate/types.d.ts +1 -1
  160. package/dist/lib/orchestrate/types.js +1 -0
  161. package/dist/lib/orchestrate/types.js.map +1 -1
  162. package/dist/lib/pmo/index.js +1 -1
  163. package/dist/lib/pmo/index.js.map +1 -1
  164. package/dist/lib/pmo/markdown.js +1 -1
  165. package/dist/lib/pmo/markdown.js.map +1 -1
  166. package/dist/lib/pmo/schema.d.ts +3 -1
  167. package/dist/lib/pmo/schema.js +26 -2
  168. package/dist/lib/pmo/schema.js.map +1 -1
  169. package/dist/lib/pmo/storage/actions.js +1 -1
  170. package/dist/lib/pmo/storage/actions.js.map +1 -1
  171. package/dist/lib/pmo/storage/base.js +37 -15
  172. package/dist/lib/pmo/storage/base.js.map +1 -1
  173. package/dist/lib/pmo/storage/projects.js +2 -1
  174. package/dist/lib/pmo/storage/projects.js.map +1 -1
  175. package/dist/lib/pmo/storage/statuses.js +1 -1
  176. package/dist/lib/pmo/storage/statuses.js.map +1 -1
  177. package/dist/lib/pmo/storage/subtasks.js +1 -1
  178. package/dist/lib/pmo/storage/subtasks.js.map +1 -1
  179. package/dist/lib/pmo/storage/templates.js +1 -1
  180. package/dist/lib/pmo/storage/templates.js.map +1 -1
  181. package/dist/lib/pmo/storage/tickets.js +2 -1
  182. package/dist/lib/pmo/storage/tickets.js.map +1 -1
  183. package/dist/lib/pmo/storage/workflow-rules.js +1 -1
  184. package/dist/lib/pmo/storage/workflow-rules.js.map +1 -1
  185. package/dist/lib/pmo/utils.d.ts +6 -189
  186. package/dist/lib/pmo/utils.js +6 -306
  187. package/dist/lib/pmo/utils.js.map +1 -1
  188. package/dist/lib/prompt-json.d.ts +31 -0
  189. package/dist/lib/prompt-json.js.map +1 -1
  190. package/dist/lib/providers/auto-mapper.d.ts +45 -0
  191. package/dist/lib/providers/auto-mapper.js +115 -0
  192. package/dist/lib/providers/auto-mapper.js.map +1 -0
  193. package/dist/lib/providers/state-intents.d.ts +20 -0
  194. package/dist/lib/providers/state-intents.js +61 -7
  195. package/dist/lib/providers/state-intents.js.map +1 -1
  196. package/dist/lib/providers/state-resolution.d.ts +15 -11
  197. package/dist/lib/providers/state-resolution.js +54 -48
  198. package/dist/lib/providers/state-resolution.js.map +1 -1
  199. package/dist/lib/providers/transition-map.d.ts +59 -0
  200. package/dist/lib/providers/transition-map.js +113 -0
  201. package/dist/lib/providers/transition-map.js.map +1 -0
  202. package/dist/lib/session/heartbeat.js +1 -1
  203. package/dist/lib/session/heartbeat.js.map +1 -1
  204. package/dist/lib/session/index.d.ts +3 -1
  205. package/dist/lib/session/index.js +3 -1
  206. package/dist/lib/session/index.js.map +1 -1
  207. package/dist/lib/session/tmux-watchdog.d.ts +157 -0
  208. package/dist/lib/session/tmux-watchdog.js +424 -0
  209. package/dist/lib/session/tmux-watchdog.js.map +1 -0
  210. package/dist/lib/session/watcher.d.ts +22 -4
  211. package/dist/lib/session/watcher.js +66 -8
  212. package/dist/lib/session/watcher.js.map +1 -1
  213. package/dist/lib/sync/daemon-process.d.ts +9 -0
  214. package/dist/lib/sync/daemon-process.js +184 -0
  215. package/dist/lib/sync/daemon-process.js.map +1 -0
  216. package/dist/lib/sync/daemon.d.ts +39 -0
  217. package/dist/lib/sync/daemon.js +91 -0
  218. package/dist/lib/sync/daemon.js.map +1 -0
  219. package/dist/lib/sync/engine.d.ts +38 -0
  220. package/dist/lib/sync/engine.js +145 -0
  221. package/dist/lib/sync/engine.js.map +1 -0
  222. package/dist/lib/sync/merge-queue.d.ts +116 -0
  223. package/dist/lib/sync/merge-queue.js +321 -0
  224. package/dist/lib/sync/merge-queue.js.map +1 -0
  225. package/dist/lib/sync/reconciler.d.ts +44 -0
  226. package/dist/lib/sync/reconciler.js +88 -0
  227. package/dist/lib/sync/reconciler.js.map +1 -0
  228. package/dist/lib/utils/text.d.ts +44 -0
  229. package/dist/lib/utils/text.js +72 -0
  230. package/dist/lib/utils/text.js.map +1 -0
  231. package/dist/lib/work-lifecycle/post-execution.js +1 -1
  232. package/dist/lib/work-lifecycle/post-execution.js.map +1 -1
  233. package/dist/lib/work-lifecycle/settings.d.ts +138 -0
  234. package/dist/lib/work-lifecycle/settings.js +213 -0
  235. package/dist/lib/work-lifecycle/settings.js.map +1 -0
  236. package/dist/lib/work-lifecycle/transition.d.ts +73 -0
  237. package/dist/lib/work-lifecycle/transition.js +124 -0
  238. package/dist/lib/work-lifecycle/transition.js.map +1 -0
  239. package/oclif.manifest.json +3235 -3380
  240. package/package.json +1 -1
  241. package/dist/commands/action/create.d.ts +0 -26
  242. package/dist/commands/action/create.js +0 -245
  243. package/dist/commands/action/create.js.map +0 -1
  244. package/dist/commands/action/delete.d.ts +0 -18
  245. package/dist/commands/action/delete.js +0 -78
  246. package/dist/commands/action/delete.js.map +0 -1
  247. package/dist/commands/action/index.js +0 -103
  248. package/dist/commands/action/index.js.map +0 -1
  249. package/dist/commands/action/list.d.ts +0 -15
  250. package/dist/commands/action/list.js +0 -90
  251. package/dist/commands/action/list.js.map +0 -1
  252. package/dist/commands/action/run.d.ts +0 -20
  253. package/dist/commands/action/run.js +0 -188
  254. package/dist/commands/action/run.js.map +0 -1
  255. package/dist/commands/action/show.d.ts +0 -17
  256. package/dist/commands/action/show.js +0 -78
  257. package/dist/commands/action/show.js.map +0 -1
  258. package/dist/commands/action/update.d.ts +0 -27
  259. package/dist/commands/action/update.js +0 -288
  260. package/dist/commands/action/update.js.map +0 -1
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Board Sync Reconciler
3
+ *
4
+ * Core reconciliation logic that detects drift between GitHub PR state
5
+ * and ticket provider state, then produces corrective actions.
6
+ *
7
+ * Provider-agnostic: works with any ticket provider (Linear, PMO, etc.)
8
+ * and any git host that exposes PR info.
9
+ *
10
+ * Reconciliation rules:
11
+ * 1. Merged PR + ticket not Done → move to Done
12
+ * 2. Green CI + ticket In Progress → move to Review
13
+ * 3. Ticket In Progress + no active agent → flag as stale
14
+ * 4. Ticket In Review + PR closed (not merged) → move to Backlog
15
+ */
16
+ // =============================================================================
17
+ // Reconciler
18
+ // =============================================================================
19
+ /**
20
+ * Determine reconciliation actions for a single ticket.
21
+ */
22
+ export function reconcileTicket(ctx) {
23
+ const { ticket, pr, checks, hasActiveExecution } = ctx;
24
+ const category = ticket.statusCategory;
25
+ // Rule 1: Merged PR + ticket not Done → move to Done
26
+ if (pr?.state === 'MERGED' && category !== 'completed' && category !== 'canceled') {
27
+ return {
28
+ type: 'move_to_done',
29
+ ticketId: ticket.id,
30
+ ticketTitle: ticket.title,
31
+ reason: `PR #${pr.number} is merged but ticket is still in ${ticket.statusName ?? category}`,
32
+ targetStatus: 'Done',
33
+ };
34
+ }
35
+ // Rule 4: Ticket in review + PR closed (not merged) → move to Backlog
36
+ // Check this before rule 2 since a closed PR should take precedence
37
+ if (pr?.state === 'CLOSED' && category === 'started' && isReviewStatus(ticket)) {
38
+ return {
39
+ type: 'move_to_backlog',
40
+ ticketId: ticket.id,
41
+ ticketTitle: ticket.title,
42
+ reason: `PR #${pr.number} was closed without merging`,
43
+ targetStatus: 'Backlog',
44
+ };
45
+ }
46
+ // Rule 2: Green CI + ticket In Progress → move to Review
47
+ if (pr?.state === 'OPEN' &&
48
+ !pr.isDraft &&
49
+ category === 'started' &&
50
+ !isReviewStatus(ticket) &&
51
+ checks.length > 0 &&
52
+ allChecksGreen(checks)) {
53
+ return {
54
+ type: 'move_to_review',
55
+ ticketId: ticket.id,
56
+ ticketTitle: ticket.title,
57
+ reason: `PR #${pr.number} has all CI checks passing`,
58
+ targetStatus: 'Review',
59
+ };
60
+ }
61
+ // Rule 3: Ticket In Progress + no active agent + no open PR → flag as stale
62
+ if (category === 'started' &&
63
+ !isReviewStatus(ticket) &&
64
+ !hasActiveExecution &&
65
+ (!pr || pr.state === 'CLOSED')) {
66
+ return {
67
+ type: 'flag_stale',
68
+ ticketId: ticket.id,
69
+ ticketTitle: ticket.title,
70
+ reason: 'No active agent and no open PR',
71
+ };
72
+ }
73
+ return null;
74
+ }
75
+ /**
76
+ * Check if all CI checks have passed.
77
+ */
78
+ function allChecksGreen(checks) {
79
+ return checks.every(c => c.conclusion === 'SUCCESS' || c.conclusion === 'NEUTRAL' || c.conclusion === 'SKIPPED');
80
+ }
81
+ /**
82
+ * Check if a ticket is in a review-like status.
83
+ */
84
+ function isReviewStatus(ticket) {
85
+ const name = (ticket.statusName ?? '').toLowerCase();
86
+ return name.includes('review') || name.includes('in review');
87
+ }
88
+ //# sourceMappingURL=reconciler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reconciler.js","sourceRoot":"","sources":["../../../src/lib/sync/reconciler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAqCH,gFAAgF;AAChF,aAAa;AACb,gFAAgF;AAEhF;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,GAAqB;IACnD,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,kBAAkB,EAAE,GAAG,GAAG,CAAA;IACtD,MAAM,QAAQ,GAAG,MAAM,CAAC,cAAc,CAAA;IAEtC,qDAAqD;IACrD,IAAI,EAAE,EAAE,KAAK,KAAK,QAAQ,IAAI,QAAQ,KAAK,WAAW,IAAI,QAAQ,KAAK,UAAU,EAAE,CAAC;QAClF,OAAO;YACL,IAAI,EAAE,cAAc;YACpB,QAAQ,EAAE,MAAM,CAAC,EAAE;YACnB,WAAW,EAAE,MAAM,CAAC,KAAK;YACzB,MAAM,EAAE,OAAO,EAAE,CAAC,MAAM,qCAAqC,MAAM,CAAC,UAAU,IAAI,QAAQ,EAAE;YAC5F,YAAY,EAAE,MAAM;SACrB,CAAA;IACH,CAAC;IAED,sEAAsE;IACtE,oEAAoE;IACpE,IAAI,EAAE,EAAE,KAAK,KAAK,QAAQ,IAAI,QAAQ,KAAK,SAAS,IAAI,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC;QAC/E,OAAO;YACL,IAAI,EAAE,iBAAiB;YACvB,QAAQ,EAAE,MAAM,CAAC,EAAE;YACnB,WAAW,EAAE,MAAM,CAAC,KAAK;YACzB,MAAM,EAAE,OAAO,EAAE,CAAC,MAAM,6BAA6B;YACrD,YAAY,EAAE,SAAS;SACxB,CAAA;IACH,CAAC;IAED,yDAAyD;IACzD,IACE,EAAE,EAAE,KAAK,KAAK,MAAM;QACpB,CAAC,EAAE,CAAC,OAAO;QACX,QAAQ,KAAK,SAAS;QACtB,CAAC,cAAc,CAAC,MAAM,CAAC;QACvB,MAAM,CAAC,MAAM,GAAG,CAAC;QACjB,cAAc,CAAC,MAAM,CAAC,EACtB,CAAC;QACD,OAAO;YACL,IAAI,EAAE,gBAAgB;YACtB,QAAQ,EAAE,MAAM,CAAC,EAAE;YACnB,WAAW,EAAE,MAAM,CAAC,KAAK;YACzB,MAAM,EAAE,OAAO,EAAE,CAAC,MAAM,4BAA4B;YACpD,YAAY,EAAE,QAAQ;SACvB,CAAA;IACH,CAAC;IAED,4EAA4E;IAC5E,IACE,QAAQ,KAAK,SAAS;QACtB,CAAC,cAAc,CAAC,MAAM,CAAC;QACvB,CAAC,kBAAkB;QACnB,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,KAAK,KAAK,QAAQ,CAAC,EAC9B,CAAC;QACD,OAAO;YACL,IAAI,EAAE,YAAY;YAClB,QAAQ,EAAE,MAAM,CAAC,EAAE;YACnB,WAAW,EAAE,MAAM,CAAC,KAAK;YACzB,MAAM,EAAE,gCAAgC;SACzC,CAAA;IACH,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC;AAED;;GAEG;AACH,SAAS,cAAc,CAAC,MAAiB;IACvC,OAAO,MAAM,CAAC,KAAK,CACjB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,SAAS,IAAI,CAAC,CAAC,UAAU,KAAK,SAAS,IAAI,CAAC,CAAC,UAAU,KAAK,SAAS,CAC5F,CAAA;AACH,CAAC;AAED;;GAEG;AACH,SAAS,cAAc,CAAC,MAAc;IACpC,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAA;IACpD,OAAO,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAA;AAC9D,CAAC"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Text and general-purpose utility functions.
3
+ */
4
+ /**
5
+ * Convert a string to a URL-safe slug
6
+ */
7
+ export declare function slugify(text: string): string;
8
+ /**
9
+ * Format a date as ISO string (date only)
10
+ */
11
+ export declare function formatDate(date: Date): string;
12
+ /**
13
+ * Format a date as ISO timestamp
14
+ */
15
+ export declare function formatTimestamp(date: Date): string;
16
+ /**
17
+ * Parse an ISO date string
18
+ */
19
+ export declare function parseDate(str: string): Date;
20
+ /**
21
+ * Parsed entity ID components
22
+ */
23
+ export interface ParsedEntityId {
24
+ entityType: string;
25
+ number: number;
26
+ raw: string;
27
+ }
28
+ /**
29
+ * Parse an entity ID into its components.
30
+ *
31
+ * Format: TKT-001 → { entityType: 'TKT', number: 1 }
32
+ *
33
+ * @param id - Entity ID to parse
34
+ * @returns Parsed components, or null if invalid format
35
+ */
36
+ export declare function parseEntityId(id: string): ParsedEntityId | null;
37
+ /**
38
+ * Deep clone an object
39
+ */
40
+ export declare function deepClone<T>(obj: T): T;
41
+ /**
42
+ * Check if two arrays have the same elements (order-independent)
43
+ */
44
+ export declare function arraysEqual<T>(a: T[], b: T[]): boolean;
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Text and general-purpose utility functions.
3
+ */
4
+ /**
5
+ * Convert a string to a URL-safe slug
6
+ */
7
+ export function slugify(text) {
8
+ return text
9
+ .toLowerCase()
10
+ .trim()
11
+ .replace(/[^\w\s-]/g, '') // Remove non-word chars (except spaces and hyphens)
12
+ .replace(/[\s_]+/g, '-') // Replace spaces and underscores with hyphens
13
+ .replace(/-+/g, '-') // Replace multiple hyphens with single hyphen
14
+ .replace(/^-+|-+$/g, '') // Remove leading/trailing hyphens
15
+ .substring(0, 100); // Limit length
16
+ }
17
+ /**
18
+ * Format a date as ISO string (date only)
19
+ */
20
+ export function formatDate(date) {
21
+ return date.toISOString().split('T')[0];
22
+ }
23
+ /**
24
+ * Format a date as ISO timestamp
25
+ */
26
+ export function formatTimestamp(date) {
27
+ return date.toISOString();
28
+ }
29
+ /**
30
+ * Parse an ISO date string
31
+ */
32
+ export function parseDate(str) {
33
+ return new Date(str);
34
+ }
35
+ /**
36
+ * Parse an entity ID into its components.
37
+ *
38
+ * Format: TKT-001 → { entityType: 'TKT', number: 1 }
39
+ *
40
+ * @param id - Entity ID to parse
41
+ * @returns Parsed components, or null if invalid format
42
+ */
43
+ export function parseEntityId(id) {
44
+ if (!id)
45
+ return null;
46
+ const match = id.match(/^([A-Z]+)-(\d+)$/);
47
+ if (match) {
48
+ return {
49
+ entityType: match[1],
50
+ number: parseInt(match[2], 10),
51
+ raw: id,
52
+ };
53
+ }
54
+ return null;
55
+ }
56
+ /**
57
+ * Deep clone an object
58
+ */
59
+ export function deepClone(obj) {
60
+ return JSON.parse(JSON.stringify(obj));
61
+ }
62
+ /**
63
+ * Check if two arrays have the same elements (order-independent)
64
+ */
65
+ export function arraysEqual(a, b) {
66
+ if (a.length !== b.length)
67
+ return false;
68
+ const sortedA = [...a].sort();
69
+ const sortedB = [...b].sort();
70
+ return sortedA.every((val, idx) => val === sortedB[idx]);
71
+ }
72
+ //# sourceMappingURL=text.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text.js","sourceRoot":"","sources":["../../../src/lib/utils/text.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,MAAM,UAAU,OAAO,CAAC,IAAY;IAClC,OAAO,IAAI;SACR,WAAW,EAAE;SACb,IAAI,EAAE;SACN,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,oDAAoD;SAC7E,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,CAAG,8CAA8C;SACxE,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAO,8CAA8C;SACxE,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAG,kCAAkC;SAC5D,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA,CAAS,eAAe;AAC9C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,IAAU;IACnC,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA;AACzC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,IAAU;IACxC,OAAO,IAAI,CAAC,WAAW,EAAE,CAAA;AAC3B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,SAAS,CAAC,GAAW;IACnC,OAAO,IAAI,IAAI,CAAC,GAAG,CAAC,CAAA;AACtB,CAAC;AAWD;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAAC,EAAU;IACtC,IAAI,CAAC,EAAE;QAAE,OAAO,IAAI,CAAC;IAErB,MAAM,KAAK,GAAG,EAAE,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;IAC3C,IAAI,KAAK,EAAE,CAAC;QACV,OAAO;YACL,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC;YACpB,MAAM,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;YAC9B,GAAG,EAAE,EAAE;SACR,CAAC;IACJ,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,SAAS,CAAI,GAAM;IACjC,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAA;AACxC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAI,CAAM,EAAE,CAAM;IAC3C,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM;QAAE,OAAO,KAAK,CAAA;IACvC,MAAM,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;IAC7B,MAAM,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;IAC7B,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC,CAAA;AAC1D,CAAC"}
@@ -13,7 +13,7 @@
13
13
  * (Linear, Jira, etc.) — not through the local PMO as a cache layer.
14
14
  * The local PMO is just the default provider for users without integrations.
15
15
  */
16
- import { getWorkColumnSetting, findColumnByName, getReviewGateSetting } from '../pmo/utils.js';
16
+ import { getWorkColumnSetting, findColumnByName, getReviewGateSetting } from './settings.js';
17
17
  import { resolveTicketProvider } from '../providers/resolver.js';
18
18
  import { tryValidateCommits } from '../execution/commit-validation.js';
19
19
  import { moveWithProvider } from '../providers/state-resolution.js';
@@ -1 +1 @@
1
- {"version":3,"file":"post-execution.js","sourceRoot":"","sources":["../../../src/lib/work-lifecycle/post-execution.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"post-execution.js","sourceRoot":"","sources":["../../../src/lib/work-lifecycle/post-execution.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,138 @@
1
+ /**
2
+ * Work lifecycle settings — column, priority, and review gate configuration.
3
+ */
4
+ import type { ReviewGateMode } from '../pmo/types.js';
5
+ /**
6
+ * Database interface for settings access (compatible with better-sqlite3)
7
+ */
8
+ interface DatabaseLike {
9
+ prepare(sql: string): {
10
+ get(...params: unknown[]): unknown;
11
+ run(...params: unknown[]): unknown;
12
+ };
13
+ }
14
+ /**
15
+ * Default column names for work commands (Linear-style workflow)
16
+ *
17
+ * Linear-style: Backlog → Planned → In Progress → Review → Done
18
+ * - planned: Move tickets here when scheduled/assigned
19
+ * - in_progress: Move tickets here when work starts
20
+ * - review: Move tickets here when work is ready for review
21
+ * - done: Move tickets here when work is complete (reviewed/merged)
22
+ */
23
+ export declare const DEFAULT_WORK_COLUMNS: {
24
+ readonly planned: "Planned";
25
+ readonly in_progress: "In Progress";
26
+ readonly review: "Review";
27
+ readonly done: "Done";
28
+ };
29
+ export type WorkColumnType = keyof typeof DEFAULT_WORK_COLUMNS;
30
+ /**
31
+ * Get a work column setting from pmo_settings with fallback to default.
32
+ * Column matching is case-insensitive.
33
+ *
34
+ * Settings keys:
35
+ * - column_in_progress: Column to move tickets to when work starts
36
+ * - column_review: Column to move tickets to when work is ready for review
37
+ * - column_done: Column to move tickets to when work is complete
38
+ *
39
+ * @param db - Database instance
40
+ * @param columnType - Type of column (in_progress, review, done)
41
+ * @returns The configured column name, or the default if not set
42
+ */
43
+ export declare function getWorkColumnSetting(db: DatabaseLike, columnType: WorkColumnType): string;
44
+ /**
45
+ * Set a work column setting in pmo_settings.
46
+ *
47
+ * @param db - Database instance
48
+ * @param columnType - Type of column (in_progress, review, done)
49
+ * @param columnName - Name of the column to use
50
+ */
51
+ export declare function setWorkColumnSetting(db: DatabaseLike, columnType: WorkColumnType, columnName: string): void;
52
+ /**
53
+ * Find a column by configured name (case-insensitive match).
54
+ * Returns the actual column name from the board if found, null otherwise.
55
+ *
56
+ * @param columnNames - Array of column names from the board
57
+ * @param targetColumn - The column name to find (from settings or default)
58
+ * @returns The matching column name, or null if not found
59
+ */
60
+ export declare function findColumnByName(columnNames: string[], targetColumn: string): string | null;
61
+ /**
62
+ * Default priority scale (backwards compatible with hardcoded P0-P3).
63
+ */
64
+ export declare const DEFAULT_PRIORITIES: readonly ["P0", "P1", "P2", "P3"];
65
+ /**
66
+ * Get the workspace priority scale from pmo_settings.
67
+ * Returns the user-defined priority scale, or DEFAULT_PRIORITIES if not set.
68
+ *
69
+ * Priority values are ordered strings - position in array determines sort order.
70
+ * Index 0 is highest priority.
71
+ *
72
+ * @param db - Database instance
73
+ * @returns Array of priority strings ordered from highest to lowest
74
+ */
75
+ export declare function getWorkspacePriorities(db: DatabaseLike): string[];
76
+ /**
77
+ * Set the workspace priority scale in pmo_settings.
78
+ *
79
+ * @param db - Database instance
80
+ * @param priorities - Array of priority strings ordered from highest to lowest
81
+ */
82
+ export declare function setWorkspacePriorities(db: DatabaseLike, priorities: string[]): void;
83
+ /**
84
+ * Check if a value is a valid priority for the workspace.
85
+ *
86
+ * @param db - Database instance
87
+ * @param value - Value to check
88
+ * @returns true if the value is in the workspace priority scale
89
+ */
90
+ export declare function isValidWorkspacePriority(db: DatabaseLike, value: string): boolean;
91
+ /**
92
+ * Get the sort index for a priority value.
93
+ * Returns the position in the priority array (0 = highest priority).
94
+ * Returns Infinity for unknown priorities (sorts last).
95
+ *
96
+ * @param db - Database instance
97
+ * @param value - Priority value
98
+ * @returns Sort index (lower = higher priority)
99
+ */
100
+ export declare function getPrioritySortIndex(db: DatabaseLike, value: string | undefined | null): number;
101
+ /**
102
+ * Valid review gate modes.
103
+ */
104
+ export declare const REVIEW_GATE_MODES: readonly ReviewGateMode[];
105
+ /**
106
+ * Default review gate mode for workspace.
107
+ */
108
+ export declare const DEFAULT_REVIEW_GATE: ReviewGateMode;
109
+ /**
110
+ * Get the workspace review gate default from pmo_settings.
111
+ * Returns the configured mode, or 'required' if not set.
112
+ *
113
+ * @param db - Database instance
114
+ * @returns The configured review gate mode
115
+ */
116
+ export declare function getReviewGateSetting(db: DatabaseLike): ReviewGateMode;
117
+ /**
118
+ * Set the workspace review gate default in pmo_settings.
119
+ *
120
+ * @param db - Database instance
121
+ * @param mode - Review gate mode to set
122
+ */
123
+ export declare function setReviewGateSetting(db: DatabaseLike, mode: ReviewGateMode): void;
124
+ /**
125
+ * Check if a value is a valid review gate mode.
126
+ */
127
+ export declare function isValidReviewGateMode(value: string): value is ReviewGateMode;
128
+ /**
129
+ * Resolve the effective review gate mode given the hierarchy of overrides.
130
+ * Most specific wins: per-spawn > per-action > workspace default.
131
+ *
132
+ * @param spawnOverride - Value from --review-gate flag on `prlt work start`
133
+ * @param actionOverride - Value from the action's review_gate column
134
+ * @param db - Database instance for workspace default lookup
135
+ * @returns The resolved review gate mode
136
+ */
137
+ export declare function resolveReviewGate(spawnOverride: ReviewGateMode | undefined, actionOverride: ReviewGateMode | undefined, db: DatabaseLike): ReviewGateMode;
138
+ export {};
@@ -0,0 +1,213 @@
1
+ /**
2
+ * Work lifecycle settings — column, priority, and review gate configuration.
3
+ */
4
+ // =============================================================================
5
+ // Work Column Settings
6
+ // =============================================================================
7
+ /**
8
+ * Default column names for work commands (Linear-style workflow)
9
+ *
10
+ * Linear-style: Backlog → Planned → In Progress → Review → Done
11
+ * - planned: Move tickets here when scheduled/assigned
12
+ * - in_progress: Move tickets here when work starts
13
+ * - review: Move tickets here when work is ready for review
14
+ * - done: Move tickets here when work is complete (reviewed/merged)
15
+ */
16
+ export const DEFAULT_WORK_COLUMNS = {
17
+ planned: 'Planned',
18
+ in_progress: 'In Progress',
19
+ review: 'Review',
20
+ done: 'Done',
21
+ };
22
+ /**
23
+ * Get a work column setting from pmo_settings with fallback to default.
24
+ * Column matching is case-insensitive.
25
+ *
26
+ * Settings keys:
27
+ * - column_in_progress: Column to move tickets to when work starts
28
+ * - column_review: Column to move tickets to when work is ready for review
29
+ * - column_done: Column to move tickets to when work is complete
30
+ *
31
+ * @param db - Database instance
32
+ * @param columnType - Type of column (in_progress, review, done)
33
+ * @returns The configured column name, or the default if not set
34
+ */
35
+ export function getWorkColumnSetting(db, columnType) {
36
+ const settingKey = `column_${columnType}`;
37
+ const row = db.prepare(`SELECT value FROM pmo_settings WHERE key = ?`).get(settingKey);
38
+ return row?.value || DEFAULT_WORK_COLUMNS[columnType];
39
+ }
40
+ /**
41
+ * Set a work column setting in pmo_settings.
42
+ *
43
+ * @param db - Database instance
44
+ * @param columnType - Type of column (in_progress, review, done)
45
+ * @param columnName - Name of the column to use
46
+ */
47
+ export function setWorkColumnSetting(db, columnType, columnName) {
48
+ const settingKey = `column_${columnType}`;
49
+ db.prepare(`
50
+ INSERT INTO pmo_settings (key, value) VALUES (?, ?)
51
+ ON CONFLICT(key) DO UPDATE SET value = ?
52
+ `).run(settingKey, columnName, columnName);
53
+ }
54
+ /**
55
+ * Find a column by configured name (case-insensitive match).
56
+ * Returns the actual column name from the board if found, null otherwise.
57
+ *
58
+ * @param columnNames - Array of column names from the board
59
+ * @param targetColumn - The column name to find (from settings or default)
60
+ * @returns The matching column name, or null if not found
61
+ */
62
+ export function findColumnByName(columnNames, targetColumn) {
63
+ const targetLower = targetColumn.toLowerCase();
64
+ // First try exact match (case-insensitive)
65
+ const exactMatch = columnNames.find(col => col.toLowerCase() === targetLower);
66
+ if (exactMatch)
67
+ return exactMatch;
68
+ // Then try partial match (contains)
69
+ const partialMatch = columnNames.find(col => col.toLowerCase().includes(targetLower) ||
70
+ targetLower.includes(col.toLowerCase()));
71
+ return partialMatch || null;
72
+ }
73
+ // =============================================================================
74
+ // Workspace Priority Settings
75
+ // =============================================================================
76
+ /**
77
+ * Default priority scale (backwards compatible with hardcoded P0-P3).
78
+ */
79
+ export const DEFAULT_PRIORITIES = ['P0', 'P1', 'P2', 'P3'];
80
+ /**
81
+ * Settings key for storing workspace priorities.
82
+ */
83
+ const PRIORITIES_SETTING_KEY = 'priorities';
84
+ /**
85
+ * Get the workspace priority scale from pmo_settings.
86
+ * Returns the user-defined priority scale, or DEFAULT_PRIORITIES if not set.
87
+ *
88
+ * Priority values are ordered strings - position in array determines sort order.
89
+ * Index 0 is highest priority.
90
+ *
91
+ * @param db - Database instance
92
+ * @returns Array of priority strings ordered from highest to lowest
93
+ */
94
+ export function getWorkspacePriorities(db) {
95
+ const row = db.prepare(`SELECT value FROM pmo_settings WHERE key = ?`).get(PRIORITIES_SETTING_KEY);
96
+ if (!row)
97
+ return [...DEFAULT_PRIORITIES];
98
+ try {
99
+ const parsed = JSON.parse(row.value);
100
+ if (Array.isArray(parsed) && parsed.length > 0 && parsed.every((p) => typeof p === 'string')) {
101
+ return parsed;
102
+ }
103
+ return [...DEFAULT_PRIORITIES];
104
+ }
105
+ catch {
106
+ return [...DEFAULT_PRIORITIES];
107
+ }
108
+ }
109
+ /**
110
+ * Set the workspace priority scale in pmo_settings.
111
+ *
112
+ * @param db - Database instance
113
+ * @param priorities - Array of priority strings ordered from highest to lowest
114
+ */
115
+ export function setWorkspacePriorities(db, priorities) {
116
+ const value = JSON.stringify(priorities);
117
+ db.prepare(`
118
+ INSERT INTO pmo_settings (key, value) VALUES (?, ?)
119
+ ON CONFLICT(key) DO UPDATE SET value = ?
120
+ `).run(PRIORITIES_SETTING_KEY, value, value);
121
+ }
122
+ /**
123
+ * Check if a value is a valid priority for the workspace.
124
+ *
125
+ * @param db - Database instance
126
+ * @param value - Value to check
127
+ * @returns true if the value is in the workspace priority scale
128
+ */
129
+ export function isValidWorkspacePriority(db, value) {
130
+ const priorities = getWorkspacePriorities(db);
131
+ return priorities.includes(value);
132
+ }
133
+ /**
134
+ * Get the sort index for a priority value.
135
+ * Returns the position in the priority array (0 = highest priority).
136
+ * Returns Infinity for unknown priorities (sorts last).
137
+ *
138
+ * @param db - Database instance
139
+ * @param value - Priority value
140
+ * @returns Sort index (lower = higher priority)
141
+ */
142
+ export function getPrioritySortIndex(db, value) {
143
+ if (!value)
144
+ return Infinity;
145
+ const priorities = getWorkspacePriorities(db);
146
+ const index = priorities.indexOf(value);
147
+ return index !== -1 ? index : Infinity;
148
+ }
149
+ // =============================================================================
150
+ // Review Gate Settings
151
+ // =============================================================================
152
+ /**
153
+ * Valid review gate modes.
154
+ */
155
+ export const REVIEW_GATE_MODES = ['required', 'auto', 'post'];
156
+ /**
157
+ * Default review gate mode for workspace.
158
+ */
159
+ export const DEFAULT_REVIEW_GATE = 'required';
160
+ /**
161
+ * Settings key for workspace-level review gate default.
162
+ */
163
+ const REVIEW_GATE_SETTING_KEY = 'review_gate';
164
+ /**
165
+ * Get the workspace review gate default from pmo_settings.
166
+ * Returns the configured mode, or 'required' if not set.
167
+ *
168
+ * @param db - Database instance
169
+ * @returns The configured review gate mode
170
+ */
171
+ export function getReviewGateSetting(db) {
172
+ const row = db.prepare(`SELECT value FROM pmo_settings WHERE key = ?`).get(REVIEW_GATE_SETTING_KEY);
173
+ const value = row?.value;
174
+ if (value === 'required' || value === 'auto' || value === 'post') {
175
+ return value;
176
+ }
177
+ return DEFAULT_REVIEW_GATE;
178
+ }
179
+ /**
180
+ * Set the workspace review gate default in pmo_settings.
181
+ *
182
+ * @param db - Database instance
183
+ * @param mode - Review gate mode to set
184
+ */
185
+ export function setReviewGateSetting(db, mode) {
186
+ db.prepare(`
187
+ INSERT INTO pmo_settings (key, value) VALUES (?, ?)
188
+ ON CONFLICT(key) DO UPDATE SET value = ?
189
+ `).run(REVIEW_GATE_SETTING_KEY, mode, mode);
190
+ }
191
+ /**
192
+ * Check if a value is a valid review gate mode.
193
+ */
194
+ export function isValidReviewGateMode(value) {
195
+ return REVIEW_GATE_MODES.includes(value);
196
+ }
197
+ /**
198
+ * Resolve the effective review gate mode given the hierarchy of overrides.
199
+ * Most specific wins: per-spawn > per-action > workspace default.
200
+ *
201
+ * @param spawnOverride - Value from --review-gate flag on `prlt work start`
202
+ * @param actionOverride - Value from the action's review_gate column
203
+ * @param db - Database instance for workspace default lookup
204
+ * @returns The resolved review gate mode
205
+ */
206
+ export function resolveReviewGate(spawnOverride, actionOverride, db) {
207
+ if (spawnOverride)
208
+ return spawnOverride;
209
+ if (actionOverride)
210
+ return actionOverride;
211
+ return getReviewGateSetting(db);
212
+ }
213
+ //# sourceMappingURL=settings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings.js","sourceRoot":"","sources":["../../../src/lib/work-lifecycle/settings.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Work Transition Helper
3
+ *
4
+ * Shared logic for intent-based ticket transitions used by all work commands.
5
+ * Each work command specifies a transition intent, and this module resolves
6
+ * it to the correct provider state and moves the ticket.
7
+ *
8
+ * This replaces the old pattern of hardcoding column names via
9
+ * getWorkColumnSetting() + findColumnByName() in each command.
10
+ *
11
+ * Transition is best-effort: if no mapping exists, the operation still runs.
12
+ */
13
+ import type Database from 'better-sqlite3';
14
+ /**
15
+ * Minimal ticket shape needed for intent-based transitions.
16
+ * Accepts both full Ticket objects and partial objects from batch spawn paths.
17
+ */
18
+ export interface TransitionTicket {
19
+ id: string;
20
+ projectId?: string;
21
+ statusName?: string;
22
+ }
23
+ import type { ProviderStorage, TicketProvider } from '../providers/types.js';
24
+ import type { TransitionIntent } from '../providers/state-intents.js';
25
+ /**
26
+ * Result of attempting a ticket transition.
27
+ */
28
+ export interface TransitionResult {
29
+ /** Whether the ticket was moved successfully */
30
+ moved: boolean;
31
+ /** The resolved target column name, if any */
32
+ targetColumn?: string;
33
+ /** The previous column name */
34
+ previousColumn?: string;
35
+ /** Human-readable explanation of what happened */
36
+ message?: string;
37
+ }
38
+ /**
39
+ * Resolve an intent to a target column name on the board.
40
+ *
41
+ * Resolution order:
42
+ * 1. pmo_transition_map — explicit user-confirmed mappings
43
+ * 2. Legacy column settings (column_in_progress, column_review, column_done)
44
+ * 3. Built-in default column names
45
+ *
46
+ * This only resolves the name — it does not move the ticket.
47
+ */
48
+ export declare function resolveIntentToColumn(db: Database.Database, intent: TransitionIntent, providerName: string, columnNames: string[]): string | null;
49
+ /**
50
+ * Move a ticket based on a transition intent.
51
+ *
52
+ * This is the primary function work commands should call for transitions.
53
+ * It resolves the intent to a column name, moves the ticket in the local PMO,
54
+ * and optionally syncs to the external provider.
55
+ *
56
+ * @param opts.db - Database instance
57
+ * @param opts.storage - PMO storage instance
58
+ * @param opts.ticket - The ticket to move
59
+ * @param opts.intent - The transition intent
60
+ * @param opts.providerName - Provider name for transition map lookup
61
+ * @param opts.resolveProvider - Function to resolve the external ticket provider
62
+ * @param opts.log - Optional logging callback
63
+ * @returns TransitionResult
64
+ */
65
+ export declare function moveTicketByIntent(opts: {
66
+ db: Database.Database;
67
+ storage: ProviderStorage;
68
+ ticket: TransitionTicket;
69
+ intent: TransitionIntent;
70
+ providerName: string;
71
+ resolveProvider?: (ticketId: string, projectId: string) => Promise<TicketProvider>;
72
+ log?: (msg: string) => void;
73
+ }): Promise<TransitionResult>;