very-happy-cli 0.2.89 → 0.2.91
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-DuxcHPyn.mjs → AcpBackend-B5RRlzLU.mjs} +1 -1
- package/dist/{AcpBackend-ClEvE-A-.cjs → AcpBackend-GqveWg8u.cjs} +1 -1
- package/dist/{AcpSessionManager-CGrA8bTm.mjs → AcpSessionManager-Ij1pI5Ex.mjs} +1 -1
- package/dist/{AcpSessionManager-DgbEf8FX.cjs → AcpSessionManager-YcrSZwvq.cjs} +1 -1
- package/dist/{config-BZNnPK1L.cjs → config-C4NCw7Dz.cjs} +2 -2
- package/dist/{config-CdoGLla8.mjs → config-ra8iKxdU.mjs} +2 -2
- package/dist/{index-Bx-UTV3I.cjs → index-C1HIm7NY.cjs} +4 -4
- package/dist/{index-BP2wylez.mjs → index-CB5H7YI6.mjs} +5 -5
- package/dist/{index-DYDAFqAN.cjs → index-FkXJNwiy.cjs} +141 -39
- package/dist/{index-vCgb7QnZ.mjs → index-UCYD5Wk3.mjs} +138 -36
- package/dist/index.cjs +2 -2
- package/dist/index.mjs +2 -2
- package/dist/{installTerminalHooks-T4NE5fmC.cjs → installTerminalHooks-CoK5wNcA.cjs} +2 -2
- package/dist/{installTerminalHooks-C7JS6CBM.mjs → installTerminalHooks-TkkGzzbI.mjs} +2 -2
- package/dist/lib.cjs +1 -1
- package/dist/lib.d.cts +42 -0
- package/dist/lib.d.mts +42 -0
- package/dist/lib.mjs +1 -1
- package/dist/{mcp-B3EgenZh.mjs → mcp-C3MiqObi.mjs} +2 -2
- package/dist/{mcp-DgPg5mKa.cjs → mcp-DcRvswVI.cjs} +2 -2
- package/dist/{runGemini-B3iv1QRL.mjs → runGemini-BbC0uwUj.mjs} +4 -4
- package/dist/{runGemini-xZnGj7jx.cjs → runGemini-Dnvd2gWq.cjs} +4 -4
- package/dist/{runOpenClaw-CmM4ZLYi.mjs → runOpenClaw--nbqTW3K.mjs} +3 -3
- package/dist/{runOpenClaw-6ZLPeYYZ.cjs → runOpenClaw-CnuTBNQW.cjs} +3 -3
- package/dist/{send-M2ax7UGy.mjs → send-9nJxn09Y.mjs} +2 -2
- package/dist/{send-S9ibMiAt.cjs → send-DkKOPatx.cjs} +2 -2
- package/dist/{spawn-Dx_xnLlg.mjs → spawn-CRW4ioms.mjs} +2 -2
- package/dist/{spawn-ie_kfwQe.cjs → spawn-DE7WhS8Y.cjs} +2 -2
- package/dist/{types-d_104eQF.mjs → types-BKyjG23_.mjs} +304 -52
- package/dist/{types-DLI6sss2.cjs → types-ClDADuxP.cjs} +306 -52
- 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-BKyjG23_.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-ClDADuxP.cjs');
|
|
7
7
|
|
|
8
8
|
const DEFAULT_TIMEOUTS = {
|
|
9
9
|
/** Default initialization timeout: 60 seconds */
|
|
@@ -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-ClDADuxP.cjs');
|
|
8
|
+
var index = require('./index-FkXJNwiy.cjs');
|
|
9
9
|
require('axios');
|
|
10
10
|
require('chalk');
|
|
11
11
|
require('node:util');
|
|
@@ -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-BKyjG23_.mjs';
|
|
6
|
+
import { D as DEFAULT_GEMINI_MODEL, G as GEMINI_MODEL_ENV } from './index-UCYD5Wk3.mjs';
|
|
7
7
|
import 'axios';
|
|
8
8
|
import 'chalk';
|
|
9
9
|
import 'node:util';
|
|
@@ -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-GqveWg8u.cjs');
|
|
4
|
+
var persistence = require('./types-ClDADuxP.cjs');
|
|
5
|
+
var AcpSessionManager = require('./AcpSessionManager-YcrSZwvq.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-FkXJNwiy.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-B5RRlzLU.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-B5RRlzLU.mjs';
|
|
3
|
+
import { h as connectionState, A as ApiClient, i as readSettings, j as encodeBase64, l as logger, p as projectPath } from './types-BKyjG23_.mjs';
|
|
4
|
+
import { A as AcpSessionManager } from './AcpSessionManager-Ij1pI5Ex.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-UCYD5Wk3.mjs';
|
|
8
8
|
import 'node:child_process';
|
|
9
9
|
import '@agentclientprotocol/sdk';
|
|
10
10
|
import 'axios';
|
|
@@ -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-ClDADuxP.cjs');
|
|
7
7
|
var spawn = require('cross-spawn');
|
|
8
8
|
var path = require('node:path');
|
|
9
9
|
var node_readline = require('node:readline');
|
|
@@ -1655,6 +1655,12 @@ function resolveRemoteClaudePermissionMode(currentMode, incomingMode, sandboxEna
|
|
|
1655
1655
|
}
|
|
1656
1656
|
return nextMode;
|
|
1657
1657
|
}
|
|
1658
|
+
function reconcilePublishedPermissionMode(input) {
|
|
1659
|
+
if (!input.effective) return null;
|
|
1660
|
+
const mismatch = input.effective !== input.intent;
|
|
1661
|
+
if (input.effective === input.published) return mismatch ? { publish: input.effective, mismatch } : null;
|
|
1662
|
+
return { publish: input.effective, mismatch };
|
|
1663
|
+
}
|
|
1658
1664
|
|
|
1659
1665
|
function parseCompact(message) {
|
|
1660
1666
|
const trimmed = message.trim();
|
|
@@ -1984,7 +1990,12 @@ async function claudeRemote(opts) {
|
|
|
1984
1990
|
mcpServers: systemInit.mcp_servers?.map((s) => ({ name: s.name, status: s.status })),
|
|
1985
1991
|
skills: systemInit.skills,
|
|
1986
1992
|
model: systemInit.model,
|
|
1987
|
-
modelIsDefault: initial.mode.model == null
|
|
1993
|
+
modelIsDefault: initial.mode.model == null,
|
|
1994
|
+
// The SDK's own verdict on the mode it will enforce —
|
|
1995
|
+
// settings (permissions.deny/ask/defaultMode/
|
|
1996
|
+
// disableBypassPermissionsMode) can override what we
|
|
1997
|
+
// asked for. runClaude publishes THIS, not our intent.
|
|
1998
|
+
permissionMode: systemInit.permissionMode
|
|
1988
1999
|
});
|
|
1989
2000
|
}
|
|
1990
2001
|
if (systemInit.session_id) {
|
|
@@ -2002,6 +2013,10 @@ async function claudeRemote(opts) {
|
|
|
2002
2013
|
if (message.type === "result") {
|
|
2003
2014
|
updateThinking(false);
|
|
2004
2015
|
persistence.logger.debug("[claudeRemote] Result received");
|
|
2016
|
+
const denials = message.permission_denials;
|
|
2017
|
+
if (denials && denials.length > 0) {
|
|
2018
|
+
persistence.logger.warn(`[claudeRemote] ${denials.length} tool call(s) auto-denied by Claude Code policy: ${denials.map((d) => d.tool_name ?? "?").join(", ")}`);
|
|
2019
|
+
}
|
|
2005
2020
|
if (isCompactCommand) {
|
|
2006
2021
|
const compactSucceeded = message.subtype === "success";
|
|
2007
2022
|
persistence.logger.debug(`[claudeRemote] Compaction ${compactSucceeded ? "completed" : "failed"}`);
|
|
@@ -2087,6 +2102,8 @@ class PermissionHandler {
|
|
|
2087
2102
|
setPermissionModeCallback;
|
|
2088
2103
|
modeChangeQueue = Promise.resolve();
|
|
2089
2104
|
deferredPermissionMode;
|
|
2105
|
+
/** Fired when an approval response (plan approval / approve-with-mode) moved the mode. */
|
|
2106
|
+
onModeChangedCallback;
|
|
2090
2107
|
constructor(session) {
|
|
2091
2108
|
this.session = session;
|
|
2092
2109
|
this.setupClientHandler();
|
|
@@ -2100,6 +2117,18 @@ class PermissionHandler {
|
|
|
2100
2117
|
handleModeChange(mode) {
|
|
2101
2118
|
this.permissionMode = mapToClaudeMode(mode);
|
|
2102
2119
|
}
|
|
2120
|
+
/** Current locally enforced mode (what canUseTool applies right now). */
|
|
2121
|
+
getPermissionMode() {
|
|
2122
|
+
return this.permissionMode;
|
|
2123
|
+
}
|
|
2124
|
+
/**
|
|
2125
|
+
* Observe mode transitions that originate inside the approval flow
|
|
2126
|
+
* (ExitPlanMode approval, approve-with-mode). Live/idle RPC changes and
|
|
2127
|
+
* queue-driven changes are owned by the launcher and do not fire this.
|
|
2128
|
+
*/
|
|
2129
|
+
setOnModeChanged(callback) {
|
|
2130
|
+
this.onModeChangedCallback = callback;
|
|
2131
|
+
}
|
|
2103
2132
|
/**
|
|
2104
2133
|
* Set callback to dynamically change permission mode on the active query.
|
|
2105
2134
|
* Called by claudeRemote after the Query object is created.
|
|
@@ -2188,24 +2217,19 @@ class PermissionHandler {
|
|
|
2188
2217
|
updatedInput: persistence.contentLogMetadata(response.updatedInput)
|
|
2189
2218
|
});
|
|
2190
2219
|
if (response.approved) {
|
|
2191
|
-
const newMode = response.mode && ["default", "acceptEdits", "bypassPermissions"].includes(response.mode) ? response.mode : "
|
|
2220
|
+
const newMode = response.mode && ["default", "acceptEdits", "bypassPermissions"].includes(response.mode) ? response.mode : "bypassPermissions";
|
|
2192
2221
|
persistence.logger.debug(`Plan approved - allowing ExitPlanMode with ${newMode} as the local follow-up mode`);
|
|
2193
2222
|
this.permissionMode = newMode;
|
|
2223
|
+
this.onModeChangedCallback?.(newMode);
|
|
2194
2224
|
pending.resolve({ behavior: "allow", updatedInput: pending.input || {} });
|
|
2195
2225
|
} else {
|
|
2196
2226
|
pending.resolve({ behavior: "deny", message: response.reason || "Plan rejected" });
|
|
2197
2227
|
}
|
|
2198
2228
|
} else {
|
|
2199
2229
|
if (response.approved && response.mode) {
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
this.permissionMode = response.mode;
|
|
2204
|
-
} catch (err) {
|
|
2205
|
-
const reason = `Failed to switch permission mode: ${err instanceof Error ? err.message : String(err)}`;
|
|
2206
|
-
pending.resolve({ behavior: "deny", message: reason });
|
|
2207
|
-
return { ...response, approved: false, reason };
|
|
2208
|
-
}
|
|
2230
|
+
this.permissionMode = response.mode;
|
|
2231
|
+
this.deferredPermissionMode = response.mode;
|
|
2232
|
+
this.onModeChangedCallback?.(response.mode);
|
|
2209
2233
|
}
|
|
2210
2234
|
if (response.approved && !pending.suggestions?.length && response.allowTools?.length) {
|
|
2211
2235
|
response.allowTools.forEach((tool) => {
|
|
@@ -2546,6 +2570,17 @@ class PermissionHandler {
|
|
|
2546
2570
|
}
|
|
2547
2571
|
}
|
|
2548
2572
|
|
|
2573
|
+
function rewriteQueuedPermissionMode(queue, hasher, permissionMode) {
|
|
2574
|
+
let rewritten = 0;
|
|
2575
|
+
for (const item of queue) {
|
|
2576
|
+
if (item.mode.permissionMode === permissionMode) continue;
|
|
2577
|
+
item.mode = { ...item.mode, permissionMode };
|
|
2578
|
+
item.modeHash = hasher(item.mode);
|
|
2579
|
+
rewritten += 1;
|
|
2580
|
+
}
|
|
2581
|
+
return rewritten;
|
|
2582
|
+
}
|
|
2583
|
+
|
|
2549
2584
|
function formatClaudeMessageForInk(message, messageBuffer, onAssistantResult) {
|
|
2550
2585
|
persistence.logger.debugLargeJson("[CLAUDE INK] Message from remote mode:", message);
|
|
2551
2586
|
switch (message.type) {
|
|
@@ -2800,7 +2835,13 @@ class SDKToLogConverter {
|
|
|
2800
2835
|
type: "user",
|
|
2801
2836
|
message: userMsg.message,
|
|
2802
2837
|
...userMsg.parent_tool_use_id ? { parent_tool_use_id: userMsg.parent_tool_use_id } : {},
|
|
2803
|
-
...meta ? { isMeta: true } : {}
|
|
2838
|
+
...meta ? { isMeta: true } : {},
|
|
2839
|
+
// B-260-P2: structured tool output (Agent/Task final report +
|
|
2840
|
+
// run totals, or the `async_launched` stub marker) and the
|
|
2841
|
+
// message origin (task-notification). Both are consumed by
|
|
2842
|
+
// sessionProtocolMapper; the raw-line schema is passthrough.
|
|
2843
|
+
...userMsg.tool_use_result !== void 0 ? { tool_use_result: userMsg.tool_use_result } : {},
|
|
2844
|
+
...userMsg.origin ? { origin: userMsg.origin } : {}
|
|
2804
2845
|
};
|
|
2805
2846
|
if (Array.isArray(userMsg.message.content)) {
|
|
2806
2847
|
for (const content of userMsg.message.content) {
|
|
@@ -3311,7 +3352,7 @@ function createTurnSteeringController() {
|
|
|
3311
3352
|
};
|
|
3312
3353
|
}
|
|
3313
3354
|
|
|
3314
|
-
async function claudeRemoteLauncher(session, onPermissionModeChange) {
|
|
3355
|
+
async function claudeRemoteLauncher(session, onPermissionModeChange, onEffectivePermissionMode) {
|
|
3315
3356
|
persistence.logger.debug("[claudeRemoteLauncher] Starting remote launcher");
|
|
3316
3357
|
const hasTTY = process.stdout.isTTY && process.stdin.isTTY;
|
|
3317
3358
|
persistence.logger.debug(`[claudeRemoteLauncher] TTY available: ${hasTTY}`);
|
|
@@ -3373,16 +3414,23 @@ async function claudeRemoteLauncher(session, onPermissionModeChange) {
|
|
|
3373
3414
|
});
|
|
3374
3415
|
session.client.rpcHandlerManager.registerHandler("switch", doSwitch);
|
|
3375
3416
|
let livePermissionModeHandler = null;
|
|
3417
|
+
let idlePermissionModeHandler = null;
|
|
3376
3418
|
session.client.rpcHandlerManager.registerHandler(
|
|
3377
3419
|
"set-permission-mode",
|
|
3378
3420
|
async (request) => {
|
|
3379
3421
|
const requestedMode = parseClaudePermissionMode(request?.mode);
|
|
3380
3422
|
if (!requestedMode) throw new Error("Invalid Claude permission mode");
|
|
3381
|
-
if (
|
|
3382
|
-
return { mode:
|
|
3423
|
+
if (livePermissionModeHandler) return { mode: await livePermissionModeHandler(requestedMode) };
|
|
3424
|
+
if (idlePermissionModeHandler) return { mode: idlePermissionModeHandler(requestedMode) };
|
|
3425
|
+
throw new Error("No active Claude query");
|
|
3383
3426
|
}
|
|
3384
3427
|
);
|
|
3385
3428
|
const permissionHandler = new PermissionHandler(session);
|
|
3429
|
+
idlePermissionModeHandler = (nextMode) => {
|
|
3430
|
+
permissionHandler.handleModeChange(nextMode);
|
|
3431
|
+
onPermissionModeChange?.(nextMode);
|
|
3432
|
+
return nextMode;
|
|
3433
|
+
};
|
|
3386
3434
|
permissionHandler.reset("Previous CLI process exited before responding");
|
|
3387
3435
|
const messageQueue = new OutgoingMessageQueue(
|
|
3388
3436
|
(logMessage) => session.client.sendClaudeSessionMessage(logMessage)
|
|
@@ -3532,6 +3580,23 @@ async function claudeRemoteLauncher(session, onPermissionModeChange) {
|
|
|
3532
3580
|
abortFuture = new Future();
|
|
3533
3581
|
let modeHash = null;
|
|
3534
3582
|
let mode = null;
|
|
3583
|
+
const commitPermissionMode = (nextMode) => {
|
|
3584
|
+
permissionHandler.handleModeChange(nextMode);
|
|
3585
|
+
if (mode) {
|
|
3586
|
+
mode = { ...mode, permissionMode: nextMode };
|
|
3587
|
+
modeHash = session.queue.modeHasher(mode);
|
|
3588
|
+
}
|
|
3589
|
+
rewriteQueuedPermissionMode(session.queue.queue, session.queue.modeHasher, nextMode);
|
|
3590
|
+
if (pending) {
|
|
3591
|
+
pending = { ...pending, mode: { ...pending.mode, permissionMode: nextMode } };
|
|
3592
|
+
}
|
|
3593
|
+
onPermissionModeChange?.(nextMode);
|
|
3594
|
+
return nextMode;
|
|
3595
|
+
};
|
|
3596
|
+
idlePermissionModeHandler = commitPermissionMode;
|
|
3597
|
+
permissionHandler.setOnModeChanged((nextMode) => {
|
|
3598
|
+
commitPermissionMode(nextMode);
|
|
3599
|
+
});
|
|
3535
3600
|
try {
|
|
3536
3601
|
const attachmentDirectory = chatAttachmentDirectory(persistence.configuration.happyHomeDir, session.client.sessionId);
|
|
3537
3602
|
await persistence.ensurePrivateDirectory(attachmentDirectory);
|
|
@@ -3597,6 +3662,7 @@ async function claudeRemoteLauncher(session, onPermissionModeChange) {
|
|
|
3597
3662
|
skillCount: metadata.skills?.length ?? 0
|
|
3598
3663
|
});
|
|
3599
3664
|
session.client.updateMetadata((currentMetadata) => applyClaudeSdkMetadata(currentMetadata, metadata));
|
|
3665
|
+
if (metadata.permissionMode) onEffectivePermissionMode?.(metadata.permissionMode);
|
|
3600
3666
|
},
|
|
3601
3667
|
onQueryReady: (q) => {
|
|
3602
3668
|
turnSteering.setInterrupt(q.interrupt);
|
|
@@ -3774,7 +3840,7 @@ async function loop(opts) {
|
|
|
3774
3840
|
break;
|
|
3775
3841
|
}
|
|
3776
3842
|
case "remote": {
|
|
3777
|
-
const reason = await claudeRemoteLauncher(session, opts.onPermissionModeChange);
|
|
3843
|
+
const reason = await claudeRemoteLauncher(session, opts.onPermissionModeChange, opts.onEffectivePermissionMode);
|
|
3778
3844
|
switch (reason) {
|
|
3779
3845
|
case "exit":
|
|
3780
3846
|
return 0;
|
|
@@ -6636,7 +6702,7 @@ function createMirrorManager(deps) {
|
|
|
6636
6702
|
let chain = Promise.resolve();
|
|
6637
6703
|
const isTerminalAlive = deps.isTerminalAlive ?? ((terminalId) => {
|
|
6638
6704
|
try {
|
|
6639
|
-
return node_child_process.spawnSync("tmux", ["has-session", "-t", `=vh-${terminalId}:`], { stdio: "ignore", timeout: 3e3 }).status === 0;
|
|
6705
|
+
return node_child_process.spawnSync("tmux", persistence.tmuxArgs(["has-session", "-t", `=vh-${terminalId}:`]), { stdio: "ignore", timeout: 3e3, env: persistence.scrubTmuxClientEnv({ ...process.env }) }).status === 0;
|
|
6640
6706
|
} catch {
|
|
6641
6707
|
return false;
|
|
6642
6708
|
}
|
|
@@ -8807,7 +8873,7 @@ const MAX_TITLE_CHARS = 60;
|
|
|
8807
8873
|
const GENERATION_TIMEOUT_MS = 3e4;
|
|
8808
8874
|
function resolveClaudeBinary() {
|
|
8809
8875
|
try {
|
|
8810
|
-
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-
|
|
8876
|
+
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-FkXJNwiy.cjs', document.baseURI).href)));
|
|
8811
8877
|
const utilsPath = path.resolve(path.join(persistence.projectPath(), "scripts", "claude_version_utils.cjs"));
|
|
8812
8878
|
const { getClaudeCliPath } = require$1(utilsPath);
|
|
8813
8879
|
const path$1 = getClaudeCliPath();
|
|
@@ -9264,7 +9330,10 @@ async function runClaude(credentials, options = {}) {
|
|
|
9264
9330
|
// a brand-new session cannot pick a PDF until after sending once.
|
|
9265
9331
|
attachmentKinds: [...CLAUDE_ATTACHMENT_KINDS],
|
|
9266
9332
|
queueCancellation: true,
|
|
9267
|
-
capabilities: ["claude-steer-v1", "claude-live-permission-v1"],
|
|
9333
|
+
capabilities: ["claude-steer-v1", "claude-live-permission-v1", "claude-live-permission-v2"],
|
|
9334
|
+
// Effective mode this process enforces. Kept current by
|
|
9335
|
+
// publishPermissionMode below; the web renders it instead of guessing.
|
|
9336
|
+
permissionMode: mapToClaudeMode(initialPermissionMode ?? "default"),
|
|
9268
9337
|
sandbox: sandboxConfig?.enabled ? sandboxConfig : null,
|
|
9269
9338
|
dangerouslySkipPermissions,
|
|
9270
9339
|
...forkedFromSessionId ? { parentSessionId: forkedFromSessionId } : {},
|
|
@@ -9369,7 +9438,11 @@ async function runClaude(credentials, options = {}) {
|
|
|
9369
9438
|
...meta,
|
|
9370
9439
|
lifecycleState: "running",
|
|
9371
9440
|
archivedBy: void 0,
|
|
9372
|
-
queueCancellation: true
|
|
9441
|
+
queueCancellation: true,
|
|
9442
|
+
// B-262 batch 2 (B5): a reconnected process re-publishes the mode
|
|
9443
|
+
// IT enforces; the server copy may still carry the previous
|
|
9444
|
+
// process's value.
|
|
9445
|
+
permissionMode: mapToClaudeMode(initialPermissionMode ?? "default")
|
|
9373
9446
|
}));
|
|
9374
9447
|
}
|
|
9375
9448
|
const forkClaudeSessionId = process.env.HAPPY_FORK_CLAUDE_SESSION_ID;
|
|
@@ -9501,6 +9574,30 @@ async function runClaude(credentials, options = {}) {
|
|
|
9501
9574
|
)
|
|
9502
9575
|
}));
|
|
9503
9576
|
let currentPermissionMode = initialPermissionMode;
|
|
9577
|
+
let publishedPermissionMode = mapToClaudeMode(initialPermissionMode ?? "default");
|
|
9578
|
+
const publishPermissionMode = (mode) => {
|
|
9579
|
+
currentPermissionMode = mode;
|
|
9580
|
+
const published = mapToClaudeMode(mode ?? "default");
|
|
9581
|
+
if (published === publishedPermissionMode) return;
|
|
9582
|
+
publishedPermissionMode = published;
|
|
9583
|
+
session.updateMetadata((meta) => ({ ...meta, permissionMode: published }));
|
|
9584
|
+
};
|
|
9585
|
+
const publishEffectivePermissionMode = (effective) => {
|
|
9586
|
+
const decision = reconcilePublishedPermissionMode({
|
|
9587
|
+
intent: mapToClaudeMode(currentPermissionMode ?? "default"),
|
|
9588
|
+
published: publishedPermissionMode,
|
|
9589
|
+
effective
|
|
9590
|
+
});
|
|
9591
|
+
if (!decision) return;
|
|
9592
|
+
if (decision.mismatch) {
|
|
9593
|
+
persistence.logger.warn(`[loop] Claude Code enforces permission mode '${effective}' but this process asked for '${mapToClaudeMode(currentPermissionMode ?? "default")}' \u2014 check ~/.claude settings (permissions.deny/ask/defaultMode/disableBypassPermissionsMode). Publishing the effective mode.`);
|
|
9594
|
+
}
|
|
9595
|
+
if (decision.publish !== publishedPermissionMode) {
|
|
9596
|
+
publishedPermissionMode = decision.publish;
|
|
9597
|
+
session.updateMetadata((meta) => ({ ...meta, permissionMode: decision.publish }));
|
|
9598
|
+
}
|
|
9599
|
+
};
|
|
9600
|
+
let lastExplicitModeSwitchAt = 0;
|
|
9504
9601
|
let currentModel = options.model ?? DEFAULT_CLAUDE_MODEL;
|
|
9505
9602
|
let currentFallbackModel = void 0;
|
|
9506
9603
|
let currentCustomSystemPrompt = void 0;
|
|
@@ -9509,7 +9606,6 @@ async function runClaude(credentials, options = {}) {
|
|
|
9509
9606
|
let currentDisallowedTools = withAssistantDenylist(void 0, isAssistantVariant);
|
|
9510
9607
|
let currentEffort = DEFAULT_CLAUDE_EFFORT;
|
|
9511
9608
|
const resetCurrentModeDefaults = () => {
|
|
9512
|
-
currentPermissionMode = initialPermissionMode;
|
|
9513
9609
|
currentModel = options.model ?? DEFAULT_CLAUDE_MODEL;
|
|
9514
9610
|
currentFallbackModel = void 0;
|
|
9515
9611
|
currentCustomSystemPrompt = void 0;
|
|
@@ -9546,14 +9642,18 @@ async function runClaude(credentials, options = {}) {
|
|
|
9546
9642
|
}
|
|
9547
9643
|
const attachmentsForThisMessage = await session.drainAttachmentsForUserMessage();
|
|
9548
9644
|
let messagePermissionMode = currentPermissionMode;
|
|
9549
|
-
|
|
9645
|
+
const messageCreatedAt = message.createdAt;
|
|
9646
|
+
const staleModeSnapshot = message.meta?.permissionMode !== void 0 && typeof messageCreatedAt === "number" && messageCreatedAt < lastExplicitModeSwitchAt;
|
|
9647
|
+
if (staleModeSnapshot) {
|
|
9648
|
+
persistence.logger.debug(`[loop] Ignoring stale meta.permissionMode=${message.meta?.permissionMode} (message ${messageCreatedAt} predates explicit switch ${lastExplicitModeSwitchAt}); keeping ${currentPermissionMode}`);
|
|
9649
|
+
} else if (message.meta?.permissionMode) {
|
|
9550
9650
|
const previousPermissionMode = currentPermissionMode;
|
|
9551
9651
|
messagePermissionMode = resolveRemoteClaudePermissionMode(
|
|
9552
9652
|
currentPermissionMode,
|
|
9553
9653
|
message.meta.permissionMode,
|
|
9554
9654
|
sandboxEnabled
|
|
9555
9655
|
);
|
|
9556
|
-
|
|
9656
|
+
publishPermissionMode(messagePermissionMode);
|
|
9557
9657
|
const ignoredDefaultDowngrade = (previousPermissionMode === "bypassPermissions" || previousPermissionMode === "yolo") && message.meta.permissionMode === "default" && currentPermissionMode === previousPermissionMode;
|
|
9558
9658
|
if (ignoredDefaultDowngrade) {
|
|
9559
9659
|
persistence.logger.debug(`[loop] Ignoring permission mode downgrade from ${previousPermissionMode} to default`);
|
|
@@ -9810,9 +9910,11 @@ async function runClaude(credentials, options = {}) {
|
|
|
9810
9910
|
},
|
|
9811
9911
|
onAbort: resetCurrentModeDefaults,
|
|
9812
9912
|
onPermissionModeChange: (mode) => {
|
|
9813
|
-
|
|
9814
|
-
|
|
9913
|
+
lastExplicitModeSwitchAt = Date.now();
|
|
9914
|
+
publishPermissionMode(mode);
|
|
9915
|
+
persistence.logger.debug(`[loop] Permission mode updated from session RPC / approval to: ${mode}`);
|
|
9815
9916
|
},
|
|
9917
|
+
onEffectivePermissionMode: (mode) => publishEffectivePermissionMode(mode),
|
|
9816
9918
|
mcpServers: {
|
|
9817
9919
|
"happy": {
|
|
9818
9920
|
type: "http",
|
|
@@ -10955,9 +11057,9 @@ function resolveLocalSignupBootstrap(configuredMode, configuredInviteCodes, gene
|
|
|
10955
11057
|
};
|
|
10956
11058
|
}
|
|
10957
11059
|
|
|
10958
|
-
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-
|
|
11060
|
+
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-FkXJNwiy.cjs', document.baseURI).href)));
|
|
10959
11061
|
const __dirname$1 = path.dirname(__filename$1);
|
|
10960
|
-
const require_ = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-
|
|
11062
|
+
const require_ = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-FkXJNwiy.cjs', document.baseURI).href)));
|
|
10961
11063
|
const PRISMA_QUERY_ENGINE_FILES = {
|
|
10962
11064
|
"arm64-darwin": "libquery_engine-darwin-arm64.dylib.node",
|
|
10963
11065
|
"x64-darwin": "libquery_engine-darwin.dylib.node",
|
|
@@ -13569,7 +13671,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
13569
13671
|
process.exit(0);
|
|
13570
13672
|
} else if (subcommand === "install-terminal-hooks") {
|
|
13571
13673
|
try {
|
|
13572
|
-
const { installTerminalHooks, parseTerminalHooksArgs, TERMINAL_HOOKS_HELP } = await Promise.resolve().then(function () { return require('./installTerminalHooks-
|
|
13674
|
+
const { installTerminalHooks, parseTerminalHooksArgs, TERMINAL_HOOKS_HELP } = await Promise.resolve().then(function () { return require('./installTerminalHooks-CoK5wNcA.cjs'); });
|
|
13573
13675
|
const command = parseTerminalHooksArgs(args.slice(1));
|
|
13574
13676
|
if (command.action === "help") {
|
|
13575
13677
|
console.log(TERMINAL_HOOKS_HELP);
|
|
@@ -13586,7 +13688,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
13586
13688
|
}
|
|
13587
13689
|
} else if (subcommand === "spawn") {
|
|
13588
13690
|
try {
|
|
13589
|
-
const { handleSpawnCommand } = await Promise.resolve().then(function () { return require('./spawn-
|
|
13691
|
+
const { handleSpawnCommand } = await Promise.resolve().then(function () { return require('./spawn-DE7WhS8Y.cjs'); });
|
|
13590
13692
|
await handleSpawnCommand(args.slice(1));
|
|
13591
13693
|
} catch (error) {
|
|
13592
13694
|
console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
|
|
@@ -13598,7 +13700,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
13598
13700
|
return;
|
|
13599
13701
|
} else if (subcommand === "send") {
|
|
13600
13702
|
try {
|
|
13601
|
-
const { handleSendCommand } = await Promise.resolve().then(function () { return require('./send-
|
|
13703
|
+
const { handleSendCommand } = await Promise.resolve().then(function () { return require('./send-DkKOPatx.cjs'); });
|
|
13602
13704
|
await handleSendCommand(args.slice(1));
|
|
13603
13705
|
} catch (error) {
|
|
13604
13706
|
console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
|
|
@@ -13704,9 +13806,9 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
13704
13806
|
if (geminiSubcommand === "project" && args[2] === "set" && args[3]) {
|
|
13705
13807
|
const projectId = args[3];
|
|
13706
13808
|
try {
|
|
13707
|
-
const { saveGoogleCloudProjectToConfig } = await Promise.resolve().then(function () { return require('./config-
|
|
13708
|
-
const { readCredentialsForConfiguredRelay: readCredentialsForConfiguredRelay2 } = await Promise.resolve().then(function () { return require('./types-
|
|
13709
|
-
const { ApiClient: ApiClient2 } = await Promise.resolve().then(function () { return require('./types-
|
|
13809
|
+
const { saveGoogleCloudProjectToConfig } = await Promise.resolve().then(function () { return require('./config-C4NCw7Dz.cjs'); });
|
|
13810
|
+
const { readCredentialsForConfiguredRelay: readCredentialsForConfiguredRelay2 } = await Promise.resolve().then(function () { return require('./types-ClDADuxP.cjs'); }).then(function (n) { return n.persistence; });
|
|
13811
|
+
const { ApiClient: ApiClient2 } = await Promise.resolve().then(function () { return require('./types-ClDADuxP.cjs'); }).then(function (n) { return n.api; });
|
|
13710
13812
|
let userEmail = void 0;
|
|
13711
13813
|
try {
|
|
13712
13814
|
const credentials = await readCredentialsForConfiguredRelay2();
|
|
@@ -13737,7 +13839,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
13737
13839
|
}
|
|
13738
13840
|
if (geminiSubcommand === "project" && args[2] === "get") {
|
|
13739
13841
|
try {
|
|
13740
|
-
const { readGeminiLocalConfig } = await Promise.resolve().then(function () { return require('./config-
|
|
13842
|
+
const { readGeminiLocalConfig } = await Promise.resolve().then(function () { return require('./config-C4NCw7Dz.cjs'); });
|
|
13741
13843
|
const config = readGeminiLocalConfig();
|
|
13742
13844
|
if (config.googleCloudProject) {
|
|
13743
13845
|
console.log(`Current Google Cloud Project: ${config.googleCloudProject}`);
|
|
@@ -13777,7 +13879,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
13777
13879
|
process.exit(0);
|
|
13778
13880
|
}
|
|
13779
13881
|
try {
|
|
13780
|
-
const { runGemini } = await Promise.resolve().then(function () { return require('./runGemini-
|
|
13882
|
+
const { runGemini } = await Promise.resolve().then(function () { return require('./runGemini-Dnvd2gWq.cjs'); });
|
|
13781
13883
|
let startedBy = void 0;
|
|
13782
13884
|
for (let i = 1; i < args.length; i++) {
|
|
13783
13885
|
if (args[i] === "--started-by") {
|
|
@@ -13799,7 +13901,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
13799
13901
|
return;
|
|
13800
13902
|
} else if (subcommand === "acp") {
|
|
13801
13903
|
try {
|
|
13802
|
-
const { runAcp, resolveAcpAgentConfig } = await Promise.resolve().then(function () { return require('./index-
|
|
13904
|
+
const { runAcp, resolveAcpAgentConfig } = await Promise.resolve().then(function () { return require('./index-C1HIm7NY.cjs'); });
|
|
13803
13905
|
let startedBy = void 0;
|
|
13804
13906
|
let verbose = false;
|
|
13805
13907
|
const acpArgs = [];
|
|
@@ -13839,7 +13941,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
13839
13941
|
return;
|
|
13840
13942
|
} else if (subcommand === "openclaw") {
|
|
13841
13943
|
try {
|
|
13842
|
-
const { runOpenClaw } = await Promise.resolve().then(function () { return require('./runOpenClaw-
|
|
13944
|
+
const { runOpenClaw } = await Promise.resolve().then(function () { return require('./runOpenClaw-CnuTBNQW.cjs'); });
|
|
13843
13945
|
let startedBy = void 0;
|
|
13844
13946
|
let verbose = false;
|
|
13845
13947
|
let gatewayUrl;
|
|
@@ -13890,7 +13992,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
13890
13992
|
return;
|
|
13891
13993
|
} else if (subcommand === "mcp" && args.length === 1) {
|
|
13892
13994
|
try {
|
|
13893
|
-
const { handleMcpCommand } = await Promise.resolve().then(function () { return require('./mcp-
|
|
13995
|
+
const { handleMcpCommand } = await Promise.resolve().then(function () { return require('./mcp-DcRvswVI.cjs'); });
|
|
13894
13996
|
await handleMcpCommand();
|
|
13895
13997
|
} catch (error) {
|
|
13896
13998
|
process.stderr.write(`[very-happy mcp] Fatal: ${error instanceof Error ? error.message : String(error)}
|