@openclaw/codex 2026.9.1 → 2026.9.2

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 (67) hide show
  1. package/dist/api.js +6 -6
  2. package/dist/{attempt-client-cleanup-DYHcRQAa.js → attempt-client-cleanup-Bp1ZOnk2.js} +76 -32
  3. package/dist/{attempt-context-DmQUNWwT.js → attempt-context-CSazkWns.js} +6 -6
  4. package/dist/{bounded-turn-wzJrwKKe.js → bounded-turn-DxGJRYbY.js} +46 -45
  5. package/dist/{capabilities-dIjNVCYH.js → capabilities-B1mgvpP8.js} +2 -1
  6. package/dist/cli-metadata.js +1 -1
  7. package/dist/{command-formatters-CLHhEB1Q.js → command-formatters-DSbGMXA0.js} +2 -2
  8. package/dist/{command-handlers-CTGb2csu.js → command-handlers-DOJvGv6-.js} +146 -74
  9. package/dist/{compact-_t0HQrUS.js → compact-Y_xBqrHN.js} +83 -48
  10. package/dist/{config-BhmfC1s6.js → config-CyapYSji.js} +47 -105
  11. package/dist/config-utils-C57JiJrU.js +69 -0
  12. package/dist/doctor-contract-api.js +4 -5
  13. package/dist/{dynamic-tools-BU9tmlYm.js → dynamic-tools-BwpvTxaX.js} +678 -638
  14. package/dist/{effective-mcp-catalog-DzYBW4h1.js → effective-mcp-catalog-CY9Jn4bA.js} +4 -3
  15. package/dist/{event-projector-assistant-message-DHRFXKbS.js → event-projector-assistant-message-B9kp6iGC.js} +11 -2
  16. package/dist/{event-projector-usage-C5mcrGjp.js → event-projector-usage-ZqEVbAEY.js} +30 -13
  17. package/dist/{harness-DXVZ5II5.js → harness-Czh2Sdoc.js} +36 -13
  18. package/dist/harness.js +1 -1
  19. package/dist/{image-payload-sanitizer-CnfoUPCE.js → image-payload-sanitizer-tupAr-2o.js} +29 -15
  20. package/dist/index.js +68 -84
  21. package/dist/{isolated-completion-kg9kv4iH.js → isolated-completion-CRh-51AK.js} +9 -21
  22. package/dist/{managed-binary-4-Vjz5GH.js → managed-binary-DcpnJF9x.js} +105 -73
  23. package/dist/media-understanding-provider.js +1 -1
  24. package/dist/{model-catalog-CUM68Hkl.js → model-catalog-DT5vo6qo.js} +5 -5
  25. package/dist/{models-sYnEc0gd.js → models-CcrgSMQR.js} +4 -4
  26. package/dist/{native-subagent-monitor-CnH147jH.js → native-subagent-monitor-B3bvQGcg.js} +12 -11
  27. package/dist/{node-exec-server.runtime-CstNHCmC.js → node-exec-server.runtime-nfbUOtUB.js} +3 -3
  28. package/dist/{plugin-approval-roundtrip-CNe-Xrjx.js → plugin-approval-roundtrip-aQVdyL5g.js} +1 -1
  29. package/dist/{plugin-marketplace-discovery-CfFlKqDl.js → plugin-marketplace-discovery-B7gHXJ3d.js} +35 -22
  30. package/dist/{plugin-metadata-cache-BFrPhb2c.js → plugin-metadata-cache-BwCLTY_U.js} +5 -5
  31. package/dist/{provider-capabilities-DW5p4k9w.js → provider-capabilities-BpG9Ltc5.js} +2 -2
  32. package/dist/{rate-limits-CawQJfUS.js → rate-limits-Fx_l4eNa.js} +1 -1
  33. package/dist/{request-DYAI5FQE.js → request-C8H22rPi.js} +2 -2
  34. package/dist/{run-attempt-D1hJO4fX.js → run-attempt-BzthFQSM.js} +977 -723
  35. package/dist/{runtime-artifact-C3jVimFn.js → runtime-artifact-Bh_gf6-t.js} +3 -3
  36. package/dist/{session-binding-BHuTCRZQ.js → session-binding-4Ki04sW-.js} +94 -282
  37. package/dist/session-binding-record-CyaXZvTe.js +270 -0
  38. package/dist/{session-catalog-yyvTWFOw.js → session-catalog-B47uwekb.js} +266 -114
  39. package/dist/{session-cli-CmFEXMAM.js → session-cli-BjLhpmS1.js} +1 -1
  40. package/dist/session-history-DWmMqiqW.js +93 -0
  41. package/dist/session-history-read-LHldwvyh.js +36 -0
  42. package/dist/session-history-worker-runtime.js +48 -0
  43. package/dist/{settled-turn-context-D3SNWtUn.js → session-history.worker-zZVcx0ME.js} +30 -31
  44. package/dist/session-history.worker.js +2 -0
  45. package/dist/{session-initialization-BeWzjGiR.js → session-initialization-BCFVnLL4.js} +2 -1
  46. package/dist/{session-permission-policy-DeWVTCMj.js → session-permission-policy-BaueHmSj.js} +1 -1
  47. package/dist/{session-retirement-BujDjXVF.js → session-retirement-DNdmYdFc.js} +7 -7
  48. package/dist/{session-upstream-marker-C351-5Qw.js → session-upstream-marker-DReTpGz6.js} +4 -3
  49. package/dist/settled-turn-context-BOM3Y1pl.js +45 -0
  50. package/dist/{settled-turn-finalizer-BVJx4yoc.js → settled-turn-finalizer-BI-b1sry.js} +53 -42
  51. package/dist/{shared-client-DxcfF9KX.js → shared-client-CKhX2kFt.js} +279 -268
  52. package/dist/{side-question-BTZAII4l.js → side-question-B6DWAw1A.js} +85 -36
  53. package/dist/{thread-lifecycle-DAcEJ_Om.js → thread-lifecycle-DPK30jad.js} +382 -388
  54. package/dist/{thread-ownership-zGokd8i1.js → thread-ownership-CbucAmmp.js} +5 -5
  55. package/dist/thread-policy-CTalhWFy.js +105 -0
  56. package/dist/{thread-resume-C7pyVKeW.js → thread-resume-BLgqkUc1.js} +7 -7
  57. package/dist/{transcript-mirror-DTUxFWa_.js → transcript-mirror-_njEB84z.js} +67 -125
  58. package/dist/transcript-mirror-attestation-Byl34PC-.js +76 -0
  59. package/dist/{transport-stdio-CyPldczm.js → transport-stdio-CzTngV0j.js} +10 -8
  60. package/dist/{upstream-session-fork-CYlBIGVt.js → upstream-session-fork-1fwbNKzQ.js} +85 -165
  61. package/dist/{usage-Bj-rrzkR.js → usage-i9fv5-4m.js} +3 -3
  62. package/dist/{web-search-provider.runtime-D2FWSK4w.js → web-search-provider.runtime-DKQn67A7.js} +3 -3
  63. package/package.json +6 -6
  64. package/dist/binding-connection-E6uDsPlx.js +0 -45
  65. package/dist/launch-args-RXQwn8zV.js +0 -90
  66. package/dist/session-history-C5J1AKzG.js +0 -87
  67. package/dist/thread-policy-g4KbJPzp.js +0 -54
