very-happy-cli 0.2.152 → 0.2.154

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 (61) hide show
  1. package/dist/{AcpBackend-CogiKCng.cjs → AcpBackend-B14xNj5L.cjs} +2 -2
  2. package/dist/{AcpBackend-Bs3wwYbt.mjs → AcpBackend-Ckyadhf4.mjs} +2 -2
  3. package/dist/{AcpSessionManager-BazkBuFo.cjs → AcpSessionManager-CCHmPdrR.cjs} +1 -1
  4. package/dist/{AcpSessionManager-BT8PJMEm.mjs → AcpSessionManager-H8t4P-IW.mjs} +1 -1
  5. package/dist/{agentGuidance-CqBn77AI.cjs → agentGuidance-DUBXppv-.cjs} +2 -1
  6. package/dist/{agentGuidance-Daxn5Nvj.mjs → agentGuidance-TLYQxsm2.mjs} +2 -1
  7. package/dist/{agentHome-CCYfs8Ec.mjs → agentHome-B20RWdgE.mjs} +3 -3
  8. package/dist/{agentHome-CpJjrQZc.cjs → agentHome-BUsLTZnz.cjs} +3 -3
  9. package/dist/{auto-DV5emt1-.mjs → auto-BQnncDcs.mjs} +7 -7
  10. package/dist/{auto-DncmTDvw.cjs → auto-IeldARBS.cjs} +7 -7
  11. package/dist/codex/happyMcpStdioBridge.cjs +2 -2
  12. package/dist/codex/happyMcpStdioBridge.mjs +2 -2
  13. package/dist/{config-DbKpQpdL.mjs → config-B-ocQh5V.mjs} +5 -5
  14. package/dist/{config-DeJgSMh-.cjs → config-DM_xI9M6.cjs} +5 -5
  15. package/dist/{index-BauTv2jB.mjs → index-BELV05ko.mjs} +284 -45
  16. package/dist/{index-imt4mC41.cjs → index-BUxBxSxJ.cjs} +9 -9
  17. package/dist/{index-CN7OF2cU.mjs → index-CIx3248o.mjs} +5 -5
  18. package/dist/{index-DahaLbu4.mjs → index-ZKuBjvHi.mjs} +9 -9
  19. package/dist/{index-ZIW1jrYm.cjs → index-eCjkm8Y2.cjs} +307 -66
  20. package/dist/{index-CRaJ9k2p.cjs → index-okLyUzeD.cjs} +5 -5
  21. package/dist/index.cjs +5 -5
  22. package/dist/index.mjs +5 -5
  23. package/dist/{install-CDR3qBhs.cjs → install-BZOdxfPd.cjs} +1 -1
  24. package/dist/{install-C1K3nrxF.mjs → install-CoLN3whR.mjs} +1 -1
  25. package/dist/{installPiTools-C-Lxv4Bt.mjs → installPiTools-Cj7yU9Fc.mjs} +2 -1
  26. package/dist/{installPiTools-BKnXjrVu.cjs → installPiTools-DuZ6jZvX.cjs} +3 -2
  27. package/dist/{installTerminalHooks-BoDxpaBO.cjs → installTerminalHooks-CA4OcAS7.cjs} +7 -7
  28. package/dist/{installTerminalHooks-VvmlO6Ue.mjs → installTerminalHooks-Dde_8t36.mjs} +6 -6
  29. package/dist/lib.cjs +3 -3
  30. package/dist/lib.mjs +3 -3
  31. package/dist/{limits-BNTWyUaZ.cjs → limits-CmzISka2.cjs} +7 -7
  32. package/dist/{limits-CKR_HJnO.mjs → limits-Dt7_unH4.mjs} +7 -7
  33. package/dist/{mcp-CCKCKL6l.cjs → mcp-7iDHlyCI.cjs} +14 -6
  34. package/dist/{mcp-D4dAo5BQ.mjs → mcp-9Ui4nQZL.mjs} +14 -7
  35. package/dist/piExtension.d.mts +4 -1
  36. package/dist/piExtension.mjs +24 -1
  37. package/dist/{piRuntime-Bn5ypbjH.cjs → piRuntime-BesGGPME.cjs} +2 -2
  38. package/dist/{piRuntime-CW-XA4rz.mjs → piRuntime-C4E4pgye.mjs} +2 -2
  39. package/dist/{piTerminal-BLSXK1u2.mjs → piTerminal-CCEGCQOY.mjs} +8 -7
  40. package/dist/{piTerminal-B7K75aXB.cjs → piTerminal-fUogwxYr.cjs} +8 -7
  41. package/dist/{runGemini-D5N11LxO.mjs → runGemini-BW-pEklU.mjs} +7 -7
  42. package/dist/{runGemini-Bgg1BzDK.cjs → runGemini-CNPGSsSK.cjs} +8 -8
  43. package/dist/{runOpenClaw-B9qWHybc.cjs → runOpenClaw-Bsodkg_s.cjs} +6 -6
  44. package/dist/{runOpenClaw-CCpyKbrn.mjs → runOpenClaw-NRB6-_jU.mjs} +6 -6
  45. package/dist/{send-wl9ei8yG.cjs → send-Bd00QcHC.cjs} +56 -18
  46. package/dist/{send-C44kcXz5.mjs → send-DYeSFg8s.mjs} +56 -19
  47. package/dist/{sessions-DXJEcUg6.mjs → sessions-DlPOYKLU.mjs} +5 -5
  48. package/dist/{sessions-Tad8elmy.cjs → sessions-RIFUoy_g.cjs} +5 -5
  49. package/dist/{spawn-BOlb5y1_.mjs → spawn-D1bhyHbH.mjs} +5 -5
  50. package/dist/{spawn-DA8WAFmm.cjs → spawn-DxrfHTF4.cjs} +5 -5
  51. package/dist/{teams-qVLrFcdd.cjs → teams-Cfy0VMCo.cjs} +6 -6
  52. package/dist/{teams-Bs8lI887.mjs → teams-pfKHpkgL.mjs} +6 -6
  53. package/dist/terminalTitleSuggest-DKgX3osW.mjs +38 -0
  54. package/dist/terminalTitleSuggest-Dji8I0Jy.cjs +45 -0
  55. package/dist/{todo-nzsqGZqp.mjs → todo-B2CjDg_V.mjs} +2 -2
  56. package/dist/{todo-mCMoGjJk.cjs → todo-B4cBFzHB.cjs} +2 -2
  57. package/dist/{types-CN28qJl7.cjs → types-Bd_TGr0F.cjs} +34 -10
  58. package/dist/{types-xKrxbCRv.mjs → types-D5RWyBE5.mjs} +32 -9
  59. package/package.json +7 -7
  60. package/dist/projectPath-CSpqWdxp.mjs +0 -10
  61. package/dist/projectPath-ChLhdOyt.cjs +0 -13
