fix(cli-detect): detect native Kimi Code (code.kimi.com) build (#98)#99
Merged
Conversation
Two CLIs share the `kimi` binary name: the legacy Python kimi-cli (MoonshotAI/kimi-cli, ~/.kimi, prints "kimi, version 1.46.0") and the native Kimi Code build (code.kimi.com installer → ~/.kimi-code, prints a bare semver "0.6.0", account-authed via `kimi login`). The native installer even renames the Python build to `kimi-legacy`. Both expose the same `kimi --print --output-format stream-json` headless interface, so this is ONE lineage — detection simply never recognised the new build. - cli-detect: accept a bare semver in the kimi --version signature (the basename allowlist still requires the binary be named `kimi`, so this is as safe as the existing gemini/opencode bare-version matchers); also probe ~/.kimi-code/bin in fallbackPaths for non-PATH installs. - kimi shim: extract pure, testable chooseKimiTransport(homeDir, override) and drive `kimi` directly when ~/.kimi-code exists, instead of falling through to opencode-go (which would fail outright without an OpenCode Go sub, or silently ignore the user's kimi install). Tests: bare-semver + legacy signature detection; 8 transport-precedence cases. Verdict: approved by chorus review-only (7 reviewers).
This was referenced May 30, 2026
Merged
chorus-codes
added a commit
that referenced
this pull request
May 30, 2026
…stence (#101) Follow-up to v0.8.61 (#99). chooseKimiTransport decided "drive kimi directly vs route to opencode-go" on `fs.existsSync(~/.kimi-code)`, but dispatch resolves the binary by name and detection resolves a concrete path — these disagree when BOTH kimi builds are installed. If a ~/.kimi-code dir existed but PATH resolved `kimi` to an unconfigured legacy Python build, v0.8.61 drove it directly → "LLM not set", instead of falling back to opencode-go. - New `isNativeKimiBinary(homeDir, binPath)` realpaths BOTH the binary and the ~/.kimi-code dir before a lexical containment check, so a symlinked binary (/usr/local/bin/kimi → ~/.kimi-code/bin/kimi) OR a symlinked ~/.kimi-code dir both compare in the same namespace. Returns undefined when the path is unknown so the caller falls back to dir existence. - chooseKimiTransport now takes a tri-state `isNativeBuild?: boolean`, staying fs-light/unit-testable. `false` (resolved, non-native) skips the dir shortcut and falls to the config probe — the dual-install fix. - isPathUnder: `..` guard now matches a real parent ref only, not a child segment that merely starts with dots (e.g. `..helpers/bin`). Tests: +15 (isPathUnder lexical, isNativeKimiBinary incl. symlinked-binary and symlinked-dir cases, tri-state precedence). Two chorus self-review rounds: round 1 request_changes (realpath asymmetry) → fixed → round 2 approved by all 7 reviewers. Note: a fallback-detected kimi whose dir isn't on the spawn PATH still ENOENTs (runHeadless spawns bare `kimi`) — pre-existing, tracked separately. Co-authored-by: chorus-codes <280607145+chorus-codes@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #98.
The two-kimi problem
@theeasypet reported that Kimi Code (the native CLI from
code.kimi.com, installed to~/.kimi-code/bin/kimi) isn't detected. Investigation showed the two "kimi" CLIs are old and new builds of the same product, not rivals:kimi-cli(legacy)MoonshotAI/kimi-cli(pip/uv/npm)code.kimi.cominstaller~/.kimi/bin~/.kimi-code/bin--versionkimi, version 1.46.00.6.0~/.kimi/config.tomlmodelkimi login(account)kimi --print --output-format stream-jsonThe native installer renames any prior Python build to
kimi-legacy— Moonshot is migrating users to the native binary. Since both share the same headless contract chorus already drives, this stays one lineage; detection just never recognised the new build.Why the one-line regex relax (from the issue) isn't enough
Relaxing the signature alone makes a Kimi-Code-only user "detected but broken": with no
~/.kimi/config.toml,detectKimiTransport()falls through to the opencode-go path, so reviews either fail (no OpenCode Go sub) or silently ignore the kimi binary they installed. This PR fixes detection and transport.Changes
cli-detect.ts) — accept a bare semver in the kimi--versionsignature. The basename allowlist still gates on the binary being namedkimi, so it's as safe as the existing gemini/opencode bare-version matchers.cli-detect.ts) — probe~/.kimi-code/binalongside~/.kimi/bin.kimi.ts) — extract a pure, testablechooseKimiTransport(homeDir, override); when~/.kimi-codeexists, drivekimidirectly instead of routing to opencode-go. Precedence: env override →~/.kimi-code→ configured~/.kimi/config.toml→ opencode-go.Tests
cli-detect-utils.test.ts: acceptskimi, version 1.46.0(legacy) and bare0.6.0(native); still rejects junk--version.kimi-transport.test.ts(new): 8 cases over the full transport precedence, including the key "~/.kimi-codebeats an empty~/.kimi/config.toml" case and both env overrides.~/.kimi-code→ direct transport.review-only(7 independent reviewers) → approved.Known follow-up (needs reporter verification)
chorus passes
-m <model>to the kimi binary. The legacy Python build accepts it; I couldn't verify the native v0.6.0 binary accepts-mlocally (not installed on the dev box). 4 reviewers flagged this as a non-blocking watch item. @theeasypet — could you confirm a kimi review actually runs end-to-end after this lands? If-mis rejected by the native build, the follow-up is a one-liner (omit-mfor the native transport and let the account default apply).