very-happy-cli 0.2.150 → 0.2.151

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 (50) hide show
  1. package/dist/{AcpBackend-C-dhGJgd.mjs → AcpBackend-BjTA5gUB.mjs} +2 -2
  2. package/dist/{AcpBackend-CXawaWWx.cjs → AcpBackend-blE9IEod.cjs} +2 -2
  3. package/dist/{AcpSessionManager-DKOtSqJc.mjs → AcpSessionManager-D-9mrp40.mjs} +1 -1
  4. package/dist/{AcpSessionManager-TrwEZR7y.cjs → AcpSessionManager-bF8PYu_B.cjs} +1 -1
  5. package/dist/{agentGuidance-Dla-BXO8.cjs → agentGuidance-BXa9ikrZ.cjs} +1 -1
  6. package/dist/{agentGuidance-DrfhtVP1.mjs → agentGuidance-Dvo3cZMW.mjs} +1 -1
  7. package/dist/{agentHome-Dm-Wjs38.mjs → agentHome-CeFDNzvq.mjs} +2 -2
  8. package/dist/{agentHome-rylNIkix.cjs → agentHome-D6MSfwnp.cjs} +2 -2
  9. package/dist/codex/happyMcpStdioBridge.cjs +2 -2
  10. package/dist/codex/happyMcpStdioBridge.mjs +2 -2
  11. package/dist/{config-Dhu6LU0h.mjs → config-C-A1XF62.mjs} +4 -4
  12. package/dist/{config-CgPu2wtS.cjs → config-Cadw1sAk.cjs} +4 -4
  13. package/dist/{index-DEVkDRas.cjs → index-BKGspSWk.cjs} +7 -7
  14. package/dist/{index-CpNYvMTJ.mjs → index-CIyjJy8D.mjs} +214 -59
  15. package/dist/{index-K6mUS0jF.cjs → index-CqtfRzug.cjs} +220 -62
  16. package/dist/{index-CzpooENj.mjs → index-DEp6CmmS.mjs} +8 -8
  17. package/dist/{index-BsYH1sjV.mjs → index-DYQgcgL2.mjs} +4 -4
  18. package/dist/{index-DvfCUuDK.cjs → index-vyRqLjDv.cjs} +4 -4
  19. package/dist/index.cjs +4 -4
  20. package/dist/index.mjs +4 -4
  21. package/dist/{installTerminalHooks-NIbsQ1wi.cjs → installTerminalHooks-Bf_adbl3.cjs} +4 -4
  22. package/dist/{installTerminalHooks-BF_tmw9V.mjs → installTerminalHooks-Ch_yTtEA.mjs} +4 -4
  23. package/dist/lib.cjs +2 -2
  24. package/dist/lib.mjs +2 -2
  25. package/dist/{limits-FThmm7WR.mjs → limits-DS-bnYYp.mjs} +7 -7
  26. package/dist/{limits-Dyma1REp.cjs → limits-DwcY3kyi.cjs} +7 -7
  27. package/dist/{mcp-_TVUSg8W.cjs → mcp-CMxEZ6-0.cjs} +4 -4
  28. package/dist/{mcp-DzydgXpf.mjs → mcp-zu8n8TkR.mjs} +4 -4
  29. package/dist/{piRuntime-ACOhil6t.mjs → piRuntime-Cu6cXZ6N.mjs} +2 -2
  30. package/dist/{piRuntime-CSAiJk0X.cjs → piRuntime-D3ny0mVg.cjs} +2 -2
  31. package/dist/{piTerminal-BlE4vbvZ.mjs → piTerminal-M677UP7y.mjs} +6 -6
  32. package/dist/{piTerminal-DHxGB3Ic.cjs → piTerminal-kDSd_r9X.cjs} +6 -6
  33. package/dist/{runGemini-BMYCU16c.cjs → runGemini-DuwdVV1O.cjs} +6 -6
  34. package/dist/{runGemini-D5IV1MoF.mjs → runGemini-DvJwQVGp.mjs} +6 -6
  35. package/dist/{runOpenClaw-CWPXrKMJ.mjs → runOpenClaw-BG82bF18.mjs} +5 -5
  36. package/dist/{runOpenClaw-Qs4eFtcS.cjs → runOpenClaw-BsvtCE_H.cjs} +5 -5
  37. package/dist/{send-qXWGilm8.cjs → send-aUkjhey7.cjs} +20 -6
  38. package/dist/{send-Dv0km8UI.mjs → send-o6WM-1G8.mjs} +20 -6
  39. package/dist/{sessions-CpIdDhH7.cjs → sessions-B3vP18kz.cjs} +56 -10
  40. package/dist/{sessions-DoULfKui.mjs → sessions-DlU3foY_.mjs} +56 -10
  41. package/dist/{spawn-DqzG1bTH.cjs → spawn-DH6_p4-f.cjs} +166 -27
  42. package/dist/spawn-DxHIIqhi.mjs +397 -0
  43. package/dist/{teams-ByEgUzsH.cjs → teams-BW8D1n3o.cjs} +4 -4
  44. package/dist/{teams-4mhNh5cj.mjs → teams-DoAA_CcN.mjs} +4 -4
  45. package/dist/{todo-D7SDXL0c.cjs → todo-Bcc2XxGh.cjs} +3 -3
  46. package/dist/{todo-C9IAUf0K.mjs → todo-BhJbG5eq.mjs} +3 -3
  47. package/dist/{types-BD542hb1.mjs → types-BN3eiipi.mjs} +46 -3
  48. package/dist/{types-D2Gkpe0N.cjs → types-CPubg05Z.cjs} +52 -2
  49. package/package.json +7 -7
  50. package/dist/spawn-DQuOmUP7.mjs +0 -258
@@ -1,14 +1,14 @@
1
1
  import{createRequire as _pkgrollCR}from"node:module";const require=_pkgrollCR(import.meta.url);import chalk from 'chalk';
2
2
  import os, { homedir, userInfo, tmpdir } from 'node:os';
3
3
  import { randomUUID, randomInt, randomBytes, createHash as createHash$1, timingSafeEqual } from 'node:crypto';