@@ -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 index = require('./types-CN28qJl7.cjs');
7
- var persistence = require('./limits-BNTWyUaZ.cjs');
6
+ var index = require('./types-Bd_TGr0F.cjs');
7
+ var persistence = require('./limits-CmzISka2.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
- var projectPath = require('./projectPath-ChLhdOyt.cjs');
13
- var agentGuidance = require('./agentGuidance-CqBn77AI.cjs');
12
+ var terminalTitleSuggest = require('./terminalTitleSuggest-Dji8I0Jy.cjs');
13
+ var agentGuidance = require('./agentGuidance-DUBXppv-.cjs');
14
14
  var promises = require('node:fs/promises');
15
15
  var fs = require('fs/promises');
16
16
  var ink = require('ink');
@@ -522,7 +522,7 @@ class ExitCodeError extends Error {
522
522
  this.exitCode = exitCode;
523
523
  }
524
524
  }
525
- const claudeCliPath = path.resolve(path.join(projectPath.projectPath(), "scripts", "claude_local_launcher.cjs"));
525
+ const claudeCliPath = path.resolve(path.join(terminalTitleSuggest.projectPath(), "scripts", "claude_local_launcher.cjs"));
526
526
  function quoteShellArg(value) {
527
527
  return `'${value.replace(/'/g, `'\\''`)}'`;
528
528
  }
@@ -4878,8 +4878,8 @@ function createSessionMetadata(opts) {
4878
4878
  ...opts.teamOperationId ? { teamOperationId: opts.teamOperationId } : {},
4879
4879
  homeDir: os.homedir(),
4880
4880
  happyHomeDir: persistence.configuration.happyHomeDir,
4881
- happyLibDir: projectPath.projectPath(),
4882
- happyToolsDir: path.resolve(projectPath.projectPath(), "tools", "unpacked"),
4881
+ happyLibDir: terminalTitleSuggest.projectPath(),
4882
+ happyToolsDir: path.resolve(terminalTitleSuggest.projectPath(), "tools", "unpacked"),
4883
4883
  startedFromDaemon: opts.startedBy === "daemon",
4884
4884
  hostPid: process.pid,
4885
4885
  startedBy: opts.startedBy || "terminal",
@@ -5206,7 +5206,7 @@ function printCliUpdateStatus(state) {
5206
5206
  console.log(chalk.yellow(" \u25B3 A newer CLI is available."));
5207
5207
  }
5208
5208
  if (summary.installCommand) console.log(` Update: ${summary.installCommand}`);
5209
- const facts = gatherInstallLocationFacts(projectPath.projectPath());
5209
+ const facts = gatherInstallLocationFacts(terminalTitleSuggest.projectPath());
5210
5210
  for (const warning of facts ? installLocationWarnings(facts, state?.cliUpdate?.recommendedVersion ?? void 0) : []) {
5211
5211
  console.log(chalk.yellow(` \u26A0 ${warning}`));
5212
5212
  }
@@ -5338,7 +5338,7 @@ ${typeLabels[type] || type}:`));
5338
5338
  console.log(chalk.yellow("No log files found"));
5339
5339
  }
5340
5340
  console.log(chalk.bold("\n\u{1F527} Daemon Spawn Diagnostics"));
5341
- const projectRoot = projectPath.projectPath();
5341
+ const projectRoot = terminalTitleSuggest.projectPath();
5342
5342
  const wrapperPath = path.join(projectRoot, "bin", "very-happy.mjs");
5343
5343
  const cliEntrypoint = path.join(projectRoot, "dist", "index.mjs");
5344
5344
  console.log(`Project Root: ${chalk.blue(projectRoot)}`);
