Merge kitty-protocol-support into main

This commit is contained in:
Mario Zechner 2025-12-19 01:21:47 +01:00
commit 139af12b37
11 changed files with 281 additions and 28 deletions

View file

@ -1,4 +1,4 @@
import { Editor } from "@mariozechner/pi-tui";
import { Editor, isCtrlC, isCtrlD, isCtrlO, isCtrlP, isCtrlT, isShiftTab } from "@mariozechner/pi-tui";
/**
* Custom editor that handles Escape and Ctrl+C keys for coding-agent
@ -6,6 +6,7 @@ import { Editor } from "@mariozechner/pi-tui";
export class CustomEditor extends Editor {
public onEscape?: () => void;
public onCtrlC?: () => void;
public onCtrlD?: () => void;
public onShiftTab?: () => void;
public onCtrlP?: () => void;
public onCtrlO?: () => void;
@ -13,25 +14,25 @@ export class CustomEditor extends Editor {
handleInput(data: string): void {
// Intercept Ctrl+T for thinking block visibility toggle
if (data === "\x14" && this.onCtrlT) {
if (isCtrlT(data) && this.onCtrlT) {
this.onCtrlT();
return;
}
// Intercept Ctrl+O for tool output expansion
if (data === "\x0f" && this.onCtrlO) {
if (isCtrlO(data) && this.onCtrlO) {
this.onCtrlO();
return;
}
// Intercept Ctrl+P for model cycling
if (data === "\x10" && this.onCtrlP) {
if (isCtrlP(data) && this.onCtrlP) {
this.onCtrlP();
return;
}
// Intercept Shift+Tab for thinking level cycling
if (data === "\x1b[Z" && this.onShiftTab) {
if (isShiftTab(data) && this.onShiftTab) {
this.onShiftTab();
return;
}
@ -44,11 +45,20 @@ export class CustomEditor extends Editor {
}
// Intercept Ctrl+C
if (data === "\x03" && this.onCtrlC) {
if (isCtrlC(data) && this.onCtrlC) {
this.onCtrlC();
return;
}
// Intercept Ctrl+D (only when editor is empty)
if (isCtrlD(data)) {
if (this.getText().length === 0 && this.onCtrlD) {
this.onCtrlD();
}
// Always consume Ctrl+D (don't pass to parent)
return;
}
// Pass to parent for normal handling
super.handleInput(data);
}

View file

@ -1,4 +1,4 @@
import { type Component, Container, Input, Spacer, Text, truncateToWidth } from "@mariozechner/pi-tui";
import { type Component, Container, Input, isCtrlC, Spacer, Text, truncateToWidth } from "@mariozechner/pi-tui";
import type { SessionManager } from "../../../core/session-manager.js";
import { fuzzyFilter } from "../../../utils/fuzzy.js";
import { theme } from "../theme/theme.js";
@ -145,7 +145,7 @@ class SessionList implements Component {
}
}
// Ctrl+C - exit process
else if (keyData === "\x03") {
else if (isCtrlC(keyData)) {
process.exit(0);
}
// Pass everything else to search input

View file

@ -1,4 +1,4 @@
import { type Component, Container, Spacer, Text, truncateToWidth } from "@mariozechner/pi-tui";
import { type Component, Container, isCtrlC, Spacer, Text, truncateToWidth } from "@mariozechner/pi-tui";
import { theme } from "../theme/theme.js";
import { DynamicBorder } from "./dynamic-border.js";
@ -100,7 +100,7 @@ class UserMessageList implements Component {
}
}
// Ctrl+C - cancel
else if (keyData === "\x03") {
else if (isCtrlC(keyData)) {
if (this.onCancel) {
this.onCancel();
}

View file

@ -573,6 +573,7 @@ export class InteractiveMode {
};
this.editor.onCtrlC = () => this.handleCtrlC();
this.editor.onCtrlD = () => this.handleCtrlD();
this.editor.onShiftTab = () => this.cycleThinkingLevel();
this.editor.onCtrlP = () => this.cycleModel();
this.editor.onCtrlO = () => this.toggleToolOutputExpansion();
@ -1144,6 +1145,12 @@ export class InteractiveMode {
}
}
private handleCtrlD(): void {
// Only called when editor is empty (enforced by CustomEditor)
this.stop();
process.exit(0);
}
private updateEditorBorderColor(): void {
if (this.isBashMode) {
this.editor.borderColor = theme.getBashModeBorderColor();