@proletariat/cli 0.2.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +561 -251
- package/bin/dev.cmd +3 -0
- package/bin/dev.js +5 -0
- package/bin/run.cmd +3 -0
- package/bin/run.js +23 -0
- package/dist/commands/action/create.d.ts +21 -0
- package/dist/commands/action/create.js +126 -0
- package/dist/commands/action/delete.d.ts +17 -0
- package/dist/commands/action/delete.js +78 -0
- package/dist/commands/action/index.d.ts +15 -0
- package/dist/commands/action/index.js +107 -0
- package/dist/commands/action/list.d.ts +14 -0
- package/dist/commands/action/list.js +89 -0
- package/dist/commands/action/run.d.ts +19 -0
- package/dist/commands/action/run.js +179 -0
- package/dist/commands/action/show.d.ts +15 -0
- package/dist/commands/action/show.js +47 -0
- package/dist/commands/action/update.d.ts +22 -0
- package/dist/commands/action/update.js +168 -0
- package/dist/commands/agent/index.d.ts +13 -0
- package/dist/commands/agent/index.js +131 -0
- package/dist/commands/agent/list.d.ts +7 -0
- package/dist/commands/agent/list.js +126 -0
- package/dist/commands/agent/login.d.ts +16 -0
- package/dist/commands/agent/login.js +146 -0
- package/dist/commands/agent/rebuild.d.ts +18 -0
- package/dist/commands/agent/rebuild.js +133 -0
- package/dist/commands/agent/restart.d.ts +17 -0
- package/dist/commands/agent/restart.js +116 -0
- package/dist/commands/agent/shell.d.ts +23 -0
- package/dist/commands/agent/shell.js +378 -0
- package/dist/commands/agent/staff/add.d.ts +15 -0
- package/dist/commands/agent/staff/add.js +281 -0
- package/dist/commands/agent/staff/index.d.ts +14 -0
- package/dist/commands/agent/staff/index.js +90 -0
- package/dist/commands/agent/staff/list.d.ts +7 -0
- package/dist/commands/agent/staff/list.js +90 -0
- package/dist/commands/agent/staff/remove.d.ts +16 -0
- package/dist/commands/agent/staff/remove.js +137 -0
- package/dist/commands/agent/status.d.ts +17 -0
- package/dist/commands/agent/status.js +139 -0
- package/dist/commands/agent/temp/cleanup.d.ts +23 -0
- package/dist/commands/agent/temp/cleanup.js +388 -0
- package/dist/commands/agent/temp/index.d.ts +14 -0
- package/dist/commands/agent/temp/index.js +82 -0
- package/dist/commands/agent/temp/list.d.ts +7 -0
- package/dist/commands/agent/temp/list.js +108 -0
- package/dist/commands/agent/themes/add-names.d.ts +10 -0
- package/dist/commands/agent/themes/add-names.js +67 -0
- package/dist/commands/agent/themes/create.d.ts +13 -0
- package/dist/commands/agent/themes/create.js +66 -0
- package/dist/commands/agent/themes/index.d.ts +9 -0
- package/dist/commands/agent/themes/index.js +194 -0
- package/dist/commands/agent/themes/list.d.ts +6 -0
- package/dist/commands/agent/themes/list.js +41 -0
- package/dist/commands/agent/themes/set.d.ts +12 -0
- package/dist/commands/agent/themes/set.js +77 -0
- package/dist/commands/agent/visit.d.ts +16 -0
- package/dist/commands/agent/visit.js +88 -0
- package/dist/commands/autocomplete/setup.d.ts +14 -0
- package/dist/commands/autocomplete/setup.js +154 -0
- package/dist/commands/board/index.d.ts +17 -0
- package/dist/commands/board/index.js +255 -0
- package/dist/commands/board/watch.d.ts +13 -0
- package/dist/commands/board/watch.js +52 -0
- package/dist/commands/branch/create.d.ts +50 -0
- package/dist/commands/branch/create.js +624 -0
- package/dist/commands/branch/index.d.ts +13 -0
- package/dist/commands/branch/index.js +50 -0
- package/dist/commands/branch/list.d.ts +17 -0
- package/dist/commands/branch/list.js +120 -0
- package/dist/commands/branch/validate.d.ts +15 -0
- package/dist/commands/branch/validate.js +73 -0
- package/dist/commands/commit.d.ts +71 -0
- package/dist/commands/commit.js +499 -0
- package/dist/commands/docker/clean.d.ts +13 -0
- package/dist/commands/docker/clean.js +224 -0
- package/dist/commands/docker/index.d.ts +19 -0
- package/dist/commands/docker/index.js +274 -0
- package/dist/commands/docker/list.d.ts +16 -0
- package/dist/commands/docker/list.js +200 -0
- package/dist/commands/docker/logs.d.ts +14 -0
- package/dist/commands/docker/logs.js +118 -0
- package/dist/commands/docker/prune.d.ts +14 -0
- package/dist/commands/docker/prune.js +211 -0
- package/dist/commands/docker/restart.d.ts +14 -0
- package/dist/commands/docker/restart.js +129 -0
- package/dist/commands/docker/shell.d.ts +14 -0
- package/dist/commands/docker/shell.js +103 -0
- package/dist/commands/docker/start.d.ts +12 -0
- package/dist/commands/docker/start.js +92 -0
- package/dist/commands/docker/status.d.ts +7 -0
- package/dist/commands/docker/status.js +40 -0
- package/dist/commands/docker/stop.d.ts +14 -0
- package/dist/commands/docker/stop.js +134 -0
- package/dist/commands/docker/sync.d.ts +15 -0
- package/dist/commands/docker/sync.js +112 -0
- package/dist/commands/epic/activate.d.ts +13 -0
- package/dist/commands/epic/activate.js +118 -0
- package/dist/commands/epic/archive.d.ts +14 -0
- package/dist/commands/epic/archive.js +132 -0
- package/dist/commands/epic/create.d.ts +15 -0
- package/dist/commands/epic/create.js +137 -0
- package/dist/commands/epic/index.d.ts +13 -0
- package/dist/commands/epic/index.js +88 -0
- package/dist/commands/epic/link/block.d.ts +14 -0
- package/dist/commands/epic/link/block.js +79 -0
- package/dist/commands/epic/link/duplicates.d.ts +14 -0
- package/dist/commands/epic/link/duplicates.js +66 -0
- package/dist/commands/epic/link/index.d.ts +19 -0
- package/dist/commands/epic/link/index.js +242 -0
- package/dist/commands/epic/link/relates.d.ts +14 -0
- package/dist/commands/epic/link/relates.js +66 -0
- package/dist/commands/epic/link/remove.d.ts +16 -0
- package/dist/commands/epic/link/remove.js +89 -0
- package/dist/commands/epic/list.d.ts +11 -0
- package/dist/commands/epic/list.js +87 -0
- package/dist/commands/epic/move.d.ts +15 -0
- package/dist/commands/epic/move.js +184 -0
- package/dist/commands/epic/progress.d.ts +16 -0
- package/dist/commands/epic/progress.js +166 -0
- package/dist/commands/epic/project.d.ts +15 -0
- package/dist/commands/epic/project.js +219 -0
- package/dist/commands/epic/reorder.d.ts +21 -0
- package/dist/commands/epic/reorder.js +160 -0
- package/dist/commands/epic/spec.d.ts +15 -0
- package/dist/commands/epic/spec.js +191 -0
- package/dist/commands/epic/ticket.d.ts +18 -0
- package/dist/commands/epic/ticket.js +291 -0
- package/dist/commands/epic/view.d.ts +13 -0
- package/dist/commands/epic/view.js +117 -0
- package/dist/commands/execution/index.d.ts +13 -0
- package/dist/commands/execution/index.js +70 -0
- package/dist/commands/execution/list.d.ts +15 -0
- package/dist/commands/execution/list.js +144 -0
- package/dist/commands/execution/logs.d.ts +18 -0
- package/dist/commands/execution/logs.js +161 -0
- package/dist/commands/execution/stop.d.ts +22 -0
- package/dist/commands/execution/stop.js +248 -0
- package/dist/commands/gh/index.d.ts +9 -0
- package/dist/commands/gh/index.js +53 -0
- package/dist/commands/gh/login.d.ts +6 -0
- package/dist/commands/gh/login.js +57 -0
- package/dist/commands/gh/status.d.ts +6 -0
- package/dist/commands/gh/status.js +48 -0
- package/dist/commands/gh/token.d.ts +6 -0
- package/dist/commands/gh/token.js +59 -0
- package/dist/commands/init.d.ts +26 -0
- package/dist/commands/init.js +200 -0
- package/dist/commands/phase/create.d.ts +22 -0
- package/dist/commands/phase/create.js +123 -0
- package/dist/commands/phase/delete.d.ts +17 -0
- package/dist/commands/phase/delete.js +73 -0
- package/dist/commands/phase/list.d.ts +12 -0
- package/dist/commands/phase/list.js +76 -0
- package/dist/commands/phase/move.d.ts +17 -0
- package/dist/commands/phase/move.js +115 -0
- package/dist/commands/phase/template/apply.d.ts +17 -0
- package/dist/commands/phase/template/apply.js +106 -0
- package/dist/commands/phase/template/create.d.ts +16 -0
- package/dist/commands/phase/template/create.js +58 -0
- package/dist/commands/phase/template/delete.d.ts +17 -0
- package/dist/commands/phase/template/delete.js +98 -0
- package/dist/commands/phase/template/index.d.ts +15 -0
- package/dist/commands/phase/template/index.js +128 -0
- package/dist/commands/phase/template/list.d.ts +16 -0
- package/dist/commands/phase/template/list.js +95 -0
- package/dist/commands/phase/template/update.d.ts +17 -0
- package/dist/commands/phase/template/update.js +89 -0
- package/dist/commands/phase/update.d.ts +23 -0
- package/dist/commands/phase/update.js +174 -0
- package/dist/commands/pmo/init.d.ts +25 -0
- package/dist/commands/pmo/init.js +341 -0
- package/dist/commands/pr/create.d.ts +17 -0
- package/dist/commands/pr/create.js +242 -0
- package/dist/commands/pr/index.d.ts +9 -0
- package/dist/commands/pr/index.js +68 -0
- package/dist/commands/pr/link.d.ts +14 -0
- package/dist/commands/pr/link.js +212 -0
- package/dist/commands/pr/status.d.ts +12 -0
- package/dist/commands/pr/status.js +161 -0
- package/dist/commands/project/archive.d.ts +17 -0
- package/dist/commands/project/archive.js +83 -0
- package/dist/commands/project/create.d.ts +22 -0
- package/dist/commands/project/create.js +143 -0
- package/dist/commands/project/delete.d.ts +17 -0
- package/dist/commands/project/delete.js +128 -0
- package/dist/commands/project/index.d.ts +13 -0
- package/dist/commands/project/index.js +64 -0
- package/dist/commands/project/list.d.ts +14 -0
- package/dist/commands/project/list.js +96 -0
- package/dist/commands/project/spec.d.ts +18 -0
- package/dist/commands/project/spec.js +216 -0
- package/dist/commands/project/unarchive.d.ts +15 -0
- package/dist/commands/project/unarchive.js +35 -0
- package/dist/commands/project/view.d.ts +16 -0
- package/dist/commands/project/view.js +94 -0
- package/dist/commands/repo/add.d.ts +21 -0
- package/dist/commands/repo/add.js +118 -0
- package/dist/commands/repo/index.d.ts +13 -0
- package/dist/commands/repo/index.js +114 -0
- package/dist/commands/repo/list.d.ts +13 -0
- package/dist/commands/repo/list.js +96 -0
- package/dist/commands/repo/remove.d.ts +23 -0
- package/dist/commands/repo/remove.js +217 -0
- package/dist/commands/repo/view.d.ts +15 -0
- package/dist/commands/repo/view.js +99 -0
- package/dist/commands/session/attach.d.ts +40 -0
- package/dist/commands/session/attach.js +307 -0
- package/dist/commands/session/index.d.ts +13 -0
- package/dist/commands/session/index.js +64 -0
- package/dist/commands/session/list.d.ts +21 -0
- package/dist/commands/session/list.js +181 -0
- package/dist/commands/spec/create.d.ts +19 -0
- package/dist/commands/spec/create.js +130 -0
- package/dist/commands/spec/index.d.ts +13 -0
- package/dist/commands/spec/index.js +68 -0
- package/dist/commands/spec/link/depends.d.ts +14 -0
- package/dist/commands/spec/link/depends.js +64 -0
- package/dist/commands/spec/link/duplicates.d.ts +14 -0
- package/dist/commands/spec/link/duplicates.js +63 -0
- package/dist/commands/spec/link/index.d.ts +19 -0
- package/dist/commands/spec/link/index.js +200 -0
- package/dist/commands/spec/link/relates.d.ts +14 -0
- package/dist/commands/spec/link/relates.js +63 -0
- package/dist/commands/spec/link/remove.d.ts +16 -0
- package/dist/commands/spec/link/remove.js +94 -0
- package/dist/commands/spec/list.d.ts +12 -0
- package/dist/commands/spec/list.js +75 -0
- package/dist/commands/spec/plan.d.ts +15 -0
- package/dist/commands/spec/plan.js +108 -0
- package/dist/commands/spec/ticket.d.ts +18 -0
- package/dist/commands/spec/ticket.js +160 -0
- package/dist/commands/spec/view.d.ts +15 -0
- package/dist/commands/spec/view.js +163 -0
- package/dist/commands/status/create.d.ts +21 -0
- package/dist/commands/status/create.js +140 -0
- package/dist/commands/status/delete.d.ts +13 -0
- package/dist/commands/status/delete.js +77 -0
- package/dist/commands/status/index.d.ts +14 -0
- package/dist/commands/status/index.js +91 -0
- package/dist/commands/status/list.d.ts +12 -0
- package/dist/commands/status/list.js +93 -0
- package/dist/commands/status/move.d.ts +14 -0
- package/dist/commands/status/move.js +120 -0
- package/dist/commands/status/update.d.ts +20 -0
- package/dist/commands/status/update.js +180 -0
- package/dist/commands/template/delete.d.ts +15 -0
- package/dist/commands/template/delete.js +142 -0
- package/dist/commands/template/index.d.ts +10 -0
- package/dist/commands/template/index.js +64 -0
- package/dist/commands/template/list.d.ts +18 -0
- package/dist/commands/template/list.js +157 -0
- package/dist/commands/template/phase/apply.d.ts +14 -0
- package/dist/commands/template/phase/apply.js +41 -0
- package/dist/commands/template/phase/create.d.ts +12 -0
- package/dist/commands/template/phase/create.js +29 -0
- package/dist/commands/template/phase/delete.d.ts +13 -0
- package/dist/commands/template/phase/delete.js +34 -0
- package/dist/commands/template/phase/index.d.ts +10 -0
- package/dist/commands/template/phase/index.js +62 -0
- package/dist/commands/template/phase/list.d.ts +11 -0
- package/dist/commands/template/phase/list.js +34 -0
- package/dist/commands/template/phase/update.d.ts +13 -0
- package/dist/commands/template/phase/update.js +35 -0
- package/dist/commands/template/ticket/apply.d.ts +17 -0
- package/dist/commands/template/ticket/apply.js +58 -0
- package/dist/commands/template/ticket/delete.d.ts +13 -0
- package/dist/commands/template/ticket/delete.js +34 -0
- package/dist/commands/template/ticket/index.d.ts +10 -0
- package/dist/commands/template/ticket/index.js +62 -0
- package/dist/commands/template/ticket/list.d.ts +11 -0
- package/dist/commands/template/ticket/list.js +34 -0
- package/dist/commands/template/ticket/save.d.ts +13 -0
- package/dist/commands/template/ticket/save.js +35 -0
- package/dist/commands/ticket/bulk.d.ts +13 -0
- package/dist/commands/ticket/bulk.js +145 -0
- package/dist/commands/ticket/complete.d.ts +16 -0
- package/dist/commands/ticket/complete.js +170 -0
- package/dist/commands/ticket/create.d.ts +22 -0
- package/dist/commands/ticket/create.js +390 -0
- package/dist/commands/ticket/delete.d.ts +16 -0
- package/dist/commands/ticket/delete.js +178 -0
- package/dist/commands/ticket/edit.d.ts +27 -0
- package/dist/commands/ticket/edit.js +322 -0
- package/dist/commands/ticket/epic.d.ts +20 -0
- package/dist/commands/ticket/epic.js +333 -0
- package/dist/commands/ticket/index.d.ts +13 -0
- package/dist/commands/ticket/index.js +103 -0
- package/dist/commands/ticket/link/block.d.ts +14 -0
- package/dist/commands/ticket/link/block.js +94 -0
- package/dist/commands/ticket/link/duplicates.d.ts +14 -0
- package/dist/commands/ticket/link/duplicates.js +93 -0
- package/dist/commands/ticket/link/index.d.ts +19 -0
- package/dist/commands/ticket/link/index.js +239 -0
- package/dist/commands/ticket/link/relates.d.ts +14 -0
- package/dist/commands/ticket/link/relates.js +93 -0
- package/dist/commands/ticket/link/remove.d.ts +16 -0
- package/dist/commands/ticket/link/remove.js +128 -0
- package/dist/commands/ticket/list.d.ts +24 -0
- package/dist/commands/ticket/list.js +431 -0
- package/dist/commands/ticket/move.d.ts +18 -0
- package/dist/commands/ticket/move.js +212 -0
- package/dist/commands/ticket/project.d.ts +18 -0
- package/dist/commands/ticket/project.js +254 -0
- package/dist/commands/ticket/reassign.d.ts +19 -0
- package/dist/commands/ticket/reassign.js +279 -0
- package/dist/commands/ticket/spec.d.ts +18 -0
- package/dist/commands/ticket/spec.js +259 -0
- package/dist/commands/ticket/status.d.ts +13 -0
- package/dist/commands/ticket/status.js +87 -0
- package/dist/commands/ticket/template/apply.d.ts +25 -0
- package/dist/commands/ticket/template/apply.js +249 -0
- package/dist/commands/ticket/template/create.d.ts +19 -0
- package/dist/commands/ticket/template/create.js +210 -0
- package/dist/commands/ticket/template/delete.d.ts +17 -0
- package/dist/commands/ticket/template/delete.js +92 -0
- package/dist/commands/ticket/template/index.d.ts +15 -0
- package/dist/commands/ticket/template/index.js +118 -0
- package/dist/commands/ticket/template/list.d.ts +16 -0
- package/dist/commands/ticket/template/list.js +110 -0
- package/dist/commands/ticket/template/save.d.ts +14 -0
- package/dist/commands/ticket/template/save.js +110 -0
- package/dist/commands/ticket/update.d.ts +18 -0
- package/dist/commands/ticket/update.js +325 -0
- package/dist/commands/ticket/view.d.ts +13 -0
- package/dist/commands/ticket/view.js +80 -0
- package/dist/commands/whoami.d.ts +9 -0
- package/dist/commands/whoami.js +103 -0
- package/dist/commands/work/complete.d.ts +13 -0
- package/dist/commands/work/complete.js +121 -0
- package/dist/commands/work/index.d.ts +13 -0
- package/dist/commands/work/index.js +70 -0
- package/dist/commands/work/ready.d.ts +24 -0
- package/dist/commands/work/ready.js +290 -0
- package/dist/commands/work/revise.d.ts +19 -0
- package/dist/commands/work/revise.js +377 -0
- package/dist/commands/work/spawn-all.d.ts +17 -0
- package/dist/commands/work/spawn-all.js +58 -0
- package/dist/commands/work/spawn.d.ts +29 -0
- package/dist/commands/work/spawn.js +728 -0
- package/dist/commands/work/start.d.ts +39 -0
- package/dist/commands/work/start.js +1393 -0
- package/dist/commands/work/watch.d.ts +31 -0
- package/dist/commands/work/watch.js +359 -0
- package/dist/commands/workflow/create.d.ts +18 -0
- package/dist/commands/workflow/create.js +119 -0
- package/dist/commands/workflow/delete.d.ts +17 -0
- package/dist/commands/workflow/delete.js +119 -0
- package/dist/commands/workflow/index.d.ts +15 -0
- package/dist/commands/workflow/index.js +75 -0
- package/dist/commands/workflow/list.d.ts +15 -0
- package/dist/commands/workflow/list.js +75 -0
- package/dist/commands/workflow/switch.d.ts +13 -0
- package/dist/commands/workflow/switch.js +117 -0
- package/dist/commands/workflow/view.d.ts +16 -0
- package/dist/commands/workflow/view.js +114 -0
- package/dist/commands/workspace/add.d.ts +12 -0
- package/dist/commands/workspace/add.js +74 -0
- package/dist/commands/workspace/list.d.ts +9 -0
- package/dist/commands/workspace/list.js +153 -0
- package/dist/commands/workspace/remove.d.ts +13 -0
- package/dist/commands/workspace/remove.js +98 -0
- package/dist/commands/workspace/use.d.ts +12 -0
- package/dist/commands/workspace/use.js +111 -0
- package/dist/hooks/init.d.ts +11 -0
- package/dist/hooks/init.js +57 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/lib/agents/commands.d.ts +189 -0
- package/dist/lib/agents/commands.js +893 -0
- package/dist/lib/agents/index.d.ts +54 -0
- package/dist/lib/agents/index.js +382 -0
- package/dist/lib/branch/index.d.ts +120 -0
- package/dist/lib/branch/index.js +334 -0
- package/dist/lib/colors.d.ts +94 -0
- package/dist/lib/colors.js +68 -0
- package/dist/lib/commands/docker-command.d.ts +21 -0
- package/dist/lib/commands/docker-command.js +27 -0
- package/dist/lib/database/index.d.ts +176 -0
- package/dist/lib/database/index.js +581 -0
- package/dist/lib/docker/resolve.d.ts +38 -0
- package/dist/lib/docker/resolve.js +175 -0
- package/dist/lib/execution/config.d.ts +150 -0
- package/dist/lib/execution/config.js +541 -0
- package/dist/lib/execution/devcontainer.d.ts +85 -0
- package/dist/lib/execution/devcontainer.js +594 -0
- package/dist/lib/execution/index.d.ts +10 -0
- package/dist/lib/execution/index.js +10 -0
- package/dist/lib/execution/runners.d.ts +53 -0
- package/dist/lib/execution/runners.js +1182 -0
- package/dist/lib/execution/spawner.d.ts +85 -0
- package/dist/lib/execution/spawner.js +548 -0
- package/dist/lib/execution/storage.d.ts +159 -0
- package/dist/lib/execution/storage.js +425 -0
- package/dist/lib/execution/types.d.ts +145 -0
- package/dist/lib/execution/types.js +157 -0
- package/dist/lib/init/index.d.ts +75 -0
- package/dist/lib/init/index.js +355 -0
- package/dist/lib/machine-config.d.ts +170 -0
- package/dist/lib/machine-config.js +386 -0
- package/dist/lib/pmo/base-command.d.ts +195 -0
- package/dist/lib/pmo/base-command.js +319 -0
- package/dist/lib/pmo/create-spec-folders.d.ts +43 -0
- package/dist/lib/pmo/create-spec-folders.js +64 -0
- package/dist/lib/pmo/epic-files.d.ts +56 -0
- package/dist/lib/pmo/epic-files.js +195 -0
- package/dist/lib/pmo/find-pmo.d.ts +14 -0
- package/dist/lib/pmo/find-pmo.js +172 -0
- package/dist/lib/pmo/index.d.ts +109 -0
- package/dist/lib/pmo/index.js +501 -0
- package/dist/lib/pmo/markdown.d.ts +31 -0
- package/dist/lib/pmo/markdown.js +245 -0
- package/dist/lib/pmo/pmo-context.d.ts +27 -0
- package/dist/lib/pmo/pmo-context.js +44 -0
- package/dist/lib/pmo/schema.d.ts +82 -0
- package/dist/lib/pmo/schema.js +531 -0
- package/dist/lib/pmo/spec-parser.d.ts +25 -0
- package/dist/lib/pmo/spec-parser.js +205 -0
- package/dist/lib/pmo/spec-types.d.ts +43 -0
- package/dist/lib/pmo/spec-types.js +7 -0
- package/dist/lib/pmo/storage/actions.d.ts +34 -0
- package/dist/lib/pmo/storage/actions.js +177 -0
- package/dist/lib/pmo/storage/base.d.ts +47 -0
- package/dist/lib/pmo/storage/base.js +858 -0
- package/dist/lib/pmo/storage/dependencies.d.ts +61 -0
- package/dist/lib/pmo/storage/dependencies.js +267 -0
- package/dist/lib/pmo/storage/epics.d.ts +46 -0
- package/dist/lib/pmo/storage/epics.js +243 -0
- package/dist/lib/pmo/storage/helpers.d.ts +33 -0
- package/dist/lib/pmo/storage/helpers.js +148 -0
- package/dist/lib/pmo/storage/index.d.ts +186 -0
- package/dist/lib/pmo/storage/index.js +689 -0
- package/dist/lib/pmo/storage/phases.d.ts +65 -0
- package/dist/lib/pmo/storage/phases.js +392 -0
- package/dist/lib/pmo/storage/projects.d.ts +79 -0
- package/dist/lib/pmo/storage/projects.js +303 -0
- package/dist/lib/pmo/storage/specs.d.ts +77 -0
- package/dist/lib/pmo/storage/specs.js +389 -0
- package/dist/lib/pmo/storage/statuses.d.ts +63 -0
- package/dist/lib/pmo/storage/statuses.js +404 -0
- package/dist/lib/pmo/storage/subtasks.d.ts +37 -0
- package/dist/lib/pmo/storage/subtasks.js +184 -0
- package/dist/lib/pmo/storage/templates.d.ts +40 -0
- package/dist/lib/pmo/storage/templates.js +210 -0
- package/dist/lib/pmo/storage/tickets.d.ts +57 -0
- package/dist/lib/pmo/storage/tickets.js +453 -0
- package/dist/lib/pmo/storage/types.d.ts +200 -0
- package/dist/lib/pmo/storage/types.js +5 -0
- package/dist/lib/pmo/storage/views.d.ts +44 -0
- package/dist/lib/pmo/storage/views.js +355 -0
- package/dist/lib/pmo/storage-sqlite.d.ts +7 -0
- package/dist/lib/pmo/storage-sqlite.js +7 -0
- package/dist/lib/pmo/sync-manager.d.ts +92 -0
- package/dist/lib/pmo/sync-manager.js +229 -0
- package/dist/lib/pmo/types.d.ts +710 -0
- package/dist/lib/pmo/types.js +108 -0
- package/dist/lib/pmo/utils.d.ts +122 -0
- package/dist/lib/pmo/utils.js +174 -0
- package/dist/lib/pmo/watcher.d.ts +43 -0
- package/dist/lib/pmo/watcher.js +208 -0
- package/dist/lib/pr/index.d.ts +150 -0
- package/dist/lib/pr/index.js +483 -0
- package/dist/lib/prompt-json.d.ts +231 -0
- package/dist/lib/prompt-json.js +213 -0
- package/dist/lib/repos/index.d.ts +81 -0
- package/dist/lib/repos/index.js +679 -0
- package/dist/lib/styles.d.ts +98 -0
- package/dist/lib/styles.js +195 -0
- package/dist/lib/themes.d.ts +128 -0
- package/dist/lib/themes.js +301 -0
- package/dist/lib/ui/BoardUI.d.ts +21 -0
- package/dist/lib/ui/BoardUI.js +85 -0
- package/dist/lib/ui/ClaimTicketUI.d.ts +17 -0
- package/dist/lib/ui/ClaimTicketUI.js +64 -0
- package/dist/lib/ui/CreateTicketUI.d.ts +13 -0
- package/dist/lib/ui/CreateTicketUI.js +101 -0
- package/dist/lib/workspace.d.ts +66 -0
- package/dist/lib/workspace.js +204 -0
- package/oclif.manifest.json +10593 -0
- package/package.json +103 -56
- package/LICENSE +0 -21
- package/dist/bin/prlt.d.ts +0 -11
- package/dist/bin/prlt.d.ts.map +0 -1
- package/dist/bin/prlt.js +0 -144
- package/dist/bin/prlt.js.map +0 -1
- package/dist/lib/config/index.d.ts +0 -14
- package/dist/lib/config/index.d.ts.map +0 -1
- package/dist/lib/config/index.js +0 -142
- package/dist/lib/config/index.js.map +0 -1
- package/dist/lib/config/upgrade.d.ts +0 -2
- package/dist/lib/config/upgrade.d.ts.map +0 -1
- package/dist/lib/config/upgrade.js +0 -248
- package/dist/lib/config/upgrade.js.map +0 -1
- package/dist/lib/themes/index.d.ts +0 -8
- package/dist/lib/themes/index.d.ts.map +0 -1
- package/dist/lib/themes/index.js +0 -80
- package/dist/lib/themes/index.js.map +0 -1
- package/dist/lib/utils/helpers.d.ts +0 -4
- package/dist/lib/utils/helpers.d.ts.map +0 -1
- package/dist/lib/utils/helpers.js +0 -39
- package/dist/lib/utils/helpers.js.map +0 -1
- package/dist/lib/utils/logger.d.ts +0 -4
- package/dist/lib/utils/logger.d.ts.map +0 -1
- package/dist/lib/utils/logger.js +0 -28
- package/dist/lib/utils/logger.js.map +0 -1
- package/dist/lib/workspace/index.d.ts +0 -13
- package/dist/lib/workspace/index.d.ts.map +0 -1
- package/dist/lib/workspace/index.js +0 -116
- package/dist/lib/workspace/index.js.map +0 -1
- package/dist/lib/worktree/index.d.ts +0 -7
- package/dist/lib/worktree/index.d.ts.map +0 -1
- package/dist/lib/worktree/index.js +0 -362
- package/dist/lib/worktree/index.js.map +0 -1
- package/dist/lib/worktree/migrate.d.ts +0 -2
- package/dist/lib/worktree/migrate.d.ts.map +0 -1
- package/dist/lib/worktree/migrate.js +0 -214
- package/dist/lib/worktree/migrate.js.map +0 -1
- package/dist/lib/worktree/repair.d.ts +0 -3
- package/dist/lib/worktree/repair.d.ts.map +0 -1
- package/dist/lib/worktree/repair.js +0 -320
- package/dist/lib/worktree/repair.js.map +0 -1
- package/dist/types/index.d.ts +0 -57
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/index.js +0 -3
- package/dist/types/index.js.map +0 -1
|
@@ -0,0 +1,624 @@
|
|
|
1
|
+
import { Args, Flags } from '@oclif/core';
|
|
2
|
+
import * as fs from 'fs';
|
|
3
|
+
import * as path from 'path';
|
|
4
|
+
import inquirer from 'inquirer';
|
|
5
|
+
import Database from 'better-sqlite3';
|
|
6
|
+
import { PMOCommand, pmoBaseFlags } from '../../lib/pmo/index.js';
|
|
7
|
+
import { styles } from '../../lib/styles.js';
|
|
8
|
+
import { shouldOutputJson, outputPromptAsJson, outputErrorAsJson, createMetadata, buildPromptConfig, } from '../../lib/prompt-json.js';
|
|
9
|
+
import { BRANCH_TYPES, DEVELOPMENT_TYPES, BUSINESS_TYPES, isKebabCase, isValidBranchType, buildBranchName, toKebabCase, validateBranchName, branchExists, createBranch, createEmptyCommit, isGitRepo, fetchOrigin, checkoutBranch, listBranches, } from '../../lib/branch/index.js';
|
|
10
|
+
import { getCoderName, getGitUserName, getGitHubUsername } from '../../lib/execution/config.js';
|
|
11
|
+
import { getBranchType } from '../../lib/execution/types.js';
|
|
12
|
+
import { detectAgentName } from '../../lib/agents/index.js';
|
|
13
|
+
export default class BranchCreate extends PMOCommand {
|
|
14
|
+
static description = 'Create a new branch with conventional naming';
|
|
15
|
+
static examples = [
|
|
16
|
+
'<%= config.bin %> <%= command.id %>',
|
|
17
|
+
'<%= config.bin %> <%= command.id %> -T TKT-001',
|
|
18
|
+
'<%= config.bin %> <%= command.id %> -T TKT-001 -e',
|
|
19
|
+
'<%= config.bin %> <%= command.id %> feat/chris/add-user-auth',
|
|
20
|
+
'<%= config.bin %> <%= command.id %> -t feat -c chris -d add-user-auth',
|
|
21
|
+
];
|
|
22
|
+
static args = {
|
|
23
|
+
name: Args.string({
|
|
24
|
+
description: 'Full branch name (bypasses wizard)',
|
|
25
|
+
required: false,
|
|
26
|
+
}),
|
|
27
|
+
};
|
|
28
|
+
static flags = {
|
|
29
|
+
...pmoBaseFlags,
|
|
30
|
+
ticket: Flags.string({
|
|
31
|
+
char: 'T',
|
|
32
|
+
description: 'Ticket ID - auto-generates branch from ticket (or use with -t/-d for manual)',
|
|
33
|
+
}),
|
|
34
|
+
type: Flags.string({
|
|
35
|
+
char: 't',
|
|
36
|
+
description: 'Branch type',
|
|
37
|
+
options: Object.keys(BRANCH_TYPES),
|
|
38
|
+
}),
|
|
39
|
+
owner: Flags.string({
|
|
40
|
+
char: 'c',
|
|
41
|
+
description: 'Owner/coder identifier (defaults to GitHub username)',
|
|
42
|
+
}),
|
|
43
|
+
description: Flags.string({
|
|
44
|
+
char: 'd',
|
|
45
|
+
description: 'Branch description (kebab-case)',
|
|
46
|
+
}),
|
|
47
|
+
'empty-commit': Flags.boolean({
|
|
48
|
+
char: 'e',
|
|
49
|
+
description: 'Create initial commit to seed PR title',
|
|
50
|
+
default: false,
|
|
51
|
+
}),
|
|
52
|
+
'no-switch': Flags.boolean({
|
|
53
|
+
description: 'Create branch without switching to it',
|
|
54
|
+
default: false,
|
|
55
|
+
}),
|
|
56
|
+
'from-origin': Flags.boolean({
|
|
57
|
+
char: 'o',
|
|
58
|
+
description: 'Fetch and create branch from origin/main',
|
|
59
|
+
default: false,
|
|
60
|
+
}),
|
|
61
|
+
force: Flags.boolean({
|
|
62
|
+
char: 'f',
|
|
63
|
+
description: 'Non-interactive mode: skip prompts, switch to existing branch if it exists',
|
|
64
|
+
default: false,
|
|
65
|
+
}),
|
|
66
|
+
json: Flags.boolean({
|
|
67
|
+
description: 'Output prompt configuration as JSON (for AI agents/scripts)',
|
|
68
|
+
default: false,
|
|
69
|
+
}),
|
|
70
|
+
};
|
|
71
|
+
getPMOOptions() {
|
|
72
|
+
return { promptIfMultiple: false };
|
|
73
|
+
}
|
|
74
|
+
async execute() {
|
|
75
|
+
const { args, flags } = await this.parse(BranchCreate);
|
|
76
|
+
// Check if JSON output mode is active
|
|
77
|
+
const jsonMode = shouldOutputJson(flags);
|
|
78
|
+
// Helper to handle errors in JSON mode
|
|
79
|
+
const handleError = (code, message) => {
|
|
80
|
+
if (jsonMode) {
|
|
81
|
+
outputErrorAsJson(code, message, createMetadata('branch create', flags));
|
|
82
|
+
this.exit(1);
|
|
83
|
+
}
|
|
84
|
+
this.error(message);
|
|
85
|
+
};
|
|
86
|
+
// Check if in git repo
|
|
87
|
+
if (!isGitRepo()) {
|
|
88
|
+
return handleError('NOT_GIT_REPO', 'Not in a git repository.');
|
|
89
|
+
}
|
|
90
|
+
let branchName;
|
|
91
|
+
if (args.name) {
|
|
92
|
+
// Direct name provided - validate and create
|
|
93
|
+
branchName = args.name;
|
|
94
|
+
const validation = validateBranchName(branchName);
|
|
95
|
+
if (!validation.valid) {
|
|
96
|
+
// Build choices once, use for both JSON and interactive modes
|
|
97
|
+
const confirmChoices = [
|
|
98
|
+
{ name: 'No', value: 'false' },
|
|
99
|
+
{ name: 'Yes', value: 'true' },
|
|
100
|
+
];
|
|
101
|
+
const confirmMessage = `Branch name doesn't follow conventional format. ${validation.error} Continue anyway?`;
|
|
102
|
+
// In JSON mode, output validation warning prompt
|
|
103
|
+
if (jsonMode) {
|
|
104
|
+
outputPromptAsJson(buildPromptConfig('list', 'proceed', confirmMessage, confirmChoices), createMetadata('branch create', flags));
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
// Warn but allow creation
|
|
108
|
+
const { proceed } = await inquirer.prompt([
|
|
109
|
+
{
|
|
110
|
+
type: 'list',
|
|
111
|
+
name: 'proceed',
|
|
112
|
+
message: confirmMessage.replace('. ', '.\n ').replace('?', '?\n '),
|
|
113
|
+
choices: confirmChoices.map(c => ({ name: c.name, value: c.value === 'true' })),
|
|
114
|
+
default: false,
|
|
115
|
+
},
|
|
116
|
+
]);
|
|
117
|
+
if (!proceed) {
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
else if (flags.ticket && !flags.type && !flags.description) {
|
|
123
|
+
// Ticket-only mode: look up ticket and auto-generate branch name
|
|
124
|
+
const projectId = flags.project;
|
|
125
|
+
const ticketResult = await this.createFromTicketId(flags.ticket, flags.owner, projectId);
|
|
126
|
+
if (!ticketResult) {
|
|
127
|
+
return handleError('TICKET_NOT_FOUND', `Could not find ticket: ${flags.ticket}`);
|
|
128
|
+
}
|
|
129
|
+
branchName = ticketResult.branchName;
|
|
130
|
+
this._selectedTicket = ticketResult.ticket;
|
|
131
|
+
}
|
|
132
|
+
else if (flags.type && flags.description) {
|
|
133
|
+
// Flags provided - build name
|
|
134
|
+
const type = flags.type;
|
|
135
|
+
if (!isValidBranchType(type)) {
|
|
136
|
+
return handleError('INVALID_BRANCH_TYPE', `Invalid branch type: "${type}"`);
|
|
137
|
+
}
|
|
138
|
+
const description = flags.description;
|
|
139
|
+
if (!isKebabCase(description)) {
|
|
140
|
+
return handleError('INVALID_DESCRIPTION', `Description must be kebab-case: "${description}". Example: add-user-auth, fix-login-bug`);
|
|
141
|
+
}
|
|
142
|
+
// Use provided owner name or fall back to configured default
|
|
143
|
+
const ownerName = flags.owner || this.getDefaultOwnerName();
|
|
144
|
+
if (ownerName && !isKebabCase(ownerName)) {
|
|
145
|
+
return handleError('INVALID_OWNER', `Owner name must be kebab-case: "${ownerName}". Example: chris, chris-m, team-alpha`);
|
|
146
|
+
}
|
|
147
|
+
branchName = buildBranchName(type, description, {
|
|
148
|
+
ticketId: flags.ticket,
|
|
149
|
+
owner: ownerName,
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
// Interactive wizard
|
|
154
|
+
const wizardResult = await this.runWizard(jsonMode, flags);
|
|
155
|
+
if (!wizardResult)
|
|
156
|
+
return;
|
|
157
|
+
branchName = wizardResult.branchName;
|
|
158
|
+
this._selectedTicket = wizardResult.ticket;
|
|
159
|
+
this._autoCommit = wizardResult.autoCommit;
|
|
160
|
+
this._fromOrigin = wizardResult.fromOrigin;
|
|
161
|
+
this._customStartPoint = wizardResult.customStartPoint;
|
|
162
|
+
}
|
|
163
|
+
// Fetch from origin if requested (via flag or wizard)
|
|
164
|
+
const fromOrigin = flags['from-origin'] || this._fromOrigin;
|
|
165
|
+
if (fromOrigin) {
|
|
166
|
+
this.log(styles.muted('Fetching from origin/main...'));
|
|
167
|
+
if (!fetchOrigin('main')) {
|
|
168
|
+
if (!flags.force) {
|
|
169
|
+
this.warn('Could not fetch from origin/main, using local state');
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
// Check if branch exists
|
|
174
|
+
if (branchExists(branchName)) {
|
|
175
|
+
if (flags.force) {
|
|
176
|
+
// In force mode, just switch to the existing branch
|
|
177
|
+
this.log(styles.muted(`Branch "${branchName}" exists, switching to it...`));
|
|
178
|
+
try {
|
|
179
|
+
checkoutBranch(branchName);
|
|
180
|
+
this.log(styles.success(`✅ Switched to branch: ${branchName}`));
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
catch (error) {
|
|
184
|
+
this.error(`Failed to switch to branch: ${error instanceof Error ? error.message : error}`);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
this.error(`Branch "${branchName}" already exists.`);
|
|
188
|
+
}
|
|
189
|
+
// Create branch
|
|
190
|
+
this.log('');
|
|
191
|
+
this.log(styles.success(`✅ Creating branch: ${branchName}`));
|
|
192
|
+
try {
|
|
193
|
+
const customStartPoint = this._customStartPoint;
|
|
194
|
+
const startPoint = customStartPoint || (fromOrigin ? 'origin/main' : undefined);
|
|
195
|
+
createBranch(branchName, undefined, !flags['no-switch'], startPoint);
|
|
196
|
+
if (flags['no-switch']) {
|
|
197
|
+
this.log(styles.muted(` Created branch (not switched)`));
|
|
198
|
+
}
|
|
199
|
+
else {
|
|
200
|
+
this.log(styles.muted(` Switched to new branch '${branchName}'`));
|
|
201
|
+
}
|
|
202
|
+
// Initial commit to seed PR title
|
|
203
|
+
const autoCommit = this._autoCommit;
|
|
204
|
+
let createCommit = flags['empty-commit'] || autoCommit;
|
|
205
|
+
if (!createCommit && !args.name) {
|
|
206
|
+
// Only prompt in interactive mode (non-quick)
|
|
207
|
+
const { wantCommit } = await inquirer.prompt([
|
|
208
|
+
{
|
|
209
|
+
type: 'list',
|
|
210
|
+
name: 'wantCommit',
|
|
211
|
+
message: 'Create initial commit to seed PR title?',
|
|
212
|
+
choices: [
|
|
213
|
+
{ name: 'Yes', value: true },
|
|
214
|
+
{ name: 'No', value: false },
|
|
215
|
+
],
|
|
216
|
+
default: true,
|
|
217
|
+
},
|
|
218
|
+
]);
|
|
219
|
+
createCommit = wantCommit;
|
|
220
|
+
}
|
|
221
|
+
if (createCommit) {
|
|
222
|
+
// Build default commit message: use ticket info if available, otherwise branch name
|
|
223
|
+
const selectedTicket = this._selectedTicket;
|
|
224
|
+
const defaultCommitMessage = selectedTicket
|
|
225
|
+
? `${selectedTicket.id}: ${selectedTicket.title}`
|
|
226
|
+
: branchName;
|
|
227
|
+
// In autoCommit mode, skip the prompt
|
|
228
|
+
let commitMessage = defaultCommitMessage;
|
|
229
|
+
if (!autoCommit) {
|
|
230
|
+
const result = await inquirer.prompt([
|
|
231
|
+
{
|
|
232
|
+
type: 'input',
|
|
233
|
+
name: 'commitMessage',
|
|
234
|
+
message: 'Enter commit message:',
|
|
235
|
+
default: defaultCommitMessage,
|
|
236
|
+
},
|
|
237
|
+
]);
|
|
238
|
+
commitMessage = result.commitMessage;
|
|
239
|
+
}
|
|
240
|
+
createEmptyCommit(commitMessage);
|
|
241
|
+
this.log(styles.success(`✅ Created initial commit: ${commitMessage}`));
|
|
242
|
+
}
|
|
243
|
+
this.log('');
|
|
244
|
+
}
|
|
245
|
+
catch (error) {
|
|
246
|
+
this.error(`Failed to create branch: ${error instanceof Error ? error.message : error}`);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Get the default owner name.
|
|
251
|
+
* Priority: workspace config > GitHub username > git user.name
|
|
252
|
+
*/
|
|
253
|
+
getDefaultOwnerName() {
|
|
254
|
+
// Try to get from workspace database
|
|
255
|
+
let currentDir = process.cwd();
|
|
256
|
+
while (currentDir !== '/') {
|
|
257
|
+
const dbPath = path.join(currentDir, '.proletariat', 'workspace.db');
|
|
258
|
+
if (fs.existsSync(dbPath)) {
|
|
259
|
+
try {
|
|
260
|
+
const db = new Database(dbPath);
|
|
261
|
+
const coderName = getCoderName(db);
|
|
262
|
+
db.close();
|
|
263
|
+
if (coderName) {
|
|
264
|
+
return coderName;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
catch {
|
|
268
|
+
// Ignore errors and try other methods
|
|
269
|
+
}
|
|
270
|
+
break;
|
|
271
|
+
}
|
|
272
|
+
currentDir = path.dirname(currentDir);
|
|
273
|
+
}
|
|
274
|
+
// Try GitHub username (most reliable)
|
|
275
|
+
const ghUsername = getGitHubUsername();
|
|
276
|
+
if (ghUsername) {
|
|
277
|
+
return ghUsername;
|
|
278
|
+
}
|
|
279
|
+
// Fall back to git config user.name (normalized)
|
|
280
|
+
const gitUserName = getGitUserName();
|
|
281
|
+
if (gitUserName) {
|
|
282
|
+
return gitUserName.toLowerCase().replace(/[^a-z0-9]/g, '-').replace(/-+/g, '-').replace(/^-|-$/g, '');
|
|
283
|
+
}
|
|
284
|
+
return undefined;
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Create branch from ticket ID with defaults (non-interactive).
|
|
288
|
+
*/
|
|
289
|
+
async createFromTicketId(ticketId, ownerOverride, projectId) {
|
|
290
|
+
try {
|
|
291
|
+
// Search for ticket across all projects
|
|
292
|
+
const projects = await this.storage.listProjects();
|
|
293
|
+
let foundTicket = null;
|
|
294
|
+
for (const project of projects) {
|
|
295
|
+
const tickets = await this.storage.listTickets(projectId);
|
|
296
|
+
const match = tickets.find(t => t.id === ticketId);
|
|
297
|
+
if (match) {
|
|
298
|
+
foundTicket = match;
|
|
299
|
+
break;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
if (!foundTicket) {
|
|
303
|
+
return null;
|
|
304
|
+
}
|
|
305
|
+
// Auto-generate branch name with defaults
|
|
306
|
+
const type = getBranchType(foundTicket.category);
|
|
307
|
+
const slug = toKebabCase(foundTicket.title).substring(0, 20).replace(/-+$/, '');
|
|
308
|
+
const ownerName = ownerOverride || this.getDefaultOwnerName();
|
|
309
|
+
const agentName = detectAgentName();
|
|
310
|
+
const branchName = buildBranchName(type, slug, {
|
|
311
|
+
ticketId: foundTicket.id,
|
|
312
|
+
owner: ownerName,
|
|
313
|
+
agent: agentName || undefined,
|
|
314
|
+
});
|
|
315
|
+
this.log(styles.muted(`Ticket: ${foundTicket.title}`));
|
|
316
|
+
return { branchName, ticket: { id: foundTicket.id, title: foundTicket.title } };
|
|
317
|
+
}
|
|
318
|
+
catch {
|
|
319
|
+
return null;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
async runWizard(jsonMode = false, flags = {}) {
|
|
323
|
+
// Get default owner name from config or GitHub
|
|
324
|
+
const defaultOwnerName = this.getDefaultOwnerName();
|
|
325
|
+
// Load tickets from PMO (across all projects)
|
|
326
|
+
let tickets = [];
|
|
327
|
+
try {
|
|
328
|
+
// Get all projects and their tickets
|
|
329
|
+
const projects = await this.storage.listProjects();
|
|
330
|
+
const projectId = flags.project;
|
|
331
|
+
for (const project of projects) {
|
|
332
|
+
const projectTickets = await this.storage.listTickets(projectId);
|
|
333
|
+
// Filter to actionable tickets (todo, in-progress, backlog)
|
|
334
|
+
const actionable = projectTickets.filter(t => !t.status || ['todo', 'in-progress', 'backlog', 'in_progress'].includes(t.status.toLowerCase()));
|
|
335
|
+
tickets.push(...actionable.map(t => ({ ...t, projectName: project.name })));
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
catch {
|
|
339
|
+
// PMO context error - just skip ticket selection
|
|
340
|
+
}
|
|
341
|
+
// First choice: from ticket or custom
|
|
342
|
+
const hasTickets = tickets.length > 0;
|
|
343
|
+
// Build choices once, use for both JSON and interactive modes
|
|
344
|
+
const modeChoices = [
|
|
345
|
+
...(hasTickets ? [
|
|
346
|
+
{ name: 'From ticket - quick', value: 'ticket-quick' },
|
|
347
|
+
{ name: 'From ticket - customize', value: 'ticket' },
|
|
348
|
+
] : []),
|
|
349
|
+
{ name: 'Custom branch name', value: 'custom' },
|
|
350
|
+
];
|
|
351
|
+
const modeMessage = 'Create branch:';
|
|
352
|
+
// In JSON mode, output mode selection prompt
|
|
353
|
+
if (jsonMode) {
|
|
354
|
+
outputPromptAsJson(buildPromptConfig('list', 'mode', modeMessage, modeChoices), createMetadata('branch create', flags));
|
|
355
|
+
return null;
|
|
356
|
+
}
|
|
357
|
+
this.log('');
|
|
358
|
+
this.log(styles.header('🌿 Create New Branch'));
|
|
359
|
+
this.log('');
|
|
360
|
+
const { mode } = await inquirer.prompt([
|
|
361
|
+
{
|
|
362
|
+
type: 'list',
|
|
363
|
+
name: 'mode',
|
|
364
|
+
message: modeMessage,
|
|
365
|
+
choices: modeChoices.map((c, i) => ({
|
|
366
|
+
name: hasTickets && i < 2 ? `📋 ${c.name}` : (c.value === 'custom' ? `✏️ ${c.name}` : c.name),
|
|
367
|
+
value: c.value,
|
|
368
|
+
})),
|
|
369
|
+
},
|
|
370
|
+
]);
|
|
371
|
+
if (mode === 'ticket-quick' && hasTickets) {
|
|
372
|
+
return this.runTicketQuickWizard(tickets, defaultOwnerName);
|
|
373
|
+
}
|
|
374
|
+
if (mode === 'ticket' && hasTickets) {
|
|
375
|
+
return this.runTicketWizard(tickets, defaultOwnerName);
|
|
376
|
+
}
|
|
377
|
+
return this.runCustomWizard(defaultOwnerName);
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* Quick wizard - just select ticket, auto-generate with defaults.
|
|
381
|
+
*/
|
|
382
|
+
async runTicketQuickWizard(tickets, defaultOwnerName) {
|
|
383
|
+
// Select ticket (show project name if multiple projects)
|
|
384
|
+
const hasMultipleProjects = new Set(tickets.map(t => t.projectName)).size > 1;
|
|
385
|
+
const ticketChoices = tickets.map(t => ({
|
|
386
|
+
name: hasMultipleProjects
|
|
387
|
+
? `${t.id} - ${t.title.substring(0, 40)}${t.title.length > 40 ? '...' : ''} ${styles.muted(`[${t.projectName}]`)}`
|
|
388
|
+
: `${t.id} - ${t.title.substring(0, 50)}${t.title.length > 50 ? '...' : ''} ${styles.muted(`[${t.status || 'todo'}]`)}`,
|
|
389
|
+
value: t,
|
|
390
|
+
}));
|
|
391
|
+
const { ticket } = await inquirer.prompt([
|
|
392
|
+
{
|
|
393
|
+
type: 'list',
|
|
394
|
+
name: 'ticket',
|
|
395
|
+
message: 'Select ticket:',
|
|
396
|
+
choices: ticketChoices,
|
|
397
|
+
pageSize: 15,
|
|
398
|
+
},
|
|
399
|
+
]);
|
|
400
|
+
// Auto-generate branch name with defaults
|
|
401
|
+
const type = getBranchType(ticket.category);
|
|
402
|
+
const slug = toKebabCase(ticket.title).substring(0, 20).replace(/-+$/, '');
|
|
403
|
+
const agentName = detectAgentName();
|
|
404
|
+
const branchName = buildBranchName(type, slug, {
|
|
405
|
+
ticketId: ticket.id,
|
|
406
|
+
owner: defaultOwnerName,
|
|
407
|
+
agent: agentName || undefined,
|
|
408
|
+
});
|
|
409
|
+
// Quick mode: always branch from origin/main
|
|
410
|
+
return { branchName, ticket: { id: ticket.id, title: ticket.title }, autoCommit: true, fromOrigin: true };
|
|
411
|
+
}
|
|
412
|
+
/**
|
|
413
|
+
* Wizard flow for creating branch from a ticket.
|
|
414
|
+
*/
|
|
415
|
+
async runTicketWizard(tickets, defaultOwnerName) {
|
|
416
|
+
// Select ticket (show project name if multiple projects)
|
|
417
|
+
const hasMultipleProjects = new Set(tickets.map(t => t.projectName)).size > 1;
|
|
418
|
+
const ticketChoices = tickets.map(t => ({
|
|
419
|
+
name: hasMultipleProjects
|
|
420
|
+
? `${t.id} - ${t.title.substring(0, 40)}${t.title.length > 40 ? '...' : ''} ${styles.muted(`[${t.projectName}]`)}`
|
|
421
|
+
: `${t.id} - ${t.title.substring(0, 50)}${t.title.length > 50 ? '...' : ''} ${styles.muted(`[${t.status || 'todo'}]`)}`,
|
|
422
|
+
value: t,
|
|
423
|
+
}));
|
|
424
|
+
const { ticket } = await inquirer.prompt([
|
|
425
|
+
{
|
|
426
|
+
type: 'list',
|
|
427
|
+
name: 'ticket',
|
|
428
|
+
message: 'Select ticket:',
|
|
429
|
+
choices: ticketChoices,
|
|
430
|
+
pageSize: 15,
|
|
431
|
+
},
|
|
432
|
+
]);
|
|
433
|
+
// Get owner (defaults to GitHub username)
|
|
434
|
+
const { owner } = await inquirer.prompt([
|
|
435
|
+
{
|
|
436
|
+
type: 'input',
|
|
437
|
+
name: 'owner',
|
|
438
|
+
message: defaultOwnerName
|
|
439
|
+
? `Owner (default: ${defaultOwnerName}):`
|
|
440
|
+
: 'Owner (optional):',
|
|
441
|
+
default: defaultOwnerName,
|
|
442
|
+
validate: (input) => {
|
|
443
|
+
if (input && !isKebabCase(input)) {
|
|
444
|
+
return 'Owner must be kebab-case (lowercase, hyphens only)';
|
|
445
|
+
}
|
|
446
|
+
return true;
|
|
447
|
+
},
|
|
448
|
+
},
|
|
449
|
+
]);
|
|
450
|
+
// Auto-generate branch name from ticket
|
|
451
|
+
const type = getBranchType(ticket.category);
|
|
452
|
+
const slug = toKebabCase(ticket.title).substring(0, 20).replace(/-+$/, '');
|
|
453
|
+
const agentName = detectAgentName();
|
|
454
|
+
const branchName = buildBranchName(type, slug, {
|
|
455
|
+
ticketId: ticket.id,
|
|
456
|
+
owner: owner || undefined,
|
|
457
|
+
agent: agentName || undefined,
|
|
458
|
+
});
|
|
459
|
+
this.log('');
|
|
460
|
+
this.log(styles.muted(` Generated: ${branchName}`));
|
|
461
|
+
// Confirm or allow edit
|
|
462
|
+
const { confirmed } = await inquirer.prompt([
|
|
463
|
+
{
|
|
464
|
+
type: 'list',
|
|
465
|
+
name: 'confirmed',
|
|
466
|
+
message: 'Use this branch name?',
|
|
467
|
+
choices: [
|
|
468
|
+
{ name: 'Yes', value: true },
|
|
469
|
+
{ name: 'No, let me edit', value: false },
|
|
470
|
+
],
|
|
471
|
+
},
|
|
472
|
+
]);
|
|
473
|
+
// Ask where to branch from
|
|
474
|
+
const { branchFrom } = await inquirer.prompt([
|
|
475
|
+
{
|
|
476
|
+
type: 'list',
|
|
477
|
+
name: 'branchFrom',
|
|
478
|
+
message: 'Branch from:',
|
|
479
|
+
choices: [
|
|
480
|
+
{ name: 'origin/main (recommended)', value: 'origin-main' },
|
|
481
|
+
{ name: 'Current branch', value: 'current' },
|
|
482
|
+
{ name: 'Other branch...', value: 'other' },
|
|
483
|
+
],
|
|
484
|
+
default: 0,
|
|
485
|
+
},
|
|
486
|
+
]);
|
|
487
|
+
let fromOrigin = branchFrom === 'origin-main';
|
|
488
|
+
let customStartPoint;
|
|
489
|
+
if (branchFrom === 'other') {
|
|
490
|
+
customStartPoint = await this.promptForBranch();
|
|
491
|
+
}
|
|
492
|
+
if (!confirmed) {
|
|
493
|
+
// Allow manual edit
|
|
494
|
+
const { customName } = await inquirer.prompt([
|
|
495
|
+
{
|
|
496
|
+
type: 'input',
|
|
497
|
+
name: 'customName',
|
|
498
|
+
message: 'Enter branch name:',
|
|
499
|
+
default: branchName,
|
|
500
|
+
},
|
|
501
|
+
]);
|
|
502
|
+
// Still return ticket info for commit message even with custom branch name
|
|
503
|
+
return { branchName: customName, ticket: { id: ticket.id, title: ticket.title }, fromOrigin, customStartPoint };
|
|
504
|
+
}
|
|
505
|
+
return { branchName, ticket: { id: ticket.id, title: ticket.title }, fromOrigin, customStartPoint };
|
|
506
|
+
}
|
|
507
|
+
/**
|
|
508
|
+
* Wizard flow for creating a custom branch (no ticket).
|
|
509
|
+
*/
|
|
510
|
+
async runCustomWizard(defaultOwnerName) {
|
|
511
|
+
// Select type
|
|
512
|
+
const typeChoices = [
|
|
513
|
+
new inquirer.Separator('── Development ──'),
|
|
514
|
+
...DEVELOPMENT_TYPES.map((t) => ({
|
|
515
|
+
name: `${t.padEnd(6)} - ${BRANCH_TYPES[t]}`,
|
|
516
|
+
value: t,
|
|
517
|
+
})),
|
|
518
|
+
new inquirer.Separator('── Business ──'),
|
|
519
|
+
...BUSINESS_TYPES.map((t) => ({
|
|
520
|
+
name: `${t.padEnd(6)} - ${BRANCH_TYPES[t]}`,
|
|
521
|
+
value: t,
|
|
522
|
+
})),
|
|
523
|
+
];
|
|
524
|
+
const { type } = await inquirer.prompt([
|
|
525
|
+
{
|
|
526
|
+
type: 'list',
|
|
527
|
+
name: 'type',
|
|
528
|
+
message: 'Select branch type:',
|
|
529
|
+
choices: typeChoices,
|
|
530
|
+
},
|
|
531
|
+
]);
|
|
532
|
+
// Enter owner (defaults to GitHub username)
|
|
533
|
+
const { owner } = await inquirer.prompt([
|
|
534
|
+
{
|
|
535
|
+
type: 'input',
|
|
536
|
+
name: 'owner',
|
|
537
|
+
message: defaultOwnerName
|
|
538
|
+
? `Owner (default: ${defaultOwnerName}):`
|
|
539
|
+
: 'Owner (optional):',
|
|
540
|
+
default: defaultOwnerName,
|
|
541
|
+
validate: (input) => {
|
|
542
|
+
if (input && !isKebabCase(input)) {
|
|
543
|
+
return 'Owner must be kebab-case (lowercase, hyphens only)';
|
|
544
|
+
}
|
|
545
|
+
return true;
|
|
546
|
+
},
|
|
547
|
+
},
|
|
548
|
+
]);
|
|
549
|
+
// Enter description
|
|
550
|
+
const { description } = await inquirer.prompt([
|
|
551
|
+
{
|
|
552
|
+
type: 'input',
|
|
553
|
+
name: 'description',
|
|
554
|
+
message: 'Description (kebab-case):',
|
|
555
|
+
validate: (input) => {
|
|
556
|
+
if (!input.trim()) {
|
|
557
|
+
return 'Description is required';
|
|
558
|
+
}
|
|
559
|
+
// Auto-convert to kebab case for validation preview
|
|
560
|
+
const kebab = toKebabCase(input);
|
|
561
|
+
if (kebab !== input && input.includes(' ')) {
|
|
562
|
+
return `Will be converted to: ${kebab}. Use that? (press enter) or type kebab-case directly`;
|
|
563
|
+
}
|
|
564
|
+
if (!isKebabCase(input)) {
|
|
565
|
+
return 'Description must be kebab-case (lowercase, hyphens only)';
|
|
566
|
+
}
|
|
567
|
+
return true;
|
|
568
|
+
},
|
|
569
|
+
filter: (input) => toKebabCase(input),
|
|
570
|
+
},
|
|
571
|
+
]);
|
|
572
|
+
const branchName = buildBranchName(type, description, {
|
|
573
|
+
owner: owner || undefined,
|
|
574
|
+
});
|
|
575
|
+
// Ask where to branch from
|
|
576
|
+
const { branchFrom } = await inquirer.prompt([
|
|
577
|
+
{
|
|
578
|
+
type: 'list',
|
|
579
|
+
name: 'branchFrom',
|
|
580
|
+
message: 'Branch from:',
|
|
581
|
+
choices: [
|
|
582
|
+
{ name: 'origin/main (recommended)', value: 'origin-main' },
|
|
583
|
+
{ name: 'Current branch', value: 'current' },
|
|
584
|
+
{ name: 'Other branch...', value: 'other' },
|
|
585
|
+
],
|
|
586
|
+
default: 0,
|
|
587
|
+
},
|
|
588
|
+
]);
|
|
589
|
+
let fromOrigin = branchFrom === 'origin-main';
|
|
590
|
+
let customStartPoint;
|
|
591
|
+
if (branchFrom === 'other') {
|
|
592
|
+
customStartPoint = await this.promptForBranch();
|
|
593
|
+
if (!customStartPoint) {
|
|
594
|
+
return null; // User cancelled
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
// No ticket info for custom branches
|
|
598
|
+
return { branchName, fromOrigin, customStartPoint };
|
|
599
|
+
}
|
|
600
|
+
/**
|
|
601
|
+
* Prompt user to select a branch from local or remote branches.
|
|
602
|
+
*/
|
|
603
|
+
async promptForBranch() {
|
|
604
|
+
// Get all branches (local and remote)
|
|
605
|
+
const branches = listBranches(undefined, true)
|
|
606
|
+
.map((b) => b.name)
|
|
607
|
+
.filter((name) => !name.startsWith('HEAD'))
|
|
608
|
+
.sort();
|
|
609
|
+
if (branches.length === 0) {
|
|
610
|
+
this.warn('No branches found');
|
|
611
|
+
return undefined;
|
|
612
|
+
}
|
|
613
|
+
const { selectedBranch } = await inquirer.prompt([
|
|
614
|
+
{
|
|
615
|
+
type: 'list',
|
|
616
|
+
name: 'selectedBranch',
|
|
617
|
+
message: 'Select branch:',
|
|
618
|
+
choices: branches,
|
|
619
|
+
pageSize: 15,
|
|
620
|
+
},
|
|
621
|
+
]);
|
|
622
|
+
return selectedBranch;
|
|
623
|
+
}
|
|
624
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { PMOCommand } from '../../lib/pmo/index.js';
|
|
2
|
+
export default class Branch extends PMOCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static flags: {
|
|
6
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
7
|
+
project: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
8
|
+
};
|
|
9
|
+
protected getPMOOptions(): {
|
|
10
|
+
promptIfMultiple: boolean;
|
|
11
|
+
};
|
|
12
|
+
execute(): Promise<void>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { Flags } from '@oclif/core';
|
|
2
|
+
import { PMOCommand, pmoBaseFlags } from '../../lib/pmo/index.js';
|
|
3
|
+
import { shouldOutputJson, } from '../../lib/prompt-json.js';
|
|
4
|
+
export default class Branch extends PMOCommand {
|
|
5
|
+
static description = 'Interactive menu for branch operations';
|
|
6
|
+
static examples = ['<%= config.bin %> <%= command.id %>'];
|
|
7
|
+
static flags = {
|
|
8
|
+
...pmoBaseFlags,
|
|
9
|
+
json: Flags.boolean({
|
|
10
|
+
description: 'Output prompt configuration as JSON (for AI agents/scripts)',
|
|
11
|
+
default: false,
|
|
12
|
+
}),
|
|
13
|
+
};
|
|
14
|
+
getPMOOptions() {
|
|
15
|
+
return { promptIfMultiple: false };
|
|
16
|
+
}
|
|
17
|
+
async execute() {
|
|
18
|
+
const { flags } = await this.parse(Branch);
|
|
19
|
+
// Check if JSON output mode is active
|
|
20
|
+
const jsonMode = shouldOutputJson(flags);
|
|
21
|
+
// Define choices once, use for both JSON and interactive modes
|
|
22
|
+
// Each choice includes the full command for AI agents to execute
|
|
23
|
+
const menuChoices = [
|
|
24
|
+
{ id: 'create', name: 'Create new branch', command: 'prlt branch create --json' },
|
|
25
|
+
{ id: 'list', name: 'List branches', command: 'prlt branch list --format json' },
|
|
26
|
+
{ id: 'validate', name: 'Validate branch name', command: 'prlt branch validate' },
|
|
27
|
+
{ id: 'cancel', name: 'Cancel', command: '' },
|
|
28
|
+
];
|
|
29
|
+
const message = 'What would you like to do?';
|
|
30
|
+
const action = await this.selectFromList({
|
|
31
|
+
message,
|
|
32
|
+
items: menuChoices,
|
|
33
|
+
getName: (c) => c.name,
|
|
34
|
+
getValue: (c) => c.id,
|
|
35
|
+
getCommand: (c) => c.command,
|
|
36
|
+
jsonMode: jsonMode ? { flags, commandName: 'branch' } : null,
|
|
37
|
+
});
|
|
38
|
+
if (action === 'cancel' || !action) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
const commands = {
|
|
42
|
+
create: 'branch:create',
|
|
43
|
+
list: 'branch:list',
|
|
44
|
+
validate: 'branch:validate',
|
|
45
|
+
};
|
|
46
|
+
if (commands[action]) {
|
|
47
|
+
await this.config.runCommand(commands[action], []);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|