4
- import { v as notifyDaemonSessionEvent, w as getProjectPath, o as BUILTIN_TODO_DISCOVERY, x as initializeSandbox, y as wrapCommand, t as contentLogMetadata, I as InvalidateSync, R as RawJSONLinesSchema, u as delay, z as AsyncLock, S as STREAM_DELTA_MAX_CHARS, M as MAX_CHAT_ATTACHMENT_SOURCE_BYTES, C as notifyDaemonClaudeAuthFailed, D as commandOnPath, c as checkIfDaemonRunningAndCleanupStaleState, E as deriveLocalCliUpdateSummary, F as AGENT_VERSION_SOURCES, G as isClaudeSessionId, H as getLocalHappyAgentCredentialPath, J as readLocalHappyAgentCredentials, K as parseExactVersion, L as compareExactVersions, N as extractCompleteLines, O as decideBackfill, P as parseTerminalHookPayload, Q as tmuxArgs, T as scrubTmuxClientEnv, U as decideMirrorBinding, V as MIRROR_BACKFILL_LINES_DEFAULT, W as mirrorLineKey, X as mirrorLocalId, Y as listDaemonSessions, Z as stopDaemonSession, _ as detectCLIAvailability, $ as detectResumeSupport, a0 as refreshAgentHomes, d as describeAgentHome, a1 as isDaemonRunningCurrentlyInstalledHappyVersion, a2 as stopDaemon, a3 as TurnActivityTracker, a4 as summarizeSpawnSessionForLog, a5 as locateClaudeConversation, a6 as agentHomeSpawnEnv, a7 as shellescape, A as ApiClient, a8 as fetchCliUpdateState, a9 as resolveCliUpdateCheckInterval, aa as DEFAULT_CLI_UPDATE_CHECK_INTERVAL_MS, ab as cleanupDaemonState, i as isValidSessionId, s as spawnDaemonSession, ac as listVhTerminals, ad as isValidTerminalId, ae as readVhTerminal, af as sendToVhTerminal, ag as ContextUsageSchema, ah as TITLE_PROMPT_PREFIX, ai as BOARD_ANALYZER_PROMPT_PREFIX, m as connectionState, aj as startOfflineReconnection, n as notifyDaemonSessionStarted, g as createEnvelope, ak as CodexAppServerClient } from './types-BD542hb1.mjs';
5
- import { l as logger, F as ensurePrivateDirectory, G as hardenPrivateFile, c as configuration, p as packageJson, r as readSettings, H as readCredentials, x as credentialRelayProblem, o as readDaemonState, g as encodeBase64, I as readSettingsOutcome, u as updateSettings, J as encodeBase64Url, m as decodeBase64, K as writeCredentialsLegacy, L as writeCredentialsDataKey, e as readCredentialsForConfiguredRelay, j as encrypt, d as readPersistedSessions, w as writePrivateFileSync, M as decryptWithDataKey, N as decryptLegacy, O as persistSession, k as decrypt, h as ensurePrivateDirectorySync, P as acquireDaemonLock, Q as deletePersistedSessions, R as writeDaemonState, S as writeSettings, T as releaseDaemonLock, C as CLIPBOARD_TOOL_NAME, a as CLIPBOARD_TOOL_TITLE, b as CLIPBOARD_TOOL_DESCRIPTION, f as CLIPBOARD_MAX_BYTES, U as clearCredentials, V as clearMachineId, W as SandboxConfigSchema, X as getLatestDaemonLog } from './limits-FThmm7WR.mjs';
4
+ import { H as notifyDaemonSessionEvent, q as getProjectPath, z as BUILTIN_TODO_DISCOVERY, I as initializeSandbox, J as wrapCommand, E as contentLogMetadata, K as InvalidateSync, R as RawJSONLinesSchema, G as delay, L as AsyncLock, S as STREAM_DELTA_MAX_CHARS, M as MAX_CHAT_ATTACHMENT_SOURCE_BYTES, N as notifyDaemonClaudeAuthFailed, O as commandOnPath, u as checkIfDaemonRunningAndCleanupStaleState, P as deriveLocalCliUpdateSummary, Q as AGENT_VERSION_SOURCES, T as isClaudeSessionId, U as getLocalHappyAgentCredentialPath, V as readLocalHappyAgentCredentials, W as parseExactVersion, X as compareExactVersions, Y as extractCompleteLines, Z as decideBackfill, _ as parseTerminalHookPayload, $ as tmuxArgs, a0 as scrubTmuxClientEnv, a1 as decideMirrorBinding, a2 as MIRROR_BACKFILL_LINES_DEFAULT, a3 as mirrorLineKey, a4 as mirrorLocalId, a5 as listDaemonSessions, w as stopDaemonSession, a6 as detectCLIAvailability, a7 as detectResumeSupport, a8 as refreshAgentHomes, d as describeAgentHome, a9 as isDaemonRunningCurrentlyInstalledHappyVersion, aa as stopDaemon, ab as TurnActivityTracker, ac as summarizeSpawnSessionForLog, ad as locateClaudeConversation, ae as agentHomeSpawnEnv, af as shellescape, A as ApiClient, ag as fetchCliUpdateState, ah as resolveCliUpdateCheckInterval, ai as DEFAULT_CLI_UPDATE_CHECK_INTERVAL_MS, aj as cleanupDaemonState, i as isValidSessionId, v as spawnDaemonSession, ak as listVhTerminals, al as isValidTerminalId, am as readVhTerminal, an as sendToVhTerminal, ao as ContextUsageSchema, ap as TITLE_PROMPT_PREFIX, aq as BOARD_ANALYZER_PROMPT_PREFIX, x as connectionState, ar as startOfflineReconnection, y as notifyDaemonSessionStarted, c as createEnvelope, C as CodexAppServerClient } from './types-BN3eiipi.mjs';
5
+ import { l as logger, F as ensurePrivateDirectory, G as hardenPrivateFile, c as configuration, p as packageJson, r as readSettings, H as readCredentials, x as credentialRelayProblem, o as readDaemonState, g as encodeBase64, I as readSettingsOutcome, u as updateSettings, J as encodeBase64Url, m as decodeBase64, K as writeCredentialsLegacy, L as writeCredentialsDataKey, e as readCredentialsForConfiguredRelay, j as encrypt, d as readPersistedSessions, w as writePrivateFileSync, M as decryptWithDataKey, N as decryptLegacy, O as persistSession, k as decrypt, h as ensurePrivateDirectorySync, P as acquireDaemonLock, Q as deletePersistedSessions, R as writeDaemonState, S as writeSettings, T as releaseDaemonLock, C as CLIPBOARD_TOOL_NAME, a as CLIPBOARD_TOOL_TITLE, b as CLIPBOARD_TOOL_DESCRIPTION, f as CLIPBOARD_MAX_BYTES, U as clearCredentials, V as clearMachineId, W as SandboxConfigSchema, X as getLatestDaemonLog } from './limits-DS-bnYYp.mjs';
6
6
  import spawn$1, { spawn } from 'cross-spawn';
