very-happy-cli 0.2.138 → 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-bqVGMkPh.mjs → AcpBackend-BwTEBAyP.mjs} +2 -2
- package/dist/{AcpBackend-BUoDXZnv.cjs → AcpBackend-ioCPQLt4.cjs} +2 -2
- package/dist/{AcpSessionManager-BBAQ8EQf.mjs → AcpSessionManager-Bh3KETfz.mjs} +1 -1
- package/dist/{AcpSessionManager-DmmA52Ep.cjs → AcpSessionManager-o9T6W69-.cjs} +1 -1
- package/dist/{agentGuidance-WHZsBKpm.mjs → agentGuidance-DRnXdFAY.mjs} +1 -1
- package/dist/{agentGuidance-4HV-BOge.cjs → agentGuidance-Dxt2uz3R.cjs} +1 -1
- package/dist/codex/happyMcpStdioBridge.cjs +2 -2
- package/dist/codex/happyMcpStdioBridge.mjs +2 -2
- package/dist/{config-DpuZN2Rs.cjs → config-nyMHCx-i.cjs} +4 -4
- package/dist/{config-BRXqgJJj.mjs → config-o9NFsj8x.mjs} +4 -4
- package/dist/{index-Dbl5U_N0.mjs → index-BZr5l8TH.mjs} +93 -230
- package/dist/{index-DQe7ljLR.mjs → index-BkmfJyCf.mjs} +7 -7
- package/dist/{index-CRRK5P1r.cjs → index-C3NtU4Ch.cjs} +124 -266
- package/dist/{index-D8Q3OhdR.mjs → index-CTemcNko.mjs} +4 -4
- package/dist/{index-CHP265gs.cjs → index-gkFhwPXq.cjs} +4 -4
- package/dist/{index-3N-qu-RG.cjs → index-klhxcpC8.cjs} +7 -7
- package/dist/index.cjs +4 -4
- package/dist/index.mjs +4 -4
- package/dist/{installTerminalHooks-DfUGgeyb.mjs → installTerminalHooks-8CHTgUC-.mjs} +4 -4
- package/dist/{installTerminalHooks-CWGkoWDD.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-CfzVummd.cjs → limits-C_RGzva6.cjs} +26 -7
- package/dist/{limits-DEsg_gHi.mjs → limits-DefXc1TL.mjs} +26 -8
- package/dist/{mcp-UnjB3I8_.mjs → mcp-8DcunR0J.mjs} +19 -19
- package/dist/{mcp-CN2UVfut.cjs → mcp-czNIfD59.cjs} +21 -21
- package/dist/{runGemini-BZ0xXRj-.mjs → runGemini-CDUObQTD.mjs} +6 -6
- package/dist/{runGemini-BUVjTJKn.cjs → runGemini-Dy3y-lD9.cjs} +7 -7
- package/dist/{runOpenClaw-BcUmnBpW.mjs → runOpenClaw-B6KMCsVB.mjs} +5 -5
- package/dist/{runOpenClaw-Bj2EgRHB.cjs → runOpenClaw-CJusckVM.cjs} +6 -6
- package/dist/{send-BkypdBpK.cjs → send-B4Qo-87h.cjs} +4 -4
- package/dist/{send-snK_NGAA.mjs → send-BT32Jiel.mjs} +4 -4
- package/dist/{sessions-9A-uoJL_.cjs → sessions-CN2y0xBl.cjs} +4 -4
- package/dist/{sessions-DxlC4C4g.mjs → sessions-Dh0Lg-5z.mjs} +4 -4
- package/dist/{spawn-DFfHCafP.mjs → spawn-DFIyobCt.mjs} +6 -6
- package/dist/{spawn-BORLpj60.cjs → spawn-jWj3xFhX.cjs} +8 -8
- package/dist/{teams-9x2FO9RW.cjs → teams-BhFspeAY.cjs} +4 -4
- package/dist/{teams-Cfr-2Yd-.mjs → teams-CZ9ICWeB.mjs} +4 -4
- package/dist/{todo-DydKcknX.cjs → todo-B0kvqUTQ.cjs} +3 -3
- package/dist/{todo-CU5cjQZU.mjs → todo-jL3ttna3.mjs} +3 -3
- package/dist/{types-D5EsIAOe.mjs → types-CrKeJuyF.mjs} +558 -13
- package/dist/{types-CRxf_3n8.cjs → types-CxGm_YJ-.cjs} +571 -13
- package/package.json +7 -7
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
var chalk = require('chalk');
|
|
4
4
|
var os = require('node:os');
|
|
5
5
|
var node_crypto = require('node:crypto');
|
|
6
|
-
var api = require('./types-
|
|
7
|
-
var persistence = require('./limits-
|
|
6
|
+
var api = require('./types-CxGm_YJ-.cjs');
|
|
7
|
+
var persistence = require('./limits-C_RGzva6.cjs');
|
|
8
8
|
var spawn = require('cross-spawn');
|
|
9
9
|
var path = require('node:path');
|
|
10
10
|
var node_readline = require('node:readline');
|
|
11
11
|
var node_fs = require('node:fs');
|
|
12
|
-
var agentGuidance = require('./agentGuidance-
|
|
12
|
+
var agentGuidance = require('./agentGuidance-Dxt2uz3R.cjs');
|
|
13
13
|
var promises = require('node:fs/promises');
|
|
14
14
|
var fs = require('fs/promises');
|
|
15
15
|
var ink = require('ink');
|
|
@@ -115,212 +115,6 @@ function withoutServerSnapshot(response) {
|
|
|
115
115
|
return { ...response, metadataVersion: 0, agentStateVersion: 0 };
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
-
function daemonControlHeaders(controlToken) {
|
|
119
|
-
return {
|
|
120
|
-
"Content-Type": "application/json",
|
|
121
|
-
...controlToken ? { Authorization: `Bearer ${controlToken}` } : {}
|
|
122
|
-
};
|
|
123
|
-
}
|
|
124
|
-
async function daemonPost(path, body) {
|
|
125
|
-
const state = await persistence.readDaemonState();
|
|
126
|
-
if (!state?.httpPort) {
|
|
127
|
-
const errorMessage = "No daemon running, no state file found";
|
|
128
|
-
persistence.logger.debug(`[CONTROL CLIENT] ${errorMessage}`);
|
|
129
|
-
return {
|
|
130
|
-
error: errorMessage
|
|
131
|
-
};
|
|
132
|
-
}
|
|
133
|
-
try {
|
|
134
|
-
process.kill(state.pid, 0);
|
|
135
|
-
} catch (error) {
|
|
136
|
-
const errorMessage = "Daemon is not running, file is stale";
|
|
137
|
-
persistence.logger.debug(`[CONTROL CLIENT] ${errorMessage}`);
|
|
138
|
-
return {
|
|
139
|
-
error: errorMessage
|
|
140
|
-
};
|
|
141
|
-
}
|
|
142
|
-
try {
|
|
143
|
-
const timeout = process.env.HAPPY_DAEMON_HTTP_TIMEOUT ? parseInt(process.env.HAPPY_DAEMON_HTTP_TIMEOUT) : 1e4;
|
|
144
|
-
const response = await fetch(`http://127.0.0.1:${state.httpPort}${path}`, {
|
|
145
|
-
method: "POST",
|
|
146
|
-
// A state written by an old daemon has no token and must remain callable;
|
|
147
|
-
// a new daemon always writes one and rejects requests without it.
|
|
148
|
-
headers: daemonControlHeaders(state.controlToken),
|
|
149
|
-
body: JSON.stringify(body || {}),
|
|
150
|
-
// Mostly increased for stress test
|
|
151
|
-
signal: AbortSignal.timeout(timeout)
|
|
152
|
-
});
|
|
153
|
-
if (!response.ok) {
|
|
154
|
-
const failure = await response.json().catch(() => null);
|
|
155
|
-
const reason = typeof failure?.error === "string" && failure.error ? failure.error : `HTTP ${response.status}`;
|
|
156
|
-
const errorMessage = `Request failed: ${path}, ${reason}`;
|
|
157
|
-
persistence.logger.debug(`[CONTROL CLIENT] ${errorMessage}`);
|
|
158
|
-
return {
|
|
159
|
-
error: errorMessage
|
|
160
|
-
};
|
|
161
|
-
}
|
|
162
|
-
return await response.json();
|
|
163
|
-
} catch (error) {
|
|
164
|
-
const errorMessage = `Request failed: ${path}, ${error instanceof Error ? error.message : "Unknown error"}`;
|
|
165
|
-
persistence.logger.debug(`[CONTROL CLIENT] ${errorMessage}`);
|
|
166
|
-
return {
|
|
167
|
-
error: errorMessage
|
|
168
|
-
};
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
const SESSION_STARTED_RETRY_TIMEOUT_MS = 3e3;
|
|
172
|
-
const SESSION_STARTED_RETRY_INTERVAL_MS = 100;
|
|
173
|
-
async function notifyDaemonSessionStarted(sessionId, metadata, encryption) {
|
|
174
|
-
const payload = { sessionId, metadata, encryption };
|
|
175
|
-
const deadline = Date.now() + SESSION_STARTED_RETRY_TIMEOUT_MS;
|
|
176
|
-
let result;
|
|
177
|
-
while (true) {
|
|
178
|
-
result = await daemonPost("/session-started", payload);
|
|
179
|
-
if (!result?.error) {
|
|
180
|
-
return result;
|
|
181
|
-
}
|
|
182
|
-
if (Date.now() >= deadline) {
|
|
183
|
-
return result;
|
|
184
|
-
}
|
|
185
|
-
await new Promise((resolve) => setTimeout(resolve, SESSION_STARTED_RETRY_INTERVAL_MS));
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
async function listDaemonSessions() {
|
|
189
|
-
const result = await daemonPost("/list");
|
|
190
|
-
return result.children || [];
|
|
191
|
-
}
|
|
192
|
-
async function stopDaemonSession(sessionId) {
|
|
193
|
-
const result = await daemonPost("/stop-session", { sessionId });
|
|
194
|
-
return result.success || false;
|
|
195
|
-
}
|
|
196
|
-
async function spawnDaemonSession(directory, sessionId, opts) {
|
|
197
|
-
const result = await daemonPost("/spawn-session", {
|
|
198
|
-
directory,
|
|
199
|
-
sessionId,
|
|
200
|
-
spawnedBy: opts?.spawnedBy,
|
|
201
|
-
permissionMode: opts?.permissionMode,
|
|
202
|
-
agent: opts?.agent,
|
|
203
|
-
environmentVariables: opts?.environmentVariables
|
|
204
|
-
});
|
|
205
|
-
return result;
|
|
206
|
-
}
|
|
207
|
-
async function notifyDaemonSessionEvent(sessionId, event, spawnedBy) {
|
|
208
|
-
return daemonPost("/session-event", { sessionId, event, spawnedBy });
|
|
209
|
-
}
|
|
210
|
-
async function notifyDaemonClaudeAuthFailed(sessionId) {
|
|
211
|
-
return daemonPost("/session-event", { sessionId, event: "auth_failed" });
|
|
212
|
-
}
|
|
213
|
-
async function stopDaemonHttp() {
|
|
214
|
-
await daemonPost("/stop");
|
|
215
|
-
}
|
|
216
|
-
async function pushClipboardViaDaemon(text) {
|
|
217
|
-
const result = await daemonPost("/clipboard", { text });
|
|
218
|
-
if (result?.error && result.delivered === void 0) {
|
|
219
|
-
return { delivered: false, error: result.error };
|
|
220
|
-
}
|
|
221
|
-
return result;
|
|
222
|
-
}
|
|
223
|
-
async function setTerminalTitleViaDaemon(terminalId, title, ifAbsent = false) {
|
|
224
|
-
const result = await daemonPost("/terminal-title", { terminalId, title, ifAbsent });
|
|
225
|
-
if (result?.error) {
|
|
226
|
-
return { ok: false, error: result.error };
|
|
227
|
-
}
|
|
228
|
-
return { ok: result?.status === "ok", error: result?.status === "ok" ? void 0 : "unexpected daemon response" };
|
|
229
|
-
}
|
|
230
|
-
async function checkIfDaemonRunningAndCleanupStaleState() {
|
|
231
|
-
const state = await persistence.readDaemonState();
|
|
232
|
-
if (!state) {
|
|
233
|
-
return false;
|
|
234
|
-
}
|
|
235
|
-
try {
|
|
236
|
-
process.kill(state.pid, 0);
|
|
237
|
-
} catch {
|
|
238
|
-
persistence.logger.debug("[DAEMON RUN] Daemon PID not running, cleaning up state");
|
|
239
|
-
await cleanupDaemonState();
|
|
240
|
-
return false;
|
|
241
|
-
}
|
|
242
|
-
if (state.httpPort) {
|
|
243
|
-
try {
|
|
244
|
-
const response = await fetch(`http://127.0.0.1:${state.httpPort}/list`, {
|
|
245
|
-
method: "POST",
|
|
246
|
-
headers: daemonControlHeaders(state.controlToken),
|
|
247
|
-
body: "{}",
|
|
248
|
-
signal: AbortSignal.timeout(2e3)
|
|
249
|
-
});
|
|
250
|
-
if (response.ok) {
|
|
251
|
-
return true;
|
|
252
|
-
}
|
|
253
|
-
} catch {
|
|
254
|
-
persistence.logger.debug(`[DAEMON RUN] PID ${state.pid} is alive but HTTP health check failed on port ${state.httpPort}, cleaning up stale state`);
|
|
255
|
-
await cleanupDaemonState();
|
|
256
|
-
return false;
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
return true;
|
|
260
|
-
}
|
|
261
|
-
async function isDaemonRunningCurrentlyInstalledHappyVersion() {
|
|
262
|
-
persistence.logger.debug("[DAEMON CONTROL] Checking if daemon is running same version");
|
|
263
|
-
const runningDaemon = await checkIfDaemonRunningAndCleanupStaleState();
|
|
264
|
-
if (!runningDaemon) {
|
|
265
|
-
persistence.logger.debug("[DAEMON CONTROL] No daemon running, returning false");
|
|
266
|
-
return false;
|
|
267
|
-
}
|
|
268
|
-
const state = await persistence.readDaemonState();
|
|
269
|
-
if (!state) {
|
|
270
|
-
persistence.logger.debug("[DAEMON CONTROL] No daemon state found, returning false");
|
|
271
|
-
return false;
|
|
272
|
-
}
|
|
273
|
-
const currentCliVersion = persistence.configuration.currentCliVersion;
|
|
274
|
-
persistence.logger.debug(`[DAEMON CONTROL] Current CLI version: ${currentCliVersion}, Daemon started with version: ${state.startedWithCliVersion}`);
|
|
275
|
-
return currentCliVersion === state.startedWithCliVersion;
|
|
276
|
-
}
|
|
277
|
-
async function cleanupDaemonState() {
|
|
278
|
-
try {
|
|
279
|
-
await persistence.clearDaemonState();
|
|
280
|
-
persistence.logger.debug("[DAEMON RUN] Daemon state file removed");
|
|
281
|
-
} catch (error) {
|
|
282
|
-
persistence.logger.debug("[DAEMON RUN] Error cleaning up daemon metadata", error);
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
async function stopDaemon() {
|
|
286
|
-
try {
|
|
287
|
-
const state = await persistence.readDaemonState();
|
|
288
|
-
if (!state) {
|
|
289
|
-
persistence.logger.debug("No daemon state found");
|
|
290
|
-
return;
|
|
291
|
-
}
|
|
292
|
-
persistence.logger.debug(`Stopping daemon with PID ${state.pid}`);
|
|
293
|
-
try {
|
|
294
|
-
await stopDaemonHttp();
|
|
295
|
-
await waitForProcessDeath(state.pid, 2e3);
|
|
296
|
-
persistence.logger.debug("Daemon stopped gracefully via HTTP");
|
|
297
|
-
return;
|
|
298
|
-
} catch (error) {
|
|
299
|
-
persistence.logger.debug("HTTP stop failed, will force kill", error);
|
|
300
|
-
}
|
|
301
|
-
try {
|
|
302
|
-
process.kill(state.pid, "SIGKILL");
|
|
303
|
-
persistence.logger.debug("Force killed daemon");
|
|
304
|
-
} catch (error) {
|
|
305
|
-
persistence.logger.debug("Daemon already dead");
|
|
306
|
-
}
|
|
307
|
-
} catch (error) {
|
|
308
|
-
persistence.logger.debug("Error stopping daemon", error);
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
async function waitForProcessDeath(pid, timeout) {
|
|
312
|
-
const start = Date.now();
|
|
313
|
-
while (Date.now() - start < timeout) {
|
|
314
|
-
try {
|
|
315
|
-
process.kill(pid, 0);
|
|
316
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
317
|
-
} catch {
|
|
318
|
-
return;
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
throw new Error("Process did not die within timeout");
|
|
322
|
-
}
|
|
323
|
-
|
|
324
118
|
class Session {
|
|
325
119
|
path;
|
|
326
120
|
logPath;
|
|
@@ -493,7 +287,7 @@ class Session {
|
|
|
493
287
|
reportEventToDaemon = (event) => {
|
|
494
288
|
const spawnedBy = process.env.HAPPY_SPAWNED_BY;
|
|
495
289
|
if (!spawnedBy) return;
|
|
496
|
-
void notifyDaemonSessionEvent(this.client.sessionId, event, spawnedBy).catch((error) => persistence.logger.debug("[Session] Failed to report session event to daemon:", error));
|
|
290
|
+
void api.notifyDaemonSessionEvent(this.client.sessionId, event, spawnedBy).catch((error) => persistence.logger.debug("[Session] Failed to report session event to daemon:", error));
|
|
497
291
|
};
|
|
498
292
|
/** Produce an `error` notification for an unexpected session failure. */
|
|
499
293
|
onSessionError = (message) => {
|
|
@@ -4442,7 +4236,7 @@ async function claudeRemoteLauncher(session, onPermissionModeChange, onEffective
|
|
|
4442
4236
|
},
|
|
4443
4237
|
onAuthFailure: (reason) => {
|
|
4444
4238
|
session.client.sendSessionEvent({ type: "message", message: `Claude Code auth: ${reason}`, kind: "claude-auth-failed" });
|
|
4445
|
-
void notifyDaemonClaudeAuthFailed(session.client.sessionId).catch((error) => persistence.logger.debug("[remote]: auth_failed report to daemon failed:", error));
|
|
4239
|
+
void api.notifyDaemonClaudeAuthFailed(session.client.sessionId).catch((error) => persistence.logger.debug("[remote]: auth_failed report to daemon failed:", error));
|
|
4446
4240
|
},
|
|
4447
4241
|
onSessionReset: () => {
|
|
4448
4242
|
persistence.logger.debug("[remote]: Session reset");
|
|
@@ -5313,7 +5107,7 @@ function getLogFiles(logDir) {
|
|
|
5313
5107
|
async function runDoctorDaemon() {
|
|
5314
5108
|
console.log(chalk.bold("\n\u{1F916} Daemon Status"));
|
|
5315
5109
|
try {
|
|
5316
|
-
const isRunning = await checkIfDaemonRunningAndCleanupStaleState();
|
|
5110
|
+
const isRunning = await api.checkIfDaemonRunningAndCleanupStaleState();
|
|
5317
5111
|
const state = await persistence.readDaemonState();
|
|
5318
5112
|
if (isRunning && state) {
|
|
5319
5113
|
console.log(chalk.green("\u2713 Daemon is running"));
|
|
@@ -5516,7 +5310,7 @@ ${typeLabels[type] || type}:`));
|
|
|
5516
5310
|
}
|
|
5517
5311
|
console.log(chalk.bold("\n\u{1F916} Daemon Status"));
|
|
5518
5312
|
try {
|
|
5519
|
-
const isRunning = await checkIfDaemonRunningAndCleanupStaleState();
|
|
5313
|
+
const isRunning = await api.checkIfDaemonRunningAndCleanupStaleState();
|
|
5520
5314
|
const state = await persistence.readDaemonState();
|
|
5521
5315
|
const summary = daemonReadiness(authenticated, isRunning, Boolean(state));
|
|
5522
5316
|
if (summary.level === "ready" && state) {
|
|
@@ -6281,6 +6075,7 @@ function startDaemonControlServer({
|
|
|
6281
6075
|
onHappySessionWebhook,
|
|
6282
6076
|
onSessionStateEvent,
|
|
6283
6077
|
onClaudeAuthFailed,
|
|
6078
|
+
onSessionTurnEvent,
|
|
6284
6079
|
pushClipboard,
|
|
6285
6080
|
onTerminalHook,
|
|
6286
6081
|
setTerminalTitle
|
|
@@ -6337,7 +6132,7 @@ function startDaemonControlServer({
|
|
|
6337
6132
|
schema: {
|
|
6338
6133
|
body: z.z.object({
|
|
6339
6134
|
sessionId: z.z.string(),
|
|
6340
|
-
event: z.z.enum(["completed", "needs_input", "auth_failed"]),
|
|
6135
|
+
event: z.z.enum(["completed", "needs_input", "auth_failed", "turn_started", "turn_ended"]),
|
|
6341
6136
|
spawnedBy: z.z.string().optional()
|
|
6342
6137
|
}),
|
|
6343
6138
|
response: {
|
|
@@ -6353,6 +6148,10 @@ function startDaemonControlServer({
|
|
|
6353
6148
|
onClaudeAuthFailed?.(sessionId);
|
|
6354
6149
|
return { status: "ok" };
|
|
6355
6150
|
}
|
|
6151
|
+
if (event === "turn_started" || event === "turn_ended") {
|
|
6152
|
+
onSessionTurnEvent?.(sessionId, event);
|
|
6153
|
+
return { status: "ok" };
|
|
6154
|
+
}
|
|
6356
6155
|
onSessionStateEvent?.(sessionId, event, spawnedBy);
|
|
6357
6156
|
return { status: "ok" };
|
|
6358
6157
|
});
|
|
@@ -8055,7 +7854,7 @@ function parseJsonObject(text) {
|
|
|
8055
7854
|
return null;
|
|
8056
7855
|
}
|
|
8057
7856
|
}
|
|
8058
|
-
function resolveSdkClaudeBinary(platform = process.platform, arch = process.arch, resolver = (s) => node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-
|
|
7857
|
+
function resolveSdkClaudeBinary(platform = process.platform, arch = process.arch, resolver = (s) => node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-C3NtU4Ch.cjs', document.baseURI).href))).resolve(s)) {
|
|
8059
7858
|
const platformArch = `${platform}-${arch}`;
|
|
8060
7859
|
const candidates = [
|
|
8061
7860
|
`@anthropic-ai/claude-agent-sdk-${platformArch}/claude`,
|
|
@@ -9670,7 +9469,7 @@ function toSummary(id, persisted, extra) {
|
|
|
9670
9469
|
};
|
|
9671
9470
|
}
|
|
9672
9471
|
async function listSessions(options = {}) {
|
|
9673
|
-
const live = await listDaemonSessions();
|
|
9472
|
+
const live = await api.listDaemonSessions();
|
|
9674
9473
|
return mergeSessionSummaries(live, persistence.readPersistedSessions(), options);
|
|
9675
9474
|
}
|
|
9676
9475
|
function summarizeAccountSession(row, persisted, liveIds, now) {
|
|
@@ -9740,7 +9539,7 @@ async function listAccountSessions(options = {}) {
|
|
|
9740
9539
|
});
|
|
9741
9540
|
const rows = Array.isArray(response.data?.sessions) ? response.data.sessions : [];
|
|
9742
9541
|
const persisted = persistence.readPersistedSessions();
|
|
9743
|
-
const live = await listDaemonSessions();
|
|
9542
|
+
const live = await api.listDaemonSessions();
|
|
9744
9543
|
const liveIds = new Set(live.map((child) => child.happySessionId).filter((id) => typeof id === "string"));
|
|
9745
9544
|
const now = Date.now();
|
|
9746
9545
|
const summaries = rows.filter((row) => typeof row?.id === "string").map((row) => summarizeAccountSession(row, persisted[row.id], liveIds, now)).filter((summary) => options.includeArchived || !summary.archived);
|
|
@@ -9774,7 +9573,7 @@ async function readSessionTranscript(sessionId, limit) {
|
|
|
9774
9573
|
const messages = Array.isArray(response.data?.messages) ? response.data.messages : [];
|
|
9775
9574
|
messages.reverse();
|
|
9776
9575
|
const key = persistence.decodeBase64(persisted.encryptionKey);
|
|
9777
|
-
const live = await listDaemonSessions();
|
|
9576
|
+
const live = await api.listDaemonSessions();
|
|
9778
9577
|
const bodies = messages.map((message) => {
|
|
9779
9578
|
if (message.content?.t !== "encrypted") return null;
|
|
9780
9579
|
try {
|
|
@@ -9790,7 +9589,7 @@ async function readSessionTranscript(sessionId, limit) {
|
|
|
9790
9589
|
};
|
|
9791
9590
|
}
|
|
9792
9591
|
async function stopSession(sessionId) {
|
|
9793
|
-
return await stopDaemonSession(sessionId);
|
|
9592
|
+
return await api.stopDaemonSession(sessionId);
|
|
9794
9593
|
}
|
|
9795
9594
|
async function archiveSession(sessionId) {
|
|
9796
9595
|
const token = await bearerToken();
|
|
@@ -10218,7 +10017,7 @@ async function startDaemon() {
|
|
|
10218
10017
|
});
|
|
10219
10018
|
persistence.logger.debug("[DAEMON RUN] Starting daemon process...");
|
|
10220
10019
|
persistence.logger.debugLargeJson("[DAEMON RUN] Environment", getEnvironmentInfo());
|
|
10221
|
-
const runningDaemonVersionMatches = await isDaemonRunningCurrentlyInstalledHappyVersion();
|
|
10020
|
+
const runningDaemonVersionMatches = await api.isDaemonRunningCurrentlyInstalledHappyVersion();
|
|
10222
10021
|
const runningDaemonState = await persistence.readDaemonState();
|
|
10223
10022
|
const runningDaemonEndpointsMatch = Boolean(runningDaemonState) && daemonEndpointsMatch(
|
|
10224
10023
|
runningDaemonState?.serverUrl,
|
|
@@ -10228,7 +10027,7 @@ async function startDaemon() {
|
|
|
10228
10027
|
);
|
|
10229
10028
|
if (!runningDaemonVersionMatches || !runningDaemonEndpointsMatch) {
|
|
10230
10029
|
persistence.logger.debug("[DAEMON RUN] Daemon version or endpoint mismatch detected, restarting daemon");
|
|
10231
|
-
await stopDaemon();
|
|
10030
|
+
await api.stopDaemon();
|
|
10232
10031
|
} else {
|
|
10233
10032
|
persistence.logger.debug("[DAEMON RUN] Daemon version matches, keeping existing daemon");
|
|
10234
10033
|
console.log("Daemon already running with matching version");
|
|
@@ -10247,6 +10046,7 @@ async function startDaemon() {
|
|
|
10247
10046
|
const { credentials, machineId } = await authAndSetupMachineIfNeeded();
|
|
10248
10047
|
persistence.logger.debug("[DAEMON RUN] Auth and machine setup complete");
|
|
10249
10048
|
const pidToTrackedSession = /* @__PURE__ */ new Map();
|
|
10049
|
+
const turnActivity = new api.TurnActivityTracker();
|
|
10250
10050
|
const sessionIdToFinishedSession = /* @__PURE__ */ new Map();
|
|
10251
10051
|
let teamWorker;
|
|
10252
10052
|
const persisted = persistence.readPersistedSessions();
|
|
@@ -10518,6 +10318,9 @@ async function startDaemon() {
|
|
|
10518
10318
|
if (options.resumeCodexThreadId) {
|
|
10519
10319
|
extraEnv.HAPPY_FORK_CODEX_THREAD_ID = options.resumeCodexThreadId;
|
|
10520
10320
|
}
|
|
10321
|
+
if (options.importCodexThreadId && UUID_RE.test(options.importCodexThreadId)) {
|
|
10322
|
+
extraEnv.HAPPY_IMPORT_CODEX_THREAD_ID = options.importCodexThreadId;
|
|
10323
|
+
}
|
|
10521
10324
|
if (options.variant === "assistant") {
|
|
10522
10325
|
extraEnv.HAPPY_SESSION_VARIANT = "assistant";
|
|
10523
10326
|
}
|
|
@@ -11082,6 +10885,7 @@ async function startDaemon() {
|
|
|
11082
10885
|
const onChildExited = (pid) => {
|
|
11083
10886
|
const session = pidToTrackedSession.get(pid);
|
|
11084
10887
|
if (session?.happySessionId && (session.spawnedBy === "teams" || teamWorker?.hasSession(session.happySessionId))) teamWorker?.report(session.happySessionId, "exited");
|
|
10888
|
+
if (session?.happySessionId) turnActivity.forget(session.happySessionId);
|
|
11085
10889
|
if (session?.happySessionId && session.encryption) {
|
|
11086
10890
|
sessionIdToFinishedSession.set(session.happySessionId, session);
|
|
11087
10891
|
persistence.logger.debug(`[DAEMON RUN] Process PID ${pid} exited, preserved session ${session.happySessionId} for resume`);
|
|
@@ -11163,6 +10967,7 @@ async function startDaemon() {
|
|
|
11163
10967
|
onHappySessionWebhook,
|
|
11164
10968
|
onSessionStateEvent,
|
|
11165
10969
|
onClaudeAuthFailed: (sessionId) => claudeAuthServiceRef?.signalAuthFailed(sessionId),
|
|
10970
|
+
onSessionTurnEvent: (sessionId, event) => turnActivity.apply(sessionId, event),
|
|
11166
10971
|
pushClipboard: (text) => {
|
|
11167
10972
|
if (!apiMachineRef) {
|
|
11168
10973
|
return { delivered: false, truncated: false, totalBytes: 0, error: "daemon is still starting up" };
|
|
@@ -11275,7 +11080,10 @@ async function startDaemon() {
|
|
|
11275
11080
|
const updateController = createUpdateController({
|
|
11276
11081
|
policy: () => api.fetchCliUpdateState(persistence.configuration.serverUrl, persistence.packageJson.version),
|
|
11277
11082
|
enabled: async () => ((await persistence.readSettings()).cliAutoUpdate ?? "idle") !== "off",
|
|
11278
|
-
|
|
11083
|
+
// B-466: "idle" = no agent turn in flight. Idle wrappers survive a
|
|
11084
|
+
// handover (they talk to the server themselves) and web terminals live
|
|
11085
|
+
// in tmux, so neither is a reason to hold an update.
|
|
11086
|
+
idle: () => !turnActivity.hasActiveTurn(),
|
|
11279
11087
|
install: installCliSafely,
|
|
11280
11088
|
publish: (state) => {
|
|
11281
11089
|
cliUpdateStateRef = state;
|
|
@@ -11330,7 +11138,7 @@ async function startDaemon() {
|
|
|
11330
11138
|
} catch {
|
|
11331
11139
|
}
|
|
11332
11140
|
}
|
|
11333
|
-
if (bundleReplaced && !teamWorker?.busy && !updateController.isRunning() &&
|
|
11141
|
+
if (bundleReplaced && !teamWorker?.busy && !updateController.isRunning() && !turnActivity.hasActiveTurn()) {
|
|
11334
11142
|
const preflight = await preflightNewBundle(bundlePath);
|
|
11335
11143
|
if (preflight.action === "hold") {
|
|
11336
11144
|
if (lastHandoverHold !== preflight.reason) {
|
|
@@ -11340,7 +11148,7 @@ async function startDaemon() {
|
|
|
11340
11148
|
updateController.holdHandover(preflight.reason);
|
|
11341
11149
|
return;
|
|
11342
11150
|
}
|
|
11343
|
-
if (teamWorker?.busy || updateController.isRunning() ||
|
|
11151
|
+
if (teamWorker?.busy || updateController.isRunning() || turnActivity.hasActiveTurn()) return;
|
|
11344
11152
|
lastHandoverHold = null;
|
|
11345
11153
|
persistence.logger.debug("[DAEMON RUN] Daemon bundle replaced on disk and verified, handing off to new daemon");
|
|
11346
11154
|
teamWorker?.stop();
|
|
@@ -11350,7 +11158,7 @@ async function startDaemon() {
|
|
|
11350
11158
|
claudeAuthService.stop();
|
|
11351
11159
|
apiMachine.shutdown();
|
|
11352
11160
|
await stopControlServer();
|
|
11353
|
-
await cleanupDaemonState();
|
|
11161
|
+
await api.cleanupDaemonState();
|
|
11354
11162
|
await persistence.releaseDaemonLock(daemonLockHandle);
|
|
11355
11163
|
await stopCaffeinate();
|
|
11356
11164
|
try {
|
|
@@ -11423,7 +11231,7 @@ async function startDaemon() {
|
|
|
11423
11231
|
}
|
|
11424
11232
|
apiMachine.shutdown();
|
|
11425
11233
|
await stopControlServer();
|
|
11426
|
-
await cleanupDaemonState();
|
|
11234
|
+
await api.cleanupDaemonState();
|
|
11427
11235
|
await stopCaffeinate();
|
|
11428
11236
|
await persistence.releaseDaemonLock(daemonLockHandle);
|
|
11429
11237
|
persistence.logger.debug("[DAEMON RUN] Cleanup completed, exiting process");
|
|
@@ -11731,7 +11539,7 @@ ${body}`);
|
|
|
11731
11539
|
if (!normalized.ok) return fail(normalized.error);
|
|
11732
11540
|
const directory = normalized.directory;
|
|
11733
11541
|
try {
|
|
11734
|
-
const result = await spawnDaemonSession(directory, void 0, { spawnedBy: "assistant" });
|
|
11542
|
+
const result = await api.spawnDaemonSession(directory, void 0, { spawnedBy: "assistant" });
|
|
11735
11543
|
if (result?.error || !result?.sessionId) {
|
|
11736
11544
|
return fail(`Failed to spawn session: ${result?.error ?? "daemon returned no session id"}`);
|
|
11737
11545
|
}
|
|
@@ -12498,7 +12306,7 @@ function registerSideQuestionHandler(rpc, deps) {
|
|
|
12498
12306
|
const retainMs = deps.retainMs ?? SIDE_QUESTION_RETAIN_MS;
|
|
12499
12307
|
const maxRunMs = deps.maxRunMs ?? SIDE_QUESTION_MAX_RUN_MS;
|
|
12500
12308
|
const run = deps.run ?? (async (input) => {
|
|
12501
|
-
const { query } = await Promise.resolve().then(function () { return require('./index-
|
|
12309
|
+
const { query } = await Promise.resolve().then(function () { return require('./index-gkFhwPXq.cjs'); });
|
|
12502
12310
|
return runSideQuestion(query, input);
|
|
12503
12311
|
});
|
|
12504
12312
|
const slots = /* @__PURE__ */ new Map();
|
|
@@ -12600,7 +12408,7 @@ const MAX_TITLE_CHARS = 60;
|
|
|
12600
12408
|
const GENERATION_TIMEOUT_MS = 3e4;
|
|
12601
12409
|
function resolveClaudeBinary() {
|
|
12602
12410
|
try {
|
|
12603
|
-
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-
|
|
12411
|
+
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-C3NtU4Ch.cjs', document.baseURI).href)));
|
|
12604
12412
|
const utilsPath = path.resolve(path.join(api.projectPath(), "scripts", "claude_version_utils.cjs"));
|
|
12605
12413
|
const { getClaudeCliPath } = require$1(utilsPath);
|
|
12606
12414
|
const path$1 = getClaudeCliPath();
|
|
@@ -13162,7 +12970,7 @@ async function runClaude(credentials, options = {}) {
|
|
|
13162
12970
|
}
|
|
13163
12971
|
try {
|
|
13164
12972
|
persistence.logger.debug(`[START] Reporting session ${response.id} to daemon`);
|
|
13165
|
-
const result = await notifyDaemonSessionStarted(response.id, metadata, {
|
|
12973
|
+
const result = await api.notifyDaemonSessionStarted(response.id, metadata, {
|
|
13166
12974
|
encryptionKey: persistence.encodeBase64(response.encryptionKey),
|
|
13167
12975
|
encryptionVariant: response.encryptionVariant,
|
|
13168
12976
|
seq: response.seq,
|
|
@@ -13890,7 +13698,7 @@ async function handleAuthLogin(args) {
|
|
|
13890
13698
|
console.log(chalk.gray(" \u2022 Re-authenticate and register machine\n"));
|
|
13891
13699
|
try {
|
|
13892
13700
|
persistence.logger.debug("Stopping daemon for force auth...");
|
|
13893
|
-
await stopDaemon();
|
|
13701
|
+
await api.stopDaemon();
|
|
13894
13702
|
console.log(chalk.gray("\u2713 Stopped daemon"));
|
|
13895
13703
|
} catch (error) {
|
|
13896
13704
|
persistence.logger.debug("Daemon was not running or failed to stop:", error);
|
|
@@ -13955,7 +13763,7 @@ async function handleAuthLogout() {
|
|
|
13955
13763
|
if (answer.toLowerCase() === "y" || answer.toLowerCase() === "yes") {
|
|
13956
13764
|
try {
|
|
13957
13765
|
try {
|
|
13958
|
-
await stopDaemon();
|
|
13766
|
+
await api.stopDaemon();
|
|
13959
13767
|
console.log(chalk.gray("Stopped daemon"));
|
|
13960
13768
|
} catch {
|
|
13961
13769
|
}
|
|
@@ -14000,7 +13808,7 @@ async function handleAuthStatus() {
|
|
|
14000
13808
|
console.log(chalk.gray(`
|
|
14001
13809
|
Data directory: ${persistence.configuration.happyHomeDir}`));
|
|
14002
13810
|
try {
|
|
14003
|
-
const running = await checkIfDaemonRunningAndCleanupStaleState();
|
|
13811
|
+
const running = await api.checkIfDaemonRunningAndCleanupStaleState();
|
|
14004
13812
|
if (running) {
|
|
14005
13813
|
console.log(chalk.green("\u2713 Daemon running"));
|
|
14006
13814
|
} else {
|
|
@@ -14826,9 +14634,9 @@ function resolveLocalSignupBootstrap(configuredMode, configuredInviteCodes, gene
|
|
|
14826
14634
|
};
|
|
14827
14635
|
}
|
|
14828
14636
|
|
|
14829
|
-
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-
|
|
14637
|
+
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-C3NtU4Ch.cjs', document.baseURI).href)));
|
|
14830
14638
|
const __dirname$1 = path.dirname(__filename$1);
|
|
14831
|
-
const require_ = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-
|
|
14639
|
+
const require_ = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-C3NtU4Ch.cjs', document.baseURI).href)));
|
|
14832
14640
|
const PRISMA_QUERY_ENGINE_FILES = {
|
|
14833
14641
|
"arm64-darwin": "libquery_engine-darwin-arm64.dylib.node",
|
|
14834
14642
|
"x64-darwin": "libquery_engine-darwin.dylib.node",
|
|
@@ -15217,7 +15025,7 @@ const DAEMON_READY_TIMEOUT_MS = 5e3;
|
|
|
15217
15025
|
const DAEMON_READY_POLL_INTERVAL_MS = 100;
|
|
15218
15026
|
async function ensureDaemonRunning() {
|
|
15219
15027
|
persistence.logger.debug("Ensuring Happy background service is running & matches our version...");
|
|
15220
|
-
const versionMatches = await isDaemonRunningCurrentlyInstalledHappyVersion();
|
|
15028
|
+
const versionMatches = await api.isDaemonRunningCurrentlyInstalledHappyVersion();
|
|
15221
15029
|
const state = await persistence.readDaemonState();
|
|
15222
15030
|
const endpointsMatch = Boolean(state) && daemonEndpointsMatch(
|
|
15223
15031
|
state?.serverUrl,
|
|
@@ -15228,9 +15036,9 @@ async function ensureDaemonRunning() {
|
|
|
15228
15036
|
if (versionMatches && endpointsMatch) {
|
|
15229
15037
|
return;
|
|
15230
15038
|
}
|
|
15231
|
-
if (await checkIfDaemonRunningAndCleanupStaleState()) {
|
|
15039
|
+
if (await api.checkIfDaemonRunningAndCleanupStaleState()) {
|
|
15232
15040
|
persistence.logger.debug("Stopping daemon whose version or configured relay no longer matches...");
|
|
15233
|
-
await stopDaemon();
|
|
15041
|
+
await api.stopDaemon();
|
|
15234
15042
|
}
|
|
15235
15043
|
persistence.logger.debug("Starting Happy background service...");
|
|
15236
15044
|
const daemonProcess = spawnHappyCLI(["daemon", "start-sync"], {
|
|
@@ -15241,7 +15049,7 @@ async function ensureDaemonRunning() {
|
|
|
15241
15049
|
daemonProcess.unref();
|
|
15242
15050
|
const deadline = Date.now() + DAEMON_READY_TIMEOUT_MS;
|
|
15243
15051
|
while (Date.now() < deadline) {
|
|
15244
|
-
if (await checkIfDaemonRunningAndCleanupStaleState()) {
|
|
15052
|
+
if (await api.checkIfDaemonRunningAndCleanupStaleState()) {
|
|
15245
15053
|
persistence.logger.debug("Happy background service is ready");
|
|
15246
15054
|
return;
|
|
15247
15055
|
}
|
|
@@ -16594,6 +16402,43 @@ async function resumeExistingThread(opts) {
|
|
|
16594
16402
|
}
|
|
16595
16403
|
}
|
|
16596
16404
|
|
|
16405
|
+
const IMPORT_CODEX_THREAD_ENV = "HAPPY_IMPORT_CODEX_THREAD_ID";
|
|
16406
|
+
async function importCodexThread(opts) {
|
|
16407
|
+
let forked;
|
|
16408
|
+
try {
|
|
16409
|
+
forked = await opts.client.forkThread({
|
|
16410
|
+
threadId: opts.threadId,
|
|
16411
|
+
cwd: opts.cwd,
|
|
16412
|
+
mcpServers: opts.mcpServers
|
|
16413
|
+
});
|
|
16414
|
+
} catch (error) {
|
|
16415
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
16416
|
+
throw new Error(`Failed to import Codex thread ${opts.threadId}: ${reason}`);
|
|
16417
|
+
}
|
|
16418
|
+
if (!forked.threadId || forked.threadId === opts.threadId) {
|
|
16419
|
+
throw new Error(`Failed to import Codex thread ${opts.threadId}: Codex did not create an independent copy`);
|
|
16420
|
+
}
|
|
16421
|
+
opts.session.updateMetadata((currentMetadata) => ({
|
|
16422
|
+
...currentMetadata,
|
|
16423
|
+
codexThreadId: forked.threadId,
|
|
16424
|
+
importedFromCodexThreadId: opts.threadId
|
|
16425
|
+
}));
|
|
16426
|
+
let thread = forked.thread;
|
|
16427
|
+
if (!Array.isArray(thread?.turns)) {
|
|
16428
|
+
thread = (await opts.client.readThread({ threadId: forked.threadId, includeTurns: true })).thread;
|
|
16429
|
+
}
|
|
16430
|
+
const envelopes = mapCodexThreadToSessionEnvelopes(thread);
|
|
16431
|
+
for (const envelope of envelopes) {
|
|
16432
|
+
opts.session.sendSessionProtocolMessage(envelope);
|
|
16433
|
+
}
|
|
16434
|
+
opts.messageBuffer.addMessage(`Imported thread ${agentGuidance.trimIdent(opts.threadId)} as ${agentGuidance.trimIdent(forked.threadId)}`, "status");
|
|
16435
|
+
opts.session.sendSessionEvent({
|
|
16436
|
+
type: "message",
|
|
16437
|
+
message: `Imported Codex thread ${opts.threadId} (continuing as ${forked.threadId})`
|
|
16438
|
+
});
|
|
16439
|
+
return { threadId: forked.threadId, model: forked.model, replayed: envelopes.length };
|
|
16440
|
+
}
|
|
16441
|
+
|
|
16597
16442
|
function emitReadyIfIdle({ pending, queueSize, shouldExit, sendReady, notify }) {
|
|
16598
16443
|
if (shouldExit) {
|
|
16599
16444
|
return false;
|
|
@@ -16808,6 +16653,12 @@ async function runCodex(opts) {
|
|
|
16808
16653
|
...forkedFromMessageId ? { forkedFromMessageId } : {}
|
|
16809
16654
|
});
|
|
16810
16655
|
metadata.attachmentKinds = [...CLAUDE_ATTACHMENT_KINDS];
|
|
16656
|
+
const importCodexThreadId = process.env[IMPORT_CODEX_THREAD_ENV];
|
|
16657
|
+
if (importCodexThreadId) {
|
|
16658
|
+
metadata.importedFromCodexThreadId = importCodexThreadId;
|
|
16659
|
+
const importTitle = process.env.HAPPY_IMPORT_TITLE;
|
|
16660
|
+
if (importTitle) metadata.summary = { text: importTitle, updatedAt: Date.now() };
|
|
16661
|
+
}
|
|
16811
16662
|
const reconnectSessionId = process.env.HAPPY_RECONNECT_SESSION_ID;
|
|
16812
16663
|
const reconnectKeyBase64 = process.env.HAPPY_RECONNECT_ENCRYPTION_KEY;
|
|
16813
16664
|
const reconnectVariant = process.env.HAPPY_RECONNECT_ENCRYPTION_VARIANT;
|
|
@@ -16878,7 +16729,7 @@ async function runCodex(opts) {
|
|
|
16878
16729
|
if (response) {
|
|
16879
16730
|
try {
|
|
16880
16731
|
persistence.logger.debug(`[START] Reporting session ${response.id} to daemon`);
|
|
16881
|
-
const result = await notifyDaemonSessionStarted(response.id, metadata, {
|
|
16732
|
+
const result = await api.notifyDaemonSessionStarted(response.id, metadata, {
|
|
16882
16733
|
encryptionKey: persistence.encodeBase64(response.encryptionKey),
|
|
16883
16734
|
encryptionVariant: response.encryptionVariant,
|
|
16884
16735
|
seq: response.seq,
|
|
@@ -17326,6 +17177,18 @@ async function runCodex(opts) {
|
|
|
17326
17177
|
first = false;
|
|
17327
17178
|
appendSystemPromptInjected = true;
|
|
17328
17179
|
}
|
|
17180
|
+
if (!reconnectSessionId && !opts.resumeThreadId && importCodexThreadId) {
|
|
17181
|
+
await importCodexThread({
|
|
17182
|
+
client,
|
|
17183
|
+
session,
|
|
17184
|
+
messageBuffer,
|
|
17185
|
+
threadId: importCodexThreadId,
|
|
17186
|
+
cwd: process.cwd(),
|
|
17187
|
+
mcpServers
|
|
17188
|
+
});
|
|
17189
|
+
first = false;
|
|
17190
|
+
appendSystemPromptInjected = true;
|
|
17191
|
+
}
|
|
17329
17192
|
const forkCodexThreadId = process.env.HAPPY_FORK_CODEX_THREAD_ID;
|
|
17330
17193
|
if (!reconnectSessionId && forkCodexThreadId) {
|
|
17331
17194
|
try {
|
|
@@ -17679,7 +17542,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17679
17542
|
process.exit(0);
|
|
17680
17543
|
} else if (subcommand === "install-terminal-hooks") {
|
|
17681
17544
|
try {
|
|
17682
|
-
const { installTerminalHooks, parseTerminalHooksArgs, TERMINAL_HOOKS_HELP } = await Promise.resolve().then(function () { return require('./installTerminalHooks-
|
|
17545
|
+
const { installTerminalHooks, parseTerminalHooksArgs, TERMINAL_HOOKS_HELP } = await Promise.resolve().then(function () { return require('./installTerminalHooks-DZUBgnFh.cjs'); });
|
|
17683
17546
|
const command = parseTerminalHooksArgs(args.slice(1));
|
|
17684
17547
|
if (command.action === "help") {
|
|
17685
17548
|
console.log(TERMINAL_HOOKS_HELP);
|
|
@@ -17696,7 +17559,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17696
17559
|
}
|
|
17697
17560
|
} else if (subcommand === "spawn") {
|
|
17698
17561
|
try {
|
|
17699
|
-
const { handleSpawnCommand } = await Promise.resolve().then(function () { return require('./spawn-
|
|
17562
|
+
const { handleSpawnCommand } = await Promise.resolve().then(function () { return require('./spawn-jWj3xFhX.cjs'); });
|
|
17700
17563
|
await handleSpawnCommand(args.slice(1));
|
|
17701
17564
|
} catch (error) {
|
|
17702
17565
|
console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
|
|
@@ -17708,7 +17571,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17708
17571
|
return;
|
|
17709
17572
|
} else if (subcommand === "sessions") {
|
|
17710
17573
|
try {
|
|
17711
|
-
const { handleSessionsCommand } = await Promise.resolve().then(function () { return require('./sessions-
|
|
17574
|
+
const { handleSessionsCommand } = await Promise.resolve().then(function () { return require('./sessions-CN2y0xBl.cjs'); });
|
|
17712
17575
|
await handleSessionsCommand(args.slice(1));
|
|
17713
17576
|
} catch (error) {
|
|
17714
17577
|
console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
|
|
@@ -17720,7 +17583,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17720
17583
|
return;
|
|
17721
17584
|
} else if (subcommand === "send") {
|
|
17722
17585
|
try {
|
|
17723
|
-
const { handleSendCommand } = await Promise.resolve().then(function () { return require('./send-
|
|
17586
|
+
const { handleSendCommand } = await Promise.resolve().then(function () { return require('./send-B4Qo-87h.cjs'); });
|
|
17724
17587
|
await handleSendCommand(args.slice(1));
|
|
17725
17588
|
} catch (error) {
|
|
17726
17589
|
console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
|
|
@@ -17826,9 +17689,9 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17826
17689
|
if (geminiSubcommand === "project" && args[2] === "set" && args[3]) {
|
|
17827
17690
|
const projectId = args[3];
|
|
17828
17691
|
try {
|
|
17829
|
-
const { saveGoogleCloudProjectToConfig } = await Promise.resolve().then(function () { return require('./config-
|
|
17830
|
-
const { readCredentialsForConfiguredRelay: readCredentialsForConfiguredRelay2 } = await Promise.resolve().then(function () { return require('./limits-
|
|
17831
|
-
const { ApiClient: ApiClient2 } = await Promise.resolve().then(function () { return require('./types-
|
|
17692
|
+
const { saveGoogleCloudProjectToConfig } = await Promise.resolve().then(function () { return require('./config-nyMHCx-i.cjs'); });
|
|
17693
|
+
const { readCredentialsForConfiguredRelay: readCredentialsForConfiguredRelay2 } = await Promise.resolve().then(function () { return require('./limits-C_RGzva6.cjs'); }).then(function (n) { return n.persistence; });
|
|
17694
|
+
const { ApiClient: ApiClient2 } = await Promise.resolve().then(function () { return require('./types-CxGm_YJ-.cjs'); }).then(function (n) { return n.api; });
|
|
17832
17695
|
let userEmail = void 0;
|
|
17833
17696
|
try {
|
|
17834
17697
|
const credentials = await readCredentialsForConfiguredRelay2();
|
|
@@ -17859,7 +17722,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17859
17722
|
}
|
|
17860
17723
|
if (geminiSubcommand === "project" && args[2] === "get") {
|
|
17861
17724
|
try {
|
|
17862
|
-
const { readGeminiLocalConfig } = await Promise.resolve().then(function () { return require('./config-
|
|
17725
|
+
const { readGeminiLocalConfig } = await Promise.resolve().then(function () { return require('./config-nyMHCx-i.cjs'); });
|
|
17863
17726
|
const config = readGeminiLocalConfig();
|
|
17864
17727
|
if (config.googleCloudProject) {
|
|
17865
17728
|
console.log(`Current Google Cloud Project: ${config.googleCloudProject}`);
|
|
@@ -17899,7 +17762,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17899
17762
|
process.exit(0);
|
|
17900
17763
|
}
|
|
17901
17764
|
try {
|
|
17902
|
-
const { runGemini } = await Promise.resolve().then(function () { return require('./runGemini-
|
|
17765
|
+
const { runGemini } = await Promise.resolve().then(function () { return require('./runGemini-Dy3y-lD9.cjs'); });
|
|
17903
17766
|
let startedBy = void 0;
|
|
17904
17767
|
for (let i = 1; i < args.length; i++) {
|
|
17905
17768
|
if (args[i] === "--started-by") {
|
|
@@ -17929,7 +17792,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17929
17792
|
}
|
|
17930
17793
|
};
|
|
17931
17794
|
try {
|
|
17932
|
-
const { runAcp, resolveAcpAgentConfig } = await Promise.resolve().then(function () { return require('./index-
|
|
17795
|
+
const { runAcp, resolveAcpAgentConfig } = await Promise.resolve().then(function () { return require('./index-klhxcpC8.cjs'); });
|
|
17933
17796
|
const parsed = parsePiRunnerArgs(args.slice(1));
|
|
17934
17797
|
const resolved = resolveAcpAgentConfig(["pi", ...parsed.passthrough]);
|
|
17935
17798
|
const { credentials } = await authAndSetupMachineIfNeeded();
|
|
@@ -17957,7 +17820,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17957
17820
|
return;
|
|
17958
17821
|
} else if (subcommand === "acp") {
|
|
17959
17822
|
try {
|
|
17960
|
-
const { runAcp, resolveAcpAgentConfig } = await Promise.resolve().then(function () { return require('./index-
|
|
17823
|
+
const { runAcp, resolveAcpAgentConfig } = await Promise.resolve().then(function () { return require('./index-klhxcpC8.cjs'); });
|
|
17961
17824
|
let startedBy = void 0;
|
|
17962
17825
|
let verbose = false;
|
|
17963
17826
|
const acpArgs = [];
|
|
@@ -17997,7 +17860,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17997
17860
|
return;
|
|
17998
17861
|
} else if (subcommand === "openclaw") {
|
|
17999
17862
|
try {
|
|
18000
|
-
const { runOpenClaw } = await Promise.resolve().then(function () { return require('./runOpenClaw-
|
|
17863
|
+
const { runOpenClaw } = await Promise.resolve().then(function () { return require('./runOpenClaw-CJusckVM.cjs'); });
|
|
18001
17864
|
let startedBy = void 0;
|
|
18002
17865
|
let verbose = false;
|
|
18003
17866
|
let gatewayUrl;
|
|
@@ -18048,7 +17911,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
18048
17911
|
return;
|
|
18049
17912
|
} else if (subcommand === "todo") {
|
|
18050
17913
|
try {
|
|
18051
|
-
const { handleTodoCommand } = await Promise.resolve().then(function () { return require('./todo-
|
|
17914
|
+
const { handleTodoCommand } = await Promise.resolve().then(function () { return require('./todo-B0kvqUTQ.cjs'); });
|
|
18052
17915
|
await handleTodoCommand(args.slice(1));
|
|
18053
17916
|
} catch (error) {
|
|
18054
17917
|
console.error(JSON.stringify({ error: error instanceof Error ? error.message : "Todo command failed" }));
|
|
@@ -18057,7 +17920,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
18057
17920
|
return;
|
|
18058
17921
|
} else if (subcommand === "teams") {
|
|
18059
17922
|
try {
|
|
18060
|
-
const { handleTeamsCommand } = await Promise.resolve().then(function () { return require('./teams-
|
|
17923
|
+
const { handleTeamsCommand } = await Promise.resolve().then(function () { return require('./teams-BhFspeAY.cjs'); });
|
|
18061
17924
|
await handleTeamsCommand(args.slice(1));
|
|
18062
17925
|
} catch (error) {
|
|
18063
17926
|
console.error(error instanceof Error ? error.message : "Teams command failed");
|
|
@@ -18066,7 +17929,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
18066
17929
|
return;
|
|
18067
17930
|
} else if (subcommand === "mcp" && args.length === 1) {
|
|
18068
17931
|
try {
|
|
18069
|
-
const { handleMcpCommand } = await Promise.resolve().then(function () { return require('./mcp-
|
|
17932
|
+
const { handleMcpCommand } = await Promise.resolve().then(function () { return require('./mcp-czNIfD59.cjs'); });
|
|
18070
17933
|
await handleMcpCommand();
|
|
18071
17934
|
} catch (error) {
|
|
18072
17935
|
process.stderr.write(`[very-happy mcp] Fatal: ${error instanceof Error ? error.message : String(error)}
|
|
@@ -18089,7 +17952,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
18089
17952
|
const daemonSubcommand = args[1];
|
|
18090
17953
|
if (daemonSubcommand === "list") {
|
|
18091
17954
|
try {
|
|
18092
|
-
const sessions = await listDaemonSessions();
|
|
17955
|
+
const sessions = await api.listDaemonSessions();
|
|
18093
17956
|
if (sessions.length === 0) {
|
|
18094
17957
|
console.log("No active sessions this daemon is aware of (they might have been started by a previous version of the daemon)");
|
|
18095
17958
|
} else {
|
|
@@ -18107,7 +17970,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
18107
17970
|
process.exit(1);
|
|
18108
17971
|
}
|
|
18109
17972
|
try {
|
|
18110
|
-
const success = await stopDaemonSession(sessionId);
|
|
17973
|
+
const success = await api.stopDaemonSession(sessionId);
|
|
18111
17974
|
console.log(success ? "Session stopped" : "Failed to stop session");
|
|
18112
17975
|
} catch (error) {
|
|
18113
17976
|
console.log("No daemon running");
|
|
@@ -18115,7 +17978,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
18115
17978
|
return;
|
|
18116
17979
|
} else if (daemonSubcommand === "start") {
|
|
18117
17980
|
const currentState = await persistence.readDaemonState();
|
|
18118
|
-
const running = await checkIfDaemonRunningAndCleanupStaleState();
|
|
17981
|
+
const running = await api.checkIfDaemonRunningAndCleanupStaleState();
|
|
18119
17982
|
const currentDaemonMatches = currentState && currentState.startedWithCliVersion === persistence.configuration.currentCliVersion && daemonEndpointsMatch(
|
|
18120
17983
|
currentState.serverUrl,
|
|
18121
17984
|
currentState.webappUrl,
|
|
@@ -18124,7 +17987,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
18124
17987
|
);
|
|
18125
17988
|
if (running && !currentDaemonMatches) {
|
|
18126
17989
|
console.log("Configured relay or CLI version changed; restarting the existing daemon");
|
|
18127
|
-
await stopDaemon();
|
|
17990
|
+
await api.stopDaemon();
|
|
18128
17991
|
}
|
|
18129
17992
|
const child = spawnHappyCLI(["daemon", "start-sync"], {
|
|
18130
17993
|
detached: true,
|
|
@@ -18134,7 +17997,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
18134
17997
|
child.unref();
|
|
18135
17998
|
let started = false;
|
|
18136
17999
|
for (let i = 0; i < 50; i++) {
|
|
18137
|
-
if (await checkIfDaemonRunningAndCleanupStaleState()) {
|
|
18000
|
+
if (await api.checkIfDaemonRunningAndCleanupStaleState()) {
|
|
18138
18001
|
started = true;
|
|
18139
18002
|
break;
|
|
18140
18003
|
}
|
|
@@ -18151,7 +18014,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
18151
18014
|
await startDaemon();
|
|
18152
18015
|
process.exit(0);
|
|
18153
18016
|
} else if (daemonSubcommand === "stop") {
|
|
18154
|
-
await stopDaemon();
|
|
18017
|
+
await api.stopDaemon();
|
|
18155
18018
|
process.exit(0);
|
|
18156
18019
|
} else if (daemonSubcommand === "status") {
|
|
18157
18020
|
await runDoctorDaemon();
|
|
@@ -18448,7 +18311,6 @@ exports.TEAM_SKILL = TEAM_SKILL;
|
|
|
18448
18311
|
exports.TitleGenerator = TitleGenerator;
|
|
18449
18312
|
exports.appendStagedAttachmentsToPrompt = appendStagedAttachmentsToPrompt;
|
|
18450
18313
|
exports.archiveSession = archiveSession;
|
|
18451
|
-
exports.checkIfDaemonRunningAndCleanupStaleState = checkIfDaemonRunningAndCleanupStaleState;
|
|
18452
18314
|
exports.createSessionMetadata = createSessionMetadata;
|
|
18453
18315
|
exports.hashObject = hashObject;
|
|
18454
18316
|
exports.initialMachineMetadata = initialMachineMetadata;
|
|
@@ -18456,8 +18318,6 @@ exports.isValidSpawnOrigin = isValidSpawnOrigin;
|
|
|
18456
18318
|
exports.listAccountSessions = listAccountSessions;
|
|
18457
18319
|
exports.listSessions = listSessions;
|
|
18458
18320
|
exports.normalizeAcpPermissionMode = normalizeAcpPermissionMode;
|
|
18459
|
-
exports.notifyDaemonSessionStarted = notifyDaemonSessionStarted;
|
|
18460
|
-
exports.pushClipboardViaDaemon = pushClipboardViaDaemon;
|
|
18461
18321
|
exports.query = query;
|
|
18462
18322
|
exports.readSessionTranscript = readSessionTranscript;
|
|
18463
18323
|
exports.registerAgentAttachmentDownloads = registerAgentAttachmentDownloads;
|
|
@@ -18468,9 +18328,7 @@ exports.resolvePermissionRequest = resolvePermissionRequest;
|
|
|
18468
18328
|
exports.sanitizeSpawnPermissionMode = sanitizeSpawnPermissionMode;
|
|
18469
18329
|
exports.sendUserMessage = sendUserMessage;
|
|
18470
18330
|
exports.sessionWebUrl = sessionWebUrl;
|
|
18471
|
-
exports.setTerminalTitleViaDaemon = setTerminalTitleViaDaemon;
|
|
18472
18331
|
exports.setupOfflineReconnection = setupOfflineReconnection;
|
|
18473
|
-
exports.spawnDaemonSession = spawnDaemonSession;
|
|
18474
18332
|
exports.stageClaudeAttachments = stageClaudeAttachments;
|
|
18475
18333
|
exports.startHappyServer = startHappyServer;
|
|
18476
18334
|
exports.stopSession = stopSession;
|