@proletariat/cli 0.1.4 → 0.3.0
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 +510 -255
- 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 +104 -52
- 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 -139
- 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 -173
- 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 -212
- 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 -140
- 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,404 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workflow status operations.
|
|
3
|
+
* Statuses belong to workflows (not projects directly).
|
|
4
|
+
* Projects reference workflows via workflow_id.
|
|
5
|
+
*/
|
|
6
|
+
import { PMO_TABLES } from '../schema.js';
|
|
7
|
+
import { PMOError, STATE_CATEGORY_ORDER } from '../types.js';
|
|
8
|
+
import { slugify } from '../utils.js';
|
|
9
|
+
const T = PMO_TABLES;
|
|
10
|
+
/**
|
|
11
|
+
* Convert database row to Workflow object.
|
|
12
|
+
*/
|
|
13
|
+
function rowToWorkflow(row) {
|
|
14
|
+
return {
|
|
15
|
+
id: row.id,
|
|
16
|
+
name: row.name,
|
|
17
|
+
description: row.description || undefined,
|
|
18
|
+
isBuiltin: !!row.is_builtin,
|
|
19
|
+
createdAt: new Date(row.created_at),
|
|
20
|
+
updatedAt: new Date(row.updated_at),
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Convert database row to WorkflowStatus object.
|
|
25
|
+
*/
|
|
26
|
+
function rowToWorkflowStatus(row) {
|
|
27
|
+
return {
|
|
28
|
+
id: row.id,
|
|
29
|
+
workflowId: row.workflow_id,
|
|
30
|
+
name: row.name,
|
|
31
|
+
category: row.category,
|
|
32
|
+
position: row.position,
|
|
33
|
+
color: row.color || undefined,
|
|
34
|
+
description: row.description || undefined,
|
|
35
|
+
isDefault: !!row.is_default,
|
|
36
|
+
createdAt: new Date(row.created_at),
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
export class StatusStorage {
|
|
40
|
+
ctx;
|
|
41
|
+
constructor(ctx) {
|
|
42
|
+
this.ctx = ctx;
|
|
43
|
+
}
|
|
44
|
+
// ============================================================================
|
|
45
|
+
// Workflow Operations
|
|
46
|
+
// ============================================================================
|
|
47
|
+
/**
|
|
48
|
+
* List all workflows.
|
|
49
|
+
*/
|
|
50
|
+
async listWorkflows(filter) {
|
|
51
|
+
let sql = `SELECT * FROM ${T.workflows} WHERE 1=1`;
|
|
52
|
+
const params = [];
|
|
53
|
+
if (filter?.isBuiltin !== undefined) {
|
|
54
|
+
sql += ' AND is_builtin = ?';
|
|
55
|
+
params.push(filter.isBuiltin ? 1 : 0);
|
|
56
|
+
}
|
|
57
|
+
if (filter?.search) {
|
|
58
|
+
sql += ' AND (name LIKE ? OR description LIKE ?)';
|
|
59
|
+
params.push(`%${filter.search}%`, `%${filter.search}%`);
|
|
60
|
+
}
|
|
61
|
+
sql += ' ORDER BY is_builtin DESC, name';
|
|
62
|
+
const rows = this.ctx.db.prepare(sql).all(...params);
|
|
63
|
+
return rows.map(rowToWorkflow);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Get a workflow by ID.
|
|
67
|
+
*/
|
|
68
|
+
async getWorkflow(id) {
|
|
69
|
+
const row = this.ctx.db.prepare(`
|
|
70
|
+
SELECT * FROM ${T.workflows} WHERE id = ?
|
|
71
|
+
`).get(id);
|
|
72
|
+
if (!row)
|
|
73
|
+
return null;
|
|
74
|
+
return rowToWorkflow(row);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Create a new workflow.
|
|
78
|
+
*/
|
|
79
|
+
async createWorkflow(workflow) {
|
|
80
|
+
const id = workflow.id || slugify(workflow.name || 'workflow');
|
|
81
|
+
const now = new Date().toISOString();
|
|
82
|
+
// Check for duplicate name
|
|
83
|
+
const existing = this.ctx.db.prepare(`
|
|
84
|
+
SELECT id FROM ${T.workflows}
|
|
85
|
+
WHERE LOWER(name) = LOWER(?)
|
|
86
|
+
`).get(workflow.name);
|
|
87
|
+
if (existing) {
|
|
88
|
+
throw new PMOError('CONFLICT', `Workflow with name "${workflow.name}" already exists`);
|
|
89
|
+
}
|
|
90
|
+
this.ctx.db.prepare(`
|
|
91
|
+
INSERT INTO ${T.workflows} (id, name, description, is_builtin, created_at, updated_at)
|
|
92
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
93
|
+
`).run(id, workflow.name || 'New Workflow', workflow.description || null, workflow.isBuiltin ? 1 : 0, now, now);
|
|
94
|
+
return {
|
|
95
|
+
id,
|
|
96
|
+
name: workflow.name || 'New Workflow',
|
|
97
|
+
description: workflow.description,
|
|
98
|
+
isBuiltin: workflow.isBuiltin || false,
|
|
99
|
+
createdAt: new Date(now),
|
|
100
|
+
updatedAt: new Date(now),
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Update a workflow.
|
|
105
|
+
*/
|
|
106
|
+
async updateWorkflow(id, changes) {
|
|
107
|
+
const existing = await this.getWorkflow(id);
|
|
108
|
+
if (!existing) {
|
|
109
|
+
throw new PMOError('NOT_FOUND', `Workflow not found: ${id}`);
|
|
110
|
+
}
|
|
111
|
+
const updates = [];
|
|
112
|
+
const params = [];
|
|
113
|
+
if (changes.name !== undefined) {
|
|
114
|
+
// Check for duplicate name
|
|
115
|
+
const duplicate = this.ctx.db.prepare(`
|
|
116
|
+
SELECT id FROM ${T.workflows}
|
|
117
|
+
WHERE LOWER(name) = LOWER(?) AND id != ?
|
|
118
|
+
`).get(changes.name, id);
|
|
119
|
+
if (duplicate) {
|
|
120
|
+
throw new PMOError('CONFLICT', `Workflow with name "${changes.name}" already exists`);
|
|
121
|
+
}
|
|
122
|
+
updates.push('name = ?');
|
|
123
|
+
params.push(changes.name);
|
|
124
|
+
}
|
|
125
|
+
if (changes.description !== undefined) {
|
|
126
|
+
updates.push('description = ?');
|
|
127
|
+
params.push(changes.description || null);
|
|
128
|
+
}
|
|
129
|
+
if (updates.length > 0) {
|
|
130
|
+
updates.push('updated_at = ?');
|
|
131
|
+
params.push(new Date().toISOString());
|
|
132
|
+
params.push(id);
|
|
133
|
+
this.ctx.db.prepare(`UPDATE ${T.workflows} SET ${updates.join(', ')} WHERE id = ?`).run(...params);
|
|
134
|
+
}
|
|
135
|
+
return (await this.getWorkflow(id));
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Delete a workflow.
|
|
139
|
+
*/
|
|
140
|
+
async deleteWorkflow(id) {
|
|
141
|
+
const existing = await this.getWorkflow(id);
|
|
142
|
+
if (!existing) {
|
|
143
|
+
throw new PMOError('NOT_FOUND', `Workflow not found: ${id}`);
|
|
144
|
+
}
|
|
145
|
+
if (existing.isBuiltin) {
|
|
146
|
+
throw new PMOError('INVALID', `Cannot delete built-in workflow: ${existing.name}`);
|
|
147
|
+
}
|
|
148
|
+
// Check if any projects use this workflow
|
|
149
|
+
const projectCount = this.ctx.db.prepare(`
|
|
150
|
+
SELECT COUNT(*) as count FROM ${T.projects}
|
|
151
|
+
WHERE workflow_id = ?
|
|
152
|
+
`).get(id);
|
|
153
|
+
if (projectCount.count > 0) {
|
|
154
|
+
throw new PMOError('CONFLICT', `Cannot delete workflow: ${projectCount.count} project(s) are using it`);
|
|
155
|
+
}
|
|
156
|
+
// Delete associated statuses first (cascaded by FK, but explicit for safety)
|
|
157
|
+
this.ctx.db.prepare(`DELETE FROM ${T.workflow_statuses} WHERE workflow_id = ?`).run(id);
|
|
158
|
+
this.ctx.db.prepare(`DELETE FROM ${T.workflows} WHERE id = ?`).run(id);
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Get the workflow for a project.
|
|
162
|
+
*/
|
|
163
|
+
async getProjectWorkflow(projectId) {
|
|
164
|
+
const row = this.ctx.db.prepare(`
|
|
165
|
+
SELECT w.* FROM ${T.workflows} w
|
|
166
|
+
JOIN ${T.projects} p ON p.workflow_id = w.id
|
|
167
|
+
WHERE p.id = ?
|
|
168
|
+
`).get(projectId);
|
|
169
|
+
if (!row)
|
|
170
|
+
return null;
|
|
171
|
+
return rowToWorkflow(row);
|
|
172
|
+
}
|
|
173
|
+
// ============================================================================
|
|
174
|
+
// Workflow Status Operations
|
|
175
|
+
// ============================================================================
|
|
176
|
+
/**
|
|
177
|
+
* List statuses for a workflow.
|
|
178
|
+
*/
|
|
179
|
+
async listStatuses(workflowId) {
|
|
180
|
+
const rows = this.ctx.db.prepare(`
|
|
181
|
+
SELECT * FROM ${T.workflow_statuses}
|
|
182
|
+
WHERE workflow_id = ?
|
|
183
|
+
ORDER BY position
|
|
184
|
+
`).all(workflowId);
|
|
185
|
+
return rows.map(rowToWorkflowStatus);
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Get a status by ID.
|
|
189
|
+
*/
|
|
190
|
+
async getStatus(id) {
|
|
191
|
+
const row = this.ctx.db.prepare(`
|
|
192
|
+
SELECT * FROM ${T.workflow_statuses} WHERE id = ?
|
|
193
|
+
`).get(id);
|
|
194
|
+
if (!row)
|
|
195
|
+
return null;
|
|
196
|
+
return rowToWorkflowStatus(row);
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Create a new status in a workflow.
|
|
200
|
+
*/
|
|
201
|
+
async createStatus(workflowId, status) {
|
|
202
|
+
const id = status.id || `${workflowId}-${slugify(status.name || 'status')}`;
|
|
203
|
+
const category = status.category || 'backlog';
|
|
204
|
+
const now = new Date().toISOString();
|
|
205
|
+
// Validate workflow exists
|
|
206
|
+
const workflow = await this.getWorkflow(workflowId);
|
|
207
|
+
if (!workflow) {
|
|
208
|
+
throw new PMOError('NOT_FOUND', `Workflow not found: ${workflowId}`);
|
|
209
|
+
}
|
|
210
|
+
// Validate category
|
|
211
|
+
if (!STATE_CATEGORY_ORDER.includes(category)) {
|
|
212
|
+
throw new PMOError('INVALID', `Invalid category: ${category}. Must be one of: ${STATE_CATEGORY_ORDER.join(', ')}`);
|
|
213
|
+
}
|
|
214
|
+
// Get next position if not specified
|
|
215
|
+
let position = status.position;
|
|
216
|
+
if (position === undefined) {
|
|
217
|
+
const maxPos = this.ctx.db.prepare(`
|
|
218
|
+
SELECT COALESCE(MAX(position), -1) as max_pos
|
|
219
|
+
FROM ${T.workflow_statuses}
|
|
220
|
+
WHERE workflow_id = ?
|
|
221
|
+
`).get(workflowId);
|
|
222
|
+
position = maxPos.max_pos + 1;
|
|
223
|
+
}
|
|
224
|
+
// Check for duplicate name in workflow
|
|
225
|
+
const existing = this.ctx.db.prepare(`
|
|
226
|
+
SELECT id FROM ${T.workflow_statuses}
|
|
227
|
+
WHERE workflow_id = ? AND LOWER(name) = LOWER(?)
|
|
228
|
+
`).get(workflowId, status.name);
|
|
229
|
+
if (existing) {
|
|
230
|
+
throw new PMOError('CONFLICT', `Status with name "${status.name}" already exists in this workflow`);
|
|
231
|
+
}
|
|
232
|
+
// If this is the default, unset other defaults in the workflow
|
|
233
|
+
if (status.isDefault) {
|
|
234
|
+
this.ctx.db.prepare(`
|
|
235
|
+
UPDATE ${T.workflow_statuses}
|
|
236
|
+
SET is_default = 0
|
|
237
|
+
WHERE workflow_id = ?
|
|
238
|
+
`).run(workflowId);
|
|
239
|
+
}
|
|
240
|
+
this.ctx.db.prepare(`
|
|
241
|
+
INSERT INTO ${T.workflow_statuses} (id, workflow_id, name, category, position, color, description, is_default, created_at)
|
|
242
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
243
|
+
`).run(id, workflowId, status.name || 'New Status', category, position, status.color || null, status.description || null, status.isDefault ? 1 : 0, now);
|
|
244
|
+
// Update workflow's updated_at timestamp
|
|
245
|
+
this.ctx.db.prepare(`UPDATE ${T.workflows} SET updated_at = ? WHERE id = ?`).run(now, workflowId);
|
|
246
|
+
return {
|
|
247
|
+
id,
|
|
248
|
+
workflowId,
|
|
249
|
+
name: status.name || 'New Status',
|
|
250
|
+
category,
|
|
251
|
+
position,
|
|
252
|
+
color: status.color,
|
|
253
|
+
description: status.description,
|
|
254
|
+
isDefault: status.isDefault || false,
|
|
255
|
+
createdAt: new Date(now),
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Update a status.
|
|
260
|
+
*/
|
|
261
|
+
async updateStatus(id, changes) {
|
|
262
|
+
const existing = await this.getStatus(id);
|
|
263
|
+
if (!existing) {
|
|
264
|
+
throw new PMOError('NOT_FOUND', `Status not found: ${id}`);
|
|
265
|
+
}
|
|
266
|
+
const updates = [];
|
|
267
|
+
const params = [];
|
|
268
|
+
if (changes.name !== undefined) {
|
|
269
|
+
// Check for duplicate name
|
|
270
|
+
const duplicate = this.ctx.db.prepare(`
|
|
271
|
+
SELECT id FROM ${T.workflow_statuses}
|
|
272
|
+
WHERE workflow_id = ? AND LOWER(name) = LOWER(?) AND id != ?
|
|
273
|
+
`).get(existing.workflowId, changes.name, id);
|
|
274
|
+
if (duplicate) {
|
|
275
|
+
throw new PMOError('CONFLICT', `Status with name "${changes.name}" already exists in this workflow`);
|
|
276
|
+
}
|
|
277
|
+
updates.push('name = ?');
|
|
278
|
+
params.push(changes.name);
|
|
279
|
+
}
|
|
280
|
+
if (changes.category !== undefined) {
|
|
281
|
+
if (!STATE_CATEGORY_ORDER.includes(changes.category)) {
|
|
282
|
+
throw new PMOError('INVALID', `Invalid category: ${changes.category}`);
|
|
283
|
+
}
|
|
284
|
+
updates.push('category = ?');
|
|
285
|
+
params.push(changes.category);
|
|
286
|
+
}
|
|
287
|
+
if (changes.position !== undefined) {
|
|
288
|
+
updates.push('position = ?');
|
|
289
|
+
params.push(changes.position);
|
|
290
|
+
}
|
|
291
|
+
if (changes.color !== undefined) {
|
|
292
|
+
updates.push('color = ?');
|
|
293
|
+
params.push(changes.color || null);
|
|
294
|
+
}
|
|
295
|
+
if (changes.description !== undefined) {
|
|
296
|
+
updates.push('description = ?');
|
|
297
|
+
params.push(changes.description || null);
|
|
298
|
+
}
|
|
299
|
+
if (changes.isDefault !== undefined) {
|
|
300
|
+
if (changes.isDefault) {
|
|
301
|
+
// Unset other defaults
|
|
302
|
+
this.ctx.db.prepare(`
|
|
303
|
+
UPDATE ${T.workflow_statuses}
|
|
304
|
+
SET is_default = 0
|
|
305
|
+
WHERE workflow_id = ?
|
|
306
|
+
`).run(existing.workflowId);
|
|
307
|
+
}
|
|
308
|
+
updates.push('is_default = ?');
|
|
309
|
+
params.push(changes.isDefault ? 1 : 0);
|
|
310
|
+
}
|
|
311
|
+
if (updates.length > 0) {
|
|
312
|
+
params.push(id);
|
|
313
|
+
this.ctx.db.prepare(`UPDATE ${T.workflow_statuses} SET ${updates.join(', ')} WHERE id = ?`).run(...params);
|
|
314
|
+
// Update workflow's updated_at timestamp
|
|
315
|
+
this.ctx.db.prepare(`UPDATE ${T.workflows} SET updated_at = ? WHERE id = ?`).run(new Date().toISOString(), existing.workflowId);
|
|
316
|
+
}
|
|
317
|
+
return (await this.getStatus(id));
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Delete a status.
|
|
321
|
+
*/
|
|
322
|
+
async deleteStatus(id) {
|
|
323
|
+
const existing = await this.getStatus(id);
|
|
324
|
+
if (!existing) {
|
|
325
|
+
throw new PMOError('NOT_FOUND', `Status not found: ${id}`);
|
|
326
|
+
}
|
|
327
|
+
// Check if any tickets use this status
|
|
328
|
+
const ticketCount = this.ctx.db.prepare(`
|
|
329
|
+
SELECT COUNT(*) as count FROM ${T.tickets}
|
|
330
|
+
WHERE status_id = ?
|
|
331
|
+
`).get(id);
|
|
332
|
+
if (ticketCount.count > 0) {
|
|
333
|
+
throw new PMOError('CONFLICT', `Cannot delete status: ${ticketCount.count} ticket(s) are using it`);
|
|
334
|
+
}
|
|
335
|
+
this.ctx.db.prepare(`DELETE FROM ${T.workflow_statuses} WHERE id = ?`).run(id);
|
|
336
|
+
// Reorder remaining statuses
|
|
337
|
+
this.ctx.db.prepare(`
|
|
338
|
+
UPDATE ${T.workflow_statuses}
|
|
339
|
+
SET position = position - 1
|
|
340
|
+
WHERE workflow_id = ? AND position > ?
|
|
341
|
+
`).run(existing.workflowId, existing.position);
|
|
342
|
+
// Update workflow's updated_at timestamp
|
|
343
|
+
this.ctx.db.prepare(`UPDATE ${T.workflows} SET updated_at = ? WHERE id = ?`).run(new Date().toISOString(), existing.workflowId);
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* Reorder a status to a new position.
|
|
347
|
+
*/
|
|
348
|
+
async reorderStatus(id, newPosition) {
|
|
349
|
+
const existing = await this.getStatus(id);
|
|
350
|
+
if (!existing) {
|
|
351
|
+
throw new PMOError('NOT_FOUND', `Status not found: ${id}`);
|
|
352
|
+
}
|
|
353
|
+
const oldPosition = existing.position;
|
|
354
|
+
if (oldPosition === newPosition) {
|
|
355
|
+
return existing;
|
|
356
|
+
}
|
|
357
|
+
// Shift other statuses
|
|
358
|
+
if (newPosition < oldPosition) {
|
|
359
|
+
this.ctx.db.prepare(`
|
|
360
|
+
UPDATE ${T.workflow_statuses}
|
|
361
|
+
SET position = position + 1
|
|
362
|
+
WHERE workflow_id = ? AND position >= ? AND position < ?
|
|
363
|
+
`).run(existing.workflowId, newPosition, oldPosition);
|
|
364
|
+
}
|
|
365
|
+
else {
|
|
366
|
+
this.ctx.db.prepare(`
|
|
367
|
+
UPDATE ${T.workflow_statuses}
|
|
368
|
+
SET position = position - 1
|
|
369
|
+
WHERE workflow_id = ? AND position > ? AND position <= ?
|
|
370
|
+
`).run(existing.workflowId, oldPosition, newPosition);
|
|
371
|
+
}
|
|
372
|
+
// Update the status's position
|
|
373
|
+
this.ctx.db.prepare(`
|
|
374
|
+
UPDATE ${T.workflow_statuses}
|
|
375
|
+
SET position = ?
|
|
376
|
+
WHERE id = ?
|
|
377
|
+
`).run(newPosition, id);
|
|
378
|
+
// Update workflow's updated_at timestamp
|
|
379
|
+
this.ctx.db.prepare(`UPDATE ${T.workflows} SET updated_at = ? WHERE id = ?`).run(new Date().toISOString(), existing.workflowId);
|
|
380
|
+
return (await this.getStatus(id));
|
|
381
|
+
}
|
|
382
|
+
/**
|
|
383
|
+
* Get the default status for a workflow.
|
|
384
|
+
*/
|
|
385
|
+
async getDefaultStatus(workflowId) {
|
|
386
|
+
const row = this.ctx.db.prepare(`
|
|
387
|
+
SELECT * FROM ${T.workflow_statuses}
|
|
388
|
+
WHERE workflow_id = ? AND is_default = 1
|
|
389
|
+
`).get(workflowId);
|
|
390
|
+
if (!row) {
|
|
391
|
+
// If no explicit default, return first status (by position)
|
|
392
|
+
const fallback = this.ctx.db.prepare(`
|
|
393
|
+
SELECT * FROM ${T.workflow_statuses}
|
|
394
|
+
WHERE workflow_id = ?
|
|
395
|
+
ORDER BY position
|
|
396
|
+
LIMIT 1
|
|
397
|
+
`).get(workflowId);
|
|
398
|
+
if (!fallback)
|
|
399
|
+
return null;
|
|
400
|
+
return rowToWorkflowStatus(fallback);
|
|
401
|
+
}
|
|
402
|
+
return rowToWorkflowStatus(row);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Subtask operations for tickets.
|
|
3
|
+
*/
|
|
4
|
+
import { Subtask, AcceptanceCriterion } from '../types.js';
|
|
5
|
+
import { StorageContext } from './types.js';
|
|
6
|
+
export declare class SubtaskStorage {
|
|
7
|
+
private ctx;
|
|
8
|
+
constructor(ctx: StorageContext);
|
|
9
|
+
/**
|
|
10
|
+
* Add a subtask to a ticket.
|
|
11
|
+
*/
|
|
12
|
+
addSubtask(ticketId: string, title: string): Promise<Subtask>;
|
|
13
|
+
/**
|
|
14
|
+
* Toggle a subtask's done status.
|
|
15
|
+
*/
|
|
16
|
+
toggleSubtask(ticketId: string, subtaskId: string): Promise<Subtask>;
|
|
17
|
+
/**
|
|
18
|
+
* Remove a subtask from a ticket.
|
|
19
|
+
*/
|
|
20
|
+
removeSubtask(ticketId: string, subtaskId: string): Promise<void>;
|
|
21
|
+
}
|
|
22
|
+
export declare class AcceptanceCriteriaStorage {
|
|
23
|
+
private ctx;
|
|
24
|
+
constructor(ctx: StorageContext);
|
|
25
|
+
/**
|
|
26
|
+
* Add an acceptance criterion to a ticket.
|
|
27
|
+
*/
|
|
28
|
+
addAcceptanceCriterion(ticketId: string, criterion: string): Promise<AcceptanceCriterion>;
|
|
29
|
+
/**
|
|
30
|
+
* Remove an acceptance criterion from a ticket.
|
|
31
|
+
*/
|
|
32
|
+
removeAcceptanceCriterion(ticketId: string, criterionId: string): Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* Clear all acceptance criteria from a ticket.
|
|
35
|
+
*/
|
|
36
|
+
clearAcceptanceCriteria(ticketId: string): Promise<void>;
|
|
37
|
+
}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Subtask operations for tickets.
|
|
3
|
+
*/
|
|
4
|
+
import { PMO_TABLES } from '../schema.js';
|
|
5
|
+
import { PMOError } from '../types.js';
|
|
6
|
+
import { slugify } from '../utils.js';
|
|
7
|
+
const T = PMO_TABLES;
|
|
8
|
+
export class SubtaskStorage {
|
|
9
|
+
ctx;
|
|
10
|
+
constructor(ctx) {
|
|
11
|
+
this.ctx = ctx;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Add a subtask to a ticket.
|
|
15
|
+
*/
|
|
16
|
+
async addSubtask(ticketId, title) {
|
|
17
|
+
// Verify ticket exists and get project_id
|
|
18
|
+
const ticket = this.ctx.db.prepare(`
|
|
19
|
+
SELECT id, project_id FROM ${T.tickets} WHERE id = ?
|
|
20
|
+
`).get(ticketId);
|
|
21
|
+
if (!ticket) {
|
|
22
|
+
throw new PMOError('NOT_FOUND', `Ticket not found: ${ticketId}`, ticketId);
|
|
23
|
+
}
|
|
24
|
+
// Get current max position
|
|
25
|
+
const maxPos = this.ctx.db.prepare(`
|
|
26
|
+
SELECT COALESCE(MAX(position), -1) as max_pos
|
|
27
|
+
FROM ${T.subtasks} WHERE ticket_id = ?
|
|
28
|
+
`).get(ticketId);
|
|
29
|
+
const id = slugify(title);
|
|
30
|
+
const position = maxPos.max_pos + 1;
|
|
31
|
+
this.ctx.db.prepare(`
|
|
32
|
+
INSERT INTO ${T.subtasks} (id, ticket_id, title, done, position)
|
|
33
|
+
VALUES (?, ?, ?, 0, ?)
|
|
34
|
+
`).run(id, ticketId, title, position);
|
|
35
|
+
// Update ticket timestamp
|
|
36
|
+
this.ctx.db.prepare(`
|
|
37
|
+
UPDATE ${T.tickets} SET updated_at = ? WHERE id = ?
|
|
38
|
+
`).run(Date.now(), ticketId);
|
|
39
|
+
this.ctx.updateBoardTimestamp(ticket.project_id);
|
|
40
|
+
return {
|
|
41
|
+
id,
|
|
42
|
+
title,
|
|
43
|
+
done: false,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Toggle a subtask's done status.
|
|
48
|
+
*/
|
|
49
|
+
async toggleSubtask(ticketId, subtaskId) {
|
|
50
|
+
// Get ticket's project_id for board timestamp update
|
|
51
|
+
const ticket = this.ctx.db.prepare(`
|
|
52
|
+
SELECT project_id FROM ${T.tickets} WHERE id = ?
|
|
53
|
+
`).get(ticketId);
|
|
54
|
+
const existing = this.ctx.db.prepare(`
|
|
55
|
+
SELECT * FROM ${T.subtasks}
|
|
56
|
+
WHERE ticket_id = ? AND id = ?
|
|
57
|
+
`).get(ticketId, subtaskId);
|
|
58
|
+
if (!existing) {
|
|
59
|
+
throw new PMOError('NOT_FOUND', `Subtask not found: ${subtaskId}`);
|
|
60
|
+
}
|
|
61
|
+
const newDone = existing.done === 0 ? 1 : 0;
|
|
62
|
+
this.ctx.db.prepare(`
|
|
63
|
+
UPDATE ${T.subtasks}
|
|
64
|
+
SET done = ?
|
|
65
|
+
WHERE ticket_id = ? AND id = ?
|
|
66
|
+
`).run(newDone, ticketId, subtaskId);
|
|
67
|
+
// Update ticket timestamp
|
|
68
|
+
this.ctx.db.prepare(`
|
|
69
|
+
UPDATE ${T.tickets} SET updated_at = ? WHERE id = ?
|
|
70
|
+
`).run(Date.now(), ticketId);
|
|
71
|
+
if (ticket) {
|
|
72
|
+
this.ctx.updateBoardTimestamp(ticket.project_id);
|
|
73
|
+
}
|
|
74
|
+
return {
|
|
75
|
+
id: existing.id,
|
|
76
|
+
title: existing.title,
|
|
77
|
+
done: newDone === 1,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Remove a subtask from a ticket.
|
|
82
|
+
*/
|
|
83
|
+
async removeSubtask(ticketId, subtaskId) {
|
|
84
|
+
// Get ticket's project_id for board timestamp update
|
|
85
|
+
const ticket = this.ctx.db.prepare(`
|
|
86
|
+
SELECT project_id FROM ${T.tickets} WHERE id = ?
|
|
87
|
+
`).get(ticketId);
|
|
88
|
+
const result = this.ctx.db.prepare(`
|
|
89
|
+
DELETE FROM ${T.subtasks}
|
|
90
|
+
WHERE ticket_id = ? AND id = ?
|
|
91
|
+
`).run(ticketId, subtaskId);
|
|
92
|
+
if (result.changes === 0) {
|
|
93
|
+
throw new PMOError('NOT_FOUND', `Subtask not found: ${subtaskId}`);
|
|
94
|
+
}
|
|
95
|
+
// Update ticket timestamp
|
|
96
|
+
this.ctx.db.prepare(`
|
|
97
|
+
UPDATE ${T.tickets} SET updated_at = ? WHERE id = ?
|
|
98
|
+
`).run(Date.now(), ticketId);
|
|
99
|
+
if (ticket) {
|
|
100
|
+
this.ctx.updateBoardTimestamp(ticket.project_id);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
export class AcceptanceCriteriaStorage {
|
|
105
|
+
ctx;
|
|
106
|
+
constructor(ctx) {
|
|
107
|
+
this.ctx = ctx;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Add an acceptance criterion to a ticket.
|
|
111
|
+
*/
|
|
112
|
+
async addAcceptanceCriterion(ticketId, criterion) {
|
|
113
|
+
// Verify ticket exists and get project_id
|
|
114
|
+
const ticket = this.ctx.db.prepare(`
|
|
115
|
+
SELECT id, project_id FROM ${T.tickets} WHERE id = ?
|
|
116
|
+
`).get(ticketId);
|
|
117
|
+
if (!ticket) {
|
|
118
|
+
throw new PMOError('NOT_FOUND', `Ticket not found: ${ticketId}`, ticketId);
|
|
119
|
+
}
|
|
120
|
+
// Get current max position
|
|
121
|
+
const maxPos = this.ctx.db.prepare(`
|
|
122
|
+
SELECT COALESCE(MAX(position), -1) as max_pos
|
|
123
|
+
FROM ${T.ticket_acceptance_criteria} WHERE ticket_id = ?
|
|
124
|
+
`).get(ticketId);
|
|
125
|
+
const id = `ac-${Date.now()}`;
|
|
126
|
+
const position = maxPos.max_pos + 1;
|
|
127
|
+
this.ctx.db.prepare(`
|
|
128
|
+
INSERT INTO ${T.ticket_acceptance_criteria} (id, ticket_id, criterion, verifiable, verified, position)
|
|
129
|
+
VALUES (?, ?, ?, 1, 0, ?)
|
|
130
|
+
`).run(id, ticketId, criterion, position);
|
|
131
|
+
this.ctx.db.prepare(`
|
|
132
|
+
UPDATE ${T.tickets} SET updated_at = ? WHERE id = ?
|
|
133
|
+
`).run(Date.now(), ticketId);
|
|
134
|
+
this.ctx.updateBoardTimestamp(ticket.project_id);
|
|
135
|
+
return {
|
|
136
|
+
id,
|
|
137
|
+
ticketId,
|
|
138
|
+
criterion,
|
|
139
|
+
verifiable: true,
|
|
140
|
+
verified: false,
|
|
141
|
+
position,
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Remove an acceptance criterion from a ticket.
|
|
146
|
+
*/
|
|
147
|
+
async removeAcceptanceCriterion(ticketId, criterionId) {
|
|
148
|
+
// Get ticket's project_id for board timestamp update
|
|
149
|
+
const ticket = this.ctx.db.prepare(`
|
|
150
|
+
SELECT project_id FROM ${T.tickets} WHERE id = ?
|
|
151
|
+
`).get(ticketId);
|
|
152
|
+
const result = this.ctx.db.prepare(`
|
|
153
|
+
DELETE FROM ${T.ticket_acceptance_criteria}
|
|
154
|
+
WHERE ticket_id = ? AND id = ?
|
|
155
|
+
`).run(ticketId, criterionId);
|
|
156
|
+
if (result.changes === 0) {
|
|
157
|
+
throw new PMOError('NOT_FOUND', `Acceptance criterion not found: ${criterionId}`);
|
|
158
|
+
}
|
|
159
|
+
this.ctx.db.prepare(`
|
|
160
|
+
UPDATE ${T.tickets} SET updated_at = ? WHERE id = ?
|
|
161
|
+
`).run(Date.now(), ticketId);
|
|
162
|
+
if (ticket) {
|
|
163
|
+
this.ctx.updateBoardTimestamp(ticket.project_id);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Clear all acceptance criteria from a ticket.
|
|
168
|
+
*/
|
|
169
|
+
async clearAcceptanceCriteria(ticketId) {
|
|
170
|
+
// Get ticket's project_id for board timestamp update
|
|
171
|
+
const ticket = this.ctx.db.prepare(`
|
|
172
|
+
SELECT project_id FROM ${T.tickets} WHERE id = ?
|
|
173
|
+
`).get(ticketId);
|
|
174
|
+
this.ctx.db.prepare(`
|
|
175
|
+
DELETE FROM ${T.ticket_acceptance_criteria} WHERE ticket_id = ?
|
|
176
|
+
`).run(ticketId);
|
|
177
|
+
this.ctx.db.prepare(`
|
|
178
|
+
UPDATE ${T.tickets} SET updated_at = ? WHERE id = ?
|
|
179
|
+
`).run(Date.now(), ticketId);
|
|
180
|
+
if (ticket) {
|
|
181
|
+
this.ctx.updateBoardTimestamp(ticket.project_id);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ticket template operations.
|
|
3
|
+
*
|
|
4
|
+
* Note: Workflow templates have been removed. Workflows are now used directly
|
|
5
|
+
* as the source of truth for status configurations. See workflow commands
|
|
6
|
+
* and StatusStorage for workflow operations.
|
|
7
|
+
*/
|
|
8
|
+
import { TicketTemplate, TicketTemplateFilter } from '../types.js';
|
|
9
|
+
import type { StorageContext } from './types.js';
|
|
10
|
+
export declare class TemplateStorage {
|
|
11
|
+
private ctx;
|
|
12
|
+
constructor(ctx: StorageContext);
|
|
13
|
+
/**
|
|
14
|
+
* List ticket templates.
|
|
15
|
+
*/
|
|
16
|
+
listTicketTemplates(filter?: TicketTemplateFilter): Promise<TicketTemplate[]>;
|
|
17
|
+
/**
|
|
18
|
+
* Get a ticket template by ID.
|
|
19
|
+
*/
|
|
20
|
+
getTicketTemplate(id: string): Promise<TicketTemplate | null>;
|
|
21
|
+
/**
|
|
22
|
+
* Create a new ticket template.
|
|
23
|
+
*/
|
|
24
|
+
createTicketTemplate(template: Partial<TicketTemplate> & {
|
|
25
|
+
name: string;
|
|
26
|
+
}): Promise<TicketTemplate>;
|
|
27
|
+
/**
|
|
28
|
+
* Create a ticket template from an existing ticket.
|
|
29
|
+
*/
|
|
30
|
+
createTicketTemplateFromTicket(ticketId: string, name: string, description?: string): Promise<TicketTemplate>;
|
|
31
|
+
/**
|
|
32
|
+
* Update a ticket template.
|
|
33
|
+
*/
|
|
34
|
+
updateTicketTemplate(id: string, changes: Partial<TicketTemplate>): Promise<TicketTemplate>;
|
|
35
|
+
/**
|
|
36
|
+
* Delete a ticket template.
|
|
37
|
+
*/
|
|
38
|
+
deleteTicketTemplate(id: string): Promise<void>;
|
|
39
|
+
private rowToTicketTemplate;
|
|
40
|
+
}
|