erosolar-cli 2.1.171 → 2.1.172
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/agents/erosolar-code.rules.json +2 -2
- package/agents/general.rules.json +3 -21
- package/dist/StringUtils.d.ts +8 -0
- package/dist/StringUtils.d.ts.map +1 -0
- package/dist/StringUtils.js +11 -0
- package/dist/StringUtils.js.map +1 -0
- package/dist/capabilities/statusCapability.js +2 -2
- package/dist/capabilities/statusCapability.js.map +1 -1
- package/dist/contracts/agent-schemas.json +5 -5
- package/dist/core/agent.d.ts +24 -83
- package/dist/core/agent.d.ts.map +1 -1
- package/dist/core/agent.js +248 -499
- package/dist/core/agent.js.map +1 -1
- package/dist/core/aiFlowSupervisor.d.ts +44 -0
- package/dist/core/aiFlowSupervisor.d.ts.map +1 -0
- package/dist/core/aiFlowSupervisor.js +299 -0
- package/dist/core/aiFlowSupervisor.js.map +1 -0
- package/dist/core/cliTestHarness.d.ts +200 -0
- package/dist/core/cliTestHarness.d.ts.map +1 -0
- package/dist/core/cliTestHarness.js +549 -0
- package/dist/core/cliTestHarness.js.map +1 -0
- package/dist/core/preferences.d.ts +0 -1
- package/dist/core/preferences.d.ts.map +1 -1
- package/dist/core/preferences.js +1 -8
- package/dist/core/preferences.js.map +1 -1
- package/dist/core/schemaValidator.js +3 -3
- package/dist/core/schemaValidator.js.map +1 -1
- package/dist/core/testUtils.d.ts +121 -0
- package/dist/core/testUtils.d.ts.map +1 -0
- package/dist/core/testUtils.js +235 -0
- package/dist/core/testUtils.js.map +1 -0
- package/dist/core/toolPreconditions.d.ts +11 -0
- package/dist/core/toolPreconditions.d.ts.map +1 -1
- package/dist/core/toolPreconditions.js +164 -33
- package/dist/core/toolPreconditions.js.map +1 -1
- package/dist/core/toolRuntime.d.ts.map +1 -1
- package/dist/core/toolRuntime.js +114 -9
- package/dist/core/toolRuntime.js.map +1 -1
- package/dist/core/toolValidation.d.ts +116 -0
- package/dist/core/toolValidation.d.ts.map +1 -0
- package/dist/core/toolValidation.js +282 -0
- package/dist/core/toolValidation.js.map +1 -0
- package/dist/core/updateChecker.d.ts +1 -61
- package/dist/core/updateChecker.d.ts.map +1 -1
- package/dist/core/updateChecker.js +3 -147
- package/dist/core/updateChecker.js.map +1 -1
- package/dist/headless/evalMode.d.ts.map +1 -1
- package/dist/headless/evalMode.js +0 -6
- package/dist/headless/evalMode.js.map +1 -1
- package/dist/headless/headlessApp.d.ts.map +1 -1
- package/dist/headless/headlessApp.js +39 -6
- package/dist/headless/headlessApp.js.map +1 -1
- package/dist/mcp/sseClient.d.ts +1 -4
- package/dist/mcp/sseClient.d.ts.map +1 -1
- package/dist/mcp/sseClient.js +2 -36
- package/dist/mcp/sseClient.js.map +1 -1
- package/dist/mcp/stdioClient.d.ts +1 -4
- package/dist/mcp/stdioClient.d.ts.map +1 -1
- package/dist/mcp/stdioClient.js +1 -41
- package/dist/mcp/stdioClient.js.map +1 -1
- package/dist/mcp/toolBridge.d.ts +0 -3
- package/dist/mcp/toolBridge.d.ts.map +1 -1
- package/dist/mcp/toolBridge.js +2 -2
- package/dist/mcp/toolBridge.js.map +1 -1
- package/dist/mcp/types.d.ts +0 -18
- package/dist/mcp/types.d.ts.map +1 -1
- package/dist/plugins/tools/nodeDefaults.d.ts.map +1 -1
- package/dist/plugins/tools/nodeDefaults.js +2 -0
- package/dist/plugins/tools/nodeDefaults.js.map +1 -1
- package/dist/providers/openaiResponsesProvider.d.ts.map +1 -1
- package/dist/providers/openaiResponsesProvider.js +74 -79
- package/dist/providers/openaiResponsesProvider.js.map +1 -1
- package/dist/runtime/agentController.d.ts.map +1 -1
- package/dist/runtime/agentController.js +3 -6
- package/dist/runtime/agentController.js.map +1 -1
- package/dist/runtime/agentSession.d.ts +2 -0
- package/dist/runtime/agentSession.d.ts.map +1 -1
- package/dist/runtime/agentSession.js +2 -2
- package/dist/runtime/agentSession.js.map +1 -1
- package/dist/shell/interactiveShell.d.ts +18 -20
- package/dist/shell/interactiveShell.d.ts.map +1 -1
- package/dist/shell/interactiveShell.js +291 -329
- package/dist/shell/interactiveShell.js.map +1 -1
- package/dist/shell/shellApp.d.ts.map +1 -1
- package/dist/shell/shellApp.js +8 -16
- package/dist/shell/shellApp.js.map +1 -1
- package/dist/shell/systemPrompt.d.ts.map +1 -1
- package/dist/shell/systemPrompt.js +15 -4
- package/dist/shell/systemPrompt.js.map +1 -1
- package/dist/subagents/taskRunner.js +1 -2
- package/dist/subagents/taskRunner.js.map +1 -1
- package/dist/tools/bashTools.d.ts.map +1 -1
- package/dist/tools/bashTools.js +8 -101
- package/dist/tools/bashTools.js.map +1 -1
- package/dist/tools/diffUtils.d.ts +2 -8
- package/dist/tools/diffUtils.d.ts.map +1 -1
- package/dist/tools/diffUtils.js +13 -72
- package/dist/tools/diffUtils.js.map +1 -1
- package/dist/tools/grepTools.d.ts.map +1 -1
- package/dist/tools/grepTools.js +2 -10
- package/dist/tools/grepTools.js.map +1 -1
- package/dist/tools/planningTools.d.ts +10 -0
- package/dist/tools/planningTools.d.ts.map +1 -1
- package/dist/tools/planningTools.js +16 -0
- package/dist/tools/planningTools.js.map +1 -1
- package/dist/tools/searchTools.d.ts.map +1 -1
- package/dist/tools/searchTools.js +2 -4
- package/dist/tools/searchTools.js.map +1 -1
- package/dist/ui/PromptController.d.ts +4 -4
- package/dist/ui/PromptController.d.ts.map +1 -1
- package/dist/ui/PromptController.js +7 -1
- package/dist/ui/PromptController.js.map +1 -1
- package/dist/ui/ShellUIAdapter.d.ts +28 -292
- package/dist/ui/ShellUIAdapter.d.ts.map +1 -1
- package/dist/ui/ShellUIAdapter.js +121 -1513
- package/dist/ui/ShellUIAdapter.js.map +1 -1
- package/dist/ui/UnifiedUIRenderer.d.ts +30 -136
- package/dist/ui/UnifiedUIRenderer.d.ts.map +1 -1
- package/dist/ui/UnifiedUIRenderer.js +370 -955
- package/dist/ui/UnifiedUIRenderer.js.map +1 -1
- package/dist/ui/animatedStatus.d.ts +6 -128
- package/dist/ui/animatedStatus.d.ts.map +1 -1
- package/dist/ui/animatedStatus.js +50 -383
- package/dist/ui/animatedStatus.js.map +1 -1
- package/dist/ui/display.d.ts +26 -182
- package/dist/ui/display.d.ts.map +1 -1
- package/dist/ui/display.js +97 -678
- package/dist/ui/display.js.map +1 -1
- package/dist/ui/layout.d.ts +1 -0
- package/dist/ui/layout.d.ts.map +1 -1
- package/dist/ui/layout.js +12 -0
- package/dist/ui/layout.js.map +1 -1
- package/dist/ui/orchestration/UIUpdateCoordinator.d.ts +7 -61
- package/dist/ui/orchestration/UIUpdateCoordinator.d.ts.map +1 -1
- package/dist/ui/orchestration/UIUpdateCoordinator.js +20 -232
- package/dist/ui/orchestration/UIUpdateCoordinator.js.map +1 -1
- package/dist/ui/planOverlay.d.ts +28 -0
- package/dist/ui/planOverlay.d.ts.map +1 -0
- package/dist/ui/planOverlay.js +156 -0
- package/dist/ui/planOverlay.js.map +1 -0
- package/dist/ui/shortcutsHelp.d.ts.map +1 -1
- package/dist/ui/shortcutsHelp.js +1 -0
- package/dist/ui/shortcutsHelp.js.map +1 -1
- package/dist/ui/streamingFormatter.d.ts +30 -0
- package/dist/ui/streamingFormatter.d.ts.map +1 -0
- package/dist/ui/streamingFormatter.js +91 -0
- package/dist/ui/streamingFormatter.js.map +1 -0
- package/dist/ui/unified/index.d.ts +1 -30
- package/dist/ui/unified/index.d.ts.map +1 -1
- package/dist/ui/unified/index.js +2 -45
- package/dist/ui/unified/index.js.map +1 -1
- package/dist/utils/errorUtils.d.ts +16 -0
- package/dist/utils/errorUtils.d.ts.map +1 -0
- package/dist/utils/errorUtils.js +66 -0
- package/dist/utils/errorUtils.js.map +1 -0
- package/package.json +2 -1
- package/dist/codex/capabilities/codexCoreCapability.d.ts +0 -6
- package/dist/codex/capabilities/codexCoreCapability.d.ts.map +0 -1
- package/dist/codex/capabilities/codexCoreCapability.js +0 -516
- package/dist/codex/capabilities/codexCoreCapability.js.map +0 -1
- package/dist/codex/fs.d.ts +0 -4
- package/dist/codex/fs.d.ts.map +0 -1
- package/dist/codex/fs.js +0 -25
- package/dist/codex/fs.js.map +0 -1
- package/dist/codex/persistence/planStore.d.ts +0 -4
- package/dist/codex/persistence/planStore.d.ts.map +0 -1
- package/dist/codex/persistence/planStore.js +0 -59
- package/dist/codex/persistence/planStore.js.map +0 -1
- package/dist/codex/pluginAllowlist.d.ts +0 -4
- package/dist/codex/pluginAllowlist.d.ts.map +0 -1
- package/dist/codex/pluginAllowlist.js +0 -14
- package/dist/codex/pluginAllowlist.js.map +0 -1
- package/dist/codex/types.d.ts +0 -21
- package/dist/codex/types.d.ts.map +0 -1
- package/dist/codex/types.js +0 -62
- package/dist/codex/types.js.map +0 -1
- package/dist/core/reliabilityPrompt.d.ts +0 -9
- package/dist/core/reliabilityPrompt.d.ts.map +0 -1
- package/dist/core/reliabilityPrompt.js +0 -31
- package/dist/core/reliabilityPrompt.js.map +0 -1
- package/dist/ui/UnifiedUIController.d.ts +0 -81
- package/dist/ui/UnifiedUIController.d.ts.map +0 -1
- package/dist/ui/UnifiedUIController.js +0 -212
- package/dist/ui/UnifiedUIController.js.map +0 -1
- package/dist/ui/animation/AnimationScheduler.d.ts +0 -192
- package/dist/ui/animation/AnimationScheduler.d.ts.map +0 -1
- package/dist/ui/animation/AnimationScheduler.js +0 -432
- package/dist/ui/animation/AnimationScheduler.js.map +0 -1
- package/dist/ui/inPlaceUpdater.d.ts +0 -181
- package/dist/ui/inPlaceUpdater.d.ts.map +0 -1
- package/dist/ui/inPlaceUpdater.js +0 -515
- package/dist/ui/inPlaceUpdater.js.map +0 -1
- package/dist/ui/interrupts/InterruptManager.d.ts +0 -142
- package/dist/ui/interrupts/InterruptManager.d.ts.map +0 -1
- package/dist/ui/interrupts/InterruptManager.js +0 -439
- package/dist/ui/interrupts/InterruptManager.js.map +0 -1
- package/dist/ui/telemetry/ResponseTracker.d.ts +0 -22
- package/dist/ui/telemetry/ResponseTracker.d.ts.map +0 -1
- package/dist/ui/telemetry/ResponseTracker.js +0 -60
- package/dist/ui/telemetry/ResponseTracker.js.map +0 -1
- package/dist/ui/telemetry/UITelemetry.d.ts +0 -181
- package/dist/ui/telemetry/UITelemetry.d.ts.map +0 -1
- package/dist/ui/telemetry/UITelemetry.js +0 -446
- package/dist/ui/telemetry/UITelemetry.js.map +0 -1
- package/dist/ui/unified/layout.d.ts +0 -12
- package/dist/ui/unified/layout.d.ts.map +0 -1
- package/dist/ui/unified/layout.js +0 -96
- package/dist/ui/unified/layout.js.map +0 -1
|
@@ -1,181 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* InPlaceUpdater - Dynamic in-place terminal updates
|
|
3
|
-
*
|
|
4
|
-
* Enables tool results to update in place without creating new lines.
|
|
5
|
-
* Features:
|
|
6
|
-
* - Cursor management for overwriting previous output
|
|
7
|
-
* - Multi-line update support
|
|
8
|
-
* - Progress bar animations
|
|
9
|
-
* - Streaming content updates
|
|
10
|
-
* - TTY detection and fallback
|
|
11
|
-
*/
|
|
12
|
-
import { spinnerFrames } from './theme.js';
|
|
13
|
-
export interface UpdateRegion {
|
|
14
|
-
id: string;
|
|
15
|
-
startLine: number;
|
|
16
|
-
lineCount: number;
|
|
17
|
-
content: string[];
|
|
18
|
-
lastUpdate: number;
|
|
19
|
-
}
|
|
20
|
-
export interface ProgressBarOptions {
|
|
21
|
-
width?: number;
|
|
22
|
-
showPercentage?: boolean;
|
|
23
|
-
showCount?: boolean;
|
|
24
|
-
label?: string;
|
|
25
|
-
style?: 'bar' | 'braille' | 'dots';
|
|
26
|
-
}
|
|
27
|
-
export interface SpinnerOptions {
|
|
28
|
-
style?: keyof typeof spinnerFrames;
|
|
29
|
-
label?: string;
|
|
30
|
-
}
|
|
31
|
-
export interface StreamingUpdateOptions {
|
|
32
|
-
maxLines?: number;
|
|
33
|
-
truncate?: boolean;
|
|
34
|
-
preserveLastLine?: boolean;
|
|
35
|
-
}
|
|
36
|
-
export declare class InPlaceUpdater {
|
|
37
|
-
private readonly stream;
|
|
38
|
-
private regions;
|
|
39
|
-
private currentSpinnerFrame;
|
|
40
|
-
private spinnerInterval;
|
|
41
|
-
private activeSpinnerId;
|
|
42
|
-
private isTTY;
|
|
43
|
-
constructor(stream?: NodeJS.WriteStream);
|
|
44
|
-
/**
|
|
45
|
-
* Move cursor up N lines
|
|
46
|
-
*/
|
|
47
|
-
private cursorUp;
|
|
48
|
-
/**
|
|
49
|
-
* Move cursor down N lines
|
|
50
|
-
*/
|
|
51
|
-
private cursorDown;
|
|
52
|
-
/**
|
|
53
|
-
* Move cursor to beginning of line
|
|
54
|
-
*/
|
|
55
|
-
private cursorToLineStart;
|
|
56
|
-
/**
|
|
57
|
-
* Clear from cursor to end of line
|
|
58
|
-
*/
|
|
59
|
-
private clearToEndOfLine;
|
|
60
|
-
/**
|
|
61
|
-
* Clear entire line
|
|
62
|
-
*/
|
|
63
|
-
private clearLine;
|
|
64
|
-
/**
|
|
65
|
-
* Save cursor position
|
|
66
|
-
*/
|
|
67
|
-
private saveCursor;
|
|
68
|
-
/**
|
|
69
|
-
* Restore cursor position
|
|
70
|
-
*/
|
|
71
|
-
private restoreCursor;
|
|
72
|
-
/**
|
|
73
|
-
* Hide cursor
|
|
74
|
-
*/
|
|
75
|
-
hideCursor(): void;
|
|
76
|
-
/**
|
|
77
|
-
* Show cursor
|
|
78
|
-
*/
|
|
79
|
-
showCursor(): void;
|
|
80
|
-
/**
|
|
81
|
-
* Create an updateable region
|
|
82
|
-
*/
|
|
83
|
-
createRegion(id: string, initialContent: string | string[]): void;
|
|
84
|
-
/**
|
|
85
|
-
* Update a region in place
|
|
86
|
-
*/
|
|
87
|
-
updateRegion(id: string, newContent: string | string[]): void;
|
|
88
|
-
/**
|
|
89
|
-
* Delete a region
|
|
90
|
-
*/
|
|
91
|
-
deleteRegion(id: string): void;
|
|
92
|
-
/**
|
|
93
|
-
* Update a single line in place (most common use case)
|
|
94
|
-
*/
|
|
95
|
-
updateLine(content: string): void;
|
|
96
|
-
/**
|
|
97
|
-
* Finalize a line update (add newline)
|
|
98
|
-
*/
|
|
99
|
-
finalizeLine(content?: string): void;
|
|
100
|
-
/**
|
|
101
|
-
* Create a progress bar string
|
|
102
|
-
*/
|
|
103
|
-
formatProgressBar(current: number, total: number, options?: ProgressBarOptions): string;
|
|
104
|
-
/**
|
|
105
|
-
* Create a smooth braille-based progress bar
|
|
106
|
-
*/
|
|
107
|
-
private formatBrailleBar;
|
|
108
|
-
/**
|
|
109
|
-
* Update a progress bar in place
|
|
110
|
-
*/
|
|
111
|
-
updateProgress(regionId: string, current: number, total: number, options?: ProgressBarOptions): void;
|
|
112
|
-
/**
|
|
113
|
-
* Start a spinner
|
|
114
|
-
*/
|
|
115
|
-
startSpinner(id: string, label: string, options?: SpinnerOptions): void;
|
|
116
|
-
/**
|
|
117
|
-
* Update spinner label
|
|
118
|
-
*/
|
|
119
|
-
updateSpinner(label: string): void;
|
|
120
|
-
/**
|
|
121
|
-
* Stop spinner and show final message
|
|
122
|
-
*/
|
|
123
|
-
stopSpinner(finalMessage?: string, success?: boolean): void;
|
|
124
|
-
/**
|
|
125
|
-
* Render current spinner frame
|
|
126
|
-
*/
|
|
127
|
-
private renderSpinner;
|
|
128
|
-
/**
|
|
129
|
-
* Create a streaming update region that shows the last N lines
|
|
130
|
-
*/
|
|
131
|
-
createStreamingRegion(id: string, options?: StreamingUpdateOptions): (content: string) => void;
|
|
132
|
-
/**
|
|
133
|
-
* Finalize streaming region with summary
|
|
134
|
-
*/
|
|
135
|
-
finalizeStreamingRegion(id: string, summary?: string): void;
|
|
136
|
-
/**
|
|
137
|
-
* Show tool execution with in-place progress
|
|
138
|
-
*/
|
|
139
|
-
showToolProgress(toolName: string, message: string, progress?: {
|
|
140
|
-
current: number;
|
|
141
|
-
total: number;
|
|
142
|
-
}): void;
|
|
143
|
-
/**
|
|
144
|
-
* Show file operation progress
|
|
145
|
-
*/
|
|
146
|
-
showFileProgress(operation: 'read' | 'write' | 'edit', filePath: string, progress?: {
|
|
147
|
-
current: number;
|
|
148
|
-
total: number;
|
|
149
|
-
}): void;
|
|
150
|
-
/**
|
|
151
|
-
* Complete file operation with summary
|
|
152
|
-
*/
|
|
153
|
-
completeFileOperation(operation: 'read' | 'write' | 'edit', filePath: string, stats?: {
|
|
154
|
-
lines?: number;
|
|
155
|
-
additions?: number;
|
|
156
|
-
removals?: number;
|
|
157
|
-
}): void;
|
|
158
|
-
private truncatePath;
|
|
159
|
-
/**
|
|
160
|
-
* Check if TTY is available
|
|
161
|
-
*/
|
|
162
|
-
get hasTTY(): boolean;
|
|
163
|
-
/**
|
|
164
|
-
* Cleanup resources
|
|
165
|
-
*/
|
|
166
|
-
dispose(): void;
|
|
167
|
-
}
|
|
168
|
-
export declare const inPlaceUpdater: InPlaceUpdater;
|
|
169
|
-
/**
|
|
170
|
-
* Quick in-place line update
|
|
171
|
-
*/
|
|
172
|
-
export declare function updateInPlace(content: string): void;
|
|
173
|
-
/**
|
|
174
|
-
* Quick progress bar
|
|
175
|
-
*/
|
|
176
|
-
export declare function showProgress(current: number, total: number, label?: string): void;
|
|
177
|
-
/**
|
|
178
|
-
* Finalize progress with result
|
|
179
|
-
*/
|
|
180
|
-
export declare function finishProgress(message: string, success?: boolean): void;
|
|
181
|
-
//# sourceMappingURL=inPlaceUpdater.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"inPlaceUpdater.d.ts","sourceRoot":"","sources":["../../src/ui/inPlaceUpdater.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,515 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* InPlaceUpdater - Dynamic in-place terminal updates
|
|
3
|
-
*
|
|
4
|
-
* Enables tool results to update in place without creating new lines.
|
|
5
|
-
* Features:
|
|
6
|
-
* - Cursor management for overwriting previous output
|
|
7
|
-
* - Multi-line update support
|
|
8
|
-
* - Progress bar animations
|
|
9
|
-
* - Streaming content updates
|
|
10
|
-
* - TTY detection and fallback
|
|
11
|
-
*/
|
|
12
|
-
import { theme, icons, spinnerFrames, progressChars } from './theme.js';
|
|
13
|
-
import { getTerminalColumns, measure, stripAnsi } from './layout.js';
|
|
14
|
-
// ============================================================================
|
|
15
|
-
// IN-PLACE UPDATER
|
|
16
|
-
// ============================================================================
|
|
17
|
-
export class InPlaceUpdater {
|
|
18
|
-
stream;
|
|
19
|
-
regions = new Map();
|
|
20
|
-
currentSpinnerFrame = 0;
|
|
21
|
-
spinnerInterval = null;
|
|
22
|
-
activeSpinnerId = null;
|
|
23
|
-
isTTY;
|
|
24
|
-
constructor(stream = process.stdout) {
|
|
25
|
-
this.stream = stream;
|
|
26
|
-
this.isTTY = stream.isTTY === true;
|
|
27
|
-
}
|
|
28
|
-
// --------------------------------------------------------------------------
|
|
29
|
-
// CURSOR CONTROL
|
|
30
|
-
// --------------------------------------------------------------------------
|
|
31
|
-
/**
|
|
32
|
-
* Move cursor up N lines
|
|
33
|
-
*/
|
|
34
|
-
cursorUp(lines) {
|
|
35
|
-
if (this.isTTY && lines > 0) {
|
|
36
|
-
this.stream.write(`\x1b[${lines}A`);
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
/**
|
|
40
|
-
* Move cursor down N lines
|
|
41
|
-
*/
|
|
42
|
-
cursorDown(lines) {
|
|
43
|
-
if (this.isTTY && lines > 0) {
|
|
44
|
-
this.stream.write(`\x1b[${lines}B`);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* Move cursor to beginning of line
|
|
49
|
-
*/
|
|
50
|
-
cursorToLineStart() {
|
|
51
|
-
if (this.isTTY) {
|
|
52
|
-
this.stream.write('\r');
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
/**
|
|
56
|
-
* Clear from cursor to end of line
|
|
57
|
-
*/
|
|
58
|
-
clearToEndOfLine() {
|
|
59
|
-
if (this.isTTY) {
|
|
60
|
-
this.stream.write('\x1b[K');
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* Clear entire line
|
|
65
|
-
*/
|
|
66
|
-
clearLine() {
|
|
67
|
-
if (this.isTTY) {
|
|
68
|
-
this.stream.write('\r\x1b[K');
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
|
-
* Save cursor position
|
|
73
|
-
*/
|
|
74
|
-
saveCursor() {
|
|
75
|
-
if (this.isTTY) {
|
|
76
|
-
this.stream.write('\x1b[s');
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
/**
|
|
80
|
-
* Restore cursor position
|
|
81
|
-
*/
|
|
82
|
-
restoreCursor() {
|
|
83
|
-
if (this.isTTY) {
|
|
84
|
-
this.stream.write('\x1b[u');
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* Hide cursor
|
|
89
|
-
*/
|
|
90
|
-
hideCursor() {
|
|
91
|
-
if (this.isTTY) {
|
|
92
|
-
this.stream.write('\x1b[?25l');
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
/**
|
|
96
|
-
* Show cursor
|
|
97
|
-
*/
|
|
98
|
-
showCursor() {
|
|
99
|
-
if (this.isTTY) {
|
|
100
|
-
this.stream.write('\x1b[?25h');
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
// --------------------------------------------------------------------------
|
|
104
|
-
// IN-PLACE UPDATES
|
|
105
|
-
// --------------------------------------------------------------------------
|
|
106
|
-
/**
|
|
107
|
-
* Create an updateable region
|
|
108
|
-
*/
|
|
109
|
-
createRegion(id, initialContent) {
|
|
110
|
-
const content = Array.isArray(initialContent) ? initialContent : [initialContent];
|
|
111
|
-
// Write initial content
|
|
112
|
-
for (const line of content) {
|
|
113
|
-
this.stream.write(`${line}\n`);
|
|
114
|
-
}
|
|
115
|
-
this.regions.set(id, {
|
|
116
|
-
id,
|
|
117
|
-
startLine: 0, // We don't track absolute position, only relative
|
|
118
|
-
lineCount: content.length,
|
|
119
|
-
content,
|
|
120
|
-
lastUpdate: Date.now(),
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
/**
|
|
124
|
-
* Update a region in place
|
|
125
|
-
*/
|
|
126
|
-
updateRegion(id, newContent) {
|
|
127
|
-
const region = this.regions.get(id);
|
|
128
|
-
if (!region)
|
|
129
|
-
return;
|
|
130
|
-
const content = Array.isArray(newContent) ? newContent : [newContent];
|
|
131
|
-
if (this.isTTY) {
|
|
132
|
-
// Move cursor up to the start of the region
|
|
133
|
-
this.cursorUp(region.lineCount);
|
|
134
|
-
// Write new content, clearing each line
|
|
135
|
-
for (let i = 0; i < Math.max(content.length, region.lineCount); i++) {
|
|
136
|
-
this.clearLine();
|
|
137
|
-
if (i < content.length) {
|
|
138
|
-
this.stream.write(`${content[i]}\n`);
|
|
139
|
-
}
|
|
140
|
-
else {
|
|
141
|
-
this.stream.write('\n'); // Clear extra lines
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
// If new content is shorter, we need to move cursor down
|
|
145
|
-
if (content.length < region.lineCount) {
|
|
146
|
-
// We're already at the right position
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
else {
|
|
150
|
-
// Non-TTY fallback: just print new content
|
|
151
|
-
for (const line of content) {
|
|
152
|
-
this.stream.write(`${line}\n`);
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
// Update region metadata
|
|
156
|
-
region.content = content;
|
|
157
|
-
region.lineCount = content.length;
|
|
158
|
-
region.lastUpdate = Date.now();
|
|
159
|
-
}
|
|
160
|
-
/**
|
|
161
|
-
* Delete a region
|
|
162
|
-
*/
|
|
163
|
-
deleteRegion(id) {
|
|
164
|
-
const region = this.regions.get(id);
|
|
165
|
-
if (!region)
|
|
166
|
-
return;
|
|
167
|
-
if (this.isTTY) {
|
|
168
|
-
// Move up and clear all lines
|
|
169
|
-
this.cursorUp(region.lineCount);
|
|
170
|
-
for (let i = 0; i < region.lineCount; i++) {
|
|
171
|
-
this.clearLine();
|
|
172
|
-
if (i < region.lineCount - 1) {
|
|
173
|
-
this.cursorDown(1);
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
// Move back up to where the region started
|
|
177
|
-
this.cursorUp(region.lineCount - 1);
|
|
178
|
-
}
|
|
179
|
-
this.regions.delete(id);
|
|
180
|
-
}
|
|
181
|
-
/**
|
|
182
|
-
* Update a single line in place (most common use case)
|
|
183
|
-
*/
|
|
184
|
-
updateLine(content) {
|
|
185
|
-
if (this.isTTY) {
|
|
186
|
-
this.cursorToLineStart();
|
|
187
|
-
this.clearToEndOfLine();
|
|
188
|
-
this.stream.write(content);
|
|
189
|
-
}
|
|
190
|
-
else {
|
|
191
|
-
this.stream.write(`${content}\n`);
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
/**
|
|
195
|
-
* Finalize a line update (add newline)
|
|
196
|
-
*/
|
|
197
|
-
finalizeLine(content) {
|
|
198
|
-
if (content) {
|
|
199
|
-
this.updateLine(content);
|
|
200
|
-
}
|
|
201
|
-
this.stream.write('\n');
|
|
202
|
-
}
|
|
203
|
-
// --------------------------------------------------------------------------
|
|
204
|
-
// PROGRESS BAR
|
|
205
|
-
// --------------------------------------------------------------------------
|
|
206
|
-
/**
|
|
207
|
-
* Create a progress bar string
|
|
208
|
-
*/
|
|
209
|
-
formatProgressBar(current, total, options = {}) {
|
|
210
|
-
const { width = 20, showPercentage = true, showCount = false, label, style = 'bar', } = options;
|
|
211
|
-
const percentage = Math.min(100, Math.max(0, Math.round((current / total) * 100)));
|
|
212
|
-
const filled = Math.round((current / total) * width);
|
|
213
|
-
const empty = width - filled;
|
|
214
|
-
let bar;
|
|
215
|
-
switch (style) {
|
|
216
|
-
case 'braille':
|
|
217
|
-
bar = this.formatBrailleBar(current, total, width);
|
|
218
|
-
break;
|
|
219
|
-
case 'dots':
|
|
220
|
-
bar = '●'.repeat(filled) + '○'.repeat(empty);
|
|
221
|
-
break;
|
|
222
|
-
case 'bar':
|
|
223
|
-
default:
|
|
224
|
-
bar = theme.progress.bar(progressChars.filled.repeat(filled)) +
|
|
225
|
-
theme.progress.empty(progressChars.empty.repeat(empty));
|
|
226
|
-
}
|
|
227
|
-
const parts = [];
|
|
228
|
-
if (label) {
|
|
229
|
-
parts.push(theme.ui.muted(label));
|
|
230
|
-
}
|
|
231
|
-
parts.push(`[${bar}]`);
|
|
232
|
-
if (showPercentage) {
|
|
233
|
-
parts.push(theme.progress.percentage(`${percentage}%`));
|
|
234
|
-
}
|
|
235
|
-
if (showCount) {
|
|
236
|
-
parts.push(theme.ui.muted(`(${current}/${total})`));
|
|
237
|
-
}
|
|
238
|
-
return parts.join(' ');
|
|
239
|
-
}
|
|
240
|
-
/**
|
|
241
|
-
* Create a smooth braille-based progress bar
|
|
242
|
-
*/
|
|
243
|
-
formatBrailleBar(current, total, width) {
|
|
244
|
-
const ratio = current / total;
|
|
245
|
-
const fullBlocks = Math.floor(ratio * width);
|
|
246
|
-
const remainder = (ratio * width) - fullBlocks;
|
|
247
|
-
// Braille patterns for partial fill (0/8 to 8/8)
|
|
248
|
-
const partials = [' ', '⡀', '⡄', '⡆', '⡇', '⣇', '⣧', '⣷', '⣿'];
|
|
249
|
-
const partialIndex = Math.floor(remainder * 8);
|
|
250
|
-
let bar = '⣿'.repeat(fullBlocks);
|
|
251
|
-
if (fullBlocks < width) {
|
|
252
|
-
bar += partials[partialIndex];
|
|
253
|
-
bar += ' '.repeat(width - fullBlocks - 1);
|
|
254
|
-
}
|
|
255
|
-
return theme.progress.bar(bar);
|
|
256
|
-
}
|
|
257
|
-
/**
|
|
258
|
-
* Update a progress bar in place
|
|
259
|
-
*/
|
|
260
|
-
updateProgress(regionId, current, total, options = {}) {
|
|
261
|
-
const bar = this.formatProgressBar(current, total, options);
|
|
262
|
-
this.updateLine(bar);
|
|
263
|
-
}
|
|
264
|
-
// --------------------------------------------------------------------------
|
|
265
|
-
// SPINNER
|
|
266
|
-
// --------------------------------------------------------------------------
|
|
267
|
-
/**
|
|
268
|
-
* Start a spinner
|
|
269
|
-
*/
|
|
270
|
-
startSpinner(id, label, options = {}) {
|
|
271
|
-
if (this.spinnerInterval) {
|
|
272
|
-
this.stopSpinner();
|
|
273
|
-
}
|
|
274
|
-
this.activeSpinnerId = id;
|
|
275
|
-
const style = options.style || 'circle';
|
|
276
|
-
const frames = spinnerFrames[style];
|
|
277
|
-
// Initial render
|
|
278
|
-
this.renderSpinner(frames, label);
|
|
279
|
-
// Start animation
|
|
280
|
-
this.spinnerInterval = setInterval(() => {
|
|
281
|
-
this.currentSpinnerFrame = (this.currentSpinnerFrame + 1) % frames.length;
|
|
282
|
-
this.renderSpinner(frames, label);
|
|
283
|
-
}, 80);
|
|
284
|
-
}
|
|
285
|
-
/**
|
|
286
|
-
* Update spinner label
|
|
287
|
-
*/
|
|
288
|
-
updateSpinner(label) {
|
|
289
|
-
if (!this.spinnerInterval)
|
|
290
|
-
return;
|
|
291
|
-
// The next frame will pick up the new label
|
|
292
|
-
// For immediate update, we'd need to store the current frames
|
|
293
|
-
}
|
|
294
|
-
/**
|
|
295
|
-
* Stop spinner and show final message
|
|
296
|
-
*/
|
|
297
|
-
stopSpinner(finalMessage, success = true) {
|
|
298
|
-
if (this.spinnerInterval) {
|
|
299
|
-
clearInterval(this.spinnerInterval);
|
|
300
|
-
this.spinnerInterval = null;
|
|
301
|
-
}
|
|
302
|
-
if (finalMessage) {
|
|
303
|
-
const icon = success ? theme.success(icons.success) : theme.error(icons.error);
|
|
304
|
-
this.finalizeLine(`${icon} ${finalMessage}`);
|
|
305
|
-
}
|
|
306
|
-
else {
|
|
307
|
-
this.finalizeLine();
|
|
308
|
-
}
|
|
309
|
-
this.activeSpinnerId = null;
|
|
310
|
-
this.currentSpinnerFrame = 0;
|
|
311
|
-
}
|
|
312
|
-
/**
|
|
313
|
-
* Render current spinner frame
|
|
314
|
-
*/
|
|
315
|
-
renderSpinner(frames, label) {
|
|
316
|
-
const frame = theme.info(frames[this.currentSpinnerFrame]);
|
|
317
|
-
this.updateLine(`${frame} ${label}`);
|
|
318
|
-
}
|
|
319
|
-
// --------------------------------------------------------------------------
|
|
320
|
-
// STREAMING UPDATES
|
|
321
|
-
// --------------------------------------------------------------------------
|
|
322
|
-
/**
|
|
323
|
-
* Create a streaming update region that shows the last N lines
|
|
324
|
-
*/
|
|
325
|
-
createStreamingRegion(id, options = {}) {
|
|
326
|
-
const { maxLines = 5, truncate = true, preserveLastLine = true } = options;
|
|
327
|
-
const lines = [];
|
|
328
|
-
let initialized = false;
|
|
329
|
-
// Create initial empty region
|
|
330
|
-
const emptyLines = Array(maxLines).fill('');
|
|
331
|
-
this.createRegion(id, emptyLines);
|
|
332
|
-
initialized = true;
|
|
333
|
-
// Return updater function
|
|
334
|
-
return (content) => {
|
|
335
|
-
// Add new content (may contain newlines)
|
|
336
|
-
const newLines = content.split('\n');
|
|
337
|
-
for (const line of newLines) {
|
|
338
|
-
if (line || !preserveLastLine) {
|
|
339
|
-
lines.push(line);
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
// Keep only last maxLines
|
|
343
|
-
while (lines.length > maxLines) {
|
|
344
|
-
lines.shift();
|
|
345
|
-
}
|
|
346
|
-
// Pad to maxLines for consistent region size
|
|
347
|
-
const displayLines = [...lines];
|
|
348
|
-
while (displayLines.length < maxLines) {
|
|
349
|
-
displayLines.unshift('');
|
|
350
|
-
}
|
|
351
|
-
// Truncate lines if needed
|
|
352
|
-
const termWidth = getTerminalColumns() - 2;
|
|
353
|
-
const truncatedLines = truncate
|
|
354
|
-
? displayLines.map(l => {
|
|
355
|
-
const visible = measure(l);
|
|
356
|
-
if (visible > termWidth) {
|
|
357
|
-
return `${stripAnsi(l).slice(0, termWidth - 3)}...`;
|
|
358
|
-
}
|
|
359
|
-
return l;
|
|
360
|
-
})
|
|
361
|
-
: displayLines;
|
|
362
|
-
this.updateRegion(id, truncatedLines);
|
|
363
|
-
};
|
|
364
|
-
}
|
|
365
|
-
/**
|
|
366
|
-
* Finalize streaming region with summary
|
|
367
|
-
*/
|
|
368
|
-
finalizeStreamingRegion(id, summary) {
|
|
369
|
-
this.deleteRegion(id);
|
|
370
|
-
if (summary) {
|
|
371
|
-
this.stream.write(`${summary}\n`);
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
// --------------------------------------------------------------------------
|
|
375
|
-
// COMPOUND DISPLAYS
|
|
376
|
-
// --------------------------------------------------------------------------
|
|
377
|
-
/**
|
|
378
|
-
* Show tool execution with in-place progress
|
|
379
|
-
*/
|
|
380
|
-
showToolProgress(toolName, message, progress) {
|
|
381
|
-
const parts = [];
|
|
382
|
-
// Spinner or progress icon
|
|
383
|
-
if (progress) {
|
|
384
|
-
const pct = Math.round((progress.current / progress.total) * 100);
|
|
385
|
-
parts.push(theme.info(`${pct}%`));
|
|
386
|
-
}
|
|
387
|
-
else {
|
|
388
|
-
const frame = spinnerFrames.circle[this.currentSpinnerFrame];
|
|
389
|
-
parts.push(theme.info(frame));
|
|
390
|
-
}
|
|
391
|
-
// Tool name
|
|
392
|
-
parts.push(theme.tool(toolName));
|
|
393
|
-
// Message
|
|
394
|
-
parts.push(message);
|
|
395
|
-
// Progress bar if applicable
|
|
396
|
-
if (progress) {
|
|
397
|
-
const bar = this.formatProgressBar(progress.current, progress.total, {
|
|
398
|
-
width: 15,
|
|
399
|
-
showPercentage: false,
|
|
400
|
-
});
|
|
401
|
-
parts.push(bar);
|
|
402
|
-
}
|
|
403
|
-
this.updateLine(parts.join(' '));
|
|
404
|
-
}
|
|
405
|
-
/**
|
|
406
|
-
* Show file operation progress
|
|
407
|
-
*/
|
|
408
|
-
showFileProgress(operation, filePath, progress) {
|
|
409
|
-
const opIcons = {
|
|
410
|
-
read: icons.read,
|
|
411
|
-
write: icons.write,
|
|
412
|
-
edit: icons.edit,
|
|
413
|
-
};
|
|
414
|
-
const shortPath = this.truncatePath(filePath, 40);
|
|
415
|
-
const parts = [
|
|
416
|
-
theme.info(opIcons[operation] || icons.file),
|
|
417
|
-
theme.file.path(shortPath),
|
|
418
|
-
];
|
|
419
|
-
if (progress) {
|
|
420
|
-
parts.push(this.formatProgressBar(progress.current, progress.total, {
|
|
421
|
-
width: 12,
|
|
422
|
-
showPercentage: true,
|
|
423
|
-
}));
|
|
424
|
-
}
|
|
425
|
-
this.updateLine(parts.join(' '));
|
|
426
|
-
}
|
|
427
|
-
/**
|
|
428
|
-
* Complete file operation with summary
|
|
429
|
-
*/
|
|
430
|
-
completeFileOperation(operation, filePath, stats) {
|
|
431
|
-
const shortPath = this.truncatePath(filePath, 40);
|
|
432
|
-
const parts = [
|
|
433
|
-
theme.success(icons.success),
|
|
434
|
-
theme.file.path(shortPath),
|
|
435
|
-
];
|
|
436
|
-
if (stats) {
|
|
437
|
-
const details = [];
|
|
438
|
-
if (stats.lines !== undefined) {
|
|
439
|
-
details.push(`${stats.lines} lines`);
|
|
440
|
-
}
|
|
441
|
-
if (stats.additions !== undefined && stats.additions > 0) {
|
|
442
|
-
details.push(theme.file.additions(`+${stats.additions}`));
|
|
443
|
-
}
|
|
444
|
-
if (stats.removals !== undefined && stats.removals > 0) {
|
|
445
|
-
details.push(theme.file.removals(`-${stats.removals}`));
|
|
446
|
-
}
|
|
447
|
-
if (details.length > 0) {
|
|
448
|
-
parts.push(theme.ui.muted(`(${details.join(', ')})`));
|
|
449
|
-
}
|
|
450
|
-
}
|
|
451
|
-
this.finalizeLine(parts.join(' '));
|
|
452
|
-
}
|
|
453
|
-
// --------------------------------------------------------------------------
|
|
454
|
-
// UTILITIES
|
|
455
|
-
// --------------------------------------------------------------------------
|
|
456
|
-
truncatePath(path, maxLen) {
|
|
457
|
-
if (path.length <= maxLen)
|
|
458
|
-
return path;
|
|
459
|
-
const parts = path.split('/').filter(Boolean);
|
|
460
|
-
if (parts.length <= 2) {
|
|
461
|
-
return `${path.slice(0, maxLen - 3)}...`;
|
|
462
|
-
}
|
|
463
|
-
const filename = parts[parts.length - 1] || '';
|
|
464
|
-
if (filename.length <= maxLen - 4) {
|
|
465
|
-
return `.../${filename}`;
|
|
466
|
-
}
|
|
467
|
-
return `${filename.slice(0, maxLen - 3)}...`;
|
|
468
|
-
}
|
|
469
|
-
/**
|
|
470
|
-
* Check if TTY is available
|
|
471
|
-
*/
|
|
472
|
-
get hasTTY() {
|
|
473
|
-
return this.isTTY;
|
|
474
|
-
}
|
|
475
|
-
/**
|
|
476
|
-
* Cleanup resources
|
|
477
|
-
*/
|
|
478
|
-
dispose() {
|
|
479
|
-
this.stopSpinner();
|
|
480
|
-
this.showCursor();
|
|
481
|
-
this.regions.clear();
|
|
482
|
-
}
|
|
483
|
-
}
|
|
484
|
-
// ============================================================================
|
|
485
|
-
// SINGLETON INSTANCE
|
|
486
|
-
// ============================================================================
|
|
487
|
-
export const inPlaceUpdater = new InPlaceUpdater();
|
|
488
|
-
// ============================================================================
|
|
489
|
-
// CONVENIENCE FUNCTIONS
|
|
490
|
-
// ============================================================================
|
|
491
|
-
/**
|
|
492
|
-
* Quick in-place line update
|
|
493
|
-
*/
|
|
494
|
-
export function updateInPlace(content) {
|
|
495
|
-
inPlaceUpdater.updateLine(content);
|
|
496
|
-
}
|
|
497
|
-
/**
|
|
498
|
-
* Quick progress bar
|
|
499
|
-
*/
|
|
500
|
-
export function showProgress(current, total, label) {
|
|
501
|
-
const bar = inPlaceUpdater.formatProgressBar(current, total, {
|
|
502
|
-
label,
|
|
503
|
-
showPercentage: true,
|
|
504
|
-
width: 25,
|
|
505
|
-
});
|
|
506
|
-
inPlaceUpdater.updateLine(bar);
|
|
507
|
-
}
|
|
508
|
-
/**
|
|
509
|
-
* Finalize progress with result
|
|
510
|
-
*/
|
|
511
|
-
export function finishProgress(message, success = true) {
|
|
512
|
-
const icon = success ? theme.success(icons.success) : theme.error(icons.error);
|
|
513
|
-
inPlaceUpdater.finalizeLine(`${icon} ${message}`);
|
|
514
|
-
}
|
|
515
|
-
//# sourceMappingURL=inPlaceUpdater.js.map
|