@bitkyc08/opencodex 2.36.0 → 2.38.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.
Files changed (70) hide show
  1. package/bin/ocx.mjs +69 -10
  2. package/gui/dist/assets/index-C14iCj_Q.js +112 -0
  3. package/gui/dist/assets/index-D7PIz7_g.css +1 -0
  4. package/gui/dist/index.html +2 -2
  5. package/gui/dist/provider-icons/aside.svg +3 -0
  6. package/gui/dist/provider-icons/deepseek-harness.svg +3 -0
  7. package/gui/dist/provider-icons/oh-my-pi.svg +11 -0
  8. package/gui/dist/provider-icons/openclaw.svg +54 -0
  9. package/gui/dist/provider-icons/prime-agent.svg +21 -0
  10. package/gui/dist/provider-icons/zcode.svg +219 -0
  11. package/package.json +1 -1
  12. package/src/adapters/cursor/protobuf-request.ts +4 -1
  13. package/src/adapters/cursor/tool-definitions.ts +36 -4
  14. package/src/adapters/kiro-constants.ts +36 -2
  15. package/src/adapters/kiro.ts +13 -2
  16. package/src/cli/capabilities.ts +14 -0
  17. package/src/cli/claude.ts +12 -0
  18. package/src/cli/codex-cli-update.ts +96 -0
  19. package/src/cli/codex-shim-autorestore.ts +3 -0
  20. package/src/cli/export-command.ts +18 -17
  21. package/src/cli/help.ts +2 -2
  22. package/src/cli/index.ts +3 -2
  23. package/src/cli/launcher-context.ts +53 -2
  24. package/src/cli/opencode.ts +126 -33
  25. package/src/cli/registry.ts +16 -10
  26. package/src/cli/system-command.ts +6 -1
  27. package/src/clients/config-export.ts +293 -28
  28. package/src/codex/account-store.ts +10 -4
  29. package/src/codex/autostart-health.ts +3 -3
  30. package/src/codex/catalog/provider-fetch.ts +20 -1
  31. package/src/codex/catalog/sync.ts +4 -3
  32. package/src/codex/cli-install-provenance.ts +795 -0
  33. package/src/codex/convergence.ts +4 -3
  34. package/src/codex/credential-mutation-epoch.ts +11 -0
  35. package/src/codex/main-account.ts +2 -0
  36. package/src/codex/model-entitlements.ts +489 -30
  37. package/src/codex/native-profile-manager.ts +4 -0
  38. package/src/codex/reset-credit-operation-ledger.ts +1411 -0
  39. package/src/codex/reset-credit-recovery.ts +20 -2
  40. package/src/codex/shim.ts +204 -18
  41. package/src/codex/user-identity.ts +2 -1
  42. package/src/config/paths.ts +18 -3
  43. package/src/config.ts +23 -0
  44. package/src/generated/compatibility-version.json +84 -48
  45. package/src/integrations/registry.ts +112 -0
  46. package/src/integrations/state.ts +67 -5
  47. package/src/integrations/writer.ts +25 -9
  48. package/src/lib/bounded-subprocess.ts +36 -0
  49. package/src/lib/strict-semver.ts +47 -0
  50. package/src/lib/windows-elevation.ts +32 -1
  51. package/src/lib/windows-secret-acl.ts +47 -25
  52. package/src/lib/windows-service-mutation-lock.ts +133 -0
  53. package/src/lib/windows-user-principal.ts +15 -17
  54. package/src/responses/spill-store.ts +334 -29
  55. package/src/responses/state.ts +488 -7
  56. package/src/server/index.ts +4 -3
  57. package/src/server/lifecycle.ts +5 -1
  58. package/src/server/management/model-rows.ts +11 -2
  59. package/src/server/management/provider-routes.ts +4 -0
  60. package/src/server/management/system-restart.ts +5 -5
  61. package/src/server/management-api.ts +7 -2
  62. package/src/server/startup-action-control.ts +3 -2
  63. package/src/service.ts +594 -33
  64. package/src/sidecar/candidates.ts +1 -1
  65. package/src/update/codex-cli-update-launch-policy.d.mts +18 -0
  66. package/src/update/codex-cli-update-launch-policy.mjs +30 -0
  67. package/src/update/index.ts +3 -2
  68. package/src/update/job.ts +10 -11
  69. package/gui/dist/assets/index-Cy7Z_pl0.css +0 -1
  70. package/gui/dist/assets/index-DO8liQVL.js +0 -112
package/bin/ocx.mjs CHANGED
@@ -23,6 +23,10 @@ import {
23
23
  } from "../src/update/npm-cache-preflight.mjs";
24
24
  import { handoffWindowsTrayForUpdate, planWindowsTrayUpdate } from "../src/update/tray-update-plan.mjs";
25
25
  import { bootRestoreProbe, transactionalNpmUpdate } from "../src/update/transactional-install.mjs";
