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: Add `--add-dir` CLI option and `/add-dir` slash command to expand the workspace scope with additional directories — added directories are accessible to all file tools (read, write, glob, replace), persisted across sessions, and shown in the system prompt
- Shell: Add `Ctrl-O` keyboard shortcut to open the current input in an external editor (`$VISUAL`/`$EDITOR`), with auto-detection fallback to VS Code, Vim, Vi, or Nano
- Shell: Add `/editor` slash command to configure and switch the default external editor, with interactive selection and persistent config storage
- Shell: Add `/new` slash command to create and switch to a new session without restarting Kimi Code CLI
Expand Down
1 change: 1 addition & 0 deletions docs/en/configuration/data-locations.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ Session state file, stores the session's runtime state, including:

- `approval`: Approval decision state (YOLO mode on/off, auto-approved operation types)
- `dynamic_subagents`: Dynamically created subagent definitions
- `additional_dirs`: Additional workspace directories added via `--add-dir` or `/add-dir`

When resuming a session, Kimi Code CLI reads this file to restore the session state. This file uses atomic writes to prevent data corruption on crash.

Expand Down
9 changes: 5 additions & 4 deletions docs/en/customization/agents.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ The system prompt file is a Markdown template that can use `${VAR}` syntax to re
| `${KIMI_WORK_DIR_LS}` | Working directory file list |
| `${KIMI_AGENTS_MD}` | AGENTS.md file content (if exists) |
| `${KIMI_SKILLS}` | Loaded skills list |
| `${KIMI_ADDITIONAL_DIRS_INFO}` | Information about additional directories added via `--add-dir` or `/add-dir` |

You can also define custom parameters via `system_prompt_args`:

Expand Down Expand Up @@ -329,11 +330,11 @@ The following are all built-in tools in Kimi Code CLI.

## Tool security boundaries

**Working directory restrictions**
**Workspace scope**

- File reading and writing are typically done within the working directory
- Absolute paths are required when reading files outside the working directory
- Write and edit operations require user approval; absolute paths are required when operating on files outside the working directory
- File reading and writing are typically done within the working directory (and additional directories added via `--add-dir` or `/add-dir`)
- Absolute paths are required when reading files outside the workspace
- Write and edit operations require user approval; absolute paths are required when operating on files outside the workspace

**Approval mechanism**

Expand Down
3 changes: 2 additions & 1 deletion docs/en/guides/sessions.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ In addition to conversation history, Kimi Code CLI also automatically saves and

- **Approval decisions**: YOLO mode on/off status, operation types approved via "allow for this session"
- **Dynamic subagents**: Subagent definitions created via the `CreateSubagent` tool during the session
- **Additional directories**: Workspace directories added via `--add-dir` or `/add-dir`

This means you don't need to reconfigure these settings each time you resume a session. For example, if you approved auto-execution of certain shell commands in your previous session, those approvals remain in effect after resuming.

Expand Down Expand Up @@ -78,5 +79,5 @@ The bottom status bar displays the current context usage (`context: xx%`), helpi
:::

::: tip
`/clear` and `/reset` clear the conversation context but do not reset session state (such as approval decisions and dynamic subagents). To start completely fresh, it's recommended to create a new session.
`/clear` and `/reset` clear the conversation context but do not reset session state (such as approval decisions, dynamic subagents, and additional directories). To start completely fresh, it's recommended to create a new session.
:::
3 changes: 3 additions & 0 deletions docs/en/reference/kimi-command.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,12 @@ kimi [OPTIONS] COMMAND [ARGS]
| Option | Short | Description |
|--------|-------|-------------|
| `--work-dir PATH` | `-w` | Specify working directory (default current directory) |
| `--add-dir PATH` | | Add an additional directory to the workspace scope, can be specified multiple times |

The working directory determines the root directory for file operations. Relative paths work within the working directory; absolute paths are required to access files outside it.

