very-happy-cli 0.2.154 → 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-Ckyadhf4.mjs → AcpBackend-DVB0nzgR.mjs} +2 -2
- package/dist/{AcpBackend-B14xNj5L.cjs → AcpBackend-DmFcRh54.cjs} +3 -3
- package/dist/{AcpSessionManager-CCHmPdrR.cjs → AcpSessionManager-CWaSYTnT.cjs} +1 -1
- package/dist/{AcpSessionManager-H8t4P-IW.mjs → AcpSessionManager-dGDgNb-p.mjs} +1 -1
- package/dist/agentGuidance-BWxFC6UL.mjs +1613 -0
- package/dist/agentGuidance-un7YPryB.cjs +1665 -0
- package/dist/{agentHome-B20RWdgE.mjs → agentHome-ByLb2HFg.mjs} +5 -5
- package/dist/{agentHome-BUsLTZnz.cjs → agentHome-aucT8BHw.cjs} +5 -5
- package/dist/{auto-BQnncDcs.mjs → auto-BQnD6gVx.mjs} +21 -21
- package/dist/{auto-IeldARBS.cjs → auto-P9RoJaY0.cjs} +24 -24
- package/dist/codex/happyMcpStdioBridge.cjs +6 -3
- package/dist/codex/happyMcpStdioBridge.mjs +6 -3
- package/dist/{config-B-ocQh5V.mjs → config-BPZ2Y6o8.mjs} +8 -8
- package/dist/{config-DM_xI9M6.cjs → config-BoePh9PX.cjs} +8 -8
- package/dist/{index-okLyUzeD.cjs → index--KCpVs1c.cjs} +7 -7
- package/dist/{index-BELV05ko.mjs → index-B4oXnbYw.mjs} +463 -889
- package/dist/{index-ZKuBjvHi.mjs → index-BjzdXb9x.mjs} +21 -13
- package/dist/{index-BUxBxSxJ.cjs → index-DRrLaljt.cjs} +21 -13
- package/dist/{index-CIx3248o.mjs → index-DVVRqaVG.mjs} +7 -7
- package/dist/{index-eCjkm8Y2.cjs → index-D_fYUxVg.cjs} +521 -960
- package/dist/index.cjs +6 -6
- package/dist/index.mjs +6 -6
- package/dist/{install-BZOdxfPd.cjs → install-CGigiocs.cjs} +1 -1
- package/dist/{install-CoLN3whR.mjs → install-DP5aPNEX.mjs} +1 -1
- package/dist/{installTerminalHooks-CA4OcAS7.cjs → installTerminalHooks-XrcPvfBs.cjs} +5 -5
- package/dist/{installTerminalHooks-Dde_8t36.mjs → installTerminalHooks-tIg7mANc.mjs} +5 -5
- package/dist/lib.cjs +2 -2
- package/dist/lib.mjs +2 -2
- package/dist/{limits-Dt7_unH4.mjs → limits-C_DW0M0q.mjs} +309 -13
- package/dist/{limits-CmzISka2.cjs → limits-DkfHJ3nS.cjs} +329 -12
- package/dist/{mcp-7iDHlyCI.cjs → mcp-BqlXl10F.cjs} +23 -23
- package/dist/{mcp-9Ui4nQZL.mjs → mcp-o7QglAQM.mjs} +17 -17
- package/dist/{piRuntime-BesGGPME.cjs → piRuntime-BxP4B_zY.cjs} +2 -2
- package/dist/{piRuntime-C4E4pgye.mjs → piRuntime-MjiJI-nV.mjs} +2 -2
- package/dist/{piTerminal-fUogwxYr.cjs → piTerminal-DYzRcwgb.cjs} +6 -6
- package/dist/{piTerminal-CCEGCQOY.mjs → piTerminal-Dpq6yqKU.mjs} +6 -6
- package/dist/{runGemini-CNPGSsSK.cjs → runGemini-8Pxh94Fm.cjs} +7 -7
- package/dist/{runGemini-BW-pEklU.mjs → runGemini-CDlcQ-OA.mjs} +6 -6
- package/dist/{runOpenClaw-Bsodkg_s.cjs → runOpenClaw-B5FSZIbK.cjs} +6 -6
- package/dist/{runOpenClaw-NRB6-_jU.mjs → runOpenClaw-YkhsgPs0.mjs} +5 -5
- package/dist/{send-Bd00QcHC.cjs → send-CwrYXTPr.cjs} +8 -42
- package/dist/{send-DYeSFg8s.mjs → send-DJStmLBv.mjs} +5 -39
- package/dist/{sessions-DlPOYKLU.mjs → sessions-JaVXlSqj.mjs} +88 -45
- package/dist/{sessions-RIFUoy_g.cjs → sessions-MX21NJXd.cjs} +99 -56
- package/dist/{spawn-D1bhyHbH.mjs → spawn-BaPnjClT.mjs} +22 -22
- package/dist/{spawn-DxrfHTF4.cjs → spawn-cIoglKVf.cjs} +30 -30
- package/dist/{teams-pfKHpkgL.mjs → teams-DXV5Pwwt.mjs} +8 -8
- package/dist/{teams-Cfy0VMCo.cjs → teams-Dqk7F3D-.cjs} +8 -8
- package/dist/{todo-B2CjDg_V.mjs → todo-2Z1REhfx.mjs} +8 -6
- package/dist/{todo-B4cBFzHB.cjs → todo-Buuqn9gm.cjs} +8 -6
- package/dist/{types-D5RWyBE5.mjs → types-CkbfdRzq.mjs} +4 -282
- package/dist/{types-Bd_TGr0F.cjs → types-a2xsH2UI.cjs} +16 -311
- package/package.json +7 -7
- package/dist/agentGuidance-DUBXppv-.cjs +0 -554
- package/dist/agentGuidance-TLYQxsm2.mjs +0 -530
|
@@ -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';
|
|
@@ -332,41 +332,6 @@ const AgentMessageSchema = z.object({
|
|
|
332
332
|
});
|
|
333
333
|
z.union([UserMessageSchema, AgentMessageSchema]);
|
|
334
334
|
|
|
335
|
-
async function delay(ms) {
|
|
336
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
337
|
-
}
|
|
338
|
-
function exponentialBackoffDelay(currentFailureCount, minDelay, maxDelay, maxFailureCount) {
|
|
339
|
-
let maxDelayRet = minDelay + (maxDelay - minDelay) / maxFailureCount * Math.min(currentFailureCount, maxFailureCount);
|
|
340
|
-
return Math.round(Math.random() * maxDelayRet);
|
|
341
|
-
}
|
|
342
|
-
function createBackoff(opts) {
|
|
343
|
-
return async (callback) => {
|
|
344
|
-
let currentFailureCount = 0;
|
|
345
|
-
const minDelay = opts && opts.minDelay !== void 0 ? opts.minDelay : 250;
|
|
346
|
-
const maxDelay = opts && opts.maxDelay !== void 0 ? opts.maxDelay : 1e3;
|
|
347
|
-
const maxFailureCount = opts && opts.maxFailureCount !== void 0 ? opts.maxFailureCount : 50;
|
|
348
|
-
while (true) {
|
|
349
|
-
try {
|
|
350
|
-
return await callback();
|
|
351
|
-
} catch (e) {
|
|
352
|
-
if (currentFailureCount < maxFailureCount) {
|
|
353
|
-
currentFailureCount++;
|
|
354
|
-
}
|
|
355
|
-
if (opts && opts.onError) {
|
|
356
|
-
opts.onError(e, currentFailureCount);
|
|
357
|
-
}
|
|
358
|
-
let waitForRequest = exponentialBackoffDelay(currentFailureCount, minDelay, maxDelay, maxFailureCount);
|
|
359
|
-
await delay(waitForRequest);
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
};
|
|
363
|
-
}
|
|
364
|
-
let backoff = createBackoff({
|
|
365
|
-
onError: (e, failuresCount) => {
|
|
366
|
-
logger.debug(`[BACKOFF] retry ${failuresCount}:`, e?.message || e);
|
|
367
|
-
}
|
|
368
|
-
});
|
|
369
|
-
|
|
370
335
|
function isRateQuotaCode(code) {
|
|
371
336
|
return typeof code === "string" && code.endsWith("_rate_quota_exceeded");
|
|
372
337
|
}
|
|
@@ -2221,240 +2186,6 @@ class TurnReporter {
|
|
|
2221
2186
|
}
|
|
2222
2187
|
}
|
|
2223
2188
|
|
|
2224
|
-
function daemonControlHeaders(controlToken) {
|
|
2225
|
-
return {
|
|
2226
|
-
"Content-Type": "application/json",
|
|
2227
|
-
...controlToken ? { Authorization: `Bearer ${controlToken}` } : {}
|
|
2228
|
-
};
|
|
2229
|
-
}
|
|
2230
|
-
async function daemonPost(path, body) {
|
|
2231
|
-
const state = await readDaemonState();
|
|
2232
|
-
if (!state?.httpPort) {
|
|
2233
|
-
const errorMessage = "No daemon running, no state file found";
|
|
2234
|
-
logger.debug(`[CONTROL CLIENT] ${errorMessage}`);
|
|
2235
|
-
return {
|
|
2236
|
-
error: errorMessage
|
|
2237
|
-
};
|
|
2238
|
-
}
|
|
2239
|
-
try {
|
|
2240
|
-
process.kill(state.pid, 0);
|
|
2241
|
-
} catch (error) {
|
|
2242
|
-
const errorMessage = "Daemon is not running, file is stale";
|
|
2243
|
-
logger.debug(`[CONTROL CLIENT] ${errorMessage}`);
|
|
2244
|
-
return {
|
|
2245
|
-
error: errorMessage
|
|
2246
|
-
};
|
|
2247
|
-
}
|
|
2248
|
-
try {
|
|
2249
|
-
const timeout = process.env.HAPPY_DAEMON_HTTP_TIMEOUT ? parseInt(process.env.HAPPY_DAEMON_HTTP_TIMEOUT) : 1e4;
|
|
2250
|
-
const response = await fetch(`http://127.0.0.1:${state.httpPort}${path}`, {
|
|
2251
|
-
method: "POST",
|
|
2252
|
-
// A state written by an old daemon has no token and must remain callable;
|
|
2253
|
-
// a new daemon always writes one and rejects requests without it.
|
|
2254
|
-
headers: daemonControlHeaders(state.controlToken),
|
|
2255
|
-
body: JSON.stringify(body || {}),
|
|
2256
|
-
// Mostly increased for stress test
|
|
2257
|
-
signal: AbortSignal.timeout(timeout)
|
|
2258
|
-
});
|
|
2259
|
-
if (!response.ok) {
|
|
2260
|
-
const failure = await response.json().catch(() => null);
|
|
2261
|
-
const reason = typeof failure?.error === "string" && failure.error ? failure.error : `HTTP ${response.status}`;
|
|
2262
|
-
const errorMessage = `Request failed: ${path}, ${reason}`;
|
|
2263
|
-
logger.debug(`[CONTROL CLIENT] ${errorMessage}`);
|
|
2264
|
-
return {
|
|
2265
|
-
error: errorMessage
|
|
2266
|
-
};
|
|
2267
|
-
}
|
|
2268
|
-
return await response.json();
|
|
2269
|
-
} catch (error) {
|
|
2270
|
-
const errorMessage = `Request failed: ${path}, ${error instanceof Error ? error.message : "Unknown error"}`;
|
|
2271
|
-
logger.debug(`[CONTROL CLIENT] ${errorMessage}`);
|
|
2272
|
-
return {
|
|
2273
|
-
error: errorMessage
|
|
2274
|
-
};
|
|
2275
|
-
}
|
|
2276
|
-
}
|
|
2277
|
-
const SESSION_STARTED_RETRY_TIMEOUT_MS = 3e3;
|
|
2278
|
-
const SESSION_STARTED_RETRY_INTERVAL_MS = 100;
|
|
2279
|
-
async function notifyDaemonSessionStarted(sessionId, metadata, encryption) {
|
|
2280
|
-
const payload = { sessionId, metadata, encryption };
|
|
2281
|
-
const deadline = Date.now() + SESSION_STARTED_RETRY_TIMEOUT_MS;
|
|
2282
|
-
let result;
|
|
2283
|
-
while (true) {
|
|
2284
|
-
result = await daemonPost("/session-started", payload);
|
|
2285
|
-
if (!result?.error) {
|
|
2286
|
-
return result;
|
|
2287
|
-
}
|
|
2288
|
-
if (Date.now() >= deadline) {
|
|
2289
|
-
return result;
|
|
2290
|
-
}
|
|
2291
|
-
await new Promise((resolve) => setTimeout(resolve, SESSION_STARTED_RETRY_INTERVAL_MS));
|
|
2292
|
-
}
|
|
2293
|
-
}
|
|
2294
|
-
async function listDaemonSessions() {
|
|
2295
|
-
const result = await daemonPost("/list");
|
|
2296
|
-
return result.children || [];
|
|
2297
|
-
}
|
|
2298
|
-
async function stopDaemonSession(sessionId) {
|
|
2299
|
-
const result = await daemonPost("/stop-session", { sessionId });
|
|
2300
|
-
return result.success || false;
|
|
2301
|
-
}
|
|
2302
|
-
async function spawnDaemonSession(directory, sessionId, opts) {
|
|
2303
|
-
const result = await daemonPost("/spawn-session", {
|
|
2304
|
-
directory,
|
|
2305
|
-
sessionId,
|
|
2306
|
-
spawnedBy: opts?.spawnedBy,
|
|
2307
|
-
permissionMode: opts?.permissionMode,
|
|
2308
|
-
agent: opts?.agent,
|
|
2309
|
-
environmentVariables: opts?.environmentVariables,
|
|
2310
|
-
resumeClaudeSessionId: opts?.resumeClaudeSessionId,
|
|
2311
|
-
resumeCodexThreadId: opts?.resumeCodexThreadId,
|
|
2312
|
-
parentSessionId: opts?.parentSessionId
|
|
2313
|
-
});
|
|
2314
|
-
return result;
|
|
2315
|
-
}
|
|
2316
|
-
const ROUTE_NOT_FOUND_RE = /, (Not Found|HTTP 404)$/;
|
|
2317
|
-
async function resumeDaemonSession(sessionId, opts) {
|
|
2318
|
-
const result = await daemonPost("/resume-session", {
|
|
2319
|
-
sessionId,
|
|
2320
|
-
...opts?.model !== void 0 ? { model: opts.model } : {},
|
|
2321
|
-
...opts?.permissionMode !== void 0 ? { permissionMode: opts.permissionMode } : {}
|
|
2322
|
-
});
|
|
2323
|
-
if (result?.error) {
|
|
2324
|
-
const raw = String(result.error);
|
|
2325
|
-
const error = ROUTE_NOT_FOUND_RE.test(raw) ? "daemon too old to resume sessions (no /resume-session route); upgrade very-happy-cli and run `very-happy daemon start`" : raw.replace(/^Request failed: \/resume-session, /, "");
|
|
2326
|
-
return { success: false, error };
|
|
2327
|
-
}
|
|
2328
|
-
if (result?.success === true && typeof result.sessionId === "string") {
|
|
2329
|
-
return { success: true, sessionId: result.sessionId };
|
|
2330
|
-
}
|
|
2331
|
-
return { success: false, error: typeof result?.error === "string" ? result.error : "unexpected daemon response" };
|
|
2332
|
-
}
|
|
2333
|
-
async function notifyDaemonSessionEvent(sessionId, event, spawnedBy) {
|
|
2334
|
-
return daemonPost("/session-event", { sessionId, event, spawnedBy });
|
|
2335
|
-
}
|
|
2336
|
-
async function notifyDaemonClaudeAuthFailed(sessionId) {
|
|
2337
|
-
return daemonPost("/session-event", { sessionId, event: "auth_failed" });
|
|
2338
|
-
}
|
|
2339
|
-
async function notifyDaemonTurnEvent(sessionId, event) {
|
|
2340
|
-
return daemonPost("/session-event", { sessionId, event });
|
|
2341
|
-
}
|
|
2342
|
-
async function stopDaemonHttp() {
|
|
2343
|
-
await daemonPost("/stop");
|
|
2344
|
-
}
|
|
2345
|
-
async function pushClipboardViaDaemon(text, terminalId) {
|
|
2346
|
-
const result = await daemonPost("/clipboard", { text, ...terminalId ? { terminalId } : {} });
|
|
2347
|
-
if (result?.error && result.delivered === void 0) {
|
|
2348
|
-
return { delivered: false, error: result.error };
|
|
2349
|
-
}
|
|
2350
|
-
return result;
|
|
2351
|
-
}
|
|
2352
|
-
async function pushFilePreviewViaDaemon(terminalId, path, mode = "file") {
|
|
2353
|
-
const result = await daemonPost("/file-preview", { terminalId, path, mode });
|
|
2354
|
-
if (result?.error) return { delivered: false, error: result.error };
|
|
2355
|
-
return { delivered: result?.delivered === true, ...result?.delivered === true ? {} : { error: "preview was not delivered" } };
|
|
2356
|
-
}
|
|
2357
|
-
async function setTerminalTitleViaDaemon(terminalId, title, ifAbsent = false) {
|
|
2358
|
-
const result = await daemonPost("/terminal-title", { terminalId, title, ifAbsent });
|
|
2359
|
-
if (result?.error) {
|
|
2360
|
-
return { ok: false, error: result.error };
|
|
2361
|
-
}
|
|
2362
|
-
return { ok: result?.status === "ok", error: result?.status === "ok" ? void 0 : "unexpected daemon response" };
|
|
2363
|
-
}
|
|
2364
|
-
async function checkIfDaemonRunningAndCleanupStaleState() {
|
|
2365
|
-
const state = await readDaemonState();
|
|
2366
|
-
if (!state) {
|
|
2367
|
-
return false;
|
|
2368
|
-
}
|
|
2369
|
-
try {
|
|
2370
|
-
process.kill(state.pid, 0);
|
|
2371
|
-
} catch {
|
|
2372
|
-
logger.debug("[DAEMON RUN] Daemon PID not running, cleaning up state");
|
|
2373
|
-
await cleanupDaemonState();
|
|
2374
|
-
return false;
|
|
2375
|
-
}
|
|
2376
|
-
if (state.httpPort) {
|
|
2377
|
-
try {
|
|
2378
|
-
const response = await fetch(`http://127.0.0.1:${state.httpPort}/list`, {
|
|
2379
|
-
method: "POST",
|
|
2380
|
-
headers: daemonControlHeaders(state.controlToken),
|
|
2381
|
-
body: "{}",
|
|
2382
|
-
signal: AbortSignal.timeout(2e3)
|
|
2383
|
-
});
|
|
2384
|
-
if (response.ok) {
|
|
2385
|
-
return true;
|
|
2386
|
-
}
|
|
2387
|
-
} catch {
|
|
2388
|
-
logger.debug(`[DAEMON RUN] PID ${state.pid} is alive but HTTP health check failed on port ${state.httpPort}, cleaning up stale state`);
|
|
2389
|
-
await cleanupDaemonState();
|
|
2390
|
-
return false;
|
|
2391
|
-
}
|
|
2392
|
-
}
|
|
2393
|
-
return true;
|
|
2394
|
-
}
|
|
2395
|
-
async function isDaemonRunningCurrentlyInstalledHappyVersion() {
|
|
2396
|
-
logger.debug("[DAEMON CONTROL] Checking if daemon is running same version");
|
|
2397
|
-
const runningDaemon = await checkIfDaemonRunningAndCleanupStaleState();
|
|
2398
|
-
if (!runningDaemon) {
|
|
2399
|
-
logger.debug("[DAEMON CONTROL] No daemon running, returning false");
|
|
2400
|
-
return false;
|
|
2401
|
-
}
|
|
2402
|
-
const state = await readDaemonState();
|
|
2403
|
-
if (!state) {
|
|
2404
|
-
logger.debug("[DAEMON CONTROL] No daemon state found, returning false");
|
|
2405
|
-
return false;
|
|
2406
|
-
}
|
|
2407
|
-
const currentCliVersion = configuration.currentCliVersion;
|
|
2408
|
-
logger.debug(`[DAEMON CONTROL] Current CLI version: ${currentCliVersion}, Daemon started with version: ${state.startedWithCliVersion}`);
|
|
2409
|
-
return currentCliVersion === state.startedWithCliVersion;
|
|
2410
|
-
}
|
|
2411
|
-
async function cleanupDaemonState() {
|
|
2412
|
-
try {
|
|
2413
|
-
await clearDaemonState();
|
|
2414
|
-
logger.debug("[DAEMON RUN] Daemon state file removed");
|
|
2415
|
-
} catch (error) {
|
|
2416
|
-
logger.debug("[DAEMON RUN] Error cleaning up daemon metadata", error);
|
|
2417
|
-
}
|
|
2418
|
-
}
|
|
2419
|
-
async function stopDaemon() {
|
|
2420
|
-
try {
|
|
2421
|
-
const state = await readDaemonState();
|
|
2422
|
-
if (!state) {
|
|
2423
|
-
logger.debug("No daemon state found");
|
|
2424
|
-
return;
|
|
2425
|
-
}
|
|
2426
|
-
logger.debug(`Stopping daemon with PID ${state.pid}`);
|
|
2427
|
-
try {
|
|
2428
|
-
await stopDaemonHttp();
|
|
2429
|
-
await waitForProcessDeath(state.pid, 2e3);
|
|
2430
|
-
logger.debug("Daemon stopped gracefully via HTTP");
|
|
2431
|
-
return;
|
|
2432
|
-
} catch (error) {
|
|
2433
|
-
logger.debug("HTTP stop failed, will force kill", error);
|
|
2434
|
-
}
|
|
2435
|
-
try {
|
|
2436
|
-
process.kill(state.pid, "SIGKILL");
|
|
2437
|
-
logger.debug("Force killed daemon");
|
|
2438
|
-
} catch (error) {
|
|
2439
|
-
logger.debug("Daemon already dead");
|
|
2440
|
-
}
|
|
2441
|
-
} catch (error) {
|
|
2442
|
-
logger.debug("Error stopping daemon", error);
|
|
2443
|
-
}
|
|
2444
|
-
}
|
|
2445
|
-
async function waitForProcessDeath(pid, timeout) {
|
|
2446
|
-
const start = Date.now();
|
|
2447
|
-
while (Date.now() - start < timeout) {
|
|
2448
|
-
try {
|
|
2449
|
-
process.kill(pid, 0);
|
|
2450
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
2451
|
-
} catch {
|
|
2452
|
-
return;
|
|
2453
|
-
}
|
|
2454
|
-
}
|
|
2455
|
-
throw new Error("Process did not die within timeout");
|
|
2456
|
-
}
|
|
2457
|
-
|
|
2458
2189
|
class ApiSessionClient extends EventEmitter {
|
|
2459
2190
|
token;
|
|
2460
2191
|
sessionId;
|
|
@@ -4161,7 +3892,7 @@ function attachStartupCommand(sessionId, socket) {
|
|
|
4161
3892
|
return ` TMUX= tmux${sock} attach-session -t ${shellescape(sessionId)}`;
|
|
4162
3893
|
}
|
|
4163
3894
|
|
|
4164
|
-
const TERMINAL_ID_RE
|
|
3895
|
+
const TERMINAL_ID_RE = /^[a-zA-Z0-9_-]{1,64}$/;
|
|
4165
3896
|
function recordGeometry(record) {
|
|
4166
3897
|
return record.cols !== void 0 && record.rows !== void 0 ? { cols: record.cols, rows: record.rows } : {};
|
|
4167
3898
|
}
|
|
@@ -10916,7 +10647,7 @@ class WebTerminalManager {
|
|
|
10916
10647
|
* the stale-client resurrection hole B-149 closed.
|
|
10917
10648
|
*/
|
|
10918
10649
|
restoreClosedTerminal(terminalId) {
|
|
10919
|
-
if (typeof terminalId !== "string" || !TERMINAL_ID_RE
|
|
10650
|
+
if (typeof terminalId !== "string" || !TERMINAL_ID_RE.test(terminalId)) return { type: "error", reason: "invalid-id" };
|
|
10920
10651
|
if (!isTmuxAvailable()) return { type: "error", reason: "no-tmux" };
|
|
10921
10652
|
const record = this.closedTerminals.find((r) => r.id === terminalId);
|
|
10922
10653
|
if (!record) return { type: "error", reason: "no-record" };
|
|
@@ -12121,15 +11852,6 @@ function sendToVhTerminal(terminalId, text, submit) {
|
|
|
12121
11852
|
return { ok: true };
|
|
12122
11853
|
}
|
|
12123
11854
|
|
|
12124
|
-
const SESSION_ID_RE = /^[a-zA-Z0-9_-]{1,128}$/;
|
|
12125
|
-
const TERMINAL_ID_RE = /^[a-zA-Z0-9_-]{1,64}$/;
|
|
12126
|
-
function isValidSessionId(id) {
|
|
12127
|
-
return typeof id === "string" && SESSION_ID_RE.test(id);
|
|
12128
|
-
}
|
|
12129
|
-
function isValidTerminalId(id) {
|
|
12130
|
-
return typeof id === "string" && TERMINAL_ID_RE.test(id);
|
|
12131
|
-
}
|
|
12132
|
-
|
|
12133
11855
|
function parseTerminalHookPayload(body) {
|
|
12134
11856
|
if (!body || typeof body !== "object") return null;
|
|
12135
11857
|
const raw = body;
|
|
@@ -16650,4 +16372,4 @@ const RawJSONLinesSchema = z.discriminatedUnion("type", [
|
|
|
16650
16372
|
}).passthrough()
|
|
16651
16373
|
]);
|
|
16652
16374
|
|
|
16653
|
-
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 };
|