Skip to content

refactor: rewrite from Python to Bun + TypeScript + React Ink#1707

Open
Yuandiaodiaodiao wants to merge 12 commits intoMoonshotAI:mainfrom
Yuandiaodiaodiao:worktree-bun-ts-refactor
Open

refactor: rewrite from Python to Bun + TypeScript + React Ink#1707
Yuandiaodiaodiao wants to merge 12 commits intoMoonshotAI:mainfrom
Yuandiaodiaodiao:worktree-bun-ts-refactor

Conversation

@Yuandiaodiaodiao
Copy link
Copy Markdown

@Yuandiaodiaodiao Yuandiaodiaodiao commented Apr 1, 2026

kimicli用python是彻底的失败 立刻重构为ts

Summary

  • Complete rewrite of kimi-cli from Python to Bun + TypeScript + React Ink TUI framework
  • Removes all Web UI code, focuses on terminal-native experience
  • Preserves the original directory structure for easy review and comparison

Key Changes

Before (Python) After (TypeScript)
Typer CLI Commander.js
Rich + prompt-toolkit React Ink (ink v6)
Pydantic validation Zod v4
asyncio async/await + Promises
kosong LLM @anthropic-ai/sdk, openai, @google/genai
KaosPath / kaos.exec Bun.file / Bun.spawn

Architecture Preserved

src/kimi_cli/
├── soul/          # Core agent loop (kimisoul, agent, context, toolset, compaction)
├── tools/         # All tool implementations (file, shell, web, think, plan, etc.)
├── wire/          # Wire protocol for UI↔Agent communication
├── ui/shell/      # React Ink TUI components
├── cli/           # CLI entry point and routing
├── config.ts      # Zod config schema + TOML loading
├── session.ts     # Session persistence
├── llm.ts         # Multi-provider LLM abstraction
├── hooks/         # Hook engine
└── utils/         # Logging, path, async utilities

Stats

  • 67 TypeScript files, 0 type errors
  • bun run src/kimi_cli/index.ts --help works

Test Plan

  • bun install succeeds
  • tsc --noEmit --skipLibCheck passes with 0 errors
  • bun run src/kimi_cli/index.ts --help shows CLI help
  • Configure a model in ~/.kimi/config.toml and test interactive chat

🤖 Generated with Claude Code


Open with Devin

Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Open in Devin Review

…act Ink

Complete rewrite of kimi-cli from Python (Typer + Rich + prompt-toolkit) to
Bun + TypeScript + React Ink TUI framework. Removes all web UI code.

Key changes:
- Runtime: Python → Bun (TypeScript)
- CLI framework: Typer → Commander.js
- TUI: Rich + prompt-toolkit → React Ink
- Validation: Pydantic → Zod v4
- LLM SDK: kosong → @anthropic-ai/sdk, openai, @google/genai
- File I/O: KaosPath → Bun.file / Bun.write
- Shell exec: kaos.exec → Bun.spawn

Architecture preserved with matching directory structure:
- soul/ — Core agent loop (kimisoul, agent, context, toolset, compaction)
- tools/ — All tool implementations (file, shell, web, think, plan, etc.)
- wire/ — Wire protocol for UI↔Agent communication
- ui/shell/ — React Ink TUI components
- cli/ — CLI entry point and routing
- config, session, hooks, auth, notifications, approval_runtime

