erosolar-cli 1.7.356 → 1.7.358
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 +24 -148
- package/dist/bin/erosolar.js +5 -21
- package/dist/bin/erosolar.js.map +1 -1
- package/dist/capabilities/agentSpawningCapability.d.ts.map +1 -1
- package/dist/capabilities/agentSpawningCapability.js +56 -31
- package/dist/capabilities/agentSpawningCapability.js.map +1 -1
- package/dist/contracts/agent-schemas.json +0 -15
- package/dist/contracts/tools.schema.json +0 -9
- package/dist/core/agent.d.ts +2 -2
- package/dist/core/agent.d.ts.map +1 -1
- package/dist/core/agent.js.map +1 -1
- package/dist/core/customCommands.d.ts +1 -0
- package/dist/core/customCommands.d.ts.map +1 -1
- package/dist/core/customCommands.js +3 -0
- package/dist/core/customCommands.js.map +1 -1
- package/dist/core/hooks.d.ts +113 -0
- package/dist/core/hooks.d.ts.map +1 -0
- package/dist/core/hooks.js +267 -0
- package/dist/core/hooks.js.map +1 -0
- package/dist/core/metricsTracker.d.ts +122 -0
- package/dist/core/metricsTracker.d.ts.map +1 -0
- package/dist/{alpha-zero → core}/metricsTracker.js +2 -5
- package/dist/core/metricsTracker.js.map +1 -0
- package/dist/core/securityAssessment.d.ts +91 -0
- package/dist/core/securityAssessment.d.ts.map +1 -0
- package/dist/core/securityAssessment.js +580 -0
- package/dist/core/securityAssessment.js.map +1 -0
- package/dist/core/sessionStore.d.ts +2 -0
- package/dist/core/sessionStore.d.ts.map +1 -1
- package/dist/core/sessionStore.js +1 -0
- package/dist/core/sessionStore.js.map +1 -1
- package/dist/core/toolPreconditions.d.ts.map +1 -1
- package/dist/core/toolPreconditions.js +0 -14
- package/dist/core/toolPreconditions.js.map +1 -1
- package/dist/core/toolRuntime.d.ts +22 -1
- package/dist/core/toolRuntime.d.ts.map +1 -1
- package/dist/core/toolRuntime.js +0 -5
- package/dist/core/toolRuntime.js.map +1 -1
- package/dist/core/toolValidation.d.ts.map +1 -1
- package/dist/core/toolValidation.js +14 -3
- package/dist/core/toolValidation.js.map +1 -1
- package/dist/core/validationRunner.d.ts +1 -3
- package/dist/core/validationRunner.d.ts.map +1 -1
- package/dist/core/validationRunner.js.map +1 -1
- package/dist/core/verification.d.ts +137 -0
- package/dist/core/verification.d.ts.map +1 -0
- package/dist/core/verification.js +323 -0
- package/dist/core/verification.js.map +1 -0
- package/dist/headless/headlessApp.d.ts.map +1 -1
- package/dist/headless/headlessApp.js +21 -0
- package/dist/headless/headlessApp.js.map +1 -1
- package/dist/mcp/sseClient.d.ts.map +1 -1
- package/dist/mcp/sseClient.js +9 -18
- package/dist/mcp/sseClient.js.map +1 -1
- package/dist/plugins/tools/build/buildPlugin.d.ts +0 -6
- package/dist/plugins/tools/build/buildPlugin.d.ts.map +1 -1
- package/dist/plugins/tools/build/buildPlugin.js +4 -10
- package/dist/plugins/tools/build/buildPlugin.js.map +1 -1
- package/dist/plugins/tools/nodeDefaults.d.ts.map +1 -1
- package/dist/plugins/tools/nodeDefaults.js +0 -2
- package/dist/plugins/tools/nodeDefaults.js.map +1 -1
- package/dist/runtime/agentSession.d.ts +2 -2
- 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 +41 -7
- package/dist/shell/interactiveShell.d.ts.map +1 -1
- package/dist/shell/interactiveShell.js +399 -166
- package/dist/shell/interactiveShell.js.map +1 -1
- package/dist/shell/shellApp.d.ts +2 -0
- package/dist/shell/shellApp.d.ts.map +1 -1
- package/dist/shell/shellApp.js +82 -9
- package/dist/shell/shellApp.js.map +1 -1
- package/dist/shell/systemPrompt.d.ts.map +1 -1
- package/dist/shell/systemPrompt.js +1 -4
- package/dist/shell/systemPrompt.js.map +1 -1
- package/dist/shell/terminalInput.d.ts +250 -125
- package/dist/shell/terminalInput.d.ts.map +1 -1
- package/dist/shell/terminalInput.js +1061 -612
- package/dist/shell/terminalInput.js.map +1 -1
- package/dist/shell/terminalInputAdapter.d.ts +106 -24
- package/dist/shell/terminalInputAdapter.d.ts.map +1 -1
- package/dist/shell/terminalInputAdapter.js +137 -30
- package/dist/shell/terminalInputAdapter.js.map +1 -1
- package/dist/subagents/agentConfig.d.ts +27 -0
- package/dist/subagents/agentConfig.d.ts.map +1 -0
- package/dist/subagents/agentConfig.js +89 -0
- package/dist/subagents/agentConfig.js.map +1 -0
- package/dist/subagents/agentRegistry.d.ts +33 -0
- package/dist/subagents/agentRegistry.d.ts.map +1 -0
- package/dist/subagents/agentRegistry.js +162 -0
- package/dist/subagents/agentRegistry.js.map +1 -0
- package/dist/subagents/taskRunner.d.ts +7 -1
- package/dist/subagents/taskRunner.d.ts.map +1 -1
- package/dist/subagents/taskRunner.js +200 -49
- package/dist/subagents/taskRunner.js.map +1 -1
- package/dist/ui/ShellUIAdapter.d.ts +7 -1
- package/dist/ui/ShellUIAdapter.d.ts.map +1 -1
- package/dist/ui/ShellUIAdapter.js +42 -18
- package/dist/ui/ShellUIAdapter.js.map +1 -1
- package/dist/ui/display.d.ts +24 -45
- package/dist/ui/display.d.ts.map +1 -1
- package/dist/ui/display.js +148 -274
- package/dist/ui/display.js.map +1 -1
- package/dist/ui/theme.d.ts.map +1 -1
- package/dist/ui/theme.js +6 -8
- package/dist/ui/theme.js.map +1 -1
- package/dist/ui/toolDisplay.d.ts +0 -158
- package/dist/ui/toolDisplay.d.ts.map +1 -1
- package/dist/ui/toolDisplay.js +0 -348
- package/dist/ui/toolDisplay.js.map +1 -1
- package/dist/ui/unified/layout.d.ts +20 -0
- package/dist/ui/unified/layout.d.ts.map +1 -1
- package/dist/ui/unified/layout.js +105 -216
- package/dist/ui/unified/layout.js.map +1 -1
- package/dist/utils/frontmatter.d.ts +10 -0
- package/dist/utils/frontmatter.d.ts.map +1 -0
- package/dist/utils/frontmatter.js +78 -0
- package/dist/utils/frontmatter.js.map +1 -0
- package/package.json +4 -4
- package/dist/alpha-zero/agentWrapper.d.ts +0 -84
- package/dist/alpha-zero/agentWrapper.d.ts.map +0 -1
- package/dist/alpha-zero/agentWrapper.js +0 -171
- package/dist/alpha-zero/agentWrapper.js.map +0 -1
- package/dist/alpha-zero/codeEvaluator.d.ts +0 -25
- package/dist/alpha-zero/codeEvaluator.d.ts.map +0 -1
- package/dist/alpha-zero/codeEvaluator.js +0 -273
- package/dist/alpha-zero/codeEvaluator.js.map +0 -1
- package/dist/alpha-zero/competitiveRunner.d.ts +0 -66
- package/dist/alpha-zero/competitiveRunner.d.ts.map +0 -1
- package/dist/alpha-zero/competitiveRunner.js +0 -224
- package/dist/alpha-zero/competitiveRunner.js.map +0 -1
- package/dist/alpha-zero/index.d.ts +0 -67
- package/dist/alpha-zero/index.d.ts.map +0 -1
- package/dist/alpha-zero/index.js +0 -99
- package/dist/alpha-zero/index.js.map +0 -1
- package/dist/alpha-zero/introspection.d.ts +0 -128
- package/dist/alpha-zero/introspection.d.ts.map +0 -1
- package/dist/alpha-zero/introspection.js +0 -300
- package/dist/alpha-zero/introspection.js.map +0 -1
- package/dist/alpha-zero/metricsTracker.d.ts +0 -71
- package/dist/alpha-zero/metricsTracker.d.ts.map +0 -1
- package/dist/alpha-zero/metricsTracker.js.map +0 -1
- package/dist/alpha-zero/security/core.d.ts +0 -125
- package/dist/alpha-zero/security/core.d.ts.map +0 -1
- package/dist/alpha-zero/security/core.js +0 -271
- package/dist/alpha-zero/security/core.js.map +0 -1
- package/dist/alpha-zero/security/google.d.ts +0 -125
- package/dist/alpha-zero/security/google.d.ts.map +0 -1
- package/dist/alpha-zero/security/google.js +0 -311
- package/dist/alpha-zero/security/google.js.map +0 -1
- package/dist/alpha-zero/security/googleLoader.d.ts +0 -17
- package/dist/alpha-zero/security/googleLoader.d.ts.map +0 -1
- package/dist/alpha-zero/security/googleLoader.js +0 -41
- package/dist/alpha-zero/security/googleLoader.js.map +0 -1
- package/dist/alpha-zero/security/index.d.ts +0 -29
- package/dist/alpha-zero/security/index.d.ts.map +0 -1
- package/dist/alpha-zero/security/index.js +0 -32
- package/dist/alpha-zero/security/index.js.map +0 -1
- package/dist/alpha-zero/security/simulation.d.ts +0 -124
- package/dist/alpha-zero/security/simulation.d.ts.map +0 -1
- package/dist/alpha-zero/security/simulation.js +0 -277
- package/dist/alpha-zero/security/simulation.js.map +0 -1
- package/dist/alpha-zero/selfModification.d.ts +0 -109
- package/dist/alpha-zero/selfModification.d.ts.map +0 -1
- package/dist/alpha-zero/selfModification.js +0 -233
- package/dist/alpha-zero/selfModification.js.map +0 -1
- package/dist/alpha-zero/types.d.ts +0 -170
- package/dist/alpha-zero/types.d.ts.map +0 -1
- package/dist/alpha-zero/types.js +0 -31
- package/dist/alpha-zero/types.js.map +0 -1
- package/dist/capabilities/securityTestingCapability.d.ts +0 -13
- package/dist/capabilities/securityTestingCapability.d.ts.map +0 -1
- package/dist/capabilities/securityTestingCapability.js +0 -25
- package/dist/capabilities/securityTestingCapability.js.map +0 -1
- package/dist/core/aiFlowOptimizer.d.ts +0 -26
- package/dist/core/aiFlowOptimizer.d.ts.map +0 -1
- package/dist/core/aiFlowOptimizer.js +0 -31
- package/dist/core/aiFlowOptimizer.js.map +0 -1
- package/dist/core/aiOptimizationEngine.d.ts +0 -158
- package/dist/core/aiOptimizationEngine.d.ts.map +0 -1
- package/dist/core/aiOptimizationEngine.js +0 -428
- package/dist/core/aiOptimizationEngine.js.map +0 -1
- package/dist/core/aiOptimizationIntegration.d.ts +0 -93
- package/dist/core/aiOptimizationIntegration.d.ts.map +0 -1
- package/dist/core/aiOptimizationIntegration.js +0 -250
- package/dist/core/aiOptimizationIntegration.js.map +0 -1
- package/dist/core/enhancedErrorRecovery.d.ts +0 -100
- package/dist/core/enhancedErrorRecovery.d.ts.map +0 -1
- package/dist/core/enhancedErrorRecovery.js +0 -345
- package/dist/core/enhancedErrorRecovery.js.map +0 -1
- package/dist/core/hooksSystem.d.ts +0 -65
- package/dist/core/hooksSystem.d.ts.map +0 -1
- package/dist/core/hooksSystem.js +0 -273
- package/dist/core/hooksSystem.js.map +0 -1
- package/dist/core/memorySystem.d.ts +0 -48
- package/dist/core/memorySystem.d.ts.map +0 -1
- package/dist/core/memorySystem.js +0 -271
- package/dist/core/memorySystem.js.map +0 -1
- package/dist/core/unified/errors.d.ts +0 -189
- package/dist/core/unified/errors.d.ts.map +0 -1
- package/dist/core/unified/errors.js +0 -497
- package/dist/core/unified/errors.js.map +0 -1
- package/dist/core/unified/index.d.ts +0 -19
- package/dist/core/unified/index.d.ts.map +0 -1
- package/dist/core/unified/index.js +0 -68
- package/dist/core/unified/index.js.map +0 -1
- package/dist/core/unified/schema.d.ts +0 -101
- package/dist/core/unified/schema.d.ts.map +0 -1
- package/dist/core/unified/schema.js +0 -350
- package/dist/core/unified/schema.js.map +0 -1
- package/dist/core/unified/toolRuntime.d.ts +0 -179
- package/dist/core/unified/toolRuntime.d.ts.map +0 -1
- package/dist/core/unified/toolRuntime.js +0 -517
- package/dist/core/unified/toolRuntime.js.map +0 -1
- package/dist/core/unified/tools.d.ts +0 -127
- package/dist/core/unified/tools.d.ts.map +0 -1
- package/dist/core/unified/tools.js +0 -1333
- package/dist/core/unified/tools.js.map +0 -1
- package/dist/core/unified/types.d.ts +0 -352
- package/dist/core/unified/types.d.ts.map +0 -1
- package/dist/core/unified/types.js +0 -12
- package/dist/core/unified/types.js.map +0 -1
- package/dist/core/unified/version.d.ts +0 -209
- package/dist/core/unified/version.d.ts.map +0 -1
- package/dist/core/unified/version.js +0 -454
- package/dist/core/unified/version.js.map +0 -1
- package/dist/plugins/tools/security/securityPlugin.d.ts +0 -3
- package/dist/plugins/tools/security/securityPlugin.d.ts.map +0 -1
- package/dist/plugins/tools/security/securityPlugin.js +0 -12
- package/dist/plugins/tools/security/securityPlugin.js.map +0 -1
- package/dist/security/active-stack-security.d.ts +0 -112
- package/dist/security/active-stack-security.d.ts.map +0 -1
- package/dist/security/active-stack-security.js +0 -296
- package/dist/security/active-stack-security.js.map +0 -1
- package/dist/security/advanced-persistence-research.d.ts +0 -92
- package/dist/security/advanced-persistence-research.d.ts.map +0 -1
- package/dist/security/advanced-persistence-research.js +0 -195
- package/dist/security/advanced-persistence-research.js.map +0 -1
- package/dist/security/advanced-targeting.d.ts +0 -119
- package/dist/security/advanced-targeting.d.ts.map +0 -1
- package/dist/security/advanced-targeting.js +0 -233
- package/dist/security/advanced-targeting.js.map +0 -1
- package/dist/security/assessment/vulnerabilityAssessment.d.ts +0 -104
- package/dist/security/assessment/vulnerabilityAssessment.d.ts.map +0 -1
- package/dist/security/assessment/vulnerabilityAssessment.js +0 -315
- package/dist/security/assessment/vulnerabilityAssessment.js.map +0 -1
- package/dist/security/authorization/securityAuthorization.d.ts +0 -88
- package/dist/security/authorization/securityAuthorization.d.ts.map +0 -1
- package/dist/security/authorization/securityAuthorization.js +0 -172
- package/dist/security/authorization/securityAuthorization.js.map +0 -1
- package/dist/security/comprehensive-targeting.d.ts +0 -85
- package/dist/security/comprehensive-targeting.d.ts.map +0 -1
- package/dist/security/comprehensive-targeting.js +0 -438
- package/dist/security/comprehensive-targeting.js.map +0 -1
- package/dist/security/global-security-integration.d.ts +0 -91
- package/dist/security/global-security-integration.d.ts.map +0 -1
- package/dist/security/global-security-integration.js +0 -218
- package/dist/security/global-security-integration.js.map +0 -1
- package/dist/security/index.d.ts +0 -38
- package/dist/security/index.d.ts.map +0 -1
- package/dist/security/index.js +0 -47
- package/dist/security/index.js.map +0 -1
- package/dist/security/persistence-analyzer.d.ts +0 -56
- package/dist/security/persistence-analyzer.d.ts.map +0 -1
- package/dist/security/persistence-analyzer.js +0 -187
- package/dist/security/persistence-analyzer.js.map +0 -1
- package/dist/security/persistence-cli.d.ts +0 -36
- package/dist/security/persistence-cli.d.ts.map +0 -1
- package/dist/security/persistence-cli.js +0 -160
- package/dist/security/persistence-cli.js.map +0 -1
- package/dist/security/persistence-research.d.ts +0 -92
- package/dist/security/persistence-research.d.ts.map +0 -1
- package/dist/security/persistence-research.js +0 -364
- package/dist/security/persistence-research.js.map +0 -1
- package/dist/security/research/persistenceResearch.d.ts +0 -97
- package/dist/security/research/persistenceResearch.d.ts.map +0 -1
- package/dist/security/research/persistenceResearch.js +0 -282
- package/dist/security/research/persistenceResearch.js.map +0 -1
- package/dist/security/security-integration.d.ts +0 -74
- package/dist/security/security-integration.d.ts.map +0 -1
- package/dist/security/security-integration.js +0 -137
- package/dist/security/security-integration.js.map +0 -1
- package/dist/security/security-testing-framework.d.ts +0 -112
- package/dist/security/security-testing-framework.d.ts.map +0 -1
- package/dist/security/security-testing-framework.js +0 -364
- package/dist/security/security-testing-framework.js.map +0 -1
- package/dist/security/simulation/attackSimulation.d.ts +0 -93
- package/dist/security/simulation/attackSimulation.d.ts.map +0 -1
- package/dist/security/simulation/attackSimulation.js +0 -341
- package/dist/security/simulation/attackSimulation.js.map +0 -1
- package/dist/security/strategic-operations.d.ts +0 -100
- package/dist/security/strategic-operations.d.ts.map +0 -1
- package/dist/security/strategic-operations.js +0 -276
- package/dist/security/strategic-operations.js.map +0 -1
- package/dist/security/tool-security-wrapper.d.ts +0 -58
- package/dist/security/tool-security-wrapper.d.ts.map +0 -1
- package/dist/security/tool-security-wrapper.js +0 -156
- package/dist/security/tool-security-wrapper.js.map +0 -1
- package/dist/shell/claudeCodeStreamHandler.d.ts +0 -145
- package/dist/shell/claudeCodeStreamHandler.d.ts.map +0 -1
- package/dist/shell/claudeCodeStreamHandler.js +0 -322
- package/dist/shell/claudeCodeStreamHandler.js.map +0 -1
- package/dist/shell/inputQueueManager.d.ts +0 -144
- package/dist/shell/inputQueueManager.d.ts.map +0 -1
- package/dist/shell/inputQueueManager.js +0 -290
- package/dist/shell/inputQueueManager.js.map +0 -1
- package/dist/shell/metricsTracker.d.ts +0 -60
- package/dist/shell/metricsTracker.d.ts.map +0 -1
- package/dist/shell/metricsTracker.js +0 -119
- package/dist/shell/metricsTracker.js.map +0 -1
- package/dist/shell/streamingOutputManager.d.ts +0 -115
- package/dist/shell/streamingOutputManager.d.ts.map +0 -1
- package/dist/shell/streamingOutputManager.js +0 -225
- package/dist/shell/streamingOutputManager.js.map +0 -1
- package/dist/tools/securityTools.d.ts +0 -22
- package/dist/tools/securityTools.d.ts.map +0 -1
- package/dist/tools/securityTools.js +0 -448
- package/dist/tools/securityTools.js.map +0 -1
- package/dist/ui/persistentPrompt.d.ts +0 -50
- package/dist/ui/persistentPrompt.d.ts.map +0 -1
- package/dist/ui/persistentPrompt.js +0 -92
- package/dist/ui/persistentPrompt.js.map +0 -1
- package/dist/ui/terminalUISchema.d.ts +0 -195
- package/dist/ui/terminalUISchema.d.ts.map +0 -1
- package/dist/ui/terminalUISchema.js +0 -113
- package/dist/ui/terminalUISchema.js.map +0 -1
- package/scripts/deploy-security-capabilities.js +0 -178
package/dist/ui/display.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createSpinner } from 'nanospinner';
|
|
2
|
-
import { clearScreenDown, cursorTo
|
|
2
|
+
import { clearScreenDown, cursorTo } from 'node:readline';
|
|
3
3
|
import { theme, icons } from './theme.js';
|
|
4
4
|
import { formatRichContent, renderMessagePanel, renderMessageBody } from './richText.js';
|
|
5
5
|
import { getTerminalColumns } from './layout.js';
|
|
@@ -7,7 +7,7 @@ import { highlightError } from './textHighlighter.js';
|
|
|
7
7
|
import { renderSectionHeading } from './designSystem.js';
|
|
8
8
|
import { isPlainOutputMode } from './outputMode.js';
|
|
9
9
|
import { writeLock } from './writeLock.js';
|
|
10
|
-
import {
|
|
10
|
+
import { renderStatusLine } from './unified/layout.js';
|
|
11
11
|
import { isStreamingMode } from './globalWriteLock.js';
|
|
12
12
|
/**
|
|
13
13
|
* Output lock to prevent race conditions during spinner/stream output.
|
|
@@ -159,11 +159,6 @@ const DISPLAY_CONSTANTS = {
|
|
|
159
159
|
};
|
|
160
160
|
// Enhanced spinner frames with smooth animation
|
|
161
161
|
const SPINNER_FRAMES = ['◐', '◓', '◑', '◒', '⣾', '⣽', '⣻', '⢿', '⡿', '⣟', '⣯', '⣷'];
|
|
162
|
-
const clampWidthToAvailable = (available, min, max) => {
|
|
163
|
-
const bounded = Math.max(1, Math.floor(available));
|
|
164
|
-
const preferred = Math.max(min, Math.min(bounded, max));
|
|
165
|
-
return Math.min(preferred, bounded);
|
|
166
|
-
};
|
|
167
162
|
/**
|
|
168
163
|
* Display class manages all terminal UI output for the application.
|
|
169
164
|
*
|
|
@@ -259,10 +254,10 @@ export class Display {
|
|
|
259
254
|
interceptor.beforeWrite?.();
|
|
260
255
|
}
|
|
261
256
|
}
|
|
262
|
-
notifyAfterOutput() {
|
|
257
|
+
notifyAfterOutput(content) {
|
|
263
258
|
const interceptors = Array.from(this.outputInterceptors);
|
|
264
259
|
for (let index = interceptors.length - 1; index >= 0; index -= 1) {
|
|
265
|
-
interceptors[index]?.afterWrite?.();
|
|
260
|
+
interceptors[index]?.afterWrite?.(content);
|
|
266
261
|
}
|
|
267
262
|
}
|
|
268
263
|
write(value, target = this.outputStream) {
|
|
@@ -291,29 +286,36 @@ export class Display {
|
|
|
291
286
|
if (typeof content !== 'string' || !content) {
|
|
292
287
|
return;
|
|
293
288
|
}
|
|
294
|
-
//
|
|
295
|
-
//
|
|
289
|
+
// Normalize carriage returns to avoid overwriting streamed content on the same line.
|
|
290
|
+
// Some providers emit '\r' when streaming; convert to '\n' so we append instead of rewriting.
|
|
291
|
+
const normalized = content.includes('\r')
|
|
292
|
+
? content.replace(/\r\n/g, '\n').replace(/\r/g, '\n')
|
|
293
|
+
: content;
|
|
294
|
+
// During streaming, use withLock to prevent interleaving with escape codes.
|
|
295
|
+
// This ensures the before/write/after sequence is atomic.
|
|
296
296
|
if (isStreamingMode()) {
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
297
|
+
writeLock.withLock(() => {
|
|
298
|
+
this.notifyBeforeOutput();
|
|
299
|
+
try {
|
|
300
|
+
this.outputStream.write(normalized);
|
|
301
|
+
}
|
|
302
|
+
catch {
|
|
303
|
+
// Ignore write failures to keep UI resilient
|
|
304
|
+
}
|
|
305
|
+
finally {
|
|
306
|
+
this.notifyAfterOutput(normalized);
|
|
307
|
+
}
|
|
308
|
+
}, 'display.writeRaw.streaming');
|
|
307
309
|
return;
|
|
308
310
|
}
|
|
309
311
|
// Outside streaming mode, use locks to coordinate with other UI
|
|
310
312
|
writeLock.withLock(() => {
|
|
311
313
|
this.notifyBeforeOutput();
|
|
312
314
|
try {
|
|
313
|
-
this.write(
|
|
315
|
+
this.write(normalized);
|
|
314
316
|
}
|
|
315
317
|
finally {
|
|
316
|
-
this.notifyAfterOutput();
|
|
318
|
+
this.notifyAfterOutput(normalized);
|
|
317
319
|
}
|
|
318
320
|
}, 'display.writeRaw');
|
|
319
321
|
}
|
|
@@ -358,125 +360,7 @@ export class Display {
|
|
|
358
360
|
}
|
|
359
361
|
return getTerminalColumns();
|
|
360
362
|
}
|
|
361
|
-
|
|
362
|
-
bannerContext = null;
|
|
363
|
-
/**
|
|
364
|
-
* Stores banner information. When silent=true, only stores state without writing.
|
|
365
|
-
* The banner can then be rendered later via renderBannerToContent().
|
|
366
|
-
*
|
|
367
|
-
* @param silent If true, only store state without writing to stdout (default: true)
|
|
368
|
-
*/
|
|
369
|
-
showWelcome(profileLabel, profileName, model, provider, workingDir, version, silent = true) {
|
|
370
|
-
// Validate required inputs
|
|
371
|
-
if (!model?.trim() || !provider?.trim() || !workingDir?.trim()) {
|
|
372
|
-
return;
|
|
373
|
-
}
|
|
374
|
-
const width = this.getBannerWidth();
|
|
375
|
-
const banner = this.buildClaudeStyleBanner(profileLabel ?? '', profileName ?? '', model, provider, workingDir, width, version);
|
|
376
|
-
if (!banner) {
|
|
377
|
-
return;
|
|
378
|
-
}
|
|
379
|
-
const height = this.measureBannerHeight(banner);
|
|
380
|
-
this.bannerState = {
|
|
381
|
-
startLine: 0, // Will be set when actually rendered
|
|
382
|
-
height,
|
|
383
|
-
width,
|
|
384
|
-
workingDir,
|
|
385
|
-
version: version?.trim() || undefined,
|
|
386
|
-
model,
|
|
387
|
-
provider,
|
|
388
|
-
profileLabel: profileLabel ?? '',
|
|
389
|
-
profileName: profileName ?? '',
|
|
390
|
-
};
|
|
391
|
-
this.bannerContext = {
|
|
392
|
-
workingDir,
|
|
393
|
-
model,
|
|
394
|
-
provider,
|
|
395
|
-
profileLabel: profileLabel ?? '',
|
|
396
|
-
profileName: profileName ?? '',
|
|
397
|
-
version: version?.trim() || undefined,
|
|
398
|
-
};
|
|
399
|
-
// Only write to stdout if not silent
|
|
400
|
-
if (!silent) {
|
|
401
|
-
const startLine = this.stdoutTracker.totalLines;
|
|
402
|
-
this.withOutput(() => {
|
|
403
|
-
this.writeLine(banner);
|
|
404
|
-
});
|
|
405
|
-
this.bannerState.startLine = startLine;
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
/**
|
|
409
|
-
* Get the current version string (if set during showWelcome).
|
|
410
|
-
*/
|
|
411
|
-
getVersion() {
|
|
412
|
-
return this.bannerContext?.version;
|
|
413
|
-
}
|
|
414
|
-
/**
|
|
415
|
-
* Get the current banner content as a string.
|
|
416
|
-
* Used by TerminalInput to re-render the banner inside the scroll region.
|
|
417
|
-
* Returns null if no banner has been displayed yet.
|
|
418
|
-
*/
|
|
419
|
-
getBannerContent() {
|
|
420
|
-
const state = this.bannerState;
|
|
421
|
-
if (!state) {
|
|
422
|
-
return null;
|
|
423
|
-
}
|
|
424
|
-
const width = this.getBannerWidth();
|
|
425
|
-
return this.buildClaudeStyleBanner(state.profileLabel, state.profileName, state.model, state.provider, state.workingDir, width, state.version);
|
|
426
|
-
}
|
|
427
|
-
/**
|
|
428
|
-
* Render banner directly to stdout (for unified UI re-rendering).
|
|
429
|
-
* This writes the banner without updating tracking state.
|
|
430
|
-
* Returns the number of lines written.
|
|
431
|
-
*/
|
|
432
|
-
renderBannerToContent() {
|
|
433
|
-
const banner = this.getBannerContent();
|
|
434
|
-
if (!banner) {
|
|
435
|
-
return 0;
|
|
436
|
-
}
|
|
437
|
-
this.withOutput(() => {
|
|
438
|
-
this.writeLine(banner);
|
|
439
|
-
});
|
|
440
|
-
return this.measureBannerHeight(banner);
|
|
441
|
-
}
|
|
442
|
-
/**
|
|
443
|
-
* Updates the session information banner with new model/provider by appending
|
|
444
|
-
* a new banner entry in the scroll region (no pinned header rewriting).
|
|
445
|
-
*/
|
|
446
|
-
updateSessionInfo(model, provider) {
|
|
447
|
-
const state = this.bannerState;
|
|
448
|
-
if (!state) {
|
|
449
|
-
return;
|
|
450
|
-
}
|
|
451
|
-
const width = this.getBannerWidth();
|
|
452
|
-
const banner = this.buildClaudeStyleBanner(state.profileLabel, state.profileName, model, provider, state.workingDir, width, state.version);
|
|
453
|
-
const height = this.measureBannerHeight(banner);
|
|
454
|
-
// If height changed or rewrite failed, do full re-render
|
|
455
|
-
if (height !== state.height || !this.tryRewriteBanner(state, banner)) {
|
|
456
|
-
this.renderAndStoreBanner(state, model, provider);
|
|
457
|
-
this.bannerContext = {
|
|
458
|
-
workingDir: state.workingDir,
|
|
459
|
-
model: state.model,
|
|
460
|
-
provider: state.provider,
|
|
461
|
-
profileLabel: state.profileLabel,
|
|
462
|
-
profileName: state.profileName,
|
|
463
|
-
version: state.version,
|
|
464
|
-
};
|
|
465
|
-
return;
|
|
466
|
-
}
|
|
467
|
-
state.model = model;
|
|
468
|
-
state.provider = provider;
|
|
469
|
-
state.width = width;
|
|
470
|
-
state.height = height;
|
|
471
|
-
this.bannerContext = {
|
|
472
|
-
workingDir: state.workingDir,
|
|
473
|
-
model,
|
|
474
|
-
provider,
|
|
475
|
-
profileLabel: state.profileLabel,
|
|
476
|
-
profileName: state.profileName,
|
|
477
|
-
version: state.version,
|
|
478
|
-
};
|
|
479
|
-
}
|
|
363
|
+
// Banner is now streamed by the shell - no storage needed
|
|
480
364
|
showThinking(message = 'Thinking...') {
|
|
481
365
|
// If we already have a spinner, just update its text instead of creating a new one
|
|
482
366
|
if (this.activeSpinner) {
|
|
@@ -756,7 +640,7 @@ export class Display {
|
|
|
756
640
|
if (!normalized) {
|
|
757
641
|
return [];
|
|
758
642
|
}
|
|
759
|
-
const width =
|
|
643
|
+
const width = Math.max(DISPLAY_CONSTANTS.MIN_ACTION_WIDTH, Math.min(this.getColumnWidth(), DISPLAY_CONSTANTS.MAX_ACTION_WIDTH));
|
|
760
644
|
const samplePrefix = this.buildSubActionPrefixes(status, true).prefix;
|
|
761
645
|
const contentWidth = Math.max(DISPLAY_CONSTANTS.MIN_CONTENT_WIDTH, width - this.visibleLength(samplePrefix));
|
|
762
646
|
const blocks = formatRichContent(normalized, contentWidth);
|
|
@@ -846,8 +730,7 @@ export class Display {
|
|
|
846
730
|
{ text: `${theme.success('✓')} ${normalized}`, tone: 'success' },
|
|
847
731
|
elapsed ? { text: `(${elapsed})`, tone: 'muted' } : null,
|
|
848
732
|
].filter(Boolean);
|
|
849
|
-
const
|
|
850
|
-
const line = renderStatusLine(parts, width);
|
|
733
|
+
const line = renderStatusLine(parts, this.getColumnWidth() - 2);
|
|
851
734
|
this.withOutput(() => {
|
|
852
735
|
this.writeLine(line);
|
|
853
736
|
});
|
|
@@ -857,6 +740,23 @@ export class Display {
|
|
|
857
740
|
// Tools are available but not listed verbosely on startup
|
|
858
741
|
// Parameter prefixed with underscore to indicate intentionally unused
|
|
859
742
|
}
|
|
743
|
+
/**
|
|
744
|
+
* Show a compact launch panel of slash commands with wrapped descriptions.
|
|
745
|
+
*/
|
|
746
|
+
showCommandPalette(commands, options) {
|
|
747
|
+
if (!commands || commands.length === 0) {
|
|
748
|
+
return;
|
|
749
|
+
}
|
|
750
|
+
const panel = this.buildCommandPalette(commands, options);
|
|
751
|
+
if (!panel.trim()) {
|
|
752
|
+
return;
|
|
753
|
+
}
|
|
754
|
+
this.withOutput(() => {
|
|
755
|
+
this.writeLine();
|
|
756
|
+
this.writeLine(panel);
|
|
757
|
+
this.writeLine();
|
|
758
|
+
});
|
|
759
|
+
}
|
|
860
760
|
/**
|
|
861
761
|
* Show ready message with keyboard shortcuts hint (compact)
|
|
862
762
|
* Note: Commands are now shown in the banner, so this is a no-op
|
|
@@ -875,58 +775,17 @@ export class Display {
|
|
|
875
775
|
// Claude Code style: don't show providers on startup, keep it minimal
|
|
876
776
|
}
|
|
877
777
|
/**
|
|
878
|
-
* Show unified status bar -
|
|
879
|
-
*
|
|
778
|
+
* Show unified status bar - Claude Code style (minimal)
|
|
779
|
+
* Note: No-op - status is shown in mode controls line
|
|
880
780
|
*/
|
|
881
781
|
showUnifiedStatusBar(_providers) {
|
|
882
|
-
// No-op
|
|
782
|
+
// No-op - banner is streamed as content, status shown in control bar
|
|
883
783
|
}
|
|
884
784
|
/**
|
|
885
|
-
* Show streaming header
|
|
886
|
-
* Keeps the streaming section visually connected to the launch banner.
|
|
785
|
+
* Show streaming header - no-op, banner is streamed as content
|
|
887
786
|
*/
|
|
888
|
-
showStreamingHeader(
|
|
889
|
-
|
|
890
|
-
const model = banner ? this.formatModelLabel(banner.model) : null;
|
|
891
|
-
const provider = banner?.provider ?? '';
|
|
892
|
-
const workspace = banner?.workingDir ?? '';
|
|
893
|
-
if (!model && !provider && !workspace) {
|
|
894
|
-
return;
|
|
895
|
-
}
|
|
896
|
-
const width = clampWidthToAvailable(this.getColumnWidth() - 4, DISPLAY_CONSTANTS.MIN_MESSAGE_WIDTH, DISPLAY_CONSTANTS.MAX_MESSAGE_WIDTH);
|
|
897
|
-
const spaceAbove = options?.spaceAbove ?? true;
|
|
898
|
-
const spaceBelow = options?.spaceBelow ?? true;
|
|
899
|
-
// Plain output keeps the header lightweight
|
|
900
|
-
if (isPlainOutputMode()) {
|
|
901
|
-
const label = model ? `Streaming ${model}` : 'Streaming response';
|
|
902
|
-
this.withOutput(() => {
|
|
903
|
-
if (spaceAbove) {
|
|
904
|
-
this.writeLine();
|
|
905
|
-
}
|
|
906
|
-
this.writeLine(`--- ${label} ---`);
|
|
907
|
-
if (spaceBelow) {
|
|
908
|
-
this.writeLine();
|
|
909
|
-
}
|
|
910
|
-
});
|
|
911
|
-
return;
|
|
912
|
-
}
|
|
913
|
-
const sessionFrame = renderSessionFrame({
|
|
914
|
-
profileLabel: banner?.profileLabel ?? '',
|
|
915
|
-
profileName: banner?.profileName ?? '',
|
|
916
|
-
model: model ?? '',
|
|
917
|
-
provider,
|
|
918
|
-
workspace,
|
|
919
|
-
width,
|
|
920
|
-
});
|
|
921
|
-
this.withOutput(() => {
|
|
922
|
-
if (spaceAbove) {
|
|
923
|
-
this.writeLine();
|
|
924
|
-
}
|
|
925
|
-
this.writeLine(sessionFrame);
|
|
926
|
-
if (spaceBelow) {
|
|
927
|
-
this.writeLine();
|
|
928
|
-
}
|
|
929
|
-
});
|
|
787
|
+
showStreamingHeader(_options) {
|
|
788
|
+
// No-op - banner is streamed as content by the shell
|
|
930
789
|
}
|
|
931
790
|
/**
|
|
932
791
|
* Show model commands help
|
|
@@ -969,7 +828,7 @@ export class Display {
|
|
|
969
828
|
if (index < 1 || total < 1 || index > total) {
|
|
970
829
|
return;
|
|
971
830
|
}
|
|
972
|
-
const width =
|
|
831
|
+
const width = Math.max(DISPLAY_CONSTANTS.MIN_THOUGHT_WIDTH, Math.min(this.getColumnWidth(), DISPLAY_CONSTANTS.MAX_MESSAGE_WIDTH));
|
|
973
832
|
const heading = renderSectionHeading(`Plan ${index}/${total}`, {
|
|
974
833
|
subtitle: step,
|
|
975
834
|
icon: icons.arrow,
|
|
@@ -991,78 +850,14 @@ export class Display {
|
|
|
991
850
|
}
|
|
992
851
|
});
|
|
993
852
|
this.stdoutTracker.reset();
|
|
994
|
-
|
|
995
|
-
this.renderAndStoreBanner(this.bannerState, this.bannerState.model, this.bannerState.provider);
|
|
996
|
-
}
|
|
853
|
+
// Banner is streamed content - no re-render on clear
|
|
997
854
|
}
|
|
998
855
|
newLine() {
|
|
999
856
|
this.withOutput(() => {
|
|
1000
857
|
this.writeLine();
|
|
1001
858
|
});
|
|
1002
859
|
}
|
|
1003
|
-
|
|
1004
|
-
const availableColumns = this.getColumnWidth();
|
|
1005
|
-
const available = availableColumns - DISPLAY_CONSTANTS.BANNER_PADDING;
|
|
1006
|
-
return clampWidthToAvailable(available, DISPLAY_CONSTANTS.MIN_BANNER_WIDTH, DISPLAY_CONSTANTS.MAX_BANNER_WIDTH);
|
|
1007
|
-
}
|
|
1008
|
-
measureBannerHeight(banner) {
|
|
1009
|
-
if (!banner) {
|
|
1010
|
-
return 0;
|
|
1011
|
-
}
|
|
1012
|
-
return banner.split('\n').length;
|
|
1013
|
-
}
|
|
1014
|
-
/**
|
|
1015
|
-
* Attempts to rewrite the banner in place using terminal cursor manipulation.
|
|
1016
|
-
* Returns true if successful, false if rewrite is not possible.
|
|
1017
|
-
*/
|
|
1018
|
-
tryRewriteBanner(state, banner) {
|
|
1019
|
-
if (!this.outputStream.isTTY) {
|
|
1020
|
-
return false;
|
|
1021
|
-
}
|
|
1022
|
-
if (!banner || state.height <= 0) {
|
|
1023
|
-
return false;
|
|
1024
|
-
}
|
|
1025
|
-
const linesWritten = this.stdoutTracker.totalLines;
|
|
1026
|
-
const linesAfterBanner = linesWritten - (state.startLine + state.height);
|
|
1027
|
-
if (linesAfterBanner < 0) {
|
|
1028
|
-
return false;
|
|
1029
|
-
}
|
|
1030
|
-
const totalOffset = linesAfterBanner + state.height;
|
|
1031
|
-
const maxRows = this.outputStream.rows;
|
|
1032
|
-
if (typeof maxRows === 'number' && maxRows > 0 && totalOffset > maxRows) {
|
|
1033
|
-
return false;
|
|
1034
|
-
}
|
|
1035
|
-
try {
|
|
1036
|
-
this.withOutput(() => {
|
|
1037
|
-
moveCursor(this.outputStream, 0, -totalOffset);
|
|
1038
|
-
cursorTo(this.outputStream, 0);
|
|
1039
|
-
this.stdoutTracker.withSuspended(() => {
|
|
1040
|
-
this.outputStream.write(`${banner}\n`);
|
|
1041
|
-
});
|
|
1042
|
-
if (linesAfterBanner > 0) {
|
|
1043
|
-
moveCursor(this.outputStream, 0, linesAfterBanner);
|
|
1044
|
-
}
|
|
1045
|
-
cursorTo(this.outputStream, 0);
|
|
1046
|
-
});
|
|
1047
|
-
return true;
|
|
1048
|
-
}
|
|
1049
|
-
catch {
|
|
1050
|
-
return false;
|
|
1051
|
-
}
|
|
1052
|
-
}
|
|
1053
|
-
renderAndStoreBanner(state, model, provider) {
|
|
1054
|
-
const width = this.getBannerWidth();
|
|
1055
|
-
const banner = this.buildClaudeStyleBanner(state.profileLabel, state.profileName, model, provider, state.workingDir, width, state.version);
|
|
1056
|
-
const startLine = this.stdoutTracker.totalLines;
|
|
1057
|
-
this.withOutput(() => {
|
|
1058
|
-
this.writeLine(banner);
|
|
1059
|
-
});
|
|
1060
|
-
state.startLine = startLine;
|
|
1061
|
-
state.height = this.measureBannerHeight(banner);
|
|
1062
|
-
state.width = width;
|
|
1063
|
-
state.model = model;
|
|
1064
|
-
state.provider = provider;
|
|
1065
|
-
}
|
|
860
|
+
// Legacy banner methods removed - banner is streamed as content by the shell
|
|
1066
861
|
formatModelLabel(model) {
|
|
1067
862
|
if (/gpt-5\.1-?codex/i.test(model)) {
|
|
1068
863
|
return model;
|
|
@@ -1129,8 +924,7 @@ export class Display {
|
|
|
1129
924
|
}
|
|
1130
925
|
resolveMessageWidth() {
|
|
1131
926
|
const columns = this.getColumnWidth();
|
|
1132
|
-
|
|
1133
|
-
return clampWidthToAvailable(available, DISPLAY_CONSTANTS.MIN_MESSAGE_WIDTH, DISPLAY_CONSTANTS.MAX_MESSAGE_WIDTH);
|
|
927
|
+
return Math.max(DISPLAY_CONSTANTS.MIN_MESSAGE_WIDTH, Math.min(columns - DISPLAY_CONSTANTS.MESSAGE_PADDING, DISPLAY_CONSTANTS.MAX_MESSAGE_WIDTH));
|
|
1134
928
|
}
|
|
1135
929
|
formatTelemetryLine(metadata) {
|
|
1136
930
|
if (!metadata) {
|
|
@@ -1161,16 +955,96 @@ export class Display {
|
|
|
1161
955
|
}
|
|
1162
956
|
return `${seconds}s`;
|
|
1163
957
|
}
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
958
|
+
buildCommandPalette(commands, options) {
|
|
959
|
+
if (!commands.length) {
|
|
960
|
+
return '';
|
|
961
|
+
}
|
|
962
|
+
const width = Math.max(DISPLAY_CONSTANTS.MIN_MESSAGE_WIDTH, Math.min(this.getColumnWidth() - 2, DISPLAY_CONSTANTS.MAX_MESSAGE_WIDTH));
|
|
963
|
+
const indent = ' ';
|
|
964
|
+
const grouped = this.groupPaletteCommands(commands);
|
|
965
|
+
const commandWidth = this.computeCommandColumnWidth(commands, width, indent.length);
|
|
966
|
+
const descWidth = Math.max(DISPLAY_CONSTANTS.MIN_WRAP_WIDTH, width - indent.length - commandWidth - 1);
|
|
967
|
+
const title = options?.title ?? 'Slash commands';
|
|
968
|
+
const intro = options?.intro ?? 'Describe a task or pick a command below:';
|
|
969
|
+
const lines = [];
|
|
970
|
+
lines.push(theme.gradient.primary(title));
|
|
971
|
+
const introLines = this.wrapLine(intro, width);
|
|
972
|
+
for (const line of introLines) {
|
|
973
|
+
lines.push(theme.ui.muted(line));
|
|
974
|
+
}
|
|
975
|
+
lines.push('');
|
|
976
|
+
grouped.forEach(({ category, items }, index) => {
|
|
977
|
+
const label = this.formatPaletteCategory(category);
|
|
978
|
+
if (label) {
|
|
979
|
+
lines.push(theme.bold(label));
|
|
980
|
+
}
|
|
981
|
+
for (const item of items) {
|
|
982
|
+
const wrappedDesc = this.wrapLine(item.description, descWidth);
|
|
983
|
+
const paddedCommand = item.command.padEnd(commandWidth);
|
|
984
|
+
const commandLabel = theme.primary(paddedCommand);
|
|
985
|
+
const firstLine = wrappedDesc[0] ?? '';
|
|
986
|
+
lines.push(`${indent}${commandLabel} ${this.colorizePaletteText(firstLine, item.tone)}`);
|
|
987
|
+
for (const extra of wrappedDesc.slice(1)) {
|
|
988
|
+
lines.push(`${indent}${' '.repeat(commandWidth)} ${this.colorizePaletteText(extra, item.tone)}`);
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
if (index < grouped.length - 1) {
|
|
992
|
+
lines.push('');
|
|
993
|
+
}
|
|
1173
994
|
});
|
|
995
|
+
return lines.join('\n').trimEnd();
|
|
996
|
+
}
|
|
997
|
+
groupPaletteCommands(commands) {
|
|
998
|
+
const FALLBACK = 'other';
|
|
999
|
+
const groups = new Map();
|
|
1000
|
+
for (const item of commands) {
|
|
1001
|
+
const key = (item.category ?? FALLBACK).toLowerCase();
|
|
1002
|
+
const bucket = groups.get(key) ?? [];
|
|
1003
|
+
bucket.push(item);
|
|
1004
|
+
groups.set(key, bucket);
|
|
1005
|
+
}
|
|
1006
|
+
const order = ['configuration', 'workspace', 'diagnostics', 'other'];
|
|
1007
|
+
const orderedKeys = [
|
|
1008
|
+
...order.filter((key) => groups.has(key)),
|
|
1009
|
+
...Array.from(groups.keys()).filter((key) => !order.includes(key)),
|
|
1010
|
+
];
|
|
1011
|
+
return orderedKeys.map((category) => ({ category, items: groups.get(category) ?? [] }));
|
|
1012
|
+
}
|
|
1013
|
+
computeCommandColumnWidth(commands, totalWidth, indentWidth) {
|
|
1014
|
+
const longest = commands.reduce((max, item) => Math.max(max, this.visibleLength(item.command)), 0);
|
|
1015
|
+
const maxAllowed = Math.max(12, Math.min(longest + 2, Math.floor(totalWidth * 0.35)));
|
|
1016
|
+
const budget = Math.max(10, totalWidth - indentWidth - DISPLAY_CONSTANTS.MIN_WRAP_WIDTH);
|
|
1017
|
+
return Math.min(maxAllowed, budget);
|
|
1018
|
+
}
|
|
1019
|
+
formatPaletteCategory(category) {
|
|
1020
|
+
if (!category) {
|
|
1021
|
+
return 'Other';
|
|
1022
|
+
}
|
|
1023
|
+
switch (category.toLowerCase()) {
|
|
1024
|
+
case 'configuration':
|
|
1025
|
+
return 'Configuration';
|
|
1026
|
+
case 'workspace':
|
|
1027
|
+
return 'Workspace';
|
|
1028
|
+
case 'diagnostics':
|
|
1029
|
+
return 'Diagnostics';
|
|
1030
|
+
case 'other':
|
|
1031
|
+
return 'Other';
|
|
1032
|
+
default:
|
|
1033
|
+
return category[0]?.toUpperCase() + category.slice(1);
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
colorizePaletteText(text, tone) {
|
|
1037
|
+
switch (tone) {
|
|
1038
|
+
case 'warn':
|
|
1039
|
+
return theme.warning(text);
|
|
1040
|
+
case 'success':
|
|
1041
|
+
return theme.success(text);
|
|
1042
|
+
case 'info':
|
|
1043
|
+
return theme.info(text);
|
|
1044
|
+
case 'muted':
|
|
1045
|
+
default:
|
|
1046
|
+
return theme.ui.muted(text);
|
|
1047
|
+
}
|
|
1174
1048
|
}
|
|
1175
1049
|
/**
|
|
1176
1050
|
* Wraps text with a prefix on the first line and optional continuation prefix.
|
|
@@ -1180,9 +1054,9 @@ export class Display {
|
|
|
1180
1054
|
if (!text) {
|
|
1181
1055
|
return prefix.trimEnd();
|
|
1182
1056
|
}
|
|
1183
|
-
const width =
|
|
1057
|
+
const width = Math.max(DISPLAY_CONSTANTS.MIN_ACTION_WIDTH, Math.min(this.getColumnWidth(), DISPLAY_CONSTANTS.MAX_ACTION_WIDTH));
|
|
1184
1058
|
const prefixWidth = this.visibleLength(prefix);
|
|
1185
|
-
const available = Math.max(
|
|
1059
|
+
const available = Math.max(DISPLAY_CONSTANTS.MIN_CONTENT_WIDTH, width - prefixWidth);
|
|
1186
1060
|
const indent = typeof options?.continuationPrefix === 'string'
|
|
1187
1061
|
? options.continuationPrefix
|
|
1188
1062
|
: ' '.repeat(Math.max(0, prefixWidth));
|
|
@@ -1234,14 +1108,14 @@ export class Display {
|
|
|
1234
1108
|
border: theme.ui.border,
|
|
1235
1109
|
label: theme.info,
|
|
1236
1110
|
};
|
|
1237
|
-
const width =
|
|
1111
|
+
const width = Math.min(this.getColumnWidth() - 4, 70);
|
|
1238
1112
|
const lines = [];
|
|
1239
1113
|
// Simple header
|
|
1240
1114
|
lines.push(`${theme.ui.muted('⏺')} ${thinkingStyle.label('Thinking')}`);
|
|
1241
1115
|
// Parse and format the thinking content with simple indentation
|
|
1242
1116
|
const contentLines = content.split('\n').filter(line => line.trim());
|
|
1243
1117
|
for (const line of contentLines) {
|
|
1244
|
-
const wrapped = this.wrapLine(line.trim(),
|
|
1118
|
+
const wrapped = this.wrapLine(line.trim(), width - 4);
|
|
1245
1119
|
for (const wrappedLine of wrapped) {
|
|
1246
1120
|
lines.push(` ${thinkingStyle.text(wrappedLine)}`);
|
|
1247
1121
|
}
|