@openclaw/codex 2026.6.11 → 2026.7.1-1

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 (42) hide show
  1. package/dist/{app-server-policy-BPTiVNsW.js → app-server-policy-C968Kgin.js} +5 -5
  2. package/dist/{attempt-notifications-BYnndyFl.js → attempt-notifications-BGsEIIDI.js} +29 -40
  3. package/dist/{command-handlers-DEPTJYk0.js → command-handlers-Dv-pzAmg.js} +278 -237
  4. package/dist/command-rpc-eLM_mtC7.js +784 -0
  5. package/dist/compact-4mVBriKT.js +603 -0
  6. package/dist/{computer-use-ClrJwoFp.js → computer-use-Bmaz333N.js} +3 -3
  7. package/dist/{config-CszD0vP3.js → config-CYEDnLJ2.js} +44 -18
  8. package/dist/conversation-binding-data-BHRpYbX3.js +121 -0
  9. package/dist/doctor-contract-api.js +590 -22
  10. package/dist/harness.js +29 -10
  11. package/dist/index.js +1134 -35
  12. package/dist/{media-understanding-provider-ZUQHN7gT.js → media-understanding-provider-BHOu9-Gg.js} +13 -8
  13. package/dist/media-understanding-provider.js +1 -1
  14. package/dist/{models-CAmfBWRl.js → models-DDmO1zwd.js} +2 -2
  15. package/dist/notification-correlation-Bo7KB3ks.js +35 -0
  16. package/dist/{plugin-app-cache-key-C9ILt7bl.js → plugin-app-cache-key-BrhVdeEf.js} +13 -5
  17. package/dist/{protocol-dh-ETiNd.js → protocol-2POPqAY4.js} +2 -1
  18. package/dist/{protocol-validators-B19q5BIX.js → protocol-validators-dZQ-UTOa.js} +205 -56
  19. package/dist/provider-capabilities-DzI8fgEu.js +6172 -0
  20. package/dist/provider-catalog.js +4 -2
  21. package/dist/{provider-B-OHpbD3.js → provider-zjPfx5Fs.js} +94 -23
  22. package/dist/provider.js +2 -2
  23. package/dist/{request-Dcd452Nk.js → request-BcJyl8KL.js} +2 -2
  24. package/dist/{run-attempt-CXxtFC9d.js → run-attempt-DNSNk_G8.js} +1250 -2992
  25. package/dist/{sandbox-guard-3tnjhjFb.js → sandbox-guard-DA2TQfZW.js} +5 -3
  26. package/dist/session-binding-C1ZXdP-x.js +627 -0
  27. package/dist/session-binding-meta-B7aEMU7g.js +6 -0
  28. package/dist/shared-client-4ICy3U6d.js +1853 -0
  29. package/dist/{side-question-C-DhgJOd.js → side-question-CMOpEhvY.js} +134 -142
  30. package/dist/{thread-lifecycle-DtT3-ehU.js → thread-lifecycle-qWE88Dn2.js} +803 -481
  31. package/dist/{web-search-provider.runtime-CkwxrXQj.js → web-search-provider.runtime-BSlriav6.js} +3 -3
  32. package/npm-shrinkwrap.json +34 -34
  33. package/openclaw.plugin.json +23 -3
  34. package/package.json +9 -6
  35. package/dist/client-CLrtWgrD.js +0 -729
  36. package/dist/client-factory-Bm6HsGob.js +0 -18
  37. package/dist/compact-aQJ0ZKhe.js +0 -278
  38. package/dist/conversation-binding-t0XMLz-j.js +0 -1557
  39. package/dist/provider-capabilities-D7hnTO76.js +0 -3201
  40. package/dist/rate-limit-cache-C7qmZ0Jh.js +0 -26
  41. package/dist/session-binding-HOuPt-E0.js +0 -338
  42. package/dist/shared-client-Dtx5i7Ez.js +0 -1013