26
+ import {
27
+ CODEX_CLI_VERSION_MANAGER_ROOT_ENV_SLOTS,
28
+ isCodexCliUpdateInspectionArgv,
29
+ } from "../src/update/codex-cli-update-launch-policy.mjs";
26
30
 
27
31
  const PKG = "@bitkyc08/opencodex";
28
32
  const require = createRequire(import.meta.url);
@@ -155,10 +159,9 @@ function runNpmSelfUpdate() {
155
159
  process.platform === "win32" ? trayInstallState() : { installed: false, running: false },
156
160
  );
157
161
  /**
158
- * Refresh the existing service without re-registering it. `service repair` discovers
159
- * the installed backend itself and, on Windows scheduler installs, rewrites the wrapper
160
- * assets and restarts the existing task without `schtasks /create` — the elevation a
161
- * non-admin `ocx update` does not have.
162
+ * Refresh the existing service in place. `service repair` discovers the installed backend;
163
+ * healthy Windows scheduler registrations avoid `schtasks /create`, while stale definitions
164
+ * may be re-registered and require elevation.
162
165
  */
163
166
  function serviceRefreshArgs() {
164
167
  return [launcher, "service", "repair"];
@@ -290,7 +293,8 @@ function runNpmSelfUpdate() {
290
293
  }
291
294
  }
