@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,539 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Progress Manager - Progress bars and spinners for long-running operations.
|
|
3
|
+
*
|
|
4
|
+
* Provides:
|
|
5
|
+
* - Single and multi-bar progress tracking
|
|
6
|
+
* - Spinner for indeterminate operations
|
|
7
|
+
* - ETA calculation
|
|
8
|
+
* - Step-based progress for sequential operations
|
|
9
|
+
* - Pipe-safe (no-op when stdout is not a TTY)
|
|
10
|
+
*
|
|
11
|
+
* @module framework/progress-manager
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import chalk from 'chalk';
|
|
15
|
+
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
// Types
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Configuration for a progress bar.
|
|
22
|
+
*/
|
|
23
|
+
export interface ProgressBarOptions {
|
|
24
|
+
/** Total number of units. */
|
|
25
|
+
total: number;
|
|
26
|
+
|
|
27
|
+
/** Bar width in characters. Defaults to 30. */
|
|
28
|
+
width?: number;
|
|
29
|
+
|
|
30
|
+
/** Label displayed before the bar. */
|
|
31
|
+
label?: string;
|
|
32
|
+
|
|
33
|
+
/** Filled character. Defaults to '='. */
|
|
34
|
+
filledChar?: string;
|
|
35
|
+
|
|
36
|
+
/** Empty character. Defaults to '-'. */
|
|
37
|
+
emptyChar?: string;
|
|
38
|
+
|
|
39
|
+
/** Show percentage. Defaults to true. */
|
|
40
|
+
showPercentage?: boolean;
|
|
41
|
+
|
|
42
|
+
/** Show ETA. Defaults to true. */
|
|
43
|
+
showETA?: boolean;
|
|
44
|
+
|
|
45
|
+
/** Show count (current/total). Defaults to true. */
|
|
46
|
+
showCount?: boolean;
|
|
47
|
+
|
|
48
|
+
/** Custom format function. */
|
|
49
|
+
format?: (state: ProgressState) => string;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Current state of a progress bar.
|
|
54
|
+
*/
|
|
55
|
+
export interface ProgressState {
|
|
56
|
+
current: number;
|
|
57
|
+
total: number;
|
|
58
|
+
percentage: number;
|
|
59
|
+
elapsed: number;
|
|
60
|
+
eta: number;
|
|
61
|
+
rate: number;
|
|
62
|
+
label: string;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* A step in a multi-step operation.
|
|
67
|
+
*/
|
|
68
|
+
export interface ProgressStep {
|
|
69
|
+
name: string;
|
|
70
|
+
status: 'pending' | 'running' | 'done' | 'failed' | 'skipped';
|
|
71
|
+
message?: string;
|
|
72
|
+
duration?: number;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Configuration for a multi-step tracker.
|
|
77
|
+
*/
|
|
78
|
+
export interface StepTrackerOptions {
|
|
79
|
+
/** Whether to show step numbers. Defaults to true. */
|
|
80
|
+
showNumbers?: boolean;
|
|
81
|
+
|
|
82
|
+
/** Whether to show elapsed time per step. Defaults to true. */
|
|
83
|
+
showDuration?: boolean;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// ---------------------------------------------------------------------------
|
|
87
|
+
// Progress Bar
|
|
88
|
+
// ---------------------------------------------------------------------------
|
|
89
|
+
|
|
90
|
+
export class ProgressBar {
|
|
91
|
+
private current: number = 0;
|
|
92
|
+
private startTime: number;
|
|
93
|
+
private options: Required<
|
|
94
|
+
Pick<
|
|
95
|
+
ProgressBarOptions,
|
|
96
|
+
| 'total'
|
|
97
|
+
| 'width'
|
|
98
|
+
| 'label'
|
|
99
|
+
| 'filledChar'
|
|
100
|
+
| 'emptyChar'
|
|
101
|
+
| 'showPercentage'
|
|
102
|
+
| 'showETA'
|
|
103
|
+
| 'showCount'
|
|
104
|
+
>
|
|
105
|
+
> &
|
|
106
|
+
Pick<ProgressBarOptions, 'format'>;
|
|
107
|
+
private isTTY: boolean;
|
|
108
|
+
private lastRender: string = '';
|
|
109
|
+
|
|
110
|
+
constructor(options: ProgressBarOptions) {
|
|
111
|
+
this.startTime = Date.now();
|
|
112
|
+
this.isTTY = process.stderr.isTTY === true;
|
|
113
|
+
this.options = {
|
|
114
|
+
total: options.total,
|
|
115
|
+
width: options.width ?? 30,
|
|
116
|
+
label: options.label ?? '',
|
|
117
|
+
filledChar: options.filledChar ?? '=',
|
|
118
|
+
emptyChar: options.emptyChar ?? '-',
|
|
119
|
+
showPercentage: options.showPercentage ?? true,
|
|
120
|
+
showETA: options.showETA ?? true,
|
|
121
|
+
showCount: options.showCount ?? true,
|
|
122
|
+
format: options.format,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Update progress to a specific value.
|
|
128
|
+
*/
|
|
129
|
+
update(value: number): void {
|
|
130
|
+
this.current = Math.min(value, this.options.total);
|
|
131
|
+
this.render();
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Increment progress by a given amount.
|
|
136
|
+
*/
|
|
137
|
+
increment(amount: number = 1): void {
|
|
138
|
+
this.update(this.current + amount);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Get the current state.
|
|
143
|
+
*/
|
|
144
|
+
getState(): ProgressState {
|
|
145
|
+
const elapsed = Date.now() - this.startTime;
|
|
146
|
+
const percentage =
|
|
147
|
+
this.options.total > 0 ? this.current / this.options.total : 0;
|
|
148
|
+
const rate = elapsed > 0 ? (this.current / elapsed) * 1000 : 0;
|
|
149
|
+
const remaining = this.options.total - this.current;
|
|
150
|
+
const eta = rate > 0 ? (remaining / rate) * 1000 : 0;
|
|
151
|
+
|
|
152
|
+
return {
|
|
153
|
+
current: this.current,
|
|
154
|
+
total: this.options.total,
|
|
155
|
+
percentage,
|
|
156
|
+
elapsed,
|
|
157
|
+
eta,
|
|
158
|
+
rate,
|
|
159
|
+
label: this.options.label,
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Render the progress bar to stderr.
|
|
165
|
+
*/
|
|
166
|
+
render(): void {
|
|
167
|
+
if (!this.isTTY) return;
|
|
168
|
+
|
|
169
|
+
const state = this.getState();
|
|
170
|
+
let line: string;
|
|
171
|
+
|
|
172
|
+
if (this.options.format) {
|
|
173
|
+
line = this.options.format(state);
|
|
174
|
+
} else {
|
|
175
|
+
line = this.defaultFormat(state);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// Only rewrite if changed
|
|
179
|
+
if (line !== this.lastRender) {
|
|
180
|
+
process.stderr.clearLine(0);
|
|
181
|
+
process.stderr.cursorTo(0);
|
|
182
|
+
process.stderr.write(line);
|
|
183
|
+
this.lastRender = line;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Finish the progress bar (add newline).
|
|
189
|
+
*/
|
|
190
|
+
finish(message?: string): void {
|
|
191
|
+
if (!this.isTTY) return;
|
|
192
|
+
|
|
193
|
+
this.current = this.options.total;
|
|
194
|
+
this.render();
|
|
195
|
+
process.stderr.write('\n');
|
|
196
|
+
|
|
197
|
+
if (message) {
|
|
198
|
+
process.stderr.write(message + '\n');
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Render the bar as a string (for non-interactive use).
|
|
204
|
+
*/
|
|
205
|
+
toString(): string {
|
|
206
|
+
const state = this.getState();
|
|
207
|
+
if (this.options.format) {
|
|
208
|
+
return this.options.format(state);
|
|
209
|
+
}
|
|
210
|
+
return this.defaultFormat(state);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// -------------------------------------------------------------------------
|
|
214
|
+
// Private
|
|
215
|
+
// -------------------------------------------------------------------------
|
|
216
|
+
|
|
217
|
+
private defaultFormat(state: ProgressState): string {
|
|
218
|
+
const parts: string[] = [];
|
|
219
|
+
|
|
220
|
+
// Label
|
|
221
|
+
if (this.options.label) {
|
|
222
|
+
parts.push(chalk.cyan(this.options.label));
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// Bar
|
|
226
|
+
const filled = Math.round(state.percentage * this.options.width);
|
|
227
|
+
const empty = this.options.width - filled;
|
|
228
|
+
const bar =
|
|
229
|
+
chalk.cyan('[') +
|
|
230
|
+
chalk.green(this.options.filledChar.repeat(filled)) +
|
|
231
|
+
chalk.gray(this.options.emptyChar.repeat(empty)) +
|
|
232
|
+
chalk.cyan(']');
|
|
233
|
+
parts.push(bar);
|
|
234
|
+
|
|
235
|
+
// Percentage
|
|
236
|
+
if (this.options.showPercentage) {
|
|
237
|
+
parts.push(`${(state.percentage * 100).toFixed(0)}%`);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// Count
|
|
241
|
+
if (this.options.showCount) {
|
|
242
|
+
parts.push(chalk.gray(`${state.current}/${state.total}`));
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// ETA
|
|
246
|
+
if (
|
|
247
|
+
this.options.showETA &&
|
|
248
|
+
state.current > 0 &&
|
|
249
|
+
state.current < state.total
|
|
250
|
+
) {
|
|
251
|
+
parts.push(chalk.gray(`ETA: ${this.formatTime(state.eta)}`));
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
return parts.join(' ');
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
private formatTime(ms: number): string {
|
|
258
|
+
const seconds = Math.ceil(ms / 1000);
|
|
259
|
+
if (seconds < 60) return `${seconds}s`;
|
|
260
|
+
const minutes = Math.floor(seconds / 60);
|
|
261
|
+
const remainingSeconds = seconds % 60;
|
|
262
|
+
return `${minutes}m${remainingSeconds}s`;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// ---------------------------------------------------------------------------
|
|
267
|
+
// Multi-Progress Manager
|
|
268
|
+
// ---------------------------------------------------------------------------
|
|
269
|
+
|
|
270
|
+
export class MultiProgressManager {
|
|
271
|
+
private bars: Map<string, ProgressBar> = new Map();
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Create and register a new progress bar.
|
|
275
|
+
*/
|
|
276
|
+
create(id: string, options: ProgressBarOptions): ProgressBar {
|
|
277
|
+
const bar = new ProgressBar(options);
|
|
278
|
+
this.bars.set(id, bar);
|
|
279
|
+
return bar;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* Get a progress bar by ID.
|
|
284
|
+
*/
|
|
285
|
+
get(id: string): ProgressBar | undefined {
|
|
286
|
+
return this.bars.get(id);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Update a progress bar by ID.
|
|
291
|
+
*/
|
|
292
|
+
update(id: string, value: number): void {
|
|
293
|
+
this.bars.get(id)?.update(value);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Finish and remove a progress bar.
|
|
298
|
+
*/
|
|
299
|
+
finish(id: string, message?: string): void {
|
|
300
|
+
const bar = this.bars.get(id);
|
|
301
|
+
if (bar) {
|
|
302
|
+
bar.finish(message);
|
|
303
|
+
this.bars.delete(id);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* Finish all progress bars.
|
|
309
|
+
*/
|
|
310
|
+
finishAll(): void {
|
|
311
|
+
for (const [id, bar] of this.bars) {
|
|
312
|
+
bar.finish();
|
|
313
|
+
this.bars.delete(id);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// ---------------------------------------------------------------------------
|
|
319
|
+
// Step Tracker
|
|
320
|
+
// ---------------------------------------------------------------------------
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* Track progress through a series of named steps.
|
|
324
|
+
*
|
|
325
|
+
* @example
|
|
326
|
+
* ```typescript
|
|
327
|
+
* const tracker = new StepTracker([
|
|
328
|
+
* 'Installing dependencies',
|
|
329
|
+
* 'Running migrations',
|
|
330
|
+
* 'Building assets',
|
|
331
|
+
* 'Verifying deployment',
|
|
332
|
+
* ]);
|
|
333
|
+
*
|
|
334
|
+
* tracker.start(0);
|
|
335
|
+
* await installDeps();
|
|
336
|
+
* tracker.complete(0);
|
|
337
|
+
*
|
|
338
|
+
* tracker.start(1);
|
|
339
|
+
* await runMigrations();
|
|
340
|
+
* tracker.complete(1);
|
|
341
|
+
* ```
|
|
342
|
+
*/
|
|
343
|
+
export class StepTracker {
|
|
344
|
+
private steps: ProgressStep[];
|
|
345
|
+
private startTimes: Map<number, number> = new Map();
|
|
346
|
+
private options: Required<StepTrackerOptions>;
|
|
347
|
+
private isTTY: boolean;
|
|
348
|
+
|
|
349
|
+
constructor(stepNames: string[], options: StepTrackerOptions = {}) {
|
|
350
|
+
this.steps = stepNames.map(name => ({
|
|
351
|
+
name,
|
|
352
|
+
status: 'pending',
|
|
353
|
+
}));
|
|
354
|
+
this.options = {
|
|
355
|
+
showNumbers: options.showNumbers ?? true,
|
|
356
|
+
showDuration: options.showDuration ?? true,
|
|
357
|
+
};
|
|
358
|
+
this.isTTY = process.stderr.isTTY === true;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* Mark a step as running.
|
|
363
|
+
*/
|
|
364
|
+
start(index: number): void {
|
|
365
|
+
const step = this.steps[index];
|
|
366
|
+
if (!step) return;
|
|
367
|
+
|
|
368
|
+
step.status = 'running';
|
|
369
|
+
this.startTimes.set(index, Date.now());
|
|
370
|
+
this.render();
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
/**
|
|
374
|
+
* Mark a step as completed.
|
|
375
|
+
*/
|
|
376
|
+
complete(index: number, message?: string): void {
|
|
377
|
+
const step = this.steps[index];
|
|
378
|
+
if (!step) return;
|
|
379
|
+
|
|
380
|
+
step.status = 'done';
|
|
381
|
+
step.message = message;
|
|
382
|
+
this.setDuration(index);
|
|
383
|
+
this.render();
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
/**
|
|
387
|
+
* Mark a step as failed.
|
|
388
|
+
*/
|
|
389
|
+
fail(index: number, message?: string): void {
|
|
390
|
+
const step = this.steps[index];
|
|
391
|
+
if (!step) return;
|
|
392
|
+
|
|
393
|
+
step.status = 'failed';
|
|
394
|
+
step.message = message;
|
|
395
|
+
this.setDuration(index);
|
|
396
|
+
this.render();
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
/**
|
|
400
|
+
* Mark a step as skipped.
|
|
401
|
+
*/
|
|
402
|
+
skip(index: number, reason?: string): void {
|
|
403
|
+
const step = this.steps[index];
|
|
404
|
+
if (!step) return;
|
|
405
|
+
|
|
406
|
+
step.status = 'skipped';
|
|
407
|
+
step.message = reason;
|
|
408
|
+
this.render();
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* Get all steps with their current status.
|
|
413
|
+
*/
|
|
414
|
+
getSteps(): readonly ProgressStep[] {
|
|
415
|
+
return this.steps;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
/**
|
|
419
|
+
* Get the overall progress as a fraction.
|
|
420
|
+
*/
|
|
421
|
+
getProgress(): { completed: number; total: number; percentage: number } {
|
|
422
|
+
const completed = this.steps.filter(
|
|
423
|
+
s => s.status === 'done' || s.status === 'skipped'
|
|
424
|
+
).length;
|
|
425
|
+
return {
|
|
426
|
+
completed,
|
|
427
|
+
total: this.steps.length,
|
|
428
|
+
percentage: this.steps.length > 0 ? completed / this.steps.length : 0,
|
|
429
|
+
};
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
/**
|
|
433
|
+
* Render step status to stderr.
|
|
434
|
+
*/
|
|
435
|
+
render(): void {
|
|
436
|
+
if (!this.isTTY) return;
|
|
437
|
+
|
|
438
|
+
const lines = this.steps.map((step, index) => {
|
|
439
|
+
const prefix = this.options.showNumbers ? `${index + 1}. ` : '';
|
|
440
|
+
const icon = this.statusIcon(step.status);
|
|
441
|
+
const name = this.statusColor(step.status, step.name);
|
|
442
|
+
const suffix = this.stepSuffix(step);
|
|
443
|
+
|
|
444
|
+
return ` ${prefix}${icon} ${name}${suffix}`;
|
|
445
|
+
});
|
|
446
|
+
|
|
447
|
+
// Move cursor up to overwrite previous render
|
|
448
|
+
const moveUp = this.steps.length;
|
|
449
|
+
if (moveUp > 0) {
|
|
450
|
+
process.stderr.write(`\x1b[${moveUp}A`);
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
for (const line of lines) {
|
|
454
|
+
process.stderr.clearLine(0);
|
|
455
|
+
process.stderr.write(line + '\n');
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
/**
|
|
460
|
+
* Render the final summary.
|
|
461
|
+
*/
|
|
462
|
+
summary(): string {
|
|
463
|
+
const { completed, total } = this.getProgress();
|
|
464
|
+
const failed = this.steps.filter(s => s.status === 'failed').length;
|
|
465
|
+
const skipped = this.steps.filter(s => s.status === 'skipped').length;
|
|
466
|
+
|
|
467
|
+
const parts: string[] = [`${completed}/${total} steps completed`];
|
|
468
|
+
|
|
469
|
+
if (failed > 0) parts.push(chalk.red(`${failed} failed`));
|
|
470
|
+
if (skipped > 0) parts.push(chalk.yellow(`${skipped} skipped`));
|
|
471
|
+
|
|
472
|
+
return parts.join(', ');
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
// -------------------------------------------------------------------------
|
|
476
|
+
// Private
|
|
477
|
+
// -------------------------------------------------------------------------
|
|
478
|
+
|
|
479
|
+
private setDuration(index: number): void {
|
|
480
|
+
const start = this.startTimes.get(index);
|
|
481
|
+
if (start !== undefined) {
|
|
482
|
+
const step = this.steps[index];
|
|
483
|
+
if (step) {
|
|
484
|
+
step.duration = Date.now() - start;
|
|
485
|
+
}
|
|
486
|
+
this.startTimes.delete(index);
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
private statusIcon(status: ProgressStep['status']): string {
|
|
491
|
+
switch (status) {
|
|
492
|
+
case 'pending':
|
|
493
|
+
return chalk.gray('[ ]');
|
|
494
|
+
case 'running':
|
|
495
|
+
return chalk.cyan('[~]');
|
|
496
|
+
case 'done':
|
|
497
|
+
return chalk.green('[+]');
|
|
498
|
+
case 'failed':
|
|
499
|
+
return chalk.red('[x]');
|
|
500
|
+
case 'skipped':
|
|
501
|
+
return chalk.yellow('[-]');
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
private statusColor(status: ProgressStep['status'], text: string): string {
|
|
506
|
+
switch (status) {
|
|
507
|
+
case 'pending':
|
|
508
|
+
return chalk.gray(text);
|
|
509
|
+
case 'running':
|
|
510
|
+
return chalk.cyan(text);
|
|
511
|
+
case 'done':
|
|
512
|
+
return chalk.green(text);
|
|
513
|
+
case 'failed':
|
|
514
|
+
return chalk.red(text);
|
|
515
|
+
case 'skipped':
|
|
516
|
+
return chalk.yellow(text);
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
private stepSuffix(step: ProgressStep): string {
|
|
521
|
+
const parts: string[] = [];
|
|
522
|
+
|
|
523
|
+
if (step.message) {
|
|
524
|
+
parts.push(chalk.gray(` - ${step.message}`));
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
if (this.options.showDuration && step.duration !== undefined) {
|
|
528
|
+
parts.push(chalk.gray(` (${this.formatDuration(step.duration)})`));
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
return parts.join('');
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
private formatDuration(ms: number): string {
|
|
535
|
+
if (ms < 1000) return `${ms}ms`;
|
|
536
|
+
if (ms < 60000) return `${(ms / 1000).toFixed(1)}s`;
|
|
537
|
+
return `${(ms / 60000).toFixed(1)}min`;
|
|
538
|
+
}
|
|
539
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -22,14 +22,14 @@ async function main() {
|
|
|
22
22
|
font: 'ANSI Shadow',
|
|
23
23
|
horizontalLayout: 'fitted',
|
|
24
24
|
verticalLayout: 'fitted',
|
|
25
|
-
})
|
|
26
|
-
)
|
|
25
|
+
})
|
|
26
|
+
)
|
|
27
27
|
);
|
|
28
28
|
|
|
29
29
|
console.log(
|
|
30
30
|
chalk.gray(
|
|
31
|
-
`The Intelligent CLI-Based Coding Agents Orchestrator v${version}\n
|
|
32
|
-
)
|
|
31
|
+
`The Intelligent CLI-Based Coding Agents Orchestrator v${version}\n`
|
|
32
|
+
)
|
|
33
33
|
);
|
|
34
34
|
|
|
35
35
|
// Initialize CLI
|
|
@@ -7,7 +7,7 @@ import { errorHandler } from '../utils/error-handler';
|
|
|
7
7
|
import { logger } from '../utils/logger';
|
|
8
8
|
|
|
9
9
|
import type { PluginManager } from '../plugins/plugin-manager';
|
|
10
|
-
import type { InteractiveSession} from '../types';
|
|
10
|
+
import type { InteractiveSession } from '../types';
|
|
11
11
|
import type { ConfigManager } from '../utils/config-manager';
|
|
12
12
|
|
|
13
13
|
/**
|
|
@@ -18,7 +18,7 @@ export class InteractiveMode {
|
|
|
18
18
|
|
|
19
19
|
constructor(
|
|
20
20
|
private configManager: ConfigManager,
|
|
21
|
-
private pluginManager: PluginManager
|
|
21
|
+
private pluginManager: PluginManager
|
|
22
22
|
) {}
|
|
23
23
|
|
|
24
24
|
/**
|
|
@@ -58,7 +58,7 @@ export class InteractiveMode {
|
|
|
58
58
|
'WUNDR_WIZARD_FAILED',
|
|
59
59
|
'Failed to launch wizard',
|
|
60
60
|
{ mode },
|
|
61
|
-
true
|
|
61
|
+
true
|
|
62
62
|
);
|
|
63
63
|
}
|
|
64
64
|
}
|
|
@@ -75,11 +75,11 @@ export class InteractiveMode {
|
|
|
75
75
|
const chatArgs = ['chat', 'start'];
|
|
76
76
|
|
|
77
77
|
if (options.model) {
|
|
78
|
-
chatArgs.push('--model', options.model);
|
|
79
|
-
}
|
|
78
|
+
chatArgs.push('--model', options.model);
|
|
79
|
+
}
|
|
80
80
|
if (options.context) {
|
|
81
|
-
chatArgs.push('--context', options.context);
|
|
82
|
-
}
|
|
81
|
+
chatArgs.push('--context', options.context);
|
|
82
|
+
}
|
|
83
83
|
|
|
84
84
|
const child = spawn('wundr', chatArgs, {
|
|
85
85
|
stdio: 'inherit',
|
|
@@ -96,7 +96,7 @@ chatArgs.push('--context', options.context);
|
|
|
96
96
|
'WUNDR_CHAT_LAUNCH_FAILED',
|
|
97
97
|
'Failed to launch chat interface',
|
|
98
98
|
{ options },
|
|
99
|
-
true
|
|
99
|
+
true
|
|
100
100
|
);
|
|
101
101
|
}
|
|
102
102
|
}
|
|
@@ -126,7 +126,7 @@ chatArgs.push('--context', options.context);
|
|
|
126
126
|
'WUNDR_TUI_LAUNCH_FAILED',
|
|
127
127
|
'Failed to launch TUI',
|
|
128
128
|
{ layout },
|
|
129
|
-
true
|
|
129
|
+
true
|
|
130
130
|
);
|
|
131
131
|
}
|
|
132
132
|
}
|
|
@@ -212,15 +212,15 @@ chatArgs.push('--context', options.context);
|
|
|
212
212
|
}
|
|
213
213
|
|
|
214
214
|
console.log(
|
|
215
|
-
chalk.green('\nš Setup complete! Your Wundr project is ready.')
|
|
215
|
+
chalk.green('\nš Setup complete! Your Wundr project is ready.')
|
|
216
216
|
);
|
|
217
217
|
console.log(chalk.gray('\nNext steps:'));
|
|
218
218
|
console.log(chalk.gray(' ⢠Run "wundr analyze" to analyze your code'));
|
|
219
219
|
console.log(
|
|
220
|
-
chalk.gray(' ⢠Run "wundr dashboard start" to launch the dashboard')
|
|
220
|
+
chalk.gray(' ⢠Run "wundr dashboard start" to launch the dashboard')
|
|
221
221
|
);
|
|
222
222
|
console.log(
|
|
223
|
-
chalk.gray(' ⢠Run "wundr --help" to see all available commands')
|
|
223
|
+
chalk.gray(' ⢠Run "wundr --help" to see all available commands')
|
|
224
224
|
);
|
|
225
225
|
}
|
|
226
226
|
|
|
@@ -326,7 +326,7 @@ chatArgs.push('--context', options.context);
|
|
|
326
326
|
}
|
|
327
327
|
|
|
328
328
|
console.log(
|
|
329
|
-
chalk.green(`\nšļø Creating ${answers.createType}: ${answers.name}\n`)
|
|
329
|
+
chalk.green(`\nšļø Creating ${answers.createType}: ${answers.name}\n`)
|
|
330
330
|
);
|
|
331
331
|
|
|
332
332
|
let command = `wundr create ${answers.createType} ${answers.name}`;
|
|
@@ -344,7 +344,7 @@ chatArgs.push('--context', options.context);
|
|
|
344
344
|
await this.simulateCommand(command);
|
|
345
345
|
|
|
346
346
|
console.log(
|
|
347
|
-
chalk.green(`\nš ${answers.createType} created successfully!`)
|
|
347
|
+
chalk.green(`\nš ${answers.createType} created successfully!`)
|
|
348
348
|
);
|
|
349
349
|
}
|
|
350
350
|
|
|
@@ -414,8 +414,8 @@ chatArgs.push('--context', options.context);
|
|
|
414
414
|
console.log(chalk.green('\nā
Governance setup complete!'));
|
|
415
415
|
console.log(
|
|
416
416
|
chalk.gray(
|
|
417
|
-
'\nRun "wundr govern check" to validate your code against the rules.'
|
|
418
|
-
)
|
|
417
|
+
'\nRun "wundr govern check" to validate your code against the rules.'
|
|
418
|
+
)
|
|
419
419
|
);
|
|
420
420
|
}
|
|
421
421
|
|