very-happy-cli 0.2.137 → 0.2.139
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/{AcpBackend-POcimRNQ.mjs → AcpBackend-BwTEBAyP.mjs} +2 -2
- package/dist/{AcpBackend-Bcmm51Ya.cjs → AcpBackend-ioCPQLt4.cjs} +2 -2
- package/dist/{AcpSessionManager-D54Juu2-.mjs → AcpSessionManager-Bh3KETfz.mjs} +1 -1
- package/dist/{AcpSessionManager-CjrwSZbh.cjs → AcpSessionManager-o9T6W69-.cjs} +1 -1
- package/dist/{agentGuidance-DulugsMk.mjs → agentGuidance-DRnXdFAY.mjs} +1 -1
- package/dist/{agentGuidance-D1tKg2UW.cjs → agentGuidance-Dxt2uz3R.cjs} +1 -1
- package/dist/codex/happyMcpStdioBridge.cjs +2 -2
- package/dist/codex/happyMcpStdioBridge.mjs +2 -2
- package/dist/{config-Dr3A4IGp.cjs → config-nyMHCx-i.cjs} +4 -4
- package/dist/{config-C1gQprK_.mjs → config-o9NFsj8x.mjs} +4 -4
- package/dist/{index-D5MRxCHs.mjs → index-BZr5l8TH.mjs} +185 -230
- package/dist/{index-B11rFE7f.mjs → index-BkmfJyCf.mjs} +7 -7
- package/dist/{index-B0KIJdSt.cjs → index-C3NtU4Ch.cjs} +216 -266
- package/dist/{index-C3agc8KT.mjs → index-CTemcNko.mjs} +4 -4
- package/dist/{index-hGg5G5uO.cjs → index-gkFhwPXq.cjs} +4 -4
- package/dist/{index-C3JqT3Ql.cjs → index-klhxcpC8.cjs} +7 -7
- package/dist/index.cjs +4 -4
- package/dist/index.mjs +4 -4
- package/dist/{installTerminalHooks-DfZTXVWO.mjs → installTerminalHooks-8CHTgUC-.mjs} +4 -4
- package/dist/{installTerminalHooks-Culr259-.cjs → installTerminalHooks-DZUBgnFh.cjs} +4 -4
- package/dist/lib.cjs +2 -2
- package/dist/lib.d.cts +21 -0
- package/dist/lib.d.mts +21 -0
- package/dist/lib.mjs +2 -2
- package/dist/{limits-CJrrAhB4.cjs → limits-C_RGzva6.cjs} +26 -7
- package/dist/{limits-CAD4UF8w.mjs → limits-DefXc1TL.mjs} +26 -8
- package/dist/{mcp-CdnZbYKV.mjs → mcp-8DcunR0J.mjs} +19 -19
- package/dist/{mcp-5Jf6V4eb.cjs → mcp-czNIfD59.cjs} +21 -21
- package/dist/{runGemini-CwWEorS7.mjs → runGemini-CDUObQTD.mjs} +6 -6
- package/dist/{runGemini-GjBPzXEt.cjs → runGemini-Dy3y-lD9.cjs} +7 -7
- package/dist/{runOpenClaw-BZHHy9T7.mjs → runOpenClaw-B6KMCsVB.mjs} +5 -5
- package/dist/{runOpenClaw-DGe5c571.cjs → runOpenClaw-CJusckVM.cjs} +6 -6
- package/dist/{send-teYpfTtw.cjs → send-B4Qo-87h.cjs} +4 -4
- package/dist/{send-BN2PncAH.mjs → send-BT32Jiel.mjs} +4 -4
- package/dist/{sessions-qP1YUf5E.cjs → sessions-CN2y0xBl.cjs} +4 -4
- package/dist/{sessions-TLUfYdLX.mjs → sessions-Dh0Lg-5z.mjs} +4 -4
- package/dist/{spawn-D3P8wJ_r.mjs → spawn-DFIyobCt.mjs} +6 -6
- package/dist/{spawn-GekaZ7h2.cjs → spawn-jWj3xFhX.cjs} +8 -8
- package/dist/{teams-BSqAW2S5.cjs → teams-BhFspeAY.cjs} +4 -4
- package/dist/{teams-WSjEXh4d.mjs → teams-CZ9ICWeB.mjs} +4 -4
- package/dist/{todo-DsnXWl77.cjs → todo-B0kvqUTQ.cjs} +3 -3
- package/dist/{todo-BblDgT77.mjs → todo-jL3ttna3.mjs} +3 -3
- package/dist/{types-B8g_V-LQ.mjs → types-CrKeJuyF.mjs} +616 -13
- package/dist/{types-BAhQF6Xp.cjs → types-CxGm_YJ-.cjs} +629 -13
- package/package.json +7 -7
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import{createRequire as _pkgrollCR}from"node:module";const require=_pkgrollCR(import.meta.url);import chalk from 'chalk';
|
|
2
2
|
import os, { homedir, userInfo, tmpdir } from 'node:os';
|
|
3
3
|
import { randomUUID, randomInt, randomBytes, createHash as createHash$1, timingSafeEqual } from 'node:crypto';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { o as notifyDaemonSessionEvent, q as getProjectPath, l as BUILTIN_TODO_DISCOVERY, p as projectPath, r as initializeSandbox, w as wrapCommand, j as contentLogMetadata, I as InvalidateSync, R as RawJSONLinesSchema, m as delay, t as AsyncLock, S as STREAM_DELTA_MAX_CHARS, M as MAX_CHAT_ATTACHMENT_SOURCE_BYTES, u as notifyDaemonClaudeAuthFailed, v as commandOnPath, c as checkIfDaemonRunningAndCleanupStaleState, x as deriveLocalCliUpdateSummary, y as AGENT_VERSION_SOURCES, z as isClaudeSessionId, C as getLocalHappyAgentCredentialPath, D as readLocalHappyAgentCredentials, E as parseExactVersion, F as compareExactVersions, G as extractCompleteLines, H as decideBackfill, J as parseTerminalHookPayload, K as tmuxArgs, L as scrubTmuxClientEnv, N as decideMirrorBinding, O as MIRROR_BACKFILL_LINES_DEFAULT, P as mirrorLineKey, Q as mirrorLocalId, T as listDaemonSessions, U as stopDaemonSession, V as detectCLIAvailability, W as detectResumeSupport, X as isDaemonRunningCurrentlyInstalledHappyVersion, Y as stopDaemon, Z as TurnActivityTracker, _ as summarizeSpawnSessionForLog, $ as shellescape, A as ApiClient, a0 as fetchCliUpdateState, a1 as resolveCliUpdateCheckInterval, a2 as DEFAULT_CLI_UPDATE_CHECK_INTERVAL_MS, a3 as cleanupDaemonState, i as isValidSessionId, s as spawnDaemonSession, a4 as listVhTerminals, a5 as isValidTerminalId, a6 as readVhTerminal, a7 as sendToVhTerminal, a8 as ContextUsageSchema, a9 as TITLE_PROMPT_PREFIX, aa as BOARD_ANALYZER_PROMPT_PREFIX, k as connectionState, ab as startOfflineReconnection, n as notifyDaemonSessionStarted, d as createEnvelope, ac as CodexAppServerClient } from './types-CrKeJuyF.mjs';
|
|
5
|
+
import { l as logger, D as ensurePrivateDirectory, E as hardenPrivateFile, c as configuration, p as packageJson, g as readSettings, F as readCredentials, u as credentialRelayProblem, o as readDaemonState, i as encodeBase64, G as readSettingsOutcome, H as updateSettings, I as encodeBase64Url, m as decodeBase64, J as writeCredentialsLegacy, K as writeCredentialsDataKey, d as readCredentialsForConfiguredRelay, j as encrypt, r as readPersistedSessions, w as writePrivateFileSync, L as decryptWithDataKey, M as decryptLegacy, N as persistSession, k as decrypt, f as ensurePrivateDirectorySync, O as acquireDaemonLock, P as deletePersistedSessions, Q as writeDaemonState, R as writeSettings, S as releaseDaemonLock, C as CLIPBOARD_TOOL_NAME, a as CLIPBOARD_TOOL_TITLE, b as CLIPBOARD_TOOL_DESCRIPTION, e as CLIPBOARD_MAX_BYTES, T as clearCredentials, U as clearMachineId, V as SandboxConfigSchema, W as getLatestDaemonLog } from './limits-DefXc1TL.mjs';
|
|
6
6
|
import spawn$1, { spawn } from 'cross-spawn';
|
|
7
7
|
import path, { join, resolve, basename, isAbsolute, dirname, sep, delimiter, normalize } from 'node:path';
|
|
8
8
|
import { createInterface } from 'node:readline';
|
|
9
9
|
import { existsSync, readFileSync, readdirSync, statSync, mkdirSync, unlinkSync, renameSync, writeFileSync, accessSync, constants, openSync, fsyncSync, closeSync, rmSync as rmSync$1, chmodSync as chmodSync$1 } from 'node:fs';
|
|
10
|
-
import { f as trimIdent, A as AGENT_GUIDANCE, t as teamScopePath, T as TeamConnectionPreflightError, e as createTeamsClient, P as PREVIEW_TOOL_NAME, R as REPORT_PROGRESS_TOOL_NAME, g as TEAM_TOOL_NAMES, r as registerTeamsTools, a as PREVIEW_TOOL_TITLE, b as PREVIEW_TOOL_DESCRIPTION, h as REPORT_PROGRESS_TOOL_TITLE, i as REPORT_PROGRESS_TOOL_DESCRIPTION } from './agentGuidance-
|
|
10
|
+
import { f as trimIdent, A as AGENT_GUIDANCE, t as teamScopePath, T as TeamConnectionPreflightError, e as createTeamsClient, P as PREVIEW_TOOL_NAME, R as REPORT_PROGRESS_TOOL_NAME, g as TEAM_TOOL_NAMES, r as registerTeamsTools, a as PREVIEW_TOOL_TITLE, b as PREVIEW_TOOL_DESCRIPTION, h as REPORT_PROGRESS_TOOL_TITLE, i as REPORT_PROGRESS_TOOL_DESCRIPTION } from './agentGuidance-DRnXdFAY.mjs';
|
|
11
11
|
import { readFile, writeFile, rename, unlink, mkdir, symlink, rm, readlink, lstat, stat, open as open$1, appendFile } from 'node:fs/promises';
|
|
12
12
|
import fs, { watch, access } from 'fs/promises';
|
|
13
13
|
import { useStdout, useInput, Box, Text, render } from 'ink';
|
|
@@ -93,212 +93,6 @@ function withoutServerSnapshot(response) {
|
|
|
93
93
|
return { ...response, metadataVersion: 0, agentStateVersion: 0 };
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
-
function daemonControlHeaders(controlToken) {
|
|
97
|
-
return {
|
|
98
|
-
"Content-Type": "application/json",
|
|
99
|
-
...controlToken ? { Authorization: `Bearer ${controlToken}` } : {}
|
|
100
|
-
};
|
|
101
|
-
}
|
|
102
|
-
async function daemonPost(path, body) {
|
|
103
|
-
const state = await readDaemonState();
|
|
104
|
-
if (!state?.httpPort) {
|
|
105
|
-
const errorMessage = "No daemon running, no state file found";
|
|
106
|
-
logger.debug(`[CONTROL CLIENT] ${errorMessage}`);
|
|
107
|
-
return {
|
|
108
|
-
error: errorMessage
|
|
109
|
-
};
|
|
110
|
-
}
|
|
111
|
-
try {
|
|
112
|
-
process.kill(state.pid, 0);
|
|
113
|
-
} catch (error) {
|
|
114
|
-
const errorMessage = "Daemon is not running, file is stale";
|
|
115
|
-
logger.debug(`[CONTROL CLIENT] ${errorMessage}`);
|
|
116
|
-
return {
|
|
117
|
-
error: errorMessage
|
|
118
|
-
};
|
|
119
|
-
}
|
|
120
|
-
try {
|
|
121
|
-
const timeout = process.env.HAPPY_DAEMON_HTTP_TIMEOUT ? parseInt(process.env.HAPPY_DAEMON_HTTP_TIMEOUT) : 1e4;
|
|
122
|
-
const response = await fetch(`http://127.0.0.1:${state.httpPort}${path}`, {
|
|
123
|
-
method: "POST",
|
|
124
|
-
// A state written by an old daemon has no token and must remain callable;
|
|
125
|
-
// a new daemon always writes one and rejects requests without it.
|
|
126
|
-
headers: daemonControlHeaders(state.controlToken),
|
|
127
|
-
body: JSON.stringify(body || {}),
|
|
128
|
-
// Mostly increased for stress test
|
|
129
|
-
signal: AbortSignal.timeout(timeout)
|
|
130
|
-
});
|
|
131
|
-
if (!response.ok) {
|
|
132
|
-
const failure = await response.json().catch(() => null);
|
|
133
|
-
const reason = typeof failure?.error === "string" && failure.error ? failure.error : `HTTP ${response.status}`;
|
|
134
|
-
const errorMessage = `Request failed: ${path}, ${reason}`;
|
|
135
|
-
logger.debug(`[CONTROL CLIENT] ${errorMessage}`);
|
|
136
|
-
return {
|
|
137
|
-
error: errorMessage
|
|
138
|
-
};
|
|
139
|
-
}
|
|
140
|
-
return await response.json();
|
|
141
|
-
} catch (error) {
|
|
142
|
-
const errorMessage = `Request failed: ${path}, ${error instanceof Error ? error.message : "Unknown error"}`;
|
|
143
|
-
logger.debug(`[CONTROL CLIENT] ${errorMessage}`);
|
|
144
|
-
return {
|
|
145
|
-
error: errorMessage
|
|
146
|
-
};
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
const SESSION_STARTED_RETRY_TIMEOUT_MS = 3e3;
|
|
150
|
-
const SESSION_STARTED_RETRY_INTERVAL_MS = 100;
|
|
151
|
-
async function notifyDaemonSessionStarted(sessionId, metadata, encryption) {
|
|
152
|
-
const payload = { sessionId, metadata, encryption };
|
|
153
|
-
const deadline = Date.now() + SESSION_STARTED_RETRY_TIMEOUT_MS;
|
|
154
|
-
let result;
|
|
155
|
-
while (true) {
|
|
156
|
-
result = await daemonPost("/session-started", payload);
|
|
157
|
-
if (!result?.error) {
|
|
158
|
-
return result;
|
|
159
|
-
}
|
|
160
|
-
if (Date.now() >= deadline) {
|
|
161
|
-
return result;
|
|
162
|
-
}
|
|
163
|
-
await new Promise((resolve) => setTimeout(resolve, SESSION_STARTED_RETRY_INTERVAL_MS));
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
async function listDaemonSessions() {
|
|
167
|
-
const result = await daemonPost("/list");
|
|
168
|
-
return result.children || [];
|
|
169
|
-
}
|
|
170
|
-
async function stopDaemonSession(sessionId) {
|
|
171
|
-
const result = await daemonPost("/stop-session", { sessionId });
|
|
172
|
-
return result.success || false;
|
|
173
|
-
}
|
|
174
|
-
async function spawnDaemonSession(directory, sessionId, opts) {
|
|
175
|
-
const result = await daemonPost("/spawn-session", {
|
|
176
|
-
directory,
|
|
177
|
-
sessionId,
|
|
178
|
-
spawnedBy: opts?.spawnedBy,
|
|
179
|
-
permissionMode: opts?.permissionMode,
|
|
180
|
-
agent: opts?.agent,
|
|
181
|
-
environmentVariables: opts?.environmentVariables
|
|
182
|
-
});
|
|
183
|
-
return result;
|
|
184
|
-
}
|
|
185
|
-
async function notifyDaemonSessionEvent(sessionId, event, spawnedBy) {
|
|
186
|
-
return daemonPost("/session-event", { sessionId, event, spawnedBy });
|
|
187
|
-
}
|
|
188
|
-
async function notifyDaemonClaudeAuthFailed(sessionId) {
|
|
189
|
-
return daemonPost("/session-event", { sessionId, event: "auth_failed" });
|
|
190
|
-
}
|
|
191
|
-
async function stopDaemonHttp() {
|
|
192
|
-
await daemonPost("/stop");
|
|
193
|
-
}
|
|
194
|
-
async function pushClipboardViaDaemon(text) {
|
|
195
|
-
const result = await daemonPost("/clipboard", { text });
|
|
196
|
-
if (result?.error && result.delivered === void 0) {
|
|
197
|
-
return { delivered: false, error: result.error };
|
|
198
|
-
}
|
|
199
|
-
return result;
|
|
200
|
-
}
|
|
201
|
-
async function setTerminalTitleViaDaemon(terminalId, title, ifAbsent = false) {
|
|
202
|
-
const result = await daemonPost("/terminal-title", { terminalId, title, ifAbsent });
|
|
203
|
-
if (result?.error) {
|
|
204
|
-
return { ok: false, error: result.error };
|
|
205
|
-
}
|
|
206
|
-
return { ok: result?.status === "ok", error: result?.status === "ok" ? void 0 : "unexpected daemon response" };
|
|
207
|
-
}
|
|
208
|
-
async function checkIfDaemonRunningAndCleanupStaleState() {
|
|
209
|
-
const state = await readDaemonState();
|
|
210
|
-
if (!state) {
|
|
211
|
-
return false;
|
|
212
|
-
}
|
|
213
|
-
try {
|
|
214
|
-
process.kill(state.pid, 0);
|
|
215
|
-
} catch {
|
|
216
|
-
logger.debug("[DAEMON RUN] Daemon PID not running, cleaning up state");
|
|
217
|
-
await cleanupDaemonState();
|
|
218
|
-
return false;
|
|
219
|
-
}
|
|
220
|
-
if (state.httpPort) {
|
|
221
|
-
try {
|
|
222
|
-
const response = await fetch(`http://127.0.0.1:${state.httpPort}/list`, {
|
|
223
|
-
method: "POST",
|
|
224
|
-
headers: daemonControlHeaders(state.controlToken),
|
|
225
|
-
body: "{}",
|
|
226
|
-
signal: AbortSignal.timeout(2e3)
|
|
227
|
-
});
|
|
228
|
-
if (response.ok) {
|
|
229
|
-
return true;
|
|
230
|
-
}
|
|
231
|
-
} catch {
|
|
232
|
-
logger.debug(`[DAEMON RUN] PID ${state.pid} is alive but HTTP health check failed on port ${state.httpPort}, cleaning up stale state`);
|
|
233
|
-
await cleanupDaemonState();
|
|
234
|
-
return false;
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
return true;
|
|
238
|
-
}
|
|
239
|
-
async function isDaemonRunningCurrentlyInstalledHappyVersion() {
|
|
240
|
-
logger.debug("[DAEMON CONTROL] Checking if daemon is running same version");
|
|
241
|
-
const runningDaemon = await checkIfDaemonRunningAndCleanupStaleState();
|
|
242
|
-
if (!runningDaemon) {
|
|
243
|
-
logger.debug("[DAEMON CONTROL] No daemon running, returning false");
|
|
244
|
-
return false;
|
|
245
|
-
}
|
|
246
|
-
const state = await readDaemonState();
|
|
247
|
-
if (!state) {
|
|
248
|
-
logger.debug("[DAEMON CONTROL] No daemon state found, returning false");
|
|
249
|
-
return false;
|
|
250
|
-
}
|
|
251
|
-
const currentCliVersion = configuration.currentCliVersion;
|
|
252
|
-
logger.debug(`[DAEMON CONTROL] Current CLI version: ${currentCliVersion}, Daemon started with version: ${state.startedWithCliVersion}`);
|
|
253
|
-
return currentCliVersion === state.startedWithCliVersion;
|
|
254
|
-
}
|
|
255
|
-
async function cleanupDaemonState() {
|
|
256
|
-
try {
|
|
257
|
-
await clearDaemonState();
|
|
258
|
-
logger.debug("[DAEMON RUN] Daemon state file removed");
|
|
259
|
-
} catch (error) {
|
|
260
|
-
logger.debug("[DAEMON RUN] Error cleaning up daemon metadata", error);
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
async function stopDaemon() {
|
|
264
|
-
try {
|
|
265
|
-
const state = await readDaemonState();
|
|
266
|
-
if (!state) {
|
|
267
|
-
logger.debug("No daemon state found");
|
|
268
|
-
return;
|
|
269
|
-
}
|
|
270
|
-
logger.debug(`Stopping daemon with PID ${state.pid}`);
|
|
271
|
-
try {
|
|
272
|
-
await stopDaemonHttp();
|
|
273
|
-
await waitForProcessDeath(state.pid, 2e3);
|
|
274
|
-
logger.debug("Daemon stopped gracefully via HTTP");
|
|
275
|
-
return;
|
|
276
|
-
} catch (error) {
|
|
277
|
-
logger.debug("HTTP stop failed, will force kill", error);
|
|
278
|
-
}
|
|
279
|
-
try {
|
|
280
|
-
process.kill(state.pid, "SIGKILL");
|
|
281
|
-
logger.debug("Force killed daemon");
|
|
282
|
-
} catch (error) {
|
|
283
|
-
logger.debug("Daemon already dead");
|
|
284
|
-
}
|
|
285
|
-
} catch (error) {
|
|
286
|
-
logger.debug("Error stopping daemon", error);
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
async function waitForProcessDeath(pid, timeout) {
|
|
290
|
-
const start = Date.now();
|
|
291
|
-
while (Date.now() - start < timeout) {
|
|
292
|
-
try {
|
|
293
|
-
process.kill(pid, 0);
|
|
294
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
295
|
-
} catch {
|
|
296
|
-
return;
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
throw new Error("Process did not die within timeout");
|
|
300
|
-
}
|
|
301
|
-
|
|
302
96
|
class Session {
|
|
303
97
|
path;
|
|
304
98
|
logPath;
|
|
@@ -6259,6 +6053,7 @@ function startDaemonControlServer({
|
|
|
6259
6053
|
onHappySessionWebhook,
|
|
6260
6054
|
onSessionStateEvent,
|
|
6261
6055
|
onClaudeAuthFailed,
|
|
6056
|
+
onSessionTurnEvent,
|
|
6262
6057
|
pushClipboard,
|
|
6263
6058
|
onTerminalHook,
|
|
6264
6059
|
setTerminalTitle
|
|
@@ -6315,7 +6110,7 @@ function startDaemonControlServer({
|
|
|
6315
6110
|
schema: {
|
|
6316
6111
|
body: z.object({
|
|
6317
6112
|
sessionId: z.string(),
|
|
6318
|
-
event: z.enum(["completed", "needs_input", "auth_failed"]),
|
|
6113
|
+
event: z.enum(["completed", "needs_input", "auth_failed", "turn_started", "turn_ended"]),
|
|
6319
6114
|
spawnedBy: z.string().optional()
|
|
6320
6115
|
}),
|
|
6321
6116
|
response: {
|
|
@@ -6331,6 +6126,10 @@ function startDaemonControlServer({
|
|
|
6331
6126
|
onClaudeAuthFailed?.(sessionId);
|
|
6332
6127
|
return { status: "ok" };
|
|
6333
6128
|
}
|
|
6129
|
+
if (event === "turn_started" || event === "turn_ended") {
|
|
6130
|
+
onSessionTurnEvent?.(sessionId, event);
|
|
6131
|
+
return { status: "ok" };
|
|
6132
|
+
}
|
|
6334
6133
|
onSessionStateEvent?.(sessionId, event, spawnedBy);
|
|
6335
6134
|
return { status: "ok" };
|
|
6336
6135
|
});
|
|
@@ -10225,6 +10024,7 @@ async function startDaemon() {
|
|
|
10225
10024
|
const { credentials, machineId } = await authAndSetupMachineIfNeeded();
|
|
10226
10025
|
logger.debug("[DAEMON RUN] Auth and machine setup complete");
|
|
10227
10026
|
const pidToTrackedSession = /* @__PURE__ */ new Map();
|
|
10027
|
+
const turnActivity = new TurnActivityTracker();
|
|
10228
10028
|
const sessionIdToFinishedSession = /* @__PURE__ */ new Map();
|
|
10229
10029
|
let teamWorker;
|
|
10230
10030
|
const persisted = readPersistedSessions();
|
|
@@ -10496,6 +10296,9 @@ async function startDaemon() {
|
|
|
10496
10296
|
if (options.resumeCodexThreadId) {
|
|
10497
10297
|
extraEnv.HAPPY_FORK_CODEX_THREAD_ID = options.resumeCodexThreadId;
|
|
10498
10298
|
}
|
|
10299
|
+
if (options.importCodexThreadId && UUID_RE.test(options.importCodexThreadId)) {
|
|
10300
|
+
extraEnv.HAPPY_IMPORT_CODEX_THREAD_ID = options.importCodexThreadId;
|
|
10301
|
+
}
|
|
10499
10302
|
if (options.variant === "assistant") {
|
|
10500
10303
|
extraEnv.HAPPY_SESSION_VARIANT = "assistant";
|
|
10501
10304
|
}
|
|
@@ -11060,6 +10863,7 @@ async function startDaemon() {
|
|
|
11060
10863
|
const onChildExited = (pid) => {
|
|
11061
10864
|
const session = pidToTrackedSession.get(pid);
|
|
11062
10865
|
if (session?.happySessionId && (session.spawnedBy === "teams" || teamWorker?.hasSession(session.happySessionId))) teamWorker?.report(session.happySessionId, "exited");
|
|
10866
|
+
if (session?.happySessionId) turnActivity.forget(session.happySessionId);
|
|
11063
10867
|
if (session?.happySessionId && session.encryption) {
|
|
11064
10868
|
sessionIdToFinishedSession.set(session.happySessionId, session);
|
|
11065
10869
|
logger.debug(`[DAEMON RUN] Process PID ${pid} exited, preserved session ${session.happySessionId} for resume`);
|
|
@@ -11141,6 +10945,7 @@ async function startDaemon() {
|
|
|
11141
10945
|
onHappySessionWebhook,
|
|
11142
10946
|
onSessionStateEvent,
|
|
11143
10947
|
onClaudeAuthFailed: (sessionId) => claudeAuthServiceRef?.signalAuthFailed(sessionId),
|
|
10948
|
+
onSessionTurnEvent: (sessionId, event) => turnActivity.apply(sessionId, event),
|
|
11144
10949
|
pushClipboard: (text) => {
|
|
11145
10950
|
if (!apiMachineRef) {
|
|
11146
10951
|
return { delivered: false, truncated: false, totalBytes: 0, error: "daemon is still starting up" };
|
|
@@ -11253,7 +11058,10 @@ async function startDaemon() {
|
|
|
11253
11058
|
const updateController = createUpdateController({
|
|
11254
11059
|
policy: () => fetchCliUpdateState(configuration.serverUrl, packageJson.version),
|
|
11255
11060
|
enabled: async () => ((await readSettings()).cliAutoUpdate ?? "idle") !== "off",
|
|
11256
|
-
|
|
11061
|
+
// B-466: "idle" = no agent turn in flight. Idle wrappers survive a
|
|
11062
|
+
// handover (they talk to the server themselves) and web terminals live
|
|
11063
|
+
// in tmux, so neither is a reason to hold an update.
|
|
11064
|
+
idle: () => !turnActivity.hasActiveTurn(),
|
|
11257
11065
|
install: installCliSafely,
|
|
11258
11066
|
publish: (state) => {
|
|
11259
11067
|
cliUpdateStateRef = state;
|
|
@@ -11308,7 +11116,7 @@ async function startDaemon() {
|
|
|
11308
11116
|
} catch {
|
|
11309
11117
|
}
|
|
11310
11118
|
}
|
|
11311
|
-
if (bundleReplaced && !teamWorker?.busy && !updateController.isRunning() &&
|
|
11119
|
+
if (bundleReplaced && !teamWorker?.busy && !updateController.isRunning() && !turnActivity.hasActiveTurn()) {
|
|
11312
11120
|
const preflight = await preflightNewBundle(bundlePath);
|
|
11313
11121
|
if (preflight.action === "hold") {
|
|
11314
11122
|
if (lastHandoverHold !== preflight.reason) {
|
|
@@ -11318,7 +11126,7 @@ async function startDaemon() {
|
|
|
11318
11126
|
updateController.holdHandover(preflight.reason);
|
|
11319
11127
|
return;
|
|
11320
11128
|
}
|
|
11321
|
-
if (teamWorker?.busy || updateController.isRunning() ||
|
|
11129
|
+
if (teamWorker?.busy || updateController.isRunning() || turnActivity.hasActiveTurn()) return;
|
|
11322
11130
|
lastHandoverHold = null;
|
|
11323
11131
|
logger.debug("[DAEMON RUN] Daemon bundle replaced on disk and verified, handing off to new daemon");
|
|
11324
11132
|
teamWorker?.stop();
|
|
@@ -12476,7 +12284,7 @@ function registerSideQuestionHandler(rpc, deps) {
|
|
|
12476
12284
|
const retainMs = deps.retainMs ?? SIDE_QUESTION_RETAIN_MS;
|
|
12477
12285
|
const maxRunMs = deps.maxRunMs ?? SIDE_QUESTION_MAX_RUN_MS;
|
|
12478
12286
|
const run = deps.run ?? (async (input) => {
|
|
12479
|
-
const { query } = await import('./index-
|
|
12287
|
+
const { query } = await import('./index-CTemcNko.mjs');
|
|
12480
12288
|
return runSideQuestion(query, input);
|
|
12481
12289
|
});
|
|
12482
12290
|
const slots = /* @__PURE__ */ new Map();
|
|
@@ -16572,6 +16380,43 @@ async function resumeExistingThread(opts) {
|
|
|
16572
16380
|
}
|
|
16573
16381
|
}
|
|
16574
16382
|
|
|
16383
|
+
const IMPORT_CODEX_THREAD_ENV = "HAPPY_IMPORT_CODEX_THREAD_ID";
|
|
16384
|
+
async function importCodexThread(opts) {
|
|
16385
|
+
let forked;
|
|
16386
|
+
try {
|
|
16387
|
+
forked = await opts.client.forkThread({
|
|
16388
|
+
threadId: opts.threadId,
|
|
16389
|
+
cwd: opts.cwd,
|
|
16390
|
+
mcpServers: opts.mcpServers
|
|
16391
|
+
});
|
|
16392
|
+
} catch (error) {
|
|
16393
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
16394
|
+
throw new Error(`Failed to import Codex thread ${opts.threadId}: ${reason}`);
|
|
16395
|
+
}
|
|
16396
|
+
if (!forked.threadId || forked.threadId === opts.threadId) {
|
|
16397
|
+
throw new Error(`Failed to import Codex thread ${opts.threadId}: Codex did not create an independent copy`);
|
|
16398
|
+
}
|
|
16399
|
+
opts.session.updateMetadata((currentMetadata) => ({
|
|
16400
|
+
...currentMetadata,
|
|
16401
|
+
codexThreadId: forked.threadId,
|
|
16402
|
+
importedFromCodexThreadId: opts.threadId
|
|
16403
|
+
}));
|
|
16404
|
+
let thread = forked.thread;
|
|
16405
|
+
if (!Array.isArray(thread?.turns)) {
|
|
16406
|
+
thread = (await opts.client.readThread({ threadId: forked.threadId, includeTurns: true })).thread;
|
|
16407
|
+
}
|
|
16408
|
+
const envelopes = mapCodexThreadToSessionEnvelopes(thread);
|
|
16409
|
+
for (const envelope of envelopes) {
|
|
16410
|
+
opts.session.sendSessionProtocolMessage(envelope);
|
|
16411
|
+
}
|
|
16412
|
+
opts.messageBuffer.addMessage(`Imported thread ${trimIdent(opts.threadId)} as ${trimIdent(forked.threadId)}`, "status");
|
|
16413
|
+
opts.session.sendSessionEvent({
|
|
16414
|
+
type: "message",
|
|
16415
|
+
message: `Imported Codex thread ${opts.threadId} (continuing as ${forked.threadId})`
|
|
16416
|
+
});
|
|
16417
|
+
return { threadId: forked.threadId, model: forked.model, replayed: envelopes.length };
|
|
16418
|
+
}
|
|
16419
|
+
|
|
16575
16420
|
function emitReadyIfIdle({ pending, queueSize, shouldExit, sendReady, notify }) {
|
|
16576
16421
|
if (shouldExit) {
|
|
16577
16422
|
return false;
|
|
@@ -16587,6 +16432,72 @@ function emitReadyIfIdle({ pending, queueSize, shouldExit, sendReady, notify })
|
|
|
16587
16432
|
return true;
|
|
16588
16433
|
}
|
|
16589
16434
|
|
|
16435
|
+
const DEFAULT_CODEX_IDLE_RELEASE_MS = 5 * 60 * 1e3;
|
|
16436
|
+
const CODEX_IDLE_RELEASE_ENV = "HAPPY_CODEX_IDLE_RELEASE_MS";
|
|
16437
|
+
function resolveCodexIdleReleaseMs(raw) {
|
|
16438
|
+
if (raw === void 0 || raw.trim() === "") return DEFAULT_CODEX_IDLE_RELEASE_MS;
|
|
16439
|
+
const parsed = Number(raw);
|
|
16440
|
+
if (!Number.isFinite(parsed) || parsed < 0) return DEFAULT_CODEX_IDLE_RELEASE_MS;
|
|
16441
|
+
return Math.floor(parsed);
|
|
16442
|
+
}
|
|
16443
|
+
function shouldReleaseIdleCodex(state) {
|
|
16444
|
+
if (state.shouldExit) return false;
|
|
16445
|
+
if (state.turnActive) return false;
|
|
16446
|
+
if (state.abortInProgress) return false;
|
|
16447
|
+
if (state.queueSize > 0) return false;
|
|
16448
|
+
return true;
|
|
16449
|
+
}
|
|
16450
|
+
class CodexIdleReleaseTimer {
|
|
16451
|
+
constructor(opts) {
|
|
16452
|
+
this.opts = opts;
|
|
16453
|
+
}
|
|
16454
|
+
timer = null;
|
|
16455
|
+
releasing = null;
|
|
16456
|
+
get enabled() {
|
|
16457
|
+
return this.opts.delayMs > 0;
|
|
16458
|
+
}
|
|
16459
|
+
get armed() {
|
|
16460
|
+
return this.timer !== null;
|
|
16461
|
+
}
|
|
16462
|
+
arm() {
|
|
16463
|
+
this.cancel();
|
|
16464
|
+
if (!this.enabled) return;
|
|
16465
|
+
const timer = setTimeout(() => {
|
|
16466
|
+
if (this.timer !== timer) return;
|
|
16467
|
+
this.timer = null;
|
|
16468
|
+
void this.fire();
|
|
16469
|
+
}, this.opts.delayMs);
|
|
16470
|
+
timer.unref?.();
|
|
16471
|
+
this.timer = timer;
|
|
16472
|
+
}
|
|
16473
|
+
cancel() {
|
|
16474
|
+
if (this.timer) {
|
|
16475
|
+
clearTimeout(this.timer);
|
|
16476
|
+
this.timer = null;
|
|
16477
|
+
}
|
|
16478
|
+
}
|
|
16479
|
+
/** Resolves once an in-flight release (if any) has finished. Test hook. */
|
|
16480
|
+
async settle() {
|
|
16481
|
+
await this.releasing;
|
|
16482
|
+
}
|
|
16483
|
+
async fire() {
|
|
16484
|
+
if (!this.opts.isIdle()) return;
|
|
16485
|
+
const run = (async () => {
|
|
16486
|
+
try {
|
|
16487
|
+
await this.opts.release();
|
|
16488
|
+
} catch (error) {
|
|
16489
|
+
this.opts.onError?.(error);
|
|
16490
|
+
}
|
|
16491
|
+
})();
|
|
16492
|
+
this.releasing = run;
|
|
16493
|
+
try {
|
|
16494
|
+
await run;
|
|
16495
|
+
} finally {
|
|
16496
|
+
if (this.releasing === run) this.releasing = null;
|
|
16497
|
+
}
|
|
16498
|
+
}
|
|
16499
|
+
}
|
|
16500
|
+
|
|
16590
16501
|
function isCodexClearText(text) {
|
|
16591
16502
|
return parseSpecialCommand(text).type === "clear";
|
|
16592
16503
|
}
|
|
@@ -16720,6 +16631,12 @@ async function runCodex(opts) {
|
|
|
16720
16631
|
...forkedFromMessageId ? { forkedFromMessageId } : {}
|
|
16721
16632
|
});
|
|
16722
16633
|
metadata.attachmentKinds = [...CLAUDE_ATTACHMENT_KINDS];
|
|
16634
|
+
const importCodexThreadId = process.env[IMPORT_CODEX_THREAD_ENV];
|
|
16635
|
+
if (importCodexThreadId) {
|
|
16636
|
+
metadata.importedFromCodexThreadId = importCodexThreadId;
|
|
16637
|
+
const importTitle = process.env.HAPPY_IMPORT_TITLE;
|
|
16638
|
+
if (importTitle) metadata.summary = { text: importTitle, updatedAt: Date.now() };
|
|
16639
|
+
}
|
|
16723
16640
|
const reconnectSessionId = process.env.HAPPY_RECONNECT_SESSION_ID;
|
|
16724
16641
|
const reconnectKeyBase64 = process.env.HAPPY_RECONNECT_ENCRYPTION_KEY;
|
|
16725
16642
|
const reconnectVariant = process.env.HAPPY_RECONNECT_ENCRYPTION_VARIANT;
|
|
@@ -16765,6 +16682,7 @@ async function runCodex(opts) {
|
|
|
16765
16682
|
let client;
|
|
16766
16683
|
let reasoningProcessor;
|
|
16767
16684
|
let abortInProgress = null;
|
|
16685
|
+
let turnActive = false;
|
|
16768
16686
|
const { session: initialSession, reconnectionHandle } = setupOfflineReconnection({
|
|
16769
16687
|
api,
|
|
16770
16688
|
sessionTag,
|
|
@@ -17053,6 +16971,22 @@ async function runCodex(opts) {
|
|
|
17053
16971
|
process.stdin.setEncoding("utf8");
|
|
17054
16972
|
}
|
|
17055
16973
|
client = new CodexAppServerClient(sandboxConfig);
|
|
16974
|
+
const idleRelease = new CodexIdleReleaseTimer({
|
|
16975
|
+
delayMs: resolveCodexIdleReleaseMs(process.env[CODEX_IDLE_RELEASE_ENV]),
|
|
16976
|
+
isIdle: () => shouldReleaseIdleCodex({
|
|
16977
|
+
turnActive,
|
|
16978
|
+
queueSize: messageQueue.size(),
|
|
16979
|
+
shouldExit,
|
|
16980
|
+
abortInProgress: abortInProgress !== null
|
|
16981
|
+
}),
|
|
16982
|
+
release: async () => {
|
|
16983
|
+
const released = await client.releaseIdleProcess();
|
|
16984
|
+
if (released) {
|
|
16985
|
+
logger.debug("[Codex] Released idle app-server; thread kept for resume on next message");
|
|
16986
|
+
}
|
|
16987
|
+
},
|
|
16988
|
+
onError: (error) => logger.debug("[Codex] Idle app-server release failed", safeCodexErrorMetadata(error))
|
|
16989
|
+
});
|
|
17056
16990
|
permissionHandler = new CodexPermissionHandler(session);
|
|
17057
16991
|
permissionHandler.reset("Previous CLI process exited before responding");
|
|
17058
16992
|
reasoningProcessor = new ReasoningProcessor((message) => {
|
|
@@ -17221,6 +17155,18 @@ async function runCodex(opts) {
|
|
|
17221
17155
|
first = false;
|
|
17222
17156
|
appendSystemPromptInjected = true;
|
|
17223
17157
|
}
|
|
17158
|
+
if (!reconnectSessionId && !opts.resumeThreadId && importCodexThreadId) {
|
|
17159
|
+
await importCodexThread({
|
|
17160
|
+
client,
|
|
17161
|
+
session,
|
|
17162
|
+
messageBuffer,
|
|
17163
|
+
threadId: importCodexThreadId,
|
|
17164
|
+
cwd: process.cwd(),
|
|
17165
|
+
mcpServers
|
|
17166
|
+
});
|
|
17167
|
+
first = false;
|
|
17168
|
+
appendSystemPromptInjected = true;
|
|
17169
|
+
}
|
|
17224
17170
|
const forkCodexThreadId = process.env.HAPPY_FORK_CODEX_THREAD_ID;
|
|
17225
17171
|
if (!reconnectSessionId && forkCodexThreadId) {
|
|
17226
17172
|
try {
|
|
@@ -17242,6 +17188,7 @@ async function runCodex(opts) {
|
|
|
17242
17188
|
}
|
|
17243
17189
|
}
|
|
17244
17190
|
let pending = null;
|
|
17191
|
+
idleRelease.arm();
|
|
17245
17192
|
while (!shouldExit) {
|
|
17246
17193
|
logActiveHandles("loop-top");
|
|
17247
17194
|
let message = pending;
|
|
@@ -17262,6 +17209,8 @@ async function runCodex(opts) {
|
|
|
17262
17209
|
if (!message) {
|
|
17263
17210
|
break;
|
|
17264
17211
|
}
|
|
17212
|
+
idleRelease.cancel();
|
|
17213
|
+
turnActive = true;
|
|
17265
17214
|
if (isCodexClearText(message.message)) {
|
|
17266
17215
|
logger.debug("[Codex] Handling /clear command - resetting Codex thread state");
|
|
17267
17216
|
client.clearThreadState();
|
|
@@ -17288,10 +17237,13 @@ async function runCodex(opts) {
|
|
|
17288
17237
|
shouldExit,
|
|
17289
17238
|
sendReady
|
|
17290
17239
|
});
|
|
17240
|
+
turnActive = false;
|
|
17241
|
+
idleRelease.arm();
|
|
17291
17242
|
continue;
|
|
17292
17243
|
}
|
|
17293
17244
|
messageBuffer.addMessage(message.message, "user");
|
|
17294
17245
|
try {
|
|
17246
|
+
await client.ensureConnected();
|
|
17295
17247
|
const sandboxManagedByHappy = client.sandboxEnabled;
|
|
17296
17248
|
const executionPolicy = resolveCodexExecutionPolicy(
|
|
17297
17249
|
message.mode.permissionMode,
|
|
@@ -17358,6 +17310,8 @@ async function runCodex(opts) {
|
|
|
17358
17310
|
shouldExit,
|
|
17359
17311
|
sendReady
|
|
17360
17312
|
});
|
|
17313
|
+
turnActive = false;
|
|
17314
|
+
idleRelease.arm();
|
|
17361
17315
|
logActiveHandles("after-turn");
|
|
17362
17316
|
}
|
|
17363
17317
|
}
|
|
@@ -17381,6 +17335,7 @@ async function runCodex(opts) {
|
|
|
17381
17335
|
} catch (e) {
|
|
17382
17336
|
logger.debug("[codex]: Error while closing session", safeCodexErrorMetadata(e));
|
|
17383
17337
|
}
|
|
17338
|
+
idleRelease.cancel();
|
|
17384
17339
|
logger.debug("[codex]: client.disconnect begin");
|
|
17385
17340
|
await client.disconnect();
|
|
17386
17341
|
logger.debug("[codex]: client.disconnect done");
|
|
@@ -17565,7 +17520,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17565
17520
|
process.exit(0);
|
|
17566
17521
|
} else if (subcommand === "install-terminal-hooks") {
|
|
17567
17522
|
try {
|
|
17568
|
-
const { installTerminalHooks, parseTerminalHooksArgs, TERMINAL_HOOKS_HELP } = await import('./installTerminalHooks-
|
|
17523
|
+
const { installTerminalHooks, parseTerminalHooksArgs, TERMINAL_HOOKS_HELP } = await import('./installTerminalHooks-8CHTgUC-.mjs');
|
|
17569
17524
|
const command = parseTerminalHooksArgs(args.slice(1));
|
|
17570
17525
|
if (command.action === "help") {
|
|
17571
17526
|
console.log(TERMINAL_HOOKS_HELP);
|
|
@@ -17582,7 +17537,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17582
17537
|
}
|
|
17583
17538
|
} else if (subcommand === "spawn") {
|
|
17584
17539
|
try {
|
|
17585
|
-
const { handleSpawnCommand } = await import('./spawn-
|
|
17540
|
+
const { handleSpawnCommand } = await import('./spawn-DFIyobCt.mjs');
|
|
17586
17541
|
await handleSpawnCommand(args.slice(1));
|
|
17587
17542
|
} catch (error) {
|
|
17588
17543
|
console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
|
|
@@ -17594,7 +17549,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17594
17549
|
return;
|
|
17595
17550
|
} else if (subcommand === "sessions") {
|
|
17596
17551
|
try {
|
|
17597
|
-
const { handleSessionsCommand } = await import('./sessions-
|
|
17552
|
+
const { handleSessionsCommand } = await import('./sessions-Dh0Lg-5z.mjs');
|
|
17598
17553
|
await handleSessionsCommand(args.slice(1));
|
|
17599
17554
|
} catch (error) {
|
|
17600
17555
|
console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
|
|
@@ -17606,7 +17561,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17606
17561
|
return;
|
|
17607
17562
|
} else if (subcommand === "send") {
|
|
17608
17563
|
try {
|
|
17609
|
-
const { handleSendCommand } = await import('./send-
|
|
17564
|
+
const { handleSendCommand } = await import('./send-BT32Jiel.mjs');
|
|
17610
17565
|
await handleSendCommand(args.slice(1));
|
|
17611
17566
|
} catch (error) {
|
|
17612
17567
|
console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
|
|
@@ -17712,9 +17667,9 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17712
17667
|
if (geminiSubcommand === "project" && args[2] === "set" && args[3]) {
|
|
17713
17668
|
const projectId = args[3];
|
|
17714
17669
|
try {
|
|
17715
|
-
const { saveGoogleCloudProjectToConfig } = await import('./config-
|
|
17716
|
-
const { readCredentialsForConfiguredRelay: readCredentialsForConfiguredRelay2 } = await import('./limits-
|
|
17717
|
-
const { ApiClient: ApiClient2 } = await import('./types-
|
|
17670
|
+
const { saveGoogleCloudProjectToConfig } = await import('./config-o9NFsj8x.mjs');
|
|
17671
|
+
const { readCredentialsForConfiguredRelay: readCredentialsForConfiguredRelay2 } = await import('./limits-DefXc1TL.mjs').then(function (n) { return n.X; });
|
|
17672
|
+
const { ApiClient: ApiClient2 } = await import('./types-CrKeJuyF.mjs').then(function (n) { return n.ad; });
|
|
17718
17673
|
let userEmail = void 0;
|
|
17719
17674
|
try {
|
|
17720
17675
|
const credentials = await readCredentialsForConfiguredRelay2();
|
|
@@ -17745,7 +17700,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17745
17700
|
}
|
|
17746
17701
|
if (geminiSubcommand === "project" && args[2] === "get") {
|
|
17747
17702
|
try {
|
|
17748
|
-
const { readGeminiLocalConfig } = await import('./config-
|
|
17703
|
+
const { readGeminiLocalConfig } = await import('./config-o9NFsj8x.mjs');
|
|
17749
17704
|
const config = readGeminiLocalConfig();
|
|
17750
17705
|
if (config.googleCloudProject) {
|
|
17751
17706
|
console.log(`Current Google Cloud Project: ${config.googleCloudProject}`);
|
|
@@ -17785,7 +17740,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17785
17740
|
process.exit(0);
|
|
17786
17741
|
}
|
|
17787
17742
|
try {
|
|
17788
|
-
const { runGemini } = await import('./runGemini-
|
|
17743
|
+
const { runGemini } = await import('./runGemini-CDUObQTD.mjs');
|
|
17789
17744
|
let startedBy = void 0;
|
|
17790
17745
|
for (let i = 1; i < args.length; i++) {
|
|
17791
17746
|
if (args[i] === "--started-by") {
|
|
@@ -17815,7 +17770,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17815
17770
|
}
|
|
17816
17771
|
};
|
|
17817
17772
|
try {
|
|
17818
|
-
const { runAcp, resolveAcpAgentConfig } = await import('./index-
|
|
17773
|
+
const { runAcp, resolveAcpAgentConfig } = await import('./index-BkmfJyCf.mjs');
|
|
17819
17774
|
const parsed = parsePiRunnerArgs(args.slice(1));
|
|
17820
17775
|
const resolved = resolveAcpAgentConfig(["pi", ...parsed.passthrough]);
|
|
17821
17776
|
const { credentials } = await authAndSetupMachineIfNeeded();
|
|
@@ -17843,7 +17798,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17843
17798
|
return;
|
|
17844
17799
|
} else if (subcommand === "acp") {
|
|
17845
17800
|
try {
|
|
17846
|
-
const { runAcp, resolveAcpAgentConfig } = await import('./index-
|
|
17801
|
+
const { runAcp, resolveAcpAgentConfig } = await import('./index-BkmfJyCf.mjs');
|
|
17847
17802
|
let startedBy = void 0;
|
|
17848
17803
|
let verbose = false;
|
|
17849
17804
|
const acpArgs = [];
|
|
@@ -17883,7 +17838,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17883
17838
|
return;
|
|
17884
17839
|
} else if (subcommand === "openclaw") {
|
|
17885
17840
|
try {
|
|
17886
|
-
const { runOpenClaw } = await import('./runOpenClaw-
|
|
17841
|
+
const { runOpenClaw } = await import('./runOpenClaw-B6KMCsVB.mjs');
|
|
17887
17842
|
let startedBy = void 0;
|
|
17888
17843
|
let verbose = false;
|
|
17889
17844
|
let gatewayUrl;
|
|
@@ -17934,7 +17889,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17934
17889
|
return;
|
|
17935
17890
|
} else if (subcommand === "todo") {
|
|
17936
17891
|
try {
|
|
17937
|
-
const { handleTodoCommand } = await import('./todo-
|
|
17892
|
+
const { handleTodoCommand } = await import('./todo-jL3ttna3.mjs');
|
|
17938
17893
|
await handleTodoCommand(args.slice(1));
|
|
17939
17894
|
} catch (error) {
|
|
17940
17895
|
console.error(JSON.stringify({ error: error instanceof Error ? error.message : "Todo command failed" }));
|
|
@@ -17943,7 +17898,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17943
17898
|
return;
|
|
17944
17899
|
} else if (subcommand === "teams") {
|
|
17945
17900
|
try {
|
|
17946
|
-
const { handleTeamsCommand } = await import('./teams-
|
|
17901
|
+
const { handleTeamsCommand } = await import('./teams-CZ9ICWeB.mjs');
|
|
17947
17902
|
await handleTeamsCommand(args.slice(1));
|
|
17948
17903
|
} catch (error) {
|
|
17949
17904
|
console.error(error instanceof Error ? error.message : "Teams command failed");
|
|
@@ -17952,7 +17907,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17952
17907
|
return;
|
|
17953
17908
|
} else if (subcommand === "mcp" && args.length === 1) {
|
|
17954
17909
|
try {
|
|
17955
|
-
const { handleMcpCommand } = await import('./mcp-
|
|
17910
|
+
const { handleMcpCommand } = await import('./mcp-8DcunR0J.mjs');
|
|
17956
17911
|
await handleMcpCommand();
|
|
17957
17912
|
} catch (error) {
|
|
17958
17913
|
process.stderr.write(`[very-happy mcp] Fatal: ${error instanceof Error ? error.message : String(error)}
|
|
@@ -18314,4 +18269,4 @@ ${chalk.bold("Examples:")}
|
|
|
18314
18269
|
}
|
|
18315
18270
|
}
|
|
18316
18271
|
|
|
18317
|
-
export { ALLOWED_SPAWN_PERMISSION_MODES as A,
|
|
18272
|
+
export { ALLOWED_SPAWN_PERMISSION_MODES as A, appendStagedAttachmentsToPrompt as B, CLAUDE_ATTACHMENT_KINDS as C, DEFAULT_RECENT_LIMIT as D, BasePermissionHandler as E, writeSessionModeFile as F, GEMINI_MODEL_ENV as G, normalizeAcpPermissionMode as H, removeSessionModeFile as I, GEMINI_API_KEY_ENV as J, GOOGLE_API_KEY_ENV as K, BaseReasoningProcessor as L, MAX_READ_LIMIT as M, MessageBuffer as N, CHANGE_TITLE_INSTRUCTION as O, PI_TEAMS_EXTENSION as P, SPAWN_AGENTS as S, TEAM_SKILL as T, sanitizeSpawnPermissionMode as a, sendUserMessage as b, listSessions as c, stopSession as d, resolvePermissionRequest as e, archiveSession as f, DEFAULT_GEMINI_MODEL as g, registerAssistantSessionTools as h, isValidSpawnOrigin as i, initialMachineMetadata as j, createSessionMetadata as k, listAccountSessions as l, setupOfflineReconnection as m, MessageQueue2 as n, registerKillSessionHandler as o, StreamRelay as p, query as q, readSessionTranscript as r, sessionWebUrl as s, tmuxSupportsSessionEnv as t, hashObject as u, startHappyServer as v, waitForSessionKey as w, registerAgentAttachmentDownloads as x, TitleGenerator as y, stageClaudeAttachments as z };
|