very-happy-cli 0.2.143 → 0.2.145

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 (49) hide show
  1. package/dist/{AcpBackend-LEgn9vol.mjs → AcpBackend-BITeBnbV.mjs} +2 -2
  2. package/dist/{AcpBackend-B8oehrfU.cjs → AcpBackend-FPv5uXFa.cjs} +30 -30
  3. package/dist/{AcpSessionManager-BomdfyhZ.cjs → AcpSessionManager-vqLzM219.cjs} +9 -9
  4. package/dist/{AcpSessionManager-Yfbs5bi2.mjs → AcpSessionManager-w2srpWQJ.mjs} +1 -1
  5. package/dist/{agentGuidance-CJSl54ua.cjs → agentGuidance-Bd6GEiYp.cjs} +1 -1
  6. package/dist/{agentGuidance-BU4hxm8M.mjs → agentGuidance-HFHrz3C1.mjs} +1 -1
  7. package/dist/agentHome-CGl7FF7a.cjs +113 -0
  8. package/dist/agentHome-DBqr8rpv.mjs +107 -0
  9. package/dist/codex/happyMcpStdioBridge.cjs +2 -2
  10. package/dist/codex/happyMcpStdioBridge.mjs +2 -2
  11. package/dist/{config-euZ_K5Lo.mjs → config-B9zAvnGT.mjs} +4 -4
  12. package/dist/{config-CfqWoHmO.cjs → config-CPfFuHP6.cjs} +4 -4
  13. package/dist/{index-ZOMC8Gzn.mjs → index-BzLZu_aF.mjs} +8 -8
  14. package/dist/{index-PM_SsRpw.mjs → index-CxK0l_t0.mjs} +4 -4
  15. package/dist/{index-BREtikhm.cjs → index-D4Smqppj.cjs} +4 -4
  16. package/dist/{index-C510dSUn.cjs → index-DhwtFJEe.cjs} +309 -212
  17. package/dist/{index-Bj68y6ee.cjs → index-avfJgX4p.cjs} +31 -31
  18. package/dist/{index-DoiG88oX.mjs → index-eBrE-0R1.mjs} +136 -39
  19. package/dist/index.cjs +4 -4
  20. package/dist/index.mjs +4 -4
  21. package/dist/{installTerminalHooks-BGVQqbgq.mjs → installTerminalHooks-Dq1MFFDQ.mjs} +4 -4
  22. package/dist/{installTerminalHooks-C_jraM1j.cjs → installTerminalHooks-DspFGxBI.cjs} +4 -4
  23. package/dist/lib.cjs +5 -5
  24. package/dist/lib.mjs +2 -2
  25. package/dist/{limits-uABU-yq3.mjs → limits-CzWD9hWU.mjs} +8 -8
  26. package/dist/{limits-B3oVgqBJ.cjs → limits-DGZB-OVl.cjs} +7 -7
  27. package/dist/{mcp-G-3lL_KH.cjs → mcp-BioGrTC_.cjs} +9 -9
  28. package/dist/{mcp-CfbTQXyh.mjs → mcp-L1Yq25LB.mjs} +4 -4
  29. package/dist/{piRuntime-CWE-1W-y.cjs → piRuntime-DodWS0UI.cjs} +2 -2
  30. package/dist/{piRuntime-BE6iYQwU.mjs → piRuntime-UdVG4eJ7.mjs} +2 -2
  31. package/dist/{piTerminal-Dyc_9pGP.cjs → piTerminal-6P00O_w8.cjs} +6 -6
  32. package/dist/{piTerminal-rqKn1_Zy.mjs → piTerminal-BIRroC_N.mjs} +6 -6
  33. package/dist/{runGemini-BMlXIaTL.mjs → runGemini-B-It6K8t.mjs} +6 -6
  34. package/dist/{runGemini-C6qMFzcn.cjs → runGemini-ChCHjnIh.cjs} +24 -24
  35. package/dist/{runOpenClaw-C2_aCP7v.cjs → runOpenClaw-Cc4_zmHz.cjs} +26 -26
  36. package/dist/{runOpenClaw-CoO5Vp3S.mjs → runOpenClaw-DET6LY2v.mjs} +5 -5
  37. package/dist/{send-CBrJylJc.mjs → send-CPayvXBm.mjs} +4 -4
  38. package/dist/{send-DGVwmB-p.cjs → send-LBjLfAos.cjs} +4 -4
  39. package/dist/{sessions-DbLubh2N.mjs → sessions-CJUEp43_.mjs} +4 -4
  40. package/dist/{sessions-DyQXMN-8.cjs → sessions-WBowxNO-.cjs} +5 -5
  41. package/dist/{spawn-DIyFOn3W.cjs → spawn-BqgZc7YE.cjs} +6 -6
  42. package/dist/{spawn-wkkxEGdF.mjs → spawn-Dcetf5Jt.mjs} +4 -4
  43. package/dist/{teams-BTyVFK3P.mjs → teams-CW_Zb2Q1.mjs} +4 -4
  44. package/dist/{teams-QOkGFjkJ.cjs → teams-eIUxGmqg.cjs} +4 -4
  45. package/dist/{todo-DoLkqdBe.mjs → todo-CV5fwHg_.mjs} +3 -3
  46. package/dist/{todo-Du6pjwx_.cjs → todo-DeouLiGa.cjs} +5 -5
  47. package/dist/{types-BG4gFjLL.mjs → types-BbvxVQF3.mjs} +321 -11
  48. package/dist/{types-6__wqmmP.cjs → types-Bqo68u61.cjs} +328 -9
  49. package/package.json +7 -7
@@ -3,14 +3,14 @@
3
3
  var chalk = require('chalk');
4
4
  var os = require('node:os');
5
5
  var node_crypto = require('node:crypto');
6
- var api = require('./types-6__wqmmP.cjs');
7
- var persistence = require('./limits-B3oVgqBJ.cjs');
6
+ var index = require('./types-Bqo68u61.cjs');
7
+ var persistence = require('./limits-DGZB-OVl.cjs');
8
8
  var spawn = require('cross-spawn');
9
9
  var path = require('node:path');
10
10
  var node_readline = require('node:readline');
11
11
  var node_fs = require('node:fs');
12
12
  var projectPath = require('./projectPath-ChLhdOyt.cjs');
13
- var agentGuidance = require('./agentGuidance-CJSl54ua.cjs');
13
+ var agentGuidance = require('./agentGuidance-Bd6GEiYp.cjs');
14
14
  var promises = require('node:fs/promises');
15
15
  var fs = require('fs/promises');
16
16
  var ink = require('ink');
