@openclaw/codex 2026.7.2-beta.1 → 2026.7.2-beta.3

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 (41) hide show
  1. package/README.md +1 -1
  2. package/dist/{app-server-policy-DVcxdse_.js → app-server-policy-DUMF2Xyr.js} +1 -1
  3. package/dist/{attempt-notifications-DEv9h7iC.js → attempt-notifications-Ecjyzufe.js} +3 -6
  4. package/dist/cli-metadata.js +1 -1
  5. package/dist/{command-formatters-D6ZlGNmb.js → command-formatters-NCTL7A2q.js} +38 -3
  6. package/dist/{command-handlers-Cpl9fUWv.js → command-handlers-DtFbZiba.js} +70 -15
  7. package/dist/{compact-FnJmiPNA.js → compact-Kgy26gIM.js} +4 -5
  8. package/dist/{computer-use-DVzr8OP1.js → computer-use-C7x4ZaqR.js} +4 -4
  9. package/dist/{conversation-control-DtQ-E7mr.js → conversation-control-B0s3aIjT.js} +5 -7
  10. package/dist/doctor-contract-api.js +1 -1
  11. package/dist/{dynamic-tools-BMLoaTeG.js → dynamic-tools-D_vSVmv9.js} +851 -434
  12. package/dist/harness.js +11 -6
  13. package/dist/index.js +52 -31
  14. package/dist/{media-understanding-provider-D580L0P8.js → media-understanding-provider-IPNNQre6.js} +11 -12
  15. package/dist/media-understanding-provider.js +1 -1
  16. package/dist/{models-DuKzZA6G.js → models-DD5zBdX5.js} +5 -9
  17. package/dist/{notification-correlation-DfaCm0mx.js → notification-correlation-C8DVQ_Bq.js} +3 -3
  18. package/dist/{plugin-app-cache-key-BKNjHMEs.js → plugin-app-cache-key-DJbhLYSK.js} +2 -2
  19. package/dist/{rate-limits-Dhp04Rqo.js → rate-limits-CqhWQ2R9.js} +9 -6
  20. package/dist/{request-DborTWgw.js → request-9yf9pZjf.js} +54 -8
  21. package/dist/{run-attempt-VPVJoYDP.js → run-attempt-BIoO8ISr.js} +637 -351
  22. package/dist/{config-c48K5HP9.js → session-binding-Bmt20HfB.js} +788 -3
  23. package/dist/{session-catalog-7H112Tr_.js → session-catalog-CA7R-hX2.js} +82 -45
  24. package/dist/{session-cli-B28RhCyp.js → session-cli-Bxk3-Wqz.js} +2 -2
  25. package/dist/{shared-client-D4mFI9al.js → shared-client-CSXLtCLE.js} +304 -81
  26. package/dist/{side-question-CgJBz52s.js → side-question-DtzquMOb.js} +15 -13
  27. package/dist/{thread-lifecycle-BgLXzjvV.js → thread-lifecycle-CQ_9mAa1.js} +1821 -1582
  28. package/dist/{protocol-validators-dZQ-UTOa.js → transcript-mirror-D9rTxx2P.js} +485 -2
  29. package/dist/usage-CuPpFgTc.js +25 -0
  30. package/dist/{web-search-provider.runtime-Bs-eTn5U.js → web-search-provider.runtime-_x5XTeqh.js} +3 -3
  31. package/npm-shrinkwrap.json +30 -30
  32. package/openclaw.plugin.json +21 -6
  33. package/package.json +6 -6
  34. package/dist/capabilities-42Dfn2TV.js +0 -33
  35. package/dist/prompt-overlay.js +0 -15
  36. package/dist/protocol-BMifTfdW.js +0 -15
  37. package/dist/provider-catalog.js +0 -118
  38. package/dist/provider-discovery.js +0 -34
  39. package/dist/provider.js +0 -307
  40. package/dist/session-binding-BMfX1OX-.js +0 -786
  41. package/dist/transcript-mirror-DhLwFIL4.js +0 -485
@@ -1,9 +1,11 @@
1
+ import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
2
+ import { n as CODEX_APP_SERVER_BINDING_NAMESPACE, t as CODEX_APP_SERVER_BINDING_MAX_ENTRIES } from "./session-binding-meta-B7aEMU7g.js";
1
3
  import path from "node:path";
2
4
  import { resolvePositiveTimerTimeoutMs } from "openclaw/plugin-sdk/number-runtime";
3
- import { createHash, createHmac, randomBytes } from "node:crypto";
5
+ import { createHash, createHmac, randomBytes, randomUUID } from "node:crypto";
4
6
  import { readFileSync } from "node:fs";
5
7
  import { homedir, hostname } from "node:os";
6
- import { resolveProviderIdForAuth } from "openclaw/plugin-sdk/agent-runtime";
8
+ import { ensureAuthProfileStore, resolveDefaultAgentDir, resolveProviderIdForAuth, resolveSessionAgentIds } from "openclaw/plugin-sdk/agent-runtime";
7
9
  import { resolveExecApprovalsFromFile } from "openclaw/plugin-sdk/exec-approvals-runtime";
8
10
  import { normalizeAgentId } from "openclaw/plugin-sdk/routing";
9
11
  import { buildSecretInputSchema, normalizeResolvedSecretInputString } from "openclaw/plugin-sdk/secret-input";
@@ -11,6 +13,9 @@ import { normalizeTrimmedStringList } from "openclaw/plugin-sdk/string-coerce-ru
11
13
  import { detectWindowsSpawnCommandInlineArgs } from "openclaw/plugin-sdk/windows-spawn";
12
14
  import { parse } from "smol-toml";
13
15
  import { z } from "zod";
16
+ import { embeddedAgentLog } from "openclaw/plugin-sdk/agent-harness-runtime";
17
+ import { AsyncLocalStorage } from "node:async_hooks";
18
+ import { getSessionEntry, resolveStorePath } from "openclaw/plugin-sdk/session-store-runtime";
14
19
  //#region extensions/codex/src/app-server/session-discovery-config.ts
15
20
  const codexSessionCatalogConfigSchema = z.object({ enabled: z.boolean().optional() }).strict();