@@ -5402,8 +5402,8 @@ ${typeLabels[type] || type}:`));
5402
5402
  }
5403
5403
  console.log(chalk.gray(" An external claude command is only needed for native terminal/mirror use."));
5404
5404
  try {
5405
- const { resolveAgentHomesForCli } = await Promise.resolve().then(function () { return require('./agentHome-CpJjrQZc.cjs'); });
5406
- const { describeAgentHome } = await Promise.resolve().then(function () { return require('./types-CN28qJl7.cjs'); }).then(function (n) { return n.index; });
5405
+ const { resolveAgentHomesForCli } = await Promise.resolve().then(function () { return require('./agentHome-BUsLTZnz.cjs'); });
5406
+ const { describeAgentHome } = await Promise.resolve().then(function () { return require('./types-Bd_TGr0F.cjs'); }).then(function (n) { return n.index; });
5407
5407
  const homes = await resolveAgentHomesForCli();
5408
5408
  console.log(chalk.green(`\u2713 Claude config dir: ${describeAgentHome(homes.claudeConfigDir)}`));
5409
5409
  console.log(chalk.green(`\u2713 Codex home: ${describeAgentHome(homes.codexHome)}`));
@@ -5953,7 +5953,7 @@ function getRuntime() {
5953
5953
  const isBun = () => getRuntime() === "bun";
5954
5954
 
5955
5955
  function spawnHappyCLI(args, options = {}) {
5956
- const projectRoot = projectPath.projectPath();
5956
+ const projectRoot = terminalTitleSuggest.projectPath();
5957
5957
  const entrypoint = path.join(projectRoot, "dist", "index.mjs");
5958
5958
  let directory;
5959
5959
  if ("cwd" in options) {
@@ -6284,6 +6284,7 @@ function startDaemonControlServer({
6284
6284
  getChildren,
6285
6285
  stopSession,
6286
6286
  spawnSession,
6287
+ resumeSession,
6287
6288
  requestShutdown,
6288
6289
  onHappySessionWebhook,
6289
6290
  onSessionStateEvent,
@@ -6496,6 +6497,48 @@ function startDaemonControlServer({
6496
6497
  };
6497
6498
  }
6498
6499
  });
6500
+ typed.post("/resume-session", {
6501
+ schema: {
6502
+ body: z.z.object({
6503
+ sessionId: z.z.string().min(1).max(200),
6504
+ model: z.z.string().optional(),
6505
+ permissionMode: z.z.string().optional()
6506
+ }),
6507
+ response: {
6508
+ 200: z.z.object({
6509
+ success: z.z.boolean(),
6510
+ sessionId: z.z.string().optional(),
6511
+ error: z.z.string().optional()
6512
+ }),
6513
+ 500: z.z.object({
6514
+ success: z.z.boolean(),
6515
+ error: z.z.string().optional()
6516
+ }),
6517
+ 503: z.z.object({
6518
+ success: z.z.boolean(),
6519
+ error: z.z.string().optional()
6520
+ })
6521
+ }
6522
+ }
6523
+ }, async (request, reply) => {
6524
+ const { sessionId, model, permissionMode } = request.body;
6525
+ if (!resumeSession) {
6526
+ reply.code(503);
6527
+ return { success: false, error: "daemon is still starting up" };
6528
+ }
6529
+ persistence.logger.debug(`[CONTROL SERVER] Resume session request: ${sessionId} (model=${model ?? "unset"}, permissionMode=${permissionMode ?? "unset"})`);
6530
+ const result = await resumeSession(sessionId, { model, permissionMode });
6531
+ switch (result.type) {
6532
+ case "success":
6533
+ return { success: true, sessionId: result.sessionId };
6534
+ case "requestToApproveDirectoryCreation":
6535
+ reply.code(500);
6536
+ return { success: false, error: `Cannot resume: working directory ${result.directory} needs to be created first` };
6537
+ case "error":
6538
+ reply.code(500);
6539
+ return { success: false, error: result.errorMessage };
6540
+ }
6541
+ });
6499
6542
  typed.post("/terminal-hook", {
6500
6543
  schema: {
6501
6544
  body: z.z.any(),
@@ -7784,7 +7827,7 @@ const defaults = {
7784
7827
  npm: runNpm,
7785
7828
  fs: { lstat: promises.lstat, readlink: promises.readlink, unlink: promises.unlink, rm: promises.rm, readFile: promises.readFile, symlink: promises.symlink, access: promises.access },
7786
7829
  platform: process.platform,
7787
- runningPackageDir: projectPath.projectPath()
7830
+ runningPackageDir: terminalTitleSuggest.projectPath()
7788
7831
  };
7789
7832
  async function runningVersion(deps) {
7790
7833
  if (!deps.runningPackageDir) return null;
@@ -8144,7 +8187,7 @@ function parseJsonObject(text) {
8144
8187
  return null;
8145
8188
  }
8146
8189
  }
8147
- 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-ZIW1jrYm.cjs', document.baseURI).href))).resolve(s)) {
8190
+ 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-eCjkm8Y2.cjs', document.baseURI).href))).resolve(s)) {
8148
8191
  const platformArch = `${platform}-${arch}`;
8149
8192
  const candidates = [
8150
8193
  `@anthropic-ai/claude-agent-sdk-${platformArch}/claude`,
@@ -8857,8 +8900,8 @@ function createMirrorManager(deps) {
8857
8900
  machineId: deps.machineId,
8858
8901
  homeDir: os.homedir(),
8859
8902
  happyHomeDir: persistence.configuration.happyHomeDir,
8860
- happyLibDir: projectPath.projectPath(),
8861
- happyToolsDir: path.resolve(projectPath.projectPath(), "tools", "unpacked"),
8903
+ happyLibDir: terminalTitleSuggest.projectPath(),
8904
+ happyToolsDir: path.resolve(terminalTitleSuggest.projectPath(), "tools", "unpacked"),
8862
8905
  startedBy: "terminal",
8863
8906
  lifecycleState: "running",
8864
8907
  lifecycleStateSince: Date.now(),
@@ -9380,6 +9423,20 @@ export default async function(pi) {
9380
9423
  return data.result;
9381
9424
  }
9382
9425
  await rpc('initialize', {protocolVersion:'2024-11-05',capabilities:{},clientInfo:{name:'very-happy-pi-teams',version:'1'}});
9426
+ if (!managed && pi.setSessionName) {
9427
+ // B-500: name the pi session from its first prompt (managed sessions are titled by TitleGenerator).
9428
+ let titleArmed = false, generation = 0;
9429
+ pi.on('session_start', async () => { generation += 1; titleArmed = !pi.getSessionName?.(); });
9430
+ pi.on('before_agent_start', async (event) => {
9431
+ const prompt = event && typeof event.prompt === 'string' ? event.prompt : '';
9432
+ if (!titleArmed || !prompt.trim()) return;
9433
+ titleArmed = false;
9434
+ const expected = generation;
9435
+ rpc('very-happy/terminal-title-suggest', {prompt}).then(result => {
9436
+ if (result && result.title && expected === generation && !pi.getSessionName?.()) pi.setSessionName(result.title);
9437
+ }).catch(() => {});
9438
+ });
9439
+ }
9383
9440
  const available = await rpc('tools/list', {});
9384
9441
  for (const tool of available.tools || []) {
9385
9442
  pi.registerTool({name:tool.name,label:tool.name,description:tool.description || tool.name,parameters:tool.inputSchema,
@@ -10004,6 +10061,35 @@ async function readSessionMetadata(sessionId, persisted) {
10004
10061
  if (typeof ciphertext !== "string" || ciphertext.length === 0) return null;
10005
10062
  return persistence.decrypt(persistence.decodeBase64(persisted.encryptionKey), persisted.encryptionVariant, persistence.decodeBase64(ciphertext));
10006
10063
  }
10064
+ async function readSessionState(sessionId, persisted) {
10065
+ const token = await bearerToken();
10066
+ const response = await axios.get(`${persistence.configuration.serverUrl}/v1/sessions/${encodeURIComponent(sessionId)}`, {
10067
+ headers: {
10068
+ "Authorization": `Bearer ${token}`,
10069
+ "X-Happy-Client": `${SESSION_OPS_CLIENT}/${persistence.configuration.currentCliVersion}`
10070
+ },
10071
+ timeout: 15e3,
10072
+ validateStatus: (status) => status >= 200 && status < 300 || status === 404
10073
+ });
10074
+ if (response.status === 404) return { found: false, active: false };
10075
+ const row = response.data?.session;
10076
+ if (!row || typeof row.id !== "string") throw new Error(`Server returned no session row for ${sessionId}`);
10077
+ const state = {
10078
+ found: true,
10079
+ active: row.active === true,
10080
+ ...typeof row.activeAt === "number" ? { activeAt: row.activeAt } : {},
10081
+ archivedAt: typeof row.archivedAt === "number" ? row.archivedAt : null,
10082
+ ...typeof row.updatedAt === "number" ? { updatedAt: row.updatedAt } : {}
10083
+ };
10084
+ if (persisted && typeof row.metadata === "string" && row.metadata.length > 0) {
10085
+ try {
10086
+ const metadata = persistence.decrypt(persistence.decodeBase64(persisted.encryptionKey), persisted.encryptionVariant, persistence.decodeBase64(row.metadata));
10087
+ if (metadata?.machineId) state.machineId = metadata.machineId;
10088
+ } catch {
10089
+ }
10090
+ }
10091
+ return state;
10092
+ }
10007
10093
  class TurnWaitTimeoutError extends Error {
10008
10094
  constructor(sessionId, timeoutMs, turn) {
10009
10095
  super(`Session ${sessionId}: the latest turn did not end within ${Math.round(timeoutMs / 1e3)}s`);
@@ -10041,6 +10127,20 @@ async function archiveSession(sessionId) {
10041
10127
  }
10042
10128
  );
10043
10129
  }
10130
+ async function unarchiveSession(sessionId) {
10131
+ const token = await bearerToken();
10132
+ await axios.post(
10133
+ `${persistence.configuration.serverUrl}/v1/sessions/${encodeURIComponent(sessionId)}/unarchive`,
10134
+ {},
10135
+ {
10136
+ headers: {
10137
+ "Authorization": `Bearer ${token}`,
10138
+ "X-Happy-Client": `${SESSION_OPS_CLIENT}/${persistence.configuration.currentCliVersion}`
10139
+ },
10140
+ timeout: 1e4
10141
+ }
10142
+ );
10143
+ }
10044
10144
 
10045
10145
  function receiptPath(home, operationId) {
10046
10146
  if (!/^[a-zA-Z0-9_-]{1,128}$/.test(operationId)) throw new Error("Invalid team operation id");
@@ -10993,7 +11093,7 @@ const initialMachineMetadata = {
10993
11093
  happyCliVersion: persistence.packageJson.version,
10994
11094
  homeDir: os$1.homedir(),
10995
11095
  happyHomeDir: persistence.configuration.happyHomeDir,
10996
- happyLibDir: projectPath.projectPath(),
11096
+ happyLibDir: terminalTitleSuggest.projectPath(),
10997
11097
  cliAvailability: startupCliAvailability,
10998
11098
  resumeSupport: { ...index.detectResumeSupport(), rpcAvailable: true }
10999
11099
  };
@@ -11451,7 +11551,7 @@ async function startDaemon() {
11451
11551
  const sessionDesc = tmuxSessionName || "current/most recent session";
11452
11552
  persistence.logger.debug(`[DAEMON RUN] Attempting to spawn session in tmux: ${sessionDesc}`);
11453
11553
  const tmux = getTmuxUtilities(tmuxSessionName);
11454
- const cliPath = path$1.join(projectPath.projectPath(), "dist", "index.mjs");
11554
+ const cliPath = path$1.join(terminalTitleSuggest.projectPath(), "dist", "index.mjs");
11455
11555
  const agent = options.agent ?? "claude";
11456
11556
  if (!isSpawnAgent(agent)) {
11457
11557
  return {
@@ -12067,6 +12167,8 @@ async function startDaemon() {
12067
12167
  getChildren: getCurrentChildren,
12068
12168
  stopSession,
12069
12169
  spawnSession,
12170
+ resumeSession,
12171
+ // B-501: `very-happy send --resume`
12070
12172
  requestShutdown: () => requestShutdown("happy-cli"),
12071
12173
  onHappySessionWebhook,
12072
12174
  onSessionStateEvent,
@@ -12104,7 +12206,7 @@ async function startDaemon() {
12104
12206
  };
12105
12207
  persistence.writeDaemonState(fileState);
12106
12208
  persistence.logger.debug("[DAEMON RUN] Daemon state written");
12107
- const bundlePath = path$1.join(projectPath.projectPath(), "dist", "index.mjs");
12209
+ const bundlePath = path$1.join(terminalTitleSuggest.projectPath(), "dist", "index.mjs");
12108
12210
  let initialBundleMtimeMs = 0;
12109
12211
  try {
12110
12212
  initialBundleMtimeMs = fs$1.statSync(bundlePath).mtimeMs;
@@ -12160,7 +12262,7 @@ async function startDaemon() {
12160
12262
  });
12161
12263
  const claudeAuthService = new ClaudeAuthService({
12162
12264
  happyHomeDir: persistence.configuration.happyHomeDir,
12163
- happyLibDir: projectPath.projectPath(),
12265
+ happyLibDir: terminalTitleSuggest.projectPath(),
12164
12266
  credentialSource: daemonClaudeCredentials.source,
12165
12267
  getCredentialStore: () => claudeCredentialStoreSetting,
12166
12268
  setCredentialStore: async (store) => {
@@ -12471,6 +12573,127 @@ This session is now connected as the team lead. Call team_inspect to read the au
12471
12573
  };
12472
12574
  }
12473
12575
 
12576
+ const ACTIVE_FRESH_WINDOW_MS = 15 * 60 * 1e3;
12577
+ const DEFAULT_RESUME_WAIT_MS = 3e4;
12578
+ const DEFAULT_RESUME_POLL_MS = 1e3;
12579
+ function classifySessionState(input) {
12580
+ const { liveHere, server, now } = input;
12581
+ if (!server.found) return "not_found";
12582
+ if (typeof server.archivedAt === "number") return "archived";
12583
+ if (liveHere) return "live";
12584
+ if (server.active && typeof server.activeAt === "number" && now - server.activeAt <= ACTIVE_FRESH_WINDOW_MS) return "live";
12585
+ return "offline";
12586
+ }
12587
+ function explainNotLive(sessionId, status, resumeHint) {
12588
+ switch (status) {
12589
+ case "archived":
12590
+ return `Session ${sessionId} is archived \u2014 no live wrapper will receive this message. ${resumeHint}`;
12591
+ case "offline":
12592
+ return `Session ${sessionId} is offline (its wrapper exited or timed out) \u2014 no live wrapper will receive this message. ${resumeHint}`;
12593
+ case "not_found":
12594
+ return `Session ${sessionId} was not found on this account \u2014 it cannot be messaged or resumed. Spawn a new session instead.`;
12595
+ }
12596
+ }
12597
+ const CLI_RESUME_HINT = "Use --resume to bring it back on this machine, or spawn a new session.";
12598
+ const defaultDeps = {
12599
+ listLive: () => index.listDaemonSessions(),
12600
+ readState: (sessionId, persisted) => readSessionState(sessionId, persisted),
12601
+ send: (sessionId, persisted, text, client, options) => sendUserMessage(sessionId, persisted, text, client, options),
12602
+ unarchive: unarchiveSession,
12603
+ archive: archiveSession,
12604
+ resume: index.resumeDaemonSession,
12605
+ sleep: (ms) => index.delay(ms).then(() => void 0),
12606
+ now: () => Date.now()
12607
+ };
12608
+ async function deliverToSession(sessionId, persisted, text, client, options = {}, deps = {}) {
12609
+ const d = { ...defaultDeps, ...deps };
12610
+ const resumeHint = options.resumeHint ?? CLI_RESUME_HINT;
12611
+ const classify = async () => {
12612
+ const [live, server] = await Promise.all([d.listLive(), d.readState(sessionId, persisted)]);
12613
+ return classifySessionState({ liveHere: sessionLiveness(live, sessionId).live, server, now: d.now() });
12614
+ };
12615
+ let status = await classify();
12616
+ let resumed = false;
12617
+ let resumeOutcome;
12618
+ if (status !== "live") {
12619
+ if (!options.resume || status === "not_found") {
12620
+ return { sessionId, status, delivered: false, resumed: false, stored: false, error: explainNotLive(sessionId, status, resumeHint) };
12621
+ }
12622
+ const wasArchived = status === "archived";
12623
+ if (wasArchived) {
12624
+ try {
12625
+ await d.unarchive(sessionId);
12626
+ } catch (error) {
12627
+ const message = `unarchive failed: ${error instanceof Error ? error.message : String(error)}`;
12628
+ return { sessionId, status, delivered: false, resumed: false, stored: false, error: message, resume: { ok: false, error: message } };
12629
+ }
12630
+ }
12631
+ const outcome = await d.resume(sessionId, {
12632
+ ...typeof options.model === "string" ? { model: options.model } : {},
12633
+ ...options.permissionMode !== void 0 ? { permissionMode: options.permissionMode } : {}
12634
+ });
12635
+ if (!outcome.success) {
12636
+ let message = outcome.error ?? "resume failed";
12637
+ if (wasArchived) {
12638
+ try {
12639
+ await d.archive(sessionId);
12640
+ } catch (error) {
12641
+ message += `; failed to restore archive state: ${error instanceof Error ? error.message : String(error)}`;
12642
+ }
12643
+ }
12644
+ return { sessionId, status, delivered: false, resumed: false, stored: false, error: message, resume: { ok: false, error: message } };
12645
+ }
12646
+ resumed = true;
12647
+ resumeOutcome = { ok: true };
12648
+ status = await waitUntilLive(classify, d, options);
12649
+ if (status !== "live") {
12650
+ const waited = Math.round((options.waitMs ?? DEFAULT_RESUME_WAIT_MS) / 1e3);
12651
+ return {
12652
+ sessionId,
12653
+ status,
12654
+ delivered: false,
12655
+ resumed,
12656
+ stored: false,
12657
+ resume: resumeOutcome,
12658
+ error: `Session ${sessionId} was resumed but no live wrapper showed up within ${waited}s (state: ${status}); message not sent`
12659
+ };
12660
+ }
12661
+ }
12662
+ await d.send(sessionId, persisted, text, client, {
12663
+ ...options.model !== void 0 ? { model: options.model } : {},
12664
+ ...options.sentFrom !== void 0 ? { sentFrom: options.sentFrom } : {}
12665
+ });
12666
+ let after = "live";
12667
+ try {
12668
+ after = await classify();
12669
+ } catch {
12670
+ after = "live";
12671
+ }
12672
+ if (after !== "live") {
12673
+ return {
12674
+ sessionId,
12675
+ status: after,
12676
+ delivered: false,
12677
+ resumed,
12678
+ stored: true,
12679
+ ...resumeOutcome ? { resume: resumeOutcome } : {},
12680
+ error: `Session ${sessionId} went ${after} while sending: the message is stored server-side but no wrapper is attached to read it. ${after === "not_found" ? "Spawn a new session." : resumeHint}`
12681
+ };
12682
+ }
12683
+ return { sessionId, status: "live", delivered: true, resumed, stored: true, ...resumeOutcome ? { resume: resumeOutcome } : {} };
12684
+ }
12685
+ async function waitUntilLive(classify, d, options) {
12686
+ const waitMs = options.waitMs ?? DEFAULT_RESUME_WAIT_MS;
12687
+ const pollMs = options.pollMs ?? DEFAULT_RESUME_POLL_MS;
12688
+ const deadline = d.now() + waitMs;
12689
+ let status = await classify();
12690
+ while (status !== "live" && d.now() < deadline) {
12691
+ await d.sleep(pollMs);
12692
+ status = await classify();
12693
+ }
12694
+ return status;
12695
+ }
12696
+
12474
12697
  const PERSONAL_MEMORY_SOFT_LIMIT_CHARS = 2e3;
12475
12698
  function headingTitle(line) {
12476
12699
  const m = /^##(?!#)\s*(.*?)\s*$/.exec(line);
@@ -12570,11 +12793,13 @@ function fail(text) {
12570
12793
  function describeSession(id, persisted, extra) {
12571
12794
  const meta = persisted?.metadata;
12572
12795
  const parts = [id];
12796
+ if (extra?.live !== void 0) parts.push(extra.live ? "[running]" : "[not running]");
12573
12797
  if (meta?.summary?.text) parts.push(`title="${meta.summary.text}"`);
12574
12798
  if (meta?.path) parts.push(`cwd=${meta.path}`);
12575
12799
  if (meta?.flavor) parts.push(`agent=${meta.flavor}`);
12576
12800
  if (meta?.tags?.length) parts.push(`tags=${meta.tags.join(",")}`);
12577
12801
  if (meta?.variant === "assistant") parts.push("(assistant)");
12802
+ if (extra?.pid) parts.push(`pid=${extra.pid}`);
12578
12803
  parts.push(sessionWebUrl(id));
12579
12804
  return parts.join(" ");
12580
12805
  }
@@ -12628,19 +12853,27 @@ ${body}`);
12628
12853
  }
