news 2026/9/10 6:14:36

OpenViking TRAE CLI 内存 Hooks 适配器:生命周期钩子、URI 守卫与 MCP 集成详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
OpenViking TRAE CLI 内存 Hooks 适配器:生命周期钩子、URI 守卫与 MCP 集成详解

OpenViking TRAE CLI 内存 Hooks 适配器:生命周期钩子、URI 守卫与 MCP 集成详解

【免费下载链接】OpenVikingSelf-evolving Context Database for AI Agents. Unify Agent Memory, Knowledge RAG and Skills.项目地址: https://gitcode.com/GitHub_Trending/op/OpenViking

本文是 OpenViking 项目中examples/trae-cli-memory-hooks目录的技术指南,核心讲解如何通过 TRAE CLI 生命周期 Hooks(SessionStart/UserPromptSubmit/Stop/PreToolUse)+openviking-memoryMCP 服务器,将 TRAE CLI 接入 OpenViking 的 Agent 记忆体系,实现会话开始时注入上下文、用户提问时自动召回、对话停止时自动捕获回写,以及拦截对viking://虚拟路径的非法工具调用。读完本文,你将掌握这套适配器的安装/卸载方式、Hook 事件与输出协议、共享运行时的组装模型,以及 TRAE CLI 与 Codex 插件格式的兼容边界。

一、背景与定位:这是一个被标记为废弃(Deprecated)的适配器

examples/trae-cli-memory-hooks是 OpenViking 为TRAE CLI(TraeCode CLI)提供的生命周期适配器目录,包含三个生命周期 Hook、一个PreToolUseURI 守卫,以及openviking-memoryMCP 服务器。

需要特别注意的是,该目录在 README 开头即声明Deprecated

TraeCode CLI 2.0 已支持直接加载 Codex 格式插件。新安装统一走 examples/codex-memory-plugin,通过trae-cli命令别名安装,本适配器仅保留用于兼容性测试与存量托管安装的清理。

因此本文的主线应理解为两部分:

  1. 存量视角:理解这套独立 Hooks 适配器当年如何工作(对排障、清理、迁移到新方案至关重要);
  2. 演进视角:明确“废弃的是独立 Hooks 适配器,而不是trae-cli这个 harness”,新装用户应通过 examples/memory-plugin-shared/install.sh 的--harness trae-cli安装 Codex 格式插件。

目录内的 openviking.integration.json 清单也明确记录了这一状态:

{ "schemaVersion": 1, "id": "openviking-memory", "version": "0.1.0", "deprecated": true, "replacement": "examples/codex-memory-plugin (install through the trae-cli Codex-format alias)", "clients": ["trae-cli"], "capabilities": ["hooks", "mcp"] }

其中replacement字段指向新方案,clients表明本适配器仅面向trae-cli这一个客户端(区别于 TRAE / TRAE CN 的tr-trcn-前缀分支)。

二、运行时边界:目录里只有适配器,共享运行时由安装器组装

理解本包的第一步是认清它的运行时边界examples/trae-cli-memory-hooks目录内只包含 TRAE CLI 特有的适配层,没有自带lib/目录,共享运行时是在安装时由安装器从examples/memory-plugin-shared/lib组装进去的。

三个核心共享模块及其职责如下:

共享模块职责
lib/agent-hook-runtime.mjs处理 profile 注入、recall、capture、commit、session 状态、文件锁、凭据加载与 pending retry 重放
lib/mcp-proxy-core.mjs处理 stdio 到 OpenViking/mcp的代理
lib/agent-uri-guard.mjs处理PreToolUse阶段对本地文件/Shell 工具收到viking://虚拟路径的拦截

这套目录结构与examples/trae-memory-hooks保持一致。安装器的目标布局为:

  • examples/trae-cli-memory-hooks复制到$OV_HOME/agent-integrations/trae-cli
  • 将共享运行时组装到$OV_HOME/agent-integrations/memory-plugin-shared/lib

三、安装与卸载:一条命令完成

3.1 安装

由于 TraeCode CLI 2.0 原生支持 Codex 格式插件,官方推荐的安装方式是直接使用共享安装器,并将trae-cli作为用户可见的 harness 名称:

bash examples/memory-plugin-shared/install.sh --harness trae-cli

