Skip to content
Open
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 src/kimi_cli/acp/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ async def _setup_session(
cli_instance = await KimiCLI.create(
session,
mcp_configs=[mcp_config],
resumed=True, # _setup_session loads existing sessions
)
config = cli_instance.soul.runtime.config
acp_kaos = ACPKaos(self.conn, session.id, self.client_capabilities)
Expand Down
13 changes: 13 additions & 0 deletions src/kimi_cli/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ async def create(
thinking: bool | None = None,
# Run mode
yolo: bool = False,
plan_mode: bool = False,
resumed: bool = False,
# Extensions
agent_file: Path | None = None,
mcp_configs: list[MCPConfig] | list[dict[str, Any]] | None = None,
Expand Down Expand Up @@ -171,6 +173,10 @@ async def create(
# determine yolo mode
yolo = yolo if yolo else config.default_yolo

# determine plan mode (only for new sessions, not restored)
if not resumed:
plan_mode = plan_mode if plan_mode else config.default_plan_mode

llm = create_llm(
provider,
model,
Expand Down Expand Up @@ -236,6 +242,13 @@ async def create(

soul = KimiSoul(agent, context=context)

# Activate plan mode if requested (for new sessions or --plan flag)
if plan_mode and not soul.plan_mode:
soul._set_plan_mode(True, source="manual") # type: ignore[reportPrivateUsage]
elif plan_mode and soul.plan_mode:
# Already in plan mode from restored session, trigger activation reminder
soul._pending_plan_activation_injection = True # type: ignore[reportPrivateUsage]

# Create and inject hook engine
from kimi_cli.hooks.engine import HookEngine

Expand Down
17 changes: 16 additions & 1 deletion src/kimi_cli/cli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,13 @@ def kimi(
help="Automatically approve all actions. Default: no.",
),
] = False,
plan: Annotated[
bool,
typer.Option(
"--plan",
help="Start in plan mode. Default: no.",
),
] = False,
prompt: Annotated[
str | None,
typer.Option(
Expand Down Expand Up @@ -502,6 +509,9 @@ async def _run(session_id: str | None) -> tuple[Session, int]:
try:
startup_progress.update("Preparing session...")

# Track if we're resuming an existing session (vs creating new)
resumed = False

if session_id is not None:
session = await Session.find(work_dir, session_id)
if session is None:
Expand All @@ -510,14 +520,17 @@ async def _run(session_id: str | None) -> tuple[Session, int]:
session_id=session_id,
)
session = await Session.create(work_dir, session_id)
logger.info("Switching to session: {session_id}", session_id=session.id)
else:
resumed = True # Session was actually found
logger.info("Switching to session: {session_id}", session_id=session.id)
elif continue_:
session = await Session.continue_(work_dir)
if session is None:
raise typer.BadParameter(
"No previous session found for the working directory",
param_hint="--continue",
)
resumed = True # Continuing previous session
logger.info("Continuing previous session: {session_id}", session_id=session.id)
else:
session = await Session.create(work_dir)
Expand Down Expand Up @@ -560,6 +573,8 @@ async def _run(session_id: str | None) -> tuple[Session, int]:
model_name=model_name,
thinking=thinking,
yolo=yolo or (ui == "print"), # print mode implies yolo
plan_mode=plan,
resumed=resumed,
agent_file=agent_file,
mcp_configs=mcp_configs,
skills_dirs=skills_dirs,
Expand Down
1 change: 1 addition & 0 deletions src/kimi_cli/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ class Config(BaseModel):
default_model: str = Field(default="", description="Default model to use")
default_thinking: bool = Field(default=False, description="Default thinking mode")
default_yolo: bool = Field(default=False, description="Default yolo (auto-approve) mode")
default_plan_mode: bool = Field(default=False, description="Default plan mode for new sessions")
default_editor: str = Field(
default="",
description="Default external editor command (e.g. 'vim', 'code --wait')",
Expand Down
6 changes: 4 additions & 2 deletions src/kimi_cli/web/runner/worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,16 @@ async def run_worker(session_id: UUID) -> None:

# Create KimiCLI instance with MCP configuration
try:
kimi_cli = await KimiCLI.create(session, mcp_configs=mcp_configs or None)
kimi_cli = await KimiCLI.create(
session, mcp_configs=mcp_configs or None, resumed=True
)
except MCPConfigError as exc:
logger.warning(
"Invalid MCP config in {path}: {error}. Starting without MCP.",
path=default_mcp_file,
error=exc,
)
kimi_cli = await KimiCLI.create(session, mcp_configs=None)
kimi_cli = await KimiCLI.create(session, mcp_configs=None, resumed=True)

# Run in wire stdio mode
await kimi_cli.run_wire_stdio()
Expand Down
1 change: 1 addition & 0 deletions tests/core/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ def test_default_config_dump():
"default_model": "",
"default_thinking": False,
"default_yolo": False,
"default_plan_mode": False,
"default_editor": "",
"theme": "dark",
"models": {},
Expand Down