Skip to content

feat(tui): add scriptable statusline command to the footer#2043

Open
yichensunjoe wants to merge 1 commit into
MoonshotAI:mainfrom
yichensunjoe:feat/tui-statusline-command
Open

feat(tui): add scriptable statusline command to the footer#2043
yichensunjoe wants to merge 1 commit into
MoonshotAI:mainfrom
yichensunjoe:feat/tui-statusline-command

Conversation

@yichensunjoe

Copy link
Copy Markdown

Related Issue

Resolve #1954

Problem

See linked issue. Users want a Claude Code-style, scriptable status line in the
TUI footer instead of requesting individual built-in segments one by one.

What changed

  • New optional [statusline] section in tui.toml:
    command (empty = disabled, the default), interval_ms (default 2000,
    min 300), timeout_ms (default 5000).
  • A periodic StatusLineRunner executes the command via the shell, passes a
    session-context JSON on stdin (field names follow Claude Code's statusline
    contract — model.display_name, workspace.current_dir, context tokens,
    permission/plan mode, session id, version — so community scripts port over),
    enforces the timeout (SIGTERM → SIGKILL), caps stdout at 64 KiB, keeps the
    first line, and preserves the last successful output on failure.
  • The footer renders the output as an optional third line, passing ANSI SGR
    sequences through and truncating to width. Nothing renders until the first
    successful run.
  • /reload-tui applies config changes live; the runner lifecycle is tied to
    the footer; saveTuiConfig preserves the new section.
  • Tests: runner (7), footer (5), config (5). Full suite, typecheck, lint green.
    Docs (en/zh) and changeset (minor) included.

Checklist

  • I have read the CONTRIBUTING document.
  • I have linked a related issue, or explained the problem above.
  • I have added tests that prove my feature works.
  • Ran gen-changesets skill, or this PR needs no changeset.
  • Ran gen-docs skill, or this PR needs no doc update.

Add an opt-in [statusline] section to tui.toml (command / interval_ms /
timeout_ms). When configured, the TUI runs the command periodically with
the session context (session id, version, model, working directory,
permission mode, plan mode, context token usage) as JSON on stdin, and
renders the first stdout line — ANSI SGR colors passed through — as a
third footer line. An empty command disables the feature (the default);
failed or timed-out runs silently keep the last successful output, and
nothing is rendered before the first success. /reload-tui picks up
config changes.

Refs MoonshotAI#1954
@changeset-bot

changeset-bot Bot commented Jul 22, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: be0805d

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@moonshot-ai/kimi-code Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: be0805dab7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +52 to +58
stop(): void {
this.generation += 1;
if (this.timer !== null) {
clearInterval(this.timer);
this.timer = null;
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Kill in-flight statusline commands on stop

When the user exits or /reload-tui disables/replaces a slow statusline, stop() only clears the interval and advances the generation; it does not signal the child spawned by the already-running runOnce(). runShell ultimately calls process.exit() after KimiTUI.stop(), so that child (for example sleep 60 or a slow helper) is orphaned and can keep running after the CLI has exited. Keep a handle to the active process/process group and terminate it from stop().

Useful? React with 👍 / 👎.

Comment on lines +143 to +147
const timeout = setTimeout(() => {
proc.kill('SIGTERM');
const killTimer = setTimeout(() => {
proc.kill('SIGKILL');
}, KILL_GRACE_MS);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Kill the whole statusline command tree on timeout

When a configured command times out after spawning a child through the shell (for example sleep 60, a pipeline, or python script.py), these proc.kill() calls target only the /bin/sh -c process created by shell: true; the actual child is left running while the runner settles and schedules the next interval. This can accumulate orphaned helpers every interval_ms for any statusline that repeatedly times out, so start the command in a process group and kill the group, or otherwise track and terminate children, before settling.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature Request] 支持自定义 statusline 配置(类 Claude Code 的 HUD 状态栏机制)

1 participant