@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,679 @@
|
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import * as path from 'node:path';
|
|
3
|
+
import { execSync } from 'node:child_process';
|
|
4
|
+
import inquirer from 'inquirer';
|
|
5
|
+
import chalk from 'chalk';
|
|
6
|
+
import { styles } from '../styles.js';
|
|
7
|
+
import { colors } from '../colors.js';
|
|
8
|
+
import { openWorkspaceDatabase, addRepositoriesToDatabase, getWorkspaceRepositories } from '../database/index.js';
|
|
9
|
+
import { createDevcontainerConfig } from '../execution/devcontainer.js';
|
|
10
|
+
import { findHQRoot } from '../workspace.js';
|
|
11
|
+
/**
|
|
12
|
+
* Check if we're currently in a git repository
|
|
13
|
+
*/
|
|
14
|
+
export function isInGitRepo(dir = process.cwd()) {
|
|
15
|
+
try {
|
|
16
|
+
execSync('git rev-parse --git-dir', {
|
|
17
|
+
cwd: dir,
|
|
18
|
+
stdio: 'pipe'
|
|
19
|
+
});
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
// Not in a git repo - git rev-parse exits with non-zero status
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Get the current repository name
|
|
29
|
+
*/
|
|
30
|
+
export function getCurrentRepoName(dir = process.cwd()) {
|
|
31
|
+
if (!isInGitRepo(dir)) {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
try {
|
|
35
|
+
const remoteUrl = execSync('git config --get remote.origin.url', {
|
|
36
|
+
cwd: dir,
|
|
37
|
+
stdio: 'pipe',
|
|
38
|
+
encoding: 'utf-8'
|
|
39
|
+
}).trim();
|
|
40
|
+
// Extract repo name from URL
|
|
41
|
+
const match = remoteUrl.match(/\/([^\/]+?)(\.git)?$/);
|
|
42
|
+
if (match) {
|
|
43
|
+
return match[1];
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
// No remote origin, use directory name
|
|
48
|
+
}
|
|
49
|
+
return path.basename(dir);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Prompt user to add repositories interactively
|
|
53
|
+
*/
|
|
54
|
+
export async function promptForRepositories(currentDir = process.cwd(), existingRepos = []) {
|
|
55
|
+
const repos = [];
|
|
56
|
+
const inGitRepo = isInGitRepo(currentDir);
|
|
57
|
+
// Start with current repo if we're in one
|
|
58
|
+
if (inGitRepo) {
|
|
59
|
+
const currentRepoName = getCurrentRepoName(currentDir) || path.basename(currentDir);
|
|
60
|
+
// Check if this repo is already added
|
|
61
|
+
if (!existingRepos.includes(currentRepoName)) {
|
|
62
|
+
const { addCurrent } = await inquirer.prompt([{
|
|
63
|
+
type: 'list',
|
|
64
|
+
name: 'addCurrent',
|
|
65
|
+
message: `Add current repository (${currentRepoName}) to repos/?`,
|
|
66
|
+
choices: [
|
|
67
|
+
{ name: 'Yes', value: true },
|
|
68
|
+
{ name: 'No', value: false }
|
|
69
|
+
],
|
|
70
|
+
default: true,
|
|
71
|
+
}]);
|
|
72
|
+
if (addCurrent) {
|
|
73
|
+
// Can only clone (not move) the current repo since we're inside it
|
|
74
|
+
console.log(styles.muted('Note: Current repository will be cloned (cannot move while inside it)'));
|
|
75
|
+
repos.push({ path: currentDir, action: 'clone' });
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
// Loop to add more repos
|
|
80
|
+
let addingRepos = true;
|
|
81
|
+
while (addingRepos) {
|
|
82
|
+
const { repoAction } = await inquirer.prompt([{
|
|
83
|
+
type: 'list',
|
|
84
|
+
name: 'repoAction',
|
|
85
|
+
message: repos.length === 0
|
|
86
|
+
? 'How would you like to add repositories to the HQ?'
|
|
87
|
+
: 'Add another repository?',
|
|
88
|
+
choices: [
|
|
89
|
+
{ name: '🔍 Search for repositories on this machine', value: 'search' },
|
|
90
|
+
{ name: '📁 Manually enter repository path or Git URL', value: 'manual' },
|
|
91
|
+
{ name: '✨ Create new repository', value: 'create' },
|
|
92
|
+
{ name: repos.length === 0 ? '⏭️ Skip adding repositories' : '✅ Done adding repositories', value: 'skip' }
|
|
93
|
+
],
|
|
94
|
+
default: repos.length === 0 ? 'search' : 'skip'
|
|
95
|
+
}]);
|
|
96
|
+
if (repoAction === 'skip') {
|
|
97
|
+
addingRepos = false;
|
|
98
|
+
break;
|
|
99
|
+
}
|
|
100
|
+
if (repoAction === 'create') {
|
|
101
|
+
const newRepo = await createNewRepository();
|
|
102
|
+
if (newRepo) {
|
|
103
|
+
repos.push(newRepo);
|
|
104
|
+
}
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
if (repoAction === 'search') {
|
|
108
|
+
const foundRepos = await searchForRepositories();
|
|
109
|
+
repos.push(...foundRepos);
|
|
110
|
+
// After search, ask if they want to add more (unless they selected nothing)
|
|
111
|
+
if (foundRepos.length > 0) {
|
|
112
|
+
const { addMoreAfterSearch } = await inquirer.prompt([{
|
|
113
|
+
type: 'list',
|
|
114
|
+
name: 'addMoreAfterSearch',
|
|
115
|
+
message: 'Would you like to add more repositories?',
|
|
116
|
+
choices: [
|
|
117
|
+
{ name: 'No', value: false },
|
|
118
|
+
{ name: 'Yes', value: true }
|
|
119
|
+
],
|
|
120
|
+
default: false
|
|
121
|
+
}]);
|
|
122
|
+
if (!addMoreAfterSearch) {
|
|
123
|
+
addingRepos = false;
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
// Manual entry (existing logic)
|
|
130
|
+
const { repoPath } = await inquirer.prompt([{
|
|
131
|
+
type: 'input',
|
|
132
|
+
name: 'repoPath',
|
|
133
|
+
message: 'Enter repo path or Git URL:',
|
|
134
|
+
validate: (input) => input.trim() ? true : 'Path or URL required',
|
|
135
|
+
}]);
|
|
136
|
+
const trimmedPath = repoPath.trim();
|
|
137
|
+
if (trimmedPath.startsWith('http://') ||
|
|
138
|
+
trimmedPath.startsWith('https://') ||
|
|
139
|
+
trimmedPath.startsWith('git@')) {
|
|
140
|
+
// Git URL - always clone
|
|
141
|
+
repos.push({ path: trimmedPath, action: 'clone' });
|
|
142
|
+
console.log(styles.muted(`Will clone: ${trimmedPath}`));
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
// Local path - ask move or clone
|
|
146
|
+
const resolvedPath = path.resolve(trimmedPath);
|
|
147
|
+
const repoName = path.basename(resolvedPath);
|
|
148
|
+
// Check if we're currently inside this repo
|
|
149
|
+
const currentlyInside = process.cwd().startsWith(resolvedPath);
|
|
150
|
+
if (currentlyInside) {
|
|
151
|
+
console.log(chalk.yellow(`Cannot move ${repoName} - you're currently inside it. Will clone instead.`));
|
|
152
|
+
repos.push({ path: resolvedPath, action: 'clone' });
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
const { action } = await inquirer.prompt([{
|
|
156
|
+
type: 'list',
|
|
157
|
+
name: 'action',
|
|
158
|
+
message: `${repoName} - Move or Clone?`,
|
|
159
|
+
choices: [
|
|
160
|
+
{ name: 'Clone (keep original)', value: 'clone' },
|
|
161
|
+
{ name: 'Move (relocate to HQ)', value: 'move' },
|
|
162
|
+
],
|
|
163
|
+
}]);
|
|
164
|
+
repos.push({ path: resolvedPath, action: action });
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
return repos;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Add repositories to HQ
|
|
172
|
+
*/
|
|
173
|
+
export async function addRepositoriesToHQ(hqPath, repos) {
|
|
174
|
+
const reposDir = path.join(hqPath, 'repos');
|
|
175
|
+
// Ensure repos directory exists
|
|
176
|
+
if (!fs.existsSync(reposDir)) {
|
|
177
|
+
fs.mkdirSync(reposDir, { recursive: true });
|
|
178
|
+
}
|
|
179
|
+
const addedRepos = [];
|
|
180
|
+
for (const repo of repos) {
|
|
181
|
+
const repoName = path.basename(repo.path).replace(/\.git$/, '');
|
|
182
|
+
const targetPath = path.join(reposDir, repoName);
|
|
183
|
+
// Check if repo already exists
|
|
184
|
+
if (fs.existsSync(targetPath)) {
|
|
185
|
+
console.log(chalk.yellow(`Repository ${repoName} already exists in repos/`));
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
try {
|
|
189
|
+
if (repo.action === 'move') {
|
|
190
|
+
// Move the repository
|
|
191
|
+
console.log(styles.muted(`Moving ${repo.path} to repos/${repoName}...`));
|
|
192
|
+
fs.renameSync(repo.path, targetPath);
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
// Clone the repository
|
|
196
|
+
console.log(styles.muted(`Cloning ${repo.path} to repos/${repoName}...`));
|
|
197
|
+
execSync(`git clone ${repo.path} ${targetPath}`, {
|
|
198
|
+
stdio: 'inherit'
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
addedRepos.push(repoName);
|
|
202
|
+
console.log(chalk.green(`✅ Repository ${repoName} added successfully`));
|
|
203
|
+
}
|
|
204
|
+
catch (error) {
|
|
205
|
+
console.log(chalk.red(`Could not ${repo.action} repository: ${repo.path}`));
|
|
206
|
+
console.log(chalk.red(`Error: ${error}`));
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
return addedRepos;
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Update HQ config with new repositories
|
|
213
|
+
*/
|
|
214
|
+
export function updateHQRepos(hqPath, newRepos) {
|
|
215
|
+
const configPath = path.join(hqPath, '.proletariat', 'config.json');
|
|
216
|
+
const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
|
|
217
|
+
// Add new repos to the list (avoiding duplicates)
|
|
218
|
+
const existingRepos = config.repos || [];
|
|
219
|
+
const uniqueNewRepos = newRepos.filter(r => !existingRepos.includes(r));
|
|
220
|
+
config.repos = [...existingRepos, ...uniqueNewRepos];
|
|
221
|
+
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Create a new repository in the HQ
|
|
225
|
+
*/
|
|
226
|
+
async function createNewRepository() {
|
|
227
|
+
const { repoName, initWithReadme } = await inquirer.prompt([
|
|
228
|
+
{
|
|
229
|
+
type: 'input',
|
|
230
|
+
name: 'repoName',
|
|
231
|
+
message: 'Repository name:',
|
|
232
|
+
validate: (input) => {
|
|
233
|
+
if (!input.trim())
|
|
234
|
+
return 'Repository name is required';
|
|
235
|
+
if (!/^[a-zA-Z0-9-_]+$/.test(input)) {
|
|
236
|
+
return 'Repository name can only contain letters, numbers, hyphens, and underscores';
|
|
237
|
+
}
|
|
238
|
+
return true;
|
|
239
|
+
}
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
type: 'list',
|
|
243
|
+
name: 'initWithReadme',
|
|
244
|
+
message: 'Initialize with README.md?',
|
|
245
|
+
choices: [
|
|
246
|
+
{ name: 'Yes', value: true },
|
|
247
|
+
{ name: 'No', value: false }
|
|
248
|
+
],
|
|
249
|
+
default: true
|
|
250
|
+
}
|
|
251
|
+
]);
|
|
252
|
+
const repoPath = `/tmp/new-repo-${repoName}`;
|
|
253
|
+
try {
|
|
254
|
+
// Create temporary directory for new repo
|
|
255
|
+
fs.mkdirSync(repoPath, { recursive: true });
|
|
256
|
+
// Initialize git repository
|
|
257
|
+
execSync('git init', { cwd: repoPath });
|
|
258
|
+
execSync('git config user.email "init@proletariat.local"', { cwd: repoPath });
|
|
259
|
+
execSync('git config user.name "Proletariat Init"', { cwd: repoPath });
|
|
260
|
+
if (initWithReadme) {
|
|
261
|
+
const readmeContent = `# ${repoName}\n\nCreated by Proletariat CLI\n`;
|
|
262
|
+
fs.writeFileSync(path.join(repoPath, 'README.md'), readmeContent);
|
|
263
|
+
execSync('git add README.md', { cwd: repoPath });
|
|
264
|
+
execSync('git commit -m "Initial commit"', { cwd: repoPath });
|
|
265
|
+
}
|
|
266
|
+
console.log(chalk.green(`✅ Created new repository: ${repoName}`));
|
|
267
|
+
return { path: repoPath, action: 'move' };
|
|
268
|
+
}
|
|
269
|
+
catch (error) {
|
|
270
|
+
console.log(chalk.red(`Failed to create repository ${repoName}: ${error}`));
|
|
271
|
+
return null;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Search for existing git repositories on the machine
|
|
276
|
+
*/
|
|
277
|
+
async function searchForRepositories() {
|
|
278
|
+
console.log(chalk.blue('🔍 Searching for git repositories...'));
|
|
279
|
+
// Common development directories to search
|
|
280
|
+
const searchPaths = [
|
|
281
|
+
path.join(process.env.HOME || '~', 'Projects'),
|
|
282
|
+
path.join(process.env.HOME || '~', 'Developer'),
|
|
283
|
+
path.join(process.env.HOME || '~', 'Code'),
|
|
284
|
+
path.join(process.env.HOME || '~', 'workspace'),
|
|
285
|
+
path.join(process.env.HOME || '~', 'src'),
|
|
286
|
+
].filter(p => fs.existsSync(p));
|
|
287
|
+
if (searchPaths.length === 0) {
|
|
288
|
+
console.log(chalk.yellow('No common development directories found.'));
|
|
289
|
+
return [];
|
|
290
|
+
}
|
|
291
|
+
const foundRepos = [];
|
|
292
|
+
for (const searchPath of searchPaths) {
|
|
293
|
+
try {
|
|
294
|
+
// Find .git directories (limiting depth for performance)
|
|
295
|
+
const result = execSync(`find "${searchPath}" -name ".git" -type d -maxdepth 3`, {
|
|
296
|
+
encoding: 'utf-8',
|
|
297
|
+
stdio: 'pipe'
|
|
298
|
+
}).trim();
|
|
299
|
+
if (result) {
|
|
300
|
+
const gitDirs = result.split('\n');
|
|
301
|
+
const repoPaths = gitDirs.map(gitDir => path.dirname(gitDir));
|
|
302
|
+
foundRepos.push(...repoPaths);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
catch {
|
|
306
|
+
// Skip directories we can't access
|
|
307
|
+
console.log(styles.muted(`Skipped ${searchPath} (no access)`));
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
if (foundRepos.length === 0) {
|
|
311
|
+
console.log(chalk.yellow('No git repositories found in common directories.'));
|
|
312
|
+
return [];
|
|
313
|
+
}
|
|
314
|
+
// Remove duplicates and sort alphabetically by repo name
|
|
315
|
+
const uniqueRepos = [...new Set(foundRepos)].sort((a, b) => path.basename(a).toLowerCase().localeCompare(path.basename(b).toLowerCase()));
|
|
316
|
+
const repoChoices = uniqueRepos.map(repoPath => ({
|
|
317
|
+
name: `${path.basename(repoPath)} (${repoPath})`,
|
|
318
|
+
value: repoPath
|
|
319
|
+
}));
|
|
320
|
+
const { selectedRepos } = await inquirer.prompt([{
|
|
321
|
+
type: 'checkbox',
|
|
322
|
+
name: 'selectedRepos',
|
|
323
|
+
message: `Found ${uniqueRepos.length} repositories. Select which ones to add (SPACE to select, ENTER when done):`,
|
|
324
|
+
choices: repoChoices,
|
|
325
|
+
pageSize: 10,
|
|
326
|
+
validate: (choices) => {
|
|
327
|
+
if (choices.length === 0) {
|
|
328
|
+
return 'No repositories selected. Press SPACE to select repositories, or ENTER to continue with none.';
|
|
329
|
+
}
|
|
330
|
+
return true;
|
|
331
|
+
},
|
|
332
|
+
}]);
|
|
333
|
+
console.log(chalk.green(`✅ Selected ${selectedRepos.length} repositories`));
|
|
334
|
+
return selectedRepos.map((repoPath) => ({ path: repoPath, action: 'clone' }));
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* Find HQ root by traversing upward
|
|
338
|
+
* @deprecated Use findHQRoot from '../workspace.js' instead for PRLT_HQ_PATH support
|
|
339
|
+
*/
|
|
340
|
+
export { findHQRoot } from '../workspace.js';
|
|
341
|
+
/**
|
|
342
|
+
* Get workspace repository information
|
|
343
|
+
*/
|
|
344
|
+
export function getWorkspaceRepoInfo() {
|
|
345
|
+
const hqPath = findHQRoot();
|
|
346
|
+
if (!hqPath) {
|
|
347
|
+
throw new Error('Not in an HQ directory. Run "prlt init" first.');
|
|
348
|
+
}
|
|
349
|
+
const reposPath = path.join(hqPath, 'repos');
|
|
350
|
+
const dbRepos = getWorkspaceRepositories(hqPath);
|
|
351
|
+
const repositories = dbRepos.map(repo => {
|
|
352
|
+
const fullPath = path.join(hqPath, repo.path);
|
|
353
|
+
return getRepoStatus(repo.name, fullPath, repo);
|
|
354
|
+
});
|
|
355
|
+
return { hqPath, reposPath, repositories };
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Get detailed status for a repository
|
|
359
|
+
*/
|
|
360
|
+
export function getRepoStatus(name, fullPath, dbRepo) {
|
|
361
|
+
const info = {
|
|
362
|
+
name,
|
|
363
|
+
path: dbRepo?.path || `repos/${name}`,
|
|
364
|
+
fullPath,
|
|
365
|
+
sourceUrl: dbRepo?.source_url,
|
|
366
|
+
status: 'missing',
|
|
367
|
+
commitsAhead: 0,
|
|
368
|
+
commitsBehind: 0,
|
|
369
|
+
addedAt: dbRepo?.added_at
|
|
370
|
+
};
|
|
371
|
+
if (!fs.existsSync(fullPath)) {
|
|
372
|
+
return info;
|
|
373
|
+
}
|
|
374
|
+
try {
|
|
375
|
+
// Get current branch
|
|
376
|
+
info.branch = execSync('git rev-parse --abbrev-ref HEAD', {
|
|
377
|
+
cwd: fullPath,
|
|
378
|
+
stdio: 'pipe',
|
|
379
|
+
encoding: 'utf-8'
|
|
380
|
+
}).trim();
|
|
381
|
+
// Check for uncommitted changes
|
|
382
|
+
const status = execSync('git status --porcelain', {
|
|
383
|
+
cwd: fullPath,
|
|
384
|
+
stdio: 'pipe',
|
|
385
|
+
encoding: 'utf-8'
|
|
386
|
+
}).trim();
|
|
387
|
+
info.status = status.length > 0 ? 'dirty' : 'clean';
|
|
388
|
+
// Get commits ahead/behind
|
|
389
|
+
try {
|
|
390
|
+
const aheadBehind = execSync('git rev-list --left-right --count @{upstream}...HEAD', {
|
|
391
|
+
cwd: fullPath,
|
|
392
|
+
stdio: 'pipe',
|
|
393
|
+
encoding: 'utf-8'
|
|
394
|
+
}).trim();
|
|
395
|
+
const [behind, ahead] = aheadBehind.split('\t').map(Number);
|
|
396
|
+
info.commitsAhead = ahead || 0;
|
|
397
|
+
info.commitsBehind = behind || 0;
|
|
398
|
+
}
|
|
399
|
+
catch {
|
|
400
|
+
// No upstream configured
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
catch {
|
|
404
|
+
// Git command failed
|
|
405
|
+
info.status = 'missing';
|
|
406
|
+
}
|
|
407
|
+
return info;
|
|
408
|
+
}
|
|
409
|
+
// =============================================================================
|
|
410
|
+
// Repository CRUD Operations
|
|
411
|
+
// =============================================================================
|
|
412
|
+
/**
|
|
413
|
+
* Add a single repository to the HQ (file system + database + agent worktrees)
|
|
414
|
+
*/
|
|
415
|
+
export async function addRepository(hqPath, repoPath, action) {
|
|
416
|
+
const repoName = path.basename(repoPath).replace(/\.git$/, '');
|
|
417
|
+
const reposDir = path.join(hqPath, 'repos');
|
|
418
|
+
const targetPath = path.join(reposDir, repoName);
|
|
419
|
+
// Ensure repos directory exists
|
|
420
|
+
if (!fs.existsSync(reposDir)) {
|
|
421
|
+
fs.mkdirSync(reposDir, { recursive: true });
|
|
422
|
+
}
|
|
423
|
+
// Check if repo already exists
|
|
424
|
+
if (fs.existsSync(targetPath)) {
|
|
425
|
+
return { success: false, name: repoName, error: 'Repository already exists' };
|
|
426
|
+
}
|
|
427
|
+
try {
|
|
428
|
+
// Add to file system
|
|
429
|
+
if (action === 'move') {
|
|
430
|
+
console.log(styles.muted(`Moving ${repoPath} to repos/${repoName}...`));
|
|
431
|
+
fs.renameSync(repoPath, targetPath);
|
|
432
|
+
}
|
|
433
|
+
else {
|
|
434
|
+
console.log(styles.muted(`Cloning ${repoPath} to repos/${repoName}...`));
|
|
435
|
+
execSync(`git clone "${repoPath}" "${targetPath}"`, { stdio: 'inherit' });
|
|
436
|
+
}
|
|
437
|
+
// Add to database
|
|
438
|
+
const dbRepoData = [{
|
|
439
|
+
name: repoName,
|
|
440
|
+
path: `repos/${repoName}`,
|
|
441
|
+
source_url: repoPath,
|
|
442
|
+
action
|
|
443
|
+
}];
|
|
444
|
+
addRepositoriesToDatabase(hqPath, dbRepoData);
|
|
445
|
+
// Create worktrees for existing agents
|
|
446
|
+
await createWorktreesForRepo(hqPath, repoName, targetPath);
|
|
447
|
+
// Create devcontainer config for sandboxed execution in the central repo
|
|
448
|
+
console.log(styles.muted(`Creating devcontainer config for ${repoName}...`));
|
|
449
|
+
createDevcontainerConfig({
|
|
450
|
+
agentName: repoName, // Use repo name as identifier
|
|
451
|
+
agentDir: targetPath,
|
|
452
|
+
repoWorktrees: [], // No nested worktrees - this is the repo itself
|
|
453
|
+
});
|
|
454
|
+
return { success: true, name: repoName };
|
|
455
|
+
}
|
|
456
|
+
catch (error) {
|
|
457
|
+
return {
|
|
458
|
+
success: false,
|
|
459
|
+
name: repoName,
|
|
460
|
+
error: error instanceof Error ? error.message : String(error)
|
|
461
|
+
};
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
/**
|
|
465
|
+
* Remove a repository from the HQ
|
|
466
|
+
*/
|
|
467
|
+
export async function removeRepository(hqPath, repoName, keepFiles = false) {
|
|
468
|
+
const repoPath = path.join(hqPath, 'repos', repoName);
|
|
469
|
+
try {
|
|
470
|
+
// Remove agent worktrees first
|
|
471
|
+
await removeWorktreesForRepo(hqPath, repoName);
|
|
472
|
+
// Remove from file system (unless keepFiles)
|
|
473
|
+
if (!keepFiles && fs.existsSync(repoPath)) {
|
|
474
|
+
fs.rmSync(repoPath, { recursive: true, force: true });
|
|
475
|
+
}
|
|
476
|
+
// Remove from database
|
|
477
|
+
const db = openWorkspaceDatabase(hqPath);
|
|
478
|
+
db.prepare('DELETE FROM repositories WHERE name = ?').run(repoName);
|
|
479
|
+
db.close();
|
|
480
|
+
return { success: true };
|
|
481
|
+
}
|
|
482
|
+
catch (error) {
|
|
483
|
+
return {
|
|
484
|
+
success: false,
|
|
485
|
+
error: error instanceof Error ? error.message : String(error)
|
|
486
|
+
};
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
/**
|
|
490
|
+
* Create worktrees for a repository in all agent directories
|
|
491
|
+
*/
|
|
492
|
+
async function createWorktreesForRepo(hqPath, repoName, repoPath) {
|
|
493
|
+
const db = openWorkspaceDatabase(hqPath);
|
|
494
|
+
// Get workspace config for theme info
|
|
495
|
+
const workspace = db.prepare('SELECT theme FROM workspace').get();
|
|
496
|
+
const theme = db.prepare('SELECT workspace_dir FROM themes WHERE name = ?').get(workspace.theme);
|
|
497
|
+
// Get all agents
|
|
498
|
+
const agents = db.prepare('SELECT name FROM agents').all();
|
|
499
|
+
if (agents.length === 0) {
|
|
500
|
+
db.close();
|
|
501
|
+
return;
|
|
502
|
+
}
|
|
503
|
+
const agentsBasePath = path.join(hqPath, 'agents', theme.workspace_dir);
|
|
504
|
+
for (const agent of agents) {
|
|
505
|
+
// Name worktree directory as {repoName}-{agentName} so git creates unique worktree entries
|
|
506
|
+
// e.g., proletariat-branson instead of proletariat (which causes proletariat1, proletariat2, etc.)
|
|
507
|
+
const worktreeDirName = `${repoName}-${agent.name}`;
|
|
508
|
+
const agentRepoPath = path.join(agentsBasePath, agent.name, worktreeDirName);
|
|
509
|
+
const branchName = `agent-${agent.name}`;
|
|
510
|
+
try {
|
|
511
|
+
// Create worktree
|
|
512
|
+
execSync(`git worktree add -b "${branchName}" "${agentRepoPath}"`, {
|
|
513
|
+
cwd: repoPath,
|
|
514
|
+
stdio: 'pipe'
|
|
515
|
+
});
|
|
516
|
+
// Add to database
|
|
517
|
+
db.prepare(`
|
|
518
|
+
INSERT OR REPLACE INTO agent_worktrees
|
|
519
|
+
(agent_name, repo_name, worktree_path, branch, created_at, commits_ahead, is_clean)
|
|
520
|
+
VALUES (?, ?, ?, ?, ?, 0, 1)
|
|
521
|
+
`).run(agent.name, repoName, `agents/${theme.workspace_dir}/${agent.name}/${worktreeDirName}`, branchName, new Date().toISOString());
|
|
522
|
+
}
|
|
523
|
+
catch {
|
|
524
|
+
console.log(chalk.yellow(`Warning: Could not create worktree for ${agent.name}/${repoName}`));
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
db.close();
|
|
528
|
+
}
|
|
529
|
+
/**
|
|
530
|
+
* Remove worktrees for a repository from all agent directories
|
|
531
|
+
*/
|
|
532
|
+
async function removeWorktreesForRepo(hqPath, repoName) {
|
|
533
|
+
const db = openWorkspaceDatabase(hqPath);
|
|
534
|
+
// Get workspace config for theme info
|
|
535
|
+
const workspace = db.prepare('SELECT theme FROM workspace').get();
|
|
536
|
+
const theme = db.prepare('SELECT workspace_dir FROM themes WHERE name = ?').get(workspace.theme);
|
|
537
|
+
// Get all agents
|
|
538
|
+
const agents = db.prepare('SELECT name FROM agents').all();
|
|
539
|
+
const repoPath = path.join(hqPath, 'repos', repoName);
|
|
540
|
+
const agentsBasePath = path.join(hqPath, 'agents', theme.workspace_dir);
|
|
541
|
+
for (const agent of agents) {
|
|
542
|
+
const agentRepoPath = path.join(agentsBasePath, agent.name, repoName);
|
|
543
|
+
try {
|
|
544
|
+
// Remove worktree from git
|
|
545
|
+
if (fs.existsSync(repoPath)) {
|
|
546
|
+
execSync(`git worktree remove "${agentRepoPath}" --force`, {
|
|
547
|
+
cwd: repoPath,
|
|
548
|
+
stdio: 'pipe'
|
|
549
|
+
});
|
|
550
|
+
}
|
|
551
|
+
else if (fs.existsSync(agentRepoPath)) {
|
|
552
|
+
// Repo doesn't exist but worktree dir does - just remove directory
|
|
553
|
+
fs.rmSync(agentRepoPath, { recursive: true, force: true });
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
catch {
|
|
557
|
+
// Try to just remove the directory
|
|
558
|
+
if (fs.existsSync(agentRepoPath)) {
|
|
559
|
+
try {
|
|
560
|
+
fs.rmSync(agentRepoPath, { recursive: true, force: true });
|
|
561
|
+
}
|
|
562
|
+
catch {
|
|
563
|
+
console.log(chalk.yellow(`Warning: Could not remove worktree for ${agent.name}/${repoName}`));
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
// Remove from database
|
|
569
|
+
db.prepare('DELETE FROM agent_worktrees WHERE repo_name = ?').run(repoName);
|
|
570
|
+
db.close();
|
|
571
|
+
}
|
|
572
|
+
// =============================================================================
|
|
573
|
+
// Interactive Prompts for Commands
|
|
574
|
+
// =============================================================================
|
|
575
|
+
/**
|
|
576
|
+
* Prompt to add a single repository
|
|
577
|
+
*/
|
|
578
|
+
export async function promptAddSingleRepo() {
|
|
579
|
+
const { method } = await inquirer.prompt([{
|
|
580
|
+
type: 'list',
|
|
581
|
+
name: 'method',
|
|
582
|
+
message: 'How would you like to add a repository?',
|
|
583
|
+
choices: [
|
|
584
|
+
{ name: '🔍 Search for repositories on this machine', value: 'search' },
|
|
585
|
+
{ name: '📁 Enter path or Git URL', value: 'manual' },
|
|
586
|
+
{ name: '✨ Create new repository', value: 'create' },
|
|
587
|
+
new inquirer.Separator(),
|
|
588
|
+
{ name: '❌ Cancel', value: 'cancel' }
|
|
589
|
+
]
|
|
590
|
+
}]);
|
|
591
|
+
if (method === 'cancel') {
|
|
592
|
+
return null;
|
|
593
|
+
}
|
|
594
|
+
if (method === 'create') {
|
|
595
|
+
return createNewRepository();
|
|
596
|
+
}
|
|
597
|
+
if (method === 'search') {
|
|
598
|
+
const repos = await searchForRepositories();
|
|
599
|
+
return repos.length > 0 ? repos[0] : null;
|
|
600
|
+
}
|
|
601
|
+
// Manual entry
|
|
602
|
+
const { repoPath } = await inquirer.prompt([{
|
|
603
|
+
type: 'input',
|
|
604
|
+
name: 'repoPath',
|
|
605
|
+
message: 'Enter repo path or Git URL:',
|
|
606
|
+
validate: (input) => input.trim() ? true : 'Path or URL required'
|
|
607
|
+
}]);
|
|
608
|
+
const trimmedPath = repoPath.trim();
|
|
609
|
+
const isUrl = trimmedPath.startsWith('http://') ||
|
|
610
|
+
trimmedPath.startsWith('https://') ||
|
|
611
|
+
trimmedPath.startsWith('git@');
|
|
612
|
+
if (isUrl) {
|
|
613
|
+
return { path: trimmedPath, action: 'clone' };
|
|
614
|
+
}
|
|
615
|
+
const resolvedPath = path.resolve(trimmedPath);
|
|
616
|
+
const repoName = path.basename(resolvedPath);
|
|
617
|
+
const currentlyInside = process.cwd().startsWith(resolvedPath);
|
|
618
|
+
if (currentlyInside) {
|
|
619
|
+
console.log(chalk.yellow(`Cannot move ${repoName} - you're currently inside it. Will clone instead.`));
|
|
620
|
+
return { path: resolvedPath, action: 'clone' };
|
|
621
|
+
}
|
|
622
|
+
const { action } = await inquirer.prompt([{
|
|
623
|
+
type: 'list',
|
|
624
|
+
name: 'action',
|
|
625
|
+
message: `${repoName} - Move or Clone?`,
|
|
626
|
+
choices: [
|
|
627
|
+
{ name: 'Clone (keep original)', value: 'clone' },
|
|
628
|
+
{ name: 'Move (relocate to HQ)', value: 'move' }
|
|
629
|
+
]
|
|
630
|
+
}]);
|
|
631
|
+
return { path: resolvedPath, action: action };
|
|
632
|
+
}
|
|
633
|
+
/**
|
|
634
|
+
* Prompt to select a repository from the workspace
|
|
635
|
+
*/
|
|
636
|
+
export async function promptSelectRepo(message = 'Select repository:', allowCancel = true) {
|
|
637
|
+
const { repositories } = getWorkspaceRepoInfo();
|
|
638
|
+
if (repositories.length === 0) {
|
|
639
|
+
console.log(colors.warning('No repositories found. Add one with "prlt repo add"'));
|
|
640
|
+
return null;
|
|
641
|
+
}
|
|
642
|
+
const choices = [
|
|
643
|
+
...repositories.map(repo => ({
|
|
644
|
+
name: `${repo.name} (${repo.status}${repo.commitsAhead > 0 ? `, ${repo.commitsAhead} ahead` : ''})`,
|
|
645
|
+
value: repo.name
|
|
646
|
+
}))
|
|
647
|
+
];
|
|
648
|
+
if (allowCancel) {
|
|
649
|
+
choices.push(new inquirer.Separator(), { name: '❌ Cancel', value: 'cancel' });
|
|
650
|
+
}
|
|
651
|
+
const { selected } = await inquirer.prompt([{
|
|
652
|
+
type: 'list',
|
|
653
|
+
name: 'selected',
|
|
654
|
+
message,
|
|
655
|
+
choices
|
|
656
|
+
}]);
|
|
657
|
+
return selected === 'cancel' ? null : selected;
|
|
658
|
+
}
|
|
659
|
+
/**
|
|
660
|
+
* Prompt to select multiple repositories
|
|
661
|
+
*/
|
|
662
|
+
export async function promptSelectMultipleRepos(message = 'Select repositories:') {
|
|
663
|
+
const { repositories } = getWorkspaceRepoInfo();
|
|
664
|
+
if (repositories.length === 0) {
|
|
665
|
+
console.log(colors.warning('No repositories found.'));
|
|
666
|
+
return [];
|
|
667
|
+
}
|
|
668
|
+
const choices = repositories.map(repo => ({
|
|
669
|
+
name: `${repo.name} (${repo.status}${repo.commitsAhead > 0 ? `, ${repo.commitsAhead} ahead` : ''})`,
|
|
670
|
+
value: repo.name
|
|
671
|
+
}));
|
|
672
|
+
const { selected } = await inquirer.prompt([{
|
|
673
|
+
type: 'checkbox',
|
|
674
|
+
name: 'selected',
|
|
675
|
+
message,
|
|
676
|
+
choices
|
|
677
|
+
}]);
|
|
678
|
+
return selected;
|
|
679
|
+
}
|