run_repl 函数解析
run_repl 函数解析
位置: rust/crates/rusty-claude-cli/src/main.rs:4612-4678
run_repl 是 claw-code CLI 的交互式 REPL 主循环。它是用户在终端输入 claw(不带子命令)后进入的那个交互对话界面的核心入口。
函数签名
fn run_repl(
model: String,
allowed_tools: Option<AllowedToolSet>,
permission_mode: PermissionMode,
base_commit: Option<String>,
reasoning_effort: Option<String>,
allow_broad_cwd: bool,
) -> Result<(), Box<dyn std::error::Error>>
整体流程
run_repl()
├── 1. 启动前检查
│ ├── enforce_broad_cwd_policy() ← 安全策略
│ └── run_stale_base_preflight() ← 过期 base 警告
├── 2. 初始化
│ ├── resolve_repl_model() ← 解析模型名
│ ├── LiveCli::new() ← 创建 CLI 会话
│ ├── LineEditor::new() ← 创建行编辑器(Tab 补全)
│ ├── startup_banner() ← 打印横幅
│ └── format_connected_line() ← 打印模型连接信息
└── 3. 主循环
└── loop {
刷新补全 → 读输入 → 匹配处理
}
三个阶段
1. 启动前检查
enforce_broad_cwd_policy(allow_broad_cwd, CliOutputFormat::Text)?;
run_stale_base_preflight(base_commit.as_deref());
- 安全策略检查 (
enforce_broad_cwd_policy): 验证当前工作目录是否在允许范围内,防止访问敏感路径 - stale base 警告 (
run_stale_base_preflight): 如果--base参数引用的 commit 太旧,打印警告提示用户更新基准
2. 初始化
let resolved_model = resolve_repl_model(model);
let mut cli = LiveCli::new(resolved_model, true, allowed_tools, permission_mode)?;
let mut editor = LineEditor::new("> ", cli.repl_completion_candidates()?);
println!("{}", cli.startup_banner());
println!("{}", format_connected_line(&cli.model));
resolve_repl_model: 解析用户指定的模型名称(处理别名等)LiveCli::new: 创建核心 CLI 会话实例,封装了整个会话状态、runtime、工具权限等LineEditor::new: 创建带 Tab 补全 功能的行编辑器,提示符为>startup_banner+format_connected_line: 打印启动横幅和当前连接的模型信息
3. REPL 主循环
loop {
editor.set_completions(cli.repl_completion_candidates()?);
match editor.read_line()? {
// ...
}
}
每次迭代刷新补全候选列表,然后等待用户输入。editor.read_line() 返回三种结果:
| 结果 | 含义 | 行为 |
|---|---|---|
Submit(input) |
用户按了回车 | 按下述优先级匹配处理 |
Cancel |
Ctrl+C | 不做任何事,回到循环开头 |
Exit |
Ctrl+D | 持久化会话后退出循环 |
Submit 的匹配优先级(由高到低)
- 空输入 →
continue,跳过本轮 /exit//quit→ 调用cli.persist_session()持久化会话后break退出- 斜杠命令 →
SlashCommand::parse解析出 72 种命令,交给cli.handle_repl_command()处理。常用命令包括:/help— 帮助/model— 切换模型/compact— 压缩上下文/commit— 生成 commit/pr— 创建 PR/issue— 创建 Issue/clear— 清屏/cost— 查看费用/resume— 恢复会话/plugins— 管理插件/mcp— 管理 MCP 服务器/skills— 管理技能- ... 共 72 种
- 裸技能名 →
try_resolve_bare_skill_prompt检测首 token 是否匹配已安装的技能名:- 不以
/开头 - 纯字母数字+连字符(
a-z,0-9,-,_) - 匹配成功则包装为
/skills <input>调用,失败则走第 5 步
- 不以
- 普通文本 → 直接送给 LLM:
cli.run_turn(&trimmed)— 这是最主要的对话路径
每次成功提交后都会记录历史:
editor.push_history(input); // 行编辑器历史(上下键回溯)
cli.record_prompt_history(&trimmed); // 会话历史(/history 查看)
关键依赖
| 组件 | 位置 | 说明 |
|---|---|---|
LiveCli |
main.rs:4699 | 核心 CLI 会话,封装 runtime、工具、权限、会话管理 |
SlashCommand |
commands/src/lib.rs:1040 | 72 种斜杠命令的枚举定义和解析 |
LineEditor |
input 模块 | 带 Tab 补全和历史回溯的行编辑器 |
try_resolve_bare_skill_prompt |
main.rs:1446 | 裸技能名检测与调度 |
resolve_repl_model |
同文件 | 模型名解析(处理别名、默认值) |
enforce_broad_cwd_policy |
同文件 | 工作目录安全策略检查 |
run_stale_base_preflight |
main.rs:4601 | 过期 base commit 警告 |
总结
run_repl 是 claw-code 交互模式的核心事件循环:初始化会话 → 打印横幅 → 不断读取用户输入,区分退出(/exit/Ctrl+D)、斜杠命令(72 种 CLI 命令)、技能调度(裸技能名)、自然语言对话(送 LLM 处理)四种意图,分别路由到对应处理器。外层调用者只需关心返回的 Result<(), ...>,成功返回 Ok(()) 表示正常退出。

浙公网安备 33010602011771号