@proletariat/cli 0.2.0 → 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 +512 -253
- 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,217 @@
|
|
|
1
|
+
import { Args, Flags } from '@oclif/core';
|
|
2
|
+
import { PMOCommand, pmoBaseFlags } from '../../lib/pmo/index.js';
|
|
3
|
+
import inquirer from 'inquirer';
|
|
4
|
+
import { colors, format } from '../../lib/colors.js';
|
|
5
|
+
import { findHQRoot, promptSelectMultipleRepos, removeRepository, getWorkspaceRepoInfo } from '../../lib/repos/index.js';
|
|
6
|
+
import { shouldOutputJson, outputPromptAsJson, outputErrorAsJson, createMetadata, buildPromptConfig, } from '../../lib/prompt-json.js';
|
|
7
|
+
export default class Remove extends PMOCommand {
|
|
8
|
+
static description = 'Remove a repository from the HQ';
|
|
9
|
+
static examples = [
|
|
10
|
+
'<%= config.bin %> <%= command.id %> my-repo',
|
|
11
|
+
'<%= config.bin %> <%= command.id %> my-repo --force',
|
|
12
|
+
'<%= config.bin %> <%= command.id %>',
|
|
13
|
+
'<%= config.bin %> <%= command.id %> --bulk',
|
|
14
|
+
];
|
|
15
|
+
static args = {
|
|
16
|
+
name: Args.string({
|
|
17
|
+
description: 'Repository name to remove',
|
|
18
|
+
required: false,
|
|
19
|
+
}),
|
|
20
|
+
};
|
|
21
|
+
static flags = {
|
|
22
|
+
...pmoBaseFlags,
|
|
23
|
+
force: Flags.boolean({
|
|
24
|
+
char: 'f',
|
|
25
|
+
description: 'Skip confirmation prompt',
|
|
26
|
+
default: false,
|
|
27
|
+
}),
|
|
28
|
+
'keep-files': Flags.boolean({
|
|
29
|
+
description: 'Remove from database but keep files',
|
|
30
|
+
default: false,
|
|
31
|
+
}),
|
|
32
|
+
bulk: Flags.boolean({
|
|
33
|
+
char: 'b',
|
|
34
|
+
description: 'Remove multiple repositories interactively',
|
|
35
|
+
default: false,
|
|
36
|
+
}),
|
|
37
|
+
json: Flags.boolean({
|
|
38
|
+
description: 'Output prompt configuration as JSON (for AI agents/scripts)',
|
|
39
|
+
default: false,
|
|
40
|
+
}),
|
|
41
|
+
};
|
|
42
|
+
getPMOOptions() {
|
|
43
|
+
return { promptIfMultiple: false };
|
|
44
|
+
}
|
|
45
|
+
async execute() {
|
|
46
|
+
const { args, flags } = await this.parse(Remove);
|
|
47
|
+
// Check if JSON output mode is active
|
|
48
|
+
const jsonMode = shouldOutputJson(flags);
|
|
49
|
+
// Helper to handle errors in JSON mode
|
|
50
|
+
const handleError = (code, message) => {
|
|
51
|
+
if (jsonMode) {
|
|
52
|
+
outputErrorAsJson(code, message, createMetadata('repo remove', flags));
|
|
53
|
+
this.exit(1);
|
|
54
|
+
}
|
|
55
|
+
this.error(message);
|
|
56
|
+
};
|
|
57
|
+
// Find HQ root
|
|
58
|
+
const hqPath = findHQRoot();
|
|
59
|
+
if (!hqPath) {
|
|
60
|
+
return handleError('NOT_IN_HQ', 'Not in an HQ directory. Run "prlt init" first.');
|
|
61
|
+
}
|
|
62
|
+
// Bulk mode: remove multiple repositories interactively
|
|
63
|
+
if (flags.bulk) {
|
|
64
|
+
await this.executeBulk(hqPath, flags.force, flags['keep-files'], jsonMode, flags);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
let repoName = args.name || null;
|
|
68
|
+
// Interactive selection if no name provided
|
|
69
|
+
if (!repoName) {
|
|
70
|
+
const { repositories } = getWorkspaceRepoInfo();
|
|
71
|
+
if (repositories.length === 0) {
|
|
72
|
+
return handleError('NO_REPOSITORIES', 'No repositories found.');
|
|
73
|
+
}
|
|
74
|
+
// Build choices once, use for both JSON and interactive modes
|
|
75
|
+
const repoChoices = repositories.map(r => ({
|
|
76
|
+
name: r.name,
|
|
77
|
+
value: r.name,
|
|
78
|
+
}));
|
|
79
|
+
const selectMessage = 'Select repository to remove:';
|
|
80
|
+
// In JSON mode, output repo selection prompt
|
|
81
|
+
if (jsonMode) {
|
|
82
|
+
outputPromptAsJson(buildPromptConfig('list', 'repoName', selectMessage, repoChoices), createMetadata('repo remove', flags));
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
const { selected } = await inquirer.prompt([{
|
|
86
|
+
type: 'list',
|
|
87
|
+
name: 'selected',
|
|
88
|
+
message: selectMessage,
|
|
89
|
+
choices: repoChoices,
|
|
90
|
+
}]);
|
|
91
|
+
repoName = selected;
|
|
92
|
+
if (!repoName) {
|
|
93
|
+
this.log(colors.textMuted('Operation cancelled.'));
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// Validate repository exists
|
|
98
|
+
const { repositories } = getWorkspaceRepoInfo();
|
|
99
|
+
const repo = repositories.find(r => r.name === repoName);
|
|
100
|
+
if (!repo) {
|
|
101
|
+
return handleError('REPO_NOT_FOUND', `Repository "${repoName}" not found.`);
|
|
102
|
+
}
|
|
103
|
+
// Confirmation unless --force
|
|
104
|
+
if (!flags.force) {
|
|
105
|
+
// Build choices once, use for both JSON and interactive modes
|
|
106
|
+
const confirmChoices = [
|
|
107
|
+
{ name: 'No, cancel', value: 'false' },
|
|
108
|
+
{ name: 'Yes, remove repository', value: 'true' },
|
|
109
|
+
];
|
|
110
|
+
const confirmMessage = `Remove repository "${repoName}"? (This will remove repos/${repoName} directory and agent worktrees)`;
|
|
111
|
+
// In JSON mode, output confirmation prompt
|
|
112
|
+
if (jsonMode) {
|
|
113
|
+
outputPromptAsJson(buildPromptConfig('list', 'confirmed', confirmMessage, confirmChoices), createMetadata('repo remove', flags));
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
this.log(colors.warning('\n⚠️ This will:'));
|
|
117
|
+
this.log(colors.text(` • Remove repos/${repoName} directory`));
|
|
118
|
+
this.log(colors.text(' • Remove agent worktrees for this repo'));
|
|
119
|
+
this.log(colors.text(' • Update database\n'));
|
|
120
|
+
const { confirm } = await inquirer.prompt([{
|
|
121
|
+
type: 'list',
|
|
122
|
+
name: 'confirm',
|
|
123
|
+
message: `Are you sure you want to remove "${repoName}"?`,
|
|
124
|
+
choices: [
|
|
125
|
+
{ name: '❌ ' + confirmChoices[0].name, value: false },
|
|
126
|
+
{ name: '⚠️ ' + confirmChoices[1].name, value: true }
|
|
127
|
+
],
|
|
128
|
+
default: 0
|
|
129
|
+
}]);
|
|
130
|
+
if (!confirm) {
|
|
131
|
+
this.log(colors.textMuted('Removal cancelled.'));
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
// Remove the repository
|
|
136
|
+
this.log(colors.primary(`\nRemoving repository "${repoName}"...`));
|
|
137
|
+
const result = await removeRepository(hqPath, repoName, flags['keep-files']);
|
|
138
|
+
if (result.success) {
|
|
139
|
+
this.log(format.success(`Repository ${repoName} removed`));
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
this.error(`Failed to remove repository: ${result.error}`);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Bulk mode: remove multiple repositories interactively
|
|
147
|
+
*/
|
|
148
|
+
async executeBulk(hqPath, force, keepFiles, jsonMode = false, flags = {}) {
|
|
149
|
+
// In JSON mode, output repo selection prompt for bulk mode
|
|
150
|
+
if (jsonMode) {
|
|
151
|
+
const { repositories } = getWorkspaceRepoInfo();
|
|
152
|
+
if (repositories.length === 0) {
|
|
153
|
+
outputErrorAsJson('NO_REPOSITORIES', 'No repositories found.', createMetadata('repo remove', flags));
|
|
154
|
+
this.exit(1);
|
|
155
|
+
}
|
|
156
|
+
const repoChoices = repositories.map(r => ({
|
|
157
|
+
name: r.name,
|
|
158
|
+
value: r.name,
|
|
159
|
+
}));
|
|
160
|
+
outputPromptAsJson(buildPromptConfig('checkbox', 'repoNames', 'Select repositories to remove:', repoChoices), createMetadata('repo remove', flags));
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
this.log(colors.primary('📦 Remove Repositories (Bulk Mode)\n'));
|
|
164
|
+
// Select repositories to remove
|
|
165
|
+
const selectedRepos = await promptSelectMultipleRepos('Select repositories to remove:');
|
|
166
|
+
if (selectedRepos.length === 0) {
|
|
167
|
+
this.log(colors.textMuted('No repositories selected.'));
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
// Confirmation unless --force
|
|
171
|
+
if (!force) {
|
|
172
|
+
this.log(colors.warning('\n⚠️ This will permanently delete:'));
|
|
173
|
+
for (const name of selectedRepos) {
|
|
174
|
+
this.log(colors.text(` • repos/${name}`));
|
|
175
|
+
}
|
|
176
|
+
this.log(colors.text(' • Agent worktrees for these repos\n'));
|
|
177
|
+
const { confirm } = await inquirer.prompt([{
|
|
178
|
+
type: 'list',
|
|
179
|
+
name: 'confirm',
|
|
180
|
+
message: 'Are you sure?',
|
|
181
|
+
choices: [
|
|
182
|
+
{ name: '❌ No, cancel', value: false },
|
|
183
|
+
{ name: '⚠️ Yes, remove repositories', value: true }
|
|
184
|
+
],
|
|
185
|
+
default: 0
|
|
186
|
+
}]);
|
|
187
|
+
if (!confirm) {
|
|
188
|
+
this.log(colors.textMuted('Removal cancelled.'));
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
this.log('');
|
|
193
|
+
// Remove each repository
|
|
194
|
+
let successCount = 0;
|
|
195
|
+
let failCount = 0;
|
|
196
|
+
for (const repoName of selectedRepos) {
|
|
197
|
+
this.log(colors.textMuted(`Removing ${repoName}...`));
|
|
198
|
+
const result = await removeRepository(hqPath, repoName, keepFiles);
|
|
199
|
+
if (result.success) {
|
|
200
|
+
this.log(format.success(`Removed ${repoName}`));
|
|
201
|
+
successCount++;
|
|
202
|
+
}
|
|
203
|
+
else {
|
|
204
|
+
this.log(format.error(`Failed to remove ${repoName}: ${result.error}`));
|
|
205
|
+
failCount++;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
// Summary
|
|
209
|
+
this.log('');
|
|
210
|
+
if (successCount > 0) {
|
|
211
|
+
this.log(format.success(`Removed ${successCount} repository(ies)`));
|
|
212
|
+
}
|
|
213
|
+
if (failCount > 0) {
|
|
214
|
+
this.log(format.error(`Failed to remove ${failCount} repository(ies)`));
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { PMOCommand } from '../../lib/pmo/index.js';
|
|
2
|
+
export default class View 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
|
+
project: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
|
+
};
|
|
11
|
+
protected getPMOOptions(): {
|
|
12
|
+
promptIfMultiple: boolean;
|
|
13
|
+
};
|
|
14
|
+
execute(): Promise<void>;
|
|
15
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { Args } from '@oclif/core';
|
|
2
|
+
import { PMOCommand, pmoBaseFlags } from '../../lib/pmo/index.js';
|
|
3
|
+
import { colors, format } from '../../lib/colors.js';
|
|
4
|
+
import { findHQRoot, promptSelectRepo, getWorkspaceRepoInfo, } from '../../lib/repos/index.js';
|
|
5
|
+
import { openWorkspaceDatabase } from '../../lib/database/index.js';
|
|
6
|
+
export default class View extends PMOCommand {
|
|
7
|
+
static description = 'View detailed information about a repository';
|
|
8
|
+
static examples = [
|
|
9
|
+
'<%= config.bin %> <%= command.id %> my-repo',
|
|
10
|
+
'<%= config.bin %> <%= command.id %>',
|
|
11
|
+
];
|
|
12
|
+
static args = {
|
|
13
|
+
name: Args.string({
|
|
14
|
+
description: 'Repository name to view',
|
|
15
|
+
required: false,
|
|
16
|
+
}),
|
|
17
|
+
};
|
|
18
|
+
static flags = {
|
|
19
|
+
...pmoBaseFlags,
|
|
20
|
+
};
|
|
21
|
+
getPMOOptions() {
|
|
22
|
+
return { promptIfMultiple: false };
|
|
23
|
+
}
|
|
24
|
+
async execute() {
|
|
25
|
+
const { args } = await this.parse(View);
|
|
26
|
+
// Find HQ root
|
|
27
|
+
const hqPath = findHQRoot();
|
|
28
|
+
if (!hqPath) {
|
|
29
|
+
this.error('Not in an HQ directory. Run "prlt init" first.');
|
|
30
|
+
}
|
|
31
|
+
let repoName = args.name || null;
|
|
32
|
+
// Interactive selection if no name provided
|
|
33
|
+
if (!repoName) {
|
|
34
|
+
repoName = await promptSelectRepo('Select repository to view:');
|
|
35
|
+
if (!repoName) {
|
|
36
|
+
this.log(colors.textMuted('Operation cancelled.'));
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
// Get repository info
|
|
41
|
+
const { repositories } = getWorkspaceRepoInfo();
|
|
42
|
+
const repo = repositories.find(r => r.name === repoName);
|
|
43
|
+
if (!repo) {
|
|
44
|
+
this.error(`Repository "${repoName}" not found.`);
|
|
45
|
+
}
|
|
46
|
+
// Display repository details
|
|
47
|
+
this.log(format.title(`📦 Repository: ${repo.name}`));
|
|
48
|
+
this.log('');
|
|
49
|
+
this.log(`Path: ${colors.path(repo.path)}`);
|
|
50
|
+
if (repo.sourceUrl) {
|
|
51
|
+
this.log(`Source: ${colors.text(repo.sourceUrl)}`);
|
|
52
|
+
}
|
|
53
|
+
if (repo.addedAt) {
|
|
54
|
+
this.log(`Added: ${colors.text(new Date(repo.addedAt).toLocaleString())}`);
|
|
55
|
+
}
|
|
56
|
+
this.log(format.subtitle('\n📊 Git Status:'));
|
|
57
|
+
if (repo.status === 'missing') {
|
|
58
|
+
this.log(colors.error(' Repository directory not found'));
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
const statusIcon = repo.status === 'clean' ? '🟢' : '🟡';
|
|
62
|
+
const statusColor = repo.status === 'clean' ? colors.success : colors.warning;
|
|
63
|
+
this.log(` Branch: ${colors.warning(repo.branch || 'unknown')}`);
|
|
64
|
+
this.log(` Status: ${statusIcon} ${statusColor(repo.status)}`);
|
|
65
|
+
if (repo.commitsAhead > 0 || repo.commitsBehind > 0) {
|
|
66
|
+
let commitInfo = '';
|
|
67
|
+
if (repo.commitsAhead > 0) {
|
|
68
|
+
commitInfo += `${repo.commitsAhead} ahead`;
|
|
69
|
+
}
|
|
70
|
+
if (repo.commitsBehind > 0) {
|
|
71
|
+
if (commitInfo)
|
|
72
|
+
commitInfo += ', ';
|
|
73
|
+
commitInfo += `${repo.commitsBehind} behind`;
|
|
74
|
+
}
|
|
75
|
+
this.log(` Commits: ${colors.text(commitInfo)}`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
// Get agent worktree info
|
|
79
|
+
const db = openWorkspaceDatabase(hqPath);
|
|
80
|
+
const worktrees = db.prepare(`
|
|
81
|
+
SELECT agent_name, is_clean, commits_ahead, branch
|
|
82
|
+
FROM agent_worktrees
|
|
83
|
+
WHERE repo_name = ?
|
|
84
|
+
`).all(repoName);
|
|
85
|
+
db.close();
|
|
86
|
+
if (worktrees.length > 0) {
|
|
87
|
+
this.log(format.subtitle('\n👥 Agent Worktrees:'));
|
|
88
|
+
for (const wt of worktrees) {
|
|
89
|
+
const wtStatus = wt.is_clean ? 'clean' : 'dirty';
|
|
90
|
+
const wtColor = wt.is_clean ? colors.repoClean : colors.repoDirty;
|
|
91
|
+
let line = ` • ${colors.agentName(wt.agent_name.padEnd(10))} - ${wtColor(wtStatus)}`;
|
|
92
|
+
if (wt.commits_ahead > 0) {
|
|
93
|
+
line += colors.commitsAhead(` (${wt.commits_ahead} ahead)`);
|
|
94
|
+
}
|
|
95
|
+
this.log(line);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { PMOCommand } from '../../lib/pmo/index.js';
|
|
2
|
+
export default class SessionAttach extends PMOCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static args: {
|
|
6
|
+
session: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
7
|
+
};
|
|
8
|
+
static flags: {
|
|
9
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
|
+
'new-tab': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
11
|
+
'current-terminal': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
12
|
+
terminal: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
13
|
+
project: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
14
|
+
};
|
|
15
|
+
protected getPMOOptions(): {
|
|
16
|
+
promptIfMultiple: boolean;
|
|
17
|
+
};
|
|
18
|
+
execute(): Promise<void>;
|
|
19
|
+
/**
|
|
20
|
+
* Get verified sessions from DB that have actual tmux processes
|
|
21
|
+
* DB-driven approach: Start with executions, verify tmux sessions exist
|
|
22
|
+
*/
|
|
23
|
+
private getVerifiedSessions;
|
|
24
|
+
/**
|
|
25
|
+
* Get list of host tmux session names
|
|
26
|
+
*/
|
|
27
|
+
private getHostTmuxSessionNames;
|
|
28
|
+
/**
|
|
29
|
+
* Get map of containerId -> tmux session names
|
|
30
|
+
*/
|
|
31
|
+
private getContainerTmuxSessionMap;
|
|
32
|
+
/**
|
|
33
|
+
* Attach to session in current terminal
|
|
34
|
+
*/
|
|
35
|
+
private attachInCurrentTerminal;
|
|
36
|
+
/**
|
|
37
|
+
* Attach to session in a new terminal tab
|
|
38
|
+
*/
|
|
39
|
+
private attachInNewTab;
|
|
40
|
+
}
|
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
import { Args, Flags } from '@oclif/core';
|
|
2
|
+
import { execSync } from 'node:child_process';
|
|
3
|
+
import * as path from 'node:path';
|
|
4
|
+
import * as fs from 'node:fs';
|
|
5
|
+
import * as os from 'node:os';
|
|
6
|
+
import Database from 'better-sqlite3';
|
|
7
|
+
import { styles } from '../../lib/styles.js';
|
|
8
|
+
import { getWorkspaceInfo } from '../../lib/agents/commands.js';
|
|
9
|
+
import { ExecutionStorage } from '../../lib/execution/index.js';
|
|
10
|
+
import { PMOCommand, pmoBaseFlags } from '../../lib/pmo/index.js';
|
|
11
|
+
import { shouldOutputJson, outputErrorAsJson, createMetadata, } from '../../lib/prompt-json.js';
|
|
12
|
+
export default class SessionAttach extends PMOCommand {
|
|
13
|
+
static description = 'Attach to an active tmux session';
|
|
14
|
+
static examples = [
|
|
15
|
+
'<%= config.bin %> <%= command.id %>',
|
|
16
|
+
'<%= config.bin %> <%= command.id %> TKT-347-implement-altman',
|
|
17
|
+
'<%= config.bin %> <%= command.id %> --current-terminal',
|
|
18
|
+
];
|
|
19
|
+
static args = {
|
|
20
|
+
session: Args.string({
|
|
21
|
+
description: 'Session name or ticket ID to attach to (optional - will prompt if not provided)',
|
|
22
|
+
required: false,
|
|
23
|
+
}),
|
|
24
|
+
};
|
|
25
|
+
static flags = {
|
|
26
|
+
...pmoBaseFlags,
|
|
27
|
+
json: Flags.boolean({
|
|
28
|
+
description: 'Output prompt configuration as JSON (for AI agents/scripts)',
|
|
29
|
+
default: false,
|
|
30
|
+
}),
|
|
31
|
+
'new-tab': Flags.boolean({
|
|
32
|
+
char: 'n',
|
|
33
|
+
description: 'Open in a new terminal tab (default: true)',
|
|
34
|
+
default: true,
|
|
35
|
+
}),
|
|
36
|
+
'current-terminal': Flags.boolean({
|
|
37
|
+
char: 'c',
|
|
38
|
+
description: 'Attach in current terminal instead of new tab',
|
|
39
|
+
default: false,
|
|
40
|
+
}),
|
|
41
|
+
terminal: Flags.string({
|
|
42
|
+
char: 't',
|
|
43
|
+
description: 'Terminal app to use (iTerm, Terminal, Ghostty)',
|
|
44
|
+
default: 'iTerm',
|
|
45
|
+
}),
|
|
46
|
+
};
|
|
47
|
+
getPMOOptions() {
|
|
48
|
+
return { promptIfMultiple: false };
|
|
49
|
+
}
|
|
50
|
+
async execute() {
|
|
51
|
+
const { args, flags } = await this.parse(SessionAttach);
|
|
52
|
+
// Check if JSON output mode is active
|
|
53
|
+
const jsonMode = shouldOutputJson(flags);
|
|
54
|
+
// Get all available sessions (DB-driven)
|
|
55
|
+
const sessions = this.getVerifiedSessions();
|
|
56
|
+
if (sessions.length === 0) {
|
|
57
|
+
if (jsonMode) {
|
|
58
|
+
outputErrorAsJson('NO_SESSIONS', 'No active sessions found.', createMetadata('session attach', flags));
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
this.log('');
|
|
62
|
+
this.log(styles.muted('No active sessions found.'));
|
|
63
|
+
this.log('');
|
|
64
|
+
this.log(styles.muted('Start work with: prlt work start <ticket-id>'));
|
|
65
|
+
this.log('');
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
// Determine which session to attach to
|
|
69
|
+
let selectedSession;
|
|
70
|
+
if (args.session) {
|
|
71
|
+
// Find session by name, sessionId, or ticketId (partial match)
|
|
72
|
+
selectedSession = sessions.find(s => s.sessionId === args.session ||
|
|
73
|
+
s.sessionId.includes(args.session) ||
|
|
74
|
+
s.ticketId === args.session ||
|
|
75
|
+
s.ticketId.includes(args.session));
|
|
76
|
+
if (!selectedSession) {
|
|
77
|
+
if (jsonMode) {
|
|
78
|
+
outputErrorAsJson('SESSION_NOT_FOUND', `Session "${args.session}" not found.`, createMetadata('session attach', flags));
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
this.error(`Session "${args.session}" not found. Run "prlt session list" to see available sessions.`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
// Use selectFromList helper for session selection
|
|
86
|
+
const selected = await this.selectFromList({
|
|
87
|
+
message: 'Select a session to attach to:',
|
|
88
|
+
items: sessions,
|
|
89
|
+
getName: (s) => `${s.sessionId} (${s.ticketId}) - ${s.agentName} [${s.type}]`,
|
|
90
|
+
getValue: (s) => s.sessionId,
|
|
91
|
+
getCommand: (s) => `prlt session attach "${s.sessionId}" --json`,
|
|
92
|
+
jsonMode: jsonMode ? { flags, commandName: 'session attach' } : null,
|
|
93
|
+
});
|
|
94
|
+
if (!selected) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
selectedSession = sessions.find(s => s.sessionId === selected);
|
|
98
|
+
}
|
|
99
|
+
if (!selectedSession) {
|
|
100
|
+
this.error('No session selected');
|
|
101
|
+
}
|
|
102
|
+
// Attach to the session
|
|
103
|
+
this.log('');
|
|
104
|
+
this.log(styles.info(`Attaching to session: ${selectedSession.sessionId}`));
|
|
105
|
+
// Default to new tab unless --current-terminal is specified
|
|
106
|
+
if (flags['current-terminal']) {
|
|
107
|
+
await this.attachInCurrentTerminal(selectedSession);
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
await this.attachInNewTab(selectedSession, flags.terminal);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Get verified sessions from DB that have actual tmux processes
|
|
115
|
+
* DB-driven approach: Start with executions, verify tmux sessions exist
|
|
116
|
+
*/
|
|
117
|
+
getVerifiedSessions() {
|
|
118
|
+
const sessions = [];
|
|
119
|
+
let executionStorage = null;
|
|
120
|
+
let db = null;
|
|
121
|
+
try {
|
|
122
|
+
const workspaceInfo = getWorkspaceInfo();
|
|
123
|
+
const dbPath = path.join(workspaceInfo.path, '.proletariat', 'workspace.db');
|
|
124
|
+
db = new Database(dbPath);
|
|
125
|
+
executionStorage = new ExecutionStorage(db);
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
return sessions; // Not in workspace
|
|
129
|
+
}
|
|
130
|
+
try {
|
|
131
|
+
// Get active executions from DB
|
|
132
|
+
const activeExecutions = [
|
|
133
|
+
...(executionStorage.listExecutions({ status: 'running' }) || []),
|
|
134
|
+
...(executionStorage.listExecutions({ status: 'starting' }) || []),
|
|
135
|
+
];
|
|
136
|
+
// Get actual tmux sessions for verification
|
|
137
|
+
const hostTmuxSessions = this.getHostTmuxSessionNames();
|
|
138
|
+
const containerTmuxSessions = this.getContainerTmuxSessionMap();
|
|
139
|
+
for (const exec of activeExecutions) {
|
|
140
|
+
if (!exec.sessionId)
|
|
141
|
+
continue;
|
|
142
|
+
const isContainer = exec.environment === 'devcontainer';
|
|
143
|
+
let exists = false;
|
|
144
|
+
if (isContainer && exec.containerId) {
|
|
145
|
+
const containerSessions = containerTmuxSessions.get(exec.containerId);
|
|
146
|
+
exists = containerSessions?.includes(exec.sessionId) ?? false;
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
exists = hostTmuxSessions.includes(exec.sessionId);
|
|
150
|
+
}
|
|
151
|
+
// Only include sessions that actually exist
|
|
152
|
+
if (exists) {
|
|
153
|
+
sessions.push({
|
|
154
|
+
name: exec.sessionId,
|
|
155
|
+
sessionId: exec.sessionId,
|
|
156
|
+
type: isContainer ? 'container' : 'host',
|
|
157
|
+
containerId: exec.containerId,
|
|
158
|
+
ticketId: exec.ticketId,
|
|
159
|
+
agentName: exec.agentName,
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
finally {
|
|
165
|
+
db?.close();
|
|
166
|
+
}
|
|
167
|
+
return sessions;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Get list of host tmux session names
|
|
171
|
+
*/
|
|
172
|
+
getHostTmuxSessionNames() {
|
|
173
|
+
try {
|
|
174
|
+
execSync('which tmux', { stdio: 'pipe' });
|
|
175
|
+
const output = execSync('tmux list-sessions -F "#{session_name}"', { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] }).trim();
|
|
176
|
+
if (!output)
|
|
177
|
+
return [];
|
|
178
|
+
return output.split('\n');
|
|
179
|
+
}
|
|
180
|
+
catch {
|
|
181
|
+
return [];
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Get map of containerId -> tmux session names
|
|
186
|
+
*/
|
|
187
|
+
getContainerTmuxSessionMap() {
|
|
188
|
+
const sessionMap = new Map();
|
|
189
|
+
try {
|
|
190
|
+
const containersOutput = execSync('docker ps --filter "label=devcontainer.local_folder" --format "{{.ID}}"', { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] }).trim();
|
|
191
|
+
if (!containersOutput)
|
|
192
|
+
return sessionMap;
|
|
193
|
+
for (const containerId of containersOutput.split('\n')) {
|
|
194
|
+
try {
|
|
195
|
+
const tmuxOutput = execSync(`docker exec ${containerId} tmux list-sessions -F "#{session_name}" 2>/dev/null`, { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] }).trim();
|
|
196
|
+
if (tmuxOutput) {
|
|
197
|
+
sessionMap.set(containerId, tmuxOutput.split('\n'));
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
catch {
|
|
201
|
+
// Container has no tmux sessions
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
catch {
|
|
206
|
+
// Docker not available
|
|
207
|
+
}
|
|
208
|
+
return sessionMap;
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Attach to session in current terminal
|
|
212
|
+
*/
|
|
213
|
+
async attachInCurrentTerminal(session) {
|
|
214
|
+
try {
|
|
215
|
+
if (session.type === 'container' && session.containerId) {
|
|
216
|
+
execSync(`docker exec -it ${session.containerId} tmux attach -t "${session.sessionId}"`, { stdio: 'inherit' });
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
execSync(`tmux attach -t "${session.sessionId}"`, { stdio: 'inherit' });
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
catch {
|
|
223
|
+
this.error(`Failed to attach to ${session.type} session "${session.sessionId}"`);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Attach to session in a new terminal tab
|
|
228
|
+
*/
|
|
229
|
+
async attachInNewTab(session, terminalApp) {
|
|
230
|
+
// Build a readable title for the tab
|
|
231
|
+
const title = `${session.ticketId} (${session.agentName})`;
|
|
232
|
+
// Create a script that sets tab title and attaches to tmux
|
|
233
|
+
const baseDir = path.join(os.homedir(), '.proletariat', 'scripts');
|
|
234
|
+
fs.mkdirSync(baseDir, { recursive: true });
|
|
235
|
+
const scriptPath = path.join(baseDir, `attach-${Date.now()}.sh`);
|
|
236
|
+
// Different attach command for container vs host sessions
|
|
237
|
+
const attachCmd = session.type === 'container' && session.containerId
|
|
238
|
+
? `docker exec -it ${session.containerId} tmux -u attach -t "${session.sessionId}"`
|
|
239
|
+
: `tmux attach -t "${session.sessionId}"`;
|
|
240
|
+
const script = `#!/bin/bash
|
|
241
|
+
# Set terminal tab title
|
|
242
|
+
echo -ne "\\033]0;${title}\\007"
|
|
243
|
+
echo -ne "\\033]1;${title}\\007"
|
|
244
|
+
|
|
245
|
+
echo "Attaching to: ${session.sessionId} (${session.type})"
|
|
246
|
+
${attachCmd}
|
|
247
|
+
|
|
248
|
+
# Clean up
|
|
249
|
+
rm -f "${scriptPath}"
|
|
250
|
+
exec $SHELL
|
|
251
|
+
`;
|
|
252
|
+
fs.writeFileSync(scriptPath, script, { mode: 0o755 });
|
|
253
|
+
// Open in new tab and run the attach script
|
|
254
|
+
try {
|
|
255
|
+
switch (terminalApp) {
|
|
256
|
+
case 'iTerm':
|
|
257
|
+
execSync(`osascript -e '
|
|
258
|
+
tell application "iTerm"
|
|
259
|
+
activate
|
|
260
|
+
tell current window
|
|
261
|
+
set newTab to (create tab with default profile)
|
|
262
|
+
tell current session of newTab
|
|
263
|
+
set name to "${title}"
|
|
264
|
+
write text "${scriptPath}"
|
|
265
|
+
end tell
|
|
266
|
+
end tell
|
|
267
|
+
end tell
|
|
268
|
+
'`);
|
|
269
|
+
break;
|
|
270
|
+
case 'Ghostty':
|
|
271
|
+
execSync(`osascript -e '
|
|
272
|
+
tell application "Ghostty"
|
|
273
|
+
activate
|
|
274
|
+
end tell
|
|
275
|
+
tell application "System Events"
|
|
276
|
+
tell process "Ghostty"
|
|
277
|
+
keystroke "t" using command down
|
|
278
|
+
delay 0.3
|
|
279
|
+
keystroke "${scriptPath}"
|
|
280
|
+
keystroke return
|
|
281
|
+
end tell
|
|
282
|
+
end tell
|
|
283
|
+
'`);
|
|
284
|
+
break;
|
|
285
|
+
case 'Terminal':
|
|
286
|
+
default:
|
|
287
|
+
execSync(`osascript -e '
|
|
288
|
+
tell application "Terminal"
|
|
289
|
+
activate
|
|
290
|
+
tell application "System Events"
|
|
291
|
+
tell process "Terminal"
|
|
292
|
+
keystroke "t" using command down
|
|
293
|
+
end tell
|
|
294
|
+
end tell
|
|
295
|
+
delay 0.3
|
|
296
|
+
do script "${scriptPath}" in front window
|
|
297
|
+
end tell
|
|
298
|
+
'`);
|
|
299
|
+
break;
|
|
300
|
+
}
|
|
301
|
+
this.log(styles.success('Opened new tab and attaching to session'));
|
|
302
|
+
}
|
|
303
|
+
catch (error) {
|
|
304
|
+
this.error(`Failed to open terminal tab: ${error instanceof Error ? error.message : error}`);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}
|