Skip to content

本地代理服务 ​

本文引用的源码文件

本文引用的文件

目录 ​

  1. 引言
  2. 项目结构
  3. 核心组件
  4. 架构总览
  5. 详细组件分析
  6. 依赖关系分析
  7. 性能与容量特性
  8. 部署与配置指南
  9. 安全最佳实践
  10. 故障诊断指南
  11. 结论

引言 ​

本地代理服务是 AI Helper 双进程架构中的 Node.js Agent 端,负责为 Chrome 扩展提供受控的本地文件系统访问、系统命令执行、长期记忆、RAG 检索、MCP 工具调用与技能管理。Agent 通过 HTTP API 和 WebSocket 暴露能力,并通过配对码 + Token 机制完成扩展与代理之间的认证绑定。

关键约束:

  • 扩展端(Manifest V3)与 Agent 端(Node.js)版本号保持同步,当前以 2.3.1 为准。
  • Agent 源码修改后必须重启进程,新接口才生效。
  • 扩展端 Service Worker 存在生命周期硬约束,side panel 与 background 消息传递是常见故障点。
  • 所有面向浏览器的响应需遵循 CORS 白名单策略,仅允许 chrome-extension:// 来源跨域读取。

章节来源

项目结构 ​

Agent 入口为 agent/src/server.js,采用单文件路由 + 多模块职责分离的设计:

  • HTTP 路由与请求处理集中在 server.js。
  • 认证逻辑在 auth.js。
  • 路径沙箱与命令分级在 security.js。
  • 子进程命令执行与超时控制封装在 executor.js。
  • 回收站逻辑在 trash.js。
  • 配置加载、缓存与写锁在 config.js。
graph TB
Client["浏览器扩展<br/>Chrome Extension"] --> HTTP["HTTP 服务器<br/>server.js"]
Client --> WS["WebSocket 服务器<br/>server.js"]
HTTP --> Auth["认证模块<br/>auth.js"]
HTTP --> Security["安全模块<br/>security.js"]
HTTP --> Executor["命令执行器<br/>executor.js"]
HTTP --> Trash["回收站模块<br/>trash.js"]
HTTP --> Config["配置模块<br/>config.js"]
HTTP --> Memory["长期记忆路由<br/>memory/routes.js"]
HTTP --> RAG["RAG 路由<br/>rag/routes.js"]
HTTP --> MCP["MCP 注册表<br/>mcp/registry.js"]
HTTP --> Skill["技能注册表<br/>skill/registry.js"]

图表来源

章节来源

核心组件 ​

  • HTTP 服务器:统一解析请求、CORS、国际化、认证拦截、路由分发、错误兜底。
  • WebSocket 服务器:仅开放 /ws/exec/{execId},用于命令流式输出。
  • 认证系统:配对码轮换、Token 验证、活跃连接窗口、失败锁定。
  • 安全系统:路径白名单 + 硬阻止 + 符号链接校验;命令黑名单/灰名单/白名单三级管控。
  • 命令执行引擎:shell 选择、子进程管理、stdout/stderr 流式广播、超时预算与延长策略、进程终止。
  • 文件操作服务:读、写、列表、统计、删除、移动、重命名、下载、批量下载、流式下载、XLSX 预览。
  • 回收站:软删除、元数据持久化、跨设备回退、7 天自动清理。
  • 配置管理:默认值、内存缓存、mtime 刷新、写入互斥锁、敏感字段落盘混淆。

章节来源

架构总览 ​

Agent 的请求处理流程可概括为:

  1. 解析 Accept-Language,设置各模块语言。
  2. 处理 OPTIONS 预检,仅放行 chrome-extension:// 来源。
  3. 对无需认证的接口直接处理(配对、健康检查、本机关闭)。
  4. 对需要认证的接口校验 Bearer Token。
  5. 按 pathname 分发到文件、命令、Skill、MCP、Memory、RAG 等路由。
  6. 所有异常进入全局 catch,返回国际化错误。
