MoonshotAI / MoonshotAI/kimi-code

[Bug] kimi upgrade exits 0 without upgrading in non-TTY environments — automation cannot detect the no-op

Open
#2,629 0 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

Summary

In non-TTY environments (piped stdin/stdout), kimi upgrade prints the manual-update message and exits with code 0 without performing any update. Automation (CI scripts, desktop apps, wrappers) that only checks the exit code cannot distinguish "upgrade succeeded" from "upgrade was a no-op", and will silently report success while the CLI is still on the old version.

Environment

  • OS: macOS (darwin-arm64)
  • Install method: official script (~/.kimi-code/bin, native install)
  • Version: 0.31.1 -> 0.32.0

Steps to reproduce

kimi upgrade < /dev/null        # stdin/stdout not a TTY

Output:

A newer version of @moonshot-ai/kimi-code is available (0.31.1 -> 0.32.0).
Detected install source: native (windows). Auto-update is not supported on this platform.
To update manually, run: curl -fsSL https://code.kimi.com/kimi-code/install.sh | bash
echo $?   # → 0, but `kimi --version` is still 0.31.1

For comparison, under a PTY (script -q /dev/null kimi upgrade) the CLI works as expected: it shows the interactive update menu (Source: native, Command: curl -fsSL https://code.kimi.com/kimi-code/install.sh | bash) because canAutoInstall("native", "darwin") returns true.

Root cause

apps/kimi-code/src/cli/sub/upgrade.ts: the manual branch is taken when !canAutoInstall(...) || !isInteractive, where isInteractive = process.stdin.isTTY && process.stdout.isTTY. For piped/automation calls isInteractive is false, so the CLI always falls into the manual-message branch and returns 0.

Note this is different from (and not covered by) #2391: install-source detection is not broken on macOS — the misleading native (windows) text is just a hardcoded template in renderManualUpdateMessage. The real blocker for automation is the TTY gate combined with exit code 0.

Expected behavior

For automation, one of the following would work:

  1. A non-interactive flag (e.g. kimi upgrade --yes) that runs the install without prompting, or
  2. A non-zero exit code (or machine-readable output) when the command did not actually update, so callers can detect the no-op.

Impact

Any tool that invokes kimi upgrade programmatically (CI pipelines, desktop apps like myTauri app, package managers) will falsely report "upgrade completed" while the CLI remains outdated — with no error surfaced to the user.

Related: #2391 (misleading platform text in the manual message), #2409 (text-only fix; does not address the non-TTY exit-code behavior).

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 in apps/kimi-code/src/cli/sub/upgrade.ts by reading the manual branch, canAutoInstall, and the isInteractive check. Reproduce kimi upgrade with stdin redirected from /dev/null, then define the non-interactive behavior so callers can distinguish an actual update from a no-op. Done means automation no longer silently reports success when the version remains unchanged.

Written by the indexing model from the issue text.

Assessment

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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.