very-happy-cli 0.2.121 → 0.2.123
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-Cdj56ZfU.cjs → AcpBackend-DzIvpTxZ.cjs} +1 -1
- package/dist/{AcpBackend-BxvQ6O4k.mjs → AcpBackend-hM-qHLN3.mjs} +1 -1
- package/dist/{AcpSessionManager-DlWlQVhw.mjs → AcpSessionManager-CRPZPHPa.mjs} +1 -1
- package/dist/{AcpSessionManager-DahCU78z.cjs → AcpSessionManager-DyU3Ikgj.cjs} +1 -1
- package/dist/{config-DxOhdFEx.cjs → config-4RaHrVSV.cjs} +2 -2
- package/dist/{config-osO37dR1.mjs → config-alG86PDN.mjs} +2 -2
- package/dist/{index-Iz-M3qbz.mjs → index-36AkXNF2.mjs} +388 -188
- package/dist/{index-DObePs_K.cjs → index-5b9YhV-1.cjs} +390 -190
- package/dist/{index-Bv53Zygv.cjs → index-Beh0UZf8.cjs} +4 -4
- package/dist/{index-BcwAnM9k.mjs → index-Cg3Vfc00.mjs} +5 -5
- package/dist/{index-Vjo1jIJH.cjs → index-DWBKJ5zy.cjs} +2 -2
- package/dist/{index-DtZFY8aS.mjs → index-vyYHKKk6.mjs} +2 -2
- package/dist/index.cjs +2 -2
- package/dist/index.mjs +2 -2
- package/dist/{installTerminalHooks-DehsXLmV.cjs → installTerminalHooks-DWCa5j7u.cjs} +2 -2
- package/dist/{installTerminalHooks-Bq11vOqF.mjs → installTerminalHooks-DqUPkh0l.mjs} +2 -2
- package/dist/lib.cjs +1 -1
- package/dist/lib.d.cts +7 -0
- package/dist/lib.d.mts +7 -0
- package/dist/lib.mjs +1 -1
- package/dist/{mcp-Cpx9Qlch.cjs → mcp-BBya5dsZ.cjs} +2 -2
- package/dist/{mcp-Bx1B3uny.mjs → mcp-DZIdcsJp.mjs} +2 -2
- package/dist/{runGemini-CMgudbJs.mjs → runGemini-BQa2eF3i.mjs} +4 -4
- package/dist/{runGemini-DI8DipUx.cjs → runGemini-DmWxHIwS.cjs} +4 -4
- package/dist/{runOpenClaw-DR3fLtVf.mjs → runOpenClaw-362eg04u.mjs} +3 -3
- package/dist/{runOpenClaw-CetdjTl-.cjs → runOpenClaw-boyJtPBq.cjs} +3 -3
- package/dist/{send-Cq0NZCn8.cjs → send-BINA__Ke.cjs} +2 -2
- package/dist/{send-M4b_hD7t.mjs → send-CT22-8Tp.mjs} +2 -2
- package/dist/{sessions-DW4lrLOp.cjs → sessions-DXYxV6Np.cjs} +2 -2
- package/dist/{sessions-CelkWhqX.mjs → sessions-DemgtCkr.mjs} +2 -2
- package/dist/{spawn-D3cwBlWI.cjs → spawn-BtV9dU1i.cjs} +2 -2
- package/dist/{spawn-C4fF0q3Z.mjs → spawn-D2egvPgO.mjs} +2 -2
- package/dist/{types-P2cJWD0E.mjs → types-BqW7nEN_.mjs} +88 -39
- package/dist/{types-COOYpI8_.cjs → types-Cd_tUN3U.cjs} +89 -39
- package/package.json +7 -7
|
@@ -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.123";
|
|
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.123",
|
|
168
|
+
"very-happy-tools-x64-darwin": "0.2.123",
|
|
169
|
+
"very-happy-tools-arm64-linux": "0.2.123",
|
|
170
|
+
"very-happy-tools-x64-linux": "0.2.123",
|
|
171
|
+
"very-happy-tools-arm64-win32": "0.2.123",
|
|
172
|
+
"very-happy-tools-x64-win32": "0.2.123"
|
|
173
173
|
};
|
|
174
174
|
var devDependencies = {
|
|
175
175
|
"@slopus/happy-wire": "workspace:*",
|
|
@@ -1032,6 +1032,22 @@ const ReleaseDrainNoticeSchema = z.z.object({
|
|
|
1032
1032
|
deadline: z.z.number().int().positive(),
|
|
1033
1033
|
mode: z.z.literal("make-before-break")
|
|
1034
1034
|
});
|
|
1035
|
+
const ConnectionDiagnosticEventSchema = z.z.object({
|
|
1036
|
+
attemptId: z.z.string().uuid(),
|
|
1037
|
+
machineId: z.z.string().min(1).max(256).regex(/^[A-Za-z0-9_-]+$/).optional(),
|
|
1038
|
+
at: z.z.number().int().min(0).max(Number.MAX_SAFE_INTEGER),
|
|
1039
|
+
stage: z.z.enum(["control", "relay_discovery", "relay_connect", "relay_probe", "machine_rpc", "terminal_open"]),
|
|
1040
|
+
outcome: z.z.enum(["started", "success", "timeout", "error", "offline", "cancelled", "fallback"]),
|
|
1041
|
+
durationMs: z.z.number().int().min(0).max(3e5),
|
|
1042
|
+
deviceClass: z.z.enum(["mobile", "desktop", "unknown"]),
|
|
1043
|
+
visibility: z.z.enum(["visible", "hidden"]),
|
|
1044
|
+
relayRegion: z.z.enum(["central", "sg", "us", "other", "unknown"]).optional(),
|
|
1045
|
+
timing: z.z.enum(["active", "background", "censored", "unknown"]).optional(),
|
|
1046
|
+
client: z.z.string().regex(/^web\/(?:[a-f0-9]{7,40}|unknown)$/)
|
|
1047
|
+
}).strict();
|
|
1048
|
+
z.z.object({
|
|
1049
|
+
events: z.z.array(ConnectionDiagnosticEventSchema).min(1).max(32)
|
|
1050
|
+
}).strict();
|
|
1035
1051
|
|
|
1036
1052
|
z.z.object({
|
|
1037
1053
|
host: z.z.string(),
|
|
@@ -1081,6 +1097,7 @@ const CliUpdateStateSchema = z.z.object({
|
|
|
1081
1097
|
/** B-351: the version this machine may install by itself. Pinned separately
|
|
1082
1098
|
* from `recommendedVersion`; null means no unattended install. */
|
|
1083
1099
|
autoUpdateVersion: z.z.string().nullable().optional(),
|
|
1100
|
+
retrySupported: z.z.boolean().optional(),
|
|
1084
1101
|
checkedAt: z.z.number(),
|
|
1085
1102
|
/**
|
|
1086
1103
|
* B-321: a new bundle is on disk but refused to run, so the daemon is still
|
|
@@ -1691,7 +1708,7 @@ class RpcHandlerManager {
|
|
|
1691
1708
|
}
|
|
1692
1709
|
}
|
|
1693
1710
|
|
|
1694
|
-
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-
|
|
1711
|
+
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-Cd_tUN3U.cjs', document.baseURI).href))));
|
|
1695
1712
|
function projectPath() {
|
|
1696
1713
|
const path = path$1.resolve(__dirname$1, "..");
|
|
1697
1714
|
return path;
|
|
@@ -14506,28 +14523,50 @@ function selectStableRelay(candidates, probes, connectedRelayId, tracker = null)
|
|
|
14506
14523
|
tracker: { challengerRelayId: fastest.id, consecutiveWins }
|
|
14507
14524
|
};
|
|
14508
14525
|
}
|
|
14526
|
+
const RELAY_REFRESH_TIMEOUT_MS = 8e3;
|
|
14527
|
+
async function withinDeadline(timeoutMs, operation, parent) {
|
|
14528
|
+
const controller = new AbortController();
|
|
14529
|
+
let timer;
|
|
14530
|
+
let cancel;
|
|
14531
|
+
const deadline = new Promise((_, reject) => {
|
|
14532
|
+
cancel = () => {
|
|
14533
|
+
reject(new Error("relay request deadline exceeded"));
|
|
14534
|
+
controller.abort();
|
|
14535
|
+
};
|
|
14536
|
+
timer = setTimeout(cancel, timeoutMs);
|
|
14537
|
+
parent?.addEventListener("abort", cancel, { once: true });
|
|
14538
|
+
if (parent?.aborted) cancel();
|
|
14539
|
+
});
|
|
14540
|
+
try {
|
|
14541
|
+
return await Promise.race([Promise.resolve().then(() => {
|
|
14542
|
+
controller.signal.throwIfAborted();
|
|
14543
|
+
return operation(controller.signal);
|
|
14544
|
+
}), deadline]);
|
|
14545
|
+
} finally {
|
|
14546
|
+
clearTimeout(timer);
|
|
14547
|
+
parent?.removeEventListener("abort", cancel);
|
|
14548
|
+
}
|
|
14549
|
+
}
|
|
14509
14550
|
async function probeRelayCandidates(candidates, options = {}) {
|
|
14510
14551
|
const timeoutMs = options.timeoutMs ?? 2e3;
|
|
14511
14552
|
const fetchImpl = options.fetchImpl ?? fetch;
|
|
14512
14553
|
const now = options.now ?? (() => performance.now());
|
|
14513
14554
|
const measured = await Promise.all(candidates.map(async (candidate) => {
|
|
14514
|
-
const controller = new AbortController();
|
|
14515
|
-
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
14516
14555
|
const startedAt = now();
|
|
14517
14556
|
try {
|
|
14518
|
-
|
|
14519
|
-
|
|
14520
|
-
|
|
14521
|
-
|
|
14522
|
-
|
|
14523
|
-
|
|
14524
|
-
|
|
14525
|
-
|
|
14526
|
-
|
|
14557
|
+
return await withinDeadline(timeoutMs, async (signal) => {
|
|
14558
|
+
const response = await fetchImpl(`${candidate.url}/health`, {
|
|
14559
|
+
method: "GET",
|
|
14560
|
+
cache: "no-store",
|
|
14561
|
+
signal
|
|
14562
|
+
});
|
|
14563
|
+
if (!response.ok) return null;
|
|
14564
|
+
const body = await response.json();
|
|
14565
|
+
if (body.ok !== true || body.relayId !== candidate.id) return null;
|
|
14566
|
+
return { relayId: candidate.id, rttMs: Math.max(0, now() - startedAt) };
|
|
14567
|
+
}, options.signal);
|
|
14527
14568
|
} catch {
|
|
14528
14569
|
return null;
|
|
14529
|
-
} finally {
|
|
14530
|
-
clearTimeout(timeout);
|
|
14531
14570
|
}
|
|
14532
14571
|
}));
|
|
14533
14572
|
return measured.filter((probe) => probe !== null);
|
|
@@ -14535,25 +14574,32 @@ async function probeRelayCandidates(candidates, options = {}) {
|
|
|
14535
14574
|
async function discoverAndClaimRelay(input) {
|
|
14536
14575
|
const fetchImpl = input.fetchImpl ?? fetch;
|
|
14537
14576
|
try {
|
|
14538
|
-
|
|
14539
|
-
|
|
14540
|
-
|
|
14541
|
-
|
|
14542
|
-
|
|
14543
|
-
|
|
14544
|
-
|
|
14545
|
-
|
|
14546
|
-
|
|
14547
|
-
|
|
14548
|
-
|
|
14549
|
-
|
|
14550
|
-
|
|
14551
|
-
|
|
14552
|
-
|
|
14577
|
+
return await withinDeadline(RELAY_REFRESH_TIMEOUT_MS, async (signal) => {
|
|
14578
|
+
const discoveryResponse = await fetchImpl(`${input.controlUrl}/v1/relays`, {
|
|
14579
|
+
headers: { Authorization: `Bearer ${input.token}` },
|
|
14580
|
+
cache: "no-store",
|
|
14581
|
+
signal
|
|
14582
|
+
});
|
|
14583
|
+
if (!discoveryResponse.ok) return null;
|
|
14584
|
+
const discovery = RelayCandidatesResponseSchema.parse(await discoveryResponse.json());
|
|
14585
|
+
signal.throwIfAborted();
|
|
14586
|
+
if (!discovery.enabled || discovery.candidates.length === 0) return null;
|
|
14587
|
+
const probes = await probeRelayCandidates(discovery.candidates, { fetchImpl, signal });
|
|
14588
|
+
signal.throwIfAborted();
|
|
14589
|
+
const decision = selectStableRelay(discovery.candidates, probes, input.connectedRelayId, input.switchTracker);
|
|
14590
|
+
const selected = decision.candidate;
|
|
14591
|
+
if (!selected) return null;
|
|
14592
|
+
const claimResponse = await fetchImpl(`${input.controlUrl}/v1/relays/machines/${encodeURIComponent(input.machineId)}/claim`, {
|
|
14593
|
+
method: "POST",
|
|
14594
|
+
signal,
|
|
14595
|
+
headers: { Authorization: `Bearer ${input.token}`, "Content-Type": "application/json" },
|
|
14596
|
+
body: JSON.stringify({ relayId: selected.id, probes })
|
|
14597
|
+
});
|
|
14598
|
+
if (!claimResponse.ok) return null;
|
|
14599
|
+
const claimed = RelayAssignmentResponseSchema.parse(await claimResponse.json());
|
|
14600
|
+
signal.throwIfAborted();
|
|
14601
|
+
return claimed.assignment ? { assignment: claimed.assignment, probes, switchTracker: decision.tracker } : null;
|
|
14553
14602
|
});
|
|
14554
|
-
if (!claimResponse.ok) return null;
|
|
14555
|
-
const claimed = RelayAssignmentResponseSchema.parse(await claimResponse.json());
|
|
14556
|
-
return claimed.assignment ? { assignment: claimed.assignment, probes, switchTracker: decision.tracker } : null;
|
|
14557
14603
|
} catch {
|
|
14558
14604
|
return null;
|
|
14559
14605
|
}
|
|
@@ -14782,6 +14828,9 @@ class ApiMachineClient {
|
|
|
14782
14828
|
encTerminalData(dataBase64) {
|
|
14783
14829
|
return encodeBase64(encrypt(this.machine.encryptionKey, this.machine.encryptionVariant, dataBase64));
|
|
14784
14830
|
}
|
|
14831
|
+
setCliUpdateRetryHandler(handler) {
|
|
14832
|
+
this.rpcHandlerManager.registerHandler("cli-update-retry", (params) => handler(params && typeof params === "object" ? params.version : void 0));
|
|
14833
|
+
}
|
|
14785
14834
|
/** Cache the latest relay policy locally and publish it now or on the next
|
|
14786
14835
|
* socket connect. This makes startup/offline races harmless. */
|
|
14787
14836
|
setCliUpdateState(state) {
|
|
@@ -16851,6 +16900,7 @@ exports.logger = logger;
|
|
|
16851
16900
|
exports.mirrorLineKey = mirrorLineKey;
|
|
16852
16901
|
exports.mirrorLocalId = mirrorLocalId;
|
|
16853
16902
|
exports.packageJson = packageJson;
|
|
16903
|
+
exports.parseExactVersion = parseExactVersion;
|
|
16854
16904
|
exports.parseTerminalHookPayload = parseTerminalHookPayload;
|
|
16855
16905
|
exports.persistSession = persistSession;
|
|
16856
16906
|
exports.persistence = persistence;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "very-happy-cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.123",
|
|
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.123",
|
|
117
|
+
"very-happy-tools-x64-darwin": "0.2.123",
|
|
118
|
+
"very-happy-tools-arm64-linux": "0.2.123",
|
|
119
|
+
"very-happy-tools-x64-linux": "0.2.123",
|
|
120
|
+
"very-happy-tools-arm64-win32": "0.2.123",
|
|
121
|
+
"very-happy-tools-x64-win32": "0.2.123"
|
|
122
122
|
},
|
|
123
123
|
"devDependencies": {
|
|
124
124
|
"@slopus/happy-wire": "workspace:*",
|