Skip to content

fix(launcher): warn when opencode project-layer config bypasses the proxy - #844

Merged
ranxianglei merged 2 commits into
masterfrom
2026-09-16_opencode-project-bypass-warning
Sep 17, 2026
Merged

ranxianglei merged 2 commits into
masterfrom
2026-09-16_opencode-project-bypass-warning

Conversation

@ranxianglei

Copy link
Copy Markdown
Owner

#843 的修复(方案 (b):检测+警告,issue 中 owner 建议的最小可行路径)。

根因(已 hands-on + 源码双重验证)

launcher 经 $OPENCODE_CONFIG=<临时文件>(env 级)交付改写后的 provider baseURL,但 opencode 的配置优先级是 project 层 > $OPENCODE_CONFIG > global XDG(本机 opencode 1.14.46 opencode debug config 实测,并对照 sst/opencode dev 分支 packages/opencode/src/config/paths.ts / config.ts 合并顺序确认):

  1. 场景 1:项目文件重定义了同名 provider → 项目值胜出 → 流量直连上游,无压缩、无警告;
  2. 场景 2:provider 仅存在于项目文件 → readOpencodeConfig 只读 global + $OPENCODE_CONFIG,discovery 根本看不到它 → 无改写、无警告。

改动(仅检测+警告,不改变任何运行时行为)

  • src/client-config.ts:新增 readOpencodeProjectLayer(cwd) —— 复刻 opencode 的项目层发现规则:从 cwd 向上走到 git 根为止(无仓库则到文件系统根);每层检查 <dir>/opencode.json{,c} 与 <dir>/.opencode/opencode.json{,c};支持 jsonc 注释与尾逗号;同名 provider 由最近层胜出,记录 blame 文件。
  • src/launcher.ts:新增 opencodeEffectiveCwd(识别 opencode 唯一的配置相关 flag --dir)与 opencodeProjectBypassWarnings:项目层中未被 bili 路由的显式 baseURL(/bili/ wrapped 形式或已在 MITM domains 的 https host 视为已路由)分两类警告——重定义了 discovery 可见的 provider,或仅存在于项目层;baseURL 缺失的条目会经 opencode deep-merge 继承交付值,不告警(避免误报)。launch 时逐条打印,风格对齐 hermes/kimi 先例("traffic will NOT go through the proxy")。
  • tests/launcher.test.ts:新增 4 个测试(git 边界 walk/nearest-wins/.opencode 目录/jsonc、无 git 多层 walk、--dir 解析、警告矩阵含各静默场景)。

验证

  • npm run typecheck ✅
  • npm test:1515 pass / 0 fail / 2 skipped(gated e2e)
  • npm run build ✅
  • E2E(构建产物 + BILI_CLIENT_BIN shim + 伪造 HOME):项目目录跑 bili opencode 精确打印两条预期警告(含 blame 文件绝对路径);干净 cwd 无任何警告。

遗留(报告,不在本 PR 范围)

  • OPENCODE_CONFIG_DIR 环境变量同样压过 $OPENCODE_CONFIG(同类绕过,更罕见)——留给后续评估;
  • 方案 (a)(discovery 补项目层)按 issue 结论"再评估";注意单独做 (a) 修不了场景 1(运行时 project 仍压过 env),只能让信息更全;
  • hermes 的配置源模型仍未验证(issue 原文已注明)。

Fixes #843

@ranxianglei

Copy link
Copy Markdown
Owner Author

🤖 Powered by ework · qwen3.8-27b