16
21
  const codexDiscoveryConfigSchema = z.object({
@@ -163,8 +168,10 @@ const codexPluginConfigSchema = z.object({
163
168
  clearEnv: z.array(z.string()).optional(),
164
169
  remoteWorkspaceRoot: codexAppServerRemoteWorkspaceRootSchema.optional(),
165
170
  codeModeOnly: z.boolean().optional(),
171
+ loopDetectionPreToolUseRelay: z.boolean().optional(),
166
172
  requestTimeoutMs: z.number().positive().optional(),
167
173
  turnCompletionIdleTimeoutMs: z.number().positive().optional(),
174
+ turnAssistantCompletionIdleTimeoutMs: z.number().positive().optional(),
168
175
  postToolRawAssistantCompletionIdleTimeoutMs: z.number().positive().optional(),
169
176
  approvalPolicy: codexAppServerApprovalPolicySchema.optional(),
170
177
  sandbox: codexAppServerSandboxSchema.optional(),
@@ -358,8 +365,10 @@ function resolveCodexAppServerRuntimeOptions(params = {}) {
358
365
  remoteAppsSubstrate,
359
366
  ...remoteWorkspaceRoot ? { remoteWorkspaceRoot } : {},
360
367
  codeModeOnly: config.codeModeOnly === true,
368
+ loopDetectionPreToolUseRelay: config.loopDetectionPreToolUseRelay !== false,
361
369
  requestTimeoutMs: normalizePositiveNumber(config.requestTimeoutMs, 6e4),
362
370
  turnCompletionIdleTimeoutMs: normalizePositiveNumber(config.turnCompletionIdleTimeoutMs, 6e4),
371
+ turnAssistantCompletionIdleTimeoutMs: normalizePositiveNumber(config.turnAssistantCompletionIdleTimeoutMs, 1e4),
363
372
  ...config.postToolRawAssistantCompletionIdleTimeoutMs !== void 0 ? { postToolRawAssistantCompletionIdleTimeoutMs: normalizePositiveNumber(config.postToolRawAssistantCompletionIdleTimeoutMs, 6e4) } : {},
364
373
  approvalPolicy: forcedPolicy?.approvalPolicy ?? approvalPolicy,
365
374
  approvalPolicySource,
@@ -1306,4 +1315,780 @@ function splitShellWords(value) {
1306
1315
  return words;
1307
1316
  }
1308
1317
  //#endregion
1309
- export { resolveCodexPluginsPolicy as _, codexAppServerStartOptionsKey as a, shouldAutoApproveCodexAppServerApprovals as b, isCodexFastServiceTier as c, readCodexPluginConfig as d, resolveCodexAppServerRuntimeOptions as f, resolveCodexModelBackedReviewerPolicyContext as g, resolveCodexComputerUseConfig as h, canUseCodexModelBackedApprovalsReviewerForModel as i, isCodexSandboxExecServerEnabled as l, resolveCodexAppServerUserHomeDir as m, CODEX_PLUGINS_WORKSPACE_MARKETPLACE_NAME as n, codexSandboxPolicyForTurn as o, resolveCodexAppServerStartOptionsForAgent as p, assertCodexAppServerConnectionSecurity as r, isCodexAppServerApprovalPolicyAllowedByRequirements as s, CODEX_PLUGINS_MARKETPLACE_NAME as t, normalizeCodexServiceTier as u, resolveCodexSupervisionAppServerRuntimeOptions as v, withMcpElicitationsApprovalPolicy as x, resolveOpenClawExecPolicyForCodexAppServer as y };
1318
+ //#region extensions/codex/src/app-server/session-binding.ts
1319
+ /** SQLite-backed Codex app-server thread bindings. */
1320
+ var session_binding_exports = /* @__PURE__ */ __exportAll({
1321
+ CODEX_APP_SERVER_BINDING_GUARDED_REQUEST_TIMEOUT_MS: () => CODEX_APP_SERVER_BINDING_GUARDED_REQUEST_TIMEOUT_MS,
1322
+ CODEX_APP_SERVER_BINDING_MAX_ENTRIES: () => CODEX_APP_SERVER_BINDING_MAX_ENTRIES,
1323
+ CODEX_APP_SERVER_BINDING_NAMESPACE: () => CODEX_APP_SERVER_BINDING_NAMESPACE,
1324
+ CodexSupervisionBindingReplacementError: () => CodexSupervisionBindingReplacementError,
1325
+ assertCodexBindingMayBeReplaced: () => assertCodexBindingMayBeReplaced,
1326
+ bindingStoreKey: () => bindingStoreKey,
1327
+ createCodexAppServerBindingStore: () => createCodexAppServerBindingStore,
1328
+ createStoredCodexAppServerBinding: () => createStoredCodexAppServerBinding,
1329
+ hashCodexAppServerBindingFingerprint: () => hashCodexAppServerBindingFingerprint,
1330
+ isCodexAppServerNativeAuthProfile: () => isCodexAppServerNativeAuthProfile,
1331
+ normalizeCodexAppServerBindingModelProvider: () => normalizeCodexAppServerBindingModelProvider,
1332
+ normalizeStoredCodexAppServerBindingFingerprints: () => normalizeStoredCodexAppServerBindingFingerprints,
1333
+ readCodexAppServerThreadBinding: () => readCodexAppServerThreadBinding,
1334
+ readStoredCodexAppServerBinding: () => readStoredCodexAppServerBinding,
1335
+ reclaimCurrentCodexSessionGeneration: () => reclaimCurrentCodexSessionGeneration,
1336
+ resolveCodexAppServerBindingModelProvider: () => resolveCodexAppServerBindingModelProvider,
1337
+ sessionBindingIdentity: () => sessionBindingIdentity
1338
+ });
1339
+ const CODEX_APP_SERVER_NATIVE_AUTH_PROVIDER = "openai";
1340
+ const PUBLIC_OPENAI_MODEL_PROVIDER = "openai";
1341
+ const BINDING_LEASE_RETRY_INTERVAL_MS = 1e3;
1342
+ const BOUNDED_BINDING_FINGERPRINT_PATTERN = /^sha256:[a-f0-9]{64}$/i;
1343
+ const CODEX_APP_SERVER_BINDING_GUARDED_REQUEST_TIMEOUT_MS = 6e4;
1344
+ const BINDING_LEASE_STALE_MS = 65e3;
1345
+ const BINDING_LEASE_WAIT_MS = 7e4;
1346
+ const BINDING_LEASE_RENEW_INTERVAL_MS = Math.floor(BINDING_LEASE_STALE_MS / 3);
1347
+ const PHYSICAL_SESSION_RETIRE_TTL_MS = BINDING_LEASE_WAIT_MS;
1348
+ /** Resolves the same agent scope OpenClaw uses for transcript/session ownership. */
1349
+ function sessionBindingIdentity(params) {
1350
+ const { sessionAgentId } = resolveSessionAgentIds(params);
1351
+ const sessionKey = params.sessionKey?.trim();
1352
+ return {
1353
+ kind: "session",
1354
+ agentId: sessionAgentId,
1355
+ sessionId: params.sessionId,
1356
+ ...sessionKey ? { sessionKey } : {}
1357
+ };
1358
+ }
1359
+ const optionalStringSchema = z.string().optional().catch(void 0);
1360
+ const optionalBooleanSchema = z.boolean().optional().catch(void 0);
1361
+ const optionalNonBlankStringSchema = z.string().refine((value) => Boolean(value.trim())).optional().catch(void 0);
1362
+ const optionalTimestampSchema = z.string().refine((value) => Number.isFinite(Date.parse(value))).optional().catch(void 0);
1363
+ const pendingSupervisionBranchSchema = z.object({
1364
+ sourceThreadId: z.string().trim().min(1),
1365
+ connectionFingerprint: z.string().trim().min(1).optional(),
1366
+ lastTurnId: z.string().trim().min(1).optional(),
1367
+ cleanupThreadIds: z.array(z.string().trim().min(1)).max(2).optional()
1368
+ }).strict().superRefine((pending, context) => {
1369
+ const cleanupThreadIds = pending.cleanupThreadIds ?? [];
1370
+ if (new Set(cleanupThreadIds).size !== cleanupThreadIds.length) context.addIssue({
1371
+ code: "custom",
1372
+ message: "pending supervision cleanup thread ids must be unique"
1373
+ });
1374
+ if (cleanupThreadIds.includes(pending.sourceThreadId)) context.addIssue({
1375
+ code: "custom",
1376
+ message: "pending supervision cleanup cannot target its source"
1377
+ });
1378
+ });
1379
+ const contextEngineProjectionSchema = z.object({
1380
+ schemaVersion: z.literal(1),
1381
+ mode: z.literal("thread_bootstrap"),
1382
+ epoch: z.string().refine((value) => Boolean(value.trim())),
1383
+ fingerprint: optionalStringSchema
1384
+ }).strict();
1385
+ const contextEngineSchema = z.object({
1386
+ schemaVersion: z.literal(1),
1387
+ engineId: z.string(),
1388
+ policyFingerprint: z.string(),
1389
+ projection: contextEngineProjectionSchema.optional().catch(void 0)
1390
+ }).strict();
1391
+ const destructiveApprovalModeSchema = z.enum([
1392
+ "allow",
1393
+ "deny",
1394
+ "auto",
1395
+ "ask"
1396
+ ]).optional().catch(void 0);
1397
+ const accountAppPolicyEntrySchema = z.object({
1398
+ source: z.literal("account"),
1399
+ appName: z.string(),
1400
+ allowDestructiveActions: z.boolean(),
1401
+ destructiveApprovalMode: destructiveApprovalModeSchema,
1402
+ mcpServerNames: z.array(z.string())
1403
+ }).strict();
1404
+ const pluginAppPolicyEntrySchema = z.object({
1405
+ source: z.literal("plugin").optional(),
1406
+ configKey: z.string(),
1407
+ marketplaceName: z.enum([CODEX_PLUGINS_MARKETPLACE_NAME, CODEX_PLUGINS_WORKSPACE_MARKETPLACE_NAME]),
1408
+ pluginName: z.string(),
1409
+ allowDestructiveActions: z.boolean(),
1410
+ destructiveApprovalMode: destructiveApprovalModeSchema,
1411
+ mcpServerNames: z.array(z.string())
1412
+ }).strict();
1413
+ const pluginAppPolicyContextSchema = z.object({
1414
+ fingerprint: z.string(),
1415
+ apps: z.record(z.string(), z.union([accountAppPolicyEntrySchema, pluginAppPolicyEntrySchema])),
1416
+ pluginAppIds: z.record(z.string(), z.array(z.string())).default({})
1417
+ }).strict();
1418
+ const threadBindingSchema = z.object({
1419
+ threadId: z.string().refine((value) => Boolean(value.trim())),
1420
+ clientId: optionalStringSchema,
1421
+ cwd: z.string(),
1422
+ connectionScope: z.literal("supervision").optional(),
1423
+ supervisionSourceThreadId: z.string().trim().min(1).optional(),
1424
+ authProfileId: optionalStringSchema,
1425
+ model: optionalStringSchema,
1426
+ preserveNativeModel: z.literal(true).optional().catch(void 0),
1427
+ pendingSupervisionBranch: pendingSupervisionBranchSchema.optional(),
1428
+ modelProvider: z.string().transform((value) => value.trim()).pipe(z.string().min(1)).optional().catch(void 0),
1429
+ approvalPolicy: z.preprocess((value) => value === "on-failure" ? "on-request" : value, z.enum([
1430
+ "never",
1431
+ "on-request",
1432
+ "untrusted"
1433
+ ]).optional()).catch(void 0),
1434
+ sandbox: z.enum([
1435
+ "read-only",
1436
+ "workspace-write",
1437
+ "danger-full-access"
1438
+ ]).optional().catch(void 0),
1439
+ serviceTier: z.preprocess(normalizeCodexServiceTier, z.custom((value) => typeof value === "string").optional()).optional().catch(void 0),
1440
+ networkProxyProfileName: optionalStringSchema,
1441
+ networkProxyConfigFingerprint: optionalStringSchema,
1442
+ dynamicToolsFingerprint: optionalStringSchema,
1443
+ dynamicToolsContainDeferred: optionalBooleanSchema,
1444
+ webSearchThreadConfigFingerprint: optionalStringSchema,
1445
+ userMcpServersFingerprint: optionalStringSchema,
1446
+ mcpServersFingerprint: optionalStringSchema,
1447
+ ringZeroConfigFingerprint: optionalStringSchema,
1448
+ ringZeroClientInstanceId: optionalStringSchema,
1449
+ nativeHookRelayGeneration: optionalNonBlankStringSchema,
1450
+ appServerRuntimeFingerprint: optionalStringSchema,
1451
+ pluginAppsFingerprint: optionalStringSchema,
1452
+ pluginAppsInputFingerprint: optionalStringSchema,
1453
+ pluginAppPolicyContext: pluginAppPolicyContextSchema.optional().catch(void 0),
1454
+ contextEngine: contextEngineSchema.optional().catch(void 0),
1455
+ environmentSelectionFingerprint: optionalStringSchema,
1456
+ conversationStartId: optionalStringSchema,
1457
+ conversationSourceTransferComplete: z.literal(true).optional().catch(void 0),
1458
+ historyCoveredThrough: optionalTimestampSchema
1459
+ }).superRefine((binding, context) => {
1460
+ if (binding.connectionScope === "supervision") {
1461
+ if (!binding.supervisionSourceThreadId) context.addIssue({
1462
+ code: "custom",
1463
+ message: "supervision connection ownership requires its native source thread id"
1464
+ });
1465
+ if (binding.preserveNativeModel !== true) context.addIssue({
1466
+ code: "custom",
1467
+ message: "supervision connection ownership requires native model ownership"
1468
+ });
1469
+ if (binding.conversationSourceTransferComplete !== true) context.addIssue({
1470
+ code: "custom",
1471
+ message: "supervision connection ownership requires a completed source transfer"
1472
+ });
1473
+ if (!binding.pendingSupervisionBranch && (!binding.model?.trim() || !binding.modelProvider)) context.addIssue({
1474
+ code: "custom",
1475
+ message: "materialized supervision bindings require a native model and provider"
1476
+ });
1477
+ }
1478
+ if (binding.supervisionSourceThreadId && binding.connectionScope !== "supervision") context.addIssue({
1479
+ code: "custom",
1480
+ message: "a supervision source thread id requires supervision connection ownership"
1481
+ });
1482
+ if (!binding.pendingSupervisionBranch) return;
1483
+ if (binding.threadId !== binding.pendingSupervisionBranch.sourceThreadId) context.addIssue({
1484
+ code: "custom",
1485
+ message: "pending supervision source must match the provisional thread binding"
1486
+ });
1487
+ if (binding.supervisionSourceThreadId !== binding.pendingSupervisionBranch.sourceThreadId) context.addIssue({
1488
+ code: "custom",
1489
+ message: "pending supervision source must match its durable source identity"
1490
+ });
1491
+ if (binding.preserveNativeModel !== true) context.addIssue({
1492
+ code: "custom",
1493
+ message: "pending supervision bindings must defer model selection to Codex App Server"
1494
+ });
1495
+ if (binding.connectionScope !== "supervision") context.addIssue({
1496
+ code: "custom",
1497
+ message: "pending supervision bindings require supervision connection ownership"
1498
+ });
1499
+ });
1500
+ var CodexSupervisionBindingReplacementError = class extends Error {
1501
+ constructor(threadId, operation) {
1502
+ super(`Refusing to replace supervised Codex thread ${threadId} while ${operation}; its native user-home connection and model ownership must be preserved`);
1503
+ this.name = "CodexSupervisionBindingReplacementError";
1504
+ }
1505
+ };
1506
+ function assertCodexBindingMayBeReplaced(binding, operation) {
1507
+ if (binding?.connectionScope === "supervision") throw new CodexSupervisionBindingReplacementError(binding.threadId, operation);
1508
+ }
1509
+ const bindingLeaseSchema = z.object({
1510
+ token: z.string().refine((value) => Boolean(value.trim())),
1511
+ expiresAt: z.number().finite()
1512
+ });
1513
+ const storedSessionIdSchema = z.string().transform((value) => value.trim()).pipe(z.string().min(1)).optional().catch(void 0);
1514
+ const storedBindingSchema = z.discriminatedUnion("state", [z.object({
1515
+ version: z.literal(1),
1516
+ state: z.literal("active"),
1517
+ binding: threadBindingSchema,
1518
+ sessionId: storedSessionIdSchema,
1519
+ lease: bindingLeaseSchema.optional().catch(void 0)
1520
+ }), z.object({
1521
+ version: z.literal(1),
1522
+ state: z.literal("cleared"),
1523
+ sessionId: storedSessionIdSchema,
1524
+ lease: bindingLeaseSchema.optional().catch(void 0),
1525
+ retired: z.literal(true).optional().catch(void 0)
1526
+ })]);
1527
+ function hashCodexAppServerBindingFingerprint(canonical) {
1528
+ return `sha256:${createHash("sha256").update(canonical).digest("hex")}`;
1529
+ }
1530
+ function normalizeLegacyBindingFingerprint(value) {
1531
+ if (typeof value !== "string" || value === "" || value === "[]" || BOUNDED_BINDING_FINGERPRINT_PATTERN.test(value)) return value;
1532
+ return hashCodexAppServerBindingFingerprint(value);
1533
+ }
1534
+ function normalizeLegacyBindingFingerprints(record) {
1535
+ let normalized = record;
1536
+ for (const key of ["dynamicToolsFingerprint", "userMcpServersFingerprint"]) {
1537
+ const value = record[key];
1538
+ const next = normalizeLegacyBindingFingerprint(value);
1539
+ if (next === value) continue;
1540
+ if (normalized === record) normalized = { ...record };
1541
+ normalized[key] = next;
1542
+ }
1543
+ return normalized;
1544
+ }
1545
+ function normalizeStoredCodexAppServerBindingFingerprints(value) {
1546
+ const stored = readStoredCodexAppServerBinding(value);
1547
+ if (!stored || stored.state !== "active") return stored;
1548
+ const binding = normalizeLegacyBindingFingerprints(stored.binding);
1549
+ return binding === stored.binding ? stored : readStoredCodexAppServerBinding({
1550
+ ...stored,
1551
+ binding
1552
+ });
1553
+ }
1554
+ /** Encodes a migrated sidecar binding as one canonical plugin-state row. */
1555
+ function createStoredCodexAppServerBinding(value, options = {}) {
1556
+ const rawRecord = asRecord(value);
1557
+ if (!rawRecord) return;
1558
+ const record = normalizeLegacyBindingFingerprints(rawRecord);
1559
+ if (record.schemaVersion !== 1 && record.schemaVersion !== 2) return;
1560
+ const pluginAppPolicyContext = readPluginAppPolicyContext(record.pluginAppPolicyContext, record.schemaVersion);
1561
+ const historyCoveredThrough = readTimestamp(record.historyCoveredThrough) ?? readTimestamp(record.updatedAt) ?? readTimestamp(record.createdAt) ?? readTimestamp(options.now) ?? (/* @__PURE__ */ new Date()).toISOString();
1562
+ const authProfileId = typeof record.authProfileId === "string" ? record.authProfileId : void 0;
1563
+ const binding = readCodexAppServerThreadBinding({
1564
+ ...record,
1565
+ modelProvider: normalizeCodexAppServerBindingModelProvider({
1566
+ ...options.lookup,
1567
+ authProfileId,
1568
+ modelProvider: typeof record.modelProvider === "string" ? record.modelProvider : void 0
1569
+ }),
1570
+ cwd: typeof record.cwd === "string" ? record.cwd : "",
1571
+ pluginAppPolicyContext,
1572
+ historyCoveredThrough
1573
+ });
1574
+ return binding ? {
1575
+ version: 1,
1576
+ state: "active",
1577
+ binding: stripUndefinedBinding(binding)
1578
+ } : void 0;
1579
+ }
1580
+ function bindingLeaseLostError(key, cause) {
1581
+ return new Error(`Lost Codex binding lease: ${key}`, cause === void 0 ? void 0 : { cause });
1582
+ }
1583
+ /** Lets the authoritative OpenClaw session generation claim a stale stable binding row. */
1584
+ async function reclaimCurrentCodexSessionGeneration(params) {
1585
+ const sessionKey = params.identity.sessionKey?.trim();
1586
+ if (!sessionKey) return true;
1587
+ const plan = await params.bindingStore.prepareSessionGenerationReclaim(params.identity);
1588
+ if (plan.kind === "resolved") return plan.result;
1589
+ try {
1590
+ const storePath = resolveStorePath(params.config?.session?.store, { agentId: params.identity.agentId });
1591
+ if (getSessionEntry({
1592
+ agentId: params.identity.agentId,
1593
+ hydrateSkillPromptRefs: false,
1594
+ readConsistency: "latest",
1595
+ sessionKey,
1596
+ storePath
1597
+ })?.sessionId !== params.identity.sessionId) return false;
1598
+ } catch {
1599
+ return false;
1600
+ }
1601
+ return await params.bindingStore.mutate(params.identity, {
1602
+ kind: "reclaim-generation",
1603
+ expectedPreviousSessionId: plan.expectedPreviousSessionId
1604
+ });
1605
+ }
1606
+ /** Creates the single binding facade owned by the Codex plugin runtime. */
1607
+ function createCodexAppServerBindingStore(state) {
1608
+ const update = state.update?.bind(state);
1609
+ if (!update) throw new Error("Codex app-server bindings require atomic plugin-state updates");
1610
+ const leaseContext = new AsyncLocalStorage();
1611
+ const archiveContext = new AsyncLocalStorage();
1612
+ let activeBindingMutations = 0;
1613
+ let pendingArchives = 0;
1614
+ let archiveTail = Promise.resolve();
1615
+ let bindingMutationsDrained = [];
1616
+ const waitForBindingMutations = async () => {
1617
+ if (activeBindingMutations === 0) return;
1618
+ await new Promise((resolve) => {
1619
+ bindingMutationsDrained.push(resolve);
1620
+ });
1621
+ };
1622
+ const runBindingMutation = async (run) => {
1623
+ if (archiveContext.getStore() === true) return await run();
1624
+ if (pendingArchives > 0) throw new Error("Codex binding mutation blocked while a native archive is in progress; retry");
1625
+ activeBindingMutations += 1;
1626
+ try {
1627
+ return await run();
1628
+ } finally {
1629
+ activeBindingMutations -= 1;
1630
+ if (activeBindingMutations === 0) {
1631
+ const drained = bindingMutationsDrained;
1632
+ bindingMutationsDrained = [];
1633
+ for (const resolve of drained) resolve();
1634
+ }
1635
+ }
1636
+ };
1637
+ const renewLease = (key, owner) => {
1638
+ if (owner.failure) return;
1639
+ try {
1640
+ let renewed = false;
1641
+ const stored = update(key, (raw) => {
1642
+ const current = readStoredCodexAppServerBinding(raw);
1643
+ if (raw !== void 0 && !current) throw new Error(`Invalid Codex app-server binding row: ${key}`);
1644
+ const lease = current?.lease;
1645
+ const now = Date.now();
1646
+ if (!lease || lease.token !== owner.token || lease.expiresAt <= now) return;
1647
+ renewed = true;
1648
+ return {
1649
+ ...current,
1650
+ lease: {
1651
+ token: owner.token,
1652
+ expiresAt: now + BINDING_LEASE_STALE_MS
1653
+ }
1654
+ };
1655
+ });
1656
+ if (!renewed || !stored) owner.failure = bindingLeaseLostError(key);
1657
+ } catch (error) {
1658
+ owner.failure = bindingLeaseLostError(key, error);
1659
+ }
1660
+ };
1661
+ const transactKey = async (key, apply, ttlMs) => {
1662
+ const deadline = Date.now() + BINDING_LEASE_WAIT_MS;
1663
+ while (true) {
1664
+ let busy = false;
1665
+ let leaseLost = false;
1666
+ let result;
1667
+ const ownedLease = leaseContext.getStore()?.get(key);
1668
+ if (ownedLease?.failure) throw ownedLease.failure;
1669
+ const ownedToken = ownedLease?.token;
1670
+ update(key, (raw) => {
1671
+ const current = readStoredCodexAppServerBinding(raw);
1672
+ if (raw !== void 0 && !current) throw new Error(`Invalid Codex app-server binding row: ${key}`);
1673
+ const activeLease = current?.lease;
1674
+ const now = Date.now();
1675
+ if (ownedToken && (!activeLease || activeLease.token !== ownedToken || activeLease.expiresAt <= now)) {
1676
+ leaseLost = true;
1677
+ return;
1678
+ }
1679
+ if (activeLease && activeLease.token !== ownedToken && activeLease.expiresAt > now) {
1680
+ busy = true;
1681
+ return;
1682
+ }
1683
+ const applied = apply(current, ownedToken);
1684
+ result = applied.result;
1685
+ return applied.next;
1686
+ }, ttlMs == null ? void 0 : { ttlMs });
1687
+ if (leaseLost) {
1688
+ const failure = bindingLeaseLostError(key);
1689
+ if (ownedLease) ownedLease.failure = failure;
1690
+ throw failure;
1691
+ }
1692
+ if (!busy) return result;
1693
+ if (Date.now() >= deadline) throw new Error(`Timed out waiting for Codex binding lease: ${key}`);
1694
+ await sleep(BINDING_LEASE_RETRY_INTERVAL_MS);
1695
+ }
1696
+ };
1697
+ return {
1698
+ async read(identity) {
1699
+ const key = bindingStoreKey(identity);
1700
+ const raw = state.lookup(key);
1701
+ const stored = readStoredCodexAppServerBinding(raw);
1702
+ if (raw !== void 0 && !stored) throw new Error(`Invalid Codex app-server binding row: ${key}`);
1703
+ return stored?.state === "active" && ownsStoredSessionGeneration(identity, stored) ? stored.binding : void 0;
1704
+ },
1705
+ async hasOtherThreadOwner(threadId, currentIdentity) {
1706
+ const currentKey = currentIdentity ? bindingStoreKey(currentIdentity) : void 0;
1707
+ return state.entries().some(({ key, value }) => {
1708
+ const stored = readStoredCodexAppServerBinding(value);
1709
+ if (!stored) throw new Error(`Invalid Codex app-server binding row: ${key}`);
1710
+ const isCurrentOwner = currentIdentity !== void 0 && key === currentKey && (currentIdentity.kind === "conversation" || stored.sessionId === currentIdentity.sessionId.trim());
1711
+ if (stored.state !== "active" || stored.binding.threadId !== threadId || isCurrentOwner) return false;
1712
+ return true;
1713
+ });
1714
+ },
1715
+ async prepareSessionGenerationReclaim(identity) {
1716
+ const key = bindingStoreKey(identity);
1717
+ const raw = state.lookup(key);
1718
+ const current = readStoredCodexAppServerBinding(raw);
1719
+ if (raw !== void 0 && !current) throw new Error(`Invalid Codex app-server binding row: ${key}`);
1720
+ if (!current) return {
1721
+ kind: "resolved",
1722
+ result: true
1723
+ };
1724
+ const currentSessionId = current.sessionId;
1725
+ if (!currentSessionId || currentSessionId === identity.sessionId) return {
1726
+ kind: "resolved",
1727
+ result: current.state !== "cleared" || current.retired !== true
1728
+ };
1729
+ return {
1730
+ kind: "verify",
1731
+ expectedPreviousSessionId: currentSessionId
1732
+ };
1733
+ },
1734
+ async mutate(identity, mutation) {
1735
+ return await runBindingMutation(async () => {
1736
+ const key = bindingStoreKey(identity);
1737
+ const retainLegacyClear = mutation.kind === "clear" && key.startsWith("conversation:legacy-");
1738
+ return await transactKey(key, (current, leaseToken) => {
1739
+ const ownsGeneration = ownsStoredSessionGeneration(identity, current);
1740
+ const ownedLease = current?.lease && current.lease.token === leaseToken ? { lease: current.lease } : {};
1741
+ if (mutation.kind === "reclaim-generation") {
1742
+ if (identity.kind !== "session" || !identity.sessionKey?.trim()) return { result: false };
1743
+ if (!current) return { result: true };
1744
+ if (ownsGeneration) return { result: current.state !== "cleared" || current.retired !== true };
1745
+ if (current.sessionId !== mutation.expectedPreviousSessionId) return { result: false };
1746
+ if (current.state === "active" && current.binding.connectionScope === "supervision") return { result: false };
1747
+ return {
1748
+ result: true,
1749
+ next: {
1750
+ version: 1,
1751
+ state: "cleared",
1752
+ sessionId: identity.sessionId,
1753
+ ...ownedLease
1754
+ }
1755
+ };
1756
+ }
1757
+ const storedActive = current?.state === "active" ? current : void 0;
1758
+ const active = ownsGeneration ? storedActive : void 0;
1759
+ const retiredGeneration = current?.state === "cleared" && current.retired === true && ownsGeneration;
1760
+ const preservesSupervisionOwner = mutation.kind === "set" && active?.binding.connectionScope === "supervision" && isSameSupervisionOwner(active.binding, mutation.binding);
1761
+ const clearsPendingSupervisionOwner = mutation.kind === "clear" && active?.binding.connectionScope === "supervision" && matchesPendingSupervisionClear(active.binding, mutation.threadId, mutation.expectedPendingSupervisionBranch);
1762
+ if (mutation.kind === "set" && (mutation.if?.kind === "absent" && storedActive || current !== void 0 && !ownsGeneration || retiredGeneration || active?.binding.connectionScope === "supervision" && !preservesSupervisionOwner) || mutation.kind === "patch" && active?.binding.threadId !== mutation.threadId || (mutation.kind === "patch-pending-supervision-branch" || mutation.kind === "commit-pending-supervision-branch") && !matchesPendingSupervisionBranch(active?.binding, mutation.expected) || mutation.kind === "clear" && (mutation.threadId !== void 0 && active?.binding.threadId !== mutation.threadId || !ownsGeneration || active?.binding.connectionScope === "supervision" && !clearsPendingSupervisionOwner)) return { result: false };
1763
+ if (mutation.kind === "clear" && retiredGeneration) return { result: true };
1764
+ if (mutation.kind === "clear") return {
1765
+ result: true,
1766
+ next: {
1767
+ version: 1,
1768
+ state: "cleared",
1769
+ ...storedSessionGeneration(identity, current),
1770
+ ...ownedLease
1771
+ }
1772
+ };
1773
+ let binding;
1774
+ if (mutation.kind === "set") binding = validateBindingForWrite(mutation.binding);
1775
+ else if (mutation.kind === "patch-pending-supervision-branch") binding = validateBindingForWrite({
1776
+ ...active.binding,
1777
+ pendingSupervisionBranch: mutation.pending
1778
+ });
1779
+ else if (mutation.kind === "commit-pending-supervision-branch") binding = validateBindingForWrite({
1780
+ ...active.binding,
1781
+ ...mutation.patch,
1782
+ threadId: mutation.threadId,
1783
+ pendingSupervisionBranch: void 0
1784
+ });
1785
+ else binding = validateBindingForWrite({
1786
+ ...active.binding,
1787
+ ...mutation.patch,
1788
+ threadId: mutation.threadId
1789
+ });
1790
+ return {
1791
+ result: true,
1792
+ next: {
1793
+ version: 1,
1794
+ state: "active",
1795
+ binding,
1796
+ ...storedSessionGeneration(identity, current),
1797
+ ...ownedLease
1798
+ }
1799
+ };
1800
+ }, mutation.kind === "clear" && !retainLegacyClear && !leaseContext.getStore()?.has(key) ? 1 : void 0);
1801
+ });
1802
+ },
1803
+ async adoptSessionGeneration(identity, expectedPreviousSessionId) {
1804
+ return await runBindingMutation(async () => {
1805
+ const key = bindingStoreKey(identity);
1806
+ const expectedSessionId = expectedPreviousSessionId.trim();
1807
+ const targetSessionId = identity.sessionId.trim();
1808
+ if (!expectedSessionId) throw new Error("Codex session generation adoption requires the previous session id");
1809
+ return await transactKey(key, (current) => {
1810
+ if (current?.state !== "active") return { result: "absent" };
1811
+ if (current.sessionId === targetSessionId) return { result: "current" };
1812
+ if (current.sessionId !== expectedSessionId) return { result: "conflict" };
1813
+ return {
1814
+ result: "adopted",
1815
+ next: {
1816
+ ...current,
1817
+ sessionId: targetSessionId
1818
+ }
1819
+ };
1820
+ });
1821
+ });
1822
+ },
1823
+ async retireSessionGeneration(identity) {
1824
+ return await runBindingMutation(async () => {
1825
+ const key = bindingStoreKey(identity);
1826
+ return await transactKey(key, (current, leaseToken) => {
1827
+ if (!current) return { result: "absent" };
1828
+ if (!ownsStoredSessionGeneration(identity, current)) return { result: "conflict" };
1829
+ if (current.state === "cleared" && current.retired === true) return { result: "applied" };
1830
+ return {
1831
+ result: "applied",
1832
+ next: {
1833
+ version: 1,
1834
+ state: "cleared",
1835
+ retired: true,
1836
+ ...storedSessionGeneration(identity, current),
1837
+ ...current.lease && current.lease.token === leaseToken ? { lease: current.lease } : {}
1838
+ }
1839
+ };
1840
+ }, identity.sessionKey?.trim() ? void 0 : PHYSICAL_SESSION_RETIRE_TTL_MS);
1841
+ });
1842
+ },
1843
+ async withThreadArchiveFence(run) {
1844
+ pendingArchives += 1;
1845
+ const operation = archiveTail.then(async () => {
1846
+ await waitForBindingMutations();
1847
+ return await archiveContext.run(true, run);
1848
+ });
1849
+ archiveTail = operation.then(() => void 0, () => void 0);
1850
+ try {
1851
+ return await operation;
1852
+ } finally {
1853
+ pendingArchives -= 1;
1854
+ }
1855
+ },
1856
+ async withLease(identity, run) {
1857
+ const key = bindingStoreKey(identity);
1858
+ const owned = leaseContext.getStore();
1859
+ const existingOwner = owned?.get(key);
1860
+ if (existingOwner) {
1861
+ const failureBeforeRun = existingOwner.failure;
1862
+ if (failureBeforeRun) throw failureBeforeRun;
1863
+ const result = await run();
1864
+ const failureAfterRun = existingOwner.failure;
1865
+ if (failureAfterRun) throw failureAfterRun;
1866
+ return result;
1867
+ }
1868
+ const token = randomUUID();
1869
+ if (!await transactKey(key, (current) => {
1870
+ if (current?.state === "cleared" && current.retired === true && ownsStoredSessionGeneration(identity, current)) return { result: false };
1871
+ const lease = {
1872
+ token,
1873
+ expiresAt: Date.now() + BINDING_LEASE_STALE_MS
1874
+ };
1875
+ if (current?.state === "active") return {
1876
+ result: true,
1877
+ next: {
1878
+ ...current,
1879
+ ...preservedSessionGeneration(identity, current),
1880
+ lease
1881
+ }
1882
+ };
1883
+ if (current?.state === "cleared" && current.retired === true) return {
1884
+ result: true,
1885
+ next: {
1886
+ ...current,
1887
+ lease
1888
+ }
1889
+ };
1890
+ return {
1891
+ result: true,
1892
+ next: {
1893
+ version: 1,
1894
+ state: "cleared",
1895
+ ...preservedSessionGeneration(identity, current),
1896
+ lease
1897
+ }
1898
+ };
1899
+ })) throw new Error(`Codex binding generation was retired: ${key}`);
1900
+ const owner = { token };
1901
+ const nested = new Map(owned);
1902
+ nested.set(key, owner);
1903
+ const heartbeat = setInterval(() => renewLease(key, owner), BINDING_LEASE_RENEW_INTERVAL_MS);
1904
+ heartbeat.unref();
1905
+ try {
1906
+ const result = await leaseContext.run(nested, run);
1907
+ if (owner.failure) throw owner.failure;
1908
+ return result;
1909
+ } finally {
1910
+ clearInterval(heartbeat);
1911
+ try {
1912
+ const removeOwnedLease = (raw, matches) => {
1913
+ const current = readStoredCodexAppServerBinding(raw);
1914
+ if (!current || !matches(current) || current.lease?.token !== token) return;
1915
+ const { lease: _lease, ...released } = current;
1916
+ return released;
1917
+ };
1918
+ if (!update(key, (raw) => removeOwnedLease(raw, (current) => current.state === "active"))) {
1919
+ if (!update(key, (raw) => removeOwnedLease(raw, (current) => current.state === "cleared" && current.retired === true), key.startsWith("session:") ? { ttlMs: PHYSICAL_SESSION_RETIRE_TTL_MS } : void 0)) update(key, (raw) => removeOwnedLease(raw, (current) => current.state === "cleared"), { ttlMs: 1 });
1920
+ }
1921
+ } catch (error) {
1922
+ embeddedAgentLog.warn("failed to release codex app-server binding lease", {
1923
+ key,
1924
+ error
1925
+ });
1926
+ }
1927
+ }
1928
+ }
1929
+ };
1930
+ }
1931
+ function matchesPendingSupervisionBranch(binding, expected) {
1932
+ const pending = binding?.pendingSupervisionBranch;
1933
+ if (!pending || binding?.threadId !== expected.sourceThreadId) return false;
1934
+ if (pending.sourceThreadId !== expected.sourceThreadId || pending.connectionFingerprint !== expected.connectionFingerprint || pending.lastTurnId !== expected.lastTurnId) return false;
1935
+ const currentCleanup = pending.cleanupThreadIds ?? [];
1936
+ const expectedCleanup = expected.cleanupThreadIds ?? [];
1937
+ return currentCleanup.length === expectedCleanup.length && currentCleanup.every((threadId, index) => threadId === expectedCleanup[index]);
1938
+ }
1939
+ function isSameSupervisionOwner(current, replacement) {
1940
+ return replacement.connectionScope === "supervision" && replacement.threadId === current.threadId && replacement.supervisionSourceThreadId === current.supervisionSourceThreadId;
1941
+ }
1942
+ function matchesPendingSupervisionClear(binding, threadId, expected) {
1943
+ if (!expected) return false;
1944
+ const sourceThreadId = expected.sourceThreadId;
1945
+ return threadId === sourceThreadId && binding.supervisionSourceThreadId === sourceThreadId && matchesPendingSupervisionBranch(binding, expected);
1946
+ }
1947
+ /** Stable plugin-state key for one current binding owner. */
1948
+ function bindingStoreKey(identity) {
1949
+ if (identity.kind === "session") {
1950
+ const rawAgentId = identity.agentId.trim();
1951
+ const sessionId = identity.sessionId.trim();
1952
+ if (!rawAgentId) throw new Error("Codex app-server binding requires an agent id");
1953
+ if (!sessionId) throw new Error("Codex app-server binding requires a session id");
1954
+ const agentId = resolveSessionAgentIds({ agentId: rawAgentId }).sessionAgentId;
1955
+ const sessionKey = identity.sessionKey?.trim();
1956
+ if (sessionKey) return `session-key:${agentId}:${createHash("sha256").update(sessionKey).digest("base64url")}`;
1957
+ return `session:${agentId}:${sessionId}`;
1958
+ }
1959
+ const bindingId = identity.bindingId.trim();
1960
+ if (!bindingId) throw new Error("Codex app-server conversation binding requires a binding id");
1961
+ return `conversation:${bindingId}`;
1962
+ }
1963
+ function readStoredCodexAppServerBinding(value) {
1964
+ const result = storedBindingSchema.safeParse(value);
1965
+ return result.success ? stripUndefinedValue(result.data) : void 0;
1966
+ }
1967
+ function storedSessionGeneration(identity, current) {
1968
+ if (identity.kind === "session") return { sessionId: identity.sessionId };
1969
+ return current?.sessionId ? { sessionId: current.sessionId } : {};
1970
+ }
1971
+ function preservedSessionGeneration(identity, current) {
1972
+ if (current?.sessionId) return { sessionId: current.sessionId };
1973
+ return storedSessionGeneration(identity, current);
1974
+ }
1975
+ function ownsStoredSessionGeneration(identity, current) {
1976
+ return identity.kind !== "session" || !current?.sessionId || current.sessionId === identity.sessionId;
1977
+ }
1978
+ function validateBindingForWrite(binding) {
1979
+ const validated = readCodexAppServerThreadBinding(binding);
1980
+ if (!validated) throw new Error("Invalid Codex app-server thread binding");
1981
+ return stripUndefinedBinding(validated);
1982
+ }
1983
+ /** Parses stored or shipped sidecar data into the current domain value. */
1984
+ function readCodexAppServerThreadBinding(value) {
1985
+ const result = threadBindingSchema.safeParse(value);
1986
+ if (!result.success) return;
1987
+ return result.data;
1988
+ }
1989
+ function stripUndefinedBinding(binding) {
1990
+ return stripUndefinedValue(binding);
1991
+ }
1992
+ function stripUndefinedValue(value) {
1993
+ if (Array.isArray(value)) return value.map(stripUndefinedValue);
1994
+ if (!value || typeof value !== "object") return value;
1995
+ return Object.fromEntries(Object.entries(value).filter(([, entry]) => entry !== void 0).map(([key, entry]) => [key, stripUndefinedValue(entry)]));
1996
+ }
1997
+ function asRecord(value) {
1998
+ return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
1999
+ }
2000
+ function readTimestamp(value) {
2001
+ return optionalTimestampSchema.parse(value);
2002
+ }
2003
+ function readPluginAppPolicyContext(value, bindingSchemaVersion) {
2004
+ const record = asRecord(value);
2005
+ if (!record || typeof record.fingerprint !== "string") return;
2006
+ const apps = asRecord(record.apps);
2007
+ if (!apps) return;
2008
+ const parsedApps = {};
2009
+ for (const [appId, rawEntry] of Object.entries(apps)) {
2010
+ const entry = asRecord(rawEntry);
2011
+ if (!entry) return;
2012
+ const destructiveApprovalMode = readDestructiveApprovalMode(entry.destructiveApprovalMode, bindingSchemaVersion);
2013
+ const mcpServerNamesValid = Array.isArray(entry.mcpServerNames) && entry.mcpServerNames.every((serverName) => typeof serverName === "string");
2014
+ if (entry.source === "account") {
2015
+ if ("appId" in entry || typeof entry.appName !== "string" || typeof entry.allowDestructiveActions !== "boolean" || destructiveApprovalMode === "invalid" || !mcpServerNamesValid) return;
2016
+ parsedApps[appId] = {
2017
+ source: "account",
2018
+ appName: entry.appName,
2019
+ allowDestructiveActions: entry.allowDestructiveActions,
2020
+ ...destructiveApprovalMode ? { destructiveApprovalMode } : {},
2021
+ mcpServerNames: entry.mcpServerNames
2022
+ };
2023
+ continue;
2024
+ }
2025
+ if ("appId" in entry || entry.source !== void 0 && entry.source !== "plugin" || typeof entry.configKey !== "string" || entry.marketplaceName !== "openai-curated" && entry.marketplaceName !== "workspace-directory" || typeof entry.pluginName !== "string" || typeof entry.allowDestructiveActions !== "boolean" || destructiveApprovalMode === "invalid" || !mcpServerNamesValid) return;
2026
+ parsedApps[appId] = {
2027
+ configKey: entry.configKey,
2028
+ marketplaceName: entry.marketplaceName,
2029
+ pluginName: entry.pluginName,
2030
+ allowDestructiveActions: entry.allowDestructiveActions,
2031
+ ...destructiveApprovalMode ? { destructiveApprovalMode } : {},
2032
+ mcpServerNames: entry.mcpServerNames
2033
+ };
2034
+ }
2035
+ const parsedPluginAppIds = {};
2036
+ if (record.pluginAppIds !== void 0 && (!record.pluginAppIds || typeof record.pluginAppIds !== "object" || Array.isArray(record.pluginAppIds))) return;
2037
+ if (record.pluginAppIds && typeof record.pluginAppIds === "object") for (const [configKey, appIds] of Object.entries(record.pluginAppIds)) {
2038
+ if (!Array.isArray(appIds) || appIds.some((appId) => typeof appId !== "string")) return;
2039
+ parsedPluginAppIds[configKey] = appIds;
2040
+ }
2041
+ return {
2042
+ fingerprint: record.fingerprint,
2043
+ apps: parsedApps,
2044
+ pluginAppIds: parsedPluginAppIds
2045
+ };
2046
+ }
2047
+ function readDestructiveApprovalMode(value, bindingSchemaVersion) {
2048
+ if (value === void 0) return;
2049
+ if (value === "allow" || value === "deny") return value;
2050
+ if (value === "auto") return bindingSchemaVersion === 1 ? "allow" : "auto";
2051
+ if (value === "ask" && bindingSchemaVersion === 2) return "ask";
2052
+ if (value === "on-request" && bindingSchemaVersion === 1) return "auto";
2053
+ return "invalid";
2054
+ }
2055
+ function sleep(ms) {
2056
+ return new Promise((resolve) => {
2057
+ setTimeout(resolve, ms);
2058
+ });
2059
+ }
2060
+ /** Returns true when an auth profile uses native Codex/OpenAI app-server auth. */
2061
+ function isCodexAppServerNativeAuthProfile(lookup) {
2062
+ const authProfileId = lookup.authProfileId?.trim();
2063
+ if (!authProfileId) return false;
2064
+ try {
2065
+ const credential = (lookup.authProfileStore ?? ensureAuthProfileStore(lookup.agentDir?.trim() || resolveDefaultAgentDir(lookup.config ?? {}), {
2066
+ allowKeychainPrompt: false,
2067
+ config: lookup.config,
2068
+ externalCliProviderIds: [CODEX_APP_SERVER_NATIVE_AUTH_PROVIDER],
2069
+ externalCliProfileIds: [authProfileId]
2070
+ })).profiles[authProfileId];
2071
+ if (!credential || credential.type === "api_key") return false;
2072
+ const provider = credential.provider?.trim();
2073
+ return Boolean(provider && resolveProviderIdForAuth(provider, { config: lookup.config }) === CODEX_APP_SERVER_NATIVE_AUTH_PROVIDER);
2074
+ } catch (error) {
2075
+ embeddedAgentLog.debug("failed to resolve codex app-server auth profile provider", {
2076
+ authProfileId,
2077
+ error
2078
+ });
2079
+ return false;
2080
+ }
2081
+ }
2082
+ /** Hides redundant OpenAI provider attribution for native Codex auth bindings. */
2083
+ function normalizeCodexAppServerBindingModelProvider(params) {
2084
+ const modelProvider = params.modelProvider?.trim();
2085
+ if (!modelProvider) return;
2086
+ if (isCodexAppServerNativeAuthProfile(params) && modelProvider.toLowerCase() === PUBLIC_OPENAI_MODEL_PROVIDER) return;
2087
+ return modelProvider;
2088
+ }
2089
+ /** Restores the sole provider intentionally omitted from canonical binding rows. */
2090
+ function resolveCodexAppServerBindingModelProvider(params) {
2091
+ return params.modelProvider?.trim() || (isCodexAppServerNativeAuthProfile(params) ? PUBLIC_OPENAI_MODEL_PROVIDER : void 0);
2092
+ }
2093
+ //#endregion
2094
+ export { resolveCodexComputerUseConfig as C, resolveOpenClawExecPolicyForCodexAppServer as D, resolveCodexSupervisionAppServerRuntimeOptions as E, shouldAutoApproveCodexAppServerApprovals as O, resolveCodexAppServerUserHomeDir as S, resolveCodexPluginsPolicy as T, isCodexFastServiceTier as _, isCodexAppServerNativeAuthProfile as a, resolveCodexAppServerRuntimeOptions as b, sessionBindingIdentity as c, CODEX_PLUGINS_WORKSPACE_MARKETPLACE_NAME as d, assertCodexAppServerConnectionSecurity as f, isCodexAppServerApprovalPolicyAllowedByRequirements as g, codexSandboxPolicyForTurn as h, hashCodexAppServerBindingFingerprint as i, withMcpElicitationsApprovalPolicy as k, session_binding_exports as l, codexAppServerStartOptionsKey as m, assertCodexBindingMayBeReplaced as n, normalizeCodexAppServerBindingModelProvider as o, canUseCodexModelBackedApprovalsReviewerForModel as p, bindingStoreKey as r, reclaimCurrentCodexSessionGeneration as s, CODEX_APP_SERVER_BINDING_GUARDED_REQUEST_TIMEOUT_MS as t, CODEX_PLUGINS_MARKETPLACE_NAME as u, isCodexSandboxExecServerEnabled as v, resolveCodexModelBackedReviewerPolicyContext as w, resolveCodexAppServerStartOptionsForAgent as x, readCodexPluginConfig as y };