@nofendian17/opencode-relay-plugin 2.0.5 → 2.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -5
- package/index.ts +52 -24
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -65,7 +65,7 @@ Local file (auto-discovered):
|
|
|
65
65
|
| Option | Env fallback | Description |
|
|
66
66
|
| --- | --- | --- |
|
|
67
67
|
| `url: string \| string[]` | `RELAY_URL` (comma-separated) | Relay endpoint(s), `http(s)` only. Invalid entries are skipped with a warning log; if none remain valid the plugin disables itself. |
|
|
68
|
-
| `debug: boolean` | `RELAY_DEBUG=1` | Verbose per-request logging.
|
|
68
|
+
| `debug: boolean` | `RELAY_DEBUG=1` | Verbose per-request logging. **Ini opsi plugin** (`plugins[].options.debug`), **bukan** top-level `debug` di `opencode.jsonc` — top-level `debug` tidak mengaktifkan log plugin ini. Baris penting (`init`, `disabled`, `fallback`) selalu ditulis ke file log; baris verbose per-request hanya saat `debug` on. Override path dengan `RELAY_DEBUG_LOG` (dipakai tests untuk isolasi). |
|
|
69
69
|
|
|
70
70
|
## Relay protocol (unchanged from v1)
|
|
71
71
|
|
|
@@ -89,10 +89,11 @@ access logs as secret-bearing.
|
|
|
89
89
|
|
|
90
90
|
## Verify
|
|
91
91
|
|
|
92
|
-
1. Set `debug: true` + `url`
|
|
92
|
+
1. Set plugin option `debug: true` + `url` ke local echo server, run prompt, confirm
|
|
93
93
|
`x-relay-target` / `x-relay-path` headers arrive.
|
|
94
94
|
2. Stop the relay → request still succeeds via direct fallback (check
|
|
95
|
-
`[relay] relay fallback to direct` in
|
|
95
|
+
`[relay] relay fallback to direct` in the log file — path is printed in the
|
|
96
|
+
`[relay] init` line as `logFile`).
|
|
96
97
|
3. Unset `url`/`RELAY_URL` → `[relay] disabled` log, traffic goes direct.
|
|
97
98
|
4. Confirm scope: a request to `https://opencode.ai/inference/...` must show
|
|
98
99
|
`via relay` in the log. If the log only shows
|
|
@@ -100,8 +101,11 @@ access logs as secret-bearing.
|
|
|
100
101
|
`https://opencode.ai/...` URL and zero `via relay` lines, the request never
|
|
101
102
|
entered the pool — check the origin match in `index.ts`.
|
|
102
103
|
|
|
103
|
-
Note: the
|
|
104
|
-
opencode
|
|
104
|
+
Note: the default file is `os.tmpdir()/opencode-relay.log` — on macOS that is
|
|
105
|
+
`$TMPDIR/opencode-relay.log` (e.g. `/var/folders/.../T/`), NOT `/tmp/`.
|
|
106
|
+
Check the `logFile` field in the `[relay] init` line for the exact path.
|
|
107
|
+
Concurrent opencode processes append to the same file. Plugin `console.log`
|
|
108
|
+
is not forwarded to opencode logs, so always check the file, not the TUI.
|
|
105
109
|
|
|
106
110
|
## V1 vs V2 notes
|
|
107
111
|
|
package/index.ts
CHANGED
|
@@ -1,8 +1,26 @@
|
|
|
1
1
|
import { Plugin } from "@opencode/plugin"
|
|
2
|
-
import {
|
|
2
|
+
import { appendFileSync } from "node:fs"
|
|
3
3
|
import { tmpdir } from "node:os"
|
|
4
4
|
import { join } from "node:path"
|
|
5
5
|
|
|
6
|
+
// Bun runtime: node:fs/promises appendFile fails silently. Use sync API.
|
|
7
|
+
function safeAppendFile(path: string, data: string): void {
|
|
8
|
+
try {
|
|
9
|
+
appendFileSync(path, data)
|
|
10
|
+
} catch {
|
|
11
|
+
// Fallback: try Bun.write if available
|
|
12
|
+
try {
|
|
13
|
+
// @ts-ignore - Bun global may not exist in Node
|
|
14
|
+
if (typeof Bun !== "undefined") {
|
|
15
|
+
// @ts-ignore
|
|
16
|
+
Bun.write(path, data, { mode: "append" })
|
|
17
|
+
}
|
|
18
|
+
} catch {
|
|
19
|
+
// All failed - ignore
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
6
24
|
interface RelayOptions {
|
|
7
25
|
url?: string | string[]
|
|
8
26
|
debug?: boolean
|
|
@@ -198,15 +216,28 @@ function createRelayFetch(
|
|
|
198
216
|
}
|
|
199
217
|
}
|
|
200
218
|
|
|
219
|
+
function parseDebug(value: unknown): boolean | undefined {
|
|
220
|
+
if (value === undefined) return undefined
|
|
221
|
+
if (typeof value === "boolean") return value
|
|
222
|
+
if (typeof value === "number") return value !== 0
|
|
223
|
+
if (typeof value === "string") {
|
|
224
|
+
const v = value.trim().toLowerCase()
|
|
225
|
+
if (["1", "true", "yes", "on", "debug"].includes(v)) return true
|
|
226
|
+
if (["0", "false", "no", "off", ""].includes(v)) return false
|
|
227
|
+
return true
|
|
228
|
+
}
|
|
229
|
+
return Boolean(value)
|
|
230
|
+
}
|
|
231
|
+
|
|
201
232
|
function parseOptions(options: Record<string, unknown> | undefined): {
|
|
202
233
|
relays: string[]
|
|
203
234
|
debug: boolean
|
|
204
235
|
} {
|
|
205
236
|
const url = options?.["url"] as string | string[] | undefined
|
|
206
|
-
const
|
|
237
|
+
const envDebug = process.env.RELAY_DEBUG
|
|
207
238
|
return {
|
|
208
239
|
relays: normalizeRelays(url),
|
|
209
|
-
debug:
|
|
240
|
+
debug: parseDebug(options?.["debug"]) ?? parseDebug(envDebug) ?? false,
|
|
210
241
|
}
|
|
211
242
|
}
|
|
212
243
|
|
|
@@ -219,29 +250,26 @@ export default Plugin.define({
|
|
|
219
250
|
const debug = parsed.debug
|
|
220
251
|
const prefix = "[relay]"
|
|
221
252
|
// console output from v2 plugins is not forwarded to opencode logs,
|
|
222
|
-
// so
|
|
253
|
+
// so mirror important events to a file unconditionally and verbose
|
|
254
|
+
// per-request lines only when debug is on.
|
|
255
|
+
// NOTE: this is the plugin option `plugins[].options.debug`
|
|
256
|
+
// (or RELAY_DEBUG=1), NOT the top-level opencode `debug` flag.
|
|
223
257
|
// RELAY_DEBUG_LOG overrides the path (tests use an isolated file so a
|
|
224
258
|
// live opencode process appending to the default never interferes).
|
|
225
|
-
//
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
const
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
warnedLogFile = true
|
|
237
|
-
console.log(prefix, "debug log write failed", debugLogFile, String(e))
|
|
238
|
-
}
|
|
239
|
-
})
|
|
240
|
-
}
|
|
241
|
-
: undefined
|
|
259
|
+
// Default path is os.tmpdir() — on macOS that is NOT /tmp but
|
|
260
|
+
// $TMPDIR (e.g. /var/folders/.../T/opencode-relay.log).
|
|
261
|
+
// Logging never breaks requests.
|
|
262
|
+
const logFile = process.env.RELAY_DEBUG_LOG ?? DEBUG_LOG
|
|
263
|
+
const fileLog: Logger = (message, extra) => {
|
|
264
|
+
const line =
|
|
265
|
+
`${new Date().toISOString()} ${prefix} ${message}` +
|
|
266
|
+
(extra ? ` ${JSON.stringify(extra)}` : "") +
|
|
267
|
+
"\n"
|
|
268
|
+
safeAppendFile(logFile, line)
|
|
269
|
+
}
|
|
242
270
|
const emit: Logger = (message, extra) => {
|
|
243
271
|
console.log(prefix, message, extra ? JSON.stringify(extra) : "")
|
|
244
|
-
fileLog
|
|
272
|
+
fileLog(message, extra)
|
|
245
273
|
}
|
|
246
274
|
const log: Logger = (message, extra) => {
|
|
247
275
|
if (debug) emit(message, extra)
|
|
@@ -262,14 +290,14 @@ export default Plugin.define({
|
|
|
262
290
|
}
|
|
263
291
|
}
|
|
264
292
|
|
|
265
|
-
emit("init", { debug, relayCount: relays.length })
|
|
293
|
+
emit("init", { debug, relayCount: relays.length, logFile })
|
|
266
294
|
|
|
267
295
|
if (relays.length === 0) {
|
|
268
296
|
emit("disabled: no relays configured (set plugin option `url` or RELAY_URL)", {})
|
|
269
297
|
return
|
|
270
298
|
}
|
|
271
299
|
|
|
272
|
-
log("relay pool loaded", { relays })
|
|
300
|
+
log("relay pool loaded", { relays, logFile })
|
|
273
301
|
|
|
274
302
|
const rawFetch = globalThis.fetch
|
|
275
303
|
const g = globalThis as Record<string, unknown>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nofendian17/opencode-relay-plugin",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.6",
|
|
4
4
|
"description": "Route OpenCode v2 Zen (opencode.ai) traffic through relay endpoint(s) with round-robin, failover, and direct fallback. Other providers are left untouched.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./index.ts",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"@opencode/plugin": "^2.0.28",
|
|
30
|
-
"@types/node": "^26.6.
|
|
30
|
+
"@types/node": "^26.6.5",
|
|
31
31
|
"typescript": "^5.9.3"
|
|
32
32
|
}
|
|
33
33
|
}
|