Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
0eb6f93
feat: add /export and /import commands for session context management
RealKai42 Mar 3, 2026
82470e0
Merge branch 'main' into kaiyi/export-import-cmd
RealKai42 Mar 3, 2026
1c2fdc6
docs: update docs
RealKai42 Mar 3, 2026
a4d41a5
feat: enhance import/export commands with directory error handling an…
RealKai42 Mar 3, 2026
f8a65ce
Merge branch 'main' into kaiyi/export-import-cmd
RealKai42 Mar 3, 2026
31381bf
Merge branch 'main' into kaiyi/export-import-cmd
RealKai42 Mar 3, 2026
8fa9402
feat: refactor export/import commands for improved error handling and…
RealKai42 Mar 3, 2026
c1a3853
refactor: rename export and import helper functions for clarity
RealKai42 Mar 3, 2026
988af95
feat: add wire markers for session replay during context import
RealKai42 Mar 3, 2026
bde82b9
feat: add file size limit for import and corresponding error handling…
RealKai42 Mar 3, 2026
1d2b878
feat: add test for handling oversized session content in resolve_impo…
RealKai42 Mar 3, 2026
0c69bab
feat: update export output display to use shortened home path and adj…
RealKai42 Mar 3, 2026
f48098a
feat: add warnings for sensitive information in export and import pro…
RealKai42 Mar 3, 2026
5995252
feat: update .env file handling to check filename instead of extensio…
RealKai42 Mar 3, 2026
16cbc6f
feat: add is_sensitive_file utility to identify sensitive filenames a…
RealKai42 Mar 3, 2026
f3b2bec
feat: remove unused wire markers in import context and update related…
RealKai42 Mar 3, 2026
c5219c1
feat: add file type check for sensitive file warnings in import context
RealKai42 Mar 3, 2026
8c2430f
Merge branch 'main' into kaiyi/export-import-cmd
RealKai42 Mar 3, 2026
a4d333e
feat: integrate estimate_text_tokens for accurate token counting in i…
RealKai42 Mar 3, 2026
9d24c0f
feat: support relative paths in perform_export and resolve_import_sou…
RealKai42 Mar 3, 2026
79c87d2
feat: refactor import functionality to use perform_import and enhance…
RealKai42 Mar 3, 2026
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 `/export` command to export current session context (messages, metadata) to a Markdown file, and `/import` command to import context from a file or another session ID into the current session
- Shell: Show token counts (used/total) alongside context usage percentage in the status bar (e.g., `context: 42.0% (4.2k/10.0k)`)
- Shell: Rotate keyboard shortcut tips in the toolbar — tips cycle through available shortcuts on each prompt submission to save horizontal space
- MCP: Add loading indicators for MCP server connections — Shell displays a "Connecting to MCP servers..." spinner and Web shows a status message while MCP tools are being loaded
Expand Down
33 changes: 33 additions & 0 deletions docs/en/guides/sessions.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,39 @@ In addition to conversation history, Kimi Code CLI also automatically saves and

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.

## Export and import

Kimi Code CLI supports exporting session context to a file, or importing context from external files and other sessions.

**Export a session**

Enter `/export` to export the current session's complete conversation history as a Markdown file:

```
/export
```

The exported file includes session metadata, a conversation overview, and the complete conversation organized by turns. You can also specify an output path:

```
/export ~/exports/my-session.md
```

**Import context**

Enter `/import` to import context from a file or another session. The imported content is appended as reference information to the current session:

```
/import ./previous-session-export.md
/import abc12345
```

Common text-based file formats are supported (Markdown, source code, configuration files, etc.). You can also pass a session ID to import the complete conversation history from that session.

::: tip
Exported files may contain sensitive information (such as code snippets, file paths, etc.). Please review before sharing.
:::

## Clear and compact

As the conversation progresses, the context grows longer. Kimi Code CLI will automatically compress the context when needed to ensure the conversation can continue.
Expand Down
25 changes: 24 additions & 1 deletion docs/en/reference/slash-commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Slash commands are built-in commands for Kimi Code CLI, used to control sessions, configuration, and debugging. Enter a command starting with `/` in the input box to trigger.

::: tip Shell mode
Some slash commands are also available in shell mode, including `/help`, `/exit`, `/version`, `/editor`, `/changelog`, and `/feedback`.
Some slash commands are also available in shell mode, including `/help`, `/exit`, `/version`, `/editor`, `/changelog`, `/feedback`, `/export`, and `/import`.
:::

## Help and info
Expand Down Expand Up @@ -110,6 +110,29 @@ Alias: `/resume`

Use arrow keys to select a session, press `Enter` to confirm switch, press `Ctrl-C` to cancel.

### `/export`

Export the current session context to a Markdown file for archiving or sharing.

Usage:

- `/export`: Export to the current working directory with an auto-generated filename (format: `kimi-export-<first 8 chars of session ID>-<timestamp>.md`)
- `/export <path>`: Export to the specified path. If the path is a directory, the filename is auto-generated; if it is a file path, the content is written directly to that file

