opencode-qoder-bridge 0.1.2 → 0.1.5
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/CHANGELOG.md +79 -0
- package/README.md +33 -7
- package/RELEASING.md +11 -2
- package/bin/statusline.mjs +10 -1
- package/dist/cost.d.ts.map +1 -1
- package/dist/cost.js +77 -32
- package/dist/cost.js.map +1 -1
- package/dist/errors.d.ts +36 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +42 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -13
- package/dist/index.js.map +1 -1
- package/dist/language-model.d.ts +28 -1
- package/dist/language-model.d.ts.map +1 -1
- package/dist/language-model.js +31 -9
- package/dist/language-model.js.map +1 -1
- package/dist/logger.d.ts +6 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +20 -0
- package/dist/logger.js.map +1 -0
- package/dist/models.d.ts +7 -0
- package/dist/models.d.ts.map +1 -1
- package/dist/models.js +55 -13
- package/dist/models.js.map +1 -1
- package/dist/prompt-builder.d.ts.map +1 -1
- package/dist/prompt-builder.js +21 -10
- package/dist/prompt-builder.js.map +1 -1
- package/dist/provider.d.ts.map +1 -1
- package/dist/provider.js +3 -2
- package/dist/provider.js.map +1 -1
- package/dist/session-store.d.ts.map +1 -1
- package/dist/session-store.js +20 -9
- package/dist/session-store.js.map +1 -1
- package/dist/state-dir.d.ts +6 -0
- package/dist/state-dir.d.ts.map +1 -0
- package/dist/state-dir.js +14 -0
- package/dist/state-dir.js.map +1 -0
- package/dist/types.d.ts +6 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/usage.d.ts.map +1 -1
- package/dist/usage.js +3 -1
- package/dist/usage.js.map +1 -1
- package/package.json +6 -2
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,82 @@ All notable changes to this project are documented here. The format follows
|
|
|
4
4
|
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and releases use
|
|
5
5
|
[Semantic Versioning](https://semver.org/).
|
|
6
6
|
|
|
7
|
+
## [0.1.5] - 2026-08-22
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- Model discovery now requests the live catalog (`fetchStrategy: "live"`).
|
|
12
|
+
The previous `"cache"` strategy could serve an empty or stale subset of the
|
|
13
|
+
account's models, which is why not all available Qoder models were detected.
|
|
14
|
+
The CLI re-queries the server on every refresh and falls back to its local
|
|
15
|
+
cache only when the server returns nothing.
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
|
|
19
|
+
- `QODER_SCENE` set in the host environment is forwarded to the catalog
|
|
20
|
+
discovery session, and a new provider option `env` passes arbitrary
|
|
21
|
+
environment variables to the qodercli child process for chat turns.
|
|
22
|
+
- Debug logging for discovery: usable/total entry counts and discovered model
|
|
23
|
+
IDs are emitted under `QODER_BRIDGE_DEBUG=1`.
|
|
24
|
+
- Documentation for model discovery behavior and scene filtering in the
|
|
25
|
+
README troubleshooting section.
|
|
26
|
+
|
|
27
|
+
### Changed
|
|
28
|
+
|
|
29
|
+
- Catalog selection drops only disabled or malformed entries; BYOK and
|
|
30
|
+
tagged entries are kept so the bridge never hides a model the server
|
|
31
|
+
actually serves.
|
|
32
|
+
|
|
33
|
+
## [0.1.4] - 2026-08-22
|
|
34
|
+
|
|
35
|
+
### Fixed
|
|
36
|
+
|
|
37
|
+
- Removed an accidental self-dependency (`opencode-qoder-bridge`) from
|
|
38
|
+
`dependencies`, which made npm install a nested copy of the package into
|
|
39
|
+
itself.
|
|
40
|
+
- Provider metadata on stream finish is no longer double-nested; consumers now
|
|
41
|
+
read `providerMetadata.qoder.totalCostUSD`, `contextUsageRatio`, and
|
|
42
|
+
`usageEstimated` at the documented path.
|
|
43
|
+
- `doGenerate` no longer drops tool-call content parts, so non-streaming
|
|
44
|
+
callers receive tool invocations.
|
|
45
|
+
- History trimming in the prompt builder serializes each message once instead
|
|
46
|
+
of re-serializing the whole prompt per dropped turn (O(n²) → O(n)).
|
|
47
|
+
- The usage ledger flushes synchronously on process exit, so the most recent
|
|
48
|
+
turns are no longer lost when opencode shuts down inside the debounce window.
|
|
49
|
+
|
|
50
|
+
### Added
|
|
51
|
+
|
|
52
|
+
- Typed error hierarchy exported from `dist/errors.js`: `QoderBridgeError`
|
|
53
|
+
base with a stable `code`, plus `QoderCliNotFoundError`,
|
|
54
|
+
`QoderAuthError`, `QoderSessionError`, `QoderSdkResultError`, and
|
|
55
|
+
`UnsupportedCapabilityError`.
|
|
56
|
+
- Opt-in debug logging via `QODER_BRIDGE_DEBUG=1` covering model fallbacks,
|
|
57
|
+
stream aborts, background catalog refreshes, and ledger/session-store I/O
|
|
58
|
+
failures that were previously swallowed silently.
|
|
59
|
+
- Authorization failures now explain what is missing (CLI vs personal access
|
|
60
|
+
token) instead of returning an unlabeled failure.
|
|
61
|
+
- `QODER_BRIDGE_STATE_DIR` and `XDG_CONFIG_HOME` are now honored consistently
|
|
62
|
+
by every state file, including `usage.json`, `sessions.json`,
|
|
63
|
+
`models.json`, and the statusline binary (previously only the session store).
|
|
64
|
+
- Diagnostics section in the README.
|
|
65
|
+
|
|
66
|
+
### Changed
|
|
67
|
+
|
|
68
|
+
- Model catalog fetches de-duplicate concurrent refreshes into a single SDK
|
|
69
|
+
session.
|
|
70
|
+
- The `models.json` cache is written atomically with mode 0600 instead of a
|
|
71
|
+
direct partial-write-prone write.
|
|
72
|
+
- Unknown model IDs fall back to the default model with a debug log entry.
|
|
73
|
+
|
|
74
|
+
## [0.1.3] - 2026-08-20
|
|
75
|
+
|
|
76
|
+
### Changed
|
|
77
|
+
|
|
78
|
+
- Refreshed the fallback model catalog and quota reporting behavior.
|
|
79
|
+
- Removed the experimental model-backed quota command; account usage remains
|
|
80
|
+
available through the `qoder_usage` tool.
|
|
81
|
+
- Documentation updates for models and quota handling.
|
|
82
|
+
|
|
7
83
|
## [0.1.2] - 2026-08-20
|
|
8
84
|
|
|
9
85
|
### Security
|
|
@@ -66,3 +142,6 @@ also verified with an in-process MCP transport.
|
|
|
66
142
|
[0.1.1]: https://github.com/naoufalelbani/opencode-qoder-bridge/compare/v0.1.0...v0.1.1
|
|
67
143
|
[0.1.0]: https://github.com/naoufalelbani/opencode-qoder-bridge/releases/tag/v0.1.0
|
|
68
144
|
[0.1.2]: https://github.com/naoufalelbani/opencode-qoder-bridge/compare/v0.1.1...v0.1.2
|
|
145
|
+
[0.1.3]: https://github.com/naoufalelbani/opencode-qoder-bridge/compare/v0.1.2...v0.1.3
|
|
146
|
+
[0.1.4]: https://github.com/naoufalelbani/opencode-qoder-bridge/compare/v0.1.3...v0.1.4
|
|
147
|
+
[0.1.5]: https://github.com/naoufalelbani/opencode-qoder-bridge/compare/v0.1.4...v0.1.5
|
package/README.md
CHANGED
|
@@ -82,8 +82,7 @@ opencode -m qoder/performance # interactive
|
|
|
82
82
|
|
|
83
83
|
### Usage & cost
|
|
84
84
|
|
|
85
|
-
Run
|
|
86
|
-
`qoder-usage` in a terminal for the same live report, or add the statusline
|
|
85
|
+
Run `qoder-usage` in a terminal for the live report, or add the statusline
|
|
87
86
|
binary to your OpenCode statusline config:
|
|
88
87
|
|
|
89
88
|
```bash
|
|
@@ -119,8 +118,14 @@ The ledger accumulates across sessions. Delete `~/.config/opencode-qoder-bridge/
|
|
|
119
118
|
## Models
|
|
120
119
|
|
|
121
120
|
The bridge discovers the available catalog at startup through the SDK's
|
|
122
|
-
`getAvailableModels()` API.
|
|
123
|
-
|
|
121
|
+
`getAvailableModels()` API. Availability is account-, region-, rollout-, and
|
|
122
|
+
SDK-version-dependent. A live query on **2026-08-20** returned:
|
|
123
|
+
|
|
124
|
+
| Model ID | Name | Credit multiplier | Vision | Reasoning | Max input | Max output |
|
|
125
|
+
|----------|------|-------------------|--------|-----------|-----------|------------|
|
|
126
|
+
|
|
127
|
+
The following are known or historical model IDs. Some may be obsolete or
|
|
128
|
+
unavailable for a particular account and are not an availability guarantee:
|
|
124
129
|
|
|
125
130
|
| Model ID | Name | Credit multiplier | Vision | Reasoning | Max input | Max output |
|
|
126
131
|
|----------|------|-------------------|--------|-----------|-----------|------------|
|
|
@@ -131,6 +136,7 @@ returned by a live query on **2026-07-25**:
|
|
|
131
136
|
| `lite` | Lite | 0.00x | ✗ | ✗ | 180K | 32K |
|
|
132
137
|
| `cmodel` | Cantus | 1.60x | ✓ | ✓ | 180K | 32K |
|
|
133
138
|
| `qmodel_preview` | Qwen3.8-Max-Preview | 0.01x promo | ✓ | ✓ | 180K | 32K |
|
|
139
|
+
| `qmodel_38max` | Qwen3.8-Max | 0.25x | ✓ | ✓ | 180K | 32K |
|
|
134
140
|
| `qmodel_latest` | Qwen3.7-Max | 0.10x promo | ✓ | ✗ | 1M | 32K |
|
|
135
141
|
| `qmodel` | Qwen3.7-Plus | 0.04x promo | ✓ | ✗ | 1M | 32K |
|
|
136
142
|
| `kmodel_latest` | Kimi-K3 | 0.80x | ✓ | ✗ | 180K | 32K |
|
|
@@ -145,9 +151,10 @@ availability by account, plan, CLI version, or staged rollout. Promotional
|
|
|
145
151
|
multipliers are time-dependent; the SDK's current `priceFactor` is
|
|
146
152
|
authoritative. Restart OpenCode to refresh the bridge's in-process model cache.
|
|
147
153
|
|
|
148
|
-
Run
|
|
149
|
-
|
|
150
|
-
|
|
154
|
+
Run `opencode models qoder` to inspect the models currently registered with
|
|
155
|
+
OpenCode. The `qoder_models` tool also exposes capabilities, context limits,
|
|
156
|
+
and price multipliers to the agent. Model discovery is cached and refreshed in
|
|
157
|
+
the background so network or authentication latency does not block startup.
|
|
151
158
|
|
|
152
159
|
## Configuration
|
|
153
160
|
|
|
@@ -218,6 +225,15 @@ host environment is trusted.
|
|
|
218
225
|
| Auth prompt at startup | Run `qoder login`, then restart opencode |
|
|
219
226
|
| `qodercli not found` | Install the Qoder CLI; ensure `qodercli` is on PATH or under `~/.qoder/` |
|
|
220
227
|
| Model not found | Verify the model ID matches the table above |
|
|
228
|
+
| Missing models in the model list | Run `/qoder_models`; the bridge refreshes the live catalog at every startup and falls back to the last cached catalog plus the built-ins (`lite`, `auto`, `performance`) when offline. If your account serves models in a different Qoder scene, set `QODER_SCENE` before launching opencode (or via provider option `env`) |
|
|
229
|
+
|
|
230
|
+
### How model discovery works
|
|
231
|
+
|
|
232
|
+
At startup the bridge immediately exposes cached/built-in models, then
|
|
233
|
+
refreshes the live catalog from Qoder (`fetchStrategy: "live"` — the CLI
|
|
234
|
+
re-queries the server and falls back to its local cache if the server returns
|
|
235
|
+
nothing). Discovered models override built-ins with the same ID; a failed
|
|
236
|
+
refresh never removes previously known models.
|
|
221
237
|
|
|
222
238
|
## Development
|
|
223
239
|
|
|
@@ -230,6 +246,16 @@ npm run test:e2e # authenticated real-CLI test; requires QODER_E2E=1
|
|
|
230
246
|
npm run check # full pre-publish verification
|
|
231
247
|
```
|
|
232
248
|
|
|
249
|
+
### Diagnostics
|
|
250
|
+
|
|
251
|
+
Set `QODER_BRIDGE_DEBUG=1` before launching opencode to emit detailed bridge
|
|
252
|
+
logs (model fallbacks, stream aborts, background catalog refreshes, ledger and
|
|
253
|
+
session-store I/O failures). Warnings that need attention are always printed.
|
|
254
|
+
|
|
255
|
+
State files (usage ledger, session mapping, model cache) live under
|
|
256
|
+
`~/.config/opencode-qoder-bridge` by default; override with
|
|
257
|
+
`QODER_BRIDGE_STATE_DIR`, or relocate via `XDG_CONFIG_HOME`.
|
|
258
|
+
|
|
233
259
|
The end-to-end test is intentionally opt-in because it starts Qoder and may
|
|
234
260
|
consume account quota. Run it only after `qoder login`:
|
|
235
261
|
|
package/RELEASING.md
CHANGED
|
@@ -19,10 +19,18 @@ Run the complete release gate from a clean checkout:
|
|
|
19
19
|
```bash
|
|
20
20
|
npm ci
|
|
21
21
|
npm run check
|
|
22
|
+
QODER_E2E=1 npm run test:e2e # requires qoder login; consumes quota
|
|
22
23
|
npm pack --dry-run
|
|
23
24
|
npm publish
|
|
24
25
|
```
|
|
25
26
|
|
|
27
|
+
The end-to-end gate is mandatory for any release that touches
|
|
28
|
+
`src/language-model.ts`, `src/models.ts`, or `src/usage.ts`: unit tests mock
|
|
29
|
+
the SDK, so only `QODER_E2E=1` exercises real streaming, tool calls, provider
|
|
30
|
+
metadata, and live model discovery. Verify before publishing that the dry-run
|
|
31
|
+
tarball contains `dist/` (including `errors.js`, `logger.js`,
|
|
32
|
+
`state-dir.js`) and both `bin/` scripts, and nothing else unexpected.
|
|
33
|
+
|
|
26
34
|
Verify the registry package and install it through OpenCode:
|
|
27
35
|
|
|
28
36
|
```bash
|
|
@@ -51,8 +59,9 @@ After the package exists on npm:
|
|
|
51
59
|
|
|
52
60
|
## Subsequent releases
|
|
53
61
|
|
|
54
|
-
Update `version` using semantic versioning,
|
|
55
|
-
change, and push a matching
|
|
62
|
+
Update `version` using semantic versioning, document the release in
|
|
63
|
+
`CHANGELOG.md`, run the release gate, commit the change, and push a matching
|
|
64
|
+
tag:
|
|
56
65
|
|
|
57
66
|
```bash
|
|
58
67
|
npm version patch
|
package/bin/statusline.mjs
CHANGED
|
@@ -3,7 +3,16 @@ import { readFileSync } from "node:fs";
|
|
|
3
3
|
import { homedir } from "node:os";
|
|
4
4
|
import { join } from "node:path";
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
// Mirrors resolveStateDir() from src/state-dir.ts:
|
|
7
|
+
// QODER_BRIDGE_STATE_DIR > XDG_CONFIG_HOME > ~/.config.
|
|
8
|
+
function resolveStateDir(env = process.env) {
|
|
9
|
+
const override = env.QODER_BRIDGE_STATE_DIR?.trim();
|
|
10
|
+
if (override) return join(override);
|
|
11
|
+
const configHome = env.XDG_CONFIG_HOME?.trim();
|
|
12
|
+
return join(configHome || join(homedir(), ".config"), "opencode-qoder-bridge");
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const STATE_FILE = join(resolveStateDir(), "usage.json");
|
|
7
16
|
|
|
8
17
|
function fmt(usd) {
|
|
9
18
|
return `$${(usd ?? 0).toFixed(4)}`;
|
package/dist/cost.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cost.d.ts","sourceRoot":"","sources":["../src/cost.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cost.d.ts","sourceRoot":"","sources":["../src/cost.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAS5D,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,UAAU,cAAc;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACvG,MAAM,EAAE,QAAQ,EAAE,CAAC;CACpB;AAqJD,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE;QACL,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC7B,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC9B,uBAAuB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACxC,2BAA2B,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KAC7C,CAAC;IACF,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;CACzC;AAED,0DAA0D;AAC1D,wBAAgB,UAAU,CAAC,KAAK,EAAE,WAAW,GAAG,QAAQ,CA+BvD;AAED,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,cAAc,CAAC,SAAS,CAAC,CAAC;IACnC,MAAM,EAAE,QAAQ,EAAE,CAAC;CACpB;AAED,wBAAgB,SAAS,IAAI,YAAY,CAUxC;AAED,wBAAgB,WAAW,IAAI,IAAI,CAGlC;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE9C"}
|
package/dist/cost.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { chmodSync, closeSync, fsyncSync, lstatSync, mkdirSync, openSync, readFileSync, renameSync, unlinkSync, writeFileSync, } from "node:fs";
|
|
2
2
|
import { randomUUID } from "node:crypto";
|
|
3
|
-
import { homedir } from "node:os";
|
|
4
3
|
import { join } from "node:path";
|
|
5
|
-
|
|
4
|
+
import { resolveStateDir } from "./state-dir.js";
|
|
5
|
+
import { debug, describeError } from "./logger.js";
|
|
6
|
+
const STATE_DIR = resolveStateDir();
|
|
6
7
|
const STATE_FILE = join(STATE_DIR, "usage.json");
|
|
7
8
|
const MAX_STATE_BYTES = 1_000_000;
|
|
8
9
|
const UNSAFE_KEYS = new Set(["__proto__", "prototype", "constructor"]);
|
|
@@ -14,6 +15,7 @@ function load() {
|
|
|
14
15
|
try {
|
|
15
16
|
const info = lstatSync(STATE_FILE);
|
|
16
17
|
if (!info.isFile() || info.isSymbolicLink() || info.size > MAX_STATE_BYTES) {
|
|
18
|
+
debug("Cost ledger reset (missing, symlinked, or oversized state file)");
|
|
17
19
|
return emptyState();
|
|
18
20
|
}
|
|
19
21
|
try {
|
|
@@ -23,7 +25,10 @@ function load() {
|
|
|
23
25
|
const raw = readFileSync(STATE_FILE, "utf8");
|
|
24
26
|
return sanitizeState(JSON.parse(raw));
|
|
25
27
|
}
|
|
26
|
-
catch {
|
|
28
|
+
catch (error) {
|
|
29
|
+
const code = error?.code;
|
|
30
|
+
if (code !== "ENOENT")
|
|
31
|
+
debug("Cost ledger unreadable; starting empty:", describeError(error));
|
|
27
32
|
return emptyState();
|
|
28
33
|
}
|
|
29
34
|
}
|
|
@@ -78,46 +83,86 @@ function sanitizeState(value) {
|
|
|
78
83
|
}
|
|
79
84
|
let state = null;
|
|
80
85
|
let writeTimer = null;
|
|
86
|
+
let dirty = false;
|
|
87
|
+
let exitHookInstalled = false;
|
|
81
88
|
function current() {
|
|
82
89
|
state ??= load();
|
|
83
90
|
return state;
|
|
84
91
|
}
|
|
85
|
-
function
|
|
86
|
-
|
|
92
|
+
function writeStateFile() {
|
|
93
|
+
let temporary;
|
|
94
|
+
let fd;
|
|
95
|
+
try {
|
|
96
|
+
mkdirSync(STATE_DIR, { recursive: true, mode: 0o700 });
|
|
97
|
+
chmodSync(STATE_DIR, 0o700);
|
|
98
|
+
temporary = join(STATE_DIR, `.usage.${process.pid}.${randomUUID()}.tmp`);
|
|
99
|
+
fd = openSync(temporary, "wx", 0o600);
|
|
100
|
+
writeFileSync(fd, JSON.stringify(current(), null, 2), "utf8");
|
|
101
|
+
fsyncSync(fd);
|
|
102
|
+
closeSync(fd);
|
|
103
|
+
fd = undefined;
|
|
104
|
+
renameSync(temporary, STATE_FILE);
|
|
105
|
+
temporary = undefined;
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
debug("Cost ledger persist failed:", describeError(error));
|
|
109
|
+
}
|
|
110
|
+
finally {
|
|
111
|
+
if (fd !== undefined) {
|
|
112
|
+
try {
|
|
113
|
+
closeSync(fd);
|
|
114
|
+
}
|
|
115
|
+
catch { /* best-effort */ }
|
|
116
|
+
}
|
|
117
|
+
if (temporary) {
|
|
118
|
+
try {
|
|
119
|
+
unlinkSync(temporary);
|
|
120
|
+
}
|
|
121
|
+
catch { /* best-effort */ }
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* The debounced timer is unref'd, so a fast-exiting host process would drop
|
|
127
|
+
* the most recent turns. A synchronous flush on "exit" closes that gap.
|
|
128
|
+
*/
|
|
129
|
+
function installExitFlush() {
|
|
130
|
+
if (exitHookInstalled)
|
|
87
131
|
return;
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
132
|
+
exitHookInstalled = true;
|
|
133
|
+
process.on("exit", () => {
|
|
134
|
+
if (!dirty)
|
|
135
|
+
return;
|
|
136
|
+
dirty = false;
|
|
92
137
|
try {
|
|
93
138
|
mkdirSync(STATE_DIR, { recursive: true, mode: 0o700 });
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
139
|
+
const temporary = join(STATE_DIR, `.usage.${process.pid}.${randomUUID()}.exit.tmp`);
|
|
140
|
+
const fd = openSync(temporary, "wx", 0o600);
|
|
141
|
+
try {
|
|
142
|
+
writeFileSync(fd, JSON.stringify(current(), null, 2), "utf8");
|
|
143
|
+
fsyncSync(fd);
|
|
144
|
+
}
|
|
145
|
+
finally {
|
|
146
|
+
closeSync(fd);
|
|
147
|
+
}
|
|
101
148
|
renameSync(temporary, STATE_FILE);
|
|
102
|
-
temporary = undefined;
|
|
103
149
|
}
|
|
104
150
|
catch {
|
|
105
|
-
/*
|
|
106
|
-
}
|
|
107
|
-
finally {
|
|
108
|
-
if (fd !== undefined) {
|
|
109
|
-
try {
|
|
110
|
-
closeSync(fd);
|
|
111
|
-
}
|
|
112
|
-
catch { /* best-effort */ }
|
|
113
|
-
}
|
|
114
|
-
if (temporary) {
|
|
115
|
-
try {
|
|
116
|
-
unlinkSync(temporary);
|
|
117
|
-
}
|
|
118
|
-
catch { /* best-effort */ }
|
|
119
|
-
}
|
|
151
|
+
/* nothing left to do during exit */
|
|
120
152
|
}
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
function persist() {
|
|
156
|
+
dirty = true;
|
|
157
|
+
installExitFlush();
|
|
158
|
+
if (writeTimer)
|
|
159
|
+
return;
|
|
160
|
+
writeTimer = setTimeout(() => {
|
|
161
|
+
writeTimer = null;
|
|
162
|
+
if (!dirty)
|
|
163
|
+
return;
|
|
164
|
+
dirty = false;
|
|
165
|
+
writeStateFile();
|
|
121
166
|
}, 250);
|
|
122
167
|
if (typeof writeTimer.unref === "function")
|
|
123
168
|
writeTimer.unref();
|
package/dist/cost.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cost.js","sourceRoot":"","sources":["../src/cost.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EACT,SAAS,EACT,SAAS,EACT,SAAS,EACT,SAAS,EACT,QAAQ,EACR,YAAY,EACZ,UAAU,EACV,UAAU,EACV,aAAa,GACd,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"cost.js","sourceRoot":"","sources":["../src/cost.ts"],"names":[],"mappings":"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"}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export type QoderBridgeErrorCode = "QODER_CLI_NOT_FOUND" | "QODER_AUTH_FAILED" | "QODER_SESSION_INVALID_KEY" | "QODER_SDK_RESULT_ERROR" | "QODER_UNSUPPORTED_CAPABILITY";
|
|
2
|
+
/**
|
|
3
|
+
* Base class for all errors raised by the bridge. Carries a stable `code`
|
|
4
|
+
* so callers and tests can branch on failure mode without parsing messages.
|
|
5
|
+
*/
|
|
6
|
+
export declare class QoderBridgeError extends Error {
|
|
7
|
+
readonly code: QoderBridgeErrorCode;
|
|
8
|
+
constructor(code: QoderBridgeErrorCode, message: string, options?: {
|
|
9
|
+
cause?: unknown;
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
export declare class QoderCliNotFoundError extends QoderBridgeError {
|
|
13
|
+
constructor(message?: string, options?: {
|
|
14
|
+
cause?: unknown;
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
export declare class QoderAuthError extends QoderBridgeError {
|
|
18
|
+
constructor(message: string, options?: {
|
|
19
|
+
cause?: unknown;
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
export declare class QoderSessionError extends QoderBridgeError {
|
|
23
|
+
constructor(message: string, options?: {
|
|
24
|
+
cause?: unknown;
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
export declare class QoderSdkResultError extends QoderBridgeError {
|
|
28
|
+
readonly subtype: string;
|
|
29
|
+
constructor(subtype: string, detail?: string, options?: {
|
|
30
|
+
cause?: unknown;
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
export declare class UnsupportedCapabilityError extends QoderBridgeError {
|
|
34
|
+
constructor(capability: string);
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,oBAAoB,GAC5B,qBAAqB,GACrB,mBAAmB,GACnB,2BAA2B,GAC3B,wBAAwB,GACxB,8BAA8B,CAAC;AAEnC;;;GAGG;AACH,qBAAa,gBAAiB,SAAQ,KAAK;IACzC,QAAQ,CAAC,IAAI,EAAE,oBAAoB,CAAC;gBAExB,IAAI,EAAE,oBAAoB,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAMvF;AAED,qBAAa,qBAAsB,SAAQ,gBAAgB;gBAC7C,OAAO,SAA4E,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAG/H;AAED,qBAAa,cAAe,SAAQ,gBAAgB;gBACtC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAG3D;AAED,qBAAa,iBAAkB,SAAQ,gBAAgB;gBACzC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAG3D;AAED,qBAAa,mBAAoB,SAAQ,gBAAgB;IACvD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;gBAEb,OAAO,EAAE,MAAM,EAAE,MAAM,SAAK,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAIxE;AAED,qBAAa,0BAA2B,SAAQ,gBAAgB;gBAClD,UAAU,EAAE,MAAM;CAG/B"}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base class for all errors raised by the bridge. Carries a stable `code`
|
|
3
|
+
* so callers and tests can branch on failure mode without parsing messages.
|
|
4
|
+
*/
|
|
5
|
+
export class QoderBridgeError extends Error {
|
|
6
|
+
code;
|
|
7
|
+
constructor(code, message, options) {
|
|
8
|
+
super(message);
|
|
9
|
+
this.name = new.target.name;
|
|
10
|
+
this.code = code;
|
|
11
|
+
if (options?.cause !== undefined)
|
|
12
|
+
this.cause = options.cause;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
export class QoderCliNotFoundError extends QoderBridgeError {
|
|
16
|
+
constructor(message = "qodercli not found. Install Qoder CLI first: https://docs.qoder.com/cli", options) {
|
|
17
|
+
super("QODER_CLI_NOT_FOUND", message, options);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export class QoderAuthError extends QoderBridgeError {
|
|
21
|
+
constructor(message, options) {
|
|
22
|
+
super("QODER_AUTH_FAILED", message, options);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
export class QoderSessionError extends QoderBridgeError {
|
|
26
|
+
constructor(message, options) {
|
|
27
|
+
super("QODER_SESSION_INVALID_KEY", message, options);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
export class QoderSdkResultError extends QoderBridgeError {
|
|
31
|
+
subtype;
|
|
32
|
+
constructor(subtype, detail = "", options) {
|
|
33
|
+
super("QODER_SDK_RESULT_ERROR", `Qoder SDK: ${subtype}${detail ? ` | ${detail}` : ""}`, options);
|
|
34
|
+
this.subtype = subtype;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
export class UnsupportedCapabilityError extends QoderBridgeError {
|
|
38
|
+
constructor(capability) {
|
|
39
|
+
super("QODER_UNSUPPORTED_CAPABILITY", `Qoder provider does not support ${capability}`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAOA;;;GAGG;AACH,MAAM,OAAO,gBAAiB,SAAQ,KAAK;IAChC,IAAI,CAAuB;IAEpC,YAAY,IAA0B,EAAE,OAAe,EAAE,OAA6B;QACpF,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;QAC5B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,OAAO,EAAE,KAAK,KAAK,SAAS;YAAE,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;IAC/D,CAAC;CACF;AAED,MAAM,OAAO,qBAAsB,SAAQ,gBAAgB;IACzD,YAAY,OAAO,GAAG,yEAAyE,EAAE,OAA6B;QAC5H,KAAK,CAAC,qBAAqB,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IACjD,CAAC;CACF;AAED,MAAM,OAAO,cAAe,SAAQ,gBAAgB;IAClD,YAAY,OAAe,EAAE,OAA6B;QACxD,KAAK,CAAC,mBAAmB,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAC/C,CAAC;CACF;AAED,MAAM,OAAO,iBAAkB,SAAQ,gBAAgB;IACrD,YAAY,OAAe,EAAE,OAA6B;QACxD,KAAK,CAAC,2BAA2B,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IACvD,CAAC;CACF;AAED,MAAM,OAAO,mBAAoB,SAAQ,gBAAgB;IAC9C,OAAO,CAAS;IAEzB,YAAY,OAAe,EAAE,MAAM,GAAG,EAAE,EAAE,OAA6B;QACrE,KAAK,CAAC,wBAAwB,EAAE,cAAc,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC;QACjG,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;CACF;AAED,MAAM,OAAO,0BAA2B,SAAQ,gBAAgB;IAC9D,YAAY,UAAkB;QAC5B,KAAK,CAAC,8BAA8B,EAAE,mCAAmC,UAAU,EAAE,CAAC,CAAC;IACzF,CAAC;CACF"}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,MAAM,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAkDjE,QAAA,MAAM,MAAM,EAAE,MA6Ib,CAAC;AAEF,eAAe,MAAM,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -6,13 +6,10 @@ import { getLiveUsage, formatUsageReport } from "./usage.js";
|
|
|
6
6
|
import { summarize, formatCost } from "./cost.js";
|
|
7
7
|
import { ensureTuiRegistered } from "./tui-register.js";
|
|
8
8
|
import { deleteQoderSession } from "./session-store.js";
|
|
9
|
+
import { debug, describeError, isDebugEnabled, warn } from "./logger.js";
|
|
9
10
|
const PROVIDER_URL = new URL("./provider.js", import.meta.url).href;
|
|
10
|
-
const USAGE_COMMAND = new URL("../bin/usage.mjs", import.meta.url);
|
|
11
11
|
const UNSAFE_KEYS = new Set(["__proto__", "prototype", "constructor"]);
|
|
12
12
|
let configuredSessionKey;
|
|
13
|
-
function shellQuote(value) {
|
|
14
|
-
return `'${value.replaceAll("'", "'\\''")}'`;
|
|
15
|
-
}
|
|
16
13
|
function buildFallbackEntry(m) {
|
|
17
14
|
return {
|
|
18
15
|
name: m.name,
|
|
@@ -47,6 +44,8 @@ function buildDynamicEntry(m) {
|
|
|
47
44
|
}
|
|
48
45
|
const plugin = async (input) => {
|
|
49
46
|
if (input) {
|
|
47
|
+
if (isDebugEnabled())
|
|
48
|
+
debug("Plugin initializing");
|
|
50
49
|
try {
|
|
51
50
|
const result = await ensureTuiRegistered();
|
|
52
51
|
if (result === "added") {
|
|
@@ -54,20 +53,13 @@ const plugin = async (input) => {
|
|
|
54
53
|
}
|
|
55
54
|
}
|
|
56
55
|
catch (error) {
|
|
57
|
-
|
|
56
|
+
warn("Could not register Qoder sidebar:", error);
|
|
58
57
|
}
|
|
59
58
|
}
|
|
60
59
|
return {
|
|
61
60
|
async config(config) {
|
|
62
61
|
config.provider ??= {};
|
|
63
62
|
const existing = (config.provider.qoder ?? {});
|
|
64
|
-
config.command ??= {};
|
|
65
|
-
config.command["qoder-usage"] ??= {
|
|
66
|
-
template: "This is output from the local qoder-usage CLI. Echo it in a fenced text block without interpreting it:\n\n"
|
|
67
|
-
+ `!\`node ${shellQuote(USAGE_COMMAND.pathname)}\``,
|
|
68
|
-
description: "Show live Qoder credit quota and local usage totals",
|
|
69
|
-
model: "qoder/lite",
|
|
70
|
-
};
|
|
71
63
|
const builtinModels = {};
|
|
72
64
|
// Use cached/fallback models immediately. Refresh the catalog in the
|
|
73
65
|
// background so OpenCode startup never waits on network/auth discovery.
|
|
@@ -84,7 +76,9 @@ const plugin = async (input) => {
|
|
|
84
76
|
if (!UNSAFE_KEYS.has(m.id) && !builtinModels[m.id])
|
|
85
77
|
builtinModels[m.id] = buildFallbackEntry(m);
|
|
86
78
|
}
|
|
87
|
-
void fetchDynamicModels(true).catch(() => {
|
|
79
|
+
void fetchDynamicModels(true).catch((error) => {
|
|
80
|
+
debug("Background model refresh failed:", describeError(error));
|
|
81
|
+
});
|
|
88
82
|
const mergedModels = { ...builtinModels, ...(existing.models ?? {}) };
|
|
89
83
|
const bridgedMcp = bridgeMcpServers(config.mcp);
|
|
90
84
|
const mergedOptions = { ...(existing.options ?? {}) };
|
|
@@ -115,11 +109,13 @@ const plugin = async (input) => {
|
|
|
115
109
|
prompts: [],
|
|
116
110
|
async authorize() {
|
|
117
111
|
if (!findQoderCLI() && !hasQoderPAT()) {
|
|
112
|
+
warn("Authorize failed: qodercli not found on PATH and no", `${QODER_PAT_ENV} is set. Install the CLI (https://docs.qoder.com/cli)`, "or export a personal access token, then retry.");
|
|
118
113
|
return { type: "failed" };
|
|
119
114
|
}
|
|
120
115
|
if (hasQoderCredential()) {
|
|
121
116
|
return { type: "success", key: "qoder-cli-auth" };
|
|
122
117
|
}
|
|
118
|
+
warn("Authorize failed: no usable Qoder credential found.");
|
|
123
119
|
return { type: "failed" };
|
|
124
120
|
},
|
|
125
121
|
},
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEtG,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC/E,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|