npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

opencode-smart-approval

v0.7.1

Published

OpenCode command approval plugin with deterministic rules, Tirith scanning, and a restricted direct OpenCode approval agent.

Readme

opencode-smart-approval

License: MIT

English

一个 OpenCode 命令审批插件,组合严格的个人规则、Tree-sitter Shell 分析、Tirith 与受限的 OpenCode 直接审批 Agent。

这是应用层审批边界,不是命令沙盒。OpenCode、所选模型/Provider 以及所有同时加载的插件仍属于可信计算基。本插件用于减少误审批并对证据实行失败封闭处理;它不提供操作系统级文件系统或网络隔离。

要求与安装

生产契约固定在 OpenCode 1.17.14 的 @opencode-ai/plugin 及其根客户端。

npm install -g opencode-smart-approval

OpenCode 必须允许 Shell 工具,tool.execute.before 才能检查它。Provider 凭证与模型继续保存在用户的 OpenCode 配置中,例如:

{
  "permission": { "bash": "allow" },
  "plugin": ["opencode-smart-approval"],
  "small_model": "provider/reviewer-model"
}

如果 OpenCode 在执行前就 deny 或 ask bash,本插件不会收到该工具调用。可选的 small_model 按下文的模型优先级参与选择。

决策管线

每个受支持的 Shell 调用都复用同一份分析和同一个已加载策略快照:

配置访问守卫 → 用户规则 → 内置规则 → Tirith → OpenCode 直接审批 Agent

