Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Only write entries that are worth mentioning to users.

## Unreleased

- Core: Fix MCP server stderr pollution — stderr redirection is now installed before MCP servers start, so subprocess logs (e.g., OAuth debug output from `mcp-remote`) are captured into the log file instead of being printed to the terminal
- Shell: Fix subprocess hang on interactive prompts — the `Shell` tool now closes stdin immediately and sets `GIT_TERMINAL_PROMPT=0` so commands that require credentials (e.g. `git push` over HTTPS) fail fast instead of blocking until timeout
- Core: Fix JSON parsing error when LLM tool call arguments contain unescaped control characters — use `json.loads(strict=False)` across all LLM output parsing paths to prevent tool execution failure and session corruption
- Shell: Auto-trigger agent when background tasks complete while idle — the shell now detects when a background bash command or agent task finishes and automatically starts a new agent turn to process the results, instead of waiting for the user to type something
Expand Down
1 change: 1 addition & 0 deletions docs/en/release-notes/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ This page documents the changes in each Kimi Code CLI release.

## Unreleased

- Core: Fix MCP server stderr pollution — stderr redirection is now installed before MCP servers start, so subprocess logs (e.g., OAuth debug output from `mcp-remote`) are captured into the log file instead of being printed to the terminal
- Shell: Fix subprocess hang on interactive prompts — the `Shell` tool now closes stdin immediately and sets `GIT_TERMINAL_PROMPT=0` so commands that require credentials (e.g. `git push` over HTTPS) fail fast instead of blocking until timeout
- Core: Fix JSON parsing error when LLM tool call arguments contain unescaped control characters — use `json.loads(strict=False)` across all LLM output parsing paths to prevent tool execution failure and session corruption
- Shell: Auto-trigger agent when background tasks complete while idle — the shell now detects when a background bash command or agent task finishes and automatically starts a new agent turn to process the results, instead of waiting for the user to type something
Expand Down
1 change: 1 addition & 0 deletions docs/zh/release-notes/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

## 未发布

- Core:修复 MCP 服务器 stderr 污染问题——stderr 重定向现在在 MCP 服务器启动前安装,子进程日志(如 `mcp-remote` 的 OAuth 调试输出)将被捕获到日志文件,而非输出到终端
- Shell:修复子进程遇到交互式提示时挂起的问题——`Shell` 工具现在会立即关闭 stdin 并设置 `GIT_TERMINAL_PROMPT=0`,使需要凭证的命令(如通过 HTTPS 执行 `git push`)快速失败,而非阻塞至超时
- Core:修复 LLM 工具调用参数包含未转义控制字符时 JSON 解析失败的问题——在所有 LLM 输出解析路径使用 `json.loads(strict=False)`,防止工具执行失败和会话永久损坏
- Shell:空闲时自动响应后台任务完成——Shell 现在会检测后台 Bash 命令或 Agent 任务的完成,并自动发起新的 Agent 轮次处理结果,无需等待用户输入
Expand Down
20 changes: 13 additions & 7 deletions src/kimi_cli/cli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -337,9 +337,10 @@ def kimi(

from .mcp import get_global_mcp_config_file

# Don't redirect stderr yet. Our stderr redirector replaces fd=2 with a pipe, which
# would swallow Click/Typer startup errors (e.g. config parsing / BadParameter).
# We re-enable stderr redirection after KimiCLI.create() succeeds.
# Don't redirect stderr during argument parsing. Our stderr redirector
# replaces fd=2 with a pipe, which would swallow Click/Typer startup errors.
# Redirection is installed later, right before KimiCLI.create(), so that
# MCP server stderr noise is captured into logs from the start.
enable_logging(debug, redirect_stderr=False)

def _emit_fatal_error(message: str) -> None:
Expand Down Expand Up @@ -526,6 +527,15 @@ async def _run(session_id: str | None) -> tuple[Session, bool]:
if changed:
session.save_state()

# Redirect stderr *before* KimiCLI.create() so that MCP server
# subprocesses (e.g. mcp-remote OAuth debug logs) write to the log
# file instead of polluting the user's terminal. CLI argument
# parsing has already succeeded at this point, so Typer/Click
# startup errors are no longer a concern. Fatal errors from
# create() are still visible because _emit_fatal_error() writes to
# the saved original stderr fd.
redirect_stderr_to_logger()

instance = await KimiCLI.create(
session,
config=config,
Expand All @@ -542,10 +552,6 @@ async def _run(session_id: str | None) -> tuple[Session, bool]:
defer_mcp_loading=ui == "shell" and prompt is None,
)
startup_progress.stop()

# Install stderr redirection only after initialization succeeded, so runtime
# stderr noise is captured into logs without hiding startup failures.
redirect_stderr_to_logger()
preserve_background_tasks = False
try:
match ui:
Expand Down
Loading