Skip to content

feat(tui): mirror working state into terminal title (OSC 0) for terminals that can't render OSC 9;4 #1885

Description

@ColorC

What version of Kimi Code is running?

kimi --version: 0.27.0

What platform is your computer?

Windows 11 x64, VSCode 1.129.0, terminal kept in the editor area (a common layout).

What issue are you seeing?

There is no way to tell at a glance whether Kimi Code is working when the terminal lives somewhere that can't render OSC 9;4 progress. Concrete case: VSCode editor-area terminal tabs never render OSC 9;4 (only panel-area tabs do — microsoft/vscode#240117; related: #1884 for the allow-list gap). Inside the TUI the spinner is visible, but the moment you switch to another tab you lose all "is it still working?" signal.

Proposed solution

Mirror the working state into the terminal title (OSC 0) while a turn is running, e.g. <session-label> ⠋ with the braille frame animated on a timer, restored to <session-label> when the turn ends. Terminal titles are plain text and render everywhere — panel tabs, editor-area tabs, tmux, web terminals (xterm.js onTitleChange), Windows Terminal.

Prior art: Claude Code writes its working state into the terminal title the same way; this is how its users get working-state in tabs.

Ideally behind a config flag (e.g. tui.toml), default on or off per maintainer taste.

Reference implementation (local patch, works today)

I patched the installed dist/main.mjs as a stopgap. In the TUI terminal class:

setTitle(title) {
  title = title && title.length > 10 ? title.slice(0, 10) + "…" : title;
  this._tabStatusTitle = title;
  process.stdout.write(`\x1b]0;${title}\x07`);
}

setProgress(active) {
  if (this._tabStatusTimer) { clearInterval(this._tabStatusTimer); this._tabStatusTimer = undefined; }
  const base = this._tabStatusTitle || "kimi";
  if (active) {
    const frames = "⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏".split("");
    let i = 0;
    this._tabStatusTimer = setInterval(() => {
      i = (i + 1) % frames.length;
      process.stdout.write(`\x1b]0;${base} ${frames[i]}\x07`);
    }, 200);
    this._tabStatusTimer.unref?.();
  } else {
    process.stdout.write(`\x1b]0;${base}\x07`);
  }
  // ...original progress-sequence logic unchanged
}

Effect in VSCode editor-area tabs: idle node · 修复登录bu…, working node · 修复登录bu… ⠙ (spinning). The tab row finally shows which Kimi session is busy.

Happy to hear about a different surface for this (config option name, animation cadence, whether to reuse the existing 1s progress keepalive instead of a separate timer). This is a daily pain point for me — I'd love to see it land in an upcoming release so the local patch can be retired.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions