@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,108 @@
|
|
|
1
|
+
import { Flags, Args } from '@oclif/core';
|
|
2
|
+
import inquirer from 'inquirer';
|
|
3
|
+
import { PMOCommand, pmoBaseFlags } 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 SpecPlan extends PMOCommand {
|
|
7
|
+
static description = 'Generate tickets from spec by comparing ideal state vs codebase (uses LLM)';
|
|
8
|
+
static examples = [
|
|
9
|
+
'<%= config.bin %> <%= command.id %> user-authentication',
|
|
10
|
+
'<%= config.bin %> <%= command.id %> --spec api-design --dry-run',
|
|
11
|
+
];
|
|
12
|
+
static args = {
|
|
13
|
+
spec: Args.string({
|
|
14
|
+
description: 'Spec ID',
|
|
15
|
+
required: false,
|
|
16
|
+
}),
|
|
17
|
+
};
|
|
18
|
+
static flags = {
|
|
19
|
+
...pmoBaseFlags,
|
|
20
|
+
json: Flags.boolean({
|
|
21
|
+
description: 'Output prompt configuration as JSON (for AI agents/scripts)',
|
|
22
|
+
default: false,
|
|
23
|
+
}),
|
|
24
|
+
spec: Flags.string({
|
|
25
|
+
char: 's',
|
|
26
|
+
description: 'Spec ID',
|
|
27
|
+
}),
|
|
28
|
+
'dry-run': Flags.boolean({
|
|
29
|
+
description: 'Show what would be created without creating tickets',
|
|
30
|
+
default: false,
|
|
31
|
+
}),
|
|
32
|
+
};
|
|
33
|
+
async execute() {
|
|
34
|
+
const { args, flags } = await this.parse(SpecPlan);
|
|
35
|
+
// Check if JSON output mode is active
|
|
36
|
+
const jsonMode = shouldOutputJson(flags);
|
|
37
|
+
// Helper to handle errors in JSON mode
|
|
38
|
+
const handleError = (code, message) => {
|
|
39
|
+
if (jsonMode) {
|
|
40
|
+
outputErrorAsJson(code, message, createMetadata('spec plan', flags));
|
|
41
|
+
this.exit(1);
|
|
42
|
+
}
|
|
43
|
+
this.error(message);
|
|
44
|
+
};
|
|
45
|
+
// Get spec ID
|
|
46
|
+
let specId = args.spec || flags.spec;
|
|
47
|
+
if (!specId) {
|
|
48
|
+
// List specs and prompt for selection
|
|
49
|
+
const specs = await this.storage.listSpecs();
|
|
50
|
+
if (specs.length === 0) {
|
|
51
|
+
return handleError('NO_SPECS', 'No specs found. Create a spec first with "prlt spec create".');
|
|
52
|
+
}
|
|
53
|
+
// In JSON mode, output spec selection prompt
|
|
54
|
+
if (jsonMode) {
|
|
55
|
+
const specChoices = specs.map(s => ({
|
|
56
|
+
name: `${s.title} [${s.status}]${s.type ? ` (${s.type})` : ''}`,
|
|
57
|
+
value: s.id,
|
|
58
|
+
}));
|
|
59
|
+
outputPromptAsJson(buildPromptConfig('list', 'spec', 'Select spec to plan:', specChoices), createMetadata('spec plan', flags));
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
const { selectedSpec } = await inquirer.prompt([
|
|
63
|
+
{
|
|
64
|
+
type: 'list',
|
|
65
|
+
name: 'selectedSpec',
|
|
66
|
+
message: 'Select spec to plan:',
|
|
67
|
+
choices: specs.map(s => ({
|
|
68
|
+
name: `${s.title} [${s.status}]${s.type ? ` (${s.type})` : ''}`,
|
|
69
|
+
value: s.id,
|
|
70
|
+
})),
|
|
71
|
+
},
|
|
72
|
+
]);
|
|
73
|
+
specId = selectedSpec;
|
|
74
|
+
}
|
|
75
|
+
// Get the spec
|
|
76
|
+
const spec = await this.storage.getSpec(specId);
|
|
77
|
+
if (!spec) {
|
|
78
|
+
this.error(`Spec not found: ${specId}`);
|
|
79
|
+
}
|
|
80
|
+
this.log(styles.header(`\n📋 Planning from spec: ${spec.title}`));
|
|
81
|
+
this.log('');
|
|
82
|
+
// TODO: Call LLM to compare spec vs codebase and generate tickets
|
|
83
|
+
// For now, just show the spec content
|
|
84
|
+
this.log(styles.muted('Spec content:'));
|
|
85
|
+
if (spec.problem) {
|
|
86
|
+
this.log(styles.muted(`\nProblem:`));
|
|
87
|
+
this.log(` ${spec.problem}`);
|
|
88
|
+
}
|
|
89
|
+
if (spec.solution) {
|
|
90
|
+
this.log(styles.muted(`\nSolution:`));
|
|
91
|
+
this.log(` ${spec.solution}`);
|
|
92
|
+
}
|
|
93
|
+
if (spec.acceptanceCriteria) {
|
|
94
|
+
this.log(styles.muted(`\nAcceptance Criteria:`));
|
|
95
|
+
this.log(` ${spec.acceptanceCriteria}`);
|
|
96
|
+
}
|
|
97
|
+
this.log('');
|
|
98
|
+
this.log(styles.warning('LLM-based ticket generation not yet implemented.'));
|
|
99
|
+
this.log(styles.muted('This command will:'));
|
|
100
|
+
this.log(styles.muted(' 1. Read the spec (ideal state)'));
|
|
101
|
+
this.log(styles.muted(' 2. Analyze the codebase (current state)'));
|
|
102
|
+
this.log(styles.muted(' 3. Generate tickets for the delta'));
|
|
103
|
+
this.log('');
|
|
104
|
+
if (flags['dry-run']) {
|
|
105
|
+
this.log(styles.muted('(dry-run mode - no tickets would be created)'));
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { PMOCommand } from '../../lib/pmo/index.js';
|
|
2
|
+
export default class SpecTicket extends PMOCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static args: {
|
|
6
|
+
ticketId: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
7
|
+
specId: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
8
|
+
};
|
|
9
|
+
static flags: {
|
|
10
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
11
|
+
ticket: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
|
+
spec: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
13
|
+
project: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
14
|
+
};
|
|
15
|
+
execute(): Promise<void>;
|
|
16
|
+
private listAvailableSpecs;
|
|
17
|
+
private findSpecFile;
|
|
18
|
+
}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { Flags, Args } from '@oclif/core';
|
|
2
|
+
import * as fs from 'node:fs';
|
|
3
|
+
import * as path from 'node:path';
|
|
4
|
+
import inquirer from 'inquirer';
|
|
5
|
+
import { PMOCommand, pmoBaseFlags, autoExportToBoard } from '../../lib/pmo/index.js';
|
|
6
|
+
import { styles } from '../../lib/styles.js';
|
|
7
|
+
import { shouldOutputJson, outputPromptAsJson, outputErrorAsJson, createMetadata, buildPromptConfig, } from '../../lib/prompt-json.js';
|
|
8
|
+
export default class SpecTicket extends PMOCommand {
|
|
9
|
+
static description = 'Assign a ticket to a spec document';
|
|
10
|
+
static examples = [
|
|
11
|
+
'<%= config.bin %> <%= command.id %> PRLT-001 user-authentication',
|
|
12
|
+
'<%= config.bin %> <%= command.id %> --ticket PRLT-001 --spec api-design',
|
|
13
|
+
];
|
|
14
|
+
static args = {
|
|
15
|
+
ticketId: Args.string({
|
|
16
|
+
description: 'Ticket ID',
|
|
17
|
+
required: false,
|
|
18
|
+
}),
|
|
19
|
+
specId: Args.string({
|
|
20
|
+
description: 'Spec ID (filename without .md)',
|
|
21
|
+
required: false,
|
|
22
|
+
}),
|
|
23
|
+
};
|
|
24
|
+
static flags = {
|
|
25
|
+
...pmoBaseFlags,
|
|
26
|
+
json: Flags.boolean({
|
|
27
|
+
description: 'Output prompt configuration as JSON (for AI agents/scripts)',
|
|
28
|
+
default: false,
|
|
29
|
+
}),
|
|
30
|
+
ticket: Flags.string({
|
|
31
|
+
char: 't',
|
|
32
|
+
description: 'Ticket ID',
|
|
33
|
+
}),
|
|
34
|
+
spec: Flags.string({
|
|
35
|
+
char: 's',
|
|
36
|
+
description: 'Spec ID (filename without .md)',
|
|
37
|
+
}),
|
|
38
|
+
};
|
|
39
|
+
async execute() {
|
|
40
|
+
const { args, flags } = await this.parse(SpecTicket);
|
|
41
|
+
// This command requires project context
|
|
42
|
+
const projectId = await this.requireProject();
|
|
43
|
+
// Check if JSON output mode is active
|
|
44
|
+
const jsonMode = shouldOutputJson(flags);
|
|
45
|
+
// Helper to handle errors in JSON mode
|
|
46
|
+
const handleError = (code, message) => {
|
|
47
|
+
if (jsonMode) {
|
|
48
|
+
outputErrorAsJson(code, message, createMetadata('spec ticket', flags));
|
|
49
|
+
this.exit(1);
|
|
50
|
+
}
|
|
51
|
+
this.error(message);
|
|
52
|
+
};
|
|
53
|
+
// Get ticket ID
|
|
54
|
+
let ticketId = args.ticketId || flags.ticket;
|
|
55
|
+
if (!ticketId) {
|
|
56
|
+
const tickets = await this.storage.listTickets(projectId);
|
|
57
|
+
if (tickets.length === 0) {
|
|
58
|
+
return handleError('NO_TICKETS', 'No tickets found. Create one first with: prlt ticket create');
|
|
59
|
+
}
|
|
60
|
+
// In JSON mode, output ticket selection prompt
|
|
61
|
+
if (jsonMode) {
|
|
62
|
+
const ticketChoices = tickets.map(t => ({ name: `${t.id}: ${t.title}`, value: t.id }));
|
|
63
|
+
outputPromptAsJson(buildPromptConfig('list', 'ticketId', 'Select ticket to link:', ticketChoices), createMetadata('spec ticket', flags));
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
const { selectedTicket } = await inquirer.prompt([{
|
|
67
|
+
type: 'list',
|
|
68
|
+
name: 'selectedTicket',
|
|
69
|
+
message: 'Select ticket to link:',
|
|
70
|
+
choices: tickets.map(t => ({ name: `${t.id}: ${t.title}`, value: t.id })),
|
|
71
|
+
}]);
|
|
72
|
+
ticketId = selectedTicket;
|
|
73
|
+
}
|
|
74
|
+
if (!ticketId) {
|
|
75
|
+
return handleError('NO_TICKET_SELECTED', 'No ticket selected');
|
|
76
|
+
}
|
|
77
|
+
// Get ticket
|
|
78
|
+
const ticket = await this.storage.getTicket(ticketId);
|
|
79
|
+
if (!ticket) {
|
|
80
|
+
const projectName = await this.getProjectName(projectId);
|
|
81
|
+
return handleError('TICKET_NOT_FOUND', `Ticket "${ticketId}" not found in project "${projectName}"`);
|
|
82
|
+
}
|
|
83
|
+
// Get spec ID
|
|
84
|
+
let specId = args.specId || flags.spec;
|
|
85
|
+
if (!specId) {
|
|
86
|
+
const specs = await this.listAvailableSpecs(this.pmoPath, projectId);
|
|
87
|
+
if (specs.length === 0) {
|
|
88
|
+
return handleError('NO_SPECS', 'No specs found. Create one first with: prlt spec create');
|
|
89
|
+
}
|
|
90
|
+
// In JSON mode, output spec selection prompt
|
|
91
|
+
if (jsonMode) {
|
|
92
|
+
const specChoices = specs.map(s => ({ name: `${s.name} (${s.status})`, value: s.id }));
|
|
93
|
+
outputPromptAsJson(buildPromptConfig('list', 'specId', 'Select spec to link:', specChoices), createMetadata('spec ticket', flags));
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
const { selectedSpec } = await inquirer.prompt([{
|
|
97
|
+
type: 'list',
|
|
98
|
+
name: 'selectedSpec',
|
|
99
|
+
message: 'Select spec to link:',
|
|
100
|
+
choices: specs.map(s => ({ name: `${s.name} (${s.status})`, value: s.id })),
|
|
101
|
+
}]);
|
|
102
|
+
specId = selectedSpec;
|
|
103
|
+
}
|
|
104
|
+
if (!specId) {
|
|
105
|
+
this.error('No spec selected');
|
|
106
|
+
}
|
|
107
|
+
// Verify spec exists
|
|
108
|
+
const specPath = this.findSpecFile(this.pmoPath, projectId, specId);
|
|
109
|
+
if (!specPath) {
|
|
110
|
+
const projectName = await this.getProjectName(projectId);
|
|
111
|
+
this.error(`Spec "${specId}" not found in project "${projectName}"`);
|
|
112
|
+
}
|
|
113
|
+
// Check if already linked
|
|
114
|
+
if (ticket.specId === specId) {
|
|
115
|
+
this.log(styles.warning(`Ticket "${ticketId}" is already linked to spec "${specId}"`));
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
// Warn if ticket already has a different spec
|
|
119
|
+
if (ticket.specId && ticket.specId !== specId) {
|
|
120
|
+
this.log(styles.warning(`Ticket "${ticketId}" is currently linked to spec "${ticket.specId}"`));
|
|
121
|
+
this.log(styles.muted(`This will replace the existing spec link.`));
|
|
122
|
+
}
|
|
123
|
+
// Set spec on ticket (single spec per ticket)
|
|
124
|
+
await this.storage.updateTicket(ticketId, { specId });
|
|
125
|
+
// Auto-export to board.md
|
|
126
|
+
await autoExportToBoard(this.pmoPath, this.storage, (msg) => this.log(styles.muted(msg)));
|
|
127
|
+
this.log(styles.success(`\n✅ Linked ticket "${styles.emphasis(ticketId)}" to spec "${styles.emphasis(specId)}"`));
|
|
128
|
+
this.log(styles.muted(`\nView ticket:`));
|
|
129
|
+
this.log(styles.muted(` prlt ticket view ${ticketId}`));
|
|
130
|
+
}
|
|
131
|
+
async listAvailableSpecs(pmoPath, projectId) {
|
|
132
|
+
const specsBasePath = path.join(pmoPath, 'projects', projectId, 'specs');
|
|
133
|
+
const specs = [];
|
|
134
|
+
if (!fs.existsSync(specsBasePath)) {
|
|
135
|
+
return specs;
|
|
136
|
+
}
|
|
137
|
+
for (const status of ['active', 'draft', 'archived']) {
|
|
138
|
+
const statusPath = path.join(specsBasePath, status);
|
|
139
|
+
if (!fs.existsSync(statusPath)) {
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
const files = fs.readdirSync(statusPath).filter(f => f.endsWith('.md'));
|
|
143
|
+
for (const file of files) {
|
|
144
|
+
const id = path.basename(file, '.md');
|
|
145
|
+
specs.push({ id, name: id, status });
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return specs;
|
|
149
|
+
}
|
|
150
|
+
findSpecFile(pmoPath, projectId, specId) {
|
|
151
|
+
const specsBasePath = path.join(pmoPath, 'projects', projectId, 'specs');
|
|
152
|
+
for (const status of ['active', 'draft', 'archived']) {
|
|
153
|
+
const specPath = path.join(specsBasePath, status, `${specId}.md`);
|
|
154
|
+
if (fs.existsSync(specPath)) {
|
|
155
|
+
return specPath;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return null;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { PMOCommand } from '../../lib/pmo/index.js';
|
|
2
|
+
export default class SpecView extends PMOCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static args: {
|
|
6
|
+
spec: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
7
|
+
};
|
|
8
|
+
static flags: {
|
|
9
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
|
+
spec: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
|
+
full: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
12
|
+
project: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
13
|
+
};
|
|
14
|
+
execute(): Promise<void>;
|
|
15
|
+
}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { Flags, Args } from '@oclif/core';
|
|
2
|
+
import { PMOCommand, pmoBaseFlags } from '../../lib/pmo/index.js';
|
|
3
|
+
import { styles } from '../../lib/styles.js';
|
|
4
|
+
import { shouldOutputJson, outputErrorAsJson, createMetadata, } from '../../lib/prompt-json.js';
|
|
5
|
+
export default class SpecView extends PMOCommand {
|
|
6
|
+
static description = 'View a spec and its linked tickets';
|
|
7
|
+
static examples = [
|
|
8
|
+
'<%= config.bin %> <%= command.id %> user-authentication',
|
|
9
|
+
'<%= config.bin %> <%= command.id %> --spec api-design',
|
|
10
|
+
];
|
|
11
|
+
static args = {
|
|
12
|
+
spec: Args.string({
|
|
13
|
+
description: 'Spec ID',
|
|
14
|
+
required: false,
|
|
15
|
+
}),
|
|
16
|
+
};
|
|
17
|
+
static flags = {
|
|
18
|
+
...pmoBaseFlags,
|
|
19
|
+
json: Flags.boolean({
|
|
20
|
+
description: 'Output prompt configuration as JSON (for AI agents/scripts)',
|
|
21
|
+
default: false,
|
|
22
|
+
}),
|
|
23
|
+
spec: Flags.string({
|
|
24
|
+
char: 's',
|
|
25
|
+
description: 'Spec ID',
|
|
26
|
+
}),
|
|
27
|
+
full: Flags.boolean({
|
|
28
|
+
char: 'f',
|
|
29
|
+
description: 'Show all spec sections',
|
|
30
|
+
default: false,
|
|
31
|
+
}),
|
|
32
|
+
};
|
|
33
|
+
async execute() {
|
|
34
|
+
const { args, flags } = await this.parse(SpecView);
|
|
35
|
+
// This command requires project context for listing linked tickets
|
|
36
|
+
const projectId = await this.requireProject();
|
|
37
|
+
// Check if JSON output mode is active
|
|
38
|
+
const jsonMode = shouldOutputJson(flags);
|
|
39
|
+
// Helper to handle errors in JSON mode
|
|
40
|
+
const handleError = (code, message) => {
|
|
41
|
+
if (jsonMode) {
|
|
42
|
+
outputErrorAsJson(code, message, createMetadata('spec view', flags));
|
|
43
|
+
this.exit(1);
|
|
44
|
+
}
|
|
45
|
+
this.error(message);
|
|
46
|
+
};
|
|
47
|
+
// Get spec ID
|
|
48
|
+
let specId = args.spec || flags.spec;
|
|
49
|
+
if (!specId) {
|
|
50
|
+
const specs = await this.storage.listSpecs();
|
|
51
|
+
if (specs.length === 0) {
|
|
52
|
+
return handleError('NO_SPECS', 'No specs found. Create one first with: prlt spec create');
|
|
53
|
+
}
|
|
54
|
+
const selected = await this.selectFromList({
|
|
55
|
+
message: 'Select spec to view:',
|
|
56
|
+
items: specs,
|
|
57
|
+
getName: (s) => `${s.title} [${s.status}]${s.type ? ` (${s.type})` : ''}`,
|
|
58
|
+
getValue: (s) => s.id,
|
|
59
|
+
getCommand: (s) => `prlt spec view ${s.id} --json`,
|
|
60
|
+
jsonMode: jsonMode ? { flags, commandName: 'spec view' } : null,
|
|
61
|
+
});
|
|
62
|
+
if (!selected) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
specId = selected;
|
|
66
|
+
}
|
|
67
|
+
// Get the spec
|
|
68
|
+
const spec = await this.storage.getSpec(specId);
|
|
69
|
+
if (!spec) {
|
|
70
|
+
this.error(`Spec not found: ${specId}`);
|
|
71
|
+
}
|
|
72
|
+
// Get linked tickets
|
|
73
|
+
const tickets = await this.storage.getTicketsForSpec(projectId, spec.id);
|
|
74
|
+
// Get dependencies
|
|
75
|
+
const dependencies = await this.storage.getSpecDependencies(spec.id);
|
|
76
|
+
const dependents = await this.storage.getSpecDependents(spec.id);
|
|
77
|
+
// Display spec info
|
|
78
|
+
this.log(styles.title(`\n📄 ${spec.title}`));
|
|
79
|
+
this.log(styles.muted('═'.repeat(60)));
|
|
80
|
+
this.log(styles.muted(`ID: ${spec.id}`));
|
|
81
|
+
this.log(styles.muted(`Status: ${spec.status}`));
|
|
82
|
+
if (spec.type)
|
|
83
|
+
this.log(styles.muted(`Type: ${spec.type}`));
|
|
84
|
+
if (spec.tags && spec.tags.length > 0) {
|
|
85
|
+
this.log(styles.muted(`Tags: ${spec.tags.join(', ')}`));
|
|
86
|
+
}
|
|
87
|
+
this.log(styles.muted(`Created: ${spec.createdAt.toLocaleDateString()}`));
|
|
88
|
+
this.log(styles.muted(`Updated: ${spec.updatedAt.toLocaleDateString()}`));
|
|
89
|
+
// Problem
|
|
90
|
+
if (spec.problem) {
|
|
91
|
+
this.log(styles.emphasis('\n## Problem'));
|
|
92
|
+
this.log(spec.problem);
|
|
93
|
+
}
|
|
94
|
+
// Solution
|
|
95
|
+
if (spec.solution) {
|
|
96
|
+
this.log(styles.emphasis('\n## Solution'));
|
|
97
|
+
this.log(spec.solution);
|
|
98
|
+
}
|
|
99
|
+
// Decisions (always show)
|
|
100
|
+
if (spec.decisions) {
|
|
101
|
+
this.log(styles.emphasis('\n## Decisions'));
|
|
102
|
+
this.log(spec.decisions);
|
|
103
|
+
}
|
|
104
|
+
// Show more sections if --full
|
|
105
|
+
if (flags.full) {
|
|
106
|
+
if (spec.notNow) {
|
|
107
|
+
this.log(styles.emphasis('\n## Not Now'));
|
|
108
|
+
this.log(spec.notNow);
|
|
109
|
+
}
|
|
110
|
+
if (spec.uiUx) {
|
|
111
|
+
this.log(styles.emphasis('\n## UI/UX'));
|
|
112
|
+
this.log(spec.uiUx);
|
|
113
|
+
}
|
|
114
|
+
if (spec.acceptanceCriteria) {
|
|
115
|
+
this.log(styles.emphasis('\n## Acceptance Criteria'));
|
|
116
|
+
this.log(spec.acceptanceCriteria);
|
|
117
|
+
}
|
|
118
|
+
if (spec.openQuestions) {
|
|
119
|
+
this.log(styles.emphasis('\n## Open Questions'));
|
|
120
|
+
this.log(spec.openQuestions);
|
|
121
|
+
}
|
|
122
|
+
if (spec.requirementsFunctional) {
|
|
123
|
+
this.log(styles.emphasis('\n## Functional Requirements'));
|
|
124
|
+
this.log(spec.requirementsFunctional);
|
|
125
|
+
}
|
|
126
|
+
if (spec.requirementsTechnical) {
|
|
127
|
+
this.log(styles.emphasis('\n## Technical Requirements'));
|
|
128
|
+
this.log(spec.requirementsTechnical);
|
|
129
|
+
}
|
|
130
|
+
if (spec.context) {
|
|
131
|
+
this.log(styles.emphasis('\n## Context'));
|
|
132
|
+
this.log(spec.context);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
// Dependencies
|
|
136
|
+
if (dependencies.length > 0) {
|
|
137
|
+
this.log(styles.emphasis(`\n📦 Depends On (${dependencies.length}):`));
|
|
138
|
+
for (const dep of dependencies) {
|
|
139
|
+
this.log(` ${styles.code(dep.id)}: ${dep.title} [${dep.status}]`);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
if (dependents.length > 0) {
|
|
143
|
+
this.log(styles.emphasis(`\n📦 Depended On By (${dependents.length}):`));
|
|
144
|
+
for (const dep of dependents) {
|
|
145
|
+
this.log(` ${styles.code(dep.id)}: ${dep.title} [${dep.status}]`);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
// Linked tickets
|
|
149
|
+
if (tickets.length > 0) {
|
|
150
|
+
this.log(styles.emphasis(`\n🎫 Linked Tickets (${tickets.length}):`));
|
|
151
|
+
for (const ticket of tickets) {
|
|
152
|
+
this.log(` ${styles.code(ticket.id)}: ${ticket.title} [${ticket.status}]`);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
this.log(styles.muted('\n🎫 No linked tickets'));
|
|
157
|
+
}
|
|
158
|
+
this.log(styles.muted('\n' + '═'.repeat(60)));
|
|
159
|
+
if (!flags.full) {
|
|
160
|
+
this.log(styles.muted('Use --full to see all sections'));
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { PMOCommand } from '../../lib/pmo/index.js';
|
|
2
|
+
export default class StatusCreate extends PMOCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static args: {
|
|
6
|
+
name: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
7
|
+
};
|
|
8
|
+
static flags: {
|
|
9
|
+
name: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
|
+
category: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
|
+
color: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
|
+
description: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
13
|
+
default: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
14
|
+
interactive: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
15
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
16
|
+
project: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
17
|
+
};
|
|
18
|
+
execute(): Promise<void>;
|
|
19
|
+
private promptStatusData;
|
|
20
|
+
private getCategoryDescription;
|
|
21
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { Flags, Args } from '@oclif/core';
|
|
2
|
+
import inquirer from 'inquirer';
|
|
3
|
+
import { PMOCommand, pmoBaseFlags } from '../../lib/pmo/index.js';
|
|
4
|
+
import { styles } from '../../lib/styles.js';
|
|
5
|
+
import { STATE_CATEGORY_ORDER } from '../../lib/pmo/types.js';
|
|
6
|
+
import { shouldOutputJson, outputPromptAsJson, createMetadata, buildFormPromptConfig, } from '../../lib/prompt-json.js';
|
|
7
|
+
export default class StatusCreate extends PMOCommand {
|
|
8
|
+
static description = 'Create a new workflow status';
|
|
9
|
+
static examples = [
|
|
10
|
+
'<%= config.bin %> <%= command.id %> "In Review" --category started',
|
|
11
|
+
'<%= config.bin %> <%= command.id %> --name "Blocked" --category started --color "#EF4444"',
|
|
12
|
+
'<%= config.bin %> <%= command.id %> -i # Interactive mode',
|
|
13
|
+
];
|
|
14
|
+
static args = {
|
|
15
|
+
name: Args.string({
|
|
16
|
+
description: 'Status name',
|
|
17
|
+
required: false,
|
|
18
|
+
}),
|
|
19
|
+
};
|
|
20
|
+
static flags = {
|
|
21
|
+
...pmoBaseFlags,
|
|
22
|
+
name: Flags.string({
|
|
23
|
+
char: 'n',
|
|
24
|
+
description: 'Status name',
|
|
25
|
+
}),
|
|
26
|
+
category: Flags.string({
|
|
27
|
+
char: 'c',
|
|
28
|
+
description: 'Status category',
|
|
29
|
+
options: ['backlog', 'unstarted', 'started', 'completed', 'canceled'],
|
|
30
|
+
}),
|
|
31
|
+
color: Flags.string({
|
|
32
|
+
description: 'Hex color code (e.g., #FF0000)',
|
|
33
|
+
}),
|
|
34
|
+
description: Flags.string({
|
|
35
|
+
char: 'd',
|
|
36
|
+
description: 'Status description',
|
|
37
|
+
}),
|
|
38
|
+
default: Flags.boolean({
|
|
39
|
+
description: 'Set as default status for new tickets',
|
|
40
|
+
default: false,
|
|
41
|
+
}),
|
|
42
|
+
interactive: Flags.boolean({
|
|
43
|
+
char: 'i',
|
|
44
|
+
description: 'Interactive mode',
|
|
45
|
+
default: false,
|
|
46
|
+
}),
|
|
47
|
+
json: Flags.boolean({
|
|
48
|
+
description: 'Output prompt configuration as JSON (for AI agents/scripts)',
|
|
49
|
+
default: false,
|
|
50
|
+
}),
|
|
51
|
+
};
|
|
52
|
+
async execute() {
|
|
53
|
+
const { args, flags } = await this.parse(StatusCreate);
|
|
54
|
+
const projectId = await this.requireProject();
|
|
55
|
+
// Check if JSON output mode is active
|
|
56
|
+
const jsonMode = shouldOutputJson(flags);
|
|
57
|
+
let statusData;
|
|
58
|
+
// Auto-enter interactive mode if any required value is missing
|
|
59
|
+
const name = args.name || flags.name;
|
|
60
|
+
if (flags.interactive || !name || !flags.category) {
|
|
61
|
+
// Build choices once - single source of truth
|
|
62
|
+
const categoryChoices = STATE_CATEGORY_ORDER.map(cat => ({
|
|
63
|
+
name: `${cat} - ${this.getCategoryDescription(cat)}`,
|
|
64
|
+
value: cat,
|
|
65
|
+
}));
|
|
66
|
+
// Define fields once - single source of truth for both JSON and interactive modes
|
|
67
|
+
const fields = [
|
|
68
|
+
{ type: 'input', name: 'name', message: 'Status name:', default: name || flags.name },
|
|
69
|
+
{ type: 'list', name: 'category', message: 'Category:', choices: categoryChoices, default: flags.category || 'backlog' },
|
|
70
|
+
{ type: 'input', name: 'color', message: 'Color (hex, optional):', default: flags.color },
|
|
71
|
+
{ type: 'input', name: 'description', message: 'Description (optional):', default: flags.description },
|
|
72
|
+
{ type: 'confirm', name: 'isDefault', message: 'Set as default status for new tickets?', default: flags.default || false },
|
|
73
|
+
];
|
|
74
|
+
// In JSON mode, output form prompts
|
|
75
|
+
if (jsonMode) {
|
|
76
|
+
outputPromptAsJson(buildFormPromptConfig(fields), createMetadata('status create', flags));
|
|
77
|
+
}
|
|
78
|
+
statusData = await this.promptStatusData(fields);
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
statusData = {
|
|
82
|
+
name,
|
|
83
|
+
category: flags.category,
|
|
84
|
+
color: flags.color,
|
|
85
|
+
description: flags.description,
|
|
86
|
+
isDefault: flags.default,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
const status = await this.storage.createStatus(projectId, {
|
|
90
|
+
name: statusData.name,
|
|
91
|
+
category: statusData.category,
|
|
92
|
+
color: statusData.color,
|
|
93
|
+
description: statusData.description,
|
|
94
|
+
isDefault: statusData.isDefault,
|
|
95
|
+
});
|
|
96
|
+
const projectName = await this.getProjectName(projectId);
|
|
97
|
+
this.log(styles.success(`\nCreated status "${styles.emphasis(status.name)}"`));
|
|
98
|
+
this.log(styles.muted(` Category: ${status.category}`));
|
|
99
|
+
this.log(styles.muted(` Project: ${projectName}`));
|
|
100
|
+
if (status.color) {
|
|
101
|
+
this.log(styles.muted(` Color: ${status.color}`));
|
|
102
|
+
}
|
|
103
|
+
if (status.isDefault) {
|
|
104
|
+
this.log(styles.muted(` Default: yes`));
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
async promptStatusData(fields) {
|
|
108
|
+
// Build inquirer prompts from fields, adding validators
|
|
109
|
+
const answers = await inquirer.prompt(fields.map(field => ({
|
|
110
|
+
...field,
|
|
111
|
+
validate: field.name === 'name'
|
|
112
|
+
? ((input) => input.length > 0 || 'Name is required')
|
|
113
|
+
: field.name === 'color'
|
|
114
|
+
? ((input) => {
|
|
115
|
+
if (!input)
|
|
116
|
+
return true;
|
|
117
|
+
return /^#[0-9A-Fa-f]{6}$/.test(input) || 'Invalid hex color (e.g., #FF0000)';
|
|
118
|
+
})
|
|
119
|
+
: undefined,
|
|
120
|
+
})));
|
|
121
|
+
return {
|
|
122
|
+
name: answers.name,
|
|
123
|
+
category: answers.category,
|
|
124
|
+
color: answers.color || undefined,
|
|
125
|
+
description: answers.description || undefined,
|
|
126
|
+
isDefault: answers.isDefault,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
getCategoryDescription(category) {
|
|
130
|
+
const descriptions = {
|
|
131
|
+
triage: 'Inbox - needs review before entering workflow',
|
|
132
|
+
backlog: 'Not yet scheduled for work',
|
|
133
|
+
unstarted: 'Scheduled but work hasn\'t begun',
|
|
134
|
+
started: 'Work is actively in progress',
|
|
135
|
+
completed: 'Work finished successfully',
|
|
136
|
+
canceled: 'Work won\'t be done',
|
|
137
|
+
};
|
|
138
|
+
return descriptions[category];
|
|
139
|
+
}
|
|
140
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { PMOCommand } from '../../lib/pmo/index.js';
|
|
2
|
+
export default class StatusDelete 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
|
+
};
|
|
8
|
+
static flags: {
|
|
9
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
|
+
force: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
11
|
+
};
|
|
12
|
+
execute(): Promise<void>;
|
|
13
|
+
}
|