lsd-pi 1.3.2 → 1.3.7
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/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/browser-tools/tools/codegen.js +5 -5
- package/dist/resources/extensions/browser-tools/tools/navigation.js +107 -178
- package/dist/resources/extensions/browser-tools/tools/network-mock.js +112 -167
- package/dist/resources/extensions/browser-tools/tools/pages.js +182 -234
- package/dist/resources/extensions/browser-tools/tools/refs.js +202 -461
- package/dist/resources/extensions/browser-tools/tools/session.js +176 -323
- package/dist/resources/extensions/browser-tools/tools/state-persistence.js +91 -154
- package/dist/resources/extensions/browser-tools/utils.js +1 -1
- package/dist/resources/extensions/cache-timer/index.js +3 -2
- package/dist/resources/extensions/slash-commands/extension-manifest.json +2 -2
- package/dist/resources/extensions/slash-commands/fast.js +73 -0
- package/dist/resources/extensions/slash-commands/index.js +2 -0
- package/dist/resources/extensions/slash-commands/plan.js +37 -12
- package/dist/resources/extensions/subagent/background-job-manager.js +13 -0
- package/dist/resources/extensions/subagent/in-process-runner.js +387 -0
- package/dist/resources/extensions/subagent/index.js +278 -626
- package/dist/resources/extensions/subagent/legacy-runner.js +503 -0
- package/dist/resources/extensions/voice/index.js +96 -36
- package/dist/resources/extensions/voice/push-to-talk.js +26 -0
- package/dist/welcome-screen.js +2 -2
- package/package.json +1 -1
- package/packages/pi-agent-core/dist/agent.d.ts +19 -0
- package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/agent.js +16 -0
- package/packages/pi-agent-core/dist/agent.js.map +1 -1
- package/packages/pi-agent-core/src/agent.ts +32 -2
- package/packages/pi-ai/dist/providers/openai-codex-responses.d.ts +34 -1
- package/packages/pi-ai/dist/providers/openai-codex-responses.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/openai-codex-responses.js +32 -4
- package/packages/pi-ai/dist/providers/openai-codex-responses.js.map +1 -1
- package/packages/pi-ai/dist/providers/openai-codex-responses.test.js +127 -16
- package/packages/pi-ai/dist/providers/openai-codex-responses.test.js.map +1 -1
- package/packages/pi-ai/dist/providers/openai-responses.d.ts +8 -1
- package/packages/pi-ai/dist/providers/openai-responses.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/openai-responses.fast-mode.test.d.ts +2 -0
- package/packages/pi-ai/dist/providers/openai-responses.fast-mode.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/openai-responses.fast-mode.test.js +67 -0
- package/packages/pi-ai/dist/providers/openai-responses.fast-mode.test.js.map +1 -0
- package/packages/pi-ai/dist/providers/openai-responses.js +21 -3
- package/packages/pi-ai/dist/providers/openai-responses.js.map +1 -1
- package/packages/pi-ai/dist/providers/simple-options.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/simple-options.js +2 -0
- package/packages/pi-ai/dist/providers/simple-options.js.map +1 -1
- package/packages/pi-ai/dist/types.d.ts +5 -0
- package/packages/pi-ai/dist/types.d.ts.map +1 -1
- package/packages/pi-ai/dist/types.js.map +1 -1
- package/packages/pi-ai/src/providers/openai-codex-responses.test.ts +143 -20
- package/packages/pi-ai/src/providers/openai-codex-responses.ts +47 -4
- package/packages/pi-ai/src/providers/openai-responses.fast-mode.test.ts +73 -0
- package/packages/pi-ai/src/providers/openai-responses.ts +26 -3
- package/packages/pi-ai/src/providers/simple-options.ts +2 -0
- package/packages/pi-ai/src/types.ts +5 -0
- package/packages/pi-coding-agent/dist/core/keybindings.d.ts +1 -1
- package/packages/pi-coding-agent/dist/core/keybindings.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/keybindings.js +2 -0
- package/packages/pi-coding-agent/dist/core/keybindings.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.js +4 -2
- package/packages/pi-coding-agent/dist/core/sdk.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 +12 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.fast-mode.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.fast-mode.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.fast-mode.test.js +35 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.fast-mode.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.js +24 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/slash-commands.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/slash-commands.js +1 -0
- package/packages/pi-coding-agent/dist/core/slash-commands.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/system-prompt.js +6 -1
- package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tool-priority.d.ts +4 -0
- package/packages/pi-coding-agent/dist/core/tool-priority.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/tool-priority.js +18 -0
- package/packages/pi-coding-agent/dist/core/tool-priority.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/tool-priority.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/tool-priority.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/tool-priority.test.js +27 -0
- package/packages/pi-coding-agent/dist/core/tool-priority.test.js.map +1 -0
- 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/modes/interactive/components/__tests__/tool-summary-line.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-summary-line.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-summary-line.test.js +34 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-summary-line.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/btw-overlay.d.ts +45 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/btw-overlay.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/btw-overlay.js +314 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/btw-overlay.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/btw-overlay.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/btw-overlay.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/btw-overlay.test.js +122 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/btw-overlay.test.js.map +1 -0
- 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 +4 -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 +23 -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 +8 -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 +52 -6
- 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 +19 -0
- 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 +127 -14
- 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 +14 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-summary-line.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-summary-line.js +93 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-summary-line.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/__tests__/chat-controller.collapsed-tool-summary.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/__tests__/chat-controller.collapsed-tool-summary.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/__tests__/chat-controller.collapsed-tool-summary.test.js +328 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/__tests__/chat-controller.collapsed-tool-summary.test.js.map +1 -0
- 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 +123 -0
- 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.js +1 -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/controllers/input-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +7 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts +4 -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 +9 -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 +103 -23
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js +41 -0
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.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/package.json +1 -1
- package/packages/pi-coding-agent/src/core/keybindings.ts +4 -1
- package/packages/pi-coding-agent/src/core/sdk.ts +4 -2
- 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.fast-mode.test.ts +46 -0
- package/packages/pi-coding-agent/src/core/settings-manager.ts +36 -0
- package/packages/pi-coding-agent/src/core/slash-commands.ts +1 -0
- package/packages/pi-coding-agent/src/core/system-prompt.ts +6 -1
- package/packages/pi-coding-agent/src/core/tool-priority.test.ts +30 -0
- package/packages/pi-coding-agent/src/core/tool-priority.ts +17 -0
- 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/modes/interactive/components/__tests__/tool-summary-line.test.ts +41 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/btw-overlay.test.ts +172 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/btw-overlay.ts +402 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/diff.ts +105 -28
- package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +21 -6
- package/packages/pi-coding-agent/src/modes/interactive/components/settings-selector.ts +63 -6
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +1262 -1138
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-summary-line.ts +120 -0
- package/packages/pi-coding-agent/src/modes/interactive/controllers/__tests__/chat-controller.collapsed-tool-summary.test.ts +396 -0
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +530 -398
- package/packages/pi-coding-agent/src/modes/interactive/controllers/extension-ui-controller.ts +1 -1
- package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +7 -0
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-state.ts +4 -0
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +109 -23
- package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.ts +60 -1
- package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +4 -4
- 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/browser-tools/tools/codegen.ts +5 -5
- package/src/resources/extensions/browser-tools/tools/navigation.ts +118 -196
- package/src/resources/extensions/browser-tools/tools/network-mock.ts +114 -205
- package/src/resources/extensions/browser-tools/tools/pages.ts +183 -237
- package/src/resources/extensions/browser-tools/tools/refs.ts +193 -507
- package/src/resources/extensions/browser-tools/tools/session.ts +182 -321
- package/src/resources/extensions/browser-tools/tools/state-persistence.ts +94 -172
- package/src/resources/extensions/browser-tools/utils.ts +1 -1
- package/src/resources/extensions/cache-timer/index.ts +3 -2
- package/src/resources/extensions/slash-commands/extension-manifest.json +2 -2
- package/src/resources/extensions/slash-commands/fast.ts +89 -0
- package/src/resources/extensions/slash-commands/index.ts +2 -0
- package/src/resources/extensions/slash-commands/plan.ts +42 -12
- package/src/resources/extensions/subagent/background-job-manager.ts +28 -0
- package/src/resources/extensions/subagent/in-process-runner.ts +534 -0
- package/src/resources/extensions/subagent/index.ts +489 -799
- package/src/resources/extensions/subagent/legacy-runner.ts +607 -0
- package/src/resources/extensions/voice/index.ts +308 -238
- package/src/resources/extensions/voice/push-to-talk.ts +42 -0
- package/src/resources/extensions/voice/tests/push-to-talk.test.ts +109 -0
package/packages/pi-coding-agent/src/modes/interactive/controllers/extension-ui-controller.ts
CHANGED
|
@@ -53,7 +53,7 @@ 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
58
|
};
|
|
59
59
|
}
|
|
@@ -54,6 +54,13 @@ export function setupEditorSubmitHandler(host: InteractiveModeStateHost & {
|
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
if (host.session.isStreaming) {
|
|
57
|
+
if (text === "/btw" || text.startsWith("/btw ")) {
|
|
58
|
+
const handled = await dispatchSlashCommand(text, host.getSlashCommandContext());
|
|
59
|
+
if (handled) {
|
|
60
|
+
host.editor.setText("");
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
57
64
|
host.editor.addToHistory?.(text);
|
|
58
65
|
host.editor.setText("");
|
|
59
66
|
host.recordLastSentPrompt?.(text);
|
|
@@ -11,8 +11,12 @@ export interface InteractiveModeStateHost {
|
|
|
11
11
|
chatContainer: any;
|
|
12
12
|
settingsManager: any;
|
|
13
13
|
pendingTools: Map<string, any>;
|
|
14
|
+
collapsedToolSummaryLine?: any;
|
|
15
|
+
collapsedToolCallsExpanded: boolean;
|
|
14
16
|
toolOutputExpanded: boolean;
|
|
15
17
|
hideThinkingBlock: boolean;
|
|
18
|
+
notificationSoundEnabled: boolean;
|
|
19
|
+
playNotificationSoundOnAgentEnd: boolean;
|
|
16
20
|
isBashMode: boolean;
|
|
17
21
|
onInputCallback?: (text: string) => void;
|
|
18
22
|
isInitialized: boolean;
|
|
@@ -99,6 +99,7 @@ import { SessionSelectorComponent } from "./components/session-selector.js";
|
|
|
99
99
|
import { SettingsSelectorComponent } from "./components/settings-selector.js";
|
|
100
100
|
import { SkillInvocationMessageComponent } from "./components/skill-invocation-message.js";
|
|
101
101
|
import { ToolExecutionComponent } from "./components/tool-execution.js";
|
|
102
|
+
import { ToolSummaryLine } from "./components/tool-summary-line.js";
|
|
102
103
|
import { TreeSelectorComponent } from "./components/tree-selector.js";
|
|
103
104
|
import { UserMessageComponent } from "./components/user-message.js";
|
|
104
105
|
import { UserMessageSelectorComponent } from "./components/user-message-selector.js";
|
|
@@ -320,14 +321,20 @@ export class InteractiveMode {
|
|
|
320
321
|
|
|
321
322
|
// Tool execution tracking: toolCallId -> component
|
|
322
323
|
private pendingTools = new Map<string, ToolExecutionComponent>();
|
|
324
|
+
private collapsedToolSummaryLine: ToolSummaryLine | undefined = undefined;
|
|
323
325
|
private agentPtyComponents = new Map<string, EmbeddedTerminalComponent>();
|
|
324
326
|
|
|
325
327
|
// Tool output expansion state
|
|
328
|
+
private collapsedToolCallsExpanded = false;
|
|
326
329
|
private toolOutputExpanded = false;
|
|
327
330
|
|
|
328
331
|
// Thinking block visibility state
|
|
329
332
|
private hideThinkingBlock = false;
|
|
330
333
|
|
|
334
|
+
// Notification sound (terminal bell on completed agent response)
|
|
335
|
+
notificationSoundEnabled = false;
|
|
336
|
+
playNotificationSoundOnAgentEnd = false;
|
|
337
|
+
|
|
331
338
|
// Pin last prompt feature
|
|
332
339
|
private pinLastPromptEnabled = false;
|
|
333
340
|
private lastSentPromptText: string | undefined = undefined;
|
|
@@ -435,6 +442,11 @@ export class InteractiveMode {
|
|
|
435
442
|
// Load pin last prompt setting
|
|
436
443
|
this.pinLastPromptEnabled = this.settingsManager.getPinLastPrompt();
|
|
437
444
|
|
|
445
|
+
// Load notification sound setting
|
|
446
|
+
this.notificationSoundEnabled = this.settingsManager.getNotificationSound();
|
|
447
|
+
this.footer.setNotificationSoundEnabled(this.notificationSoundEnabled);
|
|
448
|
+
this.footer.setVerboseFooterEnabled(this.settingsManager.getVerboseFooter());
|
|
449
|
+
|
|
438
450
|
// Register themes from resource loader and initialize
|
|
439
451
|
setRegisteredThemes(this.session.resourceLoader.getThemes().themes);
|
|
440
452
|
initTheme(this.settingsManager.getTheme(), true, this.settingsManager.getThemeAccent());
|
|
@@ -2327,6 +2339,7 @@ export class InteractiveMode {
|
|
|
2327
2339
|
this.defaultEditor.onAction("cyclePermissionMode", () => this.cyclePermissionMode());
|
|
2328
2340
|
this.defaultEditor.onAction("showHotkeys", () => showHotkeys(this.getSlashCommandContext()));
|
|
2329
2341
|
this.defaultEditor.onAction("terminalFocus", () => this.toggleEmbeddedTerminalFocus());
|
|
2342
|
+
this.defaultEditor.onAction("toggleNotificationSound", () => this.toggleNotificationSound());
|
|
2330
2343
|
|
|
2331
2344
|
// Global debug handler on TUI (works regardless of focus)
|
|
2332
2345
|
this.ui.onDebug = () => this.handleDebugCommand();
|
|
@@ -2347,6 +2360,7 @@ export class InteractiveMode {
|
|
|
2347
2360
|
if (wasBashMode !== this.isBashMode) {
|
|
2348
2361
|
this.updateEditorBorderColor();
|
|
2349
2362
|
}
|
|
2363
|
+
this.updateEditorExpandHint();
|
|
2350
2364
|
};
|
|
2351
2365
|
|
|
2352
2366
|
// Handle clipboard image paste (triggered on Ctrl+V)
|
|
@@ -3035,6 +3049,14 @@ export class InteractiveMode {
|
|
|
3035
3049
|
}
|
|
3036
3050
|
}
|
|
3037
3051
|
|
|
3052
|
+
private toggleNotificationSound(): void {
|
|
3053
|
+
this.notificationSoundEnabled = !this.notificationSoundEnabled;
|
|
3054
|
+
this.settingsManager.setNotificationSound(this.notificationSoundEnabled);
|
|
3055
|
+
this.footer.setNotificationSoundEnabled(this.notificationSoundEnabled);
|
|
3056
|
+
this.ui.requestRender();
|
|
3057
|
+
this.showStatus(`Notification sound: ${this.notificationSoundEnabled ? "enabled" : "disabled"}`);
|
|
3058
|
+
}
|
|
3059
|
+
|
|
3038
3060
|
private async cycleModel(direction: "forward" | "backward"): Promise<void> {
|
|
3039
3061
|
try {
|
|
3040
3062
|
const result = await this.session.cycleModel(direction);
|
|
@@ -3053,57 +3075,92 @@ export class InteractiveMode {
|
|
|
3053
3075
|
}
|
|
3054
3076
|
}
|
|
3055
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
|
+
|
|
3056
3086
|
private toggleToolOutputExpansion(): void {
|
|
3057
|
-
|
|
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);
|
|
3058
3096
|
}
|
|
3059
3097
|
|
|
3060
3098
|
private setToolsExpanded(expanded: boolean): void {
|
|
3061
|
-
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;
|
|
3062
3107
|
for (const child of this.chatContainer.children) {
|
|
3063
3108
|
if (isExpandable(child)) {
|
|
3064
|
-
child.setExpanded(
|
|
3109
|
+
child.setExpanded(toolOutputExpanded);
|
|
3110
|
+
}
|
|
3111
|
+
if (child instanceof ToolExecutionComponent) {
|
|
3112
|
+
child.setHidden(!showCollapsedToolCalls && child.shouldHideWhenCollapsed(collapseToolCalls));
|
|
3113
|
+
}
|
|
3114
|
+
if (child instanceof ToolSummaryLine) {
|
|
3115
|
+
child.setHidden(!collapseToolCalls || showCollapsedToolCalls);
|
|
3065
3116
|
}
|
|
3066
3117
|
}
|
|
3067
3118
|
if (this.bashComponent) {
|
|
3068
|
-
this.bashComponent.setExpanded(
|
|
3119
|
+
this.bashComponent.setExpanded(toolOutputExpanded);
|
|
3069
3120
|
}
|
|
3070
3121
|
for (const component of this.pendingBashComponents) {
|
|
3071
|
-
component.setExpanded(
|
|
3122
|
+
component.setExpanded(toolOutputExpanded);
|
|
3072
3123
|
}
|
|
3073
3124
|
this.updateEditorExpandHint();
|
|
3074
3125
|
this.ui.requestRender();
|
|
3075
3126
|
}
|
|
3076
3127
|
|
|
3077
|
-
/** Append/remove
|
|
3128
|
+
/** Append/remove right-aligned expand and streaming hints in editor bottom border. */
|
|
3078
3129
|
updateEditorExpandHint(): void {
|
|
3079
3130
|
const expandKey = appKey(this.keybindings, "expandTools");
|
|
3080
3131
|
const collapseHint = `${theme.fg("dim", expandKey)}${theme.fg("muted", " collapse")}`;
|
|
3081
|
-
const
|
|
3082
|
-
|
|
3083
|
-
const
|
|
3084
|
-
const
|
|
3085
|
-
|
|
3086
|
-
|
|
3087
|
-
const baseHint = `${enterKey}${steerLabel} ${followUpKey}${queueLabel}`;
|
|
3132
|
+
const expandToolCallsHint = `${theme.fg("dim", expandKey)}${theme.fg("muted", " : uncollapsed tools")}`;
|
|
3133
|
+
const expandVerboseHint = `${theme.fg("dim", expandKey)}${theme.fg("muted", " : verbose")}`;
|
|
3134
|
+
const editorHasText = this.defaultEditor.getText().trim().length > 0;
|
|
3135
|
+
const streamingHints = editorHasText
|
|
3136
|
+
? `${theme.fg("dim", "↵")}${theme.fg("muted", " steer")} ${theme.fg("dim", appKey(this.keybindings, "followUp"))}${theme.fg("muted", " queue")}`
|
|
3137
|
+
: "";
|
|
3088
3138
|
|
|
3089
3139
|
// Check if there are any expandable tool outputs in the chat
|
|
3090
3140
|
const hasToolOutputs =
|
|
3091
3141
|
this.chatContainer.children.some(isExpandable) ||
|
|
3092
3142
|
!!this.bashComponent ||
|
|
3093
3143
|
this.pendingBashComponents.length > 0;
|
|
3144
|
+
const canExpandCollapsedToolCalls = this.shouldUseCollapsedToolCallIntermediateState();
|
|
3094
3145
|
|
|
3095
|
-
|
|
3146
|
+
let activeHint = expandVerboseHint;
|
|
3147
|
+
if (this.toolOutputExpanded) {
|
|
3148
|
+
activeHint = collapseHint;
|
|
3149
|
+
} else if (this.collapsedToolCallsExpanded && canExpandCollapsedToolCalls) {
|
|
3150
|
+
activeHint = expandVerboseHint;
|
|
3151
|
+
} else if (canExpandCollapsedToolCalls) {
|
|
3152
|
+
activeHint = expandToolCallsHint;
|
|
3153
|
+
}
|
|
3096
3154
|
|
|
3097
|
-
|
|
3098
|
-
|
|
3099
|
-
|
|
3100
|
-
|
|
3101
|
-
|
|
3102
|
-
|
|
3103
|
-
// Idle - show expand/collapse hint so user knows ctrl+o works
|
|
3104
|
-
this.defaultEditor.bottomHint = activeHint;
|
|
3155
|
+
const rightHints: string[] = [];
|
|
3156
|
+
if (this.loadingAnimation && streamingHints) {
|
|
3157
|
+
rightHints.push(streamingHints);
|
|
3158
|
+
}
|
|
3159
|
+
if (hasToolOutputs) {
|
|
3160
|
+
rightHints.push(activeHint);
|
|
3105
3161
|
}
|
|
3106
|
-
|
|
3162
|
+
|
|
3163
|
+
this.defaultEditor.bottomHint = rightHints.join(" ");
|
|
3107
3164
|
}
|
|
3108
3165
|
|
|
3109
3166
|
private toggleThinkingBlockVisibility(): void {
|
|
@@ -3454,7 +3511,9 @@ export class InteractiveMode {
|
|
|
3454
3511
|
enableSkillCommands: this.settingsManager.getEnableSkillCommands(),
|
|
3455
3512
|
toolProfile: this.settingsManager.getToolProfile(),
|
|
3456
3513
|
codexRotate: this.settingsManager.getCodexRotate(),
|
|
3514
|
+
fastMode: this.settingsManager.getFastMode(),
|
|
3457
3515
|
cacheTimer: this.settingsManager.getCacheTimer(),
|
|
3516
|
+
verboseFooter: this.settingsManager.getVerboseFooter(),
|
|
3458
3517
|
pinLastPrompt: this.settingsManager.getPinLastPrompt(),
|
|
3459
3518
|
steeringMode: this.session.steeringMode,
|
|
3460
3519
|
followUpMode: this.session.followUpMode,
|
|
@@ -3479,10 +3538,12 @@ export class InteractiveMode {
|
|
|
3479
3538
|
clearOnShrink: this.settingsManager.getClearOnShrink(),
|
|
3480
3539
|
timestampFormat: this.settingsManager.getTimestampFormat(),
|
|
3481
3540
|
toolOutputMode: this.settingsManager.getToolOutputMode(),
|
|
3541
|
+
collapseToolCalls: this.settingsManager.getCollapseToolCalls(),
|
|
3482
3542
|
rtk: this.settingsManager.getRtk(),
|
|
3483
3543
|
editorScheme: this.settingsManager.getEditorScheme(),
|
|
3484
3544
|
autoDream: this.settingsManager.getAutoDream(),
|
|
3485
3545
|
autoMemory: this.settingsManager.getAutoMemory(),
|
|
3546
|
+
notificationSound: this.notificationSoundEnabled,
|
|
3486
3547
|
telegramLiveRelayAutoConnect: this.settingsManager.getTelegramLiveRelayAutoConnect(),
|
|
3487
3548
|
sandboxEnabled: this.settingsManager.getSandboxSettings().enabled ?? true,
|
|
3488
3549
|
sandboxNetworkMode: this.settingsManager.getSandboxSettings().networkMode
|
|
@@ -3653,10 +3714,20 @@ export class InteractiveMode {
|
|
|
3653
3714
|
this.settingsManager.setCodexRotate(enabled);
|
|
3654
3715
|
this.showStatus(`Codex rotate: ${enabled ? "enabled" : "disabled"} (restart required)`);
|
|
3655
3716
|
},
|
|
3717
|
+
onFastModeChange: (enabled) => {
|
|
3718
|
+
this.settingsManager.setFastMode(enabled);
|
|
3719
|
+
this.showStatus(`Fast mode: ${enabled ? "enabled" : "disabled"}`);
|
|
3720
|
+
},
|
|
3656
3721
|
onCacheTimerChange: (enabled) => {
|
|
3657
3722
|
this.settingsManager.setCacheTimer(enabled);
|
|
3658
3723
|
this.showStatus(`Cache timer: ${enabled ? "enabled" : "disabled"}`);
|
|
3659
3724
|
},
|
|
3725
|
+
onVerboseFooterChange: (enabled) => {
|
|
3726
|
+
this.settingsManager.setVerboseFooter(enabled);
|
|
3727
|
+
this.footer.setVerboseFooterEnabled(enabled);
|
|
3728
|
+
this.ui.requestRender();
|
|
3729
|
+
this.showStatus(`Verbose footer: ${enabled ? "enabled" : "disabled"}`);
|
|
3730
|
+
},
|
|
3660
3731
|
onPinLastPromptChange: (enabled) => {
|
|
3661
3732
|
this.settingsManager.setPinLastPrompt(enabled);
|
|
3662
3733
|
this.pinLastPromptEnabled = enabled;
|
|
@@ -3675,6 +3746,13 @@ export class InteractiveMode {
|
|
|
3675
3746
|
this.settingsManager.setAutoMemory(enabled);
|
|
3676
3747
|
this.showStatus(`Auto memory: ${enabled ? "enabled" : "disabled"}`);
|
|
3677
3748
|
},
|
|
3749
|
+
onNotificationSoundChange: (enabled) => {
|
|
3750
|
+
this.notificationSoundEnabled = enabled;
|
|
3751
|
+
this.settingsManager.setNotificationSound(enabled);
|
|
3752
|
+
this.footer.setNotificationSoundEnabled(enabled);
|
|
3753
|
+
this.ui.requestRender();
|
|
3754
|
+
this.showStatus(`Notification sound: ${enabled ? "enabled" : "disabled"}`);
|
|
3755
|
+
},
|
|
3678
3756
|
onTelegramLiveRelayAutoConnectChange: (enabled) => {
|
|
3679
3757
|
this.settingsManager.setTelegramLiveRelayAutoConnect(enabled);
|
|
3680
3758
|
this.showStatus(`Telegram autoconnect: ${enabled ? "enabled" : "disabled"}`);
|
|
@@ -3789,6 +3867,14 @@ export class InteractiveMode {
|
|
|
3789
3867
|
this.settingsManager.setEditorScheme(scheme);
|
|
3790
3868
|
this.showStatus(`Editor link scheme: ${scheme}`);
|
|
3791
3869
|
},
|
|
3870
|
+
onCollapseToolCallsChange: (enabled) => {
|
|
3871
|
+
this.settingsManager.setCollapseToolCalls(enabled);
|
|
3872
|
+
this.setToolOutputExpansionState(enabled && (this.collapsedToolCallsExpanded || this.toolOutputExpanded), this.toolOutputExpanded);
|
|
3873
|
+
if (!enabled) {
|
|
3874
|
+
this.collapsedToolSummaryLine = undefined;
|
|
3875
|
+
}
|
|
3876
|
+
this.showStatus(`Collapse tool calls: ${enabled ? "enabled" : "disabled"}`);
|
|
3877
|
+
},
|
|
3792
3878
|
onToolOutputModeChange: (mode) => {
|
|
3793
3879
|
this.settingsManager.setToolOutputMode(mode);
|
|
3794
3880
|
for (const child of this.chatContainer.children) {
|
|
@@ -17,6 +17,9 @@ import type {
|
|
|
17
17
|
EditorComponent,
|
|
18
18
|
MarkdownTheme,
|
|
19
19
|
} from "@gsd/pi-tui";
|
|
20
|
+
import {
|
|
21
|
+
streamSimple,
|
|
22
|
+
} from "@gsd/pi-ai";
|
|
20
23
|
import {
|
|
21
24
|
type Component,
|
|
22
25
|
Container,
|
|
@@ -32,17 +35,19 @@ import type { AgentSession } from "../../core/agent-session.js";
|
|
|
32
35
|
import type { AppAction, KeybindingsManager } from "../../core/keybindings.js";
|
|
33
36
|
import type { SessionManager } from "../../core/session-manager.js";
|
|
34
37
|
import type { SettingsManager } from "../../core/settings-manager.js";
|
|
38
|
+
import { convertToLlm } from "../../core/messages.js";
|
|
35
39
|
import { copyToClipboard } from "../../utils/clipboard.js";
|
|
36
40
|
import { getChangelogPath, parseChangelog } from "../../utils/changelog.js";
|
|
37
41
|
import { ArminComponent } from "./components/armin.js";
|
|
38
42
|
import { BorderedLoader } from "./components/bordered-loader.js";
|
|
43
|
+
import { BtwOverlayComponent } from "./components/btw-overlay.js";
|
|
39
44
|
import { DynamicBorder } from "./components/dynamic-border.js";
|
|
40
45
|
import { BUILTIN_SLASH_COMMANDS } from "../../core/slash-commands.js";
|
|
41
46
|
import { appKey, editorKey, formatKeyForDisplay } from "./components/keybinding-hints.js";
|
|
42
47
|
import { SelectSubmenu, THINKING_DESCRIPTIONS } from "./components/settings-selector.js";
|
|
43
48
|
import { theme } from "./theme/theme.js";
|
|
44
49
|
|
|
45
|
-
import type { TUI } from "@gsd/pi-tui";
|
|
50
|
+
import type { OverlayHandle, TUI } from "@gsd/pi-tui";
|
|
46
51
|
|
|
47
52
|
// ---------------------------------------------------------------------------
|
|
48
53
|
// Context interface — the subset of InteractiveMode needed by slash commands
|
|
@@ -173,6 +178,15 @@ export async function dispatchSlashCommand(
|
|
|
173
178
|
showHotkeys(ctx);
|
|
174
179
|
return true;
|
|
175
180
|
}
|
|
181
|
+
if (text === "/btw" || text.startsWith("/btw ")) {
|
|
182
|
+
const question = text.startsWith("/btw ") ? text.slice(5).trim() : "";
|
|
183
|
+
if (!question) {
|
|
184
|
+
ctx.showWarning("Usage: /btw <question>");
|
|
185
|
+
return true;
|
|
186
|
+
}
|
|
187
|
+
await handleBtwCommand(question, ctx);
|
|
188
|
+
return true;
|
|
189
|
+
}
|
|
176
190
|
if (text === "/fork") {
|
|
177
191
|
ctx.showUserMessageSelector();
|
|
178
192
|
return true;
|
|
@@ -704,6 +718,7 @@ export function showHotkeys(ctx: SlashCommandContext): void {
|
|
|
704
718
|
const externalEditor = getAppKeyDisplay(ctx.keybindings, "externalEditor");
|
|
705
719
|
const followUp = getAppKeyDisplay(ctx.keybindings, "followUp");
|
|
706
720
|
const dequeue = getAppKeyDisplay(ctx.keybindings, "dequeue");
|
|
721
|
+
const toggleNotificationSound = getAppKeyDisplay(ctx.keybindings, "toggleNotificationSound");
|
|
707
722
|
|
|
708
723
|
let hotkeys = `
|
|
709
724
|
**Navigation**
|
|
@@ -746,6 +761,7 @@ export function showHotkeys(ctx: SlashCommandContext): void {
|
|
|
746
761
|
| \`${externalEditor}\` | Edit message in external editor |
|
|
747
762
|
| \`${followUp}\` | Queue follow-up message |
|
|
748
763
|
| \`${dequeue}\` | Restore queued messages |
|
|
764
|
+
| \`${toggleNotificationSound}\` | Toggle notification sound |
|
|
749
765
|
| \`Ctrl+V\` | Paste image from clipboard |
|
|
750
766
|
| \`/\` | Slash commands |
|
|
751
767
|
| \`!\` | Run bash command |
|
|
@@ -779,6 +795,49 @@ export function showHotkeys(ctx: SlashCommandContext): void {
|
|
|
779
795
|
ctx.requestRender();
|
|
780
796
|
}
|
|
781
797
|
|
|
798
|
+
async function handleBtwCommand(question: string, ctx: SlashCommandContext): Promise<void> {
|
|
799
|
+
const model = ctx.session.model;
|
|
800
|
+
if (!model) {
|
|
801
|
+
ctx.showWarning("No model selected. Cannot use /btw.");
|
|
802
|
+
return;
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
if (!ctx.session.modelRegistry.isProviderRequestReady(model.provider)) {
|
|
806
|
+
ctx.showWarning(`No API key available for provider: ${model.provider}`);
|
|
807
|
+
return;
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
const systemPrompt = ctx.session.systemPrompt;
|
|
811
|
+
const messages = convertToLlm(ctx.session.messages);
|
|
812
|
+
const sessionId = ctx.session.sessionId;
|
|
813
|
+
const apiKey = await ctx.session.modelRegistry.getApiKey(model, sessionId);
|
|
814
|
+
let handle: OverlayHandle | undefined;
|
|
815
|
+
|
|
816
|
+
const overlay = new BtwOverlayComponent(
|
|
817
|
+
question,
|
|
818
|
+
model,
|
|
819
|
+
systemPrompt,
|
|
820
|
+
messages,
|
|
821
|
+
ctx.getMarkdownThemeWithSettings(),
|
|
822
|
+
ctx.ui,
|
|
823
|
+
() => {
|
|
824
|
+
handle?.hide();
|
|
825
|
+
},
|
|
826
|
+
() => {
|
|
827
|
+
ctx.requestRender();
|
|
828
|
+
},
|
|
829
|
+
streamSimple,
|
|
830
|
+
{ apiKey, sessionId },
|
|
831
|
+
);
|
|
832
|
+
|
|
833
|
+
handle = ctx.ui.showOverlay(overlay, {
|
|
834
|
+
width: "80%",
|
|
835
|
+
maxHeight: "70%",
|
|
836
|
+
anchor: "center",
|
|
837
|
+
margin: { top: 2, bottom: 2, left: 4, right: 4 },
|
|
838
|
+
});
|
|
839
|
+
}
|
|
840
|
+
|
|
782
841
|
async function handleCompactCommand(customInstructions: string | undefined, ctx: SlashCommandContext): Promise<void> {
|
|
783
842
|
const entries = ctx.sessionManager.getEntries();
|
|
784
843
|
const messageCount = entries.filter((e) => e.type === "message").length;
|
|
@@ -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",
|
|
@@ -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 +
|