very-happy-cli 0.2.114 → 0.2.115

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-BrZN8KM-.cjs} +1 -1
  2. package/dist/{AcpBackend-4DC6CDpP.mjs → AcpBackend-DEZTWZZu.mjs} +1 -1
  3. package/dist/{AcpSessionManager-CvDQWnwm.mjs → AcpSessionManager-BzP3eiOG.mjs} +1 -1
  4. package/dist/{AcpSessionManager-BBCEuz5G.cjs → AcpSessionManager-DjulpKY0.cjs} +1 -1
  5. package/dist/{config-B1W5KTvn.cjs → config-BNAsx9Wg.cjs} +2 -2
  6. package/dist/{config-BYEj8cnm.mjs → config-CMgRBQMS.mjs} +2 -2
  7. package/dist/{index-DXJ4FLp5.mjs → index-B2KfhNku.mjs} +2 -2
  8. package/dist/{index-CiNMkjGe.cjs → index-B3UkbonP.cjs} +2 -2
  9. package/dist/{index-DJcR5PQb.mjs → index-BHNEb4bc.mjs} +96 -21
  10. package/dist/{index-BtFBYvj8.cjs → index-ClR0jhjm.cjs} +4 -4
  11. package/dist/{index-B-PX710g.mjs → index-CpGR7rIw.mjs} +5 -5
  12. package/dist/{index-CQ9f70v9.cjs → index-tPXwlc_t.cjs} +95 -20
  13. package/dist/index.cjs +2 -2
  14. package/dist/index.mjs +2 -2
  15. package/dist/{installTerminalHooks-CvWutFrA.cjs → installTerminalHooks-CWfCF68p.cjs} +2 -2
  16. package/dist/{installTerminalHooks-BKqlOoi4.mjs → installTerminalHooks-DD6QuHfT.mjs} +2 -2
  17. package/dist/lib.cjs +1 -1
  18. package/dist/lib.d.cts +8 -0
  19. package/dist/lib.d.mts +8 -0
  20. package/dist/lib.mjs +1 -1
  21. package/dist/{mcp-kyB44gVF.mjs → mcp-CiNrjYox.mjs} +2 -2
  22. package/dist/{mcp-KhfiJ6OC.cjs → mcp-CqjiDRnG.cjs} +2 -2
  23. package/dist/{runGemini-Jn7L2hqR.mjs → runGemini-DdJqpywr.mjs} +4 -4
  24. package/dist/{runGemini-DYN1hVth.cjs → runGemini-UN5IznJp.cjs} +4 -4
  25. package/dist/{runOpenClaw-DHqzKgke.cjs → runOpenClaw-9hhfGllZ.cjs} +3 -3
  26. package/dist/{runOpenClaw-BZL1CSvh.mjs → runOpenClaw-CM5UrVBy.mjs} +3 -3
  27. package/dist/{send-DlNrAHnH.mjs → send-C6G2jsQp.mjs} +2 -2
  28. package/dist/{send-m-ZqzS6w.cjs → send-CnVtXOj0.cjs} +2 -2
  29. package/dist/{sessions-Qbk_H0Av.cjs → sessions-CGdcF05T.cjs} +2 -2
  30. package/dist/{sessions-CpM_qzf7.mjs → sessions-CmabJzYS.mjs} +2 -2
  31. package/dist/{spawn-D09KFk0I.cjs → spawn-CfYddkS_.cjs} +2 -2
  32. package/dist/{spawn-Do8fUG8J.mjs → spawn-qb344Y5E.mjs} +2 -2
  33. package/dist/{types-C6vCFbPv.mjs → types-B3qx8Ga1.mjs} +14 -8
  34. package/dist/{types-D14vU6_q.cjs → types-CpnzfHHS.cjs} +15 -9
  35. package/package.json +7 -7
@@ -3,7 +3,7 @@
3
3
  var node_child_process = require('node:child_process');
4
4
  var sdk = require('@agentclientprotocol/sdk');
5
5
  var node_crypto = require('node:crypto');
6
- var persistence = require('./types-D14vU6_q.cjs');
6
+ var persistence = require('./types-CpnzfHHS.cjs');
7
7
 
