feat: switched to native text sanitization, removed Bun.stripANSI

- Added `sanitizeText` function to pi-natives that strips ANSI escape sequences, removes control characters and lone surrogates, and normalizes line endings.
- Moved `sanitizeText` function from `@oh-my-pi/pi-utils` to `@oh-my-pi/pi-natives` for better code organization and native performance.
- Added line length clamping (4000 characters) to bash and Python execution output to prevent excessively long lines.
- Replaced internal `#normalizeOutput` methods with `sanitizeText` utility function in bash and Python execution components.
- Fixed bash interactive tool to gracefully handle malformed output chunks by normalizing them with `sanitizeText`.
- Simplified documentation by removing WASM terminology from package descriptions and comments.
This commit is contained in:
can1357
2026-02-14 03:25:13 +01:00
parent 2aa156060b
commit 2e33e436b4
19 changed files with 290 additions and 135 deletions
@@ -1,5 +1,5 @@
import type { AgentToolContext } from "@oh-my-pi/pi-agent-core";
import { type PtyRunResult, PtySession } from "@oh-my-pi/pi-natives";
import { type PtyRunResult, PtySession, sanitizeText } from "@oh-my-pi/pi-natives";
import {
type Component,
matchesKey,
@@ -23,9 +23,8 @@ export interface BashInteractiveResult extends OutputSummary {
}
function normalizeCaptureChunk(chunk: string): string {
const noAnsi = Bun.stripANSI(chunk);
const normalized = noAnsi.replace(/\r\n/gu, "\n").replace(/\r/gu, "\n");
return normalized.replace(/[\x00-\x08\x0B-\x1F\x7F]/gu, "");
const normalized = chunk.replace(/\r\n/gu, "\n").replace(/\r/gu, "\n");
return sanitizeText(normalized);
}
const XtermTerminal = xterm.Terminal;
@@ -168,7 +167,7 @@ class BashInteractiveOverlayComponent implements Component {
const visibleLines: string[] = [];
for (let i = 0; i < maxContentRows; i++) {
const line = buffer.getLine(viewportY + i)?.translateToString(true) ?? "";
visibleLines.push(truncateToWidth(replaceTabs(line), innerWidth));
visibleLines.push(truncateToWidth(replaceTabs(sanitizeText(line)), innerWidth));
}
return visibleLines;
}
@@ -350,7 +349,12 @@ export async function runInteractiveBashPty(
},
(err, chunk) => {
if (err || !chunk) return;
component.appendOutput(chunk);
try {
component.appendOutput(chunk);
} catch {
const normalizedChunk = normalizeCaptureChunk(chunk);
component.appendOutput(normalizedChunk);
}
const normalizedChunk = normalizeCaptureChunk(chunk);
pendingChunks = pendingChunks.then(() => sink.push(normalizedChunk)).catch(() => {});
tui.requestRender();