very-happy-cli 0.2.88 → 0.2.90
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{AcpBackend-C_simUP7.mjs → AcpBackend-BV4wSnJ3.mjs} +1 -1
- package/dist/{AcpBackend-CBZNjcYO.cjs → AcpBackend-CnYZFdd0.cjs} +1 -1
- package/dist/{AcpSessionManager-B9mJWEzL.cjs → AcpSessionManager-BPBdrrME.cjs} +1 -1
- package/dist/{AcpSessionManager-G8w8Q6tt.mjs → AcpSessionManager-Cyne6Rmg.mjs} +1 -1
- package/dist/{config-CFSdirvc.mjs → config-BEdyyciP.mjs} +2 -2
- package/dist/{config-BPPY98U1.cjs → config-CgXitj0f.cjs} +2 -2
- package/dist/{index-FxD6Abgx.cjs → index-4YmVbx7j.cjs} +199 -46
- package/dist/{index-Bp5ZSCRm.cjs → index-B1wTVXjt.cjs} +4 -4
- package/dist/{index-Cn3VqAah.mjs → index-Dfu5uvjk.mjs} +5 -5
- package/dist/{index-j2LYx2KW.mjs → index-an09rejO.mjs} +196 -43
- package/dist/index.cjs +2 -2
- package/dist/index.mjs +2 -2
- package/dist/{installTerminalHooks-DsqU3Dxc.mjs → installTerminalHooks-C-OgZr5k.mjs} +2 -2
- package/dist/{installTerminalHooks-BL25f9BN.cjs → installTerminalHooks-DDpVxk8-.cjs} +2 -2
- package/dist/lib.cjs +1 -1
- package/dist/lib.d.cts +8 -0
- package/dist/lib.d.mts +8 -0
- package/dist/lib.mjs +1 -1
- package/dist/{mcp-BVoo0PQS.cjs → mcp-B6Nq-RUL.cjs} +2 -2
- package/dist/{mcp-DV49L5g2.mjs → mcp-Du-N0qlK.mjs} +2 -2
- package/dist/{runGemini-t_Oikq3z.cjs → runGemini-ChG7cGMC.cjs} +4 -4
- package/dist/{runGemini-cm1mKuxv.mjs → runGemini-DBr_TiTL.mjs} +4 -4
- package/dist/{runOpenClaw-CCwYAKyZ.mjs → runOpenClaw-Cbde8t92.mjs} +3 -3
- package/dist/{runOpenClaw-CCGywWGD.cjs → runOpenClaw-D2jtVgpC.cjs} +3 -3
- package/dist/{send-ifKBw-7j.mjs → send-BHliX59m.mjs} +2 -2
- package/dist/{send-CqPpRb7v.cjs → send-Bjen1TUE.cjs} +2 -2
- package/dist/{spawn-28RbN4P6.cjs → spawn-CH1Rq-LW.cjs} +2 -2
- package/dist/{spawn-DkG_GIXM.mjs → spawn-JxaPHAoP.mjs} +2 -2
- package/dist/{types-DE03map-.cjs → types-BNGeiP1C.cjs} +62 -44
- package/dist/{types-AO-TVSTa.mjs → types-DS3i_5LV.mjs} +60 -44
- package/package.json +7 -7
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { spawn } from 'node:child_process';
|
|
2
2
|
import { ndJsonStream, ClientSideConnection } from '@agentclientprotocol/sdk';
|
|
3
3
|
import { randomUUID } from 'node:crypto';
|
|
4
|
-
import { l as logger, d as contentLogMetadata, e as errorLogMetadata, f as packageJson, g as delay } from './types-
|
|
4
|
+
import { l as logger, d as contentLogMetadata, e as errorLogMetadata, f as packageJson, g as delay } from './types-DS3i_5LV.mjs';
|
|
5
5
|
|
|
6
6
|
const DEFAULT_TIMEOUTS = {
|
|
7
7
|
/** Default initialization timeout: 60 seconds */
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
var node_child_process = require('node:child_process');
|
|
4
4
|
var sdk = require('@agentclientprotocol/sdk');
|
|
5
5
|
var node_crypto = require('node:crypto');
|
|
6
|
-
var persistence = require('./types-
|
|
6
|
+
var persistence = require('./types-BNGeiP1C.cjs');
|
|
7
7
|
|
|
8
8
|
const DEFAULT_TIMEOUTS = {
|
|
9
9
|
/** Default initialization timeout: 60 seconds */
|
|
@@ -2,8 +2,8 @@ import { existsSync, readFileSync, mkdirSync, writeFileSync } from 'fs';
|
|
|
2
2
|
import { join } from 'path';
|
|
3
3
|
import { homedir } from 'os';
|
|
4
4
|
import { execSync } from 'child_process';
|
|
5
|
-
import { l as logger } from './types-
|
|
6
|
-
import { D as DEFAULT_GEMINI_MODEL, G as GEMINI_MODEL_ENV } from './index-
|
|
5
|
+
import { l as logger } from './types-DS3i_5LV.mjs';
|
|
6
|
+
import { D as DEFAULT_GEMINI_MODEL, G as GEMINI_MODEL_ENV } from './index-an09rejO.mjs';
|
|
7
7
|
import 'axios';
|
|
8
8
|
import 'chalk';
|
|
9
9
|
import 'node:util';
|
|
@@ -4,8 +4,8 @@ var fs = require('fs');
|
|
|
4
4
|
var path = require('path');
|
|
5
5
|
var os = require('os');
|
|
6
6
|
var child_process = require('child_process');
|
|
7
|
-
var persistence = require('./types-
|
|
8
|
-
var index = require('./index-
|
|
7
|
+
var persistence = require('./types-BNGeiP1C.cjs');
|
|
8
|
+
var index = require('./index-4YmVbx7j.cjs');
|
|
9
9
|
require('axios');
|
|
10
10
|
require('chalk');
|
|
11
11
|
require('node:util');
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
var chalk = require('chalk');
|
|
4
4
|
var os = require('node:os');
|
|
5
5
|
var node_crypto = require('node:crypto');
|
|
6
|
-
var persistence = require('./types-
|
|
6
|
+
var persistence = require('./types-BNGeiP1C.cjs');
|
|
7
7
|
var spawn = require('cross-spawn');
|
|
8
8
|
var path = require('node:path');
|
|
9
9
|
var node_readline = require('node:readline');
|
|
@@ -1528,7 +1528,7 @@ function query(params) {
|
|
|
1528
1528
|
fallbackModel: opts?.fallbackModel,
|
|
1529
1529
|
maxTurns: opts?.maxTurns,
|
|
1530
1530
|
permissionMode: opts?.permissionMode,
|
|
1531
|
-
allowDangerouslySkipPermissions: opts?.permissionMode === "bypassPermissions",
|
|
1531
|
+
allowDangerouslySkipPermissions: opts?.allowDangerouslySkipPermissions ?? opts?.permissionMode === "bypassPermissions",
|
|
1532
1532
|
allowedTools: opts?.allowedTools,
|
|
1533
1533
|
disallowedTools: opts?.disallowedTools,
|
|
1534
1534
|
mcpServers: opts?.mcpServers,
|
|
@@ -1603,6 +1603,9 @@ const VALID_PERMISSION_MODES = [
|
|
|
1603
1603
|
function isPermissionMode(value) {
|
|
1604
1604
|
return !!value && VALID_PERMISSION_MODES.includes(value);
|
|
1605
1605
|
}
|
|
1606
|
+
function parseClaudePermissionMode(value) {
|
|
1607
|
+
return typeof value === "string" && isPermissionMode(value) ? mapToClaudeMode(value) : null;
|
|
1608
|
+
}
|
|
1606
1609
|
function extractPermissionModeFromClaudeArgs(claudeArgs) {
|
|
1607
1610
|
if (!claudeArgs || claudeArgs.length === 0) {
|
|
1608
1611
|
return void 0;
|
|
@@ -1903,6 +1906,10 @@ async function claudeRemote(opts) {
|
|
|
1903
1906
|
resume: startFrom ?? void 0,
|
|
1904
1907
|
mcpServers: opts.mcpServers,
|
|
1905
1908
|
permissionMode: mapToClaudeMode(initial.mode.permissionMode),
|
|
1909
|
+
// This is only the SDK safety opt-in; permissionMode/canUseTool still
|
|
1910
|
+
// enforce the selected policy. It must be enabled at Query creation so
|
|
1911
|
+
// a later explicit live switch to bypassPermissions can succeed.
|
|
1912
|
+
allowDangerouslySkipPermissions: true,
|
|
1906
1913
|
model: initial.mode.model,
|
|
1907
1914
|
fallbackModel: initial.mode.fallbackModel,
|
|
1908
1915
|
customSystemPrompt: initial.mode.customSystemPrompt ? initial.mode.customSystemPrompt + "\n\n" + systemPrompt : void 0,
|
|
@@ -2078,6 +2085,10 @@ class PermissionHandler {
|
|
|
2078
2085
|
onPermissionRequestCallback;
|
|
2079
2086
|
/** Callback to change permission mode on the active query (set by claudeRemote) */
|
|
2080
2087
|
setPermissionModeCallback;
|
|
2088
|
+
modeChangeQueue = Promise.resolve();
|
|
2089
|
+
deferredPermissionMode;
|
|
2090
|
+
/** Fired when an approval response (plan approval / approve-with-mode) moved the mode. */
|
|
2091
|
+
onModeChangedCallback;
|
|
2081
2092
|
constructor(session) {
|
|
2082
2093
|
this.session = session;
|
|
2083
2094
|
this.setupClientHandler();
|
|
@@ -2089,7 +2100,19 @@ class PermissionHandler {
|
|
|
2089
2100
|
this.onPermissionRequestCallback = callback;
|
|
2090
2101
|
}
|
|
2091
2102
|
handleModeChange(mode) {
|
|
2092
|
-
this.permissionMode = mode;
|
|
2103
|
+
this.permissionMode = mapToClaudeMode(mode);
|
|
2104
|
+
}
|
|
2105
|
+
/** Current locally enforced mode (what canUseTool applies right now). */
|
|
2106
|
+
getPermissionMode() {
|
|
2107
|
+
return this.permissionMode;
|
|
2108
|
+
}
|
|
2109
|
+
/**
|
|
2110
|
+
* Observe mode transitions that originate inside the approval flow
|
|
2111
|
+
* (ExitPlanMode approval, approve-with-mode). Live/idle RPC changes and
|
|
2112
|
+
* queue-driven changes are owned by the launcher and do not fire this.
|
|
2113
|
+
*/
|
|
2114
|
+
setOnModeChanged(callback) {
|
|
2115
|
+
this.onModeChangedCallback = callback;
|
|
2093
2116
|
}
|
|
2094
2117
|
/**
|
|
2095
2118
|
* Set callback to dynamically change permission mode on the active query.
|
|
@@ -2098,6 +2121,74 @@ class PermissionHandler {
|
|
|
2098
2121
|
setPermissionModeUpdater(callback) {
|
|
2099
2122
|
this.setPermissionModeCallback = callback;
|
|
2100
2123
|
}
|
|
2124
|
+
/**
|
|
2125
|
+
* Apply a user-requested mode to the active SDK Query. Mode changes are
|
|
2126
|
+
* serialized so rapid menu selections cannot finish out of order.
|
|
2127
|
+
*
|
|
2128
|
+
* A live Query can be blocked inside canUseTool. When the requested mode
|
|
2129
|
+
* would have auto-allowed that ordinary tool, finish the callback first;
|
|
2130
|
+
* interactive prompts and ExitPlanMode deliberately remain pending.
|
|
2131
|
+
*/
|
|
2132
|
+
setLivePermissionMode(mode) {
|
|
2133
|
+
const task = this.modeChangeQueue.then(() => this.applyLivePermissionMode(mode));
|
|
2134
|
+
this.modeChangeQueue = task.catch(() => void 0);
|
|
2135
|
+
return task;
|
|
2136
|
+
}
|
|
2137
|
+
async applyLivePermissionMode(mode) {
|
|
2138
|
+
if (!this.setPermissionModeCallback) {
|
|
2139
|
+
throw new Error("active Claude query is not ready");
|
|
2140
|
+
}
|
|
2141
|
+
const previousMode = this.permissionMode;
|
|
2142
|
+
this.permissionMode = mode;
|
|
2143
|
+
this.deferredPermissionMode = void 0;
|
|
2144
|
+
try {
|
|
2145
|
+
const autoApproved = [...this.pendingRequests.entries()].filter(([, pending]) => pending.kind === "tool" && this.modeAutoAllowsTool(mode, pending.toolName));
|
|
2146
|
+
for (const [id, pending] of autoApproved) {
|
|
2147
|
+
if (pending.kind !== "tool" || !this.pendingRequests.delete(id)) continue;
|
|
2148
|
+
const response = {
|
|
2149
|
+
id,
|
|
2150
|
+
approved: true,
|
|
2151
|
+
decision: "approved",
|
|
2152
|
+
reason: `Approved by live permission mode ${mode}`
|
|
2153
|
+
};
|
|
2154
|
+
const effectiveResponse = await this.handlePermissionResponse(response, pending);
|
|
2155
|
+
this.responses.set(id, { ...effectiveResponse, receivedAt: Date.now() });
|
|
2156
|
+
this.recordCompletedRequest(id, effectiveResponse);
|
|
2157
|
+
}
|
|
2158
|
+
if (this.pendingRequests.size > 0) {
|
|
2159
|
+
this.deferredPermissionMode = mode;
|
|
2160
|
+
return;
|
|
2161
|
+
}
|
|
2162
|
+
await new Promise((resolve) => setImmediate(resolve));
|
|
2163
|
+
await this.setPermissionModeCallback(mode);
|
|
2164
|
+
} catch (error) {
|
|
2165
|
+
this.permissionMode = previousMode;
|
|
2166
|
+
if (this.deferredPermissionMode === mode) this.deferredPermissionMode = void 0;
|
|
2167
|
+
throw error;
|
|
2168
|
+
}
|
|
2169
|
+
}
|
|
2170
|
+
scheduleDeferredPermissionModeUpdate() {
|
|
2171
|
+
const mode = this.deferredPermissionMode;
|
|
2172
|
+
if (!mode || this.pendingRequests.size > 0) return;
|
|
2173
|
+
this.deferredPermissionMode = void 0;
|
|
2174
|
+
setImmediate(() => {
|
|
2175
|
+
const task = this.modeChangeQueue.then(async () => {
|
|
2176
|
+
if (!this.setPermissionModeCallback || this.permissionMode !== mode) return;
|
|
2177
|
+
await this.setPermissionModeCallback(mode);
|
|
2178
|
+
});
|
|
2179
|
+
this.modeChangeQueue = task.catch((error) => {
|
|
2180
|
+
persistence.logger.debug("[PermissionHandler] Deferred SDK permission mode update failed", error);
|
|
2181
|
+
});
|
|
2182
|
+
});
|
|
2183
|
+
}
|
|
2184
|
+
modeAutoAllowsTool(mode, toolName) {
|
|
2185
|
+
if (toolName === "AskUserQuestion") return false;
|
|
2186
|
+
const descriptor = getToolDescriptor(toolName);
|
|
2187
|
+
if (descriptor.exitPlan) return false;
|
|
2188
|
+
if (mode === "bypassPermissions") return true;
|
|
2189
|
+
if (mode === "acceptEdits") return descriptor.edit;
|
|
2190
|
+
return mode === "plan" && !descriptor.dangerous;
|
|
2191
|
+
}
|
|
2101
2192
|
/**
|
|
2102
2193
|
* Handler response
|
|
2103
2194
|
*/
|
|
@@ -2111,9 +2202,10 @@ class PermissionHandler {
|
|
|
2111
2202
|
updatedInput: persistence.contentLogMetadata(response.updatedInput)
|
|
2112
2203
|
});
|
|
2113
2204
|
if (response.approved) {
|
|
2114
|
-
const newMode = response.mode && ["default", "acceptEdits", "bypassPermissions"].includes(response.mode) ? response.mode : "
|
|
2205
|
+
const newMode = response.mode && ["default", "acceptEdits", "bypassPermissions"].includes(response.mode) ? response.mode : "bypassPermissions";
|
|
2115
2206
|
persistence.logger.debug(`Plan approved - allowing ExitPlanMode with ${newMode} as the local follow-up mode`);
|
|
2116
2207
|
this.permissionMode = newMode;
|
|
2208
|
+
this.onModeChangedCallback?.(newMode);
|
|
2117
2209
|
pending.resolve({ behavior: "allow", updatedInput: pending.input || {} });
|
|
2118
2210
|
} else {
|
|
2119
2211
|
pending.resolve({ behavior: "deny", message: response.reason || "Plan rejected" });
|
|
@@ -2124,6 +2216,7 @@ class PermissionHandler {
|
|
|
2124
2216
|
if (!this.setPermissionModeCallback) throw new Error("permission mode updater unavailable");
|
|
2125
2217
|
await this.setPermissionModeCallback(response.mode);
|
|
2126
2218
|
this.permissionMode = response.mode;
|
|
2219
|
+
this.onModeChangedCallback?.(response.mode);
|
|
2127
2220
|
} catch (err) {
|
|
2128
2221
|
const reason = `Failed to switch permission mode: ${err instanceof Error ? err.message : String(err)}`;
|
|
2129
2222
|
pending.resolve({ behavior: "deny", message: reason });
|
|
@@ -2342,6 +2435,30 @@ class PermissionHandler {
|
|
|
2342
2435
|
};
|
|
2343
2436
|
});
|
|
2344
2437
|
}
|
|
2438
|
+
recordCompletedRequest(id, response) {
|
|
2439
|
+
this.session.client.updateAgentState((currentState) => {
|
|
2440
|
+
const request = currentState.requests?.[id];
|
|
2441
|
+
if (!request) return currentState;
|
|
2442
|
+
const requests = { ...currentState.requests };
|
|
2443
|
+
delete requests[id];
|
|
2444
|
+
return {
|
|
2445
|
+
...currentState,
|
|
2446
|
+
requests,
|
|
2447
|
+
completedRequests: {
|
|
2448
|
+
...currentState.completedRequests,
|
|
2449
|
+
[id]: {
|
|
2450
|
+
...request,
|
|
2451
|
+
completedAt: Date.now(),
|
|
2452
|
+
status: response.approved ? "approved" : "denied",
|
|
2453
|
+
reason: response.reason,
|
|
2454
|
+
mode: response.mode,
|
|
2455
|
+
decision: response.decision,
|
|
2456
|
+
allowedTools: response.allowTools
|
|
2457
|
+
}
|
|
2458
|
+
}
|
|
2459
|
+
};
|
|
2460
|
+
});
|
|
2461
|
+
}
|
|
2345
2462
|
/**
|
|
2346
2463
|
* Parses Bash permission strings into literal and prefix sets
|
|
2347
2464
|
*/
|
|
@@ -2380,6 +2497,7 @@ class PermissionHandler {
|
|
|
2380
2497
|
this.allowedBashLiterals.clear();
|
|
2381
2498
|
this.allowedBashPrefixes.clear();
|
|
2382
2499
|
this.permissionMode = "default";
|
|
2500
|
+
this.deferredPermissionMode = void 0;
|
|
2383
2501
|
for (const [, pending] of this.pendingRequests.entries()) {
|
|
2384
2502
|
pending.reject(new Error("Session reset"));
|
|
2385
2503
|
}
|
|
@@ -2432,28 +2550,8 @@ class PermissionHandler {
|
|
|
2432
2550
|
} else {
|
|
2433
2551
|
pending.resolve(message.approved ? { behavior: "completed", result: message.updatedInput?.result ?? "retry_fallback" } : { behavior: "cancelled" });
|
|
2434
2552
|
}
|
|
2435
|
-
this.
|
|
2436
|
-
|
|
2437
|
-
if (!request) return currentState;
|
|
2438
|
-
let r = { ...currentState.requests };
|
|
2439
|
-
delete r[id];
|
|
2440
|
-
return {
|
|
2441
|
-
...currentState,
|
|
2442
|
-
requests: r,
|
|
2443
|
-
completedRequests: {
|
|
2444
|
-
...currentState.completedRequests,
|
|
2445
|
-
[id]: {
|
|
2446
|
-
...request,
|
|
2447
|
-
completedAt: Date.now(),
|
|
2448
|
-
status: effectiveResponse.approved ? "approved" : "denied",
|
|
2449
|
-
reason: effectiveResponse.reason,
|
|
2450
|
-
mode: effectiveResponse.mode,
|
|
2451
|
-
decision: effectiveResponse.decision,
|
|
2452
|
-
allowedTools: effectiveResponse.allowTools
|
|
2453
|
-
}
|
|
2454
|
-
}
|
|
2455
|
-
};
|
|
2456
|
-
});
|
|
2553
|
+
this.recordCompletedRequest(id, effectiveResponse);
|
|
2554
|
+
this.scheduleDeferredPermissionModeUpdate();
|
|
2457
2555
|
});
|
|
2458
2556
|
}
|
|
2459
2557
|
/**
|
|
@@ -3229,7 +3327,7 @@ function createTurnSteeringController() {
|
|
|
3229
3327
|
};
|
|
3230
3328
|
}
|
|
3231
3329
|
|
|
3232
|
-
async function claudeRemoteLauncher(session) {
|
|
3330
|
+
async function claudeRemoteLauncher(session, onPermissionModeChange) {
|
|
3233
3331
|
persistence.logger.debug("[claudeRemoteLauncher] Starting remote launcher");
|
|
3234
3332
|
const hasTTY = process.stdout.isTTY && process.stdin.isTTY;
|
|
3235
3333
|
persistence.logger.debug(`[claudeRemoteLauncher] TTY available: ${hasTTY}`);
|
|
@@ -3290,7 +3388,24 @@ async function claudeRemoteLauncher(session) {
|
|
|
3290
3388
|
await turnSteering.steer();
|
|
3291
3389
|
});
|
|
3292
3390
|
session.client.rpcHandlerManager.registerHandler("switch", doSwitch);
|
|
3391
|
+
let livePermissionModeHandler = null;
|
|
3392
|
+
let idlePermissionModeHandler = null;
|
|
3393
|
+
session.client.rpcHandlerManager.registerHandler(
|
|
3394
|
+
"set-permission-mode",
|
|
3395
|
+
async (request) => {
|
|
3396
|
+
const requestedMode = parseClaudePermissionMode(request?.mode);
|
|
3397
|
+
if (!requestedMode) throw new Error("Invalid Claude permission mode");
|
|
3398
|
+
if (livePermissionModeHandler) return { mode: await livePermissionModeHandler(requestedMode) };
|
|
3399
|
+
if (idlePermissionModeHandler) return { mode: idlePermissionModeHandler(requestedMode) };
|
|
3400
|
+
throw new Error("No active Claude query");
|
|
3401
|
+
}
|
|
3402
|
+
);
|
|
3293
3403
|
const permissionHandler = new PermissionHandler(session);
|
|
3404
|
+
idlePermissionModeHandler = (nextMode) => {
|
|
3405
|
+
permissionHandler.handleModeChange(nextMode);
|
|
3406
|
+
onPermissionModeChange?.(nextMode);
|
|
3407
|
+
return nextMode;
|
|
3408
|
+
};
|
|
3294
3409
|
permissionHandler.reset("Previous CLI process exited before responding");
|
|
3295
3410
|
const messageQueue = new OutgoingMessageQueue(
|
|
3296
3411
|
(logMessage) => session.client.sendClaudeSessionMessage(logMessage)
|
|
@@ -3440,6 +3555,19 @@ async function claudeRemoteLauncher(session) {
|
|
|
3440
3555
|
abortFuture = new Future();
|
|
3441
3556
|
let modeHash = null;
|
|
3442
3557
|
let mode = null;
|
|
3558
|
+
const commitPermissionMode = (nextMode) => {
|
|
3559
|
+
permissionHandler.handleModeChange(nextMode);
|
|
3560
|
+
if (mode) {
|
|
3561
|
+
mode = { ...mode, permissionMode: nextMode };
|
|
3562
|
+
modeHash = session.queue.modeHasher(mode);
|
|
3563
|
+
}
|
|
3564
|
+
onPermissionModeChange?.(nextMode);
|
|
3565
|
+
return nextMode;
|
|
3566
|
+
};
|
|
3567
|
+
idlePermissionModeHandler = commitPermissionMode;
|
|
3568
|
+
permissionHandler.setOnModeChanged((nextMode) => {
|
|
3569
|
+
commitPermissionMode(nextMode);
|
|
3570
|
+
});
|
|
3443
3571
|
try {
|
|
3444
3572
|
const attachmentDirectory = chatAttachmentDirectory(persistence.configuration.happyHomeDir, session.client.sessionId);
|
|
3445
3573
|
await persistence.ensurePrivateDirectory(attachmentDirectory);
|
|
@@ -3526,6 +3654,15 @@ async function claudeRemoteLauncher(session) {
|
|
|
3526
3654
|
permissionHandler.setPermissionModeUpdater(async (mode2) => {
|
|
3527
3655
|
await q.setPermissionMode(mode2);
|
|
3528
3656
|
});
|
|
3657
|
+
livePermissionModeHandler = async (nextMode) => {
|
|
3658
|
+
await permissionHandler.setLivePermissionMode(nextMode);
|
|
3659
|
+
if (mode) {
|
|
3660
|
+
mode = { ...mode, permissionMode: nextMode };
|
|
3661
|
+
modeHash = session.queue.modeHasher(mode);
|
|
3662
|
+
}
|
|
3663
|
+
onPermissionModeChange?.(nextMode);
|
|
3664
|
+
return nextMode;
|
|
3665
|
+
};
|
|
3529
3666
|
},
|
|
3530
3667
|
onThinkingChange: session.onThinkingChange,
|
|
3531
3668
|
claudeEnvVars: session.claudeEnvVars,
|
|
@@ -3587,6 +3724,8 @@ async function claudeRemoteLauncher(session) {
|
|
|
3587
3724
|
} finally {
|
|
3588
3725
|
turnSteering.reset();
|
|
3589
3726
|
session.setSteerHandler(null);
|
|
3727
|
+
livePermissionModeHandler = null;
|
|
3728
|
+
permissionHandler.setPermissionModeUpdater(void 0);
|
|
3590
3729
|
sdkToLogConverter.resetTransientState();
|
|
3591
3730
|
persistence.logger.debug("[remote]: launch finally");
|
|
3592
3731
|
for (let [toolCallId, { parentToolCallId }] of ongoingToolCalls) {
|
|
@@ -3671,7 +3810,7 @@ async function loop(opts) {
|
|
|
3671
3810
|
break;
|
|
3672
3811
|
}
|
|
3673
3812
|
case "remote": {
|
|
3674
|
-
const reason = await claudeRemoteLauncher(session);
|
|
3813
|
+
const reason = await claudeRemoteLauncher(session, opts.onPermissionModeChange);
|
|
3675
3814
|
switch (reason) {
|
|
3676
3815
|
case "exit":
|
|
3677
3816
|
return 0;
|
|
@@ -6533,7 +6672,7 @@ function createMirrorManager(deps) {
|
|
|
6533
6672
|
let chain = Promise.resolve();
|
|
6534
6673
|
const isTerminalAlive = deps.isTerminalAlive ?? ((terminalId) => {
|
|
6535
6674
|
try {
|
|
6536
|
-
return node_child_process.spawnSync("tmux", ["has-session", "-t", `=vh-${terminalId}:`], { stdio: "ignore", timeout: 3e3 }).status === 0;
|
|
6675
|
+
return node_child_process.spawnSync("tmux", persistence.tmuxArgs(["has-session", "-t", `=vh-${terminalId}:`]), { stdio: "ignore", timeout: 3e3, env: persistence.scrubTmuxClientEnv({ ...process.env }) }).status === 0;
|
|
6537
6676
|
} catch {
|
|
6538
6677
|
return false;
|
|
6539
6678
|
}
|
|
@@ -8704,7 +8843,7 @@ const MAX_TITLE_CHARS = 60;
|
|
|
8704
8843
|
const GENERATION_TIMEOUT_MS = 3e4;
|
|
8705
8844
|
function resolveClaudeBinary() {
|
|
8706
8845
|
try {
|
|
8707
|
-
const require$1 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-
|
|
8846
|
+
const require$1 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-4YmVbx7j.cjs', document.baseURI).href)));
|
|
8708
8847
|
const utilsPath = path.resolve(path.join(persistence.projectPath(), "scripts", "claude_version_utils.cjs"));
|
|
8709
8848
|
const { getClaudeCliPath } = require$1(utilsPath);
|
|
8710
8849
|
const path$1 = getClaudeCliPath();
|
|
@@ -9161,7 +9300,10 @@ async function runClaude(credentials, options = {}) {
|
|
|
9161
9300
|
// a brand-new session cannot pick a PDF until after sending once.
|
|
9162
9301
|
attachmentKinds: [...CLAUDE_ATTACHMENT_KINDS],
|
|
9163
9302
|
queueCancellation: true,
|
|
9164
|
-
capabilities: ["claude-steer-v1"],
|
|
9303
|
+
capabilities: ["claude-steer-v1", "claude-live-permission-v1", "claude-live-permission-v2"],
|
|
9304
|
+
// Effective mode this process enforces. Kept current by
|
|
9305
|
+
// publishPermissionMode below; the web renders it instead of guessing.
|
|
9306
|
+
permissionMode: mapToClaudeMode(initialPermissionMode ?? "default"),
|
|
9165
9307
|
sandbox: sandboxConfig?.enabled ? sandboxConfig : null,
|
|
9166
9308
|
dangerouslySkipPermissions,
|
|
9167
9309
|
...forkedFromSessionId ? { parentSessionId: forkedFromSessionId } : {},
|
|
@@ -9398,6 +9540,14 @@ async function runClaude(credentials, options = {}) {
|
|
|
9398
9540
|
)
|
|
9399
9541
|
}));
|
|
9400
9542
|
let currentPermissionMode = initialPermissionMode;
|
|
9543
|
+
let publishedPermissionMode = mapToClaudeMode(initialPermissionMode ?? "default");
|
|
9544
|
+
const publishPermissionMode = (mode) => {
|
|
9545
|
+
currentPermissionMode = mode;
|
|
9546
|
+
const published = mapToClaudeMode(mode ?? "default");
|
|
9547
|
+
if (published === publishedPermissionMode) return;
|
|
9548
|
+
publishedPermissionMode = published;
|
|
9549
|
+
session.updateMetadata((meta) => ({ ...meta, permissionMode: published }));
|
|
9550
|
+
};
|
|
9401
9551
|
let currentModel = options.model ?? DEFAULT_CLAUDE_MODEL;
|
|
9402
9552
|
let currentFallbackModel = void 0;
|
|
9403
9553
|
let currentCustomSystemPrompt = void 0;
|
|
@@ -9406,7 +9556,6 @@ async function runClaude(credentials, options = {}) {
|
|
|
9406
9556
|
let currentDisallowedTools = withAssistantDenylist(void 0, isAssistantVariant);
|
|
9407
9557
|
let currentEffort = DEFAULT_CLAUDE_EFFORT;
|
|
9408
9558
|
const resetCurrentModeDefaults = () => {
|
|
9409
|
-
currentPermissionMode = initialPermissionMode;
|
|
9410
9559
|
currentModel = options.model ?? DEFAULT_CLAUDE_MODEL;
|
|
9411
9560
|
currentFallbackModel = void 0;
|
|
9412
9561
|
currentCustomSystemPrompt = void 0;
|
|
@@ -9450,7 +9599,7 @@ async function runClaude(credentials, options = {}) {
|
|
|
9450
9599
|
message.meta.permissionMode,
|
|
9451
9600
|
sandboxEnabled
|
|
9452
9601
|
);
|
|
9453
|
-
|
|
9602
|
+
publishPermissionMode(messagePermissionMode);
|
|
9454
9603
|
const ignoredDefaultDowngrade = (previousPermissionMode === "bypassPermissions" || previousPermissionMode === "yolo") && message.meta.permissionMode === "default" && currentPermissionMode === previousPermissionMode;
|
|
9455
9604
|
if (ignoredDefaultDowngrade) {
|
|
9456
9605
|
persistence.logger.debug(`[loop] Ignoring permission mode downgrade from ${previousPermissionMode} to default`);
|
|
@@ -9706,6 +9855,10 @@ async function runClaude(credentials, options = {}) {
|
|
|
9706
9855
|
currentSession = sessionInstance;
|
|
9707
9856
|
},
|
|
9708
9857
|
onAbort: resetCurrentModeDefaults,
|
|
9858
|
+
onPermissionModeChange: (mode) => {
|
|
9859
|
+
publishPermissionMode(mode);
|
|
9860
|
+
persistence.logger.debug(`[loop] Permission mode updated from session RPC / approval to: ${mode}`);
|
|
9861
|
+
},
|
|
9709
9862
|
mcpServers: {
|
|
9710
9863
|
"happy": {
|
|
9711
9864
|
type: "http",
|
|
@@ -10848,9 +11001,9 @@ function resolveLocalSignupBootstrap(configuredMode, configuredInviteCodes, gene
|
|
|
10848
11001
|
};
|
|
10849
11002
|
}
|
|
10850
11003
|
|
|
10851
|
-
const __filename$1 = node_url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-
|
|
11004
|
+
const __filename$1 = node_url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-4YmVbx7j.cjs', document.baseURI).href)));
|
|
10852
11005
|
const __dirname$1 = path.dirname(__filename$1);
|
|
10853
|
-
const require_ = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-
|
|
11006
|
+
const require_ = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-4YmVbx7j.cjs', document.baseURI).href)));
|
|
10854
11007
|
const PRISMA_QUERY_ENGINE_FILES = {
|
|
10855
11008
|
"arm64-darwin": "libquery_engine-darwin-arm64.dylib.node",
|
|
10856
11009
|
"x64-darwin": "libquery_engine-darwin.dylib.node",
|
|
@@ -13462,7 +13615,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
13462
13615
|
process.exit(0);
|
|
13463
13616
|
} else if (subcommand === "install-terminal-hooks") {
|
|
13464
13617
|
try {
|
|
13465
|
-
const { installTerminalHooks, parseTerminalHooksArgs, TERMINAL_HOOKS_HELP } = await Promise.resolve().then(function () { return require('./installTerminalHooks-
|
|
13618
|
+
const { installTerminalHooks, parseTerminalHooksArgs, TERMINAL_HOOKS_HELP } = await Promise.resolve().then(function () { return require('./installTerminalHooks-DDpVxk8-.cjs'); });
|
|
13466
13619
|
const command = parseTerminalHooksArgs(args.slice(1));
|
|
13467
13620
|
if (command.action === "help") {
|
|
13468
13621
|
console.log(TERMINAL_HOOKS_HELP);
|
|
@@ -13479,7 +13632,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
13479
13632
|
}
|
|
13480
13633
|
} else if (subcommand === "spawn") {
|
|
13481
13634
|
try {
|
|
13482
|
-
const { handleSpawnCommand } = await Promise.resolve().then(function () { return require('./spawn-
|
|
13635
|
+
const { handleSpawnCommand } = await Promise.resolve().then(function () { return require('./spawn-CH1Rq-LW.cjs'); });
|
|
13483
13636
|
await handleSpawnCommand(args.slice(1));
|
|
13484
13637
|
} catch (error) {
|
|
13485
13638
|
console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
|
|
@@ -13491,7 +13644,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
13491
13644
|
return;
|
|
13492
13645
|
} else if (subcommand === "send") {
|
|
13493
13646
|
try {
|
|
13494
|
-
const { handleSendCommand } = await Promise.resolve().then(function () { return require('./send-
|
|
13647
|
+
const { handleSendCommand } = await Promise.resolve().then(function () { return require('./send-Bjen1TUE.cjs'); });
|
|
13495
13648
|
await handleSendCommand(args.slice(1));
|
|
13496
13649
|
} catch (error) {
|
|
13497
13650
|
console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
|
|
@@ -13597,9 +13750,9 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
13597
13750
|
if (geminiSubcommand === "project" && args[2] === "set" && args[3]) {
|
|
13598
13751
|
const projectId = args[3];
|
|
13599
13752
|
try {
|
|
13600
|
-
const { saveGoogleCloudProjectToConfig } = await Promise.resolve().then(function () { return require('./config-
|
|
13601
|
-
const { readCredentialsForConfiguredRelay: readCredentialsForConfiguredRelay2 } = await Promise.resolve().then(function () { return require('./types-
|
|
13602
|
-
const { ApiClient: ApiClient2 } = await Promise.resolve().then(function () { return require('./types-
|
|
13753
|
+
const { saveGoogleCloudProjectToConfig } = await Promise.resolve().then(function () { return require('./config-CgXitj0f.cjs'); });
|
|
13754
|
+
const { readCredentialsForConfiguredRelay: readCredentialsForConfiguredRelay2 } = await Promise.resolve().then(function () { return require('./types-BNGeiP1C.cjs'); }).then(function (n) { return n.persistence; });
|
|
13755
|
+
const { ApiClient: ApiClient2 } = await Promise.resolve().then(function () { return require('./types-BNGeiP1C.cjs'); }).then(function (n) { return n.api; });
|
|
13603
13756
|
let userEmail = void 0;
|
|
13604
13757
|
try {
|
|
13605
13758
|
const credentials = await readCredentialsForConfiguredRelay2();
|
|
@@ -13630,7 +13783,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
13630
13783
|
}
|
|
13631
13784
|
if (geminiSubcommand === "project" && args[2] === "get") {
|
|
13632
13785
|
try {
|
|
13633
|
-
const { readGeminiLocalConfig } = await Promise.resolve().then(function () { return require('./config-
|
|
13786
|
+
const { readGeminiLocalConfig } = await Promise.resolve().then(function () { return require('./config-CgXitj0f.cjs'); });
|
|
13634
13787
|
const config = readGeminiLocalConfig();
|
|
13635
13788
|
if (config.googleCloudProject) {
|
|
13636
13789
|
console.log(`Current Google Cloud Project: ${config.googleCloudProject}`);
|
|
@@ -13670,7 +13823,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
13670
13823
|
process.exit(0);
|
|
13671
13824
|
}
|
|
13672
13825
|
try {
|
|
13673
|
-
const { runGemini } = await Promise.resolve().then(function () { return require('./runGemini-
|
|
13826
|
+
const { runGemini } = await Promise.resolve().then(function () { return require('./runGemini-ChG7cGMC.cjs'); });
|
|
13674
13827
|
let startedBy = void 0;
|
|
13675
13828
|
for (let i = 1; i < args.length; i++) {
|
|
13676
13829
|
if (args[i] === "--started-by") {
|
|
@@ -13692,7 +13845,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
13692
13845
|
return;
|
|
13693
13846
|
} else if (subcommand === "acp") {
|
|
13694
13847
|
try {
|
|
13695
|
-
const { runAcp, resolveAcpAgentConfig } = await Promise.resolve().then(function () { return require('./index-
|
|
13848
|
+
const { runAcp, resolveAcpAgentConfig } = await Promise.resolve().then(function () { return require('./index-B1wTVXjt.cjs'); });
|
|
13696
13849
|
let startedBy = void 0;
|
|
13697
13850
|
let verbose = false;
|
|
13698
13851
|
const acpArgs = [];
|
|
@@ -13732,7 +13885,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
13732
13885
|
return;
|
|
13733
13886
|
} else if (subcommand === "openclaw") {
|
|
13734
13887
|
try {
|
|
13735
|
-
const { runOpenClaw } = await Promise.resolve().then(function () { return require('./runOpenClaw-
|
|
13888
|
+
const { runOpenClaw } = await Promise.resolve().then(function () { return require('./runOpenClaw-D2jtVgpC.cjs'); });
|
|
13736
13889
|
let startedBy = void 0;
|
|
13737
13890
|
let verbose = false;
|
|
13738
13891
|
let gatewayUrl;
|
|
@@ -13783,7 +13936,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
13783
13936
|
return;
|
|
13784
13937
|
} else if (subcommand === "mcp" && args.length === 1) {
|
|
13785
13938
|
try {
|
|
13786
|
-
const { handleMcpCommand } = await Promise.resolve().then(function () { return require('./mcp-
|
|
13939
|
+
const { handleMcpCommand } = await Promise.resolve().then(function () { return require('./mcp-B6Nq-RUL.cjs'); });
|
|
13787
13940
|
await handleMcpCommand();
|
|
13788
13941
|
} catch (error) {
|
|
13789
13942
|
process.stderr.write(`[very-happy mcp] Fatal: ${error instanceof Error ? error.message : String(error)}
|
|
@@ -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-CnYZFdd0.cjs');
|
|
4
|
+
var persistence = require('./types-BNGeiP1C.cjs');
|
|
5
|
+
var AcpSessionManager = require('./AcpSessionManager-BPBdrrME.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-4YmVbx7j.cjs');
|
|
9
9
|
require('node:child_process');
|
|
10
10
|
require('@agentclientprotocol/sdk');
|
|
11
11
|
require('axios');
|
|
@@ -1,10 +1,10 @@
|
|
|
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 { h as connectionState, A as ApiClient, i as readSettings, j as encodeBase64, l as logger, p as projectPath } from './types-
|
|
4
|
-
import { A as AcpSessionManager } from './AcpSessionManager-
|
|
1
|
+
import { D as DefaultTransport, A as AcpBackend } from './AcpBackend-BV4wSnJ3.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-BV4wSnJ3.mjs';
|
|
3
|
+
import { h as connectionState, A as ApiClient, i as readSettings, j as encodeBase64, l as logger, p as projectPath } from './types-DS3i_5LV.mjs';
|
|
4
|
+
import { A as AcpSessionManager } from './AcpSessionManager-Cyne6Rmg.mjs';
|
|
5
5
|
import { randomUUID } from 'node:crypto';
|
|
6
6
|
import { join } from 'node:path';
|
|
7
|
-
import { i as initialMachineMetadata, d as createSessionMetadata, e as setupOfflineReconnection, n as notifyDaemonSessionStarted, M as MessageQueue2, h as hashObject, f as startHappyServer, r as registerKillSessionHandler, B as BasePermissionHandler } from './index-
|
|
7
|
+
import { i as initialMachineMetadata, d as createSessionMetadata, e as setupOfflineReconnection, n as notifyDaemonSessionStarted, M as MessageQueue2, h as hashObject, f as startHappyServer, r as registerKillSessionHandler, B as BasePermissionHandler } from './index-an09rejO.mjs';
|
|
8
8
|
import 'node:child_process';
|
|
9
9
|
import '@agentclientprotocol/sdk';
|
|
10
10
|
import 'axios';
|