8
8
  const DEFAULT_TIMEOUTS = {
9
9
  /** Default initialization timeout: 60 seconds */
@@ -1,7 +1,7 @@
1
1
  import { spawn } from 'node:child_process';
2
2
  import { ndJsonStream, ClientSideConnection } from '@agentclientprotocol/sdk';
3
3
  import { randomUUID } from 'node:crypto';
4
- import { l as logger, d as contentLogMetadata, e as errorLogMetadata, f as packageJson, g as delay } from './types-C6vCFbPv.mjs';
4
+ import { l as logger, d as contentLogMetadata, e as errorLogMetadata, f as packageJson, g as delay } from './types-B3qx8Ga1.mjs';
5
5
 
6
6
  const DEFAULT_TIMEOUTS = {
7
7
  /** Default initialization timeout: 60 seconds */
@@ -1,5 +1,5 @@
1
1
  import { createId } from '@paralleldrive/cuid2';
2
- import { b as createEnvelope } from './types-C6vCFbPv.mjs';
2
+ import { b as createEnvelope } from './types-B3qx8Ga1.mjs';
3
3
 
4
4
  function turnOptions(turnId, time) {
5
5
  return turnId ? { turn: turnId, time } : { time };
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var cuid2 = require('@paralleldrive/cuid2');
4
- var persistence = require('./types-D14vU6_q.cjs');
4
+ var persistence = require('./types-CpnzfHHS.cjs');
5
5
 
6
6
  function turnOptions(turnId, time) {
7
7
  return turnId ? { turn: turnId, time } : { time };
@@ -4,8 +4,8 @@ var fs = require('fs');
4
4
  var path = require('path');
5
5
  var os = require('os');
6
6
  var child_process = require('child_process');
7
- var persistence = require('./types-D14vU6_q.cjs');
8
- var index = require('./index-CQ9f70v9.cjs');
7
+ var persistence = require('./types-CpnzfHHS.cjs');
8
+ var index = require('./index-tPXwlc_t.cjs');
9
9
  require('axios');
10
10
  require('chalk');
11
11
  require('node:util');
@@ -2,8 +2,8 @@ import { existsSync, readFileSync, mkdirSync, writeFileSync } from 'fs';
2
2
  import { join } from 'path';
3
3
  import { homedir } from 'os';
4
4
  import { execSync } from 'child_process';
5
- import { l as logger } from './types-C6vCFbPv.mjs';
6
- import { g as DEFAULT_GEMINI_MODEL, G as GEMINI_MODEL_ENV } from './index-DJcR5PQb.mjs';
5
+ import { l as logger } from './types-B3qx8Ga1.mjs';
6
+ import { g as DEFAULT_GEMINI_MODEL, G as GEMINI_MODEL_ENV } from './index-BHNEb4bc.mjs';
7
7
  import 'axios';
8
8
  import 'chalk';
9
9
  import 'node:util';
@@ -1,9 +1,9 @@
1
- import { q as query } from './index-DJcR5PQb.mjs';
1
+ import { q as query } from './index-BHNEb4bc.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-C6vCFbPv.mjs';
6
+ import './types-B3qx8Ga1.mjs';
7
7
  import 'axios';
8
8
  import 'node:util';
9
9
  import 'node:fs';
@@ -1,11 +1,11 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-CQ9f70v9.cjs');
3
+ var index = require('./index-tPXwlc_t.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-CpnzfHHS.cjs');
9
9
  require('axios');
10
10
  require('node:util');
11
11
  require('node:fs');
@@ -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-B3qx8Ga1.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,17 @@ 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
+
7089
7100
  const CLAUDE_KEYCHAIN_SERVICE_PREFIX = "Claude Code";
7090
7101
  function keychainIdentity(env = process.env, deps = {}) {
7091
7102
  const home = deps.home ?? homedir();
@@ -8314,8 +8325,62 @@ const initialMachineMetadata = {
8314
8325
  cliAvailability: detectCLIAvailability(),
8315
8326
  resumeSupport: { ...detectResumeSupport(), rpcAvailable: true }
8316
8327
  };
8328
+ async function preflightNewBundle(bundlePath) {
8329
+ const home = mkdtempSync(join$1(tmpdir(), "vh-preflight-"));
8330
+ try {
8331
+ return await new Promise((resolve) => {
8332
+ let stdout = "";
8333
+ let settled = false;
8334
+ const done = (run) => {
8335
+ if (settled) return;
8336
+ settled = true;
8337
+ resolve(decideHandover(run));
8338
+ };
8339
+ let child;
8340
+ try {
8341
+ child = spawn$3(process.execPath, ["--no-warnings", "--no-deprecation", bundlePath, "--version"], {
8342
+ env: { ...process.env, HAPPY_HOME_DIR: home },
8343
+ stdio: ["ignore", "pipe", "ignore"]
8344
+ });
8345
+ } catch (error) {
8346
+ done({ exitCode: null, stdout: "", timedOut: false, spawnError: String(error) });
8347
+ return;
8348
+ }
8349
+ const timer = setTimeout(() => {
8350
+ try {
8351
+ child.kill("SIGKILL");
8352
+ } catch {
8353
+ }
8354
+ done({ exitCode: null, stdout, timedOut: true });
8355
+ }, HANDOVER_PREFLIGHT_TIMEOUT_MS);
8356
+ child.stdout?.on("data", (chunk) => {
8357
+ if (stdout.length < 8192) stdout += chunk.toString("utf8");
8358
+ });
8359
+ child.on("error", (error) => {
8360
+ clearTimeout(timer);
8361
+ done({ exitCode: null, stdout, timedOut: false, spawnError: String(error) });
8362
+ });
8363
+ child.on("close", (code) => {
8364
+ clearTimeout(timer);
8365
+ done({ exitCode: code, stdout, timedOut: false });
8366
+ });
8367
+ });
8368
+ } finally {
8369
+ try {
8370
+ rmSync(home, { recursive: true, force: true });
8371
+ } catch {
8372
+ }
8373
+ }
8374
+ }
8375
+ function withHandoverHold(state, reason) {
8376
+ if (!state) return state;
8377
+ return reason ? { ...state, handoverHold: { reason, at: Date.now() } } : { ...state, handoverHold: null };
8378
+ }
8379
+ const HANDOVER_PREFLIGHT_TIMEOUT_MS = 3e4;
8317
8380
  async function startDaemon() {
8318
8381
  let claudeAuthServiceRef = null;
8382
+ let cliUpdateStateRef = null;
8383
+ let lastHandoverHold = null;
8319
8384
  let claudeCredentialStoreSetting = (await readSettings()).claudeCredentialStore === "file" ? "file" : "auto";
8320
8385
  let requestShutdown;
8321
8386
  let resolvesWhenShutdownRequested = new Promise((resolve) => {
@@ -9387,6 +9452,7 @@ async function startDaemon() {
9387
9452
  if (!cliUpdate) return;
9388
9453
  fileState = { ...fileState, cliUpdate };
9389
9454
  writeDaemonState(fileState);
9455
+ cliUpdateStateRef = cliUpdate;
9390
9456
  apiMachine.setCliUpdateState(cliUpdate);
9391
9457
  logger.debug(`[DAEMON RUN] CLI update policy checked: ${cliUpdate.status} (recommended=${cliUpdate.recommendedVersion ?? "none"}, minimum=${cliUpdate.minimumVersion ?? "none"})`);
9392
9458
  } catch (error) {
@@ -9428,11 +9494,20 @@ async function startDaemon() {
9428
9494
  }
9429
9495
  }
9430
9496
  if (bundleReplaced) {
9431
- logger.debug("[DAEMON RUN] Daemon bundle replaced on disk, handing off to new daemon");
9497
+ const preflight = await preflightNewBundle(bundlePath);
9498
+ if (preflight.action === "hold") {
9499
+ if (lastHandoverHold !== preflight.reason) {
9500
+ lastHandoverHold = preflight.reason;
9501
+ logger.warn(`[DAEMON RUN] holding handover: ${preflight.reason}`);
9502
+ void apiMachine.setCliUpdateState(withHandoverHold(cliUpdateStateRef, preflight.reason));
9503
+ }
9504
+ return;
9505
+ }
9506
+ lastHandoverHold = null;
9507
+ logger.debug("[DAEMON RUN] Daemon bundle replaced on disk and verified, handing off to new daemon");
9432
9508
  clearInterval(restartOnStaleVersionAndHeartbeat);
9433
9509
  clearInterval(cliUpdateInterval);
9434
9510
  claudeAuthService.stop();
9435
- claudeAuthService.stop();
9436
9511
  apiMachine.shutdown();
9437
9512
  await stopControlServer();
9438
9513
  await cleanupDaemonState();
@@ -10596,7 +10671,7 @@ function registerSideQuestionHandler(rpc, deps) {
10596
10671
  const retainMs = deps.retainMs ?? SIDE_QUESTION_RETAIN_MS;
10597
10672
  const maxRunMs = deps.maxRunMs ?? SIDE_QUESTION_MAX_RUN_MS;
10598
10673
  const run = deps.run ?? (async (input) => {
10599
- const { query } = await import('./index-DXJ4FLp5.mjs');
10674
+ const { query } = await import('./index-B2KfhNku.mjs');
10600
10675
  return runSideQuestion(query, input);
10601
10676
  });
10602
10677
  const slots = /* @__PURE__ */ new Map();
@@ -12034,7 +12109,7 @@ async function handleAuthLogout() {
12034
12109
  } catch {
12035
12110
  }
12036
12111
  if (existsSync(happyDir)) {
12037
- rmSync(happyDir, { recursive: true, force: true });
12112
+ rmSync$1(happyDir, { recursive: true, force: true });
12038
12113
  }
12039
12114
  console.log(chalk.green("\u2713 Successfully logged out"));
12040
12115
  console.log(chalk.gray(' Run "very-happy auth login" to authenticate again'));
@@ -12923,7 +12998,7 @@ async function handleServerCommand(args) {
12923
12998
  const bootstrapCodeFile = path.join(dataDir, "bootstrap-invite-code");
12924
12999
  if (opts.reset && existsSync(dataDir)) {
12925
13000
  console.log(chalk.yellow(`Wiping ${dataDir}...`));
12926
- rmSync(dataDir, { recursive: true, force: true });
13001
+ rmSync$1(dataDir, { recursive: true, force: true });
12927
13002
  }
12928
13003
  mkdirSync(dataDir, { recursive: true });
12929
13004
  const masterSecret = opts.masterSecret ?? loadOrCreateMasterSecret(secretFile);
@@ -15526,7 +15601,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
15526
15601
  process.exit(0);
15527
15602
  } else if (subcommand === "install-terminal-hooks") {
15528
15603
  try {
15529
- const { installTerminalHooks, parseTerminalHooksArgs, TERMINAL_HOOKS_HELP } = await import('./installTerminalHooks-BKqlOoi4.mjs');
15604
+ const { installTerminalHooks, parseTerminalHooksArgs, TERMINAL_HOOKS_HELP } = await import('./installTerminalHooks-DD6QuHfT.mjs');
15530
15605
  const command = parseTerminalHooksArgs(args.slice(1));
15531
15606
  if (command.action === "help") {
15532
15607
  console.log(TERMINAL_HOOKS_HELP);
@@ -15543,7 +15618,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
15543
15618
  }
15544
15619
  } else if (subcommand === "spawn") {
15545
15620
  try {
15546
- const { handleSpawnCommand } = await import('./spawn-Do8fUG8J.mjs');
15621
+ const { handleSpawnCommand } = await import('./spawn-qb344Y5E.mjs');
15547
15622
  await handleSpawnCommand(args.slice(1));
15548
15623
  } catch (error) {
15549
15624
  console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
@@ -15555,7 +15630,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
15555
15630
  return;
15556
15631
  } else if (subcommand === "sessions") {
15557
15632
  try {
15558
- const { handleSessionsCommand } = await import('./sessions-CpM_qzf7.mjs');
15633
+ const { handleSessionsCommand } = await import('./sessions-CmabJzYS.mjs');
15559
15634
  await handleSessionsCommand(args.slice(1));
15560
15635
  } catch (error) {
15561
15636
  console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
@@ -15567,7 +15642,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
15567
15642
  return;
15568
15643
  } else if (subcommand === "send") {
15569
15644
  try {
15570
- const { handleSendCommand } = await import('./send-DlNrAHnH.mjs');
15645
+ const { handleSendCommand } = await import('./send-C6G2jsQp.mjs');
15571
15646
  await handleSendCommand(args.slice(1));
15572
15647
  } catch (error) {
15573
15648
  console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
@@ -15673,9 +15748,9 @@ Conversation history is preserved on the server, but in-flight tool calls are in
15673
15748
  if (geminiSubcommand === "project" && args[2] === "set" && args[3]) {
15674
15749
  const projectId = args[3];
15675
15750
  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; });
15751
+ const { saveGoogleCloudProjectToConfig } = await import('./config-CMgRBQMS.mjs');
15752
+ const { readCredentialsForConfiguredRelay: readCredentialsForConfiguredRelay2 } = await import('./types-B3qx8Ga1.mjs').then(function (n) { return n.aq; });
15753
+ const { ApiClient: ApiClient2 } = await import('./types-B3qx8Ga1.mjs').then(function (n) { return n.ar; });
15679
15754
  let userEmail = void 0;
15680
15755
  try {
15681
15756
  const credentials = await readCredentialsForConfiguredRelay2();
@@ -15706,7 +15781,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
15706
15781
  }
15707
15782
  if (geminiSubcommand === "project" && args[2] === "get") {
15708
15783
  try {
15709
- const { readGeminiLocalConfig } = await import('./config-BYEj8cnm.mjs');
15784
+ const { readGeminiLocalConfig } = await import('./config-CMgRBQMS.mjs');
15710
15785
  const config = readGeminiLocalConfig();
15711
15786
  if (config.googleCloudProject) {
15712
15787
  console.log(`Current Google Cloud Project: ${config.googleCloudProject}`);
@@ -15746,7 +15821,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
15746
15821
  process.exit(0);
15747
15822
  }
15748
15823
  try {
15749
- const { runGemini } = await import('./runGemini-Jn7L2hqR.mjs');
15824
+ const { runGemini } = await import('./runGemini-DdJqpywr.mjs');
15750
15825
  let startedBy = void 0;
15751
15826
  for (let i = 1; i < args.length; i++) {
15752
15827
  if (args[i] === "--started-by") {
@@ -15768,7 +15843,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
15768
15843
  return;
15769
15844
  } else if (subcommand === "acp") {
15770
15845
  try {
15771
- const { runAcp, resolveAcpAgentConfig } = await import('./index-B-PX710g.mjs');
15846
+ const { runAcp, resolveAcpAgentConfig } = await import('./index-CpGR7rIw.mjs');
15772
15847
  let startedBy = void 0;
15773
15848
  let verbose = false;
15774
15849
  const acpArgs = [];
@@ -15808,7 +15883,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
15808
15883
  return;
15809
15884
  } else if (subcommand === "openclaw") {
15810
15885
  try {
15811
- const { runOpenClaw } = await import('./runOpenClaw-BZL1CSvh.mjs');
15886
+ const { runOpenClaw } = await import('./runOpenClaw-CM5UrVBy.mjs');
15812
15887
  let startedBy = void 0;
15813
15888
  let verbose = false;
15814
15889
  let gatewayUrl;
@@ -15859,7 +15934,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
15859
15934
  return;
15860
15935
  } else if (subcommand === "mcp" && args.length === 1) {
15861
15936
  try {
15862
- const { handleMcpCommand } = await import('./mcp-kyB44gVF.mjs');
15937
+ const { handleMcpCommand } = await import('./mcp-CiNrjYox.mjs');
15863
15938
  await handleMcpCommand();
15864
15939
  } catch (error) {
15865
15940
  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 AcpBackend = require('./AcpBackend-BYv1pHW6.cjs');
4
- var persistence = require('./types-D14vU6_q.cjs');
5
- var AcpSessionManager = require('./AcpSessionManager-BBCEuz5G.cjs');
3
+ var AcpBackend = require('./AcpBackend-BrZN8KM-.cjs');
4
+ var persistence = require('./types-CpnzfHHS.cjs');
5
+ var AcpSessionManager = require('./AcpSessionManager-DjulpKY0.cjs');
6
6
  var node_crypto = require('node:crypto');
7
7
  var path = require('node:path');
8
- var index = require('./index-CQ9f70v9.cjs');
8
+ var index = require('./index-tPXwlc_t.cjs');
9
9
  require('node:child_process');
10
10
  require('@agentclientprotocol/sdk');
11
11
  require('axios');
@@ -1,10 +1,10 @@
1
- import { D as DefaultTransport, A as AcpBackend } from './AcpBackend-4DC6CDpP.mjs';
2
- export { a as DEFAULT_IDLE_TIMEOUT_MS, b as DEFAULT_TOOL_CALL_TIMEOUT_MS, e as extractErrorDetail, f as formatDuration, c as formatDurationMinutes, h as handleAgentMessageChunk, d as handleAgentThoughtChunk, g as handleLegacyMessageChunk, i as handlePlanUpdate, j as handleThinkingUpdate, k as handleToolCall, l as handleToolCallUpdate, p as parseArgsFromContent } from './AcpBackend-4DC6CDpP.mjs';
3
- import { h as connectionState, A as ApiClient, j as readSettings, k as encodeBase64, l as logger, p as projectPath } from './types-C6vCFbPv.mjs';
4
- import { A as AcpSessionManager } from './AcpSessionManager-CvDQWnwm.mjs';
1
+ import { D as DefaultTransport, A as AcpBackend } from './AcpBackend-DEZTWZZu.mjs';
2
+ export { a as DEFAULT_IDLE_TIMEOUT_MS, b as DEFAULT_TOOL_CALL_TIMEOUT_MS, e as extractErrorDetail, f as formatDuration, c as formatDurationMinutes, h as handleAgentMessageChunk, d as handleAgentThoughtChunk, g as handleLegacyMessageChunk, i as handlePlanUpdate, j as handleThinkingUpdate, k as handleToolCall, l as handleToolCallUpdate, p as parseArgsFromContent } from './AcpBackend-DEZTWZZu.mjs';
3
+ import { h as connectionState, A as ApiClient, j as readSettings, k as encodeBase64, l as logger, p as projectPath } from './types-B3qx8Ga1.mjs';
4
+ import { A as AcpSessionManager } from './AcpSessionManager-BzP3eiOG.mjs';
5
5
  import { randomUUID } from 'node:crypto';
6
6
  import { join } from 'node:path';
7
- import { h as initialMachineMetadata, j as createSessionMetadata, k as setupOfflineReconnection, n as notifyDaemonSessionStarted, m as MessageQueue2, o as hashObject, u as startHappyServer, v as registerKillSessionHandler, B as BasePermissionHandler } from './index-DJcR5PQb.mjs';
7
+ import { h as initialMachineMetadata, j as createSessionMetadata, k as setupOfflineReconnection, n as notifyDaemonSessionStarted, m as MessageQueue2, o as hashObject, u as startHappyServer, v as registerKillSessionHandler, B as BasePermissionHandler } from './index-BHNEb4bc.mjs';
8
8
  import 'node:child_process';
9
9
  import '@agentclientprotocol/sdk';
10
10
  import 'axios';
@@ -3,7 +3,7 @@
3
3
  var chalk = require('chalk');
4
4
  var os = require('node:os');
5
5
  var node_crypto = require('node:crypto');
6
- var persistence = require('./types-D14vU6_q.cjs');
6
+ var persistence = require('./types-CpnzfHHS.cjs');
7
7
  var spawn = require('cross-spawn');
8
8
  var path = require('node:path');
9
9
  var node_readline = require('node:readline');
@@ -7108,6 +7108,17 @@ function describeMachineIdentityConflict(conflict) {
7108
7108
  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})`;
7109
7109
  }
7110
7110
 
7111
+ const VERSION_RE = /very-happy version:\s*(\d+\.\d+\.\d+[^\s]*)/i;
7112
+ function decideHandover(run) {
7113
+ if (run.spawnError) return { action: "hold", reason: `new bundle could not be started: ${run.spawnError}` };
7114
+ if (run.timedOut) return { action: "hold", reason: "new bundle did not answer --version within the timeout" };
7115
+ if (run.exitCode !== 0) return { action: "hold", reason: `new bundle exited ${run.exitCode} on --version` };
7116
+ if (!VERSION_RE.test(run.stdout)) {
7117
+ return { action: "hold", reason: "new bundle printed no recognisable version" };
7118
+ }
7119
+ return { action: "handover" };
7120
+ }
7121
+
7111
7122
  const CLAUDE_KEYCHAIN_SERVICE_PREFIX = "Claude Code";
7112
7123
  function keychainIdentity(env = process.env, deps = {}) {
7113
7124
  const home = deps.home ?? os.homedir();
@@ -7171,7 +7182,7 @@ function parseJsonObject(text) {
7171
7182
  return null;
7172
7183
  }
7173
7184
  }
7174
- function resolveSdkClaudeBinary(platform = process.platform, arch = process.arch, resolver = (s) => node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-CQ9f70v9.cjs', document.baseURI).href))).resolve(s)) {
7185
+ function resolveSdkClaudeBinary(platform = process.platform, arch = process.arch, resolver = (s) => node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-tPXwlc_t.cjs', document.baseURI).href))).resolve(s)) {
7175
7186
  const platformArch = `${platform}-${arch}`;
7176
7187
  const candidates = [
7177
7188
  `@anthropic-ai/claude-agent-sdk-${platformArch}/claude`,
@@ -8336,8 +8347,62 @@ const initialMachineMetadata = {
8336
8347
  cliAvailability: persistence.detectCLIAvailability(),
8337
8348
  resumeSupport: { ...persistence.detectResumeSupport(), rpcAvailable: true }
8338
8349
  };
8350
+ async function preflightNewBundle(bundlePath) {
8351
+ const home = fs$1.mkdtempSync(path$1.join(os.tmpdir(), "vh-preflight-"));
8352
+ try {
8353
+ return await new Promise((resolve) => {
8354
+ let stdout = "";
8355
+ let settled = false;
8356
+ const done = (run) => {
8357
+ if (settled) return;
8358
+ settled = true;
8359
+ resolve(decideHandover(run));
8360
+ };
8361
+ let child;
8362
+ try {
8363
+ child = node_child_process.spawn(process.execPath, ["--no-warnings", "--no-deprecation", bundlePath, "--version"], {
8364
+ env: { ...process.env, HAPPY_HOME_DIR: home },
8365
+ stdio: ["ignore", "pipe", "ignore"]
8366
+ });
8367
+ } catch (error) {
8368
+ done({ exitCode: null, stdout: "", timedOut: false, spawnError: String(error) });
8369
+ return;
8370
+ }
8371
+ const timer = setTimeout(() => {
8372
+ try {
8373
+ child.kill("SIGKILL");
8374
+ } catch {
8375
+ }
8376
+ done({ exitCode: null, stdout, timedOut: true });
8377
+ }, HANDOVER_PREFLIGHT_TIMEOUT_MS);
8378
+ child.stdout?.on("data", (chunk) => {
8379
+ if (stdout.length < 8192) stdout += chunk.toString("utf8");
8380
+ });
8381
+ child.on("error", (error) => {
8382
+ clearTimeout(timer);
8383
+ done({ exitCode: null, stdout, timedOut: false, spawnError: String(error) });
8384
+ });
8385
+ child.on("close", (code) => {
8386
+ clearTimeout(timer);
8387
+ done({ exitCode: code, stdout, timedOut: false });
8388
+ });
8389
+ });
8390
+ } finally {
8391
+ try {
8392
+ fs$1.rmSync(home, { recursive: true, force: true });
8393
+ } catch {
8394
+ }
8395
+ }
8396
+ }
8397
+ function withHandoverHold(state, reason) {
8398
+ if (!state) return state;
8399
+ return reason ? { ...state, handoverHold: { reason, at: Date.now() } } : { ...state, handoverHold: null };
8400
+ }
8401
+ const HANDOVER_PREFLIGHT_TIMEOUT_MS = 3e4;
8339
8402
  async function startDaemon() {
8340
8403
  let claudeAuthServiceRef = null;
8404
+ let cliUpdateStateRef = null;
8405
+ let lastHandoverHold = null;
8341
8406
  let claudeCredentialStoreSetting = (await persistence.readSettings()).claudeCredentialStore === "file" ? "file" : "auto";
8342
8407
  let requestShutdown;
8343
8408
  let resolvesWhenShutdownRequested = new Promise((resolve) => {
@@ -9409,6 +9474,7 @@ async function startDaemon() {
9409
9474
  if (!cliUpdate) return;
9410
9475
  fileState = { ...fileState, cliUpdate };
9411
9476
  persistence.writeDaemonState(fileState);
9477
+ cliUpdateStateRef = cliUpdate;
9412
9478
  apiMachine.setCliUpdateState(cliUpdate);
9413
9479
  persistence.logger.debug(`[DAEMON RUN] CLI update policy checked: ${cliUpdate.status} (recommended=${cliUpdate.recommendedVersion ?? "none"}, minimum=${cliUpdate.minimumVersion ?? "none"})`);
9414
9480
  } catch (error) {
@@ -9450,11 +9516,20 @@ async function startDaemon() {
9450
9516
  }
9451
9517
  }
9452
9518
  if (bundleReplaced) {
9453
- persistence.logger.debug("[DAEMON RUN] Daemon bundle replaced on disk, handing off to new daemon");
9519
+ const preflight = await preflightNewBundle(bundlePath);
9520
+ if (preflight.action === "hold") {
9521
+ if (lastHandoverHold !== preflight.reason) {
9522
+ lastHandoverHold = preflight.reason;
9523
+ persistence.logger.warn(`[DAEMON RUN] holding handover: ${preflight.reason}`);
9524
+ void apiMachine.setCliUpdateState(withHandoverHold(cliUpdateStateRef, preflight.reason));
9525
+ }
9526
+ return;
9527
+ }
9528
+ lastHandoverHold = null;
9529
+ persistence.logger.debug("[DAEMON RUN] Daemon bundle replaced on disk and verified, handing off to new daemon");
9454
9530
  clearInterval(restartOnStaleVersionAndHeartbeat);
9455
9531
  clearInterval(cliUpdateInterval);
9456
9532
  claudeAuthService.stop();
9457
- claudeAuthService.stop();
9458
9533
  apiMachine.shutdown();
9459
9534
  await stopControlServer();
9460
9535
  await cleanupDaemonState();
@@ -10618,7 +10693,7 @@ function registerSideQuestionHandler(rpc, deps) {
10618
10693
  const retainMs = deps.retainMs ?? SIDE_QUESTION_RETAIN_MS;
10619
10694
  const maxRunMs = deps.maxRunMs ?? SIDE_QUESTION_MAX_RUN_MS;
10620
10695
  const run = deps.run ?? (async (input) => {
10621
- const { query } = await Promise.resolve().then(function () { return require('./index-CiNMkjGe.cjs'); });
10696
+ const { query } = await Promise.resolve().then(function () { return require('./index-B3UkbonP.cjs'); });
10622
10697
  return runSideQuestion(query, input);
10623
10698
  });
10624
10699
  const slots = /* @__PURE__ */ new Map();
@@ -10720,7 +10795,7 @@ const MAX_TITLE_CHARS = 60;
10720
10795
  const GENERATION_TIMEOUT_MS = 3e4;
10721
10796
  function resolveClaudeBinary() {
10722
10797
  try {
10723
- const require$1 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-CQ9f70v9.cjs', document.baseURI).href)));
10798
+ const require$1 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-tPXwlc_t.cjs', document.baseURI).href)));
10724
10799
  const utilsPath = path.resolve(path.join(persistence.projectPath(), "scripts", "claude_version_utils.cjs"));
10725
10800
  const { getClaudeCliPath } = require$1(utilsPath);
10726
10801
  const path$1 = getClaudeCliPath();
@@ -12922,9 +12997,9 @@ function resolveLocalSignupBootstrap(configuredMode, configuredInviteCodes, gene
12922
12997
  };
12923
12998
  }
12924
12999
 
12925
- const __filename$1 = node_url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-CQ9f70v9.cjs', document.baseURI).href)));
13000
+ const __filename$1 = node_url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-tPXwlc_t.cjs', document.baseURI).href)));
12926
13001
  const __dirname$1 = path.dirname(__filename$1);
12927
- const require_ = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-CQ9f70v9.cjs', document.baseURI).href)));
13002
+ const require_ = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-tPXwlc_t.cjs', document.baseURI).href)));
12928
13003
  const PRISMA_QUERY_ENGINE_FILES = {
12929
13004
  "arm64-darwin": "libquery_engine-darwin-arm64.dylib.node",
12930
13005
  "x64-darwin": "libquery_engine-darwin.dylib.node",
@@ -15548,7 +15623,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
15548
15623
  process.exit(0);
15549
15624
  } else if (subcommand === "install-terminal-hooks") {
15550
15625
  try {
15551
- const { installTerminalHooks, parseTerminalHooksArgs, TERMINAL_HOOKS_HELP } = await Promise.resolve().then(function () { return require('./installTerminalHooks-CvWutFrA.cjs'); });
15626
+ const { installTerminalHooks, parseTerminalHooksArgs, TERMINAL_HOOKS_HELP } = await Promise.resolve().then(function () { return require('./installTerminalHooks-CWfCF68p.cjs'); });
15552
15627
  const command = parseTerminalHooksArgs(args.slice(1));
15553
15628
  if (command.action === "help") {
15554
15629
  console.log(TERMINAL_HOOKS_HELP);
@@ -15565,7 +15640,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
15565
15640
  }
15566
15641
  } else if (subcommand === "spawn") {
15567
15642
  try {
15568
- const { handleSpawnCommand } = await Promise.resolve().then(function () { return require('./spawn-D09KFk0I.cjs'); });
15643
+ const { handleSpawnCommand } = await Promise.resolve().then(function () { return require('./spawn-CfYddkS_.cjs'); });
15569
15644
  await handleSpawnCommand(args.slice(1));
15570
15645
  } catch (error) {
15571
15646
  console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
@@ -15577,7 +15652,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
15577
15652
  return;
15578
15653
  } else if (subcommand === "sessions") {
15579
15654
  try {
15580
- const { handleSessionsCommand } = await Promise.resolve().then(function () { return require('./sessions-Qbk_H0Av.cjs'); });
15655
+ const { handleSessionsCommand } = await Promise.resolve().then(function () { return require('./sessions-CGdcF05T.cjs'); });
15581
15656
  await handleSessionsCommand(args.slice(1));
15582
15657
  } catch (error) {
15583
15658
  console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
@@ -15589,7 +15664,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
15589
15664
  return;
15590
15665
  } else if (subcommand === "send") {
15591
15666
  try {
15592
- const { handleSendCommand } = await Promise.resolve().then(function () { return require('./send-m-ZqzS6w.cjs'); });
15667
+ const { handleSendCommand } = await Promise.resolve().then(function () { return require('./send-CnVtXOj0.cjs'); });
15593
15668
  await handleSendCommand(args.slice(1));
15594
15669
  } catch (error) {
15595
15670
  console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
@@ -15695,9 +15770,9 @@ Conversation history is preserved on the server, but in-flight tool calls are in
15695
15770
  if (geminiSubcommand === "project" && args[2] === "set" && args[3]) {
15696
15771
  const projectId = args[3];
15697
15772
  try {
15698
- const { saveGoogleCloudProjectToConfig } = await Promise.resolve().then(function () { return require('./config-B1W5KTvn.cjs'); });
15699
- const { readCredentialsForConfiguredRelay: readCredentialsForConfiguredRelay2 } = await Promise.resolve().then(function () { return require('./types-D14vU6_q.cjs'); }).then(function (n) { return n.persistence; });
15700
- const { ApiClient: ApiClient2 } = await Promise.resolve().then(function () { return require('./types-D14vU6_q.cjs'); }).then(function (n) { return n.api; });
15773
+ const { saveGoogleCloudProjectToConfig } = await Promise.resolve().then(function () { return require('./config-BNAsx9Wg.cjs'); });
15774
+ const { readCredentialsForConfiguredRelay: readCredentialsForConfiguredRelay2 } = await Promise.resolve().then(function () { return require('./types-CpnzfHHS.cjs'); }).then(function (n) { return n.persistence; });
15775
+ const { ApiClient: ApiClient2 } = await Promise.resolve().then(function () { return require('./types-CpnzfHHS.cjs'); }).then(function (n) { return n.api; });
15701
15776
  let userEmail = void 0;
15702
15777
  try {
15703
15778
  const credentials = await readCredentialsForConfiguredRelay2();
@@ -15728,7 +15803,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
15728
15803
  }
15729
15804
  if (geminiSubcommand === "project" && args[2] === "get") {
15730
15805
  try {
15731
- const { readGeminiLocalConfig } = await Promise.resolve().then(function () { return require('./config-B1W5KTvn.cjs'); });
15806
+ const { readGeminiLocalConfig } = await Promise.resolve().then(function () { return require('./config-BNAsx9Wg.cjs'); });
15732
15807
  const config = readGeminiLocalConfig();
15733
15808
  if (config.googleCloudProject) {
15734
15809
  console.log(`Current Google Cloud Project: ${config.googleCloudProject}`);
@@ -15768,7 +15843,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
15768
15843
  process.exit(0);
15769
15844
  }
15770
15845
  try {
15771
- const { runGemini } = await Promise.resolve().then(function () { return require('./runGemini-DYN1hVth.cjs'); });
15846
+ const { runGemini } = await Promise.resolve().then(function () { return require('./runGemini-UN5IznJp.cjs'); });
15772
15847
  let startedBy = void 0;
15773
15848
  for (let i = 1; i < args.length; i++) {
15774
15849
  if (args[i] === "--started-by") {
@@ -15790,7 +15865,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
15790
15865
  return;
15791
15866
  } else if (subcommand === "acp") {
15792
15867
  try {
15793
- const { runAcp, resolveAcpAgentConfig } = await Promise.resolve().then(function () { return require('./index-BtFBYvj8.cjs'); });
15868
+ const { runAcp, resolveAcpAgentConfig } = await Promise.resolve().then(function () { return require('./index-ClR0jhjm.cjs'); });
15794
15869
  let startedBy = void 0;
15795
15870
  let verbose = false;
15796
15871
  const acpArgs = [];
@@ -15830,7 +15905,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
15830
15905
  return;
15831
15906
  } else if (subcommand === "openclaw") {
15832
15907
  try {
15833
- const { runOpenClaw } = await Promise.resolve().then(function () { return require('./runOpenClaw-DHqzKgke.cjs'); });
15908
+ const { runOpenClaw } = await Promise.resolve().then(function () { return require('./runOpenClaw-9hhfGllZ.cjs'); });
15834
15909
  let startedBy = void 0;
15835
15910
  let verbose = false;
15836
15911
  let gatewayUrl;
@@ -15881,7 +15956,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
15881
15956
  return;
15882
15957
  } else if (subcommand === "mcp" && args.length === 1) {
15883
15958
  try {
15884
- const { handleMcpCommand } = await Promise.resolve().then(function () { return require('./mcp-KhfiJ6OC.cjs'); });
15959
+ const { handleMcpCommand } = await Promise.resolve().then(function () { return require('./mcp-CqjiDRnG.cjs'); });
15885
15960
  await handleMcpCommand();
15886
15961
  } catch (error) {
15887
15962
  process.stderr.write(`[very-happy mcp] Fatal: ${error instanceof Error ? error.message : String(error)}
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-tPXwlc_t.cjs');
5
+ require('./types-CpnzfHHS.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-BHNEb4bc.mjs';
3
+ import './types-B3qx8Ga1.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-CpnzfHHS.cjs');
9
+ var index = require('./index-tPXwlc_t.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-B3qx8Ga1.mjs';
7
+ import { t as tmuxSupportsSessionEnv } from './index-BHNEb4bc.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-CpnzfHHS.cjs');
4
4
  require('axios');
5
5
  require('chalk');
6
6
  require('node:util');
package/dist/lib.d.cts CHANGED
@@ -336,6 +336,10 @@ 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>>>;
339
343
  }, z$1.core.$strip>;
340
344
  type CliUpdateState = z$1.infer<typeof CliUpdateStateSchema>;
341
345
  /**
@@ -415,6 +419,10 @@ declare const DaemonStateSchema: z$1.ZodObject<{
415
419
  required: "required";
416
420
  }>;
417
421
  checkedAt: z$1.ZodNumber;
422
+ handoverHold: z$1.ZodOptional<z$1.ZodNullable<z$1.ZodObject<{
423
+ reason: z$1.ZodString;
424
+ at: z$1.ZodNumber;
425
+ }, z$1.core.$strip>>>;
418
426
  }, z$1.core.$strip>>;
419
427
  claudeAuth: z$1.ZodOptional<z$1.ZodObject<{
420
428
  probeVersion: z$1.ZodNumber;
package/dist/lib.d.mts CHANGED
@@ -336,6 +336,10 @@ 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>>>;
339
343
  }, z$1.core.$strip>;
340
344
  type CliUpdateState = z$1.infer<typeof CliUpdateStateSchema>;
341
345
  /**
@@ -415,6 +419,10 @@ declare const DaemonStateSchema: z$1.ZodObject<{
415
419
  required: "required";
416
420
  }>;
417
421
  checkedAt: z$1.ZodNumber;
422
+ handoverHold: z$1.ZodOptional<z$1.ZodNullable<z$1.ZodObject<{
423
+ reason: z$1.ZodString;
424
+ at: z$1.ZodNumber;
425
+ }, z$1.core.$strip>>>;
418
426
  }, z$1.core.$strip>>;
419
427
  claudeAuth: z$1.ZodOptional<z$1.ZodObject<{
420
428
  probeVersion: z$1.ZodNumber;
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-B3qx8Ga1.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-BHNEb4bc.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-B3qx8Ga1.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-tPXwlc_t.cjs');
7
7
  var limits = require('./limits-KdWKmwtH.cjs');
8
- var persistence = require('./types-D14vU6_q.cjs');
8
+ var persistence = require('./types-CpnzfHHS.cjs');
9
9
  require('chalk');
10
10
  require('node:os');
11
11
  require('node:crypto');
@@ -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-B3qx8Ga1.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-BHNEb4bc.mjs';
7
+ import { A as AcpBackend } from './AcpBackend-DEZTWZZu.mjs';
8
+ import { readGeminiLocalConfig, determineGeminiModel, getGeminiModelSource, getInitialGeminiModel, saveGeminiModelToConfig } from './config-CMgRBQMS.mjs';
9
9
  import 'axios';
10
10
  import 'chalk';
11
11
  import 'node:util';
@@ -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-CpnzfHHS.cjs');
8
+ var index = require('./index-tPXwlc_t.cjs');
9
+ var AcpBackend = require('./AcpBackend-BrZN8KM-.cjs');
10
+ var config = require('./config-BNAsx9Wg.cjs');
11
11
  require('axios');
12
12
  require('chalk');
13
13
  require('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-CpnzfHHS.cjs');
9
+ var AcpSessionManager = require('./AcpSessionManager-DjulpKY0.cjs');
10
+ var index = require('./index-tPXwlc_t.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-B3qx8Ga1.mjs';
7
+ import { A as AcpSessionManager } from './AcpSessionManager-BzP3eiOG.mjs';
8
+ import { h as initialMachineMetadata, j as createSessionMetadata, k as setupOfflineReconnection, n as notifyDaemonSessionStarted, m as MessageQueue2, v as registerKillSessionHandler } from './index-BHNEb4bc.mjs';
9
9
  import WebSocket from 'ws';
10
10
  import * as ed from '@noble/ed25519';
11
11
  import { sha512 } from '@noble/hashes/sha2.js';
@@ -1,8 +1,8 @@
1
1
  import chalk from 'chalk';
2
2
  import { readFileSync } from 'node:fs';
3
3
  import { resolve } from 'node:path';
4
- import { r as readPersistedSessions, c as configuration } from './types-C6vCFbPv.mjs';
5
- import { d as sendUserMessage, a as sessionWebUrl } from './index-DJcR5PQb.mjs';
4
+ import { r as readPersistedSessions, c as configuration } from './types-B3qx8Ga1.mjs';
5
+ import { d as sendUserMessage, a as sessionWebUrl } from './index-BHNEb4bc.mjs';
6
6
  import 'axios';
7
7
  import 'node:util';
8
8
  import 'node:os';
@@ -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-CpnzfHHS.cjs');
7
+ var index = require('./index-tPXwlc_t.cjs');
8
8
  require('axios');
9
9
  require('node:util');
10
10
  require('node:os');
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
3
  var chalk = require('chalk');
4
- var index = require('./index-CQ9f70v9.cjs');
5
- var persistence = require('./types-D14vU6_q.cjs');
4
+ var index = require('./index-tPXwlc_t.cjs');
5
+ var persistence = require('./types-CpnzfHHS.cjs');
6
6
  require('node:os');
7
7
  require('node:crypto');
8
8
  require('cross-spawn');
@@ -1,6 +1,6 @@
1
1
  import chalk from 'chalk';
2
- import { D as DEFAULT_RECENT_LIMIT, M as MAX_READ_LIMIT, l as listSessions, r as readSessionTranscript, e as stopSession, f as archiveSession } from './index-DJcR5PQb.mjs';
3
- import { i as isValidSessionId } from './types-C6vCFbPv.mjs';
2
+ import { D as DEFAULT_RECENT_LIMIT, M as MAX_READ_LIMIT, l as listSessions, r as readSessionTranscript, e as stopSession, f as archiveSession } from './index-BHNEb4bc.mjs';
3
+ import { i as isValidSessionId } from './types-B3qx8Ga1.mjs';
4
4
  import 'node:os';
5
5
  import 'node:crypto';
6
6
  import 'cross-spawn';
@@ -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 index = require('./index-CQ9f70v9.cjs');
7
- var persistence = require('./types-D14vU6_q.cjs');
6
+ var index = require('./index-tPXwlc_t.cjs');
7
+ var persistence = require('./types-CpnzfHHS.cjs');
8
8
  require('node:os');
9
9
  require('node:crypto');
10
10
  require('cross-spawn');
@@ -1,8 +1,8 @@
1
1
  import chalk from 'chalk';
2
2
  import { readFileSync, statSync } from 'node:fs';
3
3
  import { resolve } from 'node:path';
4
- import { c as checkIfDaemonRunningAndCleanupStaleState, s as spawnDaemonSession, a as sessionWebUrl, i as isValidSpawnOrigin, b as sanitizeSpawnPermissionMode, A as ALLOWED_SPAWN_PERMISSION_MODES, w as waitForSessionKey, d as sendUserMessage } from './index-DJcR5PQb.mjs';
5
- import { l as logger } from './types-C6vCFbPv.mjs';
4
+ import { c as checkIfDaemonRunningAndCleanupStaleState, s as spawnDaemonSession, a as sessionWebUrl, i as isValidSpawnOrigin, b as sanitizeSpawnPermissionMode, A as ALLOWED_SPAWN_PERMISSION_MODES, w as waitForSessionKey, d as sendUserMessage } from './index-BHNEb4bc.mjs';
5
+ import { l as logger } from './types-B3qx8Ga1.mjs';
6
6
  import 'node:os';
7
7
  import 'node:crypto';
8
8
  import 'cross-spawn';
@@ -29,7 +29,7 @@ import { SandboxManager } from '@anthropic-ai/sandbox-runtime';
29
29
  import { Expo } from 'expo-server-sdk';
30
30
 
31
31
  var name = "very-happy-cli";
32
- var version = "0.2.114";
32
+ var version = "0.2.115";
33
33
  var description = "Remote multi-agent workspace CLI with deep Claude integration, native terminal streaming, and self-hosting.";
34
34
  var author = "Kirill Dubovitskiy";
35
35
  var contributors = [
@@ -142,12 +142,12 @@ var dependencies = {
142
142
  zod: "^4.0.0"
143
143
  };
144
144
  var optionalDependencies = {
145
- "very-happy-tools-arm64-darwin": "0.2.114",
146
- "very-happy-tools-x64-darwin": "0.2.114",
147
- "very-happy-tools-arm64-linux": "0.2.114",
148
- "very-happy-tools-x64-linux": "0.2.114",
149
- "very-happy-tools-arm64-win32": "0.2.114",
150
- "very-happy-tools-x64-win32": "0.2.114"
145
+ "very-happy-tools-arm64-darwin": "0.2.115",
146
+ "very-happy-tools-x64-darwin": "0.2.115",
147
+ "very-happy-tools-arm64-linux": "0.2.115",
148
+ "very-happy-tools-x64-linux": "0.2.115",
149
+ "very-happy-tools-arm64-win32": "0.2.115",
150
+ "very-happy-tools-x64-win32": "0.2.115"
151
151
  };
152
152
  var devDependencies = {
153
153
  "@slopus/happy-wire": "workspace:*",
@@ -1048,7 +1048,13 @@ const CliUpdateStateSchema = z$1.object({
1048
1048
  recommendedVersion: z$1.string().nullable(),
1049
1049
  minimumVersion: z$1.string().nullable(),
1050
1050
  status: z$1.enum(["current", "available", "required"]),
1051
- checkedAt: z$1.number()
1051
+ checkedAt: z$1.number(),
1052
+ /**
1053
+ * B-321: a new bundle is on disk but refused to run, so the daemon is still
1054
+ * serving the old code. Present only while that is true. Optional and additive:
1055
+ * old web builds ignore it, old daemons never send it (iron rule 4).
1056
+ */
1057
+ handoverHold: z$1.object({ reason: z$1.string(), at: z$1.number() }).nullable().optional()
1052
1058
  });
1053
1059
  const WebTerminalListItemSchema = z$1.object({
1054
1060
  id: z$1.string(),
@@ -51,7 +51,7 @@ var z__namespace = /*#__PURE__*/_interopNamespaceDefault(z);
51
51
  var pty__namespace = /*#__PURE__*/_interopNamespaceDefault(pty);
52
52
 
53
53
  var name = "very-happy-cli";
54
- var version = "0.2.114";
54
+ var version = "0.2.115";
55
55
  var description = "Remote multi-agent workspace CLI with deep Claude integration, native terminal streaming, and self-hosting.";
56
56
  var author = "Kirill Dubovitskiy";
57
57
  var contributors = [
@@ -164,12 +164,12 @@ var dependencies = {
164
164
  zod: "^4.0.0"
165
165
  };
166
166
  var optionalDependencies = {
167
- "very-happy-tools-arm64-darwin": "0.2.114",
168
- "very-happy-tools-x64-darwin": "0.2.114",
169
- "very-happy-tools-arm64-linux": "0.2.114",
170
- "very-happy-tools-x64-linux": "0.2.114",
171
- "very-happy-tools-arm64-win32": "0.2.114",
172
- "very-happy-tools-x64-win32": "0.2.114"
167
+ "very-happy-tools-arm64-darwin": "0.2.115",
168
+ "very-happy-tools-x64-darwin": "0.2.115",
169
+ "very-happy-tools-arm64-linux": "0.2.115",
170
+ "very-happy-tools-x64-linux": "0.2.115",
171
+ "very-happy-tools-arm64-win32": "0.2.115",
172
+ "very-happy-tools-x64-win32": "0.2.115"
173
173
  };
174
174
  var devDependencies = {
175
175
  "@slopus/happy-wire": "workspace:*",
@@ -1070,7 +1070,13 @@ const CliUpdateStateSchema = z.z.object({
1070
1070
  recommendedVersion: z.z.string().nullable(),
1071
1071
  minimumVersion: z.z.string().nullable(),
1072
1072
  status: z.z.enum(["current", "available", "required"]),
1073
- checkedAt: z.z.number()
1073
+ checkedAt: z.z.number(),
1074
+ /**
1075
+ * B-321: a new bundle is on disk but refused to run, so the daemon is still
1076
+ * serving the old code. Present only while that is true. Optional and additive:
1077
+ * old web builds ignore it, old daemons never send it (iron rule 4).
1078
+ */
1079
+ handoverHold: z.z.object({ reason: z.z.string(), at: z.z.number() }).nullable().optional()
1074
1080
  });
1075
1081
  const WebTerminalListItemSchema = z.z.object({
1076
1082
  id: z.z.string(),
@@ -1667,7 +1673,7 @@ class RpcHandlerManager {
1667
1673
  }
1668
1674
  }
1669
1675
 
1670
- const __dirname$1 = path$1.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('types-D14vU6_q.cjs', document.baseURI).href))));
1676
+ const __dirname$1 = path$1.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('types-CpnzfHHS.cjs', document.baseURI).href))));
1671
1677
  function projectPath() {
1672
1678
  const path = path$1.resolve(__dirname$1, "..");
1673
1679
  return path;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "very-happy-cli",
3
- "version": "0.2.114",
3
+ "version": "0.2.115",
4
4
  "description": "Remote multi-agent workspace CLI with deep Claude integration, native terminal streaming, and self-hosting.",
5
5
  "author": "Kirill Dubovitskiy",
6
6
  "contributors": [
@@ -113,12 +113,12 @@
113
113
  "zod": "^4.0.0"
114
114
  },
115
115
  "optionalDependencies": {
116
- "very-happy-tools-arm64-darwin": "0.2.114",
117
- "very-happy-tools-x64-darwin": "0.2.114",
118
- "very-happy-tools-arm64-linux": "0.2.114",
119
- "very-happy-tools-x64-linux": "0.2.114",
120
- "very-happy-tools-arm64-win32": "0.2.114",
121
- "very-happy-tools-x64-win32": "0.2.114"
116
+ "very-happy-tools-arm64-darwin": "0.2.115",
117
+ "very-happy-tools-x64-darwin": "0.2.115",
118
+ "very-happy-tools-arm64-linux": "0.2.115",
119
+ "very-happy-tools-x64-linux": "0.2.115",
120
+ "very-happy-tools-arm64-win32": "0.2.115",
121
+ "very-happy-tools-x64-win32": "0.2.115"
122
122
  },
123
123
  "devDependencies": {
124
124
  "@slopus/happy-wire": "workspace:*",