very-happy-cli 0.2.104 → 0.2.106
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-DDGfk3HJ.cjs → AcpBackend-DMmvLNNM.cjs} +1 -1
- package/dist/{AcpBackend-De4iQ_JG.mjs → AcpBackend-Ux5FD_6F.mjs} +1 -1
- package/dist/{AcpSessionManager-DRzAgHtT.mjs → AcpSessionManager-C1hoU_rK.mjs} +1 -1
- package/dist/{AcpSessionManager-Cdv6Xgwy.cjs → AcpSessionManager-RYkxYWDn.cjs} +1 -1
- package/dist/{config-E3KdWyaQ.mjs → config-DAb5saOC.mjs} +2 -2
- package/dist/{config-CqM5UxVd.cjs → config-Dkn5KcXp.cjs} +2 -2
- package/dist/{index-CX_3uUem.cjs → index-BLW-smJu.cjs} +209 -71
- package/dist/{index--TiLl7-A.mjs → index-CgWdwkhB.mjs} +205 -67
- package/dist/{index-C_dmtMJ6.mjs → index-D2ZzPm58.mjs} +5 -5
- package/dist/{index-De6H3U0N.cjs → index-D48mWUTN.cjs} +2 -2
- package/dist/{index-Bzj1XdPx.mjs → index-DCpgRGWy.mjs} +2 -2
- package/dist/{index-fuavV8uc.cjs → index-Do3JnAi7.cjs} +4 -4
- package/dist/index.cjs +2 -2
- package/dist/index.mjs +2 -2
- package/dist/{installTerminalHooks-BXMBwrvq.cjs → installTerminalHooks-9rn15uP8.cjs} +2 -2
- package/dist/{installTerminalHooks-DV0e8-V3.mjs → installTerminalHooks-l1B-nbWa.mjs} +2 -2
- package/dist/lib.cjs +1 -1
- package/dist/lib.d.cts +6 -0
- package/dist/lib.d.mts +6 -0
- package/dist/lib.mjs +1 -1
- package/dist/{mcp-Cq3On_Qo.cjs → mcp-C3zpbx-m.cjs} +2 -2
- package/dist/{mcp-DFS9Zohz.mjs → mcp-ZvHzv_lJ.mjs} +2 -2
- package/dist/{runGemini-BFjtlkZI.mjs → runGemini-0QqaFN1l.mjs} +4 -4
- package/dist/{runGemini-DFvjh8cO.cjs → runGemini-q20IdxQV.cjs} +4 -4
- package/dist/{runOpenClaw-BFYj1F4u.mjs → runOpenClaw-C6Z6MLHq.mjs} +3 -3
- package/dist/{runOpenClaw-B5Og1FED.cjs → runOpenClaw-CtWkyvDJ.cjs} +3 -3
- package/dist/{send-Bog0YPxo.cjs → send-B8YQyV3D.cjs} +2 -2
- package/dist/{send-B666yos0.mjs → send-DEhUWg8v.mjs} +2 -2
- package/dist/{spawn-DrqvVoNF.mjs → spawn-BzbPyTHU.mjs} +2 -2
- package/dist/{spawn-BSdMkMPX.cjs → spawn-ChmlP1Z_.cjs} +2 -2
- package/dist/{types-14LATr9X.cjs → types-C8-WODFE.cjs} +24 -10
- package/dist/{types-D9LyZitb.mjs → types-lSeHEzPR.mjs} +23 -9
- package/package.json +7 -7
|
@@ -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, userInfo } 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, v as ensurePrivateDirectory, M as MAX_CHAT_ATTACHMENT_SOURCE_BYTES, x as hardenPrivateFile, f as packageJson, i as readSettings, y as readCredentials, z as credentialRelayProblem, B as deriveLocalCliUpdateSummary, j as encodeBase64, C as updateSettings, D as encodeBase64Url, E as decodeBase64, F as writeCredentialsLegacy, G as writeCredentialsDataKey, H as readCredentialsForConfiguredRelay, J as encrypt, r as readPersistedSessions, K as isClaudeSessionId, L as getLocalHappyAgentCredentialPath, N as readLocalHappyAgentCredentials, O as decryptWithDataKey, P as decryptLegacy, Q as extractCompleteLines, S as decideBackfill, T as parseTerminalHookPayload, U as tmuxArgs, V as scrubTmuxClientEnv, W as decideMirrorBinding, X as MIRROR_BACKFILL_LINES_DEFAULT, Y as persistSession, Z as mirrorLineKey, _ as mirrorLocalId, w as writePrivateFileSync, $ as detectResumeSupport, a0 as detectCLIAvailability, a1 as acquireDaemonLock, a2 as summarizeSpawnSessionForLog, a3 as deletePersistedSessions, a4 as shellescape, a5 as decrypt, a6 as writeDaemonState, A as ApiClient, a7 as writeSettings, a8 as fetchCliUpdateState, a9 as resolveCliUpdateCheckInterval, aa as DEFAULT_CLI_UPDATE_CHECK_INTERVAL_MS, ab as releaseDaemonLock, ac as isValidSessionId, ad as listVhTerminals, ae as isValidTerminalId, af as readVhTerminal, ag as sendToVhTerminal, ah as TITLE_PROMPT_PREFIX, ai as BOARD_ANALYZER_PROMPT_PREFIX, h as connectionState, aj as startOfflineReconnection, ak as clearCredentials, al as clearMachineId, k as ensurePrivateDirectorySync, am as SandboxConfigSchema, b as createEnvelope, an as CodexAppServerClient, ao 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, v as ensurePrivateDirectory, M as MAX_CHAT_ATTACHMENT_SOURCE_BYTES, x as hardenPrivateFile, f as packageJson, i as readSettings, y as readCredentials, z as credentialRelayProblem, B as deriveLocalCliUpdateSummary, j as encodeBase64, C as updateSettings, D as encodeBase64Url, E as decodeBase64, F as writeCredentialsLegacy, G as writeCredentialsDataKey, H as readCredentialsForConfiguredRelay, J as encrypt, r as readPersistedSessions, K as isClaudeSessionId, L as getLocalHappyAgentCredentialPath, N as readLocalHappyAgentCredentials, O as decryptWithDataKey, P as decryptLegacy, Q as extractCompleteLines, S as decideBackfill, T as parseTerminalHookPayload, U as tmuxArgs, V as scrubTmuxClientEnv, W as decideMirrorBinding, X as MIRROR_BACKFILL_LINES_DEFAULT, Y as persistSession, Z as mirrorLineKey, _ as mirrorLocalId, w as writePrivateFileSync, $ as detectResumeSupport, a0 as detectCLIAvailability, a1 as acquireDaemonLock, a2 as summarizeSpawnSessionForLog, a3 as deletePersistedSessions, a4 as shellescape, a5 as decrypt, a6 as writeDaemonState, A as ApiClient, a7 as writeSettings, a8 as fetchCliUpdateState, a9 as resolveCliUpdateCheckInterval, aa as DEFAULT_CLI_UPDATE_CHECK_INTERVAL_MS, ab as releaseDaemonLock, ac as isValidSessionId, ad as listVhTerminals, ae as isValidTerminalId, af as readVhTerminal, ag as sendToVhTerminal, ah as TITLE_PROMPT_PREFIX, ai as BOARD_ANALYZER_PROMPT_PREFIX, h as connectionState, aj as startOfflineReconnection, ak as clearCredentials, al as clearMachineId, k as ensurePrivateDirectorySync, am as SandboxConfigSchema, b as createEnvelope, an as CodexAppServerClient, ao as getLatestDaemonLog } from './types-lSeHEzPR.mjs';
|
|
5
5
|
import spawn$1, { spawn } from 'cross-spawn';
|
|
6
6
|
import path, { join, resolve, basename, delimiter, isAbsolute, normalize, sep, dirname } from 'node:path';
|
|
7
7
|
import { createInterface } from 'node:readline';
|
|
@@ -1907,6 +1907,18 @@ async function awaitFileExist(file, timeout = 1e4) {
|
|
|
1907
1907
|
return false;
|
|
1908
1908
|
}
|
|
1909
1909
|
|
|
1910
|
+
function modelTarget(model) {
|
|
1911
|
+
return model == null || model === "" ? void 0 : model;
|
|
1912
|
+
}
|
|
1913
|
+
function needsModelSwitch(current, next) {
|
|
1914
|
+
return modelTarget(current) !== modelTarget(next);
|
|
1915
|
+
}
|
|
1916
|
+
function modelSwitchFailureNotice(model, error) {
|
|
1917
|
+
const name = modelTarget(model) ?? "default";
|
|
1918
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
1919
|
+
return `\u26A0\uFE0F Could not switch to model "${name}" \u2014 continuing with the previous model. ${detail}`;
|
|
1920
|
+
}
|
|
1921
|
+
|
|
1910
1922
|
async function claudeRemote(opts) {
|
|
1911
1923
|
let startFrom = opts.sessionId;
|
|
1912
1924
|
if (opts.sessionId && !claudeCheckSession(opts.sessionId, opts.path)) {
|
|
@@ -2013,11 +2025,12 @@ async function claudeRemote(opts) {
|
|
|
2013
2025
|
if (opts.onQueryReady) {
|
|
2014
2026
|
opts.onQueryReady({
|
|
2015
2027
|
setPermissionMode: (mode2) => response.setPermissionMode(mode2),
|
|
2028
|
+
setModel: (model) => response.setModel(modelTarget(model)),
|
|
2016
2029
|
interrupt: async () => {
|
|
2017
2030
|
await response.interrupt();
|
|
2018
2031
|
},
|
|
2019
2032
|
steer: (message, nextMode) => {
|
|
2020
|
-
mode = nextMode;
|
|
2033
|
+
mode = { ...nextMode, model: mode.model };
|
|
2021
2034
|
messages.push({
|
|
2022
2035
|
type: "user",
|
|
2023
2036
|
parent_tool_use_id: null,
|
|
@@ -2049,7 +2062,10 @@ async function claudeRemote(opts) {
|
|
|
2049
2062
|
mcpServers: systemInit.mcp_servers?.map((s) => ({ name: s.name, status: s.status })),
|
|
2050
2063
|
skills: systemInit.skills,
|
|
2051
2064
|
model: systemInit.model,
|
|
2052
|
-
|
|
2065
|
+
// `mode`, not `initial.mode`: the model can move mid-Query
|
|
2066
|
+
// via setModel, and init is re-emitted every turn with the
|
|
2067
|
+
// model actually in force.
|
|
2068
|
+
modelIsDefault: modelTarget(mode.model) === void 0,
|
|
2053
2069
|
// The SDK's own verdict on the mode it will enforce —
|
|
2054
2070
|
// settings (permissions.deny/ask/defaultMode/
|
|
2055
2071
|
// disableBypassPermissionsMode) can override what we
|
|
@@ -2094,19 +2110,29 @@ async function claudeRemote(opts) {
|
|
|
2094
2110
|
messages.end();
|
|
2095
2111
|
continue;
|
|
2096
2112
|
}
|
|
2097
|
-
opts.nextMessage().then((next) => {
|
|
2113
|
+
opts.nextMessage().then(async (next) => {
|
|
2098
2114
|
if (!next) {
|
|
2099
2115
|
messages.end();
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2116
|
+
return;
|
|
2117
|
+
}
|
|
2118
|
+
if (needsModelSwitch(mode.model, next.mode.model)) {
|
|
2119
|
+
try {
|
|
2120
|
+
await response.setModel(modelTarget(next.mode.model));
|
|
2121
|
+
logger.debug(`[claudeRemote] Model switched to ${modelTarget(next.mode.model) ?? "default"}`);
|
|
2122
|
+
} catch (e) {
|
|
2123
|
+
logger.debug(`[claudeRemote] setModel failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
2124
|
+
opts.onCompletionEvent?.(modelSwitchFailureNotice(next.mode.model, e));
|
|
2125
|
+
next = { ...next, mode: { ...next.mode, model: mode.model } };
|
|
2126
|
+
}
|
|
2109
2127
|
}
|
|
2128
|
+
mode = next.mode;
|
|
2129
|
+
updateThinking(true);
|
|
2130
|
+
messages.push({
|
|
2131
|
+
type: "user",
|
|
2132
|
+
parent_tool_use_id: null,
|
|
2133
|
+
origin: { kind: "human" },
|
|
2134
|
+
message: { role: "user", content: next.message }
|
|
2135
|
+
});
|
|
2110
2136
|
}).catch(() => {
|
|
2111
2137
|
messages.end();
|
|
2112
2138
|
});
|
|
@@ -3387,6 +3413,12 @@ function applyClaudeSdkMetadata(current, update) {
|
|
|
3387
3413
|
skills: update.skills,
|
|
3388
3414
|
attachmentKinds: [...CLAUDE_ATTACHMENT_KINDS],
|
|
3389
3415
|
queueCancellation: true,
|
|
3416
|
+
// The model Claude Code reports it is ACTUALLY running. system/init is
|
|
3417
|
+
// re-emitted at every turn boundary (verified against the pinned SDK,
|
|
3418
|
+
// 2026-09-03), including after a live setModel, so this is the web's
|
|
3419
|
+
// only ground truth for "did my switch take effect" — the picker
|
|
3420
|
+
// otherwise renders nothing but the client's own optimistic intent.
|
|
3421
|
+
...update.model ? { currentModelCode: update.model } : {},
|
|
3390
3422
|
...update.modelIsDefault && update.model ? { defaultModelCode: update.model } : {}
|
|
3391
3423
|
};
|
|
3392
3424
|
}
|
|
@@ -3421,6 +3453,102 @@ function createTurnSteeringController() {
|
|
|
3421
3453
|
};
|
|
3422
3454
|
}
|
|
3423
3455
|
|
|
3456
|
+
class LaunchModeGate {
|
|
3457
|
+
constructor(hasher) {
|
|
3458
|
+
this.hasher = hasher;
|
|
3459
|
+
}
|
|
3460
|
+
currentMode = null;
|
|
3461
|
+
currentHash = null;
|
|
3462
|
+
parked = null;
|
|
3463
|
+
/** The mode this launch is running, or null before the first message. */
|
|
3464
|
+
get mode() {
|
|
3465
|
+
return this.currentMode;
|
|
3466
|
+
}
|
|
3467
|
+
/** Hash of {@link mode}; null means "not armed yet — accept anything". */
|
|
3468
|
+
get hash() {
|
|
3469
|
+
return this.currentHash;
|
|
3470
|
+
}
|
|
3471
|
+
/** Whether a message has been adopted into this launch yet. */
|
|
3472
|
+
get armed() {
|
|
3473
|
+
return this.currentHash !== null;
|
|
3474
|
+
}
|
|
3475
|
+
/** Bind the launch to `mode`. Idempotent; safe to call with the same mode. */
|
|
3476
|
+
adopt(mode) {
|
|
3477
|
+
this.currentMode = mode;
|
|
3478
|
+
this.currentHash = this.hasher(mode);
|
|
3479
|
+
}
|
|
3480
|
+
/**
|
|
3481
|
+
* Re-adopt the current mode with one field replaced. No-op before the first
|
|
3482
|
+
* adopt: there is nothing to derive from, and arming here would make the
|
|
3483
|
+
* first real message look like a mode change.
|
|
3484
|
+
*/
|
|
3485
|
+
amend(patch) {
|
|
3486
|
+
if (this.currentMode === null) return null;
|
|
3487
|
+
this.adopt({ ...this.currentMode, ...patch });
|
|
3488
|
+
return this.currentMode;
|
|
3489
|
+
}
|
|
3490
|
+
/**
|
|
3491
|
+
* True when `incomingHash` cannot run on this launch's Query and must be
|
|
3492
|
+
* parked for a fresh one. An un-armed gate accepts anything — that is how a
|
|
3493
|
+
* new launch takes its first message, including a replayed parked one.
|
|
3494
|
+
*/
|
|
3495
|
+
requiresRelaunch(incomingHash, isolate) {
|
|
3496
|
+
if (isolate) return true;
|
|
3497
|
+
return this.armed && incomingHash !== this.currentHash;
|
|
3498
|
+
}
|
|
3499
|
+
/** True when `mode` is exactly what this launch adopted (Steer's precondition). */
|
|
3500
|
+
matches(mode) {
|
|
3501
|
+
return this.armed && this.hasher(mode) === this.currentHash;
|
|
3502
|
+
}
|
|
3503
|
+
/**
|
|
3504
|
+
* Hold a message that cannot run on this launch until its successor picks
|
|
3505
|
+
* it up. Survives {@link reset} — the parked message is precisely what the
|
|
3506
|
+
* next launch exists to run.
|
|
3507
|
+
*/
|
|
3508
|
+
park(message) {
|
|
3509
|
+
this.parked = message;
|
|
3510
|
+
}
|
|
3511
|
+
/** Whether a parked message is waiting for the next launch. */
|
|
3512
|
+
get hasParked() {
|
|
3513
|
+
return this.parked !== null;
|
|
3514
|
+
}
|
|
3515
|
+
/**
|
|
3516
|
+
* Take the parked message AND adopt its mode in one step.
|
|
3517
|
+
*
|
|
3518
|
+
* This pairing is the whole point of the class. When parking and adopting
|
|
3519
|
+
* were separate — a `pending` variable in the launcher next to a `modeHash`
|
|
3520
|
+
* one — the replay path took the message and forgot to adopt, so the gate
|
|
3521
|
+
* stayed un-armed and swallowed the NEXT mode change into a Query built for
|
|
3522
|
+
* the previous one. Nothing structural tied the two, and no unit test could
|
|
3523
|
+
* reach the wiring. Here they cannot come apart.
|
|
3524
|
+
*/
|
|
3525
|
+
takeParked() {
|
|
3526
|
+
const message = this.parked;
|
|
3527
|
+
if (!message) return null;
|
|
3528
|
+
this.parked = null;
|
|
3529
|
+
this.adopt(message.mode);
|
|
3530
|
+
return message;
|
|
3531
|
+
}
|
|
3532
|
+
/**
|
|
3533
|
+
* Re-adopt the parked message with a patched mode. Used when an explicit
|
|
3534
|
+
* mode switch lands while a message is parked: the switch is newer than the
|
|
3535
|
+
* snapshot the message carried when it was queued.
|
|
3536
|
+
*/
|
|
3537
|
+
amendParked(patch) {
|
|
3538
|
+
if (!this.parked) return;
|
|
3539
|
+
this.parked = { ...this.parked, mode: { ...this.parked.mode, ...patch } };
|
|
3540
|
+
}
|
|
3541
|
+
/**
|
|
3542
|
+
* Drop back to un-armed. Called when a launch ends. Deliberately does NOT
|
|
3543
|
+
* clear a parked message: parking happens in the launch that is ending, and
|
|
3544
|
+
* the message belongs to the one about to start.
|
|
3545
|
+
*/
|
|
3546
|
+
reset() {
|
|
3547
|
+
this.currentMode = null;
|
|
3548
|
+
this.currentHash = null;
|
|
3549
|
+
}
|
|
3550
|
+
}
|
|
3551
|
+
|
|
3424
3552
|
async function claudeRemoteLauncher(session, onPermissionModeChange, onEffectivePermissionMode) {
|
|
3425
3553
|
logger.debug("[claudeRemoteLauncher] Starting remote launcher");
|
|
3426
3554
|
const hasTTY = process.stdout.isTTY && process.stdin.isTTY;
|
|
@@ -3628,7 +3756,7 @@ async function claudeRemoteLauncher(session, onPermissionModeChange, onEffective
|
|
|
3628
3756
|
}
|
|
3629
3757
|
}
|
|
3630
3758
|
try {
|
|
3631
|
-
|
|
3759
|
+
const modeGate = new LaunchModeGate(session.queue.modeHasher);
|
|
3632
3760
|
let previousSessionId = null;
|
|
3633
3761
|
while (!exitReason) {
|
|
3634
3762
|
logger.debug("[remote]: launch");
|
|
@@ -3647,18 +3775,11 @@ async function claudeRemoteLauncher(session, onPermissionModeChange, onEffective
|
|
|
3647
3775
|
const controller = new AbortController();
|
|
3648
3776
|
abortController = controller;
|
|
3649
3777
|
abortFuture = new Future();
|
|
3650
|
-
let modeHash = null;
|
|
3651
|
-
let mode = null;
|
|
3652
3778
|
const commitPermissionMode = (nextMode) => {
|
|
3653
3779
|
permissionHandler.handleModeChange(nextMode);
|
|
3654
|
-
|
|
3655
|
-
mode = { ...mode, permissionMode: nextMode };
|
|
3656
|
-
modeHash = session.queue.modeHasher(mode);
|
|
3657
|
-
}
|
|
3780
|
+
modeGate.amend({ permissionMode: nextMode });
|
|
3658
3781
|
rewriteQueuedPermissionMode(session.queue.queue, session.queue.modeHasher, nextMode);
|
|
3659
|
-
|
|
3660
|
-
pending = { ...pending, mode: { ...pending.mode, permissionMode: nextMode } };
|
|
3661
|
-
}
|
|
3782
|
+
modeGate.amendParked({ permissionMode: nextMode });
|
|
3662
3783
|
onPermissionModeChange?.(nextMode);
|
|
3663
3784
|
return nextMode;
|
|
3664
3785
|
};
|
|
@@ -3684,22 +3805,28 @@ async function claudeRemoteLauncher(session, onPermissionModeChange, onEffective
|
|
|
3684
3805
|
return permissionHandler.isAborted(toolCallId);
|
|
3685
3806
|
},
|
|
3686
3807
|
nextMessage: async () => {
|
|
3687
|
-
|
|
3688
|
-
|
|
3689
|
-
|
|
3690
|
-
|
|
3691
|
-
return p;
|
|
3808
|
+
const parked = modeGate.takeParked();
|
|
3809
|
+
if (parked) {
|
|
3810
|
+
permissionHandler.handleModeChange(parked.mode.permissionMode);
|
|
3811
|
+
return parked;
|
|
3692
3812
|
}
|
|
3693
3813
|
let msg = await session.queue.waitForMessagesAndGetAsString(controller.signal);
|
|
3694
3814
|
if (msg) {
|
|
3695
|
-
if (
|
|
3815
|
+
if (modeGate.requiresRelaunch(msg.hash, msg.isolate)) {
|
|
3696
3816
|
logger.debug("[remote]: mode has changed, pending message");
|
|
3697
|
-
|
|
3817
|
+
const parkedAttachments = msg.attachments ?? [];
|
|
3818
|
+
const parkedStaged = parkedAttachments.length > 0 ? await stageClaudeAttachments(parkedAttachments, {
|
|
3819
|
+
happyHomeDir: configuration.happyHomeDir,
|
|
3820
|
+
sessionId: session.client.sessionId
|
|
3821
|
+
}) : [];
|
|
3822
|
+
modeGate.park({
|
|
3823
|
+
message: parkedStaged.length > 0 ? appendStagedAttachmentsToPrompt(msg.message, parkedStaged) : msg.message,
|
|
3824
|
+
mode: msg.mode
|
|
3825
|
+
});
|
|
3698
3826
|
return null;
|
|
3699
3827
|
}
|
|
3700
|
-
|
|
3701
|
-
|
|
3702
|
-
permissionHandler.handleModeChange(mode.permissionMode);
|
|
3828
|
+
modeGate.adopt(msg.mode);
|
|
3829
|
+
permissionHandler.handleModeChange(msg.mode.permissionMode);
|
|
3703
3830
|
const attachments = msg.attachments ?? [];
|
|
3704
3831
|
if (attachments.length > 0) {
|
|
3705
3832
|
const staged = await stageClaudeAttachments(attachments, {
|
|
@@ -3736,8 +3863,7 @@ async function claudeRemoteLauncher(session, onPermissionModeChange, onEffective
|
|
|
3736
3863
|
onQueryReady: (q) => {
|
|
3737
3864
|
turnSteering.setInterrupt(q.interrupt);
|
|
3738
3865
|
session.setSteerHandler(async (input) => {
|
|
3739
|
-
|
|
3740
|
-
if (!modeHash || expectedHash !== modeHash) return false;
|
|
3866
|
+
if (!modeGate.matches(input.mode)) return false;
|
|
3741
3867
|
let message = input.message;
|
|
3742
3868
|
if (input.attachments?.length) {
|
|
3743
3869
|
const staged = await stageClaudeAttachments(input.attachments, {
|
|
@@ -3746,19 +3872,16 @@ async function claudeRemoteLauncher(session, onPermissionModeChange, onEffective
|
|
|
3746
3872
|
});
|
|
3747
3873
|
message = appendStagedAttachmentsToPrompt(input.message, staged);
|
|
3748
3874
|
}
|
|
3749
|
-
if (!session.thinking ||
|
|
3875
|
+
if (!session.thinking || !modeGate.matches(input.mode)) return false;
|
|
3750
3876
|
q.steer(message, input.mode);
|
|
3751
3877
|
return true;
|
|
3752
3878
|
});
|
|
3753
|
-
permissionHandler.setPermissionModeUpdater(async (
|
|
3754
|
-
await q.setPermissionMode(
|
|
3879
|
+
permissionHandler.setPermissionModeUpdater(async (mode) => {
|
|
3880
|
+
await q.setPermissionMode(mode);
|
|
3755
3881
|
});
|
|
3756
3882
|
livePermissionModeHandler = async (nextMode) => {
|
|
3757
3883
|
await permissionHandler.setLivePermissionMode(nextMode);
|
|
3758
|
-
|
|
3759
|
-
mode = { ...mode, permissionMode: nextMode };
|
|
3760
|
-
modeHash = session.queue.modeHasher(mode);
|
|
3761
|
-
}
|
|
3884
|
+
modeGate.amend({ permissionMode: nextMode });
|
|
3762
3885
|
onPermissionModeChange?.(nextMode);
|
|
3763
3886
|
return nextMode;
|
|
3764
3887
|
};
|
|
@@ -3789,7 +3912,7 @@ async function claudeRemoteLauncher(session, onPermissionModeChange, onEffective
|
|
|
3789
3912
|
closeFailed: (error) => session.client.closeClaudeSessionTurn("failed", { error }),
|
|
3790
3913
|
onFailed: (error) => session.onSessionError(error),
|
|
3791
3914
|
onCompleted: () => {
|
|
3792
|
-
const idle = !
|
|
3915
|
+
const idle = !modeGate.hasParked && session.queue.size() === 0;
|
|
3793
3916
|
session.onTurnEnd(idle);
|
|
3794
3917
|
if (idle) {
|
|
3795
3918
|
session.api.push().sendSessionNotification({
|
|
@@ -3848,8 +3971,7 @@ async function claudeRemoteLauncher(session, onPermissionModeChange, onEffective
|
|
|
3848
3971
|
abortFuture = null;
|
|
3849
3972
|
logger.debug("[remote]: launch done");
|
|
3850
3973
|
permissionHandler.reset();
|
|
3851
|
-
|
|
3852
|
-
mode = null;
|
|
3974
|
+
modeGate.reset();
|
|
3853
3975
|
}
|
|
3854
3976
|
}
|
|
3855
3977
|
} finally {
|
|
@@ -4146,6 +4268,7 @@ class MessageQueue2 {
|
|
|
4146
4268
|
while (this.queue.length > 0 && this.queue[0].modeHash === targetModeHash && !this.queue[0].isolate) {
|
|
4147
4269
|
const item = this.queue.shift();
|
|
4148
4270
|
sameModeMessages.push(item.message);
|
|
4271
|
+
mode = item.mode;
|
|
4149
4272
|
if (item.attachments) collectedAttachments.push(...item.attachments);
|
|
4150
4273
|
}
|
|
4151
4274
|
logger.debug(`[MessageQueue2] Collected batch of ${sameModeMessages.length} messages with mode hash: ${targetModeHash}`);
|
|
@@ -4287,6 +4410,18 @@ function hashObject(obj, options, encoding = "hex") {
|
|
|
4287
4410
|
return createHash("sha256").update(jsonString).digest(encoding);
|
|
4288
4411
|
}
|
|
4289
4412
|
|
|
4413
|
+
function claudeModeHash(mode) {
|
|
4414
|
+
return hashObject({
|
|
4415
|
+
isPlan: mode.permissionMode === "plan",
|
|
4416
|
+
fallbackModel: mode.fallbackModel,
|
|
4417
|
+
customSystemPrompt: mode.customSystemPrompt,
|
|
4418
|
+
appendSystemPrompt: mode.appendSystemPrompt,
|
|
4419
|
+
allowedTools: mode.allowedTools,
|
|
4420
|
+
disallowedTools: mode.disallowedTools,
|
|
4421
|
+
effort: mode.effort
|
|
4422
|
+
});
|
|
4423
|
+
}
|
|
4424
|
+
|
|
4290
4425
|
function assistantSpawnTags(env = process.env) {
|
|
4291
4426
|
if (env.HAPPY_SPAWNED_BY !== "assistant") return void 0;
|
|
4292
4427
|
if (env.HAPPY_SESSION_VARIANT === "assistant") return void 0;
|
|
@@ -7836,6 +7971,12 @@ async function claimSessionOrExit(happySessionId, options) {
|
|
|
7836
7971
|
}
|
|
7837
7972
|
|
|
7838
7973
|
const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
7974
|
+
function sanitizeImportTitle(value) {
|
|
7975
|
+
if (typeof value !== "string") return null;
|
|
7976
|
+
const collapsed = value.replace(/[\u0000-\u001f\u007f]/g, " ").replace(/\s+/g, " ").trim();
|
|
7977
|
+
if (collapsed.length === 0) return null;
|
|
7978
|
+
return collapsed.length > 200 ? `${collapsed.slice(0, 199)}\u2026` : collapsed;
|
|
7979
|
+
}
|
|
7839
7980
|
const hostSuffix = process.env.HAPPY_VARIANT === "dev" ? "-dev" : "";
|
|
7840
7981
|
const initialMachineMetadata = {
|
|
7841
7982
|
host: os$1.hostname() + hostSuffix,
|
|
@@ -8174,6 +8315,10 @@ async function startDaemon() {
|
|
|
8174
8315
|
if (options.importedFromClaudeSessionId && UUID_RE.test(options.importedFromClaudeSessionId)) {
|
|
8175
8316
|
extraEnv.HAPPY_IMPORTED_FROM_CLAUDE_SESSION_ID = options.importedFromClaudeSessionId;
|
|
8176
8317
|
}
|
|
8318
|
+
const importTitle = sanitizeImportTitle(options.importTitle);
|
|
8319
|
+
if (importTitle) {
|
|
8320
|
+
extraEnv.HAPPY_IMPORT_TITLE = importTitle;
|
|
8321
|
+
}
|
|
8177
8322
|
if (options.resumeCodexThreadId) {
|
|
8178
8323
|
extraEnv.HAPPY_FORK_CODEX_THREAD_ID = options.resumeCodexThreadId;
|
|
8179
8324
|
}
|
|
@@ -10035,7 +10180,7 @@ function registerSideQuestionHandler(rpc, deps) {
|
|
|
10035
10180
|
const retainMs = deps.retainMs ?? SIDE_QUESTION_RETAIN_MS;
|
|
10036
10181
|
const maxRunMs = deps.maxRunMs ?? SIDE_QUESTION_MAX_RUN_MS;
|
|
10037
10182
|
const run = deps.run ?? (async (input) => {
|
|
10038
|
-
const { query } = await import('./index-
|
|
10183
|
+
const { query } = await import('./index-DCpgRGWy.mjs');
|
|
10039
10184
|
return runSideQuestion(query, input);
|
|
10040
10185
|
});
|
|
10041
10186
|
const slots = /* @__PURE__ */ new Map();
|
|
@@ -10574,6 +10719,7 @@ async function runClaude(credentials, options = {}) {
|
|
|
10574
10719
|
const forkedFromSessionId = process.env.HAPPY_FORKED_FROM_SESSION_ID;
|
|
10575
10720
|
const forkedFromMessageId = process.env.HAPPY_FORKED_FROM_MESSAGE_ID;
|
|
10576
10721
|
const importedFromClaudeSessionId = process.env.HAPPY_IMPORTED_FROM_CLAUDE_SESSION_ID;
|
|
10722
|
+
const importTitle = process.env.HAPPY_IMPORT_TITLE;
|
|
10577
10723
|
let metadata = {
|
|
10578
10724
|
path: workingDirectory,
|
|
10579
10725
|
host: os.hostname(),
|
|
@@ -10604,6 +10750,7 @@ async function runClaude(credentials, options = {}) {
|
|
|
10604
10750
|
...forkedFromSessionId ? { parentSessionId: forkedFromSessionId } : {},
|
|
10605
10751
|
...forkedFromMessageId ? { forkedFromMessageId } : {},
|
|
10606
10752
|
...importedFromClaudeSessionId ? { importedFromClaudeSessionId } : {},
|
|
10753
|
+
...importTitle ? { summary: { text: importTitle, updatedAt: Date.now() } } : {},
|
|
10607
10754
|
...isAssistantVariant ? { variant: "assistant" } : {},
|
|
10608
10755
|
// B-091: sessions the assistant dispatched (daemon spawn RPC exports
|
|
10609
10756
|
// HAPPY_SPAWNED_BY, B-069) are born with the 'assistant' tag so every
|
|
@@ -10834,16 +10981,7 @@ async function runClaude(credentials, options = {}) {
|
|
|
10834
10981
|
...currentState,
|
|
10835
10982
|
controlledByUser: options.startingMode !== "remote"
|
|
10836
10983
|
}));
|
|
10837
|
-
const messageQueue = new MessageQueue2(
|
|
10838
|
-
isPlan: mode.permissionMode === "plan",
|
|
10839
|
-
model: mode.model,
|
|
10840
|
-
fallbackModel: mode.fallbackModel,
|
|
10841
|
-
customSystemPrompt: mode.customSystemPrompt,
|
|
10842
|
-
appendSystemPrompt: mode.appendSystemPrompt,
|
|
10843
|
-
allowedTools: mode.allowedTools,
|
|
10844
|
-
disallowedTools: mode.disallowedTools,
|
|
10845
|
-
effort: mode.effort
|
|
10846
|
-
}));
|
|
10984
|
+
const messageQueue = new MessageQueue2(claudeModeHash);
|
|
10847
10985
|
session.rpcHandlerManager.registerHandler("cancelQueuedMessage", async (params) => ({
|
|
10848
10986
|
removed: messageQueue.cancelPending(
|
|
10849
10987
|
typeof params?.localKey === "string" ? params.localKey : void 0,
|
|
@@ -14970,7 +15108,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
14970
15108
|
process.exit(0);
|
|
14971
15109
|
} else if (subcommand === "install-terminal-hooks") {
|
|
14972
15110
|
try {
|
|
14973
|
-
const { installTerminalHooks, parseTerminalHooksArgs, TERMINAL_HOOKS_HELP } = await import('./installTerminalHooks-
|
|
15111
|
+
const { installTerminalHooks, parseTerminalHooksArgs, TERMINAL_HOOKS_HELP } = await import('./installTerminalHooks-l1B-nbWa.mjs');
|
|
14974
15112
|
const command = parseTerminalHooksArgs(args.slice(1));
|
|
14975
15113
|
if (command.action === "help") {
|
|
14976
15114
|
console.log(TERMINAL_HOOKS_HELP);
|
|
@@ -14987,7 +15125,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
14987
15125
|
}
|
|
14988
15126
|
} else if (subcommand === "spawn") {
|
|
14989
15127
|
try {
|
|
14990
|
-
const { handleSpawnCommand } = await import('./spawn-
|
|
15128
|
+
const { handleSpawnCommand } = await import('./spawn-BzbPyTHU.mjs');
|
|
14991
15129
|
await handleSpawnCommand(args.slice(1));
|
|
14992
15130
|
} catch (error) {
|
|
14993
15131
|
console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
|
|
@@ -14999,7 +15137,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
14999
15137
|
return;
|
|
15000
15138
|
} else if (subcommand === "send") {
|
|
15001
15139
|
try {
|
|
15002
|
-
const { handleSendCommand } = await import('./send-
|
|
15140
|
+
const { handleSendCommand } = await import('./send-DEhUWg8v.mjs');
|
|
15003
15141
|
await handleSendCommand(args.slice(1));
|
|
15004
15142
|
} catch (error) {
|
|
15005
15143
|
console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
|
|
@@ -15105,9 +15243,9 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
15105
15243
|
if (geminiSubcommand === "project" && args[2] === "set" && args[3]) {
|
|
15106
15244
|
const projectId = args[3];
|
|
15107
15245
|
try {
|
|
15108
|
-
const { saveGoogleCloudProjectToConfig } = await import('./config-
|
|
15109
|
-
const { readCredentialsForConfiguredRelay: readCredentialsForConfiguredRelay2 } = await import('./types-
|
|
15110
|
-
const { ApiClient: ApiClient2 } = await import('./types-
|
|
15246
|
+
const { saveGoogleCloudProjectToConfig } = await import('./config-DAb5saOC.mjs');
|
|
15247
|
+
const { readCredentialsForConfiguredRelay: readCredentialsForConfiguredRelay2 } = await import('./types-lSeHEzPR.mjs').then(function (n) { return n.ap; });
|
|
15248
|
+
const { ApiClient: ApiClient2 } = await import('./types-lSeHEzPR.mjs').then(function (n) { return n.aq; });
|
|
15111
15249
|
let userEmail = void 0;
|
|
15112
15250
|
try {
|
|
15113
15251
|
const credentials = await readCredentialsForConfiguredRelay2();
|
|
@@ -15138,7 +15276,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
15138
15276
|
}
|
|
15139
15277
|
if (geminiSubcommand === "project" && args[2] === "get") {
|
|
15140
15278
|
try {
|
|
15141
|
-
const { readGeminiLocalConfig } = await import('./config-
|
|
15279
|
+
const { readGeminiLocalConfig } = await import('./config-DAb5saOC.mjs');
|
|
15142
15280
|
const config = readGeminiLocalConfig();
|
|
15143
15281
|
if (config.googleCloudProject) {
|
|
15144
15282
|
console.log(`Current Google Cloud Project: ${config.googleCloudProject}`);
|
|
@@ -15178,7 +15316,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
15178
15316
|
process.exit(0);
|
|
15179
15317
|
}
|
|
15180
15318
|
try {
|
|
15181
|
-
const { runGemini } = await import('./runGemini-
|
|
15319
|
+
const { runGemini } = await import('./runGemini-0QqaFN1l.mjs');
|
|
15182
15320
|
let startedBy = void 0;
|
|
15183
15321
|
for (let i = 1; i < args.length; i++) {
|
|
15184
15322
|
if (args[i] === "--started-by") {
|
|
@@ -15200,7 +15338,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
15200
15338
|
return;
|
|
15201
15339
|
} else if (subcommand === "acp") {
|
|
15202
15340
|
try {
|
|
15203
|
-
const { runAcp, resolveAcpAgentConfig } = await import('./index-
|
|
15341
|
+
const { runAcp, resolveAcpAgentConfig } = await import('./index-D2ZzPm58.mjs');
|
|
15204
15342
|
let startedBy = void 0;
|
|
15205
15343
|
let verbose = false;
|
|
15206
15344
|
const acpArgs = [];
|
|
@@ -15240,7 +15378,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
15240
15378
|
return;
|
|
15241
15379
|
} else if (subcommand === "openclaw") {
|
|
15242
15380
|
try {
|
|
15243
|
-
const { runOpenClaw } = await import('./runOpenClaw-
|
|
15381
|
+
const { runOpenClaw } = await import('./runOpenClaw-C6Z6MLHq.mjs');
|
|
15244
15382
|
let startedBy = void 0;
|
|
15245
15383
|
let verbose = false;
|
|
15246
15384
|
let gatewayUrl;
|
|
@@ -15291,7 +15429,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
15291
15429
|
return;
|
|
15292
15430
|
} else if (subcommand === "mcp" && args.length === 1) {
|
|
15293
15431
|
try {
|
|
15294
|
-
const { handleMcpCommand } = await import('./mcp-
|
|
15432
|
+
const { handleMcpCommand } = await import('./mcp-ZvHzv_lJ.mjs');
|
|
15295
15433
|
await handleMcpCommand();
|
|
15296
15434
|
} catch (error) {
|
|
15297
15435
|
process.stderr.write(`[very-happy mcp] Fatal: ${error instanceof Error ? error.message : String(error)}
|
|
@@ -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-Ux5FD_6F.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-Ux5FD_6F.mjs';
|
|
3
|
+
import { h as connectionState, A as ApiClient, i as readSettings, j as encodeBase64, l as logger, p as projectPath } from './types-lSeHEzPR.mjs';
|
|
4
|
+
import { A as AcpSessionManager } from './AcpSessionManager-C1hoU_rK.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-CgWdwkhB.mjs';
|
|
8
8
|
import 'node:child_process';
|
|
9
9
|
import '@agentclientprotocol/sdk';
|
|
10
10
|
import 'axios';
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var index = require('./index-
|
|
3
|
+
var index = require('./index-BLW-smJu.cjs');
|
|
4
4
|
var claudeAgentSdk = require('@anthropic-ai/claude-agent-sdk');
|
|
5
5
|
require('chalk');
|
|
6
6
|
require('node:os');
|
|
7
7
|
require('node:crypto');
|
|
8
|
-
require('./types-
|
|
8
|
+
require('./types-C8-WODFE.cjs');
|
|
9
9
|
require('axios');
|
|
10
10
|
require('node:util');
|
|
11
11
|
require('node:fs');
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { q as query } from './index
|
|
1
|
+
import { q as query } from './index-CgWdwkhB.mjs';
|
|
2
2
|
export { AbortError } from '@anthropic-ai/claude-agent-sdk';
|
|
3
3
|
import 'chalk';
|
|
4
4
|
import 'node:os';
|
|
5
5
|
import 'node:crypto';
|
|
6
|
-
import './types-
|
|
6
|
+
import './types-lSeHEzPR.mjs';
|
|
7
7
|
import 'axios';
|
|
8
8
|
import 'node:util';
|
|
9
9
|
import 'node:fs';
|
|
@@ -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-DMmvLNNM.cjs');
|
|
4
|
+
var persistence = require('./types-C8-WODFE.cjs');
|
|
5
|
+
var AcpSessionManager = require('./AcpSessionManager-RYkxYWDn.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-BLW-smJu.cjs');
|
|
9
9
|
require('node:child_process');
|
|
10
10
|
require('@agentclientprotocol/sdk');
|
|
11
11
|
require('axios');
|
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-C8-WODFE.cjs');
|
|
9
|
+
var index = require('./index-BLW-smJu.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-lSeHEzPR.mjs';
|
|
7
|
+
import { t as tmuxSupportsSessionEnv } from './index-CgWdwkhB.mjs';
|
|
8
8
|
import 'axios';
|
|
9
9
|
import 'node:util';
|
|
10
10
|
import 'node:fs/promises';
|
package/dist/lib.cjs
CHANGED
package/dist/lib.d.cts
CHANGED
|
@@ -444,6 +444,7 @@ declare const UserMessageSchema: z$1.ZodObject<{
|
|
|
444
444
|
appendSystemPrompt: z$1.ZodOptional<z$1.ZodNullable<z$1.ZodString>>;
|
|
445
445
|
allowedTools: z$1.ZodOptional<z$1.ZodNullable<z$1.ZodArray<z$1.ZodString>>>;
|
|
446
446
|
disallowedTools: z$1.ZodOptional<z$1.ZodNullable<z$1.ZodArray<z$1.ZodString>>>;
|
|
447
|
+
effort: z$1.ZodOptional<z$1.ZodNullable<z$1.ZodString>>;
|
|
447
448
|
delivery: z$1.ZodOptional<z$1.ZodEnum<{
|
|
448
449
|
queue: "queue";
|
|
449
450
|
steer: "steer";
|
|
@@ -1001,6 +1002,11 @@ interface SpawnSessionOptions {
|
|
|
1001
1002
|
* metadata so the import picker hides it. Old daemons ignore the field.
|
|
1002
1003
|
*/
|
|
1003
1004
|
importedFromClaudeSessionId?: string;
|
|
1005
|
+
/**
|
|
1006
|
+
* B-294: title to stamp on the imported session's metadata (the source
|
|
1007
|
+
* conversation's summary / first prompt). Sanitized daemon-side.
|
|
1008
|
+
*/
|
|
1009
|
+
importTitle?: string;
|
|
1004
1010
|
/**
|
|
1005
1011
|
* B-051: spawn the machine's assistant (meta-agent) session. The daemon
|
|
1006
1012
|
* forces cwd to ~/.happy/assistant (the passed `directory` is ignored),
|