@openclaw/codex 2026.7.2-beta.3 → 2026.7.2-beta.5
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.
- package/dist/{app-server-policy-DUMF2Xyr.js → app-server-policy-BmDgseo_.js} +1 -1
- package/dist/attempt-client-cleanup-Ia52yRWc.js +127 -0
- package/dist/{attempt-notifications-Ecjyzufe.js → attempt-notifications-CMR2_fmR.js} +1 -1
- package/dist/{media-understanding-provider-IPNNQre6.js → bounded-turn-FEbUXoYT.js} +71 -188
- package/dist/capabilities-BHRSI6Cn.js +36 -0
- package/dist/cli-metadata.js +1 -1
- package/dist/{command-formatters-NCTL7A2q.js → command-formatters-ico4ZFnk.js} +3 -37
- package/dist/{command-handlers-DtFbZiba.js → command-handlers-CRmnwI2N.js} +1233 -1221
- package/dist/{compact-Kgy26gIM.js → compact-dEN49UH6.js} +8 -7
- package/dist/{computer-use-C7x4ZaqR.js → computer-use-BjGylO-E.js} +16 -6
- package/dist/{conversation-control-B0s3aIjT.js → conversation-control-DE7d9DOj.js} +6 -5
- package/dist/doctor-contract-api.js +24 -86
- package/dist/{dynamic-tools-D_vSVmv9.js → dynamic-tools-LIt9ojep.js} +135 -2696
- package/dist/event-projector-assistant-message-DTgnPPVF.js +101 -0
- package/dist/event-projector-usage-tvgb1NCX.js +69 -0
- package/dist/harness.js +31 -11
- package/dist/incognito-session-ET_ufDH-.js +2 -0
- package/dist/index.js +250 -275
- package/dist/media-understanding-provider.js +173 -1
- package/dist/{models-DD5zBdX5.js → models-BA01NEez.js} +2 -2
- package/dist/{notification-correlation-C8DVQ_Bq.js → notification-correlation-Bj_Ak_jI.js} +3 -3
- package/dist/{plugin-app-cache-key-DJbhLYSK.js → plugin-app-cache-key-DSXX-rXO.js} +5 -5
- package/dist/{transcript-mirror-D9rTxx2P.js → protocol-validators-Dm4eXZmt.js} +335 -595
- package/dist/{rate-limits-CqhWQ2R9.js → rate-limits-S_PXs0ul.js} +1 -1
- package/dist/realtime-voice-api-BPcA1uN9.js +494 -0
- package/dist/realtime-voice-api.js +2 -0
- package/dist/{request-9yf9pZjf.js → request-CXpPennK.js} +1 -1
- package/dist/{run-attempt-BIoO8ISr.js → run-attempt-C5GTPJOE.js} +3111 -387
- package/dist/{session-binding-Bmt20HfB.js → session-binding-DlVQ-Pxs.js} +957 -890
- package/dist/{session-catalog-CA7R-hX2.js → session-catalog-CP2oCcEb.js} +98 -87
- package/dist/{session-cli-Bxk3-Wqz.js → session-cli-CqZ0Fp2a.js} +2 -2
- package/dist/session-upstream-marker-QE-m5QFG.js +82 -0
- package/dist/settled-turn-finalizer-CA_2QXIE.js +303 -0
- package/dist/{shared-client-CSXLtCLE.js → shared-client-BVKE40c-.js} +1870 -1694
- package/dist/{side-question-DtzquMOb.js → side-question-CO12sHxo.js} +24 -16
- package/dist/{thread-lifecycle-CQ_9mAa1.js → thread-lifecycle-DRg_FdzC.js} +127 -153
- package/dist/transcript-mirror-uKA-A4tB.js +550 -0
- package/dist/upstream-session-fork-_Vrz4WJr.js +320 -0
- package/dist/{usage-CuPpFgTc.js → usage-UpVbdX5G.js} +3 -3
- package/dist/{web-search-provider.runtime-_x5XTeqh.js → web-search-provider.runtime-CaQMYDbp.js} +3 -3
- package/package.json +7 -8
- package/npm-shrinkwrap.json +0 -202
- package/dist/{auth-binding-C1czuHPA.js → auth-binding-B4FfbcCg.js} +1 -1
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { V as isJsonObject, _ as CodexAppServerRpcError, a as getLeasedSharedCodexAppServerClient, l as releaseLeasedSharedCodexAppServerClient } from "./shared-client-BVKE40c-.js";
|
|
2
|
+
import { l as sessionBindingIdentity, t as CODEX_APP_SERVER_BINDING_GUARDED_REQUEST_TIMEOUT_MS } from "./session-binding-DlVQ-Pxs.js";
|
|
3
|
+
import { _ as readCodexNotificationItem } from "./attempt-notifications-CMR2_fmR.js";
|
|
4
4
|
import { n as resolveCodexNativeExecutionBlock } from "./sandbox-guard-D1Wky__S.js";
|
|
5
|
-
import { a as resolveCodexBindingAppServerConnection, n as readCodexNotificationThreadId, r as readCodexNotificationTurnId } from "./notification-correlation-
|
|
6
|
-
import { resolveAgentDir, resolveDefaultAgentId } from "openclaw/plugin-sdk/agent-runtime";
|
|
5
|
+
import { a as resolveCodexBindingAppServerConnection, n as readCodexNotificationThreadId, r as readCodexNotificationTurnId } from "./notification-correlation-Bj_Ak_jI.js";
|
|
7
6
|
import { embeddedAgentLog, resolveCompactionTimeoutMs } from "openclaw/plugin-sdk/agent-harness-runtime";
|
|
7
|
+
import { resolveAgentDir as resolveAgentDir$1, resolveDefaultAgentId } from "openclaw/plugin-sdk/agent-runtime";
|
|
8
8
|
//#region extensions/codex/src/app-server/compact.ts
|
|
9
9
|
/**
|
|
10
10
|
* Native Codex app-server compaction bridge for bound OpenClaw sessions.
|
|
@@ -261,6 +261,7 @@ function readIgnoredCompactionOverridePaths(params) {
|
|
|
261
261
|
const inheritedProvider = !localProvider && typeof entry.inheritedRecord?.provider === "string" ? entry.inheritedRecord.provider.trim() : "";
|
|
262
262
|
const providerPath = localProvider ? `${entry.path}.compaction.provider` : inheritedProvider && entry.inheritedPath ? `${entry.inheritedPath}.compaction.provider` : void 0;
|
|
263
263
|
if (typeof entry.record.model === "string" && entry.record.model.trim()) ignored.add(`${entry.path}.compaction.model`);
|
|
264
|
+
if (typeof entry.record.thinkingLevel === "string" && entry.record.thinkingLevel.trim()) ignored.add(`${entry.path}.compaction.thinkingLevel`);
|
|
264
265
|
if (providerPath) ignored.add(providerPath);
|
|
265
266
|
}
|
|
266
267
|
return [...ignored];
|
|
@@ -352,7 +353,7 @@ async function compactCodexNativeThread(params, options) {
|
|
|
352
353
|
authProfileId: requestedAuthProfileId ?? binding.authProfileId,
|
|
353
354
|
pluginConfig: options.pluginConfig,
|
|
354
355
|
config,
|
|
355
|
-
agentDir: resolveAgentDir(config, agentId)
|
|
356
|
+
agentDir: resolveAgentDir$1(config, agentId)
|
|
356
357
|
});
|
|
357
358
|
} catch (error) {
|
|
358
359
|
return {
|
|
@@ -370,7 +371,7 @@ async function compactCodexNativeThread(params, options) {
|
|
|
370
371
|
const shouldReleaseDefaultLease = !options.clientFactory;
|
|
371
372
|
const clientFactory = options.clientFactory ?? getLeasedSharedCodexAppServerClient;
|
|
372
373
|
const runtimeAuthPlan = params.runtimeAuthPlan ?? params.runtimePlan?.auth;
|
|
373
|
-
const usesPreparedApiKey = !usesSupervisionConnection && runtimeAuthPlan?.modelRoute?.authRequirement === "api-key";
|
|
374
|
+
const usesPreparedApiKey = !usesSupervisionConnection && appServer.start.homeScope !== "user" && runtimeAuthPlan?.modelRoute?.authRequirement === "api-key";
|
|
374
375
|
const preparedApiKey = usesPreparedApiKey ? params.resolvedApiKey?.trim() : void 0;
|
|
375
376
|
if (usesPreparedApiKey && !preparedApiKey) return {
|
|
376
377
|
ok: false,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { r as requestCodexAppServerJson } from "./request-
|
|
1
|
+
import { C as isCodexAppServerIndeterminateTransportError, H as resolveFirstExistingMacOSDesktopCodexBundledMarketplacePath, S as isCodexAppServerIndeterminateRequestCancellationError, a as getLeasedSharedCodexAppServerClient, g as acquireCodexNativeConfigFence, l as releaseLeasedSharedCodexAppServerClient, u as resolveCodexNativeConfigFenceKey, x as isCodexAppServerConnectionClosedError } from "./shared-client-BVKE40c-.js";
|
|
2
|
+
import { h as resolveCodexComputerUseConfig, p as resolveCodexAppServerRuntimeOptions } from "./session-binding-DlVQ-Pxs.js";
|
|
3
|
+
import { n as describeControlFailure } from "./capabilities-BHRSI6Cn.js";
|
|
4
|
+
import { r as requestCodexAppServerJson } from "./request-CXpPennK.js";
|
|
5
5
|
import { existsSync } from "node:fs";
|
|
6
6
|
import { runExec } from "openclaw/plugin-sdk/process-runtime";
|
|
7
7
|
//#region extensions/codex/src/app-server/computer-use.ts
|
|
@@ -113,6 +113,7 @@ async function inspectCodexComputerUse(params) {
|
|
|
113
113
|
if (!runtime) throw new Error("Computer Use install could not resolve its app-server runtime");
|
|
114
114
|
client = await getLeasedSharedCodexAppServerClient({
|
|
115
115
|
startOptions: runtime.start,
|
|
116
|
+
pluginConfig: params.pluginConfig,
|
|
116
117
|
timeoutMs: params.timeoutMs ?? runtime.requestTimeoutMs,
|
|
117
118
|
config: params.config,
|
|
118
119
|
agentDir: params.agentDir,
|
|
@@ -213,9 +214,11 @@ async function ensureComputerUsePlugin(params) {
|
|
|
213
214
|
}
|
|
214
215
|
async function readComputerUseTools(params) {
|
|
215
216
|
let server = await readMcpServerStatus(params.request, params.config.mcpServerName);
|
|
216
|
-
|
|
217
|
+
let tools = Object.keys(server?.tools ?? {}).toSorted();
|
|
218
|
+
if ((!server || tools.length === 0) && params.installPlugin) {
|
|
217
219
|
await reloadMcpServers(params.request);
|
|
218
220
|
server = await readMcpServerStatus(params.request, params.config.mcpServerName);
|
|
221
|
+
tools = Object.keys(server?.tools ?? {}).toSorted();
|
|
219
222
|
}
|
|
220
223
|
if (!server) return statusFromPlugin({
|
|
221
224
|
config: params.config,
|
|
@@ -224,10 +227,17 @@ async function readComputerUseTools(params) {
|
|
|
224
227
|
reason: "mcp_missing",
|
|
225
228
|
message: `Computer Use is installed, but the ${params.config.mcpServerName} MCP server is not available.`
|
|
226
229
|
});
|
|
230
|
+
if (tools.length === 0) return statusFromPlugin({
|
|
231
|
+
config: params.config,
|
|
232
|
+
plugin: params.plugin,
|
|
233
|
+
tools,
|
|
234
|
+
reason: "mcp_missing",
|
|
235
|
+
message: `Computer Use is installed, but the ${params.config.mcpServerName} MCP server exposes no tools.`
|
|
236
|
+
});
|
|
227
237
|
const status = statusFromPlugin({
|
|
228
238
|
config: params.config,
|
|
229
239
|
plugin: params.plugin,
|
|
230
|
-
tools
|
|
240
|
+
tools,
|
|
231
241
|
reason: "ready",
|
|
232
242
|
message: "Computer Use is ready."
|
|
233
243
|
});
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { a as getLeasedSharedCodexAppServerClient, c as
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
1
|
+
import { a as getLeasedSharedCodexAppServerClient, c as releaseCodexAppServerClientLease, l as releaseLeasedSharedCodexAppServerClient, m as withLeasedCodexAppServerClientStartSelectionRetry } from "./shared-client-BVKE40c-.js";
|
|
2
|
+
import { O as isCodexFastServiceTier, S as resolveCodexModelBackedReviewerPolicyContext, o as isCodexAppServerNativeAuthProfile, p as resolveCodexAppServerRuntimeOptions, r as bindingStoreKey, s as normalizeCodexAppServerBindingModelProvider } from "./session-binding-DlVQ-Pxs.js";
|
|
3
|
+
import { x as resolveCodexBindingModelProviderFallback, y as resolveCodexAppServerRequestModelSelection } from "./thread-lifecycle-DRg_FdzC.js";
|
|
4
|
+
import { t as CODEX_CONTROL_METHODS } from "./capabilities-BHRSI6Cn.js";
|
|
5
|
+
import { r as formatCodexDisplayText } from "./command-formatters-ico4ZFnk.js";
|
|
6
|
+
import { a as resolveCodexBindingAppServerConnection } from "./notification-correlation-Bj_Ak_jI.js";
|
|
6
7
|
import { ModelSelectionLockedError } from "openclaw/plugin-sdk/model-session-runtime";
|
|
7
8
|
//#region extensions/codex/src/command-authorization.ts
|
|
8
9
|
const CODEX_NATIVE_EXECUTION_AUTH_ERROR = "Only an owner or operator.admin can control Codex native execution.";
|
|
@@ -3,37 +3,11 @@ import fs from "node:fs/promises";
|
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { listAgentIds, resolveAgentDir, resolveSessionAgentIds } from "openclaw/plugin-sdk/agent-runtime";
|
|
5
5
|
import { isDeepStrictEqual } from "node:util";
|
|
6
|
+
import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
6
7
|
import { patchSessionEntry, resolveStorePath } from "openclaw/plugin-sdk/session-store-runtime";
|
|
8
|
+
import { canonicalPathFromExistingAncestor, isPathInside, pathExists } from "openclaw/plugin-sdk/security-runtime";
|
|
7
9
|
import { withFileLock } from "openclaw/plugin-sdk/file-lock";
|
|
8
|
-
|
|
9
|
-
async function pathExists$1(filePath) {
|
|
10
|
-
try {
|
|
11
|
-
await fs.access(filePath);
|
|
12
|
-
return true;
|
|
13
|
-
} catch {
|
|
14
|
-
return false;
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
async function firstFreeArchivePath(sourcePath) {
|
|
18
|
-
for (let index = 2;; index++) {
|
|
19
|
-
const candidate = `${sourcePath}.migrated.${index}`;
|
|
20
|
-
if (!await pathExists$1(candidate)) return candidate;
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
async function archiveBindingSidecar(sourcePath) {
|
|
24
|
-
const archivePath = `${sourcePath}.migrated`;
|
|
25
|
-
if (!await pathExists$1(archivePath)) {
|
|
26
|
-
await fs.rename(sourcePath, archivePath);
|
|
27
|
-
return;
|
|
28
|
-
}
|
|
29
|
-
const [sourceBytes, archiveBytes] = await Promise.all([fs.readFile(sourcePath), fs.readFile(archivePath)]);
|
|
30
|
-
if (sourceBytes.equals(archiveBytes)) {
|
|
31
|
-
await fs.rm(sourcePath, { force: true });
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
34
|
-
await fs.rename(sourcePath, await firstFreeArchivePath(sourcePath));
|
|
35
|
-
}
|
|
36
|
-
//#endregion
|
|
10
|
+
import { archiveLegacyStateSource, legacyStateFileExists } from "openclaw/plugin-sdk/runtime-doctor";
|
|
37
11
|
//#region extensions/codex/src/migration/session-binding-sidecars.ts
|
|
38
12
|
const LEGACY_BINDING_SUFFIX = ".codex-app-server.json";
|
|
39
13
|
const CODEX_AGENT_HARNESS_ID = "codex";
|
|
@@ -49,9 +23,9 @@ const LEGACY_BINDING_LOCK_OPTIONS = {
|
|
|
49
23
|
};
|
|
50
24
|
async function collectSessionSurfaces(params) {
|
|
51
25
|
const surfaces = /* @__PURE__ */ new Map();
|
|
52
|
-
const stateRoot = await
|
|
26
|
+
const stateRoot = await canonicalPathFromExistingAncestor(params.stateDir);
|
|
53
27
|
const add = async (root, storePath, agentId, scan) => {
|
|
54
|
-
const canonicalRoot = await
|
|
28
|
+
const canonicalRoot = await canonicalPathFromExistingAncestor(root);
|
|
55
29
|
const surface = surfaces.get(canonicalRoot) ?? {
|
|
56
30
|
root: canonicalRoot,
|
|
57
31
|
scan: false,
|
|
@@ -81,7 +55,7 @@ async function collectSessionSurfaces(params) {
|
|
|
81
55
|
env: params.env
|
|
82
56
|
});
|
|
83
57
|
const root = path.dirname(storePath);
|
|
84
|
-
await add(root, storePath, agentId,
|
|
58
|
+
await add(root, storePath, agentId, isPathInside(stateRoot, await canonicalPathFromExistingAncestor(root)));
|
|
85
59
|
}
|
|
86
60
|
const legacyRoot = path.join(params.stateDir, "sessions");
|
|
87
61
|
const defaultAgentId = resolveSessionAgentIds({ config: params.config }).defaultAgentId;
|
|
@@ -92,7 +66,7 @@ async function collectLegacyBindingSources(params, options = {}) {
|
|
|
92
66
|
const surfaces = await collectSessionSurfaces(params);
|
|
93
67
|
const sources = /* @__PURE__ */ new Map();
|
|
94
68
|
const addSource = async (sidecarPath, surface) => {
|
|
95
|
-
const canonicalSidecar = await
|
|
69
|
+
const canonicalSidecar = await canonicalPathFromExistingAncestor(sidecarPath);
|
|
96
70
|
const source = sources.get(canonicalSidecar) ?? {
|
|
97
71
|
sidecarPath: canonicalSidecar,
|
|
98
72
|
transcriptPath: sidecarPath.slice(0, -22),
|
|
@@ -167,7 +141,7 @@ async function* iterateIndexedSidecars(surface) {
|
|
|
167
141
|
continue;
|
|
168
142
|
}
|
|
169
143
|
const sidecarPath = `${transcriptPath}${LEGACY_BINDING_SUFFIX}`;
|
|
170
|
-
if (await
|
|
144
|
+
if (await legacyStateFileExists(sidecarPath)) yield sidecarPath;
|
|
171
145
|
}
|
|
172
146
|
}
|
|
173
147
|
}
|
|
@@ -190,7 +164,7 @@ async function* walkSidecars(root) {
|
|
|
190
164
|
}
|
|
191
165
|
}
|
|
192
166
|
async function collectBindingOwners(sources, surfaces, params) {
|
|
193
|
-
const sourcePaths = new Set(await Promise.all(sources.map((source) =>
|
|
167
|
+
const sourcePaths = new Set(await Promise.all(sources.map((source) => canonicalPathFromExistingAncestor(source.transcriptPath))));
|
|
194
168
|
const owners = /* @__PURE__ */ new Map();
|
|
195
169
|
const storePaths = new Set(surfaces.flatMap((surface) => [...surface.storePaths]));
|
|
196
170
|
const storeAgentIds = /* @__PURE__ */ new Map();
|
|
@@ -201,7 +175,7 @@ async function collectBindingOwners(sources, surfaces, params) {
|
|
|
201
175
|
}
|
|
202
176
|
const failures = [];
|
|
203
177
|
for (const storePath of storePaths) {
|
|
204
|
-
const canonicalStorePath = await
|
|
178
|
+
const canonicalStorePath = await canonicalPathFromExistingAncestor(storePath);
|
|
205
179
|
const index = await readLegacySessionIndex(storePath);
|
|
206
180
|
if ("failure" in index) {
|
|
207
181
|
failures.push(index.failure);
|
|
@@ -219,7 +193,7 @@ async function collectBindingOwners(sources, surfaces, params) {
|
|
|
219
193
|
let canonicalLegacyTranscriptPath;
|
|
220
194
|
try {
|
|
221
195
|
legacyTranscriptPath = await resolveLegacySessionFileLocator(sessionsDir, entry, sessionId);
|
|
222
|
-
canonicalLegacyTranscriptPath = await
|
|
196
|
+
canonicalLegacyTranscriptPath = await canonicalPathFromExistingAncestor(legacyTranscriptPath);
|
|
223
197
|
} catch {
|
|
224
198
|
failures.push(`session index ${storePath} has an invalid locator for ${sessionKey}`);
|
|
225
199
|
continue;
|
|
@@ -256,8 +230,8 @@ async function resolveLegacySessionFileLocator(sessionsDir, entry, sessionId) {
|
|
|
256
230
|
const sessionFile = entry.sessionFile?.trim();
|
|
257
231
|
if (!sessionFile) return fallback;
|
|
258
232
|
const candidate = path.resolve(base, sessionFile);
|
|
259
|
-
const [canonicalBase, canonicalCandidate] = await Promise.all([
|
|
260
|
-
if (!
|
|
233
|
+
const [canonicalBase, canonicalCandidate] = await Promise.all([canonicalPathFromExistingAncestor(base), canonicalPathFromExistingAncestor(candidate)]);
|
|
234
|
+
if (!isPathInside(canonicalBase, canonicalCandidate)) throw new Error("legacy session file locator escapes its session directory");
|
|
261
235
|
return candidate;
|
|
262
236
|
}
|
|
263
237
|
function resolveLegacyBindingOwnerAgentId(params) {
|
|
@@ -302,7 +276,7 @@ async function migrateSource(source, candidates, params, store) {
|
|
|
302
276
|
return await withFileLock(source.sidecarPath, LEGACY_BINDING_LOCK_OPTIONS, async () => {
|
|
303
277
|
const [contents, stat] = await Promise.all([fs.readFile(source.sidecarPath, "utf8"), fs.stat(source.sidecarPath)]);
|
|
304
278
|
const raw = JSON.parse(contents);
|
|
305
|
-
const [{ bindingStoreKey, createStoredCodexAppServerBinding, normalizeStoredCodexAppServerBindingFingerprints, readStoredCodexAppServerBinding }, { legacyCodexConversationBindingId }] = await Promise.all([import("./session-binding-
|
|
279
|
+
const [{ bindingStoreKey, createStoredCodexAppServerBinding, normalizeStoredCodexAppServerBindingFingerprints, readStoredCodexAppServerBinding }, { legacyCodexConversationBindingId }] = await Promise.all([import("./session-binding-DlVQ-Pxs.js").then((n) => n.u), import("./conversation-binding-data-BHRpYbX3.js").then((n) => n.t)]);
|
|
306
280
|
const agentId = owner?.agentId ?? (source.agentIds.size === 1 ? [...source.agentIds][0] : void 0);
|
|
307
281
|
const baseStored = createStoredCodexAppServerBinding(raw, {
|
|
308
282
|
now: stat.mtime.toISOString(),
|
|
@@ -402,7 +376,14 @@ async function migrateSource(source, candidates, params, store) {
|
|
|
402
376
|
}
|
|
403
377
|
for (const entry of entries) if (!hasExpected(await store.lookup(entry.key), entry.value)) return retain(`canonical plugin state changed at ${entry.key}`);
|
|
404
378
|
}
|
|
405
|
-
|
|
379
|
+
const archiveWarnings = [];
|
|
380
|
+
await archiveLegacyStateSource({
|
|
381
|
+
filePath: source.sidecarPath,
|
|
382
|
+
label: "Codex app-server binding",
|
|
383
|
+
changes: [],
|
|
384
|
+
warnings: archiveWarnings
|
|
385
|
+
});
|
|
386
|
+
if (archiveWarnings.length > 0 && await pathExists(source.sidecarPath)) return retain(archiveWarnings.join("; "));
|
|
406
387
|
return {
|
|
407
388
|
archived: true,
|
|
408
389
|
importedKeys
|
|
@@ -427,7 +408,7 @@ async function recordSessionOwner(owner, env) {
|
|
|
427
408
|
} catch {
|
|
428
409
|
return "its session owner changed before Codex ownership could be recorded";
|
|
429
410
|
}
|
|
430
|
-
if (await
|
|
411
|
+
if (await canonicalPathFromExistingAncestor(currentTranscriptPath) !== await canonicalPathFromExistingAncestor(owner.transcriptPath) || currentOwner.entry.lifecycleRevision !== owner.lifecycleRevision) return "its session owner changed before Codex ownership could be recorded";
|
|
431
412
|
const legacyHarnessId = currentOwner.entry.agentHarnessId?.trim();
|
|
432
413
|
if (currentOwner.entry.agentHarnessId !== void 0 && !legacyHarnessId) return "its session owner changed before Codex ownership could be recorded";
|
|
433
414
|
if (legacyHarnessId && legacyHarnessId !== CODEX_AGENT_HARNESS_ID) return `its session is owned by agent harness ${legacyHarnessId}`;
|
|
@@ -474,54 +455,11 @@ async function readDirectoryEntries(directory) {
|
|
|
474
455
|
throw error;
|
|
475
456
|
}
|
|
476
457
|
}
|
|
477
|
-
async function isRegularFile(filePath) {
|
|
478
|
-
try {
|
|
479
|
-
return (await fs.stat(filePath)).isFile();
|
|
480
|
-
} catch {
|
|
481
|
-
return false;
|
|
482
|
-
}
|
|
483
|
-
}
|
|
484
|
-
function isRecord(value) {
|
|
485
|
-
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
486
|
-
}
|
|
487
458
|
function isSafeLegacySessionId(value) {
|
|
488
459
|
if (typeof value !== "string") return false;
|
|
489
460
|
const trimmed = value.trim();
|
|
490
461
|
return trimmed.length > 0 && trimmed.length <= 255 && /^[A-Za-z0-9][A-Za-z0-9._:@-]*$/.test(trimmed);
|
|
491
462
|
}
|
|
492
|
-
function isPathWithin(root, candidate) {
|
|
493
|
-
const relative = path.relative(root, candidate);
|
|
494
|
-
return relative === "" || relative !== ".." && !relative.startsWith(`..${path.sep}`) && !path.isAbsolute(relative);
|
|
495
|
-
}
|
|
496
|
-
async function canonicalizePath(filePath) {
|
|
497
|
-
try {
|
|
498
|
-
return await fs.realpath(filePath);
|
|
499
|
-
} catch {
|
|
500
|
-
return path.resolve(filePath);
|
|
501
|
-
}
|
|
502
|
-
}
|
|
503
|
-
async function canonicalizePathForContainment(filePath) {
|
|
504
|
-
const resolved = path.resolve(filePath);
|
|
505
|
-
const suffix = [];
|
|
506
|
-
let probe = resolved;
|
|
507
|
-
while (true) try {
|
|
508
|
-
const realProbe = await fs.realpath(probe);
|
|
509
|
-
return suffix.length === 0 ? realProbe : path.join(realProbe, ...suffix.toReversed());
|
|
510
|
-
} catch {
|
|
511
|
-
const parent = path.dirname(probe);
|
|
512
|
-
if (parent === probe) return resolved;
|
|
513
|
-
suffix.push(path.basename(probe));
|
|
514
|
-
probe = parent;
|
|
515
|
-
}
|
|
516
|
-
}
|
|
517
|
-
async function pathExists(filePath) {
|
|
518
|
-
try {
|
|
519
|
-
await fs.access(filePath);
|
|
520
|
-
return true;
|
|
521
|
-
} catch {
|
|
522
|
-
return false;
|
|
523
|
-
}
|
|
524
|
-
}
|
|
525
463
|
const stateMigrations = [{
|
|
526
464
|
id: "codex-app-server-sidecars-to-plugin-state",
|
|
527
465
|
label: "Codex app-server thread bindings",
|
|
@@ -554,7 +492,7 @@ const stateMigrations = [{
|
|
|
554
492
|
let migrated = 0;
|
|
555
493
|
let partialImports = 0;
|
|
556
494
|
for (const source of sources) {
|
|
557
|
-
const result = await migrateSource(source, ownerCollection.owners.get(await
|
|
495
|
+
const result = await migrateSource(source, ownerCollection.owners.get(await canonicalPathFromExistingAncestor(source.transcriptPath)) ?? [], params, store);
|
|
558
496
|
if (result.warning) warnings.push(result.warning);
|
|
559
497
|
if (result.notice) notices.push(result.notice);
|
|
560
498
|
if (result.archived) migrated++;
|