very-happy-cli 0.2.143 → 0.2.145
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-LEgn9vol.mjs → AcpBackend-BITeBnbV.mjs} +2 -2
- package/dist/{AcpBackend-B8oehrfU.cjs → AcpBackend-FPv5uXFa.cjs} +30 -30
- package/dist/{AcpSessionManager-BomdfyhZ.cjs → AcpSessionManager-vqLzM219.cjs} +9 -9
- package/dist/{AcpSessionManager-Yfbs5bi2.mjs → AcpSessionManager-w2srpWQJ.mjs} +1 -1
- package/dist/{agentGuidance-CJSl54ua.cjs → agentGuidance-Bd6GEiYp.cjs} +1 -1
- package/dist/{agentGuidance-BU4hxm8M.mjs → agentGuidance-HFHrz3C1.mjs} +1 -1
- package/dist/agentHome-CGl7FF7a.cjs +113 -0
- package/dist/agentHome-DBqr8rpv.mjs +107 -0
- package/dist/codex/happyMcpStdioBridge.cjs +2 -2
- package/dist/codex/happyMcpStdioBridge.mjs +2 -2
- package/dist/{config-euZ_K5Lo.mjs → config-B9zAvnGT.mjs} +4 -4
- package/dist/{config-CfqWoHmO.cjs → config-CPfFuHP6.cjs} +4 -4
- package/dist/{index-ZOMC8Gzn.mjs → index-BzLZu_aF.mjs} +8 -8
- package/dist/{index-PM_SsRpw.mjs → index-CxK0l_t0.mjs} +4 -4
- package/dist/{index-BREtikhm.cjs → index-D4Smqppj.cjs} +4 -4
- package/dist/{index-C510dSUn.cjs → index-DhwtFJEe.cjs} +309 -212
- package/dist/{index-Bj68y6ee.cjs → index-avfJgX4p.cjs} +31 -31
- package/dist/{index-DoiG88oX.mjs → index-eBrE-0R1.mjs} +136 -39
- package/dist/index.cjs +4 -4
- package/dist/index.mjs +4 -4
- package/dist/{installTerminalHooks-BGVQqbgq.mjs → installTerminalHooks-Dq1MFFDQ.mjs} +4 -4
- package/dist/{installTerminalHooks-C_jraM1j.cjs → installTerminalHooks-DspFGxBI.cjs} +4 -4
- package/dist/lib.cjs +5 -5
- package/dist/lib.mjs +2 -2
- package/dist/{limits-uABU-yq3.mjs → limits-CzWD9hWU.mjs} +8 -8
- package/dist/{limits-B3oVgqBJ.cjs → limits-DGZB-OVl.cjs} +7 -7
- package/dist/{mcp-G-3lL_KH.cjs → mcp-BioGrTC_.cjs} +9 -9
- package/dist/{mcp-CfbTQXyh.mjs → mcp-L1Yq25LB.mjs} +4 -4
- package/dist/{piRuntime-CWE-1W-y.cjs → piRuntime-DodWS0UI.cjs} +2 -2
- package/dist/{piRuntime-BE6iYQwU.mjs → piRuntime-UdVG4eJ7.mjs} +2 -2
- package/dist/{piTerminal-Dyc_9pGP.cjs → piTerminal-6P00O_w8.cjs} +6 -6
- package/dist/{piTerminal-rqKn1_Zy.mjs → piTerminal-BIRroC_N.mjs} +6 -6
- package/dist/{runGemini-BMlXIaTL.mjs → runGemini-B-It6K8t.mjs} +6 -6
- package/dist/{runGemini-C6qMFzcn.cjs → runGemini-ChCHjnIh.cjs} +24 -24
- package/dist/{runOpenClaw-C2_aCP7v.cjs → runOpenClaw-Cc4_zmHz.cjs} +26 -26
- package/dist/{runOpenClaw-CoO5Vp3S.mjs → runOpenClaw-DET6LY2v.mjs} +5 -5
- package/dist/{send-CBrJylJc.mjs → send-CPayvXBm.mjs} +4 -4
- package/dist/{send-DGVwmB-p.cjs → send-LBjLfAos.cjs} +4 -4
- package/dist/{sessions-DbLubh2N.mjs → sessions-CJUEp43_.mjs} +4 -4
- package/dist/{sessions-DyQXMN-8.cjs → sessions-WBowxNO-.cjs} +5 -5
- package/dist/{spawn-DIyFOn3W.cjs → spawn-BqgZc7YE.cjs} +6 -6
- package/dist/{spawn-wkkxEGdF.mjs → spawn-Dcetf5Jt.mjs} +4 -4
- package/dist/{teams-BTyVFK3P.mjs → teams-CW_Zb2Q1.mjs} +4 -4
- package/dist/{teams-QOkGFjkJ.cjs → teams-eIUxGmqg.cjs} +4 -4
- package/dist/{todo-DoLkqdBe.mjs → todo-CV5fwHg_.mjs} +3 -3
- package/dist/{todo-Du6pjwx_.cjs → todo-DeouLiGa.cjs} +5 -5
- package/dist/{types-BG4gFjLL.mjs → types-BbvxVQF3.mjs} +321 -11
- package/dist/{types-6__wqmmP.cjs → types-Bqo68u61.cjs} +328 -9
- package/package.json +7 -7
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var AcpBackend = require('./AcpBackend-
|
|
4
|
-
var persistence = require('./limits-
|
|
5
|
-
var AcpSessionManager = require('./AcpSessionManager-
|
|
6
|
-
var
|
|
7
|
-
var index = require('./index-
|
|
8
|
-
var piRuntime = require('./piRuntime-
|
|
3
|
+
var AcpBackend = require('./AcpBackend-FPv5uXFa.cjs');
|
|
4
|
+
var persistence = require('./limits-DGZB-OVl.cjs');
|
|
5
|
+
var AcpSessionManager = require('./AcpSessionManager-vqLzM219.cjs');
|
|
6
|
+
var index = require('./types-Bqo68u61.cjs');
|
|
7
|
+
var index$1 = require('./index-DhwtFJEe.cjs');
|
|
8
|
+
var piRuntime = require('./piRuntime-DodWS0UI.cjs');
|
|
9
9
|
var node_crypto = require('node:crypto');
|
|
10
10
|
var path = require('node:path');
|
|
11
11
|
var projectPath = require('./projectPath-ChLhdOyt.cjs');
|
|
@@ -34,7 +34,7 @@ require('fs');
|
|
|
34
34
|
require('node:readline');
|
|
35
35
|
require('@anthropic-ai/sandbox-runtime');
|
|
36
36
|
require('expo-server-sdk');
|
|
37
|
-
require('./agentGuidance-
|
|
37
|
+
require('./agentGuidance-Bd6GEiYp.cjs');
|
|
38
38
|
require('ink');
|
|
39
39
|
require('react');
|
|
40
40
|
require('@anthropic-ai/claude-agent-sdk');
|
|
@@ -555,7 +555,7 @@ function resolveRequestedLegacyModelCode(models, requested) {
|
|
|
555
555
|
}
|
|
556
556
|
return null;
|
|
557
557
|
}
|
|
558
|
-
class GenericAcpPermissionHandler extends index.BasePermissionHandler {
|
|
558
|
+
class GenericAcpPermissionHandler extends index$1.BasePermissionHandler {
|
|
559
559
|
logPrefix;
|
|
560
560
|
constructor(session, agentName) {
|
|
561
561
|
super(session);
|
|
@@ -589,17 +589,17 @@ function resolveSessionFlavor(agentName) {
|
|
|
589
589
|
async function runAcp(opts) {
|
|
590
590
|
const verbose = opts.verbose === true;
|
|
591
591
|
const sessionTag = node_crypto.randomUUID();
|
|
592
|
-
|
|
593
|
-
const api
|
|
592
|
+
index.connectionState.setBackend(opts.agentName);
|
|
593
|
+
const api = await index.ApiClient.create(opts.credentials);
|
|
594
594
|
const settings = await persistence.readSettings();
|
|
595
595
|
if (!settings?.machineId) {
|
|
596
596
|
throw new Error("No machine ID found in settings");
|
|
597
597
|
}
|
|
598
|
-
await api
|
|
598
|
+
await api.getOrCreateMachine({
|
|
599
599
|
machineId: settings.machineId,
|
|
600
|
-
metadata: index.initialMachineMetadata
|
|
600
|
+
metadata: index$1.initialMachineMetadata
|
|
601
601
|
});
|
|
602
|
-
const { state, metadata } = index.createSessionMetadata({
|
|
602
|
+
const { state, metadata } = index$1.createSessionMetadata({
|
|
603
603
|
flavor: resolveSessionFlavor(opts.agentName),
|
|
604
604
|
...process.env.VH_TEAM_OPERATION_ID ? { teamOperationId: process.env.VH_TEAM_OPERATION_ID } : {},
|
|
605
605
|
machineId: settings.machineId,
|
|
@@ -607,14 +607,14 @@ async function runAcp(opts) {
|
|
|
607
607
|
sandbox: settings.sandboxConfig
|
|
608
608
|
});
|
|
609
609
|
metadata.attachmentKinds = [];
|
|
610
|
-
const response = await api
|
|
610
|
+
const response = await api.getOrCreateSession({ tag: sessionTag, metadata, state });
|
|
611
611
|
if (response) {
|
|
612
612
|
logAcp("muted", `Happy Session ID: ${response.id}`);
|
|
613
613
|
}
|
|
614
614
|
let session;
|
|
615
615
|
let permissionHandler;
|
|
616
|
-
const { session: initialSession, reconnectionHandle } = index.setupOfflineReconnection({
|
|
617
|
-
api
|
|
616
|
+
const { session: initialSession, reconnectionHandle } = index$1.setupOfflineReconnection({
|
|
617
|
+
api,
|
|
618
618
|
sessionTag,
|
|
619
619
|
metadata,
|
|
620
620
|
state,
|
|
@@ -629,7 +629,7 @@ async function runAcp(opts) {
|
|
|
629
629
|
session = initialSession;
|
|
630
630
|
if (response) {
|
|
631
631
|
try {
|
|
632
|
-
await
|
|
632
|
+
await index.notifyDaemonSessionStarted(response.id, metadata, {
|
|
633
633
|
encryptionKey: persistence.encodeBase64(response.encryptionKey),
|
|
634
634
|
encryptionVariant: response.encryptionVariant,
|
|
635
635
|
seq: response.seq,
|
|
@@ -643,11 +643,11 @@ async function runAcp(opts) {
|
|
|
643
643
|
permissionHandler = new GenericAcpPermissionHandler(session, opts.agentName);
|
|
644
644
|
permissionHandler.reset("Previous CLI process exited before responding");
|
|
645
645
|
const streamingEnabled = process.env.HAPPY_SESSION_STREAM_DISABLED !== "1";
|
|
646
|
-
const streamRelay = new index.StreamRelay({
|
|
646
|
+
const streamRelay = new index$1.StreamRelay({
|
|
647
647
|
send: (frame) => session.sendStreamFrame(frame)
|
|
648
648
|
});
|
|
649
649
|
const sessionManager = new AcpSessionManager.AcpSessionManager(streamingEnabled ? { stream: streamRelay } : {});
|
|
650
|
-
const messageQueue = new index.MessageQueue2((mode) => index.hashObject(mode));
|
|
650
|
+
const messageQueue = new index$1.MessageQueue2((mode) => index$1.hashObject(mode));
|
|
651
651
|
let currentPermissionMode;
|
|
652
652
|
let currentModel;
|
|
653
653
|
let modeSelector = null;
|
|
@@ -668,7 +668,7 @@ async function runAcp(opts) {
|
|
|
668
668
|
return true;
|
|
669
669
|
}
|
|
670
670
|
try {
|
|
671
|
-
index.writeSessionModeFile(session.sessionId, mode);
|
|
671
|
+
index$1.writeSessionModeFile(session.sessionId, mode);
|
|
672
672
|
} catch (error) {
|
|
673
673
|
persistence.logger.debug(`[${opts.agentName}] Failed to write session mode file:`, error);
|
|
674
674
|
return false;
|
|
@@ -679,7 +679,7 @@ async function runAcp(opts) {
|
|
|
679
679
|
return true;
|
|
680
680
|
};
|
|
681
681
|
const isAssistantVariant = process.env.HAPPY_SESSION_VARIANT === "assistant";
|
|
682
|
-
const happyServer = await index.startHappyServer(session, {
|
|
682
|
+
const happyServer = await index$1.startHappyServer(session, {
|
|
683
683
|
assistant: isAssistantVariant,
|
|
684
684
|
...opts.agentName === "pi" ? { onContextUsage: (contextUsage) => {
|
|
685
685
|
session.updateAgentState((state2) => ({ ...state2, contextUsage }));
|
|
@@ -767,7 +767,7 @@ async function runAcp(opts) {
|
|
|
767
767
|
return;
|
|
768
768
|
}
|
|
769
769
|
if (permissionModeIsFileBacked()) {
|
|
770
|
-
const mode = index.normalizeAcpPermissionMode(requestedMode);
|
|
770
|
+
const mode = index$1.normalizeAcpPermissionMode(requestedMode);
|
|
771
771
|
if (!mode) {
|
|
772
772
|
persistence.logger.debug(`[${opts.agentName}] Ignoring unknown file-backed permission mode request: ${requestedMode}`);
|
|
773
773
|
return;
|
|
@@ -1031,8 +1031,8 @@ async function runAcp(opts) {
|
|
|
1031
1031
|
sendEnvelopes(sessionManager.mapMessage(msg));
|
|
1032
1032
|
};
|
|
1033
1033
|
backend.onMessage(onBackendMessage);
|
|
1034
|
-
const titleGenerator = new index.TitleGenerator(session);
|
|
1035
|
-
index.registerAgentAttachmentDownloads(session);
|
|
1034
|
+
const titleGenerator = new index$1.TitleGenerator(session);
|
|
1035
|
+
index$1.registerAgentAttachmentDownloads(session);
|
|
1036
1036
|
let userMessageDelivery = Promise.resolve();
|
|
1037
1037
|
session.onUserMessage((message) => {
|
|
1038
1038
|
const downloads = session.drainAttachmentsForUserMessage();
|
|
@@ -1088,7 +1088,7 @@ async function runAcp(opts) {
|
|
|
1088
1088
|
if (!fileBackedModeActive) {
|
|
1089
1089
|
throw new Error(`${opts.agentName} does not support live permission mode changes`);
|
|
1090
1090
|
}
|
|
1091
|
-
const mode = typeof request?.mode === "string" ? index.normalizeAcpPermissionMode(request.mode) : null;
|
|
1091
|
+
const mode = typeof request?.mode === "string" ? index$1.normalizeAcpPermissionMode(request.mode) : null;
|
|
1092
1092
|
if (!mode) {
|
|
1093
1093
|
throw new Error("Invalid permission mode");
|
|
1094
1094
|
}
|
|
@@ -1098,7 +1098,7 @@ async function runAcp(opts) {
|
|
|
1098
1098
|
return { mode };
|
|
1099
1099
|
}
|
|
1100
1100
|
);
|
|
1101
|
-
const disposeTermination = index.registerKillSessionHandler(session.rpcHandlerManager, async () => {
|
|
1101
|
+
const disposeTermination = index$1.registerKillSessionHandler(session.rpcHandlerManager, async () => {
|
|
1102
1102
|
shouldExit = true;
|
|
1103
1103
|
messageQueue.close();
|
|
1104
1104
|
clearPendingTurn(new Error("Session terminated"));
|
|
@@ -1114,7 +1114,7 @@ async function runAcp(opts) {
|
|
|
1114
1114
|
}
|
|
1115
1115
|
session.updateMetadata((current) => ({
|
|
1116
1116
|
...current,
|
|
1117
|
-
attachmentKinds: opts.agentName === "pi" && backend.supportsImageAttachments ? [...index.CLAUDE_ATTACHMENT_KINDS] : []
|
|
1117
|
+
attachmentKinds: opts.agentName === "pi" && backend.supportsImageAttachments ? [...index$1.CLAUDE_ATTACHMENT_KINDS] : []
|
|
1118
1118
|
}));
|
|
1119
1119
|
if (permissionModeIsFileBacked()) {
|
|
1120
1120
|
fileBackedModeActive = true;
|
|
@@ -1164,13 +1164,13 @@ async function runAcp(opts) {
|
|
|
1164
1164
|
}
|
|
1165
1165
|
const prompt = todoDiscoverySent ? batch.message : `${batch.message}
|
|
1166
1166
|
|
|
1167
|
-
${
|
|
1167
|
+
${index.BUILTIN_TODO_DISCOVERY}`;
|
|
1168
1168
|
const attachments = batch.attachments ?? [];
|
|
1169
|
-
const staged = attachments.length ? await index.stageClaudeAttachments(attachments, {
|
|
1169
|
+
const staged = attachments.length ? await index$1.stageClaudeAttachments(attachments, {
|
|
1170
1170
|
happyHomeDir: persistence.configuration.happyHomeDir,
|
|
1171
1171
|
sessionId: session.sessionId
|
|
1172
1172
|
}) : [];
|
|
1173
|
-
await backend.sendPrompt(acpSessionId, index.appendStagedAttachmentsToPrompt(prompt, staged), attachments);
|
|
1173
|
+
await backend.sendPrompt(acpSessionId, index$1.appendStagedAttachmentsToPrompt(prompt, staged), attachments);
|
|
1174
1174
|
todoDiscoverySent = true;
|
|
1175
1175
|
await turnEnded;
|
|
1176
1176
|
sendEnvelopes(sessionManager.endTurn(turnCancelled ? "cancelled" : "completed"));
|
|
@@ -1208,7 +1208,7 @@ ${api.BUILTIN_TODO_DISCOVERY}`;
|
|
|
1208
1208
|
await backend.dispose();
|
|
1209
1209
|
if (fileBackedPermissionMode) {
|
|
1210
1210
|
try {
|
|
1211
|
-
index.removeSessionModeFile(session.sessionId);
|
|
1211
|
+
index$1.removeSessionModeFile(session.sessionId);
|
|
1212
1212
|
} catch (error) {
|
|
1213
1213
|
persistence.logger.debug(`[${opts.agentName}] Failed to remove session mode file:`, error);
|
|
1214
1214
|
}
|
|
@@ -1,14 +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 {
|
|
5
|
-
import { l as logger,
|
|
4
|
+
import { v as notifyDaemonSessionEvent, w as getProjectPath, o as BUILTIN_TODO_DISCOVERY, x as initializeSandbox, y as wrapCommand, t as contentLogMetadata, I as InvalidateSync, R as RawJSONLinesSchema, u as delay, z as AsyncLock, S as STREAM_DELTA_MAX_CHARS, M as MAX_CHAT_ATTACHMENT_SOURCE_BYTES, C as notifyDaemonClaudeAuthFailed, D as commandOnPath, c as checkIfDaemonRunningAndCleanupStaleState, E as deriveLocalCliUpdateSummary, F as AGENT_VERSION_SOURCES, G as isClaudeSessionId, H as getLocalHappyAgentCredentialPath, J as readLocalHappyAgentCredentials, K as parseExactVersion, L as compareExactVersions, N as extractCompleteLines, O as decideBackfill, P as parseTerminalHookPayload, Q as tmuxArgs, T as scrubTmuxClientEnv, U as decideMirrorBinding, V as MIRROR_BACKFILL_LINES_DEFAULT, W as mirrorLineKey, X as mirrorLocalId, Y as listDaemonSessions, Z as stopDaemonSession, _ as detectCLIAvailability, $ as detectResumeSupport, a0 as refreshAgentHomes, d as describeAgentHome, a1 as isDaemonRunningCurrentlyInstalledHappyVersion, a2 as stopDaemon, a3 as TurnActivityTracker, a4 as summarizeSpawnSessionForLog, a5 as locateClaudeConversation, a6 as agentHomeSpawnEnv, a7 as shellescape, A as ApiClient, a8 as fetchCliUpdateState, a9 as resolveCliUpdateCheckInterval, aa as DEFAULT_CLI_UPDATE_CHECK_INTERVAL_MS, ab as cleanupDaemonState, i as isValidSessionId, s as spawnDaemonSession, ac as listVhTerminals, ad as isValidTerminalId, ae as readVhTerminal, af as sendToVhTerminal, ag as ContextUsageSchema, ah as TITLE_PROMPT_PREFIX, ai as BOARD_ANALYZER_PROMPT_PREFIX, m as connectionState, aj as startOfflineReconnection, n as notifyDaemonSessionStarted, g as createEnvelope, ak as CodexAppServerClient } from './types-BbvxVQF3.mjs';
|
|
5
|
+
import { l as logger, F as ensurePrivateDirectory, G as hardenPrivateFile, c as configuration, p as packageJson, r as readSettings, H as readCredentials, x as credentialRelayProblem, o as readDaemonState, g as encodeBase64, I as readSettingsOutcome, u as updateSettings, J as encodeBase64Url, m as decodeBase64, K as writeCredentialsLegacy, L as writeCredentialsDataKey, e as readCredentialsForConfiguredRelay, j as encrypt, d 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, f as CLIPBOARD_MAX_BYTES, U as clearCredentials, V as clearMachineId, W as SandboxConfigSchema, X as getLatestDaemonLog } from './limits-CzWD9hWU.mjs';
|
|
6
6
|
import spawn$1, { spawn } from 'cross-spawn';
|
|
7
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
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-
|
|
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-HFHrz3C1.mjs';
|
|
12
12
|
import { readFile, writeFile, rename, unlink, mkdir, symlink, rm, readlink, lstat, stat, open as open$1, appendFile } from 'node:fs/promises';
|
|
13
13
|
import fs, { watch, access } from 'fs/promises';
|
|
14
14
|
import { useStdout, useInput, Box, Text, render } from 'ink';
|
|
@@ -5294,6 +5294,16 @@ ${typeLabels[type] || type}:`));
|
|
|
5294
5294
|
console.log(chalk.gray(" OS-keychain credentials cannot be verified here; see /docs/configuration#claude-credentials."));
|
|
5295
5295
|
}
|
|
5296
5296
|
console.log(chalk.gray(" An external claude command is only needed for native terminal/mirror use."));
|
|
5297
|
+
try {
|
|
5298
|
+
const { resolveAgentHomesForCli } = await import('./agentHome-DBqr8rpv.mjs');
|
|
5299
|
+
const { describeAgentHome } = await import('./types-BbvxVQF3.mjs').then(function (n) { return n.al; });
|
|
5300
|
+
const homes = await resolveAgentHomesForCli();
|
|
5301
|
+
console.log(chalk.green(`\u2713 Claude config dir: ${describeAgentHome(homes.claudeConfigDir)}`));
|
|
5302
|
+
console.log(chalk.green(`\u2713 Codex home: ${describeAgentHome(homes.codexHome)}`));
|
|
5303
|
+
console.log(chalk.gray(" Resolved from settings.json, then your login shell, then the daemon environment; pin with `very-happy agent-home`."));
|
|
5304
|
+
} catch {
|
|
5305
|
+
console.log(chalk.yellow("\u25CB Could not resolve the Claude/Codex home directories"));
|
|
5306
|
+
}
|
|
5297
5307
|
if (availableAgents.length === 0) {
|
|
5298
5308
|
console.log(chalk.yellow("\u25CB No external agent command found on this daemon PATH"));
|
|
5299
5309
|
console.log(chalk.gray(" Codex, Gemini, OpenCode, OpenClaw, and native Claude terminal paths need their local command or gateway."));
|
|
@@ -10094,6 +10104,12 @@ async function startDaemon() {
|
|
|
10094
10104
|
let cliUpdateStateRef = null;
|
|
10095
10105
|
let lastHandoverHold = null;
|
|
10096
10106
|
let claudeCredentialStoreSetting = (await readSettings()).claudeCredentialStore === "file" ? "file" : "auto";
|
|
10107
|
+
try {
|
|
10108
|
+
const homes = await refreshAgentHomes();
|
|
10109
|
+
logger.debug(`[DAEMON RUN] Claude config dir: ${describeAgentHome(homes.claudeConfigDir)}; Codex home: ${describeAgentHome(homes.codexHome)}`);
|
|
10110
|
+
} catch (error) {
|
|
10111
|
+
logger.debug("[DAEMON RUN] agent home resolution failed; using the daemon environment as-is", error);
|
|
10112
|
+
}
|
|
10097
10113
|
let requestShutdown;
|
|
10098
10114
|
let resolvesWhenShutdownRequested = new Promise((resolve) => {
|
|
10099
10115
|
requestShutdown = (source, errorMessage) => {
|
|
@@ -10259,7 +10275,8 @@ async function startDaemon() {
|
|
|
10259
10275
|
}
|
|
10260
10276
|
};
|
|
10261
10277
|
const assistantSpawnGate = createSpawnGate();
|
|
10262
|
-
const spawnSession = (options) => {
|
|
10278
|
+
const spawnSession = async (options) => {
|
|
10279
|
+
await refreshAgentHomes();
|
|
10263
10280
|
if (assistantSpawnMode(options) !== "claude-singleton") {
|
|
10264
10281
|
return spawnSessionImpl(options);
|
|
10265
10282
|
}
|
|
@@ -10332,7 +10349,7 @@ async function startDaemon() {
|
|
|
10332
10349
|
s.encryptionVariant
|
|
10333
10350
|
);
|
|
10334
10351
|
const claudeSessionId = resolveAssistantClaudeSessionId(s.metadata, serverMetadata);
|
|
10335
|
-
const canResumeClaude = !!claudeSessionId &&
|
|
10352
|
+
const canResumeClaude = !!claudeSessionId && locateClaudeConversation(assistantHome(), claudeSessionId) !== null;
|
|
10336
10353
|
return spawnTrackedHappyProcess({
|
|
10337
10354
|
args: [
|
|
10338
10355
|
"claude",
|
|
@@ -10351,6 +10368,8 @@ async function startDaemon() {
|
|
|
10351
10368
|
// B-297: see the resume/restart paths — every spawn carries the
|
|
10352
10369
|
// credentialStore=file shim, not just fresh sessions (B-276 D8).
|
|
10353
10370
|
...claudeAuthServiceRef?.claudeProcessEnvOverrides() ?? {},
|
|
10371
|
+
// B-478: point Claude at the directory the transcript was found in.
|
|
10372
|
+
...canResumeClaude ? agentHomeSpawnEnv({ workingDirectory: assistantHome(), claudeSessionId }) : {},
|
|
10354
10373
|
HAPPY_SESSION_VARIANT: "assistant",
|
|
10355
10374
|
HAPPY_RECONNECT_SESSION_ID: assistantSessionId,
|
|
10356
10375
|
HAPPY_RECONNECT_ENCRYPTION_KEY: s.encryptionKey,
|
|
@@ -10505,6 +10524,7 @@ async function startDaemon() {
|
|
|
10505
10524
|
tmuxEnv[key] = value;
|
|
10506
10525
|
}
|
|
10507
10526
|
}
|
|
10527
|
+
Object.assign(tmuxEnv, agentHomeSpawnEnv({ workingDirectory: directory, claudeSessionId: options.resumeClaudeSessionId, codexThreadId: options.resumeCodexThreadId }));
|
|
10508
10528
|
Object.assign(tmuxEnv, extraEnv);
|
|
10509
10529
|
const tmuxResult = await tmux.spawnInTmux([fullCommand], {
|
|
10510
10530
|
sessionName: tmuxSessionName,
|
|
@@ -10599,6 +10619,9 @@ async function startDaemon() {
|
|
|
10599
10619
|
cwd: directory,
|
|
10600
10620
|
env: {
|
|
10601
10621
|
...process.env,
|
|
10622
|
+
// B-478: a fork/duplicate resumes a transcript that may live in
|
|
10623
|
+
// a moved config dir. Explicit environmentVariables still win.
|
|
10624
|
+
...agentHomeSpawnEnv({ workingDirectory: directory, claudeSessionId: options.resumeClaudeSessionId, codexThreadId: options.resumeCodexThreadId }),
|
|
10602
10625
|
...extraEnv
|
|
10603
10626
|
},
|
|
10604
10627
|
directoryCreated,
|
|
@@ -10749,6 +10772,7 @@ async function startDaemon() {
|
|
|
10749
10772
|
gate = createSpawnGate();
|
|
10750
10773
|
resumeGates.set(happySessionId, gate);
|
|
10751
10774
|
}
|
|
10775
|
+
await refreshAgentHomes();
|
|
10752
10776
|
try {
|
|
10753
10777
|
return await gate.join(() => resumeSessionImpl(happySessionId, options));
|
|
10754
10778
|
} finally {
|
|
@@ -10795,7 +10819,9 @@ async function startDaemon() {
|
|
|
10795
10819
|
}
|
|
10796
10820
|
const precheck = resumePrecheck(metadata, {
|
|
10797
10821
|
cwdExists: (p) => existsSync$1(p),
|
|
10798
|
-
|
|
10822
|
+
// B-478: also looks in every other Claude config dir the user's shell
|
|
10823
|
+
// or settings point at, not just the one the daemon was started with.
|
|
10824
|
+
conversationExists: (cwd, claudeSessionId) => locateClaudeConversation(cwd, claudeSessionId) !== null
|
|
10799
10825
|
});
|
|
10800
10826
|
let freshConversation = false;
|
|
10801
10827
|
if (!precheck.ok) {
|
|
@@ -10826,6 +10852,9 @@ async function startDaemon() {
|
|
|
10826
10852
|
// fell back to `auto` reads a different credential store than the
|
|
10827
10853
|
// fresh one next to it (B-276 D8).
|
|
10828
10854
|
...claudeAuthServiceRef?.claudeProcessEnvOverrides() ?? {},
|
|
10855
|
+
// B-478: if the transcript lives in a Claude/Codex home other than
|
|
10856
|
+
// the resolved one, this spawn is pointed there.
|
|
10857
|
+
...freshConversation ? {} : agentHomeSpawnEnv({ workingDirectory: launch.cwd, claudeSessionId: metadata.claudeSessionId, codexThreadId: metadata.codexThreadId }),
|
|
10829
10858
|
HAPPY_RECONNECT_SESSION_ID: happySessionId,
|
|
10830
10859
|
HAPPY_RECONNECT_ENCRYPTION_KEY: encodeBase64(tracked.encryption.encryptionKey),
|
|
10831
10860
|
HAPPY_RECONNECT_ENCRYPTION_VARIANT: tracked.encryption.encryptionVariant,
|
|
@@ -10887,6 +10916,7 @@ async function startDaemon() {
|
|
|
10887
10916
|
gate = createSpawnGate();
|
|
10888
10917
|
resumeGates.set(happySessionId, gate);
|
|
10889
10918
|
}
|
|
10919
|
+
await refreshAgentHomes();
|
|
10890
10920
|
try {
|
|
10891
10921
|
return await gate.replace(() => restartSessionImpl(happySessionId, options));
|
|
10892
10922
|
} finally {
|
|
@@ -10922,7 +10952,9 @@ async function startDaemon() {
|
|
|
10922
10952
|
}
|
|
10923
10953
|
const precheck = resumePrecheck(metadata, {
|
|
10924
10954
|
cwdExists: (p) => existsSync$1(p),
|
|
10925
|
-
|
|
10955
|
+
// B-478: also looks in every other Claude config dir the user's shell
|
|
10956
|
+
// or settings point at, not just the one the daemon was started with.
|
|
10957
|
+
conversationExists: (cwd2, claudeSessionId) => locateClaudeConversation(cwd2, claudeSessionId) !== null
|
|
10926
10958
|
});
|
|
10927
10959
|
let args;
|
|
10928
10960
|
let cwd;
|
|
@@ -10957,6 +10989,8 @@ async function startDaemon() {
|
|
|
10957
10989
|
// fell back to `auto` reads a different credential store than the
|
|
10958
10990
|
// fresh one next to it (B-276 D8).
|
|
10959
10991
|
...claudeAuthServiceRef?.claudeProcessEnvOverrides() ?? {},
|
|
10992
|
+
// B-478: see resumeSession.
|
|
10993
|
+
...precheck.ok ? agentHomeSpawnEnv({ workingDirectory: cwd, claudeSessionId: metadata.claudeSessionId, codexThreadId: metadata.codexThreadId }) : {},
|
|
10960
10994
|
HAPPY_RECONNECT_SESSION_ID: happySessionId,
|
|
10961
10995
|
HAPPY_RECONNECT_ENCRYPTION_KEY: encodeBase64(tracked.encryption.encryptionKey),
|
|
10962
10996
|
HAPPY_RECONNECT_ENCRYPTION_VARIANT: tracked.encryption.encryptionVariant,
|
|
@@ -12243,13 +12277,27 @@ function registerKillSessionHandler(rpcHandlerManager, killThisHappy, archiveEve
|
|
|
12243
12277
|
}
|
|
12244
12278
|
|
|
12245
12279
|
const SIDE_QUESTION_SYSTEM_PROMPT = [
|
|
12246
|
-
"
|
|
12247
|
-
"
|
|
12248
|
-
"Side questions cannot use tools: do not attempt to read files, run commands, or call tools \u2014 if",
|
|
12249
|
-
"the answer would require that, say what you would check and why.",
|
|
12250
|
-
"Do NOT continue, resume, or reference progress on the main task; the main conversation is",
|
|
12251
|
-
"unaffected by this exchange."
|
|
12280
|
+
"A user message wrapped in a side-question system-reminder is a SIDE QUESTION: answer it",
|
|
12281
|
+
"directly in one response from the conversation context, with no tools and no action on the main task."
|
|
12252
12282
|
].join(" ");
|
|
12283
|
+
const SIDE_QUESTION_REMINDER = [
|
|
12284
|
+
"<system-reminder>This is a side question from the user. You must answer this question directly in a single response.",
|
|
12285
|
+
"",
|
|
12286
|
+
"IMPORTANT CONTEXT:",
|
|
12287
|
+
"- You are a separate, lightweight agent spawned to answer this one question",
|
|
12288
|
+
"- The main agent is NOT interrupted - it continues working independently in the background",
|
|
12289
|
+
"- You share the conversation context but are a completely separate instance",
|
|
12290
|
+
'- Do NOT reference being interrupted or what you were "previously doing" - that framing is incorrect',
|
|
12291
|
+
"",
|
|
12292
|
+
"CRITICAL CONSTRAINTS:",
|
|
12293
|
+
"- You have NO tools available - you cannot read files, run commands, search, or take any actions",
|
|
12294
|
+
"- This is a one-off response - there will be no follow-up turns",
|
|
12295
|
+
"- You can ONLY provide information based on what you already know from the conversation context",
|
|
12296
|
+
`- NEVER say things like "Let me try...", "I'll now...", "Let me check...", or promise to take any action`,
|
|
12297
|
+
"- If you don't know the answer, say so - do not offer to look it up or investigate",
|
|
12298
|
+
"",
|
|
12299
|
+
"Simply answer the question with the information you have.</system-reminder>"
|
|
12300
|
+
].join("\n");
|
|
12253
12301
|
const MAX_HISTORY_CHARS = 2e3;
|
|
12254
12302
|
function clip(text, max) {
|
|
12255
12303
|
return text.length > max ? `${text.slice(0, max)}\u2026` : text;
|
|
@@ -12257,14 +12305,17 @@ function clip(text, max) {
|
|
|
12257
12305
|
function buildSideQuestionPrompt(question, history = []) {
|
|
12258
12306
|
const trimmed = question.trim();
|
|
12259
12307
|
const prior = history.filter((h) => h.question.trim() && h.answer.trim()).slice(-12);
|
|
12260
|
-
|
|
12308
|
+
const body = `${SIDE_QUESTION_REMINDER}
|
|
12309
|
+
|
|
12310
|
+
${trimmed}`;
|
|
12311
|
+
if (prior.length === 0) return body;
|
|
12261
12312
|
const lines = prior.map((h) => `Q: ${clip(h.question.trim(), MAX_HISTORY_CHARS)}
|
|
12262
12313
|
A: ${clip(h.answer.trim(), MAX_HISTORY_CHARS)}`);
|
|
12263
12314
|
return `<earlier-side-questions>
|
|
12264
12315
|
${lines.join("\n\n")}
|
|
12265
12316
|
</earlier-side-questions>
|
|
12266
12317
|
|
|
12267
|
-
${
|
|
12318
|
+
${body}`;
|
|
12268
12319
|
}
|
|
12269
12320
|
function sideQuestionQueryOptions(input) {
|
|
12270
12321
|
return {
|
|
@@ -12285,17 +12336,36 @@ function sideQuestionQueryOptions(input) {
|
|
|
12285
12336
|
abort: input.signal
|
|
12286
12337
|
};
|
|
12287
12338
|
}
|
|
12288
|
-
function
|
|
12289
|
-
if (message.type !== "assistant") return
|
|
12339
|
+
function assistantBlocks(message) {
|
|
12340
|
+
if (message.type !== "assistant") return [];
|
|
12290
12341
|
const content = message.message?.content;
|
|
12291
|
-
|
|
12292
|
-
|
|
12342
|
+
return Array.isArray(content) ? content.filter((b) => Boolean(b) && typeof b === "object") : [];
|
|
12343
|
+
}
|
|
12344
|
+
function textFromAssistant(message) {
|
|
12345
|
+
return assistantBlocks(message).map((block) => block.type === "text" ? String(block.text ?? "") : "").join("");
|
|
12346
|
+
}
|
|
12347
|
+
function toolUseFromAssistant(message) {
|
|
12348
|
+
const block = assistantBlocks(message).find((b) => b.type === "tool_use");
|
|
12349
|
+
return block ? String(block.name ?? "a tool") : null;
|
|
12350
|
+
}
|
|
12351
|
+
function toolAttemptNotice(toolName) {
|
|
12352
|
+
return `(The model tried to call ${toolName} instead of answering directly. Try rephrasing or ask in the main conversation.)`;
|
|
12353
|
+
}
|
|
12354
|
+
function apiErrorFromSystem(message) {
|
|
12355
|
+
if (message.type !== "system") return null;
|
|
12356
|
+
const m = message;
|
|
12357
|
+
if (m.subtype !== "api_error") return null;
|
|
12358
|
+
if (typeof m.error === "string") return m.error;
|
|
12359
|
+
const detail = m.error?.formatted ?? m.error?.message;
|
|
12360
|
+
return typeof detail === "string" && detail ? detail : "API error";
|
|
12293
12361
|
}
|
|
12294
12362
|
async function runSideQuestion(query, input) {
|
|
12295
12363
|
const options = sideQuestionQueryOptions(input);
|
|
12296
12364
|
const stream = query({ prompt: buildSideQuestionPrompt(input.question, input.history), options });
|
|
12297
12365
|
let streamed = "";
|
|
12298
12366
|
let final = "";
|
|
12367
|
+
let toolAttempt = null;
|
|
12368
|
+
let lastApiError = null;
|
|
12299
12369
|
let resultSeen = false;
|
|
12300
12370
|
for await (const message of stream) {
|
|
12301
12371
|
if (message.type === "stream_event") {
|
|
@@ -12314,20 +12384,31 @@ async function runSideQuestion(query, input) {
|
|
|
12314
12384
|
${text}` : text;
|
|
12315
12385
|
input.onText?.(final);
|
|
12316
12386
|
}
|
|
12387
|
+
toolAttempt ??= toolUseFromAssistant(message);
|
|
12388
|
+
continue;
|
|
12389
|
+
}
|
|
12390
|
+
if (message.type === "system") {
|
|
12391
|
+
lastApiError = apiErrorFromSystem(message) ?? lastApiError;
|
|
12317
12392
|
continue;
|
|
12318
12393
|
}
|
|
12319
12394
|
if (message.type === "result") {
|
|
12320
12395
|
resultSeen = true;
|
|
12321
12396
|
const result = message;
|
|
12322
12397
|
if (result.subtype !== "success") {
|
|
12323
|
-
|
|
12398
|
+
if (toolAttempt && result.subtype === "error_max_turns") break;
|
|
12399
|
+
const detail = Array.isArray(result.errors) && result.errors.length > 0 ? String(result.errors[0]) : typeof result.result === "string" && result.result ? result.result : lastApiError ?? result.subtype ?? "unknown";
|
|
12324
12400
|
throw new Error(`Side question failed: ${detail}`);
|
|
12325
12401
|
}
|
|
12326
12402
|
if (!final && typeof result.result === "string") final = result.result;
|
|
12327
12403
|
}
|
|
12328
12404
|
}
|
|
12329
12405
|
if (input.signal?.aborted) throw new Error("Side question cancelled");
|
|
12330
|
-
if (
|
|
12406
|
+
if (toolAttempt && !final.trim() && !streamed.trim()) {
|
|
12407
|
+
const notice = toolAttemptNotice(toolAttempt);
|
|
12408
|
+
input.onText?.(notice);
|
|
12409
|
+
return { answer: notice, hadContext: Boolean(input.resumeSessionId) };
|
|
12410
|
+
}
|
|
12411
|
+
if (!resultSeen && !final && !streamed) throw new Error(`Side question ended without a result${lastApiError ? `: ${lastApiError}` : ""}`);
|
|
12331
12412
|
return { answer: final || streamed, hadContext: Boolean(input.resumeSessionId) };
|
|
12332
12413
|
}
|
|
12333
12414
|
|
|
@@ -12354,7 +12435,7 @@ function registerSideQuestionHandler(rpc, deps) {
|
|
|
12354
12435
|
const retainMs = deps.retainMs ?? SIDE_QUESTION_RETAIN_MS;
|
|
12355
12436
|
const maxRunMs = deps.maxRunMs ?? SIDE_QUESTION_MAX_RUN_MS;
|
|
12356
12437
|
const run = deps.run ?? (async (input) => {
|
|
12357
|
-
const { query } = await import('./index-
|
|
12438
|
+
const { query } = await import('./index-CxK0l_t0.mjs');
|
|
12358
12439
|
return runSideQuestion(query, input);
|
|
12359
12440
|
});
|
|
12360
12441
|
const slots = /* @__PURE__ */ new Map();
|
|
@@ -12377,7 +12458,12 @@ function registerSideQuestionHandler(rpc, deps) {
|
|
|
12377
12458
|
if (!question) throw new Error("Side question is empty");
|
|
12378
12459
|
if (question.length > SIDE_QUESTION_MAX_CHARS) throw new Error("Side question is too long");
|
|
12379
12460
|
prune();
|
|
12380
|
-
if (active)
|
|
12461
|
+
if (active) {
|
|
12462
|
+
const stale = active;
|
|
12463
|
+
stale.abort.abort("superseded");
|
|
12464
|
+
finish(stale, "cancelled");
|
|
12465
|
+
logger.debug(`[btw] side question ${stale.requestId} superseded by a new ask`);
|
|
12466
|
+
}
|
|
12381
12467
|
const resumeSessionId = deps.getClaudeSessionId() ?? null;
|
|
12382
12468
|
const slot = {
|
|
12383
12469
|
requestId: randomUUID(),
|
|
@@ -17599,7 +17685,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17599
17685
|
return;
|
|
17600
17686
|
} else if (subcommand === "install-terminal-hooks") {
|
|
17601
17687
|
try {
|
|
17602
|
-
const { installTerminalHooks, parseTerminalHooksArgs, TERMINAL_HOOKS_HELP } = await import('./installTerminalHooks-
|
|
17688
|
+
const { installTerminalHooks, parseTerminalHooksArgs, TERMINAL_HOOKS_HELP } = await import('./installTerminalHooks-Dq1MFFDQ.mjs');
|
|
17603
17689
|
const command = parseTerminalHooksArgs(args.slice(1));
|
|
17604
17690
|
if (command.action === "help") {
|
|
17605
17691
|
console.log(TERMINAL_HOOKS_HELP);
|
|
@@ -17614,9 +17700,18 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17614
17700
|
}
|
|
17615
17701
|
process.exit(1);
|
|
17616
17702
|
}
|
|
17703
|
+
} else if (subcommand === "agent-home") {
|
|
17704
|
+
try {
|
|
17705
|
+
const { parseAgentHomeArgs, runAgentHomeCommand } = await import('./agentHome-DBqr8rpv.mjs');
|
|
17706
|
+
await runAgentHomeCommand(parseAgentHomeArgs(args.slice(1)));
|
|
17707
|
+
process.exit(0);
|
|
17708
|
+
} catch (error) {
|
|
17709
|
+
console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
|
|
17710
|
+
process.exit(1);
|
|
17711
|
+
}
|
|
17617
17712
|
} else if (subcommand === "spawn") {
|
|
17618
17713
|
try {
|
|
17619
|
-
const { handleSpawnCommand } = await import('./spawn-
|
|
17714
|
+
const { handleSpawnCommand } = await import('./spawn-Dcetf5Jt.mjs');
|
|
17620
17715
|
await handleSpawnCommand(args.slice(1));
|
|
17621
17716
|
} catch (error) {
|
|
17622
17717
|
console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
|
|
@@ -17628,7 +17723,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17628
17723
|
return;
|
|
17629
17724
|
} else if (subcommand === "sessions") {
|
|
17630
17725
|
try {
|
|
17631
|
-
const { handleSessionsCommand } = await import('./sessions-
|
|
17726
|
+
const { handleSessionsCommand } = await import('./sessions-CJUEp43_.mjs');
|
|
17632
17727
|
await handleSessionsCommand(args.slice(1));
|
|
17633
17728
|
} catch (error) {
|
|
17634
17729
|
console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
|
|
@@ -17640,7 +17735,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17640
17735
|
return;
|
|
17641
17736
|
} else if (subcommand === "send") {
|
|
17642
17737
|
try {
|
|
17643
|
-
const { handleSendCommand } = await import('./send-
|
|
17738
|
+
const { handleSendCommand } = await import('./send-CPayvXBm.mjs');
|
|
17644
17739
|
await handleSendCommand(args.slice(1));
|
|
17645
17740
|
} catch (error) {
|
|
17646
17741
|
console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
|
|
@@ -17746,9 +17841,9 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17746
17841
|
if (geminiSubcommand === "project" && args[2] === "set" && args[3]) {
|
|
17747
17842
|
const projectId = args[3];
|
|
17748
17843
|
try {
|
|
17749
|
-
const { saveGoogleCloudProjectToConfig } = await import('./config-
|
|
17750
|
-
const { readCredentialsForConfiguredRelay: readCredentialsForConfiguredRelay2 } = await import('./limits-
|
|
17751
|
-
const { ApiClient: ApiClient2 } = await import('./types-
|
|
17844
|
+
const { saveGoogleCloudProjectToConfig } = await import('./config-B9zAvnGT.mjs');
|
|
17845
|
+
const { readCredentialsForConfiguredRelay: readCredentialsForConfiguredRelay2 } = await import('./limits-CzWD9hWU.mjs').then(function (n) { return n.Y; });
|
|
17846
|
+
const { ApiClient: ApiClient2 } = await import('./types-BbvxVQF3.mjs').then(function (n) { return n.am; });
|
|
17752
17847
|
let userEmail = void 0;
|
|
17753
17848
|
try {
|
|
17754
17849
|
const credentials = await readCredentialsForConfiguredRelay2();
|
|
@@ -17779,7 +17874,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17779
17874
|
}
|
|
17780
17875
|
if (geminiSubcommand === "project" && args[2] === "get") {
|
|
17781
17876
|
try {
|
|
17782
|
-
const { readGeminiLocalConfig } = await import('./config-
|
|
17877
|
+
const { readGeminiLocalConfig } = await import('./config-B9zAvnGT.mjs');
|
|
17783
17878
|
const config = readGeminiLocalConfig();
|
|
17784
17879
|
if (config.googleCloudProject) {
|
|
17785
17880
|
console.log(`Current Google Cloud Project: ${config.googleCloudProject}`);
|
|
@@ -17819,7 +17914,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17819
17914
|
process.exit(0);
|
|
17820
17915
|
}
|
|
17821
17916
|
try {
|
|
17822
|
-
const { runGemini } = await import('./runGemini-
|
|
17917
|
+
const { runGemini } = await import('./runGemini-B-It6K8t.mjs');
|
|
17823
17918
|
let startedBy = void 0;
|
|
17824
17919
|
for (let i = 1; i < args.length; i++) {
|
|
17825
17920
|
if (args[i] === "--started-by") {
|
|
@@ -17842,7 +17937,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17842
17937
|
} else if (subcommand === "pi") {
|
|
17843
17938
|
if (args[1] === "--terminal") {
|
|
17844
17939
|
try {
|
|
17845
|
-
const { runPiTerminal } = await import('./piTerminal-
|
|
17940
|
+
const { runPiTerminal } = await import('./piTerminal-BIRroC_N.mjs');
|
|
17846
17941
|
process.exitCode = await runPiTerminal(args.slice(2));
|
|
17847
17942
|
} catch (error) {
|
|
17848
17943
|
console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
|
|
@@ -17859,7 +17954,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17859
17954
|
}
|
|
17860
17955
|
};
|
|
17861
17956
|
try {
|
|
17862
|
-
const { runAcp, resolveAcpAgentConfig } = await import('./index-
|
|
17957
|
+
const { runAcp, resolveAcpAgentConfig } = await import('./index-BzLZu_aF.mjs');
|
|
17863
17958
|
const parsed = parsePiRunnerArgs(args.slice(1));
|
|
17864
17959
|
const resolved = resolveAcpAgentConfig(["pi", ...parsed.passthrough]);
|
|
17865
17960
|
const { credentials } = await authAndSetupMachineIfNeeded();
|
|
@@ -17887,7 +17982,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17887
17982
|
return;
|
|
17888
17983
|
} else if (subcommand === "acp") {
|
|
17889
17984
|
try {
|
|
17890
|
-
const { runAcp, resolveAcpAgentConfig } = await import('./index-
|
|
17985
|
+
const { runAcp, resolveAcpAgentConfig } = await import('./index-BzLZu_aF.mjs');
|
|
17891
17986
|
let startedBy = void 0;
|
|
17892
17987
|
let verbose = false;
|
|
17893
17988
|
const acpArgs = [];
|
|
@@ -17927,7 +18022,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17927
18022
|
return;
|
|
17928
18023
|
} else if (subcommand === "openclaw") {
|
|
17929
18024
|
try {
|
|
17930
|
-
const { runOpenClaw } = await import('./runOpenClaw-
|
|
18025
|
+
const { runOpenClaw } = await import('./runOpenClaw-DET6LY2v.mjs');
|
|
17931
18026
|
let startedBy = void 0;
|
|
17932
18027
|
let verbose = false;
|
|
17933
18028
|
let gatewayUrl;
|
|
@@ -17978,7 +18073,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17978
18073
|
return;
|
|
17979
18074
|
} else if (subcommand === "todo") {
|
|
17980
18075
|
try {
|
|
17981
|
-
const { handleTodoCommand } = await import('./todo-
|
|
18076
|
+
const { handleTodoCommand } = await import('./todo-CV5fwHg_.mjs');
|
|
17982
18077
|
await handleTodoCommand(args.slice(1));
|
|
17983
18078
|
} catch (error) {
|
|
17984
18079
|
console.error(JSON.stringify({ error: error instanceof Error ? error.message : "Todo command failed" }));
|
|
@@ -17987,7 +18082,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17987
18082
|
return;
|
|
17988
18083
|
} else if (subcommand === "teams") {
|
|
17989
18084
|
try {
|
|
17990
|
-
const { handleTeamsCommand } = await import('./teams-
|
|
18085
|
+
const { handleTeamsCommand } = await import('./teams-CW_Zb2Q1.mjs');
|
|
17991
18086
|
await handleTeamsCommand(args.slice(1));
|
|
17992
18087
|
} catch (error) {
|
|
17993
18088
|
console.error(error instanceof Error ? error.message : "Teams command failed");
|
|
@@ -17996,7 +18091,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17996
18091
|
return;
|
|
17997
18092
|
} else if (subcommand === "mcp" && (args.length === 1 || args.length === 2 && args[1] === "--terminal-tools")) {
|
|
17998
18093
|
try {
|
|
17999
|
-
const { handleMcpCommand } = await import('./mcp-
|
|
18094
|
+
const { handleMcpCommand } = await import('./mcp-L1Yq25LB.mjs');
|
|
18000
18095
|
await handleMcpCommand(args[1] === "--terminal-tools");
|
|
18001
18096
|
} catch (error) {
|
|
18002
18097
|
process.stderr.write(`[very-happy mcp] Fatal: ${error instanceof Error ? error.message : String(error)}
|
|
@@ -18226,6 +18321,8 @@ ${chalk.bold("Usage:")}
|
|
|
18226
18321
|
very-happy install-terminal-hooks
|
|
18227
18322
|
Install optional Claude terminal mirror hooks
|
|
18228
18323
|
(add --remove to uninstall them)
|
|
18324
|
+
very-happy agent-home Show or pin where Claude Code / Codex keep their
|
|
18325
|
+
conversations on this machine (agent-home --help)
|
|
18229
18326
|
very-happy connect Connect AI vendor API keys
|
|
18230
18327
|
very-happy todo Built-in Todos and official agent skill (todo --help)
|
|
18231
18328
|
very-happy sandbox Configure and manage OS-level sandboxing
|