happy-imou-cloud 2.1.44 → 2.1.46
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-CMyFNQ1O.cjs → BaseReasoningProcessor-Bsnew7fc.cjs} +2 -2
- package/dist/{BaseReasoningProcessor-DVSN7PCw.mjs → BaseReasoningProcessor-Mrdbmfl3.mjs} +2 -2
- package/dist/{ProviderSelectionHandler-2IaDlDBx.mjs → ProviderSelectionHandler-BymmO261.mjs} +2 -2
- package/dist/{ProviderSelectionHandler-Dqa4j1pD.cjs → ProviderSelectionHandler-gaUVvyCU.cjs} +2 -2
- package/dist/{api-BoWVQeVe.cjs → api-Bekjk9d5.cjs} +104 -1
- package/dist/{api-BhMVpzwg.mjs → api-DTSpLLTK.mjs} +104 -2
- package/dist/{command-DoF8oaxg.cjs → command-BwhJX0G5.cjs} +2 -2
- package/dist/{command-h3Rr4Abu.mjs → command-umgXYSY2.mjs} +2 -2
- package/dist/{index-DxF1W0nt.mjs → index-CUVIZLuf.mjs} +270 -29
- package/dist/{index-kIN8gN9G.cjs → index-DkaYNlRO.cjs} +274 -30
- package/dist/index.cjs +2 -2
- package/dist/index.mjs +2 -2
- package/dist/lib.cjs +1 -1
- package/dist/lib.d.cts +86 -86
- package/dist/lib.d.mts +86 -86
- package/dist/lib.mjs +1 -1
- package/dist/{registerKillSessionHandler-CBm2WFM0.cjs → registerKillSessionHandler-BYWJJDre.cjs} +10 -5
- package/dist/{registerKillSessionHandler-Dsg63Cx6.mjs → registerKillSessionHandler-hQE08yMO.mjs} +10 -6
- package/dist/{runClaude-BpwlCyVT.mjs → runClaude-CFeIMCY2.mjs} +11 -8
- package/dist/{runClaude-Dq9OISKt.cjs → runClaude-jpo2aFey.cjs} +11 -8
- package/dist/{runCodex-BMNR2hNp.mjs → runCodex-ByjUfTyr.mjs} +496 -59
- package/dist/{runCodex-BnzErOK_.cjs → runCodex-CrxyWcga.cjs} +496 -59
- package/dist/{runGemini-CYc9Ufxo.cjs → runGemini-BhIz1N_b.cjs} +11 -8
- package/dist/{runGemini-D4Af8oH1.mjs → runGemini-CihCRgcR.mjs} +11 -8
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import{createRequire as _pkgrollCR}from"node:module";const require=_pkgrollCR(import.meta.url);import chalk from 'chalk';
|
|
2
|
-
import { l as logger, q as encodeBase64, c as configuration, t as readCredentials, u as ensureSigningCredentials, r as readSettings, v as updateSettings, w as encodeBase64Url, m as delay, x as buildClientHeaders, y as decodeBase64, z as writeCredentialsLegacy, B as writeCredentialsDataKey, C as readDaemonState, D as HAPPY_CLOUD_DAEMON_PORT, E as clearDaemonState, F as packageJson, i as isAuthenticationRequiredError, G as
|
|
2
|
+
import { l as logger, q as encodeBase64, c as configuration, t as readCredentials, u as ensureSigningCredentials, r as readSettings, v as updateSettings, w as encodeBase64Url, m as delay, x as buildClientHeaders, y as decodeBase64, z as writeCredentialsLegacy, B as writeCredentialsDataKey, C as readDaemonState, D as HAPPY_CLOUD_DAEMON_PORT, E as clearDaemonState, F as packageJson, i as isAuthenticationRequiredError, G as buildSessionRuntimeIndex, I as acquireDaemonLock, J as writeDaemonState, A as ApiClient, K as releaseDaemonLock, L as validateProfileForAgent, M as getProfileEnvironmentVariables, N as clearCredentials, O as clearMachineId, P as readHappyOrgDispatchTruthSnapshot, Q as processHappyOrgRepoRequests, R as readHappyOrgRepoTaskBoard, S as HappyOrgTurnReportSchema, T as recordHappyOrgTurnReport, U as MessageContentSchema, V as buildSocketAuth, W as encrypt, H as HeadTailPreviewBuffer, X as getLatestDaemonLog } from './api-DTSpLLTK.mjs';
|
|
3
3
|
import { z } from 'zod';
|
|
4
4
|
import fs, { writeFile as writeFile$1, rename, unlink as unlink$1 } from 'fs/promises';
|
|
5
5
|
import os$1, { homedir } from 'os';
|
|
@@ -11,7 +11,7 @@ import qrcode from 'qrcode-terminal';
|
|
|
11
11
|
import { writeFile, unlink, readdir, readFile, mkdir } from 'node:fs/promises';
|
|
12
12
|
import { createRequire } from 'node:module';
|
|
13
13
|
import os, { tmpdir, homedir as homedir$1 } from 'node:os';
|
|
14
|
-
import path, { join, resolve as resolve$1, dirname as dirname$1, normalize, isAbsolute, delimiter, basename } from 'node:path';
|
|
14
|
+
import path, { join, resolve as resolve$1, dirname as dirname$1, normalize, isAbsolute, delimiter, relative, basename } from 'node:path';
|
|
15
15
|
import open from 'open';
|
|
16
16
|
import React, { useState } from 'react';
|
|
17
17
|
import { useInput, Box, Text, render } from 'ink';
|
|
@@ -2830,16 +2830,27 @@ function createSessionMetadata(opts) {
|
|
|
2830
2830
|
};
|
|
2831
2831
|
}
|
|
2832
2832
|
|
|
2833
|
+
function archiveManagedSessionWithObserver(opts) {
|
|
2834
|
+
if (!opts.userScopedObserver || !opts.sessionIndex) {
|
|
2835
|
+
return false;
|
|
2836
|
+
}
|
|
2837
|
+
return opts.userScopedObserver.syncSessionRuntimeIndex(opts.sessionId, {
|
|
2838
|
+
...opts.sessionIndex,
|
|
2839
|
+
lifecycleState: "archived"
|
|
2840
|
+
}, {
|
|
2841
|
+
markInactive: true
|
|
2842
|
+
});
|
|
2843
|
+
}
|
|
2833
2844
|
async function archiveManagedSessionById(opts) {
|
|
2834
2845
|
try {
|
|
2835
|
-
const sessionClient = opts.api.sessionSyncClient(
|
|
2846
|
+
const sessionClient = opts.api.sessionSyncClient(opts.session);
|
|
2836
2847
|
await closeProviderSession(sessionClient, {
|
|
2837
2848
|
archiveReason: opts.archiveReason,
|
|
2838
2849
|
archivedBy: "daemon"
|
|
2839
2850
|
});
|
|
2840
2851
|
} catch (error) {
|
|
2841
2852
|
logger.debug(
|
|
2842
|
-
`[DAEMON RUN] Failed to archive managed session ${opts.
|
|
2853
|
+
`[DAEMON RUN] Failed to archive managed session ${opts.session.id}: ${opts.archiveReason}`,
|
|
2843
2854
|
error
|
|
2844
2855
|
);
|
|
2845
2856
|
}
|
|
@@ -2868,7 +2879,7 @@ async function precreateDaemonManagedSession(opts) {
|
|
|
2868
2879
|
async function archivePrecreatedManagedSession(opts) {
|
|
2869
2880
|
await archiveManagedSessionById({
|
|
2870
2881
|
api: opts.api,
|
|
2871
|
-
|
|
2882
|
+
session: opts.session,
|
|
2872
2883
|
archiveReason: opts.archiveReason
|
|
2873
2884
|
});
|
|
2874
2885
|
}
|
|
@@ -2877,11 +2888,15 @@ async function archiveDetachedManagedSessionIfNeeded(opts) {
|
|
|
2877
2888
|
if (trackedSession.startedBy !== "daemon" || !trackedSession.happySessionId || trackedSession.happySessionMetadataFromLocalWebhook || trackedSession.skipDetachedManagedSessionArchive) {
|
|
2878
2889
|
return false;
|
|
2879
2890
|
}
|
|
2880
|
-
|
|
2881
|
-
|
|
2891
|
+
if (!archiveManagedSessionWithObserver({
|
|
2892
|
+
userScopedObserver: opts.userScopedObserver,
|
|
2882
2893
|
sessionId: trackedSession.happySessionId,
|
|
2883
|
-
|
|
2884
|
-
})
|
|
2894
|
+
sessionIndex: trackedSession.sessionIndex
|
|
2895
|
+
})) {
|
|
2896
|
+
logger.debug(
|
|
2897
|
+
`[DAEMON RUN] Detached managed session ${trackedSession.happySessionId} cannot be archived because runtime index sync is unavailable`
|
|
2898
|
+
);
|
|
2899
|
+
}
|
|
2885
2900
|
return true;
|
|
2886
2901
|
}
|
|
2887
2902
|
|
|
@@ -2959,6 +2974,7 @@ function createTrackedSessionFromRemoteIndexEntry(entry) {
|
|
|
2959
2974
|
return {
|
|
2960
2975
|
startedBy,
|
|
2961
2976
|
happySessionId: entry.id,
|
|
2977
|
+
sessionIndex: entry.sessionIndex ?? null,
|
|
2962
2978
|
pid: entry.sessionIndex?.hostPid ?? 0
|
|
2963
2979
|
};
|
|
2964
2980
|
}
|
|
@@ -2985,6 +3001,7 @@ async function recoverTrackedSessionsFromRemoteIndex({
|
|
|
2985
3001
|
machineId,
|
|
2986
3002
|
trackedSessionPids,
|
|
2987
3003
|
trackSession,
|
|
3004
|
+
removeTrackedSession,
|
|
2988
3005
|
userScopedObserver,
|
|
2989
3006
|
lookupHappyProcessByPid = findHappyProcessByPid,
|
|
2990
3007
|
archiveStaleSessions = true,
|
|
@@ -2999,7 +3016,13 @@ async function recoverTrackedSessionsFromRemoteIndex({
|
|
|
2999
3016
|
for (const session of sessions) {
|
|
3000
3017
|
const sessionIndex = session.sessionIndex;
|
|
3001
3018
|
const pid = sessionIndex?.hostPid;
|
|
3002
|
-
if (!sessionIndex || sessionIndex.machineId !== machineId || typeof pid !== "number"
|
|
3019
|
+
if (!sessionIndex || sessionIndex.machineId !== machineId || typeof pid !== "number") {
|
|
3020
|
+
continue;
|
|
3021
|
+
}
|
|
3022
|
+
if (sessionIndex.lifecycleState === "archived" || session.active === false) {
|
|
3023
|
+
if (alreadyTracked.has(pid)) {
|
|
3024
|
+
removeTrackedSession?.(pid, session.id);
|
|
3025
|
+
}
|
|
3003
3026
|
continue;
|
|
3004
3027
|
}
|
|
3005
3028
|
if (alreadyTracked.has(pid)) {
|
|
@@ -3039,6 +3062,7 @@ async function recoverTrackedSessionsFromRemoteIndex({
|
|
|
3039
3062
|
}
|
|
3040
3063
|
const archived = await archiveStaleRemoteSession(userScopedObserver, session);
|
|
3041
3064
|
if (archived) {
|
|
3065
|
+
removeTrackedSession?.(pid, session.id);
|
|
3042
3066
|
archivedStaleCount++;
|
|
3043
3067
|
} else {
|
|
3044
3068
|
skippedStaleCount++;
|
|
@@ -3107,6 +3131,7 @@ function createTrackedSessionFromRegistryEntry(entry) {
|
|
|
3107
3131
|
startedBy: metadata.startedBy === "daemon" ? "daemon" : "happy directly - likely by user from terminal",
|
|
3108
3132
|
happySessionId: entry.sessionId,
|
|
3109
3133
|
happySessionMetadataFromLocalWebhook: metadata,
|
|
3134
|
+
sessionIndex: buildSessionRuntimeIndex(metadata),
|
|
3110
3135
|
pid: entry.pid
|
|
3111
3136
|
};
|
|
3112
3137
|
}
|
|
@@ -3499,11 +3524,13 @@ async function startDaemon() {
|
|
|
3499
3524
|
const pidToTrackedSession = /* @__PURE__ */ new Map();
|
|
3500
3525
|
const pidToAwaiter = /* @__PURE__ */ new Map();
|
|
3501
3526
|
const getCurrentChildren = () => Array.from(pidToTrackedSession.values());
|
|
3527
|
+
let userScopedObserver = null;
|
|
3502
3528
|
const removeTrackedSession = (pid, archiveReason) => {
|
|
3503
3529
|
const trackedSession = pidToTrackedSession.get(pid);
|
|
3504
3530
|
if (trackedSession && api) {
|
|
3505
3531
|
void archiveDetachedManagedSessionIfNeeded({
|
|
3506
3532
|
api,
|
|
3533
|
+
userScopedObserver,
|
|
3507
3534
|
trackedSession,
|
|
3508
3535
|
archiveReason
|
|
3509
3536
|
});
|
|
@@ -3523,6 +3550,7 @@ async function startDaemon() {
|
|
|
3523
3550
|
if (existingSession && existingSession.startedBy === "daemon") {
|
|
3524
3551
|
existingSession.happySessionId = sessionId;
|
|
3525
3552
|
existingSession.happySessionMetadataFromLocalWebhook = sessionMetadata;
|
|
3553
|
+
existingSession.sessionIndex = buildSessionRuntimeIndex(sessionMetadata);
|
|
3526
3554
|
logger.debug(`[DAEMON RUN] Updated daemon-spawned session ${sessionId} with metadata`);
|
|
3527
3555
|
const awaiter = pidToAwaiter.get(pid);
|
|
3528
3556
|
if (awaiter) {
|
|
@@ -3538,6 +3566,7 @@ async function startDaemon() {
|
|
|
3538
3566
|
startedBy: "happy directly - likely by user from terminal",
|
|
3539
3567
|
happySessionId: sessionId,
|
|
3540
3568
|
happySessionMetadataFromLocalWebhook: sessionMetadata,
|
|
3569
|
+
sessionIndex: buildSessionRuntimeIndex(sessionMetadata),
|
|
3541
3570
|
pid
|
|
3542
3571
|
};
|
|
3543
3572
|
pidToTrackedSession.set(pid, trackedSession);
|
|
@@ -3696,6 +3725,7 @@ async function startDaemon() {
|
|
|
3696
3725
|
requestedSessionId: options.sessionId,
|
|
3697
3726
|
precreatedSessionId: precreatedCodexSession?.id
|
|
3698
3727
|
}),
|
|
3728
|
+
sessionIndex: buildSessionRuntimeIndex(precreatedCodexSession?.metadata),
|
|
3699
3729
|
skipDetachedManagedSessionArchive: reuseExistingManagedSession,
|
|
3700
3730
|
pid: tmuxResult.pid,
|
|
3701
3731
|
// Real PID from tmux -P flag
|
|
@@ -3840,6 +3870,7 @@ ${stderrSnapshot}`);
|
|
|
3840
3870
|
requestedSessionId: options.sessionId,
|
|
3841
3871
|
precreatedSessionId: precreatedCodexSession?.id
|
|
3842
3872
|
}),
|
|
3873
|
+
sessionIndex: buildSessionRuntimeIndex(precreatedCodexSession?.metadata),
|
|
3843
3874
|
skipDetachedManagedSessionArchive: reuseExistingManagedSession,
|
|
3844
3875
|
pid: happyProcess.pid,
|
|
3845
3876
|
childProcess: happyProcess,
|
|
@@ -4028,7 +4059,6 @@ ${stderrSnapshot}`);
|
|
|
4028
4059
|
};
|
|
4029
4060
|
api = await ApiClient.create(credentials);
|
|
4030
4061
|
const activeApi = api;
|
|
4031
|
-
let userScopedObserver = null;
|
|
4032
4062
|
if (credentials.signing) {
|
|
4033
4063
|
try {
|
|
4034
4064
|
userScopedObserver = activeApi.userScopedObserverClient?.() ?? null;
|
|
@@ -4063,6 +4093,13 @@ ${stderrSnapshot}`);
|
|
|
4063
4093
|
trackSession: (pid, trackedSession) => {
|
|
4064
4094
|
pidToTrackedSession.set(pid, trackedSession);
|
|
4065
4095
|
},
|
|
4096
|
+
removeTrackedSession: (pid, sessionId) => {
|
|
4097
|
+
const trackedSession = pidToTrackedSession.get(pid);
|
|
4098
|
+
if (trackedSession?.happySessionId === sessionId) {
|
|
4099
|
+
pidToTrackedSession.delete(pid);
|
|
4100
|
+
logger.debug(`[DAEMON RUN] Removed archived remote session ${sessionId} from tracking`);
|
|
4101
|
+
}
|
|
4102
|
+
},
|
|
4066
4103
|
userScopedObserver,
|
|
4067
4104
|
archiveStaleSessions: opts.archiveStaleSessions,
|
|
4068
4105
|
skipArchivalSessionIds: pendingManagedRespawnSessionIds
|
|
@@ -8609,11 +8646,15 @@ class AcpBackend {
|
|
|
8609
8646
|
transport;
|
|
8610
8647
|
sessionPreferences;
|
|
8611
8648
|
sessionConfigOptions = null;
|
|
8649
|
+
agentCapabilities = null;
|
|
8612
8650
|
/** Keep a short rolling stderr buffer so startup failures can surface the real cause. */
|
|
8613
8651
|
recentStderrLines = [];
|
|
8614
8652
|
acpMaxMultilineStdoutBytes;
|
|
8615
8653
|
oversizedStdoutNoticeEmittedForCurrentTurn = false;
|
|
8616
8654
|
resourceCleanupDone = false;
|
|
8655
|
+
getProviderSessionId() {
|
|
8656
|
+
return this.acpSessionId;
|
|
8657
|
+
}
|
|
8617
8658
|
recordRecentStderr(text) {
|
|
8618
8659
|
const normalized = text.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
|
|
8619
8660
|
if (normalized.length === 0) {
|
|
@@ -8650,6 +8691,14 @@ class AcpBackend {
|
|
|
8650
8691
|
updateSessionConfigOptions(configOptions) {
|
|
8651
8692
|
this.sessionConfigOptions = Array.isArray(configOptions) ? configOptions : null;
|
|
8652
8693
|
}
|
|
8694
|
+
supportsLoadSession() {
|
|
8695
|
+
const capabilities = this.agentCapabilities;
|
|
8696
|
+
return capabilities?.loadSession === true;
|
|
8697
|
+
}
|
|
8698
|
+
supportsResumeSession() {
|
|
8699
|
+
const capabilities = this.agentCapabilities;
|
|
8700
|
+
return capabilities?.sessionCapabilities?.resume != null;
|
|
8701
|
+
}
|
|
8653
8702
|
syncSessionConfigOptionsFromUpdate(update) {
|
|
8654
8703
|
const configOptions = update.configOptions;
|
|
8655
8704
|
if (!Array.isArray(configOptions)) {
|
|
@@ -9231,7 +9280,7 @@ Recent stderr: ${recentStderrSummaryLine}` : `Signal: ${signal}`;
|
|
|
9231
9280
|
await delay(initDelayMs);
|
|
9232
9281
|
}
|
|
9233
9282
|
logger.debug(`[AcpBackend] Initializing connection (timeout: ${initTimeout}ms)...`);
|
|
9234
|
-
await withRetry(
|
|
9283
|
+
const initializeResponse = await withRetry(
|
|
9235
9284
|
async () => {
|
|
9236
9285
|
let timeoutHandle = null;
|
|
9237
9286
|
try {
|
|
@@ -9272,6 +9321,7 @@ Recent stderr: ${recentStderrSummaryLine}` : `Signal: ${signal}`;
|
|
|
9272
9321
|
shouldRetry: (error) => !(error instanceof AcpProcessStartupError)
|
|
9273
9322
|
}
|
|
9274
9323
|
);
|
|
9324
|
+
this.agentCapabilities = initializeResponse.agentCapabilities ?? null;
|
|
9275
9325
|
logger.debug(`[AcpBackend] Initialize completed`);
|
|
9276
9326
|
const mcpServers = this.options.mcpServers ? Object.entries(this.options.mcpServers).map(([name, config]) => ({
|
|
9277
9327
|
name,
|
|
@@ -9283,7 +9333,21 @@ Recent stderr: ${recentStderrSummaryLine}` : `Signal: ${signal}`;
|
|
|
9283
9333
|
cwd: this.options.cwd,
|
|
9284
9334
|
mcpServers
|
|
9285
9335
|
};
|
|
9286
|
-
|
|
9336
|
+
const requestedResumeSessionId = typeof this.options.resumeSessionId === "string" && this.options.resumeSessionId.trim() ? this.options.resumeSessionId.trim() : null;
|
|
9337
|
+
const sessionOperation = requestedResumeSessionId && this.supportsResumeSession() ? "resume" : requestedResumeSessionId && this.supportsLoadSession() ? "load" : "new";
|
|
9338
|
+
const sessionRequest = sessionOperation === "resume" ? {
|
|
9339
|
+
cwd: this.options.cwd,
|
|
9340
|
+
mcpServers,
|
|
9341
|
+
sessionId: requestedResumeSessionId
|
|
9342
|
+
} : sessionOperation === "load" ? {
|
|
9343
|
+
cwd: this.options.cwd,
|
|
9344
|
+
mcpServers,
|
|
9345
|
+
sessionId: requestedResumeSessionId
|
|
9346
|
+
} : newSessionRequest;
|
|
9347
|
+
if (requestedResumeSessionId && sessionOperation === "new") {
|
|
9348
|
+
throw new Error("ACP agent does not support session resume/load; refusing to fork the Codex conversation");
|
|
9349
|
+
}
|
|
9350
|
+
logger.debug(`[AcpBackend] ${sessionOperation === "new" ? "Creating new" : `${sessionOperation === "resume" ? "Resuming" : "Loading"} existing`} session...`);
|
|
9287
9351
|
const sessionResponse = await withRetry(
|
|
9288
9352
|
async () => {
|
|
9289
9353
|
let timeoutHandle = null;
|
|
@@ -9291,7 +9355,7 @@ Recent stderr: ${recentStderrSummaryLine}` : `Signal: ${signal}`;
|
|
|
9291
9355
|
const result = await raceWithProcessExit(
|
|
9292
9356
|
this.process,
|
|
9293
9357
|
() => Promise.race([
|
|
9294
|
-
this.connection.newSession(
|
|
9358
|
+
(sessionOperation === "resume" ? this.connection.resumeSession(sessionRequest) : sessionOperation === "load" ? this.connection.loadSession(sessionRequest) : this.connection.newSession(sessionRequest)).then((res) => {
|
|
9295
9359
|
if (timeoutHandle) {
|
|
9296
9360
|
clearTimeout(timeoutHandle);
|
|
9297
9361
|
timeoutHandle = null;
|
|
@@ -9318,14 +9382,14 @@ Recent stderr: ${recentStderrSummaryLine}` : `Signal: ${signal}`;
|
|
|
9318
9382
|
}
|
|
9319
9383
|
},
|
|
9320
9384
|
{
|
|
9321
|
-
operationName: "NewSession",
|
|
9385
|
+
operationName: sessionOperation === "resume" ? "ResumeSession" : sessionOperation === "load" ? "LoadSession" : "NewSession",
|
|
9322
9386
|
maxAttempts: RETRY_CONFIG.maxAttempts,
|
|
9323
9387
|
baseDelayMs: RETRY_CONFIG.baseDelayMs,
|
|
9324
9388
|
maxDelayMs: RETRY_CONFIG.maxDelayMs,
|
|
9325
9389
|
shouldRetry: (error) => !(error instanceof AcpProcessStartupError)
|
|
9326
9390
|
}
|
|
9327
9391
|
);
|
|
9328
|
-
this.acpSessionId = sessionResponse.sessionId;
|
|
9392
|
+
this.acpSessionId = requestedResumeSessionId ?? sessionResponse.sessionId;
|
|
9329
9393
|
this.updateSessionConfigOptions(sessionResponse.configOptions);
|
|
9330
9394
|
logger.debug(`[AcpBackend] Session created: ${this.acpSessionId}`);
|
|
9331
9395
|
await this.applySessionConfigPresets();
|
|
@@ -10004,8 +10068,23 @@ function readCodexAcpConfigOverrides() {
|
|
|
10004
10068
|
const raw = readFirstEnv("HAPPY_CODEX_ACP_CONFIG_OVERRIDES", "HAPPIER_CODEX_ACP_CONFIG_OVERRIDES");
|
|
10005
10069
|
return raw.split("\n").map((line) => line.trim()).filter(Boolean);
|
|
10006
10070
|
}
|
|
10071
|
+
function sanitizeCodexAcpBaseArgs(baseArgs = []) {
|
|
10072
|
+
const sanitized = [];
|
|
10073
|
+
for (let index = 0; index < baseArgs.length; index += 1) {
|
|
10074
|
+
const arg = baseArgs[index];
|
|
10075
|
+
if (arg === "--dangerously-bypass-approvals-and-sandbox" || arg === "--yolo" || arg.startsWith("--ask-for-approval=") || arg.startsWith("--approval-policy=") || arg.startsWith("--sandbox=")) {
|
|
10076
|
+
continue;
|
|
10077
|
+
}
|
|
10078
|
+
if (arg === "--ask-for-approval" || arg === "--approval-policy" || arg === "--sandbox") {
|
|
10079
|
+
index += 1;
|
|
10080
|
+
continue;
|
|
10081
|
+
}
|
|
10082
|
+
sanitized.push(arg);
|
|
10083
|
+
}
|
|
10084
|
+
return sanitized;
|
|
10085
|
+
}
|
|
10007
10086
|
function buildCodexAcpConfigArgs(options) {
|
|
10008
|
-
const args =
|
|
10087
|
+
const args = sanitizeCodexAcpBaseArgs(options.baseArgs);
|
|
10009
10088
|
const overrides = [...readCodexAcpConfigOverrides()];
|
|
10010
10089
|
if (options.model) {
|
|
10011
10090
|
overrides.push(`model=${JSON.stringify(options.model)}`);
|
|
@@ -10134,6 +10213,9 @@ function resolveCodexExecutable() {
|
|
|
10134
10213
|
}
|
|
10135
10214
|
return "codex";
|
|
10136
10215
|
}
|
|
10216
|
+
function shouldUseShellForCodex(executable) {
|
|
10217
|
+
return process.platform === "win32" && /\.(cmd|bat|ps1)$/i.test(executable);
|
|
10218
|
+
}
|
|
10137
10219
|
|
|
10138
10220
|
const CODEX_HOME_SEED_FILES = [
|
|
10139
10221
|
"auth.json",
|
|
@@ -10147,6 +10229,24 @@ const CODEX_HOME_SEED_DIRS = [
|
|
|
10147
10229
|
];
|
|
10148
10230
|
const MAX_CODEX_SKILL_DESCRIPTION_LENGTH = 1024;
|
|
10149
10231
|
const MANAGED_CODEX_HOME_PREFIX = "happy-codex-home-";
|
|
10232
|
+
function isPlainObject(value) {
|
|
10233
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
10234
|
+
}
|
|
10235
|
+
function isApiKeyOnlyCodexAuth(value) {
|
|
10236
|
+
if (!isPlainObject(value)) {
|
|
10237
|
+
return false;
|
|
10238
|
+
}
|
|
10239
|
+
const entries = Object.entries(value).filter(([, entryValue]) => entryValue !== void 0 && entryValue !== null);
|
|
10240
|
+
return entries.length === 1 && typeof value.OPENAI_API_KEY === "string" && value.OPENAI_API_KEY.trim().length > 0;
|
|
10241
|
+
}
|
|
10242
|
+
function shouldUseSourceCodexHomeForMutableAuth(sourceHomeDir) {
|
|
10243
|
+
try {
|
|
10244
|
+
const auth = JSON.parse(readFileSync(join(sourceHomeDir, "auth.json"), "utf8"));
|
|
10245
|
+
return !isApiKeyOnlyCodexAuth(auth);
|
|
10246
|
+
} catch {
|
|
10247
|
+
return false;
|
|
10248
|
+
}
|
|
10249
|
+
}
|
|
10150
10250
|
function getCodexPlatformTarget(platform, arch) {
|
|
10151
10251
|
if (platform === "win32" && arch === "x64") {
|
|
10152
10252
|
return {
|
|
@@ -10410,7 +10510,135 @@ function seedCodexSkillEntries(sourceSkillsDir, isolatedHomeDir, sourceLabel) {
|
|
|
10410
10510
|
}
|
|
10411
10511
|
}
|
|
10412
10512
|
}
|
|
10413
|
-
function
|
|
10513
|
+
function isWithinDirectory(parentDir, childPath, platform) {
|
|
10514
|
+
const normalizedParent = normalizePathForComparison(parentDir, platform);
|
|
10515
|
+
const normalizedChild = normalizePathForComparison(childPath, platform);
|
|
10516
|
+
return normalizedChild === normalizedParent || normalizedChild.startsWith(`${normalizedParent}/`);
|
|
10517
|
+
}
|
|
10518
|
+
function extractCodexSessionIdFromFilePath(filePath) {
|
|
10519
|
+
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$/);
|
|
10520
|
+
return match?.[1] ?? null;
|
|
10521
|
+
}
|
|
10522
|
+
function findCodexSessionFile(sourceHomeDir, resumeSessionId, platform) {
|
|
10523
|
+
const sessionsRoot = join(sourceHomeDir, "sessions");
|
|
10524
|
+
const stack = [sessionsRoot];
|
|
10525
|
+
let bestMatch = null;
|
|
10526
|
+
while (stack.length > 0) {
|
|
10527
|
+
const currentDir = stack.pop();
|
|
10528
|
+
let entries;
|
|
10529
|
+
try {
|
|
10530
|
+
entries = readdirSync(currentDir, { withFileTypes: true });
|
|
10531
|
+
} catch {
|
|
10532
|
+
continue;
|
|
10533
|
+
}
|
|
10534
|
+
for (const entry of entries) {
|
|
10535
|
+
const fullPath = join(currentDir, entry.name);
|
|
10536
|
+
if (!isWithinDirectory(sessionsRoot, fullPath, platform)) {
|
|
10537
|
+
continue;
|
|
10538
|
+
}
|
|
10539
|
+
if (entry.isDirectory()) {
|
|
10540
|
+
stack.push(fullPath);
|
|
10541
|
+
continue;
|
|
10542
|
+
}
|
|
10543
|
+
if (!entry.isFile() || extractCodexSessionIdFromFilePath(fullPath) !== resumeSessionId) {
|
|
10544
|
+
continue;
|
|
10545
|
+
}
|
|
10546
|
+
try {
|
|
10547
|
+
const mtimeMs = statSync(fullPath).mtimeMs;
|
|
10548
|
+
if (!bestMatch || mtimeMs > bestMatch.mtimeMs) {
|
|
10549
|
+
bestMatch = { path: fullPath, mtimeMs };
|
|
10550
|
+
}
|
|
10551
|
+
} catch {
|
|
10552
|
+
}
|
|
10553
|
+
}
|
|
10554
|
+
}
|
|
10555
|
+
return bestMatch?.path ?? null;
|
|
10556
|
+
}
|
|
10557
|
+
function seedCodexResumeSessionFile(sourceHomeDir, isolatedHomeDir, resumeSessionId, platform) {
|
|
10558
|
+
const normalizedResumeSessionId = typeof resumeSessionId === "string" && resumeSessionId.trim() ? resumeSessionId.trim() : null;
|
|
10559
|
+
if (!normalizedResumeSessionId) {
|
|
10560
|
+
return;
|
|
10561
|
+
}
|
|
10562
|
+
const sourceSessionFile = findCodexSessionFile(sourceHomeDir, normalizedResumeSessionId, platform);
|
|
10563
|
+
if (!sourceSessionFile) {
|
|
10564
|
+
logger.debug(`[codex] No source CODEX_HOME session file found for resume id ${normalizedResumeSessionId}`);
|
|
10565
|
+
return;
|
|
10566
|
+
}
|
|
10567
|
+
const sourceSessionsRoot = join(sourceHomeDir, "sessions");
|
|
10568
|
+
const relativeSessionPath = relative(sourceSessionsRoot, sourceSessionFile);
|
|
10569
|
+
if (!relativeSessionPath || relativeSessionPath.startsWith("..") || isAbsolute(relativeSessionPath)) {
|
|
10570
|
+
logger.debug(`[codex] Refusing to seed CODEX_HOME session outside sessions root: ${sourceSessionFile}`);
|
|
10571
|
+
return;
|
|
10572
|
+
}
|
|
10573
|
+
try {
|
|
10574
|
+
copyCodexHomeEntry(
|
|
10575
|
+
sourceSessionFile,
|
|
10576
|
+
join(isolatedHomeDir, "sessions", relativeSessionPath)
|
|
10577
|
+
);
|
|
10578
|
+
} catch (error) {
|
|
10579
|
+
logger.debug(`[codex] Failed to seed CODEX_HOME session file for ${normalizedResumeSessionId}`, error);
|
|
10580
|
+
}
|
|
10581
|
+
}
|
|
10582
|
+
function shouldSyncCodexSessionFileBack(sourcePath, destPath) {
|
|
10583
|
+
let sourceStat;
|
|
10584
|
+
try {
|
|
10585
|
+
sourceStat = statSync(sourcePath);
|
|
10586
|
+
} catch {
|
|
10587
|
+
return false;
|
|
10588
|
+
}
|
|
10589
|
+
if (!sourceStat.isFile()) {
|
|
10590
|
+
return false;
|
|
10591
|
+
}
|
|
10592
|
+
let destStat;
|
|
10593
|
+
try {
|
|
10594
|
+
destStat = statSync(destPath);
|
|
10595
|
+
} catch {
|
|
10596
|
+
return true;
|
|
10597
|
+
}
|
|
10598
|
+
return sourceStat.mtimeMs >= destStat.mtimeMs || sourceStat.size !== destStat.size;
|
|
10599
|
+
}
|
|
10600
|
+
function syncCodexSessionFilesBackToSource(isolatedHomeDir, sourceHomeDir, platform) {
|
|
10601
|
+
const isolatedSessionsRoot = join(isolatedHomeDir, "sessions");
|
|
10602
|
+
const sourceSessionsRoot = join(sourceHomeDir, "sessions");
|
|
10603
|
+
const stack = [isolatedSessionsRoot];
|
|
10604
|
+
while (stack.length > 0) {
|
|
10605
|
+
const currentDir = stack.pop();
|
|
10606
|
+
let entries;
|
|
10607
|
+
try {
|
|
10608
|
+
entries = readdirSync(currentDir, { withFileTypes: true });
|
|
10609
|
+
} catch {
|
|
10610
|
+
continue;
|
|
10611
|
+
}
|
|
10612
|
+
for (const entry of entries) {
|
|
10613
|
+
const fullPath = join(currentDir, entry.name);
|
|
10614
|
+
if (!isWithinDirectory(isolatedSessionsRoot, fullPath, platform)) {
|
|
10615
|
+
continue;
|
|
10616
|
+
}
|
|
10617
|
+
if (entry.isDirectory()) {
|
|
10618
|
+
stack.push(fullPath);
|
|
10619
|
+
continue;
|
|
10620
|
+
}
|
|
10621
|
+
if (!entry.isFile() || extractCodexSessionIdFromFilePath(fullPath) === null) {
|
|
10622
|
+
continue;
|
|
10623
|
+
}
|
|
10624
|
+
const relativeSessionPath = relative(isolatedSessionsRoot, fullPath);
|
|
10625
|
+
if (!relativeSessionPath || relativeSessionPath.startsWith("..") || isAbsolute(relativeSessionPath)) {
|
|
10626
|
+
logger.debug(`[codex] Refusing to sync CODEX_HOME session outside sessions root: ${fullPath}`);
|
|
10627
|
+
continue;
|
|
10628
|
+
}
|
|
10629
|
+
const destPath = join(sourceSessionsRoot, relativeSessionPath);
|
|
10630
|
+
if (!shouldSyncCodexSessionFileBack(fullPath, destPath)) {
|
|
10631
|
+
continue;
|
|
10632
|
+
}
|
|
10633
|
+
try {
|
|
10634
|
+
copyCodexHomeEntry(fullPath, destPath);
|
|
10635
|
+
} catch (error) {
|
|
10636
|
+
logger.debug(`[codex] Failed to sync CODEX_HOME session file back to source: ${fullPath}`, error);
|
|
10637
|
+
}
|
|
10638
|
+
}
|
|
10639
|
+
}
|
|
10640
|
+
}
|
|
10641
|
+
function seedIsolatedCodexHome(sourceHomeDir, isolatedHomeDir, bundledSkillsDir, resumeSessionId, platform) {
|
|
10414
10642
|
if (existsSync(sourceHomeDir)) {
|
|
10415
10643
|
for (const fileName of CODEX_HOME_SEED_FILES) {
|
|
10416
10644
|
try {
|
|
@@ -10431,6 +10659,7 @@ function seedIsolatedCodexHome(sourceHomeDir, isolatedHomeDir, bundledSkillsDir)
|
|
|
10431
10659
|
seedCodexSkillEntries(bundledSkillsDir, isolatedHomeDir, "bundled skills");
|
|
10432
10660
|
}
|
|
10433
10661
|
seedCodexSkillEntries(join(sourceHomeDir, "skills"), isolatedHomeDir, "source CODEX_HOME");
|
|
10662
|
+
seedCodexResumeSessionFile(sourceHomeDir, isolatedHomeDir, resumeSessionId, platform);
|
|
10434
10663
|
}
|
|
10435
10664
|
function prepareCodexAcpEnvironment(overrides = {}, options = {}) {
|
|
10436
10665
|
const env = buildCodexAcpEnv(overrides, options);
|
|
@@ -10448,17 +10677,26 @@ function prepareCodexAcpEnvironment(overrides = {}, options = {}) {
|
|
|
10448
10677
|
return { env };
|
|
10449
10678
|
}
|
|
10450
10679
|
}
|
|
10680
|
+
const sourceHomeDir = options.sourceHomeDir ?? join(homedir$1(), ".codex");
|
|
10681
|
+
const bundledSkillsDir = options.bundledSkillsDir ?? join(projectPath(), "skills");
|
|
10682
|
+
if (shouldUseSourceCodexHomeForMutableAuth(sourceHomeDir)) {
|
|
10683
|
+
logger.debug("[codex] Using source CODEX_HOME for mutable Codex auth credentials");
|
|
10684
|
+
env.CODEX_HOME = sourceHomeDir;
|
|
10685
|
+
return {
|
|
10686
|
+
env,
|
|
10687
|
+
codexHomePath: sourceHomeDir
|
|
10688
|
+
};
|
|
10689
|
+
}
|
|
10451
10690
|
const tempDirFactory = options.tempDirFactory ?? mkdtempSync;
|
|
10452
10691
|
const isolatedHomeDir = tempDirFactory(join(tmpdir(), "happy-codex-home-"));
|
|
10453
10692
|
mkdirSync$1(isolatedHomeDir, { recursive: true });
|
|
10454
|
-
|
|
10455
|
-
const bundledSkillsDir = options.bundledSkillsDir ?? join(projectPath(), "skills");
|
|
10456
|
-
seedIsolatedCodexHome(sourceHomeDir, isolatedHomeDir, bundledSkillsDir);
|
|
10693
|
+
seedIsolatedCodexHome(sourceHomeDir, isolatedHomeDir, bundledSkillsDir, options.resumeSessionId, platform);
|
|
10457
10694
|
env.CODEX_HOME = isolatedHomeDir;
|
|
10458
10695
|
return {
|
|
10459
10696
|
env,
|
|
10460
10697
|
codexHomePath: isolatedHomeDir,
|
|
10461
10698
|
cleanup: () => {
|
|
10699
|
+
syncCodexSessionFilesBackToSource(isolatedHomeDir, sourceHomeDir, platform);
|
|
10462
10700
|
rmSync(isolatedHomeDir, { recursive: true, force: true });
|
|
10463
10701
|
}
|
|
10464
10702
|
};
|
|
@@ -10491,6 +10729,8 @@ function createCodexBackend(options) {
|
|
|
10491
10729
|
const preparedEnv = prepareCodexAcpEnvironment({
|
|
10492
10730
|
...options.env,
|
|
10493
10731
|
NODE_ENV: "production"
|
|
10732
|
+
}, {
|
|
10733
|
+
resumeSessionId: options.resumeSessionId
|
|
10494
10734
|
});
|
|
10495
10735
|
const backendOptions = {
|
|
10496
10736
|
agentName: "codex",
|
|
@@ -10501,7 +10741,8 @@ function createCodexBackend(options) {
|
|
|
10501
10741
|
permissionHandler: options.permissionHandler,
|
|
10502
10742
|
selectionHandler: options.selectionHandler,
|
|
10503
10743
|
transportHandler: resolveCodexTransport(spawn.command),
|
|
10504
|
-
resourceCleanup: preparedEnv.cleanup
|
|
10744
|
+
resourceCleanup: preparedEnv.cleanup,
|
|
10745
|
+
resumeSessionId: options.resumeSessionId
|
|
10505
10746
|
};
|
|
10506
10747
|
return {
|
|
10507
10748
|
backend: new AcpBackend(backendOptions),
|
|
@@ -11935,14 +12176,14 @@ var launch = /*#__PURE__*/Object.freeze({
|
|
|
11935
12176
|
const unifiedProviderExecutors = {
|
|
11936
12177
|
claude: async (opts) => {
|
|
11937
12178
|
const claudeOptions = opts.claudeOptions ?? {};
|
|
11938
|
-
const { runClaude } = await import('./runClaude-
|
|
12179
|
+
const { runClaude } = await import('./runClaude-CFeIMCY2.mjs');
|
|
11939
12180
|
await runClaude(opts.credentials, {
|
|
11940
12181
|
...claudeOptions,
|
|
11941
12182
|
startingMode: claudeOptions.startingMode ?? (claudeOptions.startedBy === "daemon" ? "remote" : void 0)
|
|
11942
12183
|
});
|
|
11943
12184
|
},
|
|
11944
12185
|
codex: async (opts) => {
|
|
11945
|
-
const { runCodex } = await import('./runCodex-
|
|
12186
|
+
const { runCodex } = await import('./runCodex-ByjUfTyr.mjs');
|
|
11946
12187
|
await runCodex({
|
|
11947
12188
|
credentials: opts.credentials,
|
|
11948
12189
|
startedBy: opts.startedBy,
|
|
@@ -11951,7 +12192,7 @@ const unifiedProviderExecutors = {
|
|
|
11951
12192
|
});
|
|
11952
12193
|
},
|
|
11953
12194
|
gemini: async (opts) => {
|
|
11954
|
-
const { runGemini } = await import('./runGemini-
|
|
12195
|
+
const { runGemini } = await import('./runGemini-CihCRgcR.mjs');
|
|
11955
12196
|
await runGemini({
|
|
11956
12197
|
credentials: opts.credentials,
|
|
11957
12198
|
startedBy: opts.startedBy
|
|
@@ -12034,7 +12275,7 @@ function shouldRunMainClaudeFlow(opts) {
|
|
|
12034
12275
|
return;
|
|
12035
12276
|
} else if (subcommand === "runtime") {
|
|
12036
12277
|
if (args[1] === "providers") {
|
|
12037
|
-
const { renderRuntimeProviders } = await import('./command-
|
|
12278
|
+
const { renderRuntimeProviders } = await import('./command-umgXYSY2.mjs');
|
|
12038
12279
|
console.log(renderRuntimeProviders());
|
|
12039
12280
|
return;
|
|
12040
12281
|
}
|
|
@@ -12240,8 +12481,8 @@ function shouldRunMainClaudeFlow(opts) {
|
|
|
12240
12481
|
const projectId = args[3];
|
|
12241
12482
|
try {
|
|
12242
12483
|
const { saveGoogleCloudProjectToConfig } = await Promise.resolve().then(function () { return config; });
|
|
12243
|
-
const { readCredentials: readCredentials2 } = await import('./api-
|
|
12244
|
-
const { ApiClient: ApiClient2 } = await import('./api-
|
|
12484
|
+
const { readCredentials: readCredentials2 } = await import('./api-DTSpLLTK.mjs').then(function (n) { return n.Y; });
|
|
12485
|
+
const { ApiClient: ApiClient2 } = await import('./api-DTSpLLTK.mjs').then(function (n) { return n.Z; });
|
|
12245
12486
|
let userEmail = void 0;
|
|
12246
12487
|
try {
|
|
12247
12488
|
const credentials = await readCredentials2();
|
|
@@ -12659,4 +12900,4 @@ ${chalk.bold("Examples:")}
|
|
|
12659
12900
|
}
|
|
12660
12901
|
}
|
|
12661
12902
|
|
|
12662
|
-
export {
|
|
12903
|
+
export { AcpBackend as A, mapToClaudeMode as B, query as C, AbortError as D, ExitCodeError as E, Future as F, GEMINI_MODEL_ENV as G, getEnvironmentInfo as H, startCaffeinate as I, PushableAsyncIterable as P, RuntimeShell as R, createSessionMetadata as a, closeProviderSession as b, createDefaultRuntimeShell as c, createGeminiBackend as d, stopCaffeinate as e, formatDisplayMessage as f, getInitialGeminiModel as g, createCodexBackend as h, resolveCodexExecutable as i, shouldUseShellForCodex as j, readManagedSessionTag as k, resolveManagedSessionTag as l, initialMachineMetadata as m, resolveCanonicalToolNameV2 as n, isTerminalReferenceOnlyPayload as o, publishSessionRegistration as p, getProjectPath as q, readGeminiLocalConfig as r, saveGeminiModelToConfig as s, truncateDisplayMessage as t, claudeLocal as u, validateCodexAcpSpawn as v, trimIdent as w, createClaudeBackend as x, claudeCheckSession as y, projectPath as z };
|