Commit bca1374a9dad
Changed files (1)
dots
pi
agent
extensions
dots/pi/agent/extensions/terminal-status.ts
@@ -37,11 +37,16 @@ let currentBranch = "";
// Terminal Title
// =============================================================================
+/** Whether we're running in interactive TUI mode (not RPC/JSON/print) */
+let isInteractive = !process.argv.includes("--mode");
+
/**
* Set terminal tab/window title using ANSI escape codes
* OSC 0 = icon + title, OSC 2 = window title, OSC 30 = tab title
+ * Skipped in non-interactive modes (RPC, JSON) to avoid corrupting output
*/
function setTerminalTitle(title: string): void {
+ if (!isInteractive) return;
process.stderr.write(`\x1b]0;${title}\x07`);
process.stderr.write(`\x1b]2;${title}\x07`);
process.stderr.write(`\x1b]30;${title}\x07`);
@@ -260,6 +265,7 @@ function detectTerminal(): "kitty" | "wsl" | "osc777" | "linux-desktop" {
}
function notify(title: string, body: string): void {
+ if (!isInteractive) return;
const terminal = detectTerminal();
switch (terminal) {
@@ -285,8 +291,10 @@ function notify(title: string, body: string): void {
/**
* Ring terminal bell (works with kitty bell_on_tab, etc.)
+ * Skipped in non-interactive modes to avoid corrupting output
*/
function ringBell(): void {
+ if (!isInteractive) return;
process.stderr.write("\x07");
}
@@ -297,6 +305,9 @@ function ringBell(): void {
export default function (pi: ExtensionAPI) {
// Set initial title on session start
pi.on("session_start", async (_event, ctx) => {
+ // Detect non-interactive modes (RPC, JSON, print) to skip terminal output
+ // process.argv check in init covers most cases; ctx.hasUI is a backup
+ if (ctx.hasUI === false) isInteractive = false;
currentBranch = getGitBranch();
// Get initial model if available
if (ctx.model) {