very-happy-cli 0.2.153 → 0.2.155
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-YDGv4E-g.mjs → AcpBackend-DVB0nzgR.mjs} +2 -2
- package/dist/{AcpBackend-DSt8nTYm.cjs → AcpBackend-DmFcRh54.cjs} +3 -3
- package/dist/{AcpSessionManager-uov6I9C8.cjs → AcpSessionManager-CWaSYTnT.cjs} +1 -1
- package/dist/{AcpSessionManager-Cxf5HQX1.mjs → AcpSessionManager-dGDgNb-p.mjs} +1 -1
- package/dist/agentGuidance-BWxFC6UL.mjs +1613 -0
- package/dist/agentGuidance-un7YPryB.cjs +1665 -0
- package/dist/{agentHome-D68Xh2ae.mjs → agentHome-ByLb2HFg.mjs} +5 -5
- package/dist/{agentHome-BJ7bde35.cjs → agentHome-aucT8BHw.cjs} +5 -5
- package/dist/{auto-CcXxfqkC.mjs → auto-BQnD6gVx.mjs} +21 -21
- package/dist/{auto-C-90ojIH.cjs → auto-P9RoJaY0.cjs} +24 -24
- package/dist/codex/happyMcpStdioBridge.cjs +6 -3
- package/dist/codex/happyMcpStdioBridge.mjs +6 -3
- package/dist/{config-CHJ189UJ.mjs → config-BPZ2Y6o8.mjs} +8 -8
- package/dist/{config-D23kF0_u.cjs → config-BoePh9PX.cjs} +8 -8
- package/dist/{index-D49WvbDT.cjs → index--KCpVs1c.cjs} +7 -7
- package/dist/{index-BacwoXzs.mjs → index-B4oXnbYw.mjs} +522 -729
- package/dist/{index-BgYZGODP.mjs → index-BjzdXb9x.mjs} +21 -13
- package/dist/{index-DEOVn46R.cjs → index-DRrLaljt.cjs} +21 -13
- package/dist/{index-BXA9fxbK.mjs → index-DVVRqaVG.mjs} +7 -7
- package/dist/{index-DHrwHxHf.cjs → index-D_fYUxVg.cjs} +579 -798
- package/dist/index.cjs +6 -6
- package/dist/index.mjs +6 -6
- package/dist/{install-BiOXBnnS.cjs → install-CGigiocs.cjs} +1 -1
- package/dist/{install-Ca7_Z3bV.mjs → install-DP5aPNEX.mjs} +1 -1
- package/dist/{installTerminalHooks-BF0kL0ae.cjs → installTerminalHooks-XrcPvfBs.cjs} +5 -5
- package/dist/{installTerminalHooks-Bpl32K75.mjs → installTerminalHooks-tIg7mANc.mjs} +5 -5
- package/dist/lib.cjs +2 -2
- package/dist/lib.mjs +2 -2
- package/dist/{limits-BtAuKRl2.mjs → limits-C_DW0M0q.mjs} +309 -13
- package/dist/{limits-DY_sFA3J.cjs → limits-DkfHJ3nS.cjs} +329 -12
- package/dist/{mcp-JpqI2POW.cjs → mcp-BqlXl10F.cjs} +23 -23
- package/dist/{mcp-DQkmk4VV.mjs → mcp-o7QglAQM.mjs} +17 -17
- package/dist/{piRuntime-DRbbeQ72.cjs → piRuntime-BxP4B_zY.cjs} +2 -2
- package/dist/{piRuntime-DBpe12NN.mjs → piRuntime-MjiJI-nV.mjs} +2 -2
- package/dist/{piTerminal-qdJ9KZVL.cjs → piTerminal-DYzRcwgb.cjs} +6 -6
- package/dist/{piTerminal-BoHvPEZ_.mjs → piTerminal-Dpq6yqKU.mjs} +6 -6
- package/dist/{runGemini-CtOEFvhf.cjs → runGemini-8Pxh94Fm.cjs} +7 -7
- package/dist/{runGemini-YqH7a-7O.mjs → runGemini-CDlcQ-OA.mjs} +6 -6
- package/dist/{runOpenClaw-DoqZXBvL.cjs → runOpenClaw-B5FSZIbK.cjs} +6 -6
- package/dist/{runOpenClaw-DSSyFQBb.mjs → runOpenClaw-YkhsgPs0.mjs} +5 -5
- package/dist/{send-9075kHZP.cjs → send-CwrYXTPr.cjs} +58 -54
- package/dist/{send-Cs-RwqNf.mjs → send-DJStmLBv.mjs} +56 -53
- package/dist/{sessions-iBnYzVUK.mjs → sessions-JaVXlSqj.mjs} +88 -45
- package/dist/{sessions-qULzUzlI.cjs → sessions-MX21NJXd.cjs} +99 -56
- package/dist/{spawn-C6fRkedx.mjs → spawn-BaPnjClT.mjs} +22 -22
- package/dist/{spawn-od9V23cc.cjs → spawn-cIoglKVf.cjs} +30 -30
- package/dist/{teams-CkrWQ4uM.mjs → teams-DXV5Pwwt.mjs} +8 -8
- package/dist/{teams-CrCzU-AV.cjs → teams-Dqk7F3D-.cjs} +8 -8
- package/dist/{todo-aCZmSt27.mjs → todo-2Z1REhfx.mjs} +8 -6
- package/dist/{todo-BCT_ZPuV.cjs → todo-Buuqn9gm.cjs} +8 -6
- package/dist/{types-BvqOVUOW.mjs → types-CkbfdRzq.mjs} +7 -267
- package/dist/{types-CUCU7Vw8.cjs → types-a2xsH2UI.cjs} +19 -295
- package/package.json +7 -7
- package/dist/agentGuidance-BM4kMNyr.cjs +0 -553
- package/dist/agentGuidance-C8unGWp7.mjs +0 -529
|
@@ -3,38 +3,36 @@
|
|
|
3
3
|
var chalk = require('chalk');
|
|
4
4
|
var node_fs = require('node:fs');
|
|
5
5
|
var path = require('node:path');
|
|
6
|
-
var
|
|
7
|
-
var
|
|
8
|
-
var index = require('./
|
|
9
|
-
require('
|
|
10
|
-
require('node:events');
|
|
11
|
-
require('socket.io-client');
|
|
6
|
+
var persistence = require('./limits-DkfHJ3nS.cjs');
|
|
7
|
+
var index = require('./index-D_fYUxVg.cjs');
|
|
8
|
+
var index$1 = require('./types-a2xsH2UI.cjs');
|
|
9
|
+
var agentGuidance = require('./agentGuidance-un7YPryB.cjs');
|
|
12
10
|
require('zod');
|
|
11
|
+
require('@paralleldrive/cuid2');
|
|
12
|
+
require('node:fs/promises');
|
|
13
13
|
require('node:crypto');
|
|
14
|
-
require('
|
|
15
|
-
require('util');
|
|
16
|
-
require('
|
|
17
|
-
require('crypto');
|
|
18
|
-
require('path');
|
|
14
|
+
require('tweetnacl');
|
|
15
|
+
require('node:util');
|
|
16
|
+
require('node:os');
|
|
19
17
|
require('cross-spawn');
|
|
18
|
+
require('node:readline');
|
|
20
19
|
require('./terminalTitleSuggest-Dji8I0Jy.cjs');
|
|
20
|
+
require('path');
|
|
21
21
|
require('url');
|
|
22
|
+
require('fs/promises');
|
|
23
|
+
require('ink');
|
|
24
|
+
require('react');
|
|
25
|
+
require('@anthropic-ai/claude-agent-sdk');
|
|
26
|
+
require('axios');
|
|
27
|
+
require('node:events');
|
|
28
|
+
require('socket.io-client');
|
|
22
29
|
require('os');
|
|
23
|
-
require('
|
|
24
|
-
require('node:fs/promises');
|
|
25
|
-
require('node:os');
|
|
30
|
+
require('child_process');
|
|
26
31
|
require('node:child_process');
|
|
27
|
-
require('node-pty');
|
|
28
32
|
require('fs');
|
|
29
|
-
require('tweetnacl');
|
|
30
|
-
require('node:readline');
|
|
31
33
|
require('@anthropic-ai/sandbox-runtime');
|
|
32
34
|
require('expo-server-sdk');
|
|
33
|
-
require('
|
|
34
|
-
require('./agentGuidance-BM4kMNyr.cjs');
|
|
35
|
-
require('ink');
|
|
36
|
-
require('react');
|
|
37
|
-
require('@anthropic-ai/claude-agent-sdk');
|
|
35
|
+
require('crypto');
|
|
38
36
|
require('ps-list');
|
|
39
37
|
require('tmp');
|
|
40
38
|
require('open');
|
|
@@ -45,9 +43,11 @@ require('@modelcontextprotocol/sdk/server/mcp.js');
|
|
|
45
43
|
require('node:http');
|
|
46
44
|
require('@modelcontextprotocol/sdk/server/streamableHttp.js');
|
|
47
45
|
require('http');
|
|
46
|
+
require('util');
|
|
48
47
|
require('inquirer');
|
|
49
48
|
require('node:url');
|
|
50
49
|
require('node:readline/promises');
|
|
50
|
+
require('node-pty');
|
|
51
51
|
|
|
52
52
|
function nonEmpty(value) {
|
|
53
53
|
return typeof value === "string" && value.trim().length > 0;
|
|
@@ -216,9 +216,9 @@ ${chalk.bold("Exit codes:")}
|
|
|
216
216
|
`);
|
|
217
217
|
}
|
|
218
218
|
async function sendFirstMessage(sessionId, text, metaFor) {
|
|
219
|
-
const persisted = await
|
|
219
|
+
const persisted = await agentGuidance.waitForSessionKey(sessionId, 15e3);
|
|
220
220
|
const meta = metaFor(persisted.metadata?.capabilities ?? null);
|
|
221
|
-
await
|
|
221
|
+
await agentGuidance.sendUserMessage(sessionId, persisted, text, "cli-spawn", meta);
|
|
222
222
|
return meta;
|
|
223
223
|
}
|
|
224
224
|
async function handleSpawnCommand(args) {
|
|
@@ -238,7 +238,7 @@ async function handleSpawnCommand(args) {
|
|
|
238
238
|
if (options.fork !== void 0) {
|
|
239
239
|
try {
|
|
240
240
|
const persisted = persistence.readPersistedSessions()[options.fork];
|
|
241
|
-
const current = persisted ? await
|
|
241
|
+
const current = persisted ? await agentGuidance.readSessionMetadata(options.fork, persisted) : null;
|
|
242
242
|
forkSource = resolveForkSource(options.fork, persisted && current ? { ...persisted, metadata: { ...persisted.metadata, ...current } } : persisted);
|
|
243
243
|
} catch (error) {
|
|
244
244
|
console.error(chalk.red("Error:"), error instanceof Error ? error.message : String(error));
|
|
@@ -286,7 +286,7 @@ async function handleSpawnCommand(args) {
|
|
|
286
286
|
console.error(chalk.red("Error:"), `Directory does not exist: ${directory}`);
|
|
287
287
|
process.exit(1);
|
|
288
288
|
}
|
|
289
|
-
if (!await
|
|
289
|
+
if (!await persistence.checkIfDaemonRunningAndCleanupStaleState()) {
|
|
290
290
|
console.error(chalk.red("Error:"), "Happy daemon is not running on this machine.");
|
|
291
291
|
console.error(`Start it with ${chalk.cyan("very-happy daemon start")} and retry.`);
|
|
292
292
|
process.exit(1);
|
|
@@ -301,7 +301,7 @@ async function handleSpawnCommand(args) {
|
|
|
301
301
|
}
|
|
302
302
|
}
|
|
303
303
|
persistence.logger.debug(`[SPAWN CMD] Spawning session in ${directory}${forkSource ? ` (fork of ${forkSource.parentSessionId})` : ""}`);
|
|
304
|
-
const result = await
|
|
304
|
+
const result = await persistence.spawnDaemonSession(directory, void 0, {
|
|
305
305
|
spawnedBy: options.spawnedBy,
|
|
306
306
|
permissionMode,
|
|
307
307
|
agent,
|
|
@@ -315,9 +315,9 @@ async function handleSpawnCommand(args) {
|
|
|
315
315
|
process.exit(1);
|
|
316
316
|
}
|
|
317
317
|
const sessionId = result.sessionId;
|
|
318
|
-
const url =
|
|
318
|
+
const url = agentGuidance.sessionWebUrl(sessionId);
|
|
319
319
|
if (forkSource && result.resumed !== true) {
|
|
320
|
-
await
|
|
320
|
+
await persistence.stopDaemonSession(sessionId).catch(() => false);
|
|
321
321
|
console.error(chalk.red("Error:"), "The running daemon is too old to fork from the CLI (it spawned a fresh session, now stopped). Restart the daemon on this CLI version and retry.");
|
|
322
322
|
process.exit(1);
|
|
323
323
|
}
|
|
@@ -372,7 +372,7 @@ async function handleSpawnCommand(args) {
|
|
|
372
372
|
}
|
|
373
373
|
|
|
374
374
|
exports.SPAWN_AGENTS = index.SPAWN_AGENTS;
|
|
375
|
-
exports.sessionWebUrl =
|
|
375
|
+
exports.sessionWebUrl = agentGuidance.sessionWebUrl;
|
|
376
376
|
exports.handleSpawnCommand = handleSpawnCommand;
|
|
377
377
|
exports.parseEnvAssignment = parseEnvAssignment;
|
|
378
378
|
exports.parseSpawnArgs = parseSpawnArgs;
|
|
@@ -2,20 +2,20 @@ import { homedir } from 'node:os';
|
|
|
2
2
|
import { readFile } from 'node:fs/promises';
|
|
3
3
|
import { z } from 'zod';
|
|
4
4
|
import { randomUUID } from 'node:crypto';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import { a as installTeamSkill, i as installAutomationSkill } from './install-
|
|
5
|
+
import { B as teamRequest, C as createTeamsClient } from './agentGuidance-BWxFC6UL.mjs';
|
|
6
|
+
import { h as readCredentialsForConfiguredRelay } from './limits-C_DW0M0q.mjs';
|
|
7
|
+
import { a as installTeamSkill, i as installAutomationSkill } from './install-DP5aPNEX.mjs';
|
|
8
8
|
import 'node:fs';
|
|
9
9
|
import 'node:path';
|
|
10
|
+
import 'axios';
|
|
11
|
+
import 'socket.io-client';
|
|
12
|
+
import '@paralleldrive/cuid2';
|
|
10
13
|
import 'tweetnacl';
|
|
11
14
|
import 'chalk';
|
|
12
15
|
import 'node:util';
|
|
13
|
-
import '
|
|
14
|
-
import './
|
|
15
|
-
import './types-BvqOVUOW.mjs';
|
|
16
|
-
import 'axios';
|
|
16
|
+
import './index-B4oXnbYw.mjs';
|
|
17
|
+
import './types-CkbfdRzq.mjs';
|
|
17
18
|
import 'node:events';
|
|
18
|
-
import 'socket.io-client';
|
|
19
19
|
import 'child_process';
|
|
20
20
|
import 'util';
|
|
21
21
|
import 'fs/promises';
|
|
@@ -4,20 +4,20 @@ var os = require('node:os');
|
|
|
4
4
|
var promises = require('node:fs/promises');
|
|
5
5
|
var z = require('zod');
|
|
6
6
|
var node_crypto = require('node:crypto');
|
|
7
|
-
var agentGuidance = require('./agentGuidance-
|
|
8
|
-
var persistence = require('./limits-
|
|
9
|
-
var install = require('./install-
|
|
7
|
+
var agentGuidance = require('./agentGuidance-un7YPryB.cjs');
|
|
8
|
+
var persistence = require('./limits-DkfHJ3nS.cjs');
|
|
9
|
+
var install = require('./install-CGigiocs.cjs');
|
|
10
10
|
require('node:fs');
|
|
11
11
|
require('node:path');
|
|
12
|
+
require('axios');
|
|
13
|
+
require('socket.io-client');
|
|
14
|
+
require('@paralleldrive/cuid2');
|
|
12
15
|
require('tweetnacl');
|
|
13
16
|
require('chalk');
|
|
14
17
|
require('node:util');
|
|
15
|
-
require('
|
|
16
|
-
require('./
|
|
17
|
-
require('./types-CUCU7Vw8.cjs');
|
|
18
|
-
require('axios');
|
|
18
|
+
require('./index-D_fYUxVg.cjs');
|
|
19
|
+
require('./types-a2xsH2UI.cjs');
|
|
19
20
|
require('node:events');
|
|
20
|
-
require('socket.io-client');
|
|
21
21
|
require('child_process');
|
|
22
22
|
require('util');
|
|
23
23
|
require('fs/promises');
|
|
@@ -1,15 +1,17 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { h as readCredentialsForConfiguredRelay, j as createBuiltinTodoClient, c as configuration, B as BUILTIN_TODO_SKILL } from './limits-C_DW0M0q.mjs';
|
|
2
|
+
import { u as readTeamScope, v as teamScopePath } from './agentGuidance-BWxFC6UL.mjs';
|
|
3
|
+
import 'zod';
|
|
4
|
+
import '@paralleldrive/cuid2';
|
|
3
5
|
import 'node:fs/promises';
|
|
4
6
|
import 'node:fs';
|
|
5
|
-
import 'node:os';
|
|
6
|
-
import 'node:path';
|
|
7
|
-
import 'zod';
|
|
8
7
|
import 'node:crypto';
|
|
9
8
|
import 'tweetnacl';
|
|
10
9
|
import 'chalk';
|
|
11
10
|
import 'node:util';
|
|
12
|
-
import '
|
|
11
|
+
import 'node:os';
|
|
12
|
+
import 'node:path';
|
|
13
|
+
import 'axios';
|
|
14
|
+
import 'socket.io-client';
|
|
13
15
|
|
|
14
16
|
async function authenticatedBuiltinTodoClient() {
|
|
15
17
|
if (process.env.VH_TEAM_SCOPE_FILE !== void 0) {
|
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var persistence = require('./limits-
|
|
4
|
-
var agentGuidance = require('./agentGuidance-
|
|
3
|
+
var persistence = require('./limits-DkfHJ3nS.cjs');
|
|
4
|
+
var agentGuidance = require('./agentGuidance-un7YPryB.cjs');
|
|
5
|
+
require('zod');
|
|
6
|
+
require('@paralleldrive/cuid2');
|
|
5
7
|
require('node:fs/promises');
|
|
6
8
|
require('node:fs');
|
|
7
|
-
require('node:os');
|
|
8
|
-
require('node:path');
|
|
9
|
-
require('zod');
|
|
10
9
|
require('node:crypto');
|
|
11
10
|
require('tweetnacl');
|
|
12
11
|
require('chalk');
|
|
13
12
|
require('node:util');
|
|
14
|
-
require('
|
|
13
|
+
require('node:os');
|
|
14
|
+
require('node:path');
|
|
15
|
+
require('axios');
|
|
16
|
+
require('socket.io-client');
|
|
15
17
|
|
|
16
18
|
async function authenticatedBuiltinTodoClient() {
|
|
17
19
|
if (process.env.VH_TEAM_SCOPE_FILE !== void 0) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import axios from 'axios';
|
|
2
|
-
import {
|
|
2
|
+
import { R as AgentVersionsSchema, l as logger, w as encodeBase64, L as encrypt, N as decrypt, M as decodeBase64, c as configuration, e as createEnvelope, s as streamKeyOf, S as backoff, T as ReleaseDrainNoticeSchema, U as decryptBlob, V as RelayAssignmentResponseSchema, W as notifyDaemonTurnEvent, X as prepareClipboardText, Y as prepareClipboardHistoryText, g as delay, r as readSettings, d as readPersistedSessions, Z as credentialRelayProblem, F as packageJson, _ as RelayCandidatesResponseSchema, $ as readTrackedClaudeSessionIds, a0 as readTrackedCodexThreadIds, a1 as isValidTerminalId, a2 as exponentialBackoffDelay, a3 as libsodiumEncryptForPublicKey, a4 as libsodiumPublicKeyFromSecretKey, a5 as getRandomBytes, a6 as redactLogValue } from './limits-C_DW0M0q.mjs';
|
|
3
3
|
import { EventEmitter } from 'node:events';
|
|
4
4
|
import { io } from 'socket.io-client';
|
|
5
5
|
import { z } from 'zod';
|
|
@@ -73,8 +73,9 @@ const CliUpdateStateSchema = z.object({
|
|
|
73
73
|
recommendedVersion: z.string().nullable(),
|
|
74
74
|
minimumVersion: z.string().nullable(),
|
|
75
75
|
status: z.enum(["current", "available", "required"]),
|
|
76
|
-
/** B-351: the version this machine may install by itself
|
|
77
|
-
*
|
|
76
|
+
/** B-351/B-503: the version this machine may install by itself, as decided
|
|
77
|
+
* by the relay (exact pin or the promoted `latest`); null means no
|
|
78
|
+
* unattended install. */
|
|
78
79
|
autoUpdateVersion: z.string().nullable().optional(),
|
|
79
80
|
retrySupported: z.boolean().optional(),
|
|
80
81
|
manualUpdateSupported: z.boolean().optional(),
|
|
@@ -331,41 +332,6 @@ const AgentMessageSchema = z.object({
|
|
|
331
332
|
});
|
|
332
333
|
z.union([UserMessageSchema, AgentMessageSchema]);
|
|
333
334
|
|
|
334
|
-
async function delay(ms) {
|
|
335
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
336
|
-
}
|
|
337
|
-
function exponentialBackoffDelay(currentFailureCount, minDelay, maxDelay, maxFailureCount) {
|
|
338
|
-
let maxDelayRet = minDelay + (maxDelay - minDelay) / maxFailureCount * Math.min(currentFailureCount, maxFailureCount);
|
|
339
|
-
return Math.round(Math.random() * maxDelayRet);
|
|
340
|
-
}
|
|
341
|
-
function createBackoff(opts) {
|
|
342
|
-
return async (callback) => {
|
|
343
|
-
let currentFailureCount = 0;
|
|
344
|
-
const minDelay = opts && opts.minDelay !== void 0 ? opts.minDelay : 250;
|
|
345
|
-
const maxDelay = opts && opts.maxDelay !== void 0 ? opts.maxDelay : 1e3;
|
|
346
|
-
const maxFailureCount = opts && opts.maxFailureCount !== void 0 ? opts.maxFailureCount : 50;
|
|
347
|
-
while (true) {
|
|
348
|
-
try {
|
|
349
|
-
return await callback();
|
|
350
|
-
} catch (e) {
|
|
351
|
-
if (currentFailureCount < maxFailureCount) {
|
|
352
|
-
currentFailureCount++;
|
|
353
|
-
}
|
|
354
|
-
if (opts && opts.onError) {
|
|
355
|
-
opts.onError(e, currentFailureCount);
|
|
356
|
-
}
|
|
357
|
-
let waitForRequest = exponentialBackoffDelay(currentFailureCount, minDelay, maxDelay, maxFailureCount);
|
|
358
|
-
await delay(waitForRequest);
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
};
|
|
362
|
-
}
|
|
363
|
-
let backoff = createBackoff({
|
|
364
|
-
onError: (e, failuresCount) => {
|
|
365
|
-
logger.debug(`[BACKOFF] retry ${failuresCount}:`, e?.message || e);
|
|
366
|
-
}
|
|
367
|
-
});
|
|
368
|
-
|
|
369
335
|
function isRateQuotaCode(code) {
|
|
370
336
|
return typeof code === "string" && code.endsWith("_rate_quota_exceeded");
|
|
371
337
|
}
|
|
@@ -2220,223 +2186,6 @@ class TurnReporter {
|
|
|
2220
2186
|
}
|
|
2221
2187
|
}
|
|
2222
2188
|
|
|
2223
|
-
function daemonControlHeaders(controlToken) {
|
|
2224
|
-
return {
|
|
2225
|
-
"Content-Type": "application/json",
|
|
2226
|
-
...controlToken ? { Authorization: `Bearer ${controlToken}` } : {}
|
|
2227
|
-
};
|
|
2228
|
-
}
|
|
2229
|
-
async function daemonPost(path, body) {
|
|
2230
|
-
const state = await readDaemonState();
|
|
2231
|
-
if (!state?.httpPort) {
|
|
2232
|
-
const errorMessage = "No daemon running, no state file found";
|
|
2233
|
-
logger.debug(`[CONTROL CLIENT] ${errorMessage}`);
|
|
2234
|
-
return {
|
|
2235
|
-
error: errorMessage
|
|
2236
|
-
};
|
|
2237
|
-
}
|
|
2238
|
-
try {
|
|
2239
|
-
process.kill(state.pid, 0);
|
|
2240
|
-
} catch (error) {
|
|
2241
|
-
const errorMessage = "Daemon is not running, file is stale";
|
|
2242
|
-
logger.debug(`[CONTROL CLIENT] ${errorMessage}`);
|
|
2243
|
-
return {
|
|
2244
|
-
error: errorMessage
|
|
2245
|
-
};
|
|
2246
|
-
}
|
|
2247
|
-
try {
|
|
2248
|
-
const timeout = process.env.HAPPY_DAEMON_HTTP_TIMEOUT ? parseInt(process.env.HAPPY_DAEMON_HTTP_TIMEOUT) : 1e4;
|
|
2249
|
-
const response = await fetch(`http://127.0.0.1:${state.httpPort}${path}`, {
|
|
2250
|
-
method: "POST",
|
|
2251
|
-
// A state written by an old daemon has no token and must remain callable;
|
|
2252
|
-
// a new daemon always writes one and rejects requests without it.
|
|
2253
|
-
headers: daemonControlHeaders(state.controlToken),
|
|
2254
|
-
body: JSON.stringify(body || {}),
|
|
2255
|
-
// Mostly increased for stress test
|
|
2256
|
-
signal: AbortSignal.timeout(timeout)
|
|
2257
|
-
});
|
|
2258
|
-
if (!response.ok) {
|
|
2259
|
-
const failure = await response.json().catch(() => null);
|
|
2260
|
-
const reason = typeof failure?.error === "string" && failure.error ? failure.error : `HTTP ${response.status}`;
|
|
2261
|
-
const errorMessage = `Request failed: ${path}, ${reason}`;
|
|
2262
|
-
logger.debug(`[CONTROL CLIENT] ${errorMessage}`);
|
|
2263
|
-
return {
|
|
2264
|
-
error: errorMessage
|
|
2265
|
-
};
|
|
2266
|
-
}
|
|
2267
|
-
return await response.json();
|
|
2268
|
-
} catch (error) {
|
|
2269
|
-
const errorMessage = `Request failed: ${path}, ${error instanceof Error ? error.message : "Unknown error"}`;
|
|
2270
|
-
logger.debug(`[CONTROL CLIENT] ${errorMessage}`);
|
|
2271
|
-
return {
|
|
2272
|
-
error: errorMessage
|
|
2273
|
-
};
|
|
2274
|
-
}
|
|
2275
|
-
}
|
|
2276
|
-
const SESSION_STARTED_RETRY_TIMEOUT_MS = 3e3;
|
|
2277
|
-
const SESSION_STARTED_RETRY_INTERVAL_MS = 100;
|
|
2278
|
-
async function notifyDaemonSessionStarted(sessionId, metadata, encryption) {
|
|
2279
|
-
const payload = { sessionId, metadata, encryption };
|
|
2280
|
-
const deadline = Date.now() + SESSION_STARTED_RETRY_TIMEOUT_MS;
|
|
2281
|
-
let result;
|
|
2282
|
-
while (true) {
|
|
2283
|
-
result = await daemonPost("/session-started", payload);
|
|
2284
|
-
if (!result?.error) {
|
|
2285
|
-
return result;
|
|
2286
|
-
}
|
|
2287
|
-
if (Date.now() >= deadline) {
|
|
2288
|
-
return result;
|
|
2289
|
-
}
|
|
2290
|
-
await new Promise((resolve) => setTimeout(resolve, SESSION_STARTED_RETRY_INTERVAL_MS));
|
|
2291
|
-
}
|
|
2292
|
-
}
|
|
2293
|
-
async function listDaemonSessions() {
|
|
2294
|
-
const result = await daemonPost("/list");
|
|
2295
|
-
return result.children || [];
|
|
2296
|
-
}
|
|
2297
|
-
async function stopDaemonSession(sessionId) {
|
|
2298
|
-
const result = await daemonPost("/stop-session", { sessionId });
|
|
2299
|
-
return result.success || false;
|
|
2300
|
-
}
|
|
2301
|
-
async function spawnDaemonSession(directory, sessionId, opts) {
|
|
2302
|
-
const result = await daemonPost("/spawn-session", {
|
|
2303
|
-
directory,
|
|
2304
|
-
sessionId,
|
|
2305
|
-
spawnedBy: opts?.spawnedBy,
|
|
2306
|
-
permissionMode: opts?.permissionMode,
|
|
2307
|
-
agent: opts?.agent,
|
|
2308
|
-
environmentVariables: opts?.environmentVariables,
|
|
2309
|
-
resumeClaudeSessionId: opts?.resumeClaudeSessionId,
|
|
2310
|
-
resumeCodexThreadId: opts?.resumeCodexThreadId,
|
|
2311
|
-
parentSessionId: opts?.parentSessionId
|
|
2312
|
-
});
|
|
2313
|
-
return result;
|
|
2314
|
-
}
|
|
2315
|
-
async function notifyDaemonSessionEvent(sessionId, event, spawnedBy) {
|
|
2316
|
-
return daemonPost("/session-event", { sessionId, event, spawnedBy });
|
|
2317
|
-
}
|
|
2318
|
-
async function notifyDaemonClaudeAuthFailed(sessionId) {
|
|
2319
|
-
return daemonPost("/session-event", { sessionId, event: "auth_failed" });
|
|
2320
|
-
}
|
|
2321
|
-
async function notifyDaemonTurnEvent(sessionId, event) {
|
|
2322
|
-
return daemonPost("/session-event", { sessionId, event });
|
|
2323
|
-
}
|
|
2324
|
-
async function stopDaemonHttp() {
|
|
2325
|
-
await daemonPost("/stop");
|
|
2326
|
-
}
|
|
2327
|
-
async function pushClipboardViaDaemon(text, terminalId) {
|
|
2328
|
-
const result = await daemonPost("/clipboard", { text, ...terminalId ? { terminalId } : {} });
|
|
2329
|
-
if (result?.error && result.delivered === void 0) {
|
|
2330
|
-
return { delivered: false, error: result.error };
|
|
2331
|
-
}
|
|
2332
|
-
return result;
|
|
2333
|
-
}
|
|
2334
|
-
async function pushFilePreviewViaDaemon(terminalId, path, mode = "file") {
|
|
2335
|
-
const result = await daemonPost("/file-preview", { terminalId, path, mode });
|
|
2336
|
-
if (result?.error) return { delivered: false, error: result.error };
|
|
2337
|
-
return { delivered: result?.delivered === true, ...result?.delivered === true ? {} : { error: "preview was not delivered" } };
|
|
2338
|
-
}
|
|
2339
|
-
async function setTerminalTitleViaDaemon(terminalId, title, ifAbsent = false) {
|
|
2340
|
-
const result = await daemonPost("/terminal-title", { terminalId, title, ifAbsent });
|
|
2341
|
-
if (result?.error) {
|
|
2342
|
-
return { ok: false, error: result.error };
|
|
2343
|
-
}
|
|
2344
|
-
return { ok: result?.status === "ok", error: result?.status === "ok" ? void 0 : "unexpected daemon response" };
|
|
2345
|
-
}
|
|
2346
|
-
async function checkIfDaemonRunningAndCleanupStaleState() {
|
|
2347
|
-
const state = await readDaemonState();
|
|
2348
|
-
if (!state) {
|
|
2349
|
-
return false;
|
|
2350
|
-
}
|
|
2351
|
-
try {
|
|
2352
|
-
process.kill(state.pid, 0);
|
|
2353
|
-
} catch {
|
|
2354
|
-
logger.debug("[DAEMON RUN] Daemon PID not running, cleaning up state");
|
|
2355
|
-
await cleanupDaemonState();
|
|
2356
|
-
return false;
|
|
2357
|
-
}
|
|
2358
|
-
if (state.httpPort) {
|
|
2359
|
-
try {
|
|
2360
|
-
const response = await fetch(`http://127.0.0.1:${state.httpPort}/list`, {
|
|
2361
|
-
method: "POST",
|
|
2362
|
-
headers: daemonControlHeaders(state.controlToken),
|
|
2363
|
-
body: "{}",
|
|
2364
|
-
signal: AbortSignal.timeout(2e3)
|
|
2365
|
-
});
|
|
2366
|
-
if (response.ok) {
|
|
2367
|
-
return true;
|
|
2368
|
-
}
|
|
2369
|
-
} catch {
|
|
2370
|
-
logger.debug(`[DAEMON RUN] PID ${state.pid} is alive but HTTP health check failed on port ${state.httpPort}, cleaning up stale state`);
|
|
2371
|
-
await cleanupDaemonState();
|
|
2372
|
-
return false;
|
|
2373
|
-
}
|
|
2374
|
-
}
|
|
2375
|
-
return true;
|
|
2376
|
-
}
|
|
2377
|
-
async function isDaemonRunningCurrentlyInstalledHappyVersion() {
|
|
2378
|
-
logger.debug("[DAEMON CONTROL] Checking if daemon is running same version");
|
|
2379
|
-
const runningDaemon = await checkIfDaemonRunningAndCleanupStaleState();
|
|
2380
|
-
if (!runningDaemon) {
|
|
2381
|
-
logger.debug("[DAEMON CONTROL] No daemon running, returning false");
|
|
2382
|
-
return false;
|
|
2383
|
-
}
|
|
2384
|
-
const state = await readDaemonState();
|
|
2385
|
-
if (!state) {
|
|
2386
|
-
logger.debug("[DAEMON CONTROL] No daemon state found, returning false");
|
|
2387
|
-
return false;
|
|
2388
|
-
}
|
|
2389
|
-
const currentCliVersion = configuration.currentCliVersion;
|
|
2390
|
-
logger.debug(`[DAEMON CONTROL] Current CLI version: ${currentCliVersion}, Daemon started with version: ${state.startedWithCliVersion}`);
|
|
2391
|
-
return currentCliVersion === state.startedWithCliVersion;
|
|
2392
|
-
}
|
|
2393
|
-
async function cleanupDaemonState() {
|
|
2394
|
-
try {
|
|
2395
|
-
await clearDaemonState();
|
|
2396
|
-
logger.debug("[DAEMON RUN] Daemon state file removed");
|
|
2397
|
-
} catch (error) {
|
|
2398
|
-
logger.debug("[DAEMON RUN] Error cleaning up daemon metadata", error);
|
|
2399
|
-
}
|
|
2400
|
-
}
|
|
2401
|
-
async function stopDaemon() {
|
|
2402
|
-
try {
|
|
2403
|
-
const state = await readDaemonState();
|
|
2404
|
-
if (!state) {
|
|
2405
|
-
logger.debug("No daemon state found");
|
|
2406
|
-
return;
|
|
2407
|
-
}
|
|
2408
|
-
logger.debug(`Stopping daemon with PID ${state.pid}`);
|
|
2409
|
-
try {
|
|
2410
|
-
await stopDaemonHttp();
|
|
2411
|
-
await waitForProcessDeath(state.pid, 2e3);
|
|
2412
|
-
logger.debug("Daemon stopped gracefully via HTTP");
|
|
2413
|
-
return;
|
|
2414
|
-
} catch (error) {
|
|
2415
|
-
logger.debug("HTTP stop failed, will force kill", error);
|
|
2416
|
-
}
|
|
2417
|
-
try {
|
|
2418
|
-
process.kill(state.pid, "SIGKILL");
|
|
2419
|
-
logger.debug("Force killed daemon");
|
|
2420
|
-
} catch (error) {
|
|
2421
|
-
logger.debug("Daemon already dead");
|
|
2422
|
-
}
|
|
2423
|
-
} catch (error) {
|
|
2424
|
-
logger.debug("Error stopping daemon", error);
|
|
2425
|
-
}
|
|
2426
|
-
}
|
|
2427
|
-
async function waitForProcessDeath(pid, timeout) {
|
|
2428
|
-
const start = Date.now();
|
|
2429
|
-
while (Date.now() - start < timeout) {
|
|
2430
|
-
try {
|
|
2431
|
-
process.kill(pid, 0);
|
|
2432
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
2433
|
-
} catch {
|
|
2434
|
-
return;
|
|
2435
|
-
}
|
|
2436
|
-
}
|
|
2437
|
-
throw new Error("Process did not die within timeout");
|
|
2438
|
-
}
|
|
2439
|
-
|
|
2440
2189
|
class ApiSessionClient extends EventEmitter {
|
|
2441
2190
|
token;
|
|
2442
2191
|
sessionId;
|
|
@@ -4143,7 +3892,7 @@ function attachStartupCommand(sessionId, socket) {
|
|
|
4143
3892
|
return ` TMUX= tmux${sock} attach-session -t ${shellescape(sessionId)}`;
|
|
4144
3893
|
}
|
|
4145
3894
|
|
|
4146
|
-
const TERMINAL_ID_RE
|
|
3895
|
+
const TERMINAL_ID_RE = /^[a-zA-Z0-9_-]{1,64}$/;
|
|
4147
3896
|
function recordGeometry(record) {
|
|
4148
3897
|
return record.cols !== void 0 && record.rows !== void 0 ? { cols: record.cols, rows: record.rows } : {};
|
|
4149
3898
|
}
|
|
@@ -10898,7 +10647,7 @@ class WebTerminalManager {
|
|
|
10898
10647
|
* the stale-client resurrection hole B-149 closed.
|
|
10899
10648
|
*/
|
|
10900
10649
|
restoreClosedTerminal(terminalId) {
|
|
10901
|
-
if (typeof terminalId !== "string" || !TERMINAL_ID_RE
|
|
10650
|
+
if (typeof terminalId !== "string" || !TERMINAL_ID_RE.test(terminalId)) return { type: "error", reason: "invalid-id" };
|
|
10902
10651
|
if (!isTmuxAvailable()) return { type: "error", reason: "no-tmux" };
|
|
10903
10652
|
const record = this.closedTerminals.find((r) => r.id === terminalId);
|
|
10904
10653
|
if (!record) return { type: "error", reason: "no-record" };
|
|
@@ -12103,15 +11852,6 @@ function sendToVhTerminal(terminalId, text, submit) {
|
|
|
12103
11852
|
return { ok: true };
|
|
12104
11853
|
}
|
|
12105
11854
|
|
|
12106
|
-
const SESSION_ID_RE = /^[a-zA-Z0-9_-]{1,128}$/;
|
|
12107
|
-
const TERMINAL_ID_RE = /^[a-zA-Z0-9_-]{1,64}$/;
|
|
12108
|
-
function isValidSessionId(id) {
|
|
12109
|
-
return typeof id === "string" && SESSION_ID_RE.test(id);
|
|
12110
|
-
}
|
|
12111
|
-
function isValidTerminalId(id) {
|
|
12112
|
-
return typeof id === "string" && TERMINAL_ID_RE.test(id);
|
|
12113
|
-
}
|
|
12114
|
-
|
|
12115
11855
|
function parseTerminalHookPayload(body) {
|
|
12116
11856
|
if (!body || typeof body !== "object") return null;
|
|
12117
11857
|
const raw = body;
|
|
@@ -16632,4 +16372,4 @@ const RawJSONLinesSchema = z.discriminatedUnion("type", [
|
|
|
16632
16372
|
}).passthrough()
|
|
16633
16373
|
]);
|
|
16634
16374
|
|
|
16635
|
-
export {
|
|
16375
|
+
export { startOfflineReconnection as $, ApiClient as A, scrubTmuxClientEnv as B, CodexAppServerClient as C, decideMirrorBinding as D, MIRROR_BACKFILL_LINES_DEFAULT as E, ForkSourceMissingError as F, mirrorLineKey as G, mirrorLocalId as H, InvalidateSync as I, detectCLIAvailability as J, detectResumeSupport as K, refreshAgentHomes as L, MAX_CHAT_ATTACHMENT_SOURCE_BYTES as M, summarizeSpawnSessionForLog as N, locateClaudeConversation as O, agentHomeSpawnEnv as P, shellescape as Q, RawJSONLinesSchema as R, fetchCliUpdateState as S, TurnActivityTracker as T, resolveCliUpdateCheckInterval as U, DEFAULT_CLI_UPDATE_CHECK_INTERVAL_MS as V, listVhTerminals as W, readVhTerminal as X, sendToVhTerminal as Y, TITLE_PROMPT_PREFIX as Z, BOARD_ANALYZER_PROMPT_PREFIX as _, ApiSessionClient as a, index as a0, api as a1, AGENT_HOME_ENV_NAMES as b, forkCodexThread as c, describeAgentHome as d, expandHomePath as e, forkSession as f, getProjectPath as g, connectionState as h, errorLogMetadata as i, contentLogMetadata as j, initializeSandbox as k, AsyncLock as l, commandOnPath as m, deriveLocalCliUpdateSummary as n, isClaudeSessionId as o, probeLoginShellEnv as p, getLocalHappyAgentCredentialPath as q, resolveAgentHomes as r, readLocalHappyAgentCredentials as s, parseExactVersion as t, compareExactVersions as u, extractCompleteLines as v, wrapCommand as w, decideBackfill as x, parseTerminalHookPayload as y, tmuxArgs as z };
|