@proletariat/cli 0.2.0 → 0.3.1
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.
- package/README.md +561 -251
- package/bin/dev.cmd +3 -0
- package/bin/dev.js +5 -0
- package/bin/run.cmd +3 -0
- package/bin/run.js +23 -0
- package/dist/commands/action/create.d.ts +21 -0
- package/dist/commands/action/create.js +126 -0
- package/dist/commands/action/delete.d.ts +17 -0
- package/dist/commands/action/delete.js +78 -0
- package/dist/commands/action/index.d.ts +15 -0
- package/dist/commands/action/index.js +107 -0
- package/dist/commands/action/list.d.ts +14 -0
- package/dist/commands/action/list.js +89 -0
- package/dist/commands/action/run.d.ts +19 -0
- package/dist/commands/action/run.js +179 -0
- package/dist/commands/action/show.d.ts +15 -0
- package/dist/commands/action/show.js +47 -0
- package/dist/commands/action/update.d.ts +22 -0
- package/dist/commands/action/update.js +168 -0
- package/dist/commands/agent/index.d.ts +13 -0
- package/dist/commands/agent/index.js +131 -0
- package/dist/commands/agent/list.d.ts +7 -0
- package/dist/commands/agent/list.js +126 -0
- package/dist/commands/agent/login.d.ts +16 -0
- package/dist/commands/agent/login.js +146 -0
- package/dist/commands/agent/rebuild.d.ts +18 -0
- package/dist/commands/agent/rebuild.js +133 -0
- package/dist/commands/agent/restart.d.ts +17 -0
- package/dist/commands/agent/restart.js +116 -0
- package/dist/commands/agent/shell.d.ts +23 -0
- package/dist/commands/agent/shell.js +378 -0
- package/dist/commands/agent/staff/add.d.ts +15 -0
- package/dist/commands/agent/staff/add.js +281 -0
- package/dist/commands/agent/staff/index.d.ts +14 -0
- package/dist/commands/agent/staff/index.js +90 -0
- package/dist/commands/agent/staff/list.d.ts +7 -0
- package/dist/commands/agent/staff/list.js +90 -0
- package/dist/commands/agent/staff/remove.d.ts +16 -0
- package/dist/commands/agent/staff/remove.js +137 -0
- package/dist/commands/agent/status.d.ts +17 -0
- package/dist/commands/agent/status.js +139 -0
- package/dist/commands/agent/temp/cleanup.d.ts +23 -0
- package/dist/commands/agent/temp/cleanup.js +388 -0
- package/dist/commands/agent/temp/index.d.ts +14 -0
- package/dist/commands/agent/temp/index.js +82 -0
- package/dist/commands/agent/temp/list.d.ts +7 -0
- package/dist/commands/agent/temp/list.js +108 -0
- package/dist/commands/agent/themes/add-names.d.ts +10 -0
- package/dist/commands/agent/themes/add-names.js +67 -0
- package/dist/commands/agent/themes/create.d.ts +13 -0
- package/dist/commands/agent/themes/create.js +66 -0
- package/dist/commands/agent/themes/index.d.ts +9 -0
- package/dist/commands/agent/themes/index.js +194 -0
- package/dist/commands/agent/themes/list.d.ts +6 -0
- package/dist/commands/agent/themes/list.js +41 -0
- package/dist/commands/agent/themes/set.d.ts +12 -0
- package/dist/commands/agent/themes/set.js +77 -0
- package/dist/commands/agent/visit.d.ts +16 -0
- package/dist/commands/agent/visit.js +88 -0
- package/dist/commands/autocomplete/setup.d.ts +14 -0
- package/dist/commands/autocomplete/setup.js +154 -0
- package/dist/commands/board/index.d.ts +17 -0
- package/dist/commands/board/index.js +255 -0
- package/dist/commands/board/watch.d.ts +13 -0
- package/dist/commands/board/watch.js +52 -0
- package/dist/commands/branch/create.d.ts +50 -0
- package/dist/commands/branch/create.js +624 -0
- package/dist/commands/branch/index.d.ts +13 -0
- package/dist/commands/branch/index.js +50 -0
- package/dist/commands/branch/list.d.ts +17 -0
- package/dist/commands/branch/list.js +120 -0
- package/dist/commands/branch/validate.d.ts +15 -0
- package/dist/commands/branch/validate.js +73 -0
- package/dist/commands/commit.d.ts +71 -0
- package/dist/commands/commit.js +499 -0
- package/dist/commands/docker/clean.d.ts +13 -0
- package/dist/commands/docker/clean.js +224 -0
- package/dist/commands/docker/index.d.ts +19 -0
- package/dist/commands/docker/index.js +274 -0
- package/dist/commands/docker/list.d.ts +16 -0
- package/dist/commands/docker/list.js +200 -0
- package/dist/commands/docker/logs.d.ts +14 -0
- package/dist/commands/docker/logs.js +118 -0
- package/dist/commands/docker/prune.d.ts +14 -0
- package/dist/commands/docker/prune.js +211 -0
- package/dist/commands/docker/restart.d.ts +14 -0
- package/dist/commands/docker/restart.js +129 -0
- package/dist/commands/docker/shell.d.ts +14 -0
- package/dist/commands/docker/shell.js +103 -0
- package/dist/commands/docker/start.d.ts +12 -0
- package/dist/commands/docker/start.js +92 -0
- package/dist/commands/docker/status.d.ts +7 -0
- package/dist/commands/docker/status.js +40 -0
- package/dist/commands/docker/stop.d.ts +14 -0
- package/dist/commands/docker/stop.js +134 -0
- package/dist/commands/docker/sync.d.ts +15 -0
- package/dist/commands/docker/sync.js +112 -0
- package/dist/commands/epic/activate.d.ts +13 -0
- package/dist/commands/epic/activate.js +118 -0
- package/dist/commands/epic/archive.d.ts +14 -0
- package/dist/commands/epic/archive.js +132 -0
- package/dist/commands/epic/create.d.ts +15 -0
- package/dist/commands/epic/create.js +137 -0
- package/dist/commands/epic/index.d.ts +13 -0
- package/dist/commands/epic/index.js +88 -0
- package/dist/commands/epic/link/block.d.ts +14 -0
- package/dist/commands/epic/link/block.js +79 -0
- package/dist/commands/epic/link/duplicates.d.ts +14 -0
- package/dist/commands/epic/link/duplicates.js +66 -0
- package/dist/commands/epic/link/index.d.ts +19 -0
- package/dist/commands/epic/link/index.js +242 -0
- package/dist/commands/epic/link/relates.d.ts +14 -0
- package/dist/commands/epic/link/relates.js +66 -0
- package/dist/commands/epic/link/remove.d.ts +16 -0
- package/dist/commands/epic/link/remove.js +89 -0
- package/dist/commands/epic/list.d.ts +11 -0
- package/dist/commands/epic/list.js +87 -0
- package/dist/commands/epic/move.d.ts +15 -0
- package/dist/commands/epic/move.js +184 -0
- package/dist/commands/epic/progress.d.ts +16 -0
- package/dist/commands/epic/progress.js +166 -0
- package/dist/commands/epic/project.d.ts +15 -0
- package/dist/commands/epic/project.js +219 -0
- package/dist/commands/epic/reorder.d.ts +21 -0
- package/dist/commands/epic/reorder.js +160 -0
- package/dist/commands/epic/spec.d.ts +15 -0
- package/dist/commands/epic/spec.js +191 -0
- package/dist/commands/epic/ticket.d.ts +18 -0
- package/dist/commands/epic/ticket.js +291 -0
- package/dist/commands/epic/view.d.ts +13 -0
- package/dist/commands/epic/view.js +117 -0
- package/dist/commands/execution/index.d.ts +13 -0
- package/dist/commands/execution/index.js +70 -0
- package/dist/commands/execution/list.d.ts +15 -0
- package/dist/commands/execution/list.js +144 -0
- package/dist/commands/execution/logs.d.ts +18 -0
- package/dist/commands/execution/logs.js +161 -0
- package/dist/commands/execution/stop.d.ts +22 -0
- package/dist/commands/execution/stop.js +248 -0
- package/dist/commands/gh/index.d.ts +9 -0
- package/dist/commands/gh/index.js +53 -0
- package/dist/commands/gh/login.d.ts +6 -0
- package/dist/commands/gh/login.js +57 -0
- package/dist/commands/gh/status.d.ts +6 -0
- package/dist/commands/gh/status.js +48 -0
- package/dist/commands/gh/token.d.ts +6 -0
- package/dist/commands/gh/token.js +59 -0
- package/dist/commands/init.d.ts +26 -0
- package/dist/commands/init.js +200 -0
- package/dist/commands/phase/create.d.ts +22 -0
- package/dist/commands/phase/create.js +123 -0
- package/dist/commands/phase/delete.d.ts +17 -0
- package/dist/commands/phase/delete.js +73 -0
- package/dist/commands/phase/list.d.ts +12 -0
- package/dist/commands/phase/list.js +76 -0
- package/dist/commands/phase/move.d.ts +17 -0
- package/dist/commands/phase/move.js +115 -0
- package/dist/commands/phase/template/apply.d.ts +17 -0
- package/dist/commands/phase/template/apply.js +106 -0
- package/dist/commands/phase/template/create.d.ts +16 -0
- package/dist/commands/phase/template/create.js +58 -0
- package/dist/commands/phase/template/delete.d.ts +17 -0
- package/dist/commands/phase/template/delete.js +98 -0
- package/dist/commands/phase/template/index.d.ts +15 -0
- package/dist/commands/phase/template/index.js +128 -0
- package/dist/commands/phase/template/list.d.ts +16 -0
- package/dist/commands/phase/template/list.js +95 -0
- package/dist/commands/phase/template/update.d.ts +17 -0
- package/dist/commands/phase/template/update.js +89 -0
- package/dist/commands/phase/update.d.ts +23 -0
- package/dist/commands/phase/update.js +174 -0
- package/dist/commands/pmo/init.d.ts +25 -0
- package/dist/commands/pmo/init.js +341 -0
- package/dist/commands/pr/create.d.ts +17 -0
- package/dist/commands/pr/create.js +242 -0
- package/dist/commands/pr/index.d.ts +9 -0
- package/dist/commands/pr/index.js +68 -0
- package/dist/commands/pr/link.d.ts +14 -0
- package/dist/commands/pr/link.js +212 -0
- package/dist/commands/pr/status.d.ts +12 -0
- package/dist/commands/pr/status.js +161 -0
- package/dist/commands/project/archive.d.ts +17 -0
- package/dist/commands/project/archive.js +83 -0
- package/dist/commands/project/create.d.ts +22 -0
- package/dist/commands/project/create.js +143 -0
- package/dist/commands/project/delete.d.ts +17 -0
- package/dist/commands/project/delete.js +128 -0
- package/dist/commands/project/index.d.ts +13 -0
- package/dist/commands/project/index.js +64 -0
- package/dist/commands/project/list.d.ts +14 -0
- package/dist/commands/project/list.js +96 -0
- package/dist/commands/project/spec.d.ts +18 -0
- package/dist/commands/project/spec.js +216 -0
- package/dist/commands/project/unarchive.d.ts +15 -0
- package/dist/commands/project/unarchive.js +35 -0
- package/dist/commands/project/view.d.ts +16 -0
- package/dist/commands/project/view.js +94 -0
- package/dist/commands/repo/add.d.ts +21 -0
- package/dist/commands/repo/add.js +118 -0
- package/dist/commands/repo/index.d.ts +13 -0
- package/dist/commands/repo/index.js +114 -0
- package/dist/commands/repo/list.d.ts +13 -0
- package/dist/commands/repo/list.js +96 -0
- package/dist/commands/repo/remove.d.ts +23 -0
- package/dist/commands/repo/remove.js +217 -0
- package/dist/commands/repo/view.d.ts +15 -0
- package/dist/commands/repo/view.js +99 -0
- package/dist/commands/session/attach.d.ts +40 -0
- package/dist/commands/session/attach.js +307 -0
- package/dist/commands/session/index.d.ts +13 -0
- package/dist/commands/session/index.js +64 -0
- package/dist/commands/session/list.d.ts +21 -0
- package/dist/commands/session/list.js +181 -0
- package/dist/commands/spec/create.d.ts +19 -0
- package/dist/commands/spec/create.js +130 -0
- package/dist/commands/spec/index.d.ts +13 -0
- package/dist/commands/spec/index.js +68 -0
- package/dist/commands/spec/link/depends.d.ts +14 -0
- package/dist/commands/spec/link/depends.js +64 -0
- package/dist/commands/spec/link/duplicates.d.ts +14 -0
- package/dist/commands/spec/link/duplicates.js +63 -0
- package/dist/commands/spec/link/index.d.ts +19 -0
- package/dist/commands/spec/link/index.js +200 -0
- package/dist/commands/spec/link/relates.d.ts +14 -0
- package/dist/commands/spec/link/relates.js +63 -0
- package/dist/commands/spec/link/remove.d.ts +16 -0
- package/dist/commands/spec/link/remove.js +94 -0
- package/dist/commands/spec/list.d.ts +12 -0
- package/dist/commands/spec/list.js +75 -0
- package/dist/commands/spec/plan.d.ts +15 -0
- package/dist/commands/spec/plan.js +108 -0
- package/dist/commands/spec/ticket.d.ts +18 -0
- package/dist/commands/spec/ticket.js +160 -0
- package/dist/commands/spec/view.d.ts +15 -0
- package/dist/commands/spec/view.js +163 -0
- package/dist/commands/status/create.d.ts +21 -0
- package/dist/commands/status/create.js +140 -0
- package/dist/commands/status/delete.d.ts +13 -0
- package/dist/commands/status/delete.js +77 -0
- package/dist/commands/status/index.d.ts +14 -0
- package/dist/commands/status/index.js +91 -0
- package/dist/commands/status/list.d.ts +12 -0
- package/dist/commands/status/list.js +93 -0
- package/dist/commands/status/move.d.ts +14 -0
- package/dist/commands/status/move.js +120 -0
- package/dist/commands/status/update.d.ts +20 -0
- package/dist/commands/status/update.js +180 -0
- package/dist/commands/template/delete.d.ts +15 -0
- package/dist/commands/template/delete.js +142 -0
- package/dist/commands/template/index.d.ts +10 -0
- package/dist/commands/template/index.js +64 -0
- package/dist/commands/template/list.d.ts +18 -0
- package/dist/commands/template/list.js +157 -0
- package/dist/commands/template/phase/apply.d.ts +14 -0
- package/dist/commands/template/phase/apply.js +41 -0
- package/dist/commands/template/phase/create.d.ts +12 -0
- package/dist/commands/template/phase/create.js +29 -0
- package/dist/commands/template/phase/delete.d.ts +13 -0
- package/dist/commands/template/phase/delete.js +34 -0
- package/dist/commands/template/phase/index.d.ts +10 -0
- package/dist/commands/template/phase/index.js +62 -0
- package/dist/commands/template/phase/list.d.ts +11 -0
- package/dist/commands/template/phase/list.js +34 -0
- package/dist/commands/template/phase/update.d.ts +13 -0
- package/dist/commands/template/phase/update.js +35 -0
- package/dist/commands/template/ticket/apply.d.ts +17 -0
- package/dist/commands/template/ticket/apply.js +58 -0
- package/dist/commands/template/ticket/delete.d.ts +13 -0
- package/dist/commands/template/ticket/delete.js +34 -0
- package/dist/commands/template/ticket/index.d.ts +10 -0
- package/dist/commands/template/ticket/index.js +62 -0
- package/dist/commands/template/ticket/list.d.ts +11 -0
- package/dist/commands/template/ticket/list.js +34 -0
- package/dist/commands/template/ticket/save.d.ts +13 -0
- package/dist/commands/template/ticket/save.js +35 -0
- package/dist/commands/ticket/bulk.d.ts +13 -0
- package/dist/commands/ticket/bulk.js +145 -0
- package/dist/commands/ticket/complete.d.ts +16 -0
- package/dist/commands/ticket/complete.js +170 -0
- package/dist/commands/ticket/create.d.ts +22 -0
- package/dist/commands/ticket/create.js +390 -0
- package/dist/commands/ticket/delete.d.ts +16 -0
- package/dist/commands/ticket/delete.js +178 -0
- package/dist/commands/ticket/edit.d.ts +27 -0
- package/dist/commands/ticket/edit.js +322 -0
- package/dist/commands/ticket/epic.d.ts +20 -0
- package/dist/commands/ticket/epic.js +333 -0
- package/dist/commands/ticket/index.d.ts +13 -0
- package/dist/commands/ticket/index.js +103 -0
- package/dist/commands/ticket/link/block.d.ts +14 -0
- package/dist/commands/ticket/link/block.js +94 -0
- package/dist/commands/ticket/link/duplicates.d.ts +14 -0
- package/dist/commands/ticket/link/duplicates.js +93 -0
- package/dist/commands/ticket/link/index.d.ts +19 -0
- package/dist/commands/ticket/link/index.js +239 -0
- package/dist/commands/ticket/link/relates.d.ts +14 -0
- package/dist/commands/ticket/link/relates.js +93 -0
- package/dist/commands/ticket/link/remove.d.ts +16 -0
- package/dist/commands/ticket/link/remove.js +128 -0
- package/dist/commands/ticket/list.d.ts +24 -0
- package/dist/commands/ticket/list.js +431 -0
- package/dist/commands/ticket/move.d.ts +18 -0
- package/dist/commands/ticket/move.js +212 -0
- package/dist/commands/ticket/project.d.ts +18 -0
- package/dist/commands/ticket/project.js +254 -0
- package/dist/commands/ticket/reassign.d.ts +19 -0
- package/dist/commands/ticket/reassign.js +279 -0
- package/dist/commands/ticket/spec.d.ts +18 -0
- package/dist/commands/ticket/spec.js +259 -0
- package/dist/commands/ticket/status.d.ts +13 -0
- package/dist/commands/ticket/status.js +87 -0
- package/dist/commands/ticket/template/apply.d.ts +25 -0
- package/dist/commands/ticket/template/apply.js +249 -0
- package/dist/commands/ticket/template/create.d.ts +19 -0
- package/dist/commands/ticket/template/create.js +210 -0
- package/dist/commands/ticket/template/delete.d.ts +17 -0
- package/dist/commands/ticket/template/delete.js +92 -0
- package/dist/commands/ticket/template/index.d.ts +15 -0
- package/dist/commands/ticket/template/index.js +118 -0
- package/dist/commands/ticket/template/list.d.ts +16 -0
- package/dist/commands/ticket/template/list.js +110 -0
- package/dist/commands/ticket/template/save.d.ts +14 -0
- package/dist/commands/ticket/template/save.js +110 -0
- package/dist/commands/ticket/update.d.ts +18 -0
- package/dist/commands/ticket/update.js +325 -0
- package/dist/commands/ticket/view.d.ts +13 -0
- package/dist/commands/ticket/view.js +80 -0
- package/dist/commands/whoami.d.ts +9 -0
- package/dist/commands/whoami.js +103 -0
- package/dist/commands/work/complete.d.ts +13 -0
- package/dist/commands/work/complete.js +121 -0
- package/dist/commands/work/index.d.ts +13 -0
- package/dist/commands/work/index.js +70 -0
- package/dist/commands/work/ready.d.ts +24 -0
- package/dist/commands/work/ready.js +290 -0
- package/dist/commands/work/revise.d.ts +19 -0
- package/dist/commands/work/revise.js +377 -0
- package/dist/commands/work/spawn-all.d.ts +17 -0
- package/dist/commands/work/spawn-all.js +58 -0
- package/dist/commands/work/spawn.d.ts +29 -0
- package/dist/commands/work/spawn.js +728 -0
- package/dist/commands/work/start.d.ts +39 -0
- package/dist/commands/work/start.js +1393 -0
- package/dist/commands/work/watch.d.ts +31 -0
- package/dist/commands/work/watch.js +359 -0
- package/dist/commands/workflow/create.d.ts +18 -0
- package/dist/commands/workflow/create.js +119 -0
- package/dist/commands/workflow/delete.d.ts +17 -0
- package/dist/commands/workflow/delete.js +119 -0
- package/dist/commands/workflow/index.d.ts +15 -0
- package/dist/commands/workflow/index.js +75 -0
- package/dist/commands/workflow/list.d.ts +15 -0
- package/dist/commands/workflow/list.js +75 -0
- package/dist/commands/workflow/switch.d.ts +13 -0
- package/dist/commands/workflow/switch.js +117 -0
- package/dist/commands/workflow/view.d.ts +16 -0
- package/dist/commands/workflow/view.js +114 -0
- package/dist/commands/workspace/add.d.ts +12 -0
- package/dist/commands/workspace/add.js +74 -0
- package/dist/commands/workspace/list.d.ts +9 -0
- package/dist/commands/workspace/list.js +153 -0
- package/dist/commands/workspace/remove.d.ts +13 -0
- package/dist/commands/workspace/remove.js +98 -0
- package/dist/commands/workspace/use.d.ts +12 -0
- package/dist/commands/workspace/use.js +111 -0
- package/dist/hooks/init.d.ts +11 -0
- package/dist/hooks/init.js +57 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/lib/agents/commands.d.ts +189 -0
- package/dist/lib/agents/commands.js +893 -0
- package/dist/lib/agents/index.d.ts +54 -0
- package/dist/lib/agents/index.js +382 -0
- package/dist/lib/branch/index.d.ts +120 -0
- package/dist/lib/branch/index.js +334 -0
- package/dist/lib/colors.d.ts +94 -0
- package/dist/lib/colors.js +68 -0
- package/dist/lib/commands/docker-command.d.ts +21 -0
- package/dist/lib/commands/docker-command.js +27 -0
- package/dist/lib/database/index.d.ts +176 -0
- package/dist/lib/database/index.js +581 -0
- package/dist/lib/docker/resolve.d.ts +38 -0
- package/dist/lib/docker/resolve.js +175 -0
- package/dist/lib/execution/config.d.ts +150 -0
- package/dist/lib/execution/config.js +541 -0
- package/dist/lib/execution/devcontainer.d.ts +85 -0
- package/dist/lib/execution/devcontainer.js +594 -0
- package/dist/lib/execution/index.d.ts +10 -0
- package/dist/lib/execution/index.js +10 -0
- package/dist/lib/execution/runners.d.ts +53 -0
- package/dist/lib/execution/runners.js +1182 -0
- package/dist/lib/execution/spawner.d.ts +85 -0
- package/dist/lib/execution/spawner.js +548 -0
- package/dist/lib/execution/storage.d.ts +159 -0
- package/dist/lib/execution/storage.js +425 -0
- package/dist/lib/execution/types.d.ts +145 -0
- package/dist/lib/execution/types.js +157 -0
- package/dist/lib/init/index.d.ts +75 -0
- package/dist/lib/init/index.js +355 -0
- package/dist/lib/machine-config.d.ts +170 -0
- package/dist/lib/machine-config.js +386 -0
- package/dist/lib/pmo/base-command.d.ts +195 -0
- package/dist/lib/pmo/base-command.js +319 -0
- package/dist/lib/pmo/create-spec-folders.d.ts +43 -0
- package/dist/lib/pmo/create-spec-folders.js +64 -0
- package/dist/lib/pmo/epic-files.d.ts +56 -0
- package/dist/lib/pmo/epic-files.js +195 -0
- package/dist/lib/pmo/find-pmo.d.ts +14 -0
- package/dist/lib/pmo/find-pmo.js +172 -0
- package/dist/lib/pmo/index.d.ts +109 -0
- package/dist/lib/pmo/index.js +501 -0
- package/dist/lib/pmo/markdown.d.ts +31 -0
- package/dist/lib/pmo/markdown.js +245 -0
- package/dist/lib/pmo/pmo-context.d.ts +27 -0
- package/dist/lib/pmo/pmo-context.js +44 -0
- package/dist/lib/pmo/schema.d.ts +82 -0
- package/dist/lib/pmo/schema.js +531 -0
- package/dist/lib/pmo/spec-parser.d.ts +25 -0
- package/dist/lib/pmo/spec-parser.js +205 -0
- package/dist/lib/pmo/spec-types.d.ts +43 -0
- package/dist/lib/pmo/spec-types.js +7 -0
- package/dist/lib/pmo/storage/actions.d.ts +34 -0
- package/dist/lib/pmo/storage/actions.js +177 -0
- package/dist/lib/pmo/storage/base.d.ts +47 -0
- package/dist/lib/pmo/storage/base.js +858 -0
- package/dist/lib/pmo/storage/dependencies.d.ts +61 -0
- package/dist/lib/pmo/storage/dependencies.js +267 -0
- package/dist/lib/pmo/storage/epics.d.ts +46 -0
- package/dist/lib/pmo/storage/epics.js +243 -0
- package/dist/lib/pmo/storage/helpers.d.ts +33 -0
- package/dist/lib/pmo/storage/helpers.js +148 -0
- package/dist/lib/pmo/storage/index.d.ts +186 -0
- package/dist/lib/pmo/storage/index.js +689 -0
- package/dist/lib/pmo/storage/phases.d.ts +65 -0
- package/dist/lib/pmo/storage/phases.js +392 -0
- package/dist/lib/pmo/storage/projects.d.ts +79 -0
- package/dist/lib/pmo/storage/projects.js +303 -0
- package/dist/lib/pmo/storage/specs.d.ts +77 -0
- package/dist/lib/pmo/storage/specs.js +389 -0
- package/dist/lib/pmo/storage/statuses.d.ts +63 -0
- package/dist/lib/pmo/storage/statuses.js +404 -0
- package/dist/lib/pmo/storage/subtasks.d.ts +37 -0
- package/dist/lib/pmo/storage/subtasks.js +184 -0
- package/dist/lib/pmo/storage/templates.d.ts +40 -0
- package/dist/lib/pmo/storage/templates.js +210 -0
- package/dist/lib/pmo/storage/tickets.d.ts +57 -0
- package/dist/lib/pmo/storage/tickets.js +453 -0
- package/dist/lib/pmo/storage/types.d.ts +200 -0
- package/dist/lib/pmo/storage/types.js +5 -0
- package/dist/lib/pmo/storage/views.d.ts +44 -0
- package/dist/lib/pmo/storage/views.js +355 -0
- package/dist/lib/pmo/storage-sqlite.d.ts +7 -0
- package/dist/lib/pmo/storage-sqlite.js +7 -0
- package/dist/lib/pmo/sync-manager.d.ts +92 -0
- package/dist/lib/pmo/sync-manager.js +229 -0
- package/dist/lib/pmo/types.d.ts +710 -0
- package/dist/lib/pmo/types.js +108 -0
- package/dist/lib/pmo/utils.d.ts +122 -0
- package/dist/lib/pmo/utils.js +174 -0
- package/dist/lib/pmo/watcher.d.ts +43 -0
- package/dist/lib/pmo/watcher.js +208 -0
- package/dist/lib/pr/index.d.ts +150 -0
- package/dist/lib/pr/index.js +483 -0
- package/dist/lib/prompt-json.d.ts +231 -0
- package/dist/lib/prompt-json.js +213 -0
- package/dist/lib/repos/index.d.ts +81 -0
- package/dist/lib/repos/index.js +679 -0
- package/dist/lib/styles.d.ts +98 -0
- package/dist/lib/styles.js +195 -0
- package/dist/lib/themes.d.ts +128 -0
- package/dist/lib/themes.js +301 -0
- package/dist/lib/ui/BoardUI.d.ts +21 -0
- package/dist/lib/ui/BoardUI.js +85 -0
- package/dist/lib/ui/ClaimTicketUI.d.ts +17 -0
- package/dist/lib/ui/ClaimTicketUI.js +64 -0
- package/dist/lib/ui/CreateTicketUI.d.ts +13 -0
- package/dist/lib/ui/CreateTicketUI.js +101 -0
- package/dist/lib/workspace.d.ts +66 -0
- package/dist/lib/workspace.js +204 -0
- package/oclif.manifest.json +10593 -0
- package/package.json +103 -56
- package/LICENSE +0 -21
- package/dist/bin/prlt.d.ts +0 -11
- package/dist/bin/prlt.d.ts.map +0 -1
- package/dist/bin/prlt.js +0 -144
- package/dist/bin/prlt.js.map +0 -1
- package/dist/lib/config/index.d.ts +0 -14
- package/dist/lib/config/index.d.ts.map +0 -1
- package/dist/lib/config/index.js +0 -142
- package/dist/lib/config/index.js.map +0 -1
- package/dist/lib/config/upgrade.d.ts +0 -2
- package/dist/lib/config/upgrade.d.ts.map +0 -1
- package/dist/lib/config/upgrade.js +0 -248
- package/dist/lib/config/upgrade.js.map +0 -1
- package/dist/lib/themes/index.d.ts +0 -8
- package/dist/lib/themes/index.d.ts.map +0 -1
- package/dist/lib/themes/index.js +0 -80
- package/dist/lib/themes/index.js.map +0 -1
- package/dist/lib/utils/helpers.d.ts +0 -4
- package/dist/lib/utils/helpers.d.ts.map +0 -1
- package/dist/lib/utils/helpers.js +0 -39
- package/dist/lib/utils/helpers.js.map +0 -1
- package/dist/lib/utils/logger.d.ts +0 -4
- package/dist/lib/utils/logger.d.ts.map +0 -1
- package/dist/lib/utils/logger.js +0 -28
- package/dist/lib/utils/logger.js.map +0 -1
- package/dist/lib/workspace/index.d.ts +0 -13
- package/dist/lib/workspace/index.d.ts.map +0 -1
- package/dist/lib/workspace/index.js +0 -116
- package/dist/lib/workspace/index.js.map +0 -1
- package/dist/lib/worktree/index.d.ts +0 -7
- package/dist/lib/worktree/index.d.ts.map +0 -1
- package/dist/lib/worktree/index.js +0 -362
- package/dist/lib/worktree/index.js.map +0 -1
- package/dist/lib/worktree/migrate.d.ts +0 -2
- package/dist/lib/worktree/migrate.d.ts.map +0 -1
- package/dist/lib/worktree/migrate.js +0 -214
- package/dist/lib/worktree/migrate.js.map +0 -1
- package/dist/lib/worktree/repair.d.ts +0 -3
- package/dist/lib/worktree/repair.d.ts.map +0 -1
- package/dist/lib/worktree/repair.js +0 -320
- package/dist/lib/worktree/repair.js.map +0 -1
- package/dist/types/index.d.ts +0 -57
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/index.js +0 -3
- package/dist/types/index.js.map +0 -1
|
@@ -0,0 +1,453 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ticket operations for PMO.
|
|
3
|
+
* Tickets reference workflow statuses directly via status_id.
|
|
4
|
+
* Board position is derived from priority and created_at (no separate board_tickets table).
|
|
5
|
+
*/
|
|
6
|
+
import { PMO_TABLES } from '../schema.js';
|
|
7
|
+
import { PMOError } from '../types.js';
|
|
8
|
+
import { slugify, generateEntityId } from '../utils.js';
|
|
9
|
+
import { rowToTicket } from './helpers.js';
|
|
10
|
+
const T = PMO_TABLES;
|
|
11
|
+
export class TicketStorage {
|
|
12
|
+
ctx;
|
|
13
|
+
constructor(ctx) {
|
|
14
|
+
this.ctx = ctx;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Create a new ticket.
|
|
18
|
+
* Gets default status from the project's workflow.
|
|
19
|
+
*/
|
|
20
|
+
async createTicket(projectId, ticket) {
|
|
21
|
+
const id = ticket.id || generateEntityId(this.ctx.db, 'ticket');
|
|
22
|
+
const title = ticket.title || 'Untitled';
|
|
23
|
+
const now = Date.now();
|
|
24
|
+
const specId = ticket.specId || null;
|
|
25
|
+
// Get status_id from project's workflow
|
|
26
|
+
let statusId = ticket.statusId;
|
|
27
|
+
// Get the project's workflow
|
|
28
|
+
const project = this.ctx.db.prepare(`
|
|
29
|
+
SELECT workflow_id FROM ${T.projects} WHERE id = ?
|
|
30
|
+
`).get(projectId);
|
|
31
|
+
if (!project) {
|
|
32
|
+
throw new PMOError('NOT_FOUND', `Project not found: ${projectId}`);
|
|
33
|
+
}
|
|
34
|
+
const workflowId = project.workflow_id || 'default';
|
|
35
|
+
// If statusName is provided, look up status by name
|
|
36
|
+
if (!statusId && ticket.statusName) {
|
|
37
|
+
const namedStatus = this.ctx.db.prepare(`
|
|
38
|
+
SELECT id FROM ${T.workflow_statuses}
|
|
39
|
+
WHERE workflow_id = ? AND LOWER(name) = LOWER(?)
|
|
40
|
+
`).get(workflowId, ticket.statusName);
|
|
41
|
+
if (namedStatus) {
|
|
42
|
+
statusId = namedStatus.id;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (!statusId) {
|
|
46
|
+
// Get default status from workflow
|
|
47
|
+
const defaultStatus = this.ctx.db.prepare(`
|
|
48
|
+
SELECT id FROM ${T.workflow_statuses}
|
|
49
|
+
WHERE workflow_id = ? AND is_default = 1
|
|
50
|
+
`).get(workflowId);
|
|
51
|
+
if (defaultStatus) {
|
|
52
|
+
statusId = defaultStatus.id;
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
// Fall back to first status in workflow (by category then position)
|
|
56
|
+
const firstStatus = this.ctx.db.prepare(`
|
|
57
|
+
SELECT id FROM ${T.workflow_statuses}
|
|
58
|
+
WHERE workflow_id = ?
|
|
59
|
+
ORDER BY
|
|
60
|
+
CASE category
|
|
61
|
+
WHEN 'backlog' THEN 1
|
|
62
|
+
WHEN 'unstarted' THEN 2
|
|
63
|
+
WHEN 'started' THEN 3
|
|
64
|
+
WHEN 'completed' THEN 4
|
|
65
|
+
WHEN 'canceled' THEN 5
|
|
66
|
+
END,
|
|
67
|
+
position ASC
|
|
68
|
+
LIMIT 1
|
|
69
|
+
`).get(workflowId);
|
|
70
|
+
if (firstStatus) {
|
|
71
|
+
statusId = firstStatus.id;
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
throw new PMOError('NOT_FOUND', 'No statuses found in workflow. Apply a workflow template first.');
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
// Insert ticket
|
|
79
|
+
const labels = ticket.labels || [];
|
|
80
|
+
this.ctx.db.prepare(`
|
|
81
|
+
INSERT INTO ${T.tickets} (
|
|
82
|
+
id, project_id, title, description, priority, category,
|
|
83
|
+
status_id, owner, assignee, spec_id, epic_id, labels,
|
|
84
|
+
created_at, updated_at, last_synced_from_spec, last_synced_from_board
|
|
85
|
+
)
|
|
86
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
87
|
+
`).run(id, projectId, title, ticket.description || null, ticket.priority || null, ticket.category || null, statusId, ticket.owner || null, ticket.assignee || null, specId, ticket.epicId || null, JSON.stringify(labels), now, now, ticket.lastSyncedFromSpec || null, ticket.lastSyncedFromBoard || null);
|
|
88
|
+
// Insert subtasks
|
|
89
|
+
if (ticket.subtasks && ticket.subtasks.length > 0) {
|
|
90
|
+
const insertSubtask = this.ctx.db.prepare(`
|
|
91
|
+
INSERT INTO ${T.subtasks} (id, ticket_id, title, done, position)
|
|
92
|
+
VALUES (?, ?, ?, ?, ?)
|
|
93
|
+
`);
|
|
94
|
+
ticket.subtasks.forEach((st, idx) => {
|
|
95
|
+
insertSubtask.run(st.id || slugify(st.title), id, st.title, st.done ? 1 : 0, idx);
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
// Insert metadata
|
|
99
|
+
if (ticket.metadata) {
|
|
100
|
+
const insertMeta = this.ctx.db.prepare(`
|
|
101
|
+
INSERT INTO ${T.ticket_metadata} (ticket_id, key, value)
|
|
102
|
+
VALUES (?, ?, ?)
|
|
103
|
+
`);
|
|
104
|
+
for (const [key, value] of Object.entries(ticket.metadata)) {
|
|
105
|
+
insertMeta.run(id, key, value);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
this.ctx.updateBoardTimestamp(projectId);
|
|
109
|
+
return (await this.getTicketById(id));
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Get a ticket by ID.
|
|
113
|
+
*/
|
|
114
|
+
async getTicket(id) {
|
|
115
|
+
return this.getTicketById(id);
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Get a ticket by ID (internal).
|
|
119
|
+
* Looks up by ticket ID only - no project scoping required since ticket IDs are globally unique.
|
|
120
|
+
* Joins workflow_statuses to get column name (status name is the column).
|
|
121
|
+
*/
|
|
122
|
+
async getTicketById(id) {
|
|
123
|
+
const row = this.ctx.db.prepare(`
|
|
124
|
+
SELECT t.*,
|
|
125
|
+
ws.id as column_id,
|
|
126
|
+
ws.position as position,
|
|
127
|
+
ws.name as column_name
|
|
128
|
+
FROM ${T.tickets} t
|
|
129
|
+
LEFT JOIN ${T.workflow_statuses} ws ON t.status_id = ws.id
|
|
130
|
+
WHERE LOWER(t.id) = LOWER(?)
|
|
131
|
+
`).get(id);
|
|
132
|
+
if (!row)
|
|
133
|
+
return null;
|
|
134
|
+
return rowToTicket(this.ctx.db, row);
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Update a ticket.
|
|
138
|
+
* Works with ticket ID only - no project context required since ticket IDs are globally unique.
|
|
139
|
+
*/
|
|
140
|
+
async updateTicket(id, changes) {
|
|
141
|
+
const existing = await this.getTicketById(id);
|
|
142
|
+
if (!existing) {
|
|
143
|
+
throw new PMOError('NOT_FOUND', `Ticket not found: ${id}`, id);
|
|
144
|
+
}
|
|
145
|
+
const updates = [];
|
|
146
|
+
const params = [];
|
|
147
|
+
if (changes.title !== undefined) {
|
|
148
|
+
updates.push('title = ?');
|
|
149
|
+
params.push(changes.title);
|
|
150
|
+
}
|
|
151
|
+
if (changes.description !== undefined) {
|
|
152
|
+
updates.push('description = ?');
|
|
153
|
+
params.push(changes.description);
|
|
154
|
+
}
|
|
155
|
+
if (changes.priority !== undefined) {
|
|
156
|
+
updates.push('priority = ?');
|
|
157
|
+
params.push(changes.priority);
|
|
158
|
+
}
|
|
159
|
+
if (changes.category !== undefined) {
|
|
160
|
+
updates.push('category = ?');
|
|
161
|
+
params.push(changes.category);
|
|
162
|
+
}
|
|
163
|
+
if (changes.statusId !== undefined) {
|
|
164
|
+
updates.push('status_id = ?');
|
|
165
|
+
params.push(changes.statusId);
|
|
166
|
+
}
|
|
167
|
+
if (changes.owner !== undefined) {
|
|
168
|
+
updates.push('owner = ?');
|
|
169
|
+
params.push(changes.owner);
|
|
170
|
+
}
|
|
171
|
+
if (changes.assignee !== undefined) {
|
|
172
|
+
updates.push('assignee = ?');
|
|
173
|
+
params.push(changes.assignee);
|
|
174
|
+
}
|
|
175
|
+
if (changes.branch !== undefined) {
|
|
176
|
+
updates.push('branch = ?');
|
|
177
|
+
params.push(changes.branch);
|
|
178
|
+
}
|
|
179
|
+
if (changes.specId !== undefined) {
|
|
180
|
+
updates.push('spec_id = ?');
|
|
181
|
+
params.push(changes.specId);
|
|
182
|
+
}
|
|
183
|
+
if (changes.lastSyncedFromSpec !== undefined) {
|
|
184
|
+
updates.push('last_synced_from_spec = ?');
|
|
185
|
+
params.push(changes.lastSyncedFromSpec);
|
|
186
|
+
}
|
|
187
|
+
if (changes.lastSyncedFromBoard !== undefined) {
|
|
188
|
+
updates.push('last_synced_from_board = ?');
|
|
189
|
+
params.push(changes.lastSyncedFromBoard);
|
|
190
|
+
}
|
|
191
|
+
if (changes.labels !== undefined) {
|
|
192
|
+
updates.push('labels = ?');
|
|
193
|
+
params.push(JSON.stringify(changes.labels));
|
|
194
|
+
}
|
|
195
|
+
if (updates.length > 0) {
|
|
196
|
+
updates.push('updated_at = ?');
|
|
197
|
+
params.push(Date.now());
|
|
198
|
+
params.push(id);
|
|
199
|
+
this.ctx.db.prepare(`UPDATE ${T.tickets} SET ${updates.join(', ')} WHERE id = ?`).run(...params);
|
|
200
|
+
}
|
|
201
|
+
// Update subtasks if provided
|
|
202
|
+
if (changes.subtasks !== undefined) {
|
|
203
|
+
this.ctx.db.prepare(`DELETE FROM ${T.subtasks} WHERE ticket_id = ?`).run(id);
|
|
204
|
+
const insertSubtask = this.ctx.db.prepare(`
|
|
205
|
+
INSERT INTO ${T.subtasks} (id, ticket_id, title, done, position)
|
|
206
|
+
VALUES (?, ?, ?, ?, ?)
|
|
207
|
+
`);
|
|
208
|
+
changes.subtasks.forEach((st, idx) => {
|
|
209
|
+
insertSubtask.run(st.id || slugify(st.title), id, st.title, st.done ? 1 : 0, idx);
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
// Update metadata if provided
|
|
213
|
+
if (changes.metadata !== undefined) {
|
|
214
|
+
this.ctx.db.prepare(`DELETE FROM ${T.ticket_metadata} WHERE ticket_id = ?`).run(id);
|
|
215
|
+
const insertMeta = this.ctx.db.prepare(`
|
|
216
|
+
INSERT INTO ${T.ticket_metadata} (ticket_id, key, value)
|
|
217
|
+
VALUES (?, ?, ?)
|
|
218
|
+
`);
|
|
219
|
+
for (const [key, value] of Object.entries(changes.metadata)) {
|
|
220
|
+
insertMeta.run(id, key, value);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
// Update board timestamp for the ticket's actual project
|
|
224
|
+
if (existing.projectId) {
|
|
225
|
+
this.updateProjectTimestamp(existing.projectId);
|
|
226
|
+
}
|
|
227
|
+
return (await this.getTicketById(id));
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Update the timestamp for a specific project.
|
|
231
|
+
*/
|
|
232
|
+
updateProjectTimestamp(projectId) {
|
|
233
|
+
this.ctx.db.prepare(`
|
|
234
|
+
UPDATE ${T.projects}
|
|
235
|
+
SET updated_at = ?
|
|
236
|
+
WHERE id = ?
|
|
237
|
+
`).run(Date.now(), projectId);
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Move a ticket to a different status (column).
|
|
241
|
+
* In the workflow-based system, columns ARE statuses.
|
|
242
|
+
* The position parameter is ignored - tickets are sorted by priority then created_at.
|
|
243
|
+
*/
|
|
244
|
+
async moveTicket(projectId, id, column, _position) {
|
|
245
|
+
const existing = await this.getTicketById(id);
|
|
246
|
+
if (!existing) {
|
|
247
|
+
throw new PMOError('NOT_FOUND', `Ticket not found: ${id}`, id);
|
|
248
|
+
}
|
|
249
|
+
// Get project's workflow
|
|
250
|
+
const project = this.ctx.db.prepare(`
|
|
251
|
+
SELECT workflow_id FROM ${T.projects} WHERE id = ?
|
|
252
|
+
`).get(projectId);
|
|
253
|
+
if (!project) {
|
|
254
|
+
throw new PMOError('NOT_FOUND', `Project not found: ${projectId}`);
|
|
255
|
+
}
|
|
256
|
+
const workflowId = project.workflow_id || 'default';
|
|
257
|
+
// Find target status by ID or name
|
|
258
|
+
const targetStatus = this.ctx.db.prepare(`
|
|
259
|
+
SELECT id FROM ${T.workflow_statuses}
|
|
260
|
+
WHERE workflow_id = ? AND (id = ? OR LOWER(name) = LOWER(?))
|
|
261
|
+
`).get(workflowId, column, column);
|
|
262
|
+
if (!targetStatus) {
|
|
263
|
+
throw new PMOError('NOT_FOUND', `Status not found: ${column}`);
|
|
264
|
+
}
|
|
265
|
+
// Update ticket's status_id
|
|
266
|
+
this.ctx.db.prepare(`
|
|
267
|
+
UPDATE ${T.tickets}
|
|
268
|
+
SET status_id = ?, updated_at = ?
|
|
269
|
+
WHERE id = ?
|
|
270
|
+
`).run(targetStatus.id, Date.now(), id);
|
|
271
|
+
this.ctx.updateBoardTimestamp(projectId);
|
|
272
|
+
return (await this.getTicketById(id));
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Delete a ticket.
|
|
276
|
+
* Works with ticket ID only - no project context required since ticket IDs are globally unique.
|
|
277
|
+
*/
|
|
278
|
+
async deleteTicket(id) {
|
|
279
|
+
const existing = await this.getTicketById(id);
|
|
280
|
+
if (!existing) {
|
|
281
|
+
throw new PMOError('NOT_FOUND', `Ticket not found: ${id}`, id);
|
|
282
|
+
}
|
|
283
|
+
const ticketProjectId = existing.projectId;
|
|
284
|
+
if (!ticketProjectId) {
|
|
285
|
+
throw new PMOError('INVALID', `Ticket ${id} has no associated project`, id);
|
|
286
|
+
}
|
|
287
|
+
// Delete ticket (by ID only, since IDs are globally unique)
|
|
288
|
+
// Related data (subtasks, metadata) are deleted via CASCADE
|
|
289
|
+
const result = this.ctx.db.prepare(`
|
|
290
|
+
DELETE FROM ${T.tickets}
|
|
291
|
+
WHERE id = ?
|
|
292
|
+
`).run(id);
|
|
293
|
+
if (result.changes === 0) {
|
|
294
|
+
throw new PMOError('NOT_FOUND', `Ticket not found: ${id}`, id);
|
|
295
|
+
}
|
|
296
|
+
// Update board timestamp for the ticket's project
|
|
297
|
+
this.updateProjectTimestamp(ticketProjectId);
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* List tickets with optional filters.
|
|
301
|
+
* @param projectId - The project to filter by. Pass undefined to list all tickets across all projects.
|
|
302
|
+
* @param filter - Additional filters to apply.
|
|
303
|
+
*/
|
|
304
|
+
async listTickets(projectId, filter) {
|
|
305
|
+
const params = [];
|
|
306
|
+
// Build the base query using workflow_statuses
|
|
307
|
+
let query = `
|
|
308
|
+
SELECT t.*,
|
|
309
|
+
ws.id as column_id,
|
|
310
|
+
ws.position as position,
|
|
311
|
+
ws.name as column_name,
|
|
312
|
+
p.name as project_name
|
|
313
|
+
FROM ${T.tickets} t
|
|
314
|
+
LEFT JOIN ${T.workflow_statuses} ws ON t.status_id = ws.id
|
|
315
|
+
LEFT JOIN ${T.projects} p ON t.project_id = p.id
|
|
316
|
+
WHERE 1=1
|
|
317
|
+
`;
|
|
318
|
+
// Apply project scoping
|
|
319
|
+
if (projectId !== undefined) {
|
|
320
|
+
query += ' AND t.project_id = ?';
|
|
321
|
+
params.push(projectId);
|
|
322
|
+
}
|
|
323
|
+
// If projectId is undefined, list all tickets across all projects
|
|
324
|
+
if (filter?.statusId) {
|
|
325
|
+
query += ' AND t.status_id = ?';
|
|
326
|
+
params.push(filter.statusId);
|
|
327
|
+
}
|
|
328
|
+
if (filter?.statusCategory) {
|
|
329
|
+
query += ' AND ws.category = ?';
|
|
330
|
+
params.push(filter.statusCategory);
|
|
331
|
+
}
|
|
332
|
+
if (filter?.priority) {
|
|
333
|
+
query += ' AND t.priority = ?';
|
|
334
|
+
params.push(filter.priority);
|
|
335
|
+
}
|
|
336
|
+
if (filter?.category) {
|
|
337
|
+
query += ' AND t.category = ?';
|
|
338
|
+
params.push(filter.category);
|
|
339
|
+
}
|
|
340
|
+
if (filter?.owner) {
|
|
341
|
+
query += ' AND t.owner = ?';
|
|
342
|
+
params.push(filter.owner);
|
|
343
|
+
}
|
|
344
|
+
if (filter?.assignee) {
|
|
345
|
+
query += ' AND t.assignee = ?';
|
|
346
|
+
params.push(filter.assignee);
|
|
347
|
+
}
|
|
348
|
+
if (filter?.search) {
|
|
349
|
+
query += ' AND (t.title LIKE ? OR t.description LIKE ?)';
|
|
350
|
+
params.push(`%${filter.search}%`, `%${filter.search}%`);
|
|
351
|
+
}
|
|
352
|
+
if (filter?.spec) {
|
|
353
|
+
query += ' AND t.spec_id = ?';
|
|
354
|
+
params.push(filter.spec);
|
|
355
|
+
}
|
|
356
|
+
if (filter?.epic) {
|
|
357
|
+
query += ' AND t.epic_id = ?';
|
|
358
|
+
params.push(filter.epic);
|
|
359
|
+
}
|
|
360
|
+
if (filter?.column) {
|
|
361
|
+
// Column filter now uses status name
|
|
362
|
+
query += ' AND ws.name = ?';
|
|
363
|
+
params.push(filter.column);
|
|
364
|
+
}
|
|
365
|
+
// Order by project, then status position, then priority, then created_at
|
|
366
|
+
if (projectId === undefined) {
|
|
367
|
+
query += ` ORDER BY p.name, ws.position,
|
|
368
|
+
CASE t.priority
|
|
369
|
+
WHEN 'P0' THEN 0
|
|
370
|
+
WHEN 'P1' THEN 1
|
|
371
|
+
WHEN 'P2' THEN 2
|
|
372
|
+
WHEN 'P3' THEN 3
|
|
373
|
+
ELSE 4
|
|
374
|
+
END,
|
|
375
|
+
t.created_at ASC`;
|
|
376
|
+
}
|
|
377
|
+
else {
|
|
378
|
+
query += ` ORDER BY ws.position,
|
|
379
|
+
CASE t.priority
|
|
380
|
+
WHEN 'P0' THEN 0
|
|
381
|
+
WHEN 'P1' THEN 1
|
|
382
|
+
WHEN 'P2' THEN 2
|
|
383
|
+
WHEN 'P3' THEN 3
|
|
384
|
+
ELSE 4
|
|
385
|
+
END,
|
|
386
|
+
t.created_at ASC`;
|
|
387
|
+
}
|
|
388
|
+
const rows = this.ctx.db.prepare(query).all(...params);
|
|
389
|
+
return Promise.all(rows.map((row) => rowToTicket(this.ctx.db, row)));
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Move a ticket to a different project.
|
|
393
|
+
* The ticket will get the default status from the target project's workflow.
|
|
394
|
+
*/
|
|
395
|
+
async moveTicketToProject(ticketId, newProjectId) {
|
|
396
|
+
const existing = await this.getTicketById(ticketId);
|
|
397
|
+
if (!existing) {
|
|
398
|
+
throw new PMOError('NOT_FOUND', `Ticket not found: ${ticketId}`, ticketId);
|
|
399
|
+
}
|
|
400
|
+
const oldProjectId = existing.projectId;
|
|
401
|
+
if (!oldProjectId) {
|
|
402
|
+
throw new PMOError('INVALID', `Ticket ${ticketId} has no associated project`, ticketId);
|
|
403
|
+
}
|
|
404
|
+
// Check if target project exists and get its workflow
|
|
405
|
+
const targetProject = this.ctx.db.prepare(`
|
|
406
|
+
SELECT id, workflow_id FROM ${T.projects} WHERE id = ?
|
|
407
|
+
`).get(newProjectId);
|
|
408
|
+
if (!targetProject) {
|
|
409
|
+
throw new PMOError('NOT_FOUND', `Project not found: ${newProjectId}`, newProjectId);
|
|
410
|
+
}
|
|
411
|
+
const workflowId = targetProject.workflow_id || 'default';
|
|
412
|
+
// Get default status for target project's workflow
|
|
413
|
+
let newStatusId;
|
|
414
|
+
const defaultStatus = this.ctx.db.prepare(`
|
|
415
|
+
SELECT id FROM ${T.workflow_statuses}
|
|
416
|
+
WHERE workflow_id = ? AND is_default = 1
|
|
417
|
+
`).get(workflowId);
|
|
418
|
+
if (defaultStatus) {
|
|
419
|
+
newStatusId = defaultStatus.id;
|
|
420
|
+
}
|
|
421
|
+
else {
|
|
422
|
+
// Get first status in workflow
|
|
423
|
+
const firstStatus = this.ctx.db.prepare(`
|
|
424
|
+
SELECT id FROM ${T.workflow_statuses}
|
|
425
|
+
WHERE workflow_id = ?
|
|
426
|
+
ORDER BY
|
|
427
|
+
CASE category
|
|
428
|
+
WHEN 'backlog' THEN 1
|
|
429
|
+
WHEN 'unstarted' THEN 2
|
|
430
|
+
WHEN 'started' THEN 3
|
|
431
|
+
WHEN 'completed' THEN 4
|
|
432
|
+
WHEN 'canceled' THEN 5
|
|
433
|
+
END,
|
|
434
|
+
position ASC
|
|
435
|
+
LIMIT 1
|
|
436
|
+
`).get(workflowId);
|
|
437
|
+
if (firstStatus) {
|
|
438
|
+
newStatusId = firstStatus.id;
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
// Update ticket's project_id and status_id
|
|
442
|
+
const now = Date.now();
|
|
443
|
+
this.ctx.db.prepare(`
|
|
444
|
+
UPDATE ${T.tickets}
|
|
445
|
+
SET project_id = ?, status_id = ?, updated_at = ?
|
|
446
|
+
WHERE id = ?
|
|
447
|
+
`).run(newProjectId, newStatusId || existing.statusId, now, ticketId);
|
|
448
|
+
// Update timestamps for both projects
|
|
449
|
+
this.updateProjectTimestamp(oldProjectId);
|
|
450
|
+
this.updateProjectTimestamp(newProjectId);
|
|
451
|
+
return (await this.getTicketById(ticketId));
|
|
452
|
+
}
|
|
453
|
+
}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal types for storage modules.
|
|
3
|
+
* These types are shared between storage modules but not exported publicly.
|
|
4
|
+
*/
|
|
5
|
+
import Database from 'better-sqlite3';
|
|
6
|
+
/**
|
|
7
|
+
* Base context passed to all storage modules.
|
|
8
|
+
* Contains the database connection only - project ID is passed explicitly to operations.
|
|
9
|
+
*/
|
|
10
|
+
export interface StorageContext {
|
|
11
|
+
/** Database connection */
|
|
12
|
+
db: Database.Database;
|
|
13
|
+
/** Update the board timestamp for a project */
|
|
14
|
+
updateBoardTimestamp: (projectId: string) => void;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Row types for database queries.
|
|
18
|
+
* These mirror the database schema columns.
|
|
19
|
+
*/
|
|
20
|
+
export interface TicketRow {
|
|
21
|
+
id: string;
|
|
22
|
+
project_id: string;
|
|
23
|
+
title: string;
|
|
24
|
+
description: string | null;
|
|
25
|
+
priority: string | null;
|
|
26
|
+
category: string | null;
|
|
27
|
+
status_id: string;
|
|
28
|
+
owner: string | null;
|
|
29
|
+
assignee: string | null;
|
|
30
|
+
branch: string | null;
|
|
31
|
+
spec_id: string | null;
|
|
32
|
+
epic_id: string | null;
|
|
33
|
+
labels: string | null;
|
|
34
|
+
column_id: string | null;
|
|
35
|
+
column_name: string | null;
|
|
36
|
+
project_name: string | null;
|
|
37
|
+
position: number | null;
|
|
38
|
+
created_at: string;
|
|
39
|
+
updated_at: string;
|
|
40
|
+
last_synced_from_spec: string | null;
|
|
41
|
+
last_synced_from_board: string | null;
|
|
42
|
+
}
|
|
43
|
+
export interface StatusRow {
|
|
44
|
+
id: string;
|
|
45
|
+
project_id: string;
|
|
46
|
+
name: string;
|
|
47
|
+
category: string;
|
|
48
|
+
position: number;
|
|
49
|
+
color: string | null;
|
|
50
|
+
description: string | null;
|
|
51
|
+
is_default: number;
|
|
52
|
+
created_at: string;
|
|
53
|
+
}
|
|
54
|
+
export interface SpecRow {
|
|
55
|
+
id: string;
|
|
56
|
+
title: string;
|
|
57
|
+
status: string;
|
|
58
|
+
type: string | null;
|
|
59
|
+
tags: string | null;
|
|
60
|
+
depends_on: string | null;
|
|
61
|
+
problem: string | null;
|
|
62
|
+
solution: string | null;
|
|
63
|
+
decisions: string | null;
|
|
64
|
+
not_now: string | null;
|
|
65
|
+
ui_ux: string | null;
|
|
66
|
+
acceptance_criteria: string | null;
|
|
67
|
+
open_questions: string | null;
|
|
68
|
+
requirements_functional: string | null;
|
|
69
|
+
requirements_technical: string | null;
|
|
70
|
+
context: string | null;
|
|
71
|
+
created_at: string;
|
|
72
|
+
updated_at: string;
|
|
73
|
+
}
|
|
74
|
+
export interface EpicRow {
|
|
75
|
+
id: string;
|
|
76
|
+
project_id: string;
|
|
77
|
+
title: string;
|
|
78
|
+
description: string | null;
|
|
79
|
+
status: string;
|
|
80
|
+
position: number;
|
|
81
|
+
file_path: string | null;
|
|
82
|
+
spec_id: string | null;
|
|
83
|
+
created_at: string;
|
|
84
|
+
updated_at: string;
|
|
85
|
+
}
|
|
86
|
+
export interface ProjectRow {
|
|
87
|
+
id: string;
|
|
88
|
+
name: string;
|
|
89
|
+
template: string | null;
|
|
90
|
+
description: string | null;
|
|
91
|
+
status: string;
|
|
92
|
+
phase_id: string | null;
|
|
93
|
+
workflow_id: string | null;
|
|
94
|
+
is_archived: number;
|
|
95
|
+
target_date: string | null;
|
|
96
|
+
initiative_id: string | null;
|
|
97
|
+
created_at: string;
|
|
98
|
+
updated_at: string;
|
|
99
|
+
}
|
|
100
|
+
export interface WorkflowRow {
|
|
101
|
+
id: string;
|
|
102
|
+
name: string;
|
|
103
|
+
description: string | null;
|
|
104
|
+
is_builtin: number;
|
|
105
|
+
created_at: string;
|
|
106
|
+
updated_at: string;
|
|
107
|
+
}
|
|
108
|
+
export interface WorkflowStatusRow {
|
|
109
|
+
id: string;
|
|
110
|
+
workflow_id: string;
|
|
111
|
+
name: string;
|
|
112
|
+
category: string;
|
|
113
|
+
position: number;
|
|
114
|
+
color: string | null;
|
|
115
|
+
description: string | null;
|
|
116
|
+
is_default: number;
|
|
117
|
+
created_at: string;
|
|
118
|
+
}
|
|
119
|
+
export interface ColumnRow {
|
|
120
|
+
id: string;
|
|
121
|
+
project_id: string;
|
|
122
|
+
name: string;
|
|
123
|
+
position: number;
|
|
124
|
+
created_at: string;
|
|
125
|
+
}
|
|
126
|
+
export interface SubtaskRow {
|
|
127
|
+
id: string;
|
|
128
|
+
ticket_id: string;
|
|
129
|
+
title: string;
|
|
130
|
+
done: number;
|
|
131
|
+
position: number;
|
|
132
|
+
}
|
|
133
|
+
export interface AcceptanceCriterionRow {
|
|
134
|
+
id: string;
|
|
135
|
+
ticket_id: string;
|
|
136
|
+
criterion: string;
|
|
137
|
+
verifiable: number;
|
|
138
|
+
verified: number;
|
|
139
|
+
verified_at: string | null;
|
|
140
|
+
verified_by: string | null;
|
|
141
|
+
position: number;
|
|
142
|
+
}
|
|
143
|
+
export interface PhaseRow {
|
|
144
|
+
id: string;
|
|
145
|
+
name: string;
|
|
146
|
+
category: string;
|
|
147
|
+
position: number;
|
|
148
|
+
color: string | null;
|
|
149
|
+
description: string | null;
|
|
150
|
+
is_default: number;
|
|
151
|
+
created_at: string;
|
|
152
|
+
}
|
|
153
|
+
export interface PhaseTemplateRow {
|
|
154
|
+
id: string;
|
|
155
|
+
name: string;
|
|
156
|
+
description: string | null;
|
|
157
|
+
is_builtin: number;
|
|
158
|
+
phases: string;
|
|
159
|
+
created_at: string;
|
|
160
|
+
}
|
|
161
|
+
export interface WorkActionRow {
|
|
162
|
+
id: string;
|
|
163
|
+
name: string;
|
|
164
|
+
description: string | null;
|
|
165
|
+
prompt: string;
|
|
166
|
+
end_prompt: string | null;
|
|
167
|
+
default_category: string | null;
|
|
168
|
+
is_builtin: number;
|
|
169
|
+
position: number;
|
|
170
|
+
created_at: string;
|
|
171
|
+
}
|
|
172
|
+
export interface BoardViewRow {
|
|
173
|
+
id: string;
|
|
174
|
+
project_id: string;
|
|
175
|
+
name: string;
|
|
176
|
+
description: string | null;
|
|
177
|
+
is_default: number;
|
|
178
|
+
filters: string | null;
|
|
179
|
+
group_by: string | null;
|
|
180
|
+
sort_by: string | null;
|
|
181
|
+
columns: string | null;
|
|
182
|
+
created_at: string;
|
|
183
|
+
updated_at: string;
|
|
184
|
+
}
|
|
185
|
+
export interface TicketTemplateRow {
|
|
186
|
+
id: string;
|
|
187
|
+
name: string;
|
|
188
|
+
description: string | null;
|
|
189
|
+
default_title: string | null;
|
|
190
|
+
default_description: string | null;
|
|
191
|
+
default_priority: string | null;
|
|
192
|
+
default_category: string | null;
|
|
193
|
+
default_status_id: string | null;
|
|
194
|
+
default_assignee: string | null;
|
|
195
|
+
default_owner: string | null;
|
|
196
|
+
default_labels: string;
|
|
197
|
+
suggested_subtasks: string | null;
|
|
198
|
+
is_builtin: number;
|
|
199
|
+
created_at: string;
|
|
200
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Board view operations.
|
|
3
|
+
*/
|
|
4
|
+
import { Board, BoardView, BoardViewFilter, BoardViewFilters } from '../types.js';
|
|
5
|
+
import { StorageContext } from './types.js';
|
|
6
|
+
export declare class ViewStorage {
|
|
7
|
+
private ctx;
|
|
8
|
+
constructor(ctx: StorageContext);
|
|
9
|
+
/**
|
|
10
|
+
* List board views.
|
|
11
|
+
*/
|
|
12
|
+
listBoardViews(filter?: BoardViewFilter): Promise<BoardView[]>;
|
|
13
|
+
/**
|
|
14
|
+
* Get a board view by ID.
|
|
15
|
+
*/
|
|
16
|
+
getBoardView(id: string): Promise<BoardView | null>;
|
|
17
|
+
/**
|
|
18
|
+
* Create a new board view.
|
|
19
|
+
*/
|
|
20
|
+
createBoardView(view: Partial<BoardView>): Promise<BoardView>;
|
|
21
|
+
/**
|
|
22
|
+
* Update a board view.
|
|
23
|
+
*/
|
|
24
|
+
updateBoardView(id: string, changes: Partial<BoardView>): Promise<BoardView>;
|
|
25
|
+
/**
|
|
26
|
+
* Delete a board view.
|
|
27
|
+
*/
|
|
28
|
+
deleteBoardView(id: string): Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* Get the default board view for a project.
|
|
31
|
+
*/
|
|
32
|
+
getDefaultBoardView(projectId: string): Promise<BoardView | null>;
|
|
33
|
+
/**
|
|
34
|
+
* Get board with optional filters applied.
|
|
35
|
+
*/
|
|
36
|
+
getBoardWithView(projectId: string, viewId?: string, filters?: BoardViewFilters): Promise<Board>;
|
|
37
|
+
/**
|
|
38
|
+
* Get tickets for a column (workflow status) with filters applied.
|
|
39
|
+
*/
|
|
40
|
+
private getTicketsForColumnWithFilters;
|
|
41
|
+
private rowToTicketWithColumn;
|
|
42
|
+
private sortTickets;
|
|
43
|
+
private rowToBoardView;
|
|
44
|
+
}
|