ClawX 恢复 ACP Chat 中的 OpenClaw 文件活动:write/edit/apply_patch 工具调用的安全投影与渲染实践 人工智能AI 应用桌面应用交互助手【免费下载链接】ClawXClawX is a desktop app that provides a graphical interface for OpenClaw AI agents. It turns CLI-based AI orchestration into a desktop experience without using the terminal. China website is https://clawx.com.cn.项目地址https://gitcode.com/gh_mirrors/cl/ClawX点击查看免费下载导读本文聚焦 ClawXOpenClaw AI Agent 的桌面图形化客户端中restore-acp-file-activity这一运行时桥接任务的完整设计与实现如何在 ACP Chat 时间线之上把 OpenClaw Agent 成功执行的write、edit、apply_patch工具调用还原为逐轮次per-turn的文件按钮、变更摘要与会话级session-levelChanges 面板。你会了解到这套纯渲染层投影的数据模型、三种工具输入的规范语法Canonical Inputs、工作区绑定workspace-scoped的路径安全模型以及它与附件Attachments管线的严格边界最终掌握该功能在 openclaw-file-activities.ts 中的核心实现原理与测试验证锚点。一、任务背景从hydration 设计到纯投影设计restore-acp-file-activity是 harness/specs/tasks/restore-acp-file-activity.md 中定义的一项runtime-bridge类型任务隶属于gateway-backend-communication场景。其意图intent非常明确Restore per-turn and session-level OpenClaw file activity in ACP Chat while keeping tool-derived file access inside the bound workspace.即在 ACP Chat 中恢复逐轮次与会话级的 OpenClaw 文件活动同时保证由工具派生的文件访问始终被约束在已绑定的工作区内。任务名称中的 restore 对应参考文档 harness/reference/openclaw-file-activity.md 末尾的一句关键说明This reference replaces the former OpenClaw file activity hydration design while retaining its protocol grammar, security model, and aggregation semantics.也就是说本任务是替代旧的hydration水合设计——旧方案试图把文件活动物化出来而新方案改为纯渲染层投影pure Renderer projection文件活动不是持久化的数据、不是磁盘差异记录而是 Renderer 基于当前 ACP 时间线实时计算出来的视图。协议语法、安全模型与聚合语义则原样保留。从源码结构看这一设计的落地范围横跨渲染层、主进程与共享契约投影算法src/lib/acp/openclaw-file-activities.ts本任务的核心实现也是权威类型定义处时间线分组src/lib/acp/timeline-groups.ts主进程工作区文件 APIelectron/services/files-api.tsHost API 契约shared/host-api/contract.tsWorkspaceFileRef等类型UI 组件src/pages/Chat/AcpTurnFileActivity.tsx、src/pages/Chat/AcpFileCard.tsx测试锚点tests/unit/openclaw-file-activities.test.ts、tests/e2e/chat-file-changes.spec.ts二、语义边界文件活动是什么、不是什么参考文档 harness/reference/openclaw-file-activity.md 开宗明义地划定了语义边界文件活动是由成功的 OpenClaw 文件编辑类工具调用所声明的文件变更记录是活跃 ACP 时间线的纯渲染层投影。文件活动不是Git diff、经过磁盘验证的差异、或会话开始时的基线快照。与之配套的非目标negative scope约束同样严格。ClawX不会扫描或监听工作区no workspace scanning/watching创建快照no snapshots推断 shell/脚本副作用no inferred shell side effects解析任意自然语言文本来猜测文件操作no arbitrary prose parsing调用sessions.files.list来人为制造差异no manufactured diffs持久化一份独立的活动账本no persisted activity ledger。主进程Main不解释工具语义只执行工作区作用域内的 read/stat 以及明确的原生文件操作。这一点在 tool-derived-file-safety.md 规则中被进一步固化File activity remains a record of completed canonical OpenClawwrite,edit, andapply_patchinputs. It must not claim to be a verified disk or Git diff, scan the workspace, infer shell effects, or persist a separate ledger.同时支持的工具恰好是write、edit、apply_patch三种这一判定规则也有明确的实现依据。在 openclaw-file-activities.ts 中parseToolName会截取 ACP 工具 title 中第一个冒号之前的部分做 trim 小写归一化只有精确等于三种受支持名称才被接受function parseToolName(title: string): OpenClawFileToolName | null { const colon title.indexOf(:); if (colon 0) return null; const name title.slice(0, colon).trim().toLowerCase(); return name write || name edit || name apply_patch ? name : null; }单元测试 tests/unit/openclaw-file-activities.test.ts 中 normalizes exact title prefixes and rejects unsupported or malformed near-matches 用例验证了这一点 EdIt : b、APPLY_PATCH: c会被归一化后接受而WriteFile: x、rewrite: x、exec: x、write file: x这类近似匹配全部被拒绝。状态方面只有completed状态的调用才产生活动pending、running、failed、cancelled以及格式异常的调用仍然作为普通工具卡片展示但不会产生任何文件活动 UI。三、Canonical Inputs三种工具输入的规范语法文件活动的产出完全由工具调用的**原始输入canonical raw input**驱动。参考文档对三种工具的字段解析规则做了精确约定源码parseWrite/parseEdit/parseApplyPatch与之一一对应。3.1 write路径别名优先级与空到新片段write与edit共用的路径字段优先级为path→file_path→filePath→file见readPath实现。write接受字符串content投影为一个空到新empty-to-new片段动作记为created。需要特别说明created描述的是工具意图并不断言该文件此前一定不存在。如果只有合法路径而没有字符串 content则产生一条仅有路径的记录其行数统计标记为不可用unavailable而不是臆造为 0。function parseWrite(input: Recordstring, unknown, context: PathContext): ParsedActivity[] { const candidate readPath(input); if (!candidate) return []; const relativePath resolveToolPath(candidate, context); if (!relativePath) return []; const fragments typeof input.content string ? [{ oldText: , newText: input.content }] : []; return [{ relativePath, action: created, fragments }]; }对应测试 uses canonical path alias precedence and retains path-only Writes 确认当四个字段同时存在时只采用path且 path-only 记录的added/removed为null。3.2 editedits 数组 顶层兼容形状拒绝宽泛别名edit接受两种形态规范形态edits: Array{ oldText, newText }官方兼容形态顶层直接给出oldText/newText。两类都会解析数组中的非法条目缺少字符串类型的oldText/newText会被跳过刻意不支持old_string、new_string这类宽泛别名。实现见validEditFragment与parseEdit先展平edits数组再把顶层的oldText/newText作为一条追加片段。测试 accepts only canonical array and top-level Edit pairs and skips invalid entries 展示了一个典型输入edits数组含三条合法、缺 newText、空对空外加顶层旧新文本最终产生三条片段——说明缺 newText 的条目被静默跳过空对空条目oldText: 与newText: 均为字符串则被保留。3.3 apply_patch信封、包裹器、Hunk 语法与原子性失败apply_patch是语法最复杂的工具解析器parseApplyPatch/parsePatch/parsePatchHunk/parseUpdateChunk实现了 OpenClaw patch 信封的完整文法信封必须以*** Begin Patch开头、*** End Patch结尾可选包裹器为EOF、EOF、EOF首行出现包裹器时末行必须以EOF结尾并整行剥除见unwrapAndValidatePatch。支持的节sections*** Add File: path前缀行作为内容、*** Update File: path、*** Delete File: path以及 Update 之后可紧跟的*** Move to: path。Update 块语法上下文行用空格前缀同时计入 old/new 两侧-行只进 old 侧行只进 new 侧第一个 Update chunk 允许省略上下文标记后续 chunk 必须携带*** End of File属于语法标记而非内容。原子失败语法错误会整体拒绝整个 tool payload——即使前面有本可通过的 hunk也不产生任何部分活动见测试 atomically discards malformed apply-patch payloads包含not-prefixed非法行的 patch 使整个投影为空。Move 语义真实移动归一化后源路径 ≠ 目标路径产生源删除 目标创建且更新片段挂在目标上归一化后相同如./same.txt移动到nested/../same.txt则折叠为一条修改记录。测试 parses Add, Update, Delete, Move, CRLF, wrappers, chunks, empty context, and End of File 用一个带 CRLF、单引号包裹器、多 chunk、空上下文、Move 的完整 patch 验证了全部语法分支collapses a same-normalized-path Move and splits a real Move 验证折叠与拆分两条路径。四、数据模型与聚合从碎片到摘要再到会话分组4.1 权威类型定义openclaw-file-activities.ts 是数据模型的权威来源参考文档明确指出 The implementation types ... are authoritativeexport type OpenClawFileToolName write | edit | apply_patch; export type AcpFileChangeFragment { oldText: string; newText: string; sequence: number; }; export type AcpFileActivity { turnId: string; toolCallId: string; toolName: OpenClawFileToolName; relativePath: string; action: created | modified | deleted; fragments: AcpFileChangeFragment[]; sequence: number; }; export type AcpTurnFileSummary { turnId: string; relativePath: string; action: created | modified | deleted; activities: AcpFileActivity[]; added: number | null; removed: number | null; }; export type AcpSessionFileGroup { relativePath: string; activities: AcpFileActivity[]; }; export type AcpFileActivityProjection { activities: AcpFileActivity[]; turnSummariesByTurnId: Recordstring, AcpTurnFileSummary[]; fileGroups: AcpSessionFileGroup[]; uniqueFileCount: number; };要点sequence是派生的展示顺序不是持久化身份turnId复用 ACP 展示分组算法groupAcpTimelineItems支持纯工具轮次即没有用户消息的 assistant-turn见 timeline-groups.ts。4.2 三层聚合投影入口projectOpenClawFileActivities的完整流程为用createPathContext校验工作区上下文见下节路径安全遍历分组后的时间线只处理assistant-turn组中的tool-call项过滤completed状态用Setstring按toolCallId去重——同一工具调用的状态更新in_progress → completed不会产生重复活动测试 uses assistant group IDs for prose and tool-only turns and deduplicates toolCallId updates 验证按三种工具解析出AcpFileActivity随后构建三层输出轮次摘要buildSummaries同一轮次、同一相对路径折叠为一个摘要动作按foldAction折叠任一新活动为 deleted → deleted有 created → created否则 modifiedadded/removed由diffLines来自diff库按行统计且先做 CRLF → LF 归一化normalizeEol缺失可统计片段时保持null绝不臆造 0。会话文件组buildFileGroups按相对路径以首次活动出现顺序分组组内轮次记录保持时间顺序。轮次差异buildAcpTurnFileChanges同一轮次同一文件的多个片段先做去重完全相同的 old/new 对只保留一次再尝试安全组合——当前一片段的新文本 后一片段的旧文本时直接拼接否则尝试在整文档片段上唯一替换replaceUnique要求旧文本唯一出现否则不合并仍无法合并的独立片段共享一个展示 diff但不声称自己是累计补丁cumulative patch。测试 folds same-turn same-path actions, sums counts, and preserves chronological file groups 验证了created→edit→delete→recreate链条下动作折叠与行数求和的结果。五、路径安全WorkspaceFileRef 与双层校验工具路径被视作不可信输入untrusted。这是整个功能的安全核心规则层由 tool-derived-file-safety.md 定义实现分渲染层与主进程两层。5.1 渲染层词法包含校验渲染层先做词法lexical校验。workspaceRoot是包含边界containment boundaryexecutionCwd是 ACP 工作目录。createPathContext要求根与 cwd 使用同一路径家族posix / windows且都是绝对路径cwd 解析后必须落在 root 内部escapesRoot拒绝..、../x前缀以及绝对路径逃逸。resolveToolPath把相对路径相对executionCwd解析、把绝对路径直接解析然后计算相对 root 的相对路径一旦逃逸包括跨家族的混用如在 POSIX 上下文收到C:\...或C:relative即返回null该活动不产生。单元测试覆盖了大量对抗性用例POSIX 下接受src/a.txt与反斜杠src\b.txt接受位于 root 内的绝对路径/workspace/c.txt拒绝../../outside.txt、/workspace-collision/x.txt词法前缀碰撞不算包含、C:\workspace\x.txt、C:workspace\x.txtWindows 下正确处理盘符相对/绝对、跨盘符拒绝、UNC\\server\share语义uses win32 drive and UNC semantics cross-platform上下文本身非法非绝对、混家族、cwd 在 root 之外时整体不产生任何投影rejects non-absolute, mixed-family, or out-of-root context before projection。参考文档还强调没有权威 root 与 cwd 的 replay 不产生投影渲染层的词法拒绝只是明显的越界路径不出现活动 UI。5.2 主进程独立规范校验 WorkspaceFileRef预览与显式原生动作自始至终使用相对引用relative reference end to endtype WorkspaceFileRef { workspaceRoot: string; relativePath: string; };主进程electron/services/files-api.ts为每一次 read/stat/原生动作独立地重新做规范校验resolveWorkspaceTarget拒绝绝对路径与含..的相对路径对 root 做realpath并确认是目录对候选路径realpath后再次确认在 root 内对不存在的文件逐级上溯父目录realpath最近的已存在父目录仍必须在 root 内openWorkspaceTarget以O_RDONLY | O_NOFOLLOW非 Windows打开fstat后调用revalidateWorkspaceTarget核对 dev/ino拒绝符号链接逃逸与打开后目标被重定向的 TOCTOU 场景处理器发现listWorkspaceOpenHandlers、选定处理器打开openWorkspaceWith、revealrevealWorkspaceFile都会重新解析WorkspaceFileRef其中选定处理器打开在真正调用原生打开前还有一次额外的回调校验() resolveWorkspaceRegularFile(payload.ref, fsP)。渲染层永远不会向主进程发送主进程规范化后的裸路径、可执行路径、命令或命令模板主进程在后一次的拒绝只会让历史活动保留而拒绝对应的文件操作本身。5.3 动作可见性规则工具派生的目标tool-derived targets一律是只读的应用内预览绝不使用裸路径 shell APIcreated/modified活动可以暴露独立的Open with菜单原生动作只由工作区作用域的 Host API 操作支撑以及 Linux 上可行的 revealdeleted活动两者都不暴露HTML 活动Open with 菜单首先提供浏览器导航到由有效工作区 root 与受包含的相对路径构造的本地文件 URL这是预览导航而非原生处理器动作。参考文档确认 src/pages/Chat/AcpFileCard.tsx 提供附件/文件活动共用的展示外壳与感知目标的菜单不共享授权限制大小内的 DOCX/PPTX 活动通过其WorkspaceFileRef进入 Office 查看器解析与单查看器约束记录在 harness/reference/office-document-preview.md。六、与附件的严格分离两条互不串扰的管线文件活动与用户可见的附件是两个独立的投影与安全边界工具输入/输出中偶然出现的路径仍只是工具派生的证据不能变成附件卡片、不能解析到工作区之外、不能使用附件作用域的授权附件证据只能来自标准 ACP 资源内容、主进程持有的用户暂存记录staging record或受约束的显式助手MEDIA:兼容性例外详见 harness/reference/acp-generated-media-and-diagnostics.md 的 bounded-transcript-exceptions 一节。主进程只在 ACP 会话加载/创建成功后才建立附件会话与相对路径上下文每一次附件解析、预览读取、系统或外部打开都要重新校验确切的会话、generation、引用与规范目标——附件证据可以解析到工作区之外。而文件活动永远不进入附件管线其显式原生动作通过WorkspaceFileRef被严格限制在规范工作区内。完整的附件边界见 harness/reference/acp-attachment-access-control.md。七、用户体验与 Replay 行为场景文档 harness/specs/scenarios/acp-file-activity.md 与参考文档定义了用户可见行为expectedUserBehavior与acceptance字段见任务规范进一步固化了验收口径轮次级每个 assistant turn 对每个符合条件的路径显示一个文件按钮与一条摘要。created/modified按钮打开当前文件的 Preview 并带 Open withdeleted按钮打开 Changes 且没有 Open with。实现见 src/pages/Chat/AcpTurnFileActivity.tsx摘要行内嵌added/-removed绿色/红色计数仅当两者都非null时渲染。会话级 Changes按文件分组、按首次活动顺序排列、每组轮次记录按时间顺序每轮次每文件最多一个 diff 编辑器buildAcpTurnFileChanges的输出即此约束的实现。空会话提示没有任何合格活动的新会话明确显示该会话尚无文件变更。图标一致性Changes 中的文件头部使用与 Workspace 文件树一致的、按扩展名感知的 Material 文件图标而非通用变更图标任务规范acceptance明确 use the shared Material file icon instead of a generic change icon。多视图预览支持多视图的预览其分段切换器共享文件头名称/路径的尾部一侧不独占一行HTML 文件暴露Preview与Source两个视图默认沙箱化渲染预览切换视图时保持同一作用域读取结果。Replay 语义完整的 ACP 结构化 replay 通过同一投影恢复全部可用活动仅凭 transcript 或不完整的 replay不会推断缺失的记录切换会话时投影随活跃时间线一起清空。任务规范同时列出验证锚点单元测试 tests/unit/openclaw-file-activities.test.ts、tests/unit/files-api-workspace.test.ts 与文件预览组件测试套件以及端到端测试 tests/e2e/chat-file-changes.spec.ts后者通过 IPC mock 与录制的主进程调用断言在 tests/e2e/fixtures/electron.ts 的辅助下验证工具派生活动绝不触发无界 fallback 读取/打开。八、验收标准速览与工程约束任务规范acceptance字段汇总了最终可验证的工程口径可直接作为回归清单编号验收点1只有completed且为规范原始输入canonical raw inputs的write/edit/apply_patch才产生文件活动2失败与不支持的工具仍显示为普通工具卡片但不产生任何文件活动 UI3工具派生预览只使用工作区作用域的 read/stat Host API无无界 fallback后续工作区作用域原生动作独立重新校验WorkspaceFileRef绝不接受渲染层发来的裸规范路径4功能不扫描工作区、不使用 Git、不创建源快照、不推断 shell 副作用5完整 ACP replay 恢复可用活动不完整 replay 不虚构活动6Changes 文件头使用共享 Material 文件图标而非通用变更图标7同一轮次同一文件的碎片在安全时组合为一个展示 diff否则拼接为一个展示 diff配合这些验收点仓库还要求 docs-sync.md、ui-i18n-design-tokens.md对应 shared/i18n/locales 下 en/zh/ja/ru 的chat.json中fileActivity词条等规则生效并通过pnpm run typecheck、pnpm test、pnpm run test:e2e -- tests/e2e/chat-file-changes.spec.ts、pnpm run comms:replay、pnpm run comms:compare持续回归comms相关脚本位于 scripts/comms。结语restore-acp-file-activity代表了 ClawX 在 ACP 文件活动上的一次设计收敛用纯渲染层投影 双进程分层校验替代了旧的 hydration 思路既恢复了用户在 Chat 中直观查看 Agent 文件操作的能力轮次按钮、摘要、会话 Changes、应用内只读预览与受约束的 Open with又把工具派生的文件访问牢牢锁进WorkspaceFileRef定义的工作区边界。对于希望在 ACP 协议之上构建文件可视化与安全访问层的开发者本文所梳理的规范语法、聚合模型与双层路径校验正是可直接对照 openclaw-file-activities.ts 与 files-api.ts 落地的完整蓝图。赞分享人工智能AI 应用桌面应用交互助手【免费下载链接】ClawXClawX is a desktop app that provides a graphical interface for OpenClaw AI agents. It turns CLI-based AI orchestration into a desktop experience without using the terminal. China website is https://clawx.com.cn.项目地址https://gitcode.com/gh_mirrors/cl/ClawX点击查看免费下载相关推荐ClawX 的 ACP 文件活动机制OpenClaw 工具调用到工作区预览的安全投影与实操解析ClawX 的 ACP 文件活动机制OpenClaw 工具调用到工作区预览的安全投影与实操解析 本指南围绕 ClawX 仓库中的 acp file activ人工智能AI 应用桌面应用交互助手ClawX ACP 媒体附件渲染与 OpenClaw 有界转录兼容投影实战指南ClawX ACP 媒体附件渲染与 OpenClaw 有界转录兼容投影实战指南 本文导读 ClawX 在 ACP 原生聊天界面中提供完整的媒体附件体验——标准人工智能AI 应用桌面应用交互助手ClawX 文件活动机制深度解析基于 ACP 时间线的 OpenClaw 文件变更投影与工作区安全边界ClawX 文件活动机制深度解析基于 ACP 时间线的 OpenClaw 文件变更投影与工作区安全边界 导读 本文以 openclaw file activi人工智能AI 应用桌面应用交互助手上一篇three.js TSL 中 SampleNode 的机制解析基于回调的纹理采样节点下一篇Spring MVC Showcase 项目教程掌握企业级Web开发核心技术创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考