very-happy-cli 0.2.89 → 0.2.90

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 (31) hide show
  1. package/dist/{AcpBackend-DuxcHPyn.mjs → AcpBackend-BV4wSnJ3.mjs} +1 -1
  2. package/dist/{AcpBackend-ClEvE-A-.cjs → AcpBackend-CnYZFdd0.cjs} +1 -1
  3. package/dist/{AcpSessionManager-DgbEf8FX.cjs → AcpSessionManager-BPBdrrME.cjs} +1 -1
  4. package/dist/{AcpSessionManager-CGrA8bTm.mjs → AcpSessionManager-Cyne6Rmg.mjs} +1 -1
  5. package/dist/{config-CdoGLla8.mjs → config-BEdyyciP.mjs} +2 -2
  6. package/dist/{config-BZNnPK1L.cjs → config-CgXitj0f.cjs} +2 -2
  7. package/dist/{index-DYDAFqAN.cjs → index-4YmVbx7j.cjs} +70 -24
  8. package/dist/{index-Bx-UTV3I.cjs → index-B1wTVXjt.cjs} +4 -4
  9. package/dist/{index-BP2wylez.mjs → index-Dfu5uvjk.mjs} +5 -5
  10. package/dist/{index-vCgb7QnZ.mjs → index-an09rejO.mjs} +67 -21
  11. package/dist/index.cjs +2 -2
  12. package/dist/index.mjs +2 -2
  13. package/dist/{installTerminalHooks-C7JS6CBM.mjs → installTerminalHooks-C-OgZr5k.mjs} +2 -2
  14. package/dist/{installTerminalHooks-T4NE5fmC.cjs → installTerminalHooks-DDpVxk8-.cjs} +2 -2
  15. package/dist/lib.cjs +1 -1
  16. package/dist/lib.d.cts +8 -0
  17. package/dist/lib.d.mts +8 -0
  18. package/dist/lib.mjs +1 -1
  19. package/dist/{mcp-DgPg5mKa.cjs → mcp-B6Nq-RUL.cjs} +2 -2
  20. package/dist/{mcp-B3EgenZh.mjs → mcp-Du-N0qlK.mjs} +2 -2
  21. package/dist/{runGemini-xZnGj7jx.cjs → runGemini-ChG7cGMC.cjs} +4 -4
  22. package/dist/{runGemini-B3iv1QRL.mjs → runGemini-DBr_TiTL.mjs} +4 -4
  23. package/dist/{runOpenClaw-CmM4ZLYi.mjs → runOpenClaw-Cbde8t92.mjs} +3 -3
  24. package/dist/{runOpenClaw-6ZLPeYYZ.cjs → runOpenClaw-D2jtVgpC.cjs} +3 -3
  25. package/dist/{send-M2ax7UGy.mjs → send-BHliX59m.mjs} +2 -2
  26. package/dist/{send-S9ibMiAt.cjs → send-Bjen1TUE.cjs} +2 -2
  27. package/dist/{spawn-ie_kfwQe.cjs → spawn-CH1Rq-LW.cjs} +2 -2
  28. package/dist/{spawn-Dx_xnLlg.mjs → spawn-JxaPHAoP.mjs} +2 -2
  29. package/dist/{types-DLI6sss2.cjs → types-BNGeiP1C.cjs} +62 -44
  30. package/dist/{types-d_104eQF.mjs → types-DS3i_5LV.mjs} +60 -44
  31. package/package.json +7 -7
@@ -3,8 +3,8 @@ import { join, resolve } from 'node:path';
3
3
  import { homedir } from 'node:os';
4
4
  import { spawnSync } from 'node:child_process';
5
5
  import chalk from 'chalk';
6
- import { p as projectPath } from './types-d_104eQF.mjs';
7
- import { t as tmuxSupportsSessionEnv } from './index-vCgb7QnZ.mjs';
6
+ import { p as projectPath } from './types-DS3i_5LV.mjs';
7
+ import { t as tmuxSupportsSessionEnv } from './index-an09rejO.mjs';
8
8
  import 'axios';
9
9
  import 'node:util';
10
10
  import 'node:fs/promises';
@@ -5,8 +5,8 @@ var path = require('node:path');
5
5
  var os = require('node:os');
6
6
  var node_child_process = require('node:child_process');
7
7
  var chalk = require('chalk');
8
- var persistence = require('./types-DLI6sss2.cjs');
9
- var index = require('./index-DYDAFqAN.cjs');
8
+ var persistence = require('./types-BNGeiP1C.cjs');
9
+ var index = require('./index-4YmVbx7j.cjs');
10
10
  require('axios');
11
11
  require('node:util');
12
12
  require('node:fs/promises');
package/dist/lib.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var persistence = require('./types-DLI6sss2.cjs');
3
+ var persistence = require('./types-BNGeiP1C.cjs');
4
4
  require('axios');
5
5
  require('chalk');
6
6
  require('node:util');
package/dist/lib.d.cts CHANGED
@@ -451,6 +451,14 @@ type Metadata = {
451
451
  flavor?: string;
452
452
  sandbox?: SandboxConfig | null;
453
453
  dangerouslySkipPermissions?: boolean | null;
454
+ /**
455
+ * Effective permission mode the running Claude process enforces right now
456
+ * (SDK vocabulary: default | acceptEdits | bypassPermissions | plan). The
457
+ * CLI is the single source of truth: it writes this at start, on every
458
+ * message/RPC/plan-approval change. Web displays it verbatim; old clients
459
+ * ignore it and old CLIs never write it (capability claude-live-permission-v2).
460
+ */
461
+ permissionMode?: string;
454
462
  /** Lineage for sessions created via the fork / duplicate flow. */
455
463
  parentSessionId?: string;
456
464
  forkedFromMessageId?: string;
package/dist/lib.d.mts CHANGED
@@ -451,6 +451,14 @@ type Metadata = {
451
451
  flavor?: string;
452
452
  sandbox?: SandboxConfig | null;
453
453
  dangerouslySkipPermissions?: boolean | null;
454
+ /**
455
+ * Effective permission mode the running Claude process enforces right now
456
+ * (SDK vocabulary: default | acceptEdits | bypassPermissions | plan). The
457
+ * CLI is the single source of truth: it writes this at start, on every
458
+ * message/RPC/plan-approval change. Web displays it verbatim; old clients
459
+ * ignore it and old CLIs never write it (capability claude-live-permission-v2).
460
+ */
461
+ permissionMode?: string;
454
462
  /** Lineage for sessions created via the fork / duplicate flow. */
455
463
  parentSessionId?: string;
456
464
  forkedFromMessageId?: string;
package/dist/lib.mjs CHANGED
@@ -1,4 +1,4 @@
1
- export { A as ApiClient, a as ApiSessionClient, R as RawJSONLinesSchema, c as configuration, l as logger } from './types-d_104eQF.mjs';
1
+ export { A as ApiClient, a as ApiSessionClient, R as RawJSONLinesSchema, c as configuration, l as logger } from './types-DS3i_5LV.mjs';
2
2
  import 'axios';
3
3
  import 'chalk';
4
4
  import 'node:util';
@@ -3,9 +3,9 @@
3
3
  var mcp_js = require('@modelcontextprotocol/sdk/server/mcp.js');
4
4
  var stdio_js = require('@modelcontextprotocol/sdk/server/stdio.js');
5
5
  var z = require('zod');
6
- var index = require('./index-DYDAFqAN.cjs');
6
+ var index = require('./index-4YmVbx7j.cjs');
7
7
  var limits = require('./limits-KdWKmwtH.cjs');
8
- var persistence = require('./types-DLI6sss2.cjs');
8
+ var persistence = require('./types-BNGeiP1C.cjs');
9
9
  require('chalk');
10
10
  require('node:os');
11
11
  require('node:crypto');
@@ -1,9 +1,9 @@
1
1
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
2
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
3
3
  import { z } from 'zod';
4
- import { p as pushClipboardViaDaemon } from './index-vCgb7QnZ.mjs';
4
+ import { p as pushClipboardViaDaemon } from './index-an09rejO.mjs';
5
5
  import { C as CLIPBOARD_TOOL_NAME, a as CLIPBOARD_TOOL_TITLE, b as CLIPBOARD_TOOL_DESCRIPTION, c as CLIPBOARD_MAX_BYTES } from './limits-CwFb5S2b.mjs';
6
- import { l as logger } from './types-d_104eQF.mjs';
6
+ import { l as logger } from './types-DS3i_5LV.mjs';
7
7
  import 'chalk';
8
8
  import 'node:os';
9
9
  import 'node:crypto';
@@ -4,10 +4,10 @@ var ink = require('ink');
4
4
  var React = require('react');
5
5
  var node_crypto = require('node:crypto');
6
6
  var path = require('node:path');
7
- var persistence = require('./types-DLI6sss2.cjs');
8
- var index = require('./index-DYDAFqAN.cjs');
9
- var AcpBackend = require('./AcpBackend-ClEvE-A-.cjs');
10
- var config = require('./config-BZNnPK1L.cjs');
7
+ var persistence = require('./types-BNGeiP1C.cjs');
8
+ var index = require('./index-4YmVbx7j.cjs');
9
+ var AcpBackend = require('./AcpBackend-CnYZFdd0.cjs');
10
+ var config = require('./config-CgXitj0f.cjs');
11
11
  require('axios');
12
12
  require('chalk');
13
13
  require('node:util');
@@ -2,10 +2,10 @@ import { useStdout, useInput, Box, Text, render } from 'ink';
2
2
  import React, { useState, useRef, useEffect, useCallback } from 'react';
3
3
  import { randomUUID } from 'node:crypto';
4
4
  import { join } from 'node:path';
5
- import { l as logger, h as connectionState, A as ApiClient, i as readSettings, e as errorLogMetadata, j as encodeBase64, p as projectPath, d as contentLogMetadata } from './types-d_104eQF.mjs';
6
- import { g as GEMINI_API_KEY_ENV, j as GOOGLE_API_KEY_ENV, G as GEMINI_MODEL_ENV, B as BasePermissionHandler, k as BaseReasoningProcessor, i as initialMachineMetadata, d as createSessionMetadata, e as setupOfflineReconnection, n as notifyDaemonSessionStarted, M as MessageQueue2, h as hashObject, l as MessageBuffer, C as CHANGE_TITLE_INSTRUCTION, r as registerKillSessionHandler, f as startHappyServer } from './index-vCgb7QnZ.mjs';
7
- import { A as AcpBackend } from './AcpBackend-DuxcHPyn.mjs';
8
- import { readGeminiLocalConfig, determineGeminiModel, getGeminiModelSource, getInitialGeminiModel, saveGeminiModelToConfig } from './config-CdoGLla8.mjs';
5
+ import { l as logger, h as connectionState, A as ApiClient, i as readSettings, e as errorLogMetadata, j as encodeBase64, p as projectPath, d as contentLogMetadata } from './types-DS3i_5LV.mjs';
6
+ import { g as GEMINI_API_KEY_ENV, j as GOOGLE_API_KEY_ENV, G as GEMINI_MODEL_ENV, B as BasePermissionHandler, k as BaseReasoningProcessor, i as initialMachineMetadata, d as createSessionMetadata, e as setupOfflineReconnection, n as notifyDaemonSessionStarted, M as MessageQueue2, h as hashObject, l as MessageBuffer, C as CHANGE_TITLE_INSTRUCTION, r as registerKillSessionHandler, f as startHappyServer } from './index-an09rejO.mjs';
7
+ import { A as AcpBackend } from './AcpBackend-BV4wSnJ3.mjs';
8
+ import { readGeminiLocalConfig, determineGeminiModel, getGeminiModelSource, getInitialGeminiModel, saveGeminiModelToConfig } from './config-BEdyyciP.mjs';
9
9
  import 'axios';
10
10
  import 'chalk';
11
11
  import 'node:util';
@@ -3,9 +3,9 @@ import { execFileSync } from 'node:child_process';
3
3
  import os from 'node:os';
4
4
  import { existsSync, readFileSync } from 'node:fs';
5
5
  import { join } from 'node:path';
6
- import { k as ensurePrivateDirectorySync, m as hardenPrivateFileSync, w as writePrivateFileSync, e as errorLogMetadata, d as contentLogMetadata, h as connectionState, A as ApiClient, i as readSettings, j as encodeBase64, l as logger, c as configuration } from './types-d_104eQF.mjs';
7
- import { A as AcpSessionManager } from './AcpSessionManager-CGrA8bTm.mjs';
8
- import { i as initialMachineMetadata, d as createSessionMetadata, e as setupOfflineReconnection, n as notifyDaemonSessionStarted, M as MessageQueue2, r as registerKillSessionHandler } from './index-vCgb7QnZ.mjs';
6
+ import { k as ensurePrivateDirectorySync, m as hardenPrivateFileSync, w as writePrivateFileSync, e as errorLogMetadata, d as contentLogMetadata, h as connectionState, A as ApiClient, i as readSettings, j as encodeBase64, l as logger, c as configuration } from './types-DS3i_5LV.mjs';
7
+ import { A as AcpSessionManager } from './AcpSessionManager-Cyne6Rmg.mjs';
8
+ import { i as initialMachineMetadata, d as createSessionMetadata, e as setupOfflineReconnection, n as notifyDaemonSessionStarted, M as MessageQueue2, r as registerKillSessionHandler } from './index-an09rejO.mjs';
9
9
  import WebSocket from 'ws';
10
10
  import * as ed from '@noble/ed25519';
11
11
  import { sha512 } from '@noble/hashes/sha2.js';
@@ -5,9 +5,9 @@ var node_child_process = require('node:child_process');
5
5
  var os = require('node:os');
6
6
  var node_fs = require('node:fs');
7
7
  var path = require('node:path');
8
- var persistence = require('./types-DLI6sss2.cjs');
9
- var AcpSessionManager = require('./AcpSessionManager-DgbEf8FX.cjs');
10
- var index = require('./index-DYDAFqAN.cjs');
8
+ var persistence = require('./types-BNGeiP1C.cjs');
9
+ var AcpSessionManager = require('./AcpSessionManager-BPBdrrME.cjs');
10
+ var index = require('./index-4YmVbx7j.cjs');
11
11
  var WebSocket = require('ws');
12
12
  var ed = require('@noble/ed25519');
13
13
  var sha2_js = require('@noble/hashes/sha2.js');
@@ -1,8 +1,8 @@
1
1
  import chalk from 'chalk';
2
2
  import { readFileSync } from 'node:fs';
3
3
  import { resolve } from 'node:path';
4
- import { r as readPersistedSessions, c as configuration } from './types-d_104eQF.mjs';
5
- import { b as sendUserMessage, a as sessionWebUrl } from './index-vCgb7QnZ.mjs';
4
+ import { r as readPersistedSessions, c as configuration } from './types-DS3i_5LV.mjs';
5
+ import { b as sendUserMessage, a as sessionWebUrl } from './index-an09rejO.mjs';
6
6
  import 'axios';
7
7
  import 'node:util';
8
8
  import 'node:os';
@@ -3,8 +3,8 @@
3
3
  var chalk = require('chalk');
4
4
  var node_fs = require('node:fs');
5
5
  var path = require('node:path');
6
- var persistence = require('./types-DLI6sss2.cjs');
7
- var index = require('./index-DYDAFqAN.cjs');
6
+ var persistence = require('./types-BNGeiP1C.cjs');
7
+ var index = require('./index-4YmVbx7j.cjs');
8
8
  require('axios');
9
9
  require('node:util');
10
10
  require('node:os');
@@ -3,8 +3,8 @@
3
3
  var chalk = require('chalk');
4
4
  var node_fs = require('node:fs');
5
5
  var path = require('node:path');
6
- var index = require('./index-DYDAFqAN.cjs');
7
- var persistence = require('./types-DLI6sss2.cjs');
6
+ var index = require('./index-4YmVbx7j.cjs');
7
+ var persistence = require('./types-BNGeiP1C.cjs');
8
8
  require('node:os');
9
9
  require('node:crypto');
10
10
  require('cross-spawn');
@@ -1,8 +1,8 @@
1
1
  import chalk from 'chalk';
2
2
  import { readFileSync, statSync } from 'node:fs';
3
3
  import { resolve } from 'node:path';
4
- import { c as checkIfDaemonRunningAndCleanupStaleState, s as spawnDaemonSession, a as sessionWebUrl, w as waitForSessionKey, b as sendUserMessage } from './index-vCgb7QnZ.mjs';
5
- import { l as logger } from './types-d_104eQF.mjs';
4
+ import { c as checkIfDaemonRunningAndCleanupStaleState, s as spawnDaemonSession, a as sessionWebUrl, w as waitForSessionKey, b as sendUserMessage } from './index-an09rejO.mjs';
5
+ import { l as logger } from './types-DS3i_5LV.mjs';
6
6
  import 'node:os';
7
7
  import 'node:crypto';
8
8
  import 'cross-spawn';
@@ -51,7 +51,7 @@ var z__namespace = /*#__PURE__*/_interopNamespaceDefault(z);
51
51
  var pty__namespace = /*#__PURE__*/_interopNamespaceDefault(pty);
52
52
 
53
53
  var name = "very-happy-cli";
54
- var version = "0.2.89";
54
+ var version = "0.2.90";
55
55
  var description = "Remote multi-agent workspace CLI with deep Claude integration, native terminal streaming, and self-hosting.";
56
56
  var author = "Kirill Dubovitskiy";
57
57
  var contributors = [
@@ -164,12 +164,12 @@ var dependencies = {
164
164
  zod: "^4.0.0"
165
165
  };
166
166
  var optionalDependencies = {
167
- "very-happy-tools-arm64-darwin": "0.2.89",
168
- "very-happy-tools-x64-darwin": "0.2.89",
169
- "very-happy-tools-arm64-linux": "0.2.89",
170
- "very-happy-tools-x64-linux": "0.2.89",
171
- "very-happy-tools-arm64-win32": "0.2.89",
172
- "very-happy-tools-x64-win32": "0.2.89"
167
+ "very-happy-tools-arm64-darwin": "0.2.90",
168
+ "very-happy-tools-x64-darwin": "0.2.90",
169
+ "very-happy-tools-arm64-linux": "0.2.90",
170
+ "very-happy-tools-x64-linux": "0.2.90",
171
+ "very-happy-tools-arm64-win32": "0.2.90",
172
+ "very-happy-tools-x64-win32": "0.2.90"
173
173
  };
174
174
  var devDependencies = {
175
175
  "@slopus/happy-wire": "workspace:*",
@@ -1484,7 +1484,7 @@ class RpcHandlerManager {
1484
1484
  }
1485
1485
  }
1486
1486
 
1487
- const __dirname$1 = path$1.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('types-DLI6sss2.cjs', document.baseURI).href))));
1487
+ const __dirname$1 = path$1.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('types-BNGeiP1C.cjs', document.baseURI).href))));
1488
1488
  function projectPath() {
1489
1489
  const path = path$1.resolve(__dirname$1, "..");
1490
1490
  return path;
@@ -8829,6 +8829,20 @@ function previewAscii(line) {
8829
8829
  return line.length > 80 ? `${out}\u2026` : out;
8830
8830
  }
8831
8831
 
8832
+ const VH_TMUX_SOCKET_ENV = "VH_TMUX_SOCKET";
8833
+ function tmuxSocketFlags(env = process.env) {
8834
+ const socket = env[VH_TMUX_SOCKET_ENV];
8835
+ return socket ? ["-S", socket] : [];
8836
+ }
8837
+ function tmuxArgs(args, env = process.env) {
8838
+ return [...tmuxSocketFlags(env), ...args];
8839
+ }
8840
+ function scrubTmuxClientEnv(env) {
8841
+ delete env.TMUX;
8842
+ delete env.TMUX_PANE;
8843
+ return env;
8844
+ }
8845
+
8832
8846
  const CONTROL_CLIENT_KILL_GRACE_MS = 2e3;
8833
8847
  const CONTROL_COMMAND_TIMEOUT_MS = 1e4;
8834
8848
  function isSafeControlCommand(command) {
@@ -8838,7 +8852,7 @@ class ControlClient {
8838
8852
  constructor(tmuxSession, env, handlers) {
8839
8853
  this.tmuxSession = tmuxSession;
8840
8854
  this.handlers = handlers;
8841
- this.child = node_child_process.spawn("tmux", ["-C", "attach-session", "-t", `=${tmuxSession}:`], {
8855
+ this.child = node_child_process.spawn("tmux", tmuxArgs(["-C", "attach-session", "-t", `=${tmuxSession}:`], env), {
8842
8856
  stdio: ["pipe", "pipe", "pipe"],
8843
8857
  env
8844
8858
  });
@@ -9990,7 +10004,7 @@ let tmuxAvailableCache = null;
9990
10004
  function isTmuxAvailable() {
9991
10005
  if (tmuxAvailableCache !== null) return tmuxAvailableCache;
9992
10006
  try {
9993
- const r = node_child_process.spawnSync("tmux", ["-V"], { stdio: "ignore", env: ptyEnv() });
10007
+ const r = node_child_process.spawnSync("tmux", tmuxArgs(["-V"]), { stdio: "ignore", env: ptyEnv() });
9994
10008
  tmuxAvailableCache = r.status === 0;
9995
10009
  } catch {
9996
10010
  tmuxAvailableCache = false;
@@ -10001,7 +10015,7 @@ let tmuxEnvFlagCache = null;
10001
10015
  function tmuxSupportsEnvFlag() {
10002
10016
  if (tmuxEnvFlagCache !== null) return tmuxEnvFlagCache;
10003
10017
  try {
10004
- const r = node_child_process.spawnSync("tmux", ["-V"], { encoding: "utf8", env: ptyEnv() });
10018
+ const r = node_child_process.spawnSync("tmux", tmuxArgs(["-V"]), { encoding: "utf8", env: ptyEnv() });
10005
10019
  tmuxEnvFlagCache = r.status === 0 && tmuxSupportsNewSessionEnv(r.stdout || "");
10006
10020
  } catch {
10007
10021
  tmuxEnvFlagCache = false;
@@ -10045,6 +10059,7 @@ function ptyEnv() {
10045
10059
  for (const [k, v] of Object.entries(process.env)) {
10046
10060
  if (typeof v === "string") env[k] = v;
10047
10061
  }
10062
+ scrubTmuxClientEnv(env);
10048
10063
  const local = `${os.homedir()}/.local/bin`;
10049
10064
  if (!(env.PATH || "").split(":").includes(local)) {
10050
10065
  env.PATH = `${local}:${env.PATH || ""}`;
@@ -10700,7 +10715,7 @@ class WebTerminalManager {
10700
10715
  const name = `vh-${plan.terminalId}`;
10701
10716
  const exists = node_child_process.spawnSync(
10702
10717
  "tmux",
10703
- ["has-session", "-t", `=${name}:`],
10718
+ tmuxArgs(["has-session", "-t", `=${name}:`]),
10704
10719
  { stdio: "ignore", timeout: TMUX_PROBE_TIMEOUT_MS, env }
10705
10720
  ).status === 0;
10706
10721
  if (exists) return false;
@@ -10714,12 +10729,12 @@ class WebTerminalManager {
10714
10729
  ] : [];
10715
10730
  const created = node_child_process.spawnSync(
10716
10731
  "tmux",
10717
- tmuxNewSessionArgs(name, 120, 30, plan.cwd, envFlags, defaultShell()),
10732
+ tmuxArgs(tmuxNewSessionArgs(name, 120, 30, plan.cwd, envFlags, defaultShell())),
10718
10733
  { stdio: "ignore", timeout: TMUX_CREATE_TIMEOUT_MS, env }
10719
10734
  );
10720
10735
  const live = created.status === 0 && node_child_process.spawnSync(
10721
10736
  "tmux",
10722
- ["has-session", "-t", `=${name}:`],
10737
+ tmuxArgs(["has-session", "-t", `=${name}:`]),
10723
10738
  { stdio: "ignore", timeout: TMUX_PROBE_TIMEOUT_MS, env }
10724
10739
  ).status === 0;
10725
10740
  if (!live) {
@@ -10729,12 +10744,12 @@ class WebTerminalManager {
10729
10744
  if (plan.title) {
10730
10745
  node_child_process.spawnSync(
10731
10746
  "tmux",
10732
- ["set-option", "-t", `=${name}:`, "@vh_title", plan.title],
10747
+ tmuxArgs(["set-option", "-t", `=${name}:`, "@vh_title", plan.title]),
10733
10748
  { stdio: "ignore", timeout: TMUX_PROBE_TIMEOUT_MS, env }
10734
10749
  );
10735
10750
  }
10736
10751
  for (const argv of startupInjectionArgs(name, plan.command)) {
10737
- node_child_process.spawnSync("tmux", argv, { stdio: "ignore", timeout: TMUX_PROBE_TIMEOUT_MS, env });
10752
+ node_child_process.spawnSync("tmux", tmuxArgs(argv), { stdio: "ignore", timeout: TMUX_PROBE_TIMEOUT_MS, env });
10738
10753
  }
10739
10754
  logger.info(`[WEB TERMINAL] auto-restored ${plan.terminalId} in ${plan.cwd}`);
10740
10755
  return true;
@@ -10866,14 +10881,14 @@ class WebTerminalManager {
10866
10881
  if (opts.attachOnly || opts.resub) {
10867
10882
  const alive = isTmuxAvailable() && node_child_process.spawnSync(
10868
10883
  "tmux",
10869
- ["has-session", "-t", `=vh-${id}:`],
10884
+ tmuxArgs(["has-session", "-t", `=vh-${id}:`]),
10870
10885
  { stdio: "ignore", timeout: TMUX_PROBE_TIMEOUT_MS, env: ptyEnv() }
10871
10886
  ).status === 0;
10872
10887
  if (!alive) throw new Error("terminal-gone");
10873
10888
  } else if (this.tombstones[id]) {
10874
10889
  const alive = isTmuxAvailable() && node_child_process.spawnSync(
10875
10890
  "tmux",
10876
- ["has-session", "-t", `=vh-${id}:`],
10891
+ tmuxArgs(["has-session", "-t", `=vh-${id}:`]),
10877
10892
  { stdio: "ignore", timeout: TMUX_PROBE_TIMEOUT_MS, env: ptyEnv() }
10878
10893
  ).status === 0;
10879
10894
  if (!alive) {
@@ -10902,7 +10917,7 @@ class WebTerminalManager {
10902
10917
  try {
10903
10918
  const created = node_child_process.spawnSync(
10904
10919
  "tmux",
10905
- tmuxNewSessionArgs(tmuxSession, cols, rows, cwd, envFlags, defaultShell()),
10920
+ tmuxArgs(tmuxNewSessionArgs(tmuxSession, cols, rows, cwd, envFlags, defaultShell())),
10906
10921
  { stdio: "ignore", timeout: TMUX_CREATE_TIMEOUT_MS, env }
10907
10922
  );
10908
10923
  createdNew = created.status === 0;
@@ -10934,7 +10949,7 @@ class WebTerminalManager {
10934
10949
  ];
10935
10950
  for (const a of optArgs) {
10936
10951
  try {
10937
- node_child_process.spawnSync("tmux", a, { stdio: "ignore", timeout: TMUX_PROBE_TIMEOUT_MS, env });
10952
+ node_child_process.spawnSync("tmux", tmuxArgs(a), { stdio: "ignore", timeout: TMUX_PROBE_TIMEOUT_MS, env });
10938
10953
  } catch {
10939
10954
  }
10940
10955
  }
@@ -10943,7 +10958,7 @@ class WebTerminalManager {
10943
10958
  if (startup) {
10944
10959
  try {
10945
10960
  for (const a of startupInjectionArgs(tmuxSession, startup)) {
10946
- node_child_process.spawnSync("tmux", a, { stdio: "ignore", timeout: TMUX_PROBE_TIMEOUT_MS, env });
10961
+ node_child_process.spawnSync("tmux", tmuxArgs(a), { stdio: "ignore", timeout: TMUX_PROBE_TIMEOUT_MS, env });
10947
10962
  }
10948
10963
  logger.debug(`[WEB TERMINAL] injected startup command into new session ${tmuxSession}`);
10949
10964
  } catch {
@@ -10953,13 +10968,13 @@ class WebTerminalManager {
10953
10968
  if (!attachOnly && !createdNew) {
10954
10969
  const alive = node_child_process.spawnSync(
10955
10970
  "tmux",
10956
- ["has-session", "-t", `=${tmuxSession}:`],
10971
+ tmuxArgs(["has-session", "-t", `=${tmuxSession}:`]),
10957
10972
  { stdio: "ignore", timeout: TMUX_PROBE_TIMEOUT_MS, env }
10958
10973
  ).status === 0;
10959
10974
  if (shouldUseDirectPtyFallback(attachOnly, createdNew, alive)) {
10960
10975
  const retry = node_child_process.spawnSync(
10961
10976
  "tmux",
10962
- tmuxNewSessionArgs(tmuxSession, cols, rows, cwd, envFlags, defaultShell()),
10977
+ tmuxArgs(tmuxNewSessionArgs(tmuxSession, cols, rows, cwd, envFlags, defaultShell())),
10963
10978
  { stdio: "ignore", timeout: TMUX_CREATE_TIMEOUT_MS, env }
10964
10979
  );
10965
10980
  createdNew = retry.status === 0;
@@ -10968,7 +10983,7 @@ class WebTerminalManager {
10968
10983
  if (startup) {
10969
10984
  for (const a of startupInjectionArgs(tmuxSession, startup)) {
10970
10985
  try {
10971
- node_child_process.spawnSync("tmux", a, { stdio: "ignore", timeout: TMUX_PROBE_TIMEOUT_MS, env });
10986
+ node_child_process.spawnSync("tmux", tmuxArgs(a), { stdio: "ignore", timeout: TMUX_PROBE_TIMEOUT_MS, env });
10972
10987
  } catch {
10973
10988
  }
10974
10989
  }
@@ -10979,7 +10994,7 @@ class WebTerminalManager {
10979
10994
  if (!attachOnly && !createdNew) {
10980
10995
  const alive = node_child_process.spawnSync(
10981
10996
  "tmux",
10982
- ["has-session", "-t", `=${tmuxSession}:`],
10997
+ tmuxArgs(["has-session", "-t", `=${tmuxSession}:`]),
10983
10998
  { stdio: "ignore", timeout: TMUX_PROBE_TIMEOUT_MS, env }
10984
10999
  ).status === 0;
10985
11000
  if (!alive) {
@@ -11306,8 +11321,8 @@ class WebTerminalManager {
11306
11321
  killSession(terminalId) {
11307
11322
  const info = this.lastSeenInfo.get(terminalId) ?? this.listSessions().find((t) => t.id === terminalId);
11308
11323
  const target = `=vh-${terminalId}:`;
11309
- const killed = node_child_process.spawnSync("tmux", ["kill-session", "-t", target], { stdio: "ignore", env: ptyEnv() });
11310
- const verified = node_child_process.spawnSync("tmux", ["has-session", "-t", target], { stdio: "ignore", env: ptyEnv() });
11324
+ const killed = node_child_process.spawnSync("tmux", tmuxArgs(["kill-session", "-t", target]), { stdio: "ignore", env: ptyEnv() });
11325
+ const verified = node_child_process.spawnSync("tmux", tmuxArgs(["has-session", "-t", target]), { stdio: "ignore", env: ptyEnv() });
11311
11326
  if (!tmuxKillVerified(killed, verified)) {
11312
11327
  logger.debug(`[WEB TERMINAL] failed to verify tmux session removal ${target}`);
11313
11328
  return false;
@@ -11368,7 +11383,7 @@ class WebTerminalManager {
11368
11383
  const env = ptyEnv();
11369
11384
  const r = node_child_process.spawnSync(
11370
11385
  "tmux",
11371
- ["list-sessions", "-F", LIST_SESSIONS_FORMAT],
11386
+ tmuxArgs(["list-sessions", "-F", LIST_SESSIONS_FORMAT]),
11372
11387
  { encoding: "utf8", env }
11373
11388
  );
11374
11389
  if (r.status !== 0 || !r.stdout) return [];
@@ -11384,7 +11399,7 @@ class WebTerminalManager {
11384
11399
  try {
11385
11400
  const w = node_child_process.spawnSync(
11386
11401
  "tmux",
11387
- ["set-option", "-t", `=${s.name}:`, "@vh_title", auto],
11402
+ tmuxArgs(["set-option", "-t", `=${s.name}:`, "@vh_title", auto]),
11388
11403
  { stdio: "ignore", timeout: TMUX_PROBE_TIMEOUT_MS, env }
11389
11404
  );
11390
11405
  if (w.status === 0) title = auto;
@@ -11435,13 +11450,13 @@ class WebTerminalManager {
11435
11450
  try {
11436
11451
  const cmd = node_child_process.spawnSync(
11437
11452
  "tmux",
11438
- ["display-message", "-p", "-t", sessionName, "#{pane_current_command}"],
11453
+ tmuxArgs(["display-message", "-p", "-t", sessionName, "#{pane_current_command}"]),
11439
11454
  { encoding: "utf8", timeout: TMUX_PROBE_TIMEOUT_MS, env: ptyEnv() }
11440
11455
  );
11441
11456
  if (cmd.status !== 0 || typeof cmd.stdout !== "string") return void 0;
11442
11457
  const cap = node_child_process.spawnSync(
11443
11458
  "tmux",
11444
- ["capture-pane", "-p", "-t", sessionName, "-S", "-40"],
11459
+ tmuxArgs(["capture-pane", "-p", "-t", sessionName, "-S", "-40"]),
11445
11460
  { encoding: "utf8", timeout: TMUX_PROBE_TIMEOUT_MS, env: ptyEnv() }
11446
11461
  );
11447
11462
  if (cap.status !== 0 || typeof cap.stdout !== "string") return void 0;
@@ -11468,7 +11483,7 @@ class WebTerminalManager {
11468
11483
  try {
11469
11484
  const probe = node_child_process.spawnSync(
11470
11485
  "tmux",
11471
- ["display-message", "-p", "-t", name, "#{pane_in_mode} #{alternate_on} #{mouse_any_flag} #{pane_width} #{pane_height} #{pane_current_command}"],
11486
+ tmuxArgs(["display-message", "-p", "-t", name, "#{pane_in_mode} #{alternate_on} #{mouse_any_flag} #{pane_width} #{pane_height} #{pane_current_command}"]),
11472
11487
  { encoding: "utf8", timeout: TMUX_PROBE_TIMEOUT_MS, env: ptyEnv() }
11473
11488
  );
11474
11489
  if (probe.status !== 0 || typeof probe.stdout !== "string") return;
@@ -11486,7 +11501,7 @@ class WebTerminalManager {
11486
11501
  const hex = sgrWheelHexBytes(action.dir, action.count, Number(paneW) || 80, Number(paneH) || 24);
11487
11502
  node_child_process.spawnSync(
11488
11503
  "tmux",
11489
- ["send-keys", "-t", name, "-H", ...hex],
11504
+ tmuxArgs(["send-keys", "-t", name, "-H", ...hex]),
11490
11505
  { stdio: "ignore", timeout: TMUX_PROBE_TIMEOUT_MS, env: ptyEnv() }
11491
11506
  );
11492
11507
  return;
@@ -11494,7 +11509,7 @@ class WebTerminalManager {
11494
11509
  if (action.kind === "page-keys") {
11495
11510
  node_child_process.spawnSync(
11496
11511
  "tmux",
11497
- ["send-keys", "-t", name, "-N", String(action.count), action.key],
11512
+ tmuxArgs(["send-keys", "-t", name, "-N", String(action.count), action.key]),
11498
11513
  { stdio: "ignore", timeout: TMUX_PROBE_TIMEOUT_MS, env: ptyEnv() }
11499
11514
  );
11500
11515
  return;
@@ -11502,19 +11517,19 @@ class WebTerminalManager {
11502
11517
  if (action.kind === "keys") {
11503
11518
  node_child_process.spawnSync(
11504
11519
  "tmux",
11505
- ["send-keys", "-t", name, "-N", String(action.count), action.key],
11520
+ tmuxArgs(["send-keys", "-t", name, "-N", String(action.count), action.key]),
11506
11521
  { stdio: "ignore", timeout: TMUX_PROBE_TIMEOUT_MS, env: ptyEnv() }
11507
11522
  );
11508
11523
  return;
11509
11524
  }
11510
11525
  node_child_process.spawnSync(
11511
11526
  "tmux",
11512
- ["copy-mode", "-e", "-t", name],
11527
+ tmuxArgs(["copy-mode", "-e", "-t", name]),
11513
11528
  { stdio: "ignore", timeout: TMUX_PROBE_TIMEOUT_MS, env: ptyEnv() }
11514
11529
  );
11515
11530
  node_child_process.spawnSync(
11516
11531
  "tmux",
11517
- [
11532
+ tmuxArgs([
11518
11533
  "send-keys",
11519
11534
  "-X",
11520
11535
  "-t",
@@ -11522,7 +11537,7 @@ class WebTerminalManager {
11522
11537
  "-N",
11523
11538
  String(action.count),
11524
11539
  action.dir === "up" ? "scroll-up" : "scroll-down"
11525
- ],
11540
+ ]),
11526
11541
  { stdio: "ignore", timeout: TMUX_PROBE_TIMEOUT_MS, env: ptyEnv() }
11527
11542
  );
11528
11543
  } catch {
@@ -11556,14 +11571,14 @@ class WebTerminalManager {
11556
11571
  const name = `vh-${terminalId}`;
11557
11572
  try {
11558
11573
  if (ifAbsent) {
11559
- const cur = node_child_process.spawnSync("tmux", ["show-options", "-t", name, "-v", "@vh_title"], { encoding: "utf8", env: ptyEnv() });
11574
+ const cur = node_child_process.spawnSync("tmux", tmuxArgs(["show-options", "-t", name, "-v", "@vh_title"]), { encoding: "utf8", env: ptyEnv() });
11560
11575
  if (cur.status === 0 && cur.stdout && cur.stdout.trim()) return true;
11561
11576
  }
11562
- const r = node_child_process.spawnSync("tmux", ["set-option", "-t", name, "@vh_title", title], { stdio: "ignore", env: ptyEnv() });
11577
+ const r = node_child_process.spawnSync("tmux", tmuxArgs(["set-option", "-t", name, "@vh_title", title]), { stdio: "ignore", env: ptyEnv() });
11563
11578
  if (r.status !== 0) return false;
11564
11579
  if (!ifAbsent) {
11565
11580
  try {
11566
- node_child_process.spawnSync("tmux", ["set-option", "-t", name, "@vh_title_manual", "1"], { stdio: "ignore", env: ptyEnv() });
11581
+ node_child_process.spawnSync("tmux", tmuxArgs(["set-option", "-t", name, "@vh_title_manual", "1"]), { stdio: "ignore", env: ptyEnv() });
11567
11582
  } catch {
11568
11583
  }
11569
11584
  }
@@ -11581,7 +11596,7 @@ class WebTerminalManager {
11581
11596
  if (!valid) return false;
11582
11597
  const name = `vh-${terminalId}`;
11583
11598
  try {
11584
- const r = node_child_process.spawnSync("tmux", ["set-option", "-t", name, "@vh_tags", JSON.stringify(valid)], {
11599
+ const r = node_child_process.spawnSync("tmux", tmuxArgs(["set-option", "-t", name, "@vh_tags", JSON.stringify(valid)]), {
11585
11600
  stdio: "ignore",
11586
11601
  env: ptyEnv()
11587
11602
  });
@@ -11613,10 +11628,11 @@ function parseVhTerminals(stdout, hostname = os.hostname()) {
11613
11628
  }
11614
11629
  function runTmux(args, input) {
11615
11630
  try {
11616
- const r = node_child_process.spawnSync("tmux", args, {
11631
+ const r = node_child_process.spawnSync("tmux", tmuxArgs(args), {
11617
11632
  encoding: "utf8",
11618
11633
  timeout: TMUX_TIMEOUT_MS,
11619
- input
11634
+ input,
11635
+ env: scrubTmuxClientEnv({ ...process.env })
11620
11636
  });
11621
11637
  if (r.error) return { ok: false, stdout: "", error: r.error.message };
11622
11638
  if (r.status !== 0) return { ok: false, stdout: r.stdout ?? "", error: (r.stderr || `tmux exited with ${r.status}`).trim() };
@@ -15236,9 +15252,11 @@ exports.readSettings = readSettings;
15236
15252
  exports.readVhTerminal = readVhTerminal;
15237
15253
  exports.releaseDaemonLock = releaseDaemonLock;
15238
15254
  exports.resolveCliUpdateCheckInterval = resolveCliUpdateCheckInterval;
15255
+ exports.scrubTmuxClientEnv = scrubTmuxClientEnv;
15239
15256
  exports.sendToVhTerminal = sendToVhTerminal;
15240
15257
  exports.startOfflineReconnection = startOfflineReconnection;
15241
15258
  exports.summarizeSpawnSessionForLog = summarizeSpawnSessionForLog;
15259
+ exports.tmuxArgs = tmuxArgs;
15242
15260
  exports.updateSettings = updateSettings;
15243
15261
  exports.wrapCommand = wrapCommand;
15244
15262
  exports.writeCredentialsDataKey = writeCredentialsDataKey;