{"slug": "kimi-everywhere-run-any-coding-harness-claude-code-codex-opencode-cline-aider-on", "title": "Kimi Everywhere — run any coding harness (Claude Code, Codex, OpenCode, Cline, Aider) on one flat-fee Kimi subscription. One key, two protocols, zero token bills.", "summary": "Kimi has launched 'Kimi Everywhere', a kit that lets developers run any coding harness—including Claude Code, Codex, OpenCode, Cline, and Aider—on a single flat-fee Kimi Code subscription ($19+/mo). The kit provides an API key that speaks both Anthropic-compatible and OpenAI-compatible protocols, eliminating per-token billing. A developer can install the kit in 30 seconds and use commands like `kimi-on claude` or `kimi-on codex` to route tools through Kimi's K3 model.", "body_md": "Run any coding harness on one flat-fee Kimi subscription.\n\nYour Kimi Code subscription ($19+/mo) comes with an API key that speaks both major agent protocols:\n\nProtocol\n\nEndpoint\n\nWorks with\n\nAnthropic-compatible\n\nhttps://api.kimi.com/coding/\n\nClaude Code + anything expecting ANTHROPIC_BASE_URL\n\nOpenAI-compatible\n\nhttps://api.kimi.com/coding/v1\n\nCodex CLI, OpenCode, Cline, Roo Code, Aider + anything expecting an OpenAI base URL\n\nSame key, flat monthly fee, no pay-per-token API bills. This kit wires that key into whatever tool you already use.\n\nInstall (30 seconds)\n\n```\ncurl -fsSL https://gist.githubusercontent.com/Maciejdziuba/038c0c822d2c799cffcfdec805975e66/raw/install.sh | bash\nkimi-on setup     # paste your key from kimi.com/code/console\n```\n\nGet your key: subscribe at kimi.com/membership/pricing, then create an API key in the Kimi Code Console. This is not the pay-per-token key from platform.moonshot.ai — the Code Console key is covered by your subscription.\n\nUse\n\n```\nkimi-on claude            # Claude Code on Kimi K3\nkimi-on claude --init     # first run: also skips the Anthropic login screen\nkimi-on claude-app on     # Claude Code DESKTOP APP on Kimi (writes ~/.claude/settings.json)\nkimi-on claude-app off    # remove those settings again\nkimi-on codex             # Codex CLI (auto-adds a 'kimi' profile)\nkimi-on codex-app on      # Codex DESKTOP APP on Kimi (macOS: config + launchctl env)\nkimi-on codex-app off     # undo the launchctl env\nkimi-on opencode          # OpenCode (writes project opencode.json)\nkimi-on aider             # Aider\nkimi-on <anything>        # any other tool, both protocols injected\nkimi-on env openai        # or just print the exports and wire it yourself\nkimi-on oauth start       # NO-KEY mode: local proxy reusing your `kimi login` session\nkimi-on claude --oauth    # Claude Code on pure Kimi OAuth\n```\n\nModel switches:\n\n```\nKIMI_MODEL=kimi-for-coding kimi-on claude    # K2.7 Code\nKIMI_MODEL=\"k3[1m]\" kimi-on claude           # K3 with 1M context (Allegretto+)\n```\n\nThe universal rule\n\nAny harness, even ones this kit has never heard of:\n\nTool speaks Anthropic (Claude Code style env vars) → point it at https://api.kimi.com/coding/\n\nTool speaks OpenAI (custom base URL setting) → point it at https://api.kimi.com/coding/v1\n\nAPI key is the same Kimi Code key in both cases.\n\nkimi-on <command> automates exactly this: it exports both sets of variables and runs your command.\n\nCheat sheet\n\nFull per-tool configs (Cline, Roo Code, Codex config.toml, OpenCode JSON), plan tiers, model IDs, context limits, and the /effort mapping live in CHEATSHEET.md.\n\nWhat's in the box\n\n```\nkimi-on.sh          the universal launcher\nkimi-oauth-proxy.mjs  zero-dependency OAuth proxy (no API key mode)\ninstall.sh          one-line installer\ncodex.toml          Codex CLI provider + profile block\nopencode.json       OpenCode provider config\nCHEATSHEET.md       one-page reference for every harness\nkimi-router-SKILL.md  the Kimi Router Claude skill (split-brain: frontier model plans, K3 codes)\nkimi-k3-harness-setup.md  agent runbook: point your AI agent at it to auto-install K3 on every harness\n```\n\nRelated\n\nPairs with the Kimi Router Claude skill (included here as kimi-router-SKILL.md — save it to ~/.claude/skills/kimi-router/SKILL.md): a frontier model orchestrates and Kimi writes all the code. Router = split-brain inside one session; Everywhere = your whole harness on one subscription.\n\nk3[1m] — Claude Code env vars only: bracket form unlocks the 1M window. Everywhere else use plain k3.\n\nKeep thinking mode ON — disabling it silently routes K3/K2.7 down to K2.6.\n\nClaude Code (Anthropic protocol)\n\n```\nexport ANTHROPIC_BASE_URL=https://api.kimi.com/coding/\nexport ANTHROPIC_API_KEY=<your Kimi Code key>\nexport ANTHROPIC_MODEL=k3                     # or \"k3[1m]\" / kimi-for-coding\nexport ANTHROPIC_DEFAULT_OPUS_MODEL=$ANTHROPIC_MODEL\nexport ANTHROPIC_DEFAULT_SONNET_MODEL=$ANTHROPIC_MODEL\nexport ANTHROPIC_DEFAULT_HAIKU_MODEL=$ANTHROPIC_MODEL\nexport CLAUDE_CODE_SUBAGENT_MODEL=$ANTHROPIC_MODEL\nexport CLAUDE_CODE_EFFORT_LEVEL=high\nexport CLAUDE_CODE_AUTO_COMPACT_WINDOW=262144   # 1048576 with k3[1m]\nexport CLAUDE_CODE_MAX_CONTEXT_TOKENS=262144    # 1048576 with k3[1m]\nclaude\n```\n\nFirst run only: mark onboarding complete so Claude Code doesn't force an Anthropic login (kimi-on claude --init does this for you).\n\nEffort mapping (/effort in-session):\n\nClaude Code level\n\nK3 level\n\nlow\n\nlow\n\nmedium / high\n\nhigh\n\nxhigh / max\n\nmax\n\nCodex CLI (OpenAI protocol)\n\nAppend to ~/.codex/config.toml (or use codex.toml):\n\n```\n[model_providers.kimi]\nname = \"Kimi (subscription)\"\nbase_url = \"https://api.kimi.com/coding/v1\"\nenv_key = \"KIMI_API_KEY\"\nwire_api = \"chat\"\n\n[profiles.kimi]\nmodel_provider = \"kimi\"\nmodel = \"k3\"\n```\n\nThen:\n\n```\nexport KIMI_API_KEY=<your key>\ncodex --profile kimi\n```\n\nwire_api = \"chat\" matters — Kimi's endpoint speaks Chat Completions, not the Responses API.\n\nOpenCode\n\nDrop opencode.json into your project (or kimi-on opencode writes it):\n\n```\n{\n  \"$schema\": \"https://opencode.ai/config.json\",\n  \"provider\": {\n    \"kimi\": {\n      \"npm\": \"@ai-sdk/openai-compatible\",\n      \"name\": \"Kimi (subscription)\",\n      \"options\": {\n        \"baseURL\": \"https://api.kimi.com/coding/v1\",\n        \"apiKey\": \"{env:KIMI_API_KEY}\"\n      },\n      \"models\": {\n        \"k3\": { \"name\": \"Kimi K3\" },\n        \"kimi-for-coding\": { \"name\": \"Kimi K2.7 Code\" }\n      }\n    }\n  },\n  \"model\": \"kimi/k3\"\n}\n```\n\nCline / Roo Code (VS Code)\n\nSettings → API Provider → OpenAI Compatible:\n\nField\n\nValue\n\nBase URL\n\nhttps://api.kimi.com/coding/v1\n\nAPI Key\n\nyour Kimi Code key\n\nModel ID\n\nk3 (or kimi-for-coding)\n\nAider\n\n```\nexport OPENAI_API_BASE=https://api.kimi.com/coding/v1\nexport OPENAI_API_KEY=<your key>\naider --model openai/k3\n```\n\nAnything else\n\nSpeaks Anthropic → https://api.kimi.com/coding/. Speaks OpenAI → https://api.kimi.com/coding/v1. Same key. Or let the launcher inject both: kimi-on <command>.\n\nDesktop apps\n\nGUI apps don't see your shell env vars, so the desktop apps need a persistent route.\n\nClaude Code app — kimi-on claude-app on writes an env object into ~/.claude/settings.json (the same ANTHROPIC_BASE_URL / ANTHROPIC_API_KEY / model / context vars from the Claude Code section above) and sets hasCompletedOnboarding in ~/.claude.json. This affects every Claude Code surface (app, CLI, IDE) until you run kimi-on claude-app off, which deletes exactly those keys and leaves your other settings alone. A one-time backup of your original settings is kept at ~/.kimi-everywhere/claude-settings.backup.json. Restart the app fully after either command.\n\nCodex app — kimi-on codex-app on adds the same [model_providers.kimi] + [profiles.kimi] block to ~/.codex/config.toml as the CLI route, then runs launchctl setenv KIMI_API_KEY <key> so the GUI app can resolve env_key (macOS only; clears at logout — rerun after reboot). Fully quit and reopen the app, then pick the custom \"kimi\" entry in the model picker if offered — the app may only surface it as a \"Custom\" model. kimi-on codex-app off removes the launchctl var; the config block stays (harmless, the CLI uses it).\n\nHeavier app-native routes, if the simple key route isn't enough: codex-router (native model picker + Kimi OAuth, third-party) and opencodex (universal proxy).\n\nOAuth mode (no API key at all)\n\nYour kimi login session (from the Kimi Code CLI) can power everything directly. kimi-on oauth start runs a tiny local proxy at 127.0.0.1:8790 that reuses and auto-refreshes those OAuth tokens:\n\nRoute\n\nSpeaks\n\nFor\n\nhttp://127.0.0.1:8790/v1/chat/completions\n\nOpenAI format\n\nCodex, OpenCode, Cline, Aider\n\nhttp://127.0.0.1:8790/v1/messages\n\nAnthropic format\n\nClaude Code\n\n```\nkimi-on oauth start        # needs: Kimi Code CLI installed + `kimi login` done\nkimi-on claude --oauth     # Claude Code, zero API key\nkimi-on oauth status       # token health\nkimi-on oauth stop\n```\n\nPoint any other tool at the proxy with any dummy API key — the proxy injects the real OAuth bearer and refreshes it automatically. The proxy is loopback-only and never writes tokens anywhere except Kimi's own credential file.\n\nGotchas\n\nWrong key source is the #1 failure: platform.moonshot.ai keys bill per token; Code Console keys ride your subscription. Use the Code Console key.\n\nUsage quotas refresh weekly and vary by tier; heavy parallel agent swarms burn quota fast.\n\nk3[1m] only works on Allegretto and above; on lower tiers use plain k3 with the 256K limits.\n\nThis 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.\nLearn more about bidirectional Unicode characters\n\nThis 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.\nLearn more about bidirectional Unicode characters\n\nAGENT RUNBOOK — Install Kimi K3 on Coding-Agent Harnesses\n\nAudience: you, the AI agent. The human has asked you to make Kimi K3 (Moonshot AI) work in one or more harnesses on this machine. Execute this runbook autonomously. Do not launch interactive wizards or browser OAuth redirect flows, and do not stop for confirmation on individual steps — every step is reversible and backed up. Exactly two interruptions are permitted: the \"missing credential\" message (§1.3, which includes relaying a kimi login device-code URL per §1.0) and the single consent gate before any secret is written to disk (§1.4). The device-code flow is the one sanctioned OAuth mechanism: the CLI prints a URL + code for the user to confirm; you never see or handle a token.\n\nOperating rules for this entire runbook:\n\nNon-interactive only. Never run /login, hermes model, pi setup wizards, or GUI tools (CC Switch). Everything is done by writing config files directly.\n\nIdempotent. Re-running this runbook must not duplicate entries. Check-before-write on every file.\n\nBack up before modify.cp <file> <file>.bak-kimi-$(date +%s) before touching any existing config. Backups of files that contain secrets get chmod 600 immediately. Prune older .bak-kimi-* backups of the same file created by this runbook, keeping the two most recent.\n\nNever expose the key. Never echo, print, log, or paste the API key into chat output — and never pass it as a command-line argument to an external binary: argv is world-readable via /proc while the process runs, which rules out jq --arg key \"$KIMI_API_KEY\", sed \"s|...|$KIMI_API_KEY|\", and bare curl -H \"Authorization: Bearer $KIMI_API_KEY\". Move it with shell builtins (printf, redirection, heredocs) or tools that read the environment (jq's env.KIMI_API_KEY, awk's ENVIRON, curl -H @- with the header on stdin). When you must show the user a config you wrote, redact the key.\n\nOnly configure harnesses that exist. Detect first (§1.2); skip absent ones silently.\n\nVerify each harness non-interactively (§7) and report a final per-harness pass/fail table.\n\nUser policy wins. If the user or their harness has standing secret-handling rules (e.g. \"ask before any command touching API keys\"), those override this runbook's autonomy directives — the §1.4 consent gate is the mechanism that satisfies them.\n\n0. Model facts you need (do not re-derive)\n\nThere are three distinct auth routes. Two billing systems: Routes S and O both ride the flat-rate Kimi Code subscription (different credentials); Route P bills per token. Prefer the subscription when the user has one. Route O is the only route that needs no API key at all — it reuses a kimi login OAuth session — but it currently pays off mainly for Codex (S is simpler for Claude Code, Hermes, and Pi).\n\nRoute S — Kimi Code subscription (\"Kimi For Coding\" / KFC) — PREFERRED\n\nhttps://api.kimi.com/coding/ (Anthropic-compatible; also serves the kimi-coding providers in Hermes/Pi)\n\nModel IDs\n\nk3 (256K), k3[1m] (1M, Claude Code env vars only — everywhere else use k3), kimi-for-coding (K2.7 Code, 256K), kimi-for-coding-highspeed\n\nPlan gating\n\nStarter/legacy-Andante/Moderato tiers: k3 at 256K only. Explorer/Expert/Master (and legacy Allegretto+): k3 at 1M + highspeed\n\nThinking effort\n\nK3 supports low/high/max; Claude Code CLAUDE_CODE_EFFORT_LEVEL=high recommended; disabling thinking silently routes to K2.6\n\nRoute O — Kimi Code OAuth session (subscription login, no API key)\n\nFact\n\nValue\n\nCredential\n\nAn OAuth session created by kimi login (official Kimi Code CLI, kimi-code) — device-code flow: the CLI prints a URL + code, the user confirms in a browser. No key material passes through you.\n\nSession owner\n\nThe Kimi Code CLI stores and refreshes the session itself (~/.kimi-code/). Never read, print, or copy its credential files — bridges reuse the session, they don't extract it.\n\nBridge for Codex\n\nduolahypercho/codex-router — purpose-built router that puts kimi-oauth/k3 in the Codex model picker (App + CLI) next to native GPT models, preserving the ChatGPT login. Ships an agent runbook (AGENTS.md) and a non-interactive installer: ./install.sh --auto --providers kimi-oauth --migrate-known. Listens on 127.0.0.1 ports 4100–4103.\n\nBridge (alternative)\n\nlidge-jun/opencodex (npm @bitkyc08/opencodex, proxy on localhost:10100) — universal provider proxy for Codex and Claude Code with Kimi OAuth support. Its ocx init setup is interactive, so under this runbook use it only if codex-router fails and configure ~/.opencodex/config.json directly per its docs.\n\nPlan gating\n\nSame subscription tiers as Route S (§1.3 tier heuristic applies).\n\nRoute P — Moonshot/Kimi Open Platform (pay-per-token)\n\n(OpenRouter — moonshotai/kimi-k3, ~$3/M in, ~$15/M out — is a last-resort fallback only; do not configure it unless the user explicitly has an OpenRouter key and no Kimi key.)\n\nShared facts (both routes)\n\nFact\n\nValue\n\nK3 context window\n\n1048576 (1M) where the plan allows, else 262144\n\nThinking\n\nAlways on for K3; never send the K2.x thinking param\n\nSampling params\n\ntemperature, top_p, n, presence_penalty, frequency_penalty are fixed — never send them\n\nVision\n\nbase64 or ms://<file-id> only; content must be an array of objects\n\nOpen weights\n\nReleased by 2026-07-27; until confirmed available, self-hosting is out of scope — use the API\n\n1. Preflight\n\n1.0 Detect a Kimi Code OAuth session (Route O; check before hunting keys)\n\nFind the Kimi Code CLI: command -v kimi, else ~/.kimi-code/bin/kimi. Absent → Route O unavailable; continue with §1.1.\n\nIf present, test for a valid session with one cheap non-interactive call: kimi -p 'Reply with exactly: OK' (timeout ~60s). Success → a live OAuth session exists; record Route O available. An auth/login error → CLI installed but not logged in.\n\nInstalled-but-not-logged-in and Codex is a target: kimi login is a device-code flow, not a browser wizard — you may run it, relay the printed URL + code to the user verbatim, and wait for completion. This counts as part of the §1.3 \"missing credential\" interruption, not an extra one. If the user is unreachable or declines, drop Route O and fall back to §1.1.\n\nRoute O only covers harnesses bridged in §3 Rung O. Even when Route O is available, still run §1.1–1.3 if other harnesses (Claude Code, Hermes, Pi) are targets — they need a key route (S/P). If no key exists anywhere but a Route O session does, configure Codex via Rung O and report the other harnesses as needing a key (§1.3 message), rather than stopping everything.\n\n1.1 Locate a Moonshot API key (in order; stop at first hit)\n\nCheck without printing values (test emptiness only, e.g. [ -n \"$VAR\" ]):\n\nNormalize: export the found key as KIMI_API_KEY for the rest of this runbook (source the file or export from the found location — never echo it). It must be exported, not just a shell variable: later steps read it from the environment (jq's env, LiteLLM's os.environ/).\n\n1.2 Detect installed harnesses\n\nHarness\n\nPresent if\n\nClaude Code\n\ncommand -v claude\n\nCodex CLI\n\ncommand -v codex\n\nHermes Agent\n\ncommand -v hermes or ~/.hermes/ exists\n\nPi\n\ncommand -v pi or ~/.pi/ exists\n\nIf the user named specific harnesses, configure exactly those (and report if one isn't installed). Otherwise configure every detected harness.\n\n1.3 Classify and validate the key (the only potentially blocking step)\n\nYou must determine whether the key is a subscription (Route S) or platform (Route P) key. Probe in this order and stop at the first 200; the winning probe determines the route used for every section below.\n\n```\nCHECK=$(mktemp)   # never a fixed /tmp path — mktemp gives an unpredictable name with 0600 perms\n\n# Probe S — subscription (Anthropic-style endpoint); auth header via stdin (-H @-), not argv\nHTTP_S=$(curl -s -o \"$CHECK\" -w '%{http_code}' \\\n  https://api.kimi.com/coding/v1/messages \\\n  -H @- -H \"anthropic-version: 2023-06-01\" -H \"Content-Type: application/json\" \\\n  -d '{\"model\":\"k3\",\"max_tokens\":16,\"messages\":[{\"role\":\"user\",\"content\":\"ping\"}]}' \\\n  <<< \"x-api-key: $KIMI_API_KEY\")\n\n# Probe P — platform (OpenAI-style endpoint), only if Probe S failed\nHTTP_P=$(curl -s -o \"$CHECK\" -w '%{http_code}' \\\n  https://api.moonshot.ai/v1/chat/completions \\\n  -H @- -H \"Content-Type: application/json\" \\\n  -d '{\"model\":\"kimi-k3\",\"messages\":[{\"role\":\"user\",\"content\":\"ping\"}],\"max_completion_tokens\":16}' \\\n  <<< \"Authorization: Bearer $KIMI_API_KEY\")\n```\n\nProbe S returns 200 → Route S (subscription). Then detect the plan tier: attempt Probe S again with model kimi-for-coding-highspeed. A 200 implies an Explorer+/Allegretto+ tier → use the 1M config (k3[1m], window 1048576); a 4xx implies a base tier → use the 256K config (k3, window 262144). Record the tier. This is a heuristic — it assumes highspeed access and 1M K3 remain gated on the same tiers. If k3[1m] is later rejected during verification, downgrade to the 256K config (§8) instead of debugging the endpoint.\n\nProbe S fails, Probe P returns 200 → Route P (platform).\n\nProbe P 401 on .ai → retry against https://api.moonshot.cn/v1/...; a 200 means a China-platform key: Route P with .cn endpoints.\n\nIf multiple keys were found in §1.1, classify each and prefer any Route S key.\n\nNothing validates → check §1.0's result before stopping. A live Route O session + Codex-only target → proceed OAuth-only (§1.0 step 4). Otherwise stop and send the user this single message, then end your turn:\n\nI need a Kimi credential to finish the K3 setup. If you have a Kimi Code subscription, either (a) create a key at https://www.kimi.com/code/console (flat-rate; every paid tier can mint one), or (b) for a Codex-only setup I can use OAuth instead — install the Kimi Code CLI and I'll run kimi login and give you a URL to confirm, no key to paste. Otherwise create a pay-per-token key at https://platform.kimi.ai/console/api-keys. Then run export KIMI_API_KEY=<key> in this shell (or say \"use oauth\"), and say \"continue\" — I'll finish without further questions.\n\nrm -f \"$CHECK\" afterward — probe responses can include account metadata.\n\n1.4 Consent gate — one message before any secret is written\n\nBefore the first write of key material to disk, send the user one message listing:\n\nEvery file that will receive the key, plaintext or env-reference — e.g. ~/.claude/settings.json, ~/.zshrc, ~/.hermes/.env, ~/.config/litellm/.kimi-key, ~/.pi/agent/auth.json.\n\nFor each harness already routed to another provider: whether you will take over the default in place or create an isolated profile (decision rules in §2/§3).\n\nIf §3 Rung O will run: that codex-router will be checked out to ~/.local/share/codex-router, add a marked managed block (openai_base_url + model_catalog_json) to ~/.codex/config.toml, and install a user-level background service on ports 4100–4103. Rung O writes no key material, but it modifies config.toml, so it belongs in this gate.\n\nProceed on confirmation; apply any adjustments the user makes. Skip this gate only when the user's request already granted it explicitly (e.g. \"set up Kimi everywhere, overwrite what you need, don't ask\"). After the gate, do not ask again — the remaining steps run uninterrupted.\n\nThroughout §2–§6: SUB blocks apply on Route S, PLAT blocks on Route P. Route O has no per-harness blocks — it applies only as §3 Rung O (Codex); every other harness uses SUB or PLAT.\n\n2. Claude Code\n\nTarget file: ~/.claude/settings.json. Back it up, then merge (never overwrite the whole file — preserve permissions, theme, hooks, etc.) the route-appropriate env block into .env.\n\nSUB (Route S) — per the official Kimi Code docs. MODEL is k3[1m] on 1M-tier plans, k3 on 256K tiers (from §1.3); WINDOW is 1048576 or 262144 accordingly. Note the subscription uses ANTHROPIC_API_KEY (not AUTH_TOKEN) and effort high (not max):\n\n```\ncp ~/.claude/settings.json ~/.claude/settings.json.bak-kimi-$(date +%s) 2>/dev/null\nchmod 600 ~/.claude/settings.json.bak-kimi-* 2>/dev/null\nMODEL='k3[1m]'; WINDOW='1048576'   # or k3 / 262144 for 256K tiers\nTMP=$(mktemp)\n# key read via jq's env (exported in §1.1) — never via --arg, which exposes it in argv\njq --arg m \"$MODEL\" --arg w \"$WINDOW\" '.env = (.env // {}) + {\n  \"ANTHROPIC_BASE_URL\":\"https://api.kimi.com/coding/\",\n  \"ANTHROPIC_API_KEY\":env.KIMI_API_KEY,\n  \"ANTHROPIC_MODEL\":$m,\n  \"ANTHROPIC_DEFAULT_FABLE_MODEL\":$m,\n  \"ANTHROPIC_DEFAULT_OPUS_MODEL\":$m,\n  \"ANTHROPIC_DEFAULT_SONNET_MODEL\":$m,\n  \"ANTHROPIC_DEFAULT_HAIKU_MODEL\":$m,\n  \"CLAUDE_CODE_SUBAGENT_MODEL\":$m,\n  \"ENABLE_TOOL_SEARCH\":\"false\",\n  \"CLAUDE_CODE_EFFORT_LEVEL\":\"high\",\n  \"CLAUDE_CODE_AUTO_COMPACT_WINDOW\":$w,\n  \"CLAUDE_CODE_MAX_CONTEXT_TOKENS\":$w\n}' ~/.claude/settings.json > \"$TMP\" && mv \"$TMP\" ~/.claude/settings.json && chmod 600 ~/.claude/settings.json\n```\n\nIf Claude Code has never been onboarded on this machine, also set hasCompletedOnboarding: true (and penguinModeOrgEnabled: true) in ~/.claude.json so the user isn't dropped into the Anthropic login flow — merge, don't overwrite. Verify these keys against the installed Claude Code version first (an existing ~/.claude.json on this or another machine, or the docs); skip any key you cannot confirm rather than inventing settings.\n\nPLAT (Route P) — platform pay-per-token:\n\n```\ncp ~/.claude/settings.json ~/.claude/settings.json.bak-kimi-$(date +%s) 2>/dev/null\nchmod 600 ~/.claude/settings.json.bak-kimi-* 2>/dev/null\nTMP=$(mktemp)\njq '.env = (.env // {}) + {\n  \"ANTHROPIC_BASE_URL\":\"https://api.moonshot.ai/anthropic\",\n  \"ANTHROPIC_AUTH_TOKEN\":env.KIMI_API_KEY,\n  \"ANTHROPIC_MODEL\":\"kimi-k3\",\n  \"ANTHROPIC_DEFAULT_OPUS_MODEL\":\"kimi-k3\",\n  \"ANTHROPIC_DEFAULT_SONNET_MODEL\":\"kimi-k3\",\n  \"ANTHROPIC_DEFAULT_HAIKU_MODEL\":\"kimi-k3\",\n  \"CLAUDE_CODE_SUBAGENT_MODEL\":\"kimi-k3\",\n  \"ENABLE_TOOL_SEARCH\":\"false\",\n  \"CLAUDE_CODE_AUTO_COMPACT_WINDOW\":\"1048576\",\n  \"CLAUDE_CODE_EFFORT_LEVEL\":\"max\"\n}' ~/.claude/settings.json > \"$TMP\" && mv \"$TMP\" ~/.claude/settings.json && chmod 600 ~/.claude/settings.json\n```\n\n(Either route: if the file doesn't exist, create it as {\"env\": {...}} the same way, seeding from {}. If switching routes over a previous Kimi setup, first delete the other route's stale keys — e.g. remove ANTHROPIC_AUTH_TOKEN when writing SUB, remove ANTHROPIC_API_KEY when writing PLAT.)\n\nThen remove conflicts — settings.jsonenvoverrides shell exports, but stale rc-file exports of ANTHROPIC_* pointing at other providers still confuse diagnosis. Grep ~/.zshrc/~/.bashrc for ANTHROPIC_BASE_URL/ANTHROPIC_AUTH_TOKEN exports; if any point to a non-moonshot provider, comment them out (with a # disabled by kimi-k3 setup marker), noting this in your final report.\n\nEvery model-tier variable above is required. Missing ones make subagents and background tasks (titles, summarization) fail silently with unknown-model errors. The exact ANTHROPIC_DEFAULT_* roster tracks Claude Code releases — confirm against the installed version's docs; an unrecognized variable is ignored harmlessly, but a missing recognized one is not.\n\nPreserve-existing-setup variant: if settings.json already routes to another provider the user actively uses (e.g. a real Anthropic subscription), do not clobber it. Instead create an isolated profile: write the full config to ~/kimi-home/.claude/settings.json and append to the user's rc file:\n\n```\nalias kimi-claude='CLAUDE_CONFIG_DIR=$HOME/kimi-home/.claude claude'\n```\n\nDecision rule: existing env.ANTHROPIC_BASE_URL already moonshot → in-place merge. Existing non-moonshot base URL, or OAuth login in active use → isolated profile. \"OAuth login in active use\" is concrete: on Linux, ~/.claude/.credentials.json exists and is non-empty; on macOS, security find-generic-password -s \"Claude Code-credentials\" succeeds. Base URL absent and no OAuth credentials → in-place merge. State the choice in the §1.4 consent message and repeat it in the final report.\n\n3. Codex CLI\n\nProtocol constraint (verified by deep research, 2026-07): Codex CLI speaks only the OpenAI Responses API for custom providers — wire_api = \"chat\" was removed from Codex in early 2026. Kimi's endpoints (platform api.moonshot.ai/v1 and subscription api.kimi.com/coding/v1) are Chat Completions, so on a current Codex a direct wiring fails and a local translation bridge is required. Moonshot's official answer is the CC Switch GUI router — which you must NOT use (interactive). Attempt the ladder below in order; stop at the first rung whose §7 verification passes. Rung O first when Route O is available (§1.0) — it is the only rung that surfaces Kimi in the Codex App model picker alongside native GPT models and needs no key; Rungs A/B are the key-based (S/P) fallbacks.\n\nRung O — codex-router with the Kimi OAuth session (preferred; Route O)\n\nRequires: a valid kimi login session (§1.0), Git, Node.js ≥22.19, and uv or Python 3.10+. Missing runtime → do not install system packages without consent; skip to Rung A/B.\n\nInstall per the repo's own agent runbook (AGENTS.md in duolahypercho/codex-router — read it first and follow it where it is stricter than this section):\n\n```\n# 1. Stable checkout — never install the service from a temp clone\ngit clone https://github.com/duolahypercho/codex-router ~/.local/share/codex-router \\\n  || git -C ~/.local/share/codex-router pull --ff-only\ncd ~/.local/share/codex-router\n\n# 2. Non-interactive install, OAuth provider only.\n#    --migrate-known is safe: it only snapshots/migrates router installs the repo itself recognizes.\n./install.sh --auto --providers kimi-oauth --migrate-known\n\n# 3. Health — every core line must be OK (unselected credentials may WARN)\n./bin/doctor || ./bin/doctor --fix\n./bin/providers        # expect: kimi-oauth SHOW + ready\n```\n\nWhat it changes: only a marked # BEGIN codex-router-managed … # END block in ~/.codex/config.toml (openai_base_url → local router on 127.0.0.1:4102, plus model_catalog_json), first backup kept as config.toml.pre-codex-router. It does not touch model, model_provider, profiles, MCP config, or the ChatGPT login — native GPT models keep working; kimi-oauth/k3 appears as an additional picker entry. Internally: router :4102 → LiteLLM Responses↔Chat-Completions adapter :4100 → OAuth forwarder :4101 → Kimi Code API; all listeners on 127.0.0.1.\n\nRung O safety boundaries (from the repo's AGENTS.md; they override your defaults):\n\nNever print, read, or copy credential files or the generated /_codex-router/<capability>/v1 base URL — treat the managed URL as a local secret; show it only redacted.\n\nNever kill unknown processes on ports 4100–4103; never migrate/stop an unrecognized router — --migrate-known handles recognized ones only.\n\nDo not restart or quit the Codex App yourself; the catalog loads at app startup, so the final step is the user's: fully quit Codex (not just the window) and reopen. Say this in the report. CLI verification (§7) works without the app restart.\n\nIf doctor still fails after --fix, run ./bin/support-bundle and report its path; do not upload it.\n\nRollback: cd ~/.local/share/codex-router && ./bin/rollback (or ./bin/migrate rollback for a migrated older install); the managed config block is removable by deleting the marked lines and restoring config.toml.pre-codex-router.\n\nOn success, skip Rungs A/B entirely (no LiteLLM service needed — codex-router embeds its own adapter). If the user also wants a key-based Codex profile as backup, that is out of scope unless requested.\n\nRung A — direct config (works only on older Codex builds that still accept wire_api = \"chat\")\n\nBack up ~/.codex/config.toml, then write (update in place if a [model_providers.kimi] block exists; replace, don't duplicate, top-level keys):\n\n```\nmodel = \"k3\"                     # Route S; \"kimi-k3\" on Route P\nmodel_provider = \"kimi\"\nmodel_reasoning_effort = \"high\"\n\n[model_providers.kimi]\nname = \"Kimi\"\nbase_url = \"https://api.kimi.com/coding/v1\"   # Route S; https://api.moonshot.ai/v1 on Route P\nenv_key = \"KIMI_API_KEY\"\nwire_api = \"chat\"\n```\n\nIf codex exec errors on the config (unknown/invalid wire_api value) or requests 404, move straight to Rung B — do not debug Rung A further. (There is no direct Responses wiring: api.moonshot.ai/v1/responses returns 404 — the platform endpoint is Chat Completions only.)\n\nRung B — LiteLLM translation proxy (the non-interactive bridge; fallback on current Codex)\n\nLiteLLM exposes a Responses-API facade locally and translates to Kimi's Chat Completions upstream.\n\n```\n# 1. Install (prefer uv; fall back to pipx/pip)\nuv tool install \"litellm[proxy]\" || pipx install \"litellm[proxy]\" || pip install --user \"litellm[proxy]\"\n\n# 2. Config — ~/.config/litellm/kimi.yaml (create dir; key via env reference, not plaintext)\nmkdir -p ~/.config/litellm\ncat > ~/.config/litellm/kimi.yaml <<'EOF'\nmodel_list:\n  - model_name: kimi-k3\n    litellm_params:\n      model: moonshot/k3                    # Route S; moonshot/kimi-k3 on Route P\n      # Must be the moonshot/ prefix. openai/... passes requests through untranslated\n      # and every request fails; moonshot/ engages LiteLLM's Moonshot translation.\n      api_base: https://api.kimi.com/coding/v1   # Route S; https://api.moonshot.ai/v1 on Route P\n      api_key: os.environ/KIMI_API_KEY\nEOF\n\n# 3. Key file the unit reads — written via shell builtins only (umask 077 → 0600); never inline the key in the unit\n( umask 077; printf 'KIMI_API_KEY=%s\\n' \"$KIMI_API_KEY\" > ~/.config/litellm/.kimi-key )\n\n# 4a. Linux — run as a persistent background service (user-level systemd; survives reboots)\nmkdir -p ~/.config/systemd/user\ncat > ~/.config/systemd/user/litellm-kimi.service <<EOF\n[Unit]\nDescription=LiteLLM proxy for Kimi (Codex bridge)\n[Service]\nEnvironmentFile=%h/.config/litellm/.kimi-key\nExecStart=$(command -v litellm) --config %h/.config/litellm/kimi.yaml --port 4141\nRestart=on-failure\n[Install]\nWantedBy=default.target\nEOF\nsystemctl --user daemon-reload && systemctl --user enable --now litellm-kimi\n```\n\n(EnvironmentFile= reads KIMI_API_KEY=... lines from the file — do not use Environment=KIMI_API_KEY=<path>, which would set the variable's value to the file path itself and 401 every request.)\n\n```\n# 4b. macOS — no systemd; use a user-level launchd agent instead.\n# launchd has no EnvironmentFile equivalent, so a /bin/sh wrapper sources the 0600\n# key file at start — the key itself never appears in the plist.\nmkdir -p ~/Library/LaunchAgents\ncat > ~/Library/LaunchAgents/com.kimi.litellm.plist <<EOF\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n  <key>Label</key><string>com.kimi.litellm</string>\n  <key>ProgramArguments</key>\n  <array>\n    <string>/bin/sh</string>\n    <string>-c</string>\n    <string>set -a; . \"\\$HOME/.config/litellm/.kimi-key\"; exec $(command -v litellm) --config \"\\$HOME/.config/litellm/kimi.yaml\" --port 4141</string>\n  </array>\n  <key>RunAtLoad</key><true/>\n  <key>KeepAlive</key><dict><key>SuccessfulExit</key><false/></dict>\n</dict>\n</plist>\nEOF\nlaunchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.kimi.litellm.plist 2>/dev/null \\\n  || launchctl load ~/Library/LaunchAgents/com.kimi.litellm.plist   # older macOS fallback\n```\n\n(On hosts with neither systemd nor launchd, use the harness's tracked background-job facility to run litellm --config ... --port 4141 with KIMI_API_KEY exported, and note in the report that it must be relaunched after reboot.)\n\nThen point Codex at the proxy:\n\n```\nmodel = \"kimi-k3\"\nmodel_provider = \"kimi\"\nmodel_reasoning_effort = \"high\"\n\n[model_providers.kimi]\nname = \"Kimi via LiteLLM\"\nbase_url = \"http://localhost:4141/v1\"\nenv_key = \"KIMI_API_KEY\"        # value irrelevant to the proxy hop but must be set\nwire_api = \"responses\"\n```\n\nSanity-check the proxy itself before blaming Codex: curl -s http://localhost:4141/v1/models should list kimi-k3.\n\nRung C — report-only fallback\n\nIf Rung O prerequisites are missing and LiteLLM cannot be installed (no network/python tooling), configure nothing, and in the final report tell the user their manual options: Moonshot's CC Switch GUI routing guide (https://platform.kimi.ai/docs/guide/codex-kimi), or the interactive ocx init of opencodex (https://github.com/lidge-jun/opencodex, npm i -g @bitkyc08/opencodex) which supports Kimi OAuth for Codex and Claude Code. Do not attempt to drive either interactive flow yourself.\n\nPreserving an existing OpenAI setup\n\nKeep the user's ChatGPT/OpenAI Codex auth usable: instead of overwriting top-level model/model_provider, you may define the Kimi rung under a profile. Current Codex versions reject [profiles.kimi] blocks inside config.toml — profiles must live in their own file. Write the profile to ~/.codex/kimi.config.toml:\n\n```\n# ~/.codex/kimi.config.toml — do NOT put this in config.toml (current Codex rejects it there)\nmodel = \"kimi-k3\"\nmodel_provider = \"kimi\"\nmodel_reasoning_effort = \"high\"\n```\n\n(The [model_providers.kimi] block from the winning rung stays in ~/.codex/config.toml as before — only the profile moves.) Verify with codex exec --profile kimi .... Same decision rule as §2: take over the default only if no other provider is actively configured; otherwise use the profile and say so in the report.\n\nTop-level model/model_provider keys: replace existing values rather than appending duplicates (TOML rejects duplicate keys).\n\nCodex reads the key from the environment (env_key), so persist it: if KIMI_API_KEY isn't already exported in a shell rc file, append it to ~/.zshrc with the printfbuiltin (printf 'export KIMI_API_KEY=%s\\n' \"$KIMI_API_KEY\" >> ~/.zshrc — builtins don't expose argv; do not display the key). This puts the key in plaintext in the rc file, so ~/.zshrc must be listed in the §1.4 consent message.\n\nIf the user's Codex is authenticated with a ChatGPT subscription they use, keep that usable: add the Kimi block but note in your report that codex --profile/model_provider switching applies; optionally define the profile in ~/.codex/kimi.config.toml (as above) instead of changing the top-level default — same decision rule as §2 (clobber only if nothing else is actively configured).\n\n4. Hermes Agent\n\nKimi is a first-class Hermes provider; config is file-based, no wizard needed. Hermes' kimi-coding provider is built for the Kimi coding key — both routes use the same provider name and KIMI_API_KEY variable, so the steps below are route-independent except for the model ID (SUB: k3; PLAT: kimi-k3) and one override: on Route S, if requests fail against the provider's default endpoint, set KIMI_BASE_URL=https://api.kimi.com/coding/v1 in ~/.hermes/.env.\n\n```\n# 1. Key into ~/.hermes/.env (create file if missing; replace existing KIMI_API_KEY line, don't append a duplicate).\n# No sed: the key in sed's argv is world-readable via /proc, and |/& in a key break the replacement.\nmkdir -p ~/.hermes && touch ~/.hermes/.env && chmod 600 ~/.hermes/.env\nTMP=$(mktemp)\ngrep -v '^KIMI_API_KEY=' ~/.hermes/.env > \"$TMP\" || true\nprintf 'KIMI_API_KEY=%s\\n' \"$KIMI_API_KEY\" >> \"$TMP\"\nmv \"$TMP\" ~/.hermes/.env && chmod 600 ~/.hermes/.env\n```\n\nSet the default model in ~/.hermes/config.yaml (back up first; merge into the existing model: block if present):\n\n```\nmodel:\n  provider: \"kimi-coding\"\n  default: \"k3\"        # Route S; use \"kimi-k3\" on Route P\n```\n\nChina-platform key (from §1.3): use provider kimi-coding-cn and put the key in KIMI_CN_API_KEY instead.\n\nIf config.yaml already has a provider the user actively uses, leave model: alone and just install the key — the user can switch with /model in-session; say so in the report. Same decision rule as §2.\n\nUsage (for your verification and your report): hermes chat --provider kimi-coding --model k3 (or kimi-k3 on Route P).\n\n5. Pi\n\nConfig is file-based. The two routes diverge here — Pi's built-in kimi-coding provider only accepts subscription (Route S) keys; a platform pay-per-token key gets a 401 from it. Route P needs a custom provider in ~/.pi/agent/models.json instead.\n\nSUB (Route S) — use the built-in provider, literally named \"Kimi For Coding\" (kimi-coding), via ~/.pi/agent/auth.json. Pi's auth.json supports env interpolation, so prefer the no-plaintext form: since you persisted export KIMI_API_KEY in §3 (do it even if Codex is absent, when Pi is present), write:\n\n```\nmkdir -p ~/.pi/agent\n[ -f ~/.pi/agent/auth.json ] && cp ~/.pi/agent/auth.json ~/.pi/agent/auth.json.bak-kimi-$(date +%s)\n# merge, preserving other providers' credentials\n[ -f ~/.pi/agent/auth.json ] || echo '{}' > ~/.pi/agent/auth.json\nTMP=$(mktemp)\njq '. + {\"kimi-coding\": {\"type\": \"api_key\", \"key\": \"$KIMI_API_KEY\"}}' \\\n  ~/.pi/agent/auth.json > \"$TMP\" && mv \"$TMP\" ~/.pi/agent/auth.json\nchmod 600 ~/.pi/agent/auth.json\n```\n\nNote: \"$KIMI_API_KEY\" here is a literal string — Pi interpolates it at runtime. Do not substitute the real key into this file. auth.json beats env vars in Pi's resolution order, so this entry wins cleanly.\n\nPLAT (Route P) — do not write the key under kimi-coding (401). Define a custom Moonshot provider in ~/.pi/agent/models.json (back up first; merge if the file exists, preserving other custom providers):\n\n```\nmkdir -p ~/.pi/agent\n[ -f ~/.pi/agent/models.json ] && cp ~/.pi/agent/models.json ~/.pi/agent/models.json.bak-kimi-$(date +%s)\n[ -f ~/.pi/agent/models.json ] || echo '{}' > ~/.pi/agent/models.json\nTMP=$(mktemp)\njq '.providers = (.providers // {}) + {\n  \"moonshot\": {\n    \"name\": \"Moonshot (Kimi Platform)\",\n    \"baseUrl\": \"https://api.moonshot.ai/v1\",\n    \"api\": \"openai-completions\",\n    \"apiKey\": \"KIMI_API_KEY\",\n    \"models\": [\n      {\"id\": \"kimi-k3\", \"name\": \"Kimi K3\", \"reasoning\": true, \"contextWindow\": 1048576, \"maxTokens\": 16384}\n    ]\n  }\n}' ~/.pi/agent/models.json > \"$TMP\" && mv \"$TMP\" ~/.pi/agent/models.json\nchmod 600 ~/.pi/agent/models.json\n```\n\n\"apiKey\": \"KIMI_API_KEY\" names the env var Pi reads at runtime — no plaintext key lands in this file, but the §3 rc-file export must exist. Verify the field names against the installed Pi version's custom-provider docs before writing; if they differ, adapt rather than guessing. Use China endpoint https://api.moonshot.cn/v1 for a .cn key.\n\nModel selection in Pi is per-session (/model) — no default-model file edit is needed or safe to guess. In the report, tell the user: \"In Pi, pick Kimi K3 via /model (provider: Kimi For Coding on Route S; Moonshot on Route P).\"\n\n6. Other OpenAI-compatible harnesses (OpenCode, Cline, Aider, Zed, ...)\n\nIf the user asked for a harness not covered above and it supports custom OpenAI-compatible providers, configure its provider file with:\n\nBase URL https://api.moonshot.ai/v1, model kimi-k3, key from $KIMI_API_KEY\n\nContext window 1048576 if the harness has such a field\n\nDo not configure sampling parameters (they're fixed server-side)\n\nFind that harness's non-interactive config file yourself (docs or --help); apply the same rules: backup, merge, no wizards, no plaintext key in chat.\n\n7. Verification (all non-interactive)\n\nRun for each configured harness; collect results for the final report.\n\nUse MODEL=k3 on Route S (never k3[1m] outside Claude Code env vars) and MODEL=kimi-k3 on Route P.\n\nHarness\n\nCommand\n\nPass criterion\n\nAPI direct\n\nwinning probe from §1.3\n\nHTTP 200\n\nClaude Code\n\nclaude -p 'Reply with exactly: KIMI-OK' (with the profile's env active; model comes from settings.json)\n\nOutput contains KIMI-OK\n\nCodex CLI (Rung A/B)\n\ncodex exec 'Reply with exactly: KIMI-OK'\n\nOutput contains KIMI-OK; startup banner shows the Kimi model\n\nCodex CLI (Rung O)\n\n~/.local/share/codex-router/bin/doctor, then codex exec -m kimi-oauth/k3 'Reply with exactly: KIMI-OK'\n\nDoctor all-OK on core lines; output contains KIMI-OK. App picker entry only verifiable by the user after a full app restart — state it in the report, don't fail on it\n\nHermes\n\nhermes chat --provider kimi-coding --model $MODEL -p 'Reply with exactly: KIMI-OK' (use --print/non-interactive flag per hermes chat --help)\n\nOutput contains KIMI-OK\n\nPi\n\npi --provider kimi-coding --model k3 -p 'Reply with exactly: KIMI-OK' on Route S; pi --provider moonshot --model kimi-k3 -p '...' on Route P (check pi --help for the print flag)\n\nOutput contains KIMI-OK\n\nIf a harness's non-interactive flag differs from the above, discover it via --help rather than skipping verification. A verification failure is yours to debug (see §8) — do not hand it back to the user until you've worked through §8.\n\n8. Failure playbook (work through before reporting failure)\n\nSymptom\n\nCause\n\nFix\n\n401 (Claude Code)\n\nStale env entries in settings.json overriding your merge; or wrong-region key\n\nRe-read the file you wrote; try .cn endpoints\n\n\"model not found\"\n\nA model-tier variable still points at a Claude/GPT default\n\nRe-check all 7 model vars in §2\n\n400 invalid thinking\n\nK2.x thinking param sent, or thinking disabled\n\nK3: remove thinking, use reasoning_effort; never disable thinking\n\nTool calls misbehave (Claude Code)\n\nTool Search enabled\n\nENABLE_TOOL_SEARCH must be the string \"false\"\n\nPremature compaction / context errors\n\nWrong compact window\n\nCLAUDE_CODE_AUTO_COMPACT_WINDOW=1048576\n\nCodex ignores provider\n\nDuplicate top-level model/model_provider keys, or TOML parse error\n\ncodex exec surfaces parse errors; validate the TOML\n\nCodex rejects wire_api = \"chat\"\n\nCurrent Codex builds only support responses\n\nExpected — move to §3 Rung B (LiteLLM proxy); there is no direct Responses wiring (api.moonshot.ai/v1/responses is 404)\n\nCodex hangs 15+ min before first output\n\nHooks or MCP servers in ~/.codex/config.toml stall startup when combined with a custom provider\n\nTemporarily comment out mcp_servers/hook blocks, retry, then re-enable one at a time to find the culprit\n\nCodex rejects config: unknown [profiles.*]\n\nProfile block placed in config.toml; current Codex requires profiles in their own file\n\nMove the block to ~/.codex/kimi.config.toml (§3)\n\nEvery request via proxy fails / passthrough errors\n\nLiteLLM model uses the openai/ prefix, which doesn't translate\n\nUse moonshot/k3 (Route S) / moonshot/kimi-k3 (Route P) in kimi.yaml; restart the service\n\nCodex 404/protocol errors via proxy\n\nLiteLLM not running, wrong port, or upstream mapping wrong\n\ncurl http://localhost:4141/v1/models; check systemctl --user status litellm-kimi (Linux) or launchctl list | grep com.kimi.litellm (macOS); verify api_base/model in kimi.yaml\n\nCodex 401 via proxy\n\nUnit uses Environment=KIMI_API_KEY=<path> (value = the file path) instead of EnvironmentFile=\n\nEnvironmentFile=%h/.config/litellm/.kimi-key with a KIMI_API_KEY=... line inside (0600); restart the unit\n\nHermes uses wrong model\n\nconfig.yamlmodel: block not merged / overridden by CLI flags\n\nLiteral $KIMI_API_KEY written but env var not exported in the shell Pi runs from\n\nConfirm the rc-file export from §3; restart shell context\n\nPi 401 on Route P\n\nPlatform pay-per-token key written under the kimi-coding provider, which only accepts subscription keys\n\nRemove the kimi-coding auth.json entry; use the custom moonshot provider in models.json (§5 PLAT)\n\nSampling-param rejection\n\nHarness injects temperature etc.\n\nRemove from harness config; K3 fixes these server-side\n\n401 with a valid subscription\n\nRoute mix-up: subscription key sent to api.moonshot.ai, or platform key sent to api.kimi.com/coding/\n\nRe-run §1.3 classification; the two consoles issue different keys\n\nRung O: auth errors after previously working\n\nkimi login OAuth session expired or revoked\n\nRe-run §1.0 step 2; if dead, relay a fresh kimi login device-code URL to the user, then ./bin/doctor\n\nRung O: Kimi missing from the App picker but CLI works\n\nCatalog loads only at app startup, or stale catalog\n\nUser must fully quit Codex (not just the window) and reopen; if still missing, ./bin/refresh-catalog then quit/reopen again\n\nRung O: doctor FAIL on service/router health\n\nPort 4100–4103 conflict or service not started\n\nsystemctl --user status the router unit; if a foreign process owns the port, report it — never kill unknown processes on those ports\n\nRung O: codex exec ignores the router\n\nManaged block removed/mangled in config.toml, or another tool overwrote openai_base_url\n\nCheck the marked codex-router-managed block; ./bin/doctor --fix rebuilds it\n\n\"model not found: kimi-k3\" on Route S\n\nPlatform model ID used against the subscription endpoint\n\nSubscription model IDs are k3 / kimi-for-coding, not kimi-k3\n\nk3[1m] rejected\n\n1M form used outside Claude Code env vars, or plan is a 256K tier\n\nUse k3 everywhere else; downgrade to 256K config per §1.3 tier check\n\n9. Final report to the user (required format)\n\nEnd with a short message containing:\n\nWhich auth route was used per harness (S subscription key / O OAuth session / P platform pay-per-token) and, on Route S, which plan tier was detected (1M vs 256K).\n\nThe 1–2 things the user must know: e.g. kimi-claude alias if you made an isolated profile; /model selection note for Pi; restart open harness sessions to pick up new config; on Rung O, fully quit and reopen the Codex App to load the new model catalog.\n\nRollback one-liner: \"To undo, restore the .bak-kimi-* files listed above.\"\n\nNo secrets in the report. No questions in the report.\n\nThis 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.\nLearn more about bidirectional Unicode characters\n\nThis 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.\nLearn more about bidirectional Unicode characters\n\nSplit-brain coding mode — the session model (e.g. Claude Fable) acts as orchestrator only, and ALL code writing is delegated to a Kimi worker running headless Claude Code against Moonshot's Anthropic-compatible API. Use when the user invokes /kimi-router or asks to route coding work to Kimi.\n\nKimi Router\n\nYou are now the orchestrator. Kimi is the executor. This mode stays on for the rest of the session.\n\nThe one rule\n\nYou never write or edit code. Not one line, not a \"quick fix\". Every code change — new files, edits, refactors, config, tests — is delegated to a Kimi worker. Your job is direction: understand the task, write the brief, review the result.\n\nYou MAY still directly: read files, search, run tests/builds, run git commands, answer questions, and edit non-code documents the user asks you for (e.g. this brief, notes).\n\nSetup (once)\n\nThe worker needs these env vars (put them in ~/.kimi/env or similar, never commit them):\n\n```\nexport KIMI_API_KEY=\"sk-...\"                                # Moonshot platform key\nexport KIMI_BASE_URL=\"https://api.moonshot.ai/anthropic\"    # Anthropic-compatible endpoint\nexport KIMI_MODEL=\"kimi-k3\"                                 # exact model name from Moonshot docs\n```\n\nIf KIMI_API_KEY is not set in the environment, try source ~/.kimi/env first; if still missing, stop and ask the user for the key.\n\nThe loop (per coding task)\n\nUnderstand — read the relevant files and any AGENTS.md/CLAUDE.md yourself. Decide what should change and where.\n\nBrief — write a self-contained task brief. The worker has zero conversation context, so the brief must include:\n\nGoal in one sentence, then exact requirements.\n\nAbsolute paths of files to change (and files to read for context/conventions).\n\nConstraints (style, patterns to follow, what NOT to touch).\n\nAcceptance criteria (what must pass/work when done).\n\nDelegate — spawn one worker (serial, never parallel):\n\n```\nenv ANTHROPIC_BASE_URL=\"$KIMI_BASE_URL\" \\\n    ANTHROPIC_AUTH_TOKEN=\"$KIMI_API_KEY\" \\\n    ANTHROPIC_MODEL=\"$KIMI_MODEL\" \\\n    ANTHROPIC_SMALL_FAST_MODEL=\"$KIMI_MODEL\" \\\n    claude -p \"<brief>\" \\\n    --model \"$KIMI_MODEL\" \\\n    --permission-mode acceptEdits \\\n    --settings '{\"disableAllHooks\": true}' \\\n    --output-format stream-json --verbose \\\n    --add-dir <project-root>\n```\n\n--model is required: without it, headless Claude Code uses the user's saved default model (an Anthropic model), which the Kimi endpoint rejects. The env vars alone are not enough.\n\n--settings '{\"disableAllHooks\": true}' stops the user's global hooks (e.g. an autogit Stop hook) from firing inside the worker — otherwise the worker's changes can get auto-committed and even auto-pushed with the brief as the commit message before the orchestrator has reviewed them. The orchestrator owns git; workers must not commit. (Trade-off: guardrail hooks are also skipped, so never combine this with a broad Bash allowlist.)\n\n--output-format stream-json --verbose makes the worker emit one JSON line per step (tool calls, edits, messages) instead of staying silent until the end. Run the worker in the background, poll its output file every ~30s, and report progress to the user in plain English (e.g. \"Kimi is editing index.js now\"). The final result JSON line is the worker's report.\n\nRun it from the project root. For anything non-trivial, run it in the background (it can take minutes) and poll the output instead of blocking.\n\nReview — after the worker exits:\n\nRead the full diff (git diff).\n\nCheck it against the acceptance criteria.\n\nRun the relevant tests/build.\n\nIterate — if something is wrong or missing, do NOT fix it yourself. Write a new fix-it brief (quote the failing test output / the specific defect and file:line) and spawn another worker. Repeat until the acceptance criteria pass.\n\nReport — tell the user what Kimi changed, what you verified, and anything still open.\n\nBrief-writing tips\n\nOne task per worker. Split big features into sequential briefs; each builds on the reviewed result of the last.\n\nOver-specify. Vague briefs produce vague code. Name functions, name files, paste relevant snippets.\n\nTell the worker to follow existing patterns in named files rather than inventing new abstractions.\n\nTell the worker its stdout is a report, not a chat: end with a summary of files changed.\n\nFailure handling\n\nWorker returns an API/auth error → surface it to the user; it's a setup problem, not a coding problem.\n\nWorker produces wrong code → fix-it brief (step 5). There is no \"orchestrator takes over\" fallback.\n\nThis 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.\nLearn more about bidirectional Unicode characters", "url": "https://wpnews.pro/news/kimi-everywhere-run-any-coding-harness-claude-code-codex-opencode-cline-aider-on", "canonical_source": "https://gist.github.com/Maciejdziuba/038c0c822d2c799cffcfdec805975e66", "published_at": "2026-07-20 10:21:53+00:00", "updated_at": "2026-07-24 21:58:09.008758+00:00", "lang": "en", "topics": ["developer-tools", "artificial-intelligence", "large-language-models", "ai-products"], "entities": ["Kimi", "Claude Code", "Codex", "OpenCode", "Cline", "Aider", "Roo Code"], "alternates": {"html": "https://wpnews.pro/news/kimi-everywhere-run-any-coding-harness-claude-code-codex-opencode-cline-aider-on", "markdown": "https://wpnews.pro/news/kimi-everywhere-run-any-coding-harness-claude-code-codex-opencode-cline-aider-on.md", "text": "https://wpnews.pro/news/kimi-everywhere-run-any-coding-harness-claude-code-codex-opencode-cline-aider-on.txt", "jsonld": "https://wpnews.pro/news/kimi-everywhere-run-any-coding-harness-claude-code-codex-opencode-cline-aider-on.jsonld"}}