very-happy-cli 0.2.133 → 0.2.134
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-BQm7dNza.mjs → AcpBackend-B8KEjDwF.mjs} +3 -3
- package/dist/{AcpBackend-DgG8o4jd.cjs → AcpBackend-CeNp7tgD.cjs} +3 -3
- package/dist/{AcpSessionManager-DDFEmhQp.cjs → AcpSessionManager-Bu1d05bx.cjs} +1 -1
- package/dist/{AcpSessionManager-C7unPEZO.mjs → AcpSessionManager-KlDZbEmZ.mjs} +1 -1
- package/dist/{agentGuidance-BaplwDcV.mjs → agentGuidance-CPG5Cr5T.mjs} +1 -1
- package/dist/{agentGuidance-BItqIZTf.cjs → agentGuidance-Cg8Lha39.cjs} +1 -1
- package/dist/codex/happyMcpStdioBridge.cjs +2 -2
- package/dist/codex/happyMcpStdioBridge.mjs +2 -2
- package/dist/{config-uLywzv5t.cjs → config-C3e90AIH.cjs} +4 -4
- package/dist/{config-BZ8xEnOv.mjs → config-C4gWfnJX.mjs} +4 -4
- package/dist/{index-6Xm0CgN_.cjs → index-B1plzL9M.cjs} +37 -25
- package/dist/{index-ClCeQ1FW.mjs → index-B6UvB88K.mjs} +16 -10
- package/dist/{index-EsR8ayIg.mjs → index-BqUOj1zK.mjs} +33 -21
- package/dist/{index-D8i2EViA.mjs → index-CEDPokKf.mjs} +4 -4
- package/dist/{index-CdH3ecC5.cjs → index-CX-zp3FH.cjs} +4 -4
- package/dist/{index-Daga0ztv.cjs → index-jqG8CV0c.cjs} +15 -9
- package/dist/index.cjs +4 -4
- package/dist/index.mjs +4 -4
- package/dist/{installTerminalHooks-NH4kiB2E.mjs → installTerminalHooks-BT4Dq28Y.mjs} +4 -4
- package/dist/{installTerminalHooks-CKG0MYVK.cjs → installTerminalHooks-DPmEaHg2.cjs} +4 -4
- package/dist/lib.cjs +2 -2
- package/dist/lib.d.cts +6 -60
- package/dist/lib.d.mts +6 -60
- package/dist/lib.mjs +2 -2
- package/dist/{limits-Du7S6jqA.mjs → limits-BGeIBBE3.mjs} +7 -7
- package/dist/{limits-XRNzIlVm.cjs → limits-D6kiAfXJ.cjs} +7 -7
- package/dist/{mcp-D8zhjyZa.mjs → mcp-BGu_dUaJ.mjs} +4 -4
- package/dist/{mcp-CAMCuudA.cjs → mcp-DGZmUpuZ.cjs} +4 -4
- package/dist/{runGemini-BIVHp0ST.cjs → runGemini-BPPnulIk.cjs} +6 -6
- package/dist/{runGemini-Db4rX54F.mjs → runGemini-DGTNwiLo.mjs} +6 -6
- package/dist/{runOpenClaw-a0f2pZZp.cjs → runOpenClaw-BB3Ivt1S.cjs} +5 -5
- package/dist/{runOpenClaw-D2MceXPO.mjs → runOpenClaw-CxgTFOSM.mjs} +5 -5
- package/dist/{send-DKbumEcg.cjs → send-Bo6iKuXr.cjs} +4 -4
- package/dist/{send-1Wjb0lIh.mjs → send-DHShoBeq.mjs} +4 -4
- package/dist/{sessions-DXCCRDb5.mjs → sessions-CJuwvEr0.mjs} +4 -4
- package/dist/{sessions-SIFOOlGp.cjs → sessions-DyC5Attg.cjs} +4 -4
- package/dist/{spawn-Bj3W6HR4.mjs → spawn-QtKlr8Ig.mjs} +4 -4
- package/dist/{spawn-C-XpSPLX.cjs → spawn-gha6nGx-.cjs} +4 -4
- package/dist/{teams-CqhFQLVC.mjs → teams-BF-GxUZc.mjs} +4 -4
- package/dist/{teams-ChFzXAqr.cjs → teams-BbzWNV9e.cjs} +4 -4
- package/dist/{todo-o0clp-_I.cjs → todo-BaNaNZ8c.cjs} +3 -3
- package/dist/{todo-B0gbQHH8.mjs → todo-CkJ5UjWs.mjs} +3 -3
- package/dist/{types-6DrEgHVx.mjs → types-Cq-tvv9t.mjs} +84 -27
- package/dist/{types-CcjVmS2i.cjs → types-Dabm17Ln.cjs} +85 -28
- package/package.json +7 -7
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import{createRequire as _pkgrollCR}from"node:module";const require=_pkgrollCR(import.meta.url);import chalk from 'chalk';
|
|
2
2
|
import os, { homedir, userInfo, tmpdir } from 'node:os';
|
|
3
3
|
import { randomUUID, randomBytes, createHash as createHash$1, timingSafeEqual } from 'node:crypto';
|
|
4
|
-
import { j as getProjectPath, g as BUILTIN_TODO_DISCOVERY, p as projectPath, k as initializeSandbox, w as wrapCommand, d as contentLogMetadata, I as InvalidateSync, R as RawJSONLinesSchema, h as delay, l as AsyncLock, S as STREAM_DELTA_MAX_CHARS, M as MAX_CHAT_ATTACHMENT_SOURCE_BYTES, m as commandOnPath, n as deriveLocalCliUpdateSummary, o as isClaudeSessionId, q as getLocalHappyAgentCredentialPath, r as readLocalHappyAgentCredentials, t as parseExactVersion, u as compareExactVersions, v as extractCompleteLines, x as decideBackfill, y as parseTerminalHookPayload, z as tmuxArgs, C as scrubTmuxClientEnv, D as decideMirrorBinding, E as MIRROR_BACKFILL_LINES_DEFAULT, F as mirrorLineKey, G as mirrorLocalId, H as detectCLIAvailability, J as detectResumeSupport, K as summarizeSpawnSessionForLog, L as shellescape, A as ApiClient, N as fetchCliUpdateState, O as resolveCliUpdateCheckInterval, P as DEFAULT_CLI_UPDATE_CHECK_INTERVAL_MS, i as isValidSessionId, Q as listVhTerminals, T as isValidTerminalId, U as readVhTerminal, V as sendToVhTerminal, W as ContextUsageSchema, X as TITLE_PROMPT_PREFIX, Y as BOARD_ANALYZER_PROMPT_PREFIX, f as connectionState, Z as startOfflineReconnection, c as createEnvelope, _ as CodexAppServerClient } from './types-
|
|
5
|
-
import { z as readDaemonState, l as logger, c as configuration, A as clearDaemonState, B as ensurePrivateDirectory, D as hardenPrivateFile, p as packageJson, g as readSettings, E as readCredentials, s as credentialRelayProblem, i as encodeBase64, F as readSettingsOutcome, G as updateSettings, H as encodeBase64Url, m as decodeBase64, I as writeCredentialsLegacy, J as writeCredentialsDataKey, d as readCredentialsForConfiguredRelay, j as encrypt, r as readPersistedSessions, w as writePrivateFileSync, K as decryptWithDataKey, L as decryptLegacy, M as persistSession, k as decrypt, f as ensurePrivateDirectorySync, N as acquireDaemonLock, O as deletePersistedSessions, P as writeDaemonState, Q as writeSettings, R as releaseDaemonLock, C as CLIPBOARD_TOOL_NAME, a as CLIPBOARD_TOOL_TITLE, b as CLIPBOARD_TOOL_DESCRIPTION, e as CLIPBOARD_MAX_BYTES, S as clearCredentials, T as clearMachineId, U as SandboxConfigSchema, V as getLatestDaemonLog } from './limits-
|
|
4
|
+
import { j as getProjectPath, g as BUILTIN_TODO_DISCOVERY, p as projectPath, k as initializeSandbox, w as wrapCommand, d as contentLogMetadata, I as InvalidateSync, R as RawJSONLinesSchema, h as delay, l as AsyncLock, S as STREAM_DELTA_MAX_CHARS, M as MAX_CHAT_ATTACHMENT_SOURCE_BYTES, m as commandOnPath, n as deriveLocalCliUpdateSummary, o as isClaudeSessionId, q as getLocalHappyAgentCredentialPath, r as readLocalHappyAgentCredentials, t as parseExactVersion, u as compareExactVersions, v as extractCompleteLines, x as decideBackfill, y as parseTerminalHookPayload, z as tmuxArgs, C as scrubTmuxClientEnv, D as decideMirrorBinding, E as MIRROR_BACKFILL_LINES_DEFAULT, F as mirrorLineKey, G as mirrorLocalId, H as detectCLIAvailability, J as detectResumeSupport, K as summarizeSpawnSessionForLog, L as shellescape, A as ApiClient, N as fetchCliUpdateState, O as resolveCliUpdateCheckInterval, P as DEFAULT_CLI_UPDATE_CHECK_INTERVAL_MS, i as isValidSessionId, Q as listVhTerminals, T as isValidTerminalId, U as readVhTerminal, V as sendToVhTerminal, W as ContextUsageSchema, X as TITLE_PROMPT_PREFIX, Y as BOARD_ANALYZER_PROMPT_PREFIX, f as connectionState, Z as startOfflineReconnection, c as createEnvelope, _ as CodexAppServerClient } from './types-Cq-tvv9t.mjs';
|
|
5
|
+
import { z as readDaemonState, l as logger, c as configuration, A as clearDaemonState, B as ensurePrivateDirectory, D as hardenPrivateFile, p as packageJson, g as readSettings, E as readCredentials, s as credentialRelayProblem, i as encodeBase64, F as readSettingsOutcome, G as updateSettings, H as encodeBase64Url, m as decodeBase64, I as writeCredentialsLegacy, J as writeCredentialsDataKey, d as readCredentialsForConfiguredRelay, j as encrypt, r as readPersistedSessions, w as writePrivateFileSync, K as decryptWithDataKey, L as decryptLegacy, M as persistSession, k as decrypt, f as ensurePrivateDirectorySync, N as acquireDaemonLock, O as deletePersistedSessions, P as writeDaemonState, Q as writeSettings, R as releaseDaemonLock, C as CLIPBOARD_TOOL_NAME, a as CLIPBOARD_TOOL_TITLE, b as CLIPBOARD_TOOL_DESCRIPTION, e as CLIPBOARD_MAX_BYTES, S as clearCredentials, T as clearMachineId, U as SandboxConfigSchema, V as getLatestDaemonLog } from './limits-BGeIBBE3.mjs';
|
|
6
6
|
import spawn$1, { spawn } from 'cross-spawn';
|
|
7
7
|
import path, { join, resolve, basename, isAbsolute, dirname, sep, delimiter, normalize } from 'node:path';
|
|
8
8
|
import { createInterface } from 'node:readline';
|
|
9
9
|
import { existsSync, readFileSync, readdirSync, statSync, mkdirSync, unlinkSync, renameSync, writeFileSync, accessSync, constants, openSync, fsyncSync, closeSync, rmSync as rmSync$1, chmodSync as chmodSync$1 } from 'node:fs';
|
|
10
|
-
import { f as trimIdent, A as AGENT_GUIDANCE, t as teamScopePath, T as TeamConnectionPreflightError, e as createTeamsClient, P as PREVIEW_TOOL_NAME, R as REPORT_PROGRESS_TOOL_NAME, g as TEAM_TOOL_NAMES, r as registerTeamsTools, a as PREVIEW_TOOL_TITLE, b as PREVIEW_TOOL_DESCRIPTION, h as REPORT_PROGRESS_TOOL_TITLE, i as REPORT_PROGRESS_TOOL_DESCRIPTION } from './agentGuidance-
|
|
10
|
+
import { f as trimIdent, A as AGENT_GUIDANCE, t as teamScopePath, T as TeamConnectionPreflightError, e as createTeamsClient, P as PREVIEW_TOOL_NAME, R as REPORT_PROGRESS_TOOL_NAME, g as TEAM_TOOL_NAMES, r as registerTeamsTools, a as PREVIEW_TOOL_TITLE, b as PREVIEW_TOOL_DESCRIPTION, h as REPORT_PROGRESS_TOOL_TITLE, i as REPORT_PROGRESS_TOOL_DESCRIPTION } from './agentGuidance-CPG5Cr5T.mjs';
|
|
11
11
|
import { readFile, writeFile, rename, unlink, mkdir, symlink, rm, readlink, lstat, stat, open as open$1, appendFile } from 'node:fs/promises';
|
|
12
12
|
import fs, { watch, access } from 'fs/promises';
|
|
13
13
|
import { useStdout, useInput, Box, Text, render } from 'ink';
|
|
@@ -12018,7 +12018,7 @@ function cleanupHookSettingsFile(filepath) {
|
|
|
12018
12018
|
}
|
|
12019
12019
|
}
|
|
12020
12020
|
|
|
12021
|
-
function registerKillSessionHandler(rpcHandlerManager, killThisHappy, archiveEvents) {
|
|
12021
|
+
function registerKillSessionHandler(rpcHandlerManager, killThisHappy, archiveEvents, options) {
|
|
12022
12022
|
let terminationStarted = false;
|
|
12023
12023
|
const terminateOnce = () => {
|
|
12024
12024
|
if (terminationStarted) return;
|
|
@@ -12026,6 +12026,10 @@ function registerKillSessionHandler(rpcHandlerManager, killThisHappy, archiveEve
|
|
|
12026
12026
|
void killThisHappy();
|
|
12027
12027
|
};
|
|
12028
12028
|
archiveEvents.on("archived", terminateOnce);
|
|
12029
|
+
if (options?.processSignals) {
|
|
12030
|
+
process.on("SIGTERM", terminateOnce);
|
|
12031
|
+
process.on("SIGINT", terminateOnce);
|
|
12032
|
+
}
|
|
12029
12033
|
rpcHandlerManager.registerHandler("killSession", async () => {
|
|
12030
12034
|
logger.debug("Kill session request received");
|
|
12031
12035
|
terminateOnce();
|
|
@@ -12034,6 +12038,13 @@ function registerKillSessionHandler(rpcHandlerManager, killThisHappy, archiveEve
|
|
|
12034
12038
|
message: "Killing happy-cli process"
|
|
12035
12039
|
};
|
|
12036
12040
|
});
|
|
12041
|
+
return () => {
|
|
12042
|
+
archiveEvents.off?.("archived", terminateOnce);
|
|
12043
|
+
if (options?.processSignals) {
|
|
12044
|
+
process.off("SIGTERM", terminateOnce);
|
|
12045
|
+
process.off("SIGINT", terminateOnce);
|
|
12046
|
+
}
|
|
12047
|
+
};
|
|
12037
12048
|
}
|
|
12038
12049
|
|
|
12039
12050
|
const SIDE_QUESTION_SYSTEM_PROMPT = [
|
|
@@ -12148,7 +12159,7 @@ function registerSideQuestionHandler(rpc, deps) {
|
|
|
12148
12159
|
const retainMs = deps.retainMs ?? SIDE_QUESTION_RETAIN_MS;
|
|
12149
12160
|
const maxRunMs = deps.maxRunMs ?? SIDE_QUESTION_MAX_RUN_MS;
|
|
12150
12161
|
const run = deps.run ?? (async (input) => {
|
|
12151
|
-
const { query } = await import('./index-
|
|
12162
|
+
const { query } = await import('./index-CEDPokKf.mjs');
|
|
12152
12163
|
return runSideQuestion(query, input);
|
|
12153
12164
|
});
|
|
12154
12165
|
const slots = /* @__PURE__ */ new Map();
|
|
@@ -16627,7 +16638,7 @@ async function runCodex(opts) {
|
|
|
16627
16638
|
}
|
|
16628
16639
|
};
|
|
16629
16640
|
session.rpcHandlerManager.registerHandler("abort", handleAbort);
|
|
16630
|
-
registerKillSessionHandler(session.rpcHandlerManager, handleKillSession, session);
|
|
16641
|
+
const disposeTermination = registerKillSessionHandler(session.rpcHandlerManager, handleKillSession, session, { processSignals: true });
|
|
16631
16642
|
const messageBuffer = new MessageBuffer();
|
|
16632
16643
|
const hasTTY = process.stdout.isTTY && process.stdin.isTTY;
|
|
16633
16644
|
let inkInstance = null;
|
|
@@ -16963,6 +16974,7 @@ async function runCodex(opts) {
|
|
|
16963
16974
|
}
|
|
16964
16975
|
}
|
|
16965
16976
|
} finally {
|
|
16977
|
+
disposeTermination?.();
|
|
16966
16978
|
logger.debug("[codex]: Final cleanup start");
|
|
16967
16979
|
logActiveHandles("cleanup-start");
|
|
16968
16980
|
if (reconnectionHandle) {
|
|
@@ -17165,7 +17177,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17165
17177
|
process.exit(0);
|
|
17166
17178
|
} else if (subcommand === "install-terminal-hooks") {
|
|
17167
17179
|
try {
|
|
17168
|
-
const { installTerminalHooks, parseTerminalHooksArgs, TERMINAL_HOOKS_HELP } = await import('./installTerminalHooks-
|
|
17180
|
+
const { installTerminalHooks, parseTerminalHooksArgs, TERMINAL_HOOKS_HELP } = await import('./installTerminalHooks-BT4Dq28Y.mjs');
|
|
17169
17181
|
const command = parseTerminalHooksArgs(args.slice(1));
|
|
17170
17182
|
if (command.action === "help") {
|
|
17171
17183
|
console.log(TERMINAL_HOOKS_HELP);
|
|
@@ -17182,7 +17194,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17182
17194
|
}
|
|
17183
17195
|
} else if (subcommand === "spawn") {
|
|
17184
17196
|
try {
|
|
17185
|
-
const { handleSpawnCommand } = await import('./spawn-
|
|
17197
|
+
const { handleSpawnCommand } = await import('./spawn-QtKlr8Ig.mjs');
|
|
17186
17198
|
await handleSpawnCommand(args.slice(1));
|
|
17187
17199
|
} catch (error) {
|
|
17188
17200
|
console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
|
|
@@ -17194,7 +17206,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17194
17206
|
return;
|
|
17195
17207
|
} else if (subcommand === "sessions") {
|
|
17196
17208
|
try {
|
|
17197
|
-
const { handleSessionsCommand } = await import('./sessions-
|
|
17209
|
+
const { handleSessionsCommand } = await import('./sessions-CJuwvEr0.mjs');
|
|
17198
17210
|
await handleSessionsCommand(args.slice(1));
|
|
17199
17211
|
} catch (error) {
|
|
17200
17212
|
console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
|
|
@@ -17206,7 +17218,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17206
17218
|
return;
|
|
17207
17219
|
} else if (subcommand === "send") {
|
|
17208
17220
|
try {
|
|
17209
|
-
const { handleSendCommand } = await import('./send-
|
|
17221
|
+
const { handleSendCommand } = await import('./send-DHShoBeq.mjs');
|
|
17210
17222
|
await handleSendCommand(args.slice(1));
|
|
17211
17223
|
} catch (error) {
|
|
17212
17224
|
console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
|
|
@@ -17312,9 +17324,9 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17312
17324
|
if (geminiSubcommand === "project" && args[2] === "set" && args[3]) {
|
|
17313
17325
|
const projectId = args[3];
|
|
17314
17326
|
try {
|
|
17315
|
-
const { saveGoogleCloudProjectToConfig } = await import('./config-
|
|
17316
|
-
const { readCredentialsForConfiguredRelay: readCredentialsForConfiguredRelay2 } = await import('./limits-
|
|
17317
|
-
const { ApiClient: ApiClient2 } = await import('./types-
|
|
17327
|
+
const { saveGoogleCloudProjectToConfig } = await import('./config-C4gWfnJX.mjs');
|
|
17328
|
+
const { readCredentialsForConfiguredRelay: readCredentialsForConfiguredRelay2 } = await import('./limits-BGeIBBE3.mjs').then(function (n) { return n.W; });
|
|
17329
|
+
const { ApiClient: ApiClient2 } = await import('./types-Cq-tvv9t.mjs').then(function (n) { return n.$; });
|
|
17318
17330
|
let userEmail = void 0;
|
|
17319
17331
|
try {
|
|
17320
17332
|
const credentials = await readCredentialsForConfiguredRelay2();
|
|
@@ -17345,7 +17357,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17345
17357
|
}
|
|
17346
17358
|
if (geminiSubcommand === "project" && args[2] === "get") {
|
|
17347
17359
|
try {
|
|
17348
|
-
const { readGeminiLocalConfig } = await import('./config-
|
|
17360
|
+
const { readGeminiLocalConfig } = await import('./config-C4gWfnJX.mjs');
|
|
17349
17361
|
const config = readGeminiLocalConfig();
|
|
17350
17362
|
if (config.googleCloudProject) {
|
|
17351
17363
|
console.log(`Current Google Cloud Project: ${config.googleCloudProject}`);
|
|
@@ -17385,7 +17397,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17385
17397
|
process.exit(0);
|
|
17386
17398
|
}
|
|
17387
17399
|
try {
|
|
17388
|
-
const { runGemini } = await import('./runGemini-
|
|
17400
|
+
const { runGemini } = await import('./runGemini-DGTNwiLo.mjs');
|
|
17389
17401
|
let startedBy = void 0;
|
|
17390
17402
|
for (let i = 1; i < args.length; i++) {
|
|
17391
17403
|
if (args[i] === "--started-by") {
|
|
@@ -17415,7 +17427,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17415
17427
|
}
|
|
17416
17428
|
};
|
|
17417
17429
|
try {
|
|
17418
|
-
const { runAcp, resolveAcpAgentConfig } = await import('./index-
|
|
17430
|
+
const { runAcp, resolveAcpAgentConfig } = await import('./index-B6UvB88K.mjs');
|
|
17419
17431
|
const parsed = parsePiRunnerArgs(args.slice(1));
|
|
17420
17432
|
const resolved = resolveAcpAgentConfig(["pi", ...parsed.passthrough]);
|
|
17421
17433
|
const { credentials } = await authAndSetupMachineIfNeeded();
|
|
@@ -17443,7 +17455,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17443
17455
|
return;
|
|
17444
17456
|
} else if (subcommand === "acp") {
|
|
17445
17457
|
try {
|
|
17446
|
-
const { runAcp, resolveAcpAgentConfig } = await import('./index-
|
|
17458
|
+
const { runAcp, resolveAcpAgentConfig } = await import('./index-B6UvB88K.mjs');
|
|
17447
17459
|
let startedBy = void 0;
|
|
17448
17460
|
let verbose = false;
|
|
17449
17461
|
const acpArgs = [];
|
|
@@ -17483,7 +17495,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17483
17495
|
return;
|
|
17484
17496
|
} else if (subcommand === "openclaw") {
|
|
17485
17497
|
try {
|
|
17486
|
-
const { runOpenClaw } = await import('./runOpenClaw-
|
|
17498
|
+
const { runOpenClaw } = await import('./runOpenClaw-CxgTFOSM.mjs');
|
|
17487
17499
|
let startedBy = void 0;
|
|
17488
17500
|
let verbose = false;
|
|
17489
17501
|
let gatewayUrl;
|
|
@@ -17534,7 +17546,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17534
17546
|
return;
|
|
17535
17547
|
} else if (subcommand === "todo") {
|
|
17536
17548
|
try {
|
|
17537
|
-
const { handleTodoCommand } = await import('./todo-
|
|
17549
|
+
const { handleTodoCommand } = await import('./todo-CkJ5UjWs.mjs');
|
|
17538
17550
|
await handleTodoCommand(args.slice(1));
|
|
17539
17551
|
} catch (error) {
|
|
17540
17552
|
console.error(JSON.stringify({ error: error instanceof Error ? error.message : "Todo command failed" }));
|
|
@@ -17543,7 +17555,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17543
17555
|
return;
|
|
17544
17556
|
} else if (subcommand === "teams") {
|
|
17545
17557
|
try {
|
|
17546
|
-
const { handleTeamsCommand } = await import('./teams-
|
|
17558
|
+
const { handleTeamsCommand } = await import('./teams-BF-GxUZc.mjs');
|
|
17547
17559
|
await handleTeamsCommand(args.slice(1));
|
|
17548
17560
|
} catch (error) {
|
|
17549
17561
|
console.error(error instanceof Error ? error.message : "Teams command failed");
|
|
@@ -17552,7 +17564,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17552
17564
|
return;
|
|
17553
17565
|
} else if (subcommand === "mcp" && args.length === 1) {
|
|
17554
17566
|
try {
|
|
17555
|
-
const { handleMcpCommand } = await import('./mcp-
|
|
17567
|
+
const { handleMcpCommand } = await import('./mcp-BGu_dUaJ.mjs');
|
|
17556
17568
|
await handleMcpCommand();
|
|
17557
17569
|
} catch (error) {
|
|
17558
17570
|
process.stderr.write(`[very-happy mcp] Fatal: ${error instanceof Error ? error.message : String(error)}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { q as query } from './index-
|
|
1
|
+
import { q as query } from './index-BqUOj1zK.mjs';
|
|
2
2
|
export { AbortError } from '@anthropic-ai/claude-agent-sdk';
|
|
3
3
|
import 'chalk';
|
|
4
4
|
import 'node:os';
|
|
5
5
|
import 'node:crypto';
|
|
6
|
-
import './types-
|
|
6
|
+
import './types-Cq-tvv9t.mjs';
|
|
7
7
|
import 'axios';
|
|
8
|
-
import './limits-
|
|
8
|
+
import './limits-BGeIBBE3.mjs';
|
|
9
9
|
import 'node:fs/promises';
|
|
10
10
|
import 'node:fs';
|
|
11
11
|
import 'node:path';
|
|
@@ -29,7 +29,7 @@ import 'fs';
|
|
|
29
29
|
import 'node:readline';
|
|
30
30
|
import '@anthropic-ai/sandbox-runtime';
|
|
31
31
|
import 'expo-server-sdk';
|
|
32
|
-
import './agentGuidance-
|
|
32
|
+
import './agentGuidance-CPG5Cr5T.mjs';
|
|
33
33
|
import 'ink';
|
|
34
34
|
import 'react';
|
|
35
35
|
import 'ps-list';
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var index = require('./index-
|
|
3
|
+
var index = require('./index-B1plzL9M.cjs');
|
|
4
4
|
var claudeAgentSdk = require('@anthropic-ai/claude-agent-sdk');
|
|
5
5
|
require('chalk');
|
|
6
6
|
require('node:os');
|
|
7
7
|
require('node:crypto');
|
|
8
|
-
require('./types-
|
|
8
|
+
require('./types-Dabm17Ln.cjs');
|
|
9
9
|
require('axios');
|
|
10
|
-
require('./limits-
|
|
10
|
+
require('./limits-D6kiAfXJ.cjs');
|
|
11
11
|
require('node:fs/promises');
|
|
12
12
|
require('node:fs');
|
|
13
13
|
require('node:path');
|
|
@@ -31,7 +31,7 @@ require('fs');
|
|
|
31
31
|
require('node:readline');
|
|
32
32
|
require('@anthropic-ai/sandbox-runtime');
|
|
33
33
|
require('expo-server-sdk');
|
|
34
|
-
require('./agentGuidance-
|
|
34
|
+
require('./agentGuidance-Cg8Lha39.cjs');
|
|
35
35
|
require('ink');
|
|
36
36
|
require('react');
|
|
37
37
|
require('ps-list');
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var AcpBackend = require('./AcpBackend-
|
|
4
|
-
var persistence = require('./limits-
|
|
5
|
-
var AcpSessionManager = require('./AcpSessionManager-
|
|
6
|
-
var api = require('./types-
|
|
7
|
-
var index = require('./index-
|
|
3
|
+
var AcpBackend = require('./AcpBackend-CeNp7tgD.cjs');
|
|
4
|
+
var persistence = require('./limits-D6kiAfXJ.cjs');
|
|
5
|
+
var AcpSessionManager = require('./AcpSessionManager-Bu1d05bx.cjs');
|
|
6
|
+
var api = require('./types-Dabm17Ln.cjs');
|
|
7
|
+
var index = require('./index-B1plzL9M.cjs');
|
|
8
8
|
var promises = require('node:fs/promises');
|
|
9
9
|
var node_crypto = require('node:crypto');
|
|
10
10
|
var path = require('node:path');
|
|
@@ -33,7 +33,7 @@ require('fs');
|
|
|
33
33
|
require('node:readline');
|
|
34
34
|
require('@anthropic-ai/sandbox-runtime');
|
|
35
35
|
require('expo-server-sdk');
|
|
36
|
-
require('./agentGuidance-
|
|
36
|
+
require('./agentGuidance-Cg8Lha39.cjs');
|
|
37
37
|
require('ink');
|
|
38
38
|
require('react');
|
|
39
39
|
require('@anthropic-ai/claude-agent-sdk');
|
|
@@ -750,6 +750,7 @@ async function runAcp(opts) {
|
|
|
750
750
|
let shouldExit = false;
|
|
751
751
|
let abortController = new AbortController();
|
|
752
752
|
let pendingTurn = null;
|
|
753
|
+
let turnCancelled = false;
|
|
753
754
|
const clearPendingTurn = (error) => {
|
|
754
755
|
if (!pendingTurn) {
|
|
755
756
|
return;
|
|
@@ -1095,6 +1096,7 @@ async function runAcp(opts) {
|
|
|
1095
1096
|
session.keepAlive(thinking, "remote");
|
|
1096
1097
|
}, 2e3);
|
|
1097
1098
|
async function handleAbort() {
|
|
1099
|
+
turnCancelled = thinking;
|
|
1098
1100
|
try {
|
|
1099
1101
|
if (acpSessionId) {
|
|
1100
1102
|
await backend.cancel(acpSessionId);
|
|
@@ -1124,12 +1126,12 @@ async function runAcp(opts) {
|
|
|
1124
1126
|
return { mode };
|
|
1125
1127
|
}
|
|
1126
1128
|
);
|
|
1127
|
-
index.registerKillSessionHandler(session.rpcHandlerManager, async () => {
|
|
1129
|
+
const disposeTermination = index.registerKillSessionHandler(session.rpcHandlerManager, async () => {
|
|
1128
1130
|
shouldExit = true;
|
|
1129
1131
|
messageQueue.close();
|
|
1130
1132
|
clearPendingTurn(new Error("Session terminated"));
|
|
1131
1133
|
await handleAbort();
|
|
1132
|
-
}, session);
|
|
1134
|
+
}, session, { processSignals: true });
|
|
1133
1135
|
try {
|
|
1134
1136
|
const started = await backend.startSession();
|
|
1135
1137
|
acpSessionId = started.sessionId;
|
|
@@ -1175,8 +1177,11 @@ async function runAcp(opts) {
|
|
|
1175
1177
|
}
|
|
1176
1178
|
logAcp("incoming", `Incoming prompt: ${formatUnknownForConsole(batch.message, ACP_EVENT_PREVIEW_CHARS)}`);
|
|
1177
1179
|
sendEnvelopes(sessionManager.startTurn());
|
|
1180
|
+
turnCancelled = false;
|
|
1178
1181
|
setThinking(true);
|
|
1179
1182
|
const turnEnded = waitForTurnEnd();
|
|
1183
|
+
void turnEnded.catch(() => {
|
|
1184
|
+
});
|
|
1180
1185
|
try {
|
|
1181
1186
|
if (typeof batch.mode.permissionMode === "string" && batch.mode.permissionMode.length > 0) {
|
|
1182
1187
|
await switchPermissionModeIfRequested(batch.mode.permissionMode);
|
|
@@ -1196,7 +1201,7 @@ ${api.BUILTIN_TODO_DISCOVERY}`;
|
|
|
1196
1201
|
await backend.sendPrompt(acpSessionId, index.appendStagedAttachmentsToPrompt(prompt, staged), attachments);
|
|
1197
1202
|
todoDiscoverySent = true;
|
|
1198
1203
|
await turnEnded;
|
|
1199
|
-
sendEnvelopes(sessionManager.endTurn("completed"));
|
|
1204
|
+
sendEnvelopes(sessionManager.endTurn(turnCancelled ? "cancelled" : "completed"));
|
|
1200
1205
|
streamRelay.endTurn();
|
|
1201
1206
|
setThinking(false);
|
|
1202
1207
|
session.sendSessionEvent({ type: "ready" });
|
|
@@ -1215,6 +1220,7 @@ ${api.BUILTIN_TODO_DISCOVERY}`;
|
|
|
1215
1220
|
}
|
|
1216
1221
|
}
|
|
1217
1222
|
} finally {
|
|
1223
|
+
disposeTermination?.();
|
|
1218
1224
|
setThinking(false);
|
|
1219
1225
|
clearInterval(keepAliveInterval);
|
|
1220
1226
|
streamRelay.endTurn();
|
package/dist/index.cjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
require('chalk');
|
|
4
|
-
require('./index-
|
|
5
|
-
require('./limits-
|
|
4
|
+
require('./index-B1plzL9M.cjs');
|
|
5
|
+
require('./limits-D6kiAfXJ.cjs');
|
|
6
6
|
require('zod');
|
|
7
|
-
require('./types-
|
|
7
|
+
require('./types-Dabm17Ln.cjs');
|
|
8
8
|
require('node:child_process');
|
|
9
9
|
require('node:os');
|
|
10
10
|
require('node:crypto');
|
|
@@ -12,7 +12,7 @@ require('cross-spawn');
|
|
|
12
12
|
require('node:path');
|
|
13
13
|
require('node:readline');
|
|
14
14
|
require('node:fs');
|
|
15
|
-
require('./agentGuidance-
|
|
15
|
+
require('./agentGuidance-Cg8Lha39.cjs');
|
|
16
16
|
require('node:fs/promises');
|
|
17
17
|
require('fs/promises');
|
|
18
18
|
require('ink');
|
package/dist/index.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import 'chalk';
|
|
2
|
-
import './index-
|
|
3
|
-
import './limits-
|
|
2
|
+
import './index-BqUOj1zK.mjs';
|
|
3
|
+
import './limits-BGeIBBE3.mjs';
|
|
4
4
|
import 'zod';
|
|
5
|
-
import './types-
|
|
5
|
+
import './types-Cq-tvv9t.mjs';
|
|
6
6
|
import 'node:child_process';
|
|
7
7
|
import 'node:os';
|
|
8
8
|
import 'node:crypto';
|
|
@@ -10,7 +10,7 @@ import 'cross-spawn';
|
|
|
10
10
|
import 'node:path';
|
|
11
11
|
import 'node:readline';
|
|
12
12
|
import 'node:fs';
|
|
13
|
-
import './agentGuidance-
|
|
13
|
+
import './agentGuidance-CPG5Cr5T.mjs';
|
|
14
14
|
import 'node:fs/promises';
|
|
15
15
|
import 'fs/promises';
|
|
16
16
|
import 'ink';
|
|
@@ -3,10 +3,10 @@ import { join, resolve } from 'node:path';
|
|
|
3
3
|
import { homedir } from 'node:os';
|
|
4
4
|
import { spawnSync } from 'node:child_process';
|
|
5
5
|
import chalk from 'chalk';
|
|
6
|
-
import { p as projectPath } from './types-
|
|
7
|
-
import { t as tmuxSupportsSessionEnv } from './index-
|
|
6
|
+
import { p as projectPath } from './types-Cq-tvv9t.mjs';
|
|
7
|
+
import { t as tmuxSupportsSessionEnv } from './index-BqUOj1zK.mjs';
|
|
8
8
|
import 'axios';
|
|
9
|
-
import './limits-
|
|
9
|
+
import './limits-BGeIBBE3.mjs';
|
|
10
10
|
import 'node:fs/promises';
|
|
11
11
|
import 'zod';
|
|
12
12
|
import 'node:crypto';
|
|
@@ -28,7 +28,7 @@ import 'fs';
|
|
|
28
28
|
import 'node:readline';
|
|
29
29
|
import '@anthropic-ai/sandbox-runtime';
|
|
30
30
|
import 'expo-server-sdk';
|
|
31
|
-
import './agentGuidance-
|
|
31
|
+
import './agentGuidance-CPG5Cr5T.mjs';
|
|
32
32
|
import 'ink';
|
|
33
33
|
import 'react';
|
|
34
34
|
import '@anthropic-ai/claude-agent-sdk';
|
|
@@ -5,10 +5,10 @@ var path = require('node:path');
|
|
|
5
5
|
var os = require('node:os');
|
|
6
6
|
var node_child_process = require('node:child_process');
|
|
7
7
|
var chalk = require('chalk');
|
|
8
|
-
var api = require('./types-
|
|
9
|
-
var index = require('./index-
|
|
8
|
+
var api = require('./types-Dabm17Ln.cjs');
|
|
9
|
+
var index = require('./index-B1plzL9M.cjs');
|
|
10
10
|
require('axios');
|
|
11
|
-
require('./limits-
|
|
11
|
+
require('./limits-D6kiAfXJ.cjs');
|
|
12
12
|
require('node:fs/promises');
|
|
13
13
|
require('zod');
|
|
14
14
|
require('node:crypto');
|
|
@@ -30,7 +30,7 @@ require('fs');
|
|
|
30
30
|
require('node:readline');
|
|
31
31
|
require('@anthropic-ai/sandbox-runtime');
|
|
32
32
|
require('expo-server-sdk');
|
|
33
|
-
require('./agentGuidance-
|
|
33
|
+
require('./agentGuidance-Cg8Lha39.cjs');
|
|
34
34
|
require('ink');
|
|
35
35
|
require('react');
|
|
36
36
|
require('@anthropic-ai/claude-agent-sdk');
|
package/dist/lib.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var api = require('./types-
|
|
4
|
-
var persistence = require('./limits-
|
|
3
|
+
var api = require('./types-Dabm17Ln.cjs');
|
|
4
|
+
var persistence = require('./limits-D6kiAfXJ.cjs');
|
|
5
5
|
require('axios');
|
|
6
6
|
require('node:events');
|
|
7
7
|
require('socket.io-client');
|
package/dist/lib.d.cts
CHANGED
|
@@ -408,6 +408,8 @@ declare const DaemonStateSchema: z$1.ZodObject<{
|
|
|
408
408
|
idle: "idle";
|
|
409
409
|
shell: "shell";
|
|
410
410
|
}>>;
|
|
411
|
+
agentKind: z$1.ZodOptional<z$1.ZodString>;
|
|
412
|
+
agentObservedAt: z$1.ZodOptional<z$1.ZodNumber>;
|
|
411
413
|
mirrorSessionId: z$1.ZodOptional<z$1.ZodString>;
|
|
412
414
|
restoredAt: z$1.ZodOptional<z$1.ZodNumber>;
|
|
413
415
|
manual: z$1.ZodOptional<z$1.ZodBoolean>;
|
|
@@ -1184,66 +1186,8 @@ type SpawnSessionResult = {
|
|
|
1184
1186
|
errorMessage: string;
|
|
1185
1187
|
};
|
|
1186
1188
|
|
|
1187
|
-
/**
|
|
1188
|
-
|
|
1189
|
-
*
|
|
1190
|
-
* ── Architecture (Stage 1: daemon-authoritative screen) ──────────────────────
|
|
1191
|
-
* Each web terminal is a long-lived daemon session object that owns the screen
|
|
1192
|
-
* state, so client reconnect/redraw no longer relies on tmux redrawing on
|
|
1193
|
-
* re-attach. A session holds:
|
|
1194
|
-
* 1. a node-pty attached to a BACKGROUND tmux session `vh-<id>` (the pty is
|
|
1195
|
-
* just tmux's single stable client; the tmux session holds the process);
|
|
1196
|
-
* 2. an `@xterm/headless` Terminal — every pty output chunk is `.write()` into
|
|
1197
|
-
* it, so the daemon always has the authoritative screen + scrollback;
|
|
1198
|
-
* 3. a monotonic output `seq` (incremented per emitted chunk);
|
|
1199
|
-
* 4. a bounded ring buffer of recent `{ seq, data }` chunks, used to replay
|
|
1200
|
-
* only the gap after a brief client disconnect instead of a full snapshot.
|
|
1201
|
-
*
|
|
1202
|
-
* On (re)subscribe (`open`), the daemon returns either a REPLAY (the client's
|
|
1203
|
-
* `fromSeq..now` is still covered by the ring → send just the missing chunks) or
|
|
1204
|
-
* a SNAPSHOT (serialize the headless screen, bounded scrollback). The pty is NOT
|
|
1205
|
-
* recreated on re-subscribe — the browser connecting/disconnecting is pure
|
|
1206
|
-
* subscribe/unsubscribe against the daemon buffer. This is what kills the old
|
|
1207
|
-
* single-client redraw jitter: the daemon keeps exactly one steady tmux client;
|
|
1208
|
-
* it no longer creates/destroys a tmux client on every browser open/close.
|
|
1209
|
-
*
|
|
1210
|
-
* Cross-browser survival: closing the web view only marks the session as having
|
|
1211
|
-
* no subscribers; the pty (and headless buffer) live on. An idle reaper detaches
|
|
1212
|
-
* the pty only when it has no subscribers AND has been idle past the timeout
|
|
1213
|
-
* (tmux stays alive → reopening reattaches instantly). MAX_LIVE_SESSIONS still
|
|
1214
|
-
* LRU-evicts to protect the system PTY pool.
|
|
1215
|
-
*
|
|
1216
|
-
* Transport: raw bytes are relayed base64 over the (TLS) socket through the
|
|
1217
|
-
* server, consistent with the server-trusted model. open/input/resize/close are
|
|
1218
|
-
* driven from apiMachine; live output is pushed via the injected emit callback.
|
|
1219
|
-
* If tmux isn't installed we fall back to the login shell directly (no local
|
|
1220
|
-
* attach / no background survival, but the terminal still works).
|
|
1221
|
-
*
|
|
1222
|
-
* ── List push (Stage 2: daemon-driven terminal list) ─────────────────────────
|
|
1223
|
-
* The manager also runs ONE internal list-tracking loop (startListTracking):
|
|
1224
|
-
* every tick it rebuilds the cross-device list (tmux membership + @vh_title
|
|
1225
|
-
* follow + agent classification + activity) and fires the callback only when
|
|
1226
|
-
* the list SIGNATURE changed (terminalListSignature — activityAt quantized so
|
|
1227
|
-
* raw output alone can't turn it into a metronome). Event kicks (open / kill /
|
|
1228
|
-
* exit / rename / live OSC title via headless onTitleChange) refresh within
|
|
1229
|
-
* LIST_KICK_DEBOUNCE_MS instead of waiting for the tick. apiMachine writes each
|
|
1230
|
-
* changed list into daemonState.webTerminals, which the server persists and
|
|
1231
|
-
* broadcasts — clients consume the push instead of polling `list-terminals`
|
|
1232
|
-
* (the RPC remains for old clients; both return the same item shape).
|
|
1233
|
-
*
|
|
1234
|
-
* ── Realtime activity (Stage 3: ephemeral `terminal-activity`) ───────────────
|
|
1235
|
-
* The list push above is the DURABLE lane and is deliberately coarse: one push
|
|
1236
|
-
* costs a full daemonState encrypt + CAS + DB write + broadcast, so activity
|
|
1237
|
-
* only participates in its signature at 60s granularity — which meant a
|
|
1238
|
-
* terminal that was merely PRINTING could take up to a minute to float to the
|
|
1239
|
-
* top of the sidebar. Stage 3 adds a second, ephemeral lane for exactly that
|
|
1240
|
-
* one number: `terminal-activity` frames carrying `[{ id, activityAt }]`,
|
|
1241
|
-
* relayed by the server to the account's web clients and stored nowhere. Fed
|
|
1242
|
-
* by the live pty stream (leading-edge throttled to ~1s) and by the tracking
|
|
1243
|
-
* tick (which is the only observer of COLD sessions' tmux activity). Emitted
|
|
1244
|
-
* only when a value actually moved, so an idle machine sends nothing at all.
|
|
1245
|
-
* The 60s bucket stays exactly as it is — the two lanes have different jobs.
|
|
1246
|
-
*/
|
|
1189
|
+
/** Agent-specific visible-screen adapters. Unknown is deliberately not idle. */
|
|
1190
|
+
type CodingAgentKind = 'claude' | 'codex' | 'pi';
|
|
1247
1191
|
|
|
1248
1192
|
/**
|
|
1249
1193
|
* Coarse state of the agent (Claude Code) inside a web terminal, surfaced in
|
|
@@ -1267,6 +1211,8 @@ interface TerminalListItem {
|
|
|
1267
1211
|
createdAt?: number;
|
|
1268
1212
|
activityAt?: number;
|
|
1269
1213
|
agentState?: AgentState;
|
|
1214
|
+
agentKind?: CodingAgentKind;
|
|
1215
|
+
agentObservedAt?: number;
|
|
1270
1216
|
/** Mirror reconcile (design v3): stricter "claude is really here" gate (its
|
|
1271
1217
|
* own TUI footer/dialog present) — daemon-internal, NOT pushed to web and
|
|
1272
1218
|
* NOT part of the list signature. Only this may trigger mirror adopt (which
|
package/dist/lib.d.mts
CHANGED
|
@@ -408,6 +408,8 @@ declare const DaemonStateSchema: z$1.ZodObject<{
|
|
|
408
408
|
idle: "idle";
|
|
409
409
|
shell: "shell";
|
|
410
410
|
}>>;
|
|
411
|
+
agentKind: z$1.ZodOptional<z$1.ZodString>;
|
|
412
|
+
agentObservedAt: z$1.ZodOptional<z$1.ZodNumber>;
|
|
411
413
|
mirrorSessionId: z$1.ZodOptional<z$1.ZodString>;
|
|
412
414
|
restoredAt: z$1.ZodOptional<z$1.ZodNumber>;
|
|
413
415
|
manual: z$1.ZodOptional<z$1.ZodBoolean>;
|
|
@@ -1184,66 +1186,8 @@ type SpawnSessionResult = {
|
|
|
1184
1186
|
errorMessage: string;
|
|
1185
1187
|
};
|
|
1186
1188
|
|
|
1187
|
-
/**
|
|
1188
|
-
|
|
1189
|
-
*
|
|
1190
|
-
* ── Architecture (Stage 1: daemon-authoritative screen) ──────────────────────
|
|
1191
|
-
* Each web terminal is a long-lived daemon session object that owns the screen
|
|
1192
|
-
* state, so client reconnect/redraw no longer relies on tmux redrawing on
|
|
1193
|
-
* re-attach. A session holds:
|
|
1194
|
-
* 1. a node-pty attached to a BACKGROUND tmux session `vh-<id>` (the pty is
|
|
1195
|
-
* just tmux's single stable client; the tmux session holds the process);
|
|
1196
|
-
* 2. an `@xterm/headless` Terminal — every pty output chunk is `.write()` into
|
|
1197
|
-
* it, so the daemon always has the authoritative screen + scrollback;
|
|
1198
|
-
* 3. a monotonic output `seq` (incremented per emitted chunk);
|
|
1199
|
-
* 4. a bounded ring buffer of recent `{ seq, data }` chunks, used to replay
|
|
1200
|
-
* only the gap after a brief client disconnect instead of a full snapshot.
|
|
1201
|
-
*
|
|
1202
|
-
* On (re)subscribe (`open`), the daemon returns either a REPLAY (the client's
|
|
1203
|
-
* `fromSeq..now` is still covered by the ring → send just the missing chunks) or
|
|
1204
|
-
* a SNAPSHOT (serialize the headless screen, bounded scrollback). The pty is NOT
|
|
1205
|
-
* recreated on re-subscribe — the browser connecting/disconnecting is pure
|
|
1206
|
-
* subscribe/unsubscribe against the daemon buffer. This is what kills the old
|
|
1207
|
-
* single-client redraw jitter: the daemon keeps exactly one steady tmux client;
|
|
1208
|
-
* it no longer creates/destroys a tmux client on every browser open/close.
|
|
1209
|
-
*
|
|
1210
|
-
* Cross-browser survival: closing the web view only marks the session as having
|
|
1211
|
-
* no subscribers; the pty (and headless buffer) live on. An idle reaper detaches
|
|
1212
|
-
* the pty only when it has no subscribers AND has been idle past the timeout
|
|
1213
|
-
* (tmux stays alive → reopening reattaches instantly). MAX_LIVE_SESSIONS still
|
|
1214
|
-
* LRU-evicts to protect the system PTY pool.
|
|
1215
|
-
*
|
|
1216
|
-
* Transport: raw bytes are relayed base64 over the (TLS) socket through the
|
|
1217
|
-
* server, consistent with the server-trusted model. open/input/resize/close are
|
|
1218
|
-
* driven from apiMachine; live output is pushed via the injected emit callback.
|
|
1219
|
-
* If tmux isn't installed we fall back to the login shell directly (no local
|
|
1220
|
-
* attach / no background survival, but the terminal still works).
|
|
1221
|
-
*
|
|
1222
|
-
* ── List push (Stage 2: daemon-driven terminal list) ─────────────────────────
|
|
1223
|
-
* The manager also runs ONE internal list-tracking loop (startListTracking):
|
|
1224
|
-
* every tick it rebuilds the cross-device list (tmux membership + @vh_title
|
|
1225
|
-
* follow + agent classification + activity) and fires the callback only when
|
|
1226
|
-
* the list SIGNATURE changed (terminalListSignature — activityAt quantized so
|
|
1227
|
-
* raw output alone can't turn it into a metronome). Event kicks (open / kill /
|
|
1228
|
-
* exit / rename / live OSC title via headless onTitleChange) refresh within
|
|
1229
|
-
* LIST_KICK_DEBOUNCE_MS instead of waiting for the tick. apiMachine writes each
|
|
1230
|
-
* changed list into daemonState.webTerminals, which the server persists and
|
|
1231
|
-
* broadcasts — clients consume the push instead of polling `list-terminals`
|
|
1232
|
-
* (the RPC remains for old clients; both return the same item shape).
|
|
1233
|
-
*
|
|
1234
|
-
* ── Realtime activity (Stage 3: ephemeral `terminal-activity`) ───────────────
|
|
1235
|
-
* The list push above is the DURABLE lane and is deliberately coarse: one push
|
|
1236
|
-
* costs a full daemonState encrypt + CAS + DB write + broadcast, so activity
|
|
1237
|
-
* only participates in its signature at 60s granularity — which meant a
|
|
1238
|
-
* terminal that was merely PRINTING could take up to a minute to float to the
|
|
1239
|
-
* top of the sidebar. Stage 3 adds a second, ephemeral lane for exactly that
|
|
1240
|
-
* one number: `terminal-activity` frames carrying `[{ id, activityAt }]`,
|
|
1241
|
-
* relayed by the server to the account's web clients and stored nowhere. Fed
|
|
1242
|
-
* by the live pty stream (leading-edge throttled to ~1s) and by the tracking
|
|
1243
|
-
* tick (which is the only observer of COLD sessions' tmux activity). Emitted
|
|
1244
|
-
* only when a value actually moved, so an idle machine sends nothing at all.
|
|
1245
|
-
* The 60s bucket stays exactly as it is — the two lanes have different jobs.
|
|
1246
|
-
*/
|
|
1189
|
+
/** Agent-specific visible-screen adapters. Unknown is deliberately not idle. */
|
|
1190
|
+
type CodingAgentKind = 'claude' | 'codex' | 'pi';
|
|
1247
1191
|
|
|
1248
1192
|
/**
|
|
1249
1193
|
* Coarse state of the agent (Claude Code) inside a web terminal, surfaced in
|
|
@@ -1267,6 +1211,8 @@ interface TerminalListItem {
|
|
|
1267
1211
|
createdAt?: number;
|
|
1268
1212
|
activityAt?: number;
|
|
1269
1213
|
agentState?: AgentState;
|
|
1214
|
+
agentKind?: CodingAgentKind;
|
|
1215
|
+
agentObservedAt?: number;
|
|
1270
1216
|
/** Mirror reconcile (design v3): stricter "claude is really here" gate (its
|
|
1271
1217
|
* own TUI footer/dialog present) — daemon-internal, NOT pushed to web and
|
|
1272
1218
|
* NOT part of the list signature. Only this may trigger mirror adopt (which
|
package/dist/lib.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { A as ApiClient, a as ApiSessionClient, R as RawJSONLinesSchema } from './types-
|
|
2
|
-
export { c as configuration, l as logger } from './limits-
|
|
1
|
+
export { A as ApiClient, a as ApiSessionClient, R as RawJSONLinesSchema } from './types-Cq-tvv9t.mjs';
|
|
2
|
+
export { c as configuration, l as logger } from './limits-BGeIBBE3.mjs';
|
|
3
3
|
import 'axios';
|
|
4
4
|
import 'node:events';
|
|
5
5
|
import 'socket.io-client';
|
|
@@ -9,7 +9,7 @@ import chalk from 'chalk';
|
|
|
9
9
|
import { inspect } from 'node:util';
|
|
10
10
|
|
|
11
11
|
var name = "very-happy-cli";
|
|
12
|
-
var version = "0.2.
|
|
12
|
+
var version = "0.2.134";
|
|
13
13
|
var description = "Remote multi-agent workspace CLI with deep Claude integration, native terminal streaming, and self-hosting.";
|
|
14
14
|
var author = "Kirill Dubovitskiy";
|
|
15
15
|
var contributors = [
|
|
@@ -122,12 +122,12 @@ var dependencies = {
|
|
|
122
122
|
zod: "^4.0.0"
|
|
123
123
|
};
|
|
124
124
|
var optionalDependencies = {
|
|
125
|
-
"very-happy-tools-arm64-darwin": "0.2.
|
|
126
|
-
"very-happy-tools-x64-darwin": "0.2.
|
|
127
|
-
"very-happy-tools-arm64-linux": "0.2.
|
|
128
|
-
"very-happy-tools-x64-linux": "0.2.
|
|
129
|
-
"very-happy-tools-arm64-win32": "0.2.
|
|
130
|
-
"very-happy-tools-x64-win32": "0.2.
|
|
125
|
+
"very-happy-tools-arm64-darwin": "0.2.134",
|
|
126
|
+
"very-happy-tools-x64-darwin": "0.2.134",
|
|
127
|
+
"very-happy-tools-arm64-linux": "0.2.134",
|
|
128
|
+
"very-happy-tools-x64-linux": "0.2.134",
|
|
129
|
+
"very-happy-tools-arm64-win32": "0.2.134",
|
|
130
|
+
"very-happy-tools-x64-win32": "0.2.134"
|
|
131
131
|
};
|
|
132
132
|
var devDependencies = {
|
|
133
133
|
"@slopus/happy-wire": "workspace:*",
|