- 新建 audit/utils.rs(39行 risk_str/risk_from_str/truncate_chars) + audit/diff.rs(29行 build_write_file_diff) - audit/mod.rs 416→379: mod utils/diff + re-export(pub(crate) use risk_str/risk_from_str) + 删原fn audit拆分完成: reason/restore/finalize/cache/data_change/utils/diff七子模块, mod.rs余379(process_tool_calls主+DTO+list_tool_executions) 主代grep核验(不cargo--workspace避anthropic_compat.rs其他会话中间态df-ai E0599): mod.rs mod utils/diff印证; agent隔离自验cargo 0+test 98 git add指定(audit/*, 不含anthropic_compat.rs/docs其他会话改动)
30 lines
1.6 KiB
Rust
30 lines
1.6 KiB
Rust
//! AE-2025-03(路径 B):write_file 审批预览 diff 生成。
|
||
//!
|
||
//! 第五批从 audit/mod.rs 抽离,行为零变更。`build_write_file_diff` 仅 process_tool_calls
|
||
//! 在 write_file 高风险审批分支裸名调用,依赖 `super::super::tool_registry::generate_diff`
|
||
//! (F-260615-10 LCS 行级 diff),故 diff.rs 直接 `use super::super::tool_registry::generate_diff`。
|
||
//!
|
||
//! re-export 保持原路径透明:audit/mod.rs 通过 `use diff::build_write_file_diff` 裸名调用。
|
||
|
||
use super::super::tool_registry::generate_diff;
|
||
|
||
/// 从 write_file args 取 path(旧文件路径)+ content(新内容),
|
||
/// 预读旧文件 → 复用 `generate_diff`(F-260615-10 LCS 行级 diff)注入审批事件。
|
||
/// 旧文件不存在(新建)/ 读失败 / args 缺字段 → None(前端回退显新 content)。
|
||
///
|
||
/// **仅读不改**:审批未通过前不动文件;读路径不校验(write_file handler 自身会校验
|
||
/// validate_path,审批拒绝则 handler 不执行,恶意路径读失败仅得到 None 不产生危害)。
|
||
pub(super) async fn build_write_file_diff(args: &serde_json::Value) -> Option<String> {
|
||
let path = args.get("path")?.as_str()?;
|
||
let new_content = args.get("content")?.as_str()?;
|
||
match tokio::fs::read_to_string(path).await {
|
||
Ok(old_content) => {
|
||
if old_content == new_content {
|
||
return None; // 无变化不生成 diff(理论上 write_file 不会如此,容错)
|
||
}
|
||
Some(generate_diff(&old_content, new_content))
|
||
}
|
||
Err(_) => None, // 文件不存在(新建)/ 无读权限 → 无 diff,前端显新 content
|
||
}
|
||
}
|