@bitkyc08/opencodex 2.6.17 → 2.6.18-preview.20260703
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 -0
- package/bin/ocx.mjs +70 -5
- package/gui/dist/assets/index-BGrHb_az.js +9 -0
- package/gui/dist/assets/index-DDcEW0Cm.css +1 -0
- package/gui/dist/index.html +2 -2
- package/package.json +3 -1
- package/src/adapters/anthropic.ts +9 -2
- package/src/adapters/base.ts +6 -0
- package/src/adapters/cursor/arg-codec.ts +38 -0
- package/src/adapters/cursor/arg-normalize.ts +88 -0
- package/src/adapters/cursor/cursor-errors.ts +85 -0
- package/src/adapters/cursor/discovery.ts +144 -0
- package/src/adapters/cursor/effort-map.ts +74 -0
- package/src/adapters/cursor/exec-policy.ts +44 -0
- package/src/adapters/cursor/framing.ts +136 -0
- package/src/adapters/cursor/gen/agent_pb.ts +15274 -0
- package/src/adapters/cursor/kv-store.ts +25 -0
- package/src/adapters/cursor/live-models.ts +93 -0
- package/src/adapters/cursor/live-smoke-gate.ts +41 -0
- package/src/adapters/cursor/live-transport.ts +758 -0
- package/src/adapters/cursor/mcp-config.ts +42 -0
- package/src/adapters/cursor/mcp-manager.ts +236 -0
- package/src/adapters/cursor/message-mapper.ts +46 -0
- package/src/adapters/cursor/native-exec-common.ts +55 -0
- package/src/adapters/cursor/native-exec-desktop.ts +177 -0
- package/src/adapters/cursor/native-exec-fs.ts +284 -0
- package/src/adapters/cursor/native-exec-mcp.ts +151 -0
- package/src/adapters/cursor/native-exec-network.ts +32 -0
- package/src/adapters/cursor/native-exec-shell.ts +191 -0
- package/src/adapters/cursor/native-exec-tools.ts +118 -0
- package/src/adapters/cursor/native-exec.ts +177 -0
- package/src/adapters/cursor/protobuf-events.ts +309 -0
- package/src/adapters/cursor/protobuf-request.ts +347 -0
- package/src/adapters/cursor/request-builder.ts +98 -0
- package/src/adapters/cursor/tool-definitions.ts +301 -0
- package/src/adapters/cursor/transport-retry.ts +116 -0
- package/src/adapters/cursor/transport.ts +47 -0
- package/src/adapters/cursor/types.ts +36 -0
- package/src/adapters/cursor.ts +99 -0
- package/src/adapters/google.ts +7 -1
- package/src/adapters/kiro.ts +15 -0
- package/src/adapters/openai-chat.ts +7 -2
- package/src/adapters/run-turn-queue.ts +58 -0
- package/src/adapters/tool-catalog-nudge.ts +71 -0
- package/src/bridge.ts +7 -1
- package/src/cli-help.ts +9 -2
- package/src/cli-status.ts +7 -5
- package/src/cli.ts +122 -79
- package/src/codex-catalog.ts +213 -71
- package/src/codex-history-provider.ts +31 -14
- package/src/codex-inject.ts +17 -9
- package/src/codex-paths.ts +2 -1
- package/src/codex-shim.ts +30 -7
- package/src/codex-sync.ts +70 -0
- package/src/config.ts +58 -2
- package/src/doctor.ts +4 -2
- package/src/index.ts +1 -0
- package/src/model-cache.ts +22 -2
- package/src/oauth/callback-server.ts +44 -16
- package/src/oauth/cursor.ts +188 -0
- package/src/oauth/index.ts +29 -3
- package/src/oauth/key-providers.ts +20 -33
- package/src/oauth/login-cli.ts +7 -4
- package/src/open-url.ts +5 -1
- package/src/ports.ts +13 -0
- package/src/process-control.ts +76 -0
- package/src/provider-label.ts +10 -5
- package/src/providers/derive.ts +30 -3
- package/src/providers/registry.ts +39 -1
- package/src/proxy-liveness.ts +122 -0
- package/src/responses/parser.ts +1 -0
- package/src/responses/state.ts +83 -0
- package/src/router.ts +38 -23
- package/src/server/adapter-resolve.ts +3 -0
- package/src/server.ts +130 -18
- package/src/service.ts +94 -32
- package/src/types.ts +24 -1
- package/src/update-job.ts +360 -0
- package/src/update.ts +73 -11
- package/src/usage-log.ts +3 -3
- package/src/usage-summary.ts +3 -2
- package/src/win-paths.ts +68 -0
- package/gui/dist/assets/index-DIBiVVC0.css +0 -1
- package/gui/dist/assets/index-DcnD944i.js +0 -9
package/README.md
CHANGED
|
@@ -181,12 +181,21 @@ next Codex session. opencodex keeps two separate behaviors:
|
|
|
181
181
|
| Kimi (Moonshot) | `openai-chat` | oauth / key |
|
|
182
182
|
| Google Gemini | `google` | key |
|
|
183
183
|
| Azure OpenAI | `azure-openai` | key |
|
|
184
|
+
| Cursor (experimental) | `cursor` | dashboard/local config; live transport + native exec |
|
|
184
185
|
| Ollama Cloud + 17-provider catalog | `openai-chat` | key |
|
|
185
186
|
| Ollama / vLLM / LM Studio (local) | `openai-chat` | key (usually blank) |
|
|
186
187
|
| Any OpenAI-compatible endpoint | `openai-chat` | key |
|
|
187
188
|
|
|
188
189
|
Plus DeepSeek, Groq, OpenRouter, Together, Fireworks, Cerebras, Mistral, Hugging Face, NVIDIA NIM, MiniMax, Qwen Portal, and more. See the full list with `ocx init` or in the [provider docs](https://lidge-jun.github.io/opencodex/reference/configuration/).
|
|
189
190
|
|
|
191
|
+
Cursor support is a staged experimental bridge: it appears in `ocx init` and the dashboard Add
|
|
192
|
+
Provider picker as a local config with Cursor's static public model catalog. Live
|
|
193
|
+
HTTP/2 transport is enabled when a Cursor access token is configured, and Cursor native
|
|
194
|
+
read/write/delete/ls/grep/shell/fetch requests are handled by opencodex. MCP, screen recording,
|
|
195
|
+
and computer-use are exposed through executor hooks; when no local executor is configured,
|
|
196
|
+
opencodex returns typed no-executor results instead of policy-blocking the request. Cursor OAuth
|
|
197
|
+
and live model discovery remain separate future phases.
|
|
198
|
+
|
|
190
199
|
## CLI
|
|
191
200
|
|
|
192
201
|
```bash
|
package/bin/ocx.mjs
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
*/
|
|
11
11
|
import { spawn, spawnSync } from "node:child_process";
|
|
12
12
|
import { createRequire } from "node:module";
|
|
13
|
-
import { existsSync, readFileSync, statSync } from "node:fs";
|
|
13
|
+
import { existsSync, readFileSync, readdirSync, statSync } 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";
|
|
@@ -41,19 +41,43 @@ function currentPackageVersion() {
|
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
function updateTag(currentVersion) {
|
|
44
|
+
// Allowlist the tag: the value is argv-controlled and (on Windows) flows into a
|
|
45
|
+
// shell-joined spawnSync — never forward arbitrary strings.
|
|
44
46
|
const tagIndex = process.argv.indexOf("--tag");
|
|
45
|
-
|
|
47
|
+
const explicit = tagIndex !== -1 ? process.argv[tagIndex + 1] : undefined;
|
|
48
|
+
if (explicit === "preview" || explicit === "latest") return explicit;
|
|
46
49
|
return String(currentVersion).includes("-preview.") ? "preview" : "latest";
|
|
47
50
|
}
|
|
48
51
|
|
|
52
|
+
function expandUserPath(raw) {
|
|
53
|
+
// Mirror src/config.ts expandUserPath — the Bun proxy expands `~`, so this launcher's
|
|
54
|
+
// pid/state gates must resolve the same directory or they silently check the wrong path.
|
|
55
|
+
if (raw === "~") return homedir();
|
|
56
|
+
if (raw.startsWith("~/") || raw.startsWith("~\\")) return join(homedir(), raw.slice(2));
|
|
57
|
+
return raw;
|
|
58
|
+
}
|
|
59
|
+
|
|
49
60
|
function configDir() {
|
|
50
|
-
|
|
61
|
+
const raw = process.env.OPENCODEX_HOME?.trim();
|
|
62
|
+
return resolve(raw ? expandUserPath(raw) : join(homedir(), ".opencodex"));
|
|
51
63
|
}
|
|
52
64
|
|
|
53
65
|
function shouldRepairCodexShim() {
|
|
54
66
|
return existsSync(join(configDir(), "codex-shim.json"));
|
|
55
67
|
}
|
|
56
68
|
|
|
69
|
+
function historyRestoreIncomplete() {
|
|
70
|
+
// Mirror src/update.ts historyRestoreIncomplete — a codex-history-backup-*.json surviving
|
|
71
|
+
// a stop means the native-history restore was skipped (locked state DB).
|
|
72
|
+
try {
|
|
73
|
+
return readdirSync(configDir()).some(
|
|
74
|
+
name => name.startsWith("codex-history-backup-") && name.endsWith(".json"),
|
|
75
|
+
);
|
|
76
|
+
} catch {
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
57
81
|
function repairCodexShimIfNeeded() {
|
|
58
82
|
if (!shouldRepairCodexShim()) return;
|
|
59
83
|
const launcher = fileURLToPath(import.meta.url);
|
|
@@ -70,10 +94,14 @@ function runNpmSelfUpdate() {
|
|
|
70
94
|
const current = currentPackageVersion();
|
|
71
95
|
const tag = updateTag(current);
|
|
72
96
|
const npm = npmBin();
|
|
97
|
+
// Node ≥18.20/20.12 refuses to spawn .cmd/.bat without a shell (CVE-2024-27980
|
|
98
|
+
// hardening) — spawning "npm.cmd" shell-less throws EINVAL on Windows.
|
|
99
|
+
const winShell = process.platform === "win32";
|
|
73
100
|
const latestResult = spawnSync(npm, ["view", `${PKG}@${tag}`, "version"], {
|
|
74
101
|
encoding: "utf8",
|
|
75
102
|
timeout: 12000,
|
|
76
103
|
windowsHide: true,
|
|
104
|
+
shell: winShell,
|
|
77
105
|
});
|
|
78
106
|
const latest = latestResult.status === 0 ? latestResult.stdout.trim() : "";
|
|
79
107
|
|
|
@@ -83,17 +111,54 @@ function runNpmSelfUpdate() {
|
|
|
83
111
|
process.exit(0);
|
|
84
112
|
}
|
|
85
113
|
|
|
114
|
+
// Remember whether a background service manages the proxy BEFORE stopping — `ocx stop`
|
|
115
|
+
// unloads it permanently, so a successful update must reinstall it afterwards.
|
|
116
|
+
const serviceWasInstalled = existsSync(join(configDir(), "service-state.json"));
|
|
117
|
+
|
|
118
|
+
// Never replace package files under a live proxy — stop it first (full `ocx stop`
|
|
119
|
+
// semantics: graceful drain, service stop, native Codex restore). Gate on the service
|
|
120
|
+
// and the runtime-port record too: a service-managed or orphaned proxy can be live
|
|
121
|
+
// while ocx.pid is stale/missing.
|
|
122
|
+
const launcher = fileURLToPath(import.meta.url);
|
|
123
|
+
const hasRuntimeState =
|
|
124
|
+
existsSync(join(configDir(), "ocx.pid")) || existsSync(join(configDir(), "runtime-port.json"));
|
|
125
|
+
if (serviceWasInstalled || hasRuntimeState) {
|
|
126
|
+
console.log("⏹ Stopping the running proxy before updating...");
|
|
127
|
+
const stopRes = spawnSync(process.execPath, [launcher, "stop"], { stdio: "inherit", windowsHide: true });
|
|
128
|
+
const stillHasRuntimeState =
|
|
129
|
+
existsSync(join(configDir(), "ocx.pid")) || existsSync(join(configDir(), "runtime-port.json"));
|
|
130
|
+
if (stopRes.status !== 0 || stillHasRuntimeState) {
|
|
131
|
+
console.error("opencodex: could not stop the running proxy; aborting the update. Run 'ocx stop' and retry.");
|
|
132
|
+
process.exit(1);
|
|
133
|
+
}
|
|
134
|
+
if (historyRestoreIncomplete()) {
|
|
135
|
+
console.warn(
|
|
136
|
+
"opencodex: WARNING — Codex resume history was NOT restored (history DB locked; Codex app/IDE open?).\n" +
|
|
137
|
+
" Routed threads stay hidden in the native Codex app until restored.\n" +
|
|
138
|
+
" After the update: close the Codex app, then run 'ocx stop' once to restore.",
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
86
143
|
console.log(`Updating${latest ? ` to v${latest}` : ""}...\n$ ${npm} install -g ${PKG}@${tag}`);
|
|
87
144
|
const res = spawnSync(npm, ["install", "-g", `${PKG}@${tag}`], {
|
|
88
145
|
stdio: "inherit",
|
|
89
146
|
timeout: 180000,
|
|
90
147
|
windowsHide: true,
|
|
148
|
+
shell: winShell,
|
|
91
149
|
});
|
|
92
150
|
if (res.status === 0) {
|
|
93
151
|
console.log(`\nUpdated${latest ? ` to v${latest}` : ""}.`);
|
|
94
152
|
repairCodexShimIfNeeded();
|
|
95
|
-
|
|
96
|
-
|
|
153
|
+
// The stop above unloaded any managed service; reinstall via the freshly-installed
|
|
154
|
+
// launcher so the new files write the baked paths and the service restarts.
|
|
155
|
+
if (serviceWasInstalled) {
|
|
156
|
+
console.log("Reinstalling the background service with the updated files...");
|
|
157
|
+
const svc = spawnSync(process.execPath, [launcher, "service", "install"], { stdio: "inherit", windowsHide: true });
|
|
158
|
+
if (svc.status !== 0) console.warn("opencodex: service refresh failed — run 'ocx service install' manually.");
|
|
159
|
+
} else {
|
|
160
|
+
console.log("Restart the proxy: ocx start");
|
|
161
|
+
}
|
|
97
162
|
process.exit(0);
|
|
98
163
|
}
|
|
99
164
|
console.error(`\nUpdate failed (${npm} exit ${res.status ?? "?"}). Try manually: ${npm} install -g ${PKG}@${tag}`);
|