@@ -1,9 +1,9 @@
1
- import { i as resolvePackagedCodexNativeCommand } from "./managed-binary-4-Vjz5GH.js";
2
- import { n as resolveCodexAppServerSpawnEnv } from "./transport-stdio-CyPldczm.js";
1
+ import { i as resolvePackagedCodexNativeCommand } from "./managed-binary-DcpnJF9x.js";
2
+ import { n as resolveCodexAppServerSpawnEnv } from "./transport-stdio-CzTngV0j.js";
3
+ import { createHash } from "node:crypto";
3
4
  import fs from "node:fs/promises";
4
5
  import path from "node:path";
5
6
  import { isPathInside } from "openclaw/plugin-sdk/file-access-runtime";
6
- import { createHash } from "node:crypto";
7
7
  import { constants } from "node:fs";
8
8
  import { resolveWindowsExecutablePath, resolveWindowsSpawnProgram } from "openclaw/plugin-sdk/windows-spawn";
9
9
  //#region extensions/codex/src/app-server/runtime-artifact.ts
@@ -1,15 +1,13 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
2
- import { P as CODEX_PLUGIN_MARKETPLACE_NAME_PATTERN, j as normalizeCodexServiceTier } from "./config-BhmfC1s6.js";
2
+ import { g as CODEX_PLUGIN_MARKETPLACE_NAME_PATTERN } from "./config-utils-C57JiJrU.js";
3
+ import { a as readCodexBindingTimestamp, c as readStoredCodexAppServerBinding, d as validateBindingForWrite, i as readCodexBindingSessionEntry, l as sessionBindingIdentity, n as ownsStoredSessionGeneration, o as readCodexSessionOwnershipBinding, r as readCodexAppServerThreadBinding, s as readCurrentCodexAppServerBinding, t as bindingStoreKey, u as stripUndefinedBinding } from "./session-binding-record-CyaXZvTe.js";
3
4
  import { n as CODEX_APP_SERVER_BINDING_NAMESPACE, t as CODEX_APP_SERVER_BINDING_MAX_ENTRIES } from "./session-binding-meta-B7aEMU7g.js";
