diff --git a/packages/coding-agent/CHANGELOG.md b/packages/coding-agent/CHANGELOG.md index d10a3806..8b6787f3 100644 --- a/packages/coding-agent/CHANGELOG.md +++ b/packages/coding-agent/CHANGELOG.md @@ -49,7 +49,6 @@ - Fixed the `plan-mode` example extension to allow `eza` in the read-only bash allowlist instead of the deprecated `exa` command ([#3240](https://github.com/badlogic/pi-mono/pull/3240) by [@rwachtler](https://github.com/rwachtler)) - Fixed `google-vertex` API key resolution to treat `gcp-vertex-credentials` as an Application Default Credentials marker instead of a literal API key, so marker-based setups correctly fall back to ADC ([#3221](https://github.com/badlogic/pi-mono/pull/3221) by [@deepkilo](https://github.com/deepkilo)) - Fixed RPC `prompt` to wait for prompt preflight success before emitting its single authoritative response, while still treating handled and queued prompts as success ([#3049](https://github.com/badlogic/pi-mono/issues/3049)) -- Fixed Alt keybindings inside Zellij by skipping the Kitty keyboard protocol query there and enabling xterm `modifyOtherKeys` mode 2 directly ([#3163](https://github.com/badlogic/pi-mono/issues/3163)) - Fixed `/scoped-models` reordering to propagate into the `/model` scoped tab, preserving the user-defined scoped model order instead of re-sorting it ([#3217](https://github.com/badlogic/pi-mono/issues/3217)) - Fixed `session_shutdown` to fire on `SIGHUP` and `SIGTERM` in interactive, print, and RPC modes so extensions can run shutdown cleanup on those signal-driven exits ([#3212](https://github.com/badlogic/pi-mono/issues/3212)) - Fixed screenshot path parsing to handle lower case am/pm in macOS screenshot filenames ([#3194](https://github.com/badlogic/pi-mono/pull/3194) by [@jay-aye-see-kay](https://github.com/jay-aye-see-kay)) diff --git a/packages/coding-agent/docs/terminal-setup.md b/packages/coding-agent/docs/terminal-setup.md index fd80e231..74b0df2a 100644 --- a/packages/coding-agent/docs/terminal-setup.md +++ b/packages/coding-agent/docs/terminal-setup.md @@ -32,12 +32,6 @@ If you want `Shift+Enter` to keep working in tmux via that remap, add `ctrl+j` t } ``` -## Zellij - -Pi detects Zellij automatically and skips the Kitty keyboard protocol query there. -Zellij currently forwards that query to the outer terminal but still sends Alt as legacy ESC-prefixed sequences, which can break Alt keybindings if applications enable Kitty mode. -Pi uses xterm `modifyOtherKeys` mode 2 inside Zellij instead, so no extra Zellij config is required. - ## WezTerm Create `~/.wezterm.lua`: diff --git a/packages/tui/CHANGELOG.md b/packages/tui/CHANGELOG.md index 12185e97..9f3e7221 100644 --- a/packages/tui/CHANGELOG.md +++ b/packages/tui/CHANGELOG.md @@ -8,12 +8,6 @@ - Fixed markdown strikethrough parsing to require strict double-tilde delimiters (`~~text~~`) with non-whitespace boundaries, preventing accidental strikethrough from loose tilde usage. -## [0.67.3] - 2026-04-15 - -### Fixed - -- Fixed Alt keybindings inside Zellij by skipping the Kitty keyboard protocol query there and enabling xterm `modifyOtherKeys` mode 2 directly ([#3163](https://github.com/badlogic/pi-mono/issues/3163)) - ## [0.67.2] - 2026-04-14 ### Added diff --git a/packages/tui/src/terminal.ts b/packages/tui/src/terminal.ts index 1ef9b451..d98d1954 100644 --- a/packages/tui/src/terminal.ts +++ b/packages/tui/src/terminal.ts @@ -184,17 +184,6 @@ export class ProcessTerminal implements Terminal { private queryAndEnableKittyProtocol(): void { this.setupStdinBuffer(); process.stdin.on("data", this.stdinDataHandler!); - - // Zellij forwards the Kitty query to the outer terminal, which can make - // Pi enable its Kitty parser even though Zellij still sends Alt as - // legacy ESC-prefixed sequences. Skip the Kitty query there and use - // modifyOtherKeys directly instead. - if (process.env.ZELLIJ) { - process.stdout.write("\x1b[>4;2m"); - this._modifyOtherKeysActive = true; - return; - } - process.stdout.write("\x1b[?u"); setTimeout(() => { if (!this._kittyProtocolActive && !this._modifyOtherKeysActive) { diff --git a/packages/tui/test/terminal.test.ts b/packages/tui/test/terminal.test.ts deleted file mode 100644 index 77ecaf83..00000000 --- a/packages/tui/test/terminal.test.ts +++ /dev/null @@ -1,76 +0,0 @@ -import assert from "node:assert"; -import { describe, it } from "node:test"; -import { ProcessTerminal } from "../src/terminal.js"; - -function withEnv(name: string, value: string | undefined, fn: () => void): void { - const previous = process.env[name]; - if (value === undefined) delete process.env[name]; - else process.env[name] = value; - try { - fn(); - } finally { - if (previous === undefined) delete process.env[name]; - else process.env[name] = previous; - } -} - -describe("ProcessTerminal", () => { - it("should skip the Kitty query inside Zellij and enable modifyOtherKeys immediately", () => { - const terminal = new ProcessTerminal(); - const writes: string[] = []; - const stdinOnCalls: Array<{ event: string | symbol; listener: (...args: unknown[]) => void }> = []; - const stdinRemoveCalls: Array<{ event: string | symbol; listener: (...args: unknown[]) => void }> = []; - const stdoutRemoveCalls: Array<{ event: string | symbol; listener: (...args: unknown[]) => void }> = []; - - const originalStdoutWrite = process.stdout.write; - const originalStdinOn = process.stdin.on; - const originalStdinRemoveListener = process.stdin.removeListener; - const originalStdinPause = process.stdin.pause; - const originalStdoutRemoveListener = process.stdout.removeListener; - - process.stdout.write = ((chunk: string | Uint8Array) => { - writes.push(typeof chunk === "string" ? chunk : Buffer.from(chunk).toString("utf8")); - return true; - }) as typeof process.stdout.write; - process.stdin.on = ((event: string | symbol, listener: (...args: unknown[]) => void) => { - stdinOnCalls.push({ event, listener }); - return process.stdin; - }) as typeof process.stdin.on; - process.stdin.removeListener = ((event: string | symbol, listener: (...args: unknown[]) => void) => { - stdinRemoveCalls.push({ event, listener }); - return process.stdin; - }) as typeof process.stdin.removeListener; - process.stdin.pause = (() => process.stdin) as typeof process.stdin.pause; - process.stdout.removeListener = ((event: string | symbol, listener: (...args: unknown[]) => void) => { - stdoutRemoveCalls.push({ event, listener }); - return process.stdout; - }) as typeof process.stdout.removeListener; - - try { - withEnv("ZELLIJ", "1", () => { - ( - terminal as unknown as { - queryAndEnableKittyProtocol(): void; - } - ).queryAndEnableKittyProtocol(); - }); - - assert.deepStrictEqual(writes, ["\x1b[>4;2m"]); - assert.strictEqual(stdinOnCalls.length, 1); - assert.strictEqual(stdinOnCalls[0]?.event, "data"); - - terminal.stop(); - - assert.deepStrictEqual(writes, ["\x1b[>4;2m", "\x1b[?2004l", "\x1b[>4;0m"]); - assert.strictEqual(stdinRemoveCalls.length, 1); - assert.strictEqual(stdinRemoveCalls[0]?.event, "data"); - assert.strictEqual(stdoutRemoveCalls.length, 0); - } finally { - process.stdout.write = originalStdoutWrite; - process.stdin.on = originalStdinOn; - process.stdin.removeListener = originalStdinRemoveListener; - process.stdin.pause = originalStdinPause; - process.stdout.removeListener = originalStdoutRemoveListener; - } - }); -});