The exported file includes:
- Session metadata (session ID, export time, working directory, message count, token count)
- Conversation overview (topic, number of turns, tool call count)
- Complete conversation history organized by turns, including user messages, AI responses, tool calls, and tool results

### `/import`

Import context from a file or another session into the current session. The imported content is appended as reference context, and the AI can use this information to inform subsequent interactions.

Usage:

- `/import <file_path>`: Import from a file. Supports common text-based formats such as Markdown, plain text, source code, and configuration files; binary files (e.g., images, PDFs, archives) are not supported
- `/import <session_id>`: Import from the specified session ID. Cannot import the current session into itself

### `/clear`

Clear the current session's context and start a new conversation.
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 `/export` command to export current session context (messages, metadata) to a Markdown file, and `/import` command to import context from a file or another session ID into the current session
- Shell: Show token counts (used/total) alongside context usage percentage in the status bar (e.g., `context: 42.0% (4.2k/10.0k)`)
- Shell: Rotate keyboard shortcut tips in the toolbar — tips cycle through available shortcuts on each prompt submission to save horizontal space
- MCP: Add loading indicators for MCP server connections — Shell displays a "Connecting to MCP servers..." spinner and Web shows a status message while MCP tools are being loaded
Expand Down
33 changes: 33 additions & 0 deletions docs/zh/guides/sessions.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,39 @@ kimi --session abc123

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

## 导出与导入

Kimi Code CLI 支持将会话上下文导出为文件,或从外部文件和其他会话导入上下文。

**导出会话**

输入 `/export` 可以将当前会话的完整对话历史导出为 Markdown 文件:

```
/export
```

导出文件包含会话元数据、对话概览和按轮次组织的完整对话记录。你也可以指定输出路径:

```
/export ~/exports/my-session.md
```

**导入上下文**

输入 `/import` 可以从文件或其他会话导入上下文。导入的内容会作为参考信息附加到当前会话中:

```
/import ./previous-session-export.md
/import abc12345
```

支持导入常见的文本格式文件(Markdown、代码、配置文件等)。你也可以传入一个会话 ID,从该会话导入完整的对话历史。

::: tip 提示
导出文件可能包含敏感信息(如代码片段、文件路径等),分享前请注意检查。
:::

## 清空与压缩

随着对话的进行,上下文会越来越长。Kimi Code CLI 会在需要的时候自动对上下文进行压缩,确保对话能够继续。
Expand Down
25 changes: 24 additions & 1 deletion docs/zh/reference/slash-commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
斜杠命令是 Kimi Code CLI 的内置命令,用于控制会话、配置和调试。在输入框中输入 `/` 开头的命令即可触发。

::: tip Shell 模式
部分斜杠命令在 Shell 模式下也可以使用,包括 `/help`、`/exit`、`/version`、`/editor`、`/changelog` 和 `/feedback`。
部分斜杠命令在 Shell 模式下也可以使用,包括 `/help`、`/exit`、`/version`、`/editor`、`/changelog`、`/feedback`、`/export` 和 `/import`。
:::

## 帮助与信息
Expand Down Expand Up @@ -110,6 +110,29 @@

使用方向键选择会话,按 `Enter` 确认切换,按 `Ctrl-C` 取消。

### `/export`

将当前会话的上下文导出为 Markdown 文件,方便归档或分享。

用法:

- `/export`:导出到当前工作目录,文件名自动生成(格式为 `kimi-export-<会话ID前8位>-<时间戳>.md`)
- `/export <path>`:导出到指定路径。如果路径是目录,文件名会自动生成;如果是文件路径,则直接写入该文件

导出文件包含:
- 会话元数据(会话 ID、导出时间、工作目录、消息数、token 数)
- 对话概览(主题、轮次数、工具调用次数)
- 完整的对话历史,按轮次组织,包括用户消息、AI 回复、工具调用和工具结果

### `/import`

从文件或其他会话导入上下文到当前会话。导入的内容会作为参考上下文附加到当前对话中,AI 可以利用这些信息来辅助后续的交互。

用法:

- `/import <file_path>`:从文件导入。支持 Markdown、文本、代码、配置文件等常见文本格式;不支持二进制文件(如图片、PDF、压缩包)
- `/import <session_id>`:从指定会话 ID 导入。不能导入当前会话自身

### `/clear`

