Codesocks
Route selected OpenCode V2 providers through HTTP, HTTPS, or SOCKS proxies without changing baseURL.
0
1,351
近 7 天 92
39.2
生态多维模型
13 小时前
2026-10-20
快速安装与配置
opencode.json写入当前项目的 opencode.json,只对这个仓库生效。
opencode.json
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["@hallaxius/codesocks@0.1.7"]
}写入 ~/.config/opencode/opencode.json,对所有项目生效。
~/.config/opencode/opencode.json
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["@hallaxius/codesocks@0.1.7"]
}若你要在本地改造这个插件,先装到项目里再从本地路径引用。
shell
pnpm add -D @hallaxius/codesocksOpenCode 启动时会通过内嵌运行时自动加载 npm 依赖并缓存至本地目录,无需手动在全局环境执行安装。
Maintained by Hallaxius.
Native OpenCode V2 plugin (@opencode/plugin 2.x) that routes HTTP traffic of selected providers through an explicit HTTP/HTTPS/SOCKS proxy, preserving baseURL, body, credentials, and streaming (SSE).
Flow: prompt → provider http.request hook → local 127.0.0.1 relay → configured proxy → original baseURL.
Does not eliminate provider rate limits. What the plugin does is change the egress IP and apply per-provider pacing/queueing (
maxConcurrent,minIntervalMs,429backoff honoringRetry-After). Account/plan limits still apply.
Compatibility
- OpenCode V2 (
>=2.0.15 <3), tested against CLI2.0.15and theanomalyco/opencodev2branch (SHA6bffe79indocs/opencode-analysis.md). - Stable local-directory entrypoint:
server.jsre-exportsdist/index.js(the V2 loader requires a directory, not a file). Plugin.define({ id: "codesocks" }),ctx.provider.transformforcessettings.transport = "http"on selected providers,ctx.session.hook("http.request", …, { providerID })rewrites,experimental.ws.handshakefails closed (WebSocket does not go through the relay).
Installation
bun install
bun run build
In the project (or global) opencode.jsonc, register the package directory:
{
"plugins": [{ "package": "file:///path/to/codesocks" }]
}
Configuration — codesocks.jsonc
Lives next to opencode.jsonc/opencode.json (directly or inside .opencode/) for easy maintenance. Deterministic precedence, no merging:
- Plugin option
configPath(relative toctx.location.directory) — must exist. $CODESOCKS_CONFIG— must exist.- Nearest sibling walking up from
directoryto the root:codesocks.jsoncnext toopencode.json/jsonc, directly or in.opencode/. - Global:
dirname($OPENCODE_CONFIG)/$OPENCODE_CONFIG_DIR/$XDG_CONFIG_HOME/opencode/<home>/.config/opencode. - Absent → plugin disabled (empty maps), no error.
Minimal example (examples/codesocks.example.jsonc):
{
"$schema": "../codesocks.schema.json",
"enabled": false, // switch to true after configuring a real proxy
"proxies": {
// "socks5h://{env:PROXY_USER}:{env:PROXY_PASS}@127.0.0.1:1080"
"local": "socks5h://127.0.0.1:1080"
},
"providers": {
"openai": {
"proxy": "local",
"allowedOrigins": ["https://api.openai.com"],
"maxConcurrent": 2,
"minIntervalMs": 0,
"timeoutMs": 120000,
"maxQueueWaitMs": 120000
}
}
}
Rules (fail-closed, never leaking URLs in errors):
proxies:http,https,socks4,socks4a,socks5,socks5hschemes; no path/query/fragment/PAC. Secrets only via{env:NAME}in proxy URLs; a missing/empty variable is an error.providers.<id>:proxymust exist inproxies(own-key comparison),allowedOriginsnon-empty, exacthttp(s)origins normalized toorigin(case/default-port/trailing-slash normalized), no credentials/path.- Unknown fields,
__proto__, invalid JSONC, or an unreadable selected file =ConfigError. - The
__proto__key is rejected by scanning the raw text before parsing; internal maps use null prototypes.
Relay security
- HTTP relay on
127.0.0.1only, ephemeral port; rewrite via random 32-byte single-use tickets, 60 s expiry, 1024 pending cap, method check; invalid/replayed ticket =403. - Only
allowedOriginsorigins; an unapproved origin errors before any network happens (credentials never leave for the wrong destination). - Upstream
3xxis blocked with a generic502(never follows redirects outside the proxy);429appliescooldownfromRetry-After(seconds/date, 1 s default, never shortens an existing wait). - Hop-by-hop and
proxy-*headers stripped; status/body/SSE preserved; abort/timeout cancel the upstream socket; explicit agents (http-proxy-agent/https-proxy-agent/socks-proxy-agent) with noHTTP_PROXY/HTTPS_PROXY/NO_PROXY. socks5hresolves DNS at the proxy (domain ATYP); end-to-end verified TLS, never disabling verification.
Verification
bun run check # typecheck + build + 37 tests (bun test tests)
bun run smoke:opencode # brings up fake local SSE origin + proxy and runs isolated `opencode run --standalone`
bun audit --production # clean — 0 vulnerabilities (the transitive @opentelemetry/core moderate went away upstream with @opencode/plugin 2.0.22)
npm pack --dry-run # tarball: dist + server.js + schema + examples + README + LICENSE
Expected smoke: {"result":"PASS","proxyHits":2,"upstreamHits":2,"marker":"CODESOCKS_SMOKE_OK"}.
Honest limits
- WebSocket on selected providers is refused (use HTTP).
ctx.generate.textoutside a session does not pass through session hooks. - Queue capped at 256 per provider;
503when the queue is unavailable, generic502on transport failure. - Current audit: clean (
bun audit --productionwith 0 vulnerabilities; the transitive@opentelemetry/coremoderate was fixed upstream in@opencode/plugin 2.0.22). No high direct dependency after swapping theproxy-agentumbrella for explicit agents.
同类生态推荐
Model Fallback
@smart-coders-hq/opencode-model-fallback
OpenCode plugin for ordered model fallback chains, preemptive redirect, and automatic rate limit recovery.
Startup Commands
opencode-startup-commands
Launch trusted background commands when OpenCode initializes a project or directory.
Yatefca
yatefca
Deterministic, non-LLM session titles from a first message — a tiny library plus a ready-to-use opencode plugin.