MoonshotAI / MoonshotAI/kimi-code
kimi rc silently exits 0 when login lives in scoped oauth/kimi-code-env-* slot
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 7.5k
- Forks
- 1.2k
- Avg merge
- 11h 53m
- Merged PRs (30d)
- 350
Description
你运行的 Kimi Code 版本是?
0.39.0
你使用的是哪个开放平台/订阅?
Kimi Code(kimi login)。本机 config.toml 里 managed provider 的 oauth.key 为 scoped 槽 oauth/kimi-code-env-<hash>(非默认 oauth/kimi-code),oauth_host 为 https://auth.kimi.ai。
你使用的是哪个模型?
无关(启动阶段、连中继之前就退出)
你的电脑平台是?
Darwin 25.5.0 arm64 arm
你遇到了什么问题?
kimi web 正常;同一登录态下 kimi rc / kimi web --remote-control 在打出 server ready 后约 1 秒以 exit 0 退出,stderr 为空,没有 QR、没有 Remote Control URL,终端像被中断。
$ export KIMI_CODE_EXPERIMENTAL_REMOTE_CONTROL=1
$ kimi rc --log-level debug
{"level":30,...,"msg":"Server listening at http://127.0.0.1:58627"}
{"level":30,...,"msg":"provider-model catalog auto-refresh enabled"}
{"level":30,...,"msg":"serving the REST/WS API and the bundled web UI"}
{"level":30,...,"msg":"server ready"}
$ echo $?
0
同一版本在另一台机器上(默认 oauth/kimi-code 槽)可以成功连上中继。
复现步骤?
-
使用会写入 scoped OAuth 槽的登录方式(
oauth.key = "oauth/kimi-code-env-<hash>")。凭证文件实际为:~/.kimi-code/credentials/kimi-code-env-<hash>.json目录里 没有
~/.kimi-code/credentials/kimi-code.json。 -
确认
kimi/kimi web可用(它们走完整 OAuth toolkit,会读 config 里的oauth.key)。 -
export KIMI_CODE_EXPERIMENTAL_REMOTE_CONTROL=1 && kimi rc --log-level debug -
进程在
server ready后立刻回到 shell,exit 0,无错误信息。
期望的行为是什么?
- Remote Control 应读取 当前 managed provider 在 config 中的
oauth.key(与kimi login/ TUI 同一槽),而不是写死默认oauth/kimi-code。 - 找不到 refresh token 时应把错误打到 stderr,并以非 0 退出,例如:
Remote Control requires a Kimi login. Run \kimi login` first.`
补充信息
根因 1 — 读错凭证槽
startRemoteControl 只传了 providerName,没有 oauthKey:
https://github.com/MoonshotAI/kimi-code/blob/main/apps/kimi-code/src/cli/sub/web/remote-control.ts
const token = await storage.load(
resolveKimiTokenStorageName({ providerName: KIMI_CODE_PROVIDER_NAME }),
);
if (token?.refreshToken === undefined || token.refreshToken.length === 0) {
throw new Error('Remote Control requires a Kimi login. Run `kimi login` first.');
}
resolveKimiTokenStorageName 在 oauthKey 缺失时回退到 KIMI_CODE_OAUTH_KEY(oauth/kimi-code)→ 文件名 kimi-code.json:
https://github.com/MoonshotAI/kimi-code/blob/main/packages/oauth/src/toolkit.ts
export function resolveKimiTokenStorageName(input: {
readonly providerName?: string | undefined;
readonly oauthKey?: string | undefined;
}): string {
const key = input.oauthKey ?? KIMI_CODE_OAUTH_KEY;
// oauth/kimi-code → kimi-code.json
// oauth/kimi-code-env-* → kimi-code-env-*.json
同一仓库里 OAuth toolkit 的 login / ensureFresh / tokenProvider 都会用 oauthRef.key ?? defaultOAuthKey(baseUrl, oauthHost)。kimi rc 没有走这条路径。
根因 2 — 启动失败被吞成 exit 0
runServerInProcess 在 onReady 抛错时会先 running.close(),再 throw error:
https://github.com/MoonshotAI/kimi-code/blob/main/apps/kimi-code/src/cli/sub/web/run.ts
} catch (error) {
try {
await hooks.onShutdown?.('startup_failed');
} finally {
await running.close();
await shutdownTelemetry({ timeoutMs: CLI_SHUTDOWN_TIMEOUT_MS });
}
throw error;
}
close() 关掉 listen socket 后,如果后续 throw / process.stderr.write + process.exit(1) 还没跑完,事件循环已空,Node 以 0 退出。--trace-exit 看不到 process.exit()。用户因此看不到 “requires a Kimi login”。
对比:handleWebCommand 的 catch 本来会 stderr.write + process.exit(1),但这条路径经常到不了。
临时 workaround(请勿当作正式修复)
ln -sf kimi-code-env-<hash>.json ~/.kimi-code/credentials/kimi-code.json
做完软链后,同一台机器上 kimi rc 能连上中继并打出 QR。kimi login 若写出新的 kimi-code-env-*.json,软链会失效。
建议修复
startRemoteControl从当前 config 的 managed provideroauth.key(或defaultOAuthKey)解析 storage name,与 toolkit 对齐。onReady失败时先把 error 写到 stderr(或设process.exitCode = 1再 close),避免 close 把失败变成静默成功退出。- 加单测:凭证只在
kimi-code-env-*.json、没有kimi-code.json时,kimi rc仍应读到 refresh token。
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 in apps/kimi-code/src/cli/sub/web/remote-control.ts and packages/oauth/src/toolkit.ts to trace how the managed provider’s oauth.key becomes a credential storage name. Then inspect apps/kimi-code/src/cli/sub/web/run.ts and add a unit test covering only a scoped kimi-code-env-*.json credential file. Done means kimi rc finds that refresh token and startup failures report the error on stderr with a non-zero exit.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- authentication, cli
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100