Find a file
liruifengv dad2b87cee
refactor(tui): split kimi-tui God-class into controllers and command modules (#142)
* refactor(tui): extract TasksBrowserController from KimiTUI

将 /tasks 浏览器相关的 16 个方法(~450 行)从 KimiTUI 提取到独立的
TasksBrowserController。KimiTUI 通过 Host 接口传 this 给 controller,
保留 4 个一行委托方法供外部调用点使用。

kimi-tui.ts: 6160 → 5711 行 (-449)

* refactor(tui): extract StreamingUIController from KimiTUI

将 Streaming Flush(15 个方法)和 Live Render Hooks(15 个方法)
共 ~475 行代码从 KimiTUI 提取到 StreamingUIController。这两个区域
之间紧密耦合(flush 方法直接调用 render hooks),合并提取避免循环依赖。

同时迁移了 5 个实例变量:flushTimer, lastFlushAt, pendingAssistantFlush,
pendingThinkingFlush, pendingToolCallFlushIds。

kimi-tui.ts: 5711 → 5268 行 (-443)

* refactor(tui): extract SessionEventHandler from KimiTUI

将 Session Events(39 个方法)和 Background Task Lifecycle(4 个方法)
共 ~960 行代码从 KimiTUI 提取到 SessionEventHandler。包含事件分发、
turn/step 生命周期、thinking/assistant delta 处理、tool call 管理、
compaction 流程、subagent 管理、MCP 状态渲染、background task 事件。

kimi-tui.ts: 5268 → 4316 行 (-952)

* refactor(tui): extract SessionReplayRenderer from KimiTUI

将 Session Replay 的 21 个方法(~410 行)从 KimiTUI 提取到
SessionReplayRenderer。包含会话历史回放水合(snapshot hydration)、
replay record 渲染、thinking/assistant/tool call 回放、skill 激活、
权限变更、审批结果、background task 通知等逻辑。

kimi-tui.ts: 4316 → 3911 行 (-405)

* refactor(tui): extract slash command handlers from KimiTUI

将 Slash Command Handlers 区域(~765 行)从 KimiTUI 提取到两个文件:
- slash-commands.ts (684 行):命令逻辑(plan/yolo/compact/editor/theme/
  model/title/fork/init/login/connect/logout/feedback)
- slash-command-prompts.ts (183 行):UI prompt 函数(platform selection、
  logout provider、feedback input、API key、model selector 等)

prompt 函数拆为独立模块避免 ESM 同模块内部调用 mock 不生效的问题。
测试改为 vi.mock 对应的 prompt 模块。

kimi-tui.ts: 3911 → 3163 行 (-748)

* refactor(tui): extract AuthFlowController from KimiTUI

将 Auth / Model Bootstrap 的 6 个方法(~115 行)从 KimiTUI 提取到
AuthFlowController。包含 refreshAvailableModels、
enterLoginRequiredStartupState、activateModelAfterLogin、
clearActiveSessionAfterLogout、refreshConfigAfterLogin、
refreshConfigAfterLogout。

kimi-tui.ts: 3163 → 3063 行 (-100)

* refactor(tui): clean up dead imports after controller extraction

移除 kimi-tui.ts 和 controller 文件中因代码提取而残留的 55+ 个
无用 import(SDK event types、OAuth 工具函数、catalog 类型等)。

kimi-tui.ts: 3063 → 3005 行 (-58)

* refactor(tui): remove delegate methods and direct controller references

Phase A: 删除 14 个零调用者的纯委托方法
Phase B: 内联 8 个少量调用者委托(调用处直接引用 controller)
Phase C: controller 之间通过 host 上的 controller 引用直接协作,
         不再绕 kimi-tui 中转(SessionEventHandler → tasksBrowserController,
         SlashCommands → authFlow)

kimi-tui.ts: 3005 → 2956 行 (-49)

* refactor(tui): move pickers, config apply, info commands to slash-commands controller

Phase D: 将 pickers(editor/model/theme/permission/settings)、
config apply(applyEditorChoice/applyThemeChoice/applyPermissionChoice/
performModelSwitch/persistModelSelection)、info commands
(showUsage/showStatusReport/showMcpServers + load* helpers)共 ~400 行
从 kimi-tui.ts 搬到 slash-commands controller。

Phase E: handleBuiltInSlashCommand 中所有 case 直接调用 slashCommands.*,
删除全部 13 个 slash command 委托方法。测试改为直接调用 controller 函数。

kimi-tui.ts: 2956 → 2566 行 (-390)

* refactor(tui): final cleanup — remove last delegates and dead imports

删除 finalizeTurn 和 activateModelAfterLogin 委托方法,
slash-commands 直接通过 host.streamingUI / host.authFlow 调用。
清理 15 个因搬运产生的 dead import。

kimi-tui.ts: 2566 → 2545 行 (-21)

* refactor(tui): clean up dead imports and empty import blocks

清理第二轮搬运后残留的 19 个 dead import 和 3 个空 import 块
(api-key-input-dialog、feedback-input-dialog、settings-selector、
feedback constants 等已搬到 slash-commands controller)。

kimi-tui.ts: 2545 → 2517 行 (-28)

* refactor(tui): inline last auth delegate methods

将 refreshAvailableModels 和 enterLoginRequiredStartupState 的
调用方改为直接访问 this.authFlow.*,删除最后两个委托方法。

kimi-tui.ts: 2517 → 2510 行 (-7)

* refactor(tui): move slash command dispatch to slash-commands controller

将 executeSlashCommand(~45 行)和 handleBuiltInSlashCommand(~80 行)
从 kimi-tui.ts 搬到 slash-commands controller。kimi-tui.ts 的
handleUserInput 现在只做空检查、replay guard、历史持久化,
然后调 slashCommands.dispatchInput(this, text)。

kimi-tui.ts: 2510 → 2367 行 (-143)

* refactor(tui): clean up 38 dead imports and 3 dead interfaces

移除因前几轮搬运残留的 import(message-replay、mcp-server-status、
background-*-status、hook-result-format、event-payload utils、
streaming/theme constants 等)和 SessionUsageResult / RuntimeStatusResult /
ManagedUsageResult 接口定义。

kimi-tui.ts: 2367 → 2311 行 (-56)

* refactor(tui): deduplicate combineStartupNotice and isOAuthLoginRequiredError

将 combineStartupNotice(kimi-tui.ts + auth-flow.ts 各一份)和
isOAuthLoginRequiredError 统一到 constant/kimi-tui.ts,两边改为 import。

kimi-tui.ts: 2311 → 2296 行 (-15)

* refactor(tui): move startup utils out of constant/kimi-tui

combineStartupNotice 和 isOAuthLoginRequiredError 是工具函数不是常量,
从 constant/kimi-tui.ts 移到 utils/startup.ts。

* refactor(tui): remove last session event/replay delegate methods

删除 handleEvent、startSessionEventSubscription、
hydrateTranscriptFromReplay 三个委托方法。
kimi-tui 内部和 auth-flow controller 改为直接访问
sessionEventHandler.startSubscription() 和
sessionReplay.hydrateFromReplay()。
测试改为通过 driver.sessionEventHandler 直接调用。

kimi-tui.ts: 2296 → 2278 行 (-18)

* refactor(tui): reduce TUIState fields by removing redundancy and merging pairs

Delete 4 redundant fields (AppState.yolo, AppState.isStreaming,
TUIState.backgroundAgents, TUIState.assistantStreamActive) that were
derivable from existing state. Merge 4 pairs of always-coupled fields
into single objects (streamingBlock, subagentInfo, activitySpinner,
activeDialog). Demote 3 fields only used by KimiTUI itself to private
class fields. Net reduction: AppState 22→20, TUIState 55→48 fields.

* refactor(tui): extract TUIState types and move streaming state into StreamingUIController

Break the type-level circular dependency where controllers imported
TUIState from kimi-tui.ts while kimi-tui.ts imported runtime values
from controllers. Shared types now live in tui-state.ts (TUIState,
createTUIState) and types.ts (KimiTUIOptions, LoginProgressSpinnerHandle,
etc.) so the import graph is strictly unidirectional.

Move 12 streaming-related fields (currentTurnId, currentStep,
assistantDraft, thinkingDraft, streamingBlock, activeThinkingComponent,
activeCompactionBlock, activeToolCalls, streamingToolCallArguments,
pendingToolComponents, pendingAgentGroup, pendingReadGroup) from the
flat TUIState bag into StreamingUIController as instance properties,
along with 3 dispose methods. TUIState shrinks from 40+ to 28 fields.

* refactor(tui): split slash-commands.ts by domain into 4 focused modules

Extract the 1223-line slash-commands.ts into domain-specific files:

- auth-commands.ts (~350 lines): login, logout, connect, OAuth flows
- config-commands.ts (~380 lines): plan, yolo, compact, model/theme/
  editor/permission pickers and apply logic
- info-commands.ts (~185 lines): feedback, usage, status, mcp reports
- session-commands.ts (~105 lines): title, fork, init

slash-commands.ts is now a slim routing hub (~210 lines) that owns
SlashCommandHost, dispatchInput, and the builtin command switch. All
public handlers are re-exported so existing consumers are unaffected.

* refactor(tui): move command handlers from controllers/ to commands/

Relocate the 6 command-related files into the existing commands/
directory where parsing and routing logic already lives:

  controllers/slash-commands.ts       → commands/dispatch.ts
  controllers/slash-command-prompts.ts → commands/prompts.ts
  controllers/auth-commands.ts        → commands/auth.ts
  controllers/config-commands.ts      → commands/config.ts
  controllers/info-commands.ts        → commands/info.ts
  controllers/session-commands.ts     → commands/session.ts

controllers/ now contains only state/lifecycle controllers
(auth-flow, session-event-handler, session-replay, streaming-ui,
tasks-browser). commands/index.ts re-exports all public symbols.

* refactor(tui): move background/render-dedup state into SessionEventHandler

Move 7 fields from TUIState into SessionEventHandler as instance
properties: backgroundAgentMetadata, backgroundTasks,
backgroundTaskTranscriptedTerminal, subagentInfo,
renderedSkillActivationIds, renderedMcpServerStatusKeys,
mcpServerStatusSpinners.

Add resetRuntimeState() to SessionEventHandler that clears all 7
fields in one call. TUIState shrinks from 28 to 21 fields.

TasksBrowserHost.backgroundTasks is now a top-level ReadonlyMap
property instead of being embedded in the state subset, with a
getter on KimiTUI that delegates to sessionEventHandler.

* refactor(tui): encapsulate StreamingUIController internal state behind semantic methods

Make 12 fields private and expose 18 semantic methods instead of letting
SessionEventHandler, SessionReplayRenderer, and KimiTUI directly
manipulate internal maps and counters. Key methods: registerToolCall(),
accumulateToolCallDelta(), completeToolResult(), markStepTruncated(),
appendThinkingDelta(), appendAssistantDelta(), cleanupAfterReplay().

* refactor(tui): extract EditorKeyboardController from KimiTUI

Move editor callback wiring, pending-exit state, clipboard media
handling, and external editor logic into a dedicated controller.
KimiTUI drops from 2070 to 1814 lines.

* refactor(tui): clean up kimi-tui.ts — strip noise comments, reorganize sections

Remove ~70 single-line comments that merely restated the method name.
Condense multi-paragraph inline comments (signal handlers, start()) to
one-liners that capture the WHY. Reorganize sections: merge the one-
method "Layout" section into Lifecycle, rename "Startup Helpers" to
"Autocomplete & Skill Commands", move stray accessors into "State &
Accessors", delete the empty trailing section, relocate input-history
helpers next to each other. 1814 → 1639 lines.

* refactor(tui): route TUIState field mutations through host methods

Controllers may still read host.state freely, but all direct field
assignments now go through setter methods on the host: setStartupReady,
clearQueuedMessages, shiftQueuedMessage, pushTranscriptEntry,
setExternalEditorRunning, setTasksBrowser. This prevents controllers
from silently mutating shared state without KimiTUI's knowledge.

* chore(tui): drop merge analysis docs, add changeset, fix 2 lint errors

- delete docs/refactor-kimi-tui-{analysis,merge-plan}.md (working notes)
- add changeset for the kimi-tui split refactor
- session-event-handler.ts: drop unused `state` destructure in finishCompaction
- editor-keyboard.ts: void-mark fire-and-forget session.cancel() promise

* chore(changeset): simplify wording
2026-05-28 14:14:20 +08:00
.agents/skills docs(changelog): sync 0.3.0 from apps/kimi-code/CHANGELOG.md (#100) 2026-05-27 12:24:45 +08:00
.changeset refactor(tui): split kimi-tui God-class into controllers and command modules (#142) 2026-05-28 14:14:20 +08:00
.github ci: add pkg.pr.new previews (#95) 2026-05-27 17:09:33 +08:00
apps refactor(tui): split kimi-tui God-class into controllers and command modules (#142) 2026-05-28 14:14:20 +08:00
build Kimi For Coding 2026-05-22 15:54:50 +08:00
docs docs(changelog): sync 0.4.0 from apps/kimi-code/CHANGELOG.md (#125) 2026-05-27 23:31:03 +08:00
packages fix(approval): show file content/diff and open full-screen preview on ctrl+e (#139) 2026-05-28 13:22:33 +08:00
plugins feat: add plugin manager and official plugins (#119) 2026-05-27 22:47:33 +08:00
.editorconfig Kimi For Coding 2026-05-22 15:54:50 +08:00
.gitignore feat: add plugin manager and official plugins (#119) 2026-05-27 22:47:33 +08:00
.npmrc Kimi For Coding 2026-05-22 15:54:50 +08:00
.nvmrc Kimi For Coding 2026-05-22 15:54:50 +08:00
.oxfmtrc.json Kimi For Coding 2026-05-22 15:54:50 +08:00
.oxlintrc.json feat: add plugin manager and official plugins (#119) 2026-05-27 22:47:33 +08:00
AGENTS.md docs: enhance PR guidelines and template (#28) 2026-05-25 20:04:23 +08:00
CONTRIBUTING.md docs: enhance PR guidelines and template (#28) 2026-05-25 20:04:23 +08:00
flake.lock Kimi For Coding 2026-05-22 15:54:50 +08:00
flake.nix Kimi For Coding 2026-05-22 15:54:50 +08:00
LICENSE Kimi For Coding 2026-05-22 15:54:50 +08:00
Makefile Kimi For Coding 2026-05-22 15:54:50 +08:00
package.json feat: add plugin manager and official plugins (#119) 2026-05-27 22:47:33 +08:00
pnpm-lock.yaml ci: add pkg.pr.new previews (#95) 2026-05-27 17:09:33 +08:00
pnpm-workspace.yaml Kimi For Coding 2026-05-22 15:54:50 +08:00
README.md Kimi For Coding 2026-05-22 15:54:50 +08:00
README.zh-CN.md Fix typo in zh readme (#1) 2026-05-22 18:54:14 +08:00
SECURITY.md Kimi For Coding 2026-05-22 15:54:50 +08:00
tsconfig.json Kimi For Coding 2026-05-22 15:54:50 +08:00
vitest.config.ts Kimi For Coding 2026-05-22 15:54:50 +08:00

Kimi Code CLI

License Docs
Documentation · Issues · 中文

Demo of using Kimi Code

What is Kimi Code CLI

Kimi Code CLI is an AI coding agent that runs in your terminal — it can read and edit code, run shell commands, search files, fetch web pages, and choose the next step based on the feedback it receives. It works out of the box with Moonshot AIs Kimi models and can also be configured to use other compatible providers.

Install

Install with the official script. No Node.js required.

  • macOS or Linux:
curl -fsSL https://code.kimi.com/kimi-code/install.sh | bash
  • Windows (PowerShell):
irm https://code.kimi.com/kimi-code/install.ps1 | iex

Then, run it with a new shell session:

kimi --version

For npm install, upgrade, uninstall, see Getting Started.

Quick Start

Open a project and start the interactive UI:

cd your-project
kimi

On first launch, run /login inside Kimi Code CLI and choose either Kimi Code OAuth or a Moonshot AI Open Platform API key. After login, try your first task:

Take a look at this project and explain its main directories.

Key Features

  • Single-binary distribution. Install with one command: no Node.js setup, PATH gymnastics, or global module conflicts.
  • Blazing-fast startup. The TUI is ready in milliseconds, so starting a session never feels heavy.
  • Purpose-built TUI. A carefully tuned interface for long, focused agent sessions.
  • Video input. Drop a screen recording or demo clip into the chat, and let the agent watch what is hard to describe in words.
  • AI-native MCP configuration. Add, edit, and authenticate Model Context Protocol servers conversationally with /mcp-config, without hand-editing JSON.
  • Subagents for focused, parallel work. Dispatch built-in coder, explore, and plan subagents in isolated contexts while keeping the main conversation clean.
  • Lifecycle hooks. Run local commands at key points to gate risky tool calls, audit decisions, trigger desktop notifications, or connect to your own automation.

Docs

Develop

Requirements: Node.js ≥ 24.15.0, pnpm 10.33.0.

git clone https://github.com/MoonshotAI/kimi-code.git
cd kimi-code
pnpm install
pnpm dev:cli    # run the CLI in dev mode
pnpm test       # run tests
pnpm typecheck  # TypeScript check
pnpm lint       # oxlint
pnpm build      # build all packages

See CONTRIBUTING.md for the full contribution guide.

Community

Acknowledgements

Our TUI is built on top of pi-tui. We thank the authors of pi-tui for their valuable work.

License

Released under the MIT License.