`--add-dir` expands the workspace scope to include directories outside the working directory, making all file tools able to access files in those directories. Added directories are persisted with the session state. You can also add directories at runtime via the [`/add-dir`](./slash-commands.md#add-dir) slash command.

## Session management

| Option | Short | Description |
Expand Down
15 changes: 15 additions & 0 deletions docs/en/reference/slash-commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,21 @@ Flow skills can also be invoked via `/skill:<name>`, which loads the content as

See [Agent Skills](../customization/skills.md#flow-skills) for details.

## Workspace

### `/add-dir`

Add an additional directory to the workspace scope. Once added, the directory is accessible to all file tools (`ReadFile`, `WriteFile`, `Glob`, `Grep`, `StrReplaceFile`, etc.) and its directory listing is shown in the system prompt. Added directories are persisted with the session state and automatically restored when resuming.

Usage:

- `/add-dir <path>`: Add the specified directory to the workspace
- `/add-dir`: Without arguments, list already added additional directories

::: tip
Directories already within the working directory do not need to be added, as they are already accessible. You can also add directories at startup via the `--add-dir` option. See [`kimi` command](./kimi-command.md#working-directory) for details.
:::

## Others

### `/init`
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: Add `--add-dir` CLI option and `/add-dir` slash command to expand the workspace scope with additional directories — added directories are accessible to all file tools (read, write, glob, replace), persisted across sessions, and shown in the system prompt
- Shell: Add `Ctrl-O` keyboard shortcut to open the current input in an external editor (`$VISUAL`/`$EDITOR`), with auto-detection fallback to VS Code, Vim, Vi, or Nano
- Shell: Add `/editor` slash command to configure and switch the default external editor, with interactive selection and persistent config storage
- Shell: Add `/new` slash command to create and switch to a new session without restarting Kimi Code CLI
Expand Down
1 change: 1 addition & 0 deletions docs/zh/configuration/data-locations.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ Wire 消息记录文件,以 JSONL 格式存储会话中的 Wire 事件。用

- `approval`:审批决策状态(YOLO 模式开关、已自动批准的操作类型)
- `dynamic_subagents`:动态创建的子 Agent 定义
- `additional_dirs`:通过 `--add-dir` 或 `/add-dir` 添加的额外工作区目录

恢复会话时,Kimi Code CLI 会读取此文件还原会话状态。此文件使用原子写入,防止崩溃时数据损坏。

Expand Down
9 changes: 5 additions & 4 deletions docs/zh/customization/agents.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ agent:
| `${KIMI_WORK_DIR_LS}` | 工作目录文件列表 |
| `${KIMI_AGENTS_MD}` | AGENTS.md 文件内容(如果存在) |
| `${KIMI_SKILLS}` | 加载的 Skills 列表 |
| `${KIMI_ADDITIONAL_DIRS_INFO}` | 通过 `--add-dir` 或 `/add-dir` 添加的额外目录信息 |

你也可以通过 `system_prompt_args` 定义自定义参数:

Expand Down Expand Up @@ -329,11 +330,11 @@ agent:

## 工具安全边界

**工作目录限制**
**工作区范围**

- 文件读写通常在工作目录内进行
- 读取工作目录外文件需使用绝对路径
- 写入和编辑操作都需要用户审批;操作工作目录外文件时,必须使用绝对路径
- 文件读写通常在工作目录(及通过 `--add-dir` 或 `/add-dir` 添加的额外目录)内进行
- 读取工作区外文件需使用绝对路径
- 写入和编辑操作都需要用户审批;操作工作区外文件时,必须使用绝对路径

**审批机制**

Expand Down
3 changes: 2 additions & 1 deletion docs/zh/guides/sessions.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ kimi --session abc123

- **审批决策**:YOLO 模式的开关状态、通过 "本会话允许" 批准过的操作类型
- **动态子 Agent**:通过 `CreateSubagent` 工具在会话中创建的子 Agent 定义
- **额外目录**:通过 `--add-dir` 或 `/add-dir` 添加的工作区目录

这意味着你不需要在每次恢复会话时重新配置这些设置。例如,如果你在上次会话中批准了某类 Shell 命令的自动执行,恢复会话后这些批准仍然有效。

Expand Down Expand Up @@ -78,5 +79,5 @@ kimi --session abc123
:::

::: tip 提示
`/clear` 和 `/reset` 会清空对话上下文,但不会重置会话状态(如审批决策和动态子 Agent)。如需完全重新开始,建议创建一个新会话。
`/clear` 和 `/reset` 会清空对话上下文,但不会重置会话状态(如审批决策、动态子 Agent 和额外目录)。如需完全重新开始,建议创建一个新会话。
:::
3 changes: 3 additions & 0 deletions docs/zh/reference/kimi-command.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,12 @@ kimi [OPTIONS] COMMAND [ARGS]
| 选项 | 简写 | 说明 |
|------|------|------|
| `--work-dir PATH` | `-w` | 指定工作目录(默认当前目录) |
| `--add-dir PATH` | | 添加额外目录到工作区范围,可多次指定 |

工作目录决定了文件操作的根目录。在工作目录内可使用相对路径,操作工作目录外的文件需使用绝对路径。

`--add-dir` 可以将工作目录之外的目录纳入工作区范围,使所有文件工具可以访问该目录中的文件。添加的目录会随会话状态持久化。运行中也可以通过 [`/add-dir`](./slash-commands.md#add-dir) 斜杠命令添加。

## 会话管理

| 选项 | 简写 | 说明 |
Expand Down
15 changes: 15 additions & 0 deletions docs/zh/reference/slash-commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,21 @@ Flow Skill 也可以通过 `/skill:<name>` 调用,此时作为普通 Skill 加

详见 [Agent Skills](../customization/skills.md#flow-skills)。

## 工作区

### `/add-dir`

将额外目录添加到工作区范围。添加后,该目录对所有文件工具(`ReadFile`、`WriteFile`、`Glob`、`Grep`、`StrReplaceFile` 等)可用,并会在系统提示词中展示目录结构。添加的目录会随会话状态持久化,恢复会话时自动还原。

用法:

- `/add-dir <path>`:添加指定目录到工作区
- `/add-dir`:不带参数时列出已添加的额外目录

::: tip 提示
已在工作目录内的目录无需添加,因为它们已经可访问。也可以在启动时通过 `--add-dir` 参数添加,详见 [`kimi` 命令](./kimi-command.md#工作目录)。
:::

## 其他

### `/init`
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:新增 `--add-dir` CLI 选项和 `/add-dir` 斜杠命令,支持将额外目录添加到工作区范围——添加的目录可被所有文件工具(读取、写入、glob、替换)访问,跨会话持久化保存,并在系统提示词中展示
- Shell:新增 `Ctrl-O` 快捷键,在外部编辑器中编辑当前输入内容(`$VISUAL`/`$EDITOR`),支持自动检测 VS Code、Vim、Vi 或 Nano
- Shell:新增 `/editor` 斜杠命令,可交互式配置和切换默认外部编辑器,设置持久保存到配置文件
- Shell:新增 `/new` 斜杠命令,无需重启 Kimi Code CLI 即可创建并切换到新会话
Expand Down
8 changes: 8 additions & 0 deletions src/kimi_cli/agents/default/system.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,14 @@ ${KIMI_WORK_DIR_LS}
```

Use this as your basic understanding of the project structure.
{% if KIMI_ADDITIONAL_DIRS_INFO %}

## Additional Directories

The following directories have been added to the workspace. You can read, write, search, and glob files in these directories as part of your workspace scope.

${KIMI_ADDITIONAL_DIRS_INFO}
{% endif %}

# Project Information

Expand Down
36 changes: 36 additions & 0 deletions src/kimi_cli/cli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,20 @@ def kimi(
help="Working directory for the agent. Default: current directory.",
),
] = None,
local_add_dirs: Annotated[
list[Path] | None,
typer.Option(
"--add-dir",
exists=True,
file_okay=False,
dir_okay=True,
readable=True,
help=(
"Add an additional directory to the workspace scope. "
"Can be specified multiple times."
),
),
] = None,
session_id: Annotated[
str | None,
typer.Option(
Expand Down Expand Up @@ -485,6 +499,28 @@ async def _run(session_id: str | None) -> tuple[Session, bool]:
session = await Session.create(work_dir)
logger.info("Created new session: {session_id}", session_id=session.id)

# Add CLI-provided additional directories to session state
if local_add_dirs:
from kimi_cli.utils.path import is_within_directory

canonical_work_dir = work_dir.canonical()
changed = False
for d in local_add_dirs:
dir_path = KaosPath.unsafe_from_local_path(d).canonical()
dir_str = str(dir_path)
# Skip dirs within work_dir (already accessible)
if is_within_directory(dir_path, canonical_work_dir):
logger.info(
"Skipping --add-dir {dir}: already within working directory",
dir=dir_str,
)
continue
if dir_str not in session.state.additional_dirs:
session.state.additional_dirs.append(dir_str)
changed = True
if changed:
session.save_state()

instance = await KimiCLI.create(
session,
config=config,
Expand Down
1 change: 1 addition & 0 deletions src/kimi_cli/session_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class SessionState(BaseModel):
version: int = 1
approval: ApprovalStateData = Field(default_factory=ApprovalStateData)
dynamic_subagents: list[DynamicSubagentSpec] = Field(default_factory=_default_dynamic_subagents)
additional_dirs: list[str] = Field(default_factory=list)


def load_session_state(session_dir: Path) -> SessionState:
Expand Down
43 changes: 43 additions & 0 deletions src/kimi_cli/soul/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ class BuiltinSystemPromptArgs:
"""The content of AGENTS.md."""
KIMI_SKILLS: str
"""Formatted information about available skills."""
KIMI_ADDITIONAL_DIRS_INFO: str
"""Formatted information about additional directories in the workspace."""


async def load_agents_md(work_dir: KaosPath) -> str | None:
Expand Down Expand Up @@ -74,6 +76,7 @@ class Runtime:
labor_market: LaborMarket
environment: Environment
skills: dict[str, Skill]
additional_dirs: list[KaosPath]

@staticmethod
async def create(
Expand Down Expand Up @@ -104,6 +107,40 @@ async def create(
for skill in skills
)

# Restore additional directories from session state, pruning stale entries
additional_dirs: list[KaosPath] = []
pruned = False
valid_dir_strs: list[str] = []
for dir_str in session.state.additional_dirs:
d = KaosPath(dir_str).canonical()
if await d.is_dir():
additional_dirs.append(d)
valid_dir_strs.append(dir_str)
else:
logger.warning(
"Additional directory no longer exists, removing from state: {dir}",
dir=dir_str,
)
pruned = True
if pruned:
session.state.additional_dirs = valid_dir_strs
session.save_state()

# Format additional dirs info for system prompt
additional_dirs_info = ""
if additional_dirs:
parts: list[str] = []
for d in additional_dirs:
try:
dir_ls = await list_directory(d)
except OSError:
logger.warning(
"Cannot list additional directory, skipping listing: {dir}", dir=d
)
dir_ls = "[directory not readable]"
parts.append(f"### `{d}`\n\n```\n{dir_ls}\n```")
additional_dirs_info = "\n\n".join(parts)

# Merge CLI flag with persisted session state
effective_yolo = yolo or session.state.approval.yolo
saved_actions = set(session.state.approval.auto_approve_actions)
Expand All @@ -130,12 +167,14 @@ def _on_approval_change() -> None:
KIMI_WORK_DIR_LS=ls_output,
KIMI_AGENTS_MD=agents_md or "",
KIMI_SKILLS=skills_formatted or "No skills found.",
KIMI_ADDITIONAL_DIRS_INFO=additional_dirs_info,
),
denwa_renji=DenwaRenji(),
approval=Approval(state=approval_state),
labor_market=LaborMarket(),
environment=environment,
skills=skills_by_name,
additional_dirs=additional_dirs,
)

def copy_for_fixed_subagent(self) -> Runtime:
Expand All @@ -151,6 +190,8 @@ def copy_for_fixed_subagent(self) -> Runtime:
labor_market=LaborMarket(), # fixed subagent has its own LaborMarket
environment=self.environment,
skills=self.skills,
# Share the same list reference so /add-dir mutations propagate to all agents
additional_dirs=self.additional_dirs,
)

def copy_for_dynamic_subagent(self) -> Runtime:
Expand All @@ -166,6 +207,8 @@ def copy_for_dynamic_subagent(self) -> Runtime:
labor_market=self.labor_market, # dynamic subagent shares LaborMarket with main agent
environment=self.environment,
skills=self.skills,
# Share the same list reference so /add-dir mutations propagate to all agents
additional_dirs=self.additional_dirs,
)


Expand Down
Loading
Loading