@proletariat/cli 0.3.16 → 0.3.18
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/dist/commands/action/create.d.ts +1 -0
- package/dist/commands/action/create.js +74 -38
- package/dist/commands/action/delete.d.ts +1 -0
- package/dist/commands/action/delete.js +23 -24
- package/dist/commands/action/index.d.ts +1 -0
- package/dist/commands/action/index.js +5 -10
- package/dist/commands/action/list.d.ts +1 -0
- package/dist/commands/action/list.js +3 -1
- package/dist/commands/action/run.d.ts +1 -0
- package/dist/commands/action/run.js +44 -32
- package/dist/commands/action/show.d.ts +2 -0
- package/dist/commands/action/update.d.ts +1 -0
- package/dist/commands/action/update.js +80 -39
- package/dist/commands/agent/auth.d.ts +2 -0
- package/dist/commands/agent/auth.js +44 -3
- package/dist/commands/agent/discover.d.ts +2 -0
- package/dist/commands/agent/discover.js +35 -3
- package/dist/commands/agent/index.d.ts +1 -0
- package/dist/commands/agent/index.js +25 -45
- package/dist/commands/agent/list.d.ts +8 -3
- package/dist/commands/agent/list.js +16 -29
- package/dist/commands/agent/login.d.ts +1 -0
- package/dist/commands/agent/login.js +14 -32
- package/dist/commands/agent/rebuild.d.ts +1 -0
- package/dist/commands/agent/rebuild.js +2 -2
- package/dist/commands/agent/remove.d.ts +17 -0
- package/dist/commands/agent/remove.js +144 -0
- package/dist/commands/agent/restart.d.ts +1 -0
- package/dist/commands/agent/restart.js +2 -2
- package/dist/commands/agent/shell.d.ts +1 -0
- package/dist/commands/agent/shell.js +63 -76
- package/dist/commands/agent/staff/add.d.ts +1 -0
- package/dist/commands/agent/staff/add.js +7 -1
- package/dist/commands/agent/staff/index.d.ts +1 -0
- package/dist/commands/agent/staff/index.js +5 -4
- package/dist/commands/agent/staff/remove.d.ts +1 -0
- package/dist/commands/agent/status.d.ts +1 -0
- package/dist/commands/agent/status.js +11 -23
- package/dist/commands/agent/temp/cleanup.d.ts +1 -0
- package/dist/commands/agent/temp/index.d.ts +1 -0
- package/dist/commands/agent/temp/index.js +4 -3
- package/dist/commands/agent/themes/index.d.ts +1 -0
- package/dist/commands/agent/themes/index.js +9 -3
- package/dist/commands/agent/themes/set.d.ts +1 -0
- package/dist/commands/agent/themes/set.js +7 -1
- package/dist/commands/agent/visit.d.ts +1 -0
- package/dist/commands/agent/visit.js +11 -23
- package/dist/commands/autocomplete/setup.d.ts +11 -0
- package/dist/commands/autocomplete/setup.js +113 -8
- package/dist/commands/board/index.d.ts +4 -0
- package/dist/commands/board/index.js +32 -30
- package/dist/commands/board/watch.d.ts +2 -0
- package/dist/commands/branch/create.d.ts +1 -0
- package/dist/commands/branch/create.js +33 -41
- package/dist/commands/branch/index.d.ts +1 -0
- package/dist/commands/branch/list.d.ts +2 -0
- package/dist/commands/branch/validate.d.ts +2 -0
- package/dist/commands/branch/where.d.ts +1 -0
- package/dist/commands/claude.d.ts +6 -0
- package/dist/commands/claude.js +166 -116
- package/dist/commands/commit.d.ts +6 -0
- package/dist/commands/commit.js +68 -73
- package/dist/commands/config/index.d.ts +13 -0
- package/dist/commands/config/index.js +142 -98
- package/dist/commands/docker/clean.d.ts +2 -1
- package/dist/commands/docker/clean.js +20 -29
- package/dist/commands/docker/index.d.ts +1 -0
- package/dist/commands/docker/index.js +37 -41
- package/dist/commands/docker/prune.d.ts +2 -1
- package/dist/commands/docker/prune.js +20 -27
- package/dist/commands/docker/restart.d.ts +2 -1
- package/dist/commands/docker/restart.js +20 -29
- package/dist/commands/docker/stop.d.ts +2 -1
- package/dist/commands/docker/stop.js +20 -29
- package/dist/commands/epic/activate.d.ts +1 -0
- package/dist/commands/epic/archive.d.ts +1 -0
- package/dist/commands/epic/create.d.ts +1 -0
- package/dist/commands/epic/index.d.ts +1 -0
- package/dist/commands/epic/link/block.d.ts +1 -0
- package/dist/commands/epic/link/duplicates.d.ts +1 -0
- package/dist/commands/epic/link/index.d.ts +1 -0
- package/dist/commands/epic/link/relates.d.ts +1 -0
- package/dist/commands/epic/link/remove.d.ts +1 -0
- package/dist/commands/epic/list.d.ts +2 -0
- package/dist/commands/epic/move.d.ts +1 -0
- package/dist/commands/epic/progress.d.ts +1 -0
- package/dist/commands/epic/project.d.ts +1 -0
- package/dist/commands/epic/reorder.d.ts +1 -0
- package/dist/commands/epic/spec.d.ts +1 -0
- package/dist/commands/epic/ticket.d.ts +1 -0
- package/dist/commands/epic/view.d.ts +1 -0
- package/dist/commands/execution/index.d.ts +1 -0
- package/dist/commands/execution/index.js +9 -25
- package/dist/commands/execution/list.d.ts +2 -0
- package/dist/commands/execution/logs.d.ts +1 -0
- package/dist/commands/execution/logs.js +6 -16
- package/dist/commands/execution/stop.d.ts +1 -0
- package/dist/commands/execution/stop.js +4 -15
- package/dist/commands/gh/index.d.ts +1 -0
- package/dist/commands/gh/index.js +27 -27
- package/dist/commands/gh/login.d.ts +4 -0
- package/dist/commands/gh/login.js +31 -0
- package/dist/commands/gh/status.d.ts +4 -0
- package/dist/commands/gh/status.js +27 -4
- package/dist/commands/gh/token.d.ts +4 -0
- package/dist/commands/gh/token.js +49 -5
- package/dist/commands/phase/create.d.ts +1 -1
- package/dist/commands/phase/create.js +116 -74
- package/dist/commands/phase/delete.d.ts +1 -0
- package/dist/commands/phase/delete.js +23 -22
- package/dist/commands/phase/list.d.ts +1 -0
- package/dist/commands/phase/list.js +3 -5
- package/dist/commands/phase/move.d.ts +1 -0
- package/dist/commands/phase/move.js +39 -39
- package/dist/commands/phase/template/apply.d.ts +1 -0
- package/dist/commands/phase/template/create.d.ts +2 -0
- package/dist/commands/phase/template/delete.d.ts +1 -0
- package/dist/commands/phase/template/index.d.ts +1 -0
- package/dist/commands/phase/template/list.d.ts +1 -0
- package/dist/commands/phase/template/update.d.ts +2 -0
- package/dist/commands/phase/update.d.ts +1 -1
- package/dist/commands/phase/update.js +89 -55
- package/dist/commands/pmo/init.d.ts +2 -0
- package/dist/commands/pmo/init.js +84 -22
- package/dist/commands/pr/create.d.ts +12 -3
- package/dist/commands/pr/create.js +130 -147
- package/dist/commands/pr/index.d.ts +6 -3
- package/dist/commands/pr/index.js +41 -39
- package/dist/commands/pr/link.d.ts +7 -3
- package/dist/commands/pr/link.js +126 -150
- package/dist/commands/pr/status.d.ts +6 -3
- package/dist/commands/pr/status.js +101 -126
- package/dist/commands/project/archive.d.ts +1 -0
- package/dist/commands/project/archive.js +15 -20
- package/dist/commands/project/create.d.ts +1 -0
- package/dist/commands/project/create.js +13 -5
- package/dist/commands/project/delete.d.ts +1 -0
- package/dist/commands/project/delete.js +14 -28
- package/dist/commands/project/index.d.ts +1 -0
- package/dist/commands/project/index.js +0 -5
- package/dist/commands/project/list.d.ts +2 -0
- package/dist/commands/project/list.js +21 -3
- package/dist/commands/project/spec.d.ts +1 -0
- package/dist/commands/project/spec.js +17 -23
- package/dist/commands/project/unarchive.d.ts +2 -0
- package/dist/commands/project/unarchive.js +21 -2
- package/dist/commands/project/view.d.ts +1 -0
- package/dist/commands/project/view.js +34 -22
- package/dist/commands/repo/add.d.ts +2 -0
- package/dist/commands/repo/add.js +44 -1
- package/dist/commands/repo/index.d.ts +1 -0
- package/dist/commands/repo/index.js +20 -38
- package/dist/commands/repo/list.d.ts +2 -0
- package/dist/commands/repo/remove.d.ts +1 -0
- package/dist/commands/repo/remove.js +45 -63
- package/dist/commands/repo/view.d.ts +2 -0
- package/dist/commands/repo/view.js +30 -5
- package/dist/commands/roadmap/add-project.d.ts +1 -0
- package/dist/commands/roadmap/create.d.ts +1 -0
- package/dist/commands/roadmap/delete.d.ts +1 -0
- package/dist/commands/roadmap/generate.d.ts +1 -0
- package/dist/commands/roadmap/index.d.ts +1 -0
- package/dist/commands/roadmap/list.d.ts +2 -0
- package/dist/commands/roadmap/remove-project.d.ts +1 -0
- package/dist/commands/roadmap/reorder.d.ts +1 -0
- package/dist/commands/roadmap/update.d.ts +1 -0
- package/dist/commands/roadmap/view.d.ts +1 -0
- package/dist/commands/session/attach.d.ts +1 -0
- package/dist/commands/session/index.d.ts +1 -0
- package/dist/commands/session/index.js +8 -25
- package/dist/commands/session/list.d.ts +2 -0
- package/dist/commands/spec/create.d.ts +1 -1
- package/dist/commands/spec/create.js +64 -65
- package/dist/commands/spec/index.d.ts +1 -0
- package/dist/commands/spec/index.js +36 -22
- package/dist/commands/spec/link/depends.d.ts +1 -0
- package/dist/commands/spec/link/depends.js +6 -6
- package/dist/commands/spec/link/duplicates.d.ts +1 -0
- package/dist/commands/spec/link/duplicates.js +6 -6
- package/dist/commands/spec/link/index.d.ts +2 -1
- package/dist/commands/spec/link/index.js +0 -4
- package/dist/commands/spec/link/relates.d.ts +1 -0
- package/dist/commands/spec/link/relates.js +6 -6
- package/dist/commands/spec/link/remove.d.ts +2 -1
- package/dist/commands/spec/link/remove.js +6 -6
- package/dist/commands/spec/list.d.ts +2 -0
- package/dist/commands/spec/list.js +25 -0
- package/dist/commands/spec/plan.d.ts +2 -1
- package/dist/commands/spec/plan.js +19 -26
- package/dist/commands/spec/ticket.d.ts +2 -1
- package/dist/commands/spec/ticket.js +48 -34
- package/dist/commands/spec/view.d.ts +2 -1
- package/dist/commands/spec/view.js +25 -16
- package/dist/commands/status/create.d.ts +1 -1
- package/dist/commands/status/create.js +80 -64
- package/dist/commands/status/delete.d.ts +2 -1
- package/dist/commands/status/delete.js +26 -22
- package/dist/commands/status/index.d.ts +1 -0
- package/dist/commands/status/index.js +26 -19
- package/dist/commands/status/list.d.ts +1 -0
- package/dist/commands/status/list.js +12 -7
- package/dist/commands/status/move.d.ts +2 -1
- package/dist/commands/status/move.js +62 -61
- package/dist/commands/status/update.d.ts +2 -2
- package/dist/commands/status/update.js +110 -77
- package/dist/commands/template/delete.d.ts +1 -0
- package/dist/commands/template/delete.js +47 -48
- package/dist/commands/template/index.d.ts +1 -0
- package/dist/commands/template/index.js +26 -33
- package/dist/commands/template/list.d.ts +1 -0
- package/dist/commands/template/phase/create.d.ts +1 -0
- package/dist/commands/template/phase/create.js +6 -0
- package/dist/commands/template/phase/index.d.ts +1 -0
- package/dist/commands/template/phase/index.js +27 -26
- package/dist/commands/template/phase/update.d.ts +1 -0
- package/dist/commands/template/phase/update.js +6 -0
- package/dist/commands/template/ticket/index.d.ts +1 -0
- package/dist/commands/template/ticket/index.js +27 -26
- package/dist/commands/template/ticket/save.d.ts +1 -0
- package/dist/commands/template/ticket/save.js +6 -0
- package/dist/commands/terminal/title.d.ts +26 -0
- package/dist/commands/terminal/title.js +37 -3
- package/dist/commands/ticket/bulk.d.ts +1 -0
- package/dist/commands/ticket/complete.d.ts +1 -0
- package/dist/commands/ticket/complete.js +18 -14
- package/dist/commands/ticket/create.d.ts +1 -0
- package/dist/commands/ticket/create.js +45 -41
- package/dist/commands/ticket/delete.d.ts +1 -0
- package/dist/commands/ticket/delete.js +1 -1
- package/dist/commands/ticket/edit.d.ts +1 -0
- package/dist/commands/ticket/edit.js +1 -1
- package/dist/commands/ticket/epic.d.ts +1 -0
- package/dist/commands/ticket/epic.js +2 -2
- package/dist/commands/ticket/index.d.ts +1 -0
- package/dist/commands/ticket/link/block.d.ts +1 -0
- package/dist/commands/ticket/link/block.js +1 -1
- package/dist/commands/ticket/link/duplicates.d.ts +1 -0
- package/dist/commands/ticket/link/duplicates.js +1 -1
- package/dist/commands/ticket/link/index.d.ts +1 -0
- package/dist/commands/ticket/link/index.js +9 -8
- package/dist/commands/ticket/link/relates.d.ts +1 -0
- package/dist/commands/ticket/link/relates.js +1 -1
- package/dist/commands/ticket/link/remove.d.ts +1 -0
- package/dist/commands/ticket/link/remove.js +1 -1
- package/dist/commands/ticket/list.d.ts +2 -0
- package/dist/commands/ticket/move.d.ts +1 -0
- package/dist/commands/ticket/move.js +27 -19
- package/dist/commands/ticket/project.d.ts +1 -0
- package/dist/commands/ticket/project.js +3 -3
- package/dist/commands/ticket/reassign.d.ts +1 -0
- package/dist/commands/ticket/reassign.js +1 -1
- package/dist/commands/ticket/spec.d.ts +1 -0
- package/dist/commands/ticket/spec.js +3 -3
- package/dist/commands/ticket/status.d.ts +1 -0
- package/dist/commands/ticket/status.js +1 -1
- package/dist/commands/ticket/template/apply.d.ts +1 -0
- package/dist/commands/ticket/template/create.d.ts +2 -0
- package/dist/commands/ticket/template/delete.d.ts +1 -0
- package/dist/commands/ticket/template/index.d.ts +1 -0
- package/dist/commands/ticket/template/list.d.ts +1 -0
- package/dist/commands/ticket/template/save.d.ts +2 -0
- package/dist/commands/ticket/update.d.ts +1 -0
- package/dist/commands/ticket/update.js +1 -1
- package/dist/commands/ticket/view.d.ts +1 -0
- package/dist/commands/ticket/view.js +1 -1
- package/dist/commands/work/complete.d.ts +1 -0
- package/dist/commands/work/index.d.ts +1 -0
- package/dist/commands/work/ready.d.ts +1 -0
- package/dist/commands/work/revise.d.ts +1 -0
- package/dist/commands/work/spawn-all.d.ts +2 -0
- package/dist/commands/work/spawn-all.js +11 -4
- package/dist/commands/work/spawn.d.ts +1 -0
- package/dist/commands/work/spawn.js +261 -166
- package/dist/commands/work/start.d.ts +1 -0
- package/dist/commands/work/start.js +270 -189
- package/dist/commands/work/watch.d.ts +1 -0
- package/dist/commands/work/watch.js +63 -58
- package/dist/commands/workflow/create.d.ts +1 -0
- package/dist/commands/workflow/create.js +2 -4
- package/dist/commands/workflow/delete.d.ts +1 -0
- package/dist/commands/workflow/delete.js +21 -33
- package/dist/commands/workflow/index.d.ts +1 -0
- package/dist/commands/workflow/list.d.ts +1 -0
- package/dist/commands/workflow/list.js +3 -6
- package/dist/commands/workflow/switch.d.ts +2 -0
- package/dist/commands/workflow/switch.js +46 -21
- package/dist/commands/workflow/view.d.ts +1 -0
- package/dist/commands/workflow/view.js +18 -27
- package/dist/commands/workspace/remove.d.ts +2 -2
- package/dist/commands/workspace/remove.js +16 -21
- package/dist/commands/workspace/use.d.ts +2 -2
- package/dist/commands/workspace/use.js +12 -18
- package/dist/lib/agents/commands.d.ts +1 -1
- package/dist/lib/agents/commands.js +4 -4
- package/dist/lib/database/drizzle-schema.d.ts +5009 -0
- package/dist/lib/database/drizzle-schema.js +699 -0
- package/dist/lib/database/drizzle.d.ts +29 -0
- package/dist/lib/database/drizzle.js +37 -0
- package/dist/lib/database/index.d.ts +1 -0
- package/dist/lib/database/index.js +1 -1
- package/dist/lib/execution/config.d.ts +6 -0
- package/dist/lib/execution/config.js +31 -13
- package/dist/lib/execution/devcontainer.js +13 -7
- package/dist/lib/execution/runners.js +24 -7
- package/dist/lib/execution/spawner.js +19 -0
- package/dist/lib/flags/index.d.ts +4 -0
- package/dist/lib/flags/index.js +4 -0
- package/dist/lib/flags/resolver.d.ts +224 -0
- package/dist/lib/flags/resolver.js +313 -0
- package/dist/lib/pmo/base-command.d.ts +53 -3
- package/dist/lib/pmo/base-command.js +92 -13
- package/dist/lib/pmo/find-pmo.d.ts +1 -1
- package/dist/lib/pmo/find-pmo.js +4 -4
- package/dist/lib/pmo/index.d.ts +1 -1
- package/dist/lib/pmo/index.js +1 -1
- package/dist/lib/pmo/storage/helpers.js +2 -1
- package/dist/lib/pmo/storage/index.d.ts +9 -0
- package/dist/lib/pmo/storage/index.js +14 -0
- package/dist/lib/pmo/storage/projects.d.ts +28 -13
- package/dist/lib/pmo/storage/projects.js +110 -34
- package/dist/lib/pmo/storage/roadmaps.d.ts +2 -0
- package/dist/lib/pmo/storage/roadmaps.js +182 -111
- package/dist/lib/pmo/storage/specs.js +13 -16
- package/dist/lib/pmo/storage/subtasks.js +17 -2
- package/dist/lib/pmo/storage/tickets.d.ts +12 -2
- package/dist/lib/pmo/storage/tickets.js +63 -5
- package/dist/lib/pmo/storage/types.d.ts +7 -3
- package/dist/lib/pmo/storage/views.d.ts +12 -1
- package/dist/lib/pmo/storage/views.js +61 -6
- package/dist/lib/prompt-command.d.ts +90 -0
- package/dist/lib/prompt-command.js +102 -0
- package/dist/lib/prompt-json.d.ts +34 -4
- package/dist/lib/prompt-json.js +35 -3
- package/dist/lib/repos/index.js +15 -15
- package/dist/lib/workspace.d.ts +4 -3
- package/dist/lib/workspace.js +3 -3
- package/oclif.manifest.json +4610 -2997
- package/package.json +13 -5
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FlagResolver - Unified flag resolution for human and machine interactive modes
|
|
3
|
+
*
|
|
4
|
+
* This abstraction unifies the two interaction patterns in the CLI:
|
|
5
|
+
* - Human interactive mode: Uses inquirer prompts, collects input, returns flags
|
|
6
|
+
* - Machine/JSON mode: Outputs prompt schema as JSON, exits for agent to process
|
|
7
|
+
*
|
|
8
|
+
* Both modes use the same underlying pattern: prompts PRODUCE flags.
|
|
9
|
+
* The execution logic only sees flags, not prompt results.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* // Define prompts for missing flags
|
|
14
|
+
* const resolver = new FlagResolver({
|
|
15
|
+
* commandName: 'ticket create',
|
|
16
|
+
* baseCommand: 'prlt ticket create',
|
|
17
|
+
* jsonMode: shouldOutputJson(flags),
|
|
18
|
+
* flags,
|
|
19
|
+
* });
|
|
20
|
+
*
|
|
21
|
+
* // Add prompts - they execute in order, can depend on previously resolved flags
|
|
22
|
+
* resolver.addPrompt({
|
|
23
|
+
* flagName: 'column',
|
|
24
|
+
* type: 'list',
|
|
25
|
+
* message: 'Select column:',
|
|
26
|
+
* choices: async () => columns.map(c => ({ name: c, value: c })),
|
|
27
|
+
* });
|
|
28
|
+
*
|
|
29
|
+
* resolver.addPrompt({
|
|
30
|
+
* flagName: 'title',
|
|
31
|
+
* type: 'input',
|
|
32
|
+
* message: 'Enter title:',
|
|
33
|
+
* when: (ctx) => ctx.flags.column !== undefined, // Only after column is selected
|
|
34
|
+
* });
|
|
35
|
+
*
|
|
36
|
+
* // Resolve all missing flags
|
|
37
|
+
* const resolved = await resolver.resolve();
|
|
38
|
+
* // resolved.column and resolved.title are now guaranteed to have values
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
import inquirer from 'inquirer';
|
|
42
|
+
import { outputPromptAsJson, createMetadata, } from '../prompt-json.js';
|
|
43
|
+
/**
|
|
44
|
+
* FlagResolver handles unified flag resolution for both human and machine modes.
|
|
45
|
+
*
|
|
46
|
+
* Usage pattern:
|
|
47
|
+
* 1. Create resolver with command info and current flags
|
|
48
|
+
* 2. Add prompt definitions for flags that may need resolution
|
|
49
|
+
* 3. Call resolve() to get complete flags
|
|
50
|
+
*
|
|
51
|
+
* In JSON mode, resolve() outputs the first unresolved prompt and exits.
|
|
52
|
+
* In interactive mode, resolve() prompts for each unresolved flag sequentially.
|
|
53
|
+
*/
|
|
54
|
+
export class FlagResolver {
|
|
55
|
+
prompts = [];
|
|
56
|
+
options;
|
|
57
|
+
resolvedFlags;
|
|
58
|
+
resolverContext;
|
|
59
|
+
constructor(options) {
|
|
60
|
+
this.options = options;
|
|
61
|
+
this.resolvedFlags = { ...options.flags };
|
|
62
|
+
this.resolverContext = {
|
|
63
|
+
flags: this.resolvedFlags,
|
|
64
|
+
args: options.args || {},
|
|
65
|
+
commandName: options.commandName,
|
|
66
|
+
baseCommand: options.baseCommand,
|
|
67
|
+
...options.context,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Add a prompt definition for resolving a flag.
|
|
72
|
+
* Prompts are processed in the order they are added.
|
|
73
|
+
*/
|
|
74
|
+
addPrompt(prompt) {
|
|
75
|
+
this.prompts.push(prompt);
|
|
76
|
+
return this;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Add multiple prompt definitions at once.
|
|
80
|
+
*/
|
|
81
|
+
addPrompts(prompts) {
|
|
82
|
+
for (const prompt of prompts) {
|
|
83
|
+
this.prompts.push(prompt);
|
|
84
|
+
}
|
|
85
|
+
return this;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Update the context with additional data.
|
|
89
|
+
* Useful for adding computed values that prompts might need.
|
|
90
|
+
*/
|
|
91
|
+
setContext(key, value) {
|
|
92
|
+
this.resolverContext[key] = value;
|
|
93
|
+
return this;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Get current context value
|
|
97
|
+
*/
|
|
98
|
+
getContext(key) {
|
|
99
|
+
return this.resolverContext[key];
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Check if a flag has a value (not undefined)
|
|
103
|
+
*/
|
|
104
|
+
hasFlag(flagName) {
|
|
105
|
+
return this.resolvedFlags[flagName] !== undefined;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Get current flag value
|
|
109
|
+
*/
|
|
110
|
+
getFlag(flagName) {
|
|
111
|
+
return this.resolvedFlags[flagName];
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Set a flag value directly (bypasses prompting)
|
|
115
|
+
*/
|
|
116
|
+
setFlag(flagName, value) {
|
|
117
|
+
this.resolvedFlags[flagName] = value;
|
|
118
|
+
this.resolverContext.flags = this.resolvedFlags;
|
|
119
|
+
return this;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Resolve all prompts and return complete flags.
|
|
123
|
+
*
|
|
124
|
+
* In JSON mode: outputs the first unresolved prompt as JSON and exits (never returns).
|
|
125
|
+
* In interactive mode: prompts for each unresolved flag and returns all flags.
|
|
126
|
+
*
|
|
127
|
+
* @returns The fully resolved flags
|
|
128
|
+
*/
|
|
129
|
+
async resolve() {
|
|
130
|
+
for (const prompt of this.prompts) {
|
|
131
|
+
// Check if flag already has a value
|
|
132
|
+
const currentValue = this.resolvedFlags[prompt.flagName];
|
|
133
|
+
if (currentValue !== undefined) {
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
// Check conditional
|
|
137
|
+
if (prompt.when && !prompt.when(this.resolverContext)) {
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
// Resolve the message if it's a function
|
|
141
|
+
const message = typeof prompt.message === 'function'
|
|
142
|
+
? prompt.message(this.resolverContext)
|
|
143
|
+
: prompt.message;
|
|
144
|
+
// Get choices if applicable
|
|
145
|
+
let choices;
|
|
146
|
+
if (prompt.choices) {
|
|
147
|
+
choices = await Promise.resolve(prompt.choices(this.resolverContext));
|
|
148
|
+
}
|
|
149
|
+
// Get default value
|
|
150
|
+
const defaultValue = typeof prompt.default === 'function'
|
|
151
|
+
? prompt.default(this.resolverContext)
|
|
152
|
+
: prompt.default;
|
|
153
|
+
if (this.options.jsonMode) {
|
|
154
|
+
// JSON MODE: Output prompt config and exit
|
|
155
|
+
await this.outputJsonPrompt(prompt, message, choices, defaultValue);
|
|
156
|
+
// outputPromptAsJson calls process.exit, so we never reach here
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
// INTERACTIVE MODE: Prompt for value
|
|
160
|
+
const value = await this.promptInteractive(prompt, message, choices, defaultValue);
|
|
161
|
+
// Transform value if needed
|
|
162
|
+
const finalValue = prompt.transform
|
|
163
|
+
? prompt.transform(value, this.resolverContext)
|
|
164
|
+
: value;
|
|
165
|
+
// Store resolved flag
|
|
166
|
+
this.resolvedFlags[prompt.flagName] = finalValue;
|
|
167
|
+
this.resolverContext.flags = this.resolvedFlags;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return this.resolvedFlags;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Output prompt as JSON for machine mode
|
|
174
|
+
*/
|
|
175
|
+
async outputJsonPrompt(prompt, message, choices, defaultValue) {
|
|
176
|
+
// Build prompt config
|
|
177
|
+
const config = {
|
|
178
|
+
type: prompt.type,
|
|
179
|
+
name: prompt.flagName,
|
|
180
|
+
message,
|
|
181
|
+
};
|
|
182
|
+
// Add choices with command field
|
|
183
|
+
if (choices) {
|
|
184
|
+
config.choices = choices.map(choice => {
|
|
185
|
+
const promptChoice = {
|
|
186
|
+
name: choice.name,
|
|
187
|
+
value: String(choice.value),
|
|
188
|
+
};
|
|
189
|
+
if (choice.disabled !== undefined) {
|
|
190
|
+
promptChoice.disabled = Boolean(choice.disabled);
|
|
191
|
+
}
|
|
192
|
+
// Generate command for this choice
|
|
193
|
+
if (choice.command) {
|
|
194
|
+
promptChoice.command = choice.command;
|
|
195
|
+
}
|
|
196
|
+
else if (!prompt.skipAutoCommand) {
|
|
197
|
+
// Auto-generate command
|
|
198
|
+
promptChoice.command = prompt.getCommand
|
|
199
|
+
? prompt.getCommand(choice.value, this.resolverContext)
|
|
200
|
+
: this.buildCommand(prompt.flagName, choice.value);
|
|
201
|
+
}
|
|
202
|
+
return promptChoice;
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
// Add default value
|
|
206
|
+
if (defaultValue !== undefined) {
|
|
207
|
+
config.default = defaultValue;
|
|
208
|
+
}
|
|
209
|
+
// Add context if provided
|
|
210
|
+
if (prompt.context) {
|
|
211
|
+
config.context = typeof prompt.context === 'function'
|
|
212
|
+
? prompt.context(this.resolverContext)
|
|
213
|
+
: prompt.context;
|
|
214
|
+
}
|
|
215
|
+
// For input prompts without choices, add helpful context
|
|
216
|
+
if (prompt.type === 'input' && !config.context) {
|
|
217
|
+
config.context = {
|
|
218
|
+
hint: `Provide ${prompt.flagName} with: ${this.buildCommand(prompt.flagName, '<value>')}`,
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
// Output and exit
|
|
222
|
+
outputPromptAsJson(config, createMetadata(this.options.commandName, this.options.flags));
|
|
223
|
+
// outputPromptAsJson calls process.exit, but TypeScript doesn't know that
|
|
224
|
+
// This line is never reached
|
|
225
|
+
throw new Error('Unreachable');
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Prompt for value in interactive mode
|
|
229
|
+
*/
|
|
230
|
+
async promptInteractive(prompt, message, choices, defaultValue) {
|
|
231
|
+
// Build inquirer prompt config as a single question object
|
|
232
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
233
|
+
const question = {
|
|
234
|
+
type: prompt.type,
|
|
235
|
+
name: prompt.flagName,
|
|
236
|
+
message,
|
|
237
|
+
default: defaultValue,
|
|
238
|
+
};
|
|
239
|
+
// Add choices for list/checkbox
|
|
240
|
+
if (choices) {
|
|
241
|
+
question.choices = choices.map(c => ({
|
|
242
|
+
name: c.name,
|
|
243
|
+
value: c.value,
|
|
244
|
+
disabled: c.disabled,
|
|
245
|
+
}));
|
|
246
|
+
}
|
|
247
|
+
// Add validation for input
|
|
248
|
+
if (prompt.validate) {
|
|
249
|
+
question.validate = (input) => {
|
|
250
|
+
return prompt.validate(input, this.resolverContext);
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
// Prompt and return value
|
|
254
|
+
const answers = await inquirer.prompt([question]);
|
|
255
|
+
return answers[prompt.flagName];
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Build a command string for a flag value
|
|
259
|
+
*/
|
|
260
|
+
buildCommand(flagName, value) {
|
|
261
|
+
const { baseCommand } = this.options;
|
|
262
|
+
// Build flags part from currently resolved flags
|
|
263
|
+
let cmd = baseCommand;
|
|
264
|
+
// Add any project flag from context
|
|
265
|
+
const projectId = this.resolverContext.projectId;
|
|
266
|
+
if (projectId && !this.resolvedFlags['project']) {
|
|
267
|
+
cmd += ` -P ${projectId}`;
|
|
268
|
+
}
|
|
269
|
+
// Add resolved flags (except the one we're prompting for)
|
|
270
|
+
for (const [key, val] of Object.entries(this.resolvedFlags)) {
|
|
271
|
+
if (key === flagName || val === undefined || key === 'json')
|
|
272
|
+
continue;
|
|
273
|
+
if (typeof val === 'boolean') {
|
|
274
|
+
if (val)
|
|
275
|
+
cmd += ` --${key}`;
|
|
276
|
+
}
|
|
277
|
+
else if (typeof val === 'string') {
|
|
278
|
+
cmd += ` --${key} "${val}"`;
|
|
279
|
+
}
|
|
280
|
+
else if (Array.isArray(val)) {
|
|
281
|
+
cmd += ` --${key} "${val.join(',')}"`;
|
|
282
|
+
}
|
|
283
|
+
else {
|
|
284
|
+
cmd += ` --${key} ${val}`;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
// Add the current flag
|
|
288
|
+
if (typeof value === 'boolean') {
|
|
289
|
+
if (value)
|
|
290
|
+
cmd += ` --${flagName}`;
|
|
291
|
+
}
|
|
292
|
+
else if (typeof value === 'string') {
|
|
293
|
+
cmd += ` --${flagName} "${value}"`;
|
|
294
|
+
}
|
|
295
|
+
else if (value !== undefined) {
|
|
296
|
+
cmd += ` --${flagName} ${value}`;
|
|
297
|
+
}
|
|
298
|
+
// Always add --json at the end
|
|
299
|
+
cmd += ' --json';
|
|
300
|
+
return cmd;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Convenience function to create a FlagResolver from command context
|
|
305
|
+
*/
|
|
306
|
+
export function createFlagResolver(options) {
|
|
307
|
+
return new FlagResolver(options);
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Helper to check if we should use JSON mode
|
|
311
|
+
* Re-exported from prompt-json for convenience
|
|
312
|
+
*/
|
|
313
|
+
export { shouldOutputJson, isMachineOutput } from '../prompt-json.js';
|
|
@@ -1,11 +1,30 @@
|
|
|
1
|
-
import { Command } from '@oclif/core';
|
|
2
1
|
import { type PMOContext } from './pmo-context.js';
|
|
2
|
+
import { PromptCommand } from '../prompt-command.js';
|
|
3
3
|
import { type JsonFlags } from '../prompt-json.js';
|
|
4
|
+
/**
|
|
5
|
+
* Base flags for JSON/agent mode support (legacy)
|
|
6
|
+
* Include these in your command's flags by spreading: ...jsonModeFlags
|
|
7
|
+
* @deprecated Use machineOutputFlags instead
|
|
8
|
+
*/
|
|
9
|
+
export declare const jsonModeFlags: {
|
|
10
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Base flags for machine-readable output mode
|
|
14
|
+
* Include these in your command's flags by spreading: ...machineOutputFlags
|
|
15
|
+
* Supports both --machine (new) and --json (legacy, deprecated)
|
|
16
|
+
*/
|
|
17
|
+
export declare const machineOutputFlags: {
|
|
18
|
+
machine: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
19
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
20
|
+
};
|
|
4
21
|
/**
|
|
5
22
|
* Base flags shared by all PMO commands
|
|
6
|
-
* Include these in your command's flags by spreading: ...
|
|
23
|
+
* Include these in your command's flags by spreading: ...pmoBaseFlags
|
|
7
24
|
*/
|
|
8
25
|
export declare const pmoBaseFlags: {
|
|
26
|
+
machine: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
27
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
9
28
|
project: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
29
|
};
|
|
11
30
|
/**
|
|
@@ -43,7 +62,7 @@ export declare const pmoBaseFlags: {
|
|
|
43
62
|
* }
|
|
44
63
|
* ```
|
|
45
64
|
*/
|
|
46
|
-
export declare abstract class PMOCommand extends
|
|
65
|
+
export declare abstract class PMOCommand extends PromptCommand {
|
|
47
66
|
/**
|
|
48
67
|
* PMO context with storage, pmoPath, etc.
|
|
49
68
|
* Available after init() runs (before execute())
|
|
@@ -162,6 +181,37 @@ export declare abstract class PMOCommand extends Command {
|
|
|
162
181
|
example?: string;
|
|
163
182
|
} | null;
|
|
164
183
|
}): Promise<string>;
|
|
184
|
+
/**
|
|
185
|
+
* Unified error handler for JSON/interactive modes.
|
|
186
|
+
*
|
|
187
|
+
* Consolidates error handling to avoid message drift between JSON and interactive modes.
|
|
188
|
+
* In JSON mode: outputs structured error JSON and exits
|
|
189
|
+
* In interactive mode: calls this.error() with the message
|
|
190
|
+
*
|
|
191
|
+
* @param code - Error code for JSON output (e.g., 'NOT_FOUND', 'DOCKER_NOT_RUNNING')
|
|
192
|
+
* @param message - Human-readable error message (used in both modes)
|
|
193
|
+
* @param options - Configuration for error handling
|
|
194
|
+
* @returns never - always throws or exits
|
|
195
|
+
*
|
|
196
|
+
* @example
|
|
197
|
+
* ```typescript
|
|
198
|
+
* // Instead of duplicating messages:
|
|
199
|
+
* // if (jsonMode) { outputErrorAsJson('CODE', 'msg', ...); }
|
|
200
|
+
* // this.error('msg');
|
|
201
|
+
*
|
|
202
|
+
* // Use:
|
|
203
|
+
* this.handleError('DOCKER_NOT_RUNNING', 'Docker is not running.', {
|
|
204
|
+
* jsonMode,
|
|
205
|
+
* commandName: 'agent auth',
|
|
206
|
+
* flags,
|
|
207
|
+
* });
|
|
208
|
+
* ```
|
|
209
|
+
*/
|
|
210
|
+
protected handleError(code: string, message: string, options: {
|
|
211
|
+
jsonMode: boolean;
|
|
212
|
+
commandName: string;
|
|
213
|
+
flags: Record<string, unknown>;
|
|
214
|
+
}): never;
|
|
165
215
|
/**
|
|
166
216
|
* Override run() to delegate to execute() and ensure cleanup
|
|
167
217
|
* Subclasses should implement execute() instead of run()
|
|
@@ -1,17 +1,47 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Flags } from '@oclif/core';
|
|
2
2
|
import inquirer from 'inquirer';
|
|
3
3
|
import { getPMOContext } from './pmo-context.js';
|
|
4
4
|
import { styles } from '../styles.js';
|
|
5
|
-
import {
|
|
5
|
+
import { PromptCommand } from '../prompt-command.js';
|
|
6
|
+
import { shouldOutputJson, outputPromptAsJson, outputErrorAsJson, createMetadata, } from '../prompt-json.js';
|
|
7
|
+
/**
|
|
8
|
+
* Base flags for JSON/agent mode support (legacy)
|
|
9
|
+
* Include these in your command's flags by spreading: ...jsonModeFlags
|
|
10
|
+
* @deprecated Use machineOutputFlags instead
|
|
11
|
+
*/
|
|
12
|
+
export const jsonModeFlags = {
|
|
13
|
+
json: Flags.boolean({
|
|
14
|
+
description: 'Output prompts as JSON for AI agents/scripts',
|
|
15
|
+
default: false,
|
|
16
|
+
}),
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Base flags for machine-readable output mode
|
|
20
|
+
* Include these in your command's flags by spreading: ...machineOutputFlags
|
|
21
|
+
* Supports both --machine (new) and --json (legacy, deprecated)
|
|
22
|
+
*/
|
|
23
|
+
export const machineOutputFlags = {
|
|
24
|
+
machine: Flags.boolean({
|
|
25
|
+
char: 'm',
|
|
26
|
+
description: 'Output as JSON for AI agents/scripts (machine-readable mode)',
|
|
27
|
+
default: false,
|
|
28
|
+
}),
|
|
29
|
+
json: Flags.boolean({
|
|
30
|
+
description: 'Output as JSON (deprecated, use --machine)',
|
|
31
|
+
default: false,
|
|
32
|
+
hidden: true, // Hide from help since it's deprecated
|
|
33
|
+
}),
|
|
34
|
+
};
|
|
6
35
|
/**
|
|
7
36
|
* Base flags shared by all PMO commands
|
|
8
|
-
* Include these in your command's flags by spreading: ...
|
|
37
|
+
* Include these in your command's flags by spreading: ...pmoBaseFlags
|
|
9
38
|
*/
|
|
10
39
|
export const pmoBaseFlags = {
|
|
11
40
|
project: Flags.string({
|
|
12
41
|
char: 'P',
|
|
13
42
|
description: 'Project ID (uses first project if only one exists)',
|
|
14
43
|
}),
|
|
44
|
+
...machineOutputFlags,
|
|
15
45
|
};
|
|
16
46
|
/**
|
|
17
47
|
* Base command class for PMO commands
|
|
@@ -48,7 +78,7 @@ export const pmoBaseFlags = {
|
|
|
48
78
|
* }
|
|
49
79
|
* ```
|
|
50
80
|
*/
|
|
51
|
-
export class PMOCommand extends
|
|
81
|
+
export class PMOCommand extends PromptCommand {
|
|
52
82
|
/**
|
|
53
83
|
* PMO context with storage, pmoPath, etc.
|
|
54
84
|
* Available after init() runs (before execute())
|
|
@@ -133,19 +163,27 @@ export class PMOCommand extends Command {
|
|
|
133
163
|
const numB = parseInt(b.name.match(/^(\d+)/)?.[1] || '999', 10);
|
|
134
164
|
return numA - numB;
|
|
135
165
|
});
|
|
166
|
+
// Auto-detect non-TTY: switch to JSON mode when no TTY present
|
|
167
|
+
const effectiveJsonMode = options?.jsonMode ?? (!process.stdin.isTTY
|
|
168
|
+
? {
|
|
169
|
+
flags: { json: true },
|
|
170
|
+
commandName: this.id ?? 'unknown',
|
|
171
|
+
baseCommand: `prlt ${(this.id ?? 'unknown').replace(/:/g, ' ')}`,
|
|
172
|
+
}
|
|
173
|
+
: null);
|
|
136
174
|
// If JSON mode is active, output project choices as JSON
|
|
137
|
-
if (
|
|
175
|
+
if (effectiveJsonMode && shouldOutputJson(effectiveJsonMode.flags)) {
|
|
138
176
|
const choices = sortedProjects.map(p => ({
|
|
139
177
|
name: `${p.name} (${p.id})`,
|
|
140
178
|
value: p.id,
|
|
141
|
-
command: `${
|
|
179
|
+
command: `${effectiveJsonMode.baseCommand} -P ${p.id} --json`,
|
|
142
180
|
}));
|
|
143
181
|
outputPromptAsJson({
|
|
144
182
|
type: 'list',
|
|
145
183
|
name: 'project',
|
|
146
184
|
message: 'Select project:',
|
|
147
185
|
choices,
|
|
148
|
-
}, createMetadata(
|
|
186
|
+
}, createMetadata(effectiveJsonMode.commandName, effectiveJsonMode.flags));
|
|
149
187
|
// outputPromptAsJson calls process.exit, so this is unreachable
|
|
150
188
|
return '';
|
|
151
189
|
}
|
|
@@ -191,6 +229,10 @@ export class PMOCommand extends Command {
|
|
|
191
229
|
*/
|
|
192
230
|
async selectFromList(options) {
|
|
193
231
|
const { message, items, getName, getValue, getCommand, jsonMode, allowCancel = false, cancelValue, } = options;
|
|
232
|
+
// Auto-detect non-TTY: switch to JSON mode when no TTY present
|
|
233
|
+
const effectiveJsonMode = jsonMode ?? (!process.stdin.isTTY
|
|
234
|
+
? { flags: { json: true }, commandName: this.id ?? 'unknown' }
|
|
235
|
+
: null);
|
|
194
236
|
// Build choices with command field
|
|
195
237
|
const choices = items.map(item => ({
|
|
196
238
|
name: getName(item),
|
|
@@ -198,13 +240,13 @@ export class PMOCommand extends Command {
|
|
|
198
240
|
command: getCommand(item),
|
|
199
241
|
}));
|
|
200
242
|
// Check for JSON mode
|
|
201
|
-
if (
|
|
243
|
+
if (effectiveJsonMode && shouldOutputJson(effectiveJsonMode.flags)) {
|
|
202
244
|
outputPromptAsJson({
|
|
203
245
|
type: 'list',
|
|
204
246
|
name: 'selection',
|
|
205
247
|
message,
|
|
206
248
|
choices,
|
|
207
|
-
}, createMetadata(
|
|
249
|
+
}, createMetadata(effectiveJsonMode.commandName, effectiveJsonMode.flags));
|
|
208
250
|
// outputPromptAsJson exits, so this is unreachable
|
|
209
251
|
return null;
|
|
210
252
|
}
|
|
@@ -238,18 +280,22 @@ export class PMOCommand extends Command {
|
|
|
238
280
|
*/
|
|
239
281
|
async promptForInput(options) {
|
|
240
282
|
const { message, fieldName, defaultValue, validate, jsonMode } = options;
|
|
283
|
+
// Auto-detect non-TTY: switch to JSON mode when no TTY present
|
|
284
|
+
const effectiveJsonMode = jsonMode ?? (!process.stdin.isTTY
|
|
285
|
+
? { flags: { json: true }, commandName: this.id ?? 'unknown', commandHint: '', example: undefined }
|
|
286
|
+
: null);
|
|
241
287
|
// Check for JSON mode
|
|
242
|
-
if (
|
|
288
|
+
if (effectiveJsonMode && shouldOutputJson(effectiveJsonMode.flags)) {
|
|
243
289
|
outputPromptAsJson({
|
|
244
290
|
type: 'input',
|
|
245
291
|
name: fieldName,
|
|
246
292
|
message,
|
|
247
293
|
default: defaultValue,
|
|
248
294
|
context: {
|
|
249
|
-
hint:
|
|
250
|
-
example:
|
|
295
|
+
hint: effectiveJsonMode.commandHint,
|
|
296
|
+
example: effectiveJsonMode.example,
|
|
251
297
|
},
|
|
252
|
-
}, createMetadata(
|
|
298
|
+
}, createMetadata(effectiveJsonMode.commandName, effectiveJsonMode.flags));
|
|
253
299
|
// outputPromptAsJson exits, so this is unreachable
|
|
254
300
|
return '';
|
|
255
301
|
}
|
|
@@ -263,6 +309,39 @@ export class PMOCommand extends Command {
|
|
|
263
309
|
}]);
|
|
264
310
|
return value;
|
|
265
311
|
}
|
|
312
|
+
/**
|
|
313
|
+
* Unified error handler for JSON/interactive modes.
|
|
314
|
+
*
|
|
315
|
+
* Consolidates error handling to avoid message drift between JSON and interactive modes.
|
|
316
|
+
* In JSON mode: outputs structured error JSON and exits
|
|
317
|
+
* In interactive mode: calls this.error() with the message
|
|
318
|
+
*
|
|
319
|
+
* @param code - Error code for JSON output (e.g., 'NOT_FOUND', 'DOCKER_NOT_RUNNING')
|
|
320
|
+
* @param message - Human-readable error message (used in both modes)
|
|
321
|
+
* @param options - Configuration for error handling
|
|
322
|
+
* @returns never - always throws or exits
|
|
323
|
+
*
|
|
324
|
+
* @example
|
|
325
|
+
* ```typescript
|
|
326
|
+
* // Instead of duplicating messages:
|
|
327
|
+
* // if (jsonMode) { outputErrorAsJson('CODE', 'msg', ...); }
|
|
328
|
+
* // this.error('msg');
|
|
329
|
+
*
|
|
330
|
+
* // Use:
|
|
331
|
+
* this.handleError('DOCKER_NOT_RUNNING', 'Docker is not running.', {
|
|
332
|
+
* jsonMode,
|
|
333
|
+
* commandName: 'agent auth',
|
|
334
|
+
* flags,
|
|
335
|
+
* });
|
|
336
|
+
* ```
|
|
337
|
+
*/
|
|
338
|
+
handleError(code, message, options) {
|
|
339
|
+
if (options.jsonMode) {
|
|
340
|
+
outputErrorAsJson(code, message, createMetadata(options.commandName, options.flags));
|
|
341
|
+
this.exit(1);
|
|
342
|
+
}
|
|
343
|
+
this.error(message);
|
|
344
|
+
}
|
|
266
345
|
/**
|
|
267
346
|
* Override run() to delegate to execute() and ensure cleanup
|
|
268
347
|
* Subclasses should implement execute() instead of run()
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Find PMO directory by checking workspace.db for pmo_projects table
|
|
3
3
|
*
|
|
4
4
|
* Search priority:
|
|
5
|
-
* 1. PRLT_HQ_PATH env var (ONLY when DEVCONTAINER=true
|
|
5
|
+
* 1. PRLT_HQ_PATH env var (ONLY when DEVCONTAINER=true or PRLT_TEST_ENV=true)
|
|
6
6
|
* 2. Current directory tree for HQ with PMO
|
|
7
7
|
* 3. Current directory tree for standalone PMO (.pmo/)
|
|
8
8
|
* 4. ~/.proletariat/config.json activeWorkspace (fallback when NOT in any workspace)
|
package/dist/lib/pmo/find-pmo.js
CHANGED
|
@@ -52,7 +52,7 @@ function hasPMOTables(dbPath) {
|
|
|
52
52
|
* Find PMO directory by checking workspace.db for pmo_projects table
|
|
53
53
|
*
|
|
54
54
|
* Search priority:
|
|
55
|
-
* 1. PRLT_HQ_PATH env var (ONLY when DEVCONTAINER=true
|
|
55
|
+
* 1. PRLT_HQ_PATH env var (ONLY when DEVCONTAINER=true or PRLT_TEST_ENV=true)
|
|
56
56
|
* 2. Current directory tree for HQ with PMO
|
|
57
57
|
* 3. Current directory tree for standalone PMO (.pmo/)
|
|
58
58
|
* 4. ~/.proletariat/config.json activeWorkspace (fallback when NOT in any workspace)
|
|
@@ -62,10 +62,10 @@ function hasPMOTables(dbPath) {
|
|
|
62
62
|
* working in different workspaces simultaneously.
|
|
63
63
|
*/
|
|
64
64
|
export function findPMO() {
|
|
65
|
-
// Check PRLT_HQ_PATH environment variable (only in devcontainers)
|
|
65
|
+
// Check PRLT_HQ_PATH environment variable (only in devcontainers or test environments)
|
|
66
66
|
const hqPath = process.env.PRLT_HQ_PATH;
|
|
67
|
-
const
|
|
68
|
-
if (hqPath &&
|
|
67
|
+
const allowEnvHqPath = process.env.DEVCONTAINER === 'true' || process.env.PRLT_TEST_ENV === 'true';
|
|
68
|
+
if (hqPath && allowEnvHqPath) {
|
|
69
69
|
// In devcontainer, PMO is always mounted at /hq/pmo regardless of database value
|
|
70
70
|
// (database stores relative path like "repos/proletariat/pmo" but mount is at /hq/pmo)
|
|
71
71
|
return path.join(hqPath, 'pmo');
|
package/dist/lib/pmo/index.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ export { startWatcher, runWatcherForeground, type WatcherOptions, type WatcherIn
|
|
|
8
8
|
export { createSpecFolders, getSpecFolderPath, getProjectPath, getProductPath, getEpicsPath, } from './create-spec-folders.js';
|
|
9
9
|
export { findPMO } from './find-pmo.js';
|
|
10
10
|
export { getPMOContext, type PMOContext, type GetPMOContextOptions } from './pmo-context.js';
|
|
11
|
-
export { PMOCommand, pmoBaseFlags } from './base-command.js';
|
|
11
|
+
export { PMOCommand, pmoBaseFlags, jsonModeFlags, machineOutputFlags } from './base-command.js';
|
|
12
12
|
export { PMO_TABLES, PMO_TABLE_SCHEMAS, PMO_INDEXES, PMO_SCHEMA_SQL, EXPECTED_TICKET_COLUMNS, validateTicketSchema, } from './schema.js';
|
|
13
13
|
export { BUILTIN_TEMPLATES, getBuiltinTemplate, getPickerTemplates, getColumnsForTemplate, getColumnSettingsForTemplate, } from './templates-builtin.js';
|
|
14
14
|
/**
|
package/dist/lib/pmo/index.js
CHANGED
|
@@ -16,7 +16,7 @@ export { startWatcher, runWatcherForeground, } from './watcher.js';
|
|
|
16
16
|
export { createSpecFolders, getSpecFolderPath, getProjectPath, getProductPath, getEpicsPath, } from './create-spec-folders.js';
|
|
17
17
|
export { findPMO } from './find-pmo.js';
|
|
18
18
|
export { getPMOContext } from './pmo-context.js';
|
|
19
|
-
export { PMOCommand, pmoBaseFlags } from './base-command.js';
|
|
19
|
+
export { PMOCommand, pmoBaseFlags, jsonModeFlags, machineOutputFlags } from './base-command.js';
|
|
20
20
|
export { PMO_TABLES, PMO_TABLE_SCHEMAS, PMO_INDEXES, PMO_SCHEMA_SQL, EXPECTED_TICKET_COLUMNS, validateTicketSchema, } from './schema.js';
|
|
21
21
|
// Re-export template utilities from shared definitions
|
|
22
22
|
export { BUILTIN_TEMPLATES, getBuiltinTemplate, getPickerTemplates, getColumnsForTemplate, getColumnSettingsForTemplate, } from './templates-builtin.js';
|
|
@@ -115,7 +115,8 @@ export function rowToSpec(row) {
|
|
|
115
115
|
status: row.status,
|
|
116
116
|
type: row.type,
|
|
117
117
|
tags: row.tags ? JSON.parse(row.tags) : undefined,
|
|
118
|
-
|
|
118
|
+
// Note: dependsOn is now handled via spec_dependencies table, not inline column
|
|
119
|
+
dependsOn: undefined,
|
|
119
120
|
problem: row.problem || undefined,
|
|
120
121
|
solution: row.solution || undefined,
|
|
121
122
|
decisions: row.decisions || undefined,
|
|
@@ -3,12 +3,17 @@
|
|
|
3
3
|
*
|
|
4
4
|
* This is the main facade that delegates to domain-specific storage modules.
|
|
5
5
|
* Uses the unified workspace.db database with pmo_ prefixed tables.
|
|
6
|
+
*
|
|
7
|
+
* This module now supports Drizzle ORM for type-safe queries while maintaining
|
|
8
|
+
* backward compatibility with raw SQL queries during the migration period.
|
|
6
9
|
*/
|
|
7
10
|
import Database from 'better-sqlite3';
|
|
11
|
+
import { DrizzleDB } from '../../database/drizzle.js';
|
|
8
12
|
import { AcceptanceCriterion, Board, BoardConfig, BoardView, BoardViewFilter, BoardViewFilters, Column, CreateTicketInput, Epic, EpicDependency, EpicDependencyType, EpicFilter, PhaseFilter, PhaseTemplate, PhaseTemplateFilter, PMOStorage, Project, ProjectFilter, ProjectPhase, Roadmap, RoadmapFilter, RoadmapProject, Spec, SpecDependency, SpecDependencyType, SpecFilter, StateCategory, Subtask, SyncResult, SyncStatus, Ticket, TicketDependency, TicketDependencyType, TicketFilter, TicketTemplate, TicketTemplateFilter, WorkAction, WorkActionFilter, Workflow, WorkflowFilter, WorkflowStatus } from '../types.js';
|
|
9
13
|
export declare class SQLiteStorage implements PMOStorage {
|
|
10
14
|
readonly type: "sqlite";
|
|
11
15
|
private db;
|
|
16
|
+
private drizzle;
|
|
12
17
|
private dbPath;
|
|
13
18
|
private projectStorage;
|
|
14
19
|
private ticketStorage;
|
|
@@ -28,6 +33,10 @@ export declare class SQLiteStorage implements PMOStorage {
|
|
|
28
33
|
* Get the underlying database connection.
|
|
29
34
|
*/
|
|
30
35
|
getDatabase(): Database.Database;
|
|
36
|
+
/**
|
|
37
|
+
* Get the Drizzle ORM database connection for type-safe queries.
|
|
38
|
+
*/
|
|
39
|
+
getDrizzle(): DrizzleDB;
|
|
31
40
|
/**
|
|
32
41
|
* Ensure PMO tables exist in the database.
|
|
33
42
|
*/
|