@bitkyc08/opencodex 2.69.0 → 2.70.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 (147) hide show
  1. package/gui/dist/assets/App-_MrbTrBe.js +51 -0
  2. package/gui/dist/assets/{Tray-uqKRqfvw.js → Tray-5PuUalET.js} +1 -1
  3. package/gui/dist/assets/index-DKrO2eF3.js +86 -0
  4. package/gui/dist/assets/quota-summary-BCLivc0Q.js +1 -0
  5. package/gui/dist/index.html +1 -1
  6. package/package.json +1 -1
  7. package/src/adapters/anthropic-model-contract.ts +119 -0
  8. package/src/adapters/anthropic.ts +14 -83
  9. package/src/adapters/base.ts +2 -0
  10. package/src/adapters/command-code-project-context.ts +542 -0
  11. package/src/adapters/command-code-tool-text.ts +99 -67
  12. package/src/adapters/command-code.ts +5 -1
  13. package/src/adapters/cursor/catalog.ts +11 -0
  14. package/src/adapters/cursor/effort-map.ts +3 -0
  15. package/src/adapters/devin/cloud-direct/catalog.ts +91 -0
  16. package/src/adapters/devin/cloud-direct/chat.ts +78 -48
  17. package/src/adapters/devin/cloud-direct/tool-schema.ts +121 -0
  18. package/src/adapters/devin/context-overflow.ts +75 -0
  19. package/src/adapters/devin/live-models.ts +174 -13
  20. package/src/adapters/devin/reasoning-signature.ts +100 -0
  21. package/src/adapters/devin.ts +310 -117
  22. package/src/adapters/kiro/payload.ts +10 -10
  23. package/src/adapters/kiro-images.ts +58 -7
  24. package/src/adapters/openai-chat/passthrough.ts +3 -1
  25. package/src/adapters/openai-chat.ts +2 -1
  26. package/src/adapters/openai-responses/passthrough.ts +2 -1
  27. package/src/bridge/response-json.ts +15 -1
  28. package/src/bridge/sse.ts +3 -1
  29. package/src/claude/intercept/model-bindings.ts +1 -0
  30. package/src/cli/account-extended.ts +31 -1
  31. package/src/cli/account.ts +3 -0
  32. package/src/cli/capabilities.ts +13 -0
  33. package/src/cli/client-start-fence.ts +36 -0
  34. package/src/cli/dispatch.ts +3 -2
  35. package/src/cli/index.ts +98 -117
  36. package/src/cli/provider-runtime.ts +23 -2
  37. package/src/cli/provider.ts +3 -0
  38. package/src/cli/resolve.ts +18 -0
  39. package/src/cli/start-owner-fence.ts +30 -0
  40. package/src/cli/stop-approval.ts +13 -1
  41. package/src/cli/stop-restore.ts +73 -0
  42. package/src/cli/tray-proxy.ts +221 -18
  43. package/src/cli/version-skew.ts +25 -23
  44. package/src/client/runtime.ts +8 -4
  45. package/src/codex/auth-api/account-list.ts +11 -5
  46. package/src/codex/auth-api/login-flow.ts +5 -3
  47. package/src/codex/auth-api/main-account-probe.ts +186 -110
  48. package/src/codex/auth-api/pool-mode-gate.ts +61 -7
  49. package/src/codex/auth-api/pool-quota-probe.ts +142 -90
  50. package/src/codex/auth-api/reset-credit-service.ts +1 -1
  51. package/src/codex/catalog/gather-capture.ts +1 -0
  52. package/src/codex/catalog/model-hints.ts +3 -3
  53. package/src/codex/catalog/provider-models.ts +2 -0
  54. package/src/codex/low-quota-events.ts +28 -0
  55. package/src/codex/low-quota-observer.ts +23 -0
  56. package/src/codex/low-quota-protection.ts +272 -0
  57. package/src/codex/quota-query-backoff.ts +148 -0
  58. package/src/codex/quota.ts +7 -2
  59. package/src/config/diagnostics.ts +10 -1
  60. package/src/config/load-degrade.ts +17 -0
  61. package/src/config/mutation-lock.ts +3 -4
  62. package/src/config/process-state.ts +1 -1
  63. package/src/config/provider-validation.ts +22 -0
  64. package/src/config/schema/blocked-model-redirects.ts +17 -0
  65. package/src/config/schema/config-schema.ts +4 -1
  66. package/src/config/schema/leaf-validators.ts +33 -2
  67. package/src/config/serving-runtimes.ts +412 -0
  68. package/src/generated/compatibility-version.json +211 -115
  69. package/src/generated/model-metadata.ts +3 -3
  70. package/src/images/loop.ts +3 -0
  71. package/src/lib/errors.ts +2 -1
  72. package/src/lib/handled-signal-exit.ts +23 -0
  73. package/src/lib/request-failure-model.ts +1 -0
  74. package/src/lib/self-launch-argv.ts +9 -0
  75. package/src/lib/shadow-call.ts +5 -2
  76. package/src/lib/strict-semver.ts +26 -0
  77. package/src/lib/transient-service-path.ts +16 -0
  78. package/src/lib/windows-service-wrappers.ts +10 -6
  79. package/src/lib/winsw.ts +3 -1
  80. package/src/oauth/anthropic-model-routes.ts +105 -0
  81. package/src/oauth/anthropic-routing.ts +85 -48
  82. package/src/oauth/devin.ts +135 -5
  83. package/src/oauth/index.ts +20 -3
  84. package/src/oauth/kiro-terminal-failover.ts +23 -9
  85. package/src/oauth/pool-settings-capability.ts +10 -2
  86. package/src/oauth/store.ts +1 -1
  87. package/src/protocols/encoders/adapter-events.ts +3 -1
  88. package/src/providers/github-copilot-context.ts +27 -0
  89. package/src/providers/kiro-models.ts +4 -0
  90. package/src/providers/model-rename-fields.ts +3 -0
  91. package/src/providers/quota/account-cache.ts +8 -3
  92. package/src/providers/quota/devin.ts +286 -0
  93. package/src/providers/quota/vendor-probes-oauth.ts +6 -2
  94. package/src/providers/quota.ts +1 -1
  95. package/src/providers/registry/entries-core.ts +1 -1
  96. package/src/providers/registry/model-seeds.ts +5 -2
  97. package/src/responses/compaction-images.ts +27 -0
  98. package/src/router.ts +104 -16
  99. package/src/routing/analytics.ts +1 -0
  100. package/src/server/auth-cors.ts +9 -1
  101. package/src/server/background-lifecycle.ts +21 -10
  102. package/src/server/chat-completions.ts +2 -1
  103. package/src/server/chat-native.ts +1 -0
  104. package/src/server/index.ts +4 -8
  105. package/src/server/inference/client-encoder-delivery.ts +3 -0
  106. package/src/server/management/context.ts +3 -0
  107. package/src/server/management/low-quota-routes.ts +14 -0
  108. package/src/server/management/oauth-account-routes.ts +21 -1
  109. package/src/server/management/provider-overwrite-carry.ts +79 -6
  110. package/src/server/management/provider-routes.ts +41 -28
  111. package/src/server/management/route-registry.ts +1 -0
  112. package/src/server/management-api.ts +7 -0
  113. package/src/server/responses/adapter-continuation.ts +3 -0
  114. package/src/server/responses/adapter-delivery.ts +3 -0
  115. package/src/server/responses/adapter-dispatch.ts +20 -4
  116. package/src/server/responses/antigravity-validation-refusal.ts +20 -0
  117. package/src/server/responses/core-auth.ts +1 -0
  118. package/src/server/responses/core-codex-account.ts +1 -0
  119. package/src/server/responses/core-normalize.ts +4 -0
  120. package/src/server/responses/passthrough-dispatch.ts +8 -1
  121. package/src/server/responses/request-sidecar-auth.ts +2 -0
  122. package/src/server/responses/request-transport.ts +27 -10
  123. package/src/server/responses/response-effects.ts +4 -1
  124. package/src/server/responses/run-turn-execution.ts +126 -42
  125. package/src/server/responses/sidecar-execution.ts +4 -1
  126. package/src/service/diagnostics.ts +3 -1
  127. package/src/service/guarded-manager-target.ts +39 -12
  128. package/src/service/launchd.ts +14 -6
  129. package/src/service/repair.ts +6 -1
  130. package/src/service/service-child-ownership.ts +168 -0
  131. package/src/service/state.ts +22 -4
  132. package/src/service/systemd.ts +2 -2
  133. package/src/service/windows-guarded-manager.ts +530 -0
  134. package/src/service/windows-taskxml.ts +2 -2
  135. package/src/service.ts +2 -0
  136. package/src/types/config.ts +26 -0
  137. package/src/types/provider.ts +12 -0
  138. package/src/types/request.ts +2 -0
  139. package/src/types.ts +1 -0
  140. package/src/usage/expected-prices.ts +13 -0
  141. package/src/usage/telemetry-contract.ts +1 -0
  142. package/src/vision/anthropic-describe.ts +2 -1
  143. package/src/web-search/anthropic-executor.ts +2 -1
  144. package/src/web-search/loop.ts +1 -0
  145. package/gui/dist/assets/App-DDbgOTh6.js +0 -51
  146. package/gui/dist/assets/index-CuaBJkG4.js +0 -86
  147. package/gui/dist/assets/quota-summary-COppQSVq.js +0 -1