292
295
  if (needDirectStart) {
293
- // A repair needs no elevation, but it can still fail or exit 0 while leaving
296
+ // Repair normally avoids elevation for a healthy registration, but a stale Windows
297
+ // scheduler definition can require it. It can also fail — or exit 0 while leaving
294
298
  // a non-viable manager. Fall back to a direct detached proxy start so the
295
299
  // update never leaves the user without a running proxy.
296
300
  console.warn(
@@ -468,7 +472,7 @@ function fail(msg) {
468
472
  process.exit(1);
469
473
  }
470
474
 
471
- function resolveBun() {
475
+ function resolveBun({ allowInstall = true } = {}) {
472
476
  // Keep direct npm-launcher starts aligned with durable service/shim installs:
473
477
  // a valid explicit runtime must win even when the bundled dependency exists.
474
478
  const override = process.env[BUN_OVERRIDE_ENV]?.trim();
@@ -493,7 +497,7 @@ function resolveBun() {
493
497
  // Lazy fallback: --ignore-scripts (or a failed postinstall) leaves the
494
498
  // ~450-byte placeholder stub. Run the bun package's own installer once.
495
499
  const installJs = join(bunDir, "install.js");
496
- if (existsSync(installJs)) {
500
+ if (allowInstall && existsSync(installJs)) {
497
501
  const r = spawnSync(process.execPath, [installJs], { stdio: "inherit" });
498
502
  if (r.status === 0) bin = findBunBinary(bunDir);
499
503
  }
@@ -512,6 +516,12 @@ if (updateHelpRequested) {
512
516
  process.exit(0);
513
517
  }
514
518
 
519
+ const codexCliUpdateInspection = isCodexCliUpdateInspectionArgv(process.argv);
520
+ if (codexCliUpdateInspection && typeof process.versions.bun === "string") {
521
+ console.error("opencodex: codex-cli-update inspection must use the published Node launcher.");
522
+ process.exit(1);
523
+ }
524
+
515
525
  if (process.argv[2] === "update" && isNodeModulesInstall() && !isBunGlobalInstall()) {
516
526
  runNpmSelfUpdate();
517
527
  }
@@ -519,7 +529,7 @@ if (process.argv[2] === "update" && isNodeModulesInstall() && !isBunGlobalInstal
519
529
  // #1849 boot probe: a prior update that lost power (or double-faulted) mid-swap leaves a
520
530
  // backup sibling and a broken live tree. Restore before anything tries to run from the
521
531
  // broken tree; reap stale backups once the live tree verifies healthy.
522
- if (isNodeModulesInstall() && !isBunGlobalInstall()) {
532
+ if (!codexCliUpdateInspection && isNodeModulesInstall() && !isBunGlobalInstall()) {
523
533
  try {
524
534
  const probe = bootRestoreProbe(resolve(here, ".."));
525
535
  if (probe.action === "restored") {
@@ -530,7 +540,7 @@ if (isNodeModulesInstall() && !isBunGlobalInstall()) {
530
540
  } catch { /* the probe must never block launch */ }
531
541
  }
532
542
 
533
- const bunRuntime = resolveBun();
543
+ const bunRuntime = resolveBun({ allowInstall: !codexCliUpdateInspection });
534
544
  const bun = bunRuntime.path;
535
545
 
536
546
  // Run the Bun child asynchronously and FORWARD termination signals to it, then wait
@@ -554,12 +564,61 @@ const bun = bunRuntime.path;
554
564
  // interpolation and provider settings legitimately read the project environment.
555
565
  const preBunAnthropicSlots = ["ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN", "ANTHROPIC_BASE_URL"]
556
566
  .filter(name => typeof process.env[name] === "string" && process.env[name] !== "");
567
+ // A configured CODEX_CLI_PATH may legitimately be cwd-relative (`./tools/codex`), which the
568
+ // ordinary runtime resolver accepts. Inspection only trusts absolute local paths, so capture
569
+ // the absolute form here, in the launcher, while the original cwd is still authoritative;
570
+ // resolving it later would silently reinterpret it against a different working directory.
571
+ //
572
+ // A bare command with no separator (`codex`) is NOT a relative path: the runtime resolver
573
+ // deliberately hands those to executable lookup along PATH. Rewriting it to `<cwd>/codex`
574
+ // would make the inspector treat it as an explicit path and stop searching PATH entirely.
575
+ const configuredCodexCliPath = typeof process.env.CODEX_CLI_PATH === "string" && process.env.CODEX_CLI_PATH !== ""
576
+ ? process.env.CODEX_CLI_PATH
577
+ : null;
578
+ const preBunCodexCliPath = configuredCodexCliPath !== null
579
+ && (configuredCodexCliPath.includes("/") || configuredCodexCliPath.includes("\\") || /^[A-Za-z]:/.test(configuredCodexCliPath))
580
+ ? resolve(configuredCodexCliPath)
581
+ : configuredCodexCliPath;
582
+ const preBunPath = typeof process.env.PATH === "string" ? process.env.PATH : null;
583
+ const preBunPathExt = typeof process.env.PATHEXT === "string" ? process.env.PATHEXT : null;
584
+ const preBunCodexCliManagerRoots = Object.fromEntries(
585
+ CODEX_CLI_VERSION_MANAGER_ROOT_ENV_SLOTS.flatMap(name => {
586
+ const value = process.env[name];
587
+ return typeof value === "string" && value !== "" ? [[name, value]] : [];
588
+ }),
589
+ );
557
590
  const launchProof = randomBytes(32).toString("base64url");
558
591
  const launchContext = JSON.stringify({
559
592
  version: 1,
560
593
  proof: launchProof,
561
594
  anthropicEnvSlots: preBunAnthropicSlots,
595
+ codexCliInspectionEnv: codexCliUpdateInspection ? {
596
+ codexCliPath: preBunCodexCliPath,
597
+ path: preBunPath,
598
+ pathExt: preBunPathExt,
599
+ managerRoots: preBunCodexCliManagerRoots,
600
+ configDir: configDir(),
601
+ } : null,
562
602
  });
603
+ // The inspection snapshot above already carries PATH, PATHEXT, and the manager-root slots as
604
+ // proof-bound values, and `inspectCodexCliInstall` reads them from that snapshot rather than
605
+ // from the live environment. Inheriting them again would spend the 32,767-character Windows
606
+ // environment block twice, so a large-but-valid shell environment could stop the Bun child
607
+ // from spawning and fail the command before it reports anything. Drop the duplicates for the
608
+ // one-shot inspection launch only; every other launch inherits the environment unchanged.
609
+ // Windows environment names are case-insensitive, but this spread produces an ordinary
610
+ // case-sensitive object, and a real Windows environment commonly spells the variable `Path`.
611
+ // Deleting only the canonical upper-case spelling would silently leave that copy behind and
612
+ // reintroduce the duplication this block exists to prevent, so match on the lowercase form.
613
+ const inheritedEnv = { ...process.env };
614
+ if (codexCliUpdateInspection) {
615
+ const snapshotted = new Set(
616
+ ["PATH", "PATHEXT", ...CODEX_CLI_VERSION_MANAGER_ROOT_ENV_SLOTS].map(name => name.toLowerCase()),
617
+ );
618
+ for (const name of Object.keys(inheritedEnv)) {
619
+ if (snapshotted.has(name.toLowerCase())) delete inheritedEnv[name];
620
+ }
621
+ }
563
622
  const child = spawn(bun, [cliPath, `${NODE_LAUNCH_PROOF_PREFIX}${launchProof}`, ...process.argv.slice(2)], {
564
623
  stdio: "inherit",
565
624
  // A headless Windows parent (Task Scheduler, dashboard restart, shortcut) has no
@@ -567,7 +626,7 @@ const child = spawn(bun, [cliPath, `${NODE_LAUNCH_PROOF_PREFIX}${launchProof}`,
567
626
  // the long-running Bun child, and closing that window kills the proxy (#1236).
568
627
  windowsHide: true,
569
628
  env: {
570
- ...process.env,
629
+ ...inheritedEnv,
571
630
  [NODE_LAUNCH_CONTEXT_ENV]: launchContext,
572
631
  [BUN_RUNTIME_SOURCE_ENV]: bunRuntime.source,
573
632
  [BUN_RUNTIME_PATH_ENV]: bunRuntime.path,