very-happy-cli 0.2.141 → 0.2.143
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-CnWSwaHk.cjs → AcpBackend-B8oehrfU.cjs} +2 -2
- package/dist/{AcpBackend-CWmjboOm.mjs → AcpBackend-LEgn9vol.mjs} +2 -2
- package/dist/{AcpSessionManager-Dxt78rPO.cjs → AcpSessionManager-BomdfyhZ.cjs} +1 -1
- package/dist/{AcpSessionManager-CtXoi6PN.mjs → AcpSessionManager-Yfbs5bi2.mjs} +1 -1
- package/dist/{agentGuidance-Do7cQka3.mjs → agentGuidance-BU4hxm8M.mjs} +1 -1
- package/dist/{agentGuidance-B9ENxSaS.cjs → agentGuidance-CJSl54ua.cjs} +1 -1
- package/dist/codex/happyMcpStdioBridge.cjs +2 -2
- package/dist/codex/happyMcpStdioBridge.mjs +2 -2
- package/dist/{config-Dn7nAHcA.cjs → config-CfqWoHmO.cjs} +5 -4
- package/dist/{config-DY57frJF.mjs → config-euZ_K5Lo.mjs} +5 -4
- package/dist/{index-BSVgut_Y.cjs → index-BREtikhm.cjs} +5 -4
- package/dist/{index-3STVDtNO.cjs → index-Bj68y6ee.cjs} +12 -40
- package/dist/{index-ChWePQEd.cjs → index-C510dSUn.cjs} +188 -132
- package/dist/{index-C55sW8E9.mjs → index-DoiG88oX.mjs} +169 -114
- package/dist/{index-DhfgAB8K.mjs → index-PM_SsRpw.mjs} +5 -4
- package/dist/{index-Dz6FgNFg.mjs → index-ZOMC8Gzn.mjs} +11 -39
- 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-zmtIrf3E.mjs → installTerminalHooks-BGVQqbgq.mjs} +8 -7
- package/dist/{installTerminalHooks--jkP17uE.cjs → installTerminalHooks-C_jraM1j.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-DbLWXlJm.cjs → limits-B3oVgqBJ.cjs} +29 -10
- package/dist/{limits-DT5Yk_UH.mjs → limits-uABU-yq3.mjs} +29 -11
- package/dist/{mcp-Bzy-X9kI.mjs → mcp-CfbTQXyh.mjs} +28 -14
- package/dist/{mcp-kE0n1dBF.cjs → mcp-G-3lL_KH.cjs} +29 -15
- package/dist/piExtension.d.mts +17 -0
- package/dist/piExtension.mjs +84 -0
- package/dist/piRuntime-BE6iYQwU.mjs +37 -0
- package/dist/piRuntime-CWE-1W-y.cjs +39 -0
- package/dist/piTerminal-Dyc_9pGP.cjs +132 -0
- package/dist/piTerminal-rqKn1_Zy.mjs +129 -0
- package/dist/projectPath-CSpqWdxp.mjs +10 -0
- package/dist/projectPath-ChLhdOyt.cjs +13 -0
- package/dist/{runGemini-BmdhYEzM.mjs → runGemini-BMlXIaTL.mjs} +8 -7
- package/dist/{runGemini-CxUz95A1.cjs → runGemini-C6qMFzcn.cjs} +9 -8
- package/dist/{runOpenClaw-RLIFJx61.cjs → runOpenClaw-C2_aCP7v.cjs} +6 -5
- package/dist/{runOpenClaw-CYpO3Vv8.mjs → runOpenClaw-CoO5Vp3S.mjs} +6 -5
- package/dist/{send-DT04hV8o.mjs → send-CBrJylJc.mjs} +5 -4
- package/dist/{send-BGcCrMUT.cjs → send-DGVwmB-p.cjs} +5 -4
- package/dist/{sessions-DDWTq2AG.mjs → sessions-DbLubh2N.mjs} +7 -6
- package/dist/{sessions-Jt9lrcrG.cjs → sessions-DyQXMN-8.cjs} +7 -6
- package/dist/{spawn-CdZgvthE.cjs → spawn-DIyFOn3W.cjs} +5 -4
- package/dist/{spawn-Ca0A70dX.mjs → spawn-wkkxEGdF.mjs} +5 -4
- package/dist/{teams-CzK1zg0m.mjs → teams-BTyVFK3P.mjs} +5 -4
- package/dist/{teams-DfVwVZ4x.cjs → teams-QOkGFjkJ.cjs} +5 -4
- package/dist/terminalToolContext-CFeGeaNm.mjs +7 -0
- package/dist/terminalToolContext-DoV9Gs7K.cjs +9 -0
- package/dist/{todo-4WhOom8k.mjs → todo-DoLkqdBe.mjs} +4 -3
- package/dist/{todo-D9nFaYpQ.cjs → todo-Du6pjwx_.cjs} +4 -3
- package/dist/{types-Bk3W89Z3.cjs → types-6__wqmmP.cjs} +80 -17
- package/dist/{types-CLosaeZT.mjs → types-BG4gFjLL.mjs} +79 -15
- package/package.json +11 -7
|
@@ -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-BG4gFjLL.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-uABU-yq3.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-BU4hxm8M.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';
|
|
@@ -6082,6 +6083,83 @@ function isAuthorizedDaemonControlRequest(authorization, controlToken) {
|
|
|
6082
6083
|
return configuredTokenIsUsable && timingSafeEqual(expectedDigest, candidateDigest);
|
|
6083
6084
|
}
|
|
6084
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
|
+
|
|
6085
6163
|
function startDaemonControlServer({
|
|
6086
6164
|
controlToken,
|
|
6087
6165
|
getChildren,
|
|
@@ -6093,6 +6171,7 @@ function startDaemonControlServer({
|
|
|
6093
6171
|
onClaudeAuthFailed,
|
|
6094
6172
|
onSessionTurnEvent,
|
|
6095
6173
|
pushClipboard,
|
|
6174
|
+
pushFilePreview,
|
|
6096
6175
|
onTerminalHook,
|
|
6097
6176
|
setTerminalTitle
|
|
6098
6177
|
}) {
|
|
@@ -6307,7 +6386,8 @@ function startDaemonControlServer({
|
|
|
6307
6386
|
typed.post("/clipboard", {
|
|
6308
6387
|
schema: {
|
|
6309
6388
|
body: z.object({
|
|
6310
|
-
text: z.string()
|
|
6389
|
+
text: z.string(),
|
|
6390
|
+
terminalId: z.string().regex(/^[a-zA-Z0-9_-]{1,64}$/).optional()
|
|
6311
6391
|
}),
|
|
6312
6392
|
response: {
|
|
6313
6393
|
200: z.object({
|
|
@@ -6319,9 +6399,25 @@ function startDaemonControlServer({
|
|
|
6319
6399
|
}
|
|
6320
6400
|
}
|
|
6321
6401
|
}, async (request) => {
|
|
6322
|
-
const { text } = request.body;
|
|
6402
|
+
const { text, terminalId } = request.body;
|
|
6323
6403
|
logger.debug(`[CONTROL SERVER] Clipboard push request (${text.length} chars)`);
|
|
6324
|
-
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");
|
|
6325
6421
|
});
|
|
6326
6422
|
typed.post("/terminal-title", {
|
|
6327
6423
|
schema: {
|
|
@@ -9044,14 +9140,15 @@ On restart inspect authoritative state and messages before taking new actions. D
|
|
|
9044
9140
|
`;
|
|
9045
9141
|
const PI_TEAMS_EXTENSION = `// Managed by Very Happy Agent Teams.
|
|
9046
9142
|
export default async function(pi) {
|
|
9047
|
-
const
|
|
9143
|
+
const managed = !!process.env.HAPPY_MCP_URL;
|
|
9144
|
+
const endpoint = process.env.HAPPY_MCP_URL || process.env.HAPPY_TERMINAL_MCP_URL;
|
|
9048
9145
|
if (!endpoint) return;
|
|
9049
9146
|
const url = new URL(endpoint);
|
|
9050
9147
|
if (!['127.0.0.1', 'localhost', '[::1]'].includes(url.hostname) || url.protocol !== 'http:') throw new Error('Very Happy MCP must be local');
|
|
9051
9148
|
const {readFile} = await import('node:fs/promises');
|
|
9052
9149
|
const {join} = await import('node:path');
|
|
9053
9150
|
const {homedir} = await import('node:os');
|
|
9054
|
-
const contextEndpoint = process.env.HAPPY_CONTEXT_USAGE_URL;
|
|
9151
|
+
const contextEndpoint = managed && process.env.HAPPY_CONTEXT_USAGE_URL;
|
|
9055
9152
|
if (contextEndpoint) {
|
|
9056
9153
|
const target = new URL(contextEndpoint);
|
|
9057
9154
|
if (target.origin !== url.origin || !target.pathname.startsWith('/runtime-context/')) throw new Error('Very Happy context must be local');
|
|
@@ -9069,7 +9166,7 @@ export default async function(pi) {
|
|
|
9069
9166
|
});
|
|
9070
9167
|
}
|
|
9071
9168
|
}
|
|
9072
|
-
pi.on('tool_call', async (event, ctx) => {
|
|
9169
|
+
if (managed) pi.on('tool_call', async (event, ctx) => {
|
|
9073
9170
|
let mode = process.env.HAPPY_PERMISSION_MODE || 'default';
|
|
9074
9171
|
const sid = process.env.HAPPY_SESSION_ID;
|
|
9075
9172
|
if (sid && /^[a-zA-Z0-9_-]+$/.test(sid)) {
|
|
@@ -9108,7 +9205,11 @@ export default async function(pi) {
|
|
|
9108
9205
|
const available = await rpc('tools/list', {});
|
|
9109
9206
|
for (const tool of available.tools || []) {
|
|
9110
9207
|
pi.registerTool({name:tool.name,label:tool.name,description:tool.description || tool.name,parameters:tool.inputSchema,
|
|
9111
|
-
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
|
+
}
|
|
9112
9213
|
});
|
|
9113
9214
|
}
|
|
9114
9215
|
}
|
|
@@ -9915,6 +10016,10 @@ Use the teams tools to inspect current task state before acting. This message is
|
|
|
9915
10016
|
} };
|
|
9916
10017
|
}
|
|
9917
10018
|
|
|
10019
|
+
function daemonExitCode(source) {
|
|
10020
|
+
return source === "exception" ? 1 : 0;
|
|
10021
|
+
}
|
|
10022
|
+
|
|
9918
10023
|
const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
9919
10024
|
function sanitizeImportTitle(value) {
|
|
9920
10025
|
if (typeof value !== "string") return null;
|
|
@@ -9994,9 +10099,9 @@ async function startDaemon() {
|
|
|
9994
10099
|
requestShutdown = (source, errorMessage) => {
|
|
9995
10100
|
logger.debug(`[DAEMON RUN] Requesting shutdown (source: ${source}, errorMessage: ${errorMessage})`);
|
|
9996
10101
|
setTimeout(async () => {
|
|
9997
|
-
logger.debug(
|
|
10102
|
+
logger.debug(`[DAEMON RUN] Shutdown did not complete in time, forcing exit with code ${daemonExitCode(source)}`);
|
|
9998
10103
|
await new Promise((resolve2) => setTimeout(resolve2, 100));
|
|
9999
|
-
process.exit(
|
|
10104
|
+
process.exit(daemonExitCode(source));
|
|
10000
10105
|
}, 1e3);
|
|
10001
10106
|
resolve({ source, errorMessage });
|
|
10002
10107
|
};
|
|
@@ -10984,11 +11089,15 @@ async function startDaemon() {
|
|
|
10984
11089
|
onSessionStateEvent,
|
|
10985
11090
|
onClaudeAuthFailed: (sessionId) => claudeAuthServiceRef?.signalAuthFailed(sessionId),
|
|
10986
11091
|
onSessionTurnEvent: (sessionId, event) => turnActivity.apply(sessionId, event),
|
|
10987
|
-
pushClipboard: (text) => {
|
|
11092
|
+
pushClipboard: (text, terminalId) => {
|
|
10988
11093
|
if (!apiMachineRef) {
|
|
10989
11094
|
return { delivered: false, truncated: false, totalBytes: 0, error: "daemon is still starting up" };
|
|
10990
11095
|
}
|
|
10991
|
-
return apiMachineRef.pushClipboard(text);
|
|
11096
|
+
return apiMachineRef.pushClipboard(text, terminalId);
|
|
11097
|
+
},
|
|
11098
|
+
pushFilePreview: (terminalId, path, mode) => {
|
|
11099
|
+
if (!apiMachineRef) return { delivered: false, error: "daemon is still starting up" };
|
|
11100
|
+
return apiMachineRef.pushFilePreview(terminalId, path, mode);
|
|
10992
11101
|
},
|
|
10993
11102
|
onTerminalHook: (body) => {
|
|
10994
11103
|
mirrorManagerRef?.handleHookPayload(body);
|
|
@@ -11250,8 +11359,8 @@ async function startDaemon() {
|
|
|
11250
11359
|
await cleanupDaemonState();
|
|
11251
11360
|
await stopCaffeinate();
|
|
11252
11361
|
await releaseDaemonLock(daemonLockHandle);
|
|
11253
|
-
logger.debug(
|
|
11254
|
-
process.exit(
|
|
11362
|
+
logger.debug(`[DAEMON RUN] Cleanup completed, exiting process with code ${daemonExitCode(source)}`);
|
|
11363
|
+
process.exit(daemonExitCode(source));
|
|
11255
11364
|
};
|
|
11256
11365
|
logger.debug("[DAEMON RUN] Daemon started successfully, waiting for shutdown request");
|
|
11257
11366
|
const shutdownRequest = await resolvesWhenShutdownRequested;
|
|
@@ -11725,83 +11834,6 @@ function normalizeProgress(value) {
|
|
|
11725
11834
|
return flat.length > PROGRESS_MAX_CHARS$1 ? flat.slice(0, PROGRESS_MAX_CHARS$1) : flat;
|
|
11726
11835
|
}
|
|
11727
11836
|
|
|
11728
|
-
const DENIED_HOME_DIRS = [
|
|
11729
|
-
".secrets",
|
|
11730
|
-
".ssh",
|
|
11731
|
-
".gnupg",
|
|
11732
|
-
".aws",
|
|
11733
|
-
".kube",
|
|
11734
|
-
".config/rbw"
|
|
11735
|
-
];
|
|
11736
|
-
const DENIED_HOME_FILES = [
|
|
11737
|
-
".claude.json",
|
|
11738
|
-
".claude/.credentials.json",
|
|
11739
|
-
".netrc",
|
|
11740
|
-
".pgpass"
|
|
11741
|
-
];
|
|
11742
|
-
const DENIED_BASENAME_PATTERNS = [
|
|
11743
|
-
/^\.env$/i,
|
|
11744
|
-
/^\.env\./i,
|
|
11745
|
-
/\.env$/i,
|
|
11746
|
-
/\.pem$/i,
|
|
11747
|
-
/\.key$/i,
|
|
11748
|
-
/\.p12$/i,
|
|
11749
|
-
/\.pfx$/i,
|
|
11750
|
-
/^id_(rsa|dsa|ecdsa|ed25519)$/i,
|
|
11751
|
-
/^\.htpasswd$/i
|
|
11752
|
-
];
|
|
11753
|
-
const DENIED_PATH_SUFFIXES = [
|
|
11754
|
-
`${sep}.git${sep}config`
|
|
11755
|
-
];
|
|
11756
|
-
function expandHome(input, home) {
|
|
11757
|
-
if (input === "~") return home;
|
|
11758
|
-
if (input.startsWith(`~${sep}`) || input.startsWith("~/")) {
|
|
11759
|
-
return resolve(home, input.slice(2));
|
|
11760
|
-
}
|
|
11761
|
-
return input;
|
|
11762
|
-
}
|
|
11763
|
-
function basenameOf(p) {
|
|
11764
|
-
const parts = p.split(sep);
|
|
11765
|
-
return parts[parts.length - 1] ?? "";
|
|
11766
|
-
}
|
|
11767
|
-
function isUnder(child, parent) {
|
|
11768
|
-
return child === parent || child.startsWith(parent.endsWith(sep) ? parent : parent + sep);
|
|
11769
|
-
}
|
|
11770
|
-
function checkPreviewPath(input, opts) {
|
|
11771
|
-
const home = homedir();
|
|
11772
|
-
const cwd = process.cwd();
|
|
11773
|
-
if (typeof input !== "string" || !input.trim()) {
|
|
11774
|
-
return { resolved: "", deniedReason: "path must be a non-empty string" };
|
|
11775
|
-
}
|
|
11776
|
-
if (input.includes("\0")) {
|
|
11777
|
-
return { resolved: "", deniedReason: "path contains a NUL byte" };
|
|
11778
|
-
}
|
|
11779
|
-
const expanded = expandHome(input.trim(), home);
|
|
11780
|
-
const resolved = isAbsolute(expanded) ? resolve(expanded) : resolve(cwd, expanded);
|
|
11781
|
-
for (const dir of DENIED_HOME_DIRS) {
|
|
11782
|
-
if (isUnder(resolved, resolve(home, dir))) {
|
|
11783
|
-
return { resolved, deniedReason: `refusing to preview anything under ~/${dir} (credential material)` };
|
|
11784
|
-
}
|
|
11785
|
-
}
|
|
11786
|
-
for (const file of DENIED_HOME_FILES) {
|
|
11787
|
-
if (resolved === resolve(home, file)) {
|
|
11788
|
-
return { resolved, deniedReason: `refusing to preview ~/${file} (credential material)` };
|
|
11789
|
-
}
|
|
11790
|
-
}
|
|
11791
|
-
const base = basenameOf(resolved);
|
|
11792
|
-
for (const pattern of DENIED_BASENAME_PATTERNS) {
|
|
11793
|
-
if (pattern.test(base)) {
|
|
11794
|
-
return { resolved, deniedReason: `refusing to preview "${base}" (looks like credential material)` };
|
|
11795
|
-
}
|
|
11796
|
-
}
|
|
11797
|
-
for (const suffix of DENIED_PATH_SUFFIXES) {
|
|
11798
|
-
if (resolved.endsWith(suffix)) {
|
|
11799
|
-
return { resolved, deniedReason: `refusing to preview ${suffix} (may contain credentials)` };
|
|
11800
|
-
}
|
|
11801
|
-
}
|
|
11802
|
-
return { resolved, deniedReason: null };
|
|
11803
|
-
}
|
|
11804
|
-
|
|
11805
11837
|
function createMcpServer(handlers, options, sessionId) {
|
|
11806
11838
|
const mcp = new McpServer({
|
|
11807
11839
|
name: "Very Happy Tools",
|
|
@@ -11853,7 +11885,7 @@ function createMcpServer(handlers, options, sessionId) {
|
|
|
11853
11885
|
return {
|
|
11854
11886
|
content: [{
|
|
11855
11887
|
type: "text",
|
|
11856
|
-
text: `
|
|
11888
|
+
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.`
|
|
11857
11889
|
}],
|
|
11858
11890
|
isError: false
|
|
11859
11891
|
};
|
|
@@ -12322,7 +12354,7 @@ function registerSideQuestionHandler(rpc, deps) {
|
|
|
12322
12354
|
const retainMs = deps.retainMs ?? SIDE_QUESTION_RETAIN_MS;
|
|
12323
12355
|
const maxRunMs = deps.maxRunMs ?? SIDE_QUESTION_MAX_RUN_MS;
|
|
12324
12356
|
const run = deps.run ?? (async (input) => {
|
|
12325
|
-
const { query } = await import('./index-
|
|
12357
|
+
const { query } = await import('./index-PM_SsRpw.mjs');
|
|
12326
12358
|
return runSideQuestion(query, input);
|
|
12327
12359
|
});
|
|
12328
12360
|
const slots = /* @__PURE__ */ new Map();
|
|
@@ -17556,9 +17588,18 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17556
17588
|
} else if (subcommand === "bye") {
|
|
17557
17589
|
console.log("Bye!");
|
|
17558
17590
|
process.exit(0);
|
|
17591
|
+
} else if (subcommand === "install-pi-tools") {
|
|
17592
|
+
try {
|
|
17593
|
+
const { handleInstallPiTools } = await import('./installPiTools-C-Lxv4Bt.mjs');
|
|
17594
|
+
await handleInstallPiTools(args.slice(1));
|
|
17595
|
+
} catch (error) {
|
|
17596
|
+
console.error(error instanceof Error ? error.message : "Pi tools installation failed");
|
|
17597
|
+
process.exitCode = 1;
|
|
17598
|
+
}
|
|
17599
|
+
return;
|
|
17559
17600
|
} else if (subcommand === "install-terminal-hooks") {
|
|
17560
17601
|
try {
|
|
17561
|
-
const { installTerminalHooks, parseTerminalHooksArgs, TERMINAL_HOOKS_HELP } = await import('./installTerminalHooks-
|
|
17602
|
+
const { installTerminalHooks, parseTerminalHooksArgs, TERMINAL_HOOKS_HELP } = await import('./installTerminalHooks-BGVQqbgq.mjs');
|
|
17562
17603
|
const command = parseTerminalHooksArgs(args.slice(1));
|
|
17563
17604
|
if (command.action === "help") {
|
|
17564
17605
|
console.log(TERMINAL_HOOKS_HELP);
|
|
@@ -17575,7 +17616,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17575
17616
|
}
|
|
17576
17617
|
} else if (subcommand === "spawn") {
|
|
17577
17618
|
try {
|
|
17578
|
-
const { handleSpawnCommand } = await import('./spawn-
|
|
17619
|
+
const { handleSpawnCommand } = await import('./spawn-wkkxEGdF.mjs');
|
|
17579
17620
|
await handleSpawnCommand(args.slice(1));
|
|
17580
17621
|
} catch (error) {
|
|
17581
17622
|
console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
|
|
@@ -17587,7 +17628,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17587
17628
|
return;
|
|
17588
17629
|
} else if (subcommand === "sessions") {
|
|
17589
17630
|
try {
|
|
17590
|
-
const { handleSessionsCommand } = await import('./sessions-
|
|
17631
|
+
const { handleSessionsCommand } = await import('./sessions-DbLubh2N.mjs');
|
|
17591
17632
|
await handleSessionsCommand(args.slice(1));
|
|
17592
17633
|
} catch (error) {
|
|
17593
17634
|
console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
|
|
@@ -17599,7 +17640,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17599
17640
|
return;
|
|
17600
17641
|
} else if (subcommand === "send") {
|
|
17601
17642
|
try {
|
|
17602
|
-
const { handleSendCommand } = await import('./send-
|
|
17643
|
+
const { handleSendCommand } = await import('./send-CBrJylJc.mjs');
|
|
17603
17644
|
await handleSendCommand(args.slice(1));
|
|
17604
17645
|
} catch (error) {
|
|
17605
17646
|
console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
|
|
@@ -17705,9 +17746,9 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17705
17746
|
if (geminiSubcommand === "project" && args[2] === "set" && args[3]) {
|
|
17706
17747
|
const projectId = args[3];
|
|
17707
17748
|
try {
|
|
17708
|
-
const { saveGoogleCloudProjectToConfig } = await import('./config-
|
|
17709
|
-
const { readCredentialsForConfiguredRelay: readCredentialsForConfiguredRelay2 } = await import('./limits-
|
|
17710
|
-
const { ApiClient: ApiClient2 } = await import('./types-
|
|
17749
|
+
const { saveGoogleCloudProjectToConfig } = await import('./config-euZ_K5Lo.mjs');
|
|
17750
|
+
const { readCredentialsForConfiguredRelay: readCredentialsForConfiguredRelay2 } = await import('./limits-uABU-yq3.mjs').then(function (n) { return n.Y; });
|
|
17751
|
+
const { ApiClient: ApiClient2 } = await import('./types-BG4gFjLL.mjs').then(function (n) { return n.ad; });
|
|
17711
17752
|
let userEmail = void 0;
|
|
17712
17753
|
try {
|
|
17713
17754
|
const credentials = await readCredentialsForConfiguredRelay2();
|
|
@@ -17738,7 +17779,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17738
17779
|
}
|
|
17739
17780
|
if (geminiSubcommand === "project" && args[2] === "get") {
|
|
17740
17781
|
try {
|
|
17741
|
-
const { readGeminiLocalConfig } = await import('./config-
|
|
17782
|
+
const { readGeminiLocalConfig } = await import('./config-euZ_K5Lo.mjs');
|
|
17742
17783
|
const config = readGeminiLocalConfig();
|
|
17743
17784
|
if (config.googleCloudProject) {
|
|
17744
17785
|
console.log(`Current Google Cloud Project: ${config.googleCloudProject}`);
|
|
@@ -17778,7 +17819,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17778
17819
|
process.exit(0);
|
|
17779
17820
|
}
|
|
17780
17821
|
try {
|
|
17781
|
-
const { runGemini } = await import('./runGemini-
|
|
17822
|
+
const { runGemini } = await import('./runGemini-BMlXIaTL.mjs');
|
|
17782
17823
|
let startedBy = void 0;
|
|
17783
17824
|
for (let i = 1; i < args.length; i++) {
|
|
17784
17825
|
if (args[i] === "--started-by") {
|
|
@@ -17799,6 +17840,16 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17799
17840
|
}
|
|
17800
17841
|
return;
|
|
17801
17842
|
} else if (subcommand === "pi") {
|
|
17843
|
+
if (args[1] === "--terminal") {
|
|
17844
|
+
try {
|
|
17845
|
+
const { runPiTerminal } = await import('./piTerminal-rqKn1_Zy.mjs');
|
|
17846
|
+
process.exitCode = await runPiTerminal(args.slice(2));
|
|
17847
|
+
} catch (error) {
|
|
17848
|
+
console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
|
|
17849
|
+
process.exitCode = 1;
|
|
17850
|
+
}
|
|
17851
|
+
return;
|
|
17852
|
+
}
|
|
17802
17853
|
let hintPrinted = false;
|
|
17803
17854
|
const printHint = (detail) => {
|
|
17804
17855
|
const hint = piAdapterMissingHint(detail);
|
|
@@ -17808,7 +17859,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17808
17859
|
}
|
|
17809
17860
|
};
|
|
17810
17861
|
try {
|
|
17811
|
-
const { runAcp, resolveAcpAgentConfig } = await import('./index-
|
|
17862
|
+
const { runAcp, resolveAcpAgentConfig } = await import('./index-ZOMC8Gzn.mjs');
|
|
17812
17863
|
const parsed = parsePiRunnerArgs(args.slice(1));
|
|
17813
17864
|
const resolved = resolveAcpAgentConfig(["pi", ...parsed.passthrough]);
|
|
17814
17865
|
const { credentials } = await authAndSetupMachineIfNeeded();
|
|
@@ -17836,7 +17887,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17836
17887
|
return;
|
|
17837
17888
|
} else if (subcommand === "acp") {
|
|
17838
17889
|
try {
|
|
17839
|
-
const { runAcp, resolveAcpAgentConfig } = await import('./index-
|
|
17890
|
+
const { runAcp, resolveAcpAgentConfig } = await import('./index-ZOMC8Gzn.mjs');
|
|
17840
17891
|
let startedBy = void 0;
|
|
17841
17892
|
let verbose = false;
|
|
17842
17893
|
const acpArgs = [];
|
|
@@ -17876,7 +17927,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17876
17927
|
return;
|
|
17877
17928
|
} else if (subcommand === "openclaw") {
|
|
17878
17929
|
try {
|
|
17879
|
-
const { runOpenClaw } = await import('./runOpenClaw-
|
|
17930
|
+
const { runOpenClaw } = await import('./runOpenClaw-CoO5Vp3S.mjs');
|
|
17880
17931
|
let startedBy = void 0;
|
|
17881
17932
|
let verbose = false;
|
|
17882
17933
|
let gatewayUrl;
|
|
@@ -17927,7 +17978,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17927
17978
|
return;
|
|
17928
17979
|
} else if (subcommand === "todo") {
|
|
17929
17980
|
try {
|
|
17930
|
-
const { handleTodoCommand } = await import('./todo-
|
|
17981
|
+
const { handleTodoCommand } = await import('./todo-DoLkqdBe.mjs');
|
|
17931
17982
|
await handleTodoCommand(args.slice(1));
|
|
17932
17983
|
} catch (error) {
|
|
17933
17984
|
console.error(JSON.stringify({ error: error instanceof Error ? error.message : "Todo command failed" }));
|
|
@@ -17936,17 +17987,17 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17936
17987
|
return;
|
|
17937
17988
|
} else if (subcommand === "teams") {
|
|
17938
17989
|
try {
|
|
17939
|
-
const { handleTeamsCommand } = await import('./teams-
|
|
17990
|
+
const { handleTeamsCommand } = await import('./teams-BTyVFK3P.mjs');
|
|
17940
17991
|
await handleTeamsCommand(args.slice(1));
|
|
17941
17992
|
} catch (error) {
|
|
17942
17993
|
console.error(error instanceof Error ? error.message : "Teams command failed");
|
|
17943
17994
|
process.exitCode = 1;
|
|
17944
17995
|
}
|
|
17945
17996
|
return;
|
|
17946
|
-
} else if (subcommand === "mcp" && args.length === 1) {
|
|
17997
|
+
} else if (subcommand === "mcp" && (args.length === 1 || args.length === 2 && args[1] === "--terminal-tools")) {
|
|
17947
17998
|
try {
|
|
17948
|
-
const { handleMcpCommand } = await import('./mcp-
|
|
17949
|
-
await handleMcpCommand();
|
|
17999
|
+
const { handleMcpCommand } = await import('./mcp-CfbTQXyh.mjs');
|
|
18000
|
+
await handleMcpCommand(args[1] === "--terminal-tools");
|
|
17950
18001
|
} catch (error) {
|
|
17951
18002
|
process.stderr.write(`[very-happy mcp] Fatal: ${error instanceof Error ? error.message : String(error)}
|
|
17952
18003
|
`);
|
|
@@ -18166,6 +18217,10 @@ ${chalk.bold("Usage:")}
|
|
|
18166
18217
|
very-happy codex Start Codex mode
|
|
18167
18218
|
very-happy gemini Start Gemini mode (ACP)
|
|
18168
18219
|
very-happy pi Start pi mode (ACP via the pi-acp adapter)
|
|
18220
|
+
very-happy pi --terminal Run native pi with title, clipboard and preview tools
|
|
18221
|
+
inside a Very Happy terminal
|
|
18222
|
+
very-happy install-pi-tools Install tools for directly launched pi sessions
|
|
18223
|
+
(add --remove to uninstall)
|
|
18169
18224
|
very-happy acp Start a generic ACP-compatible agent
|
|
18170
18225
|
very-happy openclaw Connect through a configured OpenClaw gateway
|
|
18171
18226
|
very-happy install-terminal-hooks
|
|
@@ -18307,4 +18362,4 @@ ${chalk.bold("Examples:")}
|
|
|
18307
18362
|
}
|
|
18308
18363
|
}
|
|
18309
18364
|
|
|
18310
|
-
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,
|
|
18365
|
+
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 };
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { q as query } from './index-
|
|
1
|
+
import { q as query } from './index-DoiG88oX.mjs';
|
|
2
2
|
export { AbortError } from '@anthropic-ai/claude-agent-sdk';
|
|
3
3
|
import 'chalk';
|
|
4
4
|
import 'node:os';
|
|
5
5
|
import 'node:crypto';
|
|
6
|
-
import './types-
|
|
6
|
+
import './types-BG4gFjLL.mjs';
|
|
7
7
|
import 'axios';
|
|
8
|
-
import './limits-
|
|
8
|
+
import './limits-uABU-yq3.mjs';
|
|
9
9
|
import 'node:fs/promises';
|
|
10
10
|
import 'node:fs';
|
|
11
11
|
import 'node:path';
|
|
@@ -21,6 +21,7 @@ import 'fs/promises';
|
|
|
21
21
|
import 'crypto';
|
|
22
22
|
import 'path';
|
|
23
23
|
import 'cross-spawn';
|
|
24
|
+
import './projectPath-CSpqWdxp.mjs';
|
|
24
25
|
import 'url';
|
|
25
26
|
import 'os';
|
|
26
27
|
import 'node:child_process';
|
|
@@ -29,7 +30,7 @@ import 'fs';
|
|
|
29
30
|
import 'node:readline';
|
|
30
31
|
import '@anthropic-ai/sandbox-runtime';
|
|
31
32
|
import 'expo-server-sdk';
|
|
32
|
-
import './agentGuidance-
|
|
33
|
+
import './agentGuidance-BU4hxm8M.mjs';
|
|
33
34
|
import 'ink';
|
|
34
35
|
import 'react';
|
|
35
36
|
import 'ps-list';
|
|
@@ -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-LEgn9vol.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-LEgn9vol.mjs';
|
|
3
|
+
import { f as readSettings, g as encodeBase64, l as logger, c as configuration } from './limits-uABU-yq3.mjs';
|
|
4
|
+
import { A as AcpSessionManager } from './AcpSessionManager-Yfbs5bi2.mjs';
|
|
5
|
+
import { h as connectionState, A as ApiClient, n as notifyDaemonSessionStarted, j as BUILTIN_TODO_DISCOVERY } from './types-BG4gFjLL.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-DoiG88oX.mjs';
|
|
7
|
+
import { p as preparePiTeamsRuntime } from './piRuntime-BE6iYQwU.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-BU4hxm8M.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";
|