sequenceDiagram
participant Ext as "扩展"
participant HTTP as "HTTP 服务器"
participant Auth as "认证模块"
participant Sec as "安全模块"
participant Exec as "命令执行器"
participant FS as "文件系统"
Ext->>HTTP : "POST /api/exec"
HTTP->>Auth : "验证 Bearer Token"
Auth-->>HTTP : "extensionId 或拒绝"
HTTP->>Sec : "checkCommand(command, force)"
Sec-->>HTTP : "allow/confirm/deny"
alt "deny"
HTTP-->>Ext : "403 安全拒绝"
else "confirm"
HTTP-->>Ext : "200 需要确认"
else "allow"
HTTP->>Exec : "executeCommand(command, cwd)"
Exec-->>HTTP : "execId + wsUrl"
HTTP-->>Ext : "200 execId/wsUrl"
Ext->>HTTP : "GET /api/fs/read"
HTTP->>Sec : "checkPath(path)"
Sec-->>HTTP : "allowed/resolved"
HTTP->>FS : "readFile(resolved)"
FS-->>HTTP : "content"
HTTP-->>Ext : "200 content"
end

图表来源

详细组件分析 ​

HTTP 服务器与路由 ​

HTTP 服务器承担以下职责:

  • 构建 JSON 响应并设置 CORS 头,仅允许 chrome-extension:// 来源。
  • 解析 JSON body,限制最大体大小。
  • 解析 multipart/form-data 上传。
  • 维护工作目录切换、允许路径增删。
  • 提供文件读写、列表、统计、删除、移动、重命名、下载、批量下载、流式下载、XLSX 预览。
  • 提供命令执行、停止、daemon 化。
  • 提供 Skill、MCP、Memory、RAG 路由转发。
  • 提供回收站恢复与列表。
  • 提供审计日志查询。
  • 启动 WebSocket 升级,仅接受 /ws/exec/{execId}。