在 install.sh 中,harness 参数说明为:

--harness LIST逗号分隔的 harness 列表:claude, codex, cursor, trae, trae-cn, trae-cli, zcode, opencode, pi, dsh。使用trae-cli表示 TraeCode CLI 2.0(通过其 Codex 兼容插件格式安装)。

安装器会探测本机的 TRAE CLI 可执行文件(trae-cli/traecli/traex任一存在即视为已安装),并将其规范命名为trae-cli

3.2 历史安装行为(本适配器时代)

在独立适配器时代,安装器过去的行为是:

  1. 将共享运行时组装到$OPENVIKING_HOME/agent-integrations/memory-plugin-shared/lib
  2. 将本适配器安装到$OPENVIKING_HOME/agent-integrations/trae-cli
  3. 将 Hook 合并进${TRAECLI_HOME:-${TRAE_HOME:-~/.trae}/cli}/hooks.json
  4. ${TRAE_HOME:-~/.trae}/traecli.toml中注册openviking-memoryMCP 服务器。

现在的安装器不再安装本适配器,而是走 Codex 格式插件路径,但保留了trae-cli这个 harness 名称。

3.3 卸载

bash examples/memory-plugin-shared/install.sh --harness trae-cli --uninstall --yes

卸载逻辑在 install.sh 附近:当检测到$OV_HOME/agent-integrations/trae-cli目录存在、或traecli.toml中已含[mcp_servers."openviking-memory"]时,会调用agent_remove_trae_cli_configs清理 hooks 配置与traecli.toml中对应的 MCP 段落,并移除已安装的目录。

四、Hook 与 MCP 表面:四个事件、三种输出形态

4.1 四个 Hook 事件

本包注册了四个 Hook 事件,定义在 hooks/hooks.json:

EventEntry复用评估
SessionStartscripts/session-start.mjs复用共享的 thin-harness profile 注入路径;要求 TRAE CLI 提供稳定的 session id 或等价的 cwd 兜底
UserPromptSubmitscripts/auto-recall.mjs复用共享 recall 路径;要求 TRAE CLI 将用户输入暴露为promptuser_promptmessagetext
Stopscripts/auto-capture.mjs复用共享 session append 与 commit 辅助;要求 TRAE CLI 的 stop 输入将助手回复暴露为last_assistant_messageassistant_messageresponseoutputtext_content
PreToolUsescripts/uri-guard.mjs遵循 Codex Hook 输出风格返回permissionDecision: "deny",复用共享agent-uri-guard求值器

完整的 hooks 模板如下(注意命令中的__OPENVIKING_TRAE_CLI_ROOT__占位符,安装时会被替换为该目录的绝对路径):

{ "hooks": { "SessionStart": [ { "matcher": "clear|startup|resume", "hooks": [ { "type": "command", "command": "node __OPENVIKING_TRAE_CLI_ROOT__/scripts/session-start.mjs", "timeout": 70 } ] } ], "UserPromptSubmit": [ { "matcher": "*", "hooks": [ { "type": "command", "command": "node __OPENVIKING_TRAE_CLI_ROOT__/scripts/auto-recall.mjs", "timeout": 130 } ] } ], "Stop": [ { "matcher": "*", "hooks": [ { "type": "command", "command": "node __OPENVIKING_TRAE_CLI_ROOT__/scripts/auto-capture.mjs", "timeout": 30 } ] } ], "PreToolUse": [ { "matcher": "Read|Glob|Grep|Bash|RunCommand|Shell", "hooks": [ { "type": "command", "command": "node __OPENVIKING_TRAE_CLI_ROOT__/scripts/uri-guard.mjs", "timeout": 5 } ] } ] } }

值得注意的细节:

  • SessionStart的 matcher 是clear|startup|resume,即只在会话启动/恢复/清空时触发,超时 70 秒(profile 构建 + pending 重放可能较慢);
  • UserPromptSubmitStop的 matcher 是*(所有输入),超时分别为 130 秒(recall 检索)与 30 秒;
  • PreToolUse的 matcher 精确限定在Read|Glob|Grep|Bash|RunCommand|Shell这几类本地文件与 Shell 工具上,超时仅 5 秒——因为它只需做一次 URI 判定,必须足够快。