@@ -288,7 +288,7 @@ class Session {
288
288
  reportEventToDaemon = (event) => {
289
289
  const spawnedBy = process.env.HAPPY_SPAWNED_BY;
290
290
  if (!spawnedBy) return;
291
- void api.notifyDaemonSessionEvent(this.client.sessionId, event, spawnedBy).catch((error) => persistence.logger.debug("[Session] Failed to report session event to daemon:", error));
291
+ void index.notifyDaemonSessionEvent(this.client.sessionId, event, spawnedBy).catch((error) => persistence.logger.debug("[Session] Failed to report session event to daemon:", error));
292
292
  };
293
293
  /** Produce an `error` notification for an unexpected session failure. */
294
294
  onSessionError = (message) => {
@@ -398,7 +398,7 @@ function pinSmallFastModel(env) {
398
398
  }
399
399
 
400
400
  function claudeCheckSession(sessionId, path$1) {
401
- const projectDir = api.getProjectPath(path$1);
401
+ const projectDir = index.getProjectPath(path$1);
402
402
  const sessionFile = path.join(projectDir, `${sessionId}.jsonl`);
403
403
  const sessionExists = node_fs.existsSync(sessionFile);
404
404
  if (!sessionExists) {
@@ -424,7 +424,7 @@ function claudeCheckSession(sessionId, path$1) {
424
424
 
425
425
  function claudeFindLastSession(workingDirectory) {
426
426
  try {
427
- const projectDir = api.getProjectPath(workingDirectory);
427
+ const projectDir = index.getProjectPath(workingDirectory);
428
428
  const uuidPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
429
429
  const files = node_fs.readdirSync(projectDir).filter((f) => f.endsWith(".jsonl")).map((f) => {
430
430
  const sessionId = f.replace(".jsonl", "");
@@ -478,7 +478,7 @@ function shouldIncludeCoAuthoredBy() {
478
478
 
479
479
  const BASE_SYSTEM_PROMPT = (() => agentGuidance.trimIdent(`
480
480
  ALWAYS when you start a new chat - you must call a tool "mcp__happy__change_title" to set a chat title. When you think chat title is not relevant anymore - call the tool again to change it. When chat name is too generic and you have a change to make it more specific - call the tool again to change it. This title is needed to easily find the chat in the future. Help human.
481
- `))() + "\n\n" + agentGuidance.AGENT_GUIDANCE + "\n\n" + api.BUILTIN_TODO_DISCOVERY;
481
+ `))() + "\n\n" + agentGuidance.AGENT_GUIDANCE + "\n\n" + index.BUILTIN_TODO_DISCOVERY;
482
482
  const CO_AUTHORED_CREDITS = (() => agentGuidance.trimIdent(`
483
483
  When making commit messages, instead of just giving co-credit to Claude, also give credit to Happy like so:
484
484
 
@@ -511,7 +511,7 @@ function quoteShellArg(value) {
511
511
  return `'${value.replace(/'/g, `'\\''`)}'`;
512
512
  }
513
513
  async function claudeLocal(opts) {
514
- const projectDir = api.getProjectPath(opts.path);
514
+ const projectDir = index.getProjectPath(opts.path);
515
515
  node_fs.mkdirSync(projectDir, { recursive: true });
516
516
  const hasContinueFlag = opts.claudeArgs?.includes("--continue");
517
517
  const hasResumeFlag = opts.claudeArgs?.includes("--resume");
@@ -667,7 +667,7 @@ async function claudeLocal(opts) {
667
667
  persistence.logger.warn("[ClaudeLocal] Sandbox is not supported on Windows; continuing without sandbox.");
668
668
  } else {
669
669
  try {
670
- cleanupSandbox = await api.initializeSandbox(opts.sandboxConfig, opts.path);
670
+ cleanupSandbox = await index.initializeSandbox(opts.sandboxConfig, opts.path);
671
671
  if (!spawnArgs.includes("--dangerously-skip-permissions")) {
672
672
  spawnArgs = [...spawnArgs, "--dangerously-skip-permissions"];
673
673
  }
@@ -675,7 +675,7 @@ async function claudeLocal(opts) {
675
675
  "node",
676
676
  ...spawnArgs.map((arg) => quoteShellArg(arg))
677
677
  ].join(" ");
678
- spawnCommand = await api.wrapCommand(fullCommand);
678
+ spawnCommand = await index.wrapCommand(fullCommand);
679
679
  spawnWithShell = true;
680
680
  persistence.logger.info(
681
681
  `[ClaudeLocal] Sandbox enabled: workspace=${opts.sandboxConfig.workspaceRoot ?? opts.path}, network=${opts.sandboxConfig.networkMode}`
@@ -738,7 +738,7 @@ async function claudeLocal(opts) {
738
738
  persistence.logger.debug(`[ClaudeLocal] Unknown message type: ${message.type}`);
739
739
  }
740
740
  } catch (e) {
741
- persistence.logger.debug("[ClaudeLocal] Non-JSON line from fd3:", api.contentLogMetadata(line));
741
+ persistence.logger.debug("[ClaudeLocal] Non-JSON line from fd3:", index.contentLogMetadata(line));
742
742
  }
743
743
  });
744
744
  rl.on("error", (err) => {
@@ -876,7 +876,7 @@ const INTERNAL_CLAUDE_EVENT_TYPES$1 = /* @__PURE__ */ new Set([
876
876
  "queue-operation"
877
877
  ]);
878
878
  async function createSessionScanner(opts) {
879
- const projectDir = api.getProjectPath(opts.workingDirectory);
879
+ const projectDir = index.getProjectPath(opts.workingDirectory);
880
880
  let finishedSessions = /* @__PURE__ */ new Set();
881
881
  let pendingSessions = /* @__PURE__ */ new Set();
882
882
  let currentSessionId = null;
@@ -891,7 +891,7 @@ async function createSessionScanner(opts) {
891
891
  }
892
892
  currentSessionId = opts.sessionId;
893
893
  }
894
- const sync = new api.InvalidateSync(async () => {
894
+ const sync = new index.InvalidateSync(async () => {
895
895
  let sessions = [];
896
896
  for (let p of pendingSessions) {
897
897
  if (!deadSessions.has(p)) {
@@ -1033,7 +1033,7 @@ async function readSessionLog(projectDir, sessionId) {
1033
1033
  if (message.type && INTERNAL_CLAUDE_EVENT_TYPES$1.has(message.type)) {
1034
1034
  continue;
1035
1035
  }
1036
- let parsed = api.RawJSONLinesSchema.safeParse(message);
1036
+ let parsed = index.RawJSONLinesSchema.safeParse(message);
1037
1037
  if (!parsed.success) {
1038
1038
  continue;
1039
1039
  }
@@ -1912,7 +1912,7 @@ async function awaitFileExist(file, timeout = 1e4) {
1912
1912
  await fs.access(file);
1913
1913
  return true;
1914
1914
  } catch (e) {
1915
- await api.delay(1e3);
1915
+ await index.delay(1e3);
1916
1916
  }
1917
1917
  }
1918
1918
  return false;
@@ -2107,7 +2107,7 @@ async function claudeRemote(opts) {
2107
2107
  }
2108
2108
  continue;
2109
2109
  }
2110
- persistence.logger.debug(`[claudeRemote] Message ${message.type}`, api.contentLogMetadata(message));
2110
+ persistence.logger.debug(`[claudeRemote] Message ${message.type}`, index.contentLogMetadata(message));
2111
2111
  if (message.type === "assistant" && message.error) {
2112
2112
  lastAssistantError = message.error;
2113
2113
  }
@@ -2147,7 +2147,7 @@ async function claudeRemote(opts) {
2147
2147
  }
2148
2148
  if (systemInit.session_id) {
2149
2149
  persistence.logger.debug(`[claudeRemote] Waiting for session file to be written to disk: ${systemInit.session_id}`);
2150
- const projectDir = api.getProjectPath(opts.path);
2150
+ const projectDir = index.getProjectPath(opts.path);
2151
2151
  const found = await awaitFileExist(path.join(projectDir, `${systemInit.session_id}.jsonl`), 3e4);
2152
2152
  persistence.logger.debug(`[claudeRemote] Session file found: ${systemInit.session_id} ${found}`);
2153
2153
  if (!found) {
@@ -2378,9 +2378,9 @@ class PermissionHandler {
2378
2378
  persistence.logger.debug("Plan mode result received", {
2379
2379
  approved: response.approved,
2380
2380
  mode: response.mode,
2381
- reason: api.contentLogMetadata(response.reason),
2381
+ reason: index.contentLogMetadata(response.reason),
2382
2382
  allowToolCount: response.allowTools?.length ?? 0,
2383
- updatedInput: api.contentLogMetadata(response.updatedInput)
2383
+ updatedInput: index.contentLogMetadata(response.updatedInput)
2384
2384
  });
2385
2385
  if (response.approved) {
2386
2386
  const newMode = response.mode && ["default", "acceptEdits", "bypassPermissions"].includes(response.mode) ? response.mode : "bypassPermissions";
@@ -2704,9 +2704,9 @@ class PermissionHandler {
2704
2704
  id: message.id,
2705
2705
  approved: message.approved,
2706
2706
  mode: message.mode,
2707
- reason: api.contentLogMetadata(message.reason),
2707
+ reason: index.contentLogMetadata(message.reason),
2708
2708
  allowToolCount: message.allowTools?.length ?? 0,
2709
- updatedInput: api.contentLogMetadata(message.updatedInput)
2709
+ updatedInput: index.contentLogMetadata(message.updatedInput)
2710
2710
  });
2711
2711
  const id = message.id;
2712
2712
  const pending = this.pendingRequests.get(id);
@@ -3191,7 +3191,7 @@ class OutgoingMessageQueue {
3191
3191
  }
3192
3192
  queue = [];
3193
3193
  nextId = 1;
3194
- lock = new api.AsyncLock();
3194
+ lock = new index.AsyncLock();
3195
3195
  processTimer;
3196
3196
  delayTimers = /* @__PURE__ */ new Map();
3197
3197
  /**
@@ -3483,7 +3483,7 @@ class StreamRelay {
3483
3483
  }
3484
3484
  this.pending.text += text;
3485
3485
  this.pending.bytes += Buffer.byteLength(text, "utf8");
3486
- if (this.pending.bytes >= STREAM_FLUSH_MAX_BYTES || this.pending.text.length >= api.STREAM_DELTA_MAX_CHARS) {
3486
+ if (this.pending.bytes >= STREAM_FLUSH_MAX_BYTES || this.pending.text.length >= index.STREAM_DELTA_MAX_CHARS) {
3487
3487
  this.flushPending();
3488
3488
  return;
3489
3489
  }
@@ -3663,8 +3663,8 @@ async function stageClaudeAttachments(attachments, options) {
3663
3663
  await persistence.ensurePrivateDirectory(sessionDir);
3664
3664
  const staged = [];
3665
3665
  for (const attachment of attachments) {
3666
- if (attachment.data.length > api.MAX_CHAT_ATTACHMENT_SOURCE_BYTES) {
3667
- throw new Error(`Attachment exceeds the ${api.MAX_CHAT_ATTACHMENT_SOURCE_BYTES / 1024 / 1024} MB limit`);
3666
+ if (attachment.data.length > index.MAX_CHAT_ATTACHMENT_SOURCE_BYTES) {
3667
+ throw new Error(`Attachment exceeds the ${index.MAX_CHAT_ATTACHMENT_SOURCE_BYTES / 1024 / 1024} MB limit`);
3668
3668
  }
3669
3669
  const name = safeFileName(attachment.name || "file");
3670
3670
  const targetPath = path.join(sessionDir, uniqueFileName(name));
@@ -4265,12 +4265,12 @@ async function claudeRemoteLauncher(session, onPermissionModeChange, onEffective
4265
4265
  claudeArgs: session.claudeArgs,
4266
4266
  onMessage,
4267
4267
  onCompletionEvent: (message) => {
4268
- persistence.logger.debug("[remote]: Completion event received:", api.contentLogMetadata(message));
4268
+ persistence.logger.debug("[remote]: Completion event received:", index.contentLogMetadata(message));
4269
4269
  session.client.sendSessionEvent({ type: "message", message });
4270
4270
  },
4271
4271
  onAuthFailure: (reason) => {
4272
4272
  session.client.sendSessionEvent({ type: "message", message: `Claude Code auth: ${reason}`, kind: "claude-auth-failed" });
4273
- void api.notifyDaemonClaudeAuthFailed(session.client.sessionId).catch((error) => persistence.logger.debug("[remote]: auth_failed report to daemon failed:", error));
4273
+ void index.notifyDaemonClaudeAuthFailed(session.client.sessionId).catch((error) => persistence.logger.debug("[remote]: auth_failed report to daemon failed:", error));
4274
4274
  },
4275
4275
  onSessionReset: () => {
4276
4276
  persistence.logger.debug("[remote]: Session reset");
@@ -5062,7 +5062,7 @@ function daemonReadiness(authenticated, running, hasState) {
5062
5062
  message: "\u26A0\uFE0F Daemon is not running \u2014 run `very-happy daemon start`"
5063
5063
  };
5064
5064
  }
5065
- function collectRuntimeReadiness(run = node_child_process.spawnSync, currentNodeVersion = process.version, onPath = api.commandOnPath) {
5065
+ function collectRuntimeReadiness(run = node_child_process.spawnSync, currentNodeVersion = process.version, onPath = index.commandOnPath) {
5066
5066
  const tmux = probe("tmux", run);
5067
5067
  return {
5068
5068
  node: {
@@ -5111,7 +5111,7 @@ function shareSafeEnvironmentInfo(env = process.env, runtime = process) {
5111
5111
  function printCliUpdateStatus(state) {
5112
5112
  const installed = persistence.configuration.currentCliVersion;
5113
5113
  const running = state?.startedWithCliVersion ?? null;
5114
- const summary = api.deriveLocalCliUpdateSummary(installed, running, state?.cliUpdate);
5114
+ const summary = index.deriveLocalCliUpdateSummary(installed, running, state?.cliUpdate);
5115
5115
  console.log(` Installed CLI: ${installed}`);
5116
5116
  console.log(` Running daemon: ${running ?? "not running"}`);
5117
5117
  if (state?.cliUpdate?.recommendedVersion) console.log(` Recommended: ${state.cliUpdate.recommendedVersion}`);
@@ -5146,7 +5146,7 @@ function getLogFiles(logDir) {
5146
5146
  async function runDoctorDaemon() {
5147
5147
  console.log(chalk.bold("\n\u{1F916} Daemon Status"));
5148
5148
  try {
5149
- const isRunning = await api.checkIfDaemonRunningAndCleanupStaleState();
5149
+ const isRunning = await index.checkIfDaemonRunningAndCleanupStaleState();
5150
5150
  const state = await persistence.readDaemonState();
5151
5151
  if (isRunning && state) {
5152
5152
  console.log(chalk.green("\u2713 Daemon is running"));
@@ -5316,6 +5316,16 @@ ${typeLabels[type] || type}:`));
5316
5316
  console.log(chalk.gray(" OS-keychain credentials cannot be verified here; see /docs/configuration#claude-credentials."));
5317
5317
  }
5318
5318
  console.log(chalk.gray(" An external claude command is only needed for native terminal/mirror use."));
5319
+ try {
5320
+ const { resolveAgentHomesForCli } = await Promise.resolve().then(function () { return require('./agentHome-CGl7FF7a.cjs'); });
5321
+ const { describeAgentHome } = await Promise.resolve().then(function () { return require('./types-Bqo68u61.cjs'); }).then(function (n) { return n.index; });
5322
+ const homes = await resolveAgentHomesForCli();
5323
+ console.log(chalk.green(`\u2713 Claude config dir: ${describeAgentHome(homes.claudeConfigDir)}`));
5324
+ console.log(chalk.green(`\u2713 Codex home: ${describeAgentHome(homes.codexHome)}`));
5325
+ console.log(chalk.gray(" Resolved from settings.json, then your login shell, then the daemon environment; pin with `very-happy agent-home`."));
5326
+ } catch {
5327
+ console.log(chalk.yellow("\u25CB Could not resolve the Claude/Codex home directories"));
5328
+ }
5319
5329
  if (availableAgents.length === 0) {
5320
5330
  console.log(chalk.yellow("\u25CB No external agent command found on this daemon PATH"));
5321
5331
  console.log(chalk.gray(" Codex, Gemini, OpenCode, OpenClaw, and native Claude terminal paths need their local command or gateway."));
@@ -5349,7 +5359,7 @@ ${typeLabels[type] || type}:`));
5349
5359
  }
5350
5360
  console.log(chalk.bold("\n\u{1F916} Daemon Status"));
5351
5361
  try {
5352
- const isRunning = await api.checkIfDaemonRunningAndCleanupStaleState();
5362
+ const isRunning = await index.checkIfDaemonRunningAndCleanupStaleState();
5353
5363
  const state = await persistence.readDaemonState();
5354
5364
  const summary = daemonReadiness(authenticated, isRunning, Boolean(state));
5355
5365
  if (summary.level === "ready" && state) {
@@ -5419,7 +5429,7 @@ async function registryVersion(name) {
5419
5429
  return typeof data.version === "string" ? stableVersion(data.version) : null;
5420
5430
  }
5421
5431
  async function detectAgentVersions(deps = { probe: probeAgentVersion, registryVersion }, now = Date.now()) {
5422
- const agents = await Promise.all(api.AGENT_VERSION_SOURCES.map(async (source) => {
5432
+ const agents = await Promise.all(index.AGENT_VERSION_SOURCES.map(async (source) => {
5423
5433
  const local = source.command ? await deps.probe(source.command).catch(() => ({ version: null, missing: false })) : { version: stableVersion(persistence.packageJson.dependencies["@anthropic-ai/claude-agent-sdk"]), missing: false };
5424
5434
  if (local.missing) return { id: source.id, installed: null, latest: null, status: "not-installed" };
5425
5435
  const latest = await deps.registryVersion(source.package).catch(() => null);
@@ -5678,7 +5688,7 @@ async function waitForAuthentication(keypair, claimSecret) {
5678
5688
  }
5679
5689
  process.stdout.write("\rWaiting for authentication" + ".".repeat(dots % 3 + 1) + " ");
5680
5690
  dots++;
5681
- await api.delay(1e3);
5691
+ await index.delay(1e3);
5682
5692
  }
5683
5693
  } finally {
5684
5694
  process.off("SIGINT", handleInterrupt);
@@ -6003,7 +6013,7 @@ async function waitForSessionKey(sessionId, timeoutMs) {
6003
6013
  `Session ${sessionId} has no encryption key in ${persistence.configuration.sessionsFile}. Either it was not spawned by this machine's daemon, or the daemon is too old to persist session keys.`
6004
6014
  );
6005
6015
  }
6006
- await api.delay(200);
6016
+ await index.delay(200);
6007
6017
  }
6008
6018
  }
6009
6019
  async function sendUserMessage(sessionId, persisted, text, client, options = {}) {
@@ -6065,7 +6075,7 @@ function resumePrecheck(metadata, fs) {
6065
6075
  if (!metadata.codexThreadId) return { ok: false, reason: "no-backend-id", detail: "session has no Codex thread id" };
6066
6076
  return { ok: true };
6067
6077
  }
6068
- if (!api.isClaudeSessionId(metadata.claudeSessionId)) {
6078
+ if (!index.isClaudeSessionId(metadata.claudeSessionId)) {
6069
6079
  return { ok: false, reason: "no-backend-id", detail: "session has no Claude session id" };
6070
6080
  }
6071
6081
  if (!fs.conversationExists(metadata.path, metadata.claudeSessionId)) {
@@ -7377,8 +7387,8 @@ function decryptBoxBundle(bundle, recipientSecretKey) {
7377
7387
  return decrypted ? new Uint8Array(decrypted) : null;
7378
7388
  }
7379
7389
  function readAgentCredentials() {
7380
- const credentialPath = api.getLocalHappyAgentCredentialPath();
7381
- const credentials = api.readLocalHappyAgentCredentials();
7390
+ const credentialPath = index.getLocalHappyAgentCredentialPath();
7391
+ const credentials = index.readLocalHappyAgentCredentials();
7382
7392
  if (!credentials) {
7383
7393
  throw new Error(
7384
7394
  `Cannot use the legacy CLI resume path without ${credentialPath}. This credential is produced only by the source-only internal control-plane prototype; do not install the unrelated npm package named happy-agent. Use the Web session controls instead.`
@@ -7678,7 +7688,7 @@ function ownedCliLink(link, target, packageDir) {
7678
7688
  return resolved.startsWith(path.join(packageDir, "bin") + path.sep);
7679
7689
  }
7680
7690
  async function installCliSafely(version, deps = defaults) {
7681
- const parsed = api.parseExactVersion(version);
7691
+ const parsed = index.parseExactVersion(version);
7682
7692
  if (!parsed) throw new Error("Invalid exact CLI version");
7683
7693
  const args = autoUpdateInstallArgs(parsed.exact);
7684
7694
  if (deps.platform === "win32") {
@@ -7769,7 +7779,7 @@ function createUpdateController(deps) {
7769
7779
  let lastPublished = "";
7770
7780
  const now = deps.now ?? Date.now;
7771
7781
  function validManualTarget(next, version) {
7772
- return version === next.recommendedVersion && Number.isFinite(next.checkedAt) && now() - next.checkedAt <= 65 * 6e4 && next.checkedAt <= now() + 6e4 && api.compareExactVersions(next.currentVersion, version) === -1 && (!next.minimumVersion || [0, 1].includes(api.compareExactVersions(version, next.minimumVersion) ?? -1));
7782
+ return version === next.recommendedVersion && Number.isFinite(next.checkedAt) && now() - next.checkedAt <= 65 * 6e4 && next.checkedAt <= now() + 6e4 && index.compareExactVersions(next.currentVersion, version) === -1 && (!next.minimumVersion || [0, 1].includes(index.compareExactVersions(version, next.minimumVersion) ?? -1));
7773
7783
  }
7774
7784
  function publish(state, version, detail) {
7775
7785
  if (!policy) return;
@@ -7807,7 +7817,7 @@ function createUpdateController(deps) {
7807
7817
  publish("unapproved", null);
7808
7818
  return;
7809
7819
  }
7810
- const order = api.compareExactVersions(policy.currentVersion, target);
7820
+ const order = index.compareExactVersions(policy.currentVersion, target);
7811
7821
  if (order !== -1) {
7812
7822
  publish(order === null ? "policy_stale" : "current", target);
7813
7823
  return;
@@ -7988,7 +7998,7 @@ function parseJsonObject(text) {
7988
7998
  return null;
7989
7999
  }
7990
8000
  }
7991
- 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-C510dSUn.cjs', document.baseURI).href))).resolve(s)) {
8001
+ 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-DhwtFJEe.cjs', document.baseURI).href))).resolve(s)) {
7992
8002
  const platformArch = `${platform}-${arch}`;
7993
8003
  const candidates = [
7994
8004
  `@anthropic-ai/claude-agent-sdk-${platformArch}/claude`,
@@ -8378,7 +8388,7 @@ function parseLines(lines) {
8378
8388
  try {
8379
8389
  const parsed = JSON.parse(line);
8380
8390
  if (parsed?.type && INTERNAL_CLAUDE_EVENT_TYPES.has(parsed.type)) continue;
8381
- const result = api.RawJSONLinesSchema.safeParse(parsed);
8391
+ const result = index.RawJSONLinesSchema.safeParse(parsed);
8382
8392
  if (!result.success) continue;
8383
8393
  out.push(result.data);
8384
8394
  } catch {
@@ -8422,19 +8432,19 @@ function createMirrorScanner(opts) {
8422
8432
  } finally {
8423
8433
  await handle.close();
8424
8434
  }
8425
- const { lines, consumedBytes } = api.extractCompleteLines(buf);
8435
+ const { lines, consumedBytes } = index.extractCompleteLines(buf);
8426
8436
  tail.offset += consumedBytes;
8427
8437
  if (lines.length === 0) return;
8428
8438
  let messages = parseLines(lines);
8429
8439
  if (isFirstBackfillRead) {
8430
- const decision = api.decideBackfill(messages, opts.backfillLines);
8440
+ const decision = index.decideBackfill(messages, opts.backfillLines);
8431
8441
  messages = decision.replay;
8432
8442
  if (decision.truncated) opts.events.onBackfillTruncated?.();
8433
8443
  tail.mode = "from-eof";
8434
8444
  }
8435
8445
  if (messages.length > 0) opts.events.onMessages(messages);
8436
8446
  };
8437
- const sync = new api.InvalidateSync(async () => {
8447
+ const sync = new index.InvalidateSync(async () => {
8438
8448
  for (const tail of files.values()) {
8439
8449
  try {
8440
8450
  await readTail(tail);
@@ -8518,7 +8528,7 @@ function pendingCreateSupersededBy(pending, event) {
8518
8528
  const TERMINAL_MIRROR_FLAVOR = "terminal-mirror";
8519
8529
  const RECONCILE_HYSTERESIS_MS = 2e4;
8520
8530
  function createMirrorManager(deps) {
8521
- const backfillLines = deps.backfillLines ?? api.MIRROR_BACKFILL_LINES_DEFAULT;
8531
+ const backfillLines = deps.backfillLines ?? index.MIRROR_BACKFILL_LINES_DEFAULT;
8522
8532
  const bindings = /* @__PURE__ */ new Map();
8523
8533
  const lastEndedAt = /* @__PURE__ */ new Map();
8524
8534
  const pendingCreates = /* @__PURE__ */ new Map();
@@ -8533,7 +8543,7 @@ function createMirrorManager(deps) {
8533
8543
  };
8534
8544
  const isTerminalAlive = deps.isTerminalAlive ?? ((terminalId) => {
8535
8545
  try {
8536
- return node_child_process.spawnSync("tmux", api.tmuxArgs(["has-session", "-t", `=vh-${terminalId}:`]), { stdio: "ignore", timeout: 3e3, env: api.scrubTmuxClientEnv({ ...process.env }) }).status === 0;
8546
+ return node_child_process.spawnSync("tmux", index.tmuxArgs(["has-session", "-t", `=vh-${terminalId}:`]), { stdio: "ignore", timeout: 3e3, env: index.scrubTmuxClientEnv({ ...process.env }) }).status === 0;
8537
8547
  } catch {
8538
8548
  return false;
8539
8549
  }
@@ -8541,7 +8551,7 @@ function createMirrorManager(deps) {
8541
8551
  const transcriptPathFor = (event) => {
8542
8552
  if (event.transcriptPath) return event.transcriptPath;
8543
8553
  if (!event.cwd) return null;
8544
- return path.join(api.getProjectPath(event.cwd), `${event.claudeSessionId}.jsonl`);
8554
+ return path.join(index.getProjectPath(event.cwd), `${event.claudeSessionId}.jsonl`);
8545
8555
  };
8546
8556
  const persistBinding = (binding) => {
8547
8557
  persistence.persistSession(binding.happySessionId, {
@@ -8557,8 +8567,8 @@ function createMirrorManager(deps) {
8557
8567
  };
8558
8568
  const sendMessages = (binding, messages) => {
8559
8569
  for (const message of messages) {
8560
- const key = api.mirrorLineKey(message);
8561
- binding.client.sendClaudeSessionMessage(message, key ? { localIdFor: (envelopeIndex) => api.mirrorLocalId(key, envelopeIndex) } : void 0);
8570
+ const key = index.mirrorLineKey(message);
8571
+ binding.client.sendClaudeSessionMessage(message, key ? { localIdFor: (envelopeIndex) => index.mirrorLocalId(key, envelopeIndex) } : void 0);
8562
8572
  }
8563
8573
  };
8564
8574
  const attachScanner = (binding, opts) => {
@@ -8662,7 +8672,7 @@ function createMirrorManager(deps) {
8662
8672
  archiveReason: void 0
8663
8673
  });
8664
8674
  const scanner = attachScanner(binding, { withTruncationNotice: false });
8665
- scanner.addFile(path.join(api.getProjectPath(meta.path), `${meta.claudeSessionId}.jsonl`), "backfill-tail");
8675
+ scanner.addFile(path.join(index.getProjectPath(meta.path), `${meta.claudeSessionId}.jsonl`), "backfill-tail");
8666
8676
  persistence.logger.debug(`[MIRROR] reconcile adopted terminal ${terminalId} \u2192 ${sessionId}`);
8667
8677
  deps.onBindingsChanged?.();
8668
8678
  };
@@ -8677,7 +8687,7 @@ function createMirrorManager(deps) {
8677
8687
  archiveReason: void 0
8678
8688
  });
8679
8689
  const scanner = binding.scanner ?? attachScanner(binding, { withTruncationNotice: false });
8680
- scanner.addFile(path.join(api.getProjectPath(binding.metadata.path), `${binding.claudeSessionId}.jsonl`), "backfill-tail");
8690
+ scanner.addFile(path.join(index.getProjectPath(binding.metadata.path), `${binding.claudeSessionId}.jsonl`), "backfill-tail");
8681
8691
  persistence.logger.debug(`[MIRROR] reconcile reactivated (in place) terminal ${binding.terminalId}`);
8682
8692
  deps.onBindingsChanged?.();
8683
8693
  };
@@ -8780,7 +8790,7 @@ function createMirrorManager(deps) {
8780
8790
  const parked = pendingCreates.get(event.terminalId);
8781
8791
  if (parked && pendingCreateSupersededBy(parked, event)) pendingCreates.delete(event.terminalId);
8782
8792
  const binding = bindings.get(event.terminalId) ?? null;
8783
- const decision = api.decideMirrorBinding(
8793
+ const decision = index.decideMirrorBinding(
8784
8794
  event,
8785
8795
  binding ? { status: binding.status, claudeSessionId: binding.claudeSessionId } : null
8786
8796
  );
@@ -8801,7 +8811,7 @@ function createMirrorManager(deps) {
8801
8811
  };
8802
8812
  return {
8803
8813
  handleHookPayload(body) {
8804
- const event = api.parseTerminalHookPayload(body);
8814
+ const event = index.parseTerminalHookPayload(body);
8805
8815
  if (!event) {
8806
8816
  persistence.logger.debug("[MIRROR] unparseable /terminal-hook payload dropped");
8807
8817
  return;
@@ -8929,7 +8939,7 @@ function createMirrorManager(deps) {
8929
8939
  };
8930
8940
  bindings.set(terminalId, binding);
8931
8941
  const scanner = attachScanner(binding, { withTruncationNotice: false });
8932
- scanner.addFile(path.join(api.getProjectPath(meta.path), `${meta.claudeSessionId}.jsonl`), "backfill-tail");
8942
+ scanner.addFile(path.join(index.getProjectPath(meta.path), `${meta.claudeSessionId}.jsonl`), "backfill-tail");
8933
8943
  persistence.logger.debug(`[MIRROR] restored binding terminal ${terminalId} \u2192 ${sessionId}`);
8934
8944
  deps.onBindingsChanged?.();
8935
8945
  }
@@ -9608,7 +9618,7 @@ function toSummary(id, persisted, extra) {
9608
9618
  };
9609
9619
  }
9610
9620
  async function listSessions(options = {}) {
9611
- const live = await api.listDaemonSessions();
9621
+ const live = await index.listDaemonSessions();
9612
9622
  return mergeSessionSummaries(live, persistence.readPersistedSessions(), options);
9613
9623
  }
9614
9624
  function summarizeAccountSession(row, persisted, liveIds, now) {
@@ -9678,7 +9688,7 @@ async function listAccountSessions(options = {}) {
9678
9688
  });
9679
9689
  const rows = Array.isArray(response.data?.sessions) ? response.data.sessions : [];
9680
9690
  const persisted = persistence.readPersistedSessions();
9681
- const live = await api.listDaemonSessions();
9691
+ const live = await index.listDaemonSessions();
9682
9692
  const liveIds = new Set(live.map((child) => child.happySessionId).filter((id) => typeof id === "string"));
9683
9693
  const now = Date.now();
9684
9694
  const summaries = rows.filter((row) => typeof row?.id === "string").map((row) => summarizeAccountSession(row, persisted[row.id], liveIds, now)).filter((summary) => options.includeArchived || !summary.archived);
@@ -9712,7 +9722,7 @@ async function readSessionTranscript(sessionId, limit) {
9712
9722
  const messages = Array.isArray(response.data?.messages) ? response.data.messages : [];
9713
9723
  messages.reverse();
9714
9724
  const key = persistence.decodeBase64(persisted.encryptionKey);
9715
- const live = await api.listDaemonSessions();
9725
+ const live = await index.listDaemonSessions();
9716
9726
  const bodies = messages.map((message) => {
9717
9727
  if (message.content?.t !== "encrypted") return null;
9718
9728
  try {
@@ -9728,7 +9738,7 @@ async function readSessionTranscript(sessionId, limit) {
9728
9738
  };
9729
9739
  }
9730
9740
  async function stopSession(sessionId) {
9731
- return await api.stopDaemonSession(sessionId);
9741
+ return await index.stopDaemonSession(sessionId);
9732
9742
  }
9733
9743
  async function archiveSession(sessionId) {
9734
9744
  const token = await bearerToken();
@@ -10050,7 +10060,7 @@ function sanitizeImportTitle(value) {
10050
10060
  return collapsed.length > 200 ? `${collapsed.slice(0, 199)}\u2026` : collapsed;
10051
10061
  }
10052
10062
  const hostSuffix = process.env.HAPPY_VARIANT === "dev" ? "-dev" : "";
10053
- const startupCliAvailability = api.detectCLIAvailability();
10063
+ const startupCliAvailability = index.detectCLIAvailability();
10054
10064
  const initialMachineMetadata = {
10055
10065
  teamsVersion: 1,
10056
10066
  teamLaunchVersion: 1,
@@ -10061,7 +10071,7 @@ const initialMachineMetadata = {
10061
10071
  happyHomeDir: persistence.configuration.happyHomeDir,
10062
10072
  happyLibDir: projectPath.projectPath(),
10063
10073
  cliAvailability: startupCliAvailability,
10064
- resumeSupport: { ...api.detectResumeSupport(), rpcAvailable: true }
10074
+ resumeSupport: { ...index.detectResumeSupport(), rpcAvailable: true }
10065
10075
  };
10066
10076
  async function preflightNewBundle(bundlePath) {
10067
10077
  const home = fs$1.mkdtempSync(path$1.join(os.tmpdir(), "vh-preflight-"));
@@ -10116,6 +10126,12 @@ async function startDaemon() {
10116
10126
  let cliUpdateStateRef = null;
10117
10127
  let lastHandoverHold = null;
10118
10128
  let claudeCredentialStoreSetting = (await persistence.readSettings()).claudeCredentialStore === "file" ? "file" : "auto";
10129
+ try {
10130
+ const homes = await index.refreshAgentHomes();
10131
+ persistence.logger.debug(`[DAEMON RUN] Claude config dir: ${index.describeAgentHome(homes.claudeConfigDir)}; Codex home: ${index.describeAgentHome(homes.codexHome)}`);
10132
+ } catch (error) {
10133
+ persistence.logger.debug("[DAEMON RUN] agent home resolution failed; using the daemon environment as-is", error);
10134
+ }
10119
10135
  let requestShutdown;
10120
10136
  let resolvesWhenShutdownRequested = new Promise((resolve) => {
10121
10137
  requestShutdown = (source, errorMessage) => {
@@ -10160,7 +10176,7 @@ async function startDaemon() {
10160
10176
  });
10161
10177
  persistence.logger.debug("[DAEMON RUN] Starting daemon process...");
10162
10178
  persistence.logger.debugLargeJson("[DAEMON RUN] Environment", getEnvironmentInfo());
10163
- const runningDaemonVersionMatches = await api.isDaemonRunningCurrentlyInstalledHappyVersion();
10179
+ const runningDaemonVersionMatches = await index.isDaemonRunningCurrentlyInstalledHappyVersion();
10164
10180
  const runningDaemonState = await persistence.readDaemonState();
10165
10181
  const runningDaemonEndpointsMatch = Boolean(runningDaemonState) && daemonEndpointsMatch(
10166
10182
  runningDaemonState?.serverUrl,
@@ -10170,7 +10186,7 @@ async function startDaemon() {
10170
10186
  );
10171
10187
  if (!runningDaemonVersionMatches || !runningDaemonEndpointsMatch) {
10172
10188
  persistence.logger.debug("[DAEMON RUN] Daemon version or endpoint mismatch detected, restarting daemon");
10173
- await api.stopDaemon();
10189
+ await index.stopDaemon();
10174
10190
  } else {
10175
10191
  persistence.logger.debug("[DAEMON RUN] Daemon version matches, keeping existing daemon");
10176
10192
  console.log("Daemon already running with matching version");
@@ -10189,7 +10205,7 @@ async function startDaemon() {
10189
10205
  const { credentials, machineId } = await authAndSetupMachineIfNeeded();
10190
10206
  persistence.logger.debug("[DAEMON RUN] Auth and machine setup complete");
10191
10207
  const pidToTrackedSession = /* @__PURE__ */ new Map();
10192
- const turnActivity = new api.TurnActivityTracker();
10208
+ const turnActivity = new index.TurnActivityTracker();
10193
10209
  const sessionIdToFinishedSession = /* @__PURE__ */ new Map();
10194
10210
  let teamWorker;
10195
10211
  const persisted = persistence.readPersistedSessions();
@@ -10281,7 +10297,8 @@ async function startDaemon() {
10281
10297
  }
10282
10298
  };
10283
10299
  const assistantSpawnGate = createSpawnGate();
10284
- const spawnSession = (options) => {
10300
+ const spawnSession = async (options) => {
10301
+ await index.refreshAgentHomes();
10285
10302
  if (assistantSpawnMode(options) !== "claude-singleton") {
10286
10303
  return spawnSessionImpl(options);
10287
10304
  }
@@ -10289,7 +10306,7 @@ async function startDaemon() {
10289
10306
  };
10290
10307
  const currentCliAvailability = () => apiMachineRef?.getCLIAvailability() ?? startupCliAvailability;
10291
10308
  const spawnSessionImpl = async (options) => {
10292
- persistence.logger.debugLargeJson("[DAEMON RUN] Spawning session", api.summarizeSpawnSessionForLog(options));
10309
+ persistence.logger.debugLargeJson("[DAEMON RUN] Spawning session", index.summarizeSpawnSessionForLog(options));
10293
10310
  const spawnModel = options.agent === "pi" ? sanitizeSpawnModel(options.model) : null;
10294
10311
  const spawnPermissionMode = sanitizeSpawnPermissionMode(options.permissionMode);
10295
10312
  if (options.permissionMode !== void 0 && spawnPermissionMode === null) {
@@ -10354,7 +10371,7 @@ async function startDaemon() {
10354
10371
  s.encryptionVariant
10355
10372
  );
10356
10373
  const claudeSessionId = resolveAssistantClaudeSessionId(s.metadata, serverMetadata);
10357
- const canResumeClaude = !!claudeSessionId && fs$1.existsSync(path$1.join(api.getProjectPath(assistantHome()), `${claudeSessionId}.jsonl`));
10374
+ const canResumeClaude = !!claudeSessionId && index.locateClaudeConversation(assistantHome(), claudeSessionId) !== null;
10358
10375
  return spawnTrackedHappyProcess({
10359
10376
  args: [
10360
10377
  "claude",
@@ -10373,6 +10390,8 @@ async function startDaemon() {
10373
10390
  // B-297: see the resume/restart paths — every spawn carries the
10374
10391
  // credentialStore=file shim, not just fresh sessions (B-276 D8).
10375
10392
  ...claudeAuthServiceRef?.claudeProcessEnvOverrides() ?? {},
10393
+ // B-478: point Claude at the directory the transcript was found in.
10394
+ ...canResumeClaude ? index.agentHomeSpawnEnv({ workingDirectory: assistantHome(), claudeSessionId }) : {},
10376
10395
  HAPPY_SESSION_VARIANT: "assistant",
10377
10396
  HAPPY_RECONNECT_SESSION_ID: assistantSessionId,
10378
10397
  HAPPY_RECONNECT_ENCRYPTION_KEY: s.encryptionKey,
@@ -10516,9 +10535,9 @@ async function startDaemon() {
10516
10535
  };
10517
10536
  }
10518
10537
  const resumeId = agent === "claude" ? options.resumeClaudeSessionId : agent === "codex" ? options.resumeCodexThreadId : void 0;
10519
- const resumeFragment = resumeId ? ` --resume ${api.shellescape(resumeId)}` : "";
10520
- const permissionModeFragment = spawnPermissionMode ? ` --permission-mode ${api.shellescape(spawnPermissionMode)}` : "";
10521
- const modelFragment = spawnModel ? ` --model ${api.shellescape(spawnModel)}` : "";
10538
+ const resumeFragment = resumeId ? ` --resume ${index.shellescape(resumeId)}` : "";
10539
+ const permissionModeFragment = spawnPermissionMode ? ` --permission-mode ${index.shellescape(spawnPermissionMode)}` : "";
10540
+ const modelFragment = spawnModel ? ` --model ${index.shellescape(spawnModel)}` : "";
10522
10541
  const fullCommand = `node --no-warnings --no-deprecation ${cliPath} ${agent} --happy-starting-mode remote --started-by daemon${resumeFragment}${permissionModeFragment}${modelFragment}`;
10523
10542
  const windowName = `happy-${Date.now()}-${agent}`;
10524
10543
  const tmuxEnv = {};
@@ -10527,6 +10546,7 @@ async function startDaemon() {
10527
10546
  tmuxEnv[key] = value;
10528
10547
  }
10529
10548
  }
10549
+ Object.assign(tmuxEnv, index.agentHomeSpawnEnv({ workingDirectory: directory, claudeSessionId: options.resumeClaudeSessionId, codexThreadId: options.resumeCodexThreadId }));
10530
10550
  Object.assign(tmuxEnv, extraEnv);
10531
10551
  const tmuxResult = await tmux.spawnInTmux([fullCommand], {
10532
10552
  sessionName: tmuxSessionName,
@@ -10621,6 +10641,9 @@ async function startDaemon() {
10621
10641
  cwd: directory,
10622
10642
  env: {
10623
10643
  ...process.env,
10644
+ // B-478: a fork/duplicate resumes a transcript that may live in
10645
+ // a moved config dir. Explicit environmentVariables still win.
10646
+ ...index.agentHomeSpawnEnv({ workingDirectory: directory, claudeSessionId: options.resumeClaudeSessionId, codexThreadId: options.resumeCodexThreadId }),
10624
10647
  ...extraEnv
10625
10648
  },
10626
10649
  directoryCreated,
@@ -10771,6 +10794,7 @@ async function startDaemon() {
10771
10794
  gate = createSpawnGate();
10772
10795
  resumeGates.set(happySessionId, gate);
10773
10796
  }
10797
+ await index.refreshAgentHomes();
10774
10798
  try {
10775
10799
  return await gate.join(() => resumeSessionImpl(happySessionId, options));
10776
10800
  } finally {
@@ -10817,7 +10841,9 @@ async function startDaemon() {
10817
10841
  }
10818
10842
  const precheck = resumePrecheck(metadata, {
10819
10843
  cwdExists: (p) => fs$1.existsSync(p),
10820
- conversationExists: (cwd, claudeSessionId) => fs$1.existsSync(path$1.join(api.getProjectPath(cwd), `${claudeSessionId}.jsonl`))
10844
+ // B-478: also looks in every other Claude config dir the user's shell
10845
+ // or settings point at, not just the one the daemon was started with.
10846
+ conversationExists: (cwd, claudeSessionId) => index.locateClaudeConversation(cwd, claudeSessionId) !== null
10821
10847
  });
10822
10848
  let freshConversation = false;
10823
10849
  if (!precheck.ok) {
@@ -10848,6 +10874,9 @@ async function startDaemon() {
10848
10874
  // fell back to `auto` reads a different credential store than the
10849
10875
  // fresh one next to it (B-276 D8).
10850
10876
  ...claudeAuthServiceRef?.claudeProcessEnvOverrides() ?? {},
10877
+ // B-478: if the transcript lives in a Claude/Codex home other than
10878
+ // the resolved one, this spawn is pointed there.
10879
+ ...freshConversation ? {} : index.agentHomeSpawnEnv({ workingDirectory: launch.cwd, claudeSessionId: metadata.claudeSessionId, codexThreadId: metadata.codexThreadId }),
10851
10880
  HAPPY_RECONNECT_SESSION_ID: happySessionId,
10852
10881
  HAPPY_RECONNECT_ENCRYPTION_KEY: persistence.encodeBase64(tracked.encryption.encryptionKey),
10853
10882
  HAPPY_RECONNECT_ENCRYPTION_VARIANT: tracked.encryption.encryptionVariant,
@@ -10909,6 +10938,7 @@ async function startDaemon() {
10909
10938
  gate = createSpawnGate();
10910
10939
  resumeGates.set(happySessionId, gate);
10911
10940
  }
10941
+ await index.refreshAgentHomes();
10912
10942
  try {
10913
10943
  return await gate.replace(() => restartSessionImpl(happySessionId, options));
10914
10944
  } finally {
@@ -10944,7 +10974,9 @@ async function startDaemon() {
10944
10974
  }
10945
10975
  const precheck = resumePrecheck(metadata, {
10946
10976
  cwdExists: (p) => fs$1.existsSync(p),
10947
- conversationExists: (cwd2, claudeSessionId) => fs$1.existsSync(path$1.join(api.getProjectPath(cwd2), `${claudeSessionId}.jsonl`))
10977
+ // B-478: also looks in every other Claude config dir the user's shell
10978
+ // or settings point at, not just the one the daemon was started with.
10979
+ conversationExists: (cwd2, claudeSessionId) => index.locateClaudeConversation(cwd2, claudeSessionId) !== null
10948
10980
  });
10949
10981
  let args;
10950
10982
  let cwd;
@@ -10979,6 +11011,8 @@ async function startDaemon() {
10979
11011
  // fell back to `auto` reads a different credential store than the
10980
11012
  // fresh one next to it (B-276 D8).
10981
11013
  ...claudeAuthServiceRef?.claudeProcessEnvOverrides() ?? {},
11014
+ // B-478: see resumeSession.
11015
+ ...precheck.ok ? index.agentHomeSpawnEnv({ workingDirectory: cwd, claudeSessionId: metadata.claudeSessionId, codexThreadId: metadata.codexThreadId }) : {},
10982
11016
  HAPPY_RECONNECT_SESSION_ID: happySessionId,
10983
11017
  HAPPY_RECONNECT_ENCRYPTION_KEY: persistence.encodeBase64(tracked.encryption.encryptionKey),
10984
11018
  HAPPY_RECONNECT_ENCRYPTION_VARIANT: tracked.encryption.encryptionVariant,
@@ -11156,8 +11190,8 @@ async function startDaemon() {
11156
11190
  httpPort: controlPort,
11157
11191
  startedAt: Date.now()
11158
11192
  };
11159
- const api$1 = await api.ApiClient.create(credentials);
11160
- const machine = await api$1.getOrCreateMachine({
11193
+ const api = await index.ApiClient.create(credentials);
11194
+ const machine = await api.getOrCreateMachine({
11161
11195
  machineId,
11162
11196
  metadata: initialMachineMetadata,
11163
11197
  daemonState: initialDaemonState
@@ -11171,10 +11205,10 @@ async function startDaemon() {
11171
11205
  if (identityConflict) {
11172
11206
  persistence.logger.warn(`[DAEMON RUN] machine identity conflict (${identityConflict.confidence}): ${describeMachineIdentityConflict(identityConflict)}`);
11173
11207
  }
11174
- const apiMachine = api$1.machineSyncClient(machine);
11208
+ const apiMachine = api.machineSyncClient(machine);
11175
11209
  apiMachineRef = apiMachine;
11176
11210
  const mirrorManager = createMirrorManager({
11177
- api: api$1,
11211
+ api,
11178
11212
  machineId,
11179
11213
  onBindingsChanged: () => apiMachine.requestTerminalListRefresh()
11180
11214
  });
@@ -11225,7 +11259,7 @@ async function startDaemon() {
11225
11259
  }
11226
11260
  let lastUpdateLog = "";
11227
11261
  const updateController = createUpdateController({
11228
- policy: () => api.fetchCliUpdateState(persistence.configuration.serverUrl, persistence.packageJson.version),
11262
+ policy: () => index.fetchCliUpdateState(persistence.configuration.serverUrl, persistence.packageJson.version),
11229
11263
  enabled: async () => ((await persistence.readSettings()).cliAutoUpdate ?? "idle") !== "off",
11230
11264
  // B-466: "idle" = no agent turn in flight. Idle wrappers survive a
11231
11265
  // handover (they talk to the server themselves) and web terminals live
@@ -11252,9 +11286,9 @@ async function startDaemon() {
11252
11286
  persistence.logger.debug("[DAEMON RUN] CLI update policy check failed:", error);
11253
11287
  });
11254
11288
  void refreshCliUpdate();
11255
- const cliUpdateIntervalMs = api.resolveCliUpdateCheckInterval(process.env.HAPPY_CLI_UPDATE_CHECK_INTERVAL);
11256
- if (process.env.HAPPY_CLI_UPDATE_CHECK_INTERVAL && cliUpdateIntervalMs === api.DEFAULT_CLI_UPDATE_CHECK_INTERVAL_MS && process.env.HAPPY_CLI_UPDATE_CHECK_INTERVAL.trim() !== String(api.DEFAULT_CLI_UPDATE_CHECK_INTERVAL_MS)) {
11257
- persistence.logger.warn(`[DAEMON RUN] Ignoring invalid HAPPY_CLI_UPDATE_CHECK_INTERVAL; using ${api.DEFAULT_CLI_UPDATE_CHECK_INTERVAL_MS}ms`);
11289
+ const cliUpdateIntervalMs = index.resolveCliUpdateCheckInterval(process.env.HAPPY_CLI_UPDATE_CHECK_INTERVAL);
11290
+ if (process.env.HAPPY_CLI_UPDATE_CHECK_INTERVAL && cliUpdateIntervalMs === index.DEFAULT_CLI_UPDATE_CHECK_INTERVAL_MS && process.env.HAPPY_CLI_UPDATE_CHECK_INTERVAL.trim() !== String(index.DEFAULT_CLI_UPDATE_CHECK_INTERVAL_MS)) {
11291
+ persistence.logger.warn(`[DAEMON RUN] Ignoring invalid HAPPY_CLI_UPDATE_CHECK_INTERVAL; using ${index.DEFAULT_CLI_UPDATE_CHECK_INTERVAL_MS}ms`);
11258
11292
  }
11259
11293
  const cliUpdateInterval = setInterval(() => void refreshCliUpdate(), cliUpdateIntervalMs);
11260
11294
  const stopAgentVersionChecks = startAgentVersionChecks(
@@ -11305,7 +11339,7 @@ async function startDaemon() {
11305
11339
  claudeAuthService.stop();
11306
11340
  apiMachine.shutdown();
11307
11341
  await stopControlServer();
11308
- await api.cleanupDaemonState();
11342
+ await index.cleanupDaemonState();
11309
11343
  await persistence.releaseDaemonLock(daemonLockHandle);
11310
11344
  await stopCaffeinate();
11311
11345
  try {
@@ -11378,7 +11412,7 @@ async function startDaemon() {
11378
11412
  }
11379
11413
  apiMachine.shutdown();
11380
11414
  await stopControlServer();
11381
- await api.cleanupDaemonState();
11415
+ await index.cleanupDaemonState();
11382
11416
  await stopCaffeinate();
11383
11417
  await persistence.releaseDaemonLock(daemonLockHandle);
11384
11418
  persistence.logger.debug(`[DAEMON RUN] Cleanup completed, exiting process with code ${daemonExitCode(source)}`);
@@ -11645,7 +11679,7 @@ ${sessions.map(describeSummary).join("\n")}`);
11645
11679
  limit: z.z.number().optional().describe("How many recent messages to fetch (default 20, max 100)")
11646
11680
  }
11647
11681
  }, async (args) => {
11648
- if (!api.isValidSessionId(args.sessionId)) return fail("Invalid sessionId");
11682
+ if (!index.isValidSessionId(args.sessionId)) return fail("Invalid sessionId");
11649
11683
  try {
11650
11684
  const result = await readSessionTranscript(args.sessionId, args.limit ?? 20);
11651
11685
  const body = result.transcript.length > 0 ? result.transcript : "(no readable conversation content in this range)";
@@ -11664,7 +11698,7 @@ ${body}`);
11664
11698
  text: z.z.string().describe("The message text to send")
11665
11699
  }
11666
11700
  }, async (args) => {
11667
- if (!api.isValidSessionId(args.sessionId)) return fail("Invalid sessionId");
11701
+ if (!index.isValidSessionId(args.sessionId)) return fail("Invalid sessionId");
11668
11702
  if (typeof args.text !== "string" || args.text.trim().length === 0) return fail("text must be non-empty");
11669
11703
  try {
11670
11704
  const persisted = await waitForSessionKey(args.sessionId, 0);
@@ -11686,7 +11720,7 @@ ${body}`);
11686
11720
  if (!normalized.ok) return fail(normalized.error);
11687
11721
  const directory = normalized.directory;
11688
11722
  try {
11689
- const result = await api.spawnDaemonSession(directory, void 0, { spawnedBy: "assistant" });
11723
+ const result = await index.spawnDaemonSession(directory, void 0, { spawnedBy: "assistant" });
11690
11724
  if (result?.error || !result?.sessionId) {
11691
11725
  return fail(`Failed to spawn session: ${result?.error ?? "daemon returned no session id"}`);
11692
11726
  }
@@ -11713,7 +11747,7 @@ ${body}`);
11713
11747
  sessionId: z.z.string().describe("The Happy session id to stop")
11714
11748
  }
11715
11749
  }, async (args) => {
11716
- if (!api.isValidSessionId(args.sessionId)) return fail("Invalid sessionId");
11750
+ if (!index.isValidSessionId(args.sessionId)) return fail("Invalid sessionId");
11717
11751
  try {
11718
11752
  const persisted = persistence.readPersistedSessions()[args.sessionId];
11719
11753
  const success = await stopSession(args.sessionId);
@@ -11730,7 +11764,7 @@ ${body}`);
11730
11764
  sessionId: z.z.string().describe("The Happy session id to archive")
11731
11765
  }
11732
11766
  }, async (args) => {
11733
- if (!api.isValidSessionId(args.sessionId)) return fail("Invalid sessionId");
11767
+ if (!index.isValidSessionId(args.sessionId)) return fail("Invalid sessionId");
11734
11768
  try {
11735
11769
  await archiveSession(args.sessionId);
11736
11770
  const persisted = persistence.readPersistedSessions()[args.sessionId];
@@ -11746,7 +11780,7 @@ function registerAssistantMachineTools(mcp) {
11746
11780
  title: "List Terminals",
11747
11781
  inputSchema: {}
11748
11782
  }, async () => {
11749
- const r = api.listVhTerminals();
11783
+ const r = index.listVhTerminals();
11750
11784
  if (!r.ok) return fail(`Failed to list terminals: ${r.error}`);
11751
11785
  if (r.terminals.length === 0) return ok("No web terminals are open on this machine.");
11752
11786
  const lines = r.terminals.map((t) => {
@@ -11766,8 +11800,8 @@ ${lines.join("\n")}`);
11766
11800
  lines: z.z.number().optional().describe("How many history lines to read (default 80, max 2000)")
11767
11801
  }
11768
11802
  }, async (args) => {
11769
- if (!api.isValidTerminalId(args.terminalId)) return fail("Invalid terminalId");
11770
- const r = api.readVhTerminal(args.terminalId, args.lines ?? 80);
11803
+ if (!index.isValidTerminalId(args.terminalId)) return fail("Invalid terminalId");
11804
+ const r = index.readVhTerminal(args.terminalId, args.lines ?? 80);
11771
11805
  if (!r.ok) return fail(`Failed to read terminal ${args.terminalId}: ${r.error}`);
11772
11806
  return ok(`terminal ${args.terminalId} \u2014 last output:
11773
11807
  ${r.text}`);
@@ -11781,10 +11815,10 @@ ${r.text}`);
11781
11815
  submit: z.z.boolean().optional().describe("Also press Enter after pasting (default false)")
11782
11816
  }
11783
11817
  }, async (args) => {
11784
- if (!api.isValidTerminalId(args.terminalId)) return fail("Invalid terminalId");
11818
+ if (!index.isValidTerminalId(args.terminalId)) return fail("Invalid terminalId");
11785
11819
  if (typeof args.text !== "string" || args.text.length === 0) return fail("text must be non-empty");
11786
11820
  const submit = args.submit === true;
11787
- const r = api.sendToVhTerminal(args.terminalId, args.text, submit);
11821
+ const r = index.sendToVhTerminal(args.terminalId, args.text, submit);
11788
11822
  if (!r.ok) return fail(`Failed to send to terminal ${args.terminalId}: ${r.error}`);
11789
11823
  return ok(submit ? `Pasted and submitted (Enter sent) in terminal ${args.terminalId}.` : `Pasted into terminal ${args.terminalId} WITHOUT pressing Enter \u2014 the user (or a follow-up terminal_send with submit=true) decides whether it runs.`);
11790
11824
  });
@@ -12056,7 +12090,7 @@ async function startHappyServer(client, options) {
12056
12090
  return;
12057
12091
  }
12058
12092
  }
12059
- const usage = api.ContextUsageSchema.parse({ ...JSON.parse(body), updatedAt: Date.now() });
12093
+ const usage = index.ContextUsageSchema.parse({ ...JSON.parse(body), updatedAt: Date.now() });
12060
12094
  options.onContextUsage(usage);
12061
12095
  res.writeHead(204).end();
12062
12096
  } catch {
@@ -12265,13 +12299,27 @@ function registerKillSessionHandler(rpcHandlerManager, killThisHappy, archiveEve
12265
12299
  }
12266
12300
 
12267
12301
  const SIDE_QUESTION_SYSTEM_PROMPT = [
12268
- "This is a SIDE QUESTION from the user, asked next to the main conversation above.",
12269
- "Answer it directly in a single response, using the conversation context and your own knowledge.",
12270
- "Side questions cannot use tools: do not attempt to read files, run commands, or call tools \u2014 if",
12271
- "the answer would require that, say what you would check and why.",
12272
- "Do NOT continue, resume, or reference progress on the main task; the main conversation is",
12273
- "unaffected by this exchange."
12302
+ "A user message wrapped in a side-question system-reminder is a SIDE QUESTION: answer it",
12303
+ "directly in one response from the conversation context, with no tools and no action on the main task."
12274
12304
  ].join(" ");
12305
+ const SIDE_QUESTION_REMINDER = [
12306
+ "<system-reminder>This is a side question from the user. You must answer this question directly in a single response.",
12307
+ "",
12308
+ "IMPORTANT CONTEXT:",
12309
+ "- You are a separate, lightweight agent spawned to answer this one question",
12310
+ "- The main agent is NOT interrupted - it continues working independently in the background",
12311
+ "- You share the conversation context but are a completely separate instance",
12312
+ '- Do NOT reference being interrupted or what you were "previously doing" - that framing is incorrect',
12313
+ "",
12314
+ "CRITICAL CONSTRAINTS:",
12315
+ "- You have NO tools available - you cannot read files, run commands, search, or take any actions",
12316
+ "- This is a one-off response - there will be no follow-up turns",
12317
+ "- You can ONLY provide information based on what you already know from the conversation context",
12318
+ `- NEVER say things like "Let me try...", "I'll now...", "Let me check...", or promise to take any action`,
12319
+ "- If you don't know the answer, say so - do not offer to look it up or investigate",
12320
+ "",
12321
+ "Simply answer the question with the information you have.</system-reminder>"
12322
+ ].join("\n");
12275
12323
  const MAX_HISTORY_CHARS = 2e3;
12276
12324
  function clip(text, max) {
12277
12325
  return text.length > max ? `${text.slice(0, max)}\u2026` : text;
@@ -12279,14 +12327,17 @@ function clip(text, max) {
12279
12327
  function buildSideQuestionPrompt(question, history = []) {
12280
12328
  const trimmed = question.trim();
12281
12329
  const prior = history.filter((h) => h.question.trim() && h.answer.trim()).slice(-12);
12282
- if (prior.length === 0) return trimmed;
12330
+ const body = `${SIDE_QUESTION_REMINDER}
12331
+
12332
+ ${trimmed}`;
12333
+ if (prior.length === 0) return body;
12283
12334
  const lines = prior.map((h) => `Q: ${clip(h.question.trim(), MAX_HISTORY_CHARS)}
12284
12335
  A: ${clip(h.answer.trim(), MAX_HISTORY_CHARS)}`);
12285
12336
  return `<earlier-side-questions>
12286
12337
  ${lines.join("\n\n")}
12287
12338
  </earlier-side-questions>
12288
12339
 
12289
- ${trimmed}`;
12340
+ ${body}`;
12290
12341
  }
12291
12342
  function sideQuestionQueryOptions(input) {
12292
12343
  return {
@@ -12307,17 +12358,36 @@ function sideQuestionQueryOptions(input) {
12307
12358
  abort: input.signal
12308
12359
  };
12309
12360
  }
12310
- function textFromAssistant(message) {
12311
- if (message.type !== "assistant") return "";
12361
+ function assistantBlocks(message) {
12362
+ if (message.type !== "assistant") return [];
12312
12363
  const content = message.message?.content;
12313
- if (!Array.isArray(content)) return "";
12314
- return content.map((block) => block && typeof block === "object" && block.type === "text" ? String(block.text ?? "") : "").join("");
12364
+ return Array.isArray(content) ? content.filter((b) => Boolean(b) && typeof b === "object") : [];
12365
+ }
12366
+ function textFromAssistant(message) {
12367
+ return assistantBlocks(message).map((block) => block.type === "text" ? String(block.text ?? "") : "").join("");
12368
+ }
12369
+ function toolUseFromAssistant(message) {
12370
+ const block = assistantBlocks(message).find((b) => b.type === "tool_use");
12371
+ return block ? String(block.name ?? "a tool") : null;
12372
+ }
12373
+ function toolAttemptNotice(toolName) {
12374
+ return `(The model tried to call ${toolName} instead of answering directly. Try rephrasing or ask in the main conversation.)`;
12375
+ }
12376
+ function apiErrorFromSystem(message) {
12377
+ if (message.type !== "system") return null;
12378
+ const m = message;
12379
+ if (m.subtype !== "api_error") return null;
12380
+ if (typeof m.error === "string") return m.error;
12381
+ const detail = m.error?.formatted ?? m.error?.message;
12382
+ return typeof detail === "string" && detail ? detail : "API error";
12315
12383
  }
12316
12384
  async function runSideQuestion(query, input) {
12317
12385
  const options = sideQuestionQueryOptions(input);
12318
12386
  const stream = query({ prompt: buildSideQuestionPrompt(input.question, input.history), options });
12319
12387
  let streamed = "";
12320
12388
  let final = "";
12389
+ let toolAttempt = null;
12390
+ let lastApiError = null;
12321
12391
  let resultSeen = false;
12322
12392
  for await (const message of stream) {
12323
12393
  if (message.type === "stream_event") {
@@ -12336,20 +12406,31 @@ async function runSideQuestion(query, input) {
12336
12406
  ${text}` : text;
12337
12407
  input.onText?.(final);
12338
12408
  }
12409
+ toolAttempt ??= toolUseFromAssistant(message);
12410
+ continue;
12411
+ }
12412
+ if (message.type === "system") {
12413
+ lastApiError = apiErrorFromSystem(message) ?? lastApiError;
12339
12414
  continue;
12340
12415
  }
12341
12416
  if (message.type === "result") {
12342
12417
  resultSeen = true;
12343
12418
  const result = message;
12344
12419
  if (result.subtype !== "success") {
12345
- const detail = Array.isArray(result.errors) && result.errors.length > 0 ? String(result.errors[0]) : typeof result.result === "string" && result.result ? result.result : result.subtype ?? "unknown";
12420
+ if (toolAttempt && result.subtype === "error_max_turns") break;
12421
+ const detail = Array.isArray(result.errors) && result.errors.length > 0 ? String(result.errors[0]) : typeof result.result === "string" && result.result ? result.result : lastApiError ?? result.subtype ?? "unknown";
12346
12422
  throw new Error(`Side question failed: ${detail}`);
12347
12423
  }
12348
12424
  if (!final && typeof result.result === "string") final = result.result;
12349
12425
  }
12350
12426
  }
12351
12427
  if (input.signal?.aborted) throw new Error("Side question cancelled");
12352
- if (!resultSeen && !final && !streamed) throw new Error("Side question ended without a result");
12428
+ if (toolAttempt && !final.trim() && !streamed.trim()) {
12429
+ const notice = toolAttemptNotice(toolAttempt);
12430
+ input.onText?.(notice);
12431
+ return { answer: notice, hadContext: Boolean(input.resumeSessionId) };
12432
+ }
12433
+ if (!resultSeen && !final && !streamed) throw new Error(`Side question ended without a result${lastApiError ? `: ${lastApiError}` : ""}`);
12353
12434
  return { answer: final || streamed, hadContext: Boolean(input.resumeSessionId) };
12354
12435
  }
12355
12436
 
@@ -12376,7 +12457,7 @@ function registerSideQuestionHandler(rpc, deps) {
12376
12457
  const retainMs = deps.retainMs ?? SIDE_QUESTION_RETAIN_MS;
12377
12458
  const maxRunMs = deps.maxRunMs ?? SIDE_QUESTION_MAX_RUN_MS;
12378
12459
  const run = deps.run ?? (async (input) => {
12379
- const { query } = await Promise.resolve().then(function () { return require('./index-BREtikhm.cjs'); });
12460
+ const { query } = await Promise.resolve().then(function () { return require('./index-D4Smqppj.cjs'); });
12380
12461
  return runSideQuestion(query, input);
12381
12462
  });
12382
12463
  const slots = /* @__PURE__ */ new Map();
@@ -12399,7 +12480,12 @@ function registerSideQuestionHandler(rpc, deps) {
12399
12480
  if (!question) throw new Error("Side question is empty");
12400
12481
  if (question.length > SIDE_QUESTION_MAX_CHARS) throw new Error("Side question is too long");
12401
12482
  prune();
12402
- if (active) throw new Error("A side question is already running");
12483
+ if (active) {
12484
+ const stale = active;
12485
+ stale.abort.abort("superseded");
12486
+ finish(stale, "cancelled");
12487
+ persistence.logger.debug(`[btw] side question ${stale.requestId} superseded by a new ask`);
12488
+ }
12403
12489
  const resumeSessionId = deps.getClaudeSessionId() ?? null;
12404
12490
  const slot = {
12405
12491
  requestId: node_crypto.randomUUID(),
@@ -12478,7 +12564,7 @@ const MAX_TITLE_CHARS = 60;
12478
12564
  const GENERATION_TIMEOUT_MS = 3e4;
12479
12565
  function resolveClaudeBinary() {
12480
12566
  try {
12481
- 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-C510dSUn.cjs', document.baseURI).href)));
12567
+ 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-DhwtFJEe.cjs', document.baseURI).href)));
12482
12568
  const utilsPath = path.resolve(path.join(projectPath.projectPath(), "scripts", "claude_version_utils.cjs"));
12483
12569
  const { getClaudeCliPath } = require$1(utilsPath);
12484
12570
  const path$1 = getClaudeCliPath();
@@ -12490,7 +12576,7 @@ function resolveClaudeBinary() {
12490
12576
  }
12491
12577
  function buildPrompt(firstUserMessage) {
12492
12578
  const sample = firstUserMessage.slice(0, MAX_PROMPT_SAMPLE_CHARS);
12493
- return `${api.TITLE_PROMPT_PREFIX} (match the message's language). Be concrete \u2014 name the actual task/subject. Do NOT output generic placeholders like "\u65B0\u5BF9\u8BDD"/"New chat"/"Conversation"/"Untitled". No quotes, no trailing punctuation. Reply with ONLY the title.
12579
+ return `${index.TITLE_PROMPT_PREFIX} (match the message's language). Be concrete \u2014 name the actual task/subject. Do NOT output generic placeholders like "\u65B0\u5BF9\u8BDD"/"New chat"/"Conversation"/"Untitled". No quotes, no trailing punctuation. Reply with ONLY the title.
12494
12580
 
12495
12581
  Message: "${sample}"`;
12496
12582
  }
@@ -12686,7 +12772,7 @@ function buildBoardPrompt(input) {
12686
12772
  const taskLines = tasks.length > 0 ? tasks.map((t) => `- ${t.id}: ${t.title}`).join("\n") : "(no tasks defined)";
12687
12773
  const todoBlock = input.todos.length > 0 ? input.todos.join("\n") : "(none)";
12688
12774
  return [
12689
- `${api.BOARD_ANALYZER_PROMPT_PREFIX} Analyze this session snapshot and reply with ONLY a strict JSON object, no markdown, no explanations:`,
12775
+ `${index.BOARD_ANALYZER_PROMPT_PREFIX} Analyze this session snapshot and reply with ONLY a strict JSON object, no markdown, no explanations:`,
12690
12776
  '{"taskId": string|null, "attention": "none"|"review"|"blocked", "progress": string}',
12691
12777
  "",
12692
12778
  "Rules:",
@@ -12890,8 +12976,8 @@ async function runClaude(credentials, options = {}) {
12890
12976
  if (options.startedBy === "daemon" && options.startingMode === "local") {
12891
12977
  throw new Error("Daemon-spawned sessions cannot use local/interactive mode. Use --happy-starting-mode remote or spawn sessions directly from terminal.");
12892
12978
  }
12893
- api.connectionState.setBackend("Claude");
12894
- const api$1 = await api.ApiClient.create(credentials);
12979
+ index.connectionState.setBackend("Claude");
12980
+ const api = await index.ApiClient.create(credentials);
12895
12981
  let state = {};
12896
12982
  const settings = await persistence.readSettings();
12897
12983
  let machineId = settings?.machineId;
@@ -12908,7 +12994,7 @@ async function runClaude(credentials, options = {}) {
12908
12994
  }
12909
12995
  persistence.logger.debug(`Using machineId: ${machineId}`);
12910
12996
  const sessionTag = node_crypto.randomUUID();
12911
- await api$1.getOrCreateMachine({
12997
+ await api.getOrCreateMachine({
12912
12998
  machineId,
12913
12999
  metadata: initialMachineMetadata
12914
13000
  });
@@ -12978,16 +13064,16 @@ async function runClaude(credentials, options = {}) {
12978
13064
  agentStateVersion: parseInt(reconnectAgentStateVersion || "0", 10)
12979
13065
  };
12980
13066
  } else {
12981
- response = await api$1.getOrCreateSession({ tag: sessionTag, metadata, state });
13067
+ response = await api.getOrCreateSession({ tag: sessionTag, metadata, state });
12982
13068
  }
12983
13069
  if (!response) {
12984
13070
  let offlineSessionId = null;
12985
- const reconnection = api.startOfflineReconnection({
13071
+ const reconnection = index.startOfflineReconnection({
12986
13072
  serverUrl: persistence.configuration.serverUrl,
12987
13073
  onReconnected: async () => {
12988
- const resp = await api$1.getOrCreateSession({ tag: node_crypto.randomUUID(), metadata, state });
13074
+ const resp = await api.getOrCreateSession({ tag: node_crypto.randomUUID(), metadata, state });
12989
13075
  if (!resp) throw new Error("Server unavailable");
12990
- const session2 = api$1.sessionSyncClient(resp);
13076
+ const session2 = api.sessionSyncClient(resp);
12991
13077
  const scanner = await createSessionScanner({
12992
13078
  sessionId: null,
12993
13079
  workingDirectory,
@@ -13023,12 +13109,12 @@ async function runClaude(credentials, options = {}) {
13023
13109
  }
13024
13110
  persistence.logger.debug(`Session created: ${response.id}`);
13025
13111
  await claimSessionOrExit(response.id, { takeover: !!reconnectSessionId, flavor: "claude" });
13026
- if (reconnectSessionId && !await api$1.reactivateSession(response.id)) {
13112
+ if (reconnectSessionId && !await api.reactivateSession(response.id)) {
13027
13113
  throw new Error(`Failed to reactivate archived session ${response.id}`);
13028
13114
  }
13029
13115
  let reconnectSeeded = false;
13030
13116
  if (reconnectSessionId) {
13031
- const snapshot = await api$1.getSession(response.id, response.encryptionKey, response.encryptionVariant);
13117
+ const snapshot = await api.getSession(response.id, response.encryptionKey, response.encryptionVariant);
13032
13118
  if (snapshot.ok) {
13033
13119
  response = applyServerSnapshot(response, snapshot.session);
13034
13120
  reconnectSeeded = true;
@@ -13040,7 +13126,7 @@ async function runClaude(credentials, options = {}) {
13040
13126
  }
13041
13127
  try {
13042
13128
  persistence.logger.debug(`[START] Reporting session ${response.id} to daemon`);
13043
- const result = await api.notifyDaemonSessionStarted(response.id, metadata, {
13129
+ const result = await index.notifyDaemonSessionStarted(response.id, metadata, {
13044
13130
  encryptionKey: persistence.encodeBase64(response.encryptionKey),
13045
13131
  encryptionVariant: response.encryptionVariant,
13046
13132
  seq: response.seq,
@@ -13055,7 +13141,7 @@ async function runClaude(credentials, options = {}) {
13055
13141
  } catch (error) {
13056
13142
  persistence.logger.debug("[START] Failed to report to daemon (may not be running):", error);
13057
13143
  }
13058
- const session = api$1.sessionSyncClient(response, reconnectSeeded ? { initialSeq: response.seq } : void 0);
13144
+ const session = api.sessionSyncClient(response, reconnectSeeded ? { initialSeq: response.seq } : void 0);
13059
13145
  if (reconnectSessionId) {
13060
13146
  session.suppressNextArchiveSignal();
13061
13147
  if (!reconnectSeeded) session.skipExistingMessages();
@@ -13071,7 +13157,7 @@ async function runClaude(credentials, options = {}) {
13071
13157
  }
13072
13158
  const forkClaudeSessionId = process.env.HAPPY_FORK_CLAUDE_SESSION_ID;
13073
13159
  if (!reconnectSessionId && forkClaudeSessionId) {
13074
- const jsonlPath = path.join(api.getProjectPath(workingDirectory), `${forkClaudeSessionId}.jsonl`);
13160
+ const jsonlPath = path.join(index.getProjectPath(workingDirectory), `${forkClaudeSessionId}.jsonl`);
13075
13161
  try {
13076
13162
  const file = await promises.readFile(jsonlPath, "utf-8");
13077
13163
  const lines = file.split("\n");
@@ -13084,7 +13170,7 @@ async function runClaude(credentials, options = {}) {
13084
13170
  } catch {
13085
13171
  continue;
13086
13172
  }
13087
- const result = api.RawJSONLinesSchema.safeParse(parsed);
13173
+ const result = index.RawJSONLinesSchema.safeParse(parsed);
13088
13174
  if (!result.success) continue;
13089
13175
  session.sendClaudeSessionMessage(result.data);
13090
13176
  backfilled += 1;
@@ -13126,7 +13212,7 @@ async function runClaude(credentials, options = {}) {
13126
13212
  enabled: settings?.boardLlm === true,
13127
13213
  selfReportState: boardSelfReport,
13128
13214
  fetchTasks: async () => {
13129
- const item = await api$1.kvGet("vh.board-tasks.v1");
13215
+ const item = await api.kvGet("vh.board-tasks.v1");
13130
13216
  if (!item) return null;
13131
13217
  try {
13132
13218
  const parsed = JSON.parse(Buffer.from(item.value, "base64").toString("utf8"));
@@ -13162,7 +13248,7 @@ async function runClaude(credentials, options = {}) {
13162
13248
  let currentSession = null;
13163
13249
  const hookServer = await startHookServer({
13164
13250
  onSessionHook: (sessionId, data) => {
13165
- persistence.logger.debug(`[START] Session hook received: ${sessionId}`, api.contentLogMetadata(data));
13251
+ persistence.logger.debug(`[START] Session hook received: ${sessionId}`, index.contentLogMetadata(data));
13166
13252
  remoteScanner.onNewSession(sessionId, { treatExistingAsProcessed: true });
13167
13253
  if (currentSession) {
13168
13254
  const previousSessionId = currentSession.sessionId;
@@ -13380,7 +13466,7 @@ async function runClaude(credentials, options = {}) {
13380
13466
  };
13381
13467
  messageQueue.pushIsolateAndClear(specialCommand.originalMessage || message.content.text, enhancedMode2, attachmentsForThisMessage, message.localKey);
13382
13468
  persistence.logger.debug("[start] /compact command pushed to queue:", {
13383
- ...api.contentLogMetadata(message.content.text),
13469
+ ...index.contentLogMetadata(message.content.text),
13384
13470
  attachmentCount: attachmentsForThisMessage?.length ?? 0,
13385
13471
  hasMetadata: Boolean(message.meta)
13386
13472
  });
@@ -13400,7 +13486,7 @@ async function runClaude(credentials, options = {}) {
13400
13486
  };
13401
13487
  messageQueue.pushIsolateAndClear(specialCommand.originalMessage || message.content.text, enhancedMode2, attachmentsForThisMessage, message.localKey);
13402
13488
  persistence.logger.debug("[start] /clear command pushed to queue:", {
13403
- ...api.contentLogMetadata(message.content.text),
13489
+ ...index.contentLogMetadata(message.content.text),
13404
13490
  attachmentCount: attachmentsForThisMessage?.length ?? 0,
13405
13491
  hasMetadata: Boolean(message.meta)
13406
13492
  });
@@ -13462,7 +13548,7 @@ async function runClaude(credentials, options = {}) {
13462
13548
  }) === true;
13463
13549
  if (accepted) {
13464
13550
  persistence.logger.debug("User message steered into current turn:", {
13465
- ...api.contentLogMetadata(message.content.text),
13551
+ ...index.contentLogMetadata(message.content.text),
13466
13552
  attachmentCount: attachmentsForThisMessage?.length ?? 0
13467
13553
  });
13468
13554
  return;
@@ -13471,7 +13557,7 @@ async function runClaude(credentials, options = {}) {
13471
13557
  }
13472
13558
  messageQueue.push(message.content.text, enhancedMode, attachmentsForThisMessage, message.localKey);
13473
13559
  persistence.logger.debug("User message pushed to queue:", {
13474
- ...api.contentLogMetadata(message.content.text),
13560
+ ...index.contentLogMetadata(message.content.text),
13475
13561
  attachmentCount: attachmentsForThisMessage?.length ?? 0,
13476
13562
  hasMetadata: Boolean(message.meta)
13477
13563
  });
@@ -13492,7 +13578,7 @@ async function runClaude(credentials, options = {}) {
13492
13578
  currentSession?.cleanup();
13493
13579
  session.sendSessionDeath();
13494
13580
  try {
13495
- await api$1.deactivateSession(session.sessionId);
13581
+ await api.deactivateSession(session.sessionId);
13496
13582
  } catch (err) {
13497
13583
  persistence.logger.debug("[START] deactivateSession during cleanup failed:", err);
13498
13584
  }
@@ -13539,7 +13625,7 @@ async function runClaude(credentials, options = {}) {
13539
13625
  permissionMode: initialPermissionMode,
13540
13626
  startingMode: options.startingMode,
13541
13627
  messageQueue,
13542
- api: api$1,
13628
+ api,
13543
13629
  allowedTools: happyServer.toolNames.map((toolName) => `mcp__happy__${toolName}`),
13544
13630
  onModeChange: (newMode) => {
13545
13631
  currentRunMode = newMode;
@@ -13768,7 +13854,7 @@ async function handleAuthLogin(args) {
13768
13854
  console.log(chalk.gray(" \u2022 Re-authenticate and register machine\n"));
13769
13855
  try {
13770
13856
  persistence.logger.debug("Stopping daemon for force auth...");
13771
- await api.stopDaemon();
13857
+ await index.stopDaemon();
13772
13858
  console.log(chalk.gray("\u2713 Stopped daemon"));
13773
13859
  } catch (error) {
13774
13860
  persistence.logger.debug("Daemon was not running or failed to stop:", error);
@@ -13833,7 +13919,7 @@ async function handleAuthLogout() {
13833
13919
  if (answer.toLowerCase() === "y" || answer.toLowerCase() === "yes") {
13834
13920
  try {
13835
13921
  try {
13836
- await api.stopDaemon();
13922
+ await index.stopDaemon();
13837
13923
  console.log(chalk.gray("Stopped daemon"));
13838
13924
  } catch {
13839
13925
  }
@@ -13878,7 +13964,7 @@ async function handleAuthStatus() {
13878
13964
  console.log(chalk.gray(`
13879
13965
  Data directory: ${persistence.configuration.happyHomeDir}`));
13880
13966
  try {
13881
- const running = await api.checkIfDaemonRunningAndCleanupStaleState();
13967
+ const running = await index.checkIfDaemonRunningAndCleanupStaleState();
13882
13968
  if (running) {
13883
13969
  console.log(chalk.green("\u2713 Daemon running"));
13884
13970
  } else {
@@ -14440,23 +14526,23 @@ async function handleConnectVendor(vendor, displayName) {
14440
14526
  console.log(chalk.gray(' Please run "very-happy auth login" first'));
14441
14527
  process.exit(1);
14442
14528
  }
14443
- const api$1 = await api.ApiClient.create(credentials);
14529
+ const api = await index.ApiClient.create(credentials);
14444
14530
  if (vendor === "codex") {
14445
14531
  console.log("\u{1F680} Registering Codex token with server");
14446
14532
  const codexAuthTokens = await authenticateCodex();
14447
- await api$1.registerVendorToken("openai", { oauth: codexAuthTokens });
14533
+ await api.registerVendorToken("openai", { oauth: codexAuthTokens });
14448
14534
  console.log("\u2705 Codex token registered with server");
14449
14535
  process.exit(0);
14450
14536
  } else if (vendor === "claude") {
14451
14537
  console.log("\u{1F680} Registering Anthropic token with server");
14452
14538
  const anthropicAuthTokens = await authenticateClaude();
14453
- await api$1.registerVendorToken("anthropic", { oauth: anthropicAuthTokens });
14539
+ await api.registerVendorToken("anthropic", { oauth: anthropicAuthTokens });
14454
14540
  console.log("\u2705 Anthropic token registered with server");
14455
14541
  process.exit(0);
14456
14542
  } else if (vendor === "gemini") {
14457
14543
  console.log("\u{1F680} Registering Gemini token with server");
14458
14544
  const geminiAuthTokens = await authenticateGemini();
14459
- await api$1.registerVendorToken("gemini", { oauth: geminiAuthTokens });
14545
+ await api.registerVendorToken("gemini", { oauth: geminiAuthTokens });
14460
14546
  console.log("\u2705 Gemini token registered with server");
14461
14547
  updateLocalGeminiCredentials(geminiAuthTokens);
14462
14548
  process.exit(0);
@@ -14472,7 +14558,7 @@ async function handleConnectStatus() {
14472
14558
  console.log(chalk.gray(' Please run "very-happy auth login" first'));
14473
14559
  process.exit(1);
14474
14560
  }
14475
- const api$1 = await api.ApiClient.create(credentials);
14561
+ const api = await index.ApiClient.create(credentials);
14476
14562
  const vendors = [
14477
14563
  { key: "gemini", name: "Gemini", display: "Google Gemini" },
14478
14564
  { key: "openai", name: "Codex", display: "OpenAI Codex" },
@@ -14480,7 +14566,7 @@ async function handleConnectStatus() {
14480
14566
  ];
14481
14567
  for (const vendor of vendors) {
14482
14568
  try {
14483
- const token = await api$1.getVendorToken(vendor.key);
14569
+ const token = await api.getVendorToken(vendor.key);
14484
14570
  if (token?.oauth) {
14485
14571
  let userInfo = "";
14486
14572
  if (token.oauth.id_token) {
@@ -14704,9 +14790,9 @@ function resolveLocalSignupBootstrap(configuredMode, configuredInviteCodes, gene
14704
14790
  };
14705
14791
  }
14706
14792
 
14707
- 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-C510dSUn.cjs', document.baseURI).href)));
14793
+ 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-DhwtFJEe.cjs', document.baseURI).href)));
14708
14794
  const __dirname$1 = path.dirname(__filename$1);
14709
- const require_ = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-C510dSUn.cjs', document.baseURI).href)));
14795
+ const require_ = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-DhwtFJEe.cjs', document.baseURI).href)));
14710
14796
  const PRISMA_QUERY_ENGINE_FILES = {
14711
14797
  "arm64-darwin": "libquery_engine-darwin-arm64.dylib.node",
14712
14798
  "x64-darwin": "libquery_engine-darwin.dylib.node",
@@ -15095,7 +15181,7 @@ const DAEMON_READY_TIMEOUT_MS = 5e3;
15095
15181
  const DAEMON_READY_POLL_INTERVAL_MS = 100;
15096
15182
  async function ensureDaemonRunning() {
15097
15183
  persistence.logger.debug("Ensuring Happy background service is running & matches our version...");
15098
- const versionMatches = await api.isDaemonRunningCurrentlyInstalledHappyVersion();
15184
+ const versionMatches = await index.isDaemonRunningCurrentlyInstalledHappyVersion();
15099
15185
  const state = await persistence.readDaemonState();
15100
15186
  const endpointsMatch = Boolean(state) && daemonEndpointsMatch(
15101
15187
  state?.serverUrl,
@@ -15106,9 +15192,9 @@ async function ensureDaemonRunning() {
15106
15192
  if (versionMatches && endpointsMatch) {
15107
15193
  return;
15108
15194
  }
15109
- if (await api.checkIfDaemonRunningAndCleanupStaleState()) {
15195
+ if (await index.checkIfDaemonRunningAndCleanupStaleState()) {
15110
15196
  persistence.logger.debug("Stopping daemon whose version or configured relay no longer matches...");
15111
- await api.stopDaemon();
15197
+ await index.stopDaemon();
15112
15198
  }
15113
15199
  persistence.logger.debug("Starting Happy background service...");
15114
15200
  const daemonProcess = spawnHappyCLI(["daemon", "start-sync"], {
@@ -15119,7 +15205,7 @@ async function ensureDaemonRunning() {
15119
15205
  daemonProcess.unref();
15120
15206
  const deadline = Date.now() + DAEMON_READY_TIMEOUT_MS;
15121
15207
  while (Date.now() < deadline) {
15122
- if (await api.checkIfDaemonRunningAndCleanupStaleState()) {
15208
+ if (await index.checkIfDaemonRunningAndCleanupStaleState()) {
15123
15209
  persistence.logger.debug("Happy background service is ready");
15124
15210
  return;
15125
15211
  }
@@ -15141,14 +15227,14 @@ function maybeEmitSubagentStart(subagent, opts, startedSubagents, activeSubagent
15141
15227
  if (!subagent || startedSubagents.has(subagent)) {
15142
15228
  return;
15143
15229
  }
15144
- envelopes.push(api.createEnvelope("agent", { t: "start" }, { ...opts, subagent }));
15230
+ envelopes.push(index.createEnvelope("agent", { t: "start" }, { ...opts, subagent }));
15145
15231
  startedSubagents.add(subagent);
15146
15232
  activeSubagents.add(subagent);
15147
15233
  }
15148
15234
  function emitSubagentStops(opts, startedSubagents, activeSubagents) {
15149
15235
  const envelopes = [];
15150
15236
  for (const subagent of activeSubagents) {
15151
- envelopes.push(api.createEnvelope("agent", { t: "stop" }, { ...opts, subagent }));
15237
+ envelopes.push(index.createEnvelope("agent", { t: "stop" }, { ...opts, subagent }));
15152
15238
  }
15153
15239
  activeSubagents.clear();
15154
15240
  startedSubagents.clear();
@@ -15244,7 +15330,7 @@ function turnStatus(turn) {
15244
15330
  function emitHistoricalToolCall(envelopes, turn, item, name, title, args, output) {
15245
15331
  const time = turnTimestampMs(turn);
15246
15332
  const opts = { turn: turn.id, time, codexItemId: item.id };
15247
- envelopes.push(api.createEnvelope("agent", {
15333
+ envelopes.push(index.createEnvelope("agent", {
15248
15334
  t: "tool-call-start",
15249
15335
  call: item.id,
15250
15336
  name,
@@ -15256,7 +15342,7 @@ function emitHistoricalToolCall(envelopes, turn, item, name, title, args, output
15256
15342
  id: `${item.id}:start`
15257
15343
  }));
15258
15344
  if (output && output.trim().length > 0) {
15259
- envelopes.push(api.createEnvelope("agent", {
15345
+ envelopes.push(index.createEnvelope("agent", {
15260
15346
  t: "text",
15261
15347
  text: output,
15262
15348
  thinking: true
@@ -15266,7 +15352,7 @@ function emitHistoricalToolCall(envelopes, turn, item, name, title, args, output
15266
15352
  }));
15267
15353
  }
15268
15354
  if ("status" in item && (item.status === "inProgress" || item.status === "running")) return;
15269
- envelopes.push(api.createEnvelope("agent", {
15355
+ envelopes.push(index.createEnvelope("agent", {
15270
15356
  t: "tool-call-end",
15271
15357
  call: item.id
15272
15358
  }, {
@@ -15288,7 +15374,7 @@ function mapCodexCollaborationItem(item, opts = {}, source = "history") {
15288
15374
  agentsStates: item.agentsStates ?? {}
15289
15375
  };
15290
15376
  const startId = source === "live" ? `${item.id}:${item.status ?? "unknown"}:start` : `${item.id}:start`;
15291
- const envelopes = [api.createEnvelope("agent", {
15377
+ const envelopes = [index.createEnvelope("agent", {
15292
15378
  t: "tool-call-start",
15293
15379
  call: item.id,
15294
15380
  name: "CodexCollaboration",
@@ -15297,7 +15383,7 @@ function mapCodexCollaborationItem(item, opts = {}, source = "history") {
15297
15383
  args
15298
15384
  }, { ...opts, id: startId })];
15299
15385
  if (item.status === "completed" || item.status === "failed" || item.status === "interrupted") {
15300
- envelopes.push(api.createEnvelope("agent", {
15386
+ envelopes.push(index.createEnvelope("agent", {
15301
15387
  t: "tool-call-end",
15302
15388
  call: item.id,
15303
15389
  result: { text: JSON.stringify(args, null, 2), isError: item.status !== "completed" }
@@ -15310,7 +15396,7 @@ function mapCodexThreadToSessionEnvelopes(thread) {
15310
15396
  for (const turn of thread.turns ?? []) {
15311
15397
  const startedAt = turnTimestampMs(turn);
15312
15398
  const completedAt = completedTimestampMs(turn);
15313
- envelopes.push(api.createEnvelope("agent", { t: "turn-start" }, {
15399
+ envelopes.push(index.createEnvelope("agent", { t: "turn-start" }, {
15314
15400
  id: `${turn.id}:start`,
15315
15401
  turn: turn.id,
15316
15402
  time: startedAt
@@ -15325,7 +15411,7 @@ function mapCodexThreadToSessionEnvelopes(thread) {
15325
15411
  case "userMessage": {
15326
15412
  const text = textFromInputItems(item.content);
15327
15413
  if (text) {
15328
- envelopes.push(api.createEnvelope("user", { t: "text", text }, {
15414
+ envelopes.push(index.createEnvelope("user", { t: "text", text }, {
15329
15415
  id: item.id,
15330
15416
  time: startedAt,
15331
15417
  codexItemId: item.id
@@ -15336,7 +15422,7 @@ function mapCodexThreadToSessionEnvelopes(thread) {
15336
15422
  case "agentMessage": {
15337
15423
  const text = typeof item.text === "string" ? item.text.trim() : "";
15338
15424
  if (text.length > 0) {
15339
- envelopes.push(api.createEnvelope("agent", { t: "text", text }, {
15425
+ envelopes.push(index.createEnvelope("agent", { t: "text", text }, {
15340
15426
  id: item.id,
15341
15427
  turn: turn.id,
15342
15428
  time: completedAt,
@@ -15348,7 +15434,7 @@ function mapCodexThreadToSessionEnvelopes(thread) {
15348
15434
  case "reasoning": {
15349
15435
  const text = reasoningText(item);
15350
15436
  if (text) {
15351
- envelopes.push(api.createEnvelope("agent", { t: "text", text, thinking: true }, {
15437
+ envelopes.push(index.createEnvelope("agent", { t: "text", text, thinking: true }, {
15352
15438
  id: item.id,
15353
15439
  turn: turn.id,
15354
15440
  time: startedAt,
@@ -15403,7 +15489,7 @@ function mapCodexThreadToSessionEnvelopes(thread) {
15403
15489
  }
15404
15490
  }
15405
15491
  }
15406
- envelopes.push(api.createEnvelope("agent", { t: "turn-end", status: turnStatus(turn) }, {
15492
+ envelopes.push(index.createEnvelope("agent", { t: "turn-end", status: turnStatus(turn) }, {
15407
15493
  id: `${turn.id}:end`,
15408
15494
  turn: turn.id,
15409
15495
  time: completedAt
@@ -15458,7 +15544,7 @@ function mapCodexMcpMessageToSessionEnvelopes(message, state) {
15458
15544
  }
15459
15545
  if (type === "task_started") {
15460
15546
  const turnId = cuid2.createId();
15461
- const turnStart = api.createEnvelope("agent", { t: "turn-start" }, { turn: turnId });
15547
+ const turnStart = index.createEnvelope("agent", { t: "turn-start" }, { turn: turnId });
15462
15548
  startedSubagents.clear();
15463
15549
  activeSubagents.clear();
15464
15550
  providerSubagentToSessionSubagent.clear();
@@ -15489,7 +15575,7 @@ function mapCodexMcpMessageToSessionEnvelopes(message, state) {
15489
15575
  providerSubagentToSessionSubagent,
15490
15576
  envelopes: [
15491
15577
  ...emitSubagentStops(lifecycleOpts, startedSubagents, activeSubagents),
15492
- api.createEnvelope("agent", {
15578
+ index.createEnvelope("agent", {
15493
15579
  t: "turn-end",
15494
15580
  status: pickTurnEndStatus(message, type)
15495
15581
  }, lifecycleOpts)
@@ -15519,7 +15605,7 @@ function mapCodexMcpMessageToSessionEnvelopes(message, state) {
15519
15605
  }
15520
15606
  const envelopes = [];
15521
15607
  maybeEmitSubagentStart(subagent, opts, startedSubagents, activeSubagents, envelopes);
15522
- envelopes.push(api.createEnvelope("agent", { t: "text", text: message.message }, opts));
15608
+ envelopes.push(index.createEnvelope("agent", { t: "text", text: message.message }, opts));
15523
15609
  return {
15524
15610
  currentTurnId: state.currentTurnId,
15525
15611
  startedSubagents,
@@ -15541,7 +15627,7 @@ function mapCodexMcpMessageToSessionEnvelopes(message, state) {
15541
15627
  }
15542
15628
  const envelopes = [];
15543
15629
  maybeEmitSubagentStart(subagent, opts, startedSubagents, activeSubagents, envelopes);
15544
- envelopes.push(api.createEnvelope("agent", { t: "text", text, thinking: true }, opts));
15630
+ envelopes.push(index.createEnvelope("agent", { t: "text", text, thinking: true }, opts));
15545
15631
  return {
15546
15632
  currentTurnId: state.currentTurnId,
15547
15633
  startedSubagents,
@@ -15558,7 +15644,7 @@ function mapCodexMcpMessageToSessionEnvelopes(message, state) {
15558
15644
  const envelopes = [];
15559
15645
  maybeEmitSubagentStart(subagent, opts, startedSubagents, activeSubagents, envelopes);
15560
15646
  envelopes.push(
15561
- api.createEnvelope("agent", {
15647
+ index.createEnvelope("agent", {
15562
15648
  t: "tool-call-start",
15563
15649
  call,
15564
15650
  name: "CodexBash",
@@ -15579,7 +15665,7 @@ function mapCodexMcpMessageToSessionEnvelopes(message, state) {
15579
15665
  const call = pickCallId(message);
15580
15666
  const envelopes = [];
15581
15667
  maybeEmitSubagentStart(subagent, opts, startedSubagents, activeSubagents, envelopes);
15582
- envelopes.push(api.createEnvelope("agent", { t: "tool-call-end", call }, opts));
15668
+ envelopes.push(index.createEnvelope("agent", { t: "tool-call-end", call }, opts));
15583
15669
  return {
15584
15670
  currentTurnId: state.currentTurnId,
15585
15671
  startedSubagents,
@@ -15595,7 +15681,7 @@ function mapCodexMcpMessageToSessionEnvelopes(message, state) {
15595
15681
  const envelopes = [];
15596
15682
  maybeEmitSubagentStart(subagent, opts, startedSubagents, activeSubagents, envelopes);
15597
15683
  envelopes.push(
15598
- api.createEnvelope("agent", {
15684
+ index.createEnvelope("agent", {
15599
15685
  t: "tool-call-start",
15600
15686
  call,
15601
15687
  name: "CodexPatch",
@@ -15619,7 +15705,7 @@ function mapCodexMcpMessageToSessionEnvelopes(message, state) {
15619
15705
  const call = pickCallId(message);
15620
15706
  const envelopes = [];
15621
15707
  maybeEmitSubagentStart(subagent, opts, startedSubagents, activeSubagents, envelopes);
15622
- envelopes.push(api.createEnvelope("agent", { t: "tool-call-end", call }, opts));
15708
+ envelopes.push(index.createEnvelope("agent", { t: "tool-call-end", call }, opts));
15623
15709
  return {
15624
15710
  currentTurnId: state.currentTurnId,
15625
15711
  startedSubagents,
@@ -15640,7 +15726,7 @@ function mapCodexProcessorMessageToSessionEnvelopes(message, state) {
15640
15726
  const toolLikeMessage = message;
15641
15727
  const opts = buildEnvelopeOptions(state.currentTurnId);
15642
15728
  if (message.type === "reasoning") {
15643
- return [api.createEnvelope("agent", {
15729
+ return [index.createEnvelope("agent", {
15644
15730
  t: "text",
15645
15731
  text: message.message,
15646
15732
  thinking: true
@@ -15648,7 +15734,7 @@ function mapCodexProcessorMessageToSessionEnvelopes(message, state) {
15648
15734
  }
15649
15735
  if (message.type === "tool-call") {
15650
15736
  const title = typeof toolLikeMessage.input?.title === "string" ? toolLikeMessage.input.title : `${toolLikeMessage.name || "Tool"} call`;
15651
- return [api.createEnvelope("agent", {
15737
+ return [index.createEnvelope("agent", {
15652
15738
  t: "tool-call-start",
15653
15739
  call: toolLikeMessage.callId,
15654
15740
  name: toolLikeMessage.name || "unknown",
@@ -15661,13 +15747,13 @@ function mapCodexProcessorMessageToSessionEnvelopes(message, state) {
15661
15747
  const envelopes = [];
15662
15748
  const content = toolLikeMessage.output?.content;
15663
15749
  if (typeof content === "string" && content.trim().length > 0) {
15664
- envelopes.push(api.createEnvelope("agent", {
15750
+ envelopes.push(index.createEnvelope("agent", {
15665
15751
  t: "text",
15666
15752
  text: content,
15667
15753
  thinking: true
15668
15754
  }, opts));
15669
15755
  }
15670
- envelopes.push(api.createEnvelope("agent", {
15756
+ envelopes.push(index.createEnvelope("agent", {
15671
15757
  t: "tool-call-end",
15672
15758
  call: toolLikeMessage.callId
15673
15759
  }, opts));
@@ -16356,17 +16442,17 @@ function createOfflineSessionStub(sessionTag) {
16356
16442
  }
16357
16443
 
16358
16444
  function setupOfflineReconnection(opts) {
16359
- const { api: api$1, sessionTag, metadata, state, response, onSessionSwap } = opts;
16445
+ const { api, sessionTag, metadata, state, response, onSessionSwap } = opts;
16360
16446
  let session;
16361
16447
  let reconnectionHandle = null;
16362
16448
  if (!response) {
16363
16449
  session = createOfflineSessionStub(sessionTag);
16364
- reconnectionHandle = api.startOfflineReconnection({
16450
+ reconnectionHandle = index.startOfflineReconnection({
16365
16451
  serverUrl: persistence.configuration.serverUrl,
16366
16452
  onReconnected: async () => {
16367
- const resp = await api$1.getOrCreateSession({ tag: sessionTag, metadata, state });
16453
+ const resp = await api.getOrCreateSession({ tag: sessionTag, metadata, state });
16368
16454
  if (!resp) throw new Error("Server unavailable");
16369
- const realSession = api$1.sessionSyncClient(resp);
16455
+ const realSession = api.sessionSyncClient(resp);
16370
16456
  onSessionSwap(realSession);
16371
16457
  return realSession;
16372
16458
  },
@@ -16376,7 +16462,7 @@ function setupOfflineReconnection(opts) {
16376
16462
  });
16377
16463
  return { session, reconnectionHandle, isOffline: true };
16378
16464
  } else {
16379
- session = api$1.sessionSyncClient(response, opts.sessionClientOptions);
16465
+ session = api.sessionSyncClient(response, opts.sessionClientOptions);
16380
16466
  return { session, reconnectionHandle: null, isOffline: false };
16381
16467
  }
16382
16468
  }
@@ -16626,7 +16712,7 @@ function buildCodexTurnPrompt(opts) {
16626
16712
  parts.push(opts.message);
16627
16713
  if (opts.includeTitleInstruction) {
16628
16714
  parts.push(CHANGE_TITLE_INSTRUCTION);
16629
- parts.push(api.BUILTIN_TODO_DISCOVERY);
16715
+ parts.push(index.BUILTIN_TODO_DISCOVERY);
16630
16716
  }
16631
16717
  return parts.join("\n\n");
16632
16718
  }
@@ -16694,8 +16780,8 @@ async function runCodex(opts) {
16694
16780
  process.exit(1);
16695
16781
  }
16696
16782
  const sessionTag = node_crypto.randomUUID();
16697
- api.connectionState.setBackend("Codex");
16698
- const api$1 = await api.ApiClient.create(opts.credentials);
16783
+ index.connectionState.setBackend("Codex");
16784
+ const api = await index.ApiClient.create(opts.credentials);
16699
16785
  persistence.logger.debug(`[codex] Starting with options: startedBy=${opts.startedBy || "terminal"}`);
16700
16786
  const settings = await persistence.readSettings();
16701
16787
  let machineId = settings?.machineId;
@@ -16705,7 +16791,7 @@ async function runCodex(opts) {
16705
16791
  process.exit(1);
16706
16792
  }
16707
16793
  persistence.logger.debug(`Using machineId: ${machineId}`);
16708
- await api$1.getOrCreateMachine({
16794
+ await api.getOrCreateMachine({
16709
16795
  machineId,
16710
16796
  metadata: initialMachineMetadata
16711
16797
  });
@@ -16749,17 +16835,17 @@ async function runCodex(opts) {
16749
16835
  agentStateVersion: parseInt(reconnectAgentStateVersion || "0", 10)
16750
16836
  };
16751
16837
  } else {
16752
- response = await api$1.getOrCreateSession({ tag: sessionTag, metadata, state });
16838
+ response = await api.getOrCreateSession({ tag: sessionTag, metadata, state });
16753
16839
  }
16754
16840
  if (response) {
16755
16841
  await claimSessionOrExit(response.id, { takeover: !!reconnectSessionId, flavor: "codex" });
16756
16842
  }
16757
- if (reconnectSessionId && response && !await api$1.reactivateSession(response.id)) {
16843
+ if (reconnectSessionId && response && !await api.reactivateSession(response.id)) {
16758
16844
  throw new Error(`Failed to reactivate archived session ${response.id}`);
16759
16845
  }
16760
16846
  let reconnectSeeded = false;
16761
16847
  if (reconnectSessionId && response) {
16762
- const snapshot = await api$1.getSession(response.id, response.encryptionKey, response.encryptionVariant);
16848
+ const snapshot = await api.getSession(response.id, response.encryptionKey, response.encryptionVariant);
16763
16849
  if (snapshot.ok) {
16764
16850
  response = applyServerSnapshot(response, snapshot.session);
16765
16851
  reconnectSeeded = true;
@@ -16776,7 +16862,7 @@ async function runCodex(opts) {
16776
16862
  let abortInProgress = null;
16777
16863
  let turnActive = false;
16778
16864
  const { session: initialSession, reconnectionHandle } = setupOfflineReconnection({
16779
- api: api$1,
16865
+ api,
16780
16866
  sessionTag,
16781
16867
  metadata,
16782
16868
  state,
@@ -16799,7 +16885,7 @@ async function runCodex(opts) {
16799
16885
  if (response) {
16800
16886
  try {
16801
16887
  persistence.logger.debug(`[START] Reporting session ${response.id} to daemon`);
16802
- const result = await api.notifyDaemonSessionStarted(response.id, metadata, {
16888
+ const result = await index.notifyDaemonSessionStarted(response.id, metadata, {
16803
16889
  encryptionKey: persistence.encodeBase64(response.encryptionKey),
16804
16890
  encryptionVariant: response.encryptionVariant,
16805
16891
  seq: response.seq,
@@ -16932,7 +17018,7 @@ async function runCodex(opts) {
16932
17018
  const sendReady = () => {
16933
17019
  session.sendSessionEvent({ type: "ready" });
16934
17020
  try {
16935
- api$1.push().sendSessionNotification({
17021
+ api.push().sendSessionNotification({
16936
17022
  kind: "done",
16937
17023
  metadata: session.getMetadata(),
16938
17024
  data: {
@@ -17062,7 +17148,7 @@ async function runCodex(opts) {
17062
17148
  }
17063
17149
  process.stdin.setEncoding("utf8");
17064
17150
  }
17065
- client = new api.CodexAppServerClient(sandboxConfig);
17151
+ client = new index.CodexAppServerClient(sandboxConfig);
17066
17152
  const idleRelease = new CodexIdleReleaseTimer({
17067
17153
  delayMs: resolveCodexIdleReleaseMs(process.env[CODEX_IDLE_RELEASE_ENV]),
17068
17154
  isIdle: () => shouldReleaseIdleCodex({
@@ -17621,7 +17707,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
17621
17707
  return;
17622
17708
  } else if (subcommand === "install-terminal-hooks") {
17623
17709
  try {
17624
- const { installTerminalHooks, parseTerminalHooksArgs, TERMINAL_HOOKS_HELP } = await Promise.resolve().then(function () { return require('./installTerminalHooks-C_jraM1j.cjs'); });
17710
+ const { installTerminalHooks, parseTerminalHooksArgs, TERMINAL_HOOKS_HELP } = await Promise.resolve().then(function () { return require('./installTerminalHooks-DspFGxBI.cjs'); });
17625
17711
  const command = parseTerminalHooksArgs(args.slice(1));
17626
17712
  if (command.action === "help") {
17627
17713
  console.log(TERMINAL_HOOKS_HELP);
@@ -17636,9 +17722,18 @@ Conversation history is preserved on the server, but in-flight tool calls are in
17636
17722
  }
17637
17723
  process.exit(1);
17638
17724
  }
17725
+ } else if (subcommand === "agent-home") {
17726
+ try {
17727
+ const { parseAgentHomeArgs, runAgentHomeCommand } = await Promise.resolve().then(function () { return require('./agentHome-CGl7FF7a.cjs'); });
17728
+ await runAgentHomeCommand(parseAgentHomeArgs(args.slice(1)));
17729
+ process.exit(0);
17730
+ } catch (error) {
17731
+ console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
17732
+ process.exit(1);
17733
+ }
17639
17734
  } else if (subcommand === "spawn") {
17640
17735
  try {
17641
- const { handleSpawnCommand } = await Promise.resolve().then(function () { return require('./spawn-DIyFOn3W.cjs'); });
17736
+ const { handleSpawnCommand } = await Promise.resolve().then(function () { return require('./spawn-BqgZc7YE.cjs'); });
17642
17737
  await handleSpawnCommand(args.slice(1));
17643
17738
  } catch (error) {
17644
17739
  console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
@@ -17650,7 +17745,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
17650
17745
  return;
17651
17746
  } else if (subcommand === "sessions") {
17652
17747
  try {
17653
- const { handleSessionsCommand } = await Promise.resolve().then(function () { return require('./sessions-DyQXMN-8.cjs'); });
17748
+ const { handleSessionsCommand } = await Promise.resolve().then(function () { return require('./sessions-WBowxNO-.cjs'); });
17654
17749
  await handleSessionsCommand(args.slice(1));
17655
17750
  } catch (error) {
17656
17751
  console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
@@ -17662,7 +17757,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
17662
17757
  return;
17663
17758
  } else if (subcommand === "send") {
17664
17759
  try {
17665
- const { handleSendCommand } = await Promise.resolve().then(function () { return require('./send-DGVwmB-p.cjs'); });
17760
+ const { handleSendCommand } = await Promise.resolve().then(function () { return require('./send-LBjLfAos.cjs'); });
17666
17761
  await handleSendCommand(args.slice(1));
17667
17762
  } catch (error) {
17668
17763
  console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
@@ -17768,9 +17863,9 @@ Conversation history is preserved on the server, but in-flight tool calls are in
17768
17863
  if (geminiSubcommand === "project" && args[2] === "set" && args[3]) {
17769
17864
  const projectId = args[3];
17770
17865
  try {
17771
- const { saveGoogleCloudProjectToConfig } = await Promise.resolve().then(function () { return require('./config-CfqWoHmO.cjs'); });
17772
- const { readCredentialsForConfiguredRelay: readCredentialsForConfiguredRelay2 } = await Promise.resolve().then(function () { return require('./limits-B3oVgqBJ.cjs'); }).then(function (n) { return n.persistence; });
17773
- const { ApiClient: ApiClient2 } = await Promise.resolve().then(function () { return require('./types-6__wqmmP.cjs'); }).then(function (n) { return n.api; });
17866
+ const { saveGoogleCloudProjectToConfig } = await Promise.resolve().then(function () { return require('./config-CPfFuHP6.cjs'); });
17867
+ const { readCredentialsForConfiguredRelay: readCredentialsForConfiguredRelay2 } = await Promise.resolve().then(function () { return require('./limits-DGZB-OVl.cjs'); }).then(function (n) { return n.persistence; });
17868
+ const { ApiClient: ApiClient2 } = await Promise.resolve().then(function () { return require('./types-Bqo68u61.cjs'); }).then(function (n) { return n.api; });
17774
17869
  let userEmail = void 0;
17775
17870
  try {
17776
17871
  const credentials = await readCredentialsForConfiguredRelay2();
@@ -17801,7 +17896,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
17801
17896
  }
17802
17897
  if (geminiSubcommand === "project" && args[2] === "get") {
17803
17898
  try {
17804
- const { readGeminiLocalConfig } = await Promise.resolve().then(function () { return require('./config-CfqWoHmO.cjs'); });
17899
+ const { readGeminiLocalConfig } = await Promise.resolve().then(function () { return require('./config-CPfFuHP6.cjs'); });
17805
17900
  const config = readGeminiLocalConfig();
17806
17901
  if (config.googleCloudProject) {
17807
17902
  console.log(`Current Google Cloud Project: ${config.googleCloudProject}`);
@@ -17841,7 +17936,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
17841
17936
  process.exit(0);
17842
17937
  }
17843
17938
  try {
17844
- const { runGemini } = await Promise.resolve().then(function () { return require('./runGemini-C6qMFzcn.cjs'); });
17939
+ const { runGemini } = await Promise.resolve().then(function () { return require('./runGemini-ChCHjnIh.cjs'); });
17845
17940
  let startedBy = void 0;
17846
17941
  for (let i = 1; i < args.length; i++) {
17847
17942
  if (args[i] === "--started-by") {
@@ -17864,7 +17959,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
17864
17959
  } else if (subcommand === "pi") {
17865
17960
  if (args[1] === "--terminal") {
17866
17961
  try {
17867
- const { runPiTerminal } = await Promise.resolve().then(function () { return require('./piTerminal-Dyc_9pGP.cjs'); });
17962
+ const { runPiTerminal } = await Promise.resolve().then(function () { return require('./piTerminal-6P00O_w8.cjs'); });
17868
17963
  process.exitCode = await runPiTerminal(args.slice(2));
17869
17964
  } catch (error) {
17870
17965
  console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
@@ -17881,7 +17976,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
17881
17976
  }
17882
17977
  };
17883
17978
  try {
17884
- const { runAcp, resolveAcpAgentConfig } = await Promise.resolve().then(function () { return require('./index-Bj68y6ee.cjs'); });
17979
+ const { runAcp, resolveAcpAgentConfig } = await Promise.resolve().then(function () { return require('./index-avfJgX4p.cjs'); });
17885
17980
  const parsed = parsePiRunnerArgs(args.slice(1));
17886
17981
  const resolved = resolveAcpAgentConfig(["pi", ...parsed.passthrough]);
17887
17982
  const { credentials } = await authAndSetupMachineIfNeeded();
@@ -17909,7 +18004,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
17909
18004
  return;
17910
18005
  } else if (subcommand === "acp") {
17911
18006
  try {
17912
- const { runAcp, resolveAcpAgentConfig } = await Promise.resolve().then(function () { return require('./index-Bj68y6ee.cjs'); });
18007
+ const { runAcp, resolveAcpAgentConfig } = await Promise.resolve().then(function () { return require('./index-avfJgX4p.cjs'); });
17913
18008
  let startedBy = void 0;
17914
18009
  let verbose = false;
17915
18010
  const acpArgs = [];
@@ -17949,7 +18044,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
17949
18044
  return;
17950
18045
  } else if (subcommand === "openclaw") {
17951
18046
  try {
17952
- const { runOpenClaw } = await Promise.resolve().then(function () { return require('./runOpenClaw-C2_aCP7v.cjs'); });
18047
+ const { runOpenClaw } = await Promise.resolve().then(function () { return require('./runOpenClaw-Cc4_zmHz.cjs'); });
17953
18048
  let startedBy = void 0;
17954
18049
  let verbose = false;
17955
18050
  let gatewayUrl;
@@ -18000,7 +18095,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
18000
18095
  return;
18001
18096
  } else if (subcommand === "todo") {
18002
18097
  try {
18003
- const { handleTodoCommand } = await Promise.resolve().then(function () { return require('./todo-Du6pjwx_.cjs'); });
18098
+ const { handleTodoCommand } = await Promise.resolve().then(function () { return require('./todo-DeouLiGa.cjs'); });
18004
18099
  await handleTodoCommand(args.slice(1));
18005
18100
  } catch (error) {
18006
18101
  console.error(JSON.stringify({ error: error instanceof Error ? error.message : "Todo command failed" }));
@@ -18009,7 +18104,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
18009
18104
  return;
18010
18105
  } else if (subcommand === "teams") {
18011
18106
  try {
18012
- const { handleTeamsCommand } = await Promise.resolve().then(function () { return require('./teams-QOkGFjkJ.cjs'); });
18107
+ const { handleTeamsCommand } = await Promise.resolve().then(function () { return require('./teams-eIUxGmqg.cjs'); });
18013
18108
  await handleTeamsCommand(args.slice(1));
18014
18109
  } catch (error) {
18015
18110
  console.error(error instanceof Error ? error.message : "Teams command failed");
@@ -18018,7 +18113,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
18018
18113
  return;
18019
18114
  } else if (subcommand === "mcp" && (args.length === 1 || args.length === 2 && args[1] === "--terminal-tools")) {
18020
18115
  try {
18021
- const { handleMcpCommand } = await Promise.resolve().then(function () { return require('./mcp-G-3lL_KH.cjs'); });
18116
+ const { handleMcpCommand } = await Promise.resolve().then(function () { return require('./mcp-BioGrTC_.cjs'); });
18022
18117
  await handleMcpCommand(args[1] === "--terminal-tools");
18023
18118
  } catch (error) {
18024
18119
  process.stderr.write(`[very-happy mcp] Fatal: ${error instanceof Error ? error.message : String(error)}
@@ -18041,7 +18136,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
18041
18136
  const daemonSubcommand = args[1];
18042
18137
  if (daemonSubcommand === "list") {
18043
18138
  try {
18044
- const sessions = await api.listDaemonSessions();
18139
+ const sessions = await index.listDaemonSessions();
18045
18140
  if (sessions.length === 0) {
18046
18141
  console.log("No active sessions this daemon is aware of (they might have been started by a previous version of the daemon)");
18047
18142
  } else {
@@ -18059,7 +18154,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
18059
18154
  process.exit(1);
18060
18155
  }
18061
18156
  try {
18062
- const success = await api.stopDaemonSession(sessionId);
18157
+ const success = await index.stopDaemonSession(sessionId);
18063
18158
  console.log(success ? "Session stopped" : "Failed to stop session");
18064
18159
  } catch (error) {
18065
18160
  console.log("No daemon running");
@@ -18067,7 +18162,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
18067
18162
  return;
18068
18163
  } else if (daemonSubcommand === "start") {
18069
18164
  const currentState = await persistence.readDaemonState();
18070
- const running = await api.checkIfDaemonRunningAndCleanupStaleState();
18165
+ const running = await index.checkIfDaemonRunningAndCleanupStaleState();
18071
18166
  const currentDaemonMatches = currentState && currentState.startedWithCliVersion === persistence.configuration.currentCliVersion && daemonEndpointsMatch(
18072
18167
  currentState.serverUrl,
18073
18168
  currentState.webappUrl,
@@ -18076,7 +18171,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
18076
18171
  );
18077
18172
  if (running && !currentDaemonMatches) {
18078
18173
  console.log("Configured relay or CLI version changed; restarting the existing daemon");
18079
- await api.stopDaemon();
18174
+ await index.stopDaemon();
18080
18175
  }
18081
18176
  const child = spawnHappyCLI(["daemon", "start-sync"], {
18082
18177
  detached: true,
@@ -18086,7 +18181,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
18086
18181
  child.unref();
18087
18182
  let started = false;
18088
18183
  for (let i = 0; i < 50; i++) {
18089
- if (await api.checkIfDaemonRunningAndCleanupStaleState()) {
18184
+ if (await index.checkIfDaemonRunningAndCleanupStaleState()) {
18090
18185
  started = true;
18091
18186
  break;
18092
18187
  }
@@ -18103,7 +18198,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
18103
18198
  await startDaemon();
18104
18199
  process.exit(0);
18105
18200
  } else if (daemonSubcommand === "stop") {
18106
- await api.stopDaemon();
18201
+ await index.stopDaemon();
18107
18202
  process.exit(0);
18108
18203
  } else if (daemonSubcommand === "status") {
18109
18204
  await runDoctorDaemon();
@@ -18248,6 +18343,8 @@ ${chalk.bold("Usage:")}
18248
18343
  very-happy install-terminal-hooks
18249
18344
  Install optional Claude terminal mirror hooks
18250
18345
  (add --remove to uninstall them)
18346
+ very-happy agent-home Show or pin where Claude Code / Codex keep their
18347
+ conversations on this machine (agent-home --help)
18251
18348
  very-happy connect Connect AI vendor API keys
18252
18349
  very-happy todo Built-in Todos and official agent skill (todo --help)
18253
18350
  very-happy sandbox Configure and manage OS-level sandboxing
@@ -18363,9 +18460,9 @@ ${chalk.bold("Examples:")}
18363
18460
  }
18364
18461
  console.log(chalk.blue("\u{1F4F1} Sending push notification..."));
18365
18462
  try {
18366
- const api$1 = await api.ApiClient.create(credentials);
18463
+ const api = await index.ApiClient.create(credentials);
18367
18464
  const notificationTitle = title || "Happy";
18368
- api$1.push().sendToAllDevices(
18465
+ api.push().sendToAllDevices(
18369
18466
  notificationTitle,
18370
18467
  message,
18371
18468
  {