关键路由分组:

  • 无认证:/api/pair、/api/status、/api/shutdown(远程仍需认证)、/api/heartbeat。
  • 认证后:/api/status/detail、/api/files/upload、/api/fs/*、/api/exec*、/api/trash/*、/api/logs/query、/api/skill/*、/api/mcp/*、/api/memory/*、/api/rag/*。
flowchart TD
Start(["请求进入"]) --> ParseI18n["解析语言并设置模块语言"]
ParseI18n --> OptionsCheck{"OPTIONS 预检?"}
OptionsCheck --> |是| AllowOrigin["仅放行 chrome-extension://"]
OptionsCheck --> |否| NoAuthRoutes["配对/状态/关闭/心跳"]
NoAuthRoutes --> AuthCheck["Bearer Token 校验"]
AuthCheck --> |失败| Reject["401/403"]
AuthCheck --> |成功| RouteDispatch["按 pathname 分发路由"]
RouteDispatch --> FsRoutes["文件操作"]
RouteDispatch --> ExecRoutes["命令执行"]
RouteDispatch --> MiscRoutes["Skill/MCP/Memory/RAG/日志/回收站"]
FsRoutes --> End(["返回 JSON 或二进制流"])
ExecRoutes --> End
MiscRoutes --> End

图表来源

章节来源

认证与安全系统 ​

认证系统包含:

  • 配对码生成与定时轮换。
  • 连续失败锁定。
  • Token 验证并更新最近活跃时间。
  • 已配对扩展的 Token 存储于 pairings.json,落盘前混淆。

安全系统包含:

  • 路径规范化、~ 展开、绝对路径解析。
  • 硬阻止目录(配置文件、配对记录、日志、回收站、内置技能状态)。
  • 工作目录永远放行,但 realpath 仍做硬阻止校验。
  • allowedPaths 白名单前缀匹配 + realpath 二次校验。
  • 命令黑白灰名单,支持链式命令拆分、包装器剥壳、解释器内联载荷、命令替换扫描。
classDiagram
class Auth {
+setAuthLang(lang)
+startPairCodeRotation()
+stopPairCodeRotation()
+handlePairRequest(code, extensionId, tFn)
+verifyToken(token)
}
class Security {
+setSecurityLang(lang)
+normalizePathFormat(pathStr, platformOverride)
+checkPath(pathStr, tFn)
+checkCommand(command, force, tFn)
+isHardBlocked(normalizedPath, platformOverride)
+collectCommandScopes(command, depth, out)
}
class Config {
+loadConfig()
+saveConfig(config)
+updateConfigField(key, value)
+loadPairings()
+savePairing(extensionId, token)
}
Auth --> Config : "读取/保存配对"
Security --> Config : "读取 workdir/allowedPaths"

图表来源

章节来源

文件操作服务 ​

文件操作服务覆盖完整生命周期:

  • 上传:multipart 与流式上传,均做路径安全检查与大小限制。
  • 读取:校验路径、目录判断、大小限制、UTF-8 或 base64。
  • 写入:父目录创建、base64 解码、脚本权限剥离。
  • 列表:递归枚举条目类型、大小、时间。
  • 统计:权限、时间、MIME、符号链接标记。
  • 删除:走回收站。
  • 下载:单文件、目录 zip、批量 zip、流式下载。
  • XLSX 预览:服务端解析前若干行,避免前端引入 SheetJS。
  • 目录创建、重命名、移动:严格目标路径校验,防止静默覆盖。
flowchart TD
Req["文件请求"] --> CheckPath["checkPath 安全校验"]
CheckPath --> Allowed{"允许?"}
Allowed --> |否| Deny["403 安全拒绝"]
Allowed --> |是| OpType{"操作类型"}
OpType --> Read["读取文件"]
OpType --> Write["写入文件"]
OpType --> List["列出目录"]
OpType --> Stat["文件统计"]
OpType --> Delete["移动到回收站"]
OpType --> Download["下载/打包/流式下载"]
OpType --> Preview["XLSX 预览"]
OpType --> Rename["重命名"]
OpType --> Move["移动"]
Read --> Done["返回内容"]
Write --> Done
List --> Done
Stat --> Done
Delete --> Done
Download --> Done
Preview --> Done
Rename --> Done
Move --> Done

图表来源

章节来源

命令执行引擎 ​

命令执行引擎负责:

  • 平台 shell 选择:Windows Git Bash/cmd/PowerShell,macOS zsh/bash,Linux bash/sh。
  • 子进程标准输出/错误输出流式广播。
  • 输出缓冲区上限截断。
  • 超时策略:基础超时、有输出则延长、最多延长次数、总预算封顶。
  • 进程终止:Unix 进程组 SIGTERM/SIGKILL,Windows taskkill /T /PID。
  • WebSocket 回放:已完成进程输出缓存,延迟连接客户端可回放。
  • daemon 化:显式 detach 豁免超时。
sequenceDiagram
participant API as "/api/exec"
participant Sec as "checkCommand"
participant Exec as "executeCommand"
participant Proc as "child_process"
participant WS as "WebSocket"
API->>Sec : "command, force"
Sec-->>API : "allow/confirm/deny"
alt "deny"
API-->>Client : "403 deny"
else "confirm"
API-->>Client : "200 confirm"
else "allow"
API->>Exec : "spawn shell + command"
Exec->>Proc : "stdout/stderr pipe"
Proc-->>Exec : "data chunks"
Exec-->>WS : "stdout/stderr broadcast"
Proc-->>Exec : "close/error"
Exec-->>WS : "exit/killed/timedOut"
end

图表来源

章节来源

回收站功能 ​

回收站实现软删除:

  • 移动到 ~/.ai-helper-agent/.trash/。
  • 记录原始路径、名称、大小、删除时间、是否目录。
  • 跨设备 rename 失败时回退复制+删除源。
  • 7 天 TTL 自动清理。
  • 每 6 小时定期清理。
  • 恢复时检查原路径是否被占用。
flowchart TD
DeleteReq["删除请求"] --> TrashMove["moveToTrash"]
TrashMove --> CrossDevice{"同设备?"}
CrossDevice --> |是| Rename["rename 瞬时移动"]
CrossDevice --> |否| CopyDelete["cp + rm 源"]
Rename --> Meta["写入 metadata.json"]
CopyDelete --> Meta
Meta --> Periodic["周期清理过期条目"]
Restore["恢复请求"] --> FindEntry["查找 trashId"]
FindEntry --> Exists{"原路径可用?"}
Exists --> |否| Error["返回错误"]
Exists --> |是| MoveBack["移回原路径"]
MoveBack --> CleanMeta["删除元数据"]

图表来源

章节来源

WebSocket 通信 ​

WebSocket 仅开放 /ws/exec/{execId}:

  • 升级前解析 URL。
  • 认证优先 Authorization Header,回退 query token。
  • 将客户端加入运行中进程的监听集合。
  • 心跳 ping/pong 检测半开连接。
  • 断开连接后按受管模式与旧语义分别处理超时。
sequenceDiagram
participant Client as "扩展"
participant Server as "HTTP 服务器"
participant WSS as "WebSocketServer"
participant Exec as "executor"
Client->>Server : "upgrade /ws/exec/{execId}"
Server->>Server : "verifyToken(token)"
alt "认证失败"
Server-->>Client : "403 Forbidden"
else "认证成功"
Server->>WSS : "handleUpgrade"
WSS->>Exec : "addWsClient(execId, ws)"
Exec-->>WSS : "true/false"
WSS->>Client : "开始流式 stdout/stderr"
Client->>WSS : "ping/pong"
WSS->>Exec : "disconnectWsClient on close"
end

图表来源

章节来源

依赖关系分析 ​

Agent 包依赖:

  • ws:WebSocket 服务器。
  • archiver:ZIP 打包。
  • xlsx:Excel 预览。
  • @modelcontextprotocol/sdk:MCP 协议。
  • zod:运行时校验。
  • RAG 可选依赖:vectra、transformers、pdf-parse、mammoth、officeparser、cheerio。

Agent 内部模块依赖:

  • server.js 依赖 auth、security、executor、trash、config、search、rag、memory、mcp、skill、logger、process-tree、i18n。
  • executor.js 依赖 config、i18n。
  • security.js 依赖 config、i18n。
  • trash.js 依赖 i18n、sys-lang。
  • auth.js 依赖 config、i18n、sys-lang。
  • config.js 依赖 crypto-lite、i18n。
graph LR
Server["server.js"] --> Auth["auth.js"]
Server --> Security["security.js"]
Server --> Executor["executor.js"]
Server --> Trash["trash.js"]
Server --> Config["config.js"]
Server --> Search["search.js"]
Server --> RAG["rag/*"]
Server --> Memory["memory/*"]
Server --> MCP["mcp/*"]
Server --> Skill["skill/*"]
Server --> Logger["logger.js"]
Server --> ProcessTree["process-tree.js"]
Server --> I18n["i18n.js"]

图表来源

章节来源

性能与容量特性 ​

  • 请求体大小限制:JSON body 与 multipart 均限制为 200MB。
  • 文件读取/下载默认大小限制:50MB,可通过配置调整。
  • 流式上传:200MB,按字节计数保护。
  • 命令输出缓冲区上限:5MB,超限后广播截断提示。
  • 搜索最大结果数:5000。
  • 流式下载分块:64KB,使用 setImmediate 或 drain 让出事件循环。
  • 超时策略:基础超时、有输出延长、最多 5 次延长、总预算封顶 600s。
  • 配置缓存:mtime 命中返回内存对象,减少磁盘 IO。
  • 回收站清理:每 6 小时一次,避免长时间运行积累垃圾。

章节来源

部署与配置指南 ​

安装与启动 ​

  • 官方安装渠道为 GitHub Releases 自动构建产物。
  • npm 包名为 ai-helper-agent,版本 2.3.1。
  • 入口文件为 agent/src/server.js,bin 命令为 ai-helper-agent 与别名 aha。
  • 要求 Node.js >= 18。

章节来源

环境变量与端口配置 ​

  • 默认端口:18910。
  • 默认主机:127.0.0.1。
  • 工作目录:~/.ai-helper-agent/workspace。
  • 允许路径:默认包含工作目录。
  • 配对码 TTL:默认 30 秒。
  • 命令超时:默认 300000ms。
  • 文件最大读取大小:默认 50MB。
  • RAG URL 内网访问策略:默认关闭私有网络访问。
  • 长期记忆 embedding:默认关闭,mode 可为 openai-compat 或 local。

章节来源

SSL 证书配置 ​

当前 Agent 使用原生 http.createServer,未内置 HTTPS 支持。若需 TLS:

  • 建议在前置反向代理(如 Nginx、Caddy)配置 SSL 终止。
  • Agent 仅监听本地或可信网络地址,避免直接暴露公网。
  • 若未来改为 HTTPS,需确保 CORS、Token、WebSocket upgrade 链路一致。

[本节为通用部署建议,不直接分析具体源码文件]

防火墙规则 ​

  • 推荐仅开放本地回环地址。
  • 如需远程访问,应通过防火墙限制来源 IP 段。
  • 注意 /api/shutdown 远程来源仍需认证,但仍建议最小化暴露面。

章节来源

安全最佳实践 ​

  • 始终启用 Bearer Token 认证,避免无认证接口被恶意网页读取。
  • 仅允许 chrome-extension:// 作为 CORS 来源。
  • 使用 allowedPaths 精确限定可访问目录,不要随意扩大白名单。
  • 避免将 Agent 工作目录设为 .ai-helper-agent 自身。
  • 谨慎使用 force 参数,它只能跳过灰名单,不能绕过黑名单。
  • 监控审计日志,关注 exec_denied、fs_*_blocked、auth_invalid。
  • 定期清理回收站,避免磁盘膨胀。
  • 对脚本类文件上传/写入后,Agent 会剥离执行权限,但仍应避免从不可信来源直接执行脚本。
  • RAG 依赖安装与 Agent 在线更新互斥,避免并发写 node_modules。

章节来源

故障诊断指南 ​

常见问题定位 ​

  • 端口占用:服务器启动报错 EADDRINUSE,退出进程。
  • 配对失败:检查配对码是否轮换、扩展 ID 是否正确、失败锁定是否触发。
  • Token 无效:检查 Authorization: Bearer <token> 是否正确。
  • 文件路径被拒:检查 allowedPaths、workdir、符号链接、硬阻止目录。
  • 命令被拒:查看 level=deny 原因,确认是否命中黑名单。
  • 命令超时:检查输出流是否有数据,受管模式下无输出会被判定挂起并杀死。
  • WebSocket 断连:检查心跳 ping/pong,确认插件端 SW 保活。
  • RAG 不可用:调用 /api/rag/detect 查看探测错误,必要时重新安装依赖。

日志与审计 ​

  • 审计日志分类:认证、文件、命令、安全、系统。
  • 日志查询接口:/api/logs/query,默认最近 7 天,单次最多 500 条。
  • 前台运行时日志实时输出到终端。
  • 全局未捕获异常与未处理 Promise 拒绝会被记录但不退出进程。

章节来源

结论 ​

本地代理服务通过 HTTP + WebSocket 将浏览器扩展的能力扩展到本地文件系统与命令行,同时以路径沙箱、命令分级、Token 认证、审计日志构成多层安全边界。其设计强调可控性:工作目录与白名单控制文件范围,黑名单绝对禁止高危命令,灰名单要求用户确认,回收站提供后悔空间,超时与进程树终止保障资源安全。部署时应遵循最小暴露原则,结合反向代理与防火墙规则,配合审计日志进行持续监控。