更新时间:2026-07-24
状态:候选实现已完成,等待发布门禁。当前分支已经具备 pma opencode、进程级 exact proxy、OpenCode 配置 adapter、continue/session 对既有 watch 的精确选择与复用、原生 session 归属、标题/command/compact 分类、同 Harness 翻译、确定性 wrapper/tool-loop smoke,以及真实普通多轮、工具、Skill、自定义 command、子 Agent 和 summarize 压缩证据。当前已验证的真实 provider driver 是 @ai-sdk/openai-compatible;其他 driver、三平台实机和最终发布门禁仍是合入/发布前工作。通用流程和验收门槛见 新 Harness 适配工作手册。
首版只适配 OpenCode CLI/TUI,不处理 OpenCode Desktop。
期望体验:
cd /path/to/project
pma opencodePMA 应在当前项目启动 OpenCode TUI,保持 OpenCode 原生 stdin/stdout、权限、模型选择和命令体验,同时打开或打印对应 dashboard URL。用户在 OpenCode 中进行普通对话、多轮、工具、Skill、压缩和子 Agent 操作时,PMA 捕获当前进程的 Trace。
原生参数应直接透传,例如:
pma opencode --continue
pma opencode --session <session-id>
pma opencode --fork --continue
pma opencode --model <provider/model>
pma opencode --agent <agent>
pma opencode --auto首版默认捕获当前 wrapper 启动的进程,不接管所有 OpenCode 会话,不扫描或复制用户既有会话。
以下内容来自 2026-07-24 的 OpenCode 官方文档。它们是设计输入,不是本机运行时证据;实现提交仍需记录目标版本、真实 help、fixture 和实验输出。
opencode默认启动 TUI;支持--continue、--session、--fork、--model、--agent、--auto和--port。opencode run提供非交互模式和 JSON event 输出,并支持 attach 到现有 server。opencode serve/server API 提供 session、message、child session、event、command 和 summarize 等语义接口。- 配置按 remote、global、custom、project、
.opencode、inline、managed 顺序合并;OPENCODE_CONFIG_CONTENT是 runtime override。 - 项目配置从当前目录向上查找到最近 Git 根。
- provider 可通过
options.baseURL覆写。 - OpenCode 使用 AI SDK/Models.dev;OpenAI-compatible provider 可能使用:
@ai-sdk/openai-compatible→/v1/chat/completions@ai-sdk/openai→/v1/responses
- 认证通常位于
~/.local/share/opencode/auth.json;PMA 不应读取或复制其内容。 - Skills 由原生
skill工具按需加载,模型先在工具说明中看到可用 Skill 的名称和描述。 - subagent 由 Agent/task 能力和权限控制;server API 可以观察 child sessions。
- compaction 提供
auto、prune、reserved等配置,server 有 summarize 操作。
官方参考:
2026-07-24 在 macOS arm64 上只读确认:
- OpenCode
1.18.4由 Bun 全局安装,入口位于~/.bun/bin/opencode; opencode默认启动 TUI,并在根命令支持--continue、--session、--fork、--model、--agent、--auto和--port;opencode run支持--format default|json、--attach以及同类 session/model/agent 参数;session子命令的当前 help 只列出list和delete;resume/fork 是根命令或run参数,不应被设计成session resume;debug paths报告 config/data/cache/state/log 和 SQLite DB 均位于标准用户目录;- 当前非敏感 provider 配置使用
@ai-sdk/openai-compatibledriver;provider id、base URL 和认证内容不写入公共证据文档; - 当前 shell 未设置
OPENCODE_*或XDG_*runtime override; - 本次没有读取认证内容、日志正文,没有发模型请求,也没有创建会话。
随后使用隔离 XDG 目录、loopback mock upstream 和真实 OpenCode 1.18.4 继续确认:
OPENCODE_CONFIG_CONTENT会与既有 provider/models/options 深合并;进程内只覆盖当前 provider 的baseURL时,driver、模型目录、header 和认证保持不变;- 当前
@ai-sdk/openai-compatibledriver 发送POST /v1/chat/completions,请求和响应都使用 OpenAI Chat Completions streaming; - 新会话先发无 tools 的 title-generation 内部请求,再发包含动态 tools schema 的主 Agent 请求;
- 两类请求都携带
x-session-id和x-session-affinity,且x-session-id与 CLI JSONL 事件公开的sessionID完全相同; - 因而第一轮尚无
--session参数时,Capture Proxy 也能在请求到达时精确学习 conversation id;该规则只对agent_profile=OpenCode生效,不泛化解释其他 Harness 的同名 header。
真实隔离项目和 provider 继续关闭了以下问题:
- 普通两轮、Read、Skill、自定义 command 和 Task 子 Agent 共形成 12 条 exact Chat Completions request,request index 连续;
- OpenCode 发送累计 message history;模型 tool call 属于当前下行,tool result 只在下一条上行出现;
- Skill 通过原生
skilltool call/result 进入链路;自定义 CLI command 的展开正文在 wire 上仍是普通 user message,因此必须依赖 wrapper 的本地 command 证据做额外 Harness 投影; - Task 子 Agent 产生独立模型请求,当前
x-session-id归属与共享子 Agent graph 可形成高置信 spawn/return 分支; - server
POST /session/:sessionID/summarize会发出独立模型请求,持久化 compaction 边界和summary: trueassistant message;下一次请求复用该 summary; opencode run --command compact是 generic command 路径,不等价于 TUI/compact/server summarize,不能作为压缩成功证据;- 同一会话不同轮次的首段 system 可能因 Skill 搜索路径顺序而变化。Context Delta 现在按 leading system/developer role 对齐历史,同时单独保留
fixed_context.system=changed,避免把整段累计历史误判成本轮新增。
仍未关闭的是 OpenCode server event 与 wire request 的通用合并协议、多个并行 child 的完整 lifecycle、非 @ai-sdk/openai-compatible driver,以及 TUI 任意内建 slash command 的稳定 lifecycle 证据。它们不能靠当前单一 provider 实验泛化。
OpenCode 的 provider 配置决定模型请求可能是 Anthropic、OpenAI Chat、OpenAI Responses 或其他 AI SDK provider 形态。因此:
- 不创建一个假定固定 request schema 的
opencode-normalizer; - adapter 负责发现和覆写当前 provider 的 base URL;
- Capture Proxy 保留真实 path/body/response;
- 共享
request-profile和model-response-normalizer再根据真实证据判断和解析协议;adapter 不解释展示语义; - 新协议必须先加入脱敏 fixture,再扩展共享 Trace 模块;
- 未知协议保持 Raw 可见并标为 unsupported,不伪装成完整整理结果。
CLI wrapper 的默认目标是 exact proxy。OpenCode server/event API 可以补充:
- session id;
- parent/child session;
- permission 和 tool lifecycle;
- command/summarize 生命周期。
但这些语义事件不自动等价于模型 wire request。二者需要独立 provenance,后续再按稳定 identity 合并。
当前已有 wire request 与 OpenCode 主 session 的精确 x-session-id 关联证据,并已在真实 Skill、Task child request 和本地 summarize 实验中验证对应 wire/lifecycle 形态。当前产品仍以 wire capture 为事实源;server event 只在未来存在稳定 identity contract 时作为补充来源,不能覆盖或改写 exact request。
优先方案是:
- 读取 effective provider/model 的非敏感配置;
- 用
OPENCODE_CONFIG_CONTENT注入仅当前子进程生效的 provider baseURL override; - 继续让 OpenCode 自己从原位置读取认证;
- 子进程退出即失效,无持久配置恢复负担。
实现前必须通过 mock 和真实 provider 实验证明:
- inline config 的深度合并语义;
- provider/model 级
npm与baseURL不会被意外覆盖; - project config、managed config 是否可能阻止 runtime override;
- OpenCode 是否把 baseURL 解释为 API 根还是完整 endpoint;
- Chat Completions/Responses/Anthropic 三类 path 的转发规则。
若 runtime override 不能可靠工作,才评估临时 custom config;不得直接 patch 全局或项目配置。
建议新增:
src/adapters/opencode/
discovery.mjs
config-overlay.mjs
runtime.mjs
capabilities.mjs
也可以在首个小提交中使用更少文件,但职责必须保持:
discovery:可执行文件、版本、cwd/project、provider/model、协议候选;config-overlay:构造进程级 runtime override,不含 secret;runtime:启动、watch、proxy、stdio、信号、退出和幂等清理;capabilities:new/resume/fork/proxy/server-events/translation/subagent 等显式能力。
provider-specific path/header/body 规则只有在真实 fixture 证明共享 Proxy 无法处理时才增加;展示语义继续由共享 Trace Domain 所有。
平台差异放在 src/core/platform.mjs、app-paths.mjs 或 process-tools.mjs,不散落在 adapter 和 CLI。
bin/peekmyagent.mjs 当前仍是较大的入口。OpenCode 不应继续复制整段 Claude/OpenClaw lifecycle。
首版应先抽一个最小共享 wrapper runner,至少统一:
- argv/cwd/stdin/stdout;
- watch start/reuse/stop;
- dashboard URL;
- child exit code 与 signal;
- cleanup stack;
- 临时环境覆盖;
- 错误诊断脱敏。
只抽 OpenCode 实现真正需要、且能由现有 Claude/OpenClaw 行为测试证明的部分。不要借机重写整个 CLI。
硬性边界:OpenCode adapter 只能产出 Capture/provenance/capability/Trace Domain 可消费的 DTO。Server 负责装配服务,Viewer 只消费共享 DTO。不得为 OpenCode 在 src/viewer/server.mjs、SourceRepository、Viewer API route、client.js 或 renderer 中新增 Agent/provider 条件分支。
默认复用:
CaptureRecord与 provenance;- Persistence content blobs;
- SourceRepository;
- request profile;
- content parts;
- tool call/result semantics;
- model response normalizer;
- ViewerTraceProjector;
- Raw/History/Message/Response;
- 翻译材料、缓存、搜索和 Trace bundle。
只有真实 OpenCode fixture 证明差异时,才修改:
- Harness marker 白名单;
- compact/summarize 生命周期;
- subagent identity;
- OpenCode 特有动态 tool call 类型;
- Source capability 和 Agent 文案。
输出一份不含 secret 的报告:
which/type -a opencode、真实路径、版本;opencode --help、run --help、session --help、models --help;- effective config 层级和路径;
- 当前 provider/model id 与 npm driver;
- 认证“存在/不存在”,不输出值;
- session 存储、project id、日志和 server API;
- 支持的 runtime override 环境变量。
使用隔离 HOME 和 fake provider:
- global/project/inline 分别设置不冲突和冲突字段;
- 验证
OPENCODE_CONFIG_CONTENT最终合并; - 验证只改 baseURL,不丢 model、permissions、agents、plugins 和 tools;
- 正常、非零、SIGINT 后用户文件 hash 不变。
分别验证至少两个 provider driver:
- OpenAI Chat;
- OpenAI Responses;
- 若当前真实配置使用 Anthropic,再补 Anthropic。
记录:
- path、method、content encoding、stream format;
- 保留/移除哪些 hop-by-hop headers;
- auth 只在内存转发;
- request/response size limit;
- upstream error、429、断流和取消传播;
- captured artifact 与 forwarded bytes 的关系。
连续两轮回答:
- session id 是否在 request 或本地 API 中可见;
- History 和 Message 差分是否正确;
- request index 是否连续;
- complete response、usage、stop reason 是否完整;
- resume 后是否复用同一 Source 或建立可解释的新 watch。
使用只读命令,例如查看当前目录:
用户上行
→ 模型下行 tool call
→ OpenCode 执行
→ tool result 上行
→ 模型最终回复
验证主时间线交错、call id 配对、Raw 和整理视图一致。
- 模型最初看到的是 Skill 清单还是完整正文;
skill调用的工具参数和结果;- Skill 正文随后如何进入上下文;
- slash command/project instruction/plugin 注入如何标为 Harness;
- 不把用户正文中的同名 XML/Markdown 误判为注入。
当前已为 CLI --command <name> 建立强证据链:wrapper 把规范化 command name 放进进程级 provider header,Capture Proxy 本地保存后在上游转发前移除;共享 Harness 投影使用该证据定位 command 展开的 user message,并继续在 History/Message 保留原文。确定性测试同时覆盖真实投影、普通 slash 文本反例和非法 header 值。TUI 内建 slash(例如 /compact)没有该 CLI 参数证据,仍需依靠 OpenCode 原生生命周期或经过真实 fixture 验证的精确模板,不能套用这条规则。
OpenCode 首轮实验按工作手册中的 Harness 注入识别规则记录每个候选块的:
- 原始 role、content index 和 JSON path;
- 是否有 command envelope、metadata 或本地 lifecycle event;
- 标签是否结构完整、是否在不同轮次和版本中稳定;
- 同一文本是否仍保留在 History/Message;
- 用户正文包含同名 slash/tag 时是否会被误判。
首版只允许“实验证明的白名单 marker + 明确命令 envelope”。单纯以 / 开头、包含 system/skill/agent 关键词、使用 XML/Markdown 或位于 developer role,都不足以单独判定 Harness 注入。
E5 当前结论:
- CLI 自定义 command 已进入实现,且本地
x-peek-opencode-command证据在 Capture 保存后会在上游转发前移除; - 真实 Skill 场景已经观察到
skilltool call/result,无需增加 OpenCode 专用 Viewer; --command <name>的展开正文继续保留在 History/Message,并额外投影到 Harness;- TUI
/compact的 OpenCode1.18.4精确模板已识别为harness_compact,并有普通用户讨论“summary”不被提升的反例; - 其他 TUI 内建 slash 没有稳定 command metadata 时仍保持 Message/Raw,不按
/前缀猜测。
- 自动压缩触发点;
- summarize 是否产生独立模型 request;
- 被保留/裁剪的 message;
- prune 与 summary 的区别;
- 压缩后首条 request 的 History/Message;
- 本地 lifecycle event 与模型 HTTP 交换分别记录。
当前通过隔离 HOME/XDG、loopback OpenAI-compatible mock 和真实 OpenCode server 验证:
- 普通消息先产生主模型请求;
POST /session/:sessionID/summarize产生独立 summarizer 模型请求;- summarizer system 以 anchored context summary assistant 自述,user prompt 以
Create a new anchored summary from the conversation history.开始; - OpenCode 持久化 compaction boundary 与
summary: trueassistant message; - 压缩后的下一条模型请求携带生成的 summary。
该实验不使用真实凭据,命令为 npm run experiment:opencode-compaction-local。它验证当前版本的真实压缩机制,但不把尚未捕获的 server event 冒充 wire request。
- task tool 的 call/result;
- child session id 和 parent id;
- 子 Agent 是否独立发模型请求;
- 多个 child 如何区分;
- child tool calls/results;
- return/failure/cancel;
- server events 与 wire capture 如何用确定 identity 关联。
没有稳定 identity 时,先显示独立请求和“可能关联”证据,不建立高置信分支。
当前真实 Task 场景已验证一个 child:主请求出现 task call,child 产生两个独立模型请求,随后 result 回流主会话;共享 graph 形成 spawn=1、return=1、confidence=high。多个并行 child、失败、取消和跨版本 event 仍需后续 fixture,不能从单 child 成功例外推。
- provider/model 不存在;
- auth 不存在;
- 端口占用;
- proxy 上游失败;
- OpenCode 非零退出;
- Ctrl+C/SIGTERM;
- wrapper 崩溃后的 doctor;
- 无残留临时配置、进程、端口、watch 和测试 Source。
- 本文及 Evidence Pack;
- 本机 OpenCode 版本事实;
- 配置合并、协议和 session 实验结论;
- 明确 unknowns。
pma opencode命令解析与 help;- fake OpenCode + mock upstream;
- 进程级 config overlay;
- watch/proxy/退出/清理;
- 不接真实账号。
- 一个真实 provider 的普通多轮与工具闭环;
- 脱敏 fixture;
- provenance、Source 和 Raw;
- 默认不支持的协议显式报错。
- System、Tools、Harness、History、Message、Response;
- 翻译、搜索、复制和缓存;
- 大 Trace 渐进加载;
- export/import;
- OpenCode 独立 Source 分组。
- Skill;
- compaction;
- subagent;
- server semantic events 与 wire evidence 合并。
四项彼此独立,分别要求 fixture、provenance 和必要的 identity contract。server event 的存在本身不能证明模型 wire 语义。
- 当前平台 Level 2;
- 三平台 hosted CI;
- Windows/Linux 真实机器;
- Claude/Codex/OpenClaw 最小真实回归;
- README/help/architecture/manual matrix/i18n;
- npm candidate 验证。
当前 OpenCode 聚焦入口:
smoke:opencode-config
smoke:opencode-classification
smoke:run-opencode
smoke:translation-opencode-cli
experiment:opencode-local-mock
experiment:opencode-real-integration
experiment:opencode-compaction-local
前三项和翻译项是无凭据确定性 smoke;后三项依次验证真实 OpenCode protocol、真实 provider 集成和本地模型压缩。其中真实 provider 集成必须人工确认当前 provider 可用,不进入无凭据 release gate。
聚焦复用:
smoke:proxy-openai
smoke:proxy-attribution
smoke:provenance-contract
smoke:request-profile-contract
smoke:message-semantics-contract
smoke:tool-call-semantics-contract
smoke:model-response-normalizer-contract
smoke:viewer-trace-projector-contract
smoke:viewer-translation-adapter-contract
smoke:viewer-i18n-contract
既有 Agent 最小回归:
smoke:run-claude
smoke:daemon-claude
smoke:claude-settings-env
smoke:codex-exact-proxy
smoke:codex-exact-viewer-integration
smoke:run-codex-capture
smoke:run-openclaw
smoke:openclaw-profile-cleanup
smoke:normalize
这些命令是候选入口,不是固定套餐。实际回归由改动边界决定:
| 改动 | 至少增加的真实/确定性行为 |
|---|---|
| wrapper/process | Claude、Codex CLI、OpenClaw 的正常退出、非零退出与清理 |
| Proxy/provenance | 三类来源普通消息和一轮 exact capture |
| protocol normalizer | 受影响协议的多轮、tool call/result 和 complete response |
| semantics/projector | 既有来源 Timeline、History/Message/Response 与 Viewer detail |
| translation | 已知 Agent 的 provider 选择、材料、缓存和 i18n |
会重启 Codex Desktop 的测试不得加入默认 gate。真实 OpenCode 账号测试进入 docs/manual-integration-smoke-matrix.md,不进入无凭据 release gate。
OpenCode 翻译已接入共享 provider policy,当前实现满足:
- Source 明确标记
agent_profile=OpenCode; - 优先使用 OpenCode 可用的低成本模型/低 reasoning 配置;
- 不得因为 OpenCode 翻译不可用而静默启动 Claude CLI;
- 未配置 provider 时显示可行动的诊断,不读取认证文件内容;
- System、单工具 description、单 schema field、单 Harness 注入继续复用共享 block hash;
- 同一原文跨 Source 可复用全局翻译块,History 只按会话内内容复用。
实现通过进程内 inline config 创建无工具、禁分享的专用翻译 Agent;材料经 stdin 输入,不进入进程参数。模型选择优先同一 provider 中的 small_model 或明显更轻量的已配置模型,失败时才回退到用户已配置的默认 OpenCode 模型。每次调用解析 JSONL 中的 session ID 并执行 opencode session delete,同时以 deterministic fake CLI smoke 约束密钥不输出、Claude 不回退和清理行为。真实 provider 验证仍属于手工集成门禁。
继续推进真实场景适配前仍须关闭以下问题:
- 不同 provider driver 的 baseURL 拼接差异;
- server event 与 provider request 的稳定关联键;
- 多个并行 child、失败/取消与子 Agent wire request 的完整关联;
- TUI 内建 slash command(除已验证
/compact外)的稳定 lifecycle 证据; - plugin/custom tool 是否增加新的动态 call 类型;
- managed config 是否可能禁止 runtime override;
- OpenCode 更新导致协议漂移时的版本 gate。
未知项应在实验报告中逐条关闭。不能为了尽快显示 UI 而用启发式答案代替。
OpenCode CLI 适配“可合入”意味着:
- 用户可以从任意项目目录运行
pma opencode; - 原 OpenCode 交互、权限、模型和退出码不变;
- 默认只捕获该进程,不接管历史会话;
- 至少一个真实 provider 的多轮和工具闭环是 exact wire;
- Viewer 能准确区分原始证据、语义事件和推断;
- System/Tools/Harness/History/Message/Response 和 Raw 范围正确;
- 配置、认证、端口、进程、watch 和测试 Source 清理通过;
- 翻译不可用时不错误回退到别的 Agent;
- 新适配器和既有 Agent 的聚焦回归、当前平台 release profile、三平台 CI 全绿;
- 当前事实、限制、用户命令和验证 SHA 已写入文档。
截至本文更新时间,功能与聚焦实验已经满足前八项;当前平台 Level 2、三平台 CI、候选 SHA 实机验证和 npm 发布仍属于 M5,完成前只能称为分支候选,不能称为已发布支持。