@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,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PMO Interface Types
|
|
3
|
+
*
|
|
4
|
+
* Canonical interface for the Project Management Orchestration system.
|
|
5
|
+
* All storage backends must implement the PMOStorage interface.
|
|
6
|
+
*
|
|
7
|
+
* Hierarchy:
|
|
8
|
+
* - Initiative (optional) - OKR-level grouping
|
|
9
|
+
* - Project - Discrete effort with its own board + specs
|
|
10
|
+
* - Epic (optional) - Large body of work within a project
|
|
11
|
+
* - Ticket - Individual work item
|
|
12
|
+
* - Subtask - Smallest actionable piece
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Valid priority values as a const array for validation and CLI options.
|
|
16
|
+
*/
|
|
17
|
+
export const PRIORITIES = ['P0', 'P1', 'P2', 'P3'];
|
|
18
|
+
/**
|
|
19
|
+
* Priority display names for UI presentation.
|
|
20
|
+
*/
|
|
21
|
+
export const PRIORITY_LABELS = {
|
|
22
|
+
P0: 'P0 - Critical',
|
|
23
|
+
P1: 'P1 - High',
|
|
24
|
+
P2: 'P2 - Medium',
|
|
25
|
+
P3: 'P3 - Low',
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Mapping from legacy priority values to new P0-P3 format.
|
|
29
|
+
*/
|
|
30
|
+
export const LEGACY_PRIORITY_MAP = {
|
|
31
|
+
URGENT: 'P0',
|
|
32
|
+
HIGH: 'P1',
|
|
33
|
+
MEDIUM: 'P2',
|
|
34
|
+
LOW: 'P3',
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Ticket categories for classification.
|
|
38
|
+
*/
|
|
39
|
+
export const TICKET_CATEGORIES = [
|
|
40
|
+
'feature',
|
|
41
|
+
'bug',
|
|
42
|
+
'refactor',
|
|
43
|
+
'docs',
|
|
44
|
+
'test',
|
|
45
|
+
'chore',
|
|
46
|
+
'performance',
|
|
47
|
+
'ci',
|
|
48
|
+
'build',
|
|
49
|
+
'security',
|
|
50
|
+
'database',
|
|
51
|
+
'release',
|
|
52
|
+
];
|
|
53
|
+
/**
|
|
54
|
+
* Check if a string is a valid Priority value.
|
|
55
|
+
*/
|
|
56
|
+
export function isValidPriority(value) {
|
|
57
|
+
if (!value)
|
|
58
|
+
return false;
|
|
59
|
+
return PRIORITIES.includes(value);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Check if a string is a legacy priority value.
|
|
63
|
+
*/
|
|
64
|
+
export function isLegacyPriority(value) {
|
|
65
|
+
if (!value)
|
|
66
|
+
return false;
|
|
67
|
+
return value in LEGACY_PRIORITY_MAP;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Normalize a priority value to the new P0-P3 format.
|
|
71
|
+
* Converts legacy values (URGENT/HIGH/MEDIUM/LOW) to P0-P3.
|
|
72
|
+
* Returns undefined for invalid values.
|
|
73
|
+
*/
|
|
74
|
+
export function normalizePriority(value) {
|
|
75
|
+
if (!value)
|
|
76
|
+
return undefined;
|
|
77
|
+
// Already in new format
|
|
78
|
+
if (isValidPriority(value)) {
|
|
79
|
+
return value;
|
|
80
|
+
}
|
|
81
|
+
// Convert from legacy format
|
|
82
|
+
if (isLegacyPriority(value)) {
|
|
83
|
+
return LEGACY_PRIORITY_MAP[value];
|
|
84
|
+
}
|
|
85
|
+
// Unknown value
|
|
86
|
+
return undefined;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* State category order for sorting columns/statuses
|
|
90
|
+
*/
|
|
91
|
+
export const STATE_CATEGORY_ORDER = [
|
|
92
|
+
'triage',
|
|
93
|
+
'backlog',
|
|
94
|
+
'unstarted',
|
|
95
|
+
'started',
|
|
96
|
+
'completed',
|
|
97
|
+
'canceled',
|
|
98
|
+
];
|
|
99
|
+
export class PMOError extends Error {
|
|
100
|
+
code;
|
|
101
|
+
ticketId;
|
|
102
|
+
constructor(code, message, ticketId) {
|
|
103
|
+
super(message);
|
|
104
|
+
this.code = code;
|
|
105
|
+
this.ticketId = ticketId;
|
|
106
|
+
this.name = 'PMOError';
|
|
107
|
+
}
|
|
108
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PMO Utility Functions
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Convert a string to a URL-safe slug
|
|
6
|
+
*/
|
|
7
|
+
export declare function slugify(text: string): string;
|
|
8
|
+
/**
|
|
9
|
+
* Format a date as ISO string (date only)
|
|
10
|
+
*/
|
|
11
|
+
export declare function formatDate(date: Date): string;
|
|
12
|
+
/**
|
|
13
|
+
* Format a date as ISO timestamp
|
|
14
|
+
*/
|
|
15
|
+
export declare function formatTimestamp(date: Date): string;
|
|
16
|
+
/**
|
|
17
|
+
* Parse an ISO date string
|
|
18
|
+
*/
|
|
19
|
+
export declare function parseDate(str: string): Date;
|
|
20
|
+
/**
|
|
21
|
+
* Entity type prefixes for ID generation
|
|
22
|
+
*/
|
|
23
|
+
export declare const ENTITY_PREFIXES: {
|
|
24
|
+
readonly ticket: "TKT";
|
|
25
|
+
readonly epic: "EPIC";
|
|
26
|
+
readonly spec: "SPEC";
|
|
27
|
+
readonly project: "PROJ";
|
|
28
|
+
};
|
|
29
|
+
export type EntityType = keyof typeof ENTITY_PREFIXES;
|
|
30
|
+
/**
|
|
31
|
+
* Database interface for ID generation (compatible with better-sqlite3)
|
|
32
|
+
*/
|
|
33
|
+
interface DatabaseLike {
|
|
34
|
+
prepare(sql: string): {
|
|
35
|
+
get(...params: unknown[]): unknown;
|
|
36
|
+
run(...params: unknown[]): unknown;
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Generate a sequential ID for an entity.
|
|
41
|
+
*
|
|
42
|
+
* Format: TKT-001, EPIC-001, SPEC-001, PROJ-001
|
|
43
|
+
*
|
|
44
|
+
* Uses pmo_settings table to track the next ID for each entity type.
|
|
45
|
+
* IDs are zero-padded to 3 digits (001-999), then expand (1000+).
|
|
46
|
+
*
|
|
47
|
+
* @param db - Database instance with prepare method
|
|
48
|
+
* @param entityType - Type of entity (ticket, epic, spec, project)
|
|
49
|
+
* @returns Generated ID like "TKT-001"
|
|
50
|
+
*/
|
|
51
|
+
export declare function generateEntityId(db: DatabaseLike, entityType: EntityType): string;
|
|
52
|
+
/**
|
|
53
|
+
* Parsed entity ID components
|
|
54
|
+
*/
|
|
55
|
+
export interface ParsedEntityId {
|
|
56
|
+
entityType: string;
|
|
57
|
+
number: number;
|
|
58
|
+
raw: string;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Parse an entity ID into its components.
|
|
62
|
+
*
|
|
63
|
+
* Format: TKT-001 → { entityType: 'TKT', number: 1 }
|
|
64
|
+
*
|
|
65
|
+
* @param id - Entity ID to parse
|
|
66
|
+
* @returns Parsed components, or null if invalid format
|
|
67
|
+
*/
|
|
68
|
+
export declare function parseEntityId(id: string): ParsedEntityId | null;
|
|
69
|
+
/**
|
|
70
|
+
* Deep clone an object
|
|
71
|
+
*/
|
|
72
|
+
export declare function deepClone<T>(obj: T): T;
|
|
73
|
+
/**
|
|
74
|
+
* Default column names for work commands (Linear-style workflow)
|
|
75
|
+
*
|
|
76
|
+
* Linear-style: Backlog → Planned → In Progress → Done
|
|
77
|
+
* - planned: Move tickets here when scheduled/assigned
|
|
78
|
+
* - in_progress: Move tickets here when work starts
|
|
79
|
+
* - done: Move tickets here when work is complete (includes review/merged)
|
|
80
|
+
*/
|
|
81
|
+
export declare const DEFAULT_WORK_COLUMNS: {
|
|
82
|
+
readonly planned: "Planned";
|
|
83
|
+
readonly in_progress: "In Progress";
|
|
84
|
+
readonly done: "Done";
|
|
85
|
+
};
|
|
86
|
+
export type WorkColumnType = keyof typeof DEFAULT_WORK_COLUMNS;
|
|
87
|
+
/**
|
|
88
|
+
* Get a work column setting from pmo_settings with fallback to default.
|
|
89
|
+
* Column matching is case-insensitive.
|
|
90
|
+
*
|
|
91
|
+
* Settings keys:
|
|
92
|
+
* - column_in_progress: Column to move tickets to when work starts
|
|
93
|
+
* - column_review: Column to move tickets to when work is ready for review
|
|
94
|
+
* - column_done: Column to move tickets to when work is complete
|
|
95
|
+
*
|
|
96
|
+
* @param db - Database instance
|
|
97
|
+
* @param columnType - Type of column (in_progress, review, done)
|
|
98
|
+
* @returns The configured column name, or the default if not set
|
|
99
|
+
*/
|
|
100
|
+
export declare function getWorkColumnSetting(db: DatabaseLike, columnType: WorkColumnType): string;
|
|
101
|
+
/**
|
|
102
|
+
* Set a work column setting in pmo_settings.
|
|
103
|
+
*
|
|
104
|
+
* @param db - Database instance
|
|
105
|
+
* @param columnType - Type of column (in_progress, review, done)
|
|
106
|
+
* @param columnName - Name of the column to use
|
|
107
|
+
*/
|
|
108
|
+
export declare function setWorkColumnSetting(db: DatabaseLike, columnType: WorkColumnType, columnName: string): void;
|
|
109
|
+
/**
|
|
110
|
+
* Find a column by configured name (case-insensitive match).
|
|
111
|
+
* Returns the actual column name from the board if found, null otherwise.
|
|
112
|
+
*
|
|
113
|
+
* @param columnNames - Array of column names from the board
|
|
114
|
+
* @param targetColumn - The column name to find (from settings or default)
|
|
115
|
+
* @returns The matching column name, or null if not found
|
|
116
|
+
*/
|
|
117
|
+
export declare function findColumnByName(columnNames: string[], targetColumn: string): string | null;
|
|
118
|
+
/**
|
|
119
|
+
* Check if two arrays have the same elements (order-independent)
|
|
120
|
+
*/
|
|
121
|
+
export declare function arraysEqual<T>(a: T[], b: T[]): boolean;
|
|
122
|
+
export {};
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PMO Utility Functions
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Convert a string to a URL-safe slug
|
|
6
|
+
*/
|
|
7
|
+
export function slugify(text) {
|
|
8
|
+
return text
|
|
9
|
+
.toLowerCase()
|
|
10
|
+
.trim()
|
|
11
|
+
.replace(/[^\w\s-]/g, '') // Remove non-word chars (except spaces and hyphens)
|
|
12
|
+
.replace(/[\s_]+/g, '-') // Replace spaces and underscores with hyphens
|
|
13
|
+
.replace(/-+/g, '-') // Replace multiple hyphens with single hyphen
|
|
14
|
+
.replace(/^-+|-+$/g, '') // Remove leading/trailing hyphens
|
|
15
|
+
.substring(0, 100); // Limit length
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Format a date as ISO string (date only)
|
|
19
|
+
*/
|
|
20
|
+
export function formatDate(date) {
|
|
21
|
+
return date.toISOString().split('T')[0];
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Format a date as ISO timestamp
|
|
25
|
+
*/
|
|
26
|
+
export function formatTimestamp(date) {
|
|
27
|
+
return date.toISOString();
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Parse an ISO date string
|
|
31
|
+
*/
|
|
32
|
+
export function parseDate(str) {
|
|
33
|
+
return new Date(str);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Entity type prefixes for ID generation
|
|
37
|
+
*/
|
|
38
|
+
export const ENTITY_PREFIXES = {
|
|
39
|
+
ticket: 'TKT',
|
|
40
|
+
epic: 'EPIC',
|
|
41
|
+
spec: 'SPEC',
|
|
42
|
+
project: 'PROJ',
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Generate a sequential ID for an entity.
|
|
46
|
+
*
|
|
47
|
+
* Format: TKT-001, EPIC-001, SPEC-001, PROJ-001
|
|
48
|
+
*
|
|
49
|
+
* Uses pmo_settings table to track the next ID for each entity type.
|
|
50
|
+
* IDs are zero-padded to 3 digits (001-999), then expand (1000+).
|
|
51
|
+
*
|
|
52
|
+
* @param db - Database instance with prepare method
|
|
53
|
+
* @param entityType - Type of entity (ticket, epic, spec, project)
|
|
54
|
+
* @returns Generated ID like "TKT-001"
|
|
55
|
+
*/
|
|
56
|
+
export function generateEntityId(db, entityType) {
|
|
57
|
+
const typePrefix = ENTITY_PREFIXES[entityType];
|
|
58
|
+
const settingKey = `next_${entityType}_id`;
|
|
59
|
+
// Get current counter
|
|
60
|
+
const row = db.prepare(`SELECT value FROM pmo_settings WHERE key = ?`).get(settingKey);
|
|
61
|
+
const nextNum = row ? parseInt(row.value, 10) : 1;
|
|
62
|
+
// Update counter
|
|
63
|
+
db.prepare(`
|
|
64
|
+
INSERT INTO pmo_settings (key, value) VALUES (?, ?)
|
|
65
|
+
ON CONFLICT(key) DO UPDATE SET value = ?
|
|
66
|
+
`).run(settingKey, String(nextNum + 1), String(nextNum + 1));
|
|
67
|
+
// Format ID with zero-padding (3 digits minimum)
|
|
68
|
+
const numStr = nextNum.toString().padStart(3, '0');
|
|
69
|
+
return `${typePrefix}-${numStr}`;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Parse an entity ID into its components.
|
|
73
|
+
*
|
|
74
|
+
* Format: TKT-001 → { entityType: 'TKT', number: 1 }
|
|
75
|
+
*
|
|
76
|
+
* @param id - Entity ID to parse
|
|
77
|
+
* @returns Parsed components, or null if invalid format
|
|
78
|
+
*/
|
|
79
|
+
export function parseEntityId(id) {
|
|
80
|
+
if (!id)
|
|
81
|
+
return null;
|
|
82
|
+
const match = id.match(/^([A-Z]+)-(\d+)$/);
|
|
83
|
+
if (match) {
|
|
84
|
+
return {
|
|
85
|
+
entityType: match[1],
|
|
86
|
+
number: parseInt(match[2], 10),
|
|
87
|
+
raw: id,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Deep clone an object
|
|
94
|
+
*/
|
|
95
|
+
export function deepClone(obj) {
|
|
96
|
+
return JSON.parse(JSON.stringify(obj));
|
|
97
|
+
}
|
|
98
|
+
// =============================================================================
|
|
99
|
+
// Work Column Settings
|
|
100
|
+
// =============================================================================
|
|
101
|
+
/**
|
|
102
|
+
* Default column names for work commands (Linear-style workflow)
|
|
103
|
+
*
|
|
104
|
+
* Linear-style: Backlog → Planned → In Progress → Done
|
|
105
|
+
* - planned: Move tickets here when scheduled/assigned
|
|
106
|
+
* - in_progress: Move tickets here when work starts
|
|
107
|
+
* - done: Move tickets here when work is complete (includes review/merged)
|
|
108
|
+
*/
|
|
109
|
+
export const DEFAULT_WORK_COLUMNS = {
|
|
110
|
+
planned: 'Planned',
|
|
111
|
+
in_progress: 'In Progress',
|
|
112
|
+
done: 'Done',
|
|
113
|
+
};
|
|
114
|
+
/**
|
|
115
|
+
* Get a work column setting from pmo_settings with fallback to default.
|
|
116
|
+
* Column matching is case-insensitive.
|
|
117
|
+
*
|
|
118
|
+
* Settings keys:
|
|
119
|
+
* - column_in_progress: Column to move tickets to when work starts
|
|
120
|
+
* - column_review: Column to move tickets to when work is ready for review
|
|
121
|
+
* - column_done: Column to move tickets to when work is complete
|
|
122
|
+
*
|
|
123
|
+
* @param db - Database instance
|
|
124
|
+
* @param columnType - Type of column (in_progress, review, done)
|
|
125
|
+
* @returns The configured column name, or the default if not set
|
|
126
|
+
*/
|
|
127
|
+
export function getWorkColumnSetting(db, columnType) {
|
|
128
|
+
const settingKey = `column_${columnType}`;
|
|
129
|
+
const row = db.prepare(`SELECT value FROM pmo_settings WHERE key = ?`).get(settingKey);
|
|
130
|
+
return row?.value || DEFAULT_WORK_COLUMNS[columnType];
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Set a work column setting in pmo_settings.
|
|
134
|
+
*
|
|
135
|
+
* @param db - Database instance
|
|
136
|
+
* @param columnType - Type of column (in_progress, review, done)
|
|
137
|
+
* @param columnName - Name of the column to use
|
|
138
|
+
*/
|
|
139
|
+
export function setWorkColumnSetting(db, columnType, columnName) {
|
|
140
|
+
const settingKey = `column_${columnType}`;
|
|
141
|
+
db.prepare(`
|
|
142
|
+
INSERT INTO pmo_settings (key, value) VALUES (?, ?)
|
|
143
|
+
ON CONFLICT(key) DO UPDATE SET value = ?
|
|
144
|
+
`).run(settingKey, columnName, columnName);
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Find a column by configured name (case-insensitive match).
|
|
148
|
+
* Returns the actual column name from the board if found, null otherwise.
|
|
149
|
+
*
|
|
150
|
+
* @param columnNames - Array of column names from the board
|
|
151
|
+
* @param targetColumn - The column name to find (from settings or default)
|
|
152
|
+
* @returns The matching column name, or null if not found
|
|
153
|
+
*/
|
|
154
|
+
export function findColumnByName(columnNames, targetColumn) {
|
|
155
|
+
const targetLower = targetColumn.toLowerCase();
|
|
156
|
+
// First try exact match (case-insensitive)
|
|
157
|
+
const exactMatch = columnNames.find(col => col.toLowerCase() === targetLower);
|
|
158
|
+
if (exactMatch)
|
|
159
|
+
return exactMatch;
|
|
160
|
+
// Then try partial match (contains)
|
|
161
|
+
const partialMatch = columnNames.find(col => col.toLowerCase().includes(targetLower) ||
|
|
162
|
+
targetLower.includes(col.toLowerCase()));
|
|
163
|
+
return partialMatch || null;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Check if two arrays have the same elements (order-independent)
|
|
167
|
+
*/
|
|
168
|
+
export function arraysEqual(a, b) {
|
|
169
|
+
if (a.length !== b.length)
|
|
170
|
+
return false;
|
|
171
|
+
const sortedA = [...a].sort();
|
|
172
|
+
const sortedB = [...b].sort();
|
|
173
|
+
return sortedA.every((val, idx) => val === sortedB[idx]);
|
|
174
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PMO Board Watcher
|
|
3
|
+
*
|
|
4
|
+
* Watches board.md for changes and automatically syncs to SQLite database.
|
|
5
|
+
* Uses chokidar for efficient cross-platform file watching.
|
|
6
|
+
*
|
|
7
|
+
* Features:
|
|
8
|
+
* - Debounced sync (waits for file to stabilize before syncing)
|
|
9
|
+
* - Hybrid mtime + content detection (avoids unnecessary syncs)
|
|
10
|
+
* - Graceful shutdown handling
|
|
11
|
+
*/
|
|
12
|
+
export interface WatcherOptions {
|
|
13
|
+
/** Debounce delay in milliseconds (default: 500) */
|
|
14
|
+
debounceMs?: number;
|
|
15
|
+
/** Logger function for status messages */
|
|
16
|
+
logger?: (msg: string) => void;
|
|
17
|
+
/** Callback when sync occurs */
|
|
18
|
+
onSync?: (stats: SyncStats) => void;
|
|
19
|
+
/** Callback on error */
|
|
20
|
+
onError?: (error: Error) => void;
|
|
21
|
+
}
|
|
22
|
+
export interface SyncStats {
|
|
23
|
+
syncedAt: Date;
|
|
24
|
+
ticketCount: number;
|
|
25
|
+
durationMs: number;
|
|
26
|
+
}
|
|
27
|
+
export interface WatcherInstance {
|
|
28
|
+
/** Stop watching */
|
|
29
|
+
stop: () => Promise<void>;
|
|
30
|
+
/** Force a sync now */
|
|
31
|
+
syncNow: () => Promise<SyncStats>;
|
|
32
|
+
/** Check if watcher is running */
|
|
33
|
+
isRunning: () => boolean;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Start watching kanban.md for changes
|
|
37
|
+
*/
|
|
38
|
+
export declare function startWatcher(pmoPath: string, storageType: 'sqlite' | 'git', options?: WatcherOptions, projectId?: string): WatcherInstance;
|
|
39
|
+
/**
|
|
40
|
+
* Run watcher as a foreground process (for CLI command)
|
|
41
|
+
* Handles SIGINT/SIGTERM for graceful shutdown
|
|
42
|
+
*/
|
|
43
|
+
export declare function runWatcherForeground(pmoPath: string, storageType: 'sqlite' | 'git', options?: WatcherOptions): Promise<void>;
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PMO Board Watcher
|
|
3
|
+
*
|
|
4
|
+
* Watches board.md for changes and automatically syncs to SQLite database.
|
|
5
|
+
* Uses chokidar for efficient cross-platform file watching.
|
|
6
|
+
*
|
|
7
|
+
* Features:
|
|
8
|
+
* - Debounced sync (waits for file to stabilize before syncing)
|
|
9
|
+
* - Hybrid mtime + content detection (avoids unnecessary syncs)
|
|
10
|
+
* - Graceful shutdown handling
|
|
11
|
+
*/
|
|
12
|
+
import * as fs from 'node:fs';
|
|
13
|
+
import * as path from 'node:path';
|
|
14
|
+
import * as crypto from 'node:crypto';
|
|
15
|
+
import { watch } from 'chokidar';
|
|
16
|
+
import { SQLiteStorage } from './storage-sqlite.js';
|
|
17
|
+
import { parseBoard } from './markdown.js';
|
|
18
|
+
/**
|
|
19
|
+
* Compute SHA-256 hash of content
|
|
20
|
+
*/
|
|
21
|
+
function computeHash(content) {
|
|
22
|
+
return crypto.createHash('sha256').update(content).digest('hex');
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Get the workspace.db path from a PMO path
|
|
26
|
+
*/
|
|
27
|
+
function getWorkspaceDbPath(pmoPath) {
|
|
28
|
+
const workspacePath = path.dirname(pmoPath);
|
|
29
|
+
return path.join(workspacePath, '.proletariat', 'workspace.db');
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Start watching kanban.md for changes
|
|
33
|
+
*/
|
|
34
|
+
export function startWatcher(pmoPath, storageType, options = {}, projectId) {
|
|
35
|
+
const { debounceMs = 500, logger = () => { }, onSync, onError, } = options;
|
|
36
|
+
// Get board path - either from projectId or find first project
|
|
37
|
+
let boardPath;
|
|
38
|
+
if (projectId) {
|
|
39
|
+
boardPath = path.join(pmoPath, 'projects', projectId, 'kanban.md');
|
|
40
|
+
// Fall back to legacy board.md
|
|
41
|
+
if (!fs.existsSync(boardPath)) {
|
|
42
|
+
boardPath = path.join(pmoPath, 'projects', projectId, 'board.md');
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
// Legacy: look for board.md in pmo root
|
|
47
|
+
boardPath = path.join(pmoPath, 'board.md');
|
|
48
|
+
if (!fs.existsSync(boardPath)) {
|
|
49
|
+
// Try to find first project
|
|
50
|
+
const projectsDir = path.join(pmoPath, 'projects');
|
|
51
|
+
if (fs.existsSync(projectsDir)) {
|
|
52
|
+
const projects = fs.readdirSync(projectsDir).filter(f => fs.statSync(path.join(projectsDir, f)).isDirectory());
|
|
53
|
+
if (projects.length > 0) {
|
|
54
|
+
const firstProject = projects[0];
|
|
55
|
+
boardPath = path.join(projectsDir, firstProject, 'kanban.md');
|
|
56
|
+
if (!fs.existsSync(boardPath)) {
|
|
57
|
+
boardPath = path.join(projectsDir, firstProject, 'board.md');
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
// All storage types now use unified workspace.db
|
|
64
|
+
const dbPath = getWorkspaceDbPath(pmoPath);
|
|
65
|
+
// Validate paths exist
|
|
66
|
+
if (!fs.existsSync(boardPath)) {
|
|
67
|
+
throw new Error(`kanban.md not found at ${boardPath}`);
|
|
68
|
+
}
|
|
69
|
+
if (!fs.existsSync(dbPath)) {
|
|
70
|
+
throw new Error(`Database not found at ${dbPath}. Run 'prlt init' first.`);
|
|
71
|
+
}
|
|
72
|
+
let watcher = null;
|
|
73
|
+
let debounceTimer = null;
|
|
74
|
+
let lastHash = null;
|
|
75
|
+
let isRunning = true;
|
|
76
|
+
// Initialize last hash from current file
|
|
77
|
+
try {
|
|
78
|
+
const content = fs.readFileSync(boardPath, 'utf-8');
|
|
79
|
+
lastHash = computeHash(content);
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
// Ignore - will sync on first change
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Perform sync from board.md to SQLite
|
|
86
|
+
*/
|
|
87
|
+
async function doSync() {
|
|
88
|
+
const startTime = Date.now();
|
|
89
|
+
// Read and hash content
|
|
90
|
+
const content = fs.readFileSync(boardPath, 'utf-8');
|
|
91
|
+
const currentHash = computeHash(content);
|
|
92
|
+
// Check if content actually changed
|
|
93
|
+
if (currentHash === lastHash) {
|
|
94
|
+
logger('📋 board.md unchanged (hash match), skipping sync');
|
|
95
|
+
return {
|
|
96
|
+
syncedAt: new Date(),
|
|
97
|
+
ticketCount: 0,
|
|
98
|
+
durationMs: Date.now() - startTime,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
// Parse and sync
|
|
102
|
+
const board = parseBoard(content);
|
|
103
|
+
const storage = new SQLiteStorage(dbPath);
|
|
104
|
+
try {
|
|
105
|
+
storage.rebuildFromBoard(board);
|
|
106
|
+
// Update cache metadata
|
|
107
|
+
const stats = fs.statSync(boardPath);
|
|
108
|
+
storage.setCacheMetadata({
|
|
109
|
+
boardMtime: stats.mtimeMs,
|
|
110
|
+
cacheBuiltAt: Date.now(),
|
|
111
|
+
contentHash: currentHash,
|
|
112
|
+
});
|
|
113
|
+
// Count tickets
|
|
114
|
+
const ticketCount = board.columns.reduce((sum, col) => sum + col.tickets.length, 0);
|
|
115
|
+
lastHash = currentHash;
|
|
116
|
+
const syncStats = {
|
|
117
|
+
syncedAt: new Date(),
|
|
118
|
+
ticketCount,
|
|
119
|
+
durationMs: Date.now() - startTime,
|
|
120
|
+
};
|
|
121
|
+
logger(`📥 Synced board.md → SQLite (${ticketCount} tickets, ${syncStats.durationMs}ms)`);
|
|
122
|
+
if (onSync) {
|
|
123
|
+
onSync(syncStats);
|
|
124
|
+
}
|
|
125
|
+
return syncStats;
|
|
126
|
+
}
|
|
127
|
+
finally {
|
|
128
|
+
await storage.close();
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Handle file change with debouncing
|
|
133
|
+
*/
|
|
134
|
+
function handleChange(_eventPath) {
|
|
135
|
+
if (!isRunning)
|
|
136
|
+
return;
|
|
137
|
+
// Clear existing timer
|
|
138
|
+
if (debounceTimer) {
|
|
139
|
+
clearTimeout(debounceTimer);
|
|
140
|
+
}
|
|
141
|
+
// Set new timer
|
|
142
|
+
debounceTimer = setTimeout(async () => {
|
|
143
|
+
try {
|
|
144
|
+
await doSync();
|
|
145
|
+
}
|
|
146
|
+
catch (error) {
|
|
147
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
148
|
+
logger(`❌ Sync error: ${err.message}`);
|
|
149
|
+
if (onError) {
|
|
150
|
+
onError(err);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}, debounceMs);
|
|
154
|
+
}
|
|
155
|
+
// Start watching
|
|
156
|
+
watcher = watch(boardPath, {
|
|
157
|
+
persistent: true,
|
|
158
|
+
ignoreInitial: true,
|
|
159
|
+
awaitWriteFinish: {
|
|
160
|
+
stabilityThreshold: 100,
|
|
161
|
+
pollInterval: 50,
|
|
162
|
+
},
|
|
163
|
+
});
|
|
164
|
+
watcher.on('change', handleChange);
|
|
165
|
+
watcher.on('error', (err) => {
|
|
166
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
167
|
+
logger(`❌ Watcher error: ${error.message}`);
|
|
168
|
+
if (onError) {
|
|
169
|
+
onError(error);
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
logger(`👀 Watching ${boardPath} for changes...`);
|
|
173
|
+
return {
|
|
174
|
+
stop: async () => {
|
|
175
|
+
isRunning = false;
|
|
176
|
+
if (debounceTimer) {
|
|
177
|
+
clearTimeout(debounceTimer);
|
|
178
|
+
}
|
|
179
|
+
if (watcher) {
|
|
180
|
+
await watcher.close();
|
|
181
|
+
watcher = null;
|
|
182
|
+
}
|
|
183
|
+
logger('🛑 Watcher stopped');
|
|
184
|
+
},
|
|
185
|
+
syncNow: async () => {
|
|
186
|
+
return doSync();
|
|
187
|
+
},
|
|
188
|
+
isRunning: () => isRunning,
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Run watcher as a foreground process (for CLI command)
|
|
193
|
+
* Handles SIGINT/SIGTERM for graceful shutdown
|
|
194
|
+
*/
|
|
195
|
+
export async function runWatcherForeground(pmoPath, storageType, options = {}) {
|
|
196
|
+
const watcher = startWatcher(pmoPath, storageType, options);
|
|
197
|
+
// Handle graceful shutdown
|
|
198
|
+
const shutdown = async () => {
|
|
199
|
+
await watcher.stop();
|
|
200
|
+
process.exit(0);
|
|
201
|
+
};
|
|
202
|
+
process.on('SIGINT', shutdown);
|
|
203
|
+
process.on('SIGTERM', shutdown);
|
|
204
|
+
// Keep process alive
|
|
205
|
+
await new Promise(() => {
|
|
206
|
+
// Never resolves - runs until signal
|
|
207
|
+
});
|
|
208
|
+
}
|