happy-imou-cloud 2.1.4 → 2.1.6
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/bin/happy-cloud.mjs +38 -38
- package/dist/{BaseReasoningProcessor-DgdsExMH.cjs → BaseReasoningProcessor-C3oDrA4i.cjs} +17 -4
- package/dist/{BaseReasoningProcessor-lTsZVuAU.mjs → BaseReasoningProcessor-CRXr7Axk.mjs} +16 -3
- package/dist/{ProviderSelectionHandler-CGTnB7ba.mjs → ProviderSelectionHandler-C3kHFqeq.mjs} +2 -2
- package/dist/{ProviderSelectionHandler-Bavm9TDG.cjs → ProviderSelectionHandler-Drg2Pp1-.cjs} +2 -2
- package/dist/{api-B6ESNpGB.cjs → api-CvtU4DI-.cjs} +2 -2
- package/dist/{api-l8X03rs-.mjs → api-DF9A136-.mjs} +3 -3
- package/dist/{command-DPLKOzMr.cjs → command-UZr1nodh.cjs} +3 -3
- package/dist/{command-BVCkEMtp.mjs → command-hO52qTzQ.mjs} +3 -3
- package/dist/{index-D72RMo5Z.mjs → index-B5e-MA1d.mjs} +268 -32
- package/dist/{index-D1BP-fEm.cjs → index-DA-K28E3.cjs} +264 -24
- package/dist/index.cjs +3 -3
- package/dist/index.mjs +3 -3
- package/dist/lib.cjs +1 -1
- package/dist/lib.d.cts +36 -36
- package/dist/lib.d.mts +36 -36
- package/dist/lib.mjs +1 -1
- package/dist/{persistence-CyFjFOlN.mjs → persistence-BsWBBi7E.mjs} +1 -1
- package/dist/{persistence-EDmI-c8T.cjs → persistence-CKgPuZRR.cjs} +1 -1
- package/dist/{registerKillSessionHandler-71xCO8e_.cjs → registerKillSessionHandler-3ytO-yBI.cjs} +72 -79
- package/dist/{registerKillSessionHandler-DAVhkb-l.mjs → registerKillSessionHandler-DmG1p8l7.mjs} +73 -78
- package/dist/{runClaude-BRhQLKjh.mjs → runClaude-MF34EsCp.mjs} +103 -40
- package/dist/{runClaude-DjnTGJGC.cjs → runClaude-bAlUdUGw.cjs} +106 -43
- package/dist/{runCodex-DUs_jBE-.mjs → runCodex-B31D_imZ.mjs} +10 -8
- package/dist/{runCodex-BHq7Rnq7.cjs → runCodex-CiIbJ1wa.cjs} +12 -10
- package/dist/{runGemini-pmvBZ6qU.mjs → runGemini-BJ7PxLyl.mjs} +5 -5
- package/dist/{runGemini-hkZeOnA_.cjs → runGemini-BZJR84o-.cjs} +7 -7
- package/package.json +2 -2
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var chalk = require('chalk');
|
|
4
|
-
var api = require('./api-
|
|
5
|
-
var persistence = require('./persistence-
|
|
4
|
+
var api = require('./api-CvtU4DI-.cjs');
|
|
5
|
+
var persistence = require('./persistence-CKgPuZRR.cjs');
|
|
6
6
|
var z = require('zod');
|
|
7
7
|
var fs$2 = require('fs/promises');
|
|
8
8
|
var os$1 = require('os');
|
|
@@ -72,7 +72,7 @@ async function openBrowser(url) {
|
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
const require$1 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-
|
|
75
|
+
const require$1 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-DA-K28E3.cjs', document.baseURI).href)));
|
|
76
76
|
const QRCode = require$1("qrcode-terminal/vendor/QRCode");
|
|
77
77
|
const QRErrorCorrectLevel = require$1("qrcode-terminal/vendor/QRCode/QRErrorCorrectLevel");
|
|
78
78
|
const pendingTempFiles = /* @__PURE__ */ new Set();
|
|
@@ -695,7 +695,7 @@ function setupCleanupHandlers() {
|
|
|
695
695
|
});
|
|
696
696
|
}
|
|
697
697
|
|
|
698
|
-
const __dirname$2 = path$1.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-
|
|
698
|
+
const __dirname$2 = path$1.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-DA-K28E3.cjs', document.baseURI).href))));
|
|
699
699
|
function projectPath() {
|
|
700
700
|
const path = path$1.resolve(__dirname$2, "..");
|
|
701
701
|
return path;
|
|
@@ -2521,6 +2521,128 @@ async function runDaemonHealthCheck({
|
|
|
2521
2521
|
await writeHeartbeat();
|
|
2522
2522
|
}
|
|
2523
2523
|
|
|
2524
|
+
async function closeProviderSession(session, opts = {}) {
|
|
2525
|
+
let firstError;
|
|
2526
|
+
const captureError = (error) => {
|
|
2527
|
+
if (firstError === void 0) {
|
|
2528
|
+
firstError = error;
|
|
2529
|
+
}
|
|
2530
|
+
};
|
|
2531
|
+
if (opts.archiveOnClose || opts.archiveReason) {
|
|
2532
|
+
try {
|
|
2533
|
+
session.updateMetadata((currentMetadata) => {
|
|
2534
|
+
const { archiveReason: _existingArchiveReason, ...metadataWithoutArchiveReason } = currentMetadata;
|
|
2535
|
+
return {
|
|
2536
|
+
...metadataWithoutArchiveReason,
|
|
2537
|
+
lifecycleState: "archived",
|
|
2538
|
+
lifecycleStateSince: Date.now(),
|
|
2539
|
+
archivedBy: opts.archivedBy ?? "cli",
|
|
2540
|
+
...opts.archiveReason ? { archiveReason: opts.archiveReason } : {}
|
|
2541
|
+
};
|
|
2542
|
+
});
|
|
2543
|
+
} catch (error) {
|
|
2544
|
+
captureError(error);
|
|
2545
|
+
}
|
|
2546
|
+
}
|
|
2547
|
+
try {
|
|
2548
|
+
session.sendSessionDeath();
|
|
2549
|
+
} catch (error) {
|
|
2550
|
+
captureError(error);
|
|
2551
|
+
}
|
|
2552
|
+
try {
|
|
2553
|
+
await session.flush();
|
|
2554
|
+
} catch (error) {
|
|
2555
|
+
captureError(error);
|
|
2556
|
+
}
|
|
2557
|
+
try {
|
|
2558
|
+
await session.close();
|
|
2559
|
+
} catch (error) {
|
|
2560
|
+
captureError(error);
|
|
2561
|
+
}
|
|
2562
|
+
if (firstError !== void 0) {
|
|
2563
|
+
throw firstError;
|
|
2564
|
+
}
|
|
2565
|
+
}
|
|
2566
|
+
|
|
2567
|
+
function createSessionMetadata(opts) {
|
|
2568
|
+
const state = {
|
|
2569
|
+
controlledByUser: false
|
|
2570
|
+
};
|
|
2571
|
+
const metadataPath = opts.path ?? process.cwd();
|
|
2572
|
+
const metadataHostPid = opts.hostPid === void 0 ? process.pid : opts.hostPid;
|
|
2573
|
+
const metadata = {
|
|
2574
|
+
path: metadataPath,
|
|
2575
|
+
host: os.hostname(),
|
|
2576
|
+
version: api.packageJson.version,
|
|
2577
|
+
os: os.platform(),
|
|
2578
|
+
machineId: opts.machineId,
|
|
2579
|
+
homeDir: os.homedir(),
|
|
2580
|
+
happyHomeDir: api.configuration.happyCloudHomeDir,
|
|
2581
|
+
happyLibDir: projectPath(),
|
|
2582
|
+
happyToolsDir: path.resolve(projectPath(), "tools", "unpacked"),
|
|
2583
|
+
startedFromDaemon: opts.startedBy === "daemon",
|
|
2584
|
+
startedBy: opts.startedBy || "terminal",
|
|
2585
|
+
lifecycleState: "running",
|
|
2586
|
+
lifecycleStateSince: Date.now(),
|
|
2587
|
+
flavor: opts.flavor,
|
|
2588
|
+
...metadataHostPid == null ? {} : { hostPid: metadataHostPid }
|
|
2589
|
+
};
|
|
2590
|
+
return { state, metadata };
|
|
2591
|
+
}
|
|
2592
|
+
|
|
2593
|
+
async function archiveManagedSessionById(opts) {
|
|
2594
|
+
try {
|
|
2595
|
+
const sessionClient = opts.api.sessionSyncClient({ id: opts.sessionId });
|
|
2596
|
+
await closeProviderSession(sessionClient, {
|
|
2597
|
+
archiveReason: opts.archiveReason,
|
|
2598
|
+
archivedBy: "daemon"
|
|
2599
|
+
});
|
|
2600
|
+
} catch (error) {
|
|
2601
|
+
api.logger.debug(
|
|
2602
|
+
`[DAEMON RUN] Failed to archive managed session ${opts.sessionId}: ${opts.archiveReason}`,
|
|
2603
|
+
error
|
|
2604
|
+
);
|
|
2605
|
+
}
|
|
2606
|
+
}
|
|
2607
|
+
async function precreateDaemonManagedSession(opts) {
|
|
2608
|
+
const { state, metadata } = createSessionMetadata({
|
|
2609
|
+
flavor: opts.flavor,
|
|
2610
|
+
machineId: opts.machineId,
|
|
2611
|
+
startedBy: "daemon",
|
|
2612
|
+
path: opts.directory,
|
|
2613
|
+
hostPid: null
|
|
2614
|
+
});
|
|
2615
|
+
try {
|
|
2616
|
+
return await opts.api.getOrCreateSession({
|
|
2617
|
+
tag: opts.sessionTag,
|
|
2618
|
+
metadata,
|
|
2619
|
+
state
|
|
2620
|
+
});
|
|
2621
|
+
} catch (error) {
|
|
2622
|
+
api.logger.debug(`[DAEMON RUN] Failed to precreate ${opts.flavor} session for tag ${opts.sessionTag}`, error);
|
|
2623
|
+
return null;
|
|
2624
|
+
}
|
|
2625
|
+
}
|
|
2626
|
+
async function archivePrecreatedManagedSession(opts) {
|
|
2627
|
+
await archiveManagedSessionById({
|
|
2628
|
+
api: opts.api,
|
|
2629
|
+
sessionId: opts.session.id,
|
|
2630
|
+
archiveReason: opts.archiveReason
|
|
2631
|
+
});
|
|
2632
|
+
}
|
|
2633
|
+
async function archiveDetachedManagedSessionIfNeeded(opts) {
|
|
2634
|
+
const { trackedSession } = opts;
|
|
2635
|
+
if (trackedSession.startedBy !== "daemon" || !trackedSession.happySessionId || trackedSession.happySessionMetadataFromLocalWebhook) {
|
|
2636
|
+
return false;
|
|
2637
|
+
}
|
|
2638
|
+
await archiveManagedSessionById({
|
|
2639
|
+
api: opts.api,
|
|
2640
|
+
sessionId: trackedSession.happySessionId,
|
|
2641
|
+
archiveReason: opts.archiveReason
|
|
2642
|
+
});
|
|
2643
|
+
return true;
|
|
2644
|
+
}
|
|
2645
|
+
|
|
2524
2646
|
const NON_SESSION_PROCESS_TYPES$1 = /* @__PURE__ */ new Set([
|
|
2525
2647
|
"current",
|
|
2526
2648
|
"daemon",
|
|
@@ -2843,6 +2965,19 @@ async function recoverTrackedSessionsFromLocalRegistry({
|
|
|
2843
2965
|
return { recoveredCount, removedStaleCount };
|
|
2844
2966
|
}
|
|
2845
2967
|
|
|
2968
|
+
const HAPPY_MANAGED_SESSION_TAG_ENV = "HAPPY_MANAGED_SESSION_TAG";
|
|
2969
|
+
function readManagedSessionTag(env = process.env) {
|
|
2970
|
+
const raw = env[HAPPY_MANAGED_SESSION_TAG_ENV];
|
|
2971
|
+
if (typeof raw !== "string") {
|
|
2972
|
+
return null;
|
|
2973
|
+
}
|
|
2974
|
+
const trimmed = raw.trim();
|
|
2975
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
2976
|
+
}
|
|
2977
|
+
function resolveManagedSessionTag(env = process.env) {
|
|
2978
|
+
return readManagedSessionTag(env) ?? node_crypto.randomUUID();
|
|
2979
|
+
}
|
|
2980
|
+
|
|
2846
2981
|
const DEFAULT_SESSION_WEBHOOK_TIMEOUT_MS = 45e3;
|
|
2847
2982
|
function resolveSessionWebhookTimeoutMs() {
|
|
2848
2983
|
const parsed = Number.parseInt(process.env.HAPPY_DAEMON_SESSION_WEBHOOK_TIMEOUT || "", 10);
|
|
@@ -2939,9 +3074,21 @@ async function startDaemon() {
|
|
|
2939
3074
|
}
|
|
2940
3075
|
const { credentials, machineId } = await authAndSetupMachineIfNeeded();
|
|
2941
3076
|
api.logger.debug("[DAEMON RUN] Auth and machine setup complete");
|
|
3077
|
+
let api$1 = null;
|
|
2942
3078
|
const pidToTrackedSession = /* @__PURE__ */ new Map();
|
|
2943
3079
|
const pidToAwaiter = /* @__PURE__ */ new Map();
|
|
2944
3080
|
const getCurrentChildren = () => Array.from(pidToTrackedSession.values());
|
|
3081
|
+
const removeTrackedSession = (pid, archiveReason) => {
|
|
3082
|
+
const trackedSession = pidToTrackedSession.get(pid);
|
|
3083
|
+
if (trackedSession && api$1) {
|
|
3084
|
+
void archiveDetachedManagedSessionIfNeeded({
|
|
3085
|
+
api: api$1,
|
|
3086
|
+
trackedSession,
|
|
3087
|
+
archiveReason
|
|
3088
|
+
});
|
|
3089
|
+
}
|
|
3090
|
+
pidToTrackedSession.delete(pid);
|
|
3091
|
+
};
|
|
2945
3092
|
const onHappySessionWebhook = (sessionId, sessionMetadata) => {
|
|
2946
3093
|
api.logger.debugLargeJson(`[DAEMON RUN] Session reported`, sessionMetadata);
|
|
2947
3094
|
const pid = sessionMetadata.hostPid;
|
|
@@ -2978,8 +3125,9 @@ async function startDaemon() {
|
|
|
2978
3125
|
};
|
|
2979
3126
|
const spawnSession = async (options) => {
|
|
2980
3127
|
api.logger.debugLargeJson("[DAEMON RUN] Spawning session", options);
|
|
2981
|
-
const { directory, sessionId, machineId:
|
|
3128
|
+
const { directory, sessionId, machineId: _requestedMachineId, approvedNewDirectoryCreation = true } = options;
|
|
2982
3129
|
let directoryCreated = false;
|
|
3130
|
+
let precreatedCodexSession = null;
|
|
2983
3131
|
try {
|
|
2984
3132
|
await fs$2.access(directory);
|
|
2985
3133
|
api.logger.debug(`[DAEMON RUN] Directory exists: ${directory}`);
|
|
@@ -3053,6 +3201,11 @@ async function startDaemon() {
|
|
|
3053
3201
|
}
|
|
3054
3202
|
let extraEnv = { ...profileEnv, ...authEnv };
|
|
3055
3203
|
api.logger.debug(`[DAEMON RUN] Final environment variable keys (before expansion) (${Object.keys(extraEnv).length}): ${Object.keys(extraEnv).join(", ")}`);
|
|
3204
|
+
const managedSessionTag = options.agent === "codex" ? node_crypto.randomUUID() : null;
|
|
3205
|
+
if (managedSessionTag) {
|
|
3206
|
+
extraEnv[HAPPY_MANAGED_SESSION_TAG_ENV] = managedSessionTag;
|
|
3207
|
+
api.logger.debug(`[DAEMON RUN] Reserved managed Codex session tag ${managedSessionTag}`);
|
|
3208
|
+
}
|
|
3056
3209
|
extraEnv = expandEnvironmentVariables(extraEnv, process.env);
|
|
3057
3210
|
api.logger.debug(`[DAEMON RUN] After variable expansion: ${Object.keys(extraEnv).join(", ")}`);
|
|
3058
3211
|
const potentialAuthVars = ["ANTHROPIC_AUTH_TOKEN", "CLAUDE_CODE_OAUTH_TOKEN", "OPENAI_API_KEY", "CODEX_HOME", "AZURE_OPENAI_API_KEY", "TOGETHER_API_KEY"];
|
|
@@ -3091,6 +3244,18 @@ async function startDaemon() {
|
|
|
3091
3244
|
const fullCommand = `node --no-warnings --no-deprecation ${cliPath} ${buildDaemonSpawnArgs(agent).join(" ")}`;
|
|
3092
3245
|
const windowName = `happy-${Date.now()}-${agent}`;
|
|
3093
3246
|
const tmuxEnv = buildDaemonChildEnv(process.env, extraEnv);
|
|
3247
|
+
if (managedSessionTag && api$1) {
|
|
3248
|
+
precreatedCodexSession = await precreateDaemonManagedSession({
|
|
3249
|
+
api: api$1,
|
|
3250
|
+
sessionTag: managedSessionTag,
|
|
3251
|
+
machineId,
|
|
3252
|
+
directory,
|
|
3253
|
+
flavor: "codex"
|
|
3254
|
+
});
|
|
3255
|
+
if (precreatedCodexSession) {
|
|
3256
|
+
api.logger.debug(`[DAEMON RUN] Precreated Codex session ${precreatedCodexSession.id} before tmux spawn`);
|
|
3257
|
+
}
|
|
3258
|
+
}
|
|
3094
3259
|
const tmuxResult = await tmux.spawnInTmux([fullCommand], {
|
|
3095
3260
|
sessionName: tmuxSessionName,
|
|
3096
3261
|
windowName,
|
|
@@ -3103,6 +3268,7 @@ async function startDaemon() {
|
|
|
3103
3268
|
}
|
|
3104
3269
|
const trackedSession = {
|
|
3105
3270
|
startedBy: "daemon",
|
|
3271
|
+
happySessionId: precreatedCodexSession?.id,
|
|
3106
3272
|
pid: tmuxResult.pid,
|
|
3107
3273
|
// Real PID from tmux -P flag
|
|
3108
3274
|
tmuxSessionId: tmuxResult.sessionId,
|
|
@@ -3110,6 +3276,13 @@ async function startDaemon() {
|
|
|
3110
3276
|
message: directoryCreated ? `The path '${directory}' did not exist. We created a new folder and spawned a new session in tmux session '${tmuxSessionName}'. Use 'tmux attach -t ${tmuxSessionName}' to view the session.` : `Spawned new session in tmux session '${tmuxSessionName}'. Use 'tmux attach -t ${tmuxSessionName}' to view the session.`
|
|
3111
3277
|
};
|
|
3112
3278
|
pidToTrackedSession.set(tmuxResult.pid, trackedSession);
|
|
3279
|
+
if (precreatedCodexSession) {
|
|
3280
|
+
api.logger.debug(`[DAEMON RUN] Returning precreated Codex session ${precreatedCodexSession.id} without waiting for webhook`);
|
|
3281
|
+
return {
|
|
3282
|
+
type: "success",
|
|
3283
|
+
sessionId: precreatedCodexSession.id
|
|
3284
|
+
};
|
|
3285
|
+
}
|
|
3113
3286
|
api.logger.debug(`[DAEMON RUN] Waiting for session webhook for PID ${tmuxResult.pid} (tmux)`);
|
|
3114
3287
|
return new Promise((resolve) => {
|
|
3115
3288
|
const timeout = setTimeout(() => {
|
|
@@ -3130,6 +3303,14 @@ async function startDaemon() {
|
|
|
3130
3303
|
});
|
|
3131
3304
|
});
|
|
3132
3305
|
} else {
|
|
3306
|
+
if (precreatedCodexSession && api$1) {
|
|
3307
|
+
await archivePrecreatedManagedSession({
|
|
3308
|
+
api: api$1,
|
|
3309
|
+
session: precreatedCodexSession,
|
|
3310
|
+
archiveReason: `tmux spawn failed before Codex session ${precreatedCodexSession.id} attached`
|
|
3311
|
+
});
|
|
3312
|
+
precreatedCodexSession = null;
|
|
3313
|
+
}
|
|
3133
3314
|
api.logger.debug(`[DAEMON RUN] Failed to spawn in tmux: ${tmuxResult.error}, falling back to regular spawning`);
|
|
3134
3315
|
useTmux = false;
|
|
3135
3316
|
}
|
|
@@ -3149,6 +3330,18 @@ async function startDaemon() {
|
|
|
3149
3330
|
errorMessage: spawnError.errorMessage
|
|
3150
3331
|
};
|
|
3151
3332
|
}
|
|
3333
|
+
if (managedSessionTag && api$1) {
|
|
3334
|
+
precreatedCodexSession = await precreateDaemonManagedSession({
|
|
3335
|
+
api: api$1,
|
|
3336
|
+
sessionTag: managedSessionTag,
|
|
3337
|
+
machineId,
|
|
3338
|
+
directory,
|
|
3339
|
+
flavor: "codex"
|
|
3340
|
+
});
|
|
3341
|
+
if (precreatedCodexSession) {
|
|
3342
|
+
api.logger.debug(`[DAEMON RUN] Precreated Codex session ${precreatedCodexSession.id} before process spawn`);
|
|
3343
|
+
}
|
|
3344
|
+
}
|
|
3152
3345
|
const happyProcess = spawnHappyCLI(args, {
|
|
3153
3346
|
cwd: directory,
|
|
3154
3347
|
detached: true,
|
|
@@ -3167,6 +3360,14 @@ async function startDaemon() {
|
|
|
3167
3360
|
}
|
|
3168
3361
|
if (!happyProcess.pid) {
|
|
3169
3362
|
api.logger.debug("[DAEMON RUN] Failed to spawn process - no PID returned");
|
|
3363
|
+
if (precreatedCodexSession && api$1) {
|
|
3364
|
+
await archivePrecreatedManagedSession({
|
|
3365
|
+
api: api$1,
|
|
3366
|
+
session: precreatedCodexSession,
|
|
3367
|
+
archiveReason: `spawn produced no PID for precreated Codex session ${precreatedCodexSession.id}`
|
|
3368
|
+
});
|
|
3369
|
+
precreatedCodexSession = null;
|
|
3370
|
+
}
|
|
3170
3371
|
const spawnError = createSpawnSessionError(
|
|
3171
3372
|
SPAWN_SESSION_ERROR_CODES.SPAWN_NO_PID,
|
|
3172
3373
|
"Failed to spawn Happy process - no PID returned"
|
|
@@ -3179,6 +3380,7 @@ async function startDaemon() {
|
|
|
3179
3380
|
api.logger.debug(`[DAEMON RUN] Spawned process with PID ${happyProcess.pid}`);
|
|
3180
3381
|
const trackedSession = {
|
|
3181
3382
|
startedBy: "daemon",
|
|
3383
|
+
happySessionId: precreatedCodexSession?.id,
|
|
3182
3384
|
pid: happyProcess.pid,
|
|
3183
3385
|
childProcess: happyProcess,
|
|
3184
3386
|
directoryCreated,
|
|
@@ -3197,6 +3399,13 @@ async function startDaemon() {
|
|
|
3197
3399
|
onChildExited(happyProcess.pid);
|
|
3198
3400
|
}
|
|
3199
3401
|
});
|
|
3402
|
+
if (precreatedCodexSession) {
|
|
3403
|
+
api.logger.debug(`[DAEMON RUN] Returning precreated Codex session ${precreatedCodexSession.id} without waiting for webhook`);
|
|
3404
|
+
return {
|
|
3405
|
+
type: "success",
|
|
3406
|
+
sessionId: precreatedCodexSession.id
|
|
3407
|
+
};
|
|
3408
|
+
}
|
|
3200
3409
|
api.logger.debug(`[DAEMON RUN] Waiting for session webhook for PID ${happyProcess.pid}`);
|
|
3201
3410
|
return new Promise((resolve) => {
|
|
3202
3411
|
const timeout = setTimeout(() => {
|
|
@@ -3224,6 +3433,13 @@ async function startDaemon() {
|
|
|
3224
3433
|
} catch (error) {
|
|
3225
3434
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
3226
3435
|
api.logger.debug("[DAEMON RUN] Failed to spawn session:", error);
|
|
3436
|
+
if (precreatedCodexSession && api$1) {
|
|
3437
|
+
await archivePrecreatedManagedSession({
|
|
3438
|
+
api: api$1,
|
|
3439
|
+
session: precreatedCodexSession,
|
|
3440
|
+
archiveReason: `spawn failed before precreated Codex session ${precreatedCodexSession.id} attached: ${errorMessage}`
|
|
3441
|
+
});
|
|
3442
|
+
}
|
|
3227
3443
|
const spawnError = createSpawnSessionError(
|
|
3228
3444
|
SPAWN_SESSION_ERROR_CODES.SPAWN_FAILED,
|
|
3229
3445
|
`Failed to spawn session: ${errorMessage}`
|
|
@@ -3253,7 +3469,7 @@ async function startDaemon() {
|
|
|
3253
3469
|
api.logger.debug(`[DAEMON RUN] Failed to kill external session PID ${pid}:`, error);
|
|
3254
3470
|
}
|
|
3255
3471
|
}
|
|
3256
|
-
|
|
3472
|
+
removeTrackedSession(pid, `session ${sessionId} was stopped from daemon control before local attachment completed`);
|
|
3257
3473
|
api.logger.debug(`[DAEMON RUN] Removed session ${sessionId} from tracking`);
|
|
3258
3474
|
return true;
|
|
3259
3475
|
}
|
|
@@ -3275,7 +3491,7 @@ async function startDaemon() {
|
|
|
3275
3491
|
errorMessage: spawnError.errorMessage
|
|
3276
3492
|
});
|
|
3277
3493
|
}
|
|
3278
|
-
|
|
3494
|
+
removeTrackedSession(pid, `process ${pid} exited before the managed session fully attached`);
|
|
3279
3495
|
};
|
|
3280
3496
|
const { port: controlPort, stop: stopControlServer } = await startDaemonControlServer({
|
|
3281
3497
|
getChildren: getCurrentChildren,
|
|
@@ -3313,22 +3529,23 @@ async function startDaemon() {
|
|
|
3313
3529
|
httpPort: controlPort,
|
|
3314
3530
|
startedAt: Date.now()
|
|
3315
3531
|
};
|
|
3316
|
-
|
|
3532
|
+
api$1 = await api.ApiClient.create(credentials);
|
|
3533
|
+
const activeApi = api$1;
|
|
3317
3534
|
let userScopedObserver = null;
|
|
3318
3535
|
if (credentials.signing) {
|
|
3319
3536
|
try {
|
|
3320
|
-
userScopedObserver =
|
|
3537
|
+
userScopedObserver = activeApi.userScopedObserverClient?.() ?? null;
|
|
3321
3538
|
} catch (error) {
|
|
3322
3539
|
api.logger.debug("[DAEMON RUN] Failed to start user-scoped observer, continuing without it", error);
|
|
3323
3540
|
}
|
|
3324
3541
|
}
|
|
3325
|
-
const machine = await
|
|
3542
|
+
const machine = await activeApi.getOrCreateMachine({
|
|
3326
3543
|
machineId,
|
|
3327
3544
|
metadata: initialMachineMetadata,
|
|
3328
3545
|
daemonState: initialDaemonState
|
|
3329
3546
|
});
|
|
3330
3547
|
api.logger.debug(`[DAEMON RUN] Machine registered: ${machine.id}`);
|
|
3331
|
-
const apiMachine =
|
|
3548
|
+
const apiMachine = activeApi.machineSyncClient(machine);
|
|
3332
3549
|
apiMachine.setRPCHandlers({
|
|
3333
3550
|
spawnSession,
|
|
3334
3551
|
stopSession,
|
|
@@ -3336,7 +3553,7 @@ async function startDaemon() {
|
|
|
3336
3553
|
});
|
|
3337
3554
|
const runRemoteSessionIndexRecovery = async (label) => {
|
|
3338
3555
|
const recoveryResult = await recoverTrackedSessionsFromRemoteIndex({
|
|
3339
|
-
api:
|
|
3556
|
+
api: activeApi,
|
|
3340
3557
|
machineId,
|
|
3341
3558
|
trackedSessionPids: pidToTrackedSession.keys(),
|
|
3342
3559
|
trackSession: (pid, trackedSession) => {
|
|
@@ -3392,7 +3609,7 @@ async function startDaemon() {
|
|
|
3392
3609
|
await runDaemonHealthCheck({
|
|
3393
3610
|
trackedSessionPids: pidToTrackedSession.keys(),
|
|
3394
3611
|
removeTrackedSession: (pid) => {
|
|
3395
|
-
|
|
3612
|
+
removeTrackedSession(pid, `health check removed stale tracked PID ${pid} before local attachment completed`);
|
|
3396
3613
|
},
|
|
3397
3614
|
currentCliVersion: api.configuration.currentCliVersion,
|
|
3398
3615
|
onDaemonOutdated: async () => {
|
|
@@ -8265,7 +8482,7 @@ class AbortError extends Error {
|
|
|
8265
8482
|
}
|
|
8266
8483
|
}
|
|
8267
8484
|
|
|
8268
|
-
const __filename$1 = node_url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-
|
|
8485
|
+
const __filename$1 = node_url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-DA-K28E3.cjs', document.baseURI).href)));
|
|
8269
8486
|
const __dirname$1 = path.join(__filename$1, "..");
|
|
8270
8487
|
function getGlobalClaudeVersion() {
|
|
8271
8488
|
try {
|
|
@@ -8387,6 +8604,7 @@ class Query {
|
|
|
8387
8604
|
}
|
|
8388
8605
|
pendingControlResponses = /* @__PURE__ */ new Map();
|
|
8389
8606
|
cancelControllers = /* @__PURE__ */ new Map();
|
|
8607
|
+
controlTasks = /* @__PURE__ */ new Set();
|
|
8390
8608
|
sdkMessages;
|
|
8391
8609
|
inputStream = new Stream();
|
|
8392
8610
|
canCallTool;
|
|
@@ -8435,7 +8653,12 @@ class Query {
|
|
|
8435
8653
|
}
|
|
8436
8654
|
continue;
|
|
8437
8655
|
} else if (message.type === "control_request") {
|
|
8438
|
-
|
|
8656
|
+
const controlTask = this.handleControlRequest(message).catch((error) => {
|
|
8657
|
+
api.logger.debug("[ClaudeSDK] Failed to handle control request:", error);
|
|
8658
|
+
}).finally(() => {
|
|
8659
|
+
this.controlTasks.delete(controlTask);
|
|
8660
|
+
});
|
|
8661
|
+
this.controlTasks.add(controlTask);
|
|
8439
8662
|
continue;
|
|
8440
8663
|
} else if (message.type === "control_cancel_request") {
|
|
8441
8664
|
this.handleControlCancelRequest(message);
|
|
@@ -8451,8 +8674,11 @@ class Query {
|
|
|
8451
8674
|
} catch (error) {
|
|
8452
8675
|
this.inputStream.error(error);
|
|
8453
8676
|
} finally {
|
|
8454
|
-
this.inputStream.done();
|
|
8455
8677
|
this.cleanupControllers();
|
|
8678
|
+
if (this.controlTasks.size > 0) {
|
|
8679
|
+
await Promise.allSettled(Array.from(this.controlTasks));
|
|
8680
|
+
}
|
|
8681
|
+
this.inputStream.done();
|
|
8456
8682
|
rl.close();
|
|
8457
8683
|
}
|
|
8458
8684
|
}
|
|
@@ -8517,7 +8743,7 @@ class Query {
|
|
|
8517
8743
|
response
|
|
8518
8744
|
}
|
|
8519
8745
|
};
|
|
8520
|
-
this.
|
|
8746
|
+
this.writeControlResponse(controlResponse);
|
|
8521
8747
|
} catch (error) {
|
|
8522
8748
|
const controlErrorResponse = {
|
|
8523
8749
|
type: "control_response",
|
|
@@ -8527,11 +8753,21 @@ class Query {
|
|
|
8527
8753
|
error: error instanceof Error ? error.message : String(error)
|
|
8528
8754
|
}
|
|
8529
8755
|
};
|
|
8530
|
-
this.
|
|
8756
|
+
this.writeControlResponse(controlErrorResponse);
|
|
8531
8757
|
} finally {
|
|
8532
8758
|
this.cancelControllers.delete(request.request_id);
|
|
8533
8759
|
}
|
|
8534
8760
|
}
|
|
8761
|
+
writeControlResponse(response) {
|
|
8762
|
+
if (!this.childStdin || this.childStdin.destroyed || !this.childStdin.writable) {
|
|
8763
|
+
return;
|
|
8764
|
+
}
|
|
8765
|
+
try {
|
|
8766
|
+
this.childStdin.write(JSON.stringify(response) + "\n");
|
|
8767
|
+
} catch (error) {
|
|
8768
|
+
api.logger.debug("[ClaudeSDK] Failed to write control response:", error);
|
|
8769
|
+
}
|
|
8770
|
+
}
|
|
8535
8771
|
/**
|
|
8536
8772
|
* Handle control cancel requests
|
|
8537
8773
|
* Replicates the exact logic from the SDK's handleControlCancelRequest method
|
|
@@ -9516,11 +9752,11 @@ var launch = /*#__PURE__*/Object.freeze({
|
|
|
9516
9752
|
|
|
9517
9753
|
const unifiedProviderExecutors = {
|
|
9518
9754
|
claude: async (opts) => {
|
|
9519
|
-
const { runClaude } = await Promise.resolve().then(function () { return require('./runClaude-
|
|
9755
|
+
const { runClaude } = await Promise.resolve().then(function () { return require('./runClaude-bAlUdUGw.cjs'); });
|
|
9520
9756
|
await runClaude(opts.credentials, opts.claudeOptions ?? {});
|
|
9521
9757
|
},
|
|
9522
9758
|
codex: async (opts) => {
|
|
9523
|
-
const { runCodex } = await Promise.resolve().then(function () { return require('./runCodex-
|
|
9759
|
+
const { runCodex } = await Promise.resolve().then(function () { return require('./runCodex-CiIbJ1wa.cjs'); });
|
|
9524
9760
|
await runCodex({
|
|
9525
9761
|
credentials: opts.credentials,
|
|
9526
9762
|
startedBy: opts.startedBy,
|
|
@@ -9529,7 +9765,7 @@ const unifiedProviderExecutors = {
|
|
|
9529
9765
|
});
|
|
9530
9766
|
},
|
|
9531
9767
|
gemini: async (opts) => {
|
|
9532
|
-
const { runGemini } = await Promise.resolve().then(function () { return require('./runGemini-
|
|
9768
|
+
const { runGemini } = await Promise.resolve().then(function () { return require('./runGemini-BZJR84o-.cjs'); });
|
|
9533
9769
|
await runGemini({
|
|
9534
9770
|
credentials: opts.credentials,
|
|
9535
9771
|
startedBy: opts.startedBy
|
|
@@ -9605,7 +9841,7 @@ function shouldRunMainClaudeFlow(opts) {
|
|
|
9605
9841
|
return;
|
|
9606
9842
|
} else if (subcommand === "runtime") {
|
|
9607
9843
|
if (args[1] === "providers") {
|
|
9608
|
-
const { renderRuntimeProviders } = await Promise.resolve().then(function () { return require('./command-
|
|
9844
|
+
const { renderRuntimeProviders } = await Promise.resolve().then(function () { return require('./command-UZr1nodh.cjs'); });
|
|
9609
9845
|
console.log(renderRuntimeProviders());
|
|
9610
9846
|
return;
|
|
9611
9847
|
}
|
|
@@ -9783,8 +10019,8 @@ function shouldRunMainClaudeFlow(opts) {
|
|
|
9783
10019
|
const projectId = args[3];
|
|
9784
10020
|
try {
|
|
9785
10021
|
const { saveGoogleCloudProjectToConfig } = await Promise.resolve().then(function () { return config; });
|
|
9786
|
-
const { readCredentials: readCredentials2 } = await Promise.resolve().then(function () { return require('./persistence-
|
|
9787
|
-
const { ApiClient: ApiClient2 } = await Promise.resolve().then(function () { return require('./api-
|
|
10022
|
+
const { readCredentials: readCredentials2 } = await Promise.resolve().then(function () { return require('./persistence-CKgPuZRR.cjs'); });
|
|
10023
|
+
const { ApiClient: ApiClient2 } = await Promise.resolve().then(function () { return require('./api-CvtU4DI-.cjs'); }).then(function (n) { return n.api; });
|
|
9788
10024
|
let userEmail = void 0;
|
|
9789
10025
|
try {
|
|
9790
10026
|
const credentials = await readCredentials2();
|
|
@@ -10208,10 +10444,12 @@ exports.PushableAsyncIterable = PushableAsyncIterable;
|
|
|
10208
10444
|
exports.RuntimeShell = RuntimeShell;
|
|
10209
10445
|
exports.claudeCheckSession = claudeCheckSession;
|
|
10210
10446
|
exports.claudeLocal = claudeLocal;
|
|
10447
|
+
exports.closeProviderSession = closeProviderSession;
|
|
10211
10448
|
exports.createClaudeBackend = createClaudeBackend;
|
|
10212
10449
|
exports.createCodexBackend = createCodexBackend;
|
|
10213
10450
|
exports.createDefaultRuntimeShell = createDefaultRuntimeShell;
|
|
10214
10451
|
exports.createGeminiBackend = createGeminiBackend;
|
|
10452
|
+
exports.createSessionMetadata = createSessionMetadata;
|
|
10215
10453
|
exports.formatDisplayMessage = formatDisplayMessage;
|
|
10216
10454
|
exports.getEnvironmentInfo = getEnvironmentInfo;
|
|
10217
10455
|
exports.getInitialGeminiModel = getInitialGeminiModel;
|
|
@@ -10222,7 +10460,9 @@ exports.projectPath = projectPath;
|
|
|
10222
10460
|
exports.publishSessionRegistration = publishSessionRegistration;
|
|
10223
10461
|
exports.query = query;
|
|
10224
10462
|
exports.readGeminiLocalConfig = readGeminiLocalConfig;
|
|
10463
|
+
exports.readManagedSessionTag = readManagedSessionTag;
|
|
10225
10464
|
exports.resolveCanonicalToolNameV2 = resolveCanonicalToolNameV2;
|
|
10465
|
+
exports.resolveManagedSessionTag = resolveManagedSessionTag;
|
|
10226
10466
|
exports.saveGeminiModelToConfig = saveGeminiModelToConfig;
|
|
10227
10467
|
exports.startCaffeinate = startCaffeinate;
|
|
10228
10468
|
exports.stopCaffeinate = stopCaffeinate;
|
package/dist/index.cjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
require('chalk');
|
|
4
|
-
require('./api-
|
|
5
|
-
require('./persistence-
|
|
4
|
+
require('./api-CvtU4DI-.cjs');
|
|
5
|
+
require('./persistence-CKgPuZRR.cjs');
|
|
6
6
|
require('zod');
|
|
7
|
-
require('./index-
|
|
7
|
+
require('./index-DA-K28E3.cjs');
|
|
8
8
|
require('node:child_process');
|
|
9
9
|
require('node:fs');
|
|
10
10
|
require('cross-spawn');
|
package/dist/index.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import 'chalk';
|
|
2
|
-
import './api-
|
|
3
|
-
import './persistence-
|
|
2
|
+
import './api-DF9A136-.mjs';
|
|
3
|
+
import './persistence-BsWBBi7E.mjs';
|
|
4
4
|
import 'zod';
|
|
5
|
-
import './index-
|
|
5
|
+
import './index-B5e-MA1d.mjs';
|
|
6
6
|
import 'node:child_process';
|
|
7
7
|
import 'node:fs';
|
|
8
8
|
import 'cross-spawn';
|