lsd-pi 1.3.6 → 1.3.9
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 +82 -0
- package/dist/cli.js +2 -1
- package/dist/lsd-settings-manager.d.ts +2 -0
- package/dist/lsd-settings-manager.js +5 -0
- package/dist/resource-loader.js +33 -3
- package/dist/resources/extensions/cache-timer/index.js +3 -2
- package/dist/resources/extensions/mcp-client/index.js +72 -4
- package/dist/resources/extensions/slash-commands/plan.js +5 -5
- package/dist/resources/extensions/usage/index.js +34 -2
- package/dist/resources/extensions/voice/index.js +1 -0
- package/dist/resources/extensions/voice/push-to-talk.js +2 -0
- package/dist/welcome-screen.js +2 -2
- package/package.json +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.context-usage.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/agent-session.context-usage.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/agent-session.context-usage.test.js +72 -0
- package/packages/pi-coding-agent/dist/core/agent-session.context-usage.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts +4 -0
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js +29 -2
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.js +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.collapse-tool-calls.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.collapse-tool-calls.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.collapse-tool-calls.test.js +35 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.collapse-tool-calls.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +6 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.js +12 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tool-priority.js +1 -1
- package/packages/pi-coding-agent/dist/core/tool-priority.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/edit-diff.d.ts +5 -0
- package/packages/pi-coding-agent/dist/core/tools/edit-diff.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/edit-diff.js +21 -0
- package/packages/pi-coding-agent/dist/core/tools/edit-diff.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.js +16 -1
- package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/main.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/main.js +1 -0
- package/packages/pi-coding-agent/dist/main.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-summary-line.test.js +12 -4
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-summary-line.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/diff.d.ts +7 -5
- package/packages/pi-coding-agent/dist/modes/interactive/components/diff.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/diff.js +86 -28
- package/packages/pi-coding-agent/dist/modes/interactive/components/diff.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +16 -10
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts +4 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js +26 -4
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +16 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +128 -13
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-summary-line.d.ts +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-summary-line.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-summary-line.js +48 -4
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-summary-line.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/__tests__/chat-controller.collapsed-tool-summary.test.js +137 -6
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/__tests__/chat-controller.collapsed-tool-summary.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +64 -15
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/extension-ui-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/extension-ui-controller.js +2 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/extension-ui-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +5 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +73 -27
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +4 -4
- package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js +3 -0
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/core/agent-session.context-usage.test.ts +87 -0
- package/packages/pi-coding-agent/src/core/agent-session.ts +40 -2
- package/packages/pi-coding-agent/src/core/extensions/runner.ts +1 -0
- package/packages/pi-coding-agent/src/core/extensions/types.ts +3 -0
- package/packages/pi-coding-agent/src/core/settings-manager.collapse-tool-calls.test.ts +46 -0
- package/packages/pi-coding-agent/src/core/settings-manager.ts +18 -0
- package/packages/pi-coding-agent/src/core/tool-priority.ts +1 -1
- package/packages/pi-coding-agent/src/core/tools/edit-diff.test.ts +20 -0
- package/packages/pi-coding-agent/src/core/tools/edit-diff.ts +26 -0
- package/packages/pi-coding-agent/src/main.ts +1 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-summary-line.test.ts +14 -4
- package/packages/pi-coding-agent/src/modes/interactive/components/diff.ts +105 -28
- package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +13 -6
- package/packages/pi-coding-agent/src/modes/interactive/components/settings-selector.ts +31 -4
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +137 -14
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-summary-line.ts +60 -4
- package/packages/pi-coding-agent/src/modes/interactive/controllers/__tests__/chat-controller.collapsed-tool-summary.test.ts +174 -6
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +73 -15
- package/packages/pi-coding-agent/src/modes/interactive/controllers/extension-ui-controller.ts +2 -1
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-state.ts +1 -0
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +76 -27
- package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +4 -4
- package/packages/pi-coding-agent/src/modes/rpc/rpc-mode.ts +4 -0
- package/packages/pi-tui/dist/components/editor.js +3 -3
- package/packages/pi-tui/dist/components/editor.js.map +1 -1
- package/packages/pi-tui/src/components/editor.ts +3 -3
- package/pkg/dist/modes/interactive/theme/themes.js +4 -4
- package/pkg/dist/modes/interactive/theme/themes.js.map +1 -1
- package/pkg/package.json +1 -1
- package/src/resources/extensions/cache-timer/index.ts +3 -2
- package/src/resources/extensions/mcp-client/index.ts +83 -4
- package/src/resources/extensions/mcp-client/tests/server-name-spaces.test.ts +16 -0
- package/src/resources/extensions/slash-commands/plan.ts +6 -6
- package/src/resources/extensions/usage/index.ts +40 -2
- package/src/resources/extensions/voice/index.ts +1 -0
- package/src/resources/extensions/voice/push-to-talk.ts +3 -0
- package/src/resources/extensions/voice/tests/push-to-talk.test.ts +6 -0
|
@@ -9,6 +9,15 @@ import { ToolSummaryLine } from "../components/tool-summary-line.js";
|
|
|
9
9
|
import { shouldCollapse } from "../../../core/tool-priority.js";
|
|
10
10
|
import { appKey } from "../components/keybinding-hints.js";
|
|
11
11
|
|
|
12
|
+
const GROUPABLE_COLLAPSED_TOOLS = new Set([
|
|
13
|
+
"read",
|
|
14
|
+
"find",
|
|
15
|
+
"ls",
|
|
16
|
+
"grep",
|
|
17
|
+
"lsp",
|
|
18
|
+
|
|
19
|
+
]);
|
|
20
|
+
|
|
12
21
|
export async function handleAgentEvent(host: InteractiveModeStateHost & {
|
|
13
22
|
init: () => Promise<void>;
|
|
14
23
|
getMarkdownThemeWithSettings: () => any;
|
|
@@ -42,6 +51,14 @@ export async function handleAgentEvent(host: InteractiveModeStateHost & {
|
|
|
42
51
|
host.collapsedToolSummaryLine = undefined;
|
|
43
52
|
};
|
|
44
53
|
|
|
54
|
+
// Tools that always render as their own visible row, never folded into a summary line
|
|
55
|
+
const ALWAYS_DIRECT_TOOLS = new Set([
|
|
56
|
+
"bash", "bg_shell",
|
|
57
|
+
"web_search", "search-the-web", "google_search", "search_and_read",
|
|
58
|
+
"fetch_page", "resolve_library", "get_library_docs",
|
|
59
|
+
"subagent", "await_subagent",
|
|
60
|
+
]);
|
|
61
|
+
|
|
45
62
|
const hasVisibleRender = (child: { render?: (width: number) => string[] } | undefined): boolean => {
|
|
46
63
|
if (!child?.render) return true;
|
|
47
64
|
try {
|
|
@@ -51,14 +68,20 @@ export async function handleAgentEvent(host: InteractiveModeStateHost & {
|
|
|
51
68
|
}
|
|
52
69
|
};
|
|
53
70
|
|
|
71
|
+
const canGroupCollapsedTool = (toolName: string): boolean => GROUPABLE_COLLAPSED_TOOLS.has(toolName);
|
|
72
|
+
|
|
54
73
|
const findAdjacentCollapsedToolSummary = (
|
|
74
|
+
toolName: string,
|
|
55
75
|
anchor?: { render: (width: number) => string[] },
|
|
56
76
|
): ToolSummaryLine | undefined => {
|
|
77
|
+
if (!canGroupCollapsedTool(toolName)) {
|
|
78
|
+
return undefined;
|
|
79
|
+
}
|
|
57
80
|
const anchorIndex = anchor ? host.chatContainer.children.indexOf(anchor) : host.chatContainer.children.length;
|
|
58
81
|
for (let i = anchorIndex - 1; i >= 0; i--) {
|
|
59
82
|
const child = host.chatContainer.children[i];
|
|
60
83
|
if (child instanceof ToolSummaryLine) {
|
|
61
|
-
return child;
|
|
84
|
+
return child.canGroupWith(toolName) ? child : undefined;
|
|
62
85
|
}
|
|
63
86
|
if (child instanceof ToolExecutionComponent && child.isHidden()) {
|
|
64
87
|
continue;
|
|
@@ -71,17 +94,15 @@ export async function handleAgentEvent(host: InteractiveModeStateHost & {
|
|
|
71
94
|
return undefined;
|
|
72
95
|
};
|
|
73
96
|
|
|
74
|
-
const appendCollapsedToolSummary = (
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
}
|
|
82
|
-
if (!summary || !host.chatContainer.children.includes(summary)) {
|
|
97
|
+
const appendCollapsedToolSummary = (
|
|
98
|
+
toolName: string,
|
|
99
|
+
elapsed: number,
|
|
100
|
+
anchor?: { render: (width: number) => string[] },
|
|
101
|
+
): ToolSummaryLine => {
|
|
102
|
+
let summary = findAdjacentCollapsedToolSummary(toolName, anchor);
|
|
103
|
+
if (!summary) {
|
|
83
104
|
summary = new ToolSummaryLine();
|
|
84
|
-
summary.setHidden(host.
|
|
105
|
+
summary.setHidden(host.collapsedToolCallsExpanded);
|
|
85
106
|
if (anchor) {
|
|
86
107
|
const anchorIndex = host.chatContainer.children.indexOf(anchor);
|
|
87
108
|
if (anchorIndex >= 0) {
|
|
@@ -92,9 +113,10 @@ export async function handleAgentEvent(host: InteractiveModeStateHost & {
|
|
|
92
113
|
} else {
|
|
93
114
|
host.chatContainer.addChild(summary);
|
|
94
115
|
}
|
|
95
|
-
host.collapsedToolSummaryLine = summary;
|
|
96
116
|
}
|
|
117
|
+
host.collapsedToolSummaryLine = summary;
|
|
97
118
|
summary.addTool(toolName, elapsed);
|
|
119
|
+
return summary;
|
|
98
120
|
};
|
|
99
121
|
|
|
100
122
|
switch (event.type) {
|
|
@@ -158,7 +180,7 @@ export async function handleAgentEvent(host: InteractiveModeStateHost & {
|
|
|
158
180
|
(text) => theme.fg("accent", text),
|
|
159
181
|
host.defaultWorkingMessage,
|
|
160
182
|
);
|
|
161
|
-
host.loadingAnimation.setCycleMessages(host.workingMessages,
|
|
183
|
+
host.loadingAnimation.setCycleMessages(host.workingMessages, 10_000);
|
|
162
184
|
host.statusContainer.addChild(host.loadingAnimation);
|
|
163
185
|
host.startLoadingTips();
|
|
164
186
|
// Show steer/queue + expand hint in editor bottom border while agent is running
|
|
@@ -221,8 +243,19 @@ export async function handleAgentEvent(host: InteractiveModeStateHost & {
|
|
|
221
243
|
host.ui,
|
|
222
244
|
);
|
|
223
245
|
component.setExpanded(host.toolOutputExpanded);
|
|
246
|
+
const collapseToolCalls = host.settingsManager.getCollapseToolCalls?.() ?? false;
|
|
247
|
+
const shouldHide = collapseToolCalls && !host.collapsedToolCallsExpanded && shouldCollapse(content.name, false) && !ALWAYS_DIRECT_TOOLS.has(content.name);
|
|
224
248
|
host.chatContainer.addChild(component);
|
|
249
|
+
if (shouldHide) {
|
|
250
|
+
// Check for adjacent summary AFTER adding to container so indexOf works
|
|
251
|
+
const adjacentSummary = findAdjacentCollapsedToolSummary(content.name, component);
|
|
252
|
+
if (adjacentSummary) {
|
|
253
|
+
component.setIndented(true);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
component.setHidden(shouldHide);
|
|
225
257
|
host.pendingTools.set(content.id, component);
|
|
258
|
+
host.updateEditorExpandHint();
|
|
226
259
|
} else {
|
|
227
260
|
host.pendingTools.get(content.id)?.updateArgs(content.arguments);
|
|
228
261
|
}
|
|
@@ -240,8 +273,19 @@ export async function handleAgentEvent(host: InteractiveModeStateHost & {
|
|
|
240
273
|
host.ui,
|
|
241
274
|
);
|
|
242
275
|
component.setExpanded(host.toolOutputExpanded);
|
|
276
|
+
const collapseToolCalls = host.settingsManager.getCollapseToolCalls?.() ?? false;
|
|
277
|
+
const shouldHide = collapseToolCalls && !host.collapsedToolCallsExpanded && shouldCollapse(content.name, false) && !ALWAYS_DIRECT_TOOLS.has(content.name);
|
|
243
278
|
host.chatContainer.addChild(component);
|
|
279
|
+
if (shouldHide) {
|
|
280
|
+
// Check for adjacent summary AFTER adding to container so indexOf works
|
|
281
|
+
const adjacentSummary = findAdjacentCollapsedToolSummary(content.name, component);
|
|
282
|
+
if (adjacentSummary) {
|
|
283
|
+
component.setIndented(true);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
component.setHidden(shouldHide);
|
|
244
287
|
host.pendingTools.set(content.id, component);
|
|
288
|
+
host.updateEditorExpandHint();
|
|
245
289
|
}
|
|
246
290
|
} else if (content.type === "webSearchResult") {
|
|
247
291
|
const component = host.pendingTools.get(content.toolUseId);
|
|
@@ -322,8 +366,19 @@ export async function handleAgentEvent(host: InteractiveModeStateHost & {
|
|
|
322
366
|
host.ui,
|
|
323
367
|
);
|
|
324
368
|
component.setExpanded(host.toolOutputExpanded);
|
|
369
|
+
const collapseToolCalls = host.settingsManager.getCollapseToolCalls?.() ?? false;
|
|
370
|
+
const shouldHide = collapseToolCalls && !host.collapsedToolCallsExpanded && shouldCollapse(event.toolName, false) && !ALWAYS_DIRECT_TOOLS.has(event.toolName);
|
|
325
371
|
host.chatContainer.addChild(component);
|
|
372
|
+
if (shouldHide) {
|
|
373
|
+
// Check for adjacent summary AFTER adding to container so indexOf works
|
|
374
|
+
const adjacentSummary = findAdjacentCollapsedToolSummary(event.toolName, component);
|
|
375
|
+
if (adjacentSummary) {
|
|
376
|
+
component.setIndented(true);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
component.setHidden(shouldHide);
|
|
326
380
|
host.pendingTools.set(event.toolCallId, component);
|
|
381
|
+
host.updateEditorExpandHint();
|
|
327
382
|
host.ui.requestRender();
|
|
328
383
|
}
|
|
329
384
|
break;
|
|
@@ -371,9 +426,12 @@ export async function handleAgentEvent(host: InteractiveModeStateHost & {
|
|
|
371
426
|
const component = host.pendingTools.get(event.toolCallId);
|
|
372
427
|
if (component) {
|
|
373
428
|
component.updateResult({ ...event.result, isError: event.isError });
|
|
374
|
-
|
|
429
|
+
const collapseToolCalls = host.settingsManager.getCollapseToolCalls?.() ?? false;
|
|
430
|
+
if (collapseToolCalls && shouldCollapse(event.toolName, event.isError) && !ALWAYS_DIRECT_TOOLS.has(event.toolName)) {
|
|
375
431
|
appendCollapsedToolSummary(event.toolName, component.getElapsed(), component);
|
|
376
|
-
component.setHidden(
|
|
432
|
+
component.setHidden(!host.collapsedToolCallsExpanded);
|
|
433
|
+
component.setIndented(false);
|
|
434
|
+
host.updateEditorExpandHint();
|
|
377
435
|
} else {
|
|
378
436
|
component.setHidden(false);
|
|
379
437
|
resetCollapsedToolSummary();
|
package/packages/pi-coding-agent/src/modes/interactive/controllers/extension-ui-controller.ts
CHANGED
|
@@ -53,8 +53,9 @@ export function createExtensionUIContext(host: any): ExtensionUIContext {
|
|
|
53
53
|
}
|
|
54
54
|
return result;
|
|
55
55
|
},
|
|
56
|
-
getToolsExpanded: () => host.toolOutputExpanded,
|
|
56
|
+
getToolsExpanded: () => host.collapsedToolCallsExpanded || host.toolOutputExpanded,
|
|
57
57
|
setToolsExpanded: (expanded) => host.setToolsExpanded(expanded),
|
|
58
|
+
isEditorFocused: () => !!host.editor.focused,
|
|
58
59
|
};
|
|
59
60
|
}
|
|
60
61
|
|
|
@@ -12,6 +12,7 @@ export interface InteractiveModeStateHost {
|
|
|
12
12
|
settingsManager: any;
|
|
13
13
|
pendingTools: Map<string, any>;
|
|
14
14
|
collapsedToolSummaryLine?: any;
|
|
15
|
+
collapsedToolCallsExpanded: boolean;
|
|
15
16
|
toolOutputExpanded: boolean;
|
|
16
17
|
hideThinkingBlock: boolean;
|
|
17
18
|
notificationSoundEnabled: boolean;
|
|
@@ -325,6 +325,7 @@ export class InteractiveMode {
|
|
|
325
325
|
private agentPtyComponents = new Map<string, EmbeddedTerminalComponent>();
|
|
326
326
|
|
|
327
327
|
// Tool output expansion state
|
|
328
|
+
private collapsedToolCallsExpanded = false;
|
|
328
329
|
private toolOutputExpanded = false;
|
|
329
330
|
|
|
330
331
|
// Thinking block visibility state
|
|
@@ -444,6 +445,7 @@ export class InteractiveMode {
|
|
|
444
445
|
// Load notification sound setting
|
|
445
446
|
this.notificationSoundEnabled = this.settingsManager.getNotificationSound();
|
|
446
447
|
this.footer.setNotificationSoundEnabled(this.notificationSoundEnabled);
|
|
448
|
+
this.footer.setVerboseFooterEnabled(this.settingsManager.getVerboseFooter());
|
|
447
449
|
|
|
448
450
|
// Register themes from resource loader and initialize
|
|
449
451
|
setRegisteredThemes(this.session.resourceLoader.getThemes().themes);
|
|
@@ -1536,7 +1538,7 @@ export class InteractiveMode {
|
|
|
1536
1538
|
this.defaultEditor.onExtensionShortcut = undefined;
|
|
1537
1539
|
this.updateTerminalTitle();
|
|
1538
1540
|
if (this.loadingAnimation) {
|
|
1539
|
-
this.loadingAnimation.setCycleMessages(this.workingMessages);
|
|
1541
|
+
this.loadingAnimation.setCycleMessages(this.workingMessages, 10_000);
|
|
1540
1542
|
}
|
|
1541
1543
|
}
|
|
1542
1544
|
|
|
@@ -1879,7 +1881,7 @@ export class InteractiveMode {
|
|
|
1879
1881
|
/** Reset the loading animation back to cycling working messages. */
|
|
1880
1882
|
private resetLoadingMessage(): void {
|
|
1881
1883
|
if (this.loadingAnimation) {
|
|
1882
|
-
this.loadingAnimation.setCycleMessages(this.workingMessages);
|
|
1884
|
+
this.loadingAnimation.setCycleMessages(this.workingMessages, 10_000);
|
|
1883
1885
|
}
|
|
1884
1886
|
}
|
|
1885
1887
|
|
|
@@ -2358,6 +2360,7 @@ export class InteractiveMode {
|
|
|
2358
2360
|
if (wasBashMode !== this.isBashMode) {
|
|
2359
2361
|
this.updateEditorBorderColor();
|
|
2360
2362
|
}
|
|
2363
|
+
this.updateEditorExpandHint();
|
|
2361
2364
|
};
|
|
2362
2365
|
|
|
2363
2366
|
// Handle clipboard image paste (triggered on Ctrl+V)
|
|
@@ -3072,63 +3075,93 @@ export class InteractiveMode {
|
|
|
3072
3075
|
}
|
|
3073
3076
|
}
|
|
3074
3077
|
|
|
3078
|
+
private hasCollapsedToolCallSummaries(): boolean {
|
|
3079
|
+
return this.chatContainer.children.some((child) => child instanceof ToolSummaryLine);
|
|
3080
|
+
}
|
|
3081
|
+
|
|
3082
|
+
private shouldUseCollapsedToolCallIntermediateState(): boolean {
|
|
3083
|
+
return this.settingsManager.getCollapseToolCalls() && this.hasCollapsedToolCallSummaries();
|
|
3084
|
+
}
|
|
3085
|
+
|
|
3075
3086
|
private toggleToolOutputExpansion(): void {
|
|
3076
|
-
|
|
3087
|
+
if (this.toolOutputExpanded) {
|
|
3088
|
+
this.setToolOutputExpansionState(false, false);
|
|
3089
|
+
return;
|
|
3090
|
+
}
|
|
3091
|
+
if (this.shouldUseCollapsedToolCallIntermediateState() && !this.collapsedToolCallsExpanded) {
|
|
3092
|
+
this.setToolOutputExpansionState(true, false);
|
|
3093
|
+
return;
|
|
3094
|
+
}
|
|
3095
|
+
this.setToolOutputExpansionState(true, true);
|
|
3077
3096
|
}
|
|
3078
3097
|
|
|
3079
3098
|
private setToolsExpanded(expanded: boolean): void {
|
|
3080
|
-
this.
|
|
3099
|
+
this.setToolOutputExpansionState(expanded, expanded);
|
|
3100
|
+
}
|
|
3101
|
+
|
|
3102
|
+
private setToolOutputExpansionState(collapsedToolCallsExpanded: boolean, toolOutputExpanded: boolean): void {
|
|
3103
|
+
this.collapsedToolCallsExpanded = collapsedToolCallsExpanded || toolOutputExpanded;
|
|
3104
|
+
this.toolOutputExpanded = toolOutputExpanded;
|
|
3105
|
+
const collapseToolCalls = this.settingsManager.getCollapseToolCalls();
|
|
3106
|
+
const showCollapsedToolCalls = collapseToolCalls && this.collapsedToolCallsExpanded;
|
|
3081
3107
|
for (const child of this.chatContainer.children) {
|
|
3082
3108
|
if (isExpandable(child)) {
|
|
3083
|
-
child.setExpanded(
|
|
3109
|
+
child.setExpanded(toolOutputExpanded);
|
|
3084
3110
|
}
|
|
3085
3111
|
if (child instanceof ToolExecutionComponent) {
|
|
3086
|
-
child.setHidden(!
|
|
3112
|
+
child.setHidden(!showCollapsedToolCalls && child.shouldHideWhenCollapsed(collapseToolCalls));
|
|
3113
|
+
child.setIndented(false);
|
|
3087
3114
|
}
|
|
3088
3115
|
if (child instanceof ToolSummaryLine) {
|
|
3089
|
-
child.setHidden(
|
|
3116
|
+
child.setHidden(!collapseToolCalls || showCollapsedToolCalls);
|
|
3090
3117
|
}
|
|
3091
3118
|
}
|
|
3092
3119
|
if (this.bashComponent) {
|
|
3093
|
-
this.bashComponent.setExpanded(
|
|
3120
|
+
this.bashComponent.setExpanded(toolOutputExpanded);
|
|
3094
3121
|
}
|
|
3095
3122
|
for (const component of this.pendingBashComponents) {
|
|
3096
|
-
component.setExpanded(
|
|
3123
|
+
component.setExpanded(toolOutputExpanded);
|
|
3097
3124
|
}
|
|
3098
3125
|
this.updateEditorExpandHint();
|
|
3099
3126
|
this.ui.requestRender();
|
|
3100
3127
|
}
|
|
3101
3128
|
|
|
3102
|
-
/** Append/remove
|
|
3129
|
+
/** Append/remove right-aligned expand and streaming hints in editor bottom border. */
|
|
3103
3130
|
updateEditorExpandHint(): void {
|
|
3104
3131
|
const expandKey = appKey(this.keybindings, "expandTools");
|
|
3105
3132
|
const collapseHint = `${theme.fg("dim", expandKey)}${theme.fg("muted", " collapse")}`;
|
|
3106
|
-
const
|
|
3107
|
-
|
|
3108
|
-
const
|
|
3109
|
-
const
|
|
3110
|
-
|
|
3111
|
-
|
|
3112
|
-
const baseHint = `${enterKey}${steerLabel} ${followUpKey}${queueLabel}`;
|
|
3133
|
+
const expandToolCallsHint = `${theme.fg("dim", expandKey)}${theme.fg("muted", " : uncollapsed tools")}`;
|
|
3134
|
+
const expandVerboseHint = `${theme.fg("dim", expandKey)}${theme.fg("muted", " : verbose")}`;
|
|
3135
|
+
const editorHasText = this.defaultEditor.getText().trim().length > 0;
|
|
3136
|
+
const streamingHints = editorHasText
|
|
3137
|
+
? `${theme.fg("dim", "↵")}${theme.fg("muted", " steer")} ${theme.fg("dim", appKey(this.keybindings, "followUp"))}${theme.fg("muted", " queue")}`
|
|
3138
|
+
: "";
|
|
3113
3139
|
|
|
3114
3140
|
// Check if there are any expandable tool outputs in the chat
|
|
3115
3141
|
const hasToolOutputs =
|
|
3116
3142
|
this.chatContainer.children.some(isExpandable) ||
|
|
3117
3143
|
!!this.bashComponent ||
|
|
3118
3144
|
this.pendingBashComponents.length > 0;
|
|
3145
|
+
const canExpandCollapsedToolCalls = this.shouldUseCollapsedToolCallIntermediateState();
|
|
3119
3146
|
|
|
3120
|
-
|
|
3147
|
+
let activeHint = expandVerboseHint;
|
|
3148
|
+
if (this.toolOutputExpanded) {
|
|
3149
|
+
activeHint = collapseHint;
|
|
3150
|
+
} else if (this.collapsedToolCallsExpanded && canExpandCollapsedToolCalls) {
|
|
3151
|
+
activeHint = expandVerboseHint;
|
|
3152
|
+
} else if (canExpandCollapsedToolCalls) {
|
|
3153
|
+
activeHint = expandToolCallsHint;
|
|
3154
|
+
}
|
|
3121
3155
|
|
|
3122
|
-
|
|
3123
|
-
|
|
3124
|
-
|
|
3125
|
-
? `${baseHint} ${activeHint}`
|
|
3126
|
-
: baseHint;
|
|
3127
|
-
} else if (hasToolOutputs) {
|
|
3128
|
-
// Idle - show expand/collapse hint so user knows ctrl+o works
|
|
3129
|
-
this.defaultEditor.bottomHint = activeHint;
|
|
3156
|
+
const rightHints: string[] = [];
|
|
3157
|
+
if (this.loadingAnimation && streamingHints) {
|
|
3158
|
+
rightHints.push(streamingHints);
|
|
3130
3159
|
}
|
|
3131
|
-
|
|
3160
|
+
if (hasToolOutputs) {
|
|
3161
|
+
rightHints.push(activeHint);
|
|
3162
|
+
}
|
|
3163
|
+
|
|
3164
|
+
this.defaultEditor.bottomHint = rightHints.join(" ");
|
|
3132
3165
|
}
|
|
3133
3166
|
|
|
3134
3167
|
private toggleThinkingBlockVisibility(): void {
|
|
@@ -3481,6 +3514,7 @@ export class InteractiveMode {
|
|
|
3481
3514
|
codexRotate: this.settingsManager.getCodexRotate(),
|
|
3482
3515
|
fastMode: this.settingsManager.getFastMode(),
|
|
3483
3516
|
cacheTimer: this.settingsManager.getCacheTimer(),
|
|
3517
|
+
verboseFooter: this.settingsManager.getVerboseFooter(),
|
|
3484
3518
|
pinLastPrompt: this.settingsManager.getPinLastPrompt(),
|
|
3485
3519
|
steeringMode: this.session.steeringMode,
|
|
3486
3520
|
followUpMode: this.session.followUpMode,
|
|
@@ -3505,6 +3539,7 @@ export class InteractiveMode {
|
|
|
3505
3539
|
clearOnShrink: this.settingsManager.getClearOnShrink(),
|
|
3506
3540
|
timestampFormat: this.settingsManager.getTimestampFormat(),
|
|
3507
3541
|
toolOutputMode: this.settingsManager.getToolOutputMode(),
|
|
3542
|
+
collapseToolCalls: this.settingsManager.getCollapseToolCalls(),
|
|
3508
3543
|
rtk: this.settingsManager.getRtk(),
|
|
3509
3544
|
editorScheme: this.settingsManager.getEditorScheme(),
|
|
3510
3545
|
autoDream: this.settingsManager.getAutoDream(),
|
|
@@ -3688,6 +3723,12 @@ export class InteractiveMode {
|
|
|
3688
3723
|
this.settingsManager.setCacheTimer(enabled);
|
|
3689
3724
|
this.showStatus(`Cache timer: ${enabled ? "enabled" : "disabled"}`);
|
|
3690
3725
|
},
|
|
3726
|
+
onVerboseFooterChange: (enabled) => {
|
|
3727
|
+
this.settingsManager.setVerboseFooter(enabled);
|
|
3728
|
+
this.footer.setVerboseFooterEnabled(enabled);
|
|
3729
|
+
this.ui.requestRender();
|
|
3730
|
+
this.showStatus(`Verbose footer: ${enabled ? "enabled" : "disabled"}`);
|
|
3731
|
+
},
|
|
3691
3732
|
onPinLastPromptChange: (enabled) => {
|
|
3692
3733
|
this.settingsManager.setPinLastPrompt(enabled);
|
|
3693
3734
|
this.pinLastPromptEnabled = enabled;
|
|
@@ -3827,6 +3868,14 @@ export class InteractiveMode {
|
|
|
3827
3868
|
this.settingsManager.setEditorScheme(scheme);
|
|
3828
3869
|
this.showStatus(`Editor link scheme: ${scheme}`);
|
|
3829
3870
|
},
|
|
3871
|
+
onCollapseToolCallsChange: (enabled) => {
|
|
3872
|
+
this.settingsManager.setCollapseToolCalls(enabled);
|
|
3873
|
+
this.setToolOutputExpansionState(enabled && (this.collapsedToolCallsExpanded || this.toolOutputExpanded), this.toolOutputExpanded);
|
|
3874
|
+
if (!enabled) {
|
|
3875
|
+
this.collapsedToolSummaryLine = undefined;
|
|
3876
|
+
}
|
|
3877
|
+
this.showStatus(`Collapse tool calls: ${enabled ? "enabled" : "disabled"}`);
|
|
3878
|
+
},
|
|
3830
3879
|
onToolOutputModeChange: (mode) => {
|
|
3831
3880
|
this.settingsManager.setToolOutputMode(mode);
|
|
3832
3881
|
for (const child of this.chatContainer.children) {
|
|
@@ -78,8 +78,8 @@ const dark: ThemeJson = {
|
|
|
78
78
|
mdHr: "gray",
|
|
79
79
|
mdListBullet: "accent",
|
|
80
80
|
|
|
81
|
-
toolDiffAdded: "
|
|
82
|
-
toolDiffRemoved: "
|
|
81
|
+
toolDiffAdded: "#4ade80",
|
|
82
|
+
toolDiffRemoved: "#fb7185",
|
|
83
83
|
toolDiffContext: "gray",
|
|
84
84
|
|
|
85
85
|
syntaxComment: "#6A9955",
|
|
@@ -174,8 +174,8 @@ const light: ThemeJson = {
|
|
|
174
174
|
mdHr: "mediumGray",
|
|
175
175
|
mdListBullet: "green",
|
|
176
176
|
|
|
177
|
-
toolDiffAdded: "
|
|
178
|
-
toolDiffRemoved: "
|
|
177
|
+
toolDiffAdded: "#15803d",
|
|
178
|
+
toolDiffRemoved: "#b91c1c",
|
|
179
179
|
toolDiffContext: "mediumGray",
|
|
180
180
|
|
|
181
181
|
syntaxComment: "#008000",
|
|
@@ -422,6 +422,10 @@ export async function runRpcMode(session: AgentSession): Promise<never> {
|
|
|
422
422
|
setToolsExpanded(_expanded: boolean) {
|
|
423
423
|
// Tool expansion not supported in RPC mode - no TUI
|
|
424
424
|
},
|
|
425
|
+
|
|
426
|
+
isEditorFocused() {
|
|
427
|
+
return false;
|
|
428
|
+
},
|
|
425
429
|
});
|
|
426
430
|
|
|
427
431
|
// Set up extensions with RPC-based UI context.
|
|
@@ -343,15 +343,15 @@ export class Editor {
|
|
|
343
343
|
result.push(this.borderColor(indicator + "─".repeat(Math.max(0, remaining))));
|
|
344
344
|
}
|
|
345
345
|
else if (this.bottomHint) {
|
|
346
|
-
// Embed hint right
|
|
346
|
+
// Embed hint at far right in bottom border: ─────────────── hint ─
|
|
347
347
|
// Apply borderColor only to the dashes so the hint's own styling is preserved.
|
|
348
348
|
const hintVisible = visibleWidth(this.bottomHint);
|
|
349
349
|
const minDashes = 1;
|
|
350
350
|
const separatorWidth = 1; // single space on each side of hint
|
|
351
351
|
const totalFixed = hintVisible + separatorWidth * 2 + minDashes * 2;
|
|
352
352
|
if (width >= totalFixed) {
|
|
353
|
-
const
|
|
354
|
-
const
|
|
353
|
+
const rightDashes = minDashes;
|
|
354
|
+
const leftDashes = Math.max(minDashes, width - hintVisible - separatorWidth * 2 - rightDashes);
|
|
355
355
|
const line = this.borderColor("─".repeat(leftDashes)) +
|
|
356
356
|
" " +
|
|
357
357
|
this.bottomHint +
|