MoonshotAI / MoonshotAI/kimi-code
feat(tui): mirror working state into terminal title (OSC 0) for terminals that can't render OSC 9;4
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
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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