7
7
  import path, { join, resolve, basename, delimiter, isAbsolute, dirname, sep, normalize } from 'node:path';
8
8
  import { createInterface } from 'node:readline';
9
9
  import { existsSync, readFileSync, readdirSync, statSync, mkdirSync, realpathSync, unlinkSync, renameSync, writeFileSync, accessSync, constants as constants$1, openSync, fsyncSync, closeSync, rmSync as rmSync$1, chmodSync as chmodSync$1 } from 'node:fs';
10
10
  import { p as projectPath } from './projectPath-CSpqWdxp.mjs';
11
- import { f as trimIdent, A as AGENT_GUIDANCE, t as teamScopePath, T as TeamConnectionPreflightError, e as createTeamsClient, P as PREVIEW_TOOL_NAME, R as REPORT_PROGRESS_TOOL_NAME, g as TEAM_TOOL_NAMES, r as registerTeamsTools, a as PREVIEW_TOOL_TITLE, b as PREVIEW_TOOL_DESCRIPTION, h as REPORT_PROGRESS_TOOL_TITLE, i as REPORT_PROGRESS_TOOL_DESCRIPTION } from './agentGuidance-DrfhtVP1.mjs';
11
+ import { f as trimIdent, A as AGENT_GUIDANCE, t as teamScopePath, T as TeamConnectionPreflightError, e as createTeamsClient, P as PREVIEW_TOOL_NAME, R as REPORT_PROGRESS_TOOL_NAME, g as TEAM_TOOL_NAMES, r as registerTeamsTools, a as PREVIEW_TOOL_TITLE, b as PREVIEW_TOOL_DESCRIPTION, h as REPORT_PROGRESS_TOOL_TITLE, i as REPORT_PROGRESS_TOOL_DESCRIPTION } from './agentGuidance-Dvo3cZMW.mjs';
12
12
  import { readFile, writeFile, rename, unlink, mkdir, access as access$1, symlink, rm, readlink, lstat, constants, stat, open as open$1, appendFile } from 'node:fs/promises';
13
13
  import fs, { watch, access } from 'fs/promises';
14
14
  import { useStdout, useInput, Box, Text, render } from 'ink';
@@ -456,17 +456,23 @@ function readClaudeSettings() {
456
456
  }
457
457
  function shouldIncludeCoAuthoredBy() {
458
458
  const settings = readClaudeSettings();
459
- if (!settings || settings.includeCoAuthoredBy === void 0) {
459
+ if (!settings) {
460
+ return true;
461
+ }
462
+ if (settings.attribution?.commit === "") {
463
+ return false;
464
+ }
465
+ if (settings.includeCoAuthoredBy === void 0) {
460
466
  return true;
461
467
  }
462
468
  return settings.includeCoAuthoredBy;
463
469
  }
464
470
 
465
471
  const BASE_SYSTEM_PROMPT = (() => trimIdent(`
466
- 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.
472
+ This chat is titled automatically from the user's first message. Call "mcp__happy__change_title" only when the topic has clearly moved on or the current title is too generic to find this chat later. Do not call it as a ritual at the start of a chat, and not for a quick question you can just answer.
467
473
  `))() + "\n\n" + AGENT_GUIDANCE + "\n\n" + BUILTIN_TODO_DISCOVERY;
468
474
  const CO_AUTHORED_CREDITS = (() => trimIdent(`
469
- When making commit messages, instead of just giving co-credit to Claude, also give credit to Happy like so:
475
+ When you yourself create a git commit, instead of just giving co-credit to Claude, also give credit to Happy like so:
470
476
 
471
477
  <main commit message>
472
478
 
@@ -474,6 +480,8 @@ const CO_AUTHORED_CREDITS = (() => trimIdent(`
474
480
  via [Very Happy](https://github.com/Mereithhh/very-happy)
475
481
 
476
482
  Co-Authored-By: Claude <noreply@anthropic.com>
483
+
484
+ Do not add these lines to commit message text you only draft for the user.
477
485
  `))();
478
486
  const systemPrompt = (() => {
479
487
  const includeCoAuthored = shouldIncludeCoAuthoredBy();
@@ -870,7 +878,7 @@ async function createSessionScanner(opts) {
870
878
  let processedMessageKeys = /* @__PURE__ */ new Set();
871
879
  let deadSessions = /* @__PURE__ */ new Set();
872
880
  if (opts.sessionId) {
873
- let messages = await readSessionLog(projectDir, opts.sessionId);
881
+ let messages = await readSessionLog$1(projectDir, opts.sessionId);
874
882
  logger.debug(`[SESSION_SCANNER] Marking ${messages.length} existing messages as processed from session ${opts.sessionId}`);
875
883
  for (let m of messages) {
876
884
  processedMessageKeys.add(messageKey(m));
@@ -893,7 +901,7 @@ async function createSessionScanner(opts) {
893
901
  }
894
902
  }
895
903
  for (let session of sessions) {
896
- const sessionMessages = await readSessionLog(projectDir, session);
904
+ const sessionMessages = await readSessionLog$1(projectDir, session);
897
905
  let skipped = 0;
898
906
  let sent = 0;
899
907
  for (let file of sessionMessages) {
@@ -970,7 +978,7 @@ async function createSessionScanner(opts) {
970
978
  return;
971
979
  }
972
980
  if (options?.treatExistingAsProcessed) {
973
- const existing = await readSessionLog(projectDir, sessionId);
981
+ const existing = await readSessionLog$1(projectDir, sessionId);
974
982
  logger.debug(`[SESSION_SCANNER] Pre-marking ${existing.length} existing messages as processed for new session ${sessionId}`);
975
983
  for (const m of existing) {
976
984
  processedMessageKeys.add(messageKey(m));
@@ -998,7 +1006,7 @@ function messageKey(message) {
998
1006
  throw Error();
999
1007
  }
1000
1008
  }
1001
- async function readSessionLog(projectDir, sessionId) {
1009
+ async function readSessionLog$1(projectDir, sessionId) {
1002
1010
  const expectedSessionFile = join(projectDir, `${sessionId}.jsonl`);
1003
1011
  logger.debug(`[SESSION_SCANNER] Reading session file: ${expectedSessionFile}`);
1004
1012
  let file;
@@ -5372,8 +5380,8 @@ ${typeLabels[type] || type}:`));
5372
5380
  }
5373
5381
  console.log(chalk.gray(" An external claude command is only needed for native terminal/mirror use."));
5374
5382
  try {
5375
- const { resolveAgentHomesForCli } = await import('./agentHome-Dm-Wjs38.mjs');
5376
- const { describeAgentHome } = await import('./types-BD542hb1.mjs').then(function (n) { return n.al; });
5383
+ const { resolveAgentHomesForCli } = await import('./agentHome-CeFDNzvq.mjs');
5384
+ const { describeAgentHome } = await import('./types-BN3eiipi.mjs').then(function (n) { return n.as; });
5377
5385
  const homes = await resolveAgentHomesForCli();
5378
5386
  console.log(chalk.green(`\u2713 Claude config dir: ${describeAgentHome(homes.claudeConfigDir)}`));
5379
5387
  console.log(chalk.green(`\u2713 Codex home: ${describeAgentHome(homes.codexHome)}`));
@@ -6084,7 +6092,9 @@ async function sendUserMessage(sessionId, persisted, text, client, options = {})
6084
6092
  },
6085
6093
  meta: {
6086
6094
  sentFrom: options.sentFrom ?? "cli",
6087
- ...options.model ? { model: options.model } : {}
6095
+ ...options.model !== void 0 ? { model: options.model } : {},
6096
+ ...options.permissionMode !== void 0 ? { permissionMode: options.permissionMode } : {},
6097
+ ...options.effort !== void 0 ? { effort: options.effort } : {}
6088
6098
  }
6089
6099
  };