4.2 TRAE CLI 的 Hook 输出协议

TRAE CLI 生命周期 Hooks不使用TRAE / TRAE CN 的decision: "approve"输出风格,其输出约定如下:

  • 无操作的生命周期 Hook 输出{}
  • 上下文注入只输出hookSpecificOutput.hookEventNamehookSpecificOutput.additionalContext
  • 工具调用的放行/拒绝属于PreToolUse,通过hookSpecificOutput.permissionDecision表达;
  • 权限审批属于PermissionRequest,通过hookSpecificOutput.decision.behavior表达。

这一点在 trae-cli-hook.mjs 中得到印证:emitLifecycleOutput只有在有additionalContext时才写hookSpecificOutput,否则输出空对象{};而 uri-guard.mjs 则以 Codex 风格输出hookSpecificOutput.permissionDecision = "deny"并附带permissionDecisionReason

4.3 MCP 服务器注册

MCP 服务器名为openviking-memory,与 Codex 内存插件同名。本包保持与其他原生 Hook 集成相同的.mcp.json源形状,共享安装器会将等价的 Node 代理条目写入 TRAE CLI 的traecli.toml

{ "mcpServers": { "openviking-memory": { "command": "node", "args": ["servers/mcp-proxy.mjs"], "cwd": ".", "startup_timeout_sec": 30 } } }

从源码看,安装器实际写入的 TOML 形态更完整——见 install.sh,它生成[mcp_servers."openviking-memory"]段落,并注入OPENVIKING_INTEGRATION_IDOPENVIKING_INTEGRATION_VERSIONOPENVIKING_HOOK_SOURCE=trae-cli三个环境变量到env字段,供 Hook 与 MCP 代理运行时读取。

五、源码级剖析:三个包装脚本如何汇聚到统一适配器

5.1 事件分发的三个薄包装

session-start.mjsauto-recall.mjsauto-capture.mjs三个文件是极薄的入口,只做一件事——设置OPENVIKING_HOOK_EVENT环境变量后动态导入统一适配器:

// session-start.mjs process.env.OPENVIKING_HOOK_EVENT = "session-start"; await import("./trae-cli-hook.mjs");
// auto-recall.mjs process.env.OPENVIKING_HOOK_EVENT = "user-prompt-submit"; await import("./trae-cli-hook.mjs");
// auto-capture.mjs process.env.OPENVIKING_HOOK_EVENT = "stop"; await import("./trae-cli-hook.mjs");

这样三个 Hook 事件共享同一份逻辑,trae-cli-hook.mjs只负责按事件名走不同分支。

5.2 统一适配器trae-cli-hook.mjs

trae-cli-hook.mjs 是整个适配器的核心,从源码结构看其关键设计如下:

固定身份:使用固定的clientId = "trae-cli"与 OpenViking session 前缀trcli-(见第 25-26 行),刻意不携带 TRAE / TRAE CN 的tr-trcn-分支。会话 ID 通过共享的deriveAgentSessionId(prefix, input)派生,原生会话 ID 由resolveNativeSessionId(input)解析。

SessionStart 分支(第 55-70 行):

  • 先取withAgentHookLock文件锁(避免并发触发);
  • lastSessionStartAt做 2000ms 的节流去重;
  • 调用replayAgentPending重放上次失败未提交的 pending 消息(断点续传);
  • 调用buildAgentProfile构建 Agent profile;
  • 有 profile 时以<openviking-context source="session-start">标签注入。

UserPromptSubmit 分支(第 72-102 行):

  • resolveTraeCliPrompt(input)从 Hook 输入中提取用户提问;
  • 对同一次提问做双维度去重:优先用generation_id/request_id/message_id/prompt_id事件 ID 判重,缺失时退回promptHash+ 500ms 时间窗口;
  • 通过共享recallForPrompt执行召回,结果缓存在 hook state 中,以便 Stop 分支组装对话轮次时对齐提问;
  • 命中相同提问但无新 recall 块时复用state.recallBlock,避免重复检索。

