very-happy-cli 0.2.140 → 0.2.142
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.
- package/dist/{AcpBackend-DsSYq8T-.mjs → AcpBackend-D2LqY2to.mjs} +2 -2
- package/dist/{AcpBackend-C0Lq4uoA.cjs → AcpBackend-DJsqfgjD.cjs} +2 -2
- package/dist/{AcpSessionManager-DIqByTH7.cjs → AcpSessionManager-CTfDxziP.cjs} +1 -1
- package/dist/{AcpSessionManager-BAErE9s0.mjs → AcpSessionManager-CdeM5KD9.mjs} +1 -1
- package/dist/{agentGuidance-Dl3apItH.cjs → agentGuidance-Bi8iBjy3.cjs} +1 -1
- package/dist/{agentGuidance-xk3v4_7E.mjs → agentGuidance-Cz8QVcX3.mjs} +1 -1
- package/dist/codex/happyMcpStdioBridge.cjs +2 -2
- package/dist/codex/happyMcpStdioBridge.mjs +2 -2
- package/dist/{config-D0-jnCOC.cjs → config-BIbYBmTd.cjs} +5 -4
- package/dist/{config-BVoHul9V.mjs → config-ZsBeq10u.mjs} +5 -4
- package/dist/{index-DJvzGXVN.cjs → index-BPTPrjhL.cjs} +12 -40
- package/dist/{index-BuQn9kUK.cjs → index-Bom8mTuS.cjs} +5 -4
- package/dist/{index-BPnAbcz_.mjs → index-CNARLBax.mjs} +5 -4
- package/dist/{index-__h-pCTK.cjs → index-CSQZhQ0C.cjs} +198 -129
- package/dist/{index-BNydKYvS.mjs → index-CY0zmhIp.mjs} +11 -39
- package/dist/{index-D0IP7gXG.mjs → index-CYFendNf.mjs} +179 -111
- package/dist/index.cjs +7 -6
- package/dist/index.mjs +7 -6
- package/dist/installPiTools-BKnXjrVu.cjs +82 -0
- package/dist/installPiTools-C-Lxv4Bt.mjs +77 -0
- package/dist/{installTerminalHooks-D2ice1a-.mjs → installTerminalHooks-BPJu2WVz.mjs} +8 -7
- package/dist/{installTerminalHooks-D3jfvbyY.cjs → installTerminalHooks-DA7SyFYW.cjs} +9 -8
- package/dist/lib.cjs +3 -2
- package/dist/lib.d.cts +6 -1
- package/dist/lib.d.mts +6 -1
- package/dist/lib.mjs +3 -2
- package/dist/{limits-Dbip6eVO.cjs → limits-B3hngubn.cjs} +29 -10
- package/dist/{limits-nhD0Wran.mjs → limits-CHsz3Ba-.mjs} +29 -11
- package/dist/{mcp-V26C05fN.mjs → mcp-BkWBRWFe.mjs} +28 -14
- package/dist/{mcp-DeapmTWN.cjs → mcp-ySrfNOYl.cjs} +29 -15
- package/dist/piExtension.d.mts +17 -0
- package/dist/piExtension.mjs +84 -0
- package/dist/piRuntime-DBLUyXFr.mjs +37 -0
- package/dist/piRuntime-uX0WHVr4.cjs +39 -0
- package/dist/piTerminal-Bc3jSCnY.mjs +129 -0
- package/dist/piTerminal-DNr3hkzY.cjs +132 -0
- package/dist/projectPath-CSpqWdxp.mjs +10 -0
- package/dist/projectPath-ChLhdOyt.cjs +13 -0
- package/dist/{runGemini-D34eCFpz.cjs → runGemini-eJ08cXk7.cjs} +9 -8
- package/dist/{runGemini-sa5kAgPe.mjs → runGemini-rgFHTnG7.mjs} +8 -7
- package/dist/{runOpenClaw-B8F8D--R.cjs → runOpenClaw-D0LVzxqM.cjs} +6 -5
- package/dist/{runOpenClaw-Bdsq8KBa.mjs → runOpenClaw-GjLWwjas.mjs} +6 -5
- package/dist/{send-DP_S3wn0.cjs → send-Bg2oqt7f.cjs} +5 -4
- package/dist/{send-KICC_ACz.mjs → send-DV8liaRN.mjs} +5 -4
- package/dist/{sessions-CGBBgVZn.cjs → sessions-DPimBZ8H.cjs} +7 -6
- package/dist/{sessions-C6EvnC4B.mjs → sessions-JiL4aJkC.mjs} +7 -6
- package/dist/{spawn-BhUK0Vt2.cjs → spawn-COOcUwkG.cjs} +5 -4
- package/dist/{spawn-C1OqXJNb.mjs → spawn-CnMk3LFG.mjs} +5 -4
- package/dist/{teams-C29nEHFD.cjs → teams-DSQgHBLE.cjs} +5 -4
- package/dist/{teams-Dm5HGpNz.mjs → teams-uHZcdX9j.mjs} +5 -4
- package/dist/terminalToolContext-CFeGeaNm.mjs +7 -0
- package/dist/terminalToolContext-DoV9Gs7K.cjs +9 -0
- package/dist/{todo-CeJX0z_2.cjs → todo-DeauuUd6.cjs} +4 -3
- package/dist/{todo-C-vovA0N.mjs → todo-oHWNpEx_.mjs} +4 -3
- package/dist/{types-thyvQB2a.mjs → types-Dnoxgb7G.mjs} +30 -13
- package/dist/{types-DCVS050m.cjs → types-Xd_LJRJN.cjs} +31 -15
- package/package.json +11 -7
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
import { D as DefaultTransport, A as AcpBackend } from './AcpBackend-
|
|
2
|
-
export { a as DEFAULT_IDLE_TIMEOUT_MS, b as DEFAULT_TOOL_CALL_TIMEOUT_MS, e as extractErrorDetail, f as formatDuration, c as formatDurationMinutes, h as handleAgentMessageChunk, d as handleAgentThoughtChunk, g as handleLegacyMessageChunk, i as handlePlanUpdate, j as handleThinkingUpdate, k as handleToolCall, l as handleToolCallUpdate, p as parseArgsFromContent } from './AcpBackend-
|
|
3
|
-
import {
|
|
4
|
-
import { A as AcpSessionManager } from './AcpSessionManager-
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
1
|
+
import { D as DefaultTransport, A as AcpBackend } from './AcpBackend-D2LqY2to.mjs';
|
|
2
|
+
export { a as DEFAULT_IDLE_TIMEOUT_MS, b as DEFAULT_TOOL_CALL_TIMEOUT_MS, e as extractErrorDetail, f as formatDuration, c as formatDurationMinutes, h as handleAgentMessageChunk, d as handleAgentThoughtChunk, g as handleLegacyMessageChunk, i as handlePlanUpdate, j as handleThinkingUpdate, k as handleToolCall, l as handleToolCallUpdate, p as parseArgsFromContent } from './AcpBackend-D2LqY2to.mjs';
|
|
3
|
+
import { f as readSettings, g as encodeBase64, l as logger, c as configuration } from './limits-CHsz3Ba-.mjs';
|
|
4
|
+
import { A as AcpSessionManager } from './AcpSessionManager-CdeM5KD9.mjs';
|
|
5
|
+
import { h as connectionState, A as ApiClient, n as notifyDaemonSessionStarted, j as BUILTIN_TODO_DISCOVERY } from './types-Dnoxgb7G.mjs';
|
|
6
|
+
import { k as initialMachineMetadata, m as createSessionMetadata, n as setupOfflineReconnection, o as StreamRelay, p as MessageQueue2, u as hashObject, v as startHappyServer, x as registerAgentAttachmentDownloads, T as TitleGenerator, y as registerKillSessionHandler, C as CLAUDE_ATTACHMENT_KINDS, z as stageClaudeAttachments, B as appendStagedAttachmentsToPrompt, E as BasePermissionHandler, F as writeSessionModeFile, H as normalizeAcpPermissionMode, I as removeSessionModeFile } from './index-CYFendNf.mjs';
|
|
7
|
+
import { p as preparePiTeamsRuntime } from './piRuntime-DBLUyXFr.mjs';
|
|
8
8
|
import { randomUUID } from 'node:crypto';
|
|
9
9
|
import { join } from 'node:path';
|
|
10
|
+
import { p as projectPath } from './projectPath-CSpqWdxp.mjs';
|
|
10
11
|
import 'node:child_process';
|
|
11
12
|
import '@agentclientprotocol/sdk';
|
|
13
|
+
import 'node:fs/promises';
|
|
12
14
|
import 'node:fs';
|
|
13
15
|
import 'node:os';
|
|
14
16
|
import 'zod';
|
|
@@ -25,14 +27,13 @@ import 'fs/promises';
|
|
|
25
27
|
import 'crypto';
|
|
26
28
|
import 'path';
|
|
27
29
|
import 'cross-spawn';
|
|
28
|
-
import 'url';
|
|
29
30
|
import 'os';
|
|
30
31
|
import 'node-pty';
|
|
31
32
|
import 'fs';
|
|
32
33
|
import 'node:readline';
|
|
33
34
|
import '@anthropic-ai/sandbox-runtime';
|
|
34
35
|
import 'expo-server-sdk';
|
|
35
|
-
import './agentGuidance-
|
|
36
|
+
import './agentGuidance-Cz8QVcX3.mjs';
|
|
36
37
|
import 'ink';
|
|
37
38
|
import 'react';
|
|
38
39
|
import '@anthropic-ai/claude-agent-sdk';
|
|
@@ -49,6 +50,7 @@ import 'http';
|
|
|
49
50
|
import 'inquirer';
|
|
50
51
|
import 'node:url';
|
|
51
52
|
import 'node:readline/promises';
|
|
53
|
+
import 'url';
|
|
52
54
|
|
|
53
55
|
function createAcpBackend(options) {
|
|
54
56
|
const backendOptions = {
|
|
@@ -64,36 +66,6 @@ function createAcpBackend(options) {
|
|
|
64
66
|
return new AcpBackend(backendOptions);
|
|
65
67
|
}
|
|
66
68
|
|
|
67
|
-
async function publish(path, content, mode) {
|
|
68
|
-
const temporary = `${path}.${randomUUID()}.new`;
|
|
69
|
-
await writeFile(temporary, content, { mode, flag: "wx" });
|
|
70
|
-
await rename(temporary, path);
|
|
71
|
-
}
|
|
72
|
-
async function preparePiTeamsRuntime() {
|
|
73
|
-
const directory = join(configuration.happyHomeDir, "teams", "pi-runtime");
|
|
74
|
-
await mkdir(directory, { recursive: true, mode: 448 });
|
|
75
|
-
const extension = join(directory, "very-happy-teams.mjs");
|
|
76
|
-
await publish(extension, PI_TEAMS_EXTENSION, 384);
|
|
77
|
-
const launcher = join(directory, "pi-teams.mjs");
|
|
78
|
-
const script = `#!${process.execPath}
|
|
79
|
-
import { spawn } from 'node:child_process';
|
|
80
|
-
const child = spawn(process.env.VH_TEAM_PI_COMMAND || 'pi', ['--extension', ${JSON.stringify(extension)}, ...process.argv.slice(2)], {stdio:'inherit',env:process.env,shell:process.platform==='win32'});
|
|
81
|
-
child.on('error',()=>{process.stderr.write('Very Happy could not launch pi\\n');process.exitCode=1});
|
|
82
|
-
child.on('exit',(code)=>{process.exitCode=code ?? 1});
|
|
83
|
-
for(const signal of ['SIGINT','SIGTERM'])process.on(signal,()=>child.kill(signal));
|
|
84
|
-
`;
|
|
85
|
-
await publish(launcher, script, 448);
|
|
86
|
-
await chmod(launcher, 448);
|
|
87
|
-
let command = launcher;
|
|
88
|
-
if (process.platform === "win32") {
|
|
89
|
-
command = join(directory, "pi-teams.cmd");
|
|
90
|
-
await publish(command, `@echo off\r
|
|
91
|
-
"${process.execPath}" "${launcher}" %*\r
|
|
92
|
-
`, 448);
|
|
93
|
-
}
|
|
94
|
-
return { PI_ACP_PI_COMMAND: command, VH_TEAM_PI_COMMAND: (process.env.PI_ACP_PI_COMMAND === command ? process.env.VH_TEAM_PI_COMMAND : process.env.PI_ACP_PI_COMMAND) || "pi" };
|
|
95
|
-
}
|
|
96
|
-
|
|
97
69
|
const SUPPORTED_CATEGORIES = /* @__PURE__ */ new Set(["mode", "model", "thought_level"]);
|
|
98
70
|
function isRecord$1(value) {
|
|
99
71
|
return !!value && typeof value === "object";
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import{createRequire as _pkgrollCR}from"node:module";const require=_pkgrollCR(import.meta.url);import chalk from 'chalk';
|
|
2
2
|
import os, { homedir, userInfo, tmpdir } from 'node:os';
|
|
3
3
|
import { randomUUID, randomInt, randomBytes, createHash as createHash$1, timingSafeEqual } from 'node:crypto';
|
|
4
|
-
import { o as notifyDaemonSessionEvent, q as getProjectPath,
|
|
5
|
-
import { l as logger,
|
|
4
|
+
import { o as notifyDaemonSessionEvent, q as getProjectPath, j as BUILTIN_TODO_DISCOVERY, r as initializeSandbox, w as wrapCommand, l as contentLogMetadata, I as InvalidateSync, R as RawJSONLinesSchema, m as delay, t as AsyncLock, S as STREAM_DELTA_MAX_CHARS, M as MAX_CHAT_ATTACHMENT_SOURCE_BYTES, u as notifyDaemonClaudeAuthFailed, v as commandOnPath, c as checkIfDaemonRunningAndCleanupStaleState, x as deriveLocalCliUpdateSummary, y as AGENT_VERSION_SOURCES, z as isClaudeSessionId, C as getLocalHappyAgentCredentialPath, D as readLocalHappyAgentCredentials, E as parseExactVersion, F as compareExactVersions, G as extractCompleteLines, H as decideBackfill, J as parseTerminalHookPayload, K as tmuxArgs, L as scrubTmuxClientEnv, N as decideMirrorBinding, O as MIRROR_BACKFILL_LINES_DEFAULT, P as mirrorLineKey, Q as mirrorLocalId, T as listDaemonSessions, U as stopDaemonSession, V as detectCLIAvailability, W as detectResumeSupport, X as isDaemonRunningCurrentlyInstalledHappyVersion, Y as stopDaemon, Z as TurnActivityTracker, _ as summarizeSpawnSessionForLog, $ as shellescape, A as ApiClient, a0 as fetchCliUpdateState, a1 as resolveCliUpdateCheckInterval, a2 as DEFAULT_CLI_UPDATE_CHECK_INTERVAL_MS, a3 as cleanupDaemonState, i as isValidSessionId, s as spawnDaemonSession, a4 as listVhTerminals, a5 as isValidTerminalId, a6 as readVhTerminal, a7 as sendToVhTerminal, a8 as ContextUsageSchema, a9 as TITLE_PROMPT_PREFIX, aa as BOARD_ANALYZER_PROMPT_PREFIX, h as connectionState, ab as startOfflineReconnection, n as notifyDaemonSessionStarted, d as createEnvelope, ac as CodexAppServerClient } from './types-Dnoxgb7G.mjs';
|
|
5
|
+
import { l as logger, E as ensurePrivateDirectory, F as hardenPrivateFile, c as configuration, p as packageJson, f as readSettings, G as readCredentials, v as credentialRelayProblem, o as readDaemonState, g as encodeBase64, H as readSettingsOutcome, I as updateSettings, J as encodeBase64Url, m as decodeBase64, K as writeCredentialsLegacy, L as writeCredentialsDataKey, d as readCredentialsForConfiguredRelay, j as encrypt, r as readPersistedSessions, w as writePrivateFileSync, M as decryptWithDataKey, N as decryptLegacy, O as persistSession, k as decrypt, h as ensurePrivateDirectorySync, P as acquireDaemonLock, Q as deletePersistedSessions, R as writeDaemonState, S as writeSettings, T as releaseDaemonLock, C as CLIPBOARD_TOOL_NAME, a as CLIPBOARD_TOOL_TITLE, b as CLIPBOARD_TOOL_DESCRIPTION, e as CLIPBOARD_MAX_BYTES, U as clearCredentials, V as clearMachineId, W as SandboxConfigSchema, X as getLatestDaemonLog } from './limits-CHsz3Ba-.mjs';
|
|
6
6
|
import spawn$1, { spawn } from 'cross-spawn';
|
|
7
|
-
import path, { join, resolve, basename, isAbsolute,
|
|
7
|
+
import path, { join, resolve, basename, isAbsolute, sep, dirname, delimiter, normalize } from 'node:path';
|
|
8
8
|
import { createInterface } from 'node:readline';
|
|
9
9
|
import { existsSync, readFileSync, readdirSync, statSync, mkdirSync, unlinkSync, renameSync, writeFileSync, accessSync, constants, openSync, fsyncSync, closeSync, rmSync as rmSync$1, chmodSync as chmodSync$1 } from 'node:fs';
|
|
10
|
-
import {
|
|
10
|
+
import { p as projectPath } from './projectPath-CSpqWdxp.mjs';
|
|
11
|
+
import { f as trimIdent, A as AGENT_GUIDANCE, t as teamScopePath, T as TeamConnectionPreflightError, e as createTeamsClient, P as PREVIEW_TOOL_NAME, R as REPORT_PROGRESS_TOOL_NAME, g as TEAM_TOOL_NAMES, r as registerTeamsTools, a as PREVIEW_TOOL_TITLE, b as PREVIEW_TOOL_DESCRIPTION, h as REPORT_PROGRESS_TOOL_TITLE, i as REPORT_PROGRESS_TOOL_DESCRIPTION } from './agentGuidance-Cz8QVcX3.mjs';
|
|
11
12
|
import { readFile, writeFile, rename, unlink, mkdir, symlink, rm, readlink, lstat, stat, open as open$1, appendFile } from 'node:fs/promises';
|
|
12
13
|
import fs, { watch, access } from 'fs/promises';
|
|
13
14
|
import { useStdout, useInput, Box, Text, render } from 'ink';
|
|
@@ -1282,7 +1283,21 @@ function createRuntimeControls(isThinking) {
|
|
|
1282
1283
|
});
|
|
1283
1284
|
return { operationId: op.id };
|
|
1284
1285
|
}
|
|
1285
|
-
|
|
1286
|
+
async function stopRunningTasks() {
|
|
1287
|
+
const q = query, runGeneration = generation;
|
|
1288
|
+
if (!q || !q.canControl()) return [];
|
|
1289
|
+
const running = [...tasks.values()].filter((task) => task.status === "running" && text(task.id)).map((task) => String(task.id)).slice(0, 20);
|
|
1290
|
+
const stopped = [];
|
|
1291
|
+
await Promise.all(running.map(async (id) => {
|
|
1292
|
+
try {
|
|
1293
|
+
await q.stopTask(id);
|
|
1294
|
+
if (query === q && generation === runGeneration) stopped.push(id);
|
|
1295
|
+
} catch {
|
|
1296
|
+
}
|
|
1297
|
+
}));
|
|
1298
|
+
return stopped;
|
|
1299
|
+
}
|
|
1300
|
+
return { setQuery, observe, request, stopRunningTasks };
|
|
1286
1301
|
}
|
|
1287
1302
|
|
|
1288
1303
|
class MessageBuffer {
|
|
@@ -3897,6 +3912,9 @@ async function claudeRemoteLauncher(session, onPermissionModeChange, onEffective
|
|
|
3897
3912
|
logger.debug("[remote]: doAbort");
|
|
3898
3913
|
session.markAborting();
|
|
3899
3914
|
session.onAbort();
|
|
3915
|
+
void runtimeControls.stopRunningTasks().then((ids) => {
|
|
3916
|
+
if (ids.length > 0) logger.debug(`[remote]: stopped ${ids.length} background task(s) on abort: ${ids.join(", ")}`);
|
|
3917
|
+
}).catch((error) => logger.debug("[remote]: stopping background tasks on abort failed", error));
|
|
3900
3918
|
if (session.thinking) {
|
|
3901
3919
|
const interrupted = await turnSteering.interruptTurn().catch((e) => {
|
|
3902
3920
|
logger.debug("[remote]: interruptTurn threw, falling back to hard abort", e);
|
|
@@ -6065,6 +6083,83 @@ function isAuthorizedDaemonControlRequest(authorization, controlToken) {
|
|
|
6065
6083
|
return configuredTokenIsUsable && timingSafeEqual(expectedDigest, candidateDigest);
|
|
6066
6084
|
}
|
|
6067
6085
|
|
|
6086
|
+
const DENIED_HOME_DIRS = [
|
|
6087
|
+
".secrets",
|
|
6088
|
+
".ssh",
|
|
6089
|
+
".gnupg",
|
|
6090
|
+
".aws",
|
|
6091
|
+
".kube",
|
|
6092
|
+
".config/rbw"
|
|
6093
|
+
];
|
|
6094
|
+
const DENIED_HOME_FILES = [
|
|
6095
|
+
".claude.json",
|
|
6096
|
+
".claude/.credentials.json",
|
|
6097
|
+
".netrc",
|
|
6098
|
+
".pgpass"
|
|
6099
|
+
];
|
|
6100
|
+
const DENIED_BASENAME_PATTERNS = [
|
|
6101
|
+
/^\.env$/i,
|
|
6102
|
+
/^\.env\./i,
|
|
6103
|
+
/\.env$/i,
|
|
6104
|
+
/\.pem$/i,
|
|
6105
|
+
/\.key$/i,
|
|
6106
|
+
/\.p12$/i,
|
|
6107
|
+
/\.pfx$/i,
|
|
6108
|
+
/^id_(rsa|dsa|ecdsa|ed25519)$/i,
|
|
6109
|
+
/^\.htpasswd$/i
|
|
6110
|
+
];
|
|
6111
|
+
const DENIED_PATH_SUFFIXES = [
|
|
6112
|
+
`${sep}.git${sep}config`
|
|
6113
|
+
];
|
|
6114
|
+
function expandHome(input, home) {
|
|
6115
|
+
if (input === "~") return home;
|
|
6116
|
+
if (input.startsWith(`~${sep}`) || input.startsWith("~/")) {
|
|
6117
|
+
return resolve(home, input.slice(2));
|
|
6118
|
+
}
|
|
6119
|
+
return input;
|
|
6120
|
+
}
|
|
6121
|
+
function basenameOf(p) {
|
|
6122
|
+
const parts = p.split(sep);
|
|
6123
|
+
return parts[parts.length - 1] ?? "";
|
|
6124
|
+
}
|
|
6125
|
+
function isUnder(child, parent) {
|
|
6126
|
+
return child === parent || child.startsWith(parent.endsWith(sep) ? parent : parent + sep);
|
|
6127
|
+
}
|
|
6128
|
+
function checkPreviewPath(input, opts) {
|
|
6129
|
+
const home = homedir();
|
|
6130
|
+
const cwd = process.cwd();
|
|
6131
|
+
if (typeof input !== "string" || !input.trim()) {
|
|
6132
|
+
return { resolved: "", deniedReason: "path must be a non-empty string" };
|
|
6133
|
+
}
|
|
6134
|
+
if (input.includes("\0")) {
|
|
6135
|
+
return { resolved: "", deniedReason: "path contains a NUL byte" };
|
|
6136
|
+
}
|
|
6137
|
+
const expanded = expandHome(input.trim(), home);
|
|
6138
|
+
const resolved = isAbsolute(expanded) ? resolve(expanded) : resolve(cwd, expanded);
|
|
6139
|
+
for (const dir of DENIED_HOME_DIRS) {
|
|
6140
|
+
if (isUnder(resolved, resolve(home, dir))) {
|
|
6141
|
+
return { resolved, deniedReason: `refusing to preview anything under ~/${dir} (credential material)` };
|
|
6142
|
+
}
|
|
6143
|
+
}
|
|
6144
|
+
for (const file of DENIED_HOME_FILES) {
|
|
6145
|
+
if (resolved === resolve(home, file)) {
|
|
6146
|
+
return { resolved, deniedReason: `refusing to preview ~/${file} (credential material)` };
|
|
6147
|
+
}
|
|
6148
|
+
}
|
|
6149
|
+
const base = basenameOf(resolved);
|
|
6150
|
+
for (const pattern of DENIED_BASENAME_PATTERNS) {
|
|
6151
|
+
if (pattern.test(base)) {
|
|
6152
|
+
return { resolved, deniedReason: `refusing to preview "${base}" (looks like credential material)` };
|
|
6153
|
+
}
|
|
6154
|
+
}
|
|
6155
|
+
for (const suffix of DENIED_PATH_SUFFIXES) {
|
|
6156
|
+
if (resolved.endsWith(suffix)) {
|
|
6157
|
+
return { resolved, deniedReason: `refusing to preview ${suffix} (may contain credentials)` };
|
|
6158
|
+
}
|
|
6159
|
+
}
|
|
6160
|
+
return { resolved, deniedReason: null };
|
|
6161
|
+
}
|
|
6162
|
+
|
|
6068
6163
|
function startDaemonControlServer({
|
|
6069
6164
|
controlToken,
|
|
6070
6165
|
getChildren,
|
|
@@ -6076,6 +6171,7 @@ function startDaemonControlServer({
|
|
|
6076
6171
|
onClaudeAuthFailed,
|
|
6077
6172
|
onSessionTurnEvent,
|
|
6078
6173
|
pushClipboard,
|
|
6174
|
+
pushFilePreview,
|
|
6079
6175
|
onTerminalHook,
|
|
6080
6176
|
setTerminalTitle
|
|
6081
6177
|
}) {
|
|
@@ -6290,7 +6386,8 @@ function startDaemonControlServer({
|
|
|
6290
6386
|
typed.post("/clipboard", {
|
|
6291
6387
|
schema: {
|
|
6292
6388
|
body: z.object({
|
|
6293
|
-
text: z.string()
|
|
6389
|
+
text: z.string(),
|
|
6390
|
+
terminalId: z.string().regex(/^[a-zA-Z0-9_-]{1,64}$/).optional()
|
|
6294
6391
|
}),
|
|
6295
6392
|
response: {
|
|
6296
6393
|
200: z.object({
|
|
@@ -6302,9 +6399,25 @@ function startDaemonControlServer({
|
|
|
6302
6399
|
}
|
|
6303
6400
|
}
|
|
6304
6401
|
}, async (request) => {
|
|
6305
|
-
const { text } = request.body;
|
|
6402
|
+
const { text, terminalId } = request.body;
|
|
6306
6403
|
logger.debug(`[CONTROL SERVER] Clipboard push request (${text.length} chars)`);
|
|
6307
|
-
return pushClipboard(text);
|
|
6404
|
+
return terminalId ? pushClipboard(text, terminalId) : pushClipboard(text);
|
|
6405
|
+
});
|
|
6406
|
+
typed.post("/file-preview", {
|
|
6407
|
+
schema: {
|
|
6408
|
+
body: z.object({
|
|
6409
|
+
terminalId: z.string().regex(/^[a-zA-Z0-9_-]{1,64}$/),
|
|
6410
|
+
path: z.string().min(1),
|
|
6411
|
+
mode: z.enum(["file", "diff"]).optional()
|
|
6412
|
+
}),
|
|
6413
|
+
response: { 200: z.object({ delivered: z.boolean(), error: z.string().optional() }) }
|
|
6414
|
+
}
|
|
6415
|
+
}, async (request) => {
|
|
6416
|
+
const { terminalId, path, mode } = request.body;
|
|
6417
|
+
const verdict = checkPreviewPath(path);
|
|
6418
|
+
if (verdict.deniedReason) return { delivered: false, error: verdict.deniedReason };
|
|
6419
|
+
if (!pushFilePreview) return { delivered: false, error: "daemon is still starting up" };
|
|
6420
|
+
return pushFilePreview(terminalId, verdict.resolved, mode ?? "file");
|
|
6308
6421
|
});
|
|
6309
6422
|
typed.post("/terminal-title", {
|
|
6310
6423
|
schema: {
|
|
@@ -9027,14 +9140,15 @@ On restart inspect authoritative state and messages before taking new actions. D
|
|
|
9027
9140
|
`;
|
|
9028
9141
|
const PI_TEAMS_EXTENSION = `// Managed by Very Happy Agent Teams.
|
|
9029
9142
|
export default async function(pi) {
|
|
9030
|
-
const
|
|
9143
|
+
const managed = !!process.env.HAPPY_MCP_URL;
|
|
9144
|
+
const endpoint = process.env.HAPPY_MCP_URL || process.env.HAPPY_TERMINAL_MCP_URL;
|
|
9031
9145
|
if (!endpoint) return;
|
|
9032
9146
|
const url = new URL(endpoint);
|
|
9033
9147
|
if (!['127.0.0.1', 'localhost', '[::1]'].includes(url.hostname) || url.protocol !== 'http:') throw new Error('Very Happy MCP must be local');
|
|
9034
9148
|
const {readFile} = await import('node:fs/promises');
|
|
9035
9149
|
const {join} = await import('node:path');
|
|
9036
9150
|
const {homedir} = await import('node:os');
|
|
9037
|
-
const contextEndpoint = process.env.HAPPY_CONTEXT_USAGE_URL;
|
|
9151
|
+
const contextEndpoint = managed && process.env.HAPPY_CONTEXT_USAGE_URL;
|
|
9038
9152
|
if (contextEndpoint) {
|
|
9039
9153
|
const target = new URL(contextEndpoint);
|
|
9040
9154
|
if (target.origin !== url.origin || !target.pathname.startsWith('/runtime-context/')) throw new Error('Very Happy context must be local');
|
|
@@ -9052,7 +9166,7 @@ export default async function(pi) {
|
|
|
9052
9166
|
});
|
|
9053
9167
|
}
|
|
9054
9168
|
}
|
|
9055
|
-
pi.on('tool_call', async (event, ctx) => {
|
|
9169
|
+
if (managed) pi.on('tool_call', async (event, ctx) => {
|
|
9056
9170
|
let mode = process.env.HAPPY_PERMISSION_MODE || 'default';
|
|
9057
9171
|
const sid = process.env.HAPPY_SESSION_ID;
|
|
9058
9172
|
if (sid && /^[a-zA-Z0-9_-]+$/.test(sid)) {
|
|
@@ -9091,7 +9205,11 @@ export default async function(pi) {
|
|
|
9091
9205
|
const available = await rpc('tools/list', {});
|
|
9092
9206
|
for (const tool of available.tools || []) {
|
|
9093
9207
|
pi.registerTool({name:tool.name,label:tool.name,description:tool.description || tool.name,parameters:tool.inputSchema,
|
|
9094
|
-
async execute(_id, args) {
|
|
9208
|
+
async execute(_id, args) {
|
|
9209
|
+
const result = await rpc('tools/call', {name:tool.name,arguments:args});
|
|
9210
|
+
if (result.isError) throw new Error((result.content || []).filter(block => block.type === 'text').map(block => block.text).join('\\n') || 'Very Happy tool failed');
|
|
9211
|
+
return {content:result.content,details:{isError:false}};
|
|
9212
|
+
}
|
|
9095
9213
|
});
|
|
9096
9214
|
}
|
|
9097
9215
|
}
|
|
@@ -10967,11 +11085,15 @@ async function startDaemon() {
|
|
|
10967
11085
|
onSessionStateEvent,
|
|
10968
11086
|
onClaudeAuthFailed: (sessionId) => claudeAuthServiceRef?.signalAuthFailed(sessionId),
|
|
10969
11087
|
onSessionTurnEvent: (sessionId, event) => turnActivity.apply(sessionId, event),
|
|
10970
|
-
pushClipboard: (text) => {
|
|
11088
|
+
pushClipboard: (text, terminalId) => {
|
|
10971
11089
|
if (!apiMachineRef) {
|
|
10972
11090
|
return { delivered: false, truncated: false, totalBytes: 0, error: "daemon is still starting up" };
|
|
10973
11091
|
}
|
|
10974
|
-
return apiMachineRef.pushClipboard(text);
|
|
11092
|
+
return apiMachineRef.pushClipboard(text, terminalId);
|
|
11093
|
+
},
|
|
11094
|
+
pushFilePreview: (terminalId, path, mode) => {
|
|
11095
|
+
if (!apiMachineRef) return { delivered: false, error: "daemon is still starting up" };
|
|
11096
|
+
return apiMachineRef.pushFilePreview(terminalId, path, mode);
|
|
10975
11097
|
},
|
|
10976
11098
|
onTerminalHook: (body) => {
|
|
10977
11099
|
mirrorManagerRef?.handleHookPayload(body);
|
|
@@ -11708,83 +11830,6 @@ function normalizeProgress(value) {
|
|
|
11708
11830
|
return flat.length > PROGRESS_MAX_CHARS$1 ? flat.slice(0, PROGRESS_MAX_CHARS$1) : flat;
|
|
11709
11831
|
}
|
|
11710
11832
|
|
|
11711
|
-
const DENIED_HOME_DIRS = [
|
|
11712
|
-
".secrets",
|
|
11713
|
-
".ssh",
|
|
11714
|
-
".gnupg",
|
|
11715
|
-
".aws",
|
|
11716
|
-
".kube",
|
|
11717
|
-
".config/rbw"
|
|
11718
|
-
];
|
|
11719
|
-
const DENIED_HOME_FILES = [
|
|
11720
|
-
".claude.json",
|
|
11721
|
-
".claude/.credentials.json",
|
|
11722
|
-
".netrc",
|
|
11723
|
-
".pgpass"
|
|
11724
|
-
];
|
|
11725
|
-
const DENIED_BASENAME_PATTERNS = [
|
|
11726
|
-
/^\.env$/i,
|
|
11727
|
-
/^\.env\./i,
|
|
11728
|
-
/\.env$/i,
|
|
11729
|
-
/\.pem$/i,
|
|
11730
|
-
/\.key$/i,
|
|
11731
|
-
/\.p12$/i,
|
|
11732
|
-
/\.pfx$/i,
|
|
11733
|
-
/^id_(rsa|dsa|ecdsa|ed25519)$/i,
|
|
11734
|
-
/^\.htpasswd$/i
|
|
11735
|
-
];
|
|
11736
|
-
const DENIED_PATH_SUFFIXES = [
|
|
11737
|
-
`${sep}.git${sep}config`
|
|
11738
|
-
];
|
|
11739
|
-
function expandHome(input, home) {
|
|
11740
|
-
if (input === "~") return home;
|
|
11741
|
-
if (input.startsWith(`~${sep}`) || input.startsWith("~/")) {
|
|
11742
|
-
return resolve(home, input.slice(2));
|
|
11743
|
-
}
|
|
11744
|
-
return input;
|
|
11745
|
-
}
|
|
11746
|
-
function basenameOf(p) {
|
|
11747
|
-
const parts = p.split(sep);
|
|
11748
|
-
return parts[parts.length - 1] ?? "";
|
|
11749
|
-
}
|
|
11750
|
-
function isUnder(child, parent) {
|
|
11751
|
-
return child === parent || child.startsWith(parent.endsWith(sep) ? parent : parent + sep);
|
|
11752
|
-
}
|
|
11753
|
-
function checkPreviewPath(input, opts) {
|
|
11754
|
-
const home = homedir();
|
|
11755
|
-
const cwd = process.cwd();
|
|
11756
|
-
if (typeof input !== "string" || !input.trim()) {
|
|
11757
|
-
return { resolved: "", deniedReason: "path must be a non-empty string" };
|
|
11758
|
-
}
|
|
11759
|
-
if (input.includes("\0")) {
|
|
11760
|
-
return { resolved: "", deniedReason: "path contains a NUL byte" };
|
|
11761
|
-
}
|
|
11762
|
-
const expanded = expandHome(input.trim(), home);
|
|
11763
|
-
const resolved = isAbsolute(expanded) ? resolve(expanded) : resolve(cwd, expanded);
|
|
11764
|
-
for (const dir of DENIED_HOME_DIRS) {
|
|
11765
|
-
if (isUnder(resolved, resolve(home, dir))) {
|
|
11766
|
-
return { resolved, deniedReason: `refusing to preview anything under ~/${dir} (credential material)` };
|
|
11767
|
-
}
|
|
11768
|
-
}
|
|
11769
|
-
for (const file of DENIED_HOME_FILES) {
|
|
11770
|
-
if (resolved === resolve(home, file)) {
|
|
11771
|
-
return { resolved, deniedReason: `refusing to preview ~/${file} (credential material)` };
|
|
11772
|
-
}
|
|
11773
|
-
}
|
|
11774
|
-
const base = basenameOf(resolved);
|
|
11775
|
-
for (const pattern of DENIED_BASENAME_PATTERNS) {
|
|
11776
|
-
if (pattern.test(base)) {
|
|
11777
|
-
return { resolved, deniedReason: `refusing to preview "${base}" (looks like credential material)` };
|
|
11778
|
-
}
|
|
11779
|
-
}
|
|
11780
|
-
for (const suffix of DENIED_PATH_SUFFIXES) {
|
|
11781
|
-
if (resolved.endsWith(suffix)) {
|
|
11782
|
-
return { resolved, deniedReason: `refusing to preview ${suffix} (may contain credentials)` };
|
|
11783
|
-
}
|
|
11784
|
-
}
|
|
11785
|
-
return { resolved, deniedReason: null };
|
|
11786
|
-
}
|
|
11787
|
-
|
|
11788
11833
|
function createMcpServer(handlers, options, sessionId) {
|
|
11789
11834
|
const mcp = new McpServer({
|
|
11790
11835
|
name: "Very Happy Tools",
|
|
@@ -11836,7 +11881,7 @@ function createMcpServer(handlers, options, sessionId) {
|
|
|
11836
11881
|
return {
|
|
11837
11882
|
content: [{
|
|
11838
11883
|
type: "text",
|
|
11839
|
-
text: `
|
|
11884
|
+
text: `Queued a clipboard request for the user's open Very Happy device(s)${note}. This does not confirm that a browser wrote the clipboard; the user may need to tap a confirmation button.`
|
|
11840
11885
|
}],
|
|
11841
11886
|
isError: false
|
|
11842
11887
|
};
|
|
@@ -12305,7 +12350,7 @@ function registerSideQuestionHandler(rpc, deps) {
|
|
|
12305
12350
|
const retainMs = deps.retainMs ?? SIDE_QUESTION_RETAIN_MS;
|
|
12306
12351
|
const maxRunMs = deps.maxRunMs ?? SIDE_QUESTION_MAX_RUN_MS;
|
|
12307
12352
|
const run = deps.run ?? (async (input) => {
|
|
12308
|
-
const { query } = await import('./index-
|
|
12353
|
+
const { query } = await import('./index-CNARLBax.mjs');
|
|
12309
12354
|
return runSideQuestion(query, input);
|
|
12310
12355
|
});
|
|
12311
12356
|
const slots = /* @__PURE__ */ new Map();
|
|
@@ -17539,9 +17584,18 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17539
17584
|
} else if (subcommand === "bye") {
|
|
17540
17585
|
console.log("Bye!");
|
|
17541
17586
|
process.exit(0);
|
|
17587
|
+
} else if (subcommand === "install-pi-tools") {
|
|
17588
|
+
try {
|
|
17589
|
+
const { handleInstallPiTools } = await import('./installPiTools-C-Lxv4Bt.mjs');
|
|
17590
|
+
await handleInstallPiTools(args.slice(1));
|
|
17591
|
+
} catch (error) {
|
|
17592
|
+
console.error(error instanceof Error ? error.message : "Pi tools installation failed");
|
|
17593
|
+
process.exitCode = 1;
|
|
17594
|
+
}
|
|
17595
|
+
return;
|
|
17542
17596
|
} else if (subcommand === "install-terminal-hooks") {
|
|
17543
17597
|
try {
|
|
17544
|
-
const { installTerminalHooks, parseTerminalHooksArgs, TERMINAL_HOOKS_HELP } = await import('./installTerminalHooks-
|
|
17598
|
+
const { installTerminalHooks, parseTerminalHooksArgs, TERMINAL_HOOKS_HELP } = await import('./installTerminalHooks-BPJu2WVz.mjs');
|
|
17545
17599
|
const command = parseTerminalHooksArgs(args.slice(1));
|
|
17546
17600
|
if (command.action === "help") {
|
|
17547
17601
|
console.log(TERMINAL_HOOKS_HELP);
|
|
@@ -17558,7 +17612,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17558
17612
|
}
|
|
17559
17613
|
} else if (subcommand === "spawn") {
|
|
17560
17614
|
try {
|
|
17561
|
-
const { handleSpawnCommand } = await import('./spawn-
|
|
17615
|
+
const { handleSpawnCommand } = await import('./spawn-CnMk3LFG.mjs');
|
|
17562
17616
|
await handleSpawnCommand(args.slice(1));
|
|
17563
17617
|
} catch (error) {
|
|
17564
17618
|
console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
|
|
@@ -17570,7 +17624,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17570
17624
|
return;
|
|
17571
17625
|
} else if (subcommand === "sessions") {
|
|
17572
17626
|
try {
|
|
17573
|
-
const { handleSessionsCommand } = await import('./sessions-
|
|
17627
|
+
const { handleSessionsCommand } = await import('./sessions-JiL4aJkC.mjs');
|
|
17574
17628
|
await handleSessionsCommand(args.slice(1));
|
|
17575
17629
|
} catch (error) {
|
|
17576
17630
|
console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
|
|
@@ -17582,7 +17636,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17582
17636
|
return;
|
|
17583
17637
|
} else if (subcommand === "send") {
|
|
17584
17638
|
try {
|
|
17585
|
-
const { handleSendCommand } = await import('./send-
|
|
17639
|
+
const { handleSendCommand } = await import('./send-DV8liaRN.mjs');
|
|
17586
17640
|
await handleSendCommand(args.slice(1));
|
|
17587
17641
|
} catch (error) {
|
|
17588
17642
|
console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
|
|
@@ -17688,9 +17742,9 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17688
17742
|
if (geminiSubcommand === "project" && args[2] === "set" && args[3]) {
|
|
17689
17743
|
const projectId = args[3];
|
|
17690
17744
|
try {
|
|
17691
|
-
const { saveGoogleCloudProjectToConfig } = await import('./config-
|
|
17692
|
-
const { readCredentialsForConfiguredRelay: readCredentialsForConfiguredRelay2 } = await import('./limits-
|
|
17693
|
-
const { ApiClient: ApiClient2 } = await import('./types-
|
|
17745
|
+
const { saveGoogleCloudProjectToConfig } = await import('./config-ZsBeq10u.mjs');
|
|
17746
|
+
const { readCredentialsForConfiguredRelay: readCredentialsForConfiguredRelay2 } = await import('./limits-CHsz3Ba-.mjs').then(function (n) { return n.Y; });
|
|
17747
|
+
const { ApiClient: ApiClient2 } = await import('./types-Dnoxgb7G.mjs').then(function (n) { return n.ad; });
|
|
17694
17748
|
let userEmail = void 0;
|
|
17695
17749
|
try {
|
|
17696
17750
|
const credentials = await readCredentialsForConfiguredRelay2();
|
|
@@ -17721,7 +17775,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17721
17775
|
}
|
|
17722
17776
|
if (geminiSubcommand === "project" && args[2] === "get") {
|
|
17723
17777
|
try {
|
|
17724
|
-
const { readGeminiLocalConfig } = await import('./config-
|
|
17778
|
+
const { readGeminiLocalConfig } = await import('./config-ZsBeq10u.mjs');
|
|
17725
17779
|
const config = readGeminiLocalConfig();
|
|
17726
17780
|
if (config.googleCloudProject) {
|
|
17727
17781
|
console.log(`Current Google Cloud Project: ${config.googleCloudProject}`);
|
|
@@ -17761,7 +17815,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17761
17815
|
process.exit(0);
|
|
17762
17816
|
}
|
|
17763
17817
|
try {
|
|
17764
|
-
const { runGemini } = await import('./runGemini-
|
|
17818
|
+
const { runGemini } = await import('./runGemini-rgFHTnG7.mjs');
|
|
17765
17819
|
let startedBy = void 0;
|
|
17766
17820
|
for (let i = 1; i < args.length; i++) {
|
|
17767
17821
|
if (args[i] === "--started-by") {
|
|
@@ -17782,6 +17836,16 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17782
17836
|
}
|
|
17783
17837
|
return;
|
|
17784
17838
|
} else if (subcommand === "pi") {
|
|
17839
|
+
if (args[1] === "--terminal") {
|
|
17840
|
+
try {
|
|
17841
|
+
const { runPiTerminal } = await import('./piTerminal-Bc3jSCnY.mjs');
|
|
17842
|
+
process.exitCode = await runPiTerminal(args.slice(2));
|
|
17843
|
+
} catch (error) {
|
|
17844
|
+
console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
|
|
17845
|
+
process.exitCode = 1;
|
|
17846
|
+
}
|
|
17847
|
+
return;
|
|
17848
|
+
}
|
|
17785
17849
|
let hintPrinted = false;
|
|
17786
17850
|
const printHint = (detail) => {
|
|
17787
17851
|
const hint = piAdapterMissingHint(detail);
|
|
@@ -17791,7 +17855,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17791
17855
|
}
|
|
17792
17856
|
};
|
|
17793
17857
|
try {
|
|
17794
|
-
const { runAcp, resolveAcpAgentConfig } = await import('./index-
|
|
17858
|
+
const { runAcp, resolveAcpAgentConfig } = await import('./index-CY0zmhIp.mjs');
|
|
17795
17859
|
const parsed = parsePiRunnerArgs(args.slice(1));
|
|
17796
17860
|
const resolved = resolveAcpAgentConfig(["pi", ...parsed.passthrough]);
|
|
17797
17861
|
const { credentials } = await authAndSetupMachineIfNeeded();
|
|
@@ -17819,7 +17883,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17819
17883
|
return;
|
|
17820
17884
|
} else if (subcommand === "acp") {
|
|
17821
17885
|
try {
|
|
17822
|
-
const { runAcp, resolveAcpAgentConfig } = await import('./index-
|
|
17886
|
+
const { runAcp, resolveAcpAgentConfig } = await import('./index-CY0zmhIp.mjs');
|
|
17823
17887
|
let startedBy = void 0;
|
|
17824
17888
|
let verbose = false;
|
|
17825
17889
|
const acpArgs = [];
|
|
@@ -17859,7 +17923,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17859
17923
|
return;
|
|
17860
17924
|
} else if (subcommand === "openclaw") {
|
|
17861
17925
|
try {
|
|
17862
|
-
const { runOpenClaw } = await import('./runOpenClaw-
|
|
17926
|
+
const { runOpenClaw } = await import('./runOpenClaw-GjLWwjas.mjs');
|
|
17863
17927
|
let startedBy = void 0;
|
|
17864
17928
|
let verbose = false;
|
|
17865
17929
|
let gatewayUrl;
|
|
@@ -17910,7 +17974,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17910
17974
|
return;
|
|
17911
17975
|
} else if (subcommand === "todo") {
|
|
17912
17976
|
try {
|
|
17913
|
-
const { handleTodoCommand } = await import('./todo-
|
|
17977
|
+
const { handleTodoCommand } = await import('./todo-oHWNpEx_.mjs');
|
|
17914
17978
|
await handleTodoCommand(args.slice(1));
|
|
17915
17979
|
} catch (error) {
|
|
17916
17980
|
console.error(JSON.stringify({ error: error instanceof Error ? error.message : "Todo command failed" }));
|
|
@@ -17919,17 +17983,17 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17919
17983
|
return;
|
|
17920
17984
|
} else if (subcommand === "teams") {
|
|
17921
17985
|
try {
|
|
17922
|
-
const { handleTeamsCommand } = await import('./teams-
|
|
17986
|
+
const { handleTeamsCommand } = await import('./teams-uHZcdX9j.mjs');
|
|
17923
17987
|
await handleTeamsCommand(args.slice(1));
|
|
17924
17988
|
} catch (error) {
|
|
17925
17989
|
console.error(error instanceof Error ? error.message : "Teams command failed");
|
|
17926
17990
|
process.exitCode = 1;
|
|
17927
17991
|
}
|
|
17928
17992
|
return;
|
|
17929
|
-
} else if (subcommand === "mcp" && args.length === 1) {
|
|
17993
|
+
} else if (subcommand === "mcp" && (args.length === 1 || args.length === 2 && args[1] === "--terminal-tools")) {
|
|
17930
17994
|
try {
|
|
17931
|
-
const { handleMcpCommand } = await import('./mcp-
|
|
17932
|
-
await handleMcpCommand();
|
|
17995
|
+
const { handleMcpCommand } = await import('./mcp-BkWBRWFe.mjs');
|
|
17996
|
+
await handleMcpCommand(args[1] === "--terminal-tools");
|
|
17933
17997
|
} catch (error) {
|
|
17934
17998
|
process.stderr.write(`[very-happy mcp] Fatal: ${error instanceof Error ? error.message : String(error)}
|
|
17935
17999
|
`);
|
|
@@ -18149,6 +18213,10 @@ ${chalk.bold("Usage:")}
|
|
|
18149
18213
|
very-happy codex Start Codex mode
|
|
18150
18214
|
very-happy gemini Start Gemini mode (ACP)
|
|
18151
18215
|
very-happy pi Start pi mode (ACP via the pi-acp adapter)
|
|
18216
|
+
very-happy pi --terminal Run native pi with title, clipboard and preview tools
|
|
18217
|
+
inside a Very Happy terminal
|
|
18218
|
+
very-happy install-pi-tools Install tools for directly launched pi sessions
|
|
18219
|
+
(add --remove to uninstall)
|
|
18152
18220
|
very-happy acp Start a generic ACP-compatible agent
|
|
18153
18221
|
very-happy openclaw Connect through a configured OpenClaw gateway
|
|
18154
18222
|
very-happy install-terminal-hooks
|
|
@@ -18290,4 +18358,4 @@ ${chalk.bold("Examples:")}
|
|
|
18290
18358
|
}
|
|
18291
18359
|
}
|
|
18292
18360
|
|
|
18293
|
-
export { ALLOWED_SPAWN_PERMISSION_MODES as A, appendStagedAttachmentsToPrompt as B, CLAUDE_ATTACHMENT_KINDS as C, DEFAULT_RECENT_LIMIT as D, BasePermissionHandler as E, writeSessionModeFile as F, GEMINI_MODEL_ENV as G, normalizeAcpPermissionMode as H, removeSessionModeFile as I,
|
|
18361
|
+
export { ALLOWED_SPAWN_PERMISSION_MODES as A, appendStagedAttachmentsToPrompt as B, CLAUDE_ATTACHMENT_KINDS as C, DEFAULT_RECENT_LIMIT as D, BasePermissionHandler as E, writeSessionModeFile as F, GEMINI_MODEL_ENV as G, normalizeAcpPermissionMode as H, removeSessionModeFile as I, TEAM_SKILL as J, GEMINI_API_KEY_ENV as K, GOOGLE_API_KEY_ENV as L, MAX_READ_LIMIT as M, BaseReasoningProcessor as N, MessageBuffer as O, PI_TEAMS_EXTENSION as P, CHANGE_TITLE_INSTRUCTION as Q, SPAWN_AGENTS as S, TitleGenerator as T, sanitizeSpawnPermissionMode as a, sendUserMessage as b, listSessions as c, stopSession as d, resolvePermissionRequest as e, archiveSession as f, DEFAULT_GEMINI_MODEL as g, checkPreviewPath as h, isValidSpawnOrigin as i, registerAssistantSessionTools as j, initialMachineMetadata as k, listAccountSessions as l, createSessionMetadata as m, setupOfflineReconnection as n, StreamRelay as o, MessageQueue2 as p, query as q, readSessionTranscript as r, sessionWebUrl as s, tmuxSupportsSessionEnv as t, hashObject as u, startHappyServer as v, waitForSessionKey as w, registerAgentAttachmentDownloads as x, registerKillSessionHandler as y, stageClaudeAttachments as z };
|
package/dist/index.cjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
require('chalk');
|
|
4
|
-
require('./index-
|
|
5
|
-
require('./limits-
|
|
4
|
+
require('./index-CSQZhQ0C.cjs');
|
|
5
|
+
require('./limits-B3hngubn.cjs');
|
|
6
6
|
require('zod');
|
|
7
|
-
require('./types-
|
|
7
|
+
require('./types-Xd_LJRJN.cjs');
|
|
8
8
|
require('node:child_process');
|
|
9
9
|
require('node:os');
|
|
10
10
|
require('node:crypto');
|
|
@@ -12,7 +12,10 @@ require('cross-spawn');
|
|
|
12
12
|
require('node:path');
|
|
13
13
|
require('node:readline');
|
|
14
14
|
require('node:fs');
|
|
15
|
-
require('./
|
|
15
|
+
require('./projectPath-ChLhdOyt.cjs');
|
|
16
|
+
require('path');
|
|
17
|
+
require('url');
|
|
18
|
+
require('./agentGuidance-Bi8iBjy3.cjs');
|
|
16
19
|
require('node:fs/promises');
|
|
17
20
|
require('fs/promises');
|
|
18
21
|
require('ink');
|
|
@@ -26,7 +29,6 @@ require('os');
|
|
|
26
29
|
require('child_process');
|
|
27
30
|
require('@paralleldrive/cuid2');
|
|
28
31
|
require('fs');
|
|
29
|
-
require('path');
|
|
30
32
|
require('@anthropic-ai/sandbox-runtime');
|
|
31
33
|
require('expo-server-sdk');
|
|
32
34
|
require('crypto');
|
|
@@ -45,6 +47,5 @@ require('util');
|
|
|
45
47
|
require('inquirer');
|
|
46
48
|
require('node:url');
|
|
47
49
|
require('node:readline/promises');
|
|
48
|
-
require('url');
|
|
49
50
|
require('node-pty');
|
|
50
51
|
|