MoonshotAI / MoonshotAI/kimi-code

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

Open
#1,885 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
7.5k
Forks
1.2k
Avg merge
11h 53m
Merged PRs (30d)
350

Description

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.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the TUI terminal class and existing progress-sequence logic described in dist/main.mjs, using the reference implementation as the behavioral guide. Check the result in VSCode editor-area terminals and confirm that the terminal title shows an animated working state and returns to the session label when the turn ends.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
cli
Issue type
Feature
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
65/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.