Stop 分支(第 104-134 行):

  • cfg.autoCapture开关控制;
  • buildTraeCliTurns(input, state)从输入与 state 中还原「用户提问 + 助手回复」轮次;
  • stableHash(turnKey, role, content)计算轮次哈希并与capturedHashes(最多保留 1000 条)比对去重;
  • 通过共享addAgentMessages写入 session,随后commitAgentSession提交;capturedSinceCommit统计自上次提交以来的累积捕获量。

异常兜底main().catch保证任何异常都被记录(logError("uncaught", error))并输出{},不会因 Hook 失败阻塞 TRAE CLI 主流程。

5.3 字段映射trae-cli-turns.mjs

trae-cli-turns.mjs 负责 TRAE CLI Hook 输入字段的适配,核心是两个容忍性很强的解析函数:

  • resolveTraeCliPrompt(input):按promptuser_promptuserPromptmessagetext顺序取用户提问;
  • resolveTraeCliResponse(input):按last_assistant_messagelastAssistantMessageassistant_messageassistantMessageresponseoutputtext_content顺序取助手回复。

cleanTraeCliText会剥离上一轮注入的<openviking-context ...>...</openviking-context><relevant-memories>...</relevant-memories>标签,避免上下文标签被当作真实对话内容回写。buildTraeCliTurns则把解析出的内容组装成[{role:"user"},{role:"assistant"}]两元组并过滤空内容。

5.4 URI 守卫uri-guard.mjs

uri-guard.mjs 在PreToolUse阶段拦截危险的工具调用:

  • 工具名兼容tool_name/toolName/name/tool
  • 工具输入兼容tool_input/toolInput/input/arguments
  • 核心判定委托给共享的evaluateAgentUriGuard(toolName, toolInput):当本地文件工具(Read/Glob/Grep)或 Shell 工具(Bash/RunCommand/Shell)收到viking://虚拟路径时,返回permissionDecision: "deny"并附上permissionDecisionReason
  • 该文件同时具备“直接执行”与“模块导入”双形态:通过import.meta.urlprocess.argv[1]的 realpath 比较判断是否为入口执行,被测试导入时仅导出evaluateTraeCliUriGuard

5.5 测试覆盖

目录内附带了 trae-cli-hooks.test.mjs,用于验证字段映射与 Hook 分支逻辑。如果你要扩展 TRAE CLI 的字段兼容面,这是回归测试的锚点。

六、用户级安装形态:hooks.json 与 traecli.toml

6.1 Hook 配置文件

安装器渲染 hooks/hooks.json 时,把__OPENVIKING_TRAE_CLI_ROOT__替换为本目录的绝对路径,然后合并进当前TRAECLI_HOME/hooks.json。常见本地路径为:

~/.trae/cli/hooks.json

从 install.sh 的合并逻辑看,写入前会先过滤掉旧的 OpenViking Hook 条目(通过isOpenVikingHook识别openviking_integration_idsession-start.mjs/auto-recall.mjs/auto-capture.mjs/uri-guard.mjs/trae-cli-hook.mjs特征),并以原子写(.bak备份 + 临时文件 rename)落盘。

TRAE CLI 也支持在活动traecli.toml[hooks]段配置 Hook,但TUI 的/hooks命令显示的源才是真相(source of truth)。集成安装时优先使用用户级 hooks 文件,这样配置不绑定到单一工作区。

6.2 MCP 配置

MCP 应添加到活动traecli.toml[mcp_servers."openviking-memory"]段。项目级 MCP 文件(如<workspace>/.trae/.mcp.json<workspace>/.trae/mcp.json)TRAE CLI 虽然支持,但不是本集成推荐的写入目标。生效配置可用/mcptraecli mcp list确认。

6.3 排障与验证

  • /hooks:查看 TUI 中生效的 Hook 条目;
  • /mcptraecli mcp list:查看生效的 MCP 服务器;
  • 若已安装过旧版 OpenViking TRAE Hook 集,应替换或禁用旧条目,而不是把新草案并排在旁边——同时运行两套会导致 recall 与 capture 重复(每条提问被召回两次、每轮对话被捕获两次)。

安装器本身也会校验已安装的 Hook 入口与 MCP 配置。

七、与 Codex 不重用的部分