@@ -0,0 +1,168 @@
1
+ import { foreignServiceOwnerRefusal, unknownServiceOwnerRefusal } from "./repair";
2
+ import {
3
+ resolveServiceOwnership,
4
+ SERVICE_MANAGED_ENV,
5
+ windowsLauncherVbsPath,
6
+ windowsServiceScriptPath,
7
+ } from "./state";
8
+ import { readProcessCommandLine } from "../config/process-state";
9
+ import { winswExePath } from "../lib/winsw";
10
+ import { serviceStayOutExitCode, WINDOWS_WRAPPER_PROTOCOL_ENV } from "./windows-wrapper-exit";
11
+
12
+ export type ServiceChildOwnershipDecision =
13
+ | Readonly<{ kind: "proceed" }>
14
+ | Readonly<{ kind: "stay-out"; refusal: string }>;
15
+
16
+ /**
17
+ * Test seams for the marker-less supervisor detection below. Production callers
18
+ * pass nothing; every default is the real process query.
19
+ */
20
+ export type ServiceChildOwnershipDeps = {
21
+ platform?: NodeJS.Platform;
22
+ /** Defaults to process.ppid — the service child's direct supervisor. */
23
+ parentPid?: () => number | undefined;
24
+ /** Defaults to the shared Win32/procfs/ps command-line reader. */
25
+ processCommandLine?: (pid: number) => string | undefined;
26
+ /**
27
+ * Canonical absolute paths that prove a parent process is one of THIS
28
+ * installation's registered service hosts: the Task Scheduler wrapper script,
29
+ * its wscript launcher, or the WinSW host executable.
30
+ */
31
+ serviceHostPaths?: () => readonly string[];
32
+ };
33
+
34
+ /** The env markers a real supervisor writes that an `ocx claude`/`ocx opencode` child does not. */
35
+ function isMarkedSupervisedServiceChild(env: NodeJS.ProcessEnv): boolean {
36
+ return env[SERVICE_MANAGED_ENV] === "1" || env[WINDOWS_WRAPPER_PROTOCOL_ENV] === "1";
37
+ }
38
+
39
+ /**
40
+ * Whether the parent's command line names one of the registered service-host
41
+ * paths as a COMPLETE token. Same boundary rule as windowsWrapperKillScript:
42
+ * the character before and after the path must be whitespace or a quote, so a
43
+ * merely similar path suffix never qualifies.
44
+ */
45
+ function commandLineRunsServiceHost(
46
+ commandLine: string,
47
+ serviceHostPaths: readonly string[],
48
+ ): boolean {
49
+ const upper = commandLine.toLowerCase();
50
+ for (const serviceHostPath of serviceHostPaths) {
51
+ const needle = serviceHostPath.toLowerCase();
52
+ let from = 0;
53
+ while (from < commandLine.length) {
54
+ const at = upper.indexOf(needle, from);
55
+ if (at < 0) break;
56
+ // Boundary characters are read from the lowered copy so a case-mapping
57
+ // that changes length can never shift the token check off by a code unit.
58
+ const before = at === 0 ? " " : upper[at - 1];
59
+ const end = at + needle.length;
60
+ const after = end >= upper.length ? " " : upper[end];
61
+ if (/[\s"']/.test(before) && /[\s"']/.test(after)) return true;
62
+ from = at + 1;
63
+ }
64
+ }
65
+ return false;
66
+ }
67
+
68
+ /**
69
+ * Marker-less supervisor evidence for installs that predate the env markers.
70
+ *
71
+ * The legacy Windows Task Scheduler wrapper runs `start` inside the same
72
+ * cmd.exe that hosts the :loop, and the WinSW host spawns it directly — so on
73
+ * Windows the proof is the PARENT's command line naming the canonical wrapper
74
+ * script, launcher, or WinSW executable inside this install's config dir.
75
+ * POSIX is deliberately not guessed here: a companion whose parent exited can
76
+ * be reparented to init (a reparented `ocx claude` proxy is not a managed
77
+ * job), and `systemd --user` services are not init's children at all, so a
78
+ * ppid check would refuse some companions while still missing user units.
79
+ * Marker-less launchd/systemd registrations keep their previous behavior until
80
+ * a discriminator backed by the manager itself exists.
81
+ *
82
+ * An unreadable parent command line is evidence of NOTHING and must not refuse:
83
+ * `ocx claude`/`ocx opencode` companions carry only OCX_SERVICE=1 too, and a
84
+ * failed CIM/procfs probe cannot be allowed to break them.
85
+ */
86
+ function isUnmarkedSupervisedServiceChild(
87
+ env: NodeJS.ProcessEnv,
88
+ deps: Required<Pick<ServiceChildOwnershipDeps, "platform" | "parentPid" | "processCommandLine" | "serviceHostPaths">>,
89
+ ): boolean {
90
+ if (env.OCX_SERVICE !== "1") return false;
91
+ if (deps.platform === "win32") {
92
+ const ppid = deps.parentPid();
93
+ if (ppid === undefined || ppid <= 0) return false;
94
+ const parentCommandLine = deps.processCommandLine(ppid);
95
+ if (parentCommandLine === undefined) return false;
96
+ return commandLineRunsServiceHost(parentCommandLine, deps.serviceHostPaths());
97
+ }
98
+ return false;
99
+ }
100
+
101
+ export function isSupervisedServiceChild(env: NodeJS.ProcessEnv, deps: ServiceChildOwnershipDeps = {}): boolean {
102
+ if (isMarkedSupervisedServiceChild(env)) return true;
103
+ const resolved = {
104
+ platform: deps.platform ?? process.platform,
105
+ parentPid: deps.parentPid ?? (() => process.ppid),
106
+ processCommandLine: deps.processCommandLine ?? readProcessCommandLine,
107
+ serviceHostPaths:
108
+ deps.serviceHostPaths ??
109
+ (() => [windowsServiceScriptPath(), windowsLauncherVbsPath(), winswExePath()]),
110
+ };
111
+ return isUnmarkedSupervisedServiceChild(env, resolved);
112
+ }
113
+
114
+ /**
115
+ * Whether a supervised service child may start serving under the recorded owner.
116
+ *
117
+ * `ocx service start` already refuses to activate the npm registration while the
118
+ * desktop app owns the runtime, but the process manager itself never asked: the
119
+ * Windows boot wrapper loops `index.ts start`, so a desktop takeover was
120
+ * silently overridden the next time the wrapper respawned the child. The child
121
+ * now asks the same question before binding a port.
122
+ *
123
+ * "none" still proceeds: a service installed before ownership tracking has no
124
+ * claim to defer to. Registrations written before the supervisor env markers
125
+ * existed are identified by the parent's command line on Windows rather than
126
+ * by env alone, so an already-installed wrapper cannot sneak back in as an
127
+ * ordinary OCX_SERVICE=1 child — while `ocx claude`/`ocx opencode`
128
+ * companions, whose parent is the invoking CLI, still pass.
129
+ */
130
+ export function serviceChildOwnershipDecision(
131
+ env: NodeJS.ProcessEnv,
132
+ resolve: typeof resolveServiceOwnership = resolveServiceOwnership,
133
+ deps: ServiceChildOwnershipDeps = {},
134
+ ): ServiceChildOwnershipDecision {
135
+ return serviceChildOwnershipDecisionForClassifiedChild(isSupervisedServiceChild(env, deps), resolve);
136
+ }
137
+
138
+ /** Re-read the recorded owner after the startup mutation lease has been acquired. */
139
+ export function serviceChildOwnershipDecisionForClassifiedChild(
140
+ supervised: boolean,
141
+ resolve: typeof resolveServiceOwnership = resolveServiceOwnership,
142
+ ): ServiceChildOwnershipDecision {
143
+ if (!supervised) return Object.freeze({ kind: "proceed" as const });
144
+ const ownership = resolve();
145
+ if (ownership.kind === "unknown") {
146
+ return Object.freeze({
147
+ kind: "stay-out" as const,
148
+ refusal: unknownServiceOwnerRefusal(ownership.reason, "start"),
149
+ });
150
+ }
151
+ if (ownership.kind === "owned" && ownership.ownership.owner !== "cli") {
152
+ return Object.freeze({
153
+ kind: "stay-out" as const,
154
+ refusal: foreignServiceOwnerRefusal(ownership.ownership, "start"),
155
+ });
156
+ }
157
+ return Object.freeze({ kind: "proceed" as const });
158
+ }
159
+
160
+ /**
161
+ * Exit code a refused supervised child must use: the Windows wrapper reads 42 as
162
+ * an intentional stay-out and stops the loop; every other exit is a crash it
163
+ * restarts. Elsewhere the code is 0 — systemd only restarts on failure, and
164
+ * launchd's failure-only KeepAlive leaves an intentional exit-0 stand-down stopped.
165
+ */
166
+ export function serviceChildStayOutExitCode(env: NodeJS.ProcessEnv = process.env): number {
167
+ return serviceStayOutExitCode(env);
168
+ }
@@ -1,12 +1,14 @@
1
1
  import { accessSync, constants as fsConstants, existsSync, readFileSync, realpathSync, statSync, unlinkSync, writeFileSync } from "node:fs";
2
2
  import { homedir } from "node:os";
3
- import { delimiter, dirname, isAbsolute, join, posix, resolve, win32 } from "node:path";
3
+ import { delimiter, dirname, join, posix, resolve, win32 } from "node:path";
4
4
  import { expandUserPath, getConfigDir } from "../config";
5
5
  import { atomicWriteFileStreamed } from "../config/atomic-write";
6
6
  import { resolveCodexHomeDir, type CodexHomeDeps } from "../codex/home";
7
7
  import { resolveCodexSqliteHome } from "../codex/paths";
8
8
  import { durableBunRuntime, type BunRuntimeSource, type DurableBunRuntime } from "../lib/bun-runtime";
9
9
  import { WINSW_SHA256, WINSW_VERSION } from "../lib/winsw";
10
+ import { isTransientServiceLauncherPath } from "../lib/transient-service-path";
11
+ export { filterTransientServicePath, isTransientServiceLauncherPath } from "../lib/transient-service-path";
10
12
  import { isProtectedHomeUnderTest, isTestHomeGuardArmed } from "../lib/test-home-guard";
11
13
  import { isStandaloneBinary } from "../lib/standalone";
12
14
  import {
@@ -60,6 +62,18 @@ export function cliEntry(runtime: DurableBunRuntime = durableBunRuntime()): { bu
60
62
  };
61
63
  }
62
64
 
65
+ export function serviceLauncherPathDiagnostic(
66
+ state: ServiceInstallState | null = readServiceInstallState(),
67
+ platform: NodeJS.Platform = process.platform,
68
+ repairing = false,
69
+ ): string | null {
70
+ const launcher = state?.launcherPath;
71
+ if (!launcher || !isTransientServiceLauncherPath(launcher, platform)) return null;
72
+ return `STALE temporary launcher path (${launcher}) from a shell-local version manager — `
73
+ + (repairing ? "replacing it with a durable launcher or package-local Bun runtime"
74
+ : "run 'ocx service repair' to replace it with a durable launcher or package-local Bun runtime");
75
+ }
76
+
63
77
  /**
64
78
  * The stable `ocx` launcher to bake into a systemd unit, or null to fall back to the
65
79
  * Bun + CLI pair.
@@ -99,8 +113,11 @@ export function stableLauncherEntry(deps: {
99
113
  isExecutableFile?: (path: string) => boolean;
100
114
  pathDelimiter?: string;
101
115
  state?: ServiceInstallState | null;
116
+ platform?: NodeJS.Platform;
102
117
  } = {}): string | null {
103
118
  const env = deps.env ?? process.env;
119
+ const platform = deps.platform ?? process.platform;
120
+ const pathTools = platform === "win32" ? win32 : posix;
104
121
  const isExecutableFile = deps.isExecutableFile ?? ((path: string): boolean => {
105
122
  try {
106
123
  if (!statSync(path).isFile()) return false;
@@ -111,11 +128,12 @@ export function stableLauncherEntry(deps: {
111
128
  }
112
129
  });
113
130
  const recorded = (deps.state === undefined ? readServiceInstallState() : deps.state)?.launcherPath;
114
- if (recorded && isAbsolute(recorded) && isExecutableFile(recorded)) return recorded;
131
+ if (recorded && !isTransientServiceLauncherPath(recorded, platform)
132
+ && pathTools.isAbsolute(recorded) && isExecutableFile(recorded)) return recorded;
115
133
  const entries = (env.PATH ?? "").split(deps.pathDelimiter ?? delimiter);
116
134
  for (const entry of entries) {
117
- if (!entry || !isAbsolute(entry)) continue;
118
- const candidate = join(entry, "ocx");
135
+ if (!entry || isTransientServiceLauncherPath(entry, platform) || !pathTools.isAbsolute(entry)) continue;
136
+ const candidate = pathTools.join(entry, "ocx");
119
137
  if (isExecutableFile(candidate)) return candidate;
120
138
  }
121
139
  return null;
@@ -10,7 +10,7 @@ import { systemdProperty } from "../service-manager-probe";
10
10
  import { writeServiceApiTokenFile, sh } from "./guards";
11
11
  import { shellQuote, buildServiceShellCommand, buildServiceLauncherShellCommand, resolvedProxyEnv } from "./health";
12
12
  import type { ServiceInstallCleanupOps } from "./orchestration";
13
- import { SERVICE_MANAGED_ENV, TASK, cliEntry, stableLauncherEntry, logPath, serviceStatePath, currentCodexSqliteHomeAbsolute, writeServiceInstallState } from "./state";
13
+ import { SERVICE_MANAGED_ENV, TASK, cliEntry, filterTransientServicePath, stableLauncherEntry, logPath, serviceStatePath, currentCodexSqliteHomeAbsolute, writeServiceInstallState } from "./state";
14
14
  import { writeServiceDefinitionFile } from "./windows-ops";
15
15
 
16
16
  /** The `--port <n>` baked into the installed systemd user unit. Linux only. */
@@ -59,7 +59,7 @@ export function buildUnit(
59
59
  // independent of the host PATH.
60
60
  const launcher = deps.launcher ?? null;
61
61
  const log = logPath();
62
- const path = process.env.PATH ?? "/usr/local/bin:/usr/bin:/bin";
62
+ const path = filterTransientServicePath(process.env.PATH ?? "/usr/local/bin:/usr/bin:/bin", ":", "linux");
63
63
  const codexHome = systemdEnvironmentAssignment("CODEX_HOME", process.env.CODEX_HOME?.trim());
64
64
  const codexSqliteHome = systemdEnvironmentAssignment("CODEX_SQLITE_HOME", currentCodexSqliteHomeAbsolute());
65
65
  const opencodexHome = systemdEnvironmentAssignment("OPENCODEX_HOME", process.env.OPENCODEX_HOME?.trim());