very-happy-cli 0.2.114 → 0.2.116

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.
Files changed (35) hide show
  1. package/dist/{AcpBackend-BYv1pHW6.cjs → AcpBackend-CauAQpC1.cjs} +1 -1
  2. package/dist/{AcpBackend-4DC6CDpP.mjs → AcpBackend-CfKPvoTU.mjs} +1 -1
  3. package/dist/{AcpSessionManager-CvDQWnwm.mjs → AcpSessionManager-BQ6pBRW4.mjs} +1 -1
  4. package/dist/{AcpSessionManager-BBCEuz5G.cjs → AcpSessionManager-CA6xeET_.cjs} +1 -1
  5. package/dist/{config-B1W5KTvn.cjs → config-BoteFn-v.cjs} +2 -2
  6. package/dist/{config-BYEj8cnm.mjs → config-BpR_CwZu.mjs} +2 -2
  7. package/dist/{index-CQ9f70v9.cjs → index-4jiUeiUz.cjs} +187 -20
  8. package/dist/{index-B-PX710g.mjs → index-C45xN8s0.mjs} +5 -5
  9. package/dist/{index-DXJ4FLp5.mjs → index-D7azxfcs.mjs} +2 -2
  10. package/dist/{index-BtFBYvj8.cjs → index-DWmhmji9.cjs} +4 -4
  11. package/dist/{index-DJcR5PQb.mjs → index-Dq-eFp89.mjs} +188 -21
  12. package/dist/{index-CiNMkjGe.cjs → index-lX1UliOs.cjs} +2 -2
  13. package/dist/index.cjs +2 -2
  14. package/dist/index.mjs +2 -2
  15. package/dist/{installTerminalHooks-CvWutFrA.cjs → installTerminalHooks-DnaFkrTF.cjs} +2 -2
  16. package/dist/{installTerminalHooks-BKqlOoi4.mjs → installTerminalHooks-k3TrBHD0.mjs} +2 -2
  17. package/dist/lib.cjs +1 -1
  18. package/dist/lib.d.cts +33 -0
  19. package/dist/lib.d.mts +33 -0
  20. package/dist/lib.mjs +1 -1
  21. package/dist/{mcp-kyB44gVF.mjs → mcp-DRePTOap.mjs} +2 -2
  22. package/dist/{mcp-KhfiJ6OC.cjs → mcp-DSpEpM_2.cjs} +2 -2
  23. package/dist/{runGemini-DYN1hVth.cjs → runGemini-IWHyBq0A.cjs} +4 -4
  24. package/dist/{runGemini-Jn7L2hqR.mjs → runGemini-_9-a7duU.mjs} +4 -4
  25. package/dist/{runOpenClaw-DHqzKgke.cjs → runOpenClaw-0myYIz1U.cjs} +3 -3
  26. package/dist/{runOpenClaw-BZL1CSvh.mjs → runOpenClaw-Boq6LQ9a.mjs} +3 -3
  27. package/dist/{send-m-ZqzS6w.cjs → send-CwWvFfay.cjs} +2 -2
  28. package/dist/{send-DlNrAHnH.mjs → send-Cyo6mgMl.mjs} +2 -2
  29. package/dist/{sessions-Qbk_H0Av.cjs → sessions-CbzqYiAy.cjs} +2 -2
  30. package/dist/{sessions-CpM_qzf7.mjs → sessions-lvfTH_ql.mjs} +2 -2
  31. package/dist/{spawn-Do8fUG8J.mjs → spawn-CU0DMauA.mjs} +2 -2
  32. package/dist/{spawn-D09KFk0I.cjs → spawn-DQ6FTUK9.cjs} +2 -2
  33. package/dist/{types-D14vU6_q.cjs → types-C5kEpkcZ.cjs} +156 -15
  34. package/dist/{types-C6vCFbPv.mjs → types-Ds0SiQ1D.mjs} +155 -14
  35. package/package.json +7 -7
@@ -1,11 +1,11 @@
1
1
  import{createRequire as _pkgrollCR}from"node:module";const require=_pkgrollCR(import.meta.url);import chalk from 'chalk';
2
- import os, { homedir, userInfo } from 'node:os';
2
+ import os, { homedir, userInfo, tmpdir } from 'node:os';
3
3
  import { randomUUID, randomBytes, createHash as createHash$1, timingSafeEqual } from 'node:crypto';
4
- import { o as readDaemonState, l as logger, c as configuration, q as clearDaemonState, s as getProjectPath, p as projectPath, t as initializeSandbox, u as wrapCommand, d as contentLogMetadata, I as InvalidateSync, R as RawJSONLinesSchema, g as delay, v as AsyncLock, S as STREAM_DELTA_MAX_CHARS, x as ensurePrivateDirectory, M as MAX_CHAT_ATTACHMENT_SOURCE_BYTES, y as hardenPrivateFile, f as packageJson, j as readSettings, z as readCredentials, B as credentialRelayProblem, C as deriveLocalCliUpdateSummary, k as encodeBase64, D as updateSettings, E as encodeBase64Url, F as decodeBase64, G as writeCredentialsLegacy, H as writeCredentialsDataKey, J as readCredentialsForConfiguredRelay, K as encrypt, r as readPersistedSessions, L as isClaudeSessionId, N as getLocalHappyAgentCredentialPath, O as readLocalHappyAgentCredentials, P as decryptWithDataKey, Q as decryptLegacy, T as extractCompleteLines, U as decideBackfill, V as parseTerminalHookPayload, W as tmuxArgs, X as scrubTmuxClientEnv, Y as decideMirrorBinding, Z as MIRROR_BACKFILL_LINES_DEFAULT, _ as persistSession, $ as mirrorLineKey, a0 as mirrorLocalId, w as writePrivateFileSync, a1 as detectResumeSupport, a2 as detectCLIAvailability, a3 as acquireDaemonLock, a4 as summarizeSpawnSessionForLog, a5 as deletePersistedSessions, a6 as shellescape, a7 as decrypt, a8 as writeDaemonState, A as ApiClient, a9 as writeSettings, aa as fetchCliUpdateState, ab as resolveCliUpdateCheckInterval, ac as DEFAULT_CLI_UPDATE_CHECK_INTERVAL_MS, ad as releaseDaemonLock, i as isValidSessionId, ae as listVhTerminals, af as isValidTerminalId, ag as readVhTerminal, ah as sendToVhTerminal, ai as TITLE_PROMPT_PREFIX, aj as BOARD_ANALYZER_PROMPT_PREFIX, h as connectionState, ak as startOfflineReconnection, al as clearCredentials, am as clearMachineId, m as ensurePrivateDirectorySync, an as SandboxConfigSchema, b as createEnvelope, ao as CodexAppServerClient, ap as getLatestDaemonLog } from './types-C6vCFbPv.mjs';
4
+ import { o as readDaemonState, l as logger, c as configuration, q as clearDaemonState, s as getProjectPath, p as projectPath, t as initializeSandbox, u as wrapCommand, d as contentLogMetadata, I as InvalidateSync, R as RawJSONLinesSchema, g as delay, v as AsyncLock, S as STREAM_DELTA_MAX_CHARS, x as ensurePrivateDirectory, M as MAX_CHAT_ATTACHMENT_SOURCE_BYTES, y as hardenPrivateFile, f as packageJson, j as readSettings, z as readCredentials, B as credentialRelayProblem, C as deriveLocalCliUpdateSummary, k as encodeBase64, D as updateSettings, E as encodeBase64Url, F as decodeBase64, G as writeCredentialsLegacy, H as writeCredentialsDataKey, J as readCredentialsForConfiguredRelay, K as encrypt, r as readPersistedSessions, L as isClaudeSessionId, N as getLocalHappyAgentCredentialPath, O as readLocalHappyAgentCredentials, P as decryptWithDataKey, Q as decryptLegacy, T as extractCompleteLines, U as decideBackfill, V as parseTerminalHookPayload, W as tmuxArgs, X as scrubTmuxClientEnv, Y as decideMirrorBinding, Z as MIRROR_BACKFILL_LINES_DEFAULT, _ as persistSession, $ as mirrorLineKey, a0 as mirrorLocalId, w as writePrivateFileSync, a1 as detectResumeSupport, a2 as detectCLIAvailability, a3 as acquireDaemonLock, a4 as summarizeSpawnSessionForLog, a5 as deletePersistedSessions, a6 as shellescape, a7 as decrypt, a8 as writeDaemonState, A as ApiClient, a9 as writeSettings, aa as fetchCliUpdateState, ab as resolveCliUpdateCheckInterval, ac as DEFAULT_CLI_UPDATE_CHECK_INTERVAL_MS, ad as releaseDaemonLock, i as isValidSessionId, ae as listVhTerminals, af as isValidTerminalId, ag as readVhTerminal, ah as sendToVhTerminal, ai as TITLE_PROMPT_PREFIX, aj as BOARD_ANALYZER_PROMPT_PREFIX, h as connectionState, ak as startOfflineReconnection, al as clearCredentials, am as clearMachineId, m as ensurePrivateDirectorySync, an as SandboxConfigSchema, b as createEnvelope, ao as CodexAppServerClient, ap as getLatestDaemonLog } from './types-Ds0SiQ1D.mjs';
5
5
  import spawn$1, { spawn } from 'cross-spawn';
6
6
  import path, { join, resolve, basename, delimiter, isAbsolute, normalize, sep, dirname } from 'node:path';
7
7
  import { createInterface } from 'node:readline';
8
- import { existsSync, readFileSync, readdirSync, statSync, mkdirSync, unlinkSync, writeFileSync, accessSync, constants, renameSync, rmSync, chmodSync as chmodSync$1 } from 'node:fs';
8
+ import { existsSync, readFileSync, readdirSync, statSync, mkdirSync, unlinkSync, writeFileSync, accessSync, constants, renameSync, rmSync as rmSync$1, chmodSync as chmodSync$1 } from 'node:fs';
9
9
  import { t as trimIdent, A as AGENT_GUIDANCE, P as PREVIEW_TOOL_NAME, R as REPORT_PROGRESS_TOOL_NAME, a as PREVIEW_TOOL_TITLE, b as PREVIEW_TOOL_DESCRIPTION, c as REPORT_PROGRESS_TOOL_TITLE, d as REPORT_PROGRESS_TOOL_DESCRIPTION } from './agentGuidance-C2_pkgRI.mjs';
10
10
  import { readFile, writeFile, rename, unlink, mkdir, stat, open as open$1, appendFile } from 'node:fs/promises';
11
11
  import fs, { watch, access } from 'fs/promises';
@@ -20,7 +20,7 @@ import os$1, { homedir as homedir$1 } from 'os';
20
20
  import { spawn as spawn$2, execSync as execSync$1, exec } from 'child_process';
21
21
  import { createId } from '@paralleldrive/cuid2';
22
22
  import { execSync, spawnSync, spawn as spawn$3, execFile, execFileSync } from 'node:child_process';
23
- import { existsSync as existsSync$1, statSync as statSync$1, writeFileSync as writeFileSync$1, chmodSync, unlinkSync as unlinkSync$1 } from 'fs';
23
+ import { existsSync as existsSync$1, statSync as statSync$1, mkdtempSync, rmSync, writeFileSync as writeFileSync$1, chmodSync, unlinkSync as unlinkSync$1 } from 'fs';
24
24
  import { join as join$1 } from 'path';
25
25
  import '@anthropic-ai/sandbox-runtime';
26
26
  import 'expo-server-sdk';
@@ -7086,6 +7086,32 @@ function describeMachineIdentityConflict(conflict) {
7086
7086
  return `${cause} Two daemons sharing one machine id fight over the same machine row, and a copied ~/.claude/.credentials.json makes them invalidate each other's Claude login. Fix: run 'very-happy auth login --force' on this machine (it mints a fresh machine id), then log in to Claude here separately with 'claude'. (${diffs})`;
7087
7087
  }
7088
7088
 
7089
+ const VERSION_RE = /very-happy version:\s*(\d+\.\d+\.\d+[^\s]*)/i;
7090
+ function decideHandover(run) {
7091
+ if (run.spawnError) return { action: "hold", reason: `new bundle could not be started: ${run.spawnError}` };
7092
+ if (run.timedOut) return { action: "hold", reason: "new bundle did not answer --version within the timeout" };
7093
+ if (run.exitCode !== 0) return { action: "hold", reason: `new bundle exited ${run.exitCode} on --version` };
7094
+ if (!VERSION_RE.test(run.stdout)) {
7095
+ return { action: "hold", reason: "new bundle printed no recognisable version" };
7096
+ }
7097
+ return { action: "handover" };
7098
+ }
7099
+
7100
+ function decideAutoUpdate(context) {
7101
+ if (!context.enabled) return { action: "skip", reason: "auto-update disabled" };
7102
+ const target = context.recommendedVersion;
7103
+ if (!target) return { action: "skip", reason: "no recommended version published" };
7104
+ if (target === context.currentVersion) return { action: "skip", reason: "already current" };
7105
+ if (context.failedVersion === target) {
7106
+ return { action: "skip", reason: `already failed to install ${target} once` };
7107
+ }
7108
+ if (!context.idle) return { action: "skip", reason: "machine is busy" };
7109
+ return { action: "install", version: target };
7110
+ }
7111
+ function autoUpdateInstallArgs(version) {
7112
+ return ["i", "-g", "--allow-scripts=very-happy-cli,node-pty", `very-happy-cli@${version}`];
7113
+ }
7114
+
7089
7115
  const CLAUDE_KEYCHAIN_SERVICE_PREFIX = "Claude Code";
7090
7116
  function keychainIdentity(env = process.env, deps = {}) {
7091
7117
  const home = deps.home ?? homedir();
@@ -8314,8 +8340,96 @@ const initialMachineMetadata = {
8314
8340
  cliAvailability: detectCLIAvailability(),
8315
8341
  resumeSupport: { ...detectResumeSupport(), rpcAvailable: true }
8316
8342
  };
8343
+ async function preflightNewBundle(bundlePath) {
8344
+ const home = mkdtempSync(join$1(tmpdir(), "vh-preflight-"));
8345
+ try {
8346
+ return await new Promise((resolve) => {
8347
+ let stdout = "";
8348
+ let settled = false;
8349
+ const done = (run) => {
8350
+ if (settled) return;
8351
+ settled = true;
8352
+ resolve(decideHandover(run));
8353
+ };
8354
+ let child;
8355
+ try {
8356
+ child = spawn$3(process.execPath, ["--no-warnings", "--no-deprecation", bundlePath, "--version"], {
8357
+ env: { ...process.env, HAPPY_HOME_DIR: home },
8358
+ stdio: ["ignore", "pipe", "ignore"]
8359
+ });
8360
+ } catch (error) {
8361
+ done({ exitCode: null, stdout: "", timedOut: false, spawnError: String(error) });
8362
+ return;
8363
+ }
8364
+ const timer = setTimeout(() => {
8365
+ try {
8366
+ child.kill("SIGKILL");
8367
+ } catch {
8368
+ }
8369
+ done({ exitCode: null, stdout, timedOut: true });
8370
+ }, HANDOVER_PREFLIGHT_TIMEOUT_MS);
8371
+ child.stdout?.on("data", (chunk) => {
8372
+ if (stdout.length < 8192) stdout += chunk.toString("utf8");
8373
+ });
8374
+ child.on("error", (error) => {
8375
+ clearTimeout(timer);
8376
+ done({ exitCode: null, stdout, timedOut: false, spawnError: String(error) });
8377
+ });
8378
+ child.on("close", (code) => {
8379
+ clearTimeout(timer);
8380
+ done({ exitCode: code, stdout, timedOut: false });
8381
+ });
8382
+ });
8383
+ } finally {
8384
+ try {
8385
+ rmSync(home, { recursive: true, force: true });
8386
+ } catch {
8387
+ }
8388
+ }
8389
+ }
8390
+ function withHandoverHold(state, reason) {
8391
+ if (!state) return state;
8392
+ return reason ? { ...state, handoverHold: { reason, at: Date.now() } } : { ...state, handoverHold: null };
8393
+ }
8394
+ const HANDOVER_PREFLIGHT_TIMEOUT_MS = 3e4;
8395
+ function runNpmInstall(args) {
8396
+ return new Promise((resolve) => {
8397
+ let settled = false;
8398
+ const done = (code) => {
8399
+ if (!settled) {
8400
+ settled = true;
8401
+ resolve(code);
8402
+ }
8403
+ };
8404
+ let child;
8405
+ try {
8406
+ child = spawn$3("npm", args, { stdio: "ignore", env: process.env });
8407
+ } catch {
8408
+ done(null);
8409
+ return;
8410
+ }
8411
+ const timer = setTimeout(() => {
8412
+ try {
8413
+ child.kill("SIGKILL");
8414
+ } catch {
8415
+ }
8416
+ done(null);
8417
+ }, AUTO_UPDATE_INSTALL_TIMEOUT_MS);
8418
+ child.on("error", () => {
8419
+ clearTimeout(timer);
8420
+ done(null);
8421
+ });
8422
+ child.on("close", (code) => {
8423
+ clearTimeout(timer);
8424
+ done(code);
8425
+ });
8426
+ });
8427
+ }
8428
+ const AUTO_UPDATE_INSTALL_TIMEOUT_MS = 10 * 6e4;
8317
8429
  async function startDaemon() {
8318
8430
  let claudeAuthServiceRef = null;
8431
+ let cliUpdateStateRef = null;
8432
+ let lastHandoverHold = null;
8319
8433
  let claudeCredentialStoreSetting = (await readSettings()).claudeCredentialStore === "file" ? "file" : "auto";
8320
8434
  let requestShutdown;
8321
8435
  let resolvesWhenShutdownRequested = new Promise((resolve) => {
@@ -9378,6 +9492,48 @@ async function startDaemon() {
9378
9492
  host: initialMachineMetadata.host
9379
9493
  })).then(() => logger.debug(`[DAEMON RUN] claimed the machine record for host ${initialMachineMetadata.host}`)).catch((error) => logger.debug("[DAEMON RUN] could not refresh the recorded host:", error));
9380
9494
  }
9495
+ let autoUpdateFailedVersion = null;
9496
+ let autoUpdateRunning = false;
9497
+ const maybeAutoUpdate = async (cliUpdate) => {
9498
+ if (autoUpdateRunning) return;
9499
+ const settings = await readSettings();
9500
+ const decision = decideAutoUpdate({
9501
+ enabled: (settings.cliAutoUpdate ?? "idle") !== "off",
9502
+ currentVersion: cliUpdate.currentVersion,
9503
+ recommendedVersion: cliUpdate.recommendedVersion,
9504
+ idle: pidToTrackedSession.size === 0 && !apiMachine.hasLiveTerminals(),
9505
+ failedVersion: autoUpdateFailedVersion
9506
+ });
9507
+ if (decision.action === "skip") {
9508
+ logger.debug(`[DAEMON RUN] auto-update skipped: ${decision.reason}`);
9509
+ return;
9510
+ }
9511
+ autoUpdateRunning = true;
9512
+ const target = decision.version;
9513
+ const report = (state, detail) => {
9514
+ cliUpdateStateRef = { ...cliUpdate, autoUpdate: { state, version: target, detail, at: Date.now() } };
9515
+ void apiMachine.setCliUpdateState(cliUpdateStateRef);
9516
+ };
9517
+ logger.warn(`[DAEMON RUN] auto-updating CLI to ${target} (machine idle)`);
9518
+ report("installing");
9519
+ try {
9520
+ const code = await runNpmInstall(autoUpdateInstallArgs(target));
9521
+ if (code === 0) {
9522
+ logger.warn(`[DAEMON RUN] auto-update installed ${target}; handover follows once it verifies`);
9523
+ report("installed");
9524
+ } else {
9525
+ autoUpdateFailedVersion = target;
9526
+ logger.warn(`[DAEMON RUN] auto-update of ${target} failed with exit ${code}`);
9527
+ report("failed", `npm exited ${code}`);
9528
+ }
9529
+ } catch (error) {
9530
+ autoUpdateFailedVersion = target;
9531
+ logger.warn(`[DAEMON RUN] auto-update of ${target} could not run:`, error);
9532
+ report("failed", String(error).slice(0, 200));
9533
+ } finally {
9534
+ autoUpdateRunning = false;
9535
+ }
9536
+ };
9381
9537
  let cliUpdateCheckRunning = false;
9382
9538
  const refreshCliUpdate = async () => {
9383
9539
  if (cliUpdateCheckRunning) return;
@@ -9387,8 +9543,10 @@ async function startDaemon() {
9387
9543
  if (!cliUpdate) return;
9388
9544
  fileState = { ...fileState, cliUpdate };
9389
9545
  writeDaemonState(fileState);
9546
+ cliUpdateStateRef = cliUpdate;
9390
9547
  apiMachine.setCliUpdateState(cliUpdate);
9391
9548
  logger.debug(`[DAEMON RUN] CLI update policy checked: ${cliUpdate.status} (recommended=${cliUpdate.recommendedVersion ?? "none"}, minimum=${cliUpdate.minimumVersion ?? "none"})`);
9549
+ await maybeAutoUpdate(cliUpdate);
9392
9550
  } catch (error) {
9393
9551
  logger.debug("[DAEMON RUN] CLI update policy check failed:", error);
9394
9552
  } finally {
@@ -9428,11 +9586,20 @@ async function startDaemon() {
9428
9586
  }
9429
9587
  }
9430
9588
  if (bundleReplaced) {
9431
- logger.debug("[DAEMON RUN] Daemon bundle replaced on disk, handing off to new daemon");
9589
+ const preflight = await preflightNewBundle(bundlePath);
9590
+ if (preflight.action === "hold") {
9591
+ if (lastHandoverHold !== preflight.reason) {
9592
+ lastHandoverHold = preflight.reason;
9593
+ logger.warn(`[DAEMON RUN] holding handover: ${preflight.reason}`);
9594
+ void apiMachine.setCliUpdateState(withHandoverHold(cliUpdateStateRef, preflight.reason));
9595
+ }
9596
+ return;
9597
+ }
9598
+ lastHandoverHold = null;
9599
+ logger.debug("[DAEMON RUN] Daemon bundle replaced on disk and verified, handing off to new daemon");
9432
9600
  clearInterval(restartOnStaleVersionAndHeartbeat);
9433
9601
  clearInterval(cliUpdateInterval);
9434
9602
  claudeAuthService.stop();
9435
- claudeAuthService.stop();
9436
9603
  apiMachine.shutdown();
9437
9604
  await stopControlServer();
9438
9605
  await cleanupDaemonState();
@@ -10596,7 +10763,7 @@ function registerSideQuestionHandler(rpc, deps) {
10596
10763
  const retainMs = deps.retainMs ?? SIDE_QUESTION_RETAIN_MS;
10597
10764
  const maxRunMs = deps.maxRunMs ?? SIDE_QUESTION_MAX_RUN_MS;
10598
10765
  const run = deps.run ?? (async (input) => {
10599
- const { query } = await import('./index-DXJ4FLp5.mjs');
10766
+ const { query } = await import('./index-D7azxfcs.mjs');
10600
10767
  return runSideQuestion(query, input);
10601
10768
  });
10602
10769
  const slots = /* @__PURE__ */ new Map();
@@ -12034,7 +12201,7 @@ async function handleAuthLogout() {
12034
12201
  } catch {
12035
12202
  }
12036
12203
  if (existsSync(happyDir)) {
12037
- rmSync(happyDir, { recursive: true, force: true });
12204
+ rmSync$1(happyDir, { recursive: true, force: true });
12038
12205
  }
12039
12206
  console.log(chalk.green("\u2713 Successfully logged out"));
12040
12207
  console.log(chalk.gray(' Run "very-happy auth login" to authenticate again'));
@@ -12923,7 +13090,7 @@ async function handleServerCommand(args) {
12923
13090
  const bootstrapCodeFile = path.join(dataDir, "bootstrap-invite-code");
12924
13091
  if (opts.reset && existsSync(dataDir)) {
12925
13092
  console.log(chalk.yellow(`Wiping ${dataDir}...`));
12926
- rmSync(dataDir, { recursive: true, force: true });
13093
+ rmSync$1(dataDir, { recursive: true, force: true });
12927
13094
  }
12928
13095
  mkdirSync(dataDir, { recursive: true });
12929
13096
  const masterSecret = opts.masterSecret ?? loadOrCreateMasterSecret(secretFile);
@@ -15526,7 +15693,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
15526
15693
  process.exit(0);
15527
15694
  } else if (subcommand === "install-terminal-hooks") {
15528
15695
  try {
15529
- const { installTerminalHooks, parseTerminalHooksArgs, TERMINAL_HOOKS_HELP } = await import('./installTerminalHooks-BKqlOoi4.mjs');
15696
+ const { installTerminalHooks, parseTerminalHooksArgs, TERMINAL_HOOKS_HELP } = await import('./installTerminalHooks-k3TrBHD0.mjs');
15530
15697
  const command = parseTerminalHooksArgs(args.slice(1));
15531
15698
  if (command.action === "help") {
15532
15699
  console.log(TERMINAL_HOOKS_HELP);
@@ -15543,7 +15710,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
15543
15710
  }
15544
15711
  } else if (subcommand === "spawn") {
15545
15712
  try {
15546
- const { handleSpawnCommand } = await import('./spawn-Do8fUG8J.mjs');
15713
+ const { handleSpawnCommand } = await import('./spawn-CU0DMauA.mjs');
15547
15714
  await handleSpawnCommand(args.slice(1));
15548
15715
  } catch (error) {
15549
15716
  console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
@@ -15555,7 +15722,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
15555
15722
  return;
15556
15723
  } else if (subcommand === "sessions") {
15557
15724
  try {
15558
- const { handleSessionsCommand } = await import('./sessions-CpM_qzf7.mjs');
15725
+ const { handleSessionsCommand } = await import('./sessions-lvfTH_ql.mjs');
15559
15726
  await handleSessionsCommand(args.slice(1));
15560
15727
  } catch (error) {
15561
15728
  console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
@@ -15567,7 +15734,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
15567
15734
  return;
15568
15735
  } else if (subcommand === "send") {
15569
15736
  try {
15570
- const { handleSendCommand } = await import('./send-DlNrAHnH.mjs');
15737
+ const { handleSendCommand } = await import('./send-Cyo6mgMl.mjs');
15571
15738
  await handleSendCommand(args.slice(1));
15572
15739
  } catch (error) {
15573
15740
  console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
@@ -15673,9 +15840,9 @@ Conversation history is preserved on the server, but in-flight tool calls are in
15673
15840
  if (geminiSubcommand === "project" && args[2] === "set" && args[3]) {
15674
15841
  const projectId = args[3];
15675
15842
  try {
15676
- const { saveGoogleCloudProjectToConfig } = await import('./config-BYEj8cnm.mjs');
15677
- const { readCredentialsForConfiguredRelay: readCredentialsForConfiguredRelay2 } = await import('./types-C6vCFbPv.mjs').then(function (n) { return n.aq; });
15678
- const { ApiClient: ApiClient2 } = await import('./types-C6vCFbPv.mjs').then(function (n) { return n.ar; });
15843
+ const { saveGoogleCloudProjectToConfig } = await import('./config-BpR_CwZu.mjs');
15844
+ const { readCredentialsForConfiguredRelay: readCredentialsForConfiguredRelay2 } = await import('./types-Ds0SiQ1D.mjs').then(function (n) { return n.aq; });
15845
+ const { ApiClient: ApiClient2 } = await import('./types-Ds0SiQ1D.mjs').then(function (n) { return n.ar; });
15679
15846
  let userEmail = void 0;
15680
15847
  try {
15681
15848
  const credentials = await readCredentialsForConfiguredRelay2();
@@ -15706,7 +15873,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
15706
15873
  }
15707
15874
  if (geminiSubcommand === "project" && args[2] === "get") {
15708
15875
  try {
15709
- const { readGeminiLocalConfig } = await import('./config-BYEj8cnm.mjs');
15876
+ const { readGeminiLocalConfig } = await import('./config-BpR_CwZu.mjs');
15710
15877
  const config = readGeminiLocalConfig();
15711
15878
  if (config.googleCloudProject) {
15712
15879
  console.log(`Current Google Cloud Project: ${config.googleCloudProject}`);
@@ -15746,7 +15913,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
15746
15913
  process.exit(0);
15747
15914
  }
15748
15915
  try {
15749
- const { runGemini } = await import('./runGemini-Jn7L2hqR.mjs');
15916
+ const { runGemini } = await import('./runGemini-_9-a7duU.mjs');
15750
15917
  let startedBy = void 0;
15751
15918
  for (let i = 1; i < args.length; i++) {
15752
15919
  if (args[i] === "--started-by") {
@@ -15768,7 +15935,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
15768
15935
  return;
15769
15936
  } else if (subcommand === "acp") {
15770
15937
  try {
15771
- const { runAcp, resolveAcpAgentConfig } = await import('./index-B-PX710g.mjs');
15938
+ const { runAcp, resolveAcpAgentConfig } = await import('./index-C45xN8s0.mjs');
15772
15939
  let startedBy = void 0;
15773
15940
  let verbose = false;
15774
15941
  const acpArgs = [];
@@ -15808,7 +15975,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
15808
15975
  return;
15809
15976
  } else if (subcommand === "openclaw") {
15810
15977
  try {
15811
- const { runOpenClaw } = await import('./runOpenClaw-BZL1CSvh.mjs');
15978
+ const { runOpenClaw } = await import('./runOpenClaw-Boq6LQ9a.mjs');
15812
15979
  let startedBy = void 0;
15813
15980
  let verbose = false;
15814
15981
  let gatewayUrl;
@@ -15859,7 +16026,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
15859
16026
  return;
15860
16027
  } else if (subcommand === "mcp" && args.length === 1) {
15861
16028
  try {
15862
- const { handleMcpCommand } = await import('./mcp-kyB44gVF.mjs');
16029
+ const { handleMcpCommand } = await import('./mcp-DRePTOap.mjs');
15863
16030
  await handleMcpCommand();
15864
16031
  } catch (error) {
15865
16032
  process.stderr.write(`[very-happy mcp] Fatal: ${error instanceof Error ? error.message : String(error)}
@@ -1,11 +1,11 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-CQ9f70v9.cjs');
3
+ var index = require('./index-4jiUeiUz.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-D14vU6_q.cjs');
8
+ require('./types-C5kEpkcZ.cjs');
9
9
  require('axios');
10
10
  require('node:util');
11
11
  require('node:fs');
package/dist/index.cjs CHANGED
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
3
  require('chalk');
4
- require('./index-CQ9f70v9.cjs');
5
- require('./types-D14vU6_q.cjs');
4
+ require('./index-4jiUeiUz.cjs');
5
+ require('./types-C5kEpkcZ.cjs');
6
6
  require('zod');
7
7
  require('node:child_process');
8
8
  require('node:os');
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import 'chalk';
2
- import './index-DJcR5PQb.mjs';
3
- import './types-C6vCFbPv.mjs';
2
+ import './index-Dq-eFp89.mjs';
3
+ import './types-Ds0SiQ1D.mjs';
4
4
  import 'zod';
5
5
  import 'node:child_process';
6
6
  import 'node:os';
@@ -5,8 +5,8 @@ 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 persistence = require('./types-D14vU6_q.cjs');
9
- var index = require('./index-CQ9f70v9.cjs');
8
+ var persistence = require('./types-C5kEpkcZ.cjs');
9
+ var index = require('./index-4jiUeiUz.cjs');
10
10
  require('axios');
11
11
  require('node:util');
12
12
  require('node:fs/promises');
@@ -3,8 +3,8 @@ 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-C6vCFbPv.mjs';
7
- import { t as tmuxSupportsSessionEnv } from './index-DJcR5PQb.mjs';
6
+ import { p as projectPath } from './types-Ds0SiQ1D.mjs';
7
+ import { t as tmuxSupportsSessionEnv } from './index-Dq-eFp89.mjs';
8
8
  import 'axios';
9
9
  import 'node:util';
10
10
  import 'node:fs/promises';
package/dist/lib.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var persistence = require('./types-D14vU6_q.cjs');
3
+ var persistence = require('./types-C5kEpkcZ.cjs');
4
4
  require('axios');
5
5
  require('chalk');
6
6
  require('node:util');
package/dist/lib.d.cts CHANGED
@@ -336,6 +336,21 @@ declare const CliUpdateStateSchema: z$1.ZodObject<{
336
336
  required: "required";
337
337
  }>;
338
338
  checkedAt: z$1.ZodNumber;
339
+ handoverHold: z$1.ZodOptional<z$1.ZodNullable<z$1.ZodObject<{
340
+ reason: z$1.ZodString;
341
+ at: z$1.ZodNumber;
342
+ }, z$1.core.$strip>>>;
343
+ autoUpdate: z$1.ZodOptional<z$1.ZodNullable<z$1.ZodObject<{
344
+ state: z$1.ZodUnion<readonly [z$1.ZodEnum<{
345
+ installing: "installing";
346
+ installed: "installed";
347
+ failed: "failed";
348
+ skipped: "skipped";
349
+ }>, z$1.ZodString]>;
350
+ version: z$1.ZodNullable<z$1.ZodString>;
351
+ detail: z$1.ZodOptional<z$1.ZodString>;
352
+ at: z$1.ZodNumber;
353
+ }, z$1.core.$strip>>>;
339
354
  }, z$1.core.$strip>;
340
355
  type CliUpdateState = z$1.infer<typeof CliUpdateStateSchema>;
341
356
  /**
@@ -415,6 +430,21 @@ declare const DaemonStateSchema: z$1.ZodObject<{
415
430
  required: "required";
416
431
  }>;
417
432
  checkedAt: z$1.ZodNumber;
433
+ handoverHold: z$1.ZodOptional<z$1.ZodNullable<z$1.ZodObject<{
434
+ reason: z$1.ZodString;
435
+ at: z$1.ZodNumber;
436
+ }, z$1.core.$strip>>>;
437
+ autoUpdate: z$1.ZodOptional<z$1.ZodNullable<z$1.ZodObject<{
438
+ state: z$1.ZodUnion<readonly [z$1.ZodEnum<{
439
+ installing: "installing";
440
+ installed: "installed";
441
+ failed: "failed";
442
+ skipped: "skipped";
443
+ }>, z$1.ZodString]>;
444
+ version: z$1.ZodNullable<z$1.ZodString>;
445
+ detail: z$1.ZodOptional<z$1.ZodString>;
446
+ at: z$1.ZodNumber;
447
+ }, z$1.core.$strip>>>;
418
448
  }, z$1.core.$strip>>;
419
449
  claudeAuth: z$1.ZodOptional<z$1.ZodObject<{
420
450
  probeVersion: z$1.ZodNumber;
@@ -1247,6 +1277,9 @@ declare class ApiMachineClient {
1247
1277
  private reconnectInterval;
1248
1278
  private handoverInFlight;
1249
1279
  private encTerminals;
1280
+ /** B-327: an auto-update swaps the process that owns these terminals, so it
1281
+ * waits until there are none. */
1282
+ hasLiveTerminals(): boolean;
1250
1283
  private webTerminal;
1251
1284
  /**
1252
1285
  * Push text to the clipboard of every web client the user has open
package/dist/lib.d.mts CHANGED
@@ -336,6 +336,21 @@ declare const CliUpdateStateSchema: z$1.ZodObject<{
336
336
  required: "required";
337
337
  }>;
338
338
  checkedAt: z$1.ZodNumber;
339
+ handoverHold: z$1.ZodOptional<z$1.ZodNullable<z$1.ZodObject<{
340
+ reason: z$1.ZodString;
341
+ at: z$1.ZodNumber;
342
+ }, z$1.core.$strip>>>;
343
+ autoUpdate: z$1.ZodOptional<z$1.ZodNullable<z$1.ZodObject<{
344
+ state: z$1.ZodUnion<readonly [z$1.ZodEnum<{
345
+ installing: "installing";
346
+ installed: "installed";
347
+ failed: "failed";
348
+ skipped: "skipped";
349
+ }>, z$1.ZodString]>;
350
+ version: z$1.ZodNullable<z$1.ZodString>;
351
+ detail: z$1.ZodOptional<z$1.ZodString>;
352
+ at: z$1.ZodNumber;
353
+ }, z$1.core.$strip>>>;
339
354
  }, z$1.core.$strip>;
340
355
  type CliUpdateState = z$1.infer<typeof CliUpdateStateSchema>;
341
356
  /**
@@ -415,6 +430,21 @@ declare const DaemonStateSchema: z$1.ZodObject<{
415
430
  required: "required";
416
431
  }>;
417
432
  checkedAt: z$1.ZodNumber;
433
+ handoverHold: z$1.ZodOptional<z$1.ZodNullable<z$1.ZodObject<{
434
+ reason: z$1.ZodString;
435
+ at: z$1.ZodNumber;
436
+ }, z$1.core.$strip>>>;
437
+ autoUpdate: z$1.ZodOptional<z$1.ZodNullable<z$1.ZodObject<{
438
+ state: z$1.ZodUnion<readonly [z$1.ZodEnum<{
439
+ installing: "installing";
440
+ installed: "installed";
441
+ failed: "failed";
442
+ skipped: "skipped";
443
+ }>, z$1.ZodString]>;
444
+ version: z$1.ZodNullable<z$1.ZodString>;
445
+ detail: z$1.ZodOptional<z$1.ZodString>;
446
+ at: z$1.ZodNumber;
447
+ }, z$1.core.$strip>>>;
418
448
  }, z$1.core.$strip>>;
419
449
  claudeAuth: z$1.ZodOptional<z$1.ZodObject<{
420
450
  probeVersion: z$1.ZodNumber;
@@ -1247,6 +1277,9 @@ declare class ApiMachineClient {
1247
1277
  private reconnectInterval;
1248
1278
  private handoverInFlight;
1249
1279
  private encTerminals;
1280
+ /** B-327: an auto-update swaps the process that owns these terminals, so it
1281
+ * waits until there are none. */
1282
+ hasLiveTerminals(): boolean;
1250
1283
  private webTerminal;
1251
1284
  /**
1252
1285
  * Push text to the clipboard of every web client the user has open
package/dist/lib.mjs CHANGED
@@ -1,4 +1,4 @@
1
- export { A as ApiClient, a as ApiSessionClient, R as RawJSONLinesSchema, c as configuration, l as logger } from './types-C6vCFbPv.mjs';
1
+ export { A as ApiClient, a as ApiSessionClient, R as RawJSONLinesSchema, c as configuration, l as logger } from './types-Ds0SiQ1D.mjs';
2
2
  import 'axios';
3
3
  import 'chalk';
4
4
  import 'node:util';
@@ -1,9 +1,9 @@
1
1
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
2
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
3
3
  import { z } from 'zod';
4
- import { p as pushClipboardViaDaemon } from './index-DJcR5PQb.mjs';
4
+ import { p as pushClipboardViaDaemon } from './index-Dq-eFp89.mjs';
5
5
  import { C as CLIPBOARD_TOOL_NAME, a as CLIPBOARD_TOOL_TITLE, b as CLIPBOARD_TOOL_DESCRIPTION, c as CLIPBOARD_MAX_BYTES } from './limits-CwFb5S2b.mjs';
6
- import { l as logger } from './types-C6vCFbPv.mjs';
6
+ import { l as logger } from './types-Ds0SiQ1D.mjs';
7
7
  import 'chalk';
8
8
  import 'node:os';
9
9
  import 'node:crypto';
@@ -3,9 +3,9 @@
3
3
  var mcp_js = require('@modelcontextprotocol/sdk/server/mcp.js');
4
4
  var stdio_js = require('@modelcontextprotocol/sdk/server/stdio.js');
5
5
  var z = require('zod');
6
- var index = require('./index-CQ9f70v9.cjs');
6
+ var index = require('./index-4jiUeiUz.cjs');
7
7
  var limits = require('./limits-KdWKmwtH.cjs');
8
- var persistence = require('./types-D14vU6_q.cjs');
8
+ var persistence = require('./types-C5kEpkcZ.cjs');
9
9
  require('chalk');
10
10
  require('node:os');
11
11
  require('node:crypto');
@@ -4,10 +4,10 @@ var ink = require('ink');
4
4
  var React = require('react');
5
5
  var node_crypto = require('node:crypto');
6
6
  var path = require('node:path');
7
- var persistence = require('./types-D14vU6_q.cjs');
8
- var index = require('./index-CQ9f70v9.cjs');
9
- var AcpBackend = require('./AcpBackend-BYv1pHW6.cjs');
10
- var config = require('./config-B1W5KTvn.cjs');
7
+ var persistence = require('./types-C5kEpkcZ.cjs');
8
+ var index = require('./index-4jiUeiUz.cjs');
9
+ var AcpBackend = require('./AcpBackend-CauAQpC1.cjs');
10
+ var config = require('./config-BoteFn-v.cjs');
11
11
  require('axios');
12
12
  require('chalk');
13
13
  require('node:util');
@@ -2,10 +2,10 @@ import { useStdout, useInput, Box, Text, render } from 'ink';
2
2
  import React, { useState, useRef, useEffect, useCallback } from 'react';
3
3
  import { randomUUID } from 'node:crypto';
4
4
  import { join } from 'node:path';
5
- import { l as logger, h as connectionState, A as ApiClient, j as readSettings, e as errorLogMetadata, k as encodeBase64, p as projectPath, d as contentLogMetadata } from './types-C6vCFbPv.mjs';
6
- import { x as GEMINI_API_KEY_ENV, y as GOOGLE_API_KEY_ENV, G as GEMINI_MODEL_ENV, B as BasePermissionHandler, z as BaseReasoningProcessor, h as initialMachineMetadata, j as createSessionMetadata, k as setupOfflineReconnection, n as notifyDaemonSessionStarted, m as MessageQueue2, o as hashObject, C as MessageBuffer, E as CHANGE_TITLE_INSTRUCTION, v as registerKillSessionHandler, u as startHappyServer } from './index-DJcR5PQb.mjs';
7
- import { A as AcpBackend } from './AcpBackend-4DC6CDpP.mjs';
8
- import { readGeminiLocalConfig, determineGeminiModel, getGeminiModelSource, getInitialGeminiModel, saveGeminiModelToConfig } from './config-BYEj8cnm.mjs';
5
+ import { l as logger, h as connectionState, A as ApiClient, j as readSettings, e as errorLogMetadata, k as encodeBase64, p as projectPath, d as contentLogMetadata } from './types-Ds0SiQ1D.mjs';
6
+ import { x as GEMINI_API_KEY_ENV, y as GOOGLE_API_KEY_ENV, G as GEMINI_MODEL_ENV, B as BasePermissionHandler, z as BaseReasoningProcessor, h as initialMachineMetadata, j as createSessionMetadata, k as setupOfflineReconnection, n as notifyDaemonSessionStarted, m as MessageQueue2, o as hashObject, C as MessageBuffer, E as CHANGE_TITLE_INSTRUCTION, v as registerKillSessionHandler, u as startHappyServer } from './index-Dq-eFp89.mjs';
7
+ import { A as AcpBackend } from './AcpBackend-CfKPvoTU.mjs';
8
+ import { readGeminiLocalConfig, determineGeminiModel, getGeminiModelSource, getInitialGeminiModel, saveGeminiModelToConfig } from './config-BpR_CwZu.mjs';
9
9
  import 'axios';
10
10
  import 'chalk';
11
11
  import 'node:util';
@@ -5,9 +5,9 @@ var node_child_process = require('node:child_process');
5
5
  var os = require('node:os');
6
6
  var node_fs = require('node:fs');
7
7
  var path = require('node:path');
8
- var persistence = require('./types-D14vU6_q.cjs');
9
- var AcpSessionManager = require('./AcpSessionManager-BBCEuz5G.cjs');
10
- var index = require('./index-CQ9f70v9.cjs');
8
+ var persistence = require('./types-C5kEpkcZ.cjs');
9
+ var AcpSessionManager = require('./AcpSessionManager-CA6xeET_.cjs');
10
+ var index = require('./index-4jiUeiUz.cjs');
11
11
  var WebSocket = require('ws');
12
12
  var ed = require('@noble/ed25519');
13
13
  var sha2_js = require('@noble/hashes/sha2.js');
@@ -3,9 +3,9 @@ import { execFileSync } from 'node:child_process';
3
3
  import os from 'node:os';
4
4
  import { existsSync, readFileSync } from 'node:fs';
5
5
  import { join } from 'node:path';
6
- import { m as ensurePrivateDirectorySync, n as hardenPrivateFileSync, w as writePrivateFileSync, e as errorLogMetadata, d as contentLogMetadata, h as connectionState, A as ApiClient, j as readSettings, k as encodeBase64, l as logger, c as configuration } from './types-C6vCFbPv.mjs';
7
- import { A as AcpSessionManager } from './AcpSessionManager-CvDQWnwm.mjs';
8
- import { h as initialMachineMetadata, j as createSessionMetadata, k as setupOfflineReconnection, n as notifyDaemonSessionStarted, m as MessageQueue2, v as registerKillSessionHandler } from './index-DJcR5PQb.mjs';
6
+ import { m as ensurePrivateDirectorySync, n as hardenPrivateFileSync, w as writePrivateFileSync, e as errorLogMetadata, d as contentLogMetadata, h as connectionState, A as ApiClient, j as readSettings, k as encodeBase64, l as logger, c as configuration } from './types-Ds0SiQ1D.mjs';
7
+ import { A as AcpSessionManager } from './AcpSessionManager-BQ6pBRW4.mjs';
8
+ import { h as initialMachineMetadata, j as createSessionMetadata, k as setupOfflineReconnection, n as notifyDaemonSessionStarted, m as MessageQueue2, v as registerKillSessionHandler } from './index-Dq-eFp89.mjs';
9
9
  import WebSocket from 'ws';
10
10
  import * as ed from '@noble/ed25519';
11
11
  import { sha512 } from '@noble/hashes/sha2.js';
@@ -3,8 +3,8 @@
3
3
  var chalk = require('chalk');
4
4
  var node_fs = require('node:fs');
5
5
  var path = require('node:path');
6
- var persistence = require('./types-D14vU6_q.cjs');
7
- var index = require('./index-CQ9f70v9.cjs');
6
+ var persistence = require('./types-C5kEpkcZ.cjs');
7
+ var index = require('./index-4jiUeiUz.cjs');
8
8
  require('axios');
9
9
  require('node:util');
10
10
  require('node:os');