project-context Skill。chat.message 负责准备上下文并采集符合条件的用户提示词;experimental.chat.messages.transform 只把与当前会话、当前消息精确匹配的结果注入该轮次。PowerContext Server 始终单独运行。
安装并确认激活
opencode --version,再通过 opencode debug paths 找到配置目录。构建后的插件安装到 <config>/plugins/powercontext-opencode.js,Skill 安装到 <config>/skills/project-context/。两个目录各有归属清单;如果目标位置已经存在不归 PowerContext 管理的同名内容,安装会保留原内容并拒绝覆盖。
插件和 Skill 各自有恢复机制,但两者之间没有跨 Artifact 的事务回滚。I/O 在中途失败时,安装可能只完成一部分。此时应先检查两个目标目录,再重新运行安装,而不是把单个成功步骤当成整个集成已经完成。
powercontext doctor opencode 会检查可执行文件、版本、Skill、插件和激活状态。激活探测会短暂启动本机回环地址上的 opencode serve,轮询 GET /session,等待插件写入随机标识,然后停止进程。它不创建会话、不调用模型,也不验证 PowerContext Server、提示词 Hook、注入或权限界面。
跑通一次召回
Server 启动后,打开新的 OpenCode 会话:pc_* 工具。插件不会替你启动 Server。
这一轮在宿主中的实际顺序是:
experimental.chat.system.transform 只加入通用使用说明,不注入 PreparedContext。
Scope 与精确轮次
Scope 按以下顺序解析:- 已设置
POWERCONTEXT_OPENCODE_SCOPE_ID时使用该值;过长值会变成有界哈希。 - 否则使用会话目录。显式工具读取
context.worktree || context.directory。 - 插件寻找 Git 顶层目录,并优先把
remote.origin.url规范化为git:Scope。 - 没有可用远程仓库时,插件把项目根目录哈希成稳定的
local:Scope。
session.created 和 session.updated 更新目录缓存;没有缓存时,插件调用 client.session.get。session.deleted 会同时清除目录缓存和当前会话的已准备轮次。
每个会话只保存一个已准备轮次。转换时必须同时匹配 sessionID 和最新用户消息的 messageID,注入过一次后也不会重复注入。这个规则能阻止旧上下文进入错误轮次,但仍有一个乱序竞态:较早的准备如果最后完成,可能覆盖较新的缓存,使新轮次漏掉注入。它不会把旧内容注入新轮次;并发乱序行为仍为 Not validated。
PreparedContext 必须符合 powercontext.prepared-context.v1,并且 content_bytes 与实际 UTF-8 字节数一致。默认内容预算为 8,000 字节,可配置范围是 512–32,768 字节;HTTP 响应体另有 1 MiB 上限。注入内容会标记为宿主提供的不可信历史证据,并保留会话与消息 ID。当前测试证明转换路径不会显式写对话记录,但真实宿主是否持久化合成内容仍是 Not validated。
采集与刷新
采集会排除合成内容,并把用户提示词写成具有稳定来源信息的 Source。元数据包含来源、事件、当前目录、会话 ID 和消息 ID。采集默认开启;以下情况会跳过:POWERCONTEXT_OPENCODE_CAPTURE_PROMPTS=false;- 提示词疑似包含私钥或凭证;
- UTF-8 大小超过 200,000 字节。
flush_memory 循环;只有 current_cursor >= position 才算追上。错误、预算耗尽或游标落后都会 fail-open,且不能据此声称 Memory 已生成。OpenCode 没有在后续边界补偿刷新的队列,这条刷新路径也没有 OpenCode 专项端到端测试,因此状态为 Not validated。
自动路径不采集助手最终响应,也不记录 Task Outcome。
工具与权限
插件挂载 19 个精选 HTTP 工具,覆盖 Memory 读取与维护、手动准备和采集、Handoff 的激活/准备/定稿/提交/继续、Experience 与 Skill 的生成和读取,以及 Candidate 的只读列出与读取。 它刻意不挂载 Candidate 批准/拒绝/修订、工作契约(Work Contract)、Handoff 确认、Task Outcome、外部 Skill 注册和 Handoff 报告。需要人工治理的 Candidate 修改应在 Dashboard 或受控 API 客户端中完成。 八类持久修改在发出 HTTP 请求前都会调用宿主context.ask(),权限名为 powercontext。这些操作包括:写入 Memory、采集 Source、修订或停用 Memory、激活或提交 Handoff、生成 Experience,以及生成 Skill。这个边界是 Host-gated。pc_remember 的“询问后成功”路径已有测试;真实权限界面的允许/拒绝流程以及直接拒绝测试仍是 Not validated。
显式修改的载荷如果包含疑似敏感信息,也会在传输前被拒绝。该检查发生在 context.ask() 之后,因此宿主可能先询问,再返回 secret_rejected。
失败时应看到什么
自动准备、采集、注入和可选刷新都采用 fail-open。Server 不可用或会话上下文缺失时,普通 OpenCode 工作应继续,只是没有 PowerContext 上下文。显式工具错误必须对模型可见。配置无效时,插件发出警告并停用自己的 Hook,不让宿主进程崩溃。 发布前至少做这些负向检查:使用1.18.20 或 2.0.0 验证版本拒绝;在目标目录放入外部同名内容验证不覆盖;停止 Server 验证普通问题继续而显式写入失败;用不同消息 ID 验证不注入;逆序完成两次准备验证不会注入错误轮次;删除会话后验证缓存清空;拒绝 context.ask() 验证 HTTP 修改没有发出;让刷新游标持续落后,验证循环有界且不虚报 Memory。
当前证据边界如下:
配置默认值
不要把 Authorization 写进 URL、提示词或仓库示例。非本机回环地址必须使用 HTTPS。当前工作不应保存为 Source 时,在启动前关闭采集:
完成统一验证
先在固定 Scope 中用pc_remember 保存“修改 OpenAPI 契约后,重新生成并检查客户端”的决定,并通过 context.ask()。打开新会话,提出同一个问题。召回结果必须带 Citation,只能进入当前用户轮次的合成内容,不应在删除会话后继续出现。
随后停止 PowerContext Server,再问一个普通编码问题。OpenCode 应继续工作。再次调用 pc_remember 时,工具必须返回 unavailable 等明确失败,不能假装写入成功。
只有以下结果都可观察时,集成才完成:版本、Node.js 和安装诊断通过;插件与 Skill 目标归属正确;Scope 推导稳定;注入精确匹配会话与消息;敏感信息过滤只影响采集;显式修改经过宿主确认;自动失败与显式失败保持不同语义;上述 Unsupported、Not validated 和 Host-gated 边界没有被缩写成“已支持”。
下一页是 Pi。
