mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-15 07:04:45 +00:00
fix(tui,coding-agent): add OSC 133 user message markers support closes #1805
This commit is contained in:
parent
689e7b4ac2
commit
4cb1a56b53
5 changed files with 41 additions and 6 deletions
|
|
@ -5,6 +5,7 @@
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- Fixed IME hardware cursor positioning in the custom extension editor (`ctx.ui.editor()` / extension editor dialog) by propagating focus to the internal `Editor`, preventing the terminal cursor from getting stuck at the bottom-right during composition.
|
- Fixed IME hardware cursor positioning in the custom extension editor (`ctx.ui.editor()` / extension editor dialog) by propagating focus to the internal `Editor`, preventing the terminal cursor from getting stuck at the bottom-right during composition.
|
||||||
|
- Added OSC 133 semantic zone markers around rendered user messages to support terminal navigation between prompts in iTerm2, WezTerm, Kitty, Ghostty, and other compatible terminals ([#1805](https://github.com/badlogic/pi-mono/issues/1805))
|
||||||
|
|
||||||
## [0.55.4] - 2026-03-02
|
## [0.55.4] - 2026-03-02
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
import { Container, Markdown, type MarkdownTheme, Spacer } from "@mariozechner/pi-tui";
|
import { Container, Markdown, type MarkdownTheme, Spacer } from "@mariozechner/pi-tui";
|
||||||
import { getMarkdownTheme, theme } from "../theme/theme.js";
|
import { getMarkdownTheme, theme } from "../theme/theme.js";
|
||||||
|
|
||||||
|
const OSC133_ZONE_START = "\x1b]133;A\x07";
|
||||||
|
const OSC133_ZONE_END = "\x1b]133;B\x07";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component that renders a user message
|
* Component that renders a user message
|
||||||
*/
|
*/
|
||||||
|
|
@ -15,4 +18,15 @@ export class UserMessageComponent extends Container {
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override render(width: number): string[] {
|
||||||
|
const lines = super.render(width);
|
||||||
|
if (lines.length === 0) {
|
||||||
|
return lines;
|
||||||
|
}
|
||||||
|
|
||||||
|
lines[0] = OSC133_ZONE_START + lines[0];
|
||||||
|
lines[lines.length - 1] = lines[lines.length - 1] + OSC133_ZONE_END;
|
||||||
|
return lines;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
- Fixed TUI width calculation for regional indicator symbols (e.g. partial flag sequences like `🇨` during streaming) to prevent wrap drift and stale character artifacts in differential rendering.
|
- Fixed TUI width calculation for regional indicator symbols (e.g. partial flag sequences like `🇨` during streaming) to prevent wrap drift and stale character artifacts in differential rendering.
|
||||||
- Fixed Kitty CSI-u handling to ignore unsupported modifiers so modifier-only events do not insert stray printable characters ([#1807](https://github.com/badlogic/pi-mono/issues/1807))
|
- Fixed Kitty CSI-u handling to ignore unsupported modifiers so modifier-only events do not insert stray printable characters ([#1807](https://github.com/badlogic/pi-mono/issues/1807))
|
||||||
- Fixed single-line paste performance by inserting pasted text atomically instead of character-by-character, preventing repeated `@` autocomplete scans during paste ([#1812](https://github.com/badlogic/pi-mono/issues/1812))
|
- Fixed single-line paste performance by inserting pasted text atomically instead of character-by-character, preventing repeated `@` autocomplete scans during paste ([#1812](https://github.com/badlogic/pi-mono/issues/1812))
|
||||||
|
- Fixed `visibleWidth()` to ignore generic OSC escape sequences (including OSC 133 semantic prompt markers), preventing width drift when terminals emit semantic zone markers ([#1805](https://github.com/badlogic/pi-mono/issues/1805))
|
||||||
|
|
||||||
## [0.55.4] - 2026-03-02
|
## [0.55.4] - 2026-03-02
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -115,12 +115,21 @@ export function visibleWidth(str: string): number {
|
||||||
clean = clean.replace(/\t/g, " ");
|
clean = clean.replace(/\t/g, " ");
|
||||||
}
|
}
|
||||||
if (clean.includes("\x1b")) {
|
if (clean.includes("\x1b")) {
|
||||||
// Strip SGR codes (\x1b[...m) and cursor codes (\x1b[...G/K/H/J)
|
// Strip supported ANSI/OSC/APC escape sequences in one pass.
|
||||||
clean = clean.replace(/\x1b\[[0-9;]*[mGKHJ]/g, "");
|
// This covers CSI styling/cursor codes, OSC hyperlinks and prompt markers,
|
||||||
// Strip OSC 8 hyperlinks: \x1b]8;;URL\x07 and \x1b]8;;\x07
|
// and APC sequences like CURSOR_MARKER.
|
||||||
clean = clean.replace(/\x1b\]8;;[^\x07]*\x07/g, "");
|
let stripped = "";
|
||||||
// Strip APC sequences: \x1b_...\x07 or \x1b_...\x1b\\ (used for cursor marker)
|
let i = 0;
|
||||||
clean = clean.replace(/\x1b_[^\x07\x1b]*(?:\x07|\x1b\\)/g, "");
|
while (i < clean.length) {
|
||||||
|
const ansi = extractAnsiCode(clean, i);
|
||||||
|
if (ansi) {
|
||||||
|
i += ansi.length;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
stripped += clean[i];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
clean = stripped;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate width
|
// Calculate width
|
||||||
|
|
|
||||||
|
|
@ -111,6 +111,16 @@ describe("wrapTextWithAnsi", () => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should ignore OSC 133 semantic markers in visible width", () => {
|
||||||
|
const text = "\x1b]133;A\x07hello\x1b]133;B\x07";
|
||||||
|
assert.strictEqual(visibleWidth(text), 5);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should ignore OSC sequences terminated with ST in visible width", () => {
|
||||||
|
const text = "\x1b]133;A\x1b\\hello\x1b]133;B\x1b\\";
|
||||||
|
assert.strictEqual(visibleWidth(text), 5);
|
||||||
|
});
|
||||||
|
|
||||||
it("should treat isolated regional indicators as width 2", () => {
|
it("should treat isolated regional indicators as width 2", () => {
|
||||||
assert.strictEqual(visibleWidth("🇨"), 2);
|
assert.strictEqual(visibleWidth("🇨"), 2);
|
||||||
assert.strictEqual(visibleWidth("🇨🇳"), 2);
|
assert.strictEqual(visibleWidth("🇨🇳"), 2);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue