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
@@ -0,0 +1,38 @@
1
+ import { dirname, resolve } from 'path';
2
+ import { fileURLToPath } from 'url';
3
+ import { z } from 'zod';
4
+
5
+ const __dirname$1 = dirname(fileURLToPath(import.meta.url));
6
+ function projectPath() {
7
+ const path = resolve(__dirname$1, "..");
8
+ return path;
9
+ }
10
+
11
+ const TERMINAL_TITLE_SUGGEST_METHOD = "very-happy/terminal-title-suggest";
12
+ const TerminalTitleSuggestRequestSchema = z.object({
13
+ method: z.literal(TERMINAL_TITLE_SUGGEST_METHOD),
14
+ params: z.object({
15
+ /** The user's first prompt; the bridge samples its head (buildPrompt). */
16
+ prompt: z.string().min(1).max(2e4)
17
+ })
18
+ });
19
+ const TerminalTitleSuggestResultSchema = z.object({
20
+ /** Sanitized title, or null when nothing usable came back (keep the old title). */
21
+ title: z.string().nullable()
22
+ });
23
+ function baseName(cwd) {
24
+ const trimmed = cwd.replace(/[\\/]+$/, "");
25
+ const idx = Math.max(trimmed.lastIndexOf("/"), trimmed.lastIndexOf("\\"));
26
+ return idx >= 0 ? trimmed.slice(idx + 1) : trimmed;
27
+ }
28
+ function piSessionNameFromTitle(title, cwd) {
29
+ const m = /^(?:π|pi) - (.+)$/u.exec(title);
30
+ if (!m || !cwd) return void 0;
31
+ const suffix = ` - ${baseName(cwd)}`;
32
+ const rest = m[1];
33
+ if (!rest.endsWith(suffix)) return void 0;
34
+ const name = rest.slice(0, -suffix.length).trim();
35
+ return name || void 0;
36
+ }
37
+
38
+ export { TERMINAL_TITLE_SUGGEST_METHOD as T, TerminalTitleSuggestResultSchema as a, TerminalTitleSuggestRequestSchema as b, piSessionNameFromTitle as c, projectPath as p };
@@ -0,0 +1,45 @@
1
+ 'use strict';
2
+
3
+ var path = require('path');
4
+ var url = require('url');
5
+ var z = require('zod');
6
+
7
+ var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
8
+ const __dirname$1 = path.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('terminalTitleSuggest-Dji8I0Jy.cjs', document.baseURI).href))));
9
+ function projectPath() {
10
+ const path$1 = path.resolve(__dirname$1, "..");
11
+ return path$1;
12
+ }
13
+
14
+ const TERMINAL_TITLE_SUGGEST_METHOD = "very-happy/terminal-title-suggest";
15
+ const TerminalTitleSuggestRequestSchema = z.z.object({
16
+ method: z.z.literal(TERMINAL_TITLE_SUGGEST_METHOD),
17
+ params: z.z.object({
18
+ /** The user's first prompt; the bridge samples its head (buildPrompt). */
19
+ prompt: z.z.string().min(1).max(2e4)
20
+ })
21
+ });
22
+ const TerminalTitleSuggestResultSchema = z.z.object({
23
+ /** Sanitized title, or null when nothing usable came back (keep the old title). */
24
+ title: z.z.string().nullable()
25
+ });
26
+ function baseName(cwd) {
27
+ const trimmed = cwd.replace(/[\\/]+$/, "");
28
+ const idx = Math.max(trimmed.lastIndexOf("/"), trimmed.lastIndexOf("\\"));
29
+ return idx >= 0 ? trimmed.slice(idx + 1) : trimmed;
30
+ }
31
+ function piSessionNameFromTitle(title, cwd) {
32
+ const m = /^(?:π|pi) - (.+)$/u.exec(title);
33
+ if (!m || !cwd) return void 0;
34
+ const suffix = ` - ${baseName(cwd)}`;
35
+ const rest = m[1];
36
+ if (!rest.endsWith(suffix)) return void 0;
37
+ const name = rest.slice(0, -suffix.length).trim();
38
+ return name || void 0;
39
+ }
40
+
41
+ exports.TERMINAL_TITLE_SUGGEST_METHOD = TERMINAL_TITLE_SUGGEST_METHOD;
42
+ exports.TerminalTitleSuggestRequestSchema = TerminalTitleSuggestRequestSchema;
43
+ exports.TerminalTitleSuggestResultSchema = TerminalTitleSuggestResultSchema;
44
+ exports.piSessionNameFromTitle = piSessionNameFromTitle;
45
+ exports.projectPath = projectPath;
@@ -1,5 +1,5 @@
1
- import { f as readCredentialsForConfiguredRelay, g as createBuiltinTodoClient, c as configuration, B as BUILTIN_TODO_SKILL } from './limits-CKR_HJnO.mjs';
2
- import { f as readTeamScope, t as teamScopePath } from './agentGuidance-Daxn5Nvj.mjs';
1
+ import { f as readCredentialsForConfiguredRelay, g as createBuiltinTodoClient, c as configuration, B as BUILTIN_TODO_SKILL } from './limits-Dt7_unH4.mjs';
2
+ import { f as readTeamScope, t as teamScopePath } from './agentGuidance-TLYQxsm2.mjs';
3
3
  import 'node:fs/promises';
