@wundr.io/cli 1.0.10 → 1.0.12
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/bin/wundr.js +8 -4
- package/package.json +23 -23
- package/src/ai/ai-service.ts +16 -17
- package/src/ai/claude-client.ts +16 -16
- package/src/ai/conversation-manager.ts +29 -29
- package/src/cli.ts +4 -4
- package/src/commands/ai.ts +246 -78
- package/src/commands/alignment.ts +74 -74
- package/src/commands/analyze-optimized.ts +111 -78
- package/src/commands/analyze.ts +14 -14
- package/src/commands/batch.ts +179 -42
- package/src/commands/chat.ts +37 -30
- package/src/commands/claude-init.ts +41 -45
- package/src/commands/claude-setup.ts +204 -119
- package/src/commands/computer-setup.ts +85 -43
- package/src/commands/create-command.ts +4 -4
- package/src/commands/create.ts +27 -27
- package/src/commands/dashboard.ts +24 -24
- package/src/commands/govern.ts +25 -25
- package/src/commands/governance.ts +34 -34
- package/src/commands/guardian.ts +56 -56
- package/src/commands/init.ts +25 -22
- package/src/commands/orchestrator.ts +68 -41
- package/src/commands/performance-optimizer.ts +34 -35
- package/src/commands/plugins.ts +27 -27
- package/src/commands/project-update.ts +175 -72
- package/src/commands/rag.ts +185 -78
- package/src/commands/session.ts +35 -35
- package/src/commands/setup.ts +40 -344
- package/src/commands/test-init.ts +3 -3
- package/src/commands/test.ts +4 -4
- package/src/commands/watch.ts +28 -29
- package/src/commands/worktree.ts +49 -49
- package/src/context/context-manager.ts +10 -10
- package/src/context/session-manager.ts +41 -41
- package/src/framework/command-interface.ts +520 -0
- package/src/framework/command-registry.ts +942 -0
- package/src/framework/completion-exporter.ts +383 -0
- package/src/framework/debug-logger.ts +519 -0
- package/src/framework/error-handler.ts +867 -0
- package/src/framework/help-generator.ts +540 -0
- package/src/framework/index.ts +169 -0
- package/src/framework/interactive-repl.ts +703 -0
- package/src/framework/output-formatter.ts +834 -0
- package/src/framework/progress-manager.ts +539 -0
- package/src/index.ts +4 -4
- package/src/interactive/interactive-mode.ts +16 -16
- package/src/lib/conflict-resolution.ts +799 -9
- package/src/lib/merge-strategy.ts +529 -7
- package/src/lib/safety-mechanisms.ts +422 -18
- package/src/lib/state-detection.ts +1015 -13
- package/src/nlp/command-mapper.ts +29 -29
- package/src/nlp/command-parser.ts +17 -17
- package/src/nlp/intent-classifier.ts +7 -7
- package/src/nlp/intent-parser.ts +54 -52
- package/src/plugins/plugin-manager.ts +61 -39
- package/src/tests/computer-setup-integration.test.ts +46 -15
- package/src/types/modules.d.ts +424 -1
- package/src/utils/backup-rollback-manager.ts +11 -8
- package/src/utils/config-manager.ts +3 -3
- package/src/utils/error-handler.ts +2 -2
- package/src/utils/logger.ts +22 -22
- package/templates/batch/ci-cd.yaml +7 -7
- package/test-suites/api/health.spec.ts +20 -23
- package/test-suites/helpers/test-config.ts +14 -13
- package/test-suites/ui/accessibility.spec.ts +27 -22
- package/test-suites/ui/smoke.spec.ts +26 -21
- package/LICENSE +0 -21
- package/dist/ai/ai-service.d.ts +0 -152
- package/dist/ai/ai-service.d.ts.map +0 -1
- package/dist/ai/ai-service.js +0 -430
- package/dist/ai/ai-service.js.map +0 -1
- package/dist/ai/claude-client.d.ts +0 -130
- package/dist/ai/claude-client.d.ts.map +0 -1
- package/dist/ai/claude-client.js +0 -340
- package/dist/ai/claude-client.js.map +0 -1
- package/dist/ai/conversation-manager.d.ts +0 -164
- package/dist/ai/conversation-manager.d.ts.map +0 -1
- package/dist/ai/conversation-manager.js +0 -614
- package/dist/ai/conversation-manager.js.map +0 -1
- package/dist/ai/index.d.ts +0 -5
- package/dist/ai/index.d.ts.map +0 -1
- package/dist/ai/index.js +0 -8
- package/dist/ai/index.js.map +0 -1
- package/dist/cli.d.ts +0 -36
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js +0 -192
- package/dist/cli.js.map +0 -1
- package/dist/commands/ai.d.ts +0 -89
- package/dist/commands/ai.d.ts.map +0 -1
- package/dist/commands/ai.js +0 -799
- package/dist/commands/ai.js.map +0 -1
- package/dist/commands/alignment.d.ts +0 -78
- package/dist/commands/alignment.d.ts.map +0 -1
- package/dist/commands/alignment.js +0 -817
- package/dist/commands/alignment.js.map +0 -1
- package/dist/commands/analyze-optimized.d.ts +0 -14
- package/dist/commands/analyze-optimized.d.ts.map +0 -1
- package/dist/commands/analyze-optimized.js +0 -600
- package/dist/commands/analyze-optimized.js.map +0 -1
- package/dist/commands/analyze.d.ts +0 -65
- package/dist/commands/analyze.d.ts.map +0 -1
- package/dist/commands/analyze.js +0 -435
- package/dist/commands/analyze.js.map +0 -1
- package/dist/commands/batch.d.ts +0 -71
- package/dist/commands/batch.d.ts.map +0 -1
- package/dist/commands/batch.js +0 -738
- package/dist/commands/batch.js.map +0 -1
- package/dist/commands/chat.d.ts +0 -71
- package/dist/commands/chat.d.ts.map +0 -1
- package/dist/commands/chat.js +0 -674
- package/dist/commands/chat.js.map +0 -1
- package/dist/commands/claude-init.d.ts +0 -28
- package/dist/commands/claude-init.d.ts.map +0 -1
- package/dist/commands/claude-init.js +0 -591
- package/dist/commands/claude-init.js.map +0 -1
- package/dist/commands/claude-setup.d.ts +0 -119
- package/dist/commands/claude-setup.d.ts.map +0 -1
- package/dist/commands/claude-setup.js +0 -1073
- package/dist/commands/claude-setup.js.map +0 -1
- package/dist/commands/computer-setup-commands.d.ts +0 -53
- package/dist/commands/computer-setup-commands.d.ts.map +0 -1
- package/dist/commands/computer-setup-commands.js +0 -705
- package/dist/commands/computer-setup-commands.js.map +0 -1
- package/dist/commands/computer-setup.d.ts +0 -7
- package/dist/commands/computer-setup.d.ts.map +0 -1
- package/dist/commands/computer-setup.js +0 -849
- package/dist/commands/computer-setup.js.map +0 -1
- package/dist/commands/create-command.d.ts +0 -7
- package/dist/commands/create-command.d.ts.map +0 -1
- package/dist/commands/create-command.js +0 -158
- package/dist/commands/create-command.js.map +0 -1
- package/dist/commands/create.d.ts +0 -74
- package/dist/commands/create.d.ts.map +0 -1
- package/dist/commands/create.js +0 -556
- package/dist/commands/create.js.map +0 -1
- package/dist/commands/dashboard.d.ts +0 -91
- package/dist/commands/dashboard.d.ts.map +0 -1
- package/dist/commands/dashboard.js +0 -538
- package/dist/commands/dashboard.js.map +0 -1
- package/dist/commands/govern.d.ts +0 -70
- package/dist/commands/govern.d.ts.map +0 -1
- package/dist/commands/govern.js +0 -481
- package/dist/commands/govern.js.map +0 -1
- package/dist/commands/governance.d.ts +0 -17
- package/dist/commands/governance.d.ts.map +0 -1
- package/dist/commands/governance.js +0 -703
- package/dist/commands/governance.js.map +0 -1
- package/dist/commands/guardian.d.ts +0 -20
- package/dist/commands/guardian.d.ts.map +0 -1
- package/dist/commands/guardian.js +0 -597
- package/dist/commands/guardian.js.map +0 -1
- package/dist/commands/init.d.ts +0 -59
- package/dist/commands/init.d.ts.map +0 -1
- package/dist/commands/init.js +0 -650
- package/dist/commands/init.js.map +0 -1
- package/dist/commands/orchestrator.d.ts +0 -7
- package/dist/commands/orchestrator.d.ts.map +0 -1
- package/dist/commands/orchestrator.js +0 -571
- package/dist/commands/orchestrator.js.map +0 -1
- package/dist/commands/performance-optimizer.d.ts +0 -30
- package/dist/commands/performance-optimizer.d.ts.map +0 -1
- package/dist/commands/performance-optimizer.js +0 -650
- package/dist/commands/performance-optimizer.js.map +0 -1
- package/dist/commands/plugins.d.ts +0 -87
- package/dist/commands/plugins.d.ts.map +0 -1
- package/dist/commands/plugins.js +0 -685
- package/dist/commands/plugins.js.map +0 -1
- package/dist/commands/rag.d.ts +0 -7
- package/dist/commands/rag.d.ts.map +0 -1
- package/dist/commands/rag.js +0 -748
- package/dist/commands/rag.js.map +0 -1
- package/dist/commands/session.d.ts +0 -41
- package/dist/commands/session.d.ts.map +0 -1
- package/dist/commands/session.js +0 -441
- package/dist/commands/session.js.map +0 -1
- package/dist/commands/setup.d.ts +0 -29
- package/dist/commands/setup.d.ts.map +0 -1
- package/dist/commands/setup.js +0 -397
- package/dist/commands/setup.js.map +0 -1
- package/dist/commands/test-init.d.ts +0 -9
- package/dist/commands/test-init.d.ts.map +0 -1
- package/dist/commands/test-init.js +0 -222
- package/dist/commands/test-init.js.map +0 -1
- package/dist/commands/test.d.ts +0 -25
- package/dist/commands/test.d.ts.map +0 -1
- package/dist/commands/test.js +0 -217
- package/dist/commands/test.js.map +0 -1
- package/dist/commands/vp.d.ts +0 -7
- package/dist/commands/vp.d.ts.map +0 -1
- package/dist/commands/vp.js +0 -571
- package/dist/commands/vp.js.map +0 -1
- package/dist/commands/watch.d.ts +0 -76
- package/dist/commands/watch.d.ts.map +0 -1
- package/dist/commands/watch.js +0 -613
- package/dist/commands/watch.js.map +0 -1
- package/dist/commands/worktree.d.ts +0 -63
- package/dist/commands/worktree.d.ts.map +0 -1
- package/dist/commands/worktree.js +0 -774
- package/dist/commands/worktree.js.map +0 -1
- package/dist/context/context-manager.d.ts +0 -155
- package/dist/context/context-manager.d.ts.map +0 -1
- package/dist/context/context-manager.js +0 -383
- package/dist/context/context-manager.js.map +0 -1
- package/dist/context/index.d.ts +0 -3
- package/dist/context/index.d.ts.map +0 -1
- package/dist/context/index.js +0 -6
- package/dist/context/index.js.map +0 -1
- package/dist/context/session-manager.d.ts +0 -207
- package/dist/context/session-manager.d.ts.map +0 -1
- package/dist/context/session-manager.js +0 -686
- package/dist/context/session-manager.js.map +0 -1
- package/dist/index.d.ts +0 -8
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -51
- package/dist/index.js.map +0 -1
- package/dist/interactive/interactive-mode.d.ts +0 -76
- package/dist/interactive/interactive-mode.d.ts.map +0 -1
- package/dist/interactive/interactive-mode.js +0 -732
- package/dist/interactive/interactive-mode.js.map +0 -1
- package/dist/nlp/command-mapper.d.ts +0 -174
- package/dist/nlp/command-mapper.d.ts.map +0 -1
- package/dist/nlp/command-mapper.js +0 -624
- package/dist/nlp/command-mapper.js.map +0 -1
- package/dist/nlp/command-parser.d.ts +0 -106
- package/dist/nlp/command-parser.d.ts.map +0 -1
- package/dist/nlp/command-parser.js +0 -417
- package/dist/nlp/command-parser.js.map +0 -1
- package/dist/nlp/index.d.ts +0 -5
- package/dist/nlp/index.d.ts.map +0 -1
- package/dist/nlp/index.js +0 -8
- package/dist/nlp/index.js.map +0 -1
- package/dist/nlp/intent-classifier.d.ts +0 -59
- package/dist/nlp/intent-classifier.d.ts.map +0 -1
- package/dist/nlp/intent-classifier.js +0 -384
- package/dist/nlp/intent-classifier.js.map +0 -1
- package/dist/nlp/intent-parser.d.ts +0 -152
- package/dist/nlp/intent-parser.d.ts.map +0 -1
- package/dist/nlp/intent-parser.js +0 -744
- package/dist/nlp/intent-parser.js.map +0 -1
- package/dist/plugins/plugin-manager.d.ts +0 -120
- package/dist/plugins/plugin-manager.d.ts.map +0 -1
- package/dist/plugins/plugin-manager.js +0 -595
- package/dist/plugins/plugin-manager.js.map +0 -1
- package/dist/types/index.d.ts +0 -224
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/index.js +0 -3
- package/dist/types/index.js.map +0 -1
- package/dist/utils/backup-rollback-manager.d.ts +0 -72
- package/dist/utils/backup-rollback-manager.d.ts.map +0 -1
- package/dist/utils/backup-rollback-manager.js +0 -289
- package/dist/utils/backup-rollback-manager.js.map +0 -1
- package/dist/utils/claude-config-installer.d.ts +0 -98
- package/dist/utils/claude-config-installer.d.ts.map +0 -1
- package/dist/utils/claude-config-installer.js +0 -678
- package/dist/utils/claude-config-installer.js.map +0 -1
- package/dist/utils/config-manager.d.ts +0 -73
- package/dist/utils/config-manager.d.ts.map +0 -1
- package/dist/utils/config-manager.js +0 -339
- package/dist/utils/config-manager.js.map +0 -1
- package/dist/utils/error-handler.d.ts +0 -46
- package/dist/utils/error-handler.d.ts.map +0 -1
- package/dist/utils/error-handler.js +0 -169
- package/dist/utils/error-handler.js.map +0 -1
- package/dist/utils/logger.d.ts +0 -25
- package/dist/utils/logger.d.ts.map +0 -1
- package/dist/utils/logger.js +0 -105
- package/dist/utils/logger.js.map +0 -1
- package/src/commands/computer-setup-commands.ts +0 -872
|
@@ -0,0 +1,520 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Command Interface - Core types and contracts for the Wundr CLI framework.
|
|
3
|
+
*
|
|
4
|
+
* Every CLI command implements CommandDefinition. This provides:
|
|
5
|
+
* - Consistent argument/option typing via generics
|
|
6
|
+
* - Built-in validation before execution
|
|
7
|
+
* - Structured output via CommandResult
|
|
8
|
+
* - Optional rollback on failure
|
|
9
|
+
* - Metadata for auto-generated help text and shell completions
|
|
10
|
+
*
|
|
11
|
+
* @module framework/command-interface
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import type { Command as CommanderCommand } from 'commander';
|
|
15
|
+
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
// Command Categories
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Grouping categories for commands. Used in help text and completion scripts.
|
|
22
|
+
*/
|
|
23
|
+
export type CommandCategory =
|
|
24
|
+
| 'daemon'
|
|
25
|
+
| 'agent'
|
|
26
|
+
| 'memory'
|
|
27
|
+
| 'config'
|
|
28
|
+
| 'setup'
|
|
29
|
+
| 'batch'
|
|
30
|
+
| 'plugin'
|
|
31
|
+
| 'governance'
|
|
32
|
+
| 'analysis'
|
|
33
|
+
| 'development'
|
|
34
|
+
| 'monitoring';
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Human-readable labels for each category.
|
|
38
|
+
*/
|
|
39
|
+
export const CATEGORY_LABELS: Record<CommandCategory, string> = {
|
|
40
|
+
daemon: 'Daemon Management',
|
|
41
|
+
agent: 'Agent Management',
|
|
42
|
+
memory: 'Memory & RAG',
|
|
43
|
+
config: 'Configuration',
|
|
44
|
+
setup: 'Machine Setup',
|
|
45
|
+
batch: 'Batch Operations',
|
|
46
|
+
plugin: 'Plugin Management',
|
|
47
|
+
governance: 'Governance & Compliance',
|
|
48
|
+
analysis: 'Code Analysis',
|
|
49
|
+
development: 'Development Tools',
|
|
50
|
+
monitoring: 'Monitoring & Dashboard',
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
// ---------------------------------------------------------------------------
|
|
54
|
+
// Argument & Option Definitions
|
|
55
|
+
// ---------------------------------------------------------------------------
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Positional argument definition for a command.
|
|
59
|
+
*/
|
|
60
|
+
export interface ArgumentDefinition {
|
|
61
|
+
/** Argument name (used in help text and as the key in parsed args) */
|
|
62
|
+
name: string;
|
|
63
|
+
|
|
64
|
+
/** Human-readable description */
|
|
65
|
+
description: string;
|
|
66
|
+
|
|
67
|
+
/** Whether this argument is required */
|
|
68
|
+
required?: boolean;
|
|
69
|
+
|
|
70
|
+
/** Default value if not provided */
|
|
71
|
+
defaultValue?: string;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Optional function that returns valid completions for this argument.
|
|
75
|
+
* Used by shell completion generation.
|
|
76
|
+
*/
|
|
77
|
+
completions?: () => Promise<string[]>;
|
|
78
|
+
|
|
79
|
+
/** Variadic argument (collects remaining args into array) */
|
|
80
|
+
variadic?: boolean;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Option (flag) definition for a command.
|
|
85
|
+
*/
|
|
86
|
+
export interface OptionDefinition {
|
|
87
|
+
/** Flag specification in Commander.js format, e.g. '-p, --port <number>' */
|
|
88
|
+
flags: string;
|
|
89
|
+
|
|
90
|
+
/** Human-readable description */
|
|
91
|
+
description: string;
|
|
92
|
+
|
|
93
|
+
/** Default value */
|
|
94
|
+
defaultValue?: unknown;
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Whether this option is required.
|
|
98
|
+
* Commander marks it required; missing value causes an error before execute().
|
|
99
|
+
*/
|
|
100
|
+
required?: boolean;
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Allowed values. If set, Commander validates the value is in this set.
|
|
104
|
+
*/
|
|
105
|
+
choices?: string[];
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Environment variable that can provide this option's value.
|
|
109
|
+
* Checked if the option is not passed on the command line.
|
|
110
|
+
*/
|
|
111
|
+
envVar?: string;
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Optional function that returns valid completions for this option.
|
|
115
|
+
* Used by shell completion generation.
|
|
116
|
+
*/
|
|
117
|
+
completions?: () => Promise<string[]>;
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Whether this option conflicts with another option.
|
|
121
|
+
* Validated before execute().
|
|
122
|
+
*/
|
|
123
|
+
conflicts?: string[];
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Example usage shown in help text.
|
|
128
|
+
*/
|
|
129
|
+
export interface CommandExample {
|
|
130
|
+
/** The command invocation */
|
|
131
|
+
command: string;
|
|
132
|
+
|
|
133
|
+
/** What this example demonstrates */
|
|
134
|
+
description: string;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// ---------------------------------------------------------------------------
|
|
138
|
+
// Validation
|
|
139
|
+
// ---------------------------------------------------------------------------
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Result of command argument/option validation.
|
|
143
|
+
*/
|
|
144
|
+
export interface ValidationResult {
|
|
145
|
+
/** Whether validation passed */
|
|
146
|
+
valid: boolean;
|
|
147
|
+
|
|
148
|
+
/** Validation error messages (empty when valid) */
|
|
149
|
+
errors: ValidationError[];
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* A single validation error with field context.
|
|
154
|
+
*/
|
|
155
|
+
export interface ValidationError {
|
|
156
|
+
/** Which field (argument or option name) failed validation */
|
|
157
|
+
field: string;
|
|
158
|
+
|
|
159
|
+
/** Human-readable error message */
|
|
160
|
+
message: string;
|
|
161
|
+
|
|
162
|
+
/** Suggestion for how to fix the error */
|
|
163
|
+
suggestion?: string;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Helper to create a passing validation result.
|
|
168
|
+
*/
|
|
169
|
+
export function validationOk(): ValidationResult {
|
|
170
|
+
return { valid: true, errors: [] };
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Helper to create a failing validation result.
|
|
175
|
+
*/
|
|
176
|
+
export function validationFail(...errors: ValidationError[]): ValidationResult {
|
|
177
|
+
return { valid: false, errors };
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// ---------------------------------------------------------------------------
|
|
181
|
+
// Command Context
|
|
182
|
+
// ---------------------------------------------------------------------------
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Runtime context passed to every command's execute() method.
|
|
186
|
+
*
|
|
187
|
+
* The context is constructed by the CLI runner and contains references
|
|
188
|
+
* to shared services. Commands should NOT import singletons directly;
|
|
189
|
+
* instead they receive everything through context for testability.
|
|
190
|
+
*/
|
|
191
|
+
export interface CommandContext {
|
|
192
|
+
/** Parsed global options (--verbose, --quiet, --json, etc.) */
|
|
193
|
+
globalOptions: GlobalOptions;
|
|
194
|
+
|
|
195
|
+
/** Logger instance respecting current verbosity */
|
|
196
|
+
logger: ContextLogger;
|
|
197
|
+
|
|
198
|
+
/** Output formatter for consistent display */
|
|
199
|
+
formatter: OutputFormatterInterface;
|
|
200
|
+
|
|
201
|
+
/** Configuration manager */
|
|
202
|
+
config: ConfigManagerInterface;
|
|
203
|
+
|
|
204
|
+
/** Current working directory */
|
|
205
|
+
cwd: string;
|
|
206
|
+
|
|
207
|
+
/** Whether running in a CI environment */
|
|
208
|
+
ci: boolean;
|
|
209
|
+
|
|
210
|
+
/** Whether stdout is a TTY (affects interactive features) */
|
|
211
|
+
isTTY: boolean;
|
|
212
|
+
|
|
213
|
+
/** Abort signal for graceful cancellation */
|
|
214
|
+
signal?: AbortSignal;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Global CLI options inherited by all commands.
|
|
219
|
+
*/
|
|
220
|
+
export interface GlobalOptions {
|
|
221
|
+
verbose: boolean;
|
|
222
|
+
quiet: boolean;
|
|
223
|
+
json: boolean;
|
|
224
|
+
noColor: boolean;
|
|
225
|
+
dryRun: boolean;
|
|
226
|
+
config?: string;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Minimal logger interface for command context.
|
|
231
|
+
*/
|
|
232
|
+
export interface ContextLogger {
|
|
233
|
+
debug(message: string, ...args: unknown[]): void;
|
|
234
|
+
info(message: string, ...args: unknown[]): void;
|
|
235
|
+
warn(message: string, ...args: unknown[]): void;
|
|
236
|
+
error(message: string, ...args: unknown[]): void;
|
|
237
|
+
success(message: string, ...args: unknown[]): void;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Minimal output formatter interface for command context.
|
|
242
|
+
* Full implementation is in output-formatter.ts.
|
|
243
|
+
*/
|
|
244
|
+
export interface OutputFormatterInterface {
|
|
245
|
+
table(data: Record<string, unknown>[], options?: unknown): string;
|
|
246
|
+
json(data: unknown, pretty?: boolean): string;
|
|
247
|
+
keyValue(data: Record<string, unknown>): string;
|
|
248
|
+
list(items: string[], ordered?: boolean): string;
|
|
249
|
+
status(state: string, label: string): string;
|
|
250
|
+
progressBar(current: number, total: number, width?: number): string;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Minimal config manager interface for command context.
|
|
255
|
+
*/
|
|
256
|
+
export interface ConfigManagerInterface {
|
|
257
|
+
get<T = unknown>(key: string): T | undefined;
|
|
258
|
+
set(key: string, value: unknown): void;
|
|
259
|
+
loadConfig(path?: string): Promise<void>;
|
|
260
|
+
saveConfig(): Promise<void>;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// ---------------------------------------------------------------------------
|
|
264
|
+
// Command Result
|
|
265
|
+
// ---------------------------------------------------------------------------
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Structured result returned by every command's execute() method.
|
|
269
|
+
*
|
|
270
|
+
* Commands return data, not formatted strings. The CLI runner uses
|
|
271
|
+
* the result + global options to determine final output format.
|
|
272
|
+
*/
|
|
273
|
+
export interface CommandResult<T = unknown> {
|
|
274
|
+
/** Exit code. 0 = success, non-zero = failure. */
|
|
275
|
+
exitCode: number;
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Structured data payload. When --json is passed, this is serialized
|
|
279
|
+
* directly. Otherwise the CLI runner uses the formatter.
|
|
280
|
+
*/
|
|
281
|
+
data?: T;
|
|
282
|
+
|
|
283
|
+
/** Human-readable message for non-JSON output */
|
|
284
|
+
message?: string;
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Warnings that should be displayed but don't constitute failure.
|
|
288
|
+
*/
|
|
289
|
+
warnings?: string[];
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Helper to create a success result.
|
|
294
|
+
*/
|
|
295
|
+
export function commandSuccess<T>(
|
|
296
|
+
data?: T,
|
|
297
|
+
message?: string
|
|
298
|
+
): CommandResult<T> {
|
|
299
|
+
return { exitCode: 0, data, message };
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* Helper to create a failure result.
|
|
304
|
+
*/
|
|
305
|
+
export function commandFailure(
|
|
306
|
+
message: string,
|
|
307
|
+
exitCode: number = 1
|
|
308
|
+
): CommandResult {
|
|
309
|
+
return { exitCode, message };
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// ---------------------------------------------------------------------------
|
|
313
|
+
// Command Definition
|
|
314
|
+
// ---------------------------------------------------------------------------
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* The core interface that every CLI command must implement.
|
|
318
|
+
*
|
|
319
|
+
* @typeParam TArgs - Shape of parsed positional arguments
|
|
320
|
+
* @typeParam TOpts - Shape of parsed options
|
|
321
|
+
* @typeParam TResult - Shape of the data payload in CommandResult
|
|
322
|
+
*
|
|
323
|
+
* @example
|
|
324
|
+
* ```typescript
|
|
325
|
+
* const statusCommand: CommandDefinition<{}, { json?: boolean }, DaemonStatus> = {
|
|
326
|
+
* name: 'status',
|
|
327
|
+
* description: 'Show orchestrator daemon status',
|
|
328
|
+
* category: 'daemon',
|
|
329
|
+
* options: [
|
|
330
|
+
* { flags: '--json', description: 'Output as JSON' },
|
|
331
|
+
* ],
|
|
332
|
+
* examples: [
|
|
333
|
+
* { command: 'wundr status', description: 'Show daemon status' },
|
|
334
|
+
* { command: 'wundr status --json', description: 'Get status as JSON' },
|
|
335
|
+
* ],
|
|
336
|
+
* async execute(_args, options, context) {
|
|
337
|
+
* const status = await getDaemonStatus();
|
|
338
|
+
* return commandSuccess(status, status.running ? 'Daemon is running' : 'Daemon is stopped');
|
|
339
|
+
* },
|
|
340
|
+
* };
|
|
341
|
+
* ```
|
|
342
|
+
*/
|
|
343
|
+
export interface CommandDefinition<
|
|
344
|
+
TArgs = Record<string, unknown>,
|
|
345
|
+
TOpts = Record<string, unknown>,
|
|
346
|
+
TResult = unknown,
|
|
347
|
+
> {
|
|
348
|
+
/** Unique command name. Use colon-separated for subcommands: 'agent:list' */
|
|
349
|
+
name: string;
|
|
350
|
+
|
|
351
|
+
/** Human-readable description shown in help text */
|
|
352
|
+
description: string;
|
|
353
|
+
|
|
354
|
+
/** Category for grouping in help output */
|
|
355
|
+
category?: CommandCategory;
|
|
356
|
+
|
|
357
|
+
/** Alternative names for this command */
|
|
358
|
+
aliases?: string[];
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* Whether this command is hidden from help text.
|
|
362
|
+
* Useful for deprecated or internal commands.
|
|
363
|
+
*/
|
|
364
|
+
hidden?: boolean;
|
|
365
|
+
|
|
366
|
+
/** Positional argument definitions */
|
|
367
|
+
arguments?: ArgumentDefinition[];
|
|
368
|
+
|
|
369
|
+
/** Option/flag definitions */
|
|
370
|
+
options?: OptionDefinition[];
|
|
371
|
+
|
|
372
|
+
/** Example invocations shown in help text */
|
|
373
|
+
examples?: CommandExample[];
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* Subcommands nested under this command.
|
|
377
|
+
* For example, 'agent' has subcommands 'list', 'spawn', 'stop'.
|
|
378
|
+
*/
|
|
379
|
+
subcommands?: CommandDefinition[];
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* Validate parsed arguments and options before execution.
|
|
383
|
+
*
|
|
384
|
+
* Return `validationOk()` to proceed, or `validationFail(...)` to abort
|
|
385
|
+
* with a helpful error message. If not provided, validation always passes.
|
|
386
|
+
*
|
|
387
|
+
* @param args - Parsed positional arguments
|
|
388
|
+
* @param options - Parsed options
|
|
389
|
+
* @param context - Command execution context
|
|
390
|
+
*/
|
|
391
|
+
validate?(
|
|
392
|
+
args: TArgs,
|
|
393
|
+
options: TOpts,
|
|
394
|
+
context: CommandContext
|
|
395
|
+
): ValidationResult | Promise<ValidationResult>;
|
|
396
|
+
|
|
397
|
+
/**
|
|
398
|
+
* Execute the command.
|
|
399
|
+
*
|
|
400
|
+
* @param args - Parsed positional arguments
|
|
401
|
+
* @param options - Parsed options
|
|
402
|
+
* @param context - Command execution context
|
|
403
|
+
* @returns Structured result with exit code and optional data
|
|
404
|
+
*/
|
|
405
|
+
execute(
|
|
406
|
+
args: TArgs,
|
|
407
|
+
options: TOpts,
|
|
408
|
+
context: CommandContext
|
|
409
|
+
): Promise<CommandResult<TResult>>;
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* Optional cleanup when execute() throws or returns a non-zero exit code.
|
|
413
|
+
* Use this to undo partial changes (e.g., remove a PID file on start failure).
|
|
414
|
+
*
|
|
415
|
+
* @param error - The error that caused the rollback
|
|
416
|
+
* @param context - Command execution context
|
|
417
|
+
*/
|
|
418
|
+
rollback?(error: Error, context: CommandContext): Promise<void>;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
// ---------------------------------------------------------------------------
|
|
422
|
+
// Command Lifecycle Hooks
|
|
423
|
+
// ---------------------------------------------------------------------------
|
|
424
|
+
|
|
425
|
+
/**
|
|
426
|
+
* Hook that runs before or after command execution.
|
|
427
|
+
*/
|
|
428
|
+
export interface CommandHook {
|
|
429
|
+
/** When to run this hook */
|
|
430
|
+
phase: 'preValidate' | 'postValidate' | 'preExecute' | 'postExecute';
|
|
431
|
+
|
|
432
|
+
/**
|
|
433
|
+
* Optional filter: only run this hook for specific commands.
|
|
434
|
+
* If not provided, the hook runs for all commands.
|
|
435
|
+
*/
|
|
436
|
+
commands?: string[];
|
|
437
|
+
|
|
438
|
+
/**
|
|
439
|
+
* The hook handler. Return false to abort the pipeline (preValidate/preExecute only).
|
|
440
|
+
*/
|
|
441
|
+
handler(
|
|
442
|
+
command: CommandDefinition,
|
|
443
|
+
context: CommandContext,
|
|
444
|
+
result?: CommandResult
|
|
445
|
+
): Promise<void | boolean>;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
// ---------------------------------------------------------------------------
|
|
449
|
+
// Command Module
|
|
450
|
+
// ---------------------------------------------------------------------------
|
|
451
|
+
|
|
452
|
+
/**
|
|
453
|
+
* A command module is the unit of auto-discovery.
|
|
454
|
+
*
|
|
455
|
+
* Each file in the commands/ directory can export a `CommandModule` to be
|
|
456
|
+
* automatically registered by the `CommandRegistry`.
|
|
457
|
+
*
|
|
458
|
+
* @example
|
|
459
|
+
* ```typescript
|
|
460
|
+
* // commands/status.ts
|
|
461
|
+
* export const module: CommandModule = {
|
|
462
|
+
* command: statusCommand,
|
|
463
|
+
* hooks: [telemetryHook],
|
|
464
|
+
* };
|
|
465
|
+
* ```
|
|
466
|
+
*/
|
|
467
|
+
export interface CommandModule {
|
|
468
|
+
/** The primary command definition */
|
|
469
|
+
command: CommandDefinition;
|
|
470
|
+
|
|
471
|
+
/** Optional lifecycle hooks specific to this command */
|
|
472
|
+
hooks?: CommandHook[];
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
// ---------------------------------------------------------------------------
|
|
476
|
+
// Legacy Adapter
|
|
477
|
+
// ---------------------------------------------------------------------------
|
|
478
|
+
|
|
479
|
+
/**
|
|
480
|
+
* Adapter for wrapping existing Commander.js command functions into the
|
|
481
|
+
* CommandDefinition interface. This enables incremental migration.
|
|
482
|
+
*
|
|
483
|
+
* @param name - Command name
|
|
484
|
+
* @param description - Command description
|
|
485
|
+
* @param factory - Existing factory function that returns a Commander.Command
|
|
486
|
+
* @param category - Optional category
|
|
487
|
+
*
|
|
488
|
+
* @example
|
|
489
|
+
* ```typescript
|
|
490
|
+
* const wrapped = wrapLegacyCommand(
|
|
491
|
+
* 'orchestrator',
|
|
492
|
+
* 'Manage the Orchestrator Daemon',
|
|
493
|
+
* createOrchestratorCommand,
|
|
494
|
+
* 'daemon'
|
|
495
|
+
* );
|
|
496
|
+
* registry.register(wrapped);
|
|
497
|
+
* ```
|
|
498
|
+
*/
|
|
499
|
+
export function wrapLegacyCommand(
|
|
500
|
+
name: string,
|
|
501
|
+
description: string,
|
|
502
|
+
factory: () => CommanderCommand,
|
|
503
|
+
category?: CommandCategory
|
|
504
|
+
): CommandDefinition {
|
|
505
|
+
return {
|
|
506
|
+
name,
|
|
507
|
+
description,
|
|
508
|
+
category,
|
|
509
|
+
hidden: false,
|
|
510
|
+
async execute(_args, _options, context) {
|
|
511
|
+
// Legacy commands handle their own output.
|
|
512
|
+
// The wrapper just ensures they integrate with the registry.
|
|
513
|
+
context.logger.debug(`Delegating to legacy command: ${name}`);
|
|
514
|
+
return { exitCode: 0, message: `Legacy command ${name} executed` };
|
|
515
|
+
},
|
|
516
|
+
// The actual Commander.Command is attached by the registry during buildProgram()
|
|
517
|
+
// via the _legacyFactory property.
|
|
518
|
+
_legacyFactory: factory,
|
|
519
|
+
} as CommandDefinition & { _legacyFactory: () => CommanderCommand };
|
|
520
|
+
}
|