4
5
  import { asOptionalRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
5
- import { AgentHarnessSessionSupersededError, embeddedAgentLog } from "openclaw/plugin-sdk/agent-harness-runtime";
6
6
  import { createHash, randomUUID } from "node:crypto";
7
+ import { AgentHarnessPreflightError, AgentHarnessSessionSupersededError, embeddedAgentLog } from "openclaw/plugin-sdk/agent-harness-runtime";
7
8
  import { isDeepStrictEqual } from "node:util";
8
9
  import { ensureAuthProfileStore, resolveDefaultAgentDir, resolveProviderIdForAuth } from "openclaw/plugin-sdk/agent-runtime";
9
- import { resolveSessionAgentIdsStrict } from "openclaw/plugin-sdk/agent-scope-runtime";
10
- import { z } from "zod";
11
10
  import { AsyncLocalStorage } from "node:async_hooks";
12
- import { getSessionEntry, resolveStorePath } from "openclaw/plugin-sdk/session-store-runtime";
13
11
  //#region extensions/codex/src/app-server/session-binding.ts
14
12
  /** SQLite-backed Codex app-server thread bindings. */
15
13
  var session_binding_exports = /* @__PURE__ */ __exportAll({
@@ -30,6 +28,7 @@ var session_binding_exports = /* @__PURE__ */ __exportAll({
30
28
  readStoredCodexAppServerBinding: () => readStoredCodexAppServerBinding,
31
29
  reclaimCurrentCodexSessionGeneration: () => reclaimCurrentCodexSessionGeneration,
32
30
  resolveCodexRunSessionBindingAuthority: () => resolveCodexRunSessionBindingAuthority,
31
+ resolveCodexSessionBinding: () => resolveCodexSessionBinding,
33
32
  scopeCodexRunBindingStore: () => scopeCodexRunBindingStore,
34
33
  sessionBindingIdentity: () => sessionBindingIdentity,
35
34
  validateBindingForWrite: () => validateBindingForWrite
@@ -43,221 +42,52 @@ const BINDING_LEASE_STALE_MS = 65e3;
43
42
  const BINDING_LEASE_WAIT_MS = 7e4;
44
43
  const BINDING_LEASE_RENEW_INTERVAL_MS = Math.floor(BINDING_LEASE_STALE_MS / 3);
45
44
  const PHYSICAL_SESSION_RETIRE_TTL_MS = BINDING_LEASE_WAIT_MS;
46
- /** Resolves the same agent scope OpenClaw uses for transcript/session ownership. */
47
- function sessionBindingIdentity(params) {
48
- const { sessionAgentId } = resolveSessionAgentIdsStrict(params);
49
- const sessionKey = params.sessionKey?.trim();
50
- return {
51
- kind: "session",
52
- agentId: sessionAgentId,
53
- sessionId: params.sessionId,
54
- ...sessionKey ? { sessionKey } : {}
55
- };
56
- }
57
45
  /** Decides whether a run may share the durable stable-key binding owner. */
58
46
  function resolveCodexRunSessionBindingAuthority(params) {
59
- const sessionKey = params.identity.sessionKey?.trim();
60
- if (!sessionKey) return "ephemeral";
61
- try {
62
- const storePath = params.storePath?.trim() || resolveStorePath(params.config?.session?.store, { agentId: params.identity.agentId });
63
- const entry = getSessionEntry({
64
- agentId: params.identity.agentId,
65
- hydrateSkillPromptRefs: false,
66
- readConsistency: "latest",
67
- sessionKey,
68
- storePath
69
- });
70
- if (!entry) return "ephemeral";
71
- return entry.sessionId === params.identity.sessionId ? "current" : "superseded";
72
- } catch {
73
- return "superseded";
74
- }
47
+ return captureCodexSessionGenerationAuthority(params)[0];
48
+ }
49
+ function captureCodexSessionGenerationAuthority(params, assertCallerCurrent = () => {}) {
50
+ const readEntry = () => {
51
+ try {
52
+ return readCodexBindingSessionEntry(params);
53
+ } catch {
54
+ return null;
55
+ }
56
+ };
57
+ const entry = readEntry();
58
+ const current = entry?.sessionId === params.identity.sessionId;
59
+ const authority = entry === void 0 ? "ephemeral" : current ? "current" : "superseded";
60
+ const previousSessionId = current ? entry.previousSessionId : void 0;
61
+ const assertHostCurrent = () => {
62
+ if (authority === "ephemeral") return;
63
+ const latest = readEntry();
64
+ if (authority !== "current" || !latest || latest.sessionId !== params.identity.sessionId || latest.previousSessionId !== previousSessionId) throw createCodexSessionGenerationSupersededError(params.identity.sessionId);
65
+ };
66
+ const assertCurrent = () => {
67
+ assertCallerCurrent();
68
+ assertHostCurrent();
69
+ };
70
+ return [
71
+ authority,
72
+ previousSessionId,
73
+ assertHostCurrent,
74
+ assertCurrent
75
+ ];
75
76
  }
76
77
  /** Builds the terminal coordination error used when a newer OpenClaw session owns the binding. */
77
78
  function createCodexSessionGenerationSupersededError(sessionId) {
78
79
  return new AgentHarnessSessionSupersededError(`Codex session generation is no longer current: ${sessionId}`);
79
80
  }
80
- const optionalStringSchema = z.string().optional().catch(void 0);
81
- const optionalBooleanSchema = z.boolean().optional().catch(void 0);
82
- const optionalNonBlankStringSchema = z.string().refine((value) => Boolean(value.trim())).optional().catch(void 0);
83
- const optionalTimestampSchema = z.string().refine((value) => Number.isFinite(Date.parse(value))).optional().catch(void 0);
84
- const pendingSupervisionBranchSchema = z.object({
85
- sourceThreadId: z.string().trim().min(1),
86
- connectionFingerprint: z.string().trim().min(1).optional(),
87
- lastTurnId: z.string().trim().min(1).optional(),
88
- cleanupThreadIds: z.array(z.string().trim().min(1)).max(2).optional()
89
- }).strict().superRefine((pending, context) => {
90
- const cleanupThreadIds = pending.cleanupThreadIds ?? [];
91
- if (new Set(cleanupThreadIds).size !== cleanupThreadIds.length) context.addIssue({
92
- code: "custom",
93
- message: "pending supervision cleanup thread ids must be unique"
94
- });
95
- if (cleanupThreadIds.includes(pending.sourceThreadId)) context.addIssue({
96
- code: "custom",
97
- message: "pending supervision cleanup cannot target its source"
98
- });
99
- });
100
- const contextEngineProjectionSchema = z.object({
101
- schemaVersion: z.literal(1),
102
- mode: z.literal("thread_bootstrap"),
103
- epoch: z.string().refine((value) => Boolean(value.trim())),
104
- fingerprint: optionalStringSchema
105
- }).strict();
106
- const contextEngineSchema = z.object({
107
- schemaVersion: z.literal(1),
108
- engineId: z.string(),
109
- policyFingerprint: z.string(),
110
- projection: contextEngineProjectionSchema.optional().catch(void 0)
111
- }).strict();
112
- const destructiveApprovalModeSchema = z.enum([
113
- "allow",
114
- "deny",
115
- "auto",
116
- "ask"
117
- ]).optional().catch(void 0);
118
- const accountAppPolicyEntrySchema = z.object({
119
- source: z.literal("account"),
120
- appName: z.string(),
121
- allowDestructiveActions: z.boolean(),
122
- allowOpenWorld: z.boolean().optional(),
123
- destructiveApprovalMode: destructiveApprovalModeSchema,
124
- mcpServerNames: z.array(z.string())
125
- }).strict();
126
- const pluginAppPolicyEntrySchema = z.object({
127
- source: z.literal("plugin").optional(),
128
- configKey: z.string(),
129
- marketplaceName: z.string().regex(CODEX_PLUGIN_MARKETPLACE_NAME_PATTERN),
130
- pluginName: z.string(),
131
- allowDestructiveActions: z.boolean(),
132
- allowOpenWorld: z.boolean().optional(),
133
- destructiveApprovalMode: destructiveApprovalModeSchema,
134
- mcpServerNames: z.array(z.string())
135
- }).strict();
136
- const pluginAppPolicyContextSchema = z.object({
137
- fingerprint: z.string(),
138
- apps: z.record(z.string(), z.union([accountAppPolicyEntrySchema, pluginAppPolicyEntrySchema])),
139
- pluginAppIds: z.record(z.string(), z.array(z.string())).default({})
140
- }).strict();
141
- const threadBindingSchema = z.object({
142
- threadId: z.string().refine((value) => Boolean(value.trim())),
143
- clientId: optionalStringSchema,
144
- cwd: z.string(),
145
- rolloutPath: optionalNonBlankStringSchema,
146
- connectionScope: z.literal("supervision").optional(),
147
- supervisionSourceThreadId: z.string().trim().min(1).optional(),
148
- authProfileId: optionalStringSchema,
149
- agentWorkspaceDeveloperInstructions: optionalNonBlankStringSchema,
150
- model: optionalStringSchema,
151
- preserveNativeModel: z.literal(true).optional().catch(void 0),
152
- pendingSupervisionBranch: pendingSupervisionBranchSchema.optional(),
153
- pendingResumeConfiguration: z.literal(true).optional(),
154
- modelProvider: z.string().transform((value) => value.trim()).pipe(z.string().min(1)).optional().catch(void 0),
155
- approvalPolicy: z.preprocess((value) => value === "on-failure" ? "on-request" : value, z.enum([
156
- "never",
157
- "on-request",
158
- "untrusted"
159
- ]).optional()).catch(void 0),
160
- sandbox: z.enum([
161
- "read-only",
162
- "workspace-write",
163
- "danger-full-access"
164
- ]).optional().catch(void 0),
165
- serviceTier: z.preprocess(normalizeCodexServiceTier, z.custom((value) => typeof value === "string").optional()).optional().catch(void 0),
166
- networkProxyProfileName: optionalStringSchema,
167
- networkProxyConfigFingerprint: optionalStringSchema,
168
- dynamicToolsFingerprint: optionalStringSchema,
169
- dynamicToolsContainDeferred: optionalBooleanSchema,
170
- webSearchThreadConfigFingerprint: optionalStringSchema,
171
- nativeSkillIsolationFingerprint: optionalStringSchema,
172
- userMcpServersFingerprint: optionalStringSchema,
173
- mcpServersFingerprint: optionalStringSchema,
174
- configuredMcpOwnershipVersion: z.literal(1).optional().catch(void 0),
175
- ringZeroConfigFingerprint: optionalStringSchema,
176
- ringZeroClientInstanceId: optionalStringSchema,
177
- /** Durable fact preventing a later unrestricted turn from widening this thread. */
178
- nativeToolPolicyRestricted: z.literal(true).optional().catch(void 0),
179
- nativeHookRelayGeneration: optionalNonBlankStringSchema,
180
- appServerRuntimeFingerprint: optionalStringSchema,
181
- pluginAppsFingerprint: optionalStringSchema,
182
- pluginAppsInputFingerprint: optionalStringSchema,
183
- pluginAppPolicyContext: pluginAppPolicyContextSchema.optional().catch(void 0),
184
- contextEngine: contextEngineSchema.optional().catch(void 0),
185
- environmentSelectionFingerprint: optionalStringSchema,
186
- conversationStartId: optionalStringSchema,
187
- conversationSourceTransferComplete: z.literal(true).optional().catch(void 0),
188
- historyCoveredThrough: optionalTimestampSchema,
189
- continuityCalibration: z.object({
190
- promptChars: z.number().int().positive(),
191
- inputTokens: z.number().int().positive()
192
- }).optional().catch(void 0)
193
- }).superRefine((binding, context) => {
194
- if (binding.connectionScope === "supervision") {
195
- if (!binding.supervisionSourceThreadId) context.addIssue({
196
- code: "custom",
197
- message: "supervision connection ownership requires its native source thread id"
198
- });
199
- if (binding.preserveNativeModel !== true) context.addIssue({
200
- code: "custom",
201
- message: "supervision connection ownership requires native model ownership"
202
- });
203
- if (binding.conversationSourceTransferComplete !== true) context.addIssue({
204
- code: "custom",
205
- message: "supervision connection ownership requires a completed source transfer"
206
- });
207
- if (!binding.pendingSupervisionBranch && (!binding.model?.trim() || !binding.modelProvider)) context.addIssue({
208
- code: "custom",
209
- message: "materialized supervision bindings require a native model and provider"
210
- });
211
- }
212
- if (binding.supervisionSourceThreadId && binding.connectionScope !== "supervision") context.addIssue({
213
- code: "custom",
214
- message: "a supervision source thread id requires supervision connection ownership"
215
- });
216
- if (!binding.pendingSupervisionBranch) return;
217
- if (binding.threadId !== binding.pendingSupervisionBranch.sourceThreadId) context.addIssue({
218
- code: "custom",
219
- message: "pending supervision source must match the provisional thread binding"
220
- });
221
- if (binding.supervisionSourceThreadId !== binding.pendingSupervisionBranch.sourceThreadId) context.addIssue({
222
- code: "custom",
223
- message: "pending supervision source must match its durable source identity"
224
- });
225
- if (binding.preserveNativeModel !== true) context.addIssue({
226
- code: "custom",
227
- message: "pending supervision bindings must defer model selection to Codex App Server"
228
- });
229
- if (binding.connectionScope !== "supervision") context.addIssue({
230
- code: "custom",
231
- message: "pending supervision bindings require supervision connection ownership"
232
- });
233
- });
234
81
  var CodexSupervisionBindingReplacementError = class extends Error {
235
82
  constructor(threadId, operation) {
236
83
  super(`Refusing to replace supervised Codex thread ${threadId} while ${operation}; its native user-home connection and model ownership must be preserved`);
237
84
  this.name = "CodexSupervisionBindingReplacementError";
238
85
  }
239
86
  };
240
- function assertCodexBindingMayBeReplaced(binding, operation) {
87
+ function assertCodexBindingMayBeReplaced(binding, operation, expected) {
88
+ if (expected) throw new AgentHarnessPreflightError(`Codex native model ownership prevents ${operation}. Continue or compact the original session in its native runtime, or create a new chat with a concrete model; the original binding was preserved.`);
241
89
  if (binding?.connectionScope === "supervision") throw new CodexSupervisionBindingReplacementError(binding.threadId, operation);
242
90
  }
243
- const bindingLeaseSchema = z.object({
244
- token: z.string().refine((value) => Boolean(value.trim())),
245
- expiresAt: z.number().finite()
246
- });
247
- const storedSessionIdSchema = z.string().transform((value) => value.trim()).pipe(z.string().min(1)).optional().catch(void 0);
248
- const storedBindingSchema = z.discriminatedUnion("state", [z.object({
249
- version: z.literal(1),
250
- state: z.literal("active"),
251
- binding: threadBindingSchema,
252
- sessionId: storedSessionIdSchema,
253
- lease: bindingLeaseSchema.optional().catch(void 0)
254
- }), z.object({
255
- version: z.literal(1),
256
- state: z.literal("cleared"),
257
- sessionId: storedSessionIdSchema,
258
- lease: bindingLeaseSchema.optional().catch(void 0),
259
- retired: z.literal(true).optional().catch(void 0)
260
- })]);
261
91
  function hashCodexAppServerBindingFingerprint(canonical) {
262
92
  return `sha256:${createHash("sha256").update(canonical).digest("hex")}`;
263
93
  }
@@ -292,7 +122,7 @@ function createStoredCodexAppServerBinding(value, options = {}) {
292
122
  const record = normalizeLegacyBindingFingerprints(rawRecord);
293
123
  if (record.schemaVersion !== 1 && record.schemaVersion !== 2) return;
294
124
  const pluginAppPolicyContext = readPluginAppPolicyContext(record.pluginAppPolicyContext, record.schemaVersion);
295
- const historyCoveredThrough = readTimestamp(record.historyCoveredThrough) ?? readTimestamp(record.updatedAt) ?? readTimestamp(record.createdAt) ?? readTimestamp(options.now) ?? (/* @__PURE__ */ new Date()).toISOString();
125
+ const historyCoveredThrough = readCodexBindingTimestamp(record.historyCoveredThrough) ?? readCodexBindingTimestamp(record.updatedAt) ?? readCodexBindingTimestamp(record.createdAt) ?? readCodexBindingTimestamp(options.now) ?? (/* @__PURE__ */ new Date()).toISOString();
296
126
  const authProfileId = typeof record.authProfileId === "string" ? record.authProfileId : void 0;
297
127
  const binding = readCodexAppServerThreadBinding({
298
128
  ...record,
@@ -324,7 +154,7 @@ function scopeCodexRunBindingStore(params) {
324
154
  hasOtherThreadOwner: (threadId, identity) => params.bindingStore.hasOtherThreadOwner(threadId, identity ? mapIdentity(identity) : void 0),
325
155
  mutate: (identity, mutation, assertCurrent) => params.bindingStore.mutate(mapIdentity(identity), mutation, assertCurrent),
326
156
  prepareSessionGenerationReclaim: (identity) => params.bindingStore.prepareSessionGenerationReclaim(mapSessionIdentity(identity)),
327
- adoptSessionGeneration: (identity, expectedPreviousSessionId) => params.bindingStore.adoptSessionGeneration(mapSessionIdentity(identity), expectedPreviousSessionId),
157
+ adoptSessionGeneration: (identity, expectedPreviousSessionId, assertCurrent) => params.bindingStore.adoptSessionGeneration(mapSessionIdentity(identity), expectedPreviousSessionId, assertCurrent),
328
158
  resetSessionGeneration: (identity) => params.bindingStore.resetSessionGeneration(mapSessionIdentity(identity)),
329
159
  retireSessionGeneration: (identity) => params.bindingStore.retireSessionGeneration(mapSessionIdentity(identity)),
330
160
  withSessionDeletion: (identity, assertCurrent, run) => params.bindingStore.withSessionDeletion(mapSessionIdentity(identity), assertCurrent, run),
@@ -332,30 +162,62 @@ function scopeCodexRunBindingStore(params) {
332
162
  withLease: (identity, run) => params.bindingStore.withLease(mapIdentity(identity), run)
333
163
  };
334
164
  }
335
- /** Lets the authoritative OpenClaw session generation claim a stale stable binding row. */
336
- async function reclaimCurrentCodexSessionGeneration(params) {
337
- params.assertCurrent?.();
338
- const sessionKey = params.identity.sessionKey?.trim();
339
- if (!sessionKey) return true;
165
+ async function reclaimPreparedCodexSessionGeneration(params, authority, assertCurrent = authority[3]) {
340
166
  const plan = await params.bindingStore.prepareSessionGenerationReclaim(params.identity);
341
- params.assertCurrent?.();
167
+ assertCurrent();
342
168
  if (plan.kind === "resolved") return plan.result;
343
- try {
344
- const storePath = params.storePath?.trim() || resolveStorePath(params.config?.session?.store, { agentId: params.identity.agentId });
345
- if (getSessionEntry({
346
- agentId: params.identity.agentId,
347
- hydrateSkillPromptRefs: false,
348
- readConsistency: "latest",
349
- sessionKey,
350
- storePath
351
- })?.sessionId !== params.identity.sessionId) return false;
352
- } catch {
353
- return false;
169
+ const [state, previousSessionId, assertHostCurrent] = authority;
170
+ if (state !== "current") return false;
171
+ params.onHostGenerationVerified?.(assertHostCurrent);
172
+ if (previousSessionId === plan.expectedPreviousSessionId) {
173
+ const adopted = await params.bindingStore.adoptSessionGeneration(params.identity, previousSessionId, assertCurrent);
174
+ if (adopted !== "absent") return adopted !== "conflict";
354
175
  }
355
- return await params.bindingStore.mutate(params.identity, {
176
+ if (params.reclaimStale === false) return false;
177
+ return params.bindingStore.mutate(params.identity, {
356
178
  kind: "reclaim-generation",
357
179
  expectedPreviousSessionId: plan.expectedPreviousSessionId
358
- }, params.assertCurrent);
180
+ }, assertCurrent);
181
+ }
182
+ /** Lets the authoritative OpenClaw session generation claim a stale stable binding row. */
183
+ async function reclaimCurrentCodexSessionGeneration(params) {
184
+ params.assertCurrent?.();
185
+ if (!params.identity.sessionKey?.trim()) return true;
186
+ const authority = captureCodexSessionGenerationAuthority(params, params.assertCurrent);
187
+ if (authority[0] === "superseded") return false;
188
+ return reclaimPreparedCodexSessionGeneration(params, authority);
189
+ }
190
+ /** Resolve continuity before selecting native queues, catalogs, or connections. */
191
+ async function resolveCodexSessionBinding(params) {
192
+ let assertCurrent = params.assertCurrent ?? (() => {});
193
+ const assertAdmissionCurrent = () => {
194
+ assertCurrent();
195
+ params.signal?.throwIfAborted();
196
+ };
197
+ assertAdmissionCurrent();
198
+ params.assertBinding?.(readCodexSessionOwnershipBinding(params));
199
+ const identity = params.identity;
200
+ const authority = identity.kind === "session" && identity.sessionKey?.trim() ? captureCodexSessionGenerationAuthority({
201
+ ...params,
202
+ identity
203
+ }, assertCurrent) : void 0;
204
+ assertCurrent = authority?.[3] ?? assertCurrent;
205
+ assertAdmissionCurrent();
206
+ let binding = params.bindingStore.read(identity);
207
+ if (!binding && authority && identity.kind === "session") {
208
+ if (!await reclaimPreparedCodexSessionGeneration({
209
+ ...params,
210
+ identity,
211
+ reclaimStale: params.reclaimStale === true
212
+ }, authority, assertAdmissionCurrent) && params.reclaimStale) throw createCodexSessionGenerationSupersededError(identity.sessionId);
213
+ binding = params.bindingStore.read(identity);
214
+ }
215
+ assertAdmissionCurrent();
216
+ params.assertBinding?.(binding);
217
+ return {
218
+ binding,
219
+ assertCurrent
220
+ };
359
221
  }
360
222
  /** Creates the single binding facade owned by the Codex plugin runtime. */
361
223
  function createCodexAppServerBindingStore(state) {
@@ -562,13 +424,7 @@ function createCodexAppServerBindingStore(state) {
562
424
  });
563
425
  };
564
426
  return {
565
- async read(identity) {
566
- const key = bindingStoreKey(identity);
567
- const raw = state.lookup(key);
568
- const stored = readStoredCodexAppServerBinding(raw);
569
- if (raw !== void 0 && !stored) throw new Error(`Invalid Codex app-server binding row: ${key}`);
570
- return stored?.state === "active" && ownsStoredSessionGeneration(identity, stored) ? stored.binding : void 0;
571
- },
427
+ read: (identity) => readCurrentCodexAppServerBinding(state, identity),
572
428
  async hasOtherThreadOwner(threadId, currentIdentity) {
573
429
  const currentKey = currentIdentity ? bindingStoreKey(currentIdentity) : void 0;
574
430
  return state.entries().some(({ key, value }) => {
@@ -685,7 +541,7 @@ function createCodexAppServerBindingStore(state) {
685
541
  }, mutation.kind === "clear" && !retainLegacyClear && !leaseContext.getStore()?.has(key) ? 1 : void 0, assertCurrent);
686
542
  });
687
543
  },
688
- async adoptSessionGeneration(identity, expectedPreviousSessionId) {
544
+ async adoptSessionGeneration(identity, expectedPreviousSessionId, assertCurrent) {
689
545
  return await runBindingMutation(async () => {
690
546
  const key = bindingStoreKey(identity);
691
547
  const expectedSessionId = expectedPreviousSessionId.trim();
@@ -702,7 +558,7 @@ function createCodexAppServerBindingStore(state) {
702
558
  sessionId: targetSessionId
703
559
  }
704
560
  };
705
- });
561
+ }, void 0, assertCurrent);
706
562
  });
707
563
  },
708
564
  resetSessionGeneration: (identity) => transitionSessionGeneration(identity, "reset"),
@@ -742,7 +598,8 @@ function createCodexAppServerBindingStore(state) {
742
598
  }
743
599
  return await withBindingLease(identity, async () => {
744
600
  const owner = leaseContext.getStore().get(key);
745
- const stored = readStoredCodexAppServerBinding(state.lookup(key));
601
+ const expected = state.lookup(key);
602
+ const stored = readStoredCodexAppServerBinding(expected);
746
603
  if (!stored || !ownsStoredSessionGeneration(identity, stored)) throw new Error("Codex binding generation changed before session deletion");
747
604
  const { lease: _lease, ...expectedValue } = stored;
748
605
  let deleted;
@@ -800,26 +657,6 @@ function matchesPendingSupervisionBranch(binding, expected) {
800
657
  function isSameSupervisionOwner(current, replacement) {
801
658
  return replacement.connectionScope === "supervision" && replacement.threadId === current.threadId && replacement.supervisionSourceThreadId === current.supervisionSourceThreadId;
802
659
  }
803
- /** Stable plugin-state key for one current binding owner. */
804
- function bindingStoreKey(identity) {
805
- if (identity.kind === "session") {
806
- const rawAgentId = identity.agentId.trim();
807
- const sessionId = identity.sessionId.trim();
808
- if (!rawAgentId) throw new Error("Codex app-server binding requires an agent id");
809
- if (!sessionId) throw new Error("Codex app-server binding requires a session id");
810
- const agentId = resolveSessionAgentIdsStrict({ agentId: rawAgentId }).sessionAgentId;
811
- const sessionKey = identity.sessionKey?.trim();
812
- if (sessionKey) return `session-key:${agentId}:${createHash("sha256").update(sessionKey).digest("base64url")}`;
813
- return `session:${agentId}:${sessionId}`;
814
- }
815
- const bindingId = identity.bindingId.trim();
816
- if (!bindingId) throw new Error("Codex app-server conversation binding requires a binding id");
817
- return `conversation:${bindingId}`;
818
- }
819
- function readStoredCodexAppServerBinding(value) {
820
- const result = storedBindingSchema.safeParse(value);
821
- return result.success ? stripUndefinedValue(result.data) : void 0;
822
- }
823
660
  function storedSessionGeneration(identity, current) {
824
661
  if (identity.kind === "session") return { sessionId: identity.sessionId };
825
662
  return current?.sessionId ? { sessionId: current.sessionId } : {};
@@ -828,31 +665,6 @@ function preservedSessionGeneration(identity, current) {
828
665
  if (current?.sessionId) return { sessionId: current.sessionId };
829
666
  return storedSessionGeneration(identity, current);
830
667
  }
831
- function ownsStoredSessionGeneration(identity, current) {
832
- return identity.kind !== "session" || !current?.sessionId || current.sessionId === identity.sessionId;
833
- }
834
- function validateBindingForWrite(binding) {
835
- const validated = readCodexAppServerThreadBinding(binding);
836
- if (!validated) throw new Error("Invalid Codex app-server thread binding");
837
- return stripUndefinedBinding(validated);
838
- }
839
- /** Parses stored or shipped sidecar data into the current domain value. */
840
- function readCodexAppServerThreadBinding(value) {
841
- const result = threadBindingSchema.safeParse(value);
842
- if (!result.success) return;
843
- return result.data;
844
- }
845
- function stripUndefinedBinding(binding) {
846
- return stripUndefinedValue(binding);
847
- }
848
- function stripUndefinedValue(value) {
849
- if (Array.isArray(value)) return value.map(stripUndefinedValue);
850
- if (!value || typeof value !== "object") return value;
851
- return Object.fromEntries(Object.entries(value).filter(([, entry]) => entry !== void 0).map(([key, entry]) => [key, stripUndefinedValue(entry)]));
852
- }
853
- function readTimestamp(value) {
854
- return optionalTimestampSchema.parse(value);
855
- }
856
668
  function readPluginAppPolicyContext(value, bindingSchemaVersion) {
857
669
  const record = asOptionalRecord(value);
858
670
  if (!record || typeof record.fingerprint !== "string") return;
@@ -942,4 +754,4 @@ function normalizeCodexAppServerBindingModelProvider(params) {
942
754
  return modelProvider;
943
755
  }
944
756
  //#endregion
945
- export { hashCodexAppServerBindingFingerprint as a, reclaimCurrentCodexSessionGeneration as c, sessionBindingIdentity as d, session_binding_exports as f, createCodexSessionGenerationSupersededError as i, resolveCodexRunSessionBindingAuthority as l, assertCodexBindingMayBeReplaced as n, isCodexAppServerNativeAuthProfile as o, validateBindingForWrite as p, bindingStoreKey as r, normalizeCodexAppServerBindingModelProvider as s, CODEX_APP_SERVER_BINDING_GUARDED_REQUEST_TIMEOUT_MS as t, scopeCodexRunBindingStore as u };
757
+ export { isCodexAppServerNativeAuthProfile as a, resolveCodexRunSessionBindingAuthority as c, session_binding_exports as d, hashCodexAppServerBindingFingerprint as i, resolveCodexSessionBinding as l, assertCodexBindingMayBeReplaced as n, normalizeCodexAppServerBindingModelProvider as o, createCodexSessionGenerationSupersededError as r, reclaimCurrentCodexSessionGeneration as s, CODEX_APP_SERVER_BINDING_GUARDED_REQUEST_TIMEOUT_MS as t, scopeCodexRunBindingStore as u };