@compilr-dev/cli 0.5.5 → 0.5.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.tsbuildinfo.app +1 -1
- package/dist/.tsbuildinfo.data +1 -1
- package/dist/.tsbuildinfo.domain +1 -1
- package/dist/.tsbuildinfo.foundation +1 -1
- package/dist/agent.js +22 -1
- package/dist/commands-v2/handlers/settings.js +13 -7
- package/dist/compilr-diff-companion.vsix +0 -0
- package/dist/repl-v2.js +8 -1
- package/dist/settings/index.d.ts +11 -0
- package/dist/settings/index.js +24 -1
- package/dist/ui/keyboard-handler.d.ts +6 -4
- package/dist/ui/keyboard-handler.js +11 -11
- package/dist/ui/live-region-facade.js +1 -0
- package/dist/ui/overlay/impl/config-overlay-v2.js +6 -5
- package/dist/ui/terminal-render-item.js +25 -3
- package/dist/ui/terminal-types.d.ts +3 -0
- package/dist/ui/terminal-types.js +1 -0
- package/dist/ui/terminal-ui.d.ts +6 -6
- package/dist/ui/terminal-ui.js +38 -24
- package/dist/ui/tool-formatters.js +368 -0
- package/dist/utils/readonly-tools.d.ts +8 -0
- package/dist/utils/readonly-tools.js +29 -0
- package/package.json +1 -1
package/dist/repl-v2.js
CHANGED
|
@@ -24,7 +24,8 @@ import { getCurrentProject } from './tools/project-db.js';
|
|
|
24
24
|
import { TerminalUI } from './ui/terminal-ui.js';
|
|
25
25
|
import * as terminal from './ui/terminal.js';
|
|
26
26
|
import { getStyles } from './themes/index.js';
|
|
27
|
-
import { getSettings, getStartupMode, syncPermissionModeFromUI, getPermissionMode, permissionModeToAgentMode, getProjectSessionMode, isFirstRunComplete, getSessionRetentionDays, updateSettings } from './settings/index.js';
|
|
27
|
+
import { getSettings, getStartupMode, syncPermissionModeFromUI, getPermissionMode, permissionModeToAgentMode, getProjectSessionMode, isFirstRunComplete, getSessionRetentionDays, updateSettings, getVerbosity } from './settings/index.js';
|
|
28
|
+
import { isReadOnlyTool } from './utils/readonly-tools.js';
|
|
28
29
|
import { renderMascotWithLogo } from './ui/mascot/renderer.js';
|
|
29
30
|
import { getStartupHighlights } from './changelog/index.js';
|
|
30
31
|
import { registerCommands, executeCommand, allCommands, getAutocompleteCommands, saveCurrentSession, saveCurrentTeam, loadProjectSession, archiveCurrentSession, convertMessagesToItems, } from './commands-v2/index.js';
|
|
@@ -801,6 +802,7 @@ export class ReplV2 {
|
|
|
801
802
|
const initialUiMode = permissionModeToAgentMode(savedPermissionMode);
|
|
802
803
|
this.ui = new TerminalUI({
|
|
803
804
|
initialMode: initialUiMode,
|
|
805
|
+
config: { verbosity: getVerbosity() },
|
|
804
806
|
});
|
|
805
807
|
// Print welcome screen
|
|
806
808
|
// Skip if: login overlay shows its own branded welcome,
|
|
@@ -2483,6 +2485,7 @@ export class ReplV2 {
|
|
|
2483
2485
|
params: categoryParam,
|
|
2484
2486
|
summary: `${String(count)} tools available`,
|
|
2485
2487
|
success: result.success,
|
|
2488
|
+
readOnly: isReadOnlyTool('list_tools'),
|
|
2486
2489
|
agentId: activeAgentId,
|
|
2487
2490
|
});
|
|
2488
2491
|
this.ui.setCurrentTool(null);
|
|
@@ -2517,6 +2520,7 @@ export class ReplV2 {
|
|
|
2517
2520
|
content: content || undefined,
|
|
2518
2521
|
diffLines: innerDiffLines,
|
|
2519
2522
|
success,
|
|
2523
|
+
readOnly: isReadOnlyTool(innerToolName),
|
|
2520
2524
|
agentId: activeAgentId,
|
|
2521
2525
|
});
|
|
2522
2526
|
this.ui.setCurrentTool(null);
|
|
@@ -2545,6 +2549,7 @@ export class ReplV2 {
|
|
|
2545
2549
|
params: name,
|
|
2546
2550
|
summary: `Schema: ${name}`,
|
|
2547
2551
|
success: result.success,
|
|
2552
|
+
readOnly: isReadOnlyTool('get_tool_info'),
|
|
2548
2553
|
agentId: activeAgentId,
|
|
2549
2554
|
});
|
|
2550
2555
|
this.ui.setCurrentTool(null);
|
|
@@ -2590,6 +2595,7 @@ export class ReplV2 {
|
|
|
2590
2595
|
content: content || undefined,
|
|
2591
2596
|
diffLines,
|
|
2592
2597
|
success,
|
|
2598
|
+
readOnly: isReadOnlyTool(toolName),
|
|
2593
2599
|
agentId: activeAgentId,
|
|
2594
2600
|
});
|
|
2595
2601
|
this.ui.setCurrentTool(null);
|
|
@@ -3154,6 +3160,7 @@ export class ReplV2 {
|
|
|
3154
3160
|
params: '**/*.ts',
|
|
3155
3161
|
summary: 'Found 42 files',
|
|
3156
3162
|
content: 'src/index.ts\nsrc/config.ts\nsrc/utils/helpers.ts\n... and 39 more',
|
|
3163
|
+
readOnly: true,
|
|
3157
3164
|
});
|
|
3158
3165
|
this.ui.setTodos([
|
|
3159
3166
|
{ content: 'Analyze the request', status: 'completed' },
|
package/dist/settings/index.d.ts
CHANGED
|
@@ -13,6 +13,7 @@ export type ProjectStartupMode = 'last' | 'off';
|
|
|
13
13
|
export type MascotSetting = 'none' | 'random' | 'neutral' | 'thinking' | 'looking_left' | 'looking_right' | 'sleeping' | 'alert' | 'error' | 'success' | 'success_minimal' | 'searching' | 'skeptical';
|
|
14
14
|
export type ProjectSessionMode = 'auto' | 'ask' | 'fresh';
|
|
15
15
|
export type CompactMode = 'active' | 'all' | 'auto';
|
|
16
|
+
export type Verbosity = 'normal' | 'focused' | 'verbose';
|
|
16
17
|
/**
|
|
17
18
|
* Permission rule for a tool or pattern.
|
|
18
19
|
* Supports wildcards: git_* matches git_commit, git_branch, etc.
|
|
@@ -34,6 +35,7 @@ export interface Settings {
|
|
|
34
35
|
showTips: boolean;
|
|
35
36
|
reviseCode: boolean;
|
|
36
37
|
verbose: boolean;
|
|
38
|
+
verbosity: Verbosity;
|
|
37
39
|
progressBar: boolean;
|
|
38
40
|
checkUpdates: boolean;
|
|
39
41
|
lastUpdateCheck: number | null;
|
|
@@ -82,6 +84,7 @@ export declare const getDefaultModel: () => string | null;
|
|
|
82
84
|
export declare const isAutoCompactEnabled: () => boolean;
|
|
83
85
|
export declare const isShowTipsEnabled: () => boolean;
|
|
84
86
|
export declare const isReviseCodeEnabled: () => boolean;
|
|
87
|
+
export declare const getVerbosity: () => Verbosity;
|
|
85
88
|
export declare const isVerboseEnabled: () => boolean;
|
|
86
89
|
export declare const isProgressBarEnabled: () => boolean;
|
|
87
90
|
export declare const isTelemetryEnabled: () => boolean;
|
|
@@ -166,6 +169,14 @@ export declare function sessionRetentionToDisplay(days: number): string;
|
|
|
166
169
|
* Map display value to session retention days
|
|
167
170
|
*/
|
|
168
171
|
export declare function displayToSessionRetention(display: string): number;
|
|
172
|
+
/**
|
|
173
|
+
* Map internal verbosity to display value
|
|
174
|
+
*/
|
|
175
|
+
export declare function verbosityToDisplay(v: Verbosity): string;
|
|
176
|
+
/**
|
|
177
|
+
* Map display value to internal verbosity
|
|
178
|
+
*/
|
|
179
|
+
export declare function displayToVerbosity(d: string): Verbosity;
|
|
169
180
|
/**
|
|
170
181
|
* Map internal compact mode to display value
|
|
171
182
|
*/
|
package/dist/settings/index.js
CHANGED
|
@@ -29,6 +29,7 @@ const DEFAULT_SETTINGS = {
|
|
|
29
29
|
showTips: true, // TODO: Not yet implemented
|
|
30
30
|
reviseCode: true, // TODO: Not yet implemented
|
|
31
31
|
verbose: false,
|
|
32
|
+
verbosity: 'normal',
|
|
32
33
|
progressBar: true,
|
|
33
34
|
// Update defaults
|
|
34
35
|
checkUpdates: true, // Check for updates on startup
|
|
@@ -112,7 +113,16 @@ export function getSettings() {
|
|
|
112
113
|
return settingsCache;
|
|
113
114
|
}
|
|
114
115
|
const stored = loadFromDisk();
|
|
116
|
+
let needsSave = false;
|
|
117
|
+
// Migration: convert verbose boolean to verbosity string (before merge with defaults)
|
|
118
|
+
if (!('verbosity' in stored) && stored.verbose === true) {
|
|
119
|
+
stored.verbosity = 'verbose';
|
|
120
|
+
needsSave = true;
|
|
121
|
+
}
|
|
115
122
|
settingsCache = { ...DEFAULT_SETTINGS, ...stored };
|
|
123
|
+
if (needsSave) {
|
|
124
|
+
saveToDisk(settingsCache);
|
|
125
|
+
}
|
|
116
126
|
// Migration: convert deprecated 'cwd' to 'off'
|
|
117
127
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
118
128
|
if (settingsCache.projectStartup === 'cwd') {
|
|
@@ -179,7 +189,8 @@ export const getDefaultModel = () => getSetting('defaultModel');
|
|
|
179
189
|
export const isAutoCompactEnabled = () => getSetting('autoCompact');
|
|
180
190
|
export const isShowTipsEnabled = () => getSetting('showTips'); // TODO: Not yet implemented
|
|
181
191
|
export const isReviseCodeEnabled = () => getSetting('reviseCode'); // TODO: Not yet implemented
|
|
182
|
-
export const
|
|
192
|
+
export const getVerbosity = () => getSetting('verbosity');
|
|
193
|
+
export const isVerboseEnabled = () => getVerbosity() === 'verbose';
|
|
183
194
|
export const isProgressBarEnabled = () => getSetting('progressBar');
|
|
184
195
|
export const isTelemetryEnabled = () => getSetting('telemetryEnabled');
|
|
185
196
|
// Update getters
|
|
@@ -378,6 +389,18 @@ export function displayToSessionRetention(display) {
|
|
|
378
389
|
return parseInt(match[1], 10);
|
|
379
390
|
return 30; // Default fallback
|
|
380
391
|
}
|
|
392
|
+
/**
|
|
393
|
+
* Map internal verbosity to display value
|
|
394
|
+
*/
|
|
395
|
+
export function verbosityToDisplay(v) {
|
|
396
|
+
return v === 'normal' ? 'Normal' : v === 'focused' ? 'Focused' : 'Verbose';
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* Map display value to internal verbosity
|
|
400
|
+
*/
|
|
401
|
+
export function displayToVerbosity(d) {
|
|
402
|
+
return d === 'Focused' ? 'focused' : d === 'Verbose' ? 'verbose' : 'normal';
|
|
403
|
+
}
|
|
381
404
|
/**
|
|
382
405
|
* Map internal compact mode to display value
|
|
383
406
|
*/
|
|
@@ -11,11 +11,13 @@ import type { AutocompleteController } from './autocomplete-controller.js';
|
|
|
11
11
|
import type { OverlayManager } from './overlay-manager.js';
|
|
12
12
|
import type { StatusBarController } from './status-bar-controller.js';
|
|
13
13
|
import type { Overlay } from './overlay/index.js';
|
|
14
|
+
import type { Verbosity } from '../settings/index.js';
|
|
14
15
|
export interface KeyboardHandlerHost {
|
|
15
16
|
isGuardActive(): boolean;
|
|
16
17
|
isAgentRunning(): boolean;
|
|
17
|
-
getViewMode(): 'normal' | 'verbose-temp';
|
|
18
|
-
setViewMode(mode: 'normal' | 'verbose-temp'): void;
|
|
18
|
+
getViewMode(): 'normal' | 'focused-temp' | 'verbose-temp';
|
|
19
|
+
setViewMode(mode: 'normal' | 'focused-temp' | 'verbose-temp'): void;
|
|
20
|
+
getPersistedVerbosity(): Verbosity;
|
|
19
21
|
requestRender(): void;
|
|
20
22
|
emit(event: string, ...args: unknown[]): void;
|
|
21
23
|
readonly input: InputController;
|
|
@@ -28,10 +30,10 @@ export interface KeyboardHandlerHost {
|
|
|
28
30
|
backgroundBashCommand(): void;
|
|
29
31
|
hasRestoredHistory(): boolean;
|
|
30
32
|
showRestoredHistory(): void;
|
|
31
|
-
|
|
33
|
+
cycleVerbosityView(): void;
|
|
32
34
|
toggleLiveRegionExpanded(): void;
|
|
33
35
|
toggleTodos(): void;
|
|
34
|
-
|
|
36
|
+
reRenderConversationWithVerbosity(verbosity: Verbosity): void;
|
|
35
37
|
}
|
|
36
38
|
export declare class KeyboardHandler {
|
|
37
39
|
private keyHandler;
|
|
@@ -126,10 +126,10 @@ export class KeyboardHandler {
|
|
|
126
126
|
handleEscape() {
|
|
127
127
|
const host = this.host;
|
|
128
128
|
const { input, ac } = host;
|
|
129
|
-
// In
|
|
130
|
-
if (host.getViewMode()
|
|
129
|
+
// In temp mode, escape returns to persisted verbosity
|
|
130
|
+
if (host.getViewMode() !== 'normal') {
|
|
131
131
|
host.setViewMode('normal');
|
|
132
|
-
host.
|
|
132
|
+
host.reRenderConversationWithVerbosity(host.getPersistedVerbosity());
|
|
133
133
|
return;
|
|
134
134
|
}
|
|
135
135
|
// Route escape to active overlay if present
|
|
@@ -261,17 +261,17 @@ export class KeyboardHandler {
|
|
|
261
261
|
host.statusBar.handleKey(str, key);
|
|
262
262
|
return;
|
|
263
263
|
}
|
|
264
|
-
// In verbose-temp
|
|
265
|
-
if (host.getViewMode()
|
|
266
|
-
// Ctrl+O
|
|
264
|
+
// In temp mode (focused-temp or verbose-temp), any key (except Ctrl+O) returns to persisted
|
|
265
|
+
if (host.getViewMode() !== 'normal') {
|
|
266
|
+
// Ctrl+O cycles to next temp mode
|
|
267
267
|
if (key.ctrl && key.name === 'o') {
|
|
268
|
-
host.
|
|
268
|
+
host.cycleVerbosityView();
|
|
269
269
|
host.toggleLiveRegionExpanded();
|
|
270
270
|
return;
|
|
271
271
|
}
|
|
272
|
-
// Any other key returns to
|
|
272
|
+
// Any other key returns to persisted verbosity
|
|
273
273
|
host.setViewMode('normal');
|
|
274
|
-
host.
|
|
274
|
+
host.reRenderConversationWithVerbosity(host.getPersistedVerbosity());
|
|
275
275
|
// Don't consume the key - let it be processed normally
|
|
276
276
|
}
|
|
277
277
|
// Ctrl+C - interrupt/exit
|
|
@@ -284,9 +284,9 @@ export class KeyboardHandler {
|
|
|
284
284
|
host.toggleTodos();
|
|
285
285
|
return;
|
|
286
286
|
}
|
|
287
|
-
// Ctrl+O -
|
|
287
|
+
// Ctrl+O - cycle verbosity view mode AND LiveRegion expansion
|
|
288
288
|
if (key.ctrl && key.name === 'o') {
|
|
289
|
-
host.
|
|
289
|
+
host.cycleVerbosityView();
|
|
290
290
|
host.toggleLiveRegionExpanded();
|
|
291
291
|
return;
|
|
292
292
|
}
|
|
@@ -15,7 +15,7 @@ import * as path from 'path';
|
|
|
15
15
|
import { execSync } from 'child_process';
|
|
16
16
|
import { BaseOverlayV2, isEscape, isTab, isShiftTab, isEnter, isSpace, isCtrlC, isNavigateUp, isNavigateDown, isBackspace, getNumberKey, isPrintable, extractPrintable, renderProgressBar, formatTokens, truncate, } from '../../base/index.js';
|
|
17
17
|
import { getCurrentTheme, } from '../../../themes/index.js';
|
|
18
|
-
import { getSettings, setSetting, permissionModeToDisplay, displayToPermissionMode, notificationModeToDisplay, displayToNotificationMode, projectStartupModeToDisplay, displayToProjectStartupMode, projectSessionModeToDisplay, displayToProjectSessionMode, sessionRetentionToDisplay, displayToSessionRetention, compactModeToDisplay, displayToCompactMode, } from '../../../settings/index.js';
|
|
18
|
+
import { getSettings, setSetting, permissionModeToDisplay, displayToPermissionMode, notificationModeToDisplay, displayToNotificationMode, projectStartupModeToDisplay, displayToProjectStartupMode, projectSessionModeToDisplay, displayToProjectSessionMode, sessionRetentionToDisplay, displayToSessionRetention, compactModeToDisplay, displayToCompactMode, verbosityToDisplay, displayToVerbosity, } from '../../../settings/index.js';
|
|
19
19
|
import { getResolvedPathConfig, setDeleteProtection, setProjectMatchRequired, setWorkspacePath, setProjectsPath, setDataPath, } from '../../../settings/paths.js';
|
|
20
20
|
import { MASCOT_LABELS, } from '../../mascot/index.js';
|
|
21
21
|
import { ThemeOverlayV2 } from './theme-overlay-v2.js';
|
|
@@ -128,7 +128,7 @@ function getConfigItems(currentModel) {
|
|
|
128
128
|
// { id: 'showTips', label: 'Show tips', type: 'boolean', value: settings.showTips },
|
|
129
129
|
// TODO: Implement checkpoints/rewind feature (Claude Code v2.0)
|
|
130
130
|
// { id: 'reviseCode', label: 'Revise code (checkpoints)', type: 'boolean', value: settings.reviseCode },
|
|
131
|
-
{ id: '
|
|
131
|
+
{ id: 'verbosity', label: 'Verbosity', type: 'cycle', value: verbosityToDisplay(settings.verbosity), options: ['Normal', 'Focused', 'Verbose'] },
|
|
132
132
|
{ id: 'progressBar', label: 'Terminal progress bar', type: 'boolean', value: settings.progressBar },
|
|
133
133
|
{
|
|
134
134
|
id: 'permissionMode',
|
|
@@ -623,9 +623,7 @@ export class ConfigOverlayV2 extends BaseOverlayV2 {
|
|
|
623
623
|
case 'autoCompact':
|
|
624
624
|
setSetting('autoCompact', newValue);
|
|
625
625
|
break;
|
|
626
|
-
|
|
627
|
-
setSetting('verbose', newValue);
|
|
628
|
-
break;
|
|
626
|
+
// verbose: removed — now a 'cycle' item as 'verbosity'
|
|
629
627
|
case 'progressBar':
|
|
630
628
|
setSetting('progressBar', newValue);
|
|
631
629
|
break;
|
|
@@ -680,6 +678,9 @@ export class ConfigOverlayV2 extends BaseOverlayV2 {
|
|
|
680
678
|
case 'compactMode':
|
|
681
679
|
setSetting('compactMode', displayToCompactMode(newValue));
|
|
682
680
|
break;
|
|
681
|
+
case 'verbosity':
|
|
682
|
+
setSetting('verbosity', displayToVerbosity(newValue));
|
|
683
|
+
break;
|
|
683
684
|
}
|
|
684
685
|
return null;
|
|
685
686
|
}
|
|
@@ -63,7 +63,7 @@ export function renderItem(item, config) {
|
|
|
63
63
|
}
|
|
64
64
|
case 'thinking':
|
|
65
65
|
// Only show thinking in verbose mode
|
|
66
|
-
if (config.verbose) {
|
|
66
|
+
if (config.verbosity === 'verbose') {
|
|
67
67
|
console.log(s.muted(`∴ Thinking…`));
|
|
68
68
|
console.log('');
|
|
69
69
|
// Indent thinking text
|
|
@@ -76,6 +76,9 @@ export function renderItem(item, config) {
|
|
|
76
76
|
// If not verbose, skip entirely (but still stored in history)
|
|
77
77
|
break;
|
|
78
78
|
case 'tool-start': {
|
|
79
|
+
// In focused mode, spinner already shows tool name — skip scroll output
|
|
80
|
+
if (config.verbosity === 'focused')
|
|
81
|
+
break;
|
|
79
82
|
// Truncate long params (e.g., long bash commands)
|
|
80
83
|
const maxLen = Math.min(60, terminal.getTerminalWidth() - 15);
|
|
81
84
|
let params = item.params;
|
|
@@ -94,6 +97,25 @@ export function renderItem(item, config) {
|
|
|
94
97
|
break;
|
|
95
98
|
}
|
|
96
99
|
case 'tool-result': {
|
|
100
|
+
// === FOCUSED MODE ===
|
|
101
|
+
if (config.verbosity === 'focused') {
|
|
102
|
+
// Errors always visible
|
|
103
|
+
if (item.success === false) {
|
|
104
|
+
console.log(s.info(`● ${item.name}`) + s.error(` — ${item.summary}`));
|
|
105
|
+
console.log('');
|
|
106
|
+
}
|
|
107
|
+
else if (item.readOnly) {
|
|
108
|
+
// Read-only tools: spinner-only, no scroll output
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
// Write/mutation tools: single summary line
|
|
113
|
+
console.log(s.info(`● ${item.name}`) + s.muted(` — ${item.summary}`));
|
|
114
|
+
console.log('');
|
|
115
|
+
}
|
|
116
|
+
break;
|
|
117
|
+
}
|
|
118
|
+
// === NORMAL & VERBOSE MODES ===
|
|
97
119
|
// Truncate long params (e.g., long bash commands)
|
|
98
120
|
const maxParamsLen = Math.min(60, terminal.getTerminalWidth() - 15);
|
|
99
121
|
let paramsDisplay = item.params;
|
|
@@ -114,7 +136,7 @@ export function renderItem(item, config) {
|
|
|
114
136
|
// Diff lines: render directly (already ANSI-formatted by diff.ts)
|
|
115
137
|
if (item.diffLines && item.diffLines.length > 0) {
|
|
116
138
|
const maxDiffPreview = 10;
|
|
117
|
-
if (config.verbose || item.diffLines.length <= maxDiffPreview) {
|
|
139
|
+
if (config.verbosity === 'verbose' || item.diffLines.length <= maxDiffPreview) {
|
|
118
140
|
for (const line of item.diffLines) {
|
|
119
141
|
console.log(` ${line}`);
|
|
120
142
|
}
|
|
@@ -130,7 +152,7 @@ export function renderItem(item, config) {
|
|
|
130
152
|
else if (item.content) {
|
|
131
153
|
const contentLines = item.content.split('\n').filter((l) => l.length > 0);
|
|
132
154
|
const maxPreviewLines = 3;
|
|
133
|
-
if (config.verbose) {
|
|
155
|
+
if (config.verbosity === 'verbose') {
|
|
134
156
|
// Verbose: show all lines
|
|
135
157
|
for (const line of contentLines) {
|
|
136
158
|
console.log(s.muted(` ⎿ ${line}`));
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import type { CommandOption } from './types.js';
|
|
8
8
|
import type { FileMatch } from './file-autocomplete.js';
|
|
9
|
+
import type { Verbosity } from '../settings/index.js';
|
|
9
10
|
/**
|
|
10
11
|
* Message to be sent to the agent from a command.
|
|
11
12
|
* Allows commands to invoke the agent with a detailed prompt while
|
|
@@ -39,6 +40,7 @@ export interface TerminalUIEvents {
|
|
|
39
40
|
*/
|
|
40
41
|
export interface TerminalUIConfig {
|
|
41
42
|
verbose: boolean;
|
|
43
|
+
verbosity: Verbosity;
|
|
42
44
|
theme: string;
|
|
43
45
|
showMascot: boolean;
|
|
44
46
|
}
|
|
@@ -121,6 +123,7 @@ export type PrintableItem = {
|
|
|
121
123
|
content?: string;
|
|
122
124
|
diffLines?: string[];
|
|
123
125
|
success?: boolean;
|
|
126
|
+
readOnly?: boolean;
|
|
124
127
|
agentId?: string;
|
|
125
128
|
} | {
|
|
126
129
|
type: 'tool-error';
|
package/dist/ui/terminal-ui.d.ts
CHANGED
|
@@ -224,15 +224,15 @@ export declare class TerminalUI extends EventEmitter {
|
|
|
224
224
|
*/
|
|
225
225
|
getShowTodos(): boolean;
|
|
226
226
|
/**
|
|
227
|
-
*
|
|
228
|
-
*
|
|
229
|
-
* Any key returns to
|
|
227
|
+
* Cycle verbosity view mode (Ctrl+O)
|
|
228
|
+
* Cycles: normal → focused-temp → verbose-temp → normal
|
|
229
|
+
* Any non-Ctrl+O key returns to persisted verbosity.
|
|
230
230
|
*/
|
|
231
|
-
|
|
231
|
+
cycleVerbosityView(): void;
|
|
232
232
|
/**
|
|
233
|
-
* Re-render conversation with temporary
|
|
233
|
+
* Re-render conversation with temporary verbosity setting.
|
|
234
234
|
*/
|
|
235
|
-
private
|
|
235
|
+
private reRenderConversationWithVerbosity;
|
|
236
236
|
/**
|
|
237
237
|
* Store restored conversation items for Ctrl+R history view.
|
|
238
238
|
* Called when a session is resumed/restored.
|
package/dist/ui/terminal-ui.js
CHANGED
|
@@ -83,9 +83,10 @@ export class TerminalUI extends EventEmitter {
|
|
|
83
83
|
activeTeamAgent = null;
|
|
84
84
|
// Todo visibility (Ctrl+T to toggle)
|
|
85
85
|
showTodos = true;
|
|
86
|
-
// View mode (Ctrl+O to
|
|
87
|
-
// normal:
|
|
88
|
-
//
|
|
86
|
+
// View mode (Ctrl+O to cycle: normal → focused-temp → verbose-temp → normal)
|
|
87
|
+
// normal: use persisted verbosity setting
|
|
88
|
+
// focused-temp: temporarily show focused mode (any key returns to persisted)
|
|
89
|
+
// verbose-temp: temporarily show verbose mode (any key returns to persisted)
|
|
89
90
|
viewMode = 'normal';
|
|
90
91
|
// Status bar navigation (down arrow into footer indicators)
|
|
91
92
|
statusBar = new StatusBarController({
|
|
@@ -104,7 +105,7 @@ export class TerminalUI extends EventEmitter {
|
|
|
104
105
|
isFooterRenderAllowed: () => this.isRunning && !this.isPaused && !this.overlay.hasActiveOverlay(),
|
|
105
106
|
getRenderData: () => ({
|
|
106
107
|
liveRegion: this.live.region,
|
|
107
|
-
liveVerbose: this.config.verbose,
|
|
108
|
+
liveVerbose: this.config.verbosity === 'verbose',
|
|
108
109
|
agentRunning: this.agentRunning,
|
|
109
110
|
currentTool: this.currentTool,
|
|
110
111
|
spinnerText: this.spinnerText,
|
|
@@ -136,6 +137,7 @@ export class TerminalUI extends EventEmitter {
|
|
|
136
137
|
isAgentRunning: () => this.agentRunning,
|
|
137
138
|
getViewMode: () => this.viewMode,
|
|
138
139
|
setViewMode: (mode) => { this.viewMode = mode; },
|
|
140
|
+
getPersistedVerbosity: () => this.config.verbosity,
|
|
139
141
|
requestRender: () => { this.needsRender = true; },
|
|
140
142
|
emit: (event, ...args) => { this.emit(event, ...args); },
|
|
141
143
|
input: this.input,
|
|
@@ -148,10 +150,10 @@ export class TerminalUI extends EventEmitter {
|
|
|
148
150
|
backgroundBashCommand: () => { this.backgroundBashCommand(); },
|
|
149
151
|
hasRestoredHistory: () => this.conversation.hasRestoredHistory(),
|
|
150
152
|
showRestoredHistory: () => { this.showRestoredHistory(); },
|
|
151
|
-
|
|
153
|
+
cycleVerbosityView: () => { this.cycleVerbosityView(); },
|
|
152
154
|
toggleLiveRegionExpanded: () => { this.toggleLiveRegionExpanded(); },
|
|
153
155
|
toggleTodos: () => { this.toggleTodos(); },
|
|
154
|
-
|
|
156
|
+
reRenderConversationWithVerbosity: (verbosity) => { this.reRenderConversationWithVerbosity(verbosity); },
|
|
155
157
|
});
|
|
156
158
|
constructor(options = {}) {
|
|
157
159
|
super();
|
|
@@ -517,42 +519,50 @@ export class TerminalUI extends EventEmitter {
|
|
|
517
519
|
return this.showTodos;
|
|
518
520
|
}
|
|
519
521
|
/**
|
|
520
|
-
*
|
|
521
|
-
*
|
|
522
|
-
* Any key returns to
|
|
522
|
+
* Cycle verbosity view mode (Ctrl+O)
|
|
523
|
+
* Cycles: normal → focused-temp → verbose-temp → normal
|
|
524
|
+
* Any non-Ctrl+O key returns to persisted verbosity.
|
|
523
525
|
*/
|
|
524
|
-
|
|
526
|
+
cycleVerbosityView() {
|
|
525
527
|
if (this.viewMode === 'normal') {
|
|
528
|
+
this.viewMode = 'focused-temp';
|
|
529
|
+
this.reRenderConversationWithVerbosity('focused');
|
|
530
|
+
}
|
|
531
|
+
else if (this.viewMode === 'focused-temp') {
|
|
526
532
|
this.viewMode = 'verbose-temp';
|
|
527
|
-
this.
|
|
533
|
+
this.reRenderConversationWithVerbosity('verbose');
|
|
528
534
|
}
|
|
529
535
|
else {
|
|
530
536
|
this.viewMode = 'normal';
|
|
531
|
-
this.
|
|
537
|
+
this.reRenderConversationWithVerbosity(this.config.verbosity);
|
|
532
538
|
}
|
|
533
539
|
}
|
|
534
540
|
/**
|
|
535
|
-
* Re-render conversation with temporary
|
|
541
|
+
* Re-render conversation with temporary verbosity setting.
|
|
536
542
|
*/
|
|
537
|
-
|
|
543
|
+
reRenderConversationWithVerbosity(verbosity) {
|
|
538
544
|
const s = getStyles();
|
|
539
545
|
// Clear screen and scrollback buffer
|
|
540
546
|
process.stdout.write('\x1b[2J\x1b[3J\x1b[H');
|
|
541
547
|
// Reset footer state
|
|
542
548
|
this.footer.resetRenderState();
|
|
543
|
-
// Show mode indicator at top
|
|
544
|
-
if (
|
|
545
|
-
console.log(s.info(`[
|
|
549
|
+
// Show mode indicator at top for temp modes
|
|
550
|
+
if (this.viewMode === 'focused-temp') {
|
|
551
|
+
console.log(s.info(`[Focused View] Press any key to return`));
|
|
552
|
+
console.log('');
|
|
553
|
+
}
|
|
554
|
+
else if (this.viewMode === 'verbose-temp') {
|
|
555
|
+
console.log(s.info(`[Verbose View] Press any key to return`));
|
|
546
556
|
console.log('');
|
|
547
557
|
}
|
|
548
|
-
// Re-render all items with temporary
|
|
549
|
-
const
|
|
550
|
-
this.config.
|
|
558
|
+
// Re-render all items with temporary verbosity override
|
|
559
|
+
const originalVerbosity = this.config.verbosity;
|
|
560
|
+
this.config.verbosity = verbosity;
|
|
551
561
|
for (const item of this.conversation.history) {
|
|
552
562
|
this.renderItemToConsole(item);
|
|
553
563
|
}
|
|
554
564
|
// Restore original config
|
|
555
|
-
this.config.
|
|
565
|
+
this.config.verbosity = originalVerbosity;
|
|
556
566
|
// Footer will be re-rendered by the render loop
|
|
557
567
|
this.needsRender = true;
|
|
558
568
|
}
|
|
@@ -604,10 +614,14 @@ export class TerminalUI extends EventEmitter {
|
|
|
604
614
|
* If verbose changes, re-renders the entire conversation.
|
|
605
615
|
*/
|
|
606
616
|
setConfig(newConfig) {
|
|
607
|
-
const
|
|
617
|
+
const oldVerbosity = this.config.verbosity;
|
|
608
618
|
this.config = { ...this.config, ...newConfig };
|
|
609
|
-
//
|
|
610
|
-
if (newConfig.
|
|
619
|
+
// Keep legacy verbose in sync with verbosity
|
|
620
|
+
if (newConfig.verbosity !== undefined) {
|
|
621
|
+
this.config.verbose = newConfig.verbosity === 'verbose';
|
|
622
|
+
}
|
|
623
|
+
// If verbosity changed, re-render entire conversation
|
|
624
|
+
if (newConfig.verbosity !== undefined && newConfig.verbosity !== oldVerbosity) {
|
|
611
625
|
this.reRenderConversation();
|
|
612
626
|
}
|
|
613
627
|
// Theme change requires prompt refresh
|