12629
12854
  });
12630
12855
  mcp.registerTool("session_send", {
12631
- description: "Send a user message into an existing session on this machine. Returns immediately after delivery \u2014 it does NOT wait for the session to respond; use session_read later to check progress.",
12856
+ description: "Send a user message into an existing session on this machine. Only delivers when a live wrapper will read it: an archived / offline session is refused (the server would store the message unread) unless resume:true brings it back on this machine first. Returns immediately after delivery \u2014 it does NOT wait for the session to respond; use session_read later to check progress.",
12632
12857
  title: "Send Message to Session",
12633
12858
  inputSchema: {
12634
12859
  sessionId: z.z.string().describe("The Happy session id to message"),
12635
- text: z.z.string().describe("The message text to send")
12860
+ text: z.z.string().describe("The message text to send"),
12861
+ resume: z.z.boolean().optional().describe("If the session is archived or offline, resume it on this machine (like the web Restore button) and wait until it is live before sending")
12636
12862
  }
12637
12863
  }, async (args) => {
12638
12864
  if (!index.isValidSessionId(args.sessionId)) return fail("Invalid sessionId");
12639
12865
  if (typeof args.text !== "string" || args.text.trim().length === 0) return fail("text must be non-empty");
12640
12866
  try {
12641
12867
  const persisted = await waitForSessionKey(args.sessionId, 0);
12642
- await sendUserMessage(args.sessionId, persisted, args.text, MCP_CLIENT_TAG);
12643
- return ok(`Message delivered to ${describeSession(args.sessionId, persisted)}`);
12868
+ const result = await deliverToSession(args.sessionId, persisted, args.text, MCP_CLIENT_TAG, {
12869
+ resume: args.resume === true,
12870
+ resumeHint: "Pass resume:true to bring it back on this machine, or spawn a new session."
12871
+ });
12872
+ if (!result.delivered) {
12873
+ const detail = result.error ?? `session is ${result.status}`;
12874
+ return fail(result.stored ? `Not delivered: ${detail}` : `Session ${args.sessionId} is ${result.status}: ${detail}`);
12875
+ }
12876
+ return ok(`Message delivered${result.resumed ? " (session resumed on this machine)" : ""} to ${describeSession(args.sessionId, persisted, { live: true })}`);
12644
12877
  } catch (error) {
12645
12878
  return fail(`Failed to send: ${error instanceof Error ? error.message : String(error)}`);
12646
12879
  }
@@ -13176,7 +13409,7 @@ function generateHookSettingsFile(port) {
13176
13409
  node_fs.mkdirSync(hooksDir, { recursive: true });
13177
13410
  const filename = `session-hook-${process.pid}.json`;
13178
13411
  const filepath = path.join(hooksDir, filename);
13179
- const forwarderScript = path.resolve(projectPath.projectPath(), "scripts", "session_hook_forwarder.cjs");
13412
+ const forwarderScript = path.resolve(terminalTitleSuggest.projectPath(), "scripts", "session_hook_forwarder.cjs");
13180
13413
  const hookCommand = `node "${forwarderScript}" ${port}`;
13181
13414
  const settings = {
13182
13415
  hooks: {
@@ -13413,7 +13646,7 @@ function registerSideQuestionHandler(rpc, deps) {
13413
13646
  const retainMs = deps.retainMs ?? SIDE_QUESTION_RETAIN_MS;
13414
13647
  const maxRunMs = deps.maxRunMs ?? SIDE_QUESTION_MAX_RUN_MS;
13415
13648
  const fork = deps.run ?? (async (input) => {
13416
- const { query } = await Promise.resolve().then(function () { return require('./index-CRaJ9k2p.cjs'); });
13649
+ const { query } = await Promise.resolve().then(function () { return require('./index-okLyUzeD.cjs'); });
13417
13650
  return runSideQuestion(query, input);
13418
13651
  });
13419
13652
  const run = async (input, live) => {
@@ -13532,8 +13765,8 @@ const MAX_TITLE_CHARS = 60;
13532
13765
  const GENERATION_TIMEOUT_MS = 3e4;
13533
13766
  function resolveClaudeBinary() {
13534
13767
  try {
13535
- 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-ZIW1jrYm.cjs', document.baseURI).href)));
13536
- const utilsPath = path.resolve(path.join(projectPath.projectPath(), "scripts", "claude_version_utils.cjs"));
13768
+ 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-eCjkm8Y2.cjs', document.baseURI).href)));
13769
+ const utilsPath = path.resolve(path.join(terminalTitleSuggest.projectPath(), "scripts", "claude_version_utils.cjs"));
13537
13770
  const { getClaudeCliPath } = require$1(utilsPath);
13538
13771
  const path$1 = getClaudeCliPath();
13539
13772
  if (typeof path$1 === "string" && path$1.length > 0) return path$1;
@@ -13590,7 +13823,12 @@ function runClaudeOneShot(binary, prompt) {
13590
13823
  try {
13591
13824
  child = node_child_process.spawn(binary, ["-p", "--model", "haiku", prompt], {
13592
13825
  stdio: ["ignore", "pipe", "ignore"],
13593
- env: process.env
13826
+ // HAPPY_MANAGED=1: this claude is run BY happy. The user-wide
13827
+ // terminal-mirror SessionStart hook exits on it, so a one-shot
13828
+ // spawned from inside a vh web terminal (VH_TERMINAL_ID
13829
+ // inherited — B-500's pi terminal bridge, or `very-happy` typed
13830
+ // in a terminal) never binds a mirror session to itself.
13831
+ env: { ...process.env, HAPPY_MANAGED: "1" }
13594
13832
  });
13595
13833
  } catch (error) {
13596
13834
  persistence.logger.debug("[titleGenerator] spawn failed", { error: String(error) });
@@ -13625,6 +13863,18 @@ function runClaudeOneShot(binary, prompt) {
13625
13863
  });
13626
13864
  });
13627
13865
  }
13866
+ async function suggestTitleForPrompt(prompt) {
13867
+ const binary = resolveClaudeBinary();
13868
+ if (!binary) {
13869
+ persistence.logger.debug("[titleGenerator] no claude binary; skipping auto-title");
13870
+ return null;
13871
+ }
13872
+ const stdout = await runClaudeOneShot(binary, buildPrompt(prompt));
13873
+ if (stdout == null) return null;
13874
+ const title = sanitizeTitle(stdout);
13875
+ if (!title) persistence.logger.debug("[titleGenerator] empty/unusable title output; skipping");
13876
+ return title;
13877
+ }
13628
13878
  class TitleGenerator {
13629
13879
  constructor(session) {
13630
13880
  this.session = session;
@@ -13648,23 +13898,12 @@ class TitleGenerator {
13648
13898
  });
13649
13899
  }
13650
13900
  async generate(firstUserMessage) {
13651
- const binary = resolveClaudeBinary();
13652
- if (!binary) {
13653
- persistence.logger.debug("[titleGenerator] no claude binary; skipping auto-title");
13654
- return;
13655
- }
13656
13901
  if (this.session.getMetadata()?.summary?.text) {
13657
13902
  persistence.logger.debug("[titleGenerator] summary appeared before generation; skipping");
13658
13903
  return;
13659
13904
  }
13660
- const prompt = buildPrompt(firstUserMessage);
13661
- const stdout = await runClaudeOneShot(binary, prompt);
13662
- if (stdout == null) return;
13663
- const title = sanitizeTitle(stdout);
13664
- if (!title) {
13665
- persistence.logger.debug("[titleGenerator] empty/unusable title output; skipping");
13666
- return;
13667
- }
13905
+ const title = await suggestTitleForPrompt(firstUserMessage);
13906
+ if (!title) return;
13668
13907
  if (this.session.getMetadata()?.summary?.text) {
13669
13908
  persistence.logger.debug("[titleGenerator] summary set during generation; not overwriting");
13670
13909
  return;
@@ -13979,8 +14218,8 @@ async function runClaude(credentials, options = {}) {
13979
14218
  machineId,
13980
14219
  homeDir: os.homedir(),
13981
14220
  happyHomeDir: persistence.configuration.happyHomeDir,
13982
- happyLibDir: projectPath.projectPath(),
13983
- happyToolsDir: path.resolve(projectPath.projectPath(), "tools", "unpacked"),
14221
+ happyLibDir: terminalTitleSuggest.projectPath(),
14222
+ happyToolsDir: path.resolve(terminalTitleSuggest.projectPath(), "tools", "unpacked"),
13984
14223
  startedFromDaemon: options.startedBy === "daemon",
13985
14224
  hostPid: process.pid,
13986
14225
  startedBy: options.startedBy || "terminal",
@@ -15761,9 +16000,9 @@ function resolveLocalSignupBootstrap(configuredMode, configuredInviteCodes, gene
15761
16000
  };
15762
16001
  }
15763
16002
 
15764
- 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-ZIW1jrYm.cjs', document.baseURI).href)));
16003
+ 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-eCjkm8Y2.cjs', document.baseURI).href)));
15765
16004
  const __dirname$1 = path.dirname(__filename$1);
15766
- const require_ = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-ZIW1jrYm.cjs', document.baseURI).href)));
16005
+ const require_ = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-eCjkm8Y2.cjs', document.baseURI).href)));
15767
16006
  const PRISMA_QUERY_ENGINE_FILES = {
15768
16007
  "arm64-darwin": "libquery_engine-darwin-arm64.dylib.node",
15769
16008
  "x64-darwin": "libquery_engine-darwin.dylib.node",
@@ -18279,7 +18518,7 @@ async function runCodex(opts) {
18279
18518
  }
18280
18519
  });
18281
18520
  const happyServer = await startHappyServer(session);
18282
- const bridgeEntrypoint = path.join(projectPath.projectPath(), "bin", "very-happy-mcp.mjs");
18521
+ const bridgeEntrypoint = path.join(terminalTitleSuggest.projectPath(), "bin", "very-happy-mcp.mjs");
18283
18522
  const mcpServers = {
18284
18523
  happy: {
18285
18524
  command: process.execPath,
@@ -18692,7 +18931,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
18692
18931
  process.exit(0);
18693
18932
  } else if (subcommand === "install-pi-tools") {
18694
18933
  try {
18695
- const { handleInstallPiTools } = await Promise.resolve().then(function () { return require('./installPiTools-BKnXjrVu.cjs'); });
18934
+ const { handleInstallPiTools } = await Promise.resolve().then(function () { return require('./installPiTools-DuZ6jZvX.cjs'); });
18696
18935
  await handleInstallPiTools(args.slice(1));
18697
18936
  } catch (error) {
18698
18937
  console.error(error instanceof Error ? error.message : "Pi tools installation failed");
@@ -18701,7 +18940,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
18701
18940
  return;
18702
18941
  } else if (subcommand === "install-terminal-hooks") {
18703
18942
  try {
18704
- const { installTerminalHooks, parseTerminalHooksArgs, TERMINAL_HOOKS_HELP } = await Promise.resolve().then(function () { return require('./installTerminalHooks-BoDxpaBO.cjs'); });
18943
+ const { installTerminalHooks, parseTerminalHooksArgs, TERMINAL_HOOKS_HELP } = await Promise.resolve().then(function () { return require('./installTerminalHooks-CA4OcAS7.cjs'); });
18705
18944
  const command = parseTerminalHooksArgs(args.slice(1));
18706
18945
  if (command.action === "help") {
18707
18946
  console.log(TERMINAL_HOOKS_HELP);
@@ -18718,7 +18957,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
18718
18957
  }
18719
18958
  } else if (subcommand === "agent-home") {
18720
18959
  try {
18721
- const { parseAgentHomeArgs, runAgentHomeCommand } = await Promise.resolve().then(function () { return require('./agentHome-CpJjrQZc.cjs'); });
18960
+ const { parseAgentHomeArgs, runAgentHomeCommand } = await Promise.resolve().then(function () { return require('./agentHome-BUsLTZnz.cjs'); });
18722
18961
  await runAgentHomeCommand(parseAgentHomeArgs(args.slice(1)));
18723
18962
  process.exit(0);
18724
18963
  } catch (error) {
@@ -18727,7 +18966,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
18727
18966
  }
18728
18967
  } else if (subcommand === "spawn") {
18729
18968
  try {
18730
- const { handleSpawnCommand } = await Promise.resolve().then(function () { return require('./spawn-DA8WAFmm.cjs'); });
18969
+ const { handleSpawnCommand } = await Promise.resolve().then(function () { return require('./spawn-DxrfHTF4.cjs'); });
18731
18970
  await handleSpawnCommand(args.slice(1));
18732
18971
  } catch (error) {
18733
18972
  console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
@@ -18739,7 +18978,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
18739
18978
  return;
18740
18979
  } else if (subcommand === "sessions") {
18741
18980
  try {
18742
- const { handleSessionsCommand } = await Promise.resolve().then(function () { return require('./sessions-Tad8elmy.cjs'); });
18981
+ const { handleSessionsCommand } = await Promise.resolve().then(function () { return require('./sessions-RIFUoy_g.cjs'); });
18743
18982
  await handleSessionsCommand(args.slice(1));
18744
18983
  } catch (error) {
18745
18984
  console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
@@ -18751,7 +18990,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
18751
18990
  return;
18752
18991
  } else if (subcommand === "send") {
18753
18992
  try {
18754
- const { handleSendCommand } = await Promise.resolve().then(function () { return require('./send-wl9ei8yG.cjs'); });
18993
+ const { handleSendCommand } = await Promise.resolve().then(function () { return require('./send-Bd00QcHC.cjs'); });
18755
18994
  await handleSendCommand(args.slice(1));
18756
18995
  } catch (error) {
18757
18996
  console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
@@ -18857,9 +19096,9 @@ Conversation history is preserved on the server, but in-flight tool calls are in
18857
19096
  if (geminiSubcommand === "project" && args[2] === "set" && args[3]) {
18858
19097
  const projectId = args[3];
18859
19098
  try {
18860
- const { saveGoogleCloudProjectToConfig } = await Promise.resolve().then(function () { return require('./config-DeJgSMh-.cjs'); });
18861
- const { readCredentialsForConfiguredRelay: readCredentialsForConfiguredRelay2 } = await Promise.resolve().then(function () { return require('./limits-BNTWyUaZ.cjs'); }).then(function (n) { return n.persistence; });
18862
- const { ApiClient: ApiClient2 } = await Promise.resolve().then(function () { return require('./types-CN28qJl7.cjs'); }).then(function (n) { return n.api; });
19099
+ const { saveGoogleCloudProjectToConfig } = await Promise.resolve().then(function () { return require('./config-DM_xI9M6.cjs'); });
19100
+ const { readCredentialsForConfiguredRelay: readCredentialsForConfiguredRelay2 } = await Promise.resolve().then(function () { return require('./limits-CmzISka2.cjs'); }).then(function (n) { return n.persistence; });
19101
+ const { ApiClient: ApiClient2 } = await Promise.resolve().then(function () { return require('./types-Bd_TGr0F.cjs'); }).then(function (n) { return n.api; });
18863
19102
  let userEmail = void 0;
18864
19103
  try {
18865
19104
  const credentials = await readCredentialsForConfiguredRelay2();
@@ -18890,7 +19129,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
18890
19129
  }
18891
19130
  if (geminiSubcommand === "project" && args[2] === "get") {
18892
19131
  try {
18893
- const { readGeminiLocalConfig } = await Promise.resolve().then(function () { return require('./config-DeJgSMh-.cjs'); });
19132
+ const { readGeminiLocalConfig } = await Promise.resolve().then(function () { return require('./config-DM_xI9M6.cjs'); });
18894
19133
  const config = readGeminiLocalConfig();
18895
19134
  if (config.googleCloudProject) {
18896
19135
  console.log(`Current Google Cloud Project: ${config.googleCloudProject}`);
@@ -18930,7 +19169,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
18930
19169
  process.exit(0);
18931
19170
  }
18932
19171
  try {
18933
- const { runGemini } = await Promise.resolve().then(function () { return require('./runGemini-Bgg1BzDK.cjs'); });
19172
+ const { runGemini } = await Promise.resolve().then(function () { return require('./runGemini-CNPGSsSK.cjs'); });
18934
19173
  let startedBy = void 0;
18935
19174
  for (let i = 1; i < args.length; i++) {
18936
19175
  if (args[i] === "--started-by") {
@@ -18953,7 +19192,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
18953
19192
  } else if (subcommand === "pi") {
18954
19193
  if (args[1] === "--terminal") {
18955
19194
  try {
18956
- const { runPiTerminal } = await Promise.resolve().then(function () { return require('./piTerminal-B7K75aXB.cjs'); });
19195
+ const { runPiTerminal } = await Promise.resolve().then(function () { return require('./piTerminal-fUogwxYr.cjs'); });
18957
19196
  process.exitCode = await runPiTerminal(args.slice(2));
18958
19197
  } catch (error) {
18959
19198
  console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
@@ -18970,7 +19209,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
18970
19209
  }
18971
19210
  };
18972
19211
  try {
18973
- const { runAcp, resolveAcpAgentConfig } = await Promise.resolve().then(function () { return require('./index-imt4mC41.cjs'); });
19212
+ const { runAcp, resolveAcpAgentConfig } = await Promise.resolve().then(function () { return require('./index-BUxBxSxJ.cjs'); });
18974
19213
  const parsed = parsePiRunnerArgs(args.slice(1));
18975
19214
  const resolved = resolveAcpAgentConfig(["pi", ...parsed.passthrough]);
18976
19215
  const { credentials } = await authAndSetupMachineIfNeeded();
@@ -18998,7 +19237,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
18998
19237
  return;
18999
19238
  } else if (subcommand === "acp") {
19000
19239
  try {
19001
- const { runAcp, resolveAcpAgentConfig } = await Promise.resolve().then(function () { return require('./index-imt4mC41.cjs'); });
19240
+ const { runAcp, resolveAcpAgentConfig } = await Promise.resolve().then(function () { return require('./index-BUxBxSxJ.cjs'); });
19002
19241
  let startedBy = void 0;
19003
19242
  let verbose = false;
19004
19243
  const acpArgs = [];
@@ -19038,7 +19277,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
19038
19277
  return;
19039
19278
  } else if (subcommand === "openclaw") {
19040
19279
  try {
19041
- const { runOpenClaw } = await Promise.resolve().then(function () { return require('./runOpenClaw-B9qWHybc.cjs'); });
19280
+ const { runOpenClaw } = await Promise.resolve().then(function () { return require('./runOpenClaw-Bsodkg_s.cjs'); });
19042
19281
  let startedBy = void 0;
19043
19282
  let verbose = false;
19044
19283
  let gatewayUrl;
@@ -19089,7 +19328,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
19089
19328
  return;
19090
19329
  } else if (subcommand === "todo") {
19091
19330
  try {
19092
- const { handleTodoCommand } = await Promise.resolve().then(function () { return require('./todo-mCMoGjJk.cjs'); });
19331
+ const { handleTodoCommand } = await Promise.resolve().then(function () { return require('./todo-B4cBFzHB.cjs'); });
19093
19332
  await handleTodoCommand(args.slice(1));
19094
19333
  } catch (error) {
19095
19334
  console.error(JSON.stringify({ error: error instanceof Error ? error.message : "Todo command failed" }));
@@ -19098,7 +19337,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
19098
19337
  return;
19099
19338
  } else if (subcommand === "teams") {
19100
19339
  try {
19101
- const { handleTeamsCommand } = await Promise.resolve().then(function () { return require('./teams-qVLrFcdd.cjs'); });
19340
+ const { handleTeamsCommand } = await Promise.resolve().then(function () { return require('./teams-Cfy0VMCo.cjs'); });
19102
19341
  await handleTeamsCommand(args.slice(1));
19103
19342
  } catch (error) {
19104
19343
  console.error(error instanceof Error ? error.message : "Teams command failed");
@@ -19107,7 +19346,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
19107
19346
  return;
19108
19347
  } else if (subcommand === "auto") {
19109
19348
  try {
19110
- const { handleAutoCommand } = await Promise.resolve().then(function () { return require('./auto-DncmTDvw.cjs'); });
19349
+ const { handleAutoCommand } = await Promise.resolve().then(function () { return require('./auto-IeldARBS.cjs'); });
19111
19350
  await handleAutoCommand(args.slice(1));
19112
19351
  } catch (error) {
19113
19352
  console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Automation command failed");
@@ -19119,7 +19358,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
19119
19358
  return;
19120
19359
  } else if (subcommand === "mcp" && (args.length === 1 || args.length === 2 && args[1] === "--terminal-tools")) {
19121
19360
  try {
19122
- const { handleMcpCommand } = await Promise.resolve().then(function () { return require('./mcp-CCKCKL6l.cjs'); });
19361
+ const { handleMcpCommand } = await Promise.resolve().then(function () { return require('./mcp-7iDHlyCI.cjs'); });
19123
19362
  await handleMcpCommand(args[1] === "--terminal-tools");
19124
19363
  } catch (error) {
19125
19364
  process.stderr.write(`[very-happy mcp] Fatal: ${error instanceof Error ? error.message : String(error)}
@@ -19512,6 +19751,7 @@ exports.appendStagedAttachmentsToPrompt = appendStagedAttachmentsToPrompt;
19512
19751
  exports.archiveSession = archiveSession;
19513
19752
  exports.checkPreviewPath = checkPreviewPath;
19514
19753
  exports.createSessionMetadata = createSessionMetadata;
19754
+ exports.deliverToSession = deliverToSession;
19515
19755
  exports.describeAction = describeAction;
19516
19756
  exports.describeTrigger = describeTrigger;
19517
19757
  exports.hashObject = hashObject;
@@ -19538,6 +19778,7 @@ exports.setupOfflineReconnection = setupOfflineReconnection;
19538
19778
  exports.stageClaudeAttachments = stageClaudeAttachments;
19539
19779
  exports.startHappyServer = startHappyServer;
19540
19780
  exports.stopSession = stopSession;
19781
+ exports.suggestTitleForPrompt = suggestTitleForPrompt;
19541
19782
  exports.tmuxSupportsSessionEnv = tmuxSupportsSessionEnv;
19542
19783
  exports.triggerFromFlags = triggerFromFlags;
19543
19784
  exports.waitForSessionKey = waitForSessionKey;