very-happy-cli 0.2.92 → 0.2.94
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-BP7id8L6.cjs → AcpBackend-DoSXb9La.cjs} +1 -1
- package/dist/{AcpBackend-DDEsgc1c.mjs → AcpBackend-Ds4mP02F.mjs} +1 -1
- package/dist/{AcpSessionManager-C29t6wb_.mjs → AcpSessionManager-B6RqjyQS.mjs} +1 -1
- package/dist/{AcpSessionManager-Cys1Hsb8.cjs → AcpSessionManager-DQ6j5fp4.cjs} +1 -1
- package/dist/{config-B77vhdwT.cjs → config-IdMPfmwy.cjs} +2 -2
- package/dist/{config-CJQw0z1o.mjs → config-yrZNEia7.mjs} +2 -2
- package/dist/{index-8LDXVYWi.mjs → index-27948eGz.mjs} +133 -12
- package/dist/{index-L3o5Gz-2.cjs → index-BfCdbWQI.cjs} +4 -4
- package/dist/{index-BP9pfzdZ.mjs → index-DXpQrR4U.mjs} +5 -5
- package/dist/{index-B63Vjt4W.cjs → index-bqUSeHWU.cjs} +136 -15
- package/dist/index.cjs +2 -2
- package/dist/index.mjs +2 -2
- package/dist/{installTerminalHooks-BBc2nij4.cjs → installTerminalHooks-D0gCqzZu.cjs} +2 -2
- package/dist/{installTerminalHooks-DDRrUG_n.mjs → installTerminalHooks-dVZoe8om.mjs} +2 -2
- package/dist/lib.cjs +1 -1
- package/dist/lib.d.cts +9 -0
- package/dist/lib.d.mts +9 -0
- package/dist/lib.mjs +1 -1
- package/dist/{mcp-CYJAl5pk.mjs → mcp-BvDgylsM.mjs} +2 -2
- package/dist/{mcp-DbYXyw1U.cjs → mcp-CRcmpUpX.cjs} +2 -2
- package/dist/{runGemini-BDSWSID6.cjs → runGemini-BoVDs_V6.cjs} +4 -4
- package/dist/{runGemini-DHYs_Beq.mjs → runGemini-DIAChFOe.mjs} +4 -4
- package/dist/{runOpenClaw-DC9gb1bd.cjs → runOpenClaw-Cdsug1sI.cjs} +3 -3
- package/dist/{runOpenClaw-DTaXxvNd.mjs → runOpenClaw-DcC_uOjt.mjs} +3 -3
- package/dist/{send-BEdGwmA-.cjs → send-DoFm4-OB.cjs} +2 -2
- package/dist/{send-BQSaVz9r.mjs → send-DvDOKQ4V.mjs} +2 -2
- package/dist/{spawn-CK1ma_qc.cjs → spawn-C7QRBKkQ.cjs} +2 -2
- package/dist/{spawn-DS-Uz_Hw.mjs → spawn-CEWzROeD.mjs} +2 -2
- package/dist/{types-B_8X_rZk.mjs → types-CSOwbjq5.mjs} +37 -17
- package/dist/{types-CjlB_fKT.cjs → types-CcaZTXxx.cjs} +37 -17
- package/package.json +7 -7
|
@@ -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-CcaZTXxx.cjs');
|
|
7
7
|
|
|
8
8
|
const DEFAULT_TIMEOUTS = {
|
|
9
9
|
/** Default initialization timeout: 60 seconds */
|
|
@@ -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-CSOwbjq5.mjs';
|
|
5
5
|
|
|
6
6
|
const DEFAULT_TIMEOUTS = {
|
|
7
7
|
/** 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-CcaZTXxx.cjs');
|
|
8
|
+
var index = require('./index-bqUSeHWU.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-CSOwbjq5.mjs';
|
|
6
|
+
import { D as DEFAULT_GEMINI_MODEL, G as GEMINI_MODEL_ENV } from './index-27948eGz.mjs';
|
|
7
7
|
import 'axios';
|
|
8
8
|
import 'chalk';
|
|
9
9
|
import 'node:util';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import{createRequire as _pkgrollCR}from"node:module";const require=_pkgrollCR(import.meta.url);import chalk from 'chalk';
|
|
2
2
|
import os, { homedir } from 'node:os';
|
|
3
3
|
import { randomUUID, randomBytes, createHash as createHash$1, timingSafeEqual } from 'node:crypto';
|
|
4
|
-
import { n as readDaemonState, l as logger, c as configuration, o as clearDaemonState, q as getProjectPath, p as projectPath, s as initializeSandbox, t as wrapCommand, d as contentLogMetadata, I as InvalidateSync, R as RawJSONLinesSchema, g as delay, u as AsyncLock, 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
|
|
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, $ as detectResumeSupport, a0 as detectCLIAvailability, a1 as acquireDaemonLock, a2 as summarizeSpawnSessionForLog, a3 as deletePersistedSessions, a4 as decrypt, a5 as writeDaemonState, A as ApiClient, a6 as fetchCliUpdateState, a7 as resolveCliUpdateCheckInterval, a8 as DEFAULT_CLI_UPDATE_CHECK_INTERVAL_MS, a9 as releaseDaemonLock, aa as isValidSessionId, ab as listVhTerminals, ac as isValidTerminalId, ad as readVhTerminal, ae as sendToVhTerminal, h as connectionState, af as startOfflineReconnection, ag as clearCredentials, ah as clearMachineId, k as ensurePrivateDirectorySync, w as writePrivateFileSync, ai as SandboxConfigSchema, b as createEnvelope, aj as CodexAppServerClient, ak as getLatestDaemonLog } from './types-CSOwbjq5.mjs';
|
|
5
5
|
import spawn$1, { spawn } from 'cross-spawn';
|
|
6
6
|
import path, { join, resolve, basename, isAbsolute, normalize, sep, dirname } from 'node:path';
|
|
7
7
|
import { createInterface } from 'node:readline';
|
|
@@ -6766,10 +6766,20 @@ function createMirrorScanner(opts) {
|
|
|
6766
6766
|
}
|
|
6767
6767
|
|
|
6768
6768
|
const TERMINAL_MIRROR_FLAVOR = "terminal-mirror";
|
|
6769
|
+
const RECONCILE_HYSTERESIS_MS = 2e4;
|
|
6769
6770
|
function createMirrorManager(deps) {
|
|
6770
6771
|
const backfillLines = deps.backfillLines ?? MIRROR_BACKFILL_LINES_DEFAULT;
|
|
6771
6772
|
const bindings = /* @__PURE__ */ new Map();
|
|
6773
|
+
const lastEndedAt = /* @__PURE__ */ new Map();
|
|
6772
6774
|
let chain = Promise.resolve();
|
|
6775
|
+
const reactivate = async (binding) => {
|
|
6776
|
+
try {
|
|
6777
|
+
const ok = await deps.api.reactivateSession(binding.happySessionId);
|
|
6778
|
+
binding.needsReactivate = !ok;
|
|
6779
|
+
} catch {
|
|
6780
|
+
binding.needsReactivate = true;
|
|
6781
|
+
}
|
|
6782
|
+
};
|
|
6773
6783
|
const isTerminalAlive = deps.isTerminalAlive ?? ((terminalId) => {
|
|
6774
6784
|
try {
|
|
6775
6785
|
return spawnSync("tmux", tmuxArgs(["has-session", "-t", `=vh-${terminalId}:`]), { stdio: "ignore", timeout: 3e3, env: scrubTmuxClientEnv({ ...process.env }) }).status === 0;
|
|
@@ -6821,6 +6831,8 @@ function createMirrorManager(deps) {
|
|
|
6821
6831
|
const endBinding = async (binding, reason) => {
|
|
6822
6832
|
if (binding.status === "ended") return;
|
|
6823
6833
|
binding.status = "ended";
|
|
6834
|
+
lastEndedAt.set(binding.terminalId, Date.now());
|
|
6835
|
+
binding.needsReactivate = false;
|
|
6824
6836
|
logger.debug(`[MIRROR] ending binding for terminal ${binding.terminalId} (${reason})`);
|
|
6825
6837
|
await binding.scanner?.cleanup();
|
|
6826
6838
|
binding.scanner = null;
|
|
@@ -6848,6 +6860,76 @@ function createMirrorManager(deps) {
|
|
|
6848
6860
|
}
|
|
6849
6861
|
await binding.client.close();
|
|
6850
6862
|
};
|
|
6863
|
+
const adoptPersisted = async (terminalId, persisted) => {
|
|
6864
|
+
if (bindings.has(terminalId)) return;
|
|
6865
|
+
let best = null;
|
|
6866
|
+
for (const [sessionId2, entry2] of Object.entries(persisted)) {
|
|
6867
|
+
const meta2 = entry2.metadata;
|
|
6868
|
+
if (meta2?.flavor !== TERMINAL_MIRROR_FLAVOR) continue;
|
|
6869
|
+
if (meta2.machineId !== deps.machineId) continue;
|
|
6870
|
+
if (meta2.terminalId !== terminalId) continue;
|
|
6871
|
+
if (!meta2.claudeSessionId) continue;
|
|
6872
|
+
if (!best || entry2.savedAt > best.entry.savedAt) best = { sessionId: sessionId2, entry: entry2 };
|
|
6873
|
+
}
|
|
6874
|
+
if (!best) return;
|
|
6875
|
+
const { sessionId, entry } = best;
|
|
6876
|
+
const meta = entry.metadata;
|
|
6877
|
+
const session = {
|
|
6878
|
+
id: sessionId,
|
|
6879
|
+
seq: entry.seq,
|
|
6880
|
+
metadata: meta,
|
|
6881
|
+
metadataVersion: entry.metadataVersion,
|
|
6882
|
+
agentState: null,
|
|
6883
|
+
agentStateVersion: entry.agentStateVersion,
|
|
6884
|
+
encryptionKey: decodeBase64(entry.encryptionKey),
|
|
6885
|
+
encryptionVariant: entry.encryptionVariant
|
|
6886
|
+
};
|
|
6887
|
+
const client = deps.api.sessionSyncClient(session);
|
|
6888
|
+
client.skipExistingMessages();
|
|
6889
|
+
const binding = {
|
|
6890
|
+
terminalId,
|
|
6891
|
+
happySessionId: sessionId,
|
|
6892
|
+
claudeSessionId: meta.claudeSessionId,
|
|
6893
|
+
status: "active",
|
|
6894
|
+
client,
|
|
6895
|
+
scanner: null,
|
|
6896
|
+
persist: {
|
|
6897
|
+
encryptionKey: entry.encryptionKey,
|
|
6898
|
+
encryptionVariant: entry.encryptionVariant,
|
|
6899
|
+
seq: entry.seq,
|
|
6900
|
+
metadataVersion: entry.metadataVersion,
|
|
6901
|
+
agentStateVersion: entry.agentStateVersion
|
|
6902
|
+
},
|
|
6903
|
+
metadata: meta
|
|
6904
|
+
};
|
|
6905
|
+
bindings.set(terminalId, binding);
|
|
6906
|
+
await reactivate(binding);
|
|
6907
|
+
updateBindingMetadata(binding, {
|
|
6908
|
+
lifecycleState: "running",
|
|
6909
|
+
lifecycleStateSince: Date.now(),
|
|
6910
|
+
archivedBy: void 0,
|
|
6911
|
+
archiveReason: void 0
|
|
6912
|
+
});
|
|
6913
|
+
const scanner = attachScanner(binding, { withTruncationNotice: false });
|
|
6914
|
+
scanner.addFile(join(getProjectPath(meta.path), `${meta.claudeSessionId}.jsonl`), "backfill-tail");
|
|
6915
|
+
logger.debug(`[MIRROR] reconcile adopted terminal ${terminalId} \u2192 ${sessionId}`);
|
|
6916
|
+
deps.onBindingsChanged?.();
|
|
6917
|
+
};
|
|
6918
|
+
const reactivateInPlace = async (binding) => {
|
|
6919
|
+
if (binding.status !== "ended") return;
|
|
6920
|
+
binding.status = "active";
|
|
6921
|
+
await reactivate(binding);
|
|
6922
|
+
updateBindingMetadata(binding, {
|
|
6923
|
+
lifecycleState: "running",
|
|
6924
|
+
lifecycleStateSince: Date.now(),
|
|
6925
|
+
archivedBy: void 0,
|
|
6926
|
+
archiveReason: void 0
|
|
6927
|
+
});
|
|
6928
|
+
const scanner = binding.scanner ?? attachScanner(binding, { withTruncationNotice: false });
|
|
6929
|
+
scanner.addFile(join(getProjectPath(binding.metadata.path), `${binding.claudeSessionId}.jsonl`), "backfill-tail");
|
|
6930
|
+
logger.debug(`[MIRROR] reconcile reactivated (in place) terminal ${binding.terminalId}`);
|
|
6931
|
+
deps.onBindingsChanged?.();
|
|
6932
|
+
};
|
|
6851
6933
|
const createBinding = async (event, replaces) => {
|
|
6852
6934
|
if (replaces) {
|
|
6853
6935
|
await teardownBinding(replaces, "superseded by a fresh conversation");
|
|
@@ -6908,6 +6990,7 @@ function createMirrorManager(deps) {
|
|
|
6908
6990
|
binding.claudeSessionId = event.claudeSessionId;
|
|
6909
6991
|
if (binding.status === "ended") {
|
|
6910
6992
|
binding.status = "active";
|
|
6993
|
+
await reactivate(binding);
|
|
6911
6994
|
updateBindingMetadata(binding, {
|
|
6912
6995
|
lifecycleState: "running",
|
|
6913
6996
|
lifecycleStateSince: Date.now(),
|
|
@@ -6977,6 +7060,43 @@ function createMirrorManager(deps) {
|
|
|
6977
7060
|
}
|
|
6978
7061
|
}
|
|
6979
7062
|
},
|
|
7063
|
+
reconcile(list) {
|
|
7064
|
+
let persisted = null;
|
|
7065
|
+
const now = Date.now();
|
|
7066
|
+
for (const item of list) {
|
|
7067
|
+
const binding = bindings.get(item.id) ?? null;
|
|
7068
|
+
if (item.agentState === "shell") {
|
|
7069
|
+
if (binding && binding.status === "active") {
|
|
7070
|
+
chain = chain.then(() => {
|
|
7071
|
+
const b = bindings.get(item.id);
|
|
7072
|
+
return b && b.status === "active" ? endBinding(b, "claude exited (pane observation)") : void 0;
|
|
7073
|
+
}).catch((e) => logger.debug(`[MIRROR] reconcile end failed for ${item.id}:`, e));
|
|
7074
|
+
}
|
|
7075
|
+
continue;
|
|
7076
|
+
}
|
|
7077
|
+
if (binding && binding.status === "active" && binding.needsReactivate) {
|
|
7078
|
+
chain = chain.then(() => {
|
|
7079
|
+
const b = bindings.get(item.id);
|
|
7080
|
+
return b && b.status === "active" && b.needsReactivate ? reactivate(b) : void 0;
|
|
7081
|
+
}).catch((e) => logger.debug(`[MIRROR] reconcile reactivate-retry failed for ${item.id}:`, e));
|
|
7082
|
+
}
|
|
7083
|
+
if (!item.claudeConfident) continue;
|
|
7084
|
+
const endedAt = lastEndedAt.get(item.id);
|
|
7085
|
+
if (endedAt !== void 0 && now - endedAt < RECONCILE_HYSTERESIS_MS) continue;
|
|
7086
|
+
if (binding && binding.status === "ended") {
|
|
7087
|
+
chain = chain.then(() => {
|
|
7088
|
+
const b = bindings.get(item.id);
|
|
7089
|
+
return b && b.status === "ended" ? reactivateInPlace(b) : void 0;
|
|
7090
|
+
}).catch((e) => logger.debug(`[MIRROR] reconcile in-place reactivate failed for ${item.id}:`, e));
|
|
7091
|
+
} else if (!binding) {
|
|
7092
|
+
persisted ??= readPersistedSessions();
|
|
7093
|
+
const p = persisted;
|
|
7094
|
+
chain = chain.then(() => {
|
|
7095
|
+
return bindings.has(item.id) ? void 0 : adoptPersisted(item.id, p);
|
|
7096
|
+
}).catch((e) => logger.debug(`[MIRROR] reconcile adopt failed for ${item.id}:`, e));
|
|
7097
|
+
}
|
|
7098
|
+
}
|
|
7099
|
+
},
|
|
6980
7100
|
resolveMirrorSessionId(terminalId) {
|
|
6981
7101
|
return bindings.get(terminalId)?.happySessionId;
|
|
6982
7102
|
},
|
|
@@ -8074,6 +8194,7 @@ async function startDaemon() {
|
|
|
8074
8194
|
resolveMirrorSessionId: (terminalId) => mirrorManager.resolveMirrorSessionId(terminalId),
|
|
8075
8195
|
onTerminalClosed: (terminalId) => mirrorManager.onTerminalClosed(terminalId),
|
|
8076
8196
|
onTerminalList: (terminals) => mirrorManager.observeTerminalList(terminals),
|
|
8197
|
+
onTerminalListTick: (terminals) => mirrorManager.reconcile(terminals),
|
|
8077
8198
|
isMirrorInputAllowed: (terminalId) => mirrorManager.isMirrorInputAllowed(terminalId)
|
|
8078
8199
|
});
|
|
8079
8200
|
mirrorManager.restore().catch((error) => {
|
|
@@ -13951,7 +14072,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
13951
14072
|
process.exit(0);
|
|
13952
14073
|
} else if (subcommand === "install-terminal-hooks") {
|
|
13953
14074
|
try {
|
|
13954
|
-
const { installTerminalHooks, parseTerminalHooksArgs, TERMINAL_HOOKS_HELP } = await import('./installTerminalHooks-
|
|
14075
|
+
const { installTerminalHooks, parseTerminalHooksArgs, TERMINAL_HOOKS_HELP } = await import('./installTerminalHooks-dVZoe8om.mjs');
|
|
13955
14076
|
const command = parseTerminalHooksArgs(args.slice(1));
|
|
13956
14077
|
if (command.action === "help") {
|
|
13957
14078
|
console.log(TERMINAL_HOOKS_HELP);
|
|
@@ -13968,7 +14089,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
13968
14089
|
}
|
|
13969
14090
|
} else if (subcommand === "spawn") {
|
|
13970
14091
|
try {
|
|
13971
|
-
const { handleSpawnCommand } = await import('./spawn-
|
|
14092
|
+
const { handleSpawnCommand } = await import('./spawn-CEWzROeD.mjs');
|
|
13972
14093
|
await handleSpawnCommand(args.slice(1));
|
|
13973
14094
|
} catch (error) {
|
|
13974
14095
|
console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
|
|
@@ -13980,7 +14101,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
13980
14101
|
return;
|
|
13981
14102
|
} else if (subcommand === "send") {
|
|
13982
14103
|
try {
|
|
13983
|
-
const { handleSendCommand } = await import('./send-
|
|
14104
|
+
const { handleSendCommand } = await import('./send-DvDOKQ4V.mjs');
|
|
13984
14105
|
await handleSendCommand(args.slice(1));
|
|
13985
14106
|
} catch (error) {
|
|
13986
14107
|
console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
|
|
@@ -14086,9 +14207,9 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
14086
14207
|
if (geminiSubcommand === "project" && args[2] === "set" && args[3]) {
|
|
14087
14208
|
const projectId = args[3];
|
|
14088
14209
|
try {
|
|
14089
|
-
const { saveGoogleCloudProjectToConfig } = await import('./config-
|
|
14090
|
-
const { readCredentialsForConfiguredRelay: readCredentialsForConfiguredRelay2 } = await import('./types-
|
|
14091
|
-
const { ApiClient: ApiClient2 } = await import('./types-
|
|
14210
|
+
const { saveGoogleCloudProjectToConfig } = await import('./config-yrZNEia7.mjs');
|
|
14211
|
+
const { readCredentialsForConfiguredRelay: readCredentialsForConfiguredRelay2 } = await import('./types-CSOwbjq5.mjs').then(function (n) { return n.al; });
|
|
14212
|
+
const { ApiClient: ApiClient2 } = await import('./types-CSOwbjq5.mjs').then(function (n) { return n.am; });
|
|
14092
14213
|
let userEmail = void 0;
|
|
14093
14214
|
try {
|
|
14094
14215
|
const credentials = await readCredentialsForConfiguredRelay2();
|
|
@@ -14119,7 +14240,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
14119
14240
|
}
|
|
14120
14241
|
if (geminiSubcommand === "project" && args[2] === "get") {
|
|
14121
14242
|
try {
|
|
14122
|
-
const { readGeminiLocalConfig } = await import('./config-
|
|
14243
|
+
const { readGeminiLocalConfig } = await import('./config-yrZNEia7.mjs');
|
|
14123
14244
|
const config = readGeminiLocalConfig();
|
|
14124
14245
|
if (config.googleCloudProject) {
|
|
14125
14246
|
console.log(`Current Google Cloud Project: ${config.googleCloudProject}`);
|
|
@@ -14159,7 +14280,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
14159
14280
|
process.exit(0);
|
|
14160
14281
|
}
|
|
14161
14282
|
try {
|
|
14162
|
-
const { runGemini } = await import('./runGemini-
|
|
14283
|
+
const { runGemini } = await import('./runGemini-DIAChFOe.mjs');
|
|
14163
14284
|
let startedBy = void 0;
|
|
14164
14285
|
for (let i = 1; i < args.length; i++) {
|
|
14165
14286
|
if (args[i] === "--started-by") {
|
|
@@ -14181,7 +14302,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
14181
14302
|
return;
|
|
14182
14303
|
} else if (subcommand === "acp") {
|
|
14183
14304
|
try {
|
|
14184
|
-
const { runAcp, resolveAcpAgentConfig } = await import('./index-
|
|
14305
|
+
const { runAcp, resolveAcpAgentConfig } = await import('./index-DXpQrR4U.mjs');
|
|
14185
14306
|
let startedBy = void 0;
|
|
14186
14307
|
let verbose = false;
|
|
14187
14308
|
const acpArgs = [];
|
|
@@ -14221,7 +14342,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
14221
14342
|
return;
|
|
14222
14343
|
} else if (subcommand === "openclaw") {
|
|
14223
14344
|
try {
|
|
14224
|
-
const { runOpenClaw } = await import('./runOpenClaw-
|
|
14345
|
+
const { runOpenClaw } = await import('./runOpenClaw-DcC_uOjt.mjs');
|
|
14225
14346
|
let startedBy = void 0;
|
|
14226
14347
|
let verbose = false;
|
|
14227
14348
|
let gatewayUrl;
|
|
@@ -14272,7 +14393,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
14272
14393
|
return;
|
|
14273
14394
|
} else if (subcommand === "mcp" && args.length === 1) {
|
|
14274
14395
|
try {
|
|
14275
|
-
const { handleMcpCommand } = await import('./mcp-
|
|
14396
|
+
const { handleMcpCommand } = await import('./mcp-BvDgylsM.mjs');
|
|
14276
14397
|
await handleMcpCommand();
|
|
14277
14398
|
} catch (error) {
|
|
14278
14399
|
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-DoSXb9La.cjs');
|
|
4
|
+
var persistence = require('./types-CcaZTXxx.cjs');
|
|
5
|
+
var AcpSessionManager = require('./AcpSessionManager-DQ6j5fp4.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-bqUSeHWU.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-Ds4mP02F.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-Ds4mP02F.mjs';
|
|
3
|
+
import { h as connectionState, A as ApiClient, i as readSettings, j as encodeBase64, l as logger, p as projectPath } from './types-CSOwbjq5.mjs';
|
|
4
|
+
import { A as AcpSessionManager } from './AcpSessionManager-B6RqjyQS.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-27948eGz.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-CcaZTXxx.cjs');
|
|
7
7
|
var spawn = require('cross-spawn');
|
|
8
8
|
var path = require('node:path');
|
|
9
9
|
var node_readline = require('node:readline');
|
|
@@ -6788,10 +6788,20 @@ function createMirrorScanner(opts) {
|
|
|
6788
6788
|
}
|
|
6789
6789
|
|
|
6790
6790
|
const TERMINAL_MIRROR_FLAVOR = "terminal-mirror";
|
|
6791
|
+
const RECONCILE_HYSTERESIS_MS = 2e4;
|
|
6791
6792
|
function createMirrorManager(deps) {
|
|
6792
6793
|
const backfillLines = deps.backfillLines ?? persistence.MIRROR_BACKFILL_LINES_DEFAULT;
|
|
6793
6794
|
const bindings = /* @__PURE__ */ new Map();
|
|
6795
|
+
const lastEndedAt = /* @__PURE__ */ new Map();
|
|
6794
6796
|
let chain = Promise.resolve();
|
|
6797
|
+
const reactivate = async (binding) => {
|
|
6798
|
+
try {
|
|
6799
|
+
const ok = await deps.api.reactivateSession(binding.happySessionId);
|
|
6800
|
+
binding.needsReactivate = !ok;
|
|
6801
|
+
} catch {
|
|
6802
|
+
binding.needsReactivate = true;
|
|
6803
|
+
}
|
|
6804
|
+
};
|
|
6795
6805
|
const isTerminalAlive = deps.isTerminalAlive ?? ((terminalId) => {
|
|
6796
6806
|
try {
|
|
6797
6807
|
return node_child_process.spawnSync("tmux", persistence.tmuxArgs(["has-session", "-t", `=vh-${terminalId}:`]), { stdio: "ignore", timeout: 3e3, env: persistence.scrubTmuxClientEnv({ ...process.env }) }).status === 0;
|
|
@@ -6843,6 +6853,8 @@ function createMirrorManager(deps) {
|
|
|
6843
6853
|
const endBinding = async (binding, reason) => {
|
|
6844
6854
|
if (binding.status === "ended") return;
|
|
6845
6855
|
binding.status = "ended";
|
|
6856
|
+
lastEndedAt.set(binding.terminalId, Date.now());
|
|
6857
|
+
binding.needsReactivate = false;
|
|
6846
6858
|
persistence.logger.debug(`[MIRROR] ending binding for terminal ${binding.terminalId} (${reason})`);
|
|
6847
6859
|
await binding.scanner?.cleanup();
|
|
6848
6860
|
binding.scanner = null;
|
|
@@ -6870,6 +6882,76 @@ function createMirrorManager(deps) {
|
|
|
6870
6882
|
}
|
|
6871
6883
|
await binding.client.close();
|
|
6872
6884
|
};
|
|
6885
|
+
const adoptPersisted = async (terminalId, persisted) => {
|
|
6886
|
+
if (bindings.has(terminalId)) return;
|
|
6887
|
+
let best = null;
|
|
6888
|
+
for (const [sessionId2, entry2] of Object.entries(persisted)) {
|
|
6889
|
+
const meta2 = entry2.metadata;
|
|
6890
|
+
if (meta2?.flavor !== TERMINAL_MIRROR_FLAVOR) continue;
|
|
6891
|
+
if (meta2.machineId !== deps.machineId) continue;
|
|
6892
|
+
if (meta2.terminalId !== terminalId) continue;
|
|
6893
|
+
if (!meta2.claudeSessionId) continue;
|
|
6894
|
+
if (!best || entry2.savedAt > best.entry.savedAt) best = { sessionId: sessionId2, entry: entry2 };
|
|
6895
|
+
}
|
|
6896
|
+
if (!best) return;
|
|
6897
|
+
const { sessionId, entry } = best;
|
|
6898
|
+
const meta = entry.metadata;
|
|
6899
|
+
const session = {
|
|
6900
|
+
id: sessionId,
|
|
6901
|
+
seq: entry.seq,
|
|
6902
|
+
metadata: meta,
|
|
6903
|
+
metadataVersion: entry.metadataVersion,
|
|
6904
|
+
agentState: null,
|
|
6905
|
+
agentStateVersion: entry.agentStateVersion,
|
|
6906
|
+
encryptionKey: persistence.decodeBase64(entry.encryptionKey),
|
|
6907
|
+
encryptionVariant: entry.encryptionVariant
|
|
6908
|
+
};
|
|
6909
|
+
const client = deps.api.sessionSyncClient(session);
|
|
6910
|
+
client.skipExistingMessages();
|
|
6911
|
+
const binding = {
|
|
6912
|
+
terminalId,
|
|
6913
|
+
happySessionId: sessionId,
|
|
6914
|
+
claudeSessionId: meta.claudeSessionId,
|
|
6915
|
+
status: "active",
|
|
6916
|
+
client,
|
|
6917
|
+
scanner: null,
|
|
6918
|
+
persist: {
|
|
6919
|
+
encryptionKey: entry.encryptionKey,
|
|
6920
|
+
encryptionVariant: entry.encryptionVariant,
|
|
6921
|
+
seq: entry.seq,
|
|
6922
|
+
metadataVersion: entry.metadataVersion,
|
|
6923
|
+
agentStateVersion: entry.agentStateVersion
|
|
6924
|
+
},
|
|
6925
|
+
metadata: meta
|
|
6926
|
+
};
|
|
6927
|
+
bindings.set(terminalId, binding);
|
|
6928
|
+
await reactivate(binding);
|
|
6929
|
+
updateBindingMetadata(binding, {
|
|
6930
|
+
lifecycleState: "running",
|
|
6931
|
+
lifecycleStateSince: Date.now(),
|
|
6932
|
+
archivedBy: void 0,
|
|
6933
|
+
archiveReason: void 0
|
|
6934
|
+
});
|
|
6935
|
+
const scanner = attachScanner(binding, { withTruncationNotice: false });
|
|
6936
|
+
scanner.addFile(path.join(persistence.getProjectPath(meta.path), `${meta.claudeSessionId}.jsonl`), "backfill-tail");
|
|
6937
|
+
persistence.logger.debug(`[MIRROR] reconcile adopted terminal ${terminalId} \u2192 ${sessionId}`);
|
|
6938
|
+
deps.onBindingsChanged?.();
|
|
6939
|
+
};
|
|
6940
|
+
const reactivateInPlace = async (binding) => {
|
|
6941
|
+
if (binding.status !== "ended") return;
|
|
6942
|
+
binding.status = "active";
|
|
6943
|
+
await reactivate(binding);
|
|
6944
|
+
updateBindingMetadata(binding, {
|
|
6945
|
+
lifecycleState: "running",
|
|
6946
|
+
lifecycleStateSince: Date.now(),
|
|
6947
|
+
archivedBy: void 0,
|
|
6948
|
+
archiveReason: void 0
|
|
6949
|
+
});
|
|
6950
|
+
const scanner = binding.scanner ?? attachScanner(binding, { withTruncationNotice: false });
|
|
6951
|
+
scanner.addFile(path.join(persistence.getProjectPath(binding.metadata.path), `${binding.claudeSessionId}.jsonl`), "backfill-tail");
|
|
6952
|
+
persistence.logger.debug(`[MIRROR] reconcile reactivated (in place) terminal ${binding.terminalId}`);
|
|
6953
|
+
deps.onBindingsChanged?.();
|
|
6954
|
+
};
|
|
6873
6955
|
const createBinding = async (event, replaces) => {
|
|
6874
6956
|
if (replaces) {
|
|
6875
6957
|
await teardownBinding(replaces, "superseded by a fresh conversation");
|
|
@@ -6930,6 +7012,7 @@ function createMirrorManager(deps) {
|
|
|
6930
7012
|
binding.claudeSessionId = event.claudeSessionId;
|
|
6931
7013
|
if (binding.status === "ended") {
|
|
6932
7014
|
binding.status = "active";
|
|
7015
|
+
await reactivate(binding);
|
|
6933
7016
|
updateBindingMetadata(binding, {
|
|
6934
7017
|
lifecycleState: "running",
|
|
6935
7018
|
lifecycleStateSince: Date.now(),
|
|
@@ -6999,6 +7082,43 @@ function createMirrorManager(deps) {
|
|
|
6999
7082
|
}
|
|
7000
7083
|
}
|
|
7001
7084
|
},
|
|
7085
|
+
reconcile(list) {
|
|
7086
|
+
let persisted = null;
|
|
7087
|
+
const now = Date.now();
|
|
7088
|
+
for (const item of list) {
|
|
7089
|
+
const binding = bindings.get(item.id) ?? null;
|
|
7090
|
+
if (item.agentState === "shell") {
|
|
7091
|
+
if (binding && binding.status === "active") {
|
|
7092
|
+
chain = chain.then(() => {
|
|
7093
|
+
const b = bindings.get(item.id);
|
|
7094
|
+
return b && b.status === "active" ? endBinding(b, "claude exited (pane observation)") : void 0;
|
|
7095
|
+
}).catch((e) => persistence.logger.debug(`[MIRROR] reconcile end failed for ${item.id}:`, e));
|
|
7096
|
+
}
|
|
7097
|
+
continue;
|
|
7098
|
+
}
|
|
7099
|
+
if (binding && binding.status === "active" && binding.needsReactivate) {
|
|
7100
|
+
chain = chain.then(() => {
|
|
7101
|
+
const b = bindings.get(item.id);
|
|
7102
|
+
return b && b.status === "active" && b.needsReactivate ? reactivate(b) : void 0;
|
|
7103
|
+
}).catch((e) => persistence.logger.debug(`[MIRROR] reconcile reactivate-retry failed for ${item.id}:`, e));
|
|
7104
|
+
}
|
|
7105
|
+
if (!item.claudeConfident) continue;
|
|
7106
|
+
const endedAt = lastEndedAt.get(item.id);
|
|
7107
|
+
if (endedAt !== void 0 && now - endedAt < RECONCILE_HYSTERESIS_MS) continue;
|
|
7108
|
+
if (binding && binding.status === "ended") {
|
|
7109
|
+
chain = chain.then(() => {
|
|
7110
|
+
const b = bindings.get(item.id);
|
|
7111
|
+
return b && b.status === "ended" ? reactivateInPlace(b) : void 0;
|
|
7112
|
+
}).catch((e) => persistence.logger.debug(`[MIRROR] reconcile in-place reactivate failed for ${item.id}:`, e));
|
|
7113
|
+
} else if (!binding) {
|
|
7114
|
+
persisted ??= persistence.readPersistedSessions();
|
|
7115
|
+
const p = persisted;
|
|
7116
|
+
chain = chain.then(() => {
|
|
7117
|
+
return bindings.has(item.id) ? void 0 : adoptPersisted(item.id, p);
|
|
7118
|
+
}).catch((e) => persistence.logger.debug(`[MIRROR] reconcile adopt failed for ${item.id}:`, e));
|
|
7119
|
+
}
|
|
7120
|
+
}
|
|
7121
|
+
},
|
|
7002
7122
|
resolveMirrorSessionId(terminalId) {
|
|
7003
7123
|
return bindings.get(terminalId)?.happySessionId;
|
|
7004
7124
|
},
|
|
@@ -8096,6 +8216,7 @@ async function startDaemon() {
|
|
|
8096
8216
|
resolveMirrorSessionId: (terminalId) => mirrorManager.resolveMirrorSessionId(terminalId),
|
|
8097
8217
|
onTerminalClosed: (terminalId) => mirrorManager.onTerminalClosed(terminalId),
|
|
8098
8218
|
onTerminalList: (terminals) => mirrorManager.observeTerminalList(terminals),
|
|
8219
|
+
onTerminalListTick: (terminals) => mirrorManager.reconcile(terminals),
|
|
8099
8220
|
isMirrorInputAllowed: (terminalId) => mirrorManager.isMirrorInputAllowed(terminalId)
|
|
8100
8221
|
});
|
|
8101
8222
|
mirrorManager.restore().catch((error) => {
|
|
@@ -9156,7 +9277,7 @@ const MAX_TITLE_CHARS = 60;
|
|
|
9156
9277
|
const GENERATION_TIMEOUT_MS = 3e4;
|
|
9157
9278
|
function resolveClaudeBinary() {
|
|
9158
9279
|
try {
|
|
9159
|
-
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-
|
|
9280
|
+
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-bqUSeHWU.cjs', document.baseURI).href)));
|
|
9160
9281
|
const utilsPath = path.resolve(path.join(persistence.projectPath(), "scripts", "claude_version_utils.cjs"));
|
|
9161
9282
|
const { getClaudeCliPath } = require$1(utilsPath);
|
|
9162
9283
|
const path$1 = getClaudeCliPath();
|
|
@@ -11350,9 +11471,9 @@ function resolveLocalSignupBootstrap(configuredMode, configuredInviteCodes, gene
|
|
|
11350
11471
|
};
|
|
11351
11472
|
}
|
|
11352
11473
|
|
|
11353
|
-
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-
|
|
11474
|
+
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-bqUSeHWU.cjs', document.baseURI).href)));
|
|
11354
11475
|
const __dirname$1 = path.dirname(__filename$1);
|
|
11355
|
-
const require_ = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-
|
|
11476
|
+
const require_ = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-bqUSeHWU.cjs', document.baseURI).href)));
|
|
11356
11477
|
const PRISMA_QUERY_ENGINE_FILES = {
|
|
11357
11478
|
"arm64-darwin": "libquery_engine-darwin-arm64.dylib.node",
|
|
11358
11479
|
"x64-darwin": "libquery_engine-darwin.dylib.node",
|
|
@@ -13973,7 +14094,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
13973
14094
|
process.exit(0);
|
|
13974
14095
|
} else if (subcommand === "install-terminal-hooks") {
|
|
13975
14096
|
try {
|
|
13976
|
-
const { installTerminalHooks, parseTerminalHooksArgs, TERMINAL_HOOKS_HELP } = await Promise.resolve().then(function () { return require('./installTerminalHooks-
|
|
14097
|
+
const { installTerminalHooks, parseTerminalHooksArgs, TERMINAL_HOOKS_HELP } = await Promise.resolve().then(function () { return require('./installTerminalHooks-D0gCqzZu.cjs'); });
|
|
13977
14098
|
const command = parseTerminalHooksArgs(args.slice(1));
|
|
13978
14099
|
if (command.action === "help") {
|
|
13979
14100
|
console.log(TERMINAL_HOOKS_HELP);
|
|
@@ -13990,7 +14111,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
13990
14111
|
}
|
|
13991
14112
|
} else if (subcommand === "spawn") {
|
|
13992
14113
|
try {
|
|
13993
|
-
const { handleSpawnCommand } = await Promise.resolve().then(function () { return require('./spawn-
|
|
14114
|
+
const { handleSpawnCommand } = await Promise.resolve().then(function () { return require('./spawn-C7QRBKkQ.cjs'); });
|
|
13994
14115
|
await handleSpawnCommand(args.slice(1));
|
|
13995
14116
|
} catch (error) {
|
|
13996
14117
|
console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
|
|
@@ -14002,7 +14123,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
14002
14123
|
return;
|
|
14003
14124
|
} else if (subcommand === "send") {
|
|
14004
14125
|
try {
|
|
14005
|
-
const { handleSendCommand } = await Promise.resolve().then(function () { return require('./send-
|
|
14126
|
+
const { handleSendCommand } = await Promise.resolve().then(function () { return require('./send-DoFm4-OB.cjs'); });
|
|
14006
14127
|
await handleSendCommand(args.slice(1));
|
|
14007
14128
|
} catch (error) {
|
|
14008
14129
|
console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
|
|
@@ -14108,9 +14229,9 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
14108
14229
|
if (geminiSubcommand === "project" && args[2] === "set" && args[3]) {
|
|
14109
14230
|
const projectId = args[3];
|
|
14110
14231
|
try {
|
|
14111
|
-
const { saveGoogleCloudProjectToConfig } = await Promise.resolve().then(function () { return require('./config-
|
|
14112
|
-
const { readCredentialsForConfiguredRelay: readCredentialsForConfiguredRelay2 } = await Promise.resolve().then(function () { return require('./types-
|
|
14113
|
-
const { ApiClient: ApiClient2 } = await Promise.resolve().then(function () { return require('./types-
|
|
14232
|
+
const { saveGoogleCloudProjectToConfig } = await Promise.resolve().then(function () { return require('./config-IdMPfmwy.cjs'); });
|
|
14233
|
+
const { readCredentialsForConfiguredRelay: readCredentialsForConfiguredRelay2 } = await Promise.resolve().then(function () { return require('./types-CcaZTXxx.cjs'); }).then(function (n) { return n.persistence; });
|
|
14234
|
+
const { ApiClient: ApiClient2 } = await Promise.resolve().then(function () { return require('./types-CcaZTXxx.cjs'); }).then(function (n) { return n.api; });
|
|
14114
14235
|
let userEmail = void 0;
|
|
14115
14236
|
try {
|
|
14116
14237
|
const credentials = await readCredentialsForConfiguredRelay2();
|
|
@@ -14141,7 +14262,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
14141
14262
|
}
|
|
14142
14263
|
if (geminiSubcommand === "project" && args[2] === "get") {
|
|
14143
14264
|
try {
|
|
14144
|
-
const { readGeminiLocalConfig } = await Promise.resolve().then(function () { return require('./config-
|
|
14265
|
+
const { readGeminiLocalConfig } = await Promise.resolve().then(function () { return require('./config-IdMPfmwy.cjs'); });
|
|
14145
14266
|
const config = readGeminiLocalConfig();
|
|
14146
14267
|
if (config.googleCloudProject) {
|
|
14147
14268
|
console.log(`Current Google Cloud Project: ${config.googleCloudProject}`);
|
|
@@ -14181,7 +14302,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
14181
14302
|
process.exit(0);
|
|
14182
14303
|
}
|
|
14183
14304
|
try {
|
|
14184
|
-
const { runGemini } = await Promise.resolve().then(function () { return require('./runGemini-
|
|
14305
|
+
const { runGemini } = await Promise.resolve().then(function () { return require('./runGemini-BoVDs_V6.cjs'); });
|
|
14185
14306
|
let startedBy = void 0;
|
|
14186
14307
|
for (let i = 1; i < args.length; i++) {
|
|
14187
14308
|
if (args[i] === "--started-by") {
|
|
@@ -14203,7 +14324,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
14203
14324
|
return;
|
|
14204
14325
|
} else if (subcommand === "acp") {
|
|
14205
14326
|
try {
|
|
14206
|
-
const { runAcp, resolveAcpAgentConfig } = await Promise.resolve().then(function () { return require('./index-
|
|
14327
|
+
const { runAcp, resolveAcpAgentConfig } = await Promise.resolve().then(function () { return require('./index-BfCdbWQI.cjs'); });
|
|
14207
14328
|
let startedBy = void 0;
|
|
14208
14329
|
let verbose = false;
|
|
14209
14330
|
const acpArgs = [];
|
|
@@ -14243,7 +14364,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
14243
14364
|
return;
|
|
14244
14365
|
} else if (subcommand === "openclaw") {
|
|
14245
14366
|
try {
|
|
14246
|
-
const { runOpenClaw } = await Promise.resolve().then(function () { return require('./runOpenClaw-
|
|
14367
|
+
const { runOpenClaw } = await Promise.resolve().then(function () { return require('./runOpenClaw-Cdsug1sI.cjs'); });
|
|
14247
14368
|
let startedBy = void 0;
|
|
14248
14369
|
let verbose = false;
|
|
14249
14370
|
let gatewayUrl;
|
|
@@ -14294,7 +14415,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
14294
14415
|
return;
|
|
14295
14416
|
} else if (subcommand === "mcp" && args.length === 1) {
|
|
14296
14417
|
try {
|
|
14297
|
-
const { handleMcpCommand } = await Promise.resolve().then(function () { return require('./mcp-
|
|
14418
|
+
const { handleMcpCommand } = await Promise.resolve().then(function () { return require('./mcp-CRcmpUpX.cjs'); });
|
|
14298
14419
|
await handleMcpCommand();
|
|
14299
14420
|
} catch (error) {
|
|
14300
14421
|
process.stderr.write(`[very-happy mcp] Fatal: ${error instanceof Error ? error.message : String(error)}
|
package/dist/index.cjs
CHANGED
package/dist/index.mjs
CHANGED
|
@@ -5,8 +5,8 @@ var path = require('node:path');
|
|
|
5
5
|
var os = require('node:os');
|
|
6
6
|
var node_child_process = require('node:child_process');
|
|
7
7
|
var chalk = require('chalk');
|
|
8
|
-
var persistence = require('./types-
|
|
9
|
-
var index = require('./index-
|
|
8
|
+
var persistence = require('./types-CcaZTXxx.cjs');
|
|
9
|
+
var index = require('./index-bqUSeHWU.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-CSOwbjq5.mjs';
|
|
7
|
+
import { t as tmuxSupportsSessionEnv } from './index-27948eGz.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
|
@@ -1055,6 +1055,12 @@ interface TerminalListItem {
|
|
|
1055
1055
|
createdAt?: number;
|
|
1056
1056
|
activityAt?: number;
|
|
1057
1057
|
agentState?: AgentState;
|
|
1058
|
+
/** Mirror reconcile (design v3): stricter "claude is really here" gate (its
|
|
1059
|
+
* own TUI footer/dialog present) — daemon-internal, NOT pushed to web and
|
|
1060
|
+
* NOT part of the list signature. Only this may trigger mirror adopt (which
|
|
1061
|
+
* re-opens the B-107 input gate); `agentState` alone would false-positive
|
|
1062
|
+
* on a bare `node` process. */
|
|
1063
|
+
claudeConfident?: boolean;
|
|
1058
1064
|
/** Terminal mirror (B-105): shadow session id of the hand-typed claude
|
|
1059
1065
|
* running inside this terminal (set via the daemon's mirror resolver).
|
|
1060
1066
|
* The web shows the xterm ↔ structured toggle when present. */
|
|
@@ -1147,6 +1153,9 @@ declare class ApiMachineClient {
|
|
|
1147
1153
|
resolveMirrorSessionId: (terminalId: string) => string | undefined;
|
|
1148
1154
|
onTerminalClosed: (terminalId: string) => void;
|
|
1149
1155
|
onTerminalList: (terminals: TerminalListItem[]) => void;
|
|
1156
|
+
/** design v3: unconditional per-tick reconcile (self-heals lost bindings
|
|
1157
|
+
* on an unchanged-signature list). */
|
|
1158
|
+
onTerminalListTick: (terminals: TerminalListItem[]) => void;
|
|
1150
1159
|
isMirrorInputAllowed: (terminalId: string) => boolean;
|
|
1151
1160
|
}): void;
|
|
1152
1161
|
/** Mirror bindings changed → re-derive and (on diff) push the list now. */
|
package/dist/lib.d.mts
CHANGED
|
@@ -1055,6 +1055,12 @@ interface TerminalListItem {
|
|
|
1055
1055
|
createdAt?: number;
|
|
1056
1056
|
activityAt?: number;
|
|
1057
1057
|
agentState?: AgentState;
|
|
1058
|
+
/** Mirror reconcile (design v3): stricter "claude is really here" gate (its
|
|
1059
|
+
* own TUI footer/dialog present) — daemon-internal, NOT pushed to web and
|
|
1060
|
+
* NOT part of the list signature. Only this may trigger mirror adopt (which
|
|
1061
|
+
* re-opens the B-107 input gate); `agentState` alone would false-positive
|
|
1062
|
+
* on a bare `node` process. */
|
|
1063
|
+
claudeConfident?: boolean;
|
|
1058
1064
|
/** Terminal mirror (B-105): shadow session id of the hand-typed claude
|
|
1059
1065
|
* running inside this terminal (set via the daemon's mirror resolver).
|
|
1060
1066
|
* The web shows the xterm ↔ structured toggle when present. */
|
|
@@ -1147,6 +1153,9 @@ declare class ApiMachineClient {
|
|
|
1147
1153
|
resolveMirrorSessionId: (terminalId: string) => string | undefined;
|
|
1148
1154
|
onTerminalClosed: (terminalId: string) => void;
|
|
1149
1155
|
onTerminalList: (terminals: TerminalListItem[]) => void;
|
|
1156
|
+
/** design v3: unconditional per-tick reconcile (self-heals lost bindings
|
|
1157
|
+
* on an unchanged-signature list). */
|
|
1158
|
+
onTerminalListTick: (terminals: TerminalListItem[]) => void;
|
|
1150
1159
|
isMirrorInputAllowed: (terminalId: string) => boolean;
|
|
1151
1160
|
}): void;
|
|
1152
1161
|
/** Mirror bindings changed → re-derive and (on diff) push the list now. */
|
package/dist/lib.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { A as ApiClient, a as ApiSessionClient, R as RawJSONLinesSchema, c as configuration, l as logger } from './types-
|
|
1
|
+
export { A as ApiClient, a as ApiSessionClient, R as RawJSONLinesSchema, c as configuration, l as logger } from './types-CSOwbjq5.mjs';
|
|
2
2
|
import 'axios';
|
|
3
3
|
import 'chalk';
|
|
4
4
|
import 'node:util';
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
2
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
3
3
|
import { z } from 'zod';
|
|
4
|
-
import { p as pushClipboardViaDaemon } from './index-
|
|
4
|
+
import { p as pushClipboardViaDaemon } from './index-27948eGz.mjs';
|
|
5
5
|
import { C as CLIPBOARD_TOOL_NAME, a as CLIPBOARD_TOOL_TITLE, b as CLIPBOARD_TOOL_DESCRIPTION, c as CLIPBOARD_MAX_BYTES } from './limits-CwFb5S2b.mjs';
|
|
6
|
-
import { l as logger } from './types-
|
|
6
|
+
import { l as logger } from './types-CSOwbjq5.mjs';
|
|
7
7
|
import 'chalk';
|
|
8
8
|
import 'node:os';
|
|
9
9
|
import 'node:crypto';
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
var mcp_js = require('@modelcontextprotocol/sdk/server/mcp.js');
|
|
4
4
|
var stdio_js = require('@modelcontextprotocol/sdk/server/stdio.js');
|
|
5
5
|
var z = require('zod');
|
|
6
|
-
var index = require('./index-
|
|
6
|
+
var index = require('./index-bqUSeHWU.cjs');
|
|
7
7
|
var limits = require('./limits-KdWKmwtH.cjs');
|
|
8
|
-
var persistence = require('./types-
|
|
8
|
+
var persistence = require('./types-CcaZTXxx.cjs');
|
|
9
9
|
require('chalk');
|
|
10
10
|
require('node:os');
|
|
11
11
|
require('node:crypto');
|
|
@@ -4,10 +4,10 @@ var ink = require('ink');
|
|
|
4
4
|
var React = require('react');
|
|
5
5
|
var node_crypto = require('node:crypto');
|
|
6
6
|
var path = require('node:path');
|
|
7
|
-
var persistence = require('./types-
|
|
8
|
-
var index = require('./index-
|
|
9
|
-
var AcpBackend = require('./AcpBackend-
|
|
10
|
-
var config = require('./config-
|
|
7
|
+
var persistence = require('./types-CcaZTXxx.cjs');
|
|
8
|
+
var index = require('./index-bqUSeHWU.cjs');
|
|
9
|
+
var AcpBackend = require('./AcpBackend-DoSXb9La.cjs');
|
|
10
|
+
var config = require('./config-IdMPfmwy.cjs');
|
|
11
11
|
require('axios');
|
|
12
12
|
require('chalk');
|
|
13
13
|
require('node:util');
|
|
@@ -2,10 +2,10 @@ import { useStdout, useInput, Box, Text, render } from 'ink';
|
|
|
2
2
|
import React, { useState, useRef, useEffect, useCallback } from 'react';
|
|
3
3
|
import { randomUUID } from 'node:crypto';
|
|
4
4
|
import { join } from 'node:path';
|
|
5
|
-
import { l as logger, h as connectionState, A as ApiClient, i as readSettings, e as errorLogMetadata, j as encodeBase64, p as projectPath, d as contentLogMetadata } from './types-
|
|
6
|
-
import { g as GEMINI_API_KEY_ENV, j as GOOGLE_API_KEY_ENV, G as GEMINI_MODEL_ENV, B as BasePermissionHandler, k as BaseReasoningProcessor, i as initialMachineMetadata, d as createSessionMetadata, e as setupOfflineReconnection, n as notifyDaemonSessionStarted, M as MessageQueue2, h as hashObject, l as MessageBuffer, C as CHANGE_TITLE_INSTRUCTION, r as registerKillSessionHandler, f as startHappyServer } from './index-
|
|
7
|
-
import { A as AcpBackend } from './AcpBackend-
|
|
8
|
-
import { readGeminiLocalConfig, determineGeminiModel, getGeminiModelSource, getInitialGeminiModel, saveGeminiModelToConfig } from './config-
|
|
5
|
+
import { l as logger, h as connectionState, A as ApiClient, i as readSettings, e as errorLogMetadata, j as encodeBase64, p as projectPath, d as contentLogMetadata } from './types-CSOwbjq5.mjs';
|
|
6
|
+
import { g as GEMINI_API_KEY_ENV, j as GOOGLE_API_KEY_ENV, G as GEMINI_MODEL_ENV, B as BasePermissionHandler, k as BaseReasoningProcessor, i as initialMachineMetadata, d as createSessionMetadata, e as setupOfflineReconnection, n as notifyDaemonSessionStarted, M as MessageQueue2, h as hashObject, l as MessageBuffer, C as CHANGE_TITLE_INSTRUCTION, r as registerKillSessionHandler, f as startHappyServer } from './index-27948eGz.mjs';
|
|
7
|
+
import { A as AcpBackend } from './AcpBackend-Ds4mP02F.mjs';
|
|
8
|
+
import { readGeminiLocalConfig, determineGeminiModel, getGeminiModelSource, getInitialGeminiModel, saveGeminiModelToConfig } from './config-yrZNEia7.mjs';
|
|
9
9
|
import 'axios';
|
|
10
10
|
import 'chalk';
|
|
11
11
|
import 'node:util';
|
|
@@ -5,9 +5,9 @@ var node_child_process = require('node:child_process');
|
|
|
5
5
|
var os = require('node:os');
|
|
6
6
|
var node_fs = require('node:fs');
|
|
7
7
|
var path = require('node:path');
|
|
8
|
-
var persistence = require('./types-
|
|
9
|
-
var AcpSessionManager = require('./AcpSessionManager-
|
|
10
|
-
var index = require('./index-
|
|
8
|
+
var persistence = require('./types-CcaZTXxx.cjs');
|
|
9
|
+
var AcpSessionManager = require('./AcpSessionManager-DQ6j5fp4.cjs');
|
|
10
|
+
var index = require('./index-bqUSeHWU.cjs');
|
|
11
11
|
var WebSocket = require('ws');
|
|
12
12
|
var ed = require('@noble/ed25519');
|
|
13
13
|
var sha2_js = require('@noble/hashes/sha2.js');
|
|
@@ -3,9 +3,9 @@ import { execFileSync } from 'node:child_process';
|
|
|
3
3
|
import os from 'node:os';
|
|
4
4
|
import { existsSync, readFileSync } from 'node:fs';
|
|
5
5
|
import { join } from 'node:path';
|
|
6
|
-
import { k as ensurePrivateDirectorySync, m as hardenPrivateFileSync, w as writePrivateFileSync, e as errorLogMetadata, d as contentLogMetadata, h as connectionState, A as ApiClient, i as readSettings, j as encodeBase64, l as logger, c as configuration } from './types-
|
|
7
|
-
import { A as AcpSessionManager } from './AcpSessionManager-
|
|
8
|
-
import { i as initialMachineMetadata, d as createSessionMetadata, e as setupOfflineReconnection, n as notifyDaemonSessionStarted, M as MessageQueue2, r as registerKillSessionHandler } from './index-
|
|
6
|
+
import { k as ensurePrivateDirectorySync, m as hardenPrivateFileSync, w as writePrivateFileSync, e as errorLogMetadata, d as contentLogMetadata, h as connectionState, A as ApiClient, i as readSettings, j as encodeBase64, l as logger, c as configuration } from './types-CSOwbjq5.mjs';
|
|
7
|
+
import { A as AcpSessionManager } from './AcpSessionManager-B6RqjyQS.mjs';
|
|
8
|
+
import { i as initialMachineMetadata, d as createSessionMetadata, e as setupOfflineReconnection, n as notifyDaemonSessionStarted, M as MessageQueue2, r as registerKillSessionHandler } from './index-27948eGz.mjs';
|
|
9
9
|
import WebSocket from 'ws';
|
|
10
10
|
import * as ed from '@noble/ed25519';
|
|
11
11
|
import { sha512 } from '@noble/hashes/sha2.js';
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
var chalk = require('chalk');
|
|
4
4
|
var node_fs = require('node:fs');
|
|
5
5
|
var path = require('node:path');
|
|
6
|
-
var persistence = require('./types-
|
|
7
|
-
var index = require('./index-
|
|
6
|
+
var persistence = require('./types-CcaZTXxx.cjs');
|
|
7
|
+
var index = require('./index-bqUSeHWU.cjs');
|
|
8
8
|
require('axios');
|
|
9
9
|
require('node:util');
|
|
10
10
|
require('node:os');
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
2
|
import { readFileSync } from 'node:fs';
|
|
3
3
|
import { resolve } from 'node:path';
|
|
4
|
-
import { r as readPersistedSessions, c as configuration } from './types-
|
|
5
|
-
import { b as sendUserMessage, a as sessionWebUrl } from './index-
|
|
4
|
+
import { r as readPersistedSessions, c as configuration } from './types-CSOwbjq5.mjs';
|
|
5
|
+
import { b as sendUserMessage, a as sessionWebUrl } from './index-27948eGz.mjs';
|
|
6
6
|
import 'axios';
|
|
7
7
|
import 'node:util';
|
|
8
8
|
import 'node:os';
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
var chalk = require('chalk');
|
|
4
4
|
var node_fs = require('node:fs');
|
|
5
5
|
var path = require('node:path');
|
|
6
|
-
var index = require('./index-
|
|
7
|
-
var persistence = require('./types-
|
|
6
|
+
var index = require('./index-bqUSeHWU.cjs');
|
|
7
|
+
var persistence = require('./types-CcaZTXxx.cjs');
|
|
8
8
|
require('node:os');
|
|
9
9
|
require('node:crypto');
|
|
10
10
|
require('cross-spawn');
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
2
|
import { readFileSync, statSync } from 'node:fs';
|
|
3
3
|
import { resolve } from 'node:path';
|
|
4
|
-
import { c as checkIfDaemonRunningAndCleanupStaleState, s as spawnDaemonSession, a as sessionWebUrl, w as waitForSessionKey, b as sendUserMessage } from './index-
|
|
5
|
-
import { l as logger } from './types-
|
|
4
|
+
import { c as checkIfDaemonRunningAndCleanupStaleState, s as spawnDaemonSession, a as sessionWebUrl, w as waitForSessionKey, b as sendUserMessage } from './index-27948eGz.mjs';
|
|
5
|
+
import { l as logger } from './types-CSOwbjq5.mjs';
|
|
6
6
|
import 'node:os';
|
|
7
7
|
import 'node:crypto';
|
|
8
8
|
import 'cross-spawn';
|
|
@@ -29,7 +29,7 @@ import { SandboxManager } from '@anthropic-ai/sandbox-runtime';
|
|
|
29
29
|
import { Expo } from 'expo-server-sdk';
|
|
30
30
|
|
|
31
31
|
var name = "very-happy-cli";
|
|
32
|
-
var version = "0.2.
|
|
32
|
+
var version = "0.2.94";
|
|
33
33
|
var description = "Remote multi-agent workspace CLI with deep Claude integration, native terminal streaming, and self-hosting.";
|
|
34
34
|
var author = "Kirill Dubovitskiy";
|
|
35
35
|
var contributors = [
|
|
@@ -142,12 +142,12 @@ var dependencies = {
|
|
|
142
142
|
zod: "^4.0.0"
|
|
143
143
|
};
|
|
144
144
|
var optionalDependencies = {
|
|
145
|
-
"very-happy-tools-arm64-darwin": "0.2.
|
|
146
|
-
"very-happy-tools-x64-darwin": "0.2.
|
|
147
|
-
"very-happy-tools-arm64-linux": "0.2.
|
|
148
|
-
"very-happy-tools-x64-linux": "0.2.
|
|
149
|
-
"very-happy-tools-arm64-win32": "0.2.
|
|
150
|
-
"very-happy-tools-x64-win32": "0.2.
|
|
145
|
+
"very-happy-tools-arm64-darwin": "0.2.94",
|
|
146
|
+
"very-happy-tools-x64-darwin": "0.2.94",
|
|
147
|
+
"very-happy-tools-arm64-linux": "0.2.94",
|
|
148
|
+
"very-happy-tools-x64-linux": "0.2.94",
|
|
149
|
+
"very-happy-tools-arm64-win32": "0.2.94",
|
|
150
|
+
"very-happy-tools-x64-win32": "0.2.94"
|
|
151
151
|
};
|
|
152
152
|
var devDependencies = {
|
|
153
153
|
"@slopus/happy-wire": "workspace:*",
|
|
@@ -10257,6 +10257,13 @@ function looksLikeClaudeCommand(currentCommand) {
|
|
|
10257
10257
|
const cmd = (currentCommand || "").trim().replace(/^-/, "").toLowerCase();
|
|
10258
10258
|
return cmd === "claude" || cmd === "node" || /^\d+\.\d+(\.\d+)?$/.test(cmd);
|
|
10259
10259
|
}
|
|
10260
|
+
function isClaudeConfident(tail) {
|
|
10261
|
+
const lines = tail.replace(/\r/g, "").split("\n").map((l) => l.trimEnd());
|
|
10262
|
+
while (lines.length > 0 && lines[lines.length - 1] === "") lines.pop();
|
|
10263
|
+
const text = lines.join("\n");
|
|
10264
|
+
const last15 = lines.slice(-15).join("\n");
|
|
10265
|
+
return last15.includes("Do you want") || last15.includes("Would you like to proceed") || /^[\s│]*[❯>]\s*1\.\s/m.test(last15) || text.includes("esc to interrupt") || text.includes("? for shortcuts") || text.includes("bypass permissions on") || text.includes("\u23F5\u23F5");
|
|
10266
|
+
}
|
|
10260
10267
|
function planScrollAction(paneInMode, alternateOn, paneWantsMouse, lines, claudeLike = false, paneRows = 24) {
|
|
10261
10268
|
const count = Math.min(Math.abs(Math.trunc(lines)), 200);
|
|
10262
10269
|
if (count === 0) return { kind: "none" };
|
|
@@ -10643,9 +10650,16 @@ class WebTerminalManager {
|
|
|
10643
10650
|
/** terminalId → shadow session id (daemon's mirror manager). Feeds the
|
|
10644
10651
|
* list push (toggle availability) and closed-terminal records. */
|
|
10645
10652
|
mirrorResolver = null;
|
|
10653
|
+
mirrorTickObserver = null;
|
|
10646
10654
|
/** Fired once per terminal whose close was just recorded — the mirror
|
|
10647
10655
|
* manager archives + tears down that terminal's binding. */
|
|
10648
10656
|
onTerminalClosedCb = null;
|
|
10657
|
+
/** Mirror reconcile (design v3): fired every list-track tick, BEFORE the
|
|
10658
|
+
* signature short-circuit, so a claude-running terminal whose binding was
|
|
10659
|
+
* lost self-heals even when nothing about the list changed. */
|
|
10660
|
+
setMirrorTickObserver(fn) {
|
|
10661
|
+
this.mirrorTickObserver = fn;
|
|
10662
|
+
}
|
|
10649
10663
|
setMirrorSessionResolver(fn) {
|
|
10650
10664
|
this.mirrorResolver = fn;
|
|
10651
10665
|
this.kickListRefresh();
|
|
@@ -10828,6 +10842,7 @@ class WebTerminalManager {
|
|
|
10828
10842
|
this.emitActivity(Object.fromEntries(
|
|
10829
10843
|
list.filter((t) => t.activityAt).map((t) => [t.id, t.activityAt])
|
|
10830
10844
|
));
|
|
10845
|
+
this.mirrorTickObserver?.(list);
|
|
10831
10846
|
const sig = terminalListSignature(list);
|
|
10832
10847
|
if (sig === this.lastListSignature) return;
|
|
10833
10848
|
this.lastListSignature = sig;
|
|
@@ -11472,7 +11487,7 @@ class WebTerminalManager {
|
|
|
11472
11487
|
if (session.transport.kind !== "control") throw new Error("capture requires a control client");
|
|
11473
11488
|
const { client } = session.transport;
|
|
11474
11489
|
const batch = buildCaptureBatch({
|
|
11475
|
-
paneTarget: `=${session.tmuxSession}
|
|
11490
|
+
paneTarget: `=${session.tmuxSession}:`,
|
|
11476
11491
|
historyLines: HEADLESS_SCROLLBACK,
|
|
11477
11492
|
smallLines: SNAPSHOT_SCROLLBACK,
|
|
11478
11493
|
cols: session.cols,
|
|
@@ -11567,7 +11582,7 @@ class WebTerminalManager {
|
|
|
11567
11582
|
session.transport.pty.write(text);
|
|
11568
11583
|
return;
|
|
11569
11584
|
}
|
|
11570
|
-
const target = session.paneId ?? `=${session.tmuxSession}
|
|
11585
|
+
const target = session.paneId ?? `=${session.tmuxSession}:`;
|
|
11571
11586
|
const { commands, dropped } = encodeTerminalWrite(text, target, { normalizeKeyNames: true });
|
|
11572
11587
|
if (dropped) {
|
|
11573
11588
|
logger.debug(`[WEB TERMINAL] dropped terminal auto-reply for ${terminalId}`);
|
|
@@ -11596,7 +11611,7 @@ class WebTerminalManager {
|
|
|
11596
11611
|
session.transport.pty.write(text);
|
|
11597
11612
|
return;
|
|
11598
11613
|
}
|
|
11599
|
-
const target = session.paneId ?? `=${session.tmuxSession}
|
|
11614
|
+
const target = session.paneId ?? `=${session.tmuxSession}:`;
|
|
11600
11615
|
const plan = buildPastePlan(text, target, { dir: pasteSpoolDir() });
|
|
11601
11616
|
writeFileSync(plan.path, plan.bytes, { mode: 384 });
|
|
11602
11617
|
try {
|
|
@@ -11767,6 +11782,7 @@ class WebTerminalManager {
|
|
|
11767
11782
|
} catch {
|
|
11768
11783
|
}
|
|
11769
11784
|
}
|
|
11785
|
+
const probe = this.probeAgentState(s.name, s.paneCurrentCommand);
|
|
11770
11786
|
out.push({
|
|
11771
11787
|
id,
|
|
11772
11788
|
title,
|
|
@@ -11777,7 +11793,10 @@ class WebTerminalManager {
|
|
|
11777
11793
|
// tmux last-activity (epoch s) → ms; optional so old daemons
|
|
11778
11794
|
// simply omit it and web clients fall back to createdAt.
|
|
11779
11795
|
activityAt: s.activity,
|
|
11780
|
-
agentState:
|
|
11796
|
+
agentState: probe.agentState,
|
|
11797
|
+
// Daemon-internal (not pushed to web / not in the signature):
|
|
11798
|
+
// the mirror reconciler's stricter "claude is really here" gate.
|
|
11799
|
+
claudeConfident: probe.claudeConfident,
|
|
11781
11800
|
manual: s.manual
|
|
11782
11801
|
});
|
|
11783
11802
|
}
|
|
@@ -11799,7 +11818,7 @@ class WebTerminalManager {
|
|
|
11799
11818
|
if (live) {
|
|
11800
11819
|
try {
|
|
11801
11820
|
const { command, tail } = live.agentProbeInput();
|
|
11802
|
-
return classifyPane(command || polledCommand || "", tail);
|
|
11821
|
+
return { agentState: classifyPane(command || polledCommand || "", tail), claudeConfident: isClaudeConfident(tail) };
|
|
11803
11822
|
} catch {
|
|
11804
11823
|
}
|
|
11805
11824
|
}
|
|
@@ -11815,16 +11834,16 @@ class WebTerminalManager {
|
|
|
11815
11834
|
tmuxArgs(["display-message", "-p", "-t", sessionName, "#{pane_current_command}"]),
|
|
11816
11835
|
{ encoding: "utf8", timeout: TMUX_PROBE_TIMEOUT_MS, env: ptyEnv() }
|
|
11817
11836
|
);
|
|
11818
|
-
if (cmd.status !== 0 || typeof cmd.stdout !== "string") return void 0;
|
|
11837
|
+
if (cmd.status !== 0 || typeof cmd.stdout !== "string") return { agentState: void 0, claudeConfident: false };
|
|
11819
11838
|
const cap = spawnSync(
|
|
11820
11839
|
"tmux",
|
|
11821
11840
|
tmuxArgs(["capture-pane", "-p", "-t", sessionName, "-S", "-40"]),
|
|
11822
11841
|
{ encoding: "utf8", timeout: TMUX_PROBE_TIMEOUT_MS, env: ptyEnv() }
|
|
11823
11842
|
);
|
|
11824
|
-
if (cap.status !== 0 || typeof cap.stdout !== "string") return void 0;
|
|
11825
|
-
return classifyPane(cmd.stdout.trim(), cap.stdout);
|
|
11843
|
+
if (cap.status !== 0 || typeof cap.stdout !== "string") return { agentState: void 0, claudeConfident: false };
|
|
11844
|
+
return { agentState: classifyPane(cmd.stdout.trim(), cap.stdout), claudeConfident: isClaudeConfident(cap.stdout) };
|
|
11826
11845
|
} catch {
|
|
11827
|
-
return void 0;
|
|
11846
|
+
return { agentState: void 0, claudeConfident: false };
|
|
11828
11847
|
}
|
|
11829
11848
|
}
|
|
11830
11849
|
/**
|
|
@@ -14151,6 +14170,7 @@ class ApiMachineClient {
|
|
|
14151
14170
|
setMirrorIntegration(integration) {
|
|
14152
14171
|
this.webTerminal.setMirrorSessionResolver(integration.resolveMirrorSessionId);
|
|
14153
14172
|
this.webTerminal.setOnTerminalClosed(integration.onTerminalClosed);
|
|
14173
|
+
this.webTerminal.setMirrorTickObserver(integration.onTerminalListTick);
|
|
14154
14174
|
this.mirrorListObserver = integration.onTerminalList;
|
|
14155
14175
|
this.mirrorInputAllowed = integration.isMirrorInputAllowed;
|
|
14156
14176
|
}
|
|
@@ -15644,4 +15664,4 @@ const RawJSONLinesSchema = z$1.discriminatedUnion("type", [
|
|
|
15644
15664
|
}).passthrough()
|
|
15645
15665
|
]);
|
|
15646
15666
|
|
|
15647
|
-
export { detectResumeSupport as $, ApiClient as A, deriveLocalCliUpdateSummary as B, updateSettings as C, encodeBase64Url as D, decodeBase64 as E, writeCredentialsLegacy as F, writeCredentialsDataKey as G, readCredentialsForConfiguredRelay as H, InvalidateSync as I, encrypt as J, isClaudeSessionId as K, getLocalHappyAgentCredentialPath as L, MAX_CHAT_ATTACHMENT_SOURCE_BYTES as M, readLocalHappyAgentCredentials as N, decryptWithDataKey as O, decryptLegacy as P, extractCompleteLines as Q, RawJSONLinesSchema as R, decideBackfill as S, parseTerminalHookPayload as T, tmuxArgs as U, scrubTmuxClientEnv as V, decideMirrorBinding as W,
|
|
15667
|
+
export { detectResumeSupport as $, ApiClient as A, deriveLocalCliUpdateSummary as B, updateSettings as C, encodeBase64Url as D, decodeBase64 as E, writeCredentialsLegacy as F, writeCredentialsDataKey as G, readCredentialsForConfiguredRelay as H, InvalidateSync as I, encrypt as J, isClaudeSessionId as K, getLocalHappyAgentCredentialPath as L, MAX_CHAT_ATTACHMENT_SOURCE_BYTES as M, readLocalHappyAgentCredentials as N, decryptWithDataKey as O, decryptLegacy as P, extractCompleteLines as Q, RawJSONLinesSchema as R, decideBackfill as S, parseTerminalHookPayload as T, tmuxArgs as U, scrubTmuxClientEnv as V, decideMirrorBinding as W, MIRROR_BACKFILL_LINES_DEFAULT as X, persistSession as Y, mirrorLineKey as Z, mirrorLocalId as _, ApiSessionClient as a, detectCLIAvailability as a0, acquireDaemonLock as a1, summarizeSpawnSessionForLog as a2, deletePersistedSessions as a3, decrypt as a4, writeDaemonState as a5, fetchCliUpdateState as a6, resolveCliUpdateCheckInterval as a7, DEFAULT_CLI_UPDATE_CHECK_INTERVAL_MS as a8, releaseDaemonLock as a9, isValidSessionId as aa, listVhTerminals as ab, isValidTerminalId as ac, readVhTerminal as ad, sendToVhTerminal as ae, startOfflineReconnection as af, clearCredentials as ag, clearMachineId as ah, SandboxConfigSchema as ai, CodexAppServerClient as aj, getLatestDaemonLog as ak, persistence as al, api as am, createEnvelope as b, configuration as c, contentLogMetadata as d, errorLogMetadata as e, packageJson as f, delay as g, connectionState as h, readSettings as i, encodeBase64 as j, ensurePrivateDirectorySync as k, logger as l, hardenPrivateFileSync as m, readDaemonState as n, clearDaemonState as o, projectPath as p, getProjectPath as q, readPersistedSessions as r, initializeSandbox as s, wrapCommand as t, AsyncLock as u, ensurePrivateDirectory as v, writePrivateFileSync as w, hardenPrivateFile as x, readCredentials as y, credentialRelayProblem as z };
|
|
@@ -51,7 +51,7 @@ var z__namespace = /*#__PURE__*/_interopNamespaceDefault(z);
|
|
|
51
51
|
var pty__namespace = /*#__PURE__*/_interopNamespaceDefault(pty);
|
|
52
52
|
|
|
53
53
|
var name = "very-happy-cli";
|
|
54
|
-
var version = "0.2.
|
|
54
|
+
var version = "0.2.94";
|
|
55
55
|
var description = "Remote multi-agent workspace CLI with deep Claude integration, native terminal streaming, and self-hosting.";
|
|
56
56
|
var author = "Kirill Dubovitskiy";
|
|
57
57
|
var contributors = [
|
|
@@ -164,12 +164,12 @@ var dependencies = {
|
|
|
164
164
|
zod: "^4.0.0"
|
|
165
165
|
};
|
|
166
166
|
var optionalDependencies = {
|
|
167
|
-
"very-happy-tools-arm64-darwin": "0.2.
|
|
168
|
-
"very-happy-tools-x64-darwin": "0.2.
|
|
169
|
-
"very-happy-tools-arm64-linux": "0.2.
|
|
170
|
-
"very-happy-tools-x64-linux": "0.2.
|
|
171
|
-
"very-happy-tools-arm64-win32": "0.2.
|
|
172
|
-
"very-happy-tools-x64-win32": "0.2.
|
|
167
|
+
"very-happy-tools-arm64-darwin": "0.2.94",
|
|
168
|
+
"very-happy-tools-x64-darwin": "0.2.94",
|
|
169
|
+
"very-happy-tools-arm64-linux": "0.2.94",
|
|
170
|
+
"very-happy-tools-x64-linux": "0.2.94",
|
|
171
|
+
"very-happy-tools-arm64-win32": "0.2.94",
|
|
172
|
+
"very-happy-tools-x64-win32": "0.2.94"
|
|
173
173
|
};
|
|
174
174
|
var devDependencies = {
|
|
175
175
|
"@slopus/happy-wire": "workspace:*",
|
|
@@ -1545,7 +1545,7 @@ class RpcHandlerManager {
|
|
|
1545
1545
|
}
|
|
1546
1546
|
}
|
|
1547
1547
|
|
|
1548
|
-
const __dirname$1 = path$1.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('types-
|
|
1548
|
+
const __dirname$1 = path$1.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('types-CcaZTXxx.cjs', document.baseURI).href))));
|
|
1549
1549
|
function projectPath() {
|
|
1550
1550
|
const path = path$1.resolve(__dirname$1, "..");
|
|
1551
1551
|
return path;
|
|
@@ -10279,6 +10279,13 @@ function looksLikeClaudeCommand(currentCommand) {
|
|
|
10279
10279
|
const cmd = (currentCommand || "").trim().replace(/^-/, "").toLowerCase();
|
|
10280
10280
|
return cmd === "claude" || cmd === "node" || /^\d+\.\d+(\.\d+)?$/.test(cmd);
|
|
10281
10281
|
}
|
|
10282
|
+
function isClaudeConfident(tail) {
|
|
10283
|
+
const lines = tail.replace(/\r/g, "").split("\n").map((l) => l.trimEnd());
|
|
10284
|
+
while (lines.length > 0 && lines[lines.length - 1] === "") lines.pop();
|
|
10285
|
+
const text = lines.join("\n");
|
|
10286
|
+
const last15 = lines.slice(-15).join("\n");
|
|
10287
|
+
return last15.includes("Do you want") || last15.includes("Would you like to proceed") || /^[\s│]*[❯>]\s*1\.\s/m.test(last15) || text.includes("esc to interrupt") || text.includes("? for shortcuts") || text.includes("bypass permissions on") || text.includes("\u23F5\u23F5");
|
|
10288
|
+
}
|
|
10282
10289
|
function planScrollAction(paneInMode, alternateOn, paneWantsMouse, lines, claudeLike = false, paneRows = 24) {
|
|
10283
10290
|
const count = Math.min(Math.abs(Math.trunc(lines)), 200);
|
|
10284
10291
|
if (count === 0) return { kind: "none" };
|
|
@@ -10665,9 +10672,16 @@ class WebTerminalManager {
|
|
|
10665
10672
|
/** terminalId → shadow session id (daemon's mirror manager). Feeds the
|
|
10666
10673
|
* list push (toggle availability) and closed-terminal records. */
|
|
10667
10674
|
mirrorResolver = null;
|
|
10675
|
+
mirrorTickObserver = null;
|
|
10668
10676
|
/** Fired once per terminal whose close was just recorded — the mirror
|
|
10669
10677
|
* manager archives + tears down that terminal's binding. */
|
|
10670
10678
|
onTerminalClosedCb = null;
|
|
10679
|
+
/** Mirror reconcile (design v3): fired every list-track tick, BEFORE the
|
|
10680
|
+
* signature short-circuit, so a claude-running terminal whose binding was
|
|
10681
|
+
* lost self-heals even when nothing about the list changed. */
|
|
10682
|
+
setMirrorTickObserver(fn) {
|
|
10683
|
+
this.mirrorTickObserver = fn;
|
|
10684
|
+
}
|
|
10671
10685
|
setMirrorSessionResolver(fn) {
|
|
10672
10686
|
this.mirrorResolver = fn;
|
|
10673
10687
|
this.kickListRefresh();
|
|
@@ -10850,6 +10864,7 @@ class WebTerminalManager {
|
|
|
10850
10864
|
this.emitActivity(Object.fromEntries(
|
|
10851
10865
|
list.filter((t) => t.activityAt).map((t) => [t.id, t.activityAt])
|
|
10852
10866
|
));
|
|
10867
|
+
this.mirrorTickObserver?.(list);
|
|
10853
10868
|
const sig = terminalListSignature(list);
|
|
10854
10869
|
if (sig === this.lastListSignature) return;
|
|
10855
10870
|
this.lastListSignature = sig;
|
|
@@ -11494,7 +11509,7 @@ class WebTerminalManager {
|
|
|
11494
11509
|
if (session.transport.kind !== "control") throw new Error("capture requires a control client");
|
|
11495
11510
|
const { client } = session.transport;
|
|
11496
11511
|
const batch = buildCaptureBatch({
|
|
11497
|
-
paneTarget: `=${session.tmuxSession}
|
|
11512
|
+
paneTarget: `=${session.tmuxSession}:`,
|
|
11498
11513
|
historyLines: HEADLESS_SCROLLBACK,
|
|
11499
11514
|
smallLines: SNAPSHOT_SCROLLBACK,
|
|
11500
11515
|
cols: session.cols,
|
|
@@ -11589,7 +11604,7 @@ class WebTerminalManager {
|
|
|
11589
11604
|
session.transport.pty.write(text);
|
|
11590
11605
|
return;
|
|
11591
11606
|
}
|
|
11592
|
-
const target = session.paneId ?? `=${session.tmuxSession}
|
|
11607
|
+
const target = session.paneId ?? `=${session.tmuxSession}:`;
|
|
11593
11608
|
const { commands, dropped } = encodeTerminalWrite(text, target, { normalizeKeyNames: true });
|
|
11594
11609
|
if (dropped) {
|
|
11595
11610
|
logger.debug(`[WEB TERMINAL] dropped terminal auto-reply for ${terminalId}`);
|
|
@@ -11618,7 +11633,7 @@ class WebTerminalManager {
|
|
|
11618
11633
|
session.transport.pty.write(text);
|
|
11619
11634
|
return;
|
|
11620
11635
|
}
|
|
11621
|
-
const target = session.paneId ?? `=${session.tmuxSession}
|
|
11636
|
+
const target = session.paneId ?? `=${session.tmuxSession}:`;
|
|
11622
11637
|
const plan = buildPastePlan(text, target, { dir: pasteSpoolDir() });
|
|
11623
11638
|
node_fs.writeFileSync(plan.path, plan.bytes, { mode: 384 });
|
|
11624
11639
|
try {
|
|
@@ -11789,6 +11804,7 @@ class WebTerminalManager {
|
|
|
11789
11804
|
} catch {
|
|
11790
11805
|
}
|
|
11791
11806
|
}
|
|
11807
|
+
const probe = this.probeAgentState(s.name, s.paneCurrentCommand);
|
|
11792
11808
|
out.push({
|
|
11793
11809
|
id,
|
|
11794
11810
|
title,
|
|
@@ -11799,7 +11815,10 @@ class WebTerminalManager {
|
|
|
11799
11815
|
// tmux last-activity (epoch s) → ms; optional so old daemons
|
|
11800
11816
|
// simply omit it and web clients fall back to createdAt.
|
|
11801
11817
|
activityAt: s.activity,
|
|
11802
|
-
agentState:
|
|
11818
|
+
agentState: probe.agentState,
|
|
11819
|
+
// Daemon-internal (not pushed to web / not in the signature):
|
|
11820
|
+
// the mirror reconciler's stricter "claude is really here" gate.
|
|
11821
|
+
claudeConfident: probe.claudeConfident,
|
|
11803
11822
|
manual: s.manual
|
|
11804
11823
|
});
|
|
11805
11824
|
}
|
|
@@ -11821,7 +11840,7 @@ class WebTerminalManager {
|
|
|
11821
11840
|
if (live) {
|
|
11822
11841
|
try {
|
|
11823
11842
|
const { command, tail } = live.agentProbeInput();
|
|
11824
|
-
return classifyPane(command || polledCommand || "", tail);
|
|
11843
|
+
return { agentState: classifyPane(command || polledCommand || "", tail), claudeConfident: isClaudeConfident(tail) };
|
|
11825
11844
|
} catch {
|
|
11826
11845
|
}
|
|
11827
11846
|
}
|
|
@@ -11837,16 +11856,16 @@ class WebTerminalManager {
|
|
|
11837
11856
|
tmuxArgs(["display-message", "-p", "-t", sessionName, "#{pane_current_command}"]),
|
|
11838
11857
|
{ encoding: "utf8", timeout: TMUX_PROBE_TIMEOUT_MS, env: ptyEnv() }
|
|
11839
11858
|
);
|
|
11840
|
-
if (cmd.status !== 0 || typeof cmd.stdout !== "string") return void 0;
|
|
11859
|
+
if (cmd.status !== 0 || typeof cmd.stdout !== "string") return { agentState: void 0, claudeConfident: false };
|
|
11841
11860
|
const cap = node_child_process.spawnSync(
|
|
11842
11861
|
"tmux",
|
|
11843
11862
|
tmuxArgs(["capture-pane", "-p", "-t", sessionName, "-S", "-40"]),
|
|
11844
11863
|
{ encoding: "utf8", timeout: TMUX_PROBE_TIMEOUT_MS, env: ptyEnv() }
|
|
11845
11864
|
);
|
|
11846
|
-
if (cap.status !== 0 || typeof cap.stdout !== "string") return void 0;
|
|
11847
|
-
return classifyPane(cmd.stdout.trim(), cap.stdout);
|
|
11865
|
+
if (cap.status !== 0 || typeof cap.stdout !== "string") return { agentState: void 0, claudeConfident: false };
|
|
11866
|
+
return { agentState: classifyPane(cmd.stdout.trim(), cap.stdout), claudeConfident: isClaudeConfident(cap.stdout) };
|
|
11848
11867
|
} catch {
|
|
11849
|
-
return void 0;
|
|
11868
|
+
return { agentState: void 0, claudeConfident: false };
|
|
11850
11869
|
}
|
|
11851
11870
|
}
|
|
11852
11871
|
/**
|
|
@@ -14173,6 +14192,7 @@ class ApiMachineClient {
|
|
|
14173
14192
|
setMirrorIntegration(integration) {
|
|
14174
14193
|
this.webTerminal.setMirrorSessionResolver(integration.resolveMirrorSessionId);
|
|
14175
14194
|
this.webTerminal.setOnTerminalClosed(integration.onTerminalClosed);
|
|
14195
|
+
this.webTerminal.setMirrorTickObserver(integration.onTerminalListTick);
|
|
14176
14196
|
this.mirrorListObserver = integration.onTerminalList;
|
|
14177
14197
|
this.mirrorInputAllowed = integration.isMirrorInputAllowed;
|
|
14178
14198
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "very-happy-cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.94",
|
|
4
4
|
"description": "Remote multi-agent workspace CLI with deep Claude integration, native terminal streaming, and self-hosting.",
|
|
5
5
|
"author": "Kirill Dubovitskiy",
|
|
6
6
|
"contributors": [
|
|
@@ -113,12 +113,12 @@
|
|
|
113
113
|
"zod": "^4.0.0"
|
|
114
114
|
},
|
|
115
115
|
"optionalDependencies": {
|
|
116
|
-
"very-happy-tools-arm64-darwin": "0.2.
|
|
117
|
-
"very-happy-tools-x64-darwin": "0.2.
|
|
118
|
-
"very-happy-tools-arm64-linux": "0.2.
|
|
119
|
-
"very-happy-tools-x64-linux": "0.2.
|
|
120
|
-
"very-happy-tools-arm64-win32": "0.2.
|
|
121
|
-
"very-happy-tools-x64-win32": "0.2.
|
|
116
|
+
"very-happy-tools-arm64-darwin": "0.2.94",
|
|
117
|
+
"very-happy-tools-x64-darwin": "0.2.94",
|
|
118
|
+
"very-happy-tools-arm64-linux": "0.2.94",
|
|
119
|
+
"very-happy-tools-x64-linux": "0.2.94",
|
|
120
|
+
"very-happy-tools-arm64-win32": "0.2.94",
|
|
121
|
+
"very-happy-tools-x64-win32": "0.2.94"
|
|
122
122
|
},
|
|
123
123
|
"devDependencies": {
|
|
124
124
|
"@slopus/happy-wire": "workspace:*",
|