@iislee/opencodex 2.31.0 → 2.35.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 +3 -3
- package/bin/ocx.mjs +99 -70
- package/gui/dist/assets/index-Be1sDpWw.css +1 -0
- package/gui/dist/assets/index-D4OKgUV4.js +114 -0
- package/gui/dist/index.html +2 -2
- package/package.json +3 -1
- package/src/adapters/anthropic.ts +104 -15
- package/src/adapters/base.ts +29 -1
- package/src/adapters/command-code.ts +42 -6
- package/src/adapters/cursor/call-id.ts +44 -0
- package/src/adapters/cursor/catalog.ts +541 -0
- package/src/adapters/cursor/checkpoint-store.ts +15 -10
- package/src/adapters/cursor/cursor-errors.ts +15 -0
- package/src/adapters/cursor/discovery.ts +69 -18
- package/src/adapters/cursor/effort-map.ts +79 -1
- package/src/adapters/cursor/envelope-echo.ts +290 -0
- package/src/adapters/cursor/live-models.ts +7 -2
- package/src/adapters/cursor/live-transport.ts +14 -0
- package/src/adapters/cursor/message-mapper.ts +4 -1
- package/src/adapters/cursor/native-exec-desktop.ts +23 -0
- package/src/adapters/cursor/native-exec-fs.ts +2 -2
- package/src/adapters/cursor/native-exec-network.ts +1 -1
- package/src/adapters/cursor/native-exec-shell.ts +5 -2
- package/src/adapters/cursor/native-exec.ts +20 -0
- package/src/adapters/cursor/protobuf-request.ts +68 -14
- package/src/adapters/cursor/request-builder.ts +40 -10
- package/src/adapters/cursor/tool-definitions.ts +14 -4
- package/src/adapters/cursor/tool-result-normalize.ts +28 -5
- package/src/adapters/cursor/types.ts +20 -0
- package/src/adapters/cursor.ts +209 -38
- package/src/adapters/exec-tool-result-normalize.ts +99 -0
- package/src/adapters/google-antigravity-replay.ts +173 -25
- package/src/adapters/google-antigravity-wire.ts +5 -0
- package/src/adapters/google-errors.ts +44 -12
- package/src/adapters/google.ts +136 -24
- package/src/adapters/image.ts +1 -1
- package/src/adapters/kiro-constants.ts +27 -0
- package/src/adapters/kiro-tools.ts +55 -16
- package/src/adapters/kiro.ts +182 -23
- package/src/adapters/openai-chat.ts +300 -242
- package/src/adapters/openai-responses.ts +353 -27
- package/src/adapters/run-turn-queue.ts +36 -1
- package/src/adapters/tool-catalog-nudge.ts +4 -3
- package/src/adapters/xai-tool-schema.ts +436 -0
- package/src/adapters/xai-web-search.ts +17 -16
- package/src/bridge.ts +90 -37
- package/src/chat/inbound.ts +14 -1
- package/src/chat/outbound.ts +15 -7
- package/src/claude/agents-inject.ts +8 -1
- package/src/claude/context-windows.ts +16 -9
- package/src/claude/outbound.ts +24 -11
- package/src/cli/access.ts +46 -3
- package/src/cli/account-api.ts +116 -19
- package/src/cli/account-extended.ts +262 -29
- package/src/cli/account-main.ts +12 -12
- package/src/cli/account.ts +69 -15
- package/src/cli/agent.ts +8 -1
- package/src/cli/alias.ts +66 -0
- package/src/cli/capabilities-command.ts +94 -0
- package/src/cli/capabilities.ts +496 -0
- package/src/cli/claude-desktop.ts +31 -11
- package/src/cli/claude.ts +26 -1
- package/src/cli/dispatch.ts +256 -28
- package/src/cli/doctor.ts +126 -14
- package/src/cli/help.ts +17 -6
- package/src/cli/index.ts +39 -9
- package/src/cli/init.ts +1 -0
- package/src/cli/inspect.ts +230 -0
- package/src/cli/models-runtime.ts +95 -0
- package/src/cli/models.ts +26 -10
- package/src/cli/observe.ts +31 -8
- package/src/cli/provider-runtime.ts +16 -2
- package/src/cli/provider.ts +2 -1
- package/src/cli/registry.ts +49 -10
- package/src/cli/runtime-api.ts +51 -7
- package/src/cli/status.ts +41 -1
- package/src/cli/storage.ts +234 -0
- package/src/cli/system-command.ts +16 -0
- package/src/cli/system-restart-client.ts +1 -1
- package/src/cli/usage-report.ts +184 -0
- package/src/cli/v2.ts +34 -10
- package/src/cli/version-skew.ts +46 -0
- package/src/clients/config-export.ts +85 -3
- package/src/clients/effective-status.ts +30 -2
- package/src/clients/probes/cline.ts +81 -0
- package/src/codex/account-label.ts +21 -0
- package/src/codex/account-pause.ts +2 -1
- package/src/codex/account-priority.ts +3 -2
- package/src/codex/app-server-processes.ts +83 -7
- package/src/codex/auth-api.ts +50 -10
- package/src/codex/auth-context.ts +21 -18
- package/src/codex/autostart-health.ts +16 -0
- package/src/codex/catalog/aggregation.ts +18 -0
- package/src/codex/catalog/effort.ts +18 -3
- package/src/codex/catalog/metadata.ts +27 -1
- package/src/codex/catalog/native-models.ts +5 -2
- package/src/codex/catalog/parsing.ts +72 -27
- package/src/codex/catalog/provider-fetch.ts +187 -31
- package/src/codex/catalog/sync.ts +131 -5
- package/src/codex/catalog.ts +1 -1
- package/src/codex/codex-write-lock.ts +3 -1
- package/src/codex/convergence-types.ts +1 -1
- package/src/codex/convergence.ts +27 -2
- package/src/codex/desired-state.ts +2 -2
- package/src/codex/desktop-app-restart.ts +355 -0
- package/src/codex/history-job.ts +32 -3
- package/src/codex/history-manifest.ts +112 -0
- package/src/codex/history-migration-guardian.ts +5 -5
- package/src/codex/history-provider.ts +825 -247
- package/src/codex/history-worker.ts +8 -5
- package/src/codex/inject-coordination.ts +83 -0
- package/src/codex/inject.ts +63 -22
- package/src/codex/injected-marker.ts +1 -1
- package/src/codex/internal/history-writer.ts +4 -3
- package/src/codex/log-guard/inspect.ts +22 -4
- package/src/codex/model-entitlements.ts +9 -2
- package/src/codex/native-profile-startup.ts +157 -27
- package/src/codex/native-residue.ts +26 -33
- package/src/codex/prompt-layers.ts +371 -25
- package/src/codex/prompt-text-probe.ts +238 -0
- package/src/codex/quota.ts +91 -10
- package/src/codex/routing.ts +9 -0
- package/src/codex/shim.ts +56 -3
- package/src/codex/subagent-model-fallback.ts +104 -25
- package/src/codex/transition-state.ts +116 -8
- package/src/combos/failover.ts +27 -0
- package/src/combos/types.ts +10 -0
- package/src/compatibility/index.ts +26 -0
- package/src/compatibility/manifest.ts +253 -0
- package/src/compatibility/openai-responses.ts +121 -0
- package/src/config/atomic-write.ts +219 -0
- package/src/config/paths.ts +40 -0
- package/src/config/process-state.ts +309 -0
- package/src/config/provider-validation.ts +177 -0
- package/src/config/rebase-provenance.ts +68 -0
- package/src/config.ts +206 -824
- package/src/generated/compatibility-version.json +373 -213
- package/src/images/loop.ts +5 -4
- package/src/images/plan.ts +5 -4
- package/src/integrations/ownership-policy.ts +160 -0
- package/src/integrations/ownership.ts +46 -2
- package/src/integrations/registry.ts +7 -0
- package/src/integrations/state.ts +79 -7
- package/src/integrations/writer.ts +26 -2
- package/src/lab/conformance/fixtures/protocol-v1-cases.json +1 -1
- package/src/lab/fabric/producer-child.ts +1 -1
- package/src/lib/admin-secrets.ts +24 -0
- package/src/lib/bounded-body.ts +14 -2
- package/src/lib/config-ownership.ts +20 -0
- package/src/lib/errors.ts +36 -3
- package/src/lib/package-tree-integrity.ts +101 -0
- package/src/lib/process-control.ts +2 -1
- package/src/lib/service-secrets.ts +15 -0
- package/src/lib/tool-argument-integers.ts +56 -5
- package/src/oauth/callback-server.ts +22 -2
- package/src/oauth/cline.ts +203 -0
- package/src/oauth/generic-account-failover.ts +231 -0
- package/src/oauth/health.ts +1 -1
- package/src/oauth/index.ts +65 -6
- package/src/oauth/key-providers.ts +10 -1
- package/src/oauth/kimi.ts +9 -1
- package/src/oauth/kiro.ts +45 -0
- package/src/oauth/local-token-detect.ts +2 -0
- package/src/oauth/open-browser-choice.ts +26 -0
- package/src/oauth/store.ts +14 -5
- package/src/oauth/types.ts +15 -0
- package/src/providers/auto-compact-budget.ts +65 -0
- package/src/providers/command-code-efforts.ts +38 -6
- package/src/providers/context-cap.ts +4 -3
- package/src/providers/default-aliases.ts +65 -0
- package/src/providers/derive.ts +28 -0
- package/src/providers/fastwire.ts +7 -1
- package/src/providers/label.ts +34 -1
- package/src/providers/model-presets.ts +119 -0
- package/src/providers/new-model-policy.ts +146 -0
- package/src/providers/provider-id-rewrite.ts +2 -1
- package/src/providers/quota.ts +65 -7
- package/src/providers/registry.ts +184 -69
- package/src/providers/slug-codec.ts +52 -0
- package/src/providers/xai-transport.ts +21 -0
- package/src/reasoning-effort.ts +19 -2
- package/src/responses/apply-patch-envelope.ts +63 -0
- package/src/responses/code-mode-helper-compat.ts +50 -0
- package/src/responses/custom-tool-compat.ts +157 -39
- package/src/responses/namespace-tool-compat.ts +84 -4
- package/src/responses/parser.ts +7 -2
- package/src/responses/reasoning-replay-cache.ts +81 -3
- package/src/responses/schema.ts +5 -1
- package/src/responses/state.ts +94 -4
- package/src/responses/thought-signature-replay.ts +17 -0
- package/src/responses/turn-termination.ts +107 -0
- package/src/router.ts +40 -2
- package/src/routing/analytics.ts +1 -0
- package/src/routing/quota.ts +10 -0
- package/src/server/auth-cors.ts +27 -7
- package/src/server/chat-completions.ts +24 -16
- package/src/server/chat-native-sse.ts +3 -3
- package/src/server/chat-native.ts +30 -11
- package/src/server/claude-messages.ts +1 -1
- package/src/server/index.ts +179 -32
- package/src/server/lifecycle.ts +52 -1
- package/src/server/local-management-read-client.ts +1 -1
- package/src/server/local-provider-reload-client.ts +1 -1
- package/src/server/management/agent-settings-routes.ts +45 -23
- package/src/server/management/codex-prompt-routes.ts +570 -0
- package/src/server/management/combo-routes.ts +2 -1
- package/src/server/management/config-routes.ts +59 -12
- package/src/server/management/context.ts +10 -1
- package/src/server/management/logs-usage-routes.ts +30 -24
- package/src/server/management/model-routes.ts +274 -4
- package/src/server/management/model-rows.ts +4 -0
- package/src/server/management/native-integration-routes.ts +2 -1
- package/src/server/management/oauth-account-routes.ts +10 -4
- package/src/server/management/provider-capability-config.ts +1 -1
- package/src/server/management/provider-routes.ts +81 -11
- package/src/server/management/route-registry.ts +332 -0
- package/src/server/management/routing-profile-routes.ts +2 -2
- package/src/server/management/system-restart.ts +1 -1
- package/src/server/management-api.ts +18 -16
- package/src/server/port-reclaim.ts +1 -1
- package/src/server/proxy-liveness.ts +29 -5
- package/src/server/relay-eager.ts +147 -20
- package/src/server/relay.ts +251 -19
- package/src/server/request-log-conversation.ts +51 -0
- package/src/server/request-log.ts +70 -16
- package/src/server/responses/codex-auth-error.ts +55 -0
- package/src/server/responses/collaboration.ts +37 -3
- package/src/server/responses/combo-stream-preflight.ts +178 -0
- package/src/server/responses/compact.ts +6 -21
- package/src/server/responses/core.ts +810 -208
- package/src/server/responses/empty-completion-guard.ts +63 -6
- package/src/server/responses/fetch-helpers.ts +17 -102
- package/src/server/responses/input-admission.ts +3 -1
- package/src/server/responses/passthrough-error.ts +33 -9
- package/src/server/responses/responses-field-backfill.ts +105 -13
- package/src/server/responses/ws-upstream.ts +75 -2
- package/src/server/responses-custom-tool-repair.ts +87 -6
- package/src/server/responses-terminal-repair.ts +25 -4
- package/src/server/responses-undeclared-tool-guard.ts +241 -18
- package/src/server/sse-frame-buffer.ts +31 -4
- package/src/server/ws-bridge.ts +14 -2
- package/src/service.ts +42 -4
- package/src/storage/policy-job.ts +14 -4
- package/src/storage/policy.ts +88 -23
- package/src/types/config.ts +66 -0
- package/src/types/provider.ts +69 -0
- package/src/types/request.ts +17 -4
- package/src/types/tools.ts +116 -11
- package/src/types.ts +3 -1
- package/src/update/index.ts +5 -4
- package/src/update/job.ts +3 -1
- package/src/update/transactional-install.mjs +8 -1
- package/src/usage/expected-prices.ts +43 -24
- package/src/usage/log.ts +63 -12
- package/src/usage/summary.ts +211 -8
- package/src/vision/describe.ts +18 -13
- package/src/web-search/exa-executor.ts +40 -9
- package/src/web-search/executor.ts +10 -3
- package/src/web-search/loop.ts +5 -4
- package/gui/dist/assets/index-BF38heuV.js +0 -104
- package/gui/dist/assets/index-DMiI18Kv.css +0 -1
package/README.md
CHANGED
|
@@ -27,17 +27,17 @@ ocx start # proxy + dashboard on localhost:10100
|
|
|
27
27
|
<sub><b>Claude Code, running any model.</b><br>The picker is stock Claude Code. The brain behind it isn't.</sub>
|
|
28
28
|
</td>
|
|
29
29
|
<td width="50%" align="center">
|
|
30
|
-
<img src="assets/demo.gif" alt="opencodex demo — running a task in the Codex app on a routed non-OpenAI model" width="410"><br>
|
|
30
|
+
<img src="https://raw.githubusercontent.com/lidge-jun/opencodex/main/assets/demo.gif" alt="opencodex demo — running a task in the Codex app on a routed non-OpenAI model" width="410"><br>
|
|
31
31
|
<sub><b>Codex, running any model.</b><br>Pick a provider and go — same workflow, different brain.</sub>
|
|
32
32
|
</td>
|
|
33
33
|
</tr>
|
|
34
34
|
<tr>
|
|
35
35
|
<td width="50%" align="center">
|
|
36
|
-
<img src="assets/claude-desktop-subagent.gif" alt="Claude Desktop answering as Claude Opus 4.8, then dispatching a GPT-5.6 Sol subagent through opencodex" width="410"><br>
|
|
36
|
+
<img src="https://raw.githubusercontent.com/lidge-jun/opencodex/main/assets/claude-desktop-subagent.gif" alt="Claude Desktop answering as Claude Opus 4.8, then dispatching a GPT-5.6 Sol subagent through opencodex" width="410"><br>
|
|
37
37
|
<sub><b>Claude Desktop, running any model.</b><br>Opus answers, then hands the task to a GPT-5.6 Sol subagent.</sub>
|
|
38
38
|
</td>
|
|
39
39
|
<td width="50%" align="center">
|
|
40
|
-
<img src="assets/grok-build-subagent.gif" alt="Grok Build running GPT-5.6 Sol through opencodex and calling a Kimi K3 subagent" width="410"><br>
|
|
40
|
+
<img src="https://raw.githubusercontent.com/lidge-jun/opencodex/main/assets/grok-build-subagent.gif" alt="Grok Build running GPT-5.6 Sol through opencodex and calling a Kimi K3 subagent" width="410"><br>
|
|
41
41
|
<sub><b>Grok Build, running any model.</b><br>Sol drives the session and calls a Kimi K3 subagent.</sub>
|
|
42
42
|
</td>
|
|
43
43
|
</tr>
|
package/bin/ocx.mjs
CHANGED
|
@@ -227,11 +227,90 @@ function runNpmSelfUpdate() {
|
|
|
227
227
|
} catch { /* keep default */ }
|
|
228
228
|
}
|
|
229
229
|
|
|
230
|
+
const launcher = fileURLToPath(import.meta.url);
|
|
231
|
+
|
|
232
|
+
function startProxyDirectly() {
|
|
233
|
+
if (!existsSync(launcher)) {
|
|
234
|
+
console.error("opencodex: cannot restart the proxy because the launcher is missing; reinstall opencodex manually.");
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
const env = { ...process.env };
|
|
238
|
+
delete env.OCX_SERVICE;
|
|
239
|
+
console.log(`Attempting to restart the proxy on port ${bakePort}.`);
|
|
240
|
+
const child = spawn(process.execPath, [launcher, "start", "--port", String(bakePort)], {
|
|
241
|
+
detached: true,
|
|
242
|
+
stdio: "ignore",
|
|
243
|
+
windowsHide: true,
|
|
244
|
+
env,
|
|
245
|
+
});
|
|
246
|
+
child.on("error", error => {
|
|
247
|
+
console.error(`opencodex: direct proxy restart failed: ${error.message}`);
|
|
248
|
+
});
|
|
249
|
+
child.unref();
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
function refreshBackgroundServiceOrStartDirect() {
|
|
253
|
+
const prevBake = process.env.OCX_BAKE_PORT;
|
|
254
|
+
process.env.OCX_BAKE_PORT = String(bakePort);
|
|
255
|
+
try {
|
|
256
|
+
let svc = spawnSync(process.execPath, serviceRefreshArgs(), { stdio: "inherit", windowsHide: true });
|
|
257
|
+
// `serviceWasInstalled` is inferred from service-state.json alone, which can be
|
|
258
|
+
// STALE — present while the registration is gone. Repair refuses that case by
|
|
259
|
+
// design, and its thrown Error is indistinguishable from any other failure at
|
|
260
|
+
// this layer (plain Error, inherited stdio, generic exit status). So ask for
|
|
261
|
+
// structured state instead of parsing the failure: install only when the
|
|
262
|
+
// diagnostic says the service is genuinely absent. Installing after ANY repair
|
|
263
|
+
// failure would resurrect the elevation prompt this change exists to avoid, and
|
|
264
|
+
// could re-register a service the user just uninstalled.
|
|
265
|
+
if (svc.status !== 0 && readServiceInstalledFromStatus(launcher) === false) {
|
|
266
|
+
console.log("No registered service found — installing it instead.");
|
|
267
|
+
svc = spawnSync(process.execPath, serviceInstallArgs(), { stdio: "inherit", windowsHide: true });
|
|
268
|
+
}
|
|
269
|
+
let needDirectStart = svc.status !== 0;
|
|
270
|
+
if (!needDirectStart) {
|
|
271
|
+
// Exit 0 can still leave stale/missing assets that never bring the proxy
|
|
272
|
+
// back — match the GUI/CLI fallthrough so /healthz is not left dead.
|
|
273
|
+
try {
|
|
274
|
+
const st = spawnSync(process.execPath, [launcher, "status", "--json"], {
|
|
275
|
+
encoding: "utf8",
|
|
276
|
+
timeout: 20_000,
|
|
277
|
+
windowsHide: true,
|
|
278
|
+
});
|
|
279
|
+
if (st.status === 0 && typeof st.stdout === "string" && st.stdout.trim()) {
|
|
280
|
+
const parsed = JSON.parse(st.stdout);
|
|
281
|
+
const proxyUp = parsed?.proxy?.running === true || parsed?.proxy?.health?.ok === true;
|
|
282
|
+
const viable = parsed?.startup?.serviceViable === true;
|
|
283
|
+
if (!proxyUp && !viable) needDirectStart = true;
|
|
284
|
+
} else {
|
|
285
|
+
// status failed or empty — fail closed to direct start (match CLI).
|
|
286
|
+
needDirectStart = true;
|
|
287
|
+
}
|
|
288
|
+
} catch {
|
|
289
|
+
needDirectStart = true;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
if (needDirectStart) {
|
|
293
|
+
// A repair needs no elevation, but it can still fail — or exit 0 while leaving
|
|
294
|
+
// a non-viable manager. Fall back to a direct detached proxy start so the
|
|
295
|
+
// update never leaves the user without a running proxy.
|
|
296
|
+
console.warn(
|
|
297
|
+
svc.status === 0
|
|
298
|
+
? "opencodex: service refresh left a non-viable manager — starting the proxy directly instead."
|
|
299
|
+
: "opencodex: service refresh failed — starting the proxy directly instead.",
|
|
300
|
+
);
|
|
301
|
+
console.warn(" Run 'ocx service repair' to see why the background service could not restart.");
|
|
302
|
+
startProxyDirectly();
|
|
303
|
+
}
|
|
304
|
+
} finally {
|
|
305
|
+
if (prevBake === undefined) delete process.env.OCX_BAKE_PORT;
|
|
306
|
+
else process.env.OCX_BAKE_PORT = prevBake;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
230
310
|
// Never replace package files under a live proxy — stop it first (full `ocx stop`
|
|
231
311
|
// semantics: graceful drain, service stop, native Codex restore). Gate on the service
|
|
232
312
|
// and the runtime-port record too: a service-managed or orphaned proxy can be live
|
|
233
313
|
// while ocx.pid is stale/missing.
|
|
234
|
-
const launcher = fileURLToPath(import.meta.url);
|
|
235
314
|
if (trayBeforeUpdate.stopBeforeReplacement) {
|
|
236
315
|
console.log("⏹ Handing off the Windows tray before updating...");
|
|
237
316
|
try {
|
|
@@ -249,6 +328,17 @@ function runNpmSelfUpdate() {
|
|
|
249
328
|
}
|
|
250
329
|
const hasRuntimeState =
|
|
251
330
|
existsSync(join(configDir(), "ocx.pid")) || existsSync(join(configDir(), "runtime-port.json"));
|
|
331
|
+
|
|
332
|
+
function recoverStoppedRuntimeAfterFailure() {
|
|
333
|
+
if (serviceWasInstalled) {
|
|
334
|
+
console.warn("opencodex: update failed after stopping the proxy — restoring the previous background service.");
|
|
335
|
+
refreshBackgroundServiceOrStartDirect();
|
|
336
|
+
} else if (hasRuntimeState) {
|
|
337
|
+
console.warn("opencodex: update failed after stopping the proxy — restarting the previous version directly.");
|
|
338
|
+
startProxyDirectly();
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
252
342
|
if (serviceWasInstalled || hasRuntimeState) {
|
|
253
343
|
console.log("⏹ Stopping the running proxy before updating...");
|
|
254
344
|
const stopRes = spawnSync(process.execPath, [launcher, "stop"], { stdio: "inherit", windowsHide: true });
|
|
@@ -261,9 +351,9 @@ function runNpmSelfUpdate() {
|
|
|
261
351
|
}
|
|
262
352
|
if (historyRestoreIncomplete()) {
|
|
263
353
|
console.warn(
|
|
264
|
-
"opencodex: WARNING — Codex resume
|
|
265
|
-
"
|
|
266
|
-
" After the update: close the Codex app, then run 'ocx stop' once to
|
|
354
|
+
"opencodex: WARNING — Codex resume-history metadata restore is incomplete (a backup manifest remains).\n" +
|
|
355
|
+
" The DB may be busy or the manifest/target may need review; untracked routed history is intentionally unchanged.\n" +
|
|
356
|
+
" After the update: close the Codex app, run 'ocx doctor', then run 'ocx stop' once to retry.",
|
|
267
357
|
);
|
|
268
358
|
}
|
|
269
359
|
}
|
|
@@ -309,7 +399,8 @@ function runNpmSelfUpdate() {
|
|
|
309
399
|
// it recreates the #1849 destruction path. Report and stop; the boot probe and the
|
|
310
400
|
// recovery marker cover the swap-window states.
|
|
311
401
|
console.error(`opencodex: transactional update failed unexpectedly (${error?.message ?? error}). ` +
|
|
312
|
-
|
|
402
|
+
`The live install was not knowingly modified; run 'ocx update' again or reinstall with ` +
|
|
403
|
+
`npm install -g --allow-scripts=bun ${PKG}@${tag}.`);
|
|
313
404
|
res = { status: 1 };
|
|
314
405
|
}
|
|
315
406
|
if (res.status === 0) {
|
|
@@ -329,77 +420,15 @@ function runNpmSelfUpdate() {
|
|
|
329
420
|
// launcher so the new files write the baked paths and the service restarts.
|
|
330
421
|
if (serviceWasInstalled) {
|
|
331
422
|
console.log("Refreshing the background service with the updated files...");
|
|
332
|
-
|
|
333
|
-
process.env.OCX_BAKE_PORT = String(bakePort);
|
|
334
|
-
try {
|
|
335
|
-
let svc = spawnSync(process.execPath, serviceRefreshArgs(), { stdio: "inherit", windowsHide: true });
|
|
336
|
-
// `serviceWasInstalled` is inferred from service-state.json alone, which can be
|
|
337
|
-
// STALE — present while the registration is gone. Repair refuses that case by
|
|
338
|
-
// design, and its thrown Error is indistinguishable from any other failure at
|
|
339
|
-
// this layer (plain Error, inherited stdio, generic exit status). So ask for
|
|
340
|
-
// structured state instead of parsing the failure: install only when the
|
|
341
|
-
// diagnostic says the service is genuinely absent. Installing after ANY repair
|
|
342
|
-
// failure would resurrect the elevation prompt this change exists to avoid, and
|
|
343
|
-
// could re-register a service the user just uninstalled.
|
|
344
|
-
if (svc.status !== 0 && readServiceInstalledFromStatus(launcher) === false) {
|
|
345
|
-
console.log("No registered service found — installing it instead.");
|
|
346
|
-
svc = spawnSync(process.execPath, serviceInstallArgs(), { stdio: "inherit", windowsHide: true });
|
|
347
|
-
}
|
|
348
|
-
let needDirectStart = svc.status !== 0;
|
|
349
|
-
if (!needDirectStart) {
|
|
350
|
-
// Exit 0 can still leave stale/missing assets that never bring the proxy
|
|
351
|
-
// back — match the GUI/CLI fallthrough so /healthz is not left dead.
|
|
352
|
-
try {
|
|
353
|
-
const st = spawnSync(process.execPath, [launcher, "status", "--json"], {
|
|
354
|
-
encoding: "utf8",
|
|
355
|
-
timeout: 20_000,
|
|
356
|
-
windowsHide: true,
|
|
357
|
-
});
|
|
358
|
-
if (st.status === 0 && typeof st.stdout === "string" && st.stdout.trim()) {
|
|
359
|
-
const parsed = JSON.parse(st.stdout);
|
|
360
|
-
const proxyUp = parsed?.proxy?.running === true || parsed?.proxy?.health?.ok === true;
|
|
361
|
-
const viable = parsed?.startup?.serviceViable === true;
|
|
362
|
-
if (!proxyUp && !viable) needDirectStart = true;
|
|
363
|
-
} else {
|
|
364
|
-
// status failed or empty — fail closed to direct start (match CLI).
|
|
365
|
-
needDirectStart = true;
|
|
366
|
-
}
|
|
367
|
-
} catch {
|
|
368
|
-
needDirectStart = true;
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
if (needDirectStart) {
|
|
372
|
-
// A repair needs no elevation, but it can still fail — or exit 0 while leaving
|
|
373
|
-
// a non-viable manager. Fall back to a direct detached proxy start so the
|
|
374
|
-
// update never leaves the user without a running proxy.
|
|
375
|
-
console.warn(
|
|
376
|
-
svc.status === 0
|
|
377
|
-
? "opencodex: service refresh left a non-viable manager — starting the proxy directly instead."
|
|
378
|
-
: "opencodex: service refresh failed — starting the proxy directly instead.",
|
|
379
|
-
);
|
|
380
|
-
console.warn(" Run 'ocx service repair' to see why the background service could not restart.");
|
|
381
|
-
const env = { ...process.env };
|
|
382
|
-
delete env.OCX_SERVICE;
|
|
383
|
-
const child = spawn(process.execPath, [launcher, "start", "--port", String(bakePort)], {
|
|
384
|
-
detached: true,
|
|
385
|
-
stdio: "ignore",
|
|
386
|
-
windowsHide: true,
|
|
387
|
-
env,
|
|
388
|
-
});
|
|
389
|
-
child.unref();
|
|
390
|
-
console.log(`Proxy starting on port ${bakePort}.`);
|
|
391
|
-
}
|
|
392
|
-
} finally {
|
|
393
|
-
if (prevBake === undefined) delete process.env.OCX_BAKE_PORT;
|
|
394
|
-
else process.env.OCX_BAKE_PORT = prevBake;
|
|
395
|
-
}
|
|
423
|
+
refreshBackgroundServiceOrStartDirect();
|
|
396
424
|
} else {
|
|
397
425
|
console.log("Restart the proxy: ocx start");
|
|
398
426
|
}
|
|
399
427
|
process.exit(0);
|
|
400
428
|
}
|
|
401
429
|
if (trayBeforeUpdate.restoreOnFailure) runTrayLifecycle(launcher, "start");
|
|
402
|
-
|
|
430
|
+
recoverStoppedRuntimeAfterFailure();
|
|
431
|
+
console.error(`\nUpdate failed (npm exit ${res.status ?? "?"}). Try manually: npm install -g --allow-scripts=bun ${PKG}@${tag}`);
|
|
403
432
|
process.exit(1);
|
|
404
433
|
}
|
|
405
434
|
|