diff --git a/packages/coding-agent/src/commit/agentic/agent.ts b/packages/coding-agent/src/commit/agentic/agent.ts index 8ae14e79c..baad0cbe0 100644 --- a/packages/coding-agent/src/commit/agentic/agent.ts +++ b/packages/coding-agent/src/commit/agentic/agent.ts @@ -79,12 +79,14 @@ export async function runCommitAgentSession(input: CommitAgentInput): Promise }>(); const writeThinkingLine = (text: string) => { + if (!process.stdout.isTTY) return; const line = chalk.dim(`… ${text}`); process.stdout.write(`\r\x1b[2K${line}`); thinkingLineActive = true; }; const clearThinkingLine = () => { if (!thinkingLineActive) return; + if (!process.stdout.isTTY) return; process.stdout.write("\r\x1b[2K"); thinkingLineActive = false; }; diff --git a/packages/coding-agent/src/config/model-resolver.ts b/packages/coding-agent/src/config/model-resolver.ts index 0fd27c431..31602a645 100644 --- a/packages/coding-agent/src/config/model-resolver.ts +++ b/packages/coding-agent/src/config/model-resolver.ts @@ -13,7 +13,7 @@ import { modelsAreEqual, } from "@oh-my-pi/pi-ai"; import { fuzzyMatch } from "@oh-my-pi/pi-tui"; -import chalk from "chalk"; +import { logger } from "@oh-my-pi/pi-utils"; import MODEL_PRIO from "../priority.json" with { type: "json" }; import { parseThinkingLevel, resolveThinkingLevelForModel } from "../thinking"; import { isAuthenticated, kNoAuth, MODEL_ROLE_IDS, type ModelRegistry, type ModelRole } from "./model-registry"; diff --git a/packages/coding-agent/src/utils/title-generator.ts b/packages/coding-agent/src/utils/title-generator.ts index c87ad7a61..d0fe8a729 100644 --- a/packages/coding-agent/src/utils/title-generator.ts +++ b/packages/coding-agent/src/utils/title-generator.ts @@ -166,6 +166,7 @@ export function formatSessionTerminalTitle(sessionName: string | undefined, cwd? * Set the terminal title using OSC 0 (sets both tab and window title). Unsupported terminals ignore it. */ export function setTerminalTitle(title: string): void { + if (!process.stdout.isTTY) return; process.stdout.write(`\x1b]0;${sanitizeTerminalTitlePart(title) ?? DEFAULT_TERMINAL_TITLE}\x07`); } @@ -177,6 +178,7 @@ export function setSessionTerminalTitle(sessionName: string | undefined, cwd?: s * Save the current terminal title on terminals that support xterm window ops. */ export function pushTerminalTitle(): void { + if (!process.stdout.isTTY) return; process.stdout.write("\x1b[22;2t"); } @@ -184,5 +186,6 @@ export function pushTerminalTitle(): void { * Restore the previously saved terminal title on terminals that support xterm window ops. */ export function popTerminalTitle(): void { + if (!process.stdout.isTTY) return; process.stdout.write("\x1b[23;2t"); } diff --git a/packages/tui/src/terminal.ts b/packages/tui/src/terminal.ts index 4bfcf18fc..89ab351ec 100644 --- a/packages/tui/src/terminal.ts +++ b/packages/tui/src/terminal.ts @@ -591,6 +591,9 @@ export class ProcessTerminal implements Terminal { #safeWrite(data: string): void { if (this.#dead) return; + // Skip control sequences when stdout isn't a TTY (piped output, tests, log + // files). They serve no purpose there and would surface as visible noise. + if (!process.stdout.isTTY) return; try { process.stdout.write(data); } catch (err) {