@bitkyc08/opencodex 2.7.43-preview.20260728 → 2.8.0
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 +8 -1
- package/bin/ocx.mjs +47 -22
- package/gui/dist/assets/index-BDjpkcRN.js +67 -0
- package/gui/dist/assets/index-BHsKRFh9.css +1 -0
- package/gui/dist/index.html +2 -2
- package/package.json +1 -1
- package/src/AGENTS.md +28 -0
- package/src/adapters/anthropic.ts +15 -6
- package/src/adapters/cursor/discovery.ts +4 -1
- package/src/adapters/cursor/effort-map.ts +3 -0
- package/src/adapters/cursor/native-exec-shell.ts +18 -6
- package/src/adapters/cursor/protobuf-events.ts +24 -2
- package/src/adapters/cursor/protobuf-request.ts +1 -2
- package/src/adapters/cursor/tool-definitions.ts +68 -29
- package/src/adapters/google-wire-compiler.ts +4 -0
- package/src/adapters/google.ts +128 -2
- package/src/adapters/identity.ts +12 -2
- package/src/adapters/kiro.ts +64 -7
- package/src/adapters/mimo-free.ts +2 -0
- package/src/adapters/openai-responses.ts +246 -59
- package/src/claude/agents-inject.ts +5 -0
- package/src/claude/alias.ts +94 -14
- package/src/claude/inbound.ts +26 -9
- package/src/claude/outbound.ts +6 -3
- package/src/cli/account-auth.ts +1 -1
- package/src/cli/agent-driven.ts +37 -0
- package/src/cli/catalog-prewarm.ts +24 -0
- package/src/cli/claude.ts +35 -10
- package/src/cli/doctor.ts +71 -19
- package/src/cli/help.ts +42 -6
- package/src/cli/index.ts +93 -19
- package/src/cli/interactive-confirm.ts +133 -0
- package/src/cli/opencode.ts +701 -0
- package/src/cli/provider-runtime.ts +3 -0
- package/src/cli/provider.ts +31 -10
- package/src/cli/star-prompt.ts +79 -18
- package/src/cli/status.ts +47 -13
- package/src/cli/v2.ts +10 -1
- package/src/codex/account-id.ts +34 -0
- package/src/codex/account-lifecycle.ts +4 -1
- package/src/codex/account-namespace-match.ts +63 -0
- package/src/codex/account-namespaces.ts +149 -0
- package/src/codex/account-pause.ts +20 -0
- package/src/codex/account-store.ts +2 -0
- package/src/codex/account-usability.ts +6 -1
- package/src/codex/app-server-processes.ts +511 -0
- package/src/codex/auth-api.ts +293 -34
- package/src/codex/auth-collision.ts +2 -1
- package/src/codex/auth-context.ts +60 -17
- package/src/codex/catalog/bundled.ts +9 -2
- package/src/codex/catalog/parsing.ts +42 -2
- package/src/codex/catalog/provider-fetch.ts +264 -70
- package/src/codex/catalog/sync.ts +45 -8
- package/src/codex/catalog.ts +2 -2
- package/src/codex/features.ts +524 -5
- package/src/codex/history-provider.ts +145 -1
- package/src/codex/inject.ts +114 -14
- package/src/codex/main-account.ts +2 -8
- package/src/codex/pool-rotation.ts +186 -0
- package/src/codex/quota.ts +92 -2
- package/src/codex/routing.ts +695 -106
- package/src/codex/runtime.ts +10 -1
- package/src/codex/shim.ts +4 -1
- package/src/codex/subagent-defaults.ts +550 -0
- package/src/codex/subagent-model-fallback.ts +2 -0
- package/src/codex/sync.ts +3 -0
- package/src/config.ts +574 -25
- package/src/generated/jawcode-model-metadata.ts +12 -12
- package/src/github/star-state.ts +191 -0
- package/src/images/artifacts.ts +516 -0
- package/src/images/fulfill-video.ts +163 -0
- package/src/images/fulfill.ts +111 -0
- package/src/images/index.ts +4 -0
- package/src/images/loop.ts +789 -0
- package/src/images/plan.ts +133 -0
- package/src/images/synthetic-tool.ts +133 -0
- package/src/images/types.ts +41 -0
- package/src/images/xai-client.ts +141 -0
- package/src/images/xai-video-client.ts +163 -0
- package/src/lib/admin-secrets.ts +25 -0
- package/src/lib/bun-binary-validator.d.mts +3 -0
- package/src/lib/bun-binary-validator.mjs +18 -0
- package/src/lib/bun-runtime.ts +6 -20
- package/src/lib/config-ownership.ts +327 -0
- package/src/lib/crash-guard.ts +2 -0
- package/src/lib/destination-policy.ts +132 -7
- package/src/lib/pinned-http.ts +151 -0
- package/src/lib/process-control.ts +2 -2
- package/src/lib/provider-outbound.ts +167 -0
- package/src/lib/provider-url.ts +14 -0
- package/src/lib/proxy-env.ts +18 -0
- package/src/lib/shadow-call.ts +30 -0
- package/src/lib/test-home-guard.ts +90 -0
- package/src/lib/win-exec.ts +12 -2
- package/src/lib/windows-elevation.ts +81 -3
- package/src/lib/windows-secret-acl.ts +189 -12
- package/src/lib/winsw.ts +2 -0
- package/src/oauth/anthropic-routing.ts +570 -0
- package/src/oauth/health.ts +6 -0
- package/src/oauth/index.ts +310 -75
- package/src/oauth/key-providers.ts +38 -8
- package/src/oauth/kimi.ts +2 -0
- package/src/oauth/kiro-credentials.ts +373 -12
- package/src/oauth/kiro.ts +424 -43
- package/src/oauth/login-cli.ts +33 -6
- package/src/oauth/store.ts +56 -4
- package/src/oauth/types.ts +11 -0
- package/src/providers/alibaba-region-migration.ts +16 -3
- package/src/providers/antigravity-models.ts +3 -0
- package/src/providers/api-keys.ts +13 -6
- package/src/providers/derive.ts +8 -2
- package/src/providers/key-failover.ts +24 -4
- package/src/providers/model-discovery.ts +356 -0
- package/src/providers/quota.ts +233 -29
- package/src/providers/registry.ts +125 -3
- package/src/responses/parser.ts +11 -0
- package/src/responses/state.ts +22 -8
- package/src/responses/tool-groups.ts +19 -0
- package/src/router.ts +19 -7
- package/src/server/auth-cors.ts +114 -24
- package/src/server/claude-messages.ts +8 -1
- package/src/server/gui-static.ts +30 -6
- package/src/server/images.ts +303 -9
- package/src/server/index.ts +77 -9
- package/src/server/lifecycle.ts +25 -1
- package/src/server/live.ts +75 -25
- package/src/server/management/agent-settings-routes.ts +106 -8
- package/src/server/management/combo-routes.ts +7 -0
- package/src/server/management/config-routes.ts +22 -7
- package/src/server/management/context.ts +11 -1
- package/src/server/management/logs-usage-routes.ts +167 -3
- package/src/server/management/model-routes.ts +46 -13
- package/src/server/management/oauth-account-routes.ts +163 -17
- package/src/server/management/provider-routes.ts +73 -10
- package/src/server/management/shared.ts +2 -2
- package/src/server/management/sidebar-routes.ts +39 -0
- package/src/server/management/system-restart.ts +172 -0
- package/src/server/management/system-routes.ts +33 -10
- package/src/server/management-api.ts +5 -3
- package/src/server/management-auth.ts +216 -0
- package/src/server/proxy-liveness.ts +14 -3
- package/src/server/responses/compact.ts +21 -13
- package/src/server/responses/core.ts +614 -172
- package/src/server/responses/upstream-error.ts +48 -0
- package/src/server/responses-image-gen-repair.ts +118 -0
- package/src/server/responses-item-id-repair.ts +10 -85
- package/src/server/sse-payload-rewrite.ts +116 -0
- package/src/server/startup-action-control.ts +30 -14
- package/src/server/system-env.ts +28 -10
- package/src/service.ts +284 -19
- package/src/storage/cleanup-job.ts +57 -0
- package/src/storage/cleanup.ts +1504 -28
- package/src/storage/policy-job.ts +387 -0
- package/src/storage/policy-scheduler.ts +40 -0
- package/src/storage/policy-worker.ts +53 -0
- package/src/storage/policy.ts +522 -0
- package/src/storage/restore-job.ts +253 -0
- package/src/storage/restore-worker.ts +52 -0
- package/src/storage/storage-mutation-coordinator.ts +109 -0
- package/src/storage/worker-lifecycle.ts +81 -0
- package/src/tray/windows.ts +34 -4
- package/src/types.ts +107 -1
- package/src/update/badge.ts +72 -0
- package/src/update/index.ts +36 -18
- package/src/update/job.ts +111 -16
- package/src/update/npm-invocation.d.mts +23 -0
- package/src/update/npm-invocation.mjs +94 -0
- package/src/usage/debug.ts +2 -0
- package/src/usage/expected-prices.ts +6 -5
- package/src/usage/log.ts +12 -0
- package/src/web-search/loop.ts +57 -16
- package/gui/dist/assets/index-CjKFJHSC.js +0 -65
- package/gui/dist/assets/index-DfVGuN88.css +0 -1
package/README.md
CHANGED
|
@@ -240,11 +240,15 @@ next Codex session. opencodex keeps these behaviors:
|
|
|
240
240
|
|
|
241
241
|
- **Existing sessions keep affinity.** A thread id is bound to the selected account and reused on
|
|
242
242
|
later turns, so a long request or a mobile/SSH-attached session keeps using the same account.
|
|
243
|
+
Pausing an account clears its affinity map: in-flight requests keep captured credentials, but
|
|
244
|
+
subsequent turns are re-routed and cannot reuse the paused account.
|
|
243
245
|
- **New sessions can auto-route.** When auto-switch is enabled, opencodex compares the hottest known
|
|
244
246
|
quota window across 5h, weekly, and 30d usage, then picks a lower-usage eligible account for new
|
|
245
247
|
sessions once the active account crosses the threshold.
|
|
246
248
|
- **Quota lookup is built in.** The dashboard can refresh all account quotas in one click, and the
|
|
247
|
-
request log labels pool traffic with non-PII account ordinals.
|
|
249
|
+
request log labels pool traffic with non-PII account ordinals. **Pause exhausted** refreshes
|
|
250
|
+
eligible accounts that have credentials and pauses only those whose relevant quota window is
|
|
251
|
+
freshly confirmed at 100%; accounts without credentials and unknown or failed refreshes stay unchanged.
|
|
248
252
|
- **Failures fail closed.** Token failures mark reauthentication instead of falling back to another
|
|
249
253
|
credential silently; 429 quota responses put the account in cooldown and can fail over future work
|
|
250
254
|
to another eligible pool account.
|
|
@@ -505,6 +509,9 @@ The public docs — install, providers, routing, sidecars, Codex integration, Co
|
|
|
505
509
|
Maintainer source-of-truth notes live under [`structure/`](./structure). Historical investigations remain under [`docs/`](./docs).
|
|
506
510
|
Contributor setup lives in [`CONTRIBUTING.md`](./CONTRIBUTING.md), and security reporting guidance
|
|
507
511
|
lives in [`SECURITY.md`](./SECURITY.md).
|
|
512
|
+
Report undisclosed vulnerabilities privately through
|
|
513
|
+
[GitHub private vulnerability reporting](https://github.com/lidge-jun/opencodex/security/advisories/new),
|
|
514
|
+
not a public issue.
|
|
508
515
|
|
|
509
516
|
## Development
|
|
510
517
|
|
package/bin/ocx.mjs
CHANGED
|
@@ -10,10 +10,12 @@
|
|
|
10
10
|
*/
|
|
11
11
|
import { spawn, spawnSync } from "node:child_process";
|
|
12
12
|
import { createRequire } from "node:module";
|
|
13
|
-
import { existsSync, readFileSync, readdirSync
|
|
13
|
+
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
14
14
|
import { homedir } from "node:os";
|
|
15
15
|
import { dirname, join, resolve } from "node:path";
|
|
16
16
|
import { fileURLToPath } from "node:url";
|
|
17
|
+
import { isRealBunBinary } from "../src/lib/bun-binary-validator.mjs";
|
|
18
|
+
import { npmInvocation } from "../src/update/npm-invocation.mjs";
|
|
17
19
|
import { handoffWindowsTrayForUpdate, planWindowsTrayUpdate } from "../src/update/tray-update-plan.mjs";
|
|
18
20
|
|
|
19
21
|
const PKG = "@bitkyc08/opencodex";
|
|
@@ -29,10 +31,6 @@ function isBunGlobalInstall() {
|
|
|
29
31
|
return /[\\/]\.bun[\\/]/.test(here);
|
|
30
32
|
}
|
|
31
33
|
|
|
32
|
-
function npmBin() {
|
|
33
|
-
return process.platform === "win32" ? "npm.cmd" : "npm";
|
|
34
|
-
}
|
|
35
|
-
|
|
36
34
|
function currentPackageVersion() {
|
|
37
35
|
try {
|
|
38
36
|
return JSON.parse(readFileSync(join(here, "..", "package.json"), "utf8")).version ?? "?";
|
|
@@ -115,15 +113,17 @@ function runTrayLifecycle(launcher, action) {
|
|
|
115
113
|
function runNpmSelfUpdate() {
|
|
116
114
|
const current = currentPackageVersion();
|
|
117
115
|
const tag = updateTag(current);
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
116
|
+
const latestInvocation = npmInvocation(["view", `${PKG}@${tag}`, "version"]);
|
|
117
|
+
const installInvocation = npmInvocation(["install", "-g", `${PKG}@${tag}`]);
|
|
118
|
+
if (!latestInvocation || !installInvocation) {
|
|
119
|
+
console.error("opencodex: could not resolve npm from a trusted absolute PATH entry; aborting before stopping the proxy.");
|
|
120
|
+
process.exit(1);
|
|
121
|
+
}
|
|
122
|
+
const latestResult = spawnSync(latestInvocation.file, latestInvocation.args, {
|
|
123
123
|
encoding: "utf8",
|
|
124
124
|
timeout: 12000,
|
|
125
125
|
windowsHide: true,
|
|
126
|
-
|
|
126
|
+
...latestInvocation.options,
|
|
127
127
|
});
|
|
128
128
|
const latest = latestResult.status === 0 ? latestResult.stdout.trim() : "";
|
|
129
129
|
|
|
@@ -221,12 +221,12 @@ function runNpmSelfUpdate() {
|
|
|
221
221
|
}
|
|
222
222
|
}
|
|
223
223
|
|
|
224
|
-
console.log(`Updating${latest ? ` to v${latest}` : ""}...\n$
|
|
225
|
-
const res = spawnSync(
|
|
224
|
+
console.log(`Updating${latest ? ` to v${latest}` : ""}...\n$ npm install -g ${PKG}@${tag}`);
|
|
225
|
+
const res = spawnSync(installInvocation.file, installInvocation.args, {
|
|
226
226
|
stdio: "inherit",
|
|
227
227
|
timeout: 180000,
|
|
228
228
|
windowsHide: true,
|
|
229
|
-
|
|
229
|
+
...installInvocation.options,
|
|
230
230
|
});
|
|
231
231
|
if (res.status === 0) {
|
|
232
232
|
console.log(`\nUpdated${latest ? ` to v${latest}` : ""}.`);
|
|
@@ -278,7 +278,7 @@ function runNpmSelfUpdate() {
|
|
|
278
278
|
process.exit(0);
|
|
279
279
|
}
|
|
280
280
|
if (trayBeforeUpdate.restoreOnFailure) runTrayLifecycle(launcher, "start");
|
|
281
|
-
console.error(`\nUpdate failed (
|
|
281
|
+
console.error(`\nUpdate failed (npm exit ${res.status ?? "?"}). Try manually: npm install -g ${PKG}@${tag}`);
|
|
282
282
|
process.exit(1);
|
|
283
283
|
}
|
|
284
284
|
|
|
@@ -288,18 +288,14 @@ function bunBinDir() {
|
|
|
288
288
|
return dirname(require.resolve("bun/package.json"));
|
|
289
289
|
}
|
|
290
290
|
|
|
291
|
-
|
|
292
|
-
// postinstall downloads the real ~60MB binary. --ignore-scripts / pnpm leave
|
|
293
|
-
// the ~450-byte stub in place, which is NOT executable (ENOEXEC). A size gate
|
|
294
|
-
// cleanly distinguishes the stub from a real binary on every platform.
|
|
295
|
-
const REAL_BUN_MIN_BYTES = 1_000_000;
|
|
291
|
+
const BUN_OVERRIDE_ENV = "OPENCODEX_BUN_PATH";
|
|
296
292
|
|
|
297
293
|
function findBunBinary(bunDir) {
|
|
298
294
|
// The npm `bun` package ships the binary as bin/bun.exe on every platform;
|
|
299
295
|
// probe bin/bun too for forward compatibility.
|
|
300
296
|
for (const name of ["bun.exe", "bun"]) {
|
|
301
297
|
const p = join(bunDir, "bin", name);
|
|
302
|
-
if (
|
|
298
|
+
if (isRealBunBinary(p)) return p;
|
|
303
299
|
}
|
|
304
300
|
return null;
|
|
305
301
|
}
|
|
@@ -318,6 +314,17 @@ function fail(msg) {
|
|
|
318
314
|
}
|
|
319
315
|
|
|
320
316
|
function resolveBun() {
|
|
317
|
+
// Keep direct npm-launcher starts aligned with durable service/shim installs:
|
|
318
|
+
// a valid explicit runtime must win even when the bundled dependency exists.
|
|
319
|
+
const override = process.env[BUN_OVERRIDE_ENV]?.trim();
|
|
320
|
+
if (override) {
|
|
321
|
+
const overridePath = resolve(override);
|
|
322
|
+
if (isRealBunBinary(overridePath)) return overridePath;
|
|
323
|
+
console.error(
|
|
324
|
+
`opencodex: ${BUN_OVERRIDE_ENV} is missing, unreadable, or not a complete Bun binary; falling back to the bundled runtime.`,
|
|
325
|
+
);
|
|
326
|
+
}
|
|
327
|
+
|
|
321
328
|
let bunDir;
|
|
322
329
|
try {
|
|
323
330
|
bunDir = bunBinDir();
|
|
@@ -362,7 +369,25 @@ const bun = resolveBun();
|
|
|
362
369
|
// signal delivered only to this launcher (Codex app, IDE terminal, service wrapper,
|
|
363
370
|
// or `kill -INT <launcherPid>`) killed the launcher and ORPHANED the Bun proxy —
|
|
364
371
|
// port left bound, pid/runtime-port files left behind, Codex config not restored.
|
|
365
|
-
|
|
372
|
+
//
|
|
373
|
+
// Provenance seam for issue #701: THIS launcher runs under Node, which does not
|
|
374
|
+
// auto-load a project `.env`/`.env.local`; the Bun child does, before any opencodex
|
|
375
|
+
// code evaluates. So this is the last point that can still tell a real shell export
|
|
376
|
+
// from a working-directory dotenv value, and we record which Anthropic credential
|
|
377
|
+
// slots already existed. `src/cli/claude.ts` then treats anything present in the Bun
|
|
378
|
+
// child but missing from this list as ambient project pollution rather than user auth,
|
|
379
|
+
// which stopped a project dotenv from silently moving a claude.ai subscriber onto API
|
|
380
|
+
// billing. An EMPTY value is meaningful (the launcher ran and saw no slots) and is
|
|
381
|
+
// distinct from the variable being absent (no launcher at all — change nothing), so
|
|
382
|
+
// this must stay a plain assignment and never be collapsed to a falsy check.
|
|
383
|
+
// Disabling Bun's dotenv wholesale with --no-env-file is NOT an option: config
|
|
384
|
+
// interpolation and provider settings legitimately read the project environment.
|
|
385
|
+
const preBunAnthropicSlots = ["ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN"]
|
|
386
|
+
.filter(name => typeof process.env[name] === "string" && process.env[name] !== "");
|
|
387
|
+
const child = spawn(bun, [cliPath, ...process.argv.slice(2)], {
|
|
388
|
+
stdio: "inherit",
|
|
389
|
+
env: { ...process.env, OCX_PRE_BUN_ANTHROPIC_ENV: preBunAnthropicSlots.join(",") },
|
|
390
|
+
});
|
|
366
391
|
|
|
367
392
|
// Windows has no real POSIX signals (no SIGHUP); forwarding is best-effort there.
|
|
368
393
|
const FORWARDED = process.platform === "win32" ? ["SIGINT", "SIGTERM"] : ["SIGINT", "SIGTERM", "SIGHUP"];
|