本适配器刻意隔离了 Codex 插件生态特有的机制,保持「仅 TRAE CLI 适配层」的纯净边界:

  • 复用 Codex 插件市场的元数据与安装命令;
  • 做 Codex 特有的${PLUGIN_ROOT}变量替换;
  • 复用 Codex 特有的PreCompact提交流程;
  • 解析 Codex transcript 的 JSONL 格式,也不使用cx-<session_id>会话前缀;
  • 做 Codex 本地压缩器的启动检测。

这也是该目录在 Codex 插件格式出现后走向废弃的根本原因:TraeCode CLI 2.0 直接兼容 Codex 格式插件后,独立的 TRAE CLI 适配层就失去了存在价值。

八、当前兼容性说明与扩展指引

三个生命周期 Hook 条目在设计上是可以复用的——只要 TRAE CLI 发送的 Hook 输入 JSON 贴近现有 thin harness 约定。各事件需要的关键字段如下:

用途可接受字段(按优先级)
会话身份conversation_idsession_idsessionIdgeneration_id
工作区cwdworkspace_rootsworkspaceRoots
用户提问promptuser_promptuserPromptmessagetext
助手回复(stop)last_assistant_messagelastAssistantMessageassistant_messageassistantMessageresponseoutputtext_content
工具调用名称:tool_nametoolNamenametool;输入:tool_inputtoolInputinputarguments

如果 TRAE CLI 后续版本改用其他字段名,只需适配 trae-cli-hook.mjs 或本地的文本清理/轮次解析逻辑 trae-cli-turns.mjs,共享的 OpenViking 运行时与 MCP 代理可以保持不变——这正是「适配层薄、共享层厚」这一架构的容错红利。

九、总结

examples/trae-cli-memory-hooks是 OpenViking 与 TRAE CLI 集成演进史上的一个重要过渡节点:

  • 它证明了「四个 Hook 事件 + 共享运行时 + 独立适配层」这套集成模型可以低成本覆盖新的 CLI 客户端——新增一个客户端只需写字段映射、事件分支与薄包装脚本;
  • 它明确区分了 TRAE CLI(trcli-前缀)与 TRAE / TRAE CN(tr-/trcn-前缀)的生命周期 Hook 输出协议差异;
  • 它的废弃并非架构失败,而是 TraeCode CLI 2.0 原生支持 Codex 插件格式后的自然收敛——存量用户应通过 install.sh 的--harness trae-cli迁移到 examples/codex-memory-plugin,并借助/hooks/mcptraecli mcp list完成新旧配置的核对与清理。

如果你正在排查旧安装的残留 Hook、迁移到新插件格式,或研究 OpenViking 的 CLI 集成模式,本目录的源码与本文的剖析可作为完整的参考基线。

【免费下载链接】OpenVikingSelf-evolving Context Database for AI Agents. Unify Agent Memory, Knowledge RAG and Skills.项目地址: https://gitcode.com/GitHub_Trending/op/OpenViking

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/10 6:14:23

使用 Refine + Supabase Auth 与 Twilio 构建 React OTP 短信登录

使用 Refine Supabase Auth 与 Twilio 构建 React OTP 短信登录 【免费下载链接】refine A React Framework for building internal tools, admin panels, dashboards & B2B apps with unmatched flexibility. 项目地址: https://gitcode.com/GitHub_Trending/re/refine…

作者头像 李华
网站建设 2026/9/10 6:12:44

蛇形机器人Matlab离散运动学建模与相位波控制

简介&#xff1a;本资源是一套基于MATLAB实现的离散蛇形机器人蛇形运动仿真控制系统&#xff0c;面向计算机、自动化、机器人工程等专业本科生及研究生&#xff0c;专为毕业设计、课程设计与期末大作业打造。项目经导师指导并获99分高分评价&#xff0c;代码完整可直接运行&…

作者头像 李华
网站建设 2026/9/10 6:07:59

农业无人机巡田系统:从遥感到变量植保的端到端闭环

简介&#xff1a;这是一款面向无人机开发者与农业智能化实践者的飞行控制APP源码包&#xff0c;聚焦近地空遥感、农田巡检、处方图生成与变量植保等实际应用场景&#xff0c;融合飞控逻辑、AI视觉识别&#xff08;人脸/颜色/二维码&#xff09;及多平台适配能力&#xff0c;适合…

作者头像 李华