清空当前会话的上下文,开始新的对话。
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:新增 `/export` 命令,支持将当前会话上下文(消息、元数据)导出为 Markdown 文件;新增 `/import` 命令,支持从文件或其他会话 ID 导入上下文到当前会话
- Shell:在状态栏上下文用量旁显示 Token 数量(已用/总量),如 `context: 42.0% (4.2k/10.0k)`
- Shell:工具栏快捷键提示改为轮转显示——每次提交后循环展示不同快捷键提示,节省横向空间
- MCP:为 MCP 服务器连接添加加载指示器——Shell 在连接 MCP 服务器时显示 "Connecting to MCP servers..." 加载动画,Web 在 MCP 工具加载期间显示状态消息
Expand Down
6 changes: 3 additions & 3 deletions src/kimi_cli/soul/compaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,13 @@ def estimated_token_count(self) -> int:
"""
if self.usage is not None and len(self.messages) > 0:
summary_tokens = self.usage.output
preserved_tokens = _estimate_text_tokens(self.messages[1:])
preserved_tokens = estimate_text_tokens(self.messages[1:])
return summary_tokens + preserved_tokens

return _estimate_text_tokens(self.messages)
return estimate_text_tokens(self.messages)


def _estimate_text_tokens(messages: Sequence[Message]) -> int:
def estimate_text_tokens(messages: Sequence[Message]) -> int:
"""Estimate tokens from message text content using a character-based heuristic."""
total_chars = 0
for msg in messages:
Expand Down
74 changes: 73 additions & 1 deletion src/kimi_cli/soul/slash.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from pathlib import Path
from typing import TYPE_CHECKING

from kaos.path import KaosPath
from kosong.message import Message
from loguru import logger

Expand All @@ -13,6 +14,8 @@
from kimi_cli.soul.agent import load_agents_md
from kimi_cli.soul.context import Context
from kimi_cli.soul.message import system
from kimi_cli.utils.export import is_sensitive_file
from kimi_cli.utils.path import sanitize_cli_path, shorten_home
from kimi_cli.utils.slashcmd import SlashCommandRegistry
from kimi_cli.wire.types import StatusUpdate, TextPart

Expand Down Expand Up @@ -103,7 +106,7 @@ async def add_dir(soul: KimiSoul, args: str):

from kimi_cli.utils.path import is_within_directory, list_directory

args = args.strip()
args = sanitize_cli_path(args)
if not args:
if not soul.runtime.additional_dirs:
wire_send(TextPart(text="No additional directories. Usage: /add-dir <path>"))
Expand Down Expand Up @@ -169,3 +172,72 @@ async def add_dir(soul: KimiSoul, args: str):

wire_send(TextPart(text=f"Added directory to workspace: {path}"))
logger.info("Added additional directory: {path}", path=path)


@registry.command
async def export(soul: KimiSoul, args: str):
"""Export current session context to a markdown file"""
from kimi_cli.utils.export import perform_export

session = soul.runtime.session
result = await perform_export(
history=list(soul.context.history),
session_id=session.id,
work_dir=str(session.work_dir),
token_count=soul.context.token_count,
args=args,
default_dir=Path(str(session.work_dir)),
)
if isinstance(result, str):
wire_send(TextPart(text=result))
return
output, count = result
display = shorten_home(KaosPath(str(output)))
wire_send(TextPart(text=f"Exported {count} messages to {display}"))
wire_send(
TextPart(
text=" Note: The exported file may contain sensitive information. "
"Please be cautious when sharing it externally."
)
)


@registry.command(name="import")
async def import_context(soul: KimiSoul, args: str):
"""Import context from a file or session ID"""
from kimi_cli.utils.export import perform_import

target = sanitize_cli_path(args)
if not target:
wire_send(TextPart(text="Usage: /import <file_path or session_id>"))
return

session = soul.runtime.session
raw_max_context_size = (
soul.runtime.llm.max_context_size if soul.runtime.llm is not None else None
)
max_context_size = (
raw_max_context_size
if isinstance(raw_max_context_size, int) and raw_max_context_size > 0
else None
)
result = await perform_import(
target=target,
current_session_id=session.id,
work_dir=session.work_dir,
context=soul.context,
max_context_size=max_context_size,
)
if isinstance(result, str):
wire_send(TextPart(text=result))
return

source_desc, content_len = result
wire_send(TextPart(text=f"Imported context from {source_desc} ({content_len} chars)."))
Comment on lines +235 to +236
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Soul-level /import handler missing wire_file writes, breaking session replay

The shell-level /import handler in export_import.py:97-101 explicitly writes TurnBegin and TurnEnd to soul.wire_file so the import appears in session replay. However, the soul-level /import handler in soul/slash.py:205-243 does not write to wire_file. When /import is invoked through the wire protocol (non-shell UIs), the import action will not be recorded in the session's wire file and won't appear during session replay.

Root Cause

The shell handler at src/kimi_cli/ui/shell/export_import.py:97-101 writes wire markers:

await soul.wire_file.append_message(
    TurnBegin(user_input=f"[Imported context from {source_desc}]")
)
await soul.wire_file.append_message(TurnEnd())

But the soul-level handler at src/kimi_cli/soul/slash.py:205-243 only uses wire_send() (which sends events over the live wire protocol) and never writes to wire_file (which persists events for session replay). KimiSoul.run() at src/kimi_cli/soul/kimisoul.py:241 does call wire_send(TurnBegin(...)) but this only sends events to the wire transport — it does not write to the wire_file for replay.

Impact: When using /import in wire mode (or any non-shell UI), the import won't be visible if the session is later replayed or resumed.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

if source_desc.startswith("file") and is_sensitive_file(Path(target).name):
wire_send(
TextPart(
text="Warning: This file may contain secrets (API keys, tokens, credentials). "
"The content is now part of your session context."
)
)
Loading
Loading