| 阶段 | 行为 | |---|---| | 配置访问守卫 | 已证实会写入当前审批策略的操作直接阻断;无法排除策略写入的操作不能走 allow 快速路径,而会继续审查。 | | 用户规则 | 完整的显式 deny 立即终止;完整显式 allow 也会终止,除非配置访问守卫强制审查。部分匹配、未匹配或显式 review 会继续。 | | 内置规则 | 为基础 Shell 连接与查看命令提供极小、平台无关的快速路径:Shell 谓词(true、false、test、[)、基础位置或目录查看(ls、pwd、basename、dirname)以及 command -v 查找,均不含重定向。其他所有命令,包括所有 Git 子命令,都必须审查。 | | Tirith | 扫描完整、未拆分的命令。block 立即终止;allow 或 warn 会携带扫描证据继续。 | | 审批 Agent | 创建隐藏的 OpenCode primary 审查子会话,验证最终运行时身份,提交带有 direct_question: null 的有界证据,解析一个严格裁决,并在失败时封闭。子会话的内置 question 被拒绝;首次未授权的 high 风险 needs_confirmation 会转交主机,由父级主会话持有并呈现绑定到精确命令、规范化 cwd 与 effect SHA-256 的问题。 |

对于管道或列表,必须所有静态解析出的可执行段都获准,allow 才能短路。任一段 deny 都拒绝整条命令。同优先级冲突按 deny > review > allow;先比较更高的整数 priority。

裁决接收器只接受恰好一个完整裁决,且只能是以下两种严格形式之一:前后没有任何其他内容的原始 JSON,或内容恰为该 JSON 的单个小写 json 代码围栏。裁决周围的文本、多个或歧义的 JSON 值,以及任何其他围栏语言都会被拒绝并失败封闭。

OpenCode 根客户端直连架构

生产代码复用插件收到的精确根 PluginInput.client。它不导入 SDK /v2 客户端、不构造另一个 OpenCode 客户端或服务器、不调用 opencode run,也不启动 OpenCode 子进程。按照 OpenCode 1.17.14 的声明,每个根方法只接收一个生成的 options 对象,其中 path、query、body 和 signal 位于固定层级。插件只捕获一次这些方法,并使用:

  • app.agents 与 app.log;
  • session.messages、session.create、session.prompt、session.abort 和 session.delete。

app.log 只用于有界、尽力而为的 late-create 清理诊断;它绝不发出审批裁决,也不记录命令、prompt、路径或 Provider 内容。

审查器确实会在已经运行的 OpenCode 实例中创建子会话,并以隐藏的 primary Agent 运行;该子会话不启用内置 question,其权限明确为 deny。隐藏 primary 是固定身份属性,并不把提问所有权交给审查器。不会启动额外 OpenCode 进程,插件会在每个终局结果之后无条件删除精确的自有子会话;需要确认时,问题由父级主会话持有并呈现。

1.17.14 的生成声明与运行时传输并不完全一致。生成声明暴露 builtIn、tools、maxSteps 及旧权限形状;实测 app.agents 运行时则暴露 native、steps、规范化权限规则,以及可为 null 的 hidden、topP、color、variant。运行时消息数据也包含滞后于声明的源字段。因此所有客户端响应先视为 unknown,再由严格、锁定到源代码的 schema 解析;未知字段、错误 null 规则、重复固定 Agent 或身份漂移都会失败封闭。

策略版本 3

可信全局策略位于 ~/.config/opencode/command-approval.jsonc,或 $XDG_CONFIG_HOME/opencode/command-approval.jsonc。文件不存在时会用 v3 默认值创建。

项目可以提供 ./command-approval.jsonc,但只有可信全局文件设置 "allow_local_config": true 时才使用。本地文件启用后会完整替代该项目的全局策略,因此应把已启用的项目策略视为可信代码。

最小有效策略是:

{
  "version": 3
}

省略 review 是默认且推荐的做法:所有 review 选项都会回退到默认值,LLM 审批审查仍然启用。review: {} 仍然有效且等价,但没有必要写。

版本 3 有意采用严格模式。顶层、review、self_protection、tirith、rules 以及每条规则对象都拒绝未知字段。字符串简写、别名、无版本/v1/v2 文档及旧 command-approval.json 文件名都会被拒绝,不提供兼容回退或自动替换。

策略选项

| 选项 | 默认值与契约 | |---|---| | version | 必填字面量 3。 | | allow_local_config | false;只从可信全局文件读取。 | | self_protection.enabled | true;启用尽力而为的配置访问守卫。 | | review | 可选对象。省略或写 {} 都保持下表所有默认值,并仍然启用 LLM 审批审查。 | | review.model | 默认不存在;出现时必须是精确 trim 的 provider/model 身份,model 部分可以包含后续 /。 | | review.timeout_ms | 45000;1000 到 300000 的安全整数。 | | review.context_messages | 20;0 到 200 的安全整数;0 禁用审查器对话上下文。 | | review.confirmation | "ask";"ask" 对符合条件的首次 high 风险审查使用宿主一次性确认路径,"deny" 则不提问并把同一情形收紧为终局拒绝。它绝不会削弱任何 deny。 | | review.prompt | 默认不存在;精确 trim 的非空可信策略后缀,最多 8,192 个 UTF-16 code unit。它附加在不可变安全契约之后,不能替换契约。 | | tirith.enabled | true。 | | tirith.path | 默认不存在;精确 trim 的本地二进制绝对路径会跳过自动下载。 | | tirith.timeout_ms | 5000;500 到 60000 的安全整数。 | | tirith.fail_open | false。 | | rules.deny、rules.review、rules.allow | 用户列表默认为空,之后仍合并极小内置规则集。 |

每条规则都是严格对象:必填非空 match,以及可选非空 reason、scope: "command" | "segment"、安全整数 priority。针对可执行文件的信任应使用 segment scope。只有分析得到恰好一个静态可执行节点时,command-scope allow 才有资格终止后续阶段。

模型优先级

固定审批 Agent 按以下精确顺序选择模型:

  1. 审批策略中的有效 review.model;
  2. OpenCode opencode.json 或 opencode.jsonc 中的 small_model;
  3. 省略 Agent 的 model 属性,让 OpenCode 继承其已配置选择。

只要策略中出现无效 model,策略加载就会失败,绝不会回退到 small_model。

从 v1/v2 破坏性迁移

配置兼容已明确移除,因此迁移必须手工完成:

  1. Provider URL、API key、Provider 插件及 Provider 模型定义继续放在 OpenCode 自身配置中。
  2. 创建 command-approval.jsonc,写入 version: 3;review 可选,默认省略。不要继续使用旧 .json 文件名。
  3. 将个人规则复制为 rules.deny、rules.review、rules.allow 下的严格对象条目。
  4. 只按上表加入当前 v3 的审查、Tirith、本地策略或守卫选项。
  5. 启动 OpenCode 后按报告的精确字段类别修正;加载器不会猜测旧语义。

下面是不能复制的已移除形状示例。严格加载器会先在 version 类别拒绝它,不会使用任何退役字段:

{
  "version": 2,
  "review": {
    "base_url": "https://api.example.invalid/v1",
    "api_key": "removed",
    "max_script_bytes": 20000,
    "max_tool_calls": 3,
    "max_retries": 3
  }
}

已移除标识包括 base_url、api_key、max_script_bytes、max_tool_calls、max_retries、rules.block、risk_tool、camelCase 别名、字符串规则简写及版本 1/2 迁移行为。Provider 传输和认证现在完全归 OpenCode 管理;审查器上限与工具由插件固定,不再由策略控制。

固定受限审批 Agent

配置钩子会在自身加载顺序位置覆盖固定名称 opencode-smart-approval-reviewer,并保留无关 Agent。独立冻结的预期配置包含:

  • 固定描述 Reviews one shell command for opencode-smart-approval using only the plugin-owned guarded reader. 及不可变安全契约;
  • mode: "primary"、hidden: true、steps: 4、temperature: 0;
  • 所选的可选模型;
  • 权限 map {"*":"deny","external_directory":"deny","question":"deny","opencode_smart_approval_read":"allow"}。

primary 模式与隐藏状态是固定身份属性,隐藏固定 Agent 让它不参与普通 Agent 选择。创建前及 prompt 前,app.agents 都必须暴露恰好一个匹配 Agent,并满足固定描述、prompt、mode、steps、temperature、model、空 options、native: false、不存在已启用的可选覆盖,以及以下精确最终规范化权限后缀:

| Permission | Pattern | Action | |---|---|---| | * | * | deny | | external_directory | * | deny | | question | * | deny | | opencode_smart_approval_read | * | allow |

OpenCode 可以在末尾追加一条宿主管理的精确 .../opencode/tool-output/* 目录 allow;再出现其他后续权限规则就验证失败。每次 session.prompt 还会发送精确工具 map {"*":false,"opencode_smart_approval_read":true}。

审批 Agent 被限制为恰好一个工具:插件拥有的受守卫读取器。内置 question 工具被拒绝;本插件也不会向审批 Agent 授予 Shell、网络、通用 read/list、write/edit 或权限管理工具。这是 OpenCode 工具调度限制,不是 OS 沙盒。

受守卫读取器边界

唯一由插件提供给审查器的工具是 opencode_smart_approval_read,严格参数为 path 与可选非负安全整数 offset(默认 0)。单次调用最多返回 65,536 字节。

访问必须同时匹配当前拥有的子会话 ID、固定 Agent 名称、规范化审查目录、worktree、活动 generation 以及未中止的 prompt。清理前先撤销所有权。

  • 工作区文件在锚定的 workspace 根下按需打开。
  • 工作区之外,只租约共享 Shell 分析静态引用、且位于规范化临时根或独立 worktree 下的精确现存文件;Agent 不能浏览整个临时目录。
  • 每个路径组件都通过锚定描述符遍历。最终目标必须是只有一个链接的常规文件;符号链接、硬链接、特殊文件、路径穿越、畸形路径和作用域逃逸都失败封闭。
  • 临时引用保留 activation 时打开的精确描述符快照;工作区读取在有界 read 前后比较描述符。撤销、路径替换或身份变化不能切换被审批的字节。

权威 POSIX 敏感路径谓词不区分大小写,并拒绝任何以 / 或 = 分隔、值等于 .env、.env.local、.git、.git-credentials、.netrc、.npmrc、.pypirc、.ssh、.aws、.docker、.kube、.azure、auth.json 的组件;任何以 .env. 开头的组件;.config/gh 与 .config/gcloud;以及精确 /proc/self/environ、/proc/thread-self/environ 或数字进程/task 的 environ 路径。反斜杠在 POSIX 中仍是普通字符。描述符遍历前,会分别对请求拼写、根相对拼写和绝对拼写应用此谓词。

上下文与授权边界

审查器可以看到有界证据:命令、规范化 cwd、工具参数、Shell 分析、匹配规则、Tirith 结果、静态引用及投影后的父会话 transcript。策略 context_messages 限制请求消息数;独立上限约束复制 envelope、单 part/总文本、part 数、工具名及完整序列化审查请求。独立的确认授权读取若超过完整 envelope 上限,只会针对这一种超限按最新消息窗口 32、16、8、4、2、1 有界重试。每次重试仍执行同一套复制、schema、身份、顺序、当前调用与 deadline 校验;若单条最新消息仍超限或精确调用边界不存在,依然失败封闭。synthetic/ignored 文本、附件、summary、不支持的 part 及畸形身份/顺序会失败封闭或被排除。普通父文本会作为有界 transcript 证据被复制,不会按短语形状擦除。

Transcript 文本只是证据,不是插件授权。用户可以在其中表达意图,审查器也可以独立判断某动作安全;但引用命令、助手文本、旧审批和泛化的“继续”都不会成为插件确认。只有审查请求中由宿主验证的 authorization_candidates 部分携带来源、当前轮次新鲜度、一次性状态,以及对精确完整命令、规范化 cwd 与 effect SHA-256 的绑定。自由文本的精确语义由审查器模型判断,宿主代码则确定性地执行周边契约。序列化的 direct_question 字段始终为 null;子审查器撰写的问题及 question part 都不能授权任何内容。

两条通道是分开的:投影后的 transcript 是有界证据,可以到达审查器与 Provider;authorization_candidates 则是宿主验证的授权通道。宿主验证控制候选的来源、新鲜度、绑定与一次性使用;它不是对任意 transcript 文本的语义擦除。

审查器独立评估命令固有风险与用户授权,运行时对 allow 只做收窄式一致性处理。高风险 allow 只有在 transcript 提供 medium/high 授权或有宿主验证的授权候选时才成立;critical allow 一律拒绝;low/medium allow 即使没有任何用户授权也可以放行。

一次性知情确认

常规 low/medium 风险审查必须直接返回 allow 或 deny,不能询问用户;critical 风险必须返回 deny。当 review.confirmation: "ask" 时,只有首次、未获授权且为 high 风险的审查可以返回 needs_confirmation,并给出具体 action、data、destination、risk。当配置为 "deny" 时,审查器与宿主都会把这个精确的可确认情形转换为 deny,不发出问题。该设置不能覆盖显式规则 deny、敏感数据或 critical 风险的强制拒绝、畸形证据、超时或任何其他失败封闭结果。在 "ask" 路径上,插件会阻断该次尝试,并渲染这四项、精确完整命令、规范化 cwd、effect/disclosure SHA-256、替换状态,以及一个固定选项为 Authorize once 与 Deny 的严格宿主会话内置 question payload。原生 OpenCode 可能省略默认的 custom: true 并显示 Type your own answer;只有精确 Authorize once 才授权按 request 路由的重试,其他结构有效的单个答案都拒绝该调用且不改变兄弟待处理调用。宿主至多询问一次;子 question part、low/medium/critical 的确认请求,以及已授权重试再次返回 needs_confirmation 都会失败封闭。

等待中或已询问的宿主确认不会仅因时间经过而过期。只有宿主收到精确肯定回复 Authorize once 时,300 秒的一次性授权窗口才开始。宿主绝不会截断披露字段;如果精确命令、规范化 cwd 或确认正文超过表示性上限,请求会失败封闭,而不是询问一个不完整的问题。

回退答案只授权一次对完全相同命令的重试,而且必须等临时 current-call 身份解析为真实的持久化 assistant/tool 边界之后。临时身份只按 call ID、工具与 effect SHA-256 命名当前调用,不会伪造 part 坐标;在宿主定位到恰好一条包含恰好一个匹配被阻断工具 part 的持久化 assistant 消息之前,回退不能被 claim,因此重试绑定到 transcript 中实际被阻断的命令 part。在该精确边界解析成功之前,待处理 handoff 继续等待,不授权任何重试。

授权证据有界且只能使用一次:

  • 最新普通父用户消息中的精确 prompt 预授权,只要精确覆盖命令、effect 与 disclosure,就可以作为首次审查的证据。
  • 对宿主会话 payload 的已完成匹配 question 答案,从肯定回复时起 300 秒内只授权一次匹配重试,且必须针对完全相同的命令。
  • question 被拒绝或出错时,至多允许一次有界的失败后普通用户回退。
  • question 答案与回退文本绝不直接创建 allow。每次被接受的重试都会按适用情况重新运行用户规则与内置规则、Tirith,以及一个全新的受限审查器,且该审查必须独立 allow。
  • 无论证据如何,critical 风险仍然一律拒绝。

重放、不匹配、过期、effect 或 disclosure 改变、边界被替换/驱逐、多个候选、歧义,以及未发出或伪造的 question 完成都会失败封闭。用户响应前的自动重试会继续等待,不会旋转 handoff。

并行工具调用

OpenCode 会把 Codex、Hermes 与 Provider 的工具调用归一化为同一种分发形状,并且可能在同一 prompt 下并发运行相互独立的兄弟调用。审查前分析可以重叠,但完整审查轮次会在每个精确父会话内按 FIFO 准入。不同父会话仍可并发,并可按相反顺序完成。这个窄准入队列不调度工具执行、宿主确认问题、工具结果、兄弟结果交付或全局插件工作,也不声称拥有批处理控制。每个审批调用仍由自己的 (sessionID, callID) 对在 before-hook 审批边界解析;没有兄弟调用会继承另一个调用的键。

每个兄弟调用仍保留自己的调用键审查状态、子会话与失败结果。同一父会话的交互式轮次按到达顺序执行;不同父会话的审查子会话与失败仍相互独立,可以乱序完成,一个兄弟 settle 或失败绝不会提供另一个兄弟的结果。同一个精确用户来源最多只授权一个兄弟:当两个调用解析到同一个普通用户 prompt 时,恰好一个 claim 该槽位,另一个只携带有界 transcript 证据而不 claim。所有已 claim 的授权都保持一次性。

一个回退 handoff 只属于一个调用。渲染副本携带精确的被阻断调用身份 blocked_call_id 与指向该调用的 call_reference,并命名精确命令、规范化 cwd、effect 与 disclosure SHA-256。回复与拒绝按精确 requestID 路由,因此两个待处理、显示前缀相撞的兄弟 handoff 不会互相干扰。未变化的重复渲染会复用同一份字节,而不是替换兄弟的 prompt,因此用户永远不会看到重复或被替换的兄弟 prompt。

删除或 dispose 父会话会移除所有待处理与已 claim 的兄弟状态,包括来源预留与请求映射。在 clear 或 dispose 之后到达的迟到事件不能复活交互,它们会被忽略,也不能新增任何授权 claim。

ToolPart 及其结果只由 OpenCode 持久化。插件不持久化或重排 ToolPart;它只消费发出的 transcript,发出的 part 的确定性顺序归 OpenCode 所有,而非本插件。

面向用户的错误安全

不可信工具名、规则/扫描器/Provider/审查器 reason、路径及确认字段统一经过一个 renderer。它转义反斜杠、引号、反引号、控制字符、双向控制符与 BOM;无效 UTF-16 在普通错误中安全替换,并使确认渲染失败。

普通阻断错误把转义后工具名限制为 1,024 字节、单条 reason 1,024 字节、reason 数 16、category 数 32、reason 聚合文本 8,192 字节、完整 body 16,384 字节。确认不会截断单个披露字段:转义后的 command 上限为 8,192 字节,完整 body 上限为 16,384 字节;超限就失败封闭。

审查会话生命周期

预检查成功后,每次审查在同一个共享 deadline 下最多顺序执行三次全新子尝试,同一时刻最多只有一个活动子会话。每次被接受的授权重试也会启动一次全新的受限审查器运行,因此任何证据都不会复用先前的审查结果。每次尝试都会创建自己的精确子会话,并按 ID、目录、固定 Agent 类型、prompt settlement 与 reader lease 跟踪;返回的子会话 ID 若已被使用过,则失败封闭。只有无效裁决(invalid verdict)可以重试,且必须在其异常清理成功之后。并发调用清理的调用方会加入同一个进行中的清理 promise,因此 idle、deleted、instance disposed、hook dispose、超时及 late settlement 路径不会删除外部会话或重复删除。已到达 deleted 的句柄,后续清理直接返回 already_deleted。非终态失败的清理会清空进行中的 promise,因此后续清理或 dispose 可以重试。

在同一父会话的交互式审查 FIFO 中等待时,只暂停该等待者自己的单调审查 deadline。准入时按非负排队时长平移原有 expiry,并保留同一个单调时钟,从而精确恢复入队时测得的剩余预算;绝不会重新授予完整 timeout。准入后,Agent 验证、子会话创建、prompt、重试与清理输入仍受恢复后的 deadline 约束。立即准入则原样保留原 deadline。

解析先对完成进行分类,再决定生命周期路径:完整解析出的裁决是普通完成,malformed_envelope、limit_exceeded、identity_mismatch 与 invalid_verdict 都是异常完成。只有无 question 的普通无效裁决可以重试:即没有任何子 question part、且不是有效 JSON 的裁决。每个子 question part 都是终局且不可重试;畸形 envelope、表示性上限、身份不匹配及跟在 question part 后的坏裁决也一样。普通完成先撤销 reader lease,再删除精确子会话。异常完成会先撤销访问,按需中止尚未 settle 的 prompt,在时限内 drain,然后尝试精确删除,因此无效或畸形尝试在重试之前必定被删除。匹配的外部 session.deleted 事件会被视为已删除。

session.idle 事件只 settle 恰好属于本插件的 prompt 并撤销 reader 访问,本身不会删除子会话。普通完成和所有异常终局路径都会删除精确子会话。Dispose 会对每个剩余的非终态自有句柄执行异常清理,包括已 idle settle 的句柄与 cleanup_failed 句柄;终态的 deleted 句柄已被移出 registry,不会被重新解释。

Tirith 完整性与离线行为

配置 tirith.path 时必须使用绝对路径。未配置时,插件选择平台资产,下载有界 release/checksum/archive 数据,校验上游 archive SHA-256,在严格条目/大小限制下解压,记录二进制摘要,并原子安装到缓存。

小于 24 小时的缓存只有在元数据及当前二进制摘要匹配时才复用。刷新不可用时,过期缓存只有在重新读取元数据并重新验证精确二进制、asset、release、archive digest 与 binary digest 证明后,才可明确返回 stale_verified。畸形上游数据、已变化/撤销 release、缺失证明或被篡改字节都不能走 stale 回退。扫描器执行失败按可信 tirith.fail_open 处理,默认失败封闭。

配置访问守卫的限制

self_protection.enabled 控制一个尽力而为的执行前守卫,保护当前 reload-effective 全局策略,以及仅在显式启用时的本地策略。它会阻断已证实的 Shell 重定向/写入器及已识别的 OpenCode write、edit、patch 目标。静态歧义会强制进入 deny 之后的审查路径,因此宽泛 allow 不能静默绕过;已证实的只读操作和相邻/非活动文件不会被误阻断。

该守卫不是文件系统 ACL,无法阻止手工编辑、其他进程、宿主/core 修改、未观测到的共存插件行为或所有 TOCTOU 竞争。未知文件工具与动态 effect 可能不可见,或只能强制审查。只有在其他控制已承担风险时,才应在可信全局策略中关闭它。

宿主、插件与沙盒信任

OpenCode 1.17.14 以进程为单位加载插件,不存在针对某个审查子会话的插件开关。本插件永不修改 OPENCODE_DISABLE_DEFAULT_PLUGINS 或 OPENCODE_PURE:

  • 启动后修改 OPENCODE_DISABLE_DEFAULT_PLUGINS 无法改变单个子会话;启动时设置它还会移除已配置模型依赖的内置 Provider 集成;
  • OPENCODE_PURE 会移除包括本审批插件在内的外部插件;
  • 两者都保持不变,用户现有 OpenCode/Provider 插件配置才继续作为权威配置并保持可用。

产品没有 pure 选项。只有后续、不会打包发布的 Todo 12 验证 harness 负责隔离的 boot-only disable-default-plugins 探针;生产代码不会复制该环境。

配置钩子会在自身加载位置覆盖同名 Agent,运行时字段/权限验证也能检测后续 Agent 修改。但 app.agents 既不暴露实际启用工具 map,也不提供工具定义来源。OpenCode 可能保留重复同名工具定义,而后续 session 组装可能选择更晚的共存插件定义。因此恶意或不兼容插件可以替换受守卫读取器实现或改变宿主行为。必须审查完整插件列表,并把共存插件与 OpenCode 本身视为可信。

固定 permission/tool map 只限制 OpenCode 调度,不隔离 Provider 代码、插件、宿主进程、文件系统 syscall 或网络访问。它们只限制 OpenCode 可以把哪些工具路由给审查器;不能替代宿主验证的授权检查。子 question 被拒绝且 direct_question 为 null,因此审查器撰写或篡改的问题不能授权任何内容。允许网络的更广 OS 沙盒仍然推迟,因为 OpenCode 配置/data/cache/state/Provider 访问需要单独设计。

隐私摘要

  • 所选 Provider 可以看到 direct_question: null 的有界审查请求,以及模型与唯一受守卫读取器的交互。宿主确认发生在父会话,而不是审查子会话。
  • 审批子会话位于现有 OpenCode 进程/数据库中,并在每个终局结果之后按精确 ID 删除。
  • prompt 预授权与回退文本可能保留在父历史中,并作为有界 transcript 证据到达审查器与 Provider。宿主验证的 authorization_candidates 通道不是对任意 transcript 文本的擦除。
  • Tirith 自动下载与模型/Provider 流量遵循各自配置的网络路径。
  • 插件不会启动 opencode run、构造第二个客户端/服务器,也不会改变 Provider/插件环境标志。

从 0.6.4 迁移

0.6.4 使用需要用户精确复述的生成确认短语。该协议已退役。审查子会话现在拒绝 question 并接收 direct_question: null。首次、未获授权的 high 风险 needs_confirmation 裁决可以产生一个绑定到精确命令、规范化 cwd、effect SHA-256 与被阻断调用的宿主会话问题;肯定回复从该回复时刻启动 300 秒的一次性重试窗口。无需修改配置:同一套策略、规则与审查器设置继续有效,每次被接受的重试仍会重新运行规则、Tirith 与全新的受限审查器。

开发

bun install
bun run typecheck
bun test

参考项目

许可

MIT