@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,79 @@
|
|
|
1
|
+
import { Args, Flags } from '@oclif/core';
|
|
2
|
+
import inquirer from 'inquirer';
|
|
3
|
+
import { PMOCommand, pmoBaseFlags, autoExportToBoard } from '../../../lib/pmo/index.js';
|
|
4
|
+
import { styles } from '../../../lib/styles.js';
|
|
5
|
+
import { shouldOutputJson, outputPromptAsJson, outputErrorAsJson, createMetadata, buildPromptConfig, } from '../../../lib/prompt-json.js';
|
|
6
|
+
export default class EpicLinkBlock extends PMOCommand {
|
|
7
|
+
static description = 'Add a blocking dependency (epic is blocked by another)';
|
|
8
|
+
static examples = [
|
|
9
|
+
'<%= config.bin %> <%= command.id %> EPIC-001 EPIC-002 # EPIC-001 is blocked by EPIC-002',
|
|
10
|
+
];
|
|
11
|
+
static args = {
|
|
12
|
+
id: Args.string({ description: 'Epic ID that will be blocked', required: true }),
|
|
13
|
+
blocker: Args.string({ description: 'Epic ID that blocks this epic', required: false }),
|
|
14
|
+
};
|
|
15
|
+
static flags = {
|
|
16
|
+
...pmoBaseFlags,
|
|
17
|
+
project: Flags.string({ char: 'P', description: 'Project ID' }),
|
|
18
|
+
json: Flags.boolean({
|
|
19
|
+
description: 'Output prompt configuration as JSON (for AI agents/scripts)',
|
|
20
|
+
default: false,
|
|
21
|
+
}),
|
|
22
|
+
};
|
|
23
|
+
async execute() {
|
|
24
|
+
const { args, flags } = await this.parse(EpicLinkBlock);
|
|
25
|
+
// Check if JSON output mode is active
|
|
26
|
+
const jsonMode = shouldOutputJson(flags);
|
|
27
|
+
// Helper to handle errors in JSON mode
|
|
28
|
+
const handleError = (code, message) => {
|
|
29
|
+
if (jsonMode) {
|
|
30
|
+
outputErrorAsJson(code, message, createMetadata('epic link block', flags));
|
|
31
|
+
this.exit(1);
|
|
32
|
+
}
|
|
33
|
+
this.error(message);
|
|
34
|
+
};
|
|
35
|
+
const epic = await this.storage.getEpic(args.id);
|
|
36
|
+
if (!epic)
|
|
37
|
+
return handleError('EPIC_NOT_FOUND', `Epic not found: ${args.id}`);
|
|
38
|
+
const projectId = epic.projectId;
|
|
39
|
+
let blockerId = args.blocker;
|
|
40
|
+
if (!blockerId) {
|
|
41
|
+
const allEpics = await this.storage.listEpics(projectId);
|
|
42
|
+
const otherEpics = allEpics.filter(e => e.id !== args.id);
|
|
43
|
+
if (otherEpics.length === 0) {
|
|
44
|
+
if (jsonMode) {
|
|
45
|
+
outputErrorAsJson('NO_OTHER_EPICS', 'No other epics.', createMetadata('epic link block', flags));
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
this.log(styles.muted('\nNo other epics.'));
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
// In JSON mode, output blocker selection prompt
|
|
52
|
+
if (jsonMode) {
|
|
53
|
+
const epicChoices = otherEpics.map(e => ({ name: `${e.id} - ${e.title} (${e.status})`, value: e.id }));
|
|
54
|
+
outputPromptAsJson(buildPromptConfig('list', 'blocker', `Select epic that blocks ${args.id}:`, epicChoices), createMetadata('epic link block', flags));
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
const { selected } = await inquirer.prompt([{
|
|
58
|
+
type: 'list', name: 'selected', message: `Select epic that blocks ${args.id}:`,
|
|
59
|
+
choices: otherEpics.map(e => ({ name: `${e.id} - ${e.title} (${e.status})`, value: e.id })),
|
|
60
|
+
}]);
|
|
61
|
+
blockerId = selected;
|
|
62
|
+
}
|
|
63
|
+
const blockerEpic = await this.storage.getEpic(blockerId);
|
|
64
|
+
if (!blockerEpic)
|
|
65
|
+
return handleError('BLOCKER_EPIC_NOT_FOUND', `Epic not found: ${blockerId}`);
|
|
66
|
+
try {
|
|
67
|
+
await this.storage.createEpicDependency(args.id, blockerId, 'blocks');
|
|
68
|
+
await autoExportToBoard(this.pmoPath, this.storage, (msg) => this.log(styles.muted(msg)));
|
|
69
|
+
this.log(styles.success(`\n✅ ${styles.emphasis(args.id)} is blocked by ${styles.emphasis(blockerId)}`));
|
|
70
|
+
this.log(styles.muted(` ${epic.title} blocked by: ${blockerEpic.title}`));
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
if (error instanceof Error && (error.message.includes('already exists') || error.message.includes('self-dependency'))) {
|
|
74
|
+
this.error(error.message.includes('already exists') ? 'Dependency already exists' : 'Cannot create self-dependency');
|
|
75
|
+
}
|
|
76
|
+
throw error;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { PMOCommand } from '../../../lib/pmo/index.js';
|
|
2
|
+
export default class EpicLinkDuplicates extends PMOCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static args: {
|
|
6
|
+
id: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
7
|
+
original: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
8
|
+
};
|
|
9
|
+
static flags: {
|
|
10
|
+
project: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
12
|
+
};
|
|
13
|
+
execute(): Promise<void>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { Args, Flags } from '@oclif/core';
|
|
2
|
+
import inquirer from 'inquirer';
|
|
3
|
+
import { PMOCommand, pmoBaseFlags, autoExportToBoard } from '../../../lib/pmo/index.js';
|
|
4
|
+
import { styles } from '../../../lib/styles.js';
|
|
5
|
+
import { shouldOutputJson, outputPromptAsJson, outputErrorAsJson, createMetadata, buildPromptConfig, } from '../../../lib/prompt-json.js';
|
|
6
|
+
export default class EpicLinkDuplicates extends PMOCommand {
|
|
7
|
+
static description = 'Mark an epic as duplicate of another';
|
|
8
|
+
static examples = ['<%= config.bin %> <%= command.id %> EPIC-001 EPIC-002'];
|
|
9
|
+
static args = {
|
|
10
|
+
id: Args.string({ description: 'Duplicate epic ID', required: true }),
|
|
11
|
+
original: Args.string({ description: 'Original epic ID', required: false }),
|
|
12
|
+
};
|
|
13
|
+
static flags = {
|
|
14
|
+
...pmoBaseFlags,
|
|
15
|
+
project: Flags.string({ char: 'P', description: 'Project ID' }),
|
|
16
|
+
json: Flags.boolean({
|
|
17
|
+
description: 'Output prompt configuration as JSON (for AI agents/scripts)',
|
|
18
|
+
default: false,
|
|
19
|
+
}),
|
|
20
|
+
};
|
|
21
|
+
async execute() {
|
|
22
|
+
const { args, flags } = await this.parse(EpicLinkDuplicates);
|
|
23
|
+
// Check if JSON output mode is active
|
|
24
|
+
const jsonMode = shouldOutputJson(flags);
|
|
25
|
+
// Helper to handle errors in JSON mode
|
|
26
|
+
const handleError = (code, message) => {
|
|
27
|
+
if (jsonMode) {
|
|
28
|
+
outputErrorAsJson(code, message, createMetadata('epic link duplicates', flags));
|
|
29
|
+
this.exit(1);
|
|
30
|
+
}
|
|
31
|
+
this.error(message);
|
|
32
|
+
};
|
|
33
|
+
const epic = await this.storage.getEpic(args.id);
|
|
34
|
+
if (!epic)
|
|
35
|
+
return handleError('EPIC_NOT_FOUND', `Epic not found: ${args.id}`);
|
|
36
|
+
const projectId = epic.projectId;
|
|
37
|
+
let originalId = args.original;
|
|
38
|
+
if (!originalId) {
|
|
39
|
+
const allEpics = await this.storage.listEpics(projectId);
|
|
40
|
+
const otherEpics = allEpics.filter(e => e.id !== args.id);
|
|
41
|
+
if (otherEpics.length === 0) {
|
|
42
|
+
if (jsonMode) {
|
|
43
|
+
outputErrorAsJson('NO_OTHER_EPICS', 'No other epics.', createMetadata('epic link duplicates', flags));
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
this.log(styles.muted('\nNo other epics.'));
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
// In JSON mode, output original epic selection prompt
|
|
50
|
+
if (jsonMode) {
|
|
51
|
+
const epicChoices = otherEpics.map(e => ({ name: `${e.id} - ${e.title}`, value: e.id }));
|
|
52
|
+
outputPromptAsJson(buildPromptConfig('list', 'original', `Select the original epic (${args.id} is a duplicate of):`, epicChoices), createMetadata('epic link duplicates', flags));
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
const { selected } = await inquirer.prompt([{ type: 'list', name: 'selected', message: `Select the original epic (${args.id} is a duplicate of):`,
|
|
56
|
+
choices: otherEpics.map(e => ({ name: `${e.id} - ${e.title}`, value: e.id })) }]);
|
|
57
|
+
originalId = selected;
|
|
58
|
+
}
|
|
59
|
+
const originalEpic = await this.storage.getEpic(originalId);
|
|
60
|
+
if (!originalEpic)
|
|
61
|
+
return handleError('ORIGINAL_EPIC_NOT_FOUND', `Epic not found: ${originalId}`);
|
|
62
|
+
await this.storage.createEpicDependency(args.id, originalId, 'duplicates');
|
|
63
|
+
await autoExportToBoard(this.pmoPath, this.storage, (msg) => this.log(styles.muted(msg)));
|
|
64
|
+
this.log(styles.success(`\n✅ ${styles.emphasis(args.id)} duplicates ${styles.emphasis(originalId)}`));
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { PMOCommand } from '../../../lib/pmo/index.js';
|
|
2
|
+
export default class EpicLink extends PMOCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static args: {
|
|
6
|
+
id: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
7
|
+
};
|
|
8
|
+
static flags: {
|
|
9
|
+
project: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
|
+
blocks: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
|
+
relates: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
|
+
duplicates: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
13
|
+
all: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
14
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
15
|
+
};
|
|
16
|
+
execute(): Promise<void>;
|
|
17
|
+
private addDependency;
|
|
18
|
+
private viewDependencies;
|
|
19
|
+
}
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
import { Args, Flags } from '@oclif/core';
|
|
2
|
+
import inquirer from 'inquirer';
|
|
3
|
+
import { PMOCommand, pmoBaseFlags, autoExportToBoard } from '../../../lib/pmo/index.js';
|
|
4
|
+
import { styles } from '../../../lib/styles.js';
|
|
5
|
+
import { shouldOutputJson, outputPromptAsJson, outputErrorAsJson, createMetadata, buildPromptConfig, } from '../../../lib/prompt-json.js';
|
|
6
|
+
export default class EpicLink extends PMOCommand {
|
|
7
|
+
static description = 'Manage epic dependencies (links)';
|
|
8
|
+
static examples = [
|
|
9
|
+
'<%= config.bin %> <%= command.id %> EPIC-001 # List dependencies',
|
|
10
|
+
'<%= config.bin %> <%= command.id %> EPIC-001 --blocks EPIC-002 # EPIC-001 is blocked by EPIC-002',
|
|
11
|
+
'<%= config.bin %> <%= command.id %> EPIC-001 --relates EPIC-002 # EPIC-001 relates to EPIC-002',
|
|
12
|
+
'<%= config.bin %> <%= command.id %> EPIC-001 --duplicates EPIC-002',
|
|
13
|
+
'<%= config.bin %> <%= command.id %> EPIC-001 --all # Show all links',
|
|
14
|
+
];
|
|
15
|
+
static args = {
|
|
16
|
+
id: Args.string({
|
|
17
|
+
description: 'Epic ID',
|
|
18
|
+
required: false,
|
|
19
|
+
}),
|
|
20
|
+
};
|
|
21
|
+
static flags = {
|
|
22
|
+
...pmoBaseFlags,
|
|
23
|
+
project: Flags.string({
|
|
24
|
+
char: 'P',
|
|
25
|
+
description: 'Project ID (default: "default")',
|
|
26
|
+
}),
|
|
27
|
+
blocks: Flags.string({
|
|
28
|
+
char: 'b',
|
|
29
|
+
description: 'Add blocking dependency: this epic is blocked by TARGET',
|
|
30
|
+
}),
|
|
31
|
+
relates: Flags.string({
|
|
32
|
+
char: 'r',
|
|
33
|
+
description: 'Add relates_to dependency',
|
|
34
|
+
}),
|
|
35
|
+
duplicates: Flags.string({
|
|
36
|
+
char: 'd',
|
|
37
|
+
description: 'Add duplicates dependency',
|
|
38
|
+
}),
|
|
39
|
+
all: Flags.boolean({
|
|
40
|
+
char: 'a',
|
|
41
|
+
description: 'Show all dependencies (blockers and blocking)',
|
|
42
|
+
default: false,
|
|
43
|
+
}),
|
|
44
|
+
json: Flags.boolean({
|
|
45
|
+
description: 'Output prompt configuration as JSON (for AI agents/scripts)',
|
|
46
|
+
default: false,
|
|
47
|
+
}),
|
|
48
|
+
};
|
|
49
|
+
async execute() {
|
|
50
|
+
const { args, flags } = await this.parse(EpicLink);
|
|
51
|
+
// Check if JSON output mode is active
|
|
52
|
+
const jsonMode = shouldOutputJson(flags);
|
|
53
|
+
// Helper to handle errors in JSON mode
|
|
54
|
+
const handleError = (code, message) => {
|
|
55
|
+
if (jsonMode) {
|
|
56
|
+
outputErrorAsJson(code, message, createMetadata('epic link', flags));
|
|
57
|
+
this.exit(1);
|
|
58
|
+
}
|
|
59
|
+
this.error(message);
|
|
60
|
+
};
|
|
61
|
+
const projectId = await this.requireProject();
|
|
62
|
+
let epicId = args.id;
|
|
63
|
+
if (!epicId) {
|
|
64
|
+
const epics = await this.storage.listEpics(projectId);
|
|
65
|
+
if (epics.length === 0) {
|
|
66
|
+
if (jsonMode) {
|
|
67
|
+
outputErrorAsJson('NO_EPICS', 'No epics found.', createMetadata('epic link', flags));
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
this.log(styles.muted('\nNo epics found.'));
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
// In JSON mode, output epic selection prompt
|
|
74
|
+
if (jsonMode) {
|
|
75
|
+
const epicChoices = epics.map(e => ({ name: `${e.id} - ${e.title}`, value: e.id }));
|
|
76
|
+
outputPromptAsJson(buildPromptConfig('list', 'id', 'Select epic to manage dependencies:', epicChoices), createMetadata('epic link', flags));
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
const { selected } = await inquirer.prompt([{
|
|
80
|
+
type: 'list',
|
|
81
|
+
name: 'selected',
|
|
82
|
+
message: 'Select epic to manage dependencies:',
|
|
83
|
+
choices: epics.map(e => ({ name: `${e.id} - ${e.title}`, value: e.id })),
|
|
84
|
+
}]);
|
|
85
|
+
epicId = selected;
|
|
86
|
+
}
|
|
87
|
+
const epic = await this.storage.getEpic(epicId);
|
|
88
|
+
if (!epic) {
|
|
89
|
+
return handleError('EPIC_NOT_FOUND', `Epic not found: ${epicId}`);
|
|
90
|
+
}
|
|
91
|
+
// If a dependency flag is provided, add the dependency directly
|
|
92
|
+
if (flags.blocks || flags.relates || flags.duplicates) {
|
|
93
|
+
const targetId = flags.blocks || flags.relates || flags.duplicates;
|
|
94
|
+
const dependencyType = flags.blocks ? 'blocks' :
|
|
95
|
+
flags.relates ? 'relates_to' : 'duplicates';
|
|
96
|
+
await this.addDependency(epicId, targetId, dependencyType, epic.title);
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
// Interactive mode: show menu in a loop
|
|
100
|
+
let continueLoop = true;
|
|
101
|
+
while (continueLoop) {
|
|
102
|
+
const allEpics = await this.storage.listEpics(projectId);
|
|
103
|
+
const otherEpics = allEpics.filter(e => e.id !== epicId);
|
|
104
|
+
const { action } = await inquirer.prompt([{
|
|
105
|
+
type: 'list',
|
|
106
|
+
name: 'action',
|
|
107
|
+
message: `Dependencies for ${epic.id}:`,
|
|
108
|
+
choices: [
|
|
109
|
+
{ name: 'View dependencies', value: 'view' },
|
|
110
|
+
{ name: 'Add blocking dependency (blocked by...)', value: 'blocks' },
|
|
111
|
+
{ name: 'Add relates_to dependency', value: 'relates_to' },
|
|
112
|
+
{ name: 'Add duplicates dependency', value: 'duplicates' },
|
|
113
|
+
new inquirer.Separator(),
|
|
114
|
+
{ name: 'Remove dependency', value: 'remove' },
|
|
115
|
+
{ name: 'Done', value: 'done' },
|
|
116
|
+
],
|
|
117
|
+
}]);
|
|
118
|
+
if (action === 'done') {
|
|
119
|
+
continueLoop = false;
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
if (action === 'view') {
|
|
123
|
+
await this.viewDependencies(epicId, epic, flags.all);
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
if (action === 'remove') {
|
|
127
|
+
const dependencies = await this.storage.listEpicDependencies(epicId);
|
|
128
|
+
if (dependencies.length === 0) {
|
|
129
|
+
this.log(styles.muted('\nNo dependencies to remove.'));
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
const choices = await Promise.all(dependencies.map(async (dep) => {
|
|
133
|
+
const depEpic = await this.storage.getEpic(dep.dependsOnEpicId);
|
|
134
|
+
return {
|
|
135
|
+
name: `${dep.dependsOnEpicId} - ${depEpic?.title || 'Unknown'} (${dep.dependencyType})`,
|
|
136
|
+
value: { targetId: dep.dependsOnEpicId, type: dep.dependencyType }
|
|
137
|
+
};
|
|
138
|
+
}));
|
|
139
|
+
const { selected } = await inquirer.prompt([{
|
|
140
|
+
type: 'list',
|
|
141
|
+
name: 'selected',
|
|
142
|
+
message: 'Select dependency to remove:',
|
|
143
|
+
choices,
|
|
144
|
+
}]);
|
|
145
|
+
await this.storage.deleteEpicDependency(epicId, selected.targetId, selected.type);
|
|
146
|
+
await autoExportToBoard(this.pmoPath, this.storage, (msg) => this.log(styles.muted(msg)));
|
|
147
|
+
this.log(styles.success(`\n✅ Removed dependency: ${epicId} → ${selected.targetId}`));
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
// Add dependency
|
|
151
|
+
if (otherEpics.length === 0) {
|
|
152
|
+
this.log(styles.muted('\nNo other epics to link to.'));
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
const { targetId } = await inquirer.prompt([{
|
|
156
|
+
type: 'list',
|
|
157
|
+
name: 'targetId',
|
|
158
|
+
message: `Select epic that ${epicId} ${action === 'blocks' ? 'is blocked by' : action === 'relates_to' ? 'relates to' : 'duplicates'}:`,
|
|
159
|
+
choices: otherEpics.map(e => ({ name: `${e.id} - ${e.title}`, value: e.id })),
|
|
160
|
+
}]);
|
|
161
|
+
await this.addDependency(epicId, targetId, action, epic.title);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
async addDependency(epicId, targetId, dependencyType, epicTitle) {
|
|
165
|
+
const targetEpic = await this.storage.getEpic(targetId);
|
|
166
|
+
if (!targetEpic) {
|
|
167
|
+
this.error(`Epic not found: ${targetId}`);
|
|
168
|
+
}
|
|
169
|
+
try {
|
|
170
|
+
await this.storage.createEpicDependency(epicId, targetId, dependencyType);
|
|
171
|
+
await autoExportToBoard(this.pmoPath, this.storage, (msg) => this.log(styles.muted(msg)));
|
|
172
|
+
const typeLabel = dependencyType === 'blocks' ? 'is blocked by' :
|
|
173
|
+
dependencyType === 'relates_to' ? 'relates to' : 'duplicates';
|
|
174
|
+
this.log(styles.success(`\n✅ ${styles.emphasis(epicId)} ${typeLabel} ${styles.emphasis(targetId)}`));
|
|
175
|
+
this.log(styles.muted(` ${epicTitle}`));
|
|
176
|
+
this.log(styles.muted(` ${typeLabel} ${targetEpic.title}`));
|
|
177
|
+
}
|
|
178
|
+
catch (error) {
|
|
179
|
+
if (error instanceof Error) {
|
|
180
|
+
if (error.message.includes('already exists')) {
|
|
181
|
+
this.error('Dependency already exists');
|
|
182
|
+
}
|
|
183
|
+
if (error.message.includes('self-dependency')) {
|
|
184
|
+
this.error('Cannot create self-dependency');
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
throw error;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
async viewDependencies(epicId, epic, showAll) {
|
|
191
|
+
const dependencies = await this.storage.listEpicDependencies(epicId);
|
|
192
|
+
const isBlocked = await this.storage.isEpicBlocked(epicId);
|
|
193
|
+
this.log(`\n${styles.emphasis(epic.id)}: ${epic.title}`);
|
|
194
|
+
if (isBlocked) {
|
|
195
|
+
this.log(styles.warning(' Status: BLOCKED'));
|
|
196
|
+
}
|
|
197
|
+
const blockers = dependencies.filter(d => d.dependencyType === 'blocks');
|
|
198
|
+
if (blockers.length > 0) {
|
|
199
|
+
this.log(styles.muted('\n Blocked by:'));
|
|
200
|
+
for (const dep of blockers) {
|
|
201
|
+
const blockerEpic = await this.storage.getEpic(dep.dependsOnEpicId);
|
|
202
|
+
if (blockerEpic) {
|
|
203
|
+
const status = blockerEpic.status === 'complete' ? styles.success('complete') : styles.warning(blockerEpic.status);
|
|
204
|
+
this.log(` - ${blockerEpic.id}: ${blockerEpic.title} (${status})`);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
const otherDeps = dependencies.filter(d => d.dependencyType !== 'blocks');
|
|
209
|
+
if (otherDeps.length > 0) {
|
|
210
|
+
this.log(styles.muted('\n Related:'));
|
|
211
|
+
for (const dep of otherDeps) {
|
|
212
|
+
const relatedEpic = await this.storage.getEpic(dep.dependsOnEpicId);
|
|
213
|
+
if (relatedEpic) {
|
|
214
|
+
this.log(` - ${dep.dependencyType}: ${relatedEpic.id} - ${relatedEpic.title}`);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
if (showAll) {
|
|
219
|
+
const allEpics = await this.storage.listEpics(epic.projectId);
|
|
220
|
+
const blocking = [];
|
|
221
|
+
for (const otherEpic of allEpics) {
|
|
222
|
+
if (otherEpic.id === epicId)
|
|
223
|
+
continue;
|
|
224
|
+
const otherDeps = await this.storage.listEpicDependencies(otherEpic.id);
|
|
225
|
+
const blockingDep = otherDeps.find(d => d.dependsOnEpicId === epicId);
|
|
226
|
+
if (blockingDep) {
|
|
227
|
+
blocking.push({ epic: otherEpic, type: blockingDep.dependencyType });
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
if (blocking.length > 0) {
|
|
231
|
+
this.log(styles.muted('\n Blocking:'));
|
|
232
|
+
for (const { epic: blockedEpic, type } of blocking) {
|
|
233
|
+
this.log(` - ${blockedEpic.id}: ${blockedEpic.title} (${type})`);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
if (dependencies.length === 0) {
|
|
238
|
+
this.log(styles.muted('\n No dependencies.'));
|
|
239
|
+
}
|
|
240
|
+
this.log('');
|
|
241
|
+
}
|
|
242
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { PMOCommand } from '../../../lib/pmo/index.js';
|
|
2
|
+
export default class EpicLinkRelates extends PMOCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static args: {
|
|
6
|
+
id: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
7
|
+
target: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
8
|
+
};
|
|
9
|
+
static flags: {
|
|
10
|
+
project: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
12
|
+
};
|
|
13
|
+
execute(): Promise<void>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { Args, Flags } from '@oclif/core';
|
|
2
|
+
import inquirer from 'inquirer';
|
|
3
|
+
import { PMOCommand, pmoBaseFlags, autoExportToBoard } from '../../../lib/pmo/index.js';
|
|
4
|
+
import { styles } from '../../../lib/styles.js';
|
|
5
|
+
import { shouldOutputJson, outputPromptAsJson, outputErrorAsJson, createMetadata, buildPromptConfig, } from '../../../lib/prompt-json.js';
|
|
6
|
+
export default class EpicLinkRelates extends PMOCommand {
|
|
7
|
+
static description = 'Add a relates_to dependency (informational link)';
|
|
8
|
+
static examples = ['<%= config.bin %> <%= command.id %> EPIC-001 EPIC-002'];
|
|
9
|
+
static args = {
|
|
10
|
+
id: Args.string({ description: 'Epic ID', required: true }),
|
|
11
|
+
target: Args.string({ description: 'Related epic ID', required: false }),
|
|
12
|
+
};
|
|
13
|
+
static flags = {
|
|
14
|
+
...pmoBaseFlags,
|
|
15
|
+
project: Flags.string({ char: 'P', description: 'Project ID' }),
|
|
16
|
+
json: Flags.boolean({
|
|
17
|
+
description: 'Output prompt configuration as JSON (for AI agents/scripts)',
|
|
18
|
+
default: false,
|
|
19
|
+
}),
|
|
20
|
+
};
|
|
21
|
+
async execute() {
|
|
22
|
+
const { args, flags } = await this.parse(EpicLinkRelates);
|
|
23
|
+
// Check if JSON output mode is active
|
|
24
|
+
const jsonMode = shouldOutputJson(flags);
|
|
25
|
+
// Helper to handle errors in JSON mode
|
|
26
|
+
const handleError = (code, message) => {
|
|
27
|
+
if (jsonMode) {
|
|
28
|
+
outputErrorAsJson(code, message, createMetadata('epic link relates', flags));
|
|
29
|
+
this.exit(1);
|
|
30
|
+
}
|
|
31
|
+
this.error(message);
|
|
32
|
+
};
|
|
33
|
+
const epic = await this.storage.getEpic(args.id);
|
|
34
|
+
if (!epic)
|
|
35
|
+
return handleError('EPIC_NOT_FOUND', `Epic not found: ${args.id}`);
|
|
36
|
+
const projectId = epic.projectId;
|
|
37
|
+
let targetId = args.target;
|
|
38
|
+
if (!targetId) {
|
|
39
|
+
const allEpics = await this.storage.listEpics(projectId);
|
|
40
|
+
const otherEpics = allEpics.filter(e => e.id !== args.id);
|
|
41
|
+
if (otherEpics.length === 0) {
|
|
42
|
+
if (jsonMode) {
|
|
43
|
+
outputErrorAsJson('NO_OTHER_EPICS', 'No other epics.', createMetadata('epic link relates', flags));
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
this.log(styles.muted('\nNo other epics.'));
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
// In JSON mode, output target epic selection prompt
|
|
50
|
+
if (jsonMode) {
|
|
51
|
+
const epicChoices = otherEpics.map(e => ({ name: `${e.id} - ${e.title}`, value: e.id }));
|
|
52
|
+
outputPromptAsJson(buildPromptConfig('list', 'target', `Select epic that ${args.id} relates to:`, epicChoices), createMetadata('epic link relates', flags));
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
const { selected } = await inquirer.prompt([{ type: 'list', name: 'selected', message: `Select epic that ${args.id} relates to:`,
|
|
56
|
+
choices: otherEpics.map(e => ({ name: `${e.id} - ${e.title}`, value: e.id })) }]);
|
|
57
|
+
targetId = selected;
|
|
58
|
+
}
|
|
59
|
+
const targetEpic = await this.storage.getEpic(targetId);
|
|
60
|
+
if (!targetEpic)
|
|
61
|
+
return handleError('TARGET_EPIC_NOT_FOUND', `Epic not found: ${targetId}`);
|
|
62
|
+
await this.storage.createEpicDependency(args.id, targetId, 'relates_to');
|
|
63
|
+
await autoExportToBoard(this.pmoPath, this.storage, (msg) => this.log(styles.muted(msg)));
|
|
64
|
+
this.log(styles.success(`\n✅ ${styles.emphasis(args.id)} relates to ${styles.emphasis(targetId)}`));
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { PMOCommand } from '../../../lib/pmo/index.js';
|
|
2
|
+
export default class EpicLinkRemove extends PMOCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static args: {
|
|
6
|
+
id: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
7
|
+
target: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
8
|
+
};
|
|
9
|
+
static flags: {
|
|
10
|
+
project: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
|
+
type: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
|
+
all: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
13
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
14
|
+
};
|
|
15
|
+
execute(): Promise<void>;
|
|
16
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { Args, Flags } from '@oclif/core';
|
|
2
|
+
import inquirer from 'inquirer';
|
|
3
|
+
import { PMOCommand, pmoBaseFlags, autoExportToBoard } from '../../../lib/pmo/index.js';
|
|
4
|
+
import { styles } from '../../../lib/styles.js';
|
|
5
|
+
import { shouldOutputJson, outputPromptAsJson, outputErrorAsJson, createMetadata, buildPromptConfig, } from '../../../lib/prompt-json.js';
|
|
6
|
+
export default class EpicLinkRemove extends PMOCommand {
|
|
7
|
+
static description = 'Remove a dependency from an epic';
|
|
8
|
+
static examples = [
|
|
9
|
+
'<%= config.bin %> <%= command.id %> EPIC-001 EPIC-002',
|
|
10
|
+
'<%= config.bin %> <%= command.id %> EPIC-001 --all',
|
|
11
|
+
];
|
|
12
|
+
static args = {
|
|
13
|
+
id: Args.string({ description: 'Epic ID', required: true }),
|
|
14
|
+
target: Args.string({ description: 'Target epic ID to unlink', required: false }),
|
|
15
|
+
};
|
|
16
|
+
static flags = {
|
|
17
|
+
...pmoBaseFlags,
|
|
18
|
+
project: Flags.string({ char: 'P', description: 'Project ID' }),
|
|
19
|
+
type: Flags.string({ char: 't', description: 'Dependency type', options: ['blocks', 'relates_to', 'duplicates'] }),
|
|
20
|
+
all: Flags.boolean({ char: 'a', description: 'Remove all dependencies', default: false }),
|
|
21
|
+
json: Flags.boolean({
|
|
22
|
+
description: 'Output prompt configuration as JSON (for AI agents/scripts)',
|
|
23
|
+
default: false,
|
|
24
|
+
}),
|
|
25
|
+
};
|
|
26
|
+
async execute() {
|
|
27
|
+
const { args, flags } = await this.parse(EpicLinkRemove);
|
|
28
|
+
// Check if JSON output mode is active
|
|
29
|
+
const jsonMode = shouldOutputJson(flags);
|
|
30
|
+
// Helper to handle errors in JSON mode
|
|
31
|
+
const handleError = (code, message) => {
|
|
32
|
+
if (jsonMode) {
|
|
33
|
+
outputErrorAsJson(code, message, createMetadata('epic link remove', flags));
|
|
34
|
+
this.exit(1);
|
|
35
|
+
}
|
|
36
|
+
this.error(message);
|
|
37
|
+
};
|
|
38
|
+
const epic = await this.storage.getEpic(args.id);
|
|
39
|
+
if (!epic)
|
|
40
|
+
return handleError('EPIC_NOT_FOUND', `Epic not found: ${args.id}`);
|
|
41
|
+
const dependencies = await this.storage.listEpicDependencies(args.id);
|
|
42
|
+
if (dependencies.length === 0) {
|
|
43
|
+
if (jsonMode) {
|
|
44
|
+
outputErrorAsJson('NO_DEPENDENCIES', `Epic ${args.id} has no dependencies.`, createMetadata('epic link remove', flags));
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
this.log(styles.muted(`\nEpic ${args.id} has no dependencies.`));
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
if (flags.all) {
|
|
51
|
+
// In JSON mode, output confirmation prompt
|
|
52
|
+
if (jsonMode) {
|
|
53
|
+
const confirmChoices = [
|
|
54
|
+
{ name: 'No', value: 'false' },
|
|
55
|
+
{ name: 'Yes', value: 'true' },
|
|
56
|
+
];
|
|
57
|
+
outputPromptAsJson(buildPromptConfig('list', 'confirmed', `Remove all ${dependencies.length} dependencies?`, confirmChoices), createMetadata('epic link remove', flags));
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
const { confirmed } = await inquirer.prompt([{ type: 'confirm', name: 'confirmed', message: `Remove all ${dependencies.length} dependencies?`, default: false }]);
|
|
61
|
+
if (!confirmed) {
|
|
62
|
+
this.log(styles.muted('\nCancelled.'));
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
for (const dep of dependencies)
|
|
66
|
+
await this.storage.deleteEpicDependency(args.id, dep.dependsOnEpicId, dep.dependencyType);
|
|
67
|
+
await autoExportToBoard(this.pmoPath, this.storage, (msg) => this.log(styles.muted(msg)));
|
|
68
|
+
this.log(styles.success(`\n✅ Removed ${dependencies.length} dependencies from ${args.id}`));
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
let targetId = args.target;
|
|
72
|
+
if (!targetId) {
|
|
73
|
+
const choices = await Promise.all(dependencies.map(async (dep) => {
|
|
74
|
+
const depEpic = await this.storage.getEpic(dep.dependsOnEpicId);
|
|
75
|
+
return { name: `${dep.dependsOnEpicId} - ${depEpic?.title || 'Unknown'} (${dep.dependencyType})`, value: dep.dependsOnEpicId };
|
|
76
|
+
}));
|
|
77
|
+
// In JSON mode, output dependency selection prompt
|
|
78
|
+
if (jsonMode) {
|
|
79
|
+
outputPromptAsJson(buildPromptConfig('list', 'target', 'Select dependency to remove:', choices), createMetadata('epic link remove', flags));
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
const { selected } = await inquirer.prompt([{ type: 'list', name: 'selected', message: 'Select dependency to remove:', choices }]);
|
|
83
|
+
targetId = selected;
|
|
84
|
+
}
|
|
85
|
+
await this.storage.deleteEpicDependency(args.id, targetId, flags.type);
|
|
86
|
+
await autoExportToBoard(this.pmoPath, this.storage, (msg) => this.log(styles.muted(msg)));
|
|
87
|
+
this.log(styles.success(`\n✅ Removed dependency: ${args.id} → ${targetId}`));
|
|
88
|
+
}
|
|
89
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { PMOCommand } from '../../lib/pmo/index.js';
|
|
2
|
+
export default class EpicList extends PMOCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static flags: {
|
|
6
|
+
status: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
7
|
+
project: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
8
|
+
};
|
|
9
|
+
execute(): Promise<void>;
|
|
10
|
+
private groupByStatus;
|
|
11
|
+
}
|