主题
可点击文件路径系统
本文引用的源码文件
本文引用的文件
目录
引言
本文件聚焦“可点击文件路径系统”,即 AI Helper 在侧边栏中把 Agent 生成的工作目录文件、命令输出产物和对话消息中的文件路径,统一转化为可点击、可定位、可预览的交互能力。该系统横跨两条主线:
- 任务产物线:从 Agent 执行日志中提取写文件操作,生成“文件产物”面板,支持定位到工作目录、预览、下载等。
- 输入选择线:通过
$选择器在工作目录中检索文件/目录,并作为“基于文件的问答”附件加入输入区。 - 消息链接线:将聊天消息中的有效文件路径渲染为可点击链接,点击后跳转到工作目录面板并高亮对应条目。
该项目采用双进程架构:Chrome 扩展端(Manifest V3,版本 2.3.1)与独立本地代理端 Agent(Node.js,npm 包名 ai-helper-agent,版本 2.3.1)。两端版本号保持同步;Agent 源码修改后必须重启进程,新接口才生效。
章节来源
项目结构
围绕“可点击文件路径系统”,相关代码主要分布在 side_panel 子模块:
- artifacts-manager.js:任务文件产物管理,负责从 executionLog 提取写文件操作,提供产物列表、定位、预览、下载等。
- file-at-selector.js:输入框
$选择器,用于检索工作目录文件/目录并添加到“文件问答”。 - workspace-panel.js:工作目录文件管理器 UI,承载浏览、搜索、预览、编辑、导出、定位等能力。
- chat-manager.js:消息渲染入口之一,负责把产物按钮挂载到消息右侧,并把有效文件路径转换为可点击链接。
- utils.js:通用工具,包含 i18n 文案注入、提示、时间格式化等。
- manifest.json 与 scripts/fix-build.js:构建期处理 MV3 Service Worker、side panel HTML 脚本注入及运行时 side_panel.default_path 剥离,保证 side panel 可被 background 动态控制。
graph TB A["侧边栏消息<br/>chat-manager.js"] --> B["产物管理器<br/>artifacts-manager.js"] A --> C["工作目录面板<br/>workspace-panel.js"] D["输入 $ 选择器<br/>file-at-selector.js"] --> C B --> C E["构建修复脚本<br/>scripts/fix-build.js"] --> F["扩展清单<br/>manifest.json"] F --> A F --> C
图表来源
- src/side_panel/chat-manager.js#L1650-L1672
- src/side_panel/artifacts-manager.js#L1-L10
- src/side_panel/workspace-panel.js#L1-L20
- src/side_panel/file-at-selector.js#L1-L10
- scripts/fix-build.js#L190-L221
- manifest.json#L47-L53
章节来源
核心组件
- 产物管理器(artifacts-manager.js)
- 从 Agent 执行日志中提取写文件操作,包括 echo/cat/tee/cp/mkdir/touch 等常见模式,以及 Bash 花括号展开、heredoc 内联脚本、find/ls 输出兜底解析。
- 提供产物列表、排序、定位到工作目录、预览、下载、复制文件名/路径等操作。
- 工作目录面板(workspace-panel.js)
- 展示当前工作目录内容,支持搜索、多选、上传、删除、重命名、移动、预览、编辑、导出(Word/PDF/图片/Markdown)、在浏览器打开等。
- 暴露 locateFileInWorkspace、previewArtifactFile、resolveWorkspaceAbsolutePath 等函数供产物管理器调用。
- 输入 $ 选择器(file-at-selector.js)
- 输入
$时触发,远端递归搜索名称匹配的文件/目录,前端按前缀匹配、最近修改时间、目录优先、字典序排序,最多显示 50 条。 - 选中后将文件元数据附加到“文件问答”,并自动调整输入框高度。
- 输入
- 消息渲染(chat-manager.js)
- 当消息存在 agent_file 产物时,挂载“文件产物”按钮,并异步校验产物有效性。
- 将消息中的有效文件路径转换为可点击链接,点击后进入工作目录面板定位。
- 通用工具(utils.js)
- 提供 Toast、输入框高度自适应、下拉框定位、HTML 转义、时间格式化等基础能力。
章节来源
- src/side_panel/artifacts-manager.js#L1-L10
- src/side_panel/workspace-panel.js#L1-L20
- src/side_panel/file-at-selector.js#L1-L10
- src/side_panel/chat-manager.js#L1650-L1672
- src/side_panel/utils.js#L98-L147
架构总览
“可点击文件路径系统”的运行流程如下:
- Agent 执行命令或脚本,产生工作目录文件。
- 扩展侧从执行日志中提取产物,并在消息右侧显示“文件产物”按钮。
- 用户点击产物按钮,打开产物列表,可对单个文件进行定位、预览、下载。
- 用户在输入框输入
$,触发工作目录文件选择器,选择文件后加入“文件问答”。 - 聊天消息中的有效文件路径会被渲染为可点击链接,点击后跳转到工作目录面板并高亮对应条目。
sequenceDiagram participant User as "用户" participant Chat as "消息渲染<br/>chat-manager.js" participant Artifacts as "产物管理器<br/>artifacts-manager.js" participant Workspace as "工作目录面板<br/>workspace-panel.js" participant Selector as "$ 选择器<br/>file-at-selector.js" User->>Chat : 查看 AI 回复 Chat->>Artifacts : 检测是否存在 agent_file 产物 Artifacts-->>Chat : 返回产物列表 Chat->>Chat : 挂载“文件产物”按钮 Chat->>Chat : 将消息中的文件路径转为可点击链接 User->>Artifacts : 点击“文件产物”按钮 Artifacts->>Workspace : 定位/预览/下载文件 User->>Selector : 输入框输入 "$" Selector->>Workspace : 检索工作目录文件/目录 Selector->>Chat : 将选中的文件加入“文件问答” User->>Chat : 点击消息中的文件路径链接 Chat->>Workspace : 打开工作目录面板并定位文件
图表来源
- src/side_panel/chat-manager.js#L1650-L1672
- src/side_panel/artifacts-manager.js#L1482-L1544
- src/side_panel/workspace-panel.js#L1-L20
- src/side_panel/file-at-selector.js#L71-L104
详细组件分析
产物管理器(artifacts-manager.js)
产物管理器是“可点击文件路径系统”的核心,承担以下职责:
- 规范化路径、提取文件名/扩展名、HTML 转义。
- 解析 Bash 花括号扩展,如
mkdir -p dir/{a,b}、touch {x,y}.txt。 - 从 agent_exec 命令字符串中提取写入目标,包括重定向、cat > file、cp、tee、mkdir、touch 等。
- 解析 heredoc 内联脚本,识别 Python/shell 等解释器,静态分析脚本内部创建的文件路径。
- 从 find/ls 输出中兜底解析路径,区分目录与文件,过滤非路径 token。
- 提供产物列表渲染、排序、定位、预览、下载、复制文件名/路径等功能。
flowchart TD
Start(["开始:解析执行日志"]) --> ExtractCmd["提取 agent_exec 命令链"]
ExtractCmd --> ParseHeredoc{"是否包含 heredoc 脚本?"}
ParseHeredoc --> |是| AnalyzeScript["静态分析脚本内容<br/>提取可能创建的文件路径"]
ParseHeredoc --> |否| SkipHeredoc["跳过"]
AnalyzeScript --> MergePaths["合并候选路径"]
SkipHeredoc --> MergePaths
MergePaths --> ParseRedirects["解析重定向/tee/cp/mkdir/touch 等模式"]
ParseRedirects --> ExpandBraces["展开 Bash 花括号"]
ExpandBraces --> ResolveCwd["结合 cd 链与工作目录解析绝对路径"]
ResolveCwd --> ListOutput{"是否包含 ls/find 输出?"}
ListOutput --> |是| ParseListOutput["从列表输出兜底解析路径"]
ListOutput --> |否| Dedup["去重并过滤无效路径"]
ParseListOutput --> Dedup
Dedup --> Render["渲染产物列表"]
Render --> End(["结束"])
图表来源
- src/side_panel/artifacts-manager.js#L269-L315
- src/side_panel/artifacts-manager.js#L385-L507
- src/side_panel/artifacts-manager.js#L525-L653
- src/side_panel/artifacts-manager.js#L670-L777
章节来源
- src/side_panel/artifacts-manager.js#L1-L10
- src/side_panel/artifacts-manager.js#L135-L232
- src/side_panel/artifacts-manager.js#L269-L315
- src/side_panel/artifacts-manager.js#L385-L507
- src/side_panel/artifacts-manager.js#L525-L653
- src/side_panel/artifacts-manager.js#L670-L777
工作目录面板(workspace-panel.js)
工作目录面板是“可点击文件路径系统”的承载界面,提供:
- 工作目录根路径获取、切换、允许目录管理。
- 目录浏览、搜索、排序、多选、上传、删除、重命名、移动。
- 文件预览(文本、Markdown、PDF、Excel、PPTX、图片、媒体)、编辑、保存、取消。
- 导出为 Word/PDF/图片/Markdown,或在浏览器中打开。
- 暴露 locateFileInWorkspace、previewArtifactFile、resolveWorkspaceAbsolutePath 等函数,供产物管理器与消息链接调用。
classDiagram
class WorkspacePanel {
+initWorkspacePanel()
+openWorkspacePanel()
+closePanel()
+locateFileInWorkspace(path)
+previewArtifactFile(path, fileName)
+resolveWorkspaceAbsolutePath(path)
+searchFilesRemote(root, query, limit)
+listDirectory(path)
+downloadFileStream(path)
+downloadFilesStream(paths)
}
class ArtifactsManager {
+showArtifactsModal(artifacts, btn)
+validateArtifactsAsync(artifacts, btn)
+locateFileInWorkspace(path)
+previewArtifactFile(path, fileName)
}
WorkspacePanel <.. ArtifactsManager : "调用定位/预览方法"
图表来源
章节来源
输入 $ 选择器(file-at-selector.js)
$ 选择器用于在工作目录中快速检索文件/目录,并将其作为“文件问答”附件加入输入区:
- 输入
$时触发,若有关键词则远端递归搜索,否则展示根目录内容。 - 搜索结果按前缀匹配、最近修改时间、目录优先、字典序排序,最多显示 50 条。
- 选中文件后,移除输入框中的
$...文本,焦点回到输入框,并将文件元数据附加到“文件问答”。
flowchart TD
Input["$ 输入触发"] --> Debounce["防抖 200ms"]
Debounce --> Query{"是否有关键词?"}
Query --> |是| RemoteSearch["远端递归搜索"]
Query --> |否| ListRoot["列出根目录内容"]
RemoteSearch --> Sort["前端排序:前缀匹配 > 最近修改 > 目录优先 > 字典序"]
ListRoot --> Sort
Sort --> Render["渲染最多 50 条结果"]
Render --> Select["用户选中文件"]
Select --> Attach["附加到文件问答"]
Attach --> Focus["焦点回到输入框"]
图表来源
- src/side_panel/file-at-selector.js#L71-L104
- src/side_panel/file-at-selector.js#L127-L179
- src/side_panel/file-at-selector.js#L189-L207
- src/side_panel/file-at-selector.js#L266-L289
章节来源
- src/side_panel/file-at-selector.js#L1-L10
- src/side_panel/file-at-selector.js#L71-L104
- src/side_panel/file-at-selector.js#L127-L179
- src/side_panel/file-at-selector.js#L189-L207
- src/side_panel/file-at-selector.js#L266-L289
消息渲染与可点击路径(chat-manager.js)
消息渲染负责:
- 当消息存在 agent_file 产物时,挂载“文件产物”按钮,并异步校验产物有效性。
- 将消息中的有效文件路径转换为可点击链接,点击后跳转到工作目录面板并高亮对应条目。
sequenceDiagram participant Chat as "消息渲染<br/>chat-manager.js" participant Artifacts as "产物管理器<br/>artifacts-manager.js" participant Workspace as "工作目录面板<br/>workspace-panel.js" Chat->>Artifacts : 检测是否存在 agent_file 产物 Artifacts-->>Chat : 返回产物列表 Chat->>Chat : 挂载“文件产物”按钮 Chat->>Chat : 将消息中的文件路径转为可点击链接 User->>Chat : 点击消息中的文件路径链接 Chat->>Workspace : 打开工作目录面板并定位文件
图表来源
章节来源
构建与 Manifest 配置(scripts/fix-build.js 与 manifest.json)
构建期脚本负责:
- 生成 service-worker-loader.js,注入 background 脚本。
- 若存在 side_panel 构建产物,则在 side_panel.html 中注入 script 入口。
- 剥离 manifest.json 中的 side_panel.default_path,避免运行时覆盖 background 的 setOptions 控制。
flowchart TD Build["Vite 构建"] --> FixBuild["scripts/fix-build.js"] FixBuild --> Loader["生成 service-worker-loader.js"] FixBuild --> SidePanelHTML["注入 side_panel.html 脚本入口"] FixBuild --> Manifest["剥离 side_panel.default_path"] Manifest --> Runtime["运行时由 background 控制 side panel path"]
图表来源
章节来源
依赖关系分析
“可点击文件路径系统”的依赖关系如下:
- artifacts-manager.js 依赖 workspace-panel.js 的定位/预览方法,以及 workspace-manager.js 的工作目录 API。
- file-at-selector.js 依赖 workspace-manager.js 的工作目录 API,以及 workspace-panel.js 的 attachFilesForQuestion。
- chat-manager.js 依赖 artifacts-manager.js 的产物按钮逻辑,以及 workspace-panel.js 的路径链接转换。
- utils.js 提供通用工具,被多个模块复用。
graph LR Utils["utils.js"] --> Artifacts["artifacts-manager.js"] Utils --> Selector["file-at-selector.js"] Utils --> Chat["chat-manager.js"] Workspace["workspace-panel.js"] --> Artifacts Workspace --> Selector Workspace --> Chat
图表来源
- src/side_panel/artifacts-manager.js#L1-L10
- src/side_panel/file-at-selector.js#L1-L10
- src/side_panel/chat-manager.js#L1650-L1672
章节来源
- src/side_panel/artifacts-manager.js#L1-L10
- src/side_panel/file-at-selector.js#L1-L10
- src/side_panel/chat-manager.js#L1650-L1672
性能与可靠性
- 产物解析优化:
- 使用 Bash 花括号展开与 heredoc 静态分析,减少误判。
- 对 find/ls 输出进行黑名单过滤与启发式分类,避免权限位/用户名/时间等非路径 token 被误识别。
- 输入选择器优化:
- 远端搜索防抖 200ms,避免频繁请求。
- 前端排序后截断至 50 条,提升可读性与性能。
- 工作目录面板优化:
- 大文件预览降级为“在浏览器中打开”,避免内存压力。
- 预览期 window 监听使用 AbortSignal 管理生命周期,避免常驻监听泄漏。
- 构建期优化:
- 剥离 side_panel.default_path,避免运行时覆盖 background 的 setOptions 控制,确保 side panel 行为一致。
章节来源
- src/side_panel/artifacts-manager.js#L670-L777
- src/side_panel/file-at-selector.js#L32-L38
- src/side_panel/file-at-selector.js#L189-L207
- src/side_panel/workspace-panel.js#L516-L534
- scripts/fix-build.js#L213-L221
故障排查指南
- 产物未显示:
- 检查 Agent 是否已连接,工作目录是否已设置。
- 确认执行日志中存在 agent_file 产物,且路径有效。
- 文件定位失败:
- 检查工作目录是否包含该文件,或文件是否已被删除。
- 确认 resolveWorkspaceAbsolutePath 返回的路径是否正确。
- $ 选择器无结果:
- 检查远端搜索是否成功,关键词是否过短或过长。
- 确认工作目录权限是否足够,能否列出目录内容。
- 消息链接不可点击:
- 检查 applyFilePathLinks 是否被调用,路径是否符合工作目录规范。
- 确认 workspace-panel.js 的 locateFileInWorkspace 方法是否正常。
章节来源
- src/side_panel/artifacts-manager.js#L1482-L1544
- src/side_panel/file-at-selector.js#L127-L179
- src/side_panel/chat-manager.js#L1650-L1672
结论
“可点击文件路径系统”通过产物管理器、工作目录面板、$ 选择器和消息渲染四个核心组件,实现了从 Agent 执行日志到用户交互的完整闭环。它不仅提升了用户对生成文件的可见性和可操作性,还通过 $ 选择器增强了“基于文件的问答”体验。系统在性能与可靠性方面做了多项优化,包括防抖、截断、预览降级、构建期脚本注入等,确保在不同场景下都能稳定运行。未来可考虑进一步增强路径解析的鲁棒性,例如支持更多 shell 语法和动态变量替换,同时优化大文件预览的性能表现。