67 TypeScript files, 0 type errors.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@Yuandiaodiaodiao Yuandiaodiaodiao force-pushed the worktree-bun-ts-refactor branch from 751b51b to 963d58d Compare April 1, 2026 14:22
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 751b51bc86

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +333 to +337
const stubProvider: LLMProvider = {
modelName: model.model,
async *chat(messages: Message[], chatOpts?: ChatOptions) {
throw new Error(
`LLM provider "${provider.type}" is not yet implemented in TypeScript. ` +
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P0 Badge Replace stubbed chat provider with real provider dispatch

createLLM always returns stubProvider, and chat() immediately throws for every configured provider type, so every turn fails as soon as the model is invoked. This makes the CLI unable to generate any assistant response even with valid provider/model config, which is a full functional regression.

Useful? React with 👍 / 👎.

Comment on lines +68 to +72
React.createElement(Shell, {
modelName: app.soul.modelName,
onSubmit: (input: string) => {
app.soul.run(input);
},
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Wire soul events into shell so the interactive UI can update

The shell is rendered with only onSubmit, which calls app.soul.run(...) directly, but no onWireReady/callback bridge is provided to feed useWire with turn/text/tool/approval events. As a result the message list does not reflect agent output, and approval-required tool calls can stall because the UI never receives/returns approval events.

Useful? React with 👍 / 👎.

Comment on lines +326 to +330
contentParts.push({
type: "tool_use",
id: tc.id,
name: tc.name,
input: JSON.parse(tc.arguments || "{}"),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Handle malformed tool-call JSON without aborting the turn

Tool call arguments are parsed with JSON.parse while assembling assistant context content, and parsing errors are not caught. If a model emits invalid JSON arguments (a common transient/tool-calling failure mode), the whole turn throws before tool execution reaches the existing argument-parse error handling in toolset.handle, causing avoidable turn termination.

Useful? React with 👍 / 👎.

Yuandiaodiaodiao and others added 2 commits April 1, 2026 22:54
Tests (35 files, 376 pass):
- tests/core/ — config, context, session, toolset, compaction, approval,
  slash commands, wire messages, llm, agentspec
- tests/tools/ — read, write, replace, glob, grep, shell, fetch, think,
  ask_user, todo, tool schemas
- tests/hooks/ — hook engine
- tests/utils/ — path, async, logging, result builder
- tests/ui/ — theme, slash commands, console, events, keyboard, print mode
- tests/e2e/ — CLI entry, basic e2e
- tests/background/ — background manager

CI:
- .github/workflows/ci-kimi-cli-ts.yml — typecheck, test, build binaries
  for linux-x64/arm64, darwin-x64/arm64, windows-x64
- Auto release on "release:" commit messages

Other:
- package.json build scripts for cross-platform binary compilation
- Restore docs/, examples/, scripts/, .github/, .agents/ from main
- Remove old Python CI workflows

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Replace stub provider with real OpenAI-compatible streaming implementation
- Supports Kimi API, OpenAI API, and any compatible endpoint
- SSE stream parsing with text, thinking/reasoning, and tool_call support
- Message format conversion (ContentPart → OpenAI messages)
- Fallback LLM creation from env vars: KIMI_BASE_URL, KIMI_API_KEY, KIMI_MODEL_NAME
- Default text output callbacks for print mode
- Tested with kimi-k2.5 via api.moonshot.cn

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1e67aa7e2f

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +62 to +65
if (options.print && prompt) {
// Non-interactive print mode
await app.runPrint(prompt);
} else {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Honor --print mode without requiring positional prompt

The --print flag is documented as non-interactive, but this branch only enters print mode when prompt is also present; kimi --print (or any future stdin-driven print flow) falls through to the interactive Ink shell instead. In automation/non-TTY contexts this causes unexpected hangs or UI startup failures instead of producing print output.

Useful? React with 👍 / 👎.

Comment on lines +99 to +102
const shellPath = process.env.SHELL || "/bin/bash";

const proc = Bun.spawn([shellPath, "-c", params.command], {
stdout: "pipe",
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Use a Windows-compatible shell fallback

When SHELL is unset, the tool hardcodes /bin/bash as the executable. On Windows, SHELL is commonly absent and /bin/bash usually does not exist, so Shell tool calls fail before running the requested command. Because this commit adds Windows binaries in CI, this breaks core tool functionality on that target.

Useful? React with 👍 / 👎.

Comment on lines +236 to +237
const dirFile = Bun.file(sessionsDir);
if (!(await dirFile.exists())) return [];
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Check session directory existence with dir-aware APIs

This uses Bun.file(sessionsDir).exists() to test whether the sessions directory exists, but Bun.file(...).exists() returns false for directories, so Session.list() returns [] even when sessions are present. That makes session discovery/listing logic silently fail for normal repositories.

Useful? React with 👍 / 👎.

- Add WelcomeBox with logo, directory, session, model, tip
- Rewrite StatusBar as separator line + status text (not box)
- Update Prompt with ✨ sparkles emoji
- Switch TOML parser from @iarna/toml to smol-toml (fixes key parsing)
- Pass workDir, sessionId, thinking to Shell component

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3732f9cdd7

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +333 to +337
switch (provider.type) {
case "kimi":
case "openai_legacy":
case "openai_responses":
llmProvider = new OpenAICompatibleProvider({
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Normalize OpenAI provider type in LLM dispatch

The provider switch only handles "openai_legacy"/"openai_responses", but config parsing allows "openai" and app.ts passes that value through. In that common configuration, createLLM falls into the default branch and returns a provider that throws on the first chat() call, so OpenAI-backed sessions fail at runtime despite valid config.

Useful? React with 👍 / 👎.

Comment on lines +252 to +256
async function registerBuiltinTools(toolset: KimiToolset): Promise<void> {
// Import and register all built-in tools
const toolModules = [
() => import("../tools/file/read.ts"),
() => import("../tools/file/write.ts"),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Load tools from agent spec instead of hardcoded list

Agent construction always registers a fixed module list here, so the tool set defined in agents/*/agent.yaml (including allow/exclude controls and declared tools like background/task/plan/Agent) is never applied. This disables configured agent behaviors and subagent/background workflows even though the specs exist in the repository.

Useful? React with 👍 / 👎.

Comment on lines +58 to +60
if (!dirPath.startsWith("/")) {
return ToolError(
`\`${params.directory}\` is not an absolute path. You must provide an absolute path to search.`,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Accept Windows absolute paths in Glob validation

The absolute-path check only accepts paths starting with /, so Windows drive-letter paths (for example C:\repo) are rejected as non-absolute. On Windows, ctx.workingDir itself uses that format, which makes normal Glob calls fail with the absolute-path error and effectively breaks the tool on that platform.

Useful? React with 👍 / 👎.

Comment on lines +239 to +241
const filePath = configFile ?? getConfigFile();
const dir = filePath.substring(0, filePath.lastIndexOf("/"));
await Bun.$`mkdir -p ${dir}`.quiet();
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Use path-aware parent dir handling in saveConfig

Parent directory extraction uses lastIndexOf("/"), which returns -1 for Windows paths with backslashes. When config is first created, this can produce an empty directory string and cause the mkdir -p step to fail before config.toml is written, breaking first-run setup on Windows.

Useful? React with 👍 / 👎.

Yuandiaodiaodiao and others added 3 commits April 1, 2026 23:34
- Interactive mode callbacks now push WireUIEvents to Shell component
  instead of writing directly to process.stdout
- Print mode (--print) still uses direct stdout for non-TUI output
- Fix chat history layout: messages display from top, not flex-end
- Remove default stdout fallback from app.ts soul callbacks

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Show filtered command list when user types '/'
- Menu renders below input, pushes up from bottom
- Up/Down arrows navigate, Enter selects, Tab auto-completes
- Hide status bar when slash menu is open
- Deduplicate commands (shell + soul)
- Fuzzy filter by command name and aliases

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove nested flex-grow Box that separated messages from input.
Now messages + input are in one flex column (flex-grow), content
flows from top with natural empty space below — matching Python layout.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 38cf997b7c

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

});

try {
const [response, feedback] = await this._runtime.waitForResponse(requestId);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Resolve approval requests before waiting for response

This call can block forever because there is no wiring in this commit that resolves user approvals back into ApprovalRuntime for normal tool flows. I checked the tree for ApprovalRuntime.resolve usage and only found the internal auto-approve branch in approval.ts, so with default yolo=false any tool that requests approval can stall the turn indefinitely while awaiting waitForResponse.

Useful? React with 👍 / 👎.

// ── WorkDir Metadata ────────────────────────────────────

function getSessionsBaseDir(workDir: string): string {
return join(getShareDir(), "sessions", workDir.replace(/\//g, "_").replace(/^_/, ""));
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Normalize Windows paths when building sessions base dir

getSessionsBaseDir only rewrites /, so Windows workdirs like C:\repo\proj retain backslashes and the drive-colon in the path segment. That produces invalid/unstable session directory paths on Windows, which breaks Session.create/find/list for those workdirs.

Useful? React with 👍 / 👎.

Comment on lines +122 to +125
// Background mode - stub for now
return builder.error(
"Background tasks are not yet implemented in this version.",
);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Implement or disable run_in_background in Shell tool

The tool schema and description explicitly promote run_in_background=true for long-running commands, but this branch returns an immediate error for every such call. That creates deterministic failures for long tasks the model is guided to run in background, instead of executing or scheduling them.

Useful? React with 👍 / 👎.

Yuandiaodiaodiao and others added 3 commits April 1, 2026 23:49
- ChatList: height = content (no flexGrow), grows as messages added
- InputBox: flexGrow=1, fills remaining space, text starts from top
- When no messages, input occupies entire middle area
- Top (WelcomeBox) and Bottom (StatusBar) stay fixed

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- InputBox: flexGrow=1 + flexShrink=1 + minHeight=6
  - Fills remaining space, shrinks as ChatList grows, min 6 lines
- ChatList: flexShrink=0 — never compressed, grows with content
- Root: minHeight instead of height — allows overflow + scroll
  when ChatList + InputBox exceed screen, WelcomeBox scrolls off top
- Input always rendered (even during streaming), shows 🔄 + steer hint
- Remove disabled input state — always interactive

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6e7cae1919

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +167 to +171
yolo: options.yolo,
sessionId: options.session,
maxStepsPerTurn: options.maxStepsPerTurn,
callbacks,
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Propagate --continue into interactive app creation

In interactive mode, KimiCLI.create(...) is called without continueSession, so kimi -C is silently ignored unless --print is also used. This breaks session resume behavior for the default shell workflow and causes users to start a fresh session unexpectedly even when they requested continuation.

Useful? React with 👍 / 👎.

Comment on lines +179 to +181
onSubmit: (input: string) => {
app.soul.run(input);
},
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Route streaming input to steer instead of dropping it

The shell prompt explicitly allows input while streaming, but onSubmit always calls app.soul.run(input). KimiSoul.run returns early when a turn is already running, so any mid-turn user guidance is discarded instead of being queued as steer input. In practice this makes in-flight correction/steering impossible during long tool runs.

Useful? React with 👍 / 👎.

Comment on lines +102 to +106
const approvalState = new ApprovalState({
yolo:
opts.config.default_yolo || opts.session.state.approval.yolo,
autoApproveActions: new Set(
opts.session.state.approval.auto_approve_actions,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Persist approval state changes back into session state

Approval settings are loaded from session.state.approval into a separate ApprovalState, but no change hook writes updates back to session.state. As a result, /yolo toggles and approve_for_session decisions are lost on shutdown/resume because Session.saveState() persists stale approval data.

Useful? React with 👍 / 👎.

…nhancements

Add new modules (auth platforms, subagents, background tasks, wire jsonrpc/root_hub),
enhance existing tools (plan mode, hooks, compaction, slash commands), and improve
shell UI components (approval/debug/question/replay/usage panels, task browser).
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 302656023c

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +160 to +164
const callbacks: SoulCallbacks = {
onTextDelta: (text) => process.stdout.write(text),
onThinkDelta: (text) => process.stderr.write(chalk.dim(text)),
onError: (err) =>
process.stderr.write(chalk.red(`[ERROR] ${err.message}\n`)),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Honor print mode formatting flags

In the --print branch, output is hardwired to raw text streaming callbacks, so --output-format stream-json and --final-message-only are never applied. This causes automation that relies on JSON lines or final-only output to receive the wrong format even when those flags are explicitly set.

Useful? React with 👍 / 👎.

Comment on lines +154 to +156
// Determine config source: --config-file takes precedence over legacy --config as path
const configFile = options.configFile ?? undefined;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Parse inline --config payload instead of ignoring it

The CLI accepts --config <string>, but this code only forwards options.configFile and never consumes options.config (nor calls loadConfigFromString). As a result, users providing inline TOML/JSON config get silently ignored settings.

Useful? React with 👍 / 👎.

Comment on lines +62 to +64
if (opts.maxStepsPerTurn) {
config.loop_control.max_steps_per_turn = opts.maxStepsPerTurn;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Apply max-retries override in app creation

CLI call sites pass maxRetriesPerStep, but KimiCLI.create only applies max_steps_per_turn and never updates loop_control.max_retries_per_step. This makes --max-retries-per-step a no-op, so retry behavior stays at config defaults regardless of user input.

Useful? React with 👍 / 👎.

Comment on lines +285 to +287
const file = Bun.file(path);
// Synchronous existence check is not available — use a simple approach
return file.size > 0 ? null : null; // Will be refined when plan tools exist
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Return actual plan content in /plan view

readCurrentPlan() unconditionally returns null because the ternary expression returns null in both branches. This makes /plan view report no plan even when the plan file exists and has content.

Useful? React with 👍 / 👎.

Bring back all non-kimi_cli files (CI workflows, packages, tests, web,
vis, klips, configs, etc.) that were removed during the bun-ts refactor.
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 94b7b71d07

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +99 to +102
const planTarget = inspectPlanEditTarget(resolvedPath, {
planModeChecker: this._planModeChecker ?? ctx.getPlanMode,
planFilePathGetter: this._planFilePathGetter,
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Pass current plan path into WriteFile plan-mode guard

When plan mode is active, inspectPlanEditTarget requires a plan file path, but this call only passes this._planFilePathGetter and does not fall back to runtime context. Because tool registration never calls bindPlanMode, that getter stays unset, so WriteFile returns the “plan file is unavailable” error for every plan-mode write and blocks the core plan workflow from progressing.

Useful? React with 👍 / 👎.

});

// 6. Load agent
const agent = await loadAgent({ runtime });
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Honor CLI agent selection when constructing the runtime agent

Agent loading is hardcoded to loadAgent({ runtime }), so runtime always uses the default agent spec. Since --agent and --agent-file are parsed in cli/index.ts but KimiCLI.create has no corresponding inputs to forward, those user-facing flags are effectively no-ops across print/wire/interactive modes.

Useful? React with 👍 / 👎.

Comment on lines +343 to +345
const gitFile = Bun.file(`${current}/.git`);
if (await gitFile.exists()) return current;
const parent = dirname(current);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Detect git roots with directory-aware filesystem checks

This root-detection logic relies on Bun.file(...).exists() for .git, but Bun reports false for directories, so standard repos with a .git/ directory are not recognized as project roots. The walk then falls back to workDir as root, which skips parent-scope AGENTS.md files and breaks the intended root-to-leaf instruction merge.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant