very-happy-cli 0.2.77 → 0.2.79
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-CsLnh1So.cjs → AcpBackend-BuxJntPo.cjs} +1 -1
- package/dist/{AcpBackend-BFFC77vV.mjs → AcpBackend-DPcRh_3n.mjs} +1 -1
- package/dist/{AcpSessionManager--CixPN-p.cjs → AcpSessionManager-BOZPQZUQ.cjs} +1 -1
- package/dist/{AcpSessionManager-CU5vsxgF.mjs → AcpSessionManager-DVGWPtBC.mjs} +1 -1
- package/dist/{config-pv17N6Kg.cjs → config-DB0v5eoc.cjs} +2 -2
- package/dist/{config-CRFTYuTN.mjs → config-T7eM_8eT.mjs} +2 -2
- package/dist/{index-Dcv1RKe8.cjs → index-BGvGqzc1.cjs} +252 -73
- package/dist/{index-BkvUwyIU.mjs → index-CuLe9SB7.mjs} +5 -5
- package/dist/{index-C1OnwMx0.cjs → index-D_ZjCYNI.cjs} +4 -4
- package/dist/{index-DOb57EGb.mjs → index-HYOkniru.mjs} +249 -70
- package/dist/index.cjs +2 -2
- package/dist/index.mjs +2 -2
- package/dist/{installTerminalHooks-YyT3fv6w.cjs → installTerminalHooks-CAViJyYh.cjs} +2 -2
- package/dist/{installTerminalHooks-IXvZMGJq.mjs → installTerminalHooks-CPKThY28.mjs} +2 -2
- package/dist/lib.cjs +1 -1
- package/dist/lib.d.cts +11 -2
- package/dist/lib.d.mts +11 -2
- package/dist/lib.mjs +1 -1
- package/dist/{mcp-CsKnmeE5.cjs → mcp-DhQcmKO7.cjs} +2 -2
- package/dist/{mcp-B-GdhlKD.mjs → mcp-DhUA22wj.mjs} +2 -2
- package/dist/{runGemini-D0lddF43.mjs → runGemini-BVxviS8T.mjs} +4 -4
- package/dist/{runGemini-DuUdmlVZ.cjs → runGemini-CfWCL9K7.cjs} +4 -4
- package/dist/{runOpenClaw-BiwwYnYf.mjs → runOpenClaw-DVTaZJtj.mjs} +3 -3
- package/dist/{runOpenClaw-DEMCYSoD.cjs → runOpenClaw-kSy7Os3C.cjs} +3 -3
- package/dist/{send-DM8oqJFp.mjs → send-DjjJQXJt.mjs} +2 -2
- package/dist/{send-DijSXAMp.cjs → send-jzwPToBN.cjs} +2 -2
- package/dist/{spawn-nISXbZD5.mjs → spawn-DBpgsEkS.mjs} +2 -2
- package/dist/{spawn-De3b5Hsu.cjs → spawn-DFnYIiKP.cjs} +2 -2
- package/dist/{types-D2qSKjsO.mjs → types-BRDN6zN2.mjs} +92 -14
- package/dist/{types-NwtcBgfS.cjs → types-Dy7P_1bh.cjs} +93 -15
- package/package.json +7 -7
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var AcpBackend = require('./AcpBackend-
|
|
4
|
-
var persistence = require('./types-
|
|
5
|
-
var AcpSessionManager = require('./AcpSessionManager
|
|
3
|
+
var AcpBackend = require('./AcpBackend-BuxJntPo.cjs');
|
|
4
|
+
var persistence = require('./types-Dy7P_1bh.cjs');
|
|
5
|
+
var AcpSessionManager = require('./AcpSessionManager-BOZPQZUQ.cjs');
|
|
6
6
|
var node_crypto = require('node:crypto');
|
|
7
7
|
var path = require('node:path');
|
|
8
|
-
var index = require('./index-
|
|
8
|
+
var index = require('./index-BGvGqzc1.cjs');
|
|
9
9
|
require('node:child_process');
|
|
10
10
|
require('@agentclientprotocol/sdk');
|
|
11
11
|
require('axios');
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import{createRequire as _pkgrollCR}from"node:module";const require=_pkgrollCR(import.meta.url);import chalk from 'chalk';
|
|
2
2
|
import os, { homedir } from 'node:os';
|
|
3
3
|
import { randomUUID, randomBytes, createHash as createHash$1, timingSafeEqual } from 'node:crypto';
|
|
4
|
-
import { n as readDaemonState, l as logger, c as configuration, o as clearDaemonState, q as getProjectPath, p as projectPath, s as initializeSandbox, t as wrapCommand, d as contentLogMetadata, I as InvalidateSync, R as RawJSONLinesSchema, g as delay, u as AsyncLock, f as packageJson, i as readSettings, v as readCredentials, x as credentialRelayProblem, y as deriveLocalCliUpdateSummary, j as encodeBase64, z as updateSettings, B as encodeBase64Url, C as decodeBase64, D as writeCredentialsLegacy, E as writeCredentialsDataKey, F as readCredentialsForConfiguredRelay, G as encrypt, r as readPersistedSessions, H as getLocalHappyAgentCredentialPath, J as readLocalHappyAgentCredentials, K as decryptWithDataKey, L as decryptLegacy, M as extractCompleteLines, N as decideBackfill, O as parseTerminalHookPayload, P as decideMirrorBinding, Q as persistSession, S as MIRROR_BACKFILL_LINES_DEFAULT, T as mirrorLineKey, U as mirrorLocalId, V as detectResumeSupport, W as detectCLIAvailability, X as acquireDaemonLock, Y as summarizeSpawnSessionForLog, Z as deletePersistedSessions, _ as decrypt, $ as writeDaemonState, A as ApiClient, a0 as fetchCliUpdateState, a1 as resolveCliUpdateCheckInterval, a2 as DEFAULT_CLI_UPDATE_CHECK_INTERVAL_MS, a3 as releaseDaemonLock, a4 as isValidSessionId, a5 as listVhTerminals, a6 as isValidTerminalId, a7 as readVhTerminal, a8 as sendToVhTerminal, h as connectionState, a9 as startOfflineReconnection, aa as clearCredentials, ab as clearMachineId, k as ensurePrivateDirectorySync, w as writePrivateFileSync, ac as SandboxConfigSchema, b as createEnvelope, ad as CodexAppServerClient, ae as getLatestDaemonLog } from './types-
|
|
4
|
+
import { n as readDaemonState, l as logger, c as configuration, o as clearDaemonState, q as getProjectPath, p as projectPath, s as initializeSandbox, t as wrapCommand, d as contentLogMetadata, I as InvalidateSync, R as RawJSONLinesSchema, g as delay, u as AsyncLock, f as packageJson, i as readSettings, v as readCredentials, x as credentialRelayProblem, y as deriveLocalCliUpdateSummary, j as encodeBase64, z as updateSettings, B as encodeBase64Url, C as decodeBase64, D as writeCredentialsLegacy, E as writeCredentialsDataKey, F as readCredentialsForConfiguredRelay, G as encrypt, r as readPersistedSessions, H as getLocalHappyAgentCredentialPath, J as readLocalHappyAgentCredentials, K as decryptWithDataKey, L as decryptLegacy, M as extractCompleteLines, N as decideBackfill, O as parseTerminalHookPayload, P as decideMirrorBinding, Q as persistSession, S as MIRROR_BACKFILL_LINES_DEFAULT, T as mirrorLineKey, U as mirrorLocalId, V as detectResumeSupport, W as detectCLIAvailability, X as acquireDaemonLock, Y as summarizeSpawnSessionForLog, Z as deletePersistedSessions, _ as decrypt, $ as writeDaemonState, A as ApiClient, a0 as fetchCliUpdateState, a1 as resolveCliUpdateCheckInterval, a2 as DEFAULT_CLI_UPDATE_CHECK_INTERVAL_MS, a3 as releaseDaemonLock, a4 as isValidSessionId, a5 as listVhTerminals, a6 as isValidTerminalId, a7 as readVhTerminal, a8 as sendToVhTerminal, h as connectionState, a9 as startOfflineReconnection, aa as clearCredentials, ab as clearMachineId, k as ensurePrivateDirectorySync, w as writePrivateFileSync, ac as SandboxConfigSchema, b as createEnvelope, ad as CodexAppServerClient, ae as getLatestDaemonLog } from './types-BRDN6zN2.mjs';
|
|
5
5
|
import spawn$1, { spawn } from 'cross-spawn';
|
|
6
6
|
import path, { join, resolve, isAbsolute, normalize, sep, dirname } from 'node:path';
|
|
7
7
|
import { createInterface } from 'node:readline';
|
|
@@ -1489,6 +1489,7 @@ function query(params) {
|
|
|
1489
1489
|
fallbackModel: opts?.fallbackModel,
|
|
1490
1490
|
maxTurns: opts?.maxTurns,
|
|
1491
1491
|
permissionMode: opts?.permissionMode,
|
|
1492
|
+
allowDangerouslySkipPermissions: opts?.permissionMode === "bypassPermissions",
|
|
1492
1493
|
allowedTools: opts?.allowedTools,
|
|
1493
1494
|
disallowedTools: opts?.disallowedTools,
|
|
1494
1495
|
mcpServers: opts?.mcpServers,
|
|
@@ -1507,11 +1508,18 @@ function query(params) {
|
|
|
1507
1508
|
settingSources: ["user", "project", "local"],
|
|
1508
1509
|
strictMcpConfig: opts?.strictMcpConfig,
|
|
1509
1510
|
sessionId: void 0,
|
|
1510
|
-
effort: opts?.effort
|
|
1511
|
+
effort: opts?.effort,
|
|
1512
|
+
onElicitation: opts?.onElicitation,
|
|
1513
|
+
onUserDialog: opts?.onUserDialog,
|
|
1514
|
+
supportedDialogKinds: opts?.onUserDialog ? opts.supportedDialogKinds : void 0
|
|
1511
1515
|
};
|
|
1512
1516
|
if (opts?.abort) {
|
|
1513
1517
|
const controller = new AbortController();
|
|
1514
|
-
opts.abort.
|
|
1518
|
+
if (opts.abort.aborted) {
|
|
1519
|
+
controller.abort(opts.abort.reason);
|
|
1520
|
+
} else {
|
|
1521
|
+
opts.abort.addEventListener("abort", () => controller.abort(opts.abort?.reason), { once: true });
|
|
1522
|
+
}
|
|
1515
1523
|
sdkOptions.abortController = controller;
|
|
1516
1524
|
}
|
|
1517
1525
|
const env = {};
|
|
@@ -1864,6 +1872,9 @@ async function claudeRemote(opts) {
|
|
|
1864
1872
|
disallowedTools: initial.mode.disallowedTools,
|
|
1865
1873
|
effort: initial.mode.effort,
|
|
1866
1874
|
canCallTool: (toolName, input, options) => opts.canCallTool(toolName, input, mode, options),
|
|
1875
|
+
onElicitation: opts.onElicitation,
|
|
1876
|
+
onUserDialog: opts.onUserDialog,
|
|
1877
|
+
supportedDialogKinds: opts.onUserDialog ? ["refusal_fallback_prompt"] : void 0,
|
|
1867
1878
|
abort: opts.signal,
|
|
1868
1879
|
settingsPath: opts.hookSettingsPath
|
|
1869
1880
|
};
|
|
@@ -1929,13 +1940,14 @@ async function claudeRemote(opts) {
|
|
|
1929
1940
|
updateThinking(false);
|
|
1930
1941
|
logger.debug("[claudeRemote] Result received");
|
|
1931
1942
|
if (isCompactCommand) {
|
|
1932
|
-
|
|
1943
|
+
const compactSucceeded = message.subtype === "success";
|
|
1944
|
+
logger.debug(`[claudeRemote] Compaction ${compactSucceeded ? "completed" : "failed"}`);
|
|
1933
1945
|
if (opts.onCompletionEvent) {
|
|
1934
|
-
opts.onCompletionEvent("Compaction completed");
|
|
1946
|
+
opts.onCompletionEvent(message.subtype === "success" ? "Compaction completed" : `Compaction failed: ${message.errors?.join("\n") || message.subtype}`);
|
|
1935
1947
|
}
|
|
1936
1948
|
isCompactCommand = false;
|
|
1937
1949
|
}
|
|
1938
|
-
opts.onReady();
|
|
1950
|
+
opts.onReady(message);
|
|
1939
1951
|
opts.nextMessage().then((next) => {
|
|
1940
1952
|
if (!next) {
|
|
1941
1953
|
messages.end();
|
|
@@ -1983,6 +1995,16 @@ function getToolDescriptor(toolName) {
|
|
|
1983
1995
|
return { edit: false, exitPlan: false, dangerous: false };
|
|
1984
1996
|
}
|
|
1985
1997
|
|
|
1998
|
+
function elicitationContent(input) {
|
|
1999
|
+
if (!input) return void 0;
|
|
2000
|
+
const content = {};
|
|
2001
|
+
for (const [key, value] of Object.entries(input)) {
|
|
2002
|
+
if (typeof value === "string" || typeof value === "number" && Number.isFinite(value) || typeof value === "boolean" || Array.isArray(value) && value.every((item) => typeof item === "string")) {
|
|
2003
|
+
content[key] = value;
|
|
2004
|
+
}
|
|
2005
|
+
}
|
|
2006
|
+
return content;
|
|
2007
|
+
}
|
|
1986
2008
|
class PermissionHandler {
|
|
1987
2009
|
responses = /* @__PURE__ */ new Map();
|
|
1988
2010
|
pendingRequests = /* @__PURE__ */ new Map();
|
|
@@ -2017,19 +2039,7 @@ class PermissionHandler {
|
|
|
2017
2039
|
/**
|
|
2018
2040
|
* Handler response
|
|
2019
2041
|
*/
|
|
2020
|
-
handlePermissionResponse(response, pending) {
|
|
2021
|
-
if (response.allowTools && response.allowTools.length > 0) {
|
|
2022
|
-
response.allowTools.forEach((tool) => {
|
|
2023
|
-
if (tool.startsWith("Bash(") || tool === "Bash") {
|
|
2024
|
-
this.parseBashPermission(tool);
|
|
2025
|
-
} else {
|
|
2026
|
-
this.allowedTools.add(tool);
|
|
2027
|
-
}
|
|
2028
|
-
});
|
|
2029
|
-
}
|
|
2030
|
-
if (response.mode) {
|
|
2031
|
-
this.permissionMode = response.mode;
|
|
2032
|
-
}
|
|
2042
|
+
async handlePermissionResponse(response, pending) {
|
|
2033
2043
|
if (pending.toolName === "exit_plan_mode" || pending.toolName === "ExitPlanMode") {
|
|
2034
2044
|
logger.debug("Plan mode result received", {
|
|
2035
2045
|
approved: response.approved,
|
|
@@ -2041,10 +2051,14 @@ class PermissionHandler {
|
|
|
2041
2051
|
if (response.approved) {
|
|
2042
2052
|
const newMode = response.mode && ["default", "acceptEdits", "bypassPermissions"].includes(response.mode) ? response.mode : "default";
|
|
2043
2053
|
logger.debug(`Plan approved - switching to ${newMode} mode and allowing ExitPlanMode`);
|
|
2044
|
-
|
|
2045
|
-
this.setPermissionModeCallback
|
|
2046
|
-
|
|
2047
|
-
|
|
2054
|
+
try {
|
|
2055
|
+
if (!this.setPermissionModeCallback) throw new Error("permission mode updater unavailable");
|
|
2056
|
+
await this.setPermissionModeCallback(newMode);
|
|
2057
|
+
} catch (err) {
|
|
2058
|
+
const reason = `Failed to switch permission mode: ${err instanceof Error ? err.message : String(err)}`;
|
|
2059
|
+
logger.debug(reason);
|
|
2060
|
+
pending.resolve({ behavior: "deny", message: reason });
|
|
2061
|
+
return { ...response, approved: false, reason };
|
|
2048
2062
|
}
|
|
2049
2063
|
this.permissionMode = newMode;
|
|
2050
2064
|
pending.resolve({ behavior: "allow", updatedInput: pending.input || {} });
|
|
@@ -2052,11 +2066,36 @@ class PermissionHandler {
|
|
|
2052
2066
|
pending.resolve({ behavior: "deny", message: response.reason || "Plan rejected" });
|
|
2053
2067
|
}
|
|
2054
2068
|
} else {
|
|
2069
|
+
if (response.approved && response.mode) {
|
|
2070
|
+
try {
|
|
2071
|
+
if (!this.setPermissionModeCallback) throw new Error("permission mode updater unavailable");
|
|
2072
|
+
await this.setPermissionModeCallback(response.mode);
|
|
2073
|
+
this.permissionMode = response.mode;
|
|
2074
|
+
} catch (err) {
|
|
2075
|
+
const reason = `Failed to switch permission mode: ${err instanceof Error ? err.message : String(err)}`;
|
|
2076
|
+
pending.resolve({ behavior: "deny", message: reason });
|
|
2077
|
+
return { ...response, approved: false, reason };
|
|
2078
|
+
}
|
|
2079
|
+
}
|
|
2080
|
+
if (response.approved && !pending.suggestions?.length && response.allowTools?.length) {
|
|
2081
|
+
response.allowTools.forEach((tool) => {
|
|
2082
|
+
if (tool.startsWith("Bash(") || tool === "Bash") {
|
|
2083
|
+
this.parseBashPermission(tool);
|
|
2084
|
+
} else {
|
|
2085
|
+
this.allowedTools.add(tool);
|
|
2086
|
+
}
|
|
2087
|
+
});
|
|
2088
|
+
}
|
|
2055
2089
|
const originalInput = pending.input || {};
|
|
2056
2090
|
const updatedInput = response.updatedInput ? { ...originalInput, ...response.updatedInput } : originalInput;
|
|
2057
|
-
const result = response.approved ? {
|
|
2091
|
+
const result = response.approved ? {
|
|
2092
|
+
behavior: "allow",
|
|
2093
|
+
updatedInput,
|
|
2094
|
+
...response.decision === "approved_for_session" && pending.suggestions?.length ? { updatedPermissions: pending.suggestions } : {}
|
|
2095
|
+
} : { behavior: "deny", message: response.reason || `The user doesn't want to proceed with this tool use. The tool use was rejected (eg. if it was a file edit, the new_string was NOT written to the file). STOP what you are doing and wait for the user to tell you how to proceed.` };
|
|
2058
2096
|
pending.resolve(result);
|
|
2059
2097
|
}
|
|
2098
|
+
return response;
|
|
2060
2099
|
}
|
|
2061
2100
|
/**
|
|
2062
2101
|
* Creates the canCallTool callback for the SDK.
|
|
@@ -2065,7 +2104,7 @@ class PermissionHandler {
|
|
|
2065
2104
|
handleToolCall = async (toolName, input, mode, options) => {
|
|
2066
2105
|
const toolCallId = options.toolUseID;
|
|
2067
2106
|
if (toolName === "AskUserQuestion") {
|
|
2068
|
-
return this.handlePermissionRequest(toolCallId, toolName, input, options.signal);
|
|
2107
|
+
return this.handlePermissionRequest(toolCallId, toolName, input, options.signal, options.suggestions);
|
|
2069
2108
|
}
|
|
2070
2109
|
if (toolName === "Bash") {
|
|
2071
2110
|
const inputObj = input;
|
|
@@ -2084,7 +2123,7 @@ class PermissionHandler {
|
|
|
2084
2123
|
}
|
|
2085
2124
|
const descriptor = getToolDescriptor(toolName);
|
|
2086
2125
|
if (descriptor.exitPlan) {
|
|
2087
|
-
return this.handlePermissionRequest(toolCallId, toolName, input, options.signal);
|
|
2126
|
+
return this.handlePermissionRequest(toolCallId, toolName, input, options.signal, options.suggestions);
|
|
2088
2127
|
}
|
|
2089
2128
|
if (this.permissionMode === "bypassPermissions") {
|
|
2090
2129
|
return { behavior: "allow", updatedInput: input };
|
|
@@ -2095,19 +2134,25 @@ class PermissionHandler {
|
|
|
2095
2134
|
if (this.permissionMode === "plan" && !descriptor.dangerous) {
|
|
2096
2135
|
return { behavior: "allow", updatedInput: input };
|
|
2097
2136
|
}
|
|
2098
|
-
return this.handlePermissionRequest(toolCallId, toolName, input, options.signal);
|
|
2137
|
+
return this.handlePermissionRequest(toolCallId, toolName, input, options.signal, options.suggestions);
|
|
2099
2138
|
};
|
|
2100
2139
|
/**
|
|
2101
2140
|
* Handles individual permission requests
|
|
2102
2141
|
*/
|
|
2103
|
-
async handlePermissionRequest(id, toolName, input, signal) {
|
|
2142
|
+
async handlePermissionRequest(id, toolName, input, signal, suggestions) {
|
|
2104
2143
|
return new Promise((resolve, reject) => {
|
|
2144
|
+
if (signal.aborted) {
|
|
2145
|
+
reject(new Error("Permission request aborted", { cause: signal.reason }));
|
|
2146
|
+
return;
|
|
2147
|
+
}
|
|
2105
2148
|
const abortHandler = () => {
|
|
2106
2149
|
this.pendingRequests.delete(id);
|
|
2150
|
+
this.cancelRequestInAgentState(id, "Permission request aborted");
|
|
2107
2151
|
reject(new Error("Permission request aborted"));
|
|
2108
2152
|
};
|
|
2109
2153
|
signal.addEventListener("abort", abortHandler, { once: true });
|
|
2110
2154
|
this.pendingRequests.set(id, {
|
|
2155
|
+
kind: "tool",
|
|
2111
2156
|
resolve: (result) => {
|
|
2112
2157
|
signal.removeEventListener("abort", abortHandler);
|
|
2113
2158
|
resolve(result);
|
|
@@ -2117,7 +2162,8 @@ class PermissionHandler {
|
|
|
2117
2162
|
reject(error);
|
|
2118
2163
|
},
|
|
2119
2164
|
toolName,
|
|
2120
|
-
input
|
|
2165
|
+
input,
|
|
2166
|
+
suggestions
|
|
2121
2167
|
});
|
|
2122
2168
|
if (this.onPermissionRequestCallback) {
|
|
2123
2169
|
this.onPermissionRequestCallback(id);
|
|
@@ -2140,7 +2186,9 @@ class PermissionHandler {
|
|
|
2140
2186
|
[id]: {
|
|
2141
2187
|
tool: toolName,
|
|
2142
2188
|
arguments: input,
|
|
2143
|
-
createdAt: Date.now()
|
|
2189
|
+
createdAt: Date.now(),
|
|
2190
|
+
kind: "tool",
|
|
2191
|
+
...suggestions?.length ? { permissionSuggestions: suggestions } : {}
|
|
2144
2192
|
}
|
|
2145
2193
|
}
|
|
2146
2194
|
}));
|
|
@@ -2149,6 +2197,98 @@ class PermissionHandler {
|
|
|
2149
2197
|
logger.debug(`Permission request sent for tool call ${id}: ${toolName}`);
|
|
2150
2198
|
});
|
|
2151
2199
|
}
|
|
2200
|
+
handleElicitation = async (request, options) => {
|
|
2201
|
+
return this.handleInteractionRequest(options.requestId, "elicitation", request, options.signal);
|
|
2202
|
+
};
|
|
2203
|
+
handleUserDialog = async (request, options) => {
|
|
2204
|
+
if (request.dialogKind !== "refusal_fallback_prompt") {
|
|
2205
|
+
return { behavior: "cancelled" };
|
|
2206
|
+
}
|
|
2207
|
+
return this.handleInteractionRequest(options.requestId, "user_dialog", request, options.signal);
|
|
2208
|
+
};
|
|
2209
|
+
handleInteractionRequest(id, kind, request, signal) {
|
|
2210
|
+
return new Promise((resolve, reject) => {
|
|
2211
|
+
if (signal.aborted) {
|
|
2212
|
+
reject(new Error("Interaction request aborted", { cause: signal.reason }));
|
|
2213
|
+
return;
|
|
2214
|
+
}
|
|
2215
|
+
const abortHandler = () => {
|
|
2216
|
+
this.pendingRequests.delete(id);
|
|
2217
|
+
this.cancelRequestInAgentState(id, "Interaction request aborted");
|
|
2218
|
+
reject(new Error("Interaction request aborted", { cause: signal.reason }));
|
|
2219
|
+
};
|
|
2220
|
+
signal.addEventListener("abort", abortHandler, { once: true });
|
|
2221
|
+
const finishResolve = (value) => {
|
|
2222
|
+
signal.removeEventListener("abort", abortHandler);
|
|
2223
|
+
resolve(value);
|
|
2224
|
+
};
|
|
2225
|
+
const finishReject = (error) => {
|
|
2226
|
+
signal.removeEventListener("abort", abortHandler);
|
|
2227
|
+
reject(error);
|
|
2228
|
+
};
|
|
2229
|
+
if (kind === "elicitation") {
|
|
2230
|
+
this.pendingRequests.set(id, {
|
|
2231
|
+
kind,
|
|
2232
|
+
request,
|
|
2233
|
+
resolve: finishResolve,
|
|
2234
|
+
reject: finishReject
|
|
2235
|
+
});
|
|
2236
|
+
} else {
|
|
2237
|
+
this.pendingRequests.set(id, {
|
|
2238
|
+
kind,
|
|
2239
|
+
request,
|
|
2240
|
+
resolve: finishResolve,
|
|
2241
|
+
reject: finishReject
|
|
2242
|
+
});
|
|
2243
|
+
}
|
|
2244
|
+
const tool = "AskUserQuestion";
|
|
2245
|
+
this.publishRequest(id, tool, request, kind);
|
|
2246
|
+
});
|
|
2247
|
+
}
|
|
2248
|
+
publishRequest(id, tool, args, kind) {
|
|
2249
|
+
this.session.api.push().sendSessionNotification({
|
|
2250
|
+
kind: "permission",
|
|
2251
|
+
metadata: this.session.client.getMetadata(),
|
|
2252
|
+
data: {
|
|
2253
|
+
sessionId: this.session.client.sessionId,
|
|
2254
|
+
requestId: id,
|
|
2255
|
+
tool,
|
|
2256
|
+
type: "permission_request",
|
|
2257
|
+
provider: "claude"
|
|
2258
|
+
}
|
|
2259
|
+
});
|
|
2260
|
+
this.session.client.updateAgentState((currentState) => ({
|
|
2261
|
+
...currentState,
|
|
2262
|
+
requests: {
|
|
2263
|
+
...currentState.requests,
|
|
2264
|
+
[id]: { tool, arguments: args, createdAt: Date.now(), kind }
|
|
2265
|
+
}
|
|
2266
|
+
}));
|
|
2267
|
+
this.session.notificationProducer?.permissionRequest(tool);
|
|
2268
|
+
this.session.reportEventToDaemon("needs_input");
|
|
2269
|
+
logger.debug(`${kind} request sent: ${id}`);
|
|
2270
|
+
}
|
|
2271
|
+
cancelRequestInAgentState(id, reason) {
|
|
2272
|
+
this.session.client.updateAgentState((currentState) => {
|
|
2273
|
+
const request = currentState.requests?.[id];
|
|
2274
|
+
if (!request) return currentState;
|
|
2275
|
+
const requests = { ...currentState.requests };
|
|
2276
|
+
delete requests[id];
|
|
2277
|
+
return {
|
|
2278
|
+
...currentState,
|
|
2279
|
+
requests,
|
|
2280
|
+
completedRequests: {
|
|
2281
|
+
...currentState.completedRequests,
|
|
2282
|
+
[id]: {
|
|
2283
|
+
...request,
|
|
2284
|
+
completedAt: Date.now(),
|
|
2285
|
+
status: "canceled",
|
|
2286
|
+
reason
|
|
2287
|
+
}
|
|
2288
|
+
}
|
|
2289
|
+
};
|
|
2290
|
+
});
|
|
2291
|
+
}
|
|
2152
2292
|
/**
|
|
2153
2293
|
* Parses Bash permission strings into literal and prefix sets
|
|
2154
2294
|
*/
|
|
@@ -2229,9 +2369,16 @@ class PermissionHandler {
|
|
|
2229
2369
|
logger.debug("Permission request not found or already resolved");
|
|
2230
2370
|
return;
|
|
2231
2371
|
}
|
|
2232
|
-
this.responses.set(id, { ...message, receivedAt: Date.now() });
|
|
2233
2372
|
this.pendingRequests.delete(id);
|
|
2234
|
-
|
|
2373
|
+
let effectiveResponse = message;
|
|
2374
|
+
if (pending.kind === "tool") {
|
|
2375
|
+
effectiveResponse = await this.handlePermissionResponse(message, pending);
|
|
2376
|
+
this.responses.set(id, { ...effectiveResponse, receivedAt: Date.now() });
|
|
2377
|
+
} else if (pending.kind === "elicitation") {
|
|
2378
|
+
pending.resolve(message.approved ? { action: "accept", content: elicitationContent(message.updatedInput) } : { action: message.decision === "abort" ? "cancel" : "decline" });
|
|
2379
|
+
} else {
|
|
2380
|
+
pending.resolve(message.approved ? { behavior: "completed", result: message.updatedInput?.result ?? "retry_fallback" } : { behavior: "cancelled" });
|
|
2381
|
+
}
|
|
2235
2382
|
this.session.client.updateAgentState((currentState) => {
|
|
2236
2383
|
const request = currentState.requests?.[id];
|
|
2237
2384
|
if (!request) return currentState;
|
|
@@ -2245,10 +2392,11 @@ class PermissionHandler {
|
|
|
2245
2392
|
[id]: {
|
|
2246
2393
|
...request,
|
|
2247
2394
|
completedAt: Date.now(),
|
|
2248
|
-
status:
|
|
2249
|
-
reason:
|
|
2250
|
-
mode:
|
|
2251
|
-
|
|
2395
|
+
status: effectiveResponse.approved ? "approved" : "denied",
|
|
2396
|
+
reason: effectiveResponse.reason,
|
|
2397
|
+
mode: effectiveResponse.mode,
|
|
2398
|
+
decision: effectiveResponse.decision,
|
|
2399
|
+
allowedTools: effectiveResponse.allowTools
|
|
2252
2400
|
}
|
|
2253
2401
|
}
|
|
2254
2402
|
};
|
|
@@ -2469,7 +2617,8 @@ class SDKToLogConverter {
|
|
|
2469
2617
|
// Assistant messages often have additional fields
|
|
2470
2618
|
requestId: assistantMsg.requestId,
|
|
2471
2619
|
...assistantMsg.isCompactSummary ? { isCompactSummary: true } : {},
|
|
2472
|
-
...assistantMsg.parent_tool_use_id ? { parent_tool_use_id: assistantMsg.parent_tool_use_id } : {}
|
|
2620
|
+
...assistantMsg.parent_tool_use_id ? { parent_tool_use_id: assistantMsg.parent_tool_use_id } : {},
|
|
2621
|
+
...assistantMsg.error ? { error: assistantMsg.error } : {}
|
|
2473
2622
|
};
|
|
2474
2623
|
break;
|
|
2475
2624
|
}
|
|
@@ -2500,17 +2649,28 @@ class SDKToLogConverter {
|
|
|
2500
2649
|
total_cost_usd: resultMsg.total_cost_usd,
|
|
2501
2650
|
duration_ms: resultMsg.duration_ms,
|
|
2502
2651
|
num_turns: resultMsg.num_turns,
|
|
2503
|
-
usage: resultMsg.usage
|
|
2652
|
+
usage: resultMsg.usage,
|
|
2653
|
+
..."errors" in resultMsg ? { errors: resultMsg.errors } : {},
|
|
2654
|
+
..."terminal_reason" in resultMsg && resultMsg.terminal_reason ? { terminal_reason: resultMsg.terminal_reason } : {}
|
|
2504
2655
|
};
|
|
2505
2656
|
break;
|
|
2506
2657
|
}
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2658
|
+
// These SDK lifecycle/advisory frames are intentionally not part
|
|
2659
|
+
// of the persisted Claude transcript. Enumerating them keeps SDK
|
|
2660
|
+
// upgrades type-visible instead of silently passing new frames
|
|
2661
|
+
// through as conversation messages.
|
|
2662
|
+
case "stream_event":
|
|
2663
|
+
case "tool_progress":
|
|
2664
|
+
case "auth_status":
|
|
2665
|
+
case "tool_use_summary":
|
|
2666
|
+
case "rate_limit_event":
|
|
2667
|
+
case "prompt_suggestion":
|
|
2668
|
+
case "conversation_reset":
|
|
2669
|
+
return null;
|
|
2670
|
+
default: {
|
|
2671
|
+
const exhaustive = sdkMessage;
|
|
2672
|
+
return exhaustive;
|
|
2673
|
+
}
|
|
2514
2674
|
}
|
|
2515
2675
|
if (logMessage && logMessage.type !== "summary" && logMessage.type !== "result") {
|
|
2516
2676
|
this.lastUuid = uuid;
|
|
@@ -2806,6 +2966,17 @@ async function cleanupStdinAfterInk(opts) {
|
|
|
2806
2966
|
}
|
|
2807
2967
|
}
|
|
2808
2968
|
|
|
2969
|
+
function applyClaudeResultLifecycle(result, callbacks) {
|
|
2970
|
+
if (result && result.subtype !== "success") {
|
|
2971
|
+
const error = result.errors?.filter(Boolean).join("\n").trim() || result.subtype;
|
|
2972
|
+
callbacks.closeFailed(error);
|
|
2973
|
+
callbacks.onFailed(error);
|
|
2974
|
+
return;
|
|
2975
|
+
}
|
|
2976
|
+
callbacks.closeCompleted();
|
|
2977
|
+
callbacks.onCompleted();
|
|
2978
|
+
}
|
|
2979
|
+
|
|
2809
2980
|
async function claudeRemoteLauncher(session) {
|
|
2810
2981
|
logger.debug("[claudeRemoteLauncher] Starting remote launcher");
|
|
2811
2982
|
const hasTTY = process.stdout.isTTY && process.stdin.isTTY;
|
|
@@ -3018,6 +3189,8 @@ async function claudeRemoteLauncher(session) {
|
|
|
3018
3189
|
hookSettingsPath: session.hookSettingsPath,
|
|
3019
3190
|
jsRuntime: session.jsRuntime,
|
|
3020
3191
|
canCallTool: permissionHandler.handleToolCall,
|
|
3192
|
+
onElicitation: permissionHandler.handleElicitation,
|
|
3193
|
+
onUserDialog: permissionHandler.handleUserDialog,
|
|
3021
3194
|
isAborted: (toolCallId) => {
|
|
3022
3195
|
return permissionHandler.isAborted(toolCallId);
|
|
3023
3196
|
},
|
|
@@ -3106,21 +3279,27 @@ async function claudeRemoteLauncher(session) {
|
|
|
3106
3279
|
logger.debug("[remote]: Session reset");
|
|
3107
3280
|
session.clearSessionId();
|
|
3108
3281
|
},
|
|
3109
|
-
onReady: () => {
|
|
3110
|
-
|
|
3111
|
-
|
|
3112
|
-
|
|
3113
|
-
|
|
3114
|
-
|
|
3115
|
-
|
|
3116
|
-
|
|
3117
|
-
|
|
3118
|
-
|
|
3119
|
-
|
|
3120
|
-
|
|
3282
|
+
onReady: (result) => {
|
|
3283
|
+
applyClaudeResultLifecycle(result, {
|
|
3284
|
+
closeCompleted: () => session.client.closeClaudeSessionTurn("completed"),
|
|
3285
|
+
closeFailed: (error) => session.client.closeClaudeSessionTurn("failed", { error }),
|
|
3286
|
+
onFailed: (error) => session.onSessionError(error),
|
|
3287
|
+
onCompleted: () => {
|
|
3288
|
+
const idle = !pending && session.queue.size() === 0;
|
|
3289
|
+
session.onTurnEnd(idle);
|
|
3290
|
+
if (idle) {
|
|
3291
|
+
session.api.push().sendSessionNotification({
|
|
3292
|
+
kind: "done",
|
|
3293
|
+
metadata: session.client.getMetadata(),
|
|
3294
|
+
data: {
|
|
3295
|
+
sessionId: session.client.sessionId,
|
|
3296
|
+
type: "ready",
|
|
3297
|
+
provider: "claude"
|
|
3298
|
+
}
|
|
3299
|
+
});
|
|
3121
3300
|
}
|
|
3122
|
-
}
|
|
3123
|
-
}
|
|
3301
|
+
}
|
|
3302
|
+
});
|
|
3124
3303
|
},
|
|
3125
3304
|
signal: abortController.signal
|
|
3126
3305
|
});
|
|
@@ -12983,7 +13162,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
12983
13162
|
process.exit(0);
|
|
12984
13163
|
} else if (subcommand === "install-terminal-hooks") {
|
|
12985
13164
|
try {
|
|
12986
|
-
const { installTerminalHooks, parseTerminalHooksArgs, TERMINAL_HOOKS_HELP } = await import('./installTerminalHooks-
|
|
13165
|
+
const { installTerminalHooks, parseTerminalHooksArgs, TERMINAL_HOOKS_HELP } = await import('./installTerminalHooks-CPKThY28.mjs');
|
|
12987
13166
|
const command = parseTerminalHooksArgs(args.slice(1));
|
|
12988
13167
|
if (command.action === "help") {
|
|
12989
13168
|
console.log(TERMINAL_HOOKS_HELP);
|
|
@@ -13000,7 +13179,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
13000
13179
|
}
|
|
13001
13180
|
} else if (subcommand === "spawn") {
|
|
13002
13181
|
try {
|
|
13003
|
-
const { handleSpawnCommand } = await import('./spawn-
|
|
13182
|
+
const { handleSpawnCommand } = await import('./spawn-DBpgsEkS.mjs');
|
|
13004
13183
|
await handleSpawnCommand(args.slice(1));
|
|
13005
13184
|
} catch (error) {
|
|
13006
13185
|
console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
|
|
@@ -13012,7 +13191,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
13012
13191
|
return;
|
|
13013
13192
|
} else if (subcommand === "send") {
|
|
13014
13193
|
try {
|
|
13015
|
-
const { handleSendCommand } = await import('./send-
|
|
13194
|
+
const { handleSendCommand } = await import('./send-DjjJQXJt.mjs');
|
|
13016
13195
|
await handleSendCommand(args.slice(1));
|
|
13017
13196
|
} catch (error) {
|
|
13018
13197
|
console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
|
|
@@ -13118,9 +13297,9 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
13118
13297
|
if (geminiSubcommand === "project" && args[2] === "set" && args[3]) {
|
|
13119
13298
|
const projectId = args[3];
|
|
13120
13299
|
try {
|
|
13121
|
-
const { saveGoogleCloudProjectToConfig } = await import('./config-
|
|
13122
|
-
const { readCredentialsForConfiguredRelay: readCredentialsForConfiguredRelay2 } = await import('./types-
|
|
13123
|
-
const { ApiClient: ApiClient2 } = await import('./types-
|
|
13300
|
+
const { saveGoogleCloudProjectToConfig } = await import('./config-T7eM_8eT.mjs');
|
|
13301
|
+
const { readCredentialsForConfiguredRelay: readCredentialsForConfiguredRelay2 } = await import('./types-BRDN6zN2.mjs').then(function (n) { return n.af; });
|
|
13302
|
+
const { ApiClient: ApiClient2 } = await import('./types-BRDN6zN2.mjs').then(function (n) { return n.ag; });
|
|
13124
13303
|
let userEmail = void 0;
|
|
13125
13304
|
try {
|
|
13126
13305
|
const credentials = await readCredentialsForConfiguredRelay2();
|
|
@@ -13151,7 +13330,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
13151
13330
|
}
|
|
13152
13331
|
if (geminiSubcommand === "project" && args[2] === "get") {
|
|
13153
13332
|
try {
|
|
13154
|
-
const { readGeminiLocalConfig } = await import('./config-
|
|
13333
|
+
const { readGeminiLocalConfig } = await import('./config-T7eM_8eT.mjs');
|
|
13155
13334
|
const config = readGeminiLocalConfig();
|
|
13156
13335
|
if (config.googleCloudProject) {
|
|
13157
13336
|
console.log(`Current Google Cloud Project: ${config.googleCloudProject}`);
|
|
@@ -13191,7 +13370,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
13191
13370
|
process.exit(0);
|
|
13192
13371
|
}
|
|
13193
13372
|
try {
|
|
13194
|
-
const { runGemini } = await import('./runGemini-
|
|
13373
|
+
const { runGemini } = await import('./runGemini-BVxviS8T.mjs');
|
|
13195
13374
|
let startedBy = void 0;
|
|
13196
13375
|
for (let i = 1; i < args.length; i++) {
|
|
13197
13376
|
if (args[i] === "--started-by") {
|
|
@@ -13213,7 +13392,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
13213
13392
|
return;
|
|
13214
13393
|
} else if (subcommand === "acp") {
|
|
13215
13394
|
try {
|
|
13216
|
-
const { runAcp, resolveAcpAgentConfig } = await import('./index-
|
|
13395
|
+
const { runAcp, resolveAcpAgentConfig } = await import('./index-CuLe9SB7.mjs');
|
|
13217
13396
|
let startedBy = void 0;
|
|
13218
13397
|
let verbose = false;
|
|
13219
13398
|
const acpArgs = [];
|
|
@@ -13253,7 +13432,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
13253
13432
|
return;
|
|
13254
13433
|
} else if (subcommand === "openclaw") {
|
|
13255
13434
|
try {
|
|
13256
|
-
const { runOpenClaw } = await import('./runOpenClaw-
|
|
13435
|
+
const { runOpenClaw } = await import('./runOpenClaw-DVTaZJtj.mjs');
|
|
13257
13436
|
let startedBy = void 0;
|
|
13258
13437
|
let verbose = false;
|
|
13259
13438
|
let gatewayUrl;
|
|
@@ -13304,7 +13483,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
13304
13483
|
return;
|
|
13305
13484
|
} else if (subcommand === "mcp" && args.length === 1) {
|
|
13306
13485
|
try {
|
|
13307
|
-
const { handleMcpCommand } = await import('./mcp-
|
|
13486
|
+
const { handleMcpCommand } = await import('./mcp-DhUA22wj.mjs');
|
|
13308
13487
|
await handleMcpCommand();
|
|
13309
13488
|
} catch (error) {
|
|
13310
13489
|
process.stderr.write(`[very-happy mcp] Fatal: ${error instanceof Error ? error.message : String(error)}
|
package/dist/index.cjs
CHANGED
package/dist/index.mjs
CHANGED
|
@@ -5,8 +5,8 @@ var path = require('node:path');
|
|
|
5
5
|
var os = require('node:os');
|
|
6
6
|
var node_child_process = require('node:child_process');
|
|
7
7
|
var chalk = require('chalk');
|
|
8
|
-
var persistence = require('./types-
|
|
9
|
-
var index = require('./index-
|
|
8
|
+
var persistence = require('./types-Dy7P_1bh.cjs');
|
|
9
|
+
var index = require('./index-BGvGqzc1.cjs');
|
|
10
10
|
require('axios');
|
|
11
11
|
require('node:util');
|
|
12
12
|
require('node:fs/promises');
|
|
@@ -3,8 +3,8 @@ import { join, resolve } from 'node:path';
|
|
|
3
3
|
import { homedir } from 'node:os';
|
|
4
4
|
import { spawnSync } from 'node:child_process';
|
|
5
5
|
import chalk from 'chalk';
|
|
6
|
-
import { p as projectPath } from './types-
|
|
7
|
-
import { t as tmuxSupportsSessionEnv } from './index-
|
|
6
|
+
import { p as projectPath } from './types-BRDN6zN2.mjs';
|
|
7
|
+
import { t as tmuxSupportsSessionEnv } from './index-HYOkniru.mjs';
|
|
8
8
|
import 'axios';
|
|
9
9
|
import 'node:util';
|
|
10
10
|
import 'node:fs/promises';
|