跳到主内容

OpenCode 2.2.6:run 等后台任务,CI 会挂死

OpenCode v2.2.6 于 2026-11-06 发布:run 会等自己起的后台命令、子代理与图片任务跑完才退出,官方明说没有时间上限,CI 必须自带 timeout;MCP 支持连接池,本地 API 收紧。

2026-11-08 · OpenCode 官方 Release Notes(GitHub Releases API 逐 tag 一手核对,2026-11-08)

发布 2026-11-08核实 2026-11-08

要点

  • v2.2.6(tag 时间戳 2026-11-06T23:37:20Z,prerelease: false)已转正,接替 10-30 的 v2.2.5;1.x 线仍停在 v1.19.5。
  • opencode run 改为等待后台任务:它自己起的后台 shell 命令、子代理、图片任务全部跑完,才让模型对结果作答再退出。等待时打印 waiting for N background job(s)(--format json 下是 background_wait 事件)。
  • 官方原文明确「没有时间上限」:永不退出的任务(dev server、文件 watcher)会让 run 一直挂着,CI 必须自己设 timeout。
  • 🆕 opencode run --worktree(-w):在新的 git worktree 里起会话,--worktree=<name> 可命名;不能与 --continue / --session 同用。
  • 🆕 opencode run --archived:会话创建即归档,不进 inbox、首页与会话列表,--continue 也会跳过。
  • 🆕 MCP 连接池:pool: true 让同配置的 MCP server 在多个项目间共享一条连接,进程更少、启动更快。
  • 本地 API 安全收紧:文件读取与媒体改走沙箱化下载;/api/* 拒绝跨站浏览器导航与非许可来源请求;webfetch 与 Code Mode 的 fetch 拒绝带凭据的 URL,权限匹配时忽略 #fragment,且 Code Mode 的 fetch 会逐个校验重定向。
  • 🆕 SIGTERM 语义明确:取消会话与其后台任务,退出码 143。
  • 其余:session_move 离开当前项目前要求 external_directory 权限;按 provider / model 配置会话预热(interval: "auto" 按缓存 TTL);新增 websearch.use 策略动作与 OPENCODE_FLAGS=all;实验性 Code Mode 字节码 VM(默认关)。

这条「修复」会直接打断 CI

官方把它放在 Bug fixes 里,原文是:opencode run 现在会等待它启动的后台 shell 命令、子代理与图片任务,等它们返回结果让模型看完,然后才退出。等待期间打印 waiting for N background job(s)。

紧跟着一句更关键:"There is no time limit"。一个永不退出的任务——典型就是 npm run dev 或文件 watcher——会让 run 一直开着,直到你按 Ctrl+C 或发 SIGTERM。官方给的处置建议是「CI 任务自己设 timeout」。

这条改动的合理性很清楚:以前 run 可能在后代任务还没跑完时就退出,把「做了一半」当结果交出去,那是更糟的假成功。但代价也很清楚:任何在后台上起过常驻进程的脚本,升级后都会从「提前退出」变成「永不退出」。

场景2.2.5 及之前2.2.6
纯问答型 run直接退出直接退出
run 里起过 npm run dev可能提前退出(假成功)一直等,永不退出
CI 里 run 超时看进程策略必须显式 timeout,否则占满 runner
中断方式进程被杀SIGTERM → 取消会话与后台任务,退出码 143

给 CI 的最小修法:timeout 900 opencode run ... 之类的外层兜底,并把 143 当「被取消」而不是「失败」处理。

三处安全收紧值得单独读

① /api/* 不再接受跨站来源

文件读取与媒体改走沙箱化下载,并拒绝跨站浏览器导航与非许可来源对 /api/* 的请求。官方给的威胁模型很直白:「项目里的一个文件不能对 server 的 origin 执行脚本」。也就是说,opencode serve 起在本机之后,别的网页不能借浏览器把本地文件读走。

这条对把 opencode serve 暴露在内网或容器的团队尤其重要——此前「本地 HTTP 服务」默认被当作安全边界内。

② webfetch 拒绝带凭据的 URL,权限匹配忽略 #fragment

https://user:pass@host/... 这类带凭据的 URL 现在直接拒;权限规则匹配时把 #fragment 忽略掉。第二条是绕过修补:以前 https://allowed.com/page#@evil.com 这类构造可能让规则判断与实际请求的目标不一致。

③ Code Mode 的 fetch 逐个校验重定向

这是最容易被漏掉的一条:只校验第一个 URL 的权限系统,会被一次重定向绕过。现在每一个跳转都要过 webfetch 规则。

其余值得注意的变化

  • run --worktree:脚本化任务默认落在新 worktree 里,不污染当前工作区;与 --continue / --session 互斥(因为那两个都指向已有会话)。
  • run --archived:CI 与脚本的运行不再刷满 inbox——这是「Agent 用量上来之后会话列表变成垃圾场」的正面解法。
  • MCP 连接池(pool: true):同配置 server 跨项目共享一条连接。代价是隔离性:多个项目共用一个 MCP 进程时,它的工作目录、环境变量、凭据作用域到底算谁的,官方本条没展开。
  • MCP 连接等待 2 秒:模型调用前会等仍在连接的 server 最多 2 秒,让「启动快但没连上」的 server 也能赶上第一次提问。以前这种情况是工具直接缺席。
  • 实验性 Code Mode 字节码 VM:默认关,要显式 experimental.codemode_vm: true 或 OPENCODE_FLAGS=codemode_vm。
  • npm 升级安装脚本恢复执行:此前被禁的 npm upgrade 安装脚本重新放行——这会重新引入「升级时装包脚本执行」的风险面,容器化环境之外的团队要自己权衡。

AI 之家 观点

一、「等后台任务跑完」是正确方向的正确实现,但它把复杂度转嫁给调用方了。 假成功是 Agent 最坏的失败模式:看起来完成了,实际只做了一半。修掉它是必须的。但官方选择不设默认上限,等于要求每个脚本化调用自己兜底——这在一个 90% 的用户是「复制文档里的命令」的产品里,不是个安全默认。合理做法应该是「默认有上限 + 可关」,而不是「默认无上限 + 记得设」。

二、这次最该被记住的不是新功能,是三条安全修补背后的同一个模式。 拒绝带凭据的 URL、匹配时忽略 #fragment、逐个校验重定向——三条都在修「规则看的东西和实际执行的东西不是同一个」。这跟 11-07 那轮 Claude Code 的四处权限绕过是同一类问题:Agent 的权限系统普遍建立在「文本匹配」上,而文本可以构造。 凡是「allow 一条 URL / 一条命令」的设计,都该按这个思路自查一遍。

三、run --archived 这个小开关透露了真实用法。 官方专门为「脚本与 CI 运行」加了一个「别进我的收件箱」的选项,说明相当多的人在用 opencode run 跑自动化,而且会话列表已经被这些运行刷爆了。这类「为高频用法打补丁」的功能,比任何 roadmap 都更能说明产品实际被怎么用。

四、给使用者的四条动作:① CI 里的 opencode run 全部补外层 timeout;② 把退出码 143 当「取消」而非「失败」,否则监控会误报;③ 容器 / 内网跑 opencode serve 的,升级后复测一遍 /api/* 的访问路径(跨来源请求被拒是行为变更);④ 用 MCP 的评估 pool: true 是否适合——省进程的代价可能是隔离边界变模糊。

待核实

  • pool: true 下 MCP 进程的工作目录、环境变量与凭据作用域——官方只写「同配置共享一条连接」。
  • waiting for N background job(s) 与 background_wait 事件的具体字段,以及能否通过配置限制等待。
  • --archived 会话是否有自动清理策略,以及归档后能否重新进入。
  • npm 安装脚本恢复执行的安全边界(是否只在本地升级生效)。
  • 会话预热 interval: "auto" 的实际触发规则——按缓存 TTL 推算,但 TTL 来源未说明。

相关阅读

来源

常见问题

为什么升级后 CI 里的 opencode run 不结束了?

这是 2.2.6 的行为变更:opencode run 现在会等它自己起的后台 shell 命令、子代理与图片任务全部结束,再让模型对结果作答后退出。官方明说没有时间上限——一个永不退出的任务(dev server、文件 watcher)会让 run 一直挂着,必须靠 Ctrl+C、SIGTERM 或 CI 侧 timeout 收尾。

怎么让脚本化运行不污染会话列表?

用 opencode run --archived,会话创建时就是归档状态,不会出现在 inbox、首页与 TUI 会话列表里,也会被 --continue 跳过。

SIGTERM 之后是什么行为?

官方写 SIGTERM 会取消会话及其后台任务并以退出码 143 结束。也就是说超时杀进程现在是「取消一次会话」的语义,而不是「进程硬死」。

相关对比

Aider vs Claude Code:终端 AI 编程双雄怎么选

Aider vs Claude Code 2026 选型对比:开源 BYOK 多模型 vs Anthropic 订阅长任务 Agent,从编程能力、多模型支持、价格、Git 集成、国内可用性和适合人群判断,帮你选对终端 AI 编程工具。

Aider vs OpenCode:两个开源终端 Agent,选哪个?2026 对比

Aider 与 OpenCode 2026 选型对比:同为开源终端 agent,Aider 以 Git-native 工作流与多语言支持见长,OpenCode 主打模型无关与 TUI 体验。从 6 个维度给出取舍建议。

Claude Code vs Cline:CLI AI Agent 怎么选?2026 对比

Claude Code vs Cline 2026 选型对比:Anthropic 官方闭源 CLI Agent vs Apache-2.0 开源 VS Code 插件。从模型绑定、工作流、MCP 支持、价格、隐私和适合人群 6 个维度帮你选对 CLI AI 编程工具。

Claude Code vs Codex CLI:终端 AI Agent 双雄对比

Claude Code vs Codex CLI 2026 选型对比:Anthropic 与 OpenAI 两大官方终端 Agent 的模型、长任务、MCP 生态、Windows 支持、订阅打包价格和国内可用性全方位对比,帮你判断该用哪个终端 AI Agent,以及能不能两个一起用。

Claude Code vs Crush:Anthropic 官方 vs 多模型 TUI(2026 实测选型)

Claude Code vs Crush 怎么选:Anthropic 官方 CLI(长任务最稳),对上 Charmbracelet 开源 TUI(多模型切换 + LSP)。按模型、长任务、价格对比。

Cursor vs Claude Code:什么时候用哪个?(2026 实测选型)

Cursor 和 Claude Code 到底怎么选?一句话结论 + 决策树 + 价格实测 + 国内可用性对比。GUI 派选 Cursor,终端长任务派选 Claude Code,最优解其实是共存。

相关评测