4
4
  import 'node:fs';
5
5
  import 'node:os';
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var persistence = require('./limits-BNTWyUaZ.cjs');
4
- var agentGuidance = require('./agentGuidance-CqBn77AI.cjs');
3
+ var persistence = require('./limits-CmzISka2.cjs');
4
+ var agentGuidance = require('./agentGuidance-DUBXppv-.cjs');
5
5
  require('node:fs/promises');
6
6
  require('node:fs');
7
7
  require('node:os');
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var axios = require('axios');
4
- var persistence = require('./limits-BNTWyUaZ.cjs');
4
+ var persistence = require('./limits-CmzISka2.cjs');
5
5
  var node_events = require('node:events');
6
6
  var socket_ioClient = require('socket.io-client');
7
7
  var z = require('zod');
@@ -12,7 +12,7 @@ var fs = require('fs/promises');
12
12
  var crypto = require('crypto');
13
13
  var path = require('path');
14
14
  var spawn = require('cross-spawn');
15
- var projectPath = require('./projectPath-ChLhdOyt.cjs');
15
+ var terminalTitleSuggest = require('./terminalTitleSuggest-Dji8I0Jy.cjs');
16
16
  var os = require('os');
17
17
  var cuid2 = require('@paralleldrive/cuid2');
18
18
  var promises = require('node:fs/promises');
@@ -94,8 +94,9 @@ const CliUpdateStateSchema = z.z.object({
94
94
  recommendedVersion: z.z.string().nullable(),
95
95
  minimumVersion: z.z.string().nullable(),
96
96
  status: z.z.enum(["current", "available", "required"]),
97
- /** B-351: the version this machine may install by itself. Pinned separately
98
- * from `recommendedVersion`; null means no unattended install. */
97
+ /** B-351/B-503: the version this machine may install by itself, as decided
98
+ * by the relay (exact pin or the promoted `latest`); null means no
99
+ * unattended install. */
99
100
  autoUpdateVersion: z.z.string().nullable().optional(),
100
101
  retrySupported: z.z.boolean().optional(),
101
102
  manualUpdateSupported: z.z.boolean().optional(),
@@ -652,7 +653,7 @@ async function answerSocketRequest(ack, run, onDrop) {
652
653
  }
653
654
 
654
655
  function run$1(args, options) {
655
- const RUNNER_PATH = path.resolve(path.join(projectPath.projectPath(), "scripts", "ripgrep_launcher.cjs"));
656
+ const RUNNER_PATH = path.resolve(path.join(terminalTitleSuggest.projectPath(), "scripts", "ripgrep_launcher.cjs"));
656
657
  return new Promise((resolve2, reject) => {
657
658
  const child = spawn.spawn("node", [RUNNER_PATH, JSON.stringify(args)], {
658
659
  stdio: ["pipe", "pipe", "pipe"],
@@ -683,7 +684,7 @@ function run$1(args, options) {
683
684
  function getBinaryPath() {
684
685
  const platformName = os.platform();
685
686
  const binaryName = platformName === "win32" ? "difft.exe" : "difft";
686
- return path.resolve(path.join(projectPath.projectPath(), "tools", "unpacked", binaryName));
687
+ return path.resolve(path.join(terminalTitleSuggest.projectPath(), "tools", "unpacked", binaryName));
687
688
  }
688
689
  function run(args, options) {
689
690
  const binaryPath = getBinaryPath();
@@ -2333,6 +2334,23 @@ async function spawnDaemonSession(directory, sessionId, opts) {
2333
2334
  });
2334
2335
  return result;
2335
2336
  }
2337
+ const ROUTE_NOT_FOUND_RE = /, (Not Found|HTTP 404)$/;
2338
+ async function resumeDaemonSession(sessionId, opts) {
2339
+ const result = await daemonPost("/resume-session", {
2340
+ sessionId,
2341
+ ...opts?.model !== void 0 ? { model: opts.model } : {},
2342
+ ...opts?.permissionMode !== void 0 ? { permissionMode: opts.permissionMode } : {}
2343
+ });
2344
+ if (result?.error) {
2345
+ const raw = String(result.error);
2346
+ const error = ROUTE_NOT_FOUND_RE.test(raw) ? "daemon too old to resume sessions (no /resume-session route); upgrade very-happy-cli and run `very-happy daemon start`" : raw.replace(/^Request failed: \/resume-session, /, "");
2347
+ return { success: false, error };
2348
+ }
2349
+ if (result?.success === true && typeof result.sessionId === "string") {
2350
+ return { success: true, sessionId: result.sessionId };
2351
+ }
2352
+ return { success: false, error: typeof result?.error === "string" ? result.error : "unexpected daemon response" };
2353
+ }
2336
2354
  async function notifyDaemonSessionEvent(sessionId, event, spawnedBy) {
2337
2355
  return daemonPost("/session-event", { sessionId, event, spawnedBy });
2338
2356
  }
@@ -9910,10 +9928,15 @@ function hostListSignature(items) {
9910
9928
  const SHELL_COMMANDS = /* @__PURE__ */ new Set(["zsh", "bash", "fish", "sh", "dash", "ksh", "tcsh", "csh"]);
9911
9929
  const TITLE_MAX_CHARS = 60;
9912
9930
  const JUNK_TITLES = /* @__PURE__ */ new Set(["tmux", "claude", "node", ...SHELL_COMMANDS]);
9913
- function deriveAutoTitle(paneTitle, hostname) {
9931
+ function deriveAutoTitle(paneTitle, hostname, cwd) {
9914
9932
  if (typeof paneTitle !== "string") return void 0;
9915
9933
  const t = paneTitle.replace(/^[^\p{L}\p{N}]+/u, "").replace(/\s+/g, " ").trim();
9916
9934
  if (!t) return void 0;
9935
+ const piName = terminalTitleSuggest.piSessionNameFromTitle(t, cwd);
9936
+ if (piName) {
9937
+ const chars2 = Array.from(piName);
9938
+ return chars2.length > TITLE_MAX_CHARS ? chars2.slice(0, TITLE_MAX_CHARS).join("") : piName;
9939
+ }
9917
9940
  const lower = t.toLowerCase();
9918
9941
  const host = (hostname || "").toLowerCase();
9919
9942
  const shortHost = host.split(".")[0];
@@ -11343,7 +11366,7 @@ class WebTerminalManager {
11343
11366
  const created = new TerminalSession(id, { kind: "pty", pty: proc }, void 0, cols, rows);
11344
11367
  created.direct = { cwd, createdAt: Date.now() };
11345
11368
  created.onTitleChange((title) => {
11346
- if (created.direct && !created.direct.manual) created.direct.title = deriveAutoTitle(title, os$1.hostname());
11369
+ if (created.direct && !created.direct.manual) created.direct.title = deriveAutoTitle(title, os$1.hostname(), created.direct.cwd);
11347
11370
  });
11348
11371
  created.onOutputChunk = (chunk) => {
11349
11372
  this.emit("terminal-output", { terminalId: id, data: chunk.data, seq: chunk.seq });
@@ -11809,7 +11832,7 @@ class WebTerminalManager {
11809
11832
  if (!s || !s.name.startsWith("vh-")) continue;
11810
11833
  const id = s.name.slice(3);
11811
11834
  let title = s.vhTitle;
11812
- const auto = deriveAutoTitle(s.paneTitle, hostname);
11835
+ const auto = deriveAutoTitle(s.paneTitle, hostname, s.cwd);
11813
11836
  if (auto && !s.manual && auto !== title) {
11814
11837
  try {
11815
11838
  const w = node_child_process.spawnSync(
@@ -12067,7 +12090,7 @@ function parseVhTerminals(stdout, hostname = os$1.hostname()) {
12067
12090
  if (!s || !s.name.startsWith("vh-")) continue;
12068
12091
  out.push({
12069
12092
  id: s.name.slice(3),
12070
- title: s.vhTitle ?? deriveAutoTitle(s.paneTitle, hostname),
12093
+ title: s.vhTitle ?? deriveAutoTitle(s.paneTitle, hostname, s.cwd),
12071
12094
  cwd: s.cwd,
12072
12095
  createdAt: s.created,
12073
12096
  activityAt: s.activity
@@ -16709,6 +16732,7 @@ exports.readVhTerminal = readVhTerminal;
16709
16732
  exports.refreshAgentHomes = refreshAgentHomes;
16710
16733
  exports.resolveAgentHomes = resolveAgentHomes;
16711
16734
  exports.resolveCliUpdateCheckInterval = resolveCliUpdateCheckInterval;
16735
+ exports.resumeDaemonSession = resumeDaemonSession;
16712
16736
  exports.scrubTmuxClientEnv = scrubTmuxClientEnv;
16713
16737
  exports.sendToVhTerminal = sendToVhTerminal;
16714
16738
  exports.setTerminalTitleViaDaemon = setTerminalTitleViaDaemon;
@@ -1,5 +1,5 @@
1
1
  import axios from 'axios';
2
- import { y as AgentVersionsSchema, l as logger, j as encodeBase64, z as encrypt, D as decrypt, E as decodeBase64, c as configuration, e as createEnvelope, s as streamKeyOf, F as readDaemonState, G as clearDaemonState, R as ReleaseDrainNoticeSchema, H as decryptBlob, I as RelayAssignmentResponseSchema, J as prepareClipboardText, K as prepareClipboardHistoryText, r as readSettings, d as readPersistedSessions, L as credentialRelayProblem, p as packageJson, M as RelayCandidatesResponseSchema, N as readTrackedClaudeSessionIds, O as readTrackedCodexThreadIds, P as libsodiumEncryptForPublicKey, Q as libsodiumPublicKeyFromSecretKey, S as getRandomBytes, T as redactLogValue } from './limits-CKR_HJnO.mjs';
2
+ import { y as AgentVersionsSchema, l as logger, j as encodeBase64, z as encrypt, D as decrypt, E as decodeBase64, c as configuration, e as createEnvelope, s as streamKeyOf, F as readDaemonState, G as clearDaemonState, R as ReleaseDrainNoticeSchema, H as decryptBlob, I as RelayAssignmentResponseSchema, J as prepareClipboardText, K as prepareClipboardHistoryText, r as readSettings, d as readPersistedSessions, L as credentialRelayProblem, p as packageJson, M as RelayCandidatesResponseSchema, N as readTrackedClaudeSessionIds, O as readTrackedCodexThreadIds, P as libsodiumEncryptForPublicKey, Q as libsodiumPublicKeyFromSecretKey, S as getRandomBytes, T as redactLogValue } from './limits-Dt7_unH4.mjs';
3
3
  import { EventEmitter } from 'node:events';
4
4
  import { io } from 'socket.io-client';
5
5
  import { z } from 'zod';
@@ -10,7 +10,7 @@ import { mkdir, writeFile, appendFile, stat, rename, unlink, readdir, readFile }
10
10
  import { randomUUID, createHash } from 'crypto';
11
11
  import { resolve, join, sep } from 'path';
12
12
  import { spawn } from 'cross-spawn';
13
- import { p as projectPath } from './projectPath-CSpqWdxp.mjs';
13
+ import { p as projectPath, c as piSessionNameFromTitle } from './terminalTitleSuggest-DKgX3osW.mjs';
14
14
  import os, { platform } from 'os';
15
15
  import { createId } from '@paralleldrive/cuid2';
16
16
  import { stat as stat$1, readdir as readdir$1, lstat, open, copyFile, unlink as unlink$1, readFile as readFile$1, rename as rename$1, writeFile as writeFile$1 } from 'node:fs/promises';
@@ -73,8 +73,9 @@ const CliUpdateStateSchema = z.object({
73
73
  recommendedVersion: z.string().nullable(),
74
74
  minimumVersion: z.string().nullable(),
75
75
  status: z.enum(["current", "available", "required"]),
76
- /** B-351: the version this machine may install by itself. Pinned separately
77
- * from `recommendedVersion`; null means no unattended install. */
76
+ /** B-351/B-503: the version this machine may install by itself, as decided
77
+ * by the relay (exact pin or the promoted `latest`); null means no
78
+ * unattended install. */
78
79
  autoUpdateVersion: z.string().nullable().optional(),
79
80
  retrySupported: z.boolean().optional(),
80
81
  manualUpdateSupported: z.boolean().optional(),
@@ -2312,6 +2313,23 @@ async function spawnDaemonSession(directory, sessionId, opts) {
2312
2313
  });
2313
2314
  return result;
2314
2315
  }
2316
+ const ROUTE_NOT_FOUND_RE = /, (Not Found|HTTP 404)$/;
2317
+ async function resumeDaemonSession(sessionId, opts) {
2318
+ const result = await daemonPost("/resume-session", {
2319
+ sessionId,
2320
+ ...opts?.model !== void 0 ? { model: opts.model } : {},
2321
+ ...opts?.permissionMode !== void 0 ? { permissionMode: opts.permissionMode } : {}
2322
+ });
2323
+ if (result?.error) {
2324
+ const raw = String(result.error);
2325
+ const error = ROUTE_NOT_FOUND_RE.test(raw) ? "daemon too old to resume sessions (no /resume-session route); upgrade very-happy-cli and run `very-happy daemon start`" : raw.replace(/^Request failed: \/resume-session, /, "");
2326
+ return { success: false, error };
2327
+ }
2328
+ if (result?.success === true && typeof result.sessionId === "string") {
2329
+ return { success: true, sessionId: result.sessionId };
2330
+ }
2331
+ return { success: false, error: typeof result?.error === "string" ? result.error : "unexpected daemon response" };
2332
+ }
2315
2333
  async function notifyDaemonSessionEvent(sessionId, event, spawnedBy) {
2316
2334
  return daemonPost("/session-event", { sessionId, event, spawnedBy });
2317
2335
  }
@@ -9889,10 +9907,15 @@ function hostListSignature(items) {
9889
9907
  const SHELL_COMMANDS = /* @__PURE__ */ new Set(["zsh", "bash", "fish", "sh", "dash", "ksh", "tcsh", "csh"]);
9890
9908
  const TITLE_MAX_CHARS = 60;
9891
9909
  const JUNK_TITLES = /* @__PURE__ */ new Set(["tmux", "claude", "node", ...SHELL_COMMANDS]);
9892
- function deriveAutoTitle(paneTitle, hostname) {
9910
+ function deriveAutoTitle(paneTitle, hostname, cwd) {
9893
9911
  if (typeof paneTitle !== "string") return void 0;
9894
9912
  const t = paneTitle.replace(/^[^\p{L}\p{N}]+/u, "").replace(/\s+/g, " ").trim();
9895
9913
  if (!t) return void 0;
9914
+ const piName = piSessionNameFromTitle(t, cwd);
9915
+ if (piName) {
9916
+ const chars2 = Array.from(piName);
9917
+ return chars2.length > TITLE_MAX_CHARS ? chars2.slice(0, TITLE_MAX_CHARS).join("") : piName;
9918
+ }
9896
9919
  const lower = t.toLowerCase();
9897
9920
  const host = (hostname || "").toLowerCase();
9898
9921
  const shortHost = host.split(".")[0];
@@ -11322,7 +11345,7 @@ class WebTerminalManager {
11322
11345
  const created = new TerminalSession(id, { kind: "pty", pty: proc }, void 0, cols, rows);
11323
11346
  created.direct = { cwd, createdAt: Date.now() };
11324
11347
  created.onTitleChange((title) => {
11325
- if (created.direct && !created.direct.manual) created.direct.title = deriveAutoTitle(title, os$1.hostname());
11348
+ if (created.direct && !created.direct.manual) created.direct.title = deriveAutoTitle(title, os$1.hostname(), created.direct.cwd);
11326
11349
  });
11327
11350
  created.onOutputChunk = (chunk) => {
11328
11351
  this.emit("terminal-output", { terminalId: id, data: chunk.data, seq: chunk.seq });
@@ -11788,7 +11811,7 @@ class WebTerminalManager {
11788
11811
  if (!s || !s.name.startsWith("vh-")) continue;
11789
11812
  const id = s.name.slice(3);
11790
11813
  let title = s.vhTitle;
11791
- const auto = deriveAutoTitle(s.paneTitle, hostname);
11814
+ const auto = deriveAutoTitle(s.paneTitle, hostname, s.cwd);
11792
11815
  if (auto && !s.manual && auto !== title) {
11793
11816
  try {
11794
11817
  const w = spawnSync(
@@ -12046,7 +12069,7 @@ function parseVhTerminals(stdout, hostname = os$1.hostname()) {
12046
12069
  if (!s || !s.name.startsWith("vh-")) continue;
12047
12070
  out.push({
12048
12071
  id: s.name.slice(3),
12049
- title: s.vhTitle ?? deriveAutoTitle(s.paneTitle, hostname),
12072
+ title: s.vhTitle ?? deriveAutoTitle(s.paneTitle, hostname, s.cwd),
12050
12073
  cwd: s.cwd,
12051
12074
  createdAt: s.created,
12052
12075
  activityAt: s.activity
@@ -16627,4 +16650,4 @@ const RawJSONLinesSchema = z.discriminatedUnion("type", [
16627
16650
  }).passthrough()
16628
16651
  ]);
16629
16652
 
16630
- export { stopDaemon as $, ApiClient as A, commandOnPath as B, CodexAppServerClient as C, deriveLocalCliUpdateSummary as D, isClaudeSessionId as E, ForkSourceMissingError as F, getLocalHappyAgentCredentialPath as G, readLocalHappyAgentCredentials as H, InvalidateSync as I, parseExactVersion as J, compareExactVersions as K, extractCompleteLines as L, MAX_CHAT_ATTACHMENT_SOURCE_BYTES as M, decideBackfill as N, parseTerminalHookPayload as O, tmuxArgs as P, scrubTmuxClientEnv as Q, RawJSONLinesSchema as R, decideMirrorBinding as S, MIRROR_BACKFILL_LINES_DEFAULT as T, mirrorLineKey as U, mirrorLocalId as V, listDaemonSessions as W, detectCLIAvailability as X, detectResumeSupport as Y, refreshAgentHomes as Z, isDaemonRunningCurrentlyInstalledHappyVersion as _, ApiSessionClient as a, TurnActivityTracker as a0, summarizeSpawnSessionForLog as a1, locateClaudeConversation as a2, agentHomeSpawnEnv as a3, shellescape as a4, fetchCliUpdateState as a5, resolveCliUpdateCheckInterval as a6, DEFAULT_CLI_UPDATE_CHECK_INTERVAL_MS as a7, cleanupDaemonState as a8, listVhTerminals as a9, isValidTerminalId as aa, readVhTerminal as ab, sendToVhTerminal as ac, TITLE_PROMPT_PREFIX as ad, BOARD_ANALYZER_PROMPT_PREFIX as ae, startOfflineReconnection as af, index as ag, api as ah, AGENT_HOME_ENV_NAMES as b, delay as c, describeAgentHome as d, expandHomePath as e, forkSession as f, getProjectPath as g, forkCodexThread as h, isValidSessionId as i, checkIfDaemonRunningAndCleanupStaleState as j, stopDaemonSession as k, pushClipboardViaDaemon as l, pushFilePreviewViaDaemon as m, setTerminalTitleViaDaemon as n, connectionState as o, probeLoginShellEnv as p, notifyDaemonSessionStarted as q, resolveAgentHomes as r, spawnDaemonSession as s, errorLogMetadata as t, contentLogMetadata as u, notifyDaemonSessionEvent as v, initializeSandbox as w, wrapCommand as x, AsyncLock as y, notifyDaemonClaudeAuthFailed as z };
16653
+ export { stopDaemon as $, ApiClient as A, commandOnPath as B, CodexAppServerClient as C, deriveLocalCliUpdateSummary as D, isClaudeSessionId as E, ForkSourceMissingError as F, getLocalHappyAgentCredentialPath as G, readLocalHappyAgentCredentials as H, InvalidateSync as I, parseExactVersion as J, compareExactVersions as K, extractCompleteLines as L, MAX_CHAT_ATTACHMENT_SOURCE_BYTES as M, decideBackfill as N, parseTerminalHookPayload as O, tmuxArgs as P, scrubTmuxClientEnv as Q, RawJSONLinesSchema as R, decideMirrorBinding as S, MIRROR_BACKFILL_LINES_DEFAULT as T, mirrorLineKey as U, mirrorLocalId as V, listDaemonSessions as W, detectCLIAvailability as X, detectResumeSupport as Y, refreshAgentHomes as Z, isDaemonRunningCurrentlyInstalledHappyVersion as _, ApiSessionClient as a, TurnActivityTracker as a0, summarizeSpawnSessionForLog as a1, locateClaudeConversation as a2, agentHomeSpawnEnv as a3, shellescape as a4, fetchCliUpdateState as a5, resolveCliUpdateCheckInterval as a6, DEFAULT_CLI_UPDATE_CHECK_INTERVAL_MS as a7, cleanupDaemonState as a8, resumeDaemonSession as a9, listVhTerminals as aa, isValidTerminalId as ab, readVhTerminal as ac, sendToVhTerminal as ad, TITLE_PROMPT_PREFIX as ae, BOARD_ANALYZER_PROMPT_PREFIX as af, startOfflineReconnection as ag, index as ah, api as ai, AGENT_HOME_ENV_NAMES as b, delay as c, describeAgentHome as d, expandHomePath as e, forkSession as f, getProjectPath as g, forkCodexThread as h, isValidSessionId as i, checkIfDaemonRunningAndCleanupStaleState as j, stopDaemonSession as k, pushClipboardViaDaemon as l, pushFilePreviewViaDaemon as m, setTerminalTitleViaDaemon as n, connectionState as o, probeLoginShellEnv as p, notifyDaemonSessionStarted as q, resolveAgentHomes as r, spawnDaemonSession as s, errorLogMetadata as t, contentLogMetadata as u, notifyDaemonSessionEvent as v, initializeSandbox as w, wrapCommand as x, AsyncLock as y, notifyDaemonClaudeAuthFailed as z };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "very-happy-cli",
3
- "version": "0.2.152",
3
+ "version": "0.2.154",
4
4
  "description": "Remote multi-agent workspace CLI with deep Claude integration, native terminal streaming, and self-hosting.",
5
5
  "author": "Kirill Dubovitskiy",
6
6
  "contributors": [
@@ -117,12 +117,12 @@
117
117
  "zod": "^4.0.0"
118
118
  },
119
119
  "optionalDependencies": {
120
- "very-happy-tools-arm64-darwin": "0.2.152",
121
- "very-happy-tools-x64-darwin": "0.2.152",
122
- "very-happy-tools-arm64-linux": "0.2.152",
123
- "very-happy-tools-x64-linux": "0.2.152",
124
- "very-happy-tools-arm64-win32": "0.2.152",
125
- "very-happy-tools-x64-win32": "0.2.152"
120
+ "very-happy-tools-arm64-darwin": "0.2.154",
121
+ "very-happy-tools-x64-darwin": "0.2.154",
122
+ "very-happy-tools-arm64-linux": "0.2.154",
123
+ "very-happy-tools-x64-linux": "0.2.154",
124
+ "very-happy-tools-arm64-win32": "0.2.154",
125
+ "very-happy-tools-x64-win32": "0.2.154"
126
126
  },
127
127
  "devDependencies": {
128
128
  "@slopus/happy-wire": "workspace:*",
@@ -1,10 +0,0 @@
1
- import { dirname, resolve } from 'path';
2
- import { fileURLToPath } from 'url';
3
-
4
- const __dirname$1 = dirname(fileURLToPath(import.meta.url));
5
- function projectPath() {
6
- const path = resolve(__dirname$1, "..");
7
- return path;
8
- }
9
-
10
- export { projectPath as p };
@@ -1,13 +0,0 @@
1
- 'use strict';
2
-
3
- var path = require('path');
4
- var url = require('url');
5
-
6
- var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
7
- const __dirname$1 = path.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('projectPath-ChLhdOyt.cjs', document.baseURI).href))));
8
- function projectPath() {
9
- const path$1 = path.resolve(__dirname$1, "..");
10
- return path$1;
11
- }
12
-
13
- exports.projectPath = projectPath;