@@ -1,1013 +0,0 @@
1
- import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
2
- import { d as resolveCodexAppServerRuntimeOptions, r as codexAppServerStartOptionsKey } from "./config-CszD0vP3.js";
3
- import { c as resolveCodexAppServerSpawnEnv, o as MANAGED_CODEX_APP_SERVER_PACKAGE, t as CodexAppServerClient } from "./client-CLrtWgrD.js";
4
- import { createRequire } from "node:module";
5
- import fs, { access } from "node:fs/promises";
6
- import path from "node:path";
7
- import { createHash } from "node:crypto";
8
- import fsSync, { constants, readFileSync } from "node:fs";
9
- import os from "node:os";
10
- import { ensureAuthProfileStore, findPersistedAuthProfileCredential, loadAuthProfileStoreForSecretsRuntime, refreshOAuthCredentialForRuntime, resolveApiKeyForProfile, resolveAuthProfileOrder, resolveDefaultAgentDir, resolvePersistedAuthProfileOwnerAgentDir, resolveProviderIdForAuth } from "openclaw/plugin-sdk/agent-runtime";
11
- import { isDeepStrictEqual } from "node:util";
12
- import { hasUsableOAuthCredential } from "openclaw/plugin-sdk/provider-auth";
13
- import { fileURLToPath } from "node:url";
14
- import { withTimeout } from "openclaw/plugin-sdk/security-runtime";
15
- //#region extensions/codex/src/app-server/auth-bridge.ts
16
- const CODEX_APP_SERVER_AUTH_PROVIDER = "openai";
17
- const OPENAI_CODEX_APP_SERVER_AUTH_PROVIDER = "openai-codex";
18
- const LEGACY_CODEX_APP_SERVER_AUTH_PROVIDER = "codex-cli";
19
- const CODEX_APP_SERVER_EXTERNAL_CLI_PROVIDER_IDS = [CODEX_APP_SERVER_AUTH_PROVIDER, LEGACY_CODEX_APP_SERVER_AUTH_PROVIDER];
20
- const OPENAI_PROVIDER = "openai";
21
- const OPENAI_CODEX_DEFAULT_PROFILE_ID = "openai:default";
22
- const CODEX_HOME_ENV_VAR = "CODEX_HOME";
23
- const HOME_ENV_VAR = "HOME";
24
- const CODEX_APP_SERVER_HOME_DIRNAME = "codex-home";
25
- const CODEX_APP_SERVER_API_KEY_ENV_VARS = ["CODEX_API_KEY", "OPENAI_API_KEY"];
26
- const CODEX_APP_SERVER_HOME_ENV_VARS = [CODEX_HOME_ENV_VAR, HOME_ENV_VAR];
27
- const CODEX_AUTH_JSON_FILENAME = "auth.json";
28
- const CODEX_HOME_DIRNAME = ".codex";
29
- const scopedOAuthRefreshQueues = /* @__PURE__ */ new WeakMap();
30
- async function bridgeCodexAppServerStartOptions(params) {
31
- if (params.startOptions.transport !== "stdio") return params.startOptions;
32
- const isolatedStartOptions = await withAgentCodexHomeEnvironment(params.startOptions, params.agentDir);
33
- if (params.authProfileId === null) return isolatedStartOptions;
34
- const store = resolveCodexAppServerAuthProfileStore({
35
- agentDir: params.agentDir,
36
- authProfileId: params.authProfileId,
37
- authProfileStore: params.authProfileStore,
38
- config: params.config
39
- });
40
- return shouldClearOpenAiApiKeyForCodexAuthProfile({
41
- store,
42
- authProfileId: resolveCodexAppServerAuthProfileId({
43
- authProfileId: params.authProfileId,
44
- store,
45
- config: params.config
46
- }),
47
- config: params.config
48
- }) ? withClearedEnvironmentVariables(isolatedStartOptions, CODEX_APP_SERVER_API_KEY_ENV_VARS) : isolatedStartOptions;
49
- }
50
- function resolveCodexAppServerAuthProfileId(params) {
51
- const requested = params.authProfileId?.trim();
52
- if (requested) return requested;
53
- return resolveAuthProfileOrder({
54
- cfg: params.config,
55
- store: params.store,
56
- provider: CODEX_APP_SERVER_AUTH_PROVIDER
57
- })[0]?.trim();
58
- }
59
- function resolveCodexAppServerAuthProfileIdForAgent(params) {
60
- const store = resolveCodexAppServerAuthProfileStore({
61
- agentDir: params.agentDir?.trim() || resolveDefaultAgentDir(params.config ?? {}),
62
- authProfileId: params.authProfileId,
63
- authProfileStore: params.authProfileStore,
64
- config: params.config
65
- });
66
- return resolveCodexAppServerAuthProfileId({
67
- authProfileId: params.authProfileId,
68
- store,
69
- config: params.config
70
- });
71
- }
72
- function ensureCodexAppServerAuthProfileStore(params) {
73
- return ensureAuthProfileStore(params.agentDir, {
74
- allowKeychainPrompt: false,
75
- config: params.config,
76
- externalCliProviderIds: CODEX_APP_SERVER_EXTERNAL_CLI_PROVIDER_IDS,
77
- ...params.authProfileId ? { externalCliProfileIds: [params.authProfileId] } : {}
78
- });
79
- }
80
- function resolveCodexAppServerAuthProfileStore(params) {
81
- if (params.authProfileStore) {
82
- const providedProfileId = resolveCodexAppServerAuthProfileId({
83
- authProfileId: params.authProfileId,
84
- store: params.authProfileStore,
85
- config: params.config
86
- });
87
- if (providedProfileId && params.authProfileStore.profiles[providedProfileId]) return params.authProfileStore;
88
- }
89
- const overlaidStore = ensureCodexAppServerAuthProfileStore({
90
- agentDir: params.agentDir,
91
- authProfileId: params.authProfileId,
92
- config: params.config
93
- });
94
- if (!params.authProfileStore) return overlaidStore;
95
- const order = params.authProfileStore.order || overlaidStore.order ? {
96
- ...overlaidStore.order,
97
- ...params.authProfileStore.order
98
- } : void 0;
99
- const profiles = {
100
- ...overlaidStore.profiles,
101
- ...params.authProfileStore.profiles
102
- };
103
- const suppliedProfileIds = new Set(Object.keys(params.authProfileStore.profiles));
104
- const mergeRuntimeProfileIds = (overlaidIds, suppliedIds) => [...(overlaidIds ?? []).filter((profileId) => !suppliedProfileIds.has(profileId)), ...suppliedIds ?? []];
105
- const runtimePersistedProfileIds = mergeRuntimeProfileIds(overlaidStore.runtimePersistedProfileIds, params.authProfileStore.runtimePersistedProfileIds).filter((profileId) => profiles[profileId]);
106
- const runtimeExternalProfileIds = mergeRuntimeProfileIds(overlaidStore.runtimeExternalProfileIds, params.authProfileStore.runtimeExternalProfileIds).filter((profileId) => profiles[profileId]);
107
- const runtimeExternalProfileIdsAuthoritative = overlaidStore.runtimeExternalProfileIdsAuthoritative === true || params.authProfileStore.runtimeExternalProfileIdsAuthoritative === true;
108
- return {
109
- ...params.authProfileStore,
110
- ...order ? { order } : {},
111
- profiles,
112
- ...runtimePersistedProfileIds.length > 0 ? { runtimePersistedProfileIds: [...new Set(runtimePersistedProfileIds)] } : {},
113
- ...runtimeExternalProfileIds.length > 0 || runtimeExternalProfileIdsAuthoritative ? {
114
- runtimeExternalProfileIds: [...new Set(runtimeExternalProfileIds)],
115
- ...runtimeExternalProfileIdsAuthoritative ? { runtimeExternalProfileIdsAuthoritative: true } : {}
116
- } : {}
117
- };
118
- }
119
- async function resolveCodexAppServerAuthAccountCacheKey(params) {
120
- const agentDir = params.agentDir?.trim() || resolveDefaultAgentDir(params.config ?? {});
121
- const store = resolveCodexAppServerAuthProfileStore({
122
- agentDir,
123
- authProfileId: params.authProfileId,
124
- authProfileStore: params.authProfileStore,
125
- config: params.config
126
- });
127
- const profileId = resolveCodexAppServerAuthProfileId({
128
- authProfileId: params.authProfileId,
129
- store,
130
- config: params.config
131
- });
132
- if (!profileId) return;
133
- const credential = store.profiles[profileId];
134
- if (!credential || !isCodexAppServerAuthProfileCredential(credential, params.config)) return;
135
- if (credential.type === "api_key") {
136
- const apiKey = (await resolveApiKeyForProfile({
137
- store,
138
- profileId,
139
- agentDir
140
- }))?.apiKey?.trim();
141
- return apiKey ? `${resolveChatgptAccountId(profileId, credential)}:${fingerprintApiKeyAuthProfileCacheKey(apiKey)}` : resolveChatgptAccountId(profileId, credential);
142
- }
143
- if (credential.type === "token") {
144
- const accessToken = (await resolveApiKeyForProfile({
145
- store,
146
- profileId,
147
- agentDir
148
- }))?.apiKey?.trim();
149
- return accessToken ? `${resolveChatgptAccountId(profileId, credential)}:${fingerprintTokenAuthProfileCacheKey(accessToken)}` : resolveChatgptAccountId(profileId, credential);
150
- }
151
- return resolveChatgptAccountId(profileId, credential);
152
- }
153
- function resolveCodexAppServerEnvApiKeyCacheKey(params) {
154
- if (params.startOptions.transport !== "stdio") return;
155
- const apiKey = readFirstNonEmptyEnvEntry(resolveCodexAppServerSpawnEnv(params.startOptions, params.baseEnv ?? process.env, params.platform ?? process.platform), CODEX_APP_SERVER_API_KEY_ENV_VARS);
156
- if (!apiKey) return;
157
- const hash = createHash("sha256");
158
- hash.update("openclaw:codex:app-server-env-api-key:v1");
159
- hash.update("\0");
160
- hash.update(apiKey.key);
161
- hash.update("\0");
162
- hash.update(apiKey.value);
163
- return `${apiKey.key}:sha256:${hash.digest("hex")}`;
164
- }
165
- function resolveCodexAppServerFallbackApiKeyCacheKey(params) {
166
- if (params.startOptions.transport !== "stdio") return;
167
- return resolveCodexAppServerEnvApiKeyCacheKey(params) ?? resolveCodexCliAuthFileApiKeyCacheKey(params.baseEnv ?? process.env);
168
- }
169
- function fingerprintApiKeyAuthProfileCacheKey(apiKey) {
170
- const hash = createHash("sha256");
171
- hash.update("openclaw:codex:app-server-auth-profile-api-key:v1");
172
- hash.update("\0");
173
- hash.update(apiKey);
174
- return `api_key:sha256:${hash.digest("hex")}`;
175
- }
176
- function fingerprintTokenAuthProfileCacheKey(accessToken) {
177
- const hash = createHash("sha256");
178
- hash.update("openclaw:codex:app-server-auth-profile-token:v1");
179
- hash.update("\0");
180
- hash.update(accessToken);
181
- return `token:sha256:${hash.digest("hex")}`;
182
- }
183
- function fingerprintCodexCliAuthFileApiKeyCacheKey(apiKey) {
184
- const hash = createHash("sha256");
185
- hash.update("openclaw:codex:app-server-cli-auth-json-api-key:v1");
186
- hash.update("\0");
187
- hash.update(apiKey);
188
- return `CODEX_AUTH_JSON:sha256:${hash.digest("hex")}`;
189
- }
190
- function resolveCodexAppServerHomeDir(agentDir) {
191
- return path.join(path.resolve(agentDir), CODEX_APP_SERVER_HOME_DIRNAME);
192
- }
193
- async function withAgentCodexHomeEnvironment(startOptions, agentDir) {
194
- const codexHome = startOptions.env?.[CODEX_HOME_ENV_VAR]?.trim() ? startOptions.env[CODEX_HOME_ENV_VAR] : resolveCodexAppServerHomeDir(agentDir);
195
- const nativeHome = startOptions.env?.[HOME_ENV_VAR]?.trim() ? startOptions.env[HOME_ENV_VAR] : void 0;
196
- await fs.mkdir(codexHome, { recursive: true });
197
- if (nativeHome) await fs.mkdir(nativeHome, { recursive: true });
198
- const nextStartOptions = {
199
- ...startOptions,
200
- env: {
201
- ...startOptions.env,
202
- [CODEX_HOME_ENV_VAR]: codexHome,
203
- ...nativeHome ? { [HOME_ENV_VAR]: nativeHome } : {}
204
- }
205
- };
206
- const clearEnv = withoutClearedCodexHomeEnv(startOptions.clearEnv);
207
- if (clearEnv) nextStartOptions.clearEnv = clearEnv;
208
- else delete nextStartOptions.clearEnv;
209
- return nextStartOptions;
210
- }
211
- function withoutClearedCodexHomeEnv(clearEnv) {
212
- if (!clearEnv) return;
213
- const reserved = new Set(CODEX_APP_SERVER_HOME_ENV_VARS);
214
- const filtered = clearEnv.filter((envVar) => !reserved.has(envVar.trim().toUpperCase()));
215
- return filtered.length === clearEnv.length ? clearEnv : filtered;
216
- }
217
- async function applyCodexAppServerAuthProfile(params) {
218
- if (params.authProfileId === null) return;
219
- const loginParams = await resolveCodexAppServerAuthProfileLoginParams({
220
- agentDir: params.agentDir,
221
- authProfileId: params.authProfileId,
222
- authProfileStore: params.authProfileStore,
223
- config: params.config
224
- });
225
- if (!loginParams) {
226
- if (params.startOptions?.transport !== "stdio") return;
227
- const env = resolveCodexAppServerSpawnEnv(params.startOptions, process.env);
228
- const fallbackLoginParams = await resolveCodexAppServerFallbackApiKeyLoginParams({
229
- client: params.client,
230
- env,
231
- codexCliAuthEnv: process.env
232
- });
233
- if (fallbackLoginParams) await params.client.request("account/login/start", fallbackLoginParams);
234
- return;
235
- }
236
- await params.client.request("account/login/start", loginParams);
237
- }
238
- function resolveCodexAppServerAuthProfileLoginParams(params) {
239
- return resolveCodexAppServerAuthProfileLoginParamsInternal(params);
240
- }
241
- async function refreshCodexAppServerAuthTokens(params) {
242
- const loginParams = await resolveCodexAppServerAuthProfileLoginParamsInternal({
243
- ...params,
244
- forceOAuthRefresh: true
245
- });
246
- if (!loginParams || loginParams.type !== "chatgptAuthTokens") throw new Error("Codex app-server ChatGPT token refresh requires an OAuth auth profile.");
247
- return {
248
- accessToken: loginParams.accessToken,
249
- chatgptAccountId: loginParams.chatgptAccountId,
250
- chatgptPlanType: loginParams.chatgptPlanType ?? null
251
- };
252
- }
253
- async function resolveCodexAppServerAuthProfileLoginParamsInternal(params) {
254
- const store = resolveCodexAppServerAuthProfileStore({
255
- agentDir: params.agentDir,
256
- authProfileId: params.authProfileId,
257
- authProfileStore: params.authProfileStore,
258
- config: params.config
259
- });
260
- const profileId = resolveCodexAppServerAuthProfileId({
261
- authProfileId: params.authProfileId,
262
- store,
263
- config: params.config
264
- });
265
- if (!profileId) return;
266
- const credential = store.profiles[profileId];
267
- if (!credential) throw new Error(`Codex app-server auth profile "${profileId}" was not found.`);
268
- if (!isCodexAppServerAuthProfileCredential(credential, params.config)) throw new Error(`Codex app-server auth profile "${profileId}" must be OpenAI Codex auth or an OpenAI API-key backup.`);
269
- const loginParams = await resolveLoginParamsForCredential(profileId, credential, {
270
- agentDir: params.agentDir,
271
- store,
272
- preferStoreCredential: Boolean(params.authProfileStore?.profiles[profileId]),
273
- forceOAuthRefresh: params.forceOAuthRefresh === true,
274
- config: params.config
275
- });
276
- if (!loginParams) throw new Error(`Codex app-server auth profile "${profileId}" does not contain usable credentials.`);
277
- return loginParams;
278
- }
279
- async function resolveCodexAppServerFallbackApiKeyLoginParams(params) {
280
- const apiKey = readFirstNonEmptyEnv(params.env, CODEX_APP_SERVER_API_KEY_ENV_VARS) ?? await readCodexCliAuthFileApiKey(params.codexCliAuthEnv);
281
- if (!apiKey) return;
282
- if ((await params.client.request("account/read", { refreshToken: false })).account) return;
283
- return {
284
- type: "apiKey",
285
- apiKey
286
- };
287
- }
288
- function resolveCodexCliAuthFilePath(env) {
289
- const configuredCodexHome = env[CODEX_HOME_ENV_VAR]?.trim();
290
- if (configuredCodexHome) return path.join(resolveHomeRelativePath(configuredCodexHome, env), CODEX_AUTH_JSON_FILENAME);
291
- const home = env[HOME_ENV_VAR]?.trim() || env.USERPROFILE?.trim() || os.homedir();
292
- return path.join(home, CODEX_HOME_DIRNAME, CODEX_AUTH_JSON_FILENAME);
293
- }
294
- function resolveHomeRelativePath(value, env) {
295
- if (value === "~" || value.startsWith("~/") || value.startsWith("~\\")) {
296
- const home = env[HOME_ENV_VAR]?.trim() || env.USERPROFILE?.trim() || os.homedir();
297
- return path.join(home, value.slice(value === "~" ? 1 : 2));
298
- }
299
- return value;
300
- }
301
- function parseCodexCliAuthFileApiKey(raw) {
302
- let parsed;
303
- try {
304
- parsed = JSON.parse(raw);
305
- } catch {
306
- return;
307
- }
308
- if (!parsed || typeof parsed !== "object") return;
309
- const apiKey = parsed.OPENAI_API_KEY;
310
- return typeof apiKey === "string" && apiKey.trim() ? apiKey.trim() : void 0;
311
- }
312
- async function readCodexCliAuthFileApiKey(env) {
313
- try {
314
- return parseCodexCliAuthFileApiKey(await fs.readFile(resolveCodexCliAuthFilePath(env), "utf8"));
315
- } catch {
316
- return;
317
- }
318
- }
319
- function resolveCodexCliAuthFileApiKeyCacheKey(env) {
320
- try {
321
- const apiKey = parseCodexCliAuthFileApiKey(fsSync.readFileSync(resolveCodexCliAuthFilePath(env), "utf8"));
322
- return apiKey ? fingerprintCodexCliAuthFileApiKeyCacheKey(apiKey) : void 0;
323
- } catch {
324
- return;
325
- }
326
- }
327
- async function resolveLoginParamsForCredential(profileId, credential, params) {
328
- if (credential.type === "api_key") {
329
- const apiKey = (await resolveApiKeyForProfile({
330
- store: params.preferStoreCredential ? params.store : ensureAuthProfileStore(params.agentDir, { allowKeychainPrompt: false }),
331
- profileId,
332
- agentDir: params.agentDir
333
- }))?.apiKey?.trim();
334
- return apiKey ? {
335
- type: "apiKey",
336
- apiKey
337
- } : void 0;
338
- }
339
- if (credential.type === "token") {
340
- const accessToken = (await resolveApiKeyForProfile({
341
- store: params.preferStoreCredential ? params.store : ensureAuthProfileStore(params.agentDir, { allowKeychainPrompt: false }),
342
- profileId,
343
- agentDir: params.agentDir
344
- }))?.apiKey?.trim();
345
- return accessToken ? buildChatgptAuthTokensParams(profileId, credential, accessToken) : void 0;
346
- }
347
- if (credential.type !== "oauth") return;
348
- const resolvedCredential = await resolveOAuthCredentialForCodexAppServer(profileId, credential, {
349
- agentDir: params.agentDir,
350
- store: params.store,
351
- preferStoreCredential: params.preferStoreCredential,
352
- forceRefresh: params.forceOAuthRefresh,
353
- config: params.config
354
- });
355
- const accessToken = resolvedCredential.access?.trim();
356
- return accessToken ? buildChatgptAuthTokensParams(profileId, resolvedCredential, accessToken) : void 0;
357
- }
358
- async function resolveOAuthCredentialForCodexAppServer(profileId, credential, params) {
359
- const ownerAgentDir = resolvePersistedAuthProfileOwnerAgentDir({
360
- agentDir: params.agentDir,
361
- profileId
362
- });
363
- const persistedCredential = findPersistedAuthProfileCredential({
364
- agentDir: ownerAgentDir,
365
- profileId
366
- });
367
- const useScopedCredential = params.preferStoreCredential && shouldUseScopedOAuthCredential({
368
- store: params.store,
369
- profileId,
370
- persistedCredential,
371
- suppliedCredential: credential,
372
- config: params.config
373
- });
374
- const store = useScopedCredential ? params.store : ensureCodexAppServerAuthProfileStore({
375
- agentDir: ownerAgentDir,
376
- authProfileId: profileId,
377
- config: params.config
378
- });
379
- const persistedOAuthCredential = !useScopedCredential && persistedCredential?.type === "oauth" && isCodexAppServerAuthProvider(persistedCredential.provider, params.config) ? persistedCredential : void 0;
380
- const ownerCredential = store.profiles[profileId];
381
- const overlaidOAuthCredential = ownerCredential?.type === "oauth" && isCodexAppServerAuthProvider(ownerCredential.provider, params.config) ? ownerCredential : void 0;
382
- if (useScopedCredential && overlaidOAuthCredential) return await resolveScopedOAuthCredential({
383
- store,
384
- profileId,
385
- credential: overlaidOAuthCredential,
386
- forceRefresh: params.forceRefresh
387
- });
388
- if (params.forceRefresh && !persistedOAuthCredential && overlaidOAuthCredential) {
389
- const refreshedRuntimeCredential = await refreshOAuthCredentialForRuntime({ credential: overlaidOAuthCredential });
390
- if (!refreshedRuntimeCredential?.access?.trim()) throw new Error(`Codex app-server auth profile "${profileId}" could not refresh.`);
391
- store.profiles[profileId] = refreshedRuntimeCredential;
392
- return refreshedRuntimeCredential;
393
- }
394
- const resolved = await resolveApiKeyForProfile({
395
- store,
396
- profileId,
397
- agentDir: ownerAgentDir,
398
- forceRefresh: params.forceRefresh && Boolean(persistedOAuthCredential)
399
- });
400
- const refreshed = useScopedCredential ? void 0 : loadAuthProfileStoreForSecretsRuntime(ownerAgentDir).profiles[profileId];
401
- const refreshedOAuthCredential = refreshed?.type === "oauth" && isCodexAppServerAuthProvider(refreshed.provider, params.config) ? refreshed : void 0;
402
- if (refreshedOAuthCredential && isDeepStrictEqual(params.store.profiles[profileId], credential)) params.store.profiles[profileId] = refreshedOAuthCredential;
403
- const storedCredential = store.profiles[profileId];
404
- const candidate = refreshedOAuthCredential ? refreshedOAuthCredential : storedCredential?.type === "oauth" && isCodexAppServerAuthProvider(storedCredential.provider, params.config) ? storedCredential : credential;
405
- return resolved?.apiKey ? {
406
- ...candidate,
407
- access: resolved.apiKey
408
- } : candidate;
409
- }
410
- function shouldUseScopedOAuthCredential(params) {
411
- if (!params.store.runtimePersistedProfileIds?.includes(params.profileId)) return true;
412
- const persisted = params.persistedCredential;
413
- if (persisted?.type !== "oauth") return true;
414
- if (resolveProviderIdForAuth(persisted.provider, { config: params.config }) !== resolveProviderIdForAuth(params.suppliedCredential.provider, { config: params.config })) return true;
415
- return !isDeepStrictEqual(persisted, params.suppliedCredential) && !hasMatchingOAuthIdentity(persisted, params.suppliedCredential);
416
- }
417
- function hasMatchingOAuthIdentity(persisted, supplied) {
418
- const persistedAccountId = persisted.accountId?.trim();
419
- const suppliedAccountId = supplied.accountId?.trim();
420
- if (persistedAccountId && suppliedAccountId) return persistedAccountId === suppliedAccountId;
421
- const persistedEmail = persisted.email?.trim().toLowerCase();
422
- const suppliedEmail = supplied.email?.trim().toLowerCase();
423
- return Boolean(persistedEmail && suppliedEmail && persistedEmail === suppliedEmail);
424
- }
425
- async function resolveScopedOAuthCredential(params) {
426
- const existingRefresh = scopedOAuthRefreshQueues.get(params.store)?.get(params.profileId);
427
- if (existingRefresh) return await existingRefresh;
428
- if (!params.forceRefresh && hasUsableOAuthCredential(params.credential)) return params.credential;
429
- const storeRefreshes = scopedOAuthRefreshQueues.get(params.store) ?? /* @__PURE__ */ new Map();
430
- scopedOAuthRefreshQueues.set(params.store, storeRefreshes);
431
- const refresh = (async () => {
432
- const current = params.store.profiles[params.profileId];
433
- const credential = current?.type === "oauth" ? current : params.credential;
434
- if (!params.forceRefresh && hasUsableOAuthCredential(credential)) return credential;
435
- const refreshed = await refreshOAuthCredentialForRuntime({ credential });
436
- if (!refreshed?.access?.trim()) throw new Error(`Codex app-server auth profile "${params.profileId}" could not refresh.`);
437
- if (!isDeepStrictEqual(params.store.profiles[params.profileId], credential)) throw new Error(`Codex app-server auth profile "${params.profileId}" changed while refreshing.`);
438
- params.store.profiles[params.profileId] = refreshed;
439
- return refreshed;
440
- })();
441
- storeRefreshes.set(params.profileId, refresh);
442
- try {
443
- return await refresh;
444
- } finally {
445
- if (storeRefreshes.get(params.profileId) === refresh) storeRefreshes.delete(params.profileId);
446
- }
447
- }
448
- function isCodexAppServerAuthProvider(provider, config) {
449
- const resolvedProvider = resolveProviderIdForAuth(provider, { config });
450
- return resolvedProvider === CODEX_APP_SERVER_AUTH_PROVIDER || resolvedProvider === OPENAI_CODEX_APP_SERVER_AUTH_PROVIDER || resolvedProvider === LEGACY_CODEX_APP_SERVER_AUTH_PROVIDER;
451
- }
452
- function isOpenAIApiKeyBackupCredential(credential, config) {
453
- return credential.type === "api_key" && resolveProviderIdForAuth(credential.provider, { config }) === OPENAI_PROVIDER;
454
- }
455
- function isCodexAppServerAuthProfileCredential(credential, config) {
456
- return isCodexAppServerAuthProvider(credential.provider, config) || isOpenAIApiKeyBackupCredential(credential, config);
457
- }
458
- function shouldClearOpenAiApiKeyForCodexAuthProfile(params) {
459
- const profileId = params.authProfileId?.trim();
460
- return isCodexSubscriptionCredential(profileId ? params.store.profiles[profileId] : params.store.profiles[OPENAI_CODEX_DEFAULT_PROFILE_ID], params.config);
461
- }
462
- function isCodexSubscriptionCredential(credential, config) {
463
- if (!credential || !isCodexAppServerAuthProvider(credential.provider, config)) return false;
464
- return credential.type === "oauth" || credential.type === "token";
465
- }
466
- function withClearedEnvironmentVariables(startOptions, envVars) {
467
- const clearEnv = startOptions.clearEnv ?? [];
468
- const missingEnvVars = envVars.filter((envVar) => !clearEnv.includes(envVar));
469
- if (missingEnvVars.length === 0) return startOptions;
470
- return {
471
- ...startOptions,
472
- clearEnv: [...clearEnv, ...missingEnvVars]
473
- };
474
- }
475
- function readFirstNonEmptyEnv(env, keys) {
476
- return readFirstNonEmptyEnvEntry(env, keys)?.value;
477
- }
478
- function readFirstNonEmptyEnvEntry(env, keys) {
479
- for (const key of keys) {
480
- const value = env[key]?.trim();
481
- if (value) return {
482
- key,
483
- value
484
- };
485
- }
486
- }
487
- function buildChatgptAuthTokensParams(profileId, credential, accessToken) {
488
- return {
489
- type: "chatgptAuthTokens",
490
- accessToken,
491
- chatgptAccountId: resolveChatgptAccountId(profileId, credential),
492
- chatgptPlanType: resolveChatgptPlanType(credential)
493
- };
494
- }
495
- function resolveChatgptPlanType(credential) {
496
- const record = credential;
497
- const planType = record.chatgptPlanType ?? record.planType;
498
- return typeof planType === "string" && planType.trim() ? planType.trim() : null;
499
- }
500
- function resolveChatgptAccountId(profileId, credential) {
501
- if ("accountId" in credential && typeof credential.accountId === "string") {
502
- const accountId = credential.accountId.trim();
503
- if (accountId) return accountId;
504
- }
505
- return credential.email?.trim() || profileId;
506
- }
507
- //#endregion
508
- //#region extensions/codex/src/app-server/managed-binary.ts
509
- /**
510
- * Resolves the managed Codex app-server binary shipped with or installed beside
511
- * the Codex plugin before stdio startup.
512
- */
513
- const CODEX_PLUGIN_ROOT = resolveDefaultCodexPluginRoot(path.dirname(fileURLToPath(import.meta.url)));
514
- /** Rewrites managed stdio start options to point at an executable Codex binary path. */
515
- async function resolveManagedCodexAppServerStartOptions(startOptions, options = {}) {
516
- if (startOptions.transport !== "stdio" || startOptions.commandSource !== "managed") return startOptions;
517
- const platform = options.platform ?? process.platform;
518
- const paths = resolveManagedCodexAppServerPaths({
519
- platform,
520
- pluginRoot: options.pluginRoot
521
- });
522
- const pathExists = options.pathExists ?? commandPathExists;
523
- const commandPath = await findManagedCodexAppServerCommandPath({
524
- candidateCommandPaths: paths.candidateCommandPaths,
525
- pathExists,
526
- platform
527
- });
528
- return {
529
- ...startOptions,
530
- command: commandPath,
531
- commandSource: "resolved-managed"
532
- };
533
- }
534
- /** Returns the preferred and fallback managed Codex binary paths for a plugin root. */
535
- function resolveManagedCodexAppServerPaths(params) {
536
- const platform = params.platform ?? process.platform;
537
- const candidateCommandPaths = resolveManagedCodexAppServerCommandCandidates(params.pluginRoot ?? CODEX_PLUGIN_ROOT, platform);
538
- return {
539
- commandPath: candidateCommandPaths[0] ?? "",
540
- candidateCommandPaths
541
- };
542
- }
543
- function resolveManagedCodexAppServerCommandCandidates(pluginRoot, platform) {
544
- const pathApi = pathForPlatform(platform);
545
- const commandName = platform === "win32" ? "codex.cmd" : "codex";
546
- const roots = resolveManagedCodexAppServerCandidateRoots(pluginRoot, platform);
547
- return [...new Set([...roots.map((root) => pathApi.join(root, "node_modules", ".bin", commandName)), ...resolveManagedCodexPackageBinCandidates(roots, platform)])];
548
- }
549
- function resolveDefaultCodexPluginRoot(moduleDir) {
550
- const moduleBaseName = path.basename(moduleDir);
551
- if (moduleBaseName === "dist" || moduleBaseName === "dist-runtime") return path.dirname(moduleDir);
552
- return path.resolve(moduleDir, "..", "..");
553
- }
554
- function resolveManagedCodexAppServerCandidateRoots(pluginRoot, platform) {
555
- const pathApi = pathForPlatform(platform);
556
- const directRoots = [
557
- pluginRoot,
558
- pathApi.dirname(pluginRoot),
559
- pathApi.dirname(pathApi.dirname(pluginRoot)),
560
- isDistExtensionRoot(pluginRoot, platform) ? pathApi.dirname(pathApi.dirname(pathApi.dirname(pluginRoot))) : null
561
- ].filter((root) => Boolean(root));
562
- return [...new Set([...directRoots, ...resolveNearestNodeModulesProjectRoots(directRoots, platform)])];
563
- }
564
- function resolveNearestNodeModulesProjectRoots(roots, platform) {
565
- const pathApi = pathForPlatform(platform);
566
- const projectRoots = [];
567
- for (const root of roots) {
568
- let current = pathApi.resolve(root);
569
- while (true) {
570
- if (pathApi.basename(current) === "node_modules") {
571
- projectRoots.push(pathApi.dirname(current));
572
- break;
573
- }
574
- const parent = pathApi.dirname(current);
575
- if (parent === current) break;
576
- current = parent;
577
- }
578
- }
579
- return projectRoots;
580
- }
581
- function resolveManagedCodexPackageBinCandidates(roots, platform) {
582
- if (platform === "win32") return [];
583
- const candidates = [];
584
- for (const root of roots) {
585
- const candidate = resolveManagedCodexPackageBinCandidate(root);
586
- if (candidate) candidates.push(candidate);
587
- }
588
- return candidates;
589
- }
590
- function resolveManagedCodexPackageBinCandidate(root) {
591
- try {
592
- const packageJsonPath = createRequire(path.join(root, "package.json")).resolve(`${MANAGED_CODEX_APP_SERVER_PACKAGE}/package.json`);
593
- const packageRoot = path.dirname(packageJsonPath);
594
- const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf8"));
595
- const binPath = typeof packageJson.bin === "string" ? packageJson.bin : isRecord(packageJson.bin) && typeof packageJson.bin.codex === "string" ? packageJson.bin.codex : null;
596
- return binPath ? path.resolve(packageRoot, binPath) : null;
597
- } catch {
598
- return null;
599
- }
600
- }
601
- function isRecord(value) {
602
- return typeof value === "object" && value !== null;
603
- }
604
- function isDistExtensionRoot(pluginRoot, platform) {
605
- const pathApi = pathForPlatform(platform);
606
- const extensionsDir = pathApi.dirname(pluginRoot);
607
- const distDir = pathApi.dirname(extensionsDir);
608
- return pathApi.basename(extensionsDir) === "extensions" && (pathApi.basename(distDir) === "dist" || pathApi.basename(distDir) === "dist-runtime");
609
- }
610
- function pathForPlatform(platform) {
611
- return platform === "win32" ? path.win32 : path.posix;
612
- }
613
- async function findManagedCodexAppServerCommandPath(params) {
614
- for (const commandPath of params.candidateCommandPaths) if (await params.pathExists(commandPath, params.platform)) return commandPath;
615
- throw new Error([
616
- `Managed Codex app-server binary was not found for ${MANAGED_CODEX_APP_SERVER_PACKAGE}.`,
617
- "Reinstall or update OpenClaw, or run pnpm install in a source checkout.",
618
- "Set plugins.entries.codex.config.appServer.command or OPENCLAW_CODEX_APP_SERVER_BIN to use a custom Codex binary."
619
- ].join(" "));
620
- }
621
- async function commandPathExists(filePath, platform) {
622
- try {
623
- await access(filePath, platform === "win32" ? constants.F_OK : constants.X_OK);
624
- return true;
625
- } catch {
626
- return false;
627
- }
628
- }
629
- //#endregion
630
- //#region extensions/codex/src/app-server/timeout.ts
631
- /**
632
- * Thin Codex app-server timeout adapter around OpenClaw's shared security
633
- * runtime timeout helper.
634
- */
635
- /** Awaits a promise with a Codex-specific timeout error message. */
636
- async function withTimeout$1(promise, timeoutMs, timeoutMessage) {
637
- return await withTimeout(promise, timeoutMs, { message: timeoutMessage });
638
- }
639
- //#endregion
640
- //#region extensions/codex/src/app-server/shared-client.ts
641
- /**
642
- * Owns shared and isolated Codex app-server client startup, auth application,
643
- * lease tracking, and teardown.
644
- */
645
- var shared_client_exports = /* @__PURE__ */ __exportAll({
646
- clearSharedCodexAppServerClient: () => clearSharedCodexAppServerClient,
647
- clearSharedCodexAppServerClientAndWait: () => clearSharedCodexAppServerClientAndWait,
648
- clearSharedCodexAppServerClientIfCurrent: () => clearSharedCodexAppServerClientIfCurrent,
649
- clearSharedCodexAppServerClientIfCurrentAndUnclaimed: () => clearSharedCodexAppServerClientIfCurrentAndUnclaimed,
650
- clearSharedCodexAppServerClientIfCurrentAndWait: () => clearSharedCodexAppServerClientIfCurrentAndWait,
651
- createIsolatedCodexAppServerClient: () => createIsolatedCodexAppServerClient,
652
- detachSharedCodexAppServerClientIfCurrent: () => detachSharedCodexAppServerClientIfCurrent,
653
- getLeasedSharedCodexAppServerClient: () => getLeasedSharedCodexAppServerClient,
654
- getSharedCodexAppServerClient: () => getSharedCodexAppServerClient,
655
- releaseLeasedSharedCodexAppServerClient: () => releaseLeasedSharedCodexAppServerClient,
656
- resetSharedCodexAppServerClientForTests: () => resetSharedCodexAppServerClientForTests,
657
- retainSharedCodexAppServerClientIfCurrent: () => retainSharedCodexAppServerClientIfCurrent,
658
- retireSharedCodexAppServerClientIfCurrent: () => retireSharedCodexAppServerClientIfCurrent
659
- });
660
- const SHARED_CODEX_APP_SERVER_CLIENT_STATE = Symbol.for("openclaw.codexAppServerClientState");
661
- function getSharedCodexAppServerClientState() {
662
- const globalState = globalThis;
663
- const state = globalState[SHARED_CODEX_APP_SERVER_CLIENT_STATE];
664
- const keyedState = readKeyedSharedCodexAppServerClientState(state);
665
- if (keyedState) {
666
- const clients = keyedState.clients;
667
- for (const entry of clients.values()) {
668
- entry.activeLeases ??= 0;
669
- entry.pendingAcquires ??= 0;
670
- entry.closeWhenIdle ??= false;
671
- }
672
- const nextState = {
673
- clients,
674
- leasedReleases: keyedState.leasedReleases instanceof WeakMap ? keyedState.leasedReleases : /* @__PURE__ */ new WeakMap()
675
- };
676
- globalState[SHARED_CODEX_APP_SERVER_CLIENT_STATE] = nextState;
677
- return nextState;
678
- }
679
- const legacyState = readLegacySharedCodexAppServerClientState(state);
680
- const clients = /* @__PURE__ */ new Map();
681
- if (legacyState?.key && (legacyState.client || legacyState.promise)) {
682
- const legacyKey = legacyState.key;
683
- clients.set(legacyKey, {
684
- client: legacyState.client,
685
- promise: legacyState.promise,
686
- activeLeases: 0,
687
- pendingAcquires: 0,
688
- closeWhenIdle: false
689
- });
690
- legacyState.client?.addCloseHandler((closedClient) => clearSharedClientEntryIfCurrent(legacyKey, closedClient));
691
- }
692
- const nextState = {
693
- clients,
694
- leasedReleases: /* @__PURE__ */ new WeakMap()
695
- };
696
- globalState[SHARED_CODEX_APP_SERVER_CLIENT_STATE] = nextState;
697
- return nextState;
698
- }
699
- function readKeyedSharedCodexAppServerClientState(value) {
700
- return value !== null && typeof value === "object" && value.clients instanceof Map ? value : void 0;
701
- }
702
- function readLegacySharedCodexAppServerClientState(value) {
703
- if (value === null || typeof value !== "object") return;
704
- return value;
705
- }
706
- async function resolveCodexAppServerClientStartContext(options) {
707
- const agentDir = options?.agentDir ?? resolveDefaultAgentDir(options?.config ?? {});
708
- const usesNativeAuth = options?.authProfileId === null;
709
- const requestedAuthProfileId = options?.authProfileId === null ? void 0 : options?.authProfileId;
710
- const authProfileStore = !usesNativeAuth && options?.authProfileStore ? resolveCodexAppServerAuthProfileStore({
711
- agentDir,
712
- authProfileId: requestedAuthProfileId,
713
- authProfileStore: options.authProfileStore,
714
- config: options.config
715
- }) : options?.authProfileStore;
716
- const authProfileId = usesNativeAuth ? void 0 : resolveCodexAppServerAuthProfileIdForAgent({
717
- authProfileId: requestedAuthProfileId,
718
- agentDir,
719
- config: options?.config,
720
- ...authProfileStore ? { authProfileStore } : {}
721
- });
722
- return {
723
- agentDir,
724
- usesNativeAuth,
725
- authProfileId,
726
- authProfileStore,
727
- startOptions: await bridgeCodexAppServerStartOptions({
728
- startOptions: await resolveManagedCodexAppServerStartOptions(options?.startOptions ?? resolveCodexAppServerRuntimeOptions().start),
729
- agentDir,
730
- authProfileId: usesNativeAuth ? null : authProfileId,
731
- config: options?.config,
732
- ...authProfileStore ? { authProfileStore } : {}
733
- })
734
- };
735
- }
736
- /** Gets or starts a shared Codex app-server client without retaining a lease. */
737
- async function getSharedCodexAppServerClient(options) {
738
- return (await acquireSharedCodexAppServerClient(options)).client;
739
- }
740
- /** Gets or starts a shared Codex app-server client and records a release lease. */
741
- async function getLeasedSharedCodexAppServerClient(options) {
742
- const acquired = await acquireSharedCodexAppServerClient(options, { leased: true });
743
- const state = getSharedCodexAppServerClientState();
744
- const releases = state.leasedReleases.get(acquired.client) ?? [];
745
- releases.push(acquired.release);
746
- state.leasedReleases.set(acquired.client, releases);
747
- return acquired.client;
748
- }
749
- /** Releases one outstanding lease for a shared Codex app-server client. */
750
- function releaseLeasedSharedCodexAppServerClient(client) {
751
- const state = getSharedCodexAppServerClientState();
752
- const releases = state.leasedReleases.get(client);
753
- if (!releases) return false;
754
- const release = releases.pop();
755
- if (!release) return false;
756
- if (releases.length === 0) state.leasedReleases.delete(client);
757
- release();
758
- return true;
759
- }
760
- async function acquireSharedCodexAppServerClient(options, leaseOptions) {
761
- const { agentDir, usesNativeAuth, authProfileId, startOptions } = await resolveCodexAppServerClientStartContext(options);
762
- const fallbackApiKeyCacheKey = authProfileId ? void 0 : resolveCodexAppServerFallbackApiKeyCacheKey({ startOptions });
763
- const key = codexAppServerStartOptionsKey(startOptions, {
764
- authProfileId,
765
- agentDir: usesNativeAuth ? void 0 : agentDir,
766
- fallbackApiKeyCacheKey
767
- });
768
- const state = getSharedCodexAppServerClientState();
769
- const entry = getOrCreateSharedClientEntry(state, key);
770
- const releasePendingAcquire = retainPendingSharedClientAcquire(entry);
771
- let cleanupAbandonSignal;
772
- if (options?.abandonSignal) {
773
- const abandon = () => {
774
- releasePendingAcquire();
775
- closeSharedClientEntryIfUnclaimed(key, entry);
776
- };
777
- options.abandonSignal.addEventListener("abort", abandon, { once: true });
778
- cleanupAbandonSignal = () => options.abandonSignal?.removeEventListener("abort", abandon);
779
- if (options.abandonSignal.aborted) abandon();
780
- }
781
- const sharedPromise = entry.promise ?? (entry.promise = (async () => {
782
- const client = CodexAppServerClient.start(startOptions);
783
- entry.client = client;
784
- options?.onStartedClient?.(client);
785
- client.setActiveSharedLeaseCountProviderForUnscopedNotifications(() => entry.activeLeases);
786
- client.addCloseHandler((closedClient) => clearSharedClientEntryIfCurrent(key, closedClient));
787
- try {
788
- await client.initialize();
789
- await applyCodexAppServerAuthProfile({
790
- client,
791
- agentDir,
792
- authProfileId: usesNativeAuth ? null : authProfileId,
793
- startOptions,
794
- config: options?.config
795
- });
796
- return client;
797
- } catch (error) {
798
- client.close();
799
- throw error;
800
- }
801
- })());
802
- try {
803
- const client = await withTimeout$1(sharedPromise, options?.timeoutMs ?? 0, "codex app-server initialize timed out");
804
- client.setActiveSharedLeaseCountProviderForUnscopedNotifications(() => entry.activeLeases);
805
- const release = leaseOptions?.leased ? retainSharedClientEntry(entry) : void 0;
806
- return release ? {
807
- client,
808
- release
809
- } : { client };
810
- } catch (error) {
811
- const currentEntry = state.clients.get(key);
812
- if (currentEntry?.promise === sharedPromise) clearSharedClientEntry(key, currentEntry);
813
- throw error;
814
- } finally {
815
- cleanupAbandonSignal?.();
816
- releasePendingAcquire();
817
- }
818
- }
819
- /** Starts a non-shared Codex app-server client owned entirely by the caller. */
820
- async function createIsolatedCodexAppServerClient(options) {
821
- const { agentDir, usesNativeAuth, authProfileId, authProfileStore, startOptions } = await resolveCodexAppServerClientStartContext(options);
822
- const client = CodexAppServerClient.start(startOptions);
823
- if (authProfileId) client.addRequestHandler(async (request) => {
824
- if (request.method !== "account/chatgptAuthTokens/refresh") return;
825
- return await refreshCodexAppServerAuthTokens({
826
- agentDir,
827
- authProfileId,
828
- ...authProfileStore ? { authProfileStore } : {},
829
- config: options?.config
830
- });
831
- });
832
- const initialize = client.initialize();
833
- try {
834
- await withTimeout$1(initialize, options?.timeoutMs ?? 0, "codex app-server initialize timed out");
835
- await applyCodexAppServerAuthProfile({
836
- client,
837
- agentDir,
838
- authProfileId: usesNativeAuth ? null : authProfileId,
839
- startOptions,
840
- config: options?.config,
841
- ...authProfileStore ? { authProfileStore } : {}
842
- });
843
- return client;
844
- } catch (error) {
845
- client.close();
846
- initialize.catch(() => void 0);
847
- throw error;
848
- }
849
- }
850
- /** Clears and closes all shared clients for deterministic tests. */
851
- function resetSharedCodexAppServerClientForTests() {
852
- const state = getSharedCodexAppServerClientState();
853
- const clients = collectSharedClients(state);
854
- state.clients.clear();
855
- state.leasedReleases = /* @__PURE__ */ new WeakMap();
856
- for (const client of clients) client.close();
857
- }
858
- /** Clears and closes all shared clients. */
859
- function clearSharedCodexAppServerClient() {
860
- const state = getSharedCodexAppServerClientState();
861
- const clients = collectSharedClients(state);
862
- state.clients.clear();
863
- for (const client of clients) client.close();
864
- }
865
- /** Clears and closes the shared entry only if it still owns the supplied client. */
866
- function clearSharedCodexAppServerClientIfCurrent(client) {
867
- if (!client) return false;
868
- const state = getSharedCodexAppServerClientState();
869
- for (const [key, entry] of state.clients) if (entry.client === client) {
870
- state.clients.delete(key);
871
- client.close();
872
- return true;
873
- }
874
- return false;
875
- }
876
- /** Detaches the shared entry without closing the client when it still matches. */
877
- function detachSharedCodexAppServerClientIfCurrent(client) {
878
- if (!client) return false;
879
- const state = getSharedCodexAppServerClientState();
880
- for (const [key, entry] of state.clients) if (entry.client === client) {
881
- state.clients.delete(key);
882
- return true;
883
- }
884
- return false;
885
- }
886
- /** Retains the matching shared client and returns a release callback. */
887
- function retainSharedCodexAppServerClientIfCurrent(client) {
888
- if (!client) return;
889
- const state = getSharedCodexAppServerClientState();
890
- for (const entry of state.clients.values()) if (entry.client === client) return retainSharedClientEntry(entry);
891
- }
892
- /** Marks a matching shared client to close after active leases/acquires drain. */
893
- function retireSharedCodexAppServerClientIfCurrent(client) {
894
- if (!client) return;
895
- const state = getSharedCodexAppServerClientState();
896
- for (const [key, entry] of state.clients) if (entry.client === client) {
897
- state.clients.delete(key);
898
- entry.closeWhenIdle = true;
899
- const closed = closeRetiredSharedClientEntryIfIdle(entry);
900
- return {
901
- activeLeases: entry.activeLeases,
902
- closed
903
- };
904
- }
905
- const activeLeases = state.leasedReleases.get(client)?.length ?? 0;
906
- if (activeLeases > 0) return {
907
- activeLeases,
908
- closed: false
909
- };
910
- }
911
- /** Clears a matching shared client and waits for its process to exit. */
912
- async function clearSharedCodexAppServerClientIfCurrentAndWait(client, options) {
913
- if (!client) return false;
914
- const state = getSharedCodexAppServerClientState();
915
- for (const [key, entry] of state.clients) if (entry.client === client) {
916
- state.clients.delete(key);
917
- await client.closeAndWait(options);
918
- return true;
919
- }
920
- return false;
921
- }
922
- /** Clears all shared clients and waits for their processes to exit. */
923
- async function clearSharedCodexAppServerClientAndWait(options) {
924
- const state = getSharedCodexAppServerClientState();
925
- const clients = collectSharedClients(state);
926
- state.clients.clear();
927
- await Promise.all(clients.map((client) => client.closeAndWait(options)));
928
- }
929
- function getOrCreateSharedClientEntry(state, key) {
930
- let entry = state.clients.get(key);
931
- if (!entry) {
932
- entry = {
933
- activeLeases: 0,
934
- pendingAcquires: 0,
935
- closeWhenIdle: false
936
- };
937
- state.clients.set(key, entry);
938
- }
939
- return entry;
940
- }
941
- function clearSharedClientEntry(key, entry) {
942
- const state = getSharedCodexAppServerClientState();
943
- if (state.clients.get(key) !== entry) return;
944
- state.clients.delete(key);
945
- entry.client?.close();
946
- }
947
- function clearSharedClientEntryIfCurrent(key, client) {
948
- const state = getSharedCodexAppServerClientState();
949
- if (state.clients.get(key)?.client === client) state.clients.delete(key);
950
- }
951
- /** Clears a matching shared client only when no lease or acquire currently claims it. */
952
- function clearSharedCodexAppServerClientIfCurrentAndUnclaimed(client) {
953
- if (!client) return {
954
- found: false,
955
- closed: false,
956
- activeLeases: 0,
957
- pendingAcquires: 0
958
- };
959
- const state = getSharedCodexAppServerClientState();
960
- for (const [key, entry] of state.clients) if (entry.client === client) return {
961
- found: true,
962
- closed: closeSharedClientEntryIfUnclaimed(key, entry),
963
- activeLeases: entry.activeLeases,
964
- pendingAcquires: entry.pendingAcquires
965
- };
966
- return {
967
- found: false,
968
- closed: false,
969
- activeLeases: 0,
970
- pendingAcquires: 0
971
- };
972
- }
973
- function retainPendingSharedClientAcquire(entry) {
974
- let released = false;
975
- entry.pendingAcquires += 1;
976
- return () => {
977
- if (released) return;
978
- released = true;
979
- entry.pendingAcquires = Math.max(0, entry.pendingAcquires - 1);
980
- closeRetiredSharedClientEntryIfIdle(entry);
981
- };
982
- }
983
- function retainSharedClientEntry(entry) {
984
- let released = false;
985
- entry.activeLeases += 1;
986
- return () => {
987
- if (released) return;
988
- released = true;
989
- entry.activeLeases = Math.max(0, entry.activeLeases - 1);
990
- closeRetiredSharedClientEntryIfIdle(entry);
991
- };
992
- }
993
- function closeRetiredSharedClientEntryIfIdle(entry) {
994
- if (!entry.closeWhenIdle || entry.activeLeases > 0 || entry.pendingAcquires > 0 || !entry.client) return false;
995
- const client = entry.client;
996
- entry.closeWhenIdle = false;
997
- entry.client = void 0;
998
- client.close();
999
- return true;
1000
- }
1001
- function closeSharedClientEntryIfUnclaimed(key, entry) {
1002
- if (entry.activeLeases > 0 || entry.pendingAcquires > 0) return false;
1003
- const state = getSharedCodexAppServerClientState();
1004
- if (state.clients.get(key) !== entry) return false;
1005
- state.clients.delete(key);
1006
- entry.client?.close();
1007
- return Boolean(entry.client);
1008
- }
1009
- function collectSharedClients(state) {
1010
- return [...new Set([...state.clients.values()].map((entry) => entry.client).filter((client) => Boolean(client)))];
1011
- }
1012
- //#endregion
1013
- export { getLeasedSharedCodexAppServerClient as a, shared_client_exports as c, resolveCodexAppServerAuthAccountCacheKey as d, resolveCodexAppServerAuthProfileId as f, resolveCodexAppServerHomeDir as h, createIsolatedCodexAppServerClient as i, withTimeout$1 as l, resolveCodexAppServerFallbackApiKeyCacheKey as m, clearSharedCodexAppServerClientIfCurrentAndUnclaimed as n, releaseLeasedSharedCodexAppServerClient as o, resolveCodexAppServerAuthProfileIdForAgent as p, clearSharedCodexAppServerClientIfCurrentAndWait as r, retireSharedCodexAppServerClientIfCurrent as s, clearSharedCodexAppServerClientIfCurrent as t, refreshCodexAppServerAuthTokens as u };