happy-imou-cloud 2.1.49 → 2.1.50
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/{BaseReasoningProcessor-CAVeOdyo.mjs → BaseReasoningProcessor-2qoX8OA1.mjs} +2 -2
- package/dist/{BaseReasoningProcessor-Dn9NcoHz.cjs → BaseReasoningProcessor-D3q5lh9h.cjs} +2 -2
- package/dist/{ProviderSelectionHandler-BJJc7qOR.cjs → ProviderSelectionHandler-CO5BYEgC.cjs} +2 -2
- package/dist/{ProviderSelectionHandler-DIYidT13.mjs → ProviderSelectionHandler-CO6foZET.mjs} +2 -2
- package/dist/{api-DnqaNvyV.mjs → api-6B4EMs47.mjs} +1 -1
- package/dist/{api-D7nAeZi7.cjs → api-D4JOaMll.cjs} +1 -1
- package/dist/{command-CzfRRhVe.mjs → command-BbJCdR2t.mjs} +2 -2
- package/dist/{command-VcH4hbhi.cjs → command-DuKDmbdM.cjs} +2 -2
- package/dist/{index-xa1kwZoj.cjs → index-CZJH0CUT.cjs} +21 -12
- package/dist/{index-7Z93BoVn.mjs → index-CyGHrYHl.mjs} +18 -9
- package/dist/index.cjs +2 -2
- package/dist/index.mjs +2 -2
- package/dist/lib.cjs +1 -1
- package/dist/lib.d.cts +88 -86
- package/dist/lib.d.mts +88 -86
- package/dist/lib.mjs +1 -1
- package/dist/{registerKillSessionHandler-CfCya6si.cjs → registerKillSessionHandler-Bo_MMbdY.cjs} +2 -2
- package/dist/{registerKillSessionHandler-DLDg2EES.mjs → registerKillSessionHandler-ggfGac_S.mjs} +2 -2
- package/dist/{runClaude-BBGNmGj6.cjs → runClaude-B4eoG3Pu.cjs} +4 -4
- package/dist/{runClaude-zCwRhpOw.mjs → runClaude-jDr3i0bO.mjs} +4 -4
- package/dist/{runCodex-BbgLVjb9.mjs → runCodex-e_D1Jd_w.mjs} +217 -63
- package/dist/{runCodex-jUU6U2tZ.cjs → runCodex-hDGeZAh5.cjs} +216 -62
- package/dist/{runGemini-C0NT8MHK.cjs → runGemini-CeA9aiD1.cjs} +4 -4
- package/dist/{runGemini-DcwNsudA.mjs → runGemini-Cur84FvO.mjs} +4 -4
- package/package.json +1 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var persistence = require('./api-
|
|
4
|
-
var registerKillSessionHandler = require('./registerKillSessionHandler-
|
|
5
|
-
var index = require('./index-
|
|
3
|
+
var persistence = require('./api-D4JOaMll.cjs');
|
|
4
|
+
var registerKillSessionHandler = require('./registerKillSessionHandler-Bo_MMbdY.cjs');
|
|
5
|
+
var index = require('./index-CZJH0CUT.cjs');
|
|
6
6
|
require('cross-spawn');
|
|
7
7
|
require('@agentclientprotocol/sdk');
|
|
8
8
|
var node_crypto = require('node:crypto');
|
|
@@ -26,8 +26,8 @@ require('tweetnacl');
|
|
|
26
26
|
require('open');
|
|
27
27
|
var React = require('react');
|
|
28
28
|
var ink = require('ink');
|
|
29
|
-
var ProviderSelectionHandler = require('./ProviderSelectionHandler-
|
|
30
|
-
var BaseReasoningProcessor = require('./BaseReasoningProcessor-
|
|
29
|
+
var ProviderSelectionHandler = require('./ProviderSelectionHandler-CO5BYEgC.cjs');
|
|
30
|
+
var BaseReasoningProcessor = require('./BaseReasoningProcessor-D3q5lh9h.cjs');
|
|
31
31
|
require('zod');
|
|
32
32
|
require('socket.io-client');
|
|
33
33
|
require('expo-server-sdk');
|
|
@@ -240,12 +240,19 @@ class CodexSession {
|
|
|
240
240
|
this.sessionId = sessionId;
|
|
241
241
|
this.client.updateMetadata((metadata) => ({
|
|
242
242
|
...metadata,
|
|
243
|
-
codexSessionId: sessionId
|
|
243
|
+
codexSessionId: sessionId,
|
|
244
|
+
codexSessionCwd: this.path
|
|
244
245
|
}));
|
|
245
246
|
persistence.logger.debug(`[CodexSession] Session ID ${sessionId} added to metadata`);
|
|
246
247
|
};
|
|
247
248
|
clearSessionId = () => {
|
|
248
249
|
this.sessionId = null;
|
|
250
|
+
this.client.updateMetadata((metadata) => {
|
|
251
|
+
const nextMetadata = { ...metadata };
|
|
252
|
+
delete nextMetadata.codexSessionId;
|
|
253
|
+
delete nextMetadata.codexSessionCwd;
|
|
254
|
+
return nextMetadata;
|
|
255
|
+
});
|
|
249
256
|
persistence.logger.debug("[CodexSession] Session ID cleared");
|
|
250
257
|
};
|
|
251
258
|
handleUserObserverEphemeral = (event) => {
|
|
@@ -517,6 +524,113 @@ function getCodexExecutionFingerprint(mode) {
|
|
|
517
524
|
});
|
|
518
525
|
}
|
|
519
526
|
|
|
527
|
+
function getCodexSessionsRoot(options = {}) {
|
|
528
|
+
const codexHomeDir = options.codexHomeDir || process.env.CODEX_HOME || path.join(os.homedir(), ".codex");
|
|
529
|
+
return path.join(codexHomeDir, "sessions");
|
|
530
|
+
}
|
|
531
|
+
function collectFilesRecursive(dir, acc = []) {
|
|
532
|
+
let entries;
|
|
533
|
+
try {
|
|
534
|
+
entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
535
|
+
} catch {
|
|
536
|
+
return acc;
|
|
537
|
+
}
|
|
538
|
+
for (const entry of entries) {
|
|
539
|
+
const full = path.join(dir, entry.name);
|
|
540
|
+
if (entry.isDirectory()) {
|
|
541
|
+
collectFilesRecursive(full, acc);
|
|
542
|
+
} else if (entry.isFile()) {
|
|
543
|
+
acc.push(full);
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
return acc;
|
|
547
|
+
}
|
|
548
|
+
function extractCodexSessionIdFromPath(filePath) {
|
|
549
|
+
const match = filePath.match(/-([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})\.jsonl$/);
|
|
550
|
+
return match?.[1] ?? null;
|
|
551
|
+
}
|
|
552
|
+
function normalizePathForSessionMatch(path$1) {
|
|
553
|
+
const normalizedPath = path.normalize(path$1).replace(/[\\/]+/g, "/").replace(/\/+$/, "");
|
|
554
|
+
return process.platform === "win32" ? normalizedPath.toLowerCase() : normalizedPath;
|
|
555
|
+
}
|
|
556
|
+
function extractCodexSessionCwdFromFile(filePath) {
|
|
557
|
+
let contents;
|
|
558
|
+
try {
|
|
559
|
+
contents = fs.readFileSync(filePath, "utf8");
|
|
560
|
+
} catch {
|
|
561
|
+
return null;
|
|
562
|
+
}
|
|
563
|
+
for (const line of contents.split(/\r?\n/)) {
|
|
564
|
+
if (!line.trim()) {
|
|
565
|
+
continue;
|
|
566
|
+
}
|
|
567
|
+
let record;
|
|
568
|
+
try {
|
|
569
|
+
record = JSON.parse(line);
|
|
570
|
+
} catch {
|
|
571
|
+
continue;
|
|
572
|
+
}
|
|
573
|
+
if (record.type !== "session_meta" || typeof record.payload !== "object" || record.payload === null) {
|
|
574
|
+
continue;
|
|
575
|
+
}
|
|
576
|
+
const cwd = record.payload.cwd;
|
|
577
|
+
return typeof cwd === "string" && cwd.trim().length > 0 ? cwd : null;
|
|
578
|
+
}
|
|
579
|
+
return null;
|
|
580
|
+
}
|
|
581
|
+
function codexSessionFileMatchesCwd(filePath, cwd) {
|
|
582
|
+
const expectedCwd = cwd?.trim();
|
|
583
|
+
if (!expectedCwd) {
|
|
584
|
+
return true;
|
|
585
|
+
}
|
|
586
|
+
const actualCwd = extractCodexSessionCwdFromFile(filePath);
|
|
587
|
+
if (!actualCwd) {
|
|
588
|
+
return false;
|
|
589
|
+
}
|
|
590
|
+
return normalizePathForSessionMatch(actualCwd) === normalizePathForSessionMatch(expectedCwd);
|
|
591
|
+
}
|
|
592
|
+
function findCodexResumeFile(sessionId, options = {}) {
|
|
593
|
+
if (!sessionId) return null;
|
|
594
|
+
try {
|
|
595
|
+
const candidates = collectFilesRecursive(getCodexSessionsRoot(options)).filter((full) => full.endsWith(`-${sessionId}.jsonl`)).filter((full) => {
|
|
596
|
+
try {
|
|
597
|
+
return fs.statSync(full).isFile();
|
|
598
|
+
} catch {
|
|
599
|
+
return false;
|
|
600
|
+
}
|
|
601
|
+
}).filter((full) => codexSessionFileMatchesCwd(full, options.cwd)).sort((a, b) => fs.statSync(b).mtimeMs - fs.statSync(a).mtimeMs);
|
|
602
|
+
return candidates[0] || null;
|
|
603
|
+
} catch {
|
|
604
|
+
return null;
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
function isCodexResumeSessionValidForCwd(sessionId, cwd, options = {}) {
|
|
608
|
+
if (!sessionId?.trim()) {
|
|
609
|
+
return false;
|
|
610
|
+
}
|
|
611
|
+
return findCodexResumeFile(sessionId, { ...options, cwd }) !== null;
|
|
612
|
+
}
|
|
613
|
+
function findLatestCodexSessionIdSince(startTimeMs, options = {}) {
|
|
614
|
+
try {
|
|
615
|
+
const candidates = collectFilesRecursive(getCodexSessionsRoot(options)).filter((full) => full.endsWith(".jsonl")).filter((full) => {
|
|
616
|
+
try {
|
|
617
|
+
return fs.statSync(full).mtimeMs >= startTimeMs;
|
|
618
|
+
} catch {
|
|
619
|
+
return false;
|
|
620
|
+
}
|
|
621
|
+
}).filter((full) => codexSessionFileMatchesCwd(full, options.cwd)).sort((a, b) => fs.statSync(b).mtimeMs - fs.statSync(a).mtimeMs);
|
|
622
|
+
for (const candidate of candidates) {
|
|
623
|
+
const sessionId = extractCodexSessionIdFromPath(candidate);
|
|
624
|
+
if (sessionId) {
|
|
625
|
+
return sessionId;
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
} catch {
|
|
629
|
+
return null;
|
|
630
|
+
}
|
|
631
|
+
return null;
|
|
632
|
+
}
|
|
633
|
+
|
|
520
634
|
function delay(ms) {
|
|
521
635
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
522
636
|
}
|
|
@@ -692,6 +806,17 @@ function shouldInjectLargeOutputRecoveryHint(error) {
|
|
|
692
806
|
].filter(Boolean).join("\n").toLowerCase();
|
|
693
807
|
return searchableText.includes("memory allocation of") || searchableText.includes("out of memory") || searchableText.includes("oversized command output");
|
|
694
808
|
}
|
|
809
|
+
function isCodexUnknownResumeSessionError(error) {
|
|
810
|
+
const record = typeof error === "object" && error !== null ? error : null;
|
|
811
|
+
const searchableText = [
|
|
812
|
+
index.formatDisplayMessage(error).trim(),
|
|
813
|
+
record ? index.formatDisplayMessage(record.message).trim() : "",
|
|
814
|
+
record ? index.formatDisplayMessage(record.stderr).trim() : "",
|
|
815
|
+
record ? index.formatDisplayMessage(record.detail).trim() : "",
|
|
816
|
+
record ? index.formatDisplayMessage(record.data).trim() : ""
|
|
817
|
+
].filter(Boolean).join("\n");
|
|
818
|
+
return /unknown (session|thread)|session .* not found|thread .* not found|conversation .* not found|missing rollout path for thread|state db missing rollout path|no rollout found for thread id|resource not found/i.test(searchableText);
|
|
819
|
+
}
|
|
695
820
|
function normalizeCodexBackendError(error) {
|
|
696
821
|
const record = typeof error === "object" && error !== null ? error : null;
|
|
697
822
|
const text = index.formatDisplayMessage(error).trim();
|
|
@@ -1175,6 +1300,11 @@ async function codexRemoteLauncher(session) {
|
|
|
1175
1300
|
};
|
|
1176
1301
|
const createRuntimeHandle = async (mode) => {
|
|
1177
1302
|
const executionMode = resolveCodexAcpExecutionMode(mode);
|
|
1303
|
+
const resumeSessionId = session.sessionId && isCodexResumeSessionValidForCwd(session.sessionId, session.path) ? session.sessionId : null;
|
|
1304
|
+
if (session.sessionId && !resumeSessionId) {
|
|
1305
|
+
persistence.logger.debug(`[Codex] Refusing to resume Codex session ${session.sessionId} because its local session file does not match cwd ${session.path}`);
|
|
1306
|
+
session.clearSessionId();
|
|
1307
|
+
}
|
|
1178
1308
|
const validation = index.validateCodexAcpSpawn({
|
|
1179
1309
|
command: process.env.HAPPY_CODEX_ACP_COMMAND,
|
|
1180
1310
|
model: executionMode.model,
|
|
@@ -1195,7 +1325,7 @@ async function codexRemoteLauncher(session) {
|
|
|
1195
1325
|
sandbox: executionMode.sandbox,
|
|
1196
1326
|
approvalPolicy: executionMode.approvalPolicy,
|
|
1197
1327
|
permissionHandler,
|
|
1198
|
-
resumeSessionId
|
|
1328
|
+
resumeSessionId,
|
|
1199
1329
|
selectionHandler: {
|
|
1200
1330
|
handleSelection: (request) => selectionHandler.requestSelection(request)
|
|
1201
1331
|
}
|
|
@@ -1346,12 +1476,31 @@ async function codexRemoteLauncher(session) {
|
|
|
1346
1476
|
const turnSignal = abortController.signal;
|
|
1347
1477
|
let sentTurnResultPush = false;
|
|
1348
1478
|
let turnStatus = "task_complete";
|
|
1479
|
+
let retryingWithFreshSession = false;
|
|
1349
1480
|
currentHappyOrgTurn = message.mode.happyOrg ?? null;
|
|
1350
1481
|
try {
|
|
1351
1482
|
turnInFlight = true;
|
|
1352
1483
|
shouldCommitAccumulatedResponse = false;
|
|
1353
1484
|
const isNewRuntimeSession = runtimeHandle === null;
|
|
1354
|
-
const
|
|
1485
|
+
const attemptedResumeSessionId = isNewRuntimeSession ? session.sessionId : null;
|
|
1486
|
+
let activeRuntimeHandle;
|
|
1487
|
+
try {
|
|
1488
|
+
activeRuntimeHandle = runtimeHandle ?? await createRuntimeHandle(message.mode);
|
|
1489
|
+
} catch (error) {
|
|
1490
|
+
if (!isNewRuntimeSession || !attemptedResumeSessionId || !isCodexUnknownResumeSessionError(error) || turnSignal.aborted) {
|
|
1491
|
+
throw error;
|
|
1492
|
+
}
|
|
1493
|
+
persistence.logger.debug(`[Codex] Resume session ${attemptedResumeSessionId} failed during ACP startup; retrying with a fresh session`, error);
|
|
1494
|
+
queueHistoryInjectionForRestart("Codex resume session is unavailable. Retrying with a fresh Codex session...");
|
|
1495
|
+
session.clearSessionId();
|
|
1496
|
+
currentModeHash = null;
|
|
1497
|
+
permissionHandler.reset();
|
|
1498
|
+
selectionHandler.reset();
|
|
1499
|
+
resetTurnState();
|
|
1500
|
+
pending = message;
|
|
1501
|
+
retryingWithFreshSession = true;
|
|
1502
|
+
continue;
|
|
1503
|
+
}
|
|
1355
1504
|
if (!activeRuntimeHandle) {
|
|
1356
1505
|
throw new Error("Failed to create Codex ACP backend");
|
|
1357
1506
|
}
|
|
@@ -1378,8 +1527,25 @@ ${message.message}` : message.message;
|
|
|
1378
1527
|
promptToSend = registerKillSessionHandler.buildHappyOrgTurnPrompt(promptToSend, message.mode.happyOrg);
|
|
1379
1528
|
}
|
|
1380
1529
|
conversationHistory.addUserMessage(message.message);
|
|
1381
|
-
|
|
1382
|
-
|
|
1530
|
+
try {
|
|
1531
|
+
await activeRuntimeHandle.sendPrompt(promptToSend);
|
|
1532
|
+
await registerKillSessionHandler.waitForResponseCompleteWithAbort(activeRuntimeHandle.backend, turnSignal);
|
|
1533
|
+
} catch (error) {
|
|
1534
|
+
if (!isNewRuntimeSession || !attemptedResumeSessionId || !isCodexUnknownResumeSessionError(error) || turnSignal.aborted) {
|
|
1535
|
+
throw error;
|
|
1536
|
+
}
|
|
1537
|
+
persistence.logger.debug(`[Codex] Resume session ${attemptedResumeSessionId} is unavailable; retrying with a fresh ACP session`, error);
|
|
1538
|
+
queueHistoryInjectionForRestart("Codex resume session is unavailable. Retrying with a fresh Codex session...");
|
|
1539
|
+
await disposeRuntimeHandle();
|
|
1540
|
+
session.clearSessionId();
|
|
1541
|
+
currentModeHash = null;
|
|
1542
|
+
permissionHandler.reset();
|
|
1543
|
+
selectionHandler.reset();
|
|
1544
|
+
resetTurnState();
|
|
1545
|
+
pending = message;
|
|
1546
|
+
retryingWithFreshSession = true;
|
|
1547
|
+
continue;
|
|
1548
|
+
}
|
|
1383
1549
|
reasoningProcessor.completeCurrent();
|
|
1384
1550
|
shouldCommitAccumulatedResponse = true;
|
|
1385
1551
|
shouldInjectHistoryOnNextSession = false;
|
|
@@ -1409,6 +1575,9 @@ ${message.message}` : message.message;
|
|
|
1409
1575
|
}
|
|
1410
1576
|
} finally {
|
|
1411
1577
|
turnInFlight = false;
|
|
1578
|
+
if (retryingWithFreshSession) {
|
|
1579
|
+
continue;
|
|
1580
|
+
}
|
|
1412
1581
|
const finalizedTurn = await registerKillSessionHandler.finalizeHappyOrgTurnWithBusinessAck({
|
|
1413
1582
|
metadata: session.runtimeSession.getMetadataSnapshot?.() ?? null,
|
|
1414
1583
|
queuedTurn: message.mode.happyOrg,
|
|
@@ -1504,52 +1673,6 @@ ${message.message}` : message.message;
|
|
|
1504
1673
|
return shouldSwitchToLocal ? "switch" : "exit";
|
|
1505
1674
|
}
|
|
1506
1675
|
|
|
1507
|
-
function getCodexSessionsRoot(options = {}) {
|
|
1508
|
-
const codexHomeDir = options.codexHomeDir || process.env.CODEX_HOME || path.join(os.homedir(), ".codex");
|
|
1509
|
-
return path.join(codexHomeDir, "sessions");
|
|
1510
|
-
}
|
|
1511
|
-
function collectFilesRecursive(dir, acc = []) {
|
|
1512
|
-
let entries;
|
|
1513
|
-
try {
|
|
1514
|
-
entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
1515
|
-
} catch {
|
|
1516
|
-
return acc;
|
|
1517
|
-
}
|
|
1518
|
-
for (const entry of entries) {
|
|
1519
|
-
const full = path.join(dir, entry.name);
|
|
1520
|
-
if (entry.isDirectory()) {
|
|
1521
|
-
collectFilesRecursive(full, acc);
|
|
1522
|
-
} else if (entry.isFile()) {
|
|
1523
|
-
acc.push(full);
|
|
1524
|
-
}
|
|
1525
|
-
}
|
|
1526
|
-
return acc;
|
|
1527
|
-
}
|
|
1528
|
-
function extractCodexSessionIdFromPath(filePath) {
|
|
1529
|
-
const match = filePath.match(/-([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})\.jsonl$/);
|
|
1530
|
-
return match?.[1] ?? null;
|
|
1531
|
-
}
|
|
1532
|
-
function findLatestCodexSessionIdSince(startTimeMs, options = {}) {
|
|
1533
|
-
try {
|
|
1534
|
-
const candidates = collectFilesRecursive(getCodexSessionsRoot(options)).filter((full) => full.endsWith(".jsonl")).filter((full) => {
|
|
1535
|
-
try {
|
|
1536
|
-
return fs.statSync(full).mtimeMs >= startTimeMs;
|
|
1537
|
-
} catch {
|
|
1538
|
-
return false;
|
|
1539
|
-
}
|
|
1540
|
-
}).sort((a, b) => fs.statSync(b).mtimeMs - fs.statSync(a).mtimeMs);
|
|
1541
|
-
for (const candidate of candidates) {
|
|
1542
|
-
const sessionId = extractCodexSessionIdFromPath(candidate);
|
|
1543
|
-
if (sessionId) {
|
|
1544
|
-
return sessionId;
|
|
1545
|
-
}
|
|
1546
|
-
}
|
|
1547
|
-
} catch {
|
|
1548
|
-
return null;
|
|
1549
|
-
}
|
|
1550
|
-
return null;
|
|
1551
|
-
}
|
|
1552
|
-
|
|
1553
1676
|
const MANAGED_CODEX_HOME_PREFIX = "happy-codex-home-";
|
|
1554
1677
|
function isManagedCodexHomePath(value) {
|
|
1555
1678
|
const trimmed = value?.trim();
|
|
@@ -1616,12 +1739,17 @@ function terminateCodexLocalChild(pid) {
|
|
|
1616
1739
|
}
|
|
1617
1740
|
async function codexLocal(opts) {
|
|
1618
1741
|
const baseArgs = [...opts.codexArgs ?? []];
|
|
1619
|
-
const args = opts.sessionId ? ["resume", opts.sessionId, ...baseArgs] : baseArgs;
|
|
1620
|
-
const startTime = Date.now();
|
|
1621
|
-
let detectedSessionId = opts.sessionId;
|
|
1622
|
-
const codexExecutable = index.resolveCodexExecutable();
|
|
1623
1742
|
const codexEnv = buildCodexLocalEnv(process.env);
|
|
1624
1743
|
const codexHomeDir = resolveCodexLocalHomeDir(codexEnv);
|
|
1744
|
+
const resumeSessionId = opts.sessionId && isCodexResumeSessionValidForCwd(opts.sessionId, opts.path, { codexHomeDir }) ? opts.sessionId : null;
|
|
1745
|
+
if (opts.sessionId && !resumeSessionId) {
|
|
1746
|
+
persistence.logger.debug(`[CodexLocal] Refusing to resume Codex session ${opts.sessionId} because its local session file does not match cwd ${opts.path}`);
|
|
1747
|
+
opts.onResumeSessionInvalid?.(opts.sessionId);
|
|
1748
|
+
}
|
|
1749
|
+
const args = resumeSessionId ? ["resume", resumeSessionId, ...baseArgs] : baseArgs;
|
|
1750
|
+
const startTime = Date.now();
|
|
1751
|
+
let detectedSessionId = resumeSessionId;
|
|
1752
|
+
const codexExecutable = index.resolveCodexExecutable();
|
|
1625
1753
|
persistence.logger.debug(`[CodexLocal] Spawning ${codexExecutable} with args: ${JSON.stringify(args)}`);
|
|
1626
1754
|
releaseTerminalInputForChild();
|
|
1627
1755
|
clearTerminalForChild();
|
|
@@ -1647,7 +1775,7 @@ async function codexLocal(opts) {
|
|
|
1647
1775
|
if (detectedSessionId) {
|
|
1648
1776
|
return;
|
|
1649
1777
|
}
|
|
1650
|
-
const nextSessionId = findLatestCodexSessionIdSince(startTime, { codexHomeDir });
|
|
1778
|
+
const nextSessionId = findLatestCodexSessionIdSince(startTime, { codexHomeDir, cwd: opts.path });
|
|
1651
1779
|
if (nextSessionId) {
|
|
1652
1780
|
detectedSessionId = nextSessionId;
|
|
1653
1781
|
persistence.logger.debug(`[CodexLocal] Detected session ID: ${nextSessionId}`);
|
|
@@ -1790,6 +1918,7 @@ async function codexLocalLauncher(session) {
|
|
|
1790
1918
|
abort: processAbortController.signal,
|
|
1791
1919
|
codexArgs: session.codexArgs,
|
|
1792
1920
|
onSessionFound: recordSessionFound,
|
|
1921
|
+
onResumeSessionInvalid: session.clearSessionId,
|
|
1793
1922
|
onThinkingChange: session.onThinkingChange
|
|
1794
1923
|
});
|
|
1795
1924
|
if (sessionId) {
|
|
@@ -1959,6 +2088,17 @@ function normalizeCodexArgsForHappy(options) {
|
|
|
1959
2088
|
};
|
|
1960
2089
|
}
|
|
1961
2090
|
|
|
2091
|
+
function normalizePathForCodexResumeIdentity(path) {
|
|
2092
|
+
const normalized = path.trim().replace(/[\\/]+/g, "/").replace(/\/+$/, "");
|
|
2093
|
+
return process.platform === "win32" ? normalized.toLowerCase() : normalized;
|
|
2094
|
+
}
|
|
2095
|
+
function codexResumeCwdMatches(expected, actual) {
|
|
2096
|
+
const normalizedExpected = expected?.trim();
|
|
2097
|
+
if (!normalizedExpected) {
|
|
2098
|
+
return true;
|
|
2099
|
+
}
|
|
2100
|
+
return normalizePathForCodexResumeIdentity(normalizedExpected) === normalizePathForCodexResumeIdentity(actual);
|
|
2101
|
+
}
|
|
1962
2102
|
function resolveInitialCodexPermissionMode(opts) {
|
|
1963
2103
|
if (opts.permissionMode) {
|
|
1964
2104
|
return opts.permissionMode;
|
|
@@ -2058,6 +2198,20 @@ async function runCodex(opts) {
|
|
|
2058
2198
|
}
|
|
2059
2199
|
});
|
|
2060
2200
|
sessionClient = initialSession;
|
|
2201
|
+
const metadataCodexSessionCwd = typeof metadata.codexSessionCwd === "string" ? metadata.codexSessionCwd : null;
|
|
2202
|
+
const requestedResumeSessionId = normalizedArgs.resumeSessionId;
|
|
2203
|
+
const requestedResumeCwd = opts.resumeSessionCwd ?? metadataCodexSessionCwd;
|
|
2204
|
+
const resumeSessionMatchesCwd = requestedResumeSessionId ? codexResumeCwdMatches(requestedResumeCwd, metadata.path) && isCodexResumeSessionValidForCwd(requestedResumeSessionId, metadata.path) : false;
|
|
2205
|
+
const initialCodexSessionId = requestedResumeSessionId && resumeSessionMatchesCwd ? requestedResumeSessionId : null;
|
|
2206
|
+
if (requestedResumeSessionId && !resumeSessionMatchesCwd) {
|
|
2207
|
+
persistence.logger.debug(`[codex] Ignoring resume session ${requestedResumeSessionId} because it does not match cwd ${metadata.path}`);
|
|
2208
|
+
sessionClient.updateMetadata((currentMetadata) => {
|
|
2209
|
+
const nextMetadata = { ...currentMetadata };
|
|
2210
|
+
delete nextMetadata.codexSessionId;
|
|
2211
|
+
delete nextMetadata.codexSessionCwd;
|
|
2212
|
+
return nextMetadata;
|
|
2213
|
+
});
|
|
2214
|
+
}
|
|
2061
2215
|
const messageQueue = new registerKillSessionHandler.MessageQueue2(getCodexExecutionFingerprint);
|
|
2062
2216
|
let currentPermissionMode = initialPermissionMode;
|
|
2063
2217
|
let currentModel;
|
|
@@ -2104,7 +2258,7 @@ async function runCodex(opts) {
|
|
|
2104
2258
|
path: metadata.path,
|
|
2105
2259
|
logPath: persistence.logger.logFilePath,
|
|
2106
2260
|
startupRolePrompt: happyOrgStartupBinding?.identityPrompt ?? null,
|
|
2107
|
-
sessionId:
|
|
2261
|
+
sessionId: initialCodexSessionId,
|
|
2108
2262
|
mode: requestedStartingMode,
|
|
2109
2263
|
messageQueue,
|
|
2110
2264
|
codexArgs: normalizedArgs.codexArgs,
|
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
var ink = require('ink');
|
|
4
4
|
var React = require('react');
|
|
5
5
|
var node_crypto = require('node:crypto');
|
|
6
|
-
var persistence = require('./api-
|
|
7
|
-
var registerKillSessionHandler = require('./registerKillSessionHandler-
|
|
8
|
-
var index = require('./index-
|
|
9
|
-
var BaseReasoningProcessor = require('./BaseReasoningProcessor-
|
|
6
|
+
var persistence = require('./api-D4JOaMll.cjs');
|
|
7
|
+
var registerKillSessionHandler = require('./registerKillSessionHandler-Bo_MMbdY.cjs');
|
|
8
|
+
var index = require('./index-CZJH0CUT.cjs');
|
|
9
|
+
var BaseReasoningProcessor = require('./BaseReasoningProcessor-D3q5lh9h.cjs');
|
|
10
10
|
require('cross-spawn');
|
|
11
11
|
require('@agentclientprotocol/sdk');
|
|
12
12
|
require('ps-list');
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { useStdout, useInput, Box, Text, render } from 'ink';
|
|
2
2
|
import React, { useState, useRef, useEffect, useCallback } from 'react';
|
|
3
3
|
import { randomUUID } from 'node:crypto';
|
|
4
|
-
import { l as logger, b as connectionState, A as ApiClient, h as hashObject, d as AssistantMessageStream } from './api-
|
|
5
|
-
import { B as BasePermissionHandler, C as ConversationHistory$1, r as resolveHappyOrgQueuedTurn, e as ensureManagedProviderMachine, M as MissingMachineIdError, s as syncControlledByUserState, b as MessageQueue2, c as registerKillSessionHandler, d as MessageBuffer, f as buildHappyOrgTurnPrompt, w as waitForResponseCompleteWithAbort, h as finalizeHappyOrgTurnWithBusinessAck, i as buildTurnResultPushNotification, j as buildReadyPushNotification, l as launchRuntimeHandleWithFactoryResult, k as extractPermissionRequestPushContext, m as buildPermissionPushNotification, n as renderTerminalOutputPreview, p as prepareTerminalOutputForForwarding, o as inferToolResultError, q as forwardAgentMessageToProviderSession, t as createSessionTranscriptInkRenderer } from './registerKillSessionHandler-
|
|
6
|
-
import { g as getInitialGeminiModel, r as readGeminiLocalConfig, G as GEMINI_MODEL_ENV, b as closeProviderSession, s as saveGeminiModelToConfig, d as createGeminiBackend, e as stopCaffeinate } from './index-
|
|
7
|
-
import { B as BaseReasoningProcessor, b as bootstrapManagedProviderSession } from './BaseReasoningProcessor-
|
|
4
|
+
import { l as logger, b as connectionState, A as ApiClient, h as hashObject, d as AssistantMessageStream } from './api-6B4EMs47.mjs';
|
|
5
|
+
import { B as BasePermissionHandler, C as ConversationHistory$1, r as resolveHappyOrgQueuedTurn, e as ensureManagedProviderMachine, M as MissingMachineIdError, s as syncControlledByUserState, b as MessageQueue2, c as registerKillSessionHandler, d as MessageBuffer, f as buildHappyOrgTurnPrompt, w as waitForResponseCompleteWithAbort, h as finalizeHappyOrgTurnWithBusinessAck, i as buildTurnResultPushNotification, j as buildReadyPushNotification, l as launchRuntimeHandleWithFactoryResult, k as extractPermissionRequestPushContext, m as buildPermissionPushNotification, n as renderTerminalOutputPreview, p as prepareTerminalOutputForForwarding, o as inferToolResultError, q as forwardAgentMessageToProviderSession, t as createSessionTranscriptInkRenderer } from './registerKillSessionHandler-ggfGac_S.mjs';
|
|
6
|
+
import { g as getInitialGeminiModel, r as readGeminiLocalConfig, G as GEMINI_MODEL_ENV, b as closeProviderSession, s as saveGeminiModelToConfig, d as createGeminiBackend, e as stopCaffeinate } from './index-CyGHrYHl.mjs';
|
|
7
|
+
import { B as BaseReasoningProcessor, b as bootstrapManagedProviderSession } from './BaseReasoningProcessor-2qoX8OA1.mjs';
|
|
8
8
|
import 'cross-spawn';
|
|
9
9
|
import '@agentclientprotocol/sdk';
|
|
10
10
|
import 'ps-list';
|