feat(#640,#653,#655): client support batch — codebuddy + qoder + trae - #693
Conversation
…me (Windows) On Windows os.homedir() does not follow HOME, so resolveCodebuddyHome fell back to the real user profile and the temp-home config files were never found (discoverMitmDomains returned []). Pass CODEBUDDY_CONFIG_DIR in the helper env, parallel to the existing CODEX_HOME / ZCODE_DATA_BASE_DIR / PI_CODING_AGENT_DIR overrides. Fixes the windows-latest CI failure on PR #641.
qoder's model endpoint scheme is hardcoded https with no base-URL override env, so /bili/ rewrites cannot reach it — cert-MITM is the only route (qoder's built-in undici honors HTTPS_PROXY + NODE_EXTRA_CA_CERTS). - client-config: QoderConfig, qoderIsCnSite (QODERCLI_SITE / CN-prefixed envs / on-disk config dir), resolveQoderHome, readQoderConfig (settings.json model, QODER_MODEL_SERVER_HOST), QODER_DEFAULT_MODEL_HOSTS - launcher: bili qoder (proxy mode) — HTTPS_PROXY + NODE_EXTRA_CA_CERTS + BILLION_CONTEXT_PROXY, default model hosts whitelisted for MITM (or the QODER_MODEL_SERVER_HOST override), QODER_MODEL_TRANSPORT=http forced (legacy fallback wire unverified), #321 budget alignment via QODER_AUTOCOMPACT_WINDOW / QODERCN_AUTOCOMPACT_WINDOW, qoder/qodercli binary resolution - discover: qoder hosts in MITM domain auto-discovery - cli/README/AGENTS: help + docs Fixes #653
Trae CLI (ByteDance) is a closed Go binary with no base-URL override, so /bili/ rewrites cannot reach it — cert-MITM is the only route (the Go runtime honors HTTPS_PROXY; the CA rides SSL_CERT_FILE, the combined bundle, since it replaces Go's system trust store). - client-config: TraeConfig, resolveTraeHome (~/.trae), readTraeConfig (TRAE_CLI_API_HOST), TRAE_DEFAULT_MODEL_HOSTS - launcher: bili trae (proxy mode) — HTTPS_PROXY + SSL_CERT_FILE + BILLION_CONTEXT_PROXY, default model hosts whitelisted for MITM (or the TRAE_CLI_API_HOST override), traecli/trae-cli/trae binary resolution - server: recognize the proprietary /api/ide/v2/llm_raw_chat wire as OpenAI (OpenAI-shaped body per decompilation); an unparseable body falls to verbatim passthrough (no compression, no breakage) - discover: trae hosts in MITM domain auto-discovery - cli/README/AGENTS/CONFIGURATION: help + docs (en + zh-CN) Residual risk (needs a real-machine capture): the wire body may carry a signed/encrypted field (chatmodel.decryptMessage); if so the proxy forwards it unchanged rather than compressing. Fixes #655
# Conflicts: # src/client-config.ts
…+tests(clean vs baseline)+build verified
All conflicts were mechanical adjacent-line unions (three clients added next to each other in shared arrays/imports/if-chains). No semantic clashes. src/server.ts auto-merged cleanly (llm_raw_chat OpenAI sniffing). Verification: typecheck OK; test failure set identical to master baseline (2 pre-existing sandbox env failures); build OK.
pr641/pr654 only touched the English README usage block; pr669 added zh-CN coverage for trae only. Bring all four docs to parity: - README.zh-CN.md: 方式 1 heading + launcher usage block gain codebuddy/qoder - CONFIGURATION.md / .zh-CN.md: CLI Reference table gains codebuddy+qoder rows - src/cli.ts: fix a duplicated stale line in the Launcher help paragraph left by merge resolution (also normalizes its 2-space alignment)
📦 Built Package ArtifactBranch: Option A — Install from npm PR tag (recommended)npm install -g billion-context@pr-693Each push to this PR publishes a new version under the Option B — Download artifact
tar xzf billion-context-pr693.tgz
npm install -g packageThis comment is automatically updated on each push. |
[bot] 🏷 On it — reviewing PR #693 (client-support batch: codebuddy #640 + qoder #653 + trae #655, superseding #641/#654/#669). Head Review plan (per AGENTS.md): (1) duplicate-screen vs the three superseded PRs + confirm the union is lossless; (2) diff-cleanliness pass on every shared-array/import/help-text conflict resolution; (3) typecheck + full test suite + build locally; (4) both-compression-modes reasoning for any wire-touching change (trae |
planClientSpawn (master) routes extensionless targets through comspec on Windows, so the extensionless fake client bins never matched the stub spawnImpl (cmd === fakeX) in the three new runLaunch integration tests — the promise pending on exit left nothing to hold the event loop and the whole tail of launcher.test.ts was cancelledByParent in the windows-latest/node22 CI job (same hang the codebuddy PR hit alone, see #679; its author already fixed the codebuddy case in e9dac95 after rebased, but this branch merged the pre-fix heads of all three PRs). Mirrors the existing workaround in the hermes/omp/dsh/codex/claude tests.
[bot] 🏷 Review complete — LGTM, no blocking issues. Safe to merge. This was a read-only review on a local checkout of head Duplicate screeningNot a duplicate — #693 is the intended consolidation of #641/#654/#669 (union of their content). Keep open; those three should be closed as superseded once this lands. What I verified (with evidence)1. Merge safety vs current master — GitHub shows 2. Losslessness vs the three tips — scripted per-line presence check of every line each tip added (vs its own base): the only deltas are the shared-union lines ( 3. Local pre-flight on the PR head:
4. Diff cleanliness — normal vs whitespace-insensitive numstat are identical for every file except 5. Wire change / both compression modes — 6. Docs parity — all four docs (README.md/.zh-CN.md, CONFIGURATION.md/.zh-CN.md) get the three clients at EN/zh parity. Every functional env var is wired into src ( Minor nits (non-blocking, report-only)
Happy to fold either nit in if you want it, but neither warrants holding the merge. 中文摘要:本 PR 是把 #641/#654/#669 三个客户端支持合并成一个的整合分支;我逐行核对确认对三个原 PR 无损(仅共享数组/导入/help 行为三客户并集,且为正确超集), |
Fixes #640, #653, #655
Supersedes PRs #641, #654, #669 — all three client-support branches merged into one here so the shared-array conflicts (LAUNCH_CLIENTS / BaseClientName / ModelWindowScope / imports / help text) are resolved exactly once instead of thrice.
What's in this batch
codebuddy (#640) —
CODEBUDDY_BASE_URL/bili/rewrite (claude-style), defaulthttps://tencent.sso.codebuddy.cn/v2, OpenAI chat-completions wire; budget aligned viaCODEBUDDY_AUTO_COMPACT_WINDOW; real~/.codebuddyuntouched. Per-model urls in a codebuddy models.json still bypass the proxy (documented v1 limitation).qoder (#653) — model endpoint is hardcoded https (no base-URL override), so cert-MITM via
HTTPS_PROXY+NODE_EXTRA_CA_CERTS; static host map whitelisted (api2-v2.qoder.sh,api1.qoder.sh,api2.qoder.sh,api3.qoder.sh, CN gatewaygateway.qoder.com.cn), replaced entirely by explicitQODER_MODEL_SERVER_HOST(qoder's own env > static-map order); forcesQODER(_CN)_MODEL_TRANSPORT=http; budget viaQODER_AUTOCOMPACT_WINDOW. CN-site detection:QODERCLI_SITE=cn>QODERCN_*env > only-~/.qoder-cn-exists > intl.trae (#655) — closed Go binary, no base-URL override → cert-MITM via
HTTPS_PROXY+ combined bundle atSSL_CERT_FILE+BILLION_CONTEXT_PROXY; host fromTRAE_CLI_API_HOSTor defaults (console.enterprise.trae.cn,www.trae.cn), port stripped for SNI matching; inherited proxy vars stripped from the child env. Server side:/llm_raw_chatadded to the OpenAI-wire sniffing (logUnrecognizedPath / protocol sniff / inferWireProtocol).Docs unified (was inconsistent across the three PRs)
pr#641/#654 touched the English README only, pr#669 touched zh-CN too. This branch brings all four docs to parity:
Conflict resolution notes
Every conflict was a mechanical adjacent-line union (three clients appended next to each other in shared arrays/imports/if-chains); no semantic clashes. Resolutions verified lossless:
git diff <pr-tip> HEADminus-lines are exclusively master-side additions since 3a603b8 plus the codebuddy/qoder union edits; all exported symbols of the three PR tips present (TRAE_/resolveTraeHome/readTraeConfig/buildTraeEnv/TraeConfig, QODER_/qoderIsCnSite, Codebuddy* set); test files took ours + pure-insertion hunks, applied insertion totals match each PR's own stat (+245/+6 for qoder, +140/+6 for trae).Verification (all on this branch, local)
npm run typecheck— cleannode --import tsx --test tests/*.test.ts— failure set identical to current master (only the two pre-existing sandbox-env failures in tests/plugin-agent.test.ts:before_provider_headers stays silent when the manifest fetch keeps failing,pi extension is inert without a proxy; both fail on master too). New coverage runs green: ~7 trae launcher/discover tests + qoder/codebuddy suites.npm run build— clean, dist/index.js 2.87MB (self-contained)Residual risk carried from #655 review: trae chatmodel may encrypt the request body (Go-binary internals unknown) — worst case is passthrough (no compression, no breakage). Real-machine packet capture is the follow-up; not blocking this merge.
Fix (post-review): windows-latest/node22 hang — the three new
runLaunchtests used extensionless fake client bins; after master mergedplanClientSpawn, win32 routes extensionless targets through comspec so the stub spawn never matched and the test tail hung (fail 0, cancelled N). Same class as #679; applied the established.exeworkaround to all three clients in 755c863. All six jobs now green.