6090
6100
  const encrypted = encodeBase64(encrypt(
@@ -6395,13 +6405,22 @@ function startDaemonControlServer({
6395
6405
  permissionMode: z.string().optional(),
6396
6406
  // B-069: spawn-origin tag ('assistant' = session_spawn). Recorded on
6397
6407
  // the TrackedSession; old clients never send it.
6398
- spawnedBy: z.string().optional()
6408
+ spawnedBy: z.string().optional(),
6409
+ // B-492: `very-happy spawn --fork` — same fields the web's fork flow
6410
+ // sends over the machine RPC. Old CLIs never send them.
6411
+ resumeClaudeSessionId: z.string().regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i).optional(),
6412
+ resumeCodexThreadId: z.string().min(1).max(200).optional(),
6413
+ parentSessionId: z.string().min(1).max(200).optional()
6399
6414
  }),
6400
6415
  response: {
6401
6416
  200: z.object({
6402
6417
  success: z.boolean(),
6403
6418
  sessionId: z.string().optional(),
6404
- approvedNewDirectoryCreation: z.boolean().optional()
6419
+ approvedNewDirectoryCreation: z.boolean().optional(),
6420
+ // B-492: true when resumeClaudeSessionId / resumeCodexThreadId was
6421
+ // honoured. A caller that asked for a fork and does not get this
6422
+ // back is talking to an older daemon that spawned a fresh session.
6423
+ resumed: z.boolean().optional()
6405
6424
  }),
6406
6425
  409: z.object({
6407
6426
  success: z.boolean(),
@@ -6416,13 +6435,14 @@ function startDaemonControlServer({
6416
6435
  }
6417
6436
  }
6418
6437
  }, async (request, reply) => {
6419
- const { directory, sessionId, agent, environmentVariables, variant, forceNew, permissionMode, spawnedBy } = request.body;
6438
+ const { directory, sessionId, agent, environmentVariables, variant, forceNew, permissionMode, spawnedBy, resumeClaudeSessionId, resumeCodexThreadId, parentSessionId } = request.body;
6420
6439
  if (!directory && variant !== "assistant") {
6421
6440
  reply.code(500);
6422
6441
  return { success: false, error: "directory is required" };
6423
6442
  }
6424
6443
  logger.debug(`[CONTROL SERVER] Spawn session request: dir=${directory}, sessionId=${sessionId || "new"}, agent=${agent || "default"}, variant=${variant || "none"}, forceNew=${forceNew === true}, spawnedBy=${spawnedBy || "unset"}`);
6425
- const result = await spawnSession({ directory, sessionId, agent, environmentVariables, variant, forceNew, permissionMode, spawnedBy });
6444
+ const result = await spawnSession({ directory, sessionId, agent, environmentVariables, variant, forceNew, permissionMode, spawnedBy, resumeClaudeSessionId, resumeCodexThreadId, parentSessionId });
6445
+ const resumed = Boolean(resumeClaudeSessionId || resumeCodexThreadId);
6426
6446
  switch (result.type) {
6427
6447
  case "success":
6428
6448
  if (!result.sessionId) {
@@ -6435,7 +6455,8 @@ function startDaemonControlServer({
6435
6455
  return {
6436
6456
  success: true,
6437
6457
  sessionId: result.sessionId,
6438
- approvedNewDirectoryCreation: true
6458
+ approvedNewDirectoryCreation: true,
6459
+ ...resumed ? { resumed: true } : {}
6439
6460
  };
6440
6461
  case "requestToApproveDirectoryCreation":
6441
6462
  reply.code(409);
@@ -9367,6 +9388,8 @@ ${goal}`;
9367
9388
 
9368
9389
  const MAX_LINE_CHARS = 500;
9369
9390
  const MAX_ARGS_CHARS = 160;
9391
+ const DEFAULT_LIMITS = { line: MAX_LINE_CHARS, args: MAX_ARGS_CHARS };
9392
+ const NO_LIMITS = { line: Number.POSITIVE_INFINITY, args: Number.POSITIVE_INFINITY };
9370
9393
  function truncateText(text, max = MAX_LINE_CHARS) {
9371
9394
  const chars = Array.from(text);
9372
9395
  if (chars.length <= max) return text;
@@ -9382,12 +9405,12 @@ function safeJson(value, max) {
9382
9405
  return "[unserializable]";
9383
9406
  }
9384
9407
  }
9385
- function formatMessageBody(body) {
9408
+ function formatMessageBody(body, limits = DEFAULT_LIMITS) {
9386
9409
  if (!body || typeof body !== "object") return null;
9387
9410
  const b = body;
9388
9411
  if (b.role === "user" && b.content?.type === "text" && typeof b.content.text === "string") {
9389
9412
  const text = squash(b.content.text);
9390
- return text.length > 0 ? `user: ${truncateText(text)}` : null;
9413
+ return text.length > 0 ? `user: ${truncateText(text, limits.line)}` : null;
9391
9414
  }
9392
9415
  if (b.role === "session" && b.content && typeof b.content === "object") {
9393
9416
  const env = b.content;
@@ -9399,18 +9422,18 @@ function formatMessageBody(body) {
9399
9422
  const text = squash(String(ev.text ?? ""));
9400
9423
  if (text.length === 0) return null;
9401
9424
  const role = env.role === "user" ? "user" : "assistant";
9402
- return `${role}: ${truncateText(text)}`;
9425
+ return `${role}: ${truncateText(text, limits.line)}`;
9403
9426
  }
9404
9427
  case "tool-call-start": {
9405
9428
  const name = String(ev.name ?? "tool");
9406
9429
  const title = squash(String(ev.title ?? ""));
9407
- const args = ev.args ? safeJson(ev.args, MAX_ARGS_CHARS) : "";
9430
+ const args = ev.args ? safeJson(ev.args, limits.args) : "";
9408
9431
  const detail = title || args;
9409
- return `[tool] ${name}${detail ? `: ${truncateText(detail, MAX_ARGS_CHARS)}` : ""}`;
9432
+ return `[tool] ${name}${detail ? `: ${truncateText(detail, limits.args)}` : ""}`;
9410
9433
  }
9411
9434
  case "service": {
9412
9435
  const text = squash(String(ev.text ?? ""));
9413
- return text.length > 0 ? `[service] ${truncateText(text, MAX_ARGS_CHARS)}` : null;
9436
+ return text.length > 0 ? `[service] ${truncateText(text, limits.args)}` : null;
9414
9437
  }
9415
9438
  case "turn-end": {
9416
9439
  if (ev.status && ev.status !== "completed") return `[turn ${ev.status}]`;
@@ -9425,12 +9448,12 @@ function formatMessageBody(body) {
9425
9448
  switch (d.type) {
9426
9449
  case "message": {
9427
9450
  const text = squash(String(d.message ?? ""));
9428
- return text.length > 0 ? `assistant: ${truncateText(text)}` : null;
9451
+ return text.length > 0 ? `assistant: ${truncateText(text, limits.line)}` : null;
9429
9452
  }
9430
9453
  case "tool-call":
9431
- return `[tool] ${String(d.name ?? "tool")}: ${safeJson(d.input, MAX_ARGS_CHARS)}`;
9454
+ return `[tool] ${String(d.name ?? "tool")}: ${safeJson(d.input, limits.args)}`;
9432
9455
  case "permission-request":
9433
- return `[permission] ${String(d.toolName ?? "")}: ${truncateText(squash(String(d.description ?? "")), MAX_ARGS_CHARS)}`;
9456
+ return `[permission] ${String(d.toolName ?? "")}: ${truncateText(squash(String(d.description ?? "")), limits.args)}`;
9434
9457
  default:
9435
9458
  return null;
9436
9459
  }
@@ -9441,22 +9464,111 @@ function formatMessageBody(body) {
9441
9464
  const texts = msg.content.filter((c) => c?.type === "text" && typeof c.text === "string").map((c) => squash(c.text)).filter((t) => t.length > 0);
9442
9465
  if (texts.length > 0) {
9443
9466
  const role = msg.role === "user" ? "user" : "assistant";
9444
- return `${role}: ${truncateText(texts.join(" "))}`;
9467
+ return `${role}: ${truncateText(texts.join(" "), limits.line)}`;
9445
9468
  }
9446
9469
  }
9447
9470
  return null;
9448
9471
  }
9449
9472
  return null;
9450
9473
  }
9451
- function formatTranscript(bodies) {
9474
+ function formatTranscript(bodies, options = {}) {
9475
+ const limits = options.full ? NO_LIMITS : DEFAULT_LIMITS;
9452
9476
  const lines = [];
9453
9477
  for (const body of bodies) {
9454
- const line = formatMessageBody(body);
9478
+ const line = formatMessageBody(body, limits);
9455
9479
  if (line !== null) lines.push(line);
9456
9480
  }
9457
9481
  return lines.join("\n");
9458
9482
  }
9459
9483
 
9484
+ function asRecord(value) {
9485
+ return value && typeof value === "object" ? value : null;
9486
+ }
9487
+ function sessionEnvelope(body) {
9488
+ const b = asRecord(body);
9489
+ if (!b || b.role !== "session") return null;
9490
+ const env = asRecord(b.content);
9491
+ if (!env) return null;
9492
+ const ev = asRecord(env.ev);
9493
+ return ev && typeof ev.t === "string" ? { role: env.role, ev } : null;
9494
+ }
9495
+ function isUserPrompt(body) {
9496
+ const b = asRecord(body);
9497
+ return !!b && b.role === "user" && b.content?.type === "text" && typeof b.content.text === "string";
9498
+ }
9499
+ function agentPiece(body) {
9500
+ const env = sessionEnvelope(body);
9501
+ if (env && env.role !== "user") {
9502
+ if (env.ev.t === "text" && !env.ev.thinking) {
9503
+ const text = String(env.ev.text ?? "");
9504
+ return text.trim().length > 0 ? { kind: "text", text } : null;
9505
+ }
9506
+ if (env.ev.t === "tool-call-start") return { kind: "tool" };
9507
+ return null;
9508
+ }
9509
+ const b = asRecord(body);
9510
+ if (b?.role === "agent" && b.content?.type === "acp") {
9511
+ const d = asRecord(b.content.data);
9512
+ if (d?.type === "message") {
9513
+ const text = String(d.message ?? "");
9514
+ return text.trim().length > 0 ? { kind: "text", text } : null;
9515
+ }
9516
+ if (d?.type === "tool-call") return { kind: "tool" };
9517
+ }
9518
+ return null;
9519
+ }
9520
+ function analyzeLatestTurn(entries) {
9521
+ const lastSeq = entries.length > 0 ? entries[entries.length - 1].seq : 0;
9522
+ let userIndex = -1;
9523
+ for (let i = entries.length - 1; i >= 0; i--) {
9524
+ if (isUserPrompt(entries[i].body)) {
9525
+ userIndex = i;
9526
+ break;
9527
+ }
9528
+ }
9529
+ let ended = false;
9530
+ let status = null;
9531
+ let error = null;
9532
+ let texts = [];
9533
+ let lastMarker = null;
9534
+ let startedAfterPrompt = false;
9535
+ const emitsStarts = entries.some((entry) => sessionEnvelope(entry.body)?.ev?.t === "turn-start");
9536
+ for (let i = userIndex + 1; i < entries.length; i++) {
9537
+ const body = entries[i].body;
9538
+ const env = sessionEnvelope(body);
9539
+ if (env?.ev?.t === "turn-start") {
9540
+ lastMarker = "start";
9541
+ startedAfterPrompt = true;
9542
+ ended = false;
9543
+ status = null;
9544
+ error = null;
9545
+ texts = [];
9546
+ continue;
9547
+ }
9548
+ if (env?.ev?.t === "turn-end") {
9549
+ lastMarker = "end";
9550
+ if (userIndex >= 0 && emitsStarts && !startedAfterPrompt) continue;
9551
+ ended = true;
9552
+ status = typeof env.ev.status === "string" ? env.ev.status : null;
9553
+ error = typeof env.ev.error === "string" ? env.ev.error : null;
9554
+ continue;
9555
+ }
9556
+ const piece = agentPiece(body);
9557
+ if (!piece) continue;
9558
+ if (piece.kind === "tool") texts = [];
9559
+ else texts.push(piece.text);
9560
+ }
9561
+ if (userIndex < 0) ended = lastMarker === "end";
9562
+ return {
9563
+ userSeq: userIndex >= 0 ? entries[userIndex].seq : null,
9564
+ ended,
9565
+ status: ended ? status : null,
9566
+ error: ended ? error : null,
9567
+ answer: texts.join("\n\n").trim(),
9568
+ lastSeq
9569
+ };
9570
+ }
9571
+
9460
9572
  const USER_SOCKET_CONNECT_TIMEOUT_MS = 15e3;
9461
9573
  async function openUserScopedSocket(token, options = {}) {
9462
9574
  const socket = io(configuration.serverUrl, {
@@ -9802,19 +9914,21 @@ async function bearerToken() {
9802
9914
  if (!credentials) throw new Error("CLI is not authenticated (no ~/.happy/access.key)");
9803
9915
  return credentials.token;
9804
9916
  }
9805
- async function readSessionTranscript(sessionId, limit) {
9917
+ function requirePersisted(sessionId) {
9806
9918
  const persisted = readPersistedSessions()[sessionId];
9807
9919
  if (!persisted) {
9808
9920
  throw new Error(
9809
9921
  `No local key for session ${sessionId} \u2014 it was not spawned by this machine's daemon (or is older than 14 days).`
9810
9922
  );
9811
9923
  }
9812
- const bounded = Math.max(1, Math.min(MAX_READ_LIMIT, Math.floor(limit)));
9924
+ return persisted;
9925
+ }
9926
+ async function readSessionLog(sessionId, persisted, limit) {
9813
9927
  const token = await bearerToken();
9814
9928
  const response = await axios.get(
9815
9929
  `${configuration.serverUrl}/v3/sessions/${encodeURIComponent(sessionId)}/messages`,
9816
9930
  {
9817
- params: { before_seq: 2147483647, limit: bounded },
9931
+ params: { before_seq: 2147483647, limit },
9818
9932
  headers: {
9819
9933
  "Authorization": `Bearer ${token}`,
9820
9934
  "X-Happy-Client": `${SESSION_OPS_CLIENT}/${configuration.currentCliVersion}`
@@ -9825,21 +9939,62 @@ async function readSessionTranscript(sessionId, limit) {
9825
9939
  const messages = Array.isArray(response.data?.messages) ? response.data.messages : [];
9826
9940
  messages.reverse();
9827
9941
  const key = decodeBase64(persisted.encryptionKey);
9828
- const live = await listDaemonSessions();
9829
- const bodies = messages.map((message) => {
9830
- if (message.content?.t !== "encrypted") return null;
9942
+ return messages.map((message) => {
9943
+ if (message.content?.t !== "encrypted") return { seq: message.seq, body: null };
9831
9944
  try {
9832
- return decrypt(key, persisted.encryptionVariant, decodeBase64(message.content.c));
9945
+ return { seq: message.seq, body: decrypt(key, persisted.encryptionVariant, decodeBase64(message.content.c)) };
9833
9946
  } catch {
9834
- return null;
9947
+ return { seq: message.seq, body: null };
9835
9948
  }
9836
9949
  });
9950
+ }
9951
+ const TURN_WINDOW = 500;
9952
+ async function readSessionTranscript(sessionId, limit, options = {}) {
9953
+ const persisted = requirePersisted(sessionId);
9954
+ const bounded = Math.max(1, Math.min(MAX_READ_LIMIT, Math.floor(limit)));
9955
+ const entries = await readSessionLog(sessionId, persisted, Math.max(bounded, TURN_WINDOW));
9956
+ const shown = entries.slice(-bounded);
9957
+ const live = await listDaemonSessions();
9837
9958
  return {
9838
9959
  summary: toSummary(sessionId, persisted, sessionLiveness(live, sessionId)),
9839
- messageCount: messages.length,
9840
- transcript: formatTranscript(bodies)
9960
+ messageCount: shown.length,
9961
+ transcript: formatTranscript(shown.map((entry) => entry.body), { full: options.full }),
9962
+ turn: analyzeLatestTurn(entries)
9841
9963
  };
9842
9964
  }
9965
+ async function readSessionMetadata(sessionId, persisted) {
9966
+ const token = await bearerToken();
9967
+ const response = await axios.get(`${configuration.serverUrl}/v1/sessions/${encodeURIComponent(sessionId)}`, {
9968
+ headers: {
9969
+ "Authorization": `Bearer ${token}`,
9970
+ "X-Happy-Client": `${SESSION_OPS_CLIENT}/${configuration.currentCliVersion}`
9971
+ },
9972
+ timeout: 15e3
9973
+ });
9974
+ const ciphertext = response.data?.session?.metadata;
9975
+ if (typeof ciphertext !== "string" || ciphertext.length === 0) return null;
9976
+ return decrypt(decodeBase64(persisted.encryptionKey), persisted.encryptionVariant, decodeBase64(ciphertext));
9977
+ }
9978
+ class TurnWaitTimeoutError extends Error {
9979
+ constructor(sessionId, timeoutMs, turn) {
9980
+ super(`Session ${sessionId}: the latest turn did not end within ${Math.round(timeoutMs / 1e3)}s`);
9981
+ this.sessionId = sessionId;
9982
+ this.timeoutMs = timeoutMs;
9983
+ this.turn = turn;
9984
+ }
9985
+ }
9986
+ async function waitForTurnEnd(sessionId, options) {
9987
+ const persisted = requirePersisted(sessionId);
9988
+ const pollMs = options.pollMs ?? 3e3;
9989
+ const sleep = options.sleep ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
9990
+ const deadline = Date.now() + options.timeoutMs;
9991
+ while (true) {
9992
+ const turn = analyzeLatestTurn(await readSessionLog(sessionId, persisted, TURN_WINDOW));
9993
+ if (turn.ended) return turn;
9994
+ if (Date.now() + pollMs > deadline) throw new TurnWaitTimeoutError(sessionId, options.timeoutMs, turn);
9995
+ await sleep(pollMs);
9996
+ }
9997
+ }
9843
9998
  async function stopSession(sessionId) {
9844
9999
  return await stopDaemonSession(sessionId);
9845
10000
  }
@@ -12577,7 +12732,7 @@ function registerSideQuestionHandler(rpc, deps) {
12577
12732
  const retainMs = deps.retainMs ?? SIDE_QUESTION_RETAIN_MS;
12578
12733
  const maxRunMs = deps.maxRunMs ?? SIDE_QUESTION_MAX_RUN_MS;
12579
12734
  const fork = deps.run ?? (async (input) => {
12580
- const { query } = await import('./index-BsYH1sjV.mjs');
12735
+ const { query } = await import('./index-DYQgcgL2.mjs');
12581
12736
  return runSideQuestion(query, input);
12582
12737
  });
12583
12738
  const run = async (input, live) => {
@@ -17865,7 +18020,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
17865
18020
  return;
17866
18021
  } else if (subcommand === "install-terminal-hooks") {
17867
18022
  try {
17868
- const { installTerminalHooks, parseTerminalHooksArgs, TERMINAL_HOOKS_HELP } = await import('./installTerminalHooks-BF_tmw9V.mjs');
18023
+ const { installTerminalHooks, parseTerminalHooksArgs, TERMINAL_HOOKS_HELP } = await import('./installTerminalHooks-Ch_yTtEA.mjs');
17869
18024
  const command = parseTerminalHooksArgs(args.slice(1));
17870
18025
  if (command.action === "help") {
17871
18026
  console.log(TERMINAL_HOOKS_HELP);
@@ -17882,7 +18037,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
17882
18037
  }
17883
18038
  } else if (subcommand === "agent-home") {
17884
18039
  try {
17885
- const { parseAgentHomeArgs, runAgentHomeCommand } = await import('./agentHome-Dm-Wjs38.mjs');
18040
+ const { parseAgentHomeArgs, runAgentHomeCommand } = await import('./agentHome-CeFDNzvq.mjs');
17886
18041
  await runAgentHomeCommand(parseAgentHomeArgs(args.slice(1)));
17887
18042
  process.exit(0);
17888
18043
  } catch (error) {
@@ -17891,7 +18046,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
17891
18046
  }
17892
18047
  } else if (subcommand === "spawn") {
17893
18048
  try {
17894
- const { handleSpawnCommand } = await import('./spawn-DQuOmUP7.mjs');
18049
+ const { handleSpawnCommand } = await import('./spawn-DxHIIqhi.mjs');
17895
18050
  await handleSpawnCommand(args.slice(1));
17896
18051
  } catch (error) {
17897
18052
  console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
@@ -17903,7 +18058,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
17903
18058
  return;
17904
18059
  } else if (subcommand === "sessions") {
17905
18060
  try {
17906
- const { handleSessionsCommand } = await import('./sessions-DoULfKui.mjs');
18061
+ const { handleSessionsCommand } = await import('./sessions-DlU3foY_.mjs');
17907
18062
  await handleSessionsCommand(args.slice(1));
17908
18063
  } catch (error) {
17909
18064
  console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
@@ -17915,7 +18070,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
17915
18070
  return;
17916
18071
  } else if (subcommand === "send") {
17917
18072
  try {
17918
- const { handleSendCommand } = await import('./send-Dv0km8UI.mjs');
18073
+ const { handleSendCommand } = await import('./send-o6WM-1G8.mjs');
17919
18074
  await handleSendCommand(args.slice(1));
17920
18075
  } catch (error) {
17921
18076
  console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
@@ -18021,9 +18176,9 @@ Conversation history is preserved on the server, but in-flight tool calls are in
18021
18176
  if (geminiSubcommand === "project" && args[2] === "set" && args[3]) {
18022
18177
  const projectId = args[3];
18023
18178
  try {
18024
- const { saveGoogleCloudProjectToConfig } = await import('./config-Dhu6LU0h.mjs');
18025
- const { readCredentialsForConfiguredRelay: readCredentialsForConfiguredRelay2 } = await import('./limits-FThmm7WR.mjs').then(function (n) { return n.Y; });
18026
- const { ApiClient: ApiClient2 } = await import('./types-BD542hb1.mjs').then(function (n) { return n.am; });
18179
+ const { saveGoogleCloudProjectToConfig } = await import('./config-C-A1XF62.mjs');
18180
+ const { readCredentialsForConfiguredRelay: readCredentialsForConfiguredRelay2 } = await import('./limits-DS-bnYYp.mjs').then(function (n) { return n.Y; });
18181
+ const { ApiClient: ApiClient2 } = await import('./types-BN3eiipi.mjs').then(function (n) { return n.at; });
18027
18182
  let userEmail = void 0;
18028
18183
  try {
18029
18184
  const credentials = await readCredentialsForConfiguredRelay2();
@@ -18054,7 +18209,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
18054
18209
  }
18055
18210
  if (geminiSubcommand === "project" && args[2] === "get") {
18056
18211
  try {
18057
- const { readGeminiLocalConfig } = await import('./config-Dhu6LU0h.mjs');
18212
+ const { readGeminiLocalConfig } = await import('./config-C-A1XF62.mjs');
18058
18213
  const config = readGeminiLocalConfig();
18059
18214
  if (config.googleCloudProject) {
18060
18215
  console.log(`Current Google Cloud Project: ${config.googleCloudProject}`);
@@ -18094,7 +18249,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
18094
18249
  process.exit(0);
18095
18250
  }
18096
18251
  try {
18097
- const { runGemini } = await import('./runGemini-D5IV1MoF.mjs');
18252
+ const { runGemini } = await import('./runGemini-DvJwQVGp.mjs');
18098
18253
  let startedBy = void 0;
18099
18254
  for (let i = 1; i < args.length; i++) {
18100
18255
  if (args[i] === "--started-by") {
@@ -18117,7 +18272,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
18117
18272
  } else if (subcommand === "pi") {
18118
18273
  if (args[1] === "--terminal") {
18119
18274
  try {
18120
- const { runPiTerminal } = await import('./piTerminal-BlE4vbvZ.mjs');
18275
+ const { runPiTerminal } = await import('./piTerminal-M677UP7y.mjs');
18121
18276
  process.exitCode = await runPiTerminal(args.slice(2));
18122
18277
  } catch (error) {
18123
18278
  console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
@@ -18134,7 +18289,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
18134
18289
  }
18135
18290
  };
18136
18291
  try {
18137
- const { runAcp, resolveAcpAgentConfig } = await import('./index-CzpooENj.mjs');
18292
+ const { runAcp, resolveAcpAgentConfig } = await import('./index-DEp6CmmS.mjs');
18138
18293
  const parsed = parsePiRunnerArgs(args.slice(1));
18139
18294
  const resolved = resolveAcpAgentConfig(["pi", ...parsed.passthrough]);
18140
18295
  const { credentials } = await authAndSetupMachineIfNeeded();
@@ -18162,7 +18317,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
18162
18317
  return;
18163
18318
  } else if (subcommand === "acp") {
18164
18319
  try {
18165
- const { runAcp, resolveAcpAgentConfig } = await import('./index-CzpooENj.mjs');
18320
+ const { runAcp, resolveAcpAgentConfig } = await import('./index-DEp6CmmS.mjs');
18166
18321
  let startedBy = void 0;
18167
18322
  let verbose = false;
18168
18323
  const acpArgs = [];
@@ -18202,7 +18357,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
18202
18357
  return;
18203
18358
  } else if (subcommand === "openclaw") {
18204
18359
  try {
18205
- const { runOpenClaw } = await import('./runOpenClaw-CWPXrKMJ.mjs');
18360
+ const { runOpenClaw } = await import('./runOpenClaw-BG82bF18.mjs');
18206
18361
  let startedBy = void 0;
18207
18362
  let verbose = false;
18208
18363
  let gatewayUrl;
@@ -18253,7 +18408,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
18253
18408
  return;
18254
18409
  } else if (subcommand === "todo") {
18255
18410
  try {
18256
- const { handleTodoCommand } = await import('./todo-C9IAUf0K.mjs');
18411
+ const { handleTodoCommand } = await import('./todo-BhJbG5eq.mjs');
18257
18412
  await handleTodoCommand(args.slice(1));
18258
18413
  } catch (error) {
18259
18414
  console.error(JSON.stringify({ error: error instanceof Error ? error.message : "Todo command failed" }));
@@ -18262,7 +18417,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
18262
18417
  return;
18263
18418
  } else if (subcommand === "teams") {
18264
18419
  try {
18265
- const { handleTeamsCommand } = await import('./teams-4mhNh5cj.mjs');
18420
+ const { handleTeamsCommand } = await import('./teams-DoAA_CcN.mjs');
18266
18421
  await handleTeamsCommand(args.slice(1));
18267
18422
  } catch (error) {
18268
18423
  console.error(error instanceof Error ? error.message : "Teams command failed");
@@ -18271,7 +18426,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
18271
18426
  return;
18272
18427
  } else if (subcommand === "mcp" && (args.length === 1 || args.length === 2 && args[1] === "--terminal-tools")) {
18273
18428
  try {
18274
- const { handleMcpCommand } = await import('./mcp-DzydgXpf.mjs');
18429
+ const { handleMcpCommand } = await import('./mcp-zu8n8TkR.mjs');
18275
18430
  await handleMcpCommand(args[1] === "--terminal-tools");
18276
18431
  } catch (error) {
18277
18432
  process.stderr.write(`[very-happy mcp] Fatal: ${error instanceof Error ? error.message : String(error)}
@@ -18639,4 +18794,4 @@ ${chalk.bold("Examples:")}
18639
18794
  }
18640
18795
  }
18641
18796
 
18642
- export { ALLOWED_SPAWN_PERMISSION_MODES as A, appendStagedAttachmentsToPrompt as B, CLAUDE_ATTACHMENT_KINDS as C, DEFAULT_RECENT_LIMIT as D, BasePermissionHandler as E, writeSessionModeFile as F, GEMINI_MODEL_ENV as G, normalizeAcpPermissionMode as H, removeSessionModeFile as I, TEAM_SKILL as J, GEMINI_API_KEY_ENV as K, GOOGLE_API_KEY_ENV as L, MAX_READ_LIMIT as M, BaseReasoningProcessor as N, MessageBuffer as O, PI_TEAMS_EXTENSION as P, CHANGE_TITLE_INSTRUCTION as Q, SPAWN_AGENTS as S, TitleGenerator as T, sanitizeSpawnPermissionMode as a, sendUserMessage as b, listSessions as c, stopSession as d, resolvePermissionRequest as e, archiveSession as f, DEFAULT_GEMINI_MODEL as g, checkPreviewPath as h, isValidSpawnOrigin as i, registerAssistantSessionTools as j, initialMachineMetadata as k, listAccountSessions as l, createSessionMetadata as m, setupOfflineReconnection as n, StreamRelay as o, MessageQueue2 as p, query as q, readSessionTranscript as r, sessionWebUrl as s, tmuxSupportsSessionEnv as t, hashObject as u, startHappyServer as v, waitForSessionKey as w, registerAgentAttachmentDownloads as x, registerKillSessionHandler as y, stageClaudeAttachments as z };
18797
+ export { ALLOWED_SPAWN_PERMISSION_MODES as A, TitleGenerator as B, registerKillSessionHandler as C, DEFAULT_RECENT_LIMIT as D, CLAUDE_ATTACHMENT_KINDS as E, stageClaudeAttachments as F, GEMINI_MODEL_ENV as G, appendStagedAttachmentsToPrompt as H, BasePermissionHandler as I, writeSessionModeFile as J, normalizeAcpPermissionMode as K, removeSessionModeFile as L, MAX_READ_LIMIT as M, TEAM_SKILL as N, GEMINI_API_KEY_ENV as O, PI_TEAMS_EXTENSION as P, GOOGLE_API_KEY_ENV as Q, BaseReasoningProcessor as R, SPAWN_AGENTS as S, TurnWaitTimeoutError as T, MessageBuffer as U, CHANGE_TITLE_INSTRUCTION as V, listSessions as a, resolvePermissionRequest as b, archiveSession as c, sendUserMessage as d, sessionWebUrl as e, DEFAULT_GEMINI_MODEL as f, checkPreviewPath as g, registerAssistantSessionTools as h, readSessionMetadata as i, isValidSpawnOrigin as j, sanitizeSpawnPermissionMode as k, listAccountSessions as l, waitForSessionKey as m, initialMachineMetadata as n, createSessionMetadata as o, setupOfflineReconnection as p, query as q, readSessionTranscript as r, stopSession as s, tmuxSupportsSessionEnv as t, StreamRelay as u, MessageQueue2 as v, waitForTurnEnd as w, hashObject as x, startHappyServer as y, registerAgentAttachmentDownloads as z };