[bot] 🏷 收到。这是 [PR] issue(PR #844,分支 2026-09-16_opencode-project-bypass-warning)。按规范不重做,正在:拉取分支核对代码 → 本地跑 typecheck/test/build → 检查 CI 状态与 diff 整洁度(注意 mergeable_state 目前是 dirty,master 已前进,可能需要 rebase)。稍后给出结论。

…roxy

opencode's config precedence puts the project layer above the
$OPENCODE_CONFIG tempfile the launcher uses to deliver rewritten
provider base URLs, so project-level providers silently bypass the
proxy (no compression, no warning). Detect the project layer with the
same walk rules opencode uses (git-bounded ancestor walk, .opencode
dirs, jsonc comments/trailing commas, nearest level wins) and print a
per-provider warning naming the offending file. No runtime behavior
change.

Fixes #843
@ranxianglei
ranxianglei force-pushed the 2026-09-16_opencode-project-bypass-warning branch from a1396f9 to 0b64514 Compare September 16, 2026 08:03
@github-actions

github-actions Bot commented Sep 16, 2026 •

Copy link
Copy Markdown
Contributor

📦 Built Package Artifact

Branch: 2026-09-16_opencode-project-bypass-warning (c908e46)

Option A — Install from npm PR tag (recommended)

npm install -g billion-context@pr-844

Each push to this PR publishes a new version under the pr-844 npm tag.

Option B — Download artifact

  1. Download the artifact from the Actions run
  2. Extract the tarball and install:
tar xzf billion-context-pr844.tgz
npm install -g package

Install instructions are refreshed on each push.

Windows CI: path.resolve('/x/y') yields D:\x\y there, so asserting the
POSIX literal verbatim only holds on POSIX. Use a real mkdtemp abs path
(resolve preserves it on every platform) instead.
@ranxianglei

Copy link
Copy Markdown
Owner Author

🤖 Powered by ework · qwen3.8-27b

[bot] 🏷 Review complete — branch rebased onto current master, one CI-breaking test bug fixed, everything green. Ready for you to merge.

Code review (the change itself)

  • Warning-only, no runtime behavior change — matches plan (b) from [launcher] opencode: project-level opencode.json overrides launcher rewrite — silent compression bypass #843. Call site in runLaunch just prints via console.error, consistent with the other launcher warnings (hermes/kimi precedent).
  • isBiliRouted correctly silents /bili/-wrapped URLs and MITM-whitelisted https hosts; baseURL-less entries stay silent (deep-merge inheritance) — no false positives.
  • Project-layer walk semantics (git-root bounded, nearest-wins, .opencode dir, jsonc) are covered by the 4 new tests in tests/launcher.test.ts:3920-4019.

What I had to do (branch was 78 commits behind master)

  1. Rebased a1396f9 → origin/master (50f8f9f). Three conflicts, all adjacent additions of independent code — resolved by keeping both sides:
  2. Small cleanup while resolving: your hand-rolled jsonc parsing (stripJsonComments + dropTrailingCommas + parseJsoncFile, ~80 lines) duplicates what master already has — readConfigFileRoot (JSON.parse → vscode-jsonc-parser parseJsonc {allowTrailingComma:true}, same parser readOpencodeConfig uses). Switched readOpencodeProjectLayer to reuse it and dropped the duplicates. Diff shrank from +305/−1 to +224/−1; identical behavior on valid json/jsonc, all 4 new tests still pass.
  3. Windows CI failure found & fixed (new commit c908e46): opencodeEffectiveCwd: honors --dir asserted path.resolve("/x/y") === "/x/y" — true on POSIX, but on Windows path.resolve yields D:\x\y, so both windows jobs failed. Production code is correct (resolving --dir against cwd is exactly opencode's semantics); the test expectation was platform-bound. Rewrote it with a real mkdtempSync abs path (resolve preserves it on every platform) — no platform-specific literals.

Verification on final head c908e46

  • Local: npm run typecheck ✅ · npm test 1651 pass / 0 fail / 2 skipped (gated e2e) ✅ · npm run build ✅
  • GitHub CI: 7/7 green — test matrix ubuntu 22/24 + windows 22/24, version-guard, build-artifact, real-codex zero-token e2e.
  • PR state: mergeable_state: clean, base master, 2 commits.

Residuals from your write-up stand (noted, not blocking): OPENCODE_CONFIG_DIR env is the same bypass class (rarer, left for later evaluation); hermes config model still unverified.

一句话中文:分支落后 master 78 个提交无法直接合并——已 rebase 解决三处冲突(均为相邻新增、无逻辑交集),顺手把 PR 里 ~80 行手写 jsonc 解析替换为复用 master 已有的 readConfigFileRoot,并修复了 Windows CI 上因 path.resolve("/x/y") 平台差异而挂掉的 --dir 测试断言(生产代码本身正确);本地 typecheck/1651 项测试/build 全绿,GitHub CI 7/7 通过,PR 已处于 clean 状态,可以合并。

@ranxianglei

Copy link
Copy Markdown
Owner Author

继续

@ranxianglei
ranxianglei merged commit fb76c90 into master Sep 17, 2026
7 checks passed
@ranxianglei
ranxianglei deleted the 2026-09-16_opencode-project-bypass-warning branch October 15, 2026 05:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[launcher] opencode: project-level opencode.json overrides launcher rewrite — silent compression bypass

1 participant