@longleash/cli 0.1.0-rc.11 → 0.1.0-rc.12
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/README.md +11 -0
- package/bin/longleash.mjs +152 -32
- package/npm-shrinkwrap.json +94 -79
- package/package.json +2 -2
- package/runtime/app/dist/assets/app-CSvRpOMO.js +27 -0
- package/runtime/app/dist/assets/styles-By_DSD7A.css +1 -0
- package/runtime/app/dist/assets/{styles-ej0i2z2o.js → styles-Dfo-8KGF.js} +4 -4
- package/runtime/app/dist/assets/welcome-BPvArovG.js +41 -0
- package/runtime/app/dist/build.json +1 -1
- package/runtime/app/dist/index.html +3 -3
- package/runtime/app/dist/welcome.html +3 -3
- package/runtime/daemon/bin/longleashd.mjs +592 -53
- package/runtime/app/dist/assets/app-Dv_E_rRc.js +0 -27
- package/runtime/app/dist/assets/styles-Dr4-130w.css +0 -1
- package/runtime/app/dist/assets/welcome-CbADUhH1.js +0 -40
package/README.md
CHANGED
|
@@ -42,3 +42,14 @@ See the [first-party setup guide](https://longleash.dev/docs/getting-started),
|
|
|
42
42
|
- npm provenance is required for public releases from the official repository workflow.
|
|
43
43
|
|
|
44
44
|
LongLeash is licensed under the MIT License.
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
### Verified pairing
|
|
48
|
+
|
|
49
|
+
Run `longleash pair` in an interactive terminal and keep it open. Compare all eight digits
|
|
50
|
+
with the phone, type `yes` on the laptop, and choose **Codes match** on the phone. Both
|
|
51
|
+
confirmations are required. A mismatch, cancellation, disconnect or expiry requires a new QR.
|
|
52
|
+
Redirected input/output is refused so QR secrets cannot be written to service logs. Existing
|
|
53
|
+
paired devices continue working; older daemons must be updated and restarted before creating
|
|
54
|
+
new verified pairings. If a connection fails after both confirmations, use `longleash devices`
|
|
55
|
+
and revoke any incomplete device before pairing again.
|
package/bin/longleash.mjs
CHANGED
|
@@ -1096,9 +1096,9 @@ var require_main = __commonJS({
|
|
|
1096
1096
|
});
|
|
1097
1097
|
|
|
1098
1098
|
// src/cli.ts
|
|
1099
|
-
import { existsSync as existsSync3, readFileSync as
|
|
1099
|
+
import { existsSync as existsSync3, readFileSync as readFileSync5 } from "node:fs";
|
|
1100
1100
|
import { homedir as homedir4 } from "node:os";
|
|
1101
|
-
import { delimiter, dirname as dirname4, join as
|
|
1101
|
+
import { delimiter, dirname as dirname4, join as join5, resolve as resolve4 } from "node:path";
|
|
1102
1102
|
import { fileURLToPath } from "node:url";
|
|
1103
1103
|
import { spawn, spawnSync as spawnSync3 } from "node:child_process";
|
|
1104
1104
|
import { createInterface } from "node:readline/promises";
|
|
@@ -2138,6 +2138,56 @@ function environmentQuote(value) {
|
|
|
2138
2138
|
return `"${value.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
|
|
2139
2139
|
}
|
|
2140
2140
|
|
|
2141
|
+
// src/pairing.ts
|
|
2142
|
+
async function runVerifiedPairing(io) {
|
|
2143
|
+
if (!io.interactive) throw new Error("Pairing requires an interactive terminal. Run longleash pair without redirecting input or output.");
|
|
2144
|
+
if (io.signal.aborted) throw new Error("Pairing cancelled.");
|
|
2145
|
+
const response = await io.request("/local/pairing", { method: "POST" });
|
|
2146
|
+
if (!response.ok) throw new Error(response.status === 429 ? "Too many QRs. Wait one minute and retry." : "Could not create a QR. Update/restart the daemon and try again.");
|
|
2147
|
+
const body = await response.json();
|
|
2148
|
+
if (body.version !== 2 || !body.url || !body.challengeId || !body.expiresAt || !/^https?:\/\//.test(body.url)) {
|
|
2149
|
+
throw new Error("Update and restart the laptop daemon: this CLI requires verified pairing v2.");
|
|
2150
|
+
}
|
|
2151
|
+
const request = (action, attemptId) => io.request(`/local/pairing/${action}`, {
|
|
2152
|
+
method: "POST",
|
|
2153
|
+
headers: { "content-type": "application/json" },
|
|
2154
|
+
body: JSON.stringify({ challengeId: body.challengeId, ...attemptId ? { attemptId } : {} })
|
|
2155
|
+
});
|
|
2156
|
+
const lifetime = AbortSignal.any([io.signal, AbortSignal.timeout(Math.max(1, body.expiresAt - Date.now()))]);
|
|
2157
|
+
let completed = false;
|
|
2158
|
+
let confirmed = false;
|
|
2159
|
+
try {
|
|
2160
|
+
io.showQr(body.url);
|
|
2161
|
+
io.print("Keep this terminal open. Keep the QR and link private; do not share screenshots.");
|
|
2162
|
+
while (!lifetime.aborted) {
|
|
2163
|
+
const status = await request("status");
|
|
2164
|
+
if (!status.ok) throw new Error("Pairing ended or expired. Generate a fresh QR.");
|
|
2165
|
+
const result = await status.json();
|
|
2166
|
+
if (result.state === "paired") {
|
|
2167
|
+
completed = true;
|
|
2168
|
+
io.print("Both devices confirmed. Your phone is paired.");
|
|
2169
|
+
return;
|
|
2170
|
+
}
|
|
2171
|
+
if (result.verification && !confirmed) {
|
|
2172
|
+
const { attemptId, code } = result.verification;
|
|
2173
|
+
if (!/^\d{4} \d{4}$/.test(code) || !/^[A-Za-z0-9_-]{43}$/.test(attemptId)) throw new Error("Invalid laptop verification response.");
|
|
2174
|
+
io.print(`Compare with your phone: ${code}`);
|
|
2175
|
+
const answer = await io.ask("Do all digits match? Type yes to confirm, or anything else to cancel: ", lifetime);
|
|
2176
|
+
if (answer.trim().toLowerCase() !== "yes") throw new Error("Codes were not confirmed. Pairing cancelled; generate a fresh QR.");
|
|
2177
|
+
if (lifetime.aborted) break;
|
|
2178
|
+
if (!(await request("confirm", attemptId)).ok) throw new Error("This attempt ended before confirmation. Generate a fresh QR.");
|
|
2179
|
+
confirmed = true;
|
|
2180
|
+
io.print("Laptop confirmed. Choose Codes match on your phone to finish.");
|
|
2181
|
+
}
|
|
2182
|
+
await (io.wait ?? (() => new Promise((resolve5) => setTimeout(resolve5, 300))))();
|
|
2183
|
+
}
|
|
2184
|
+
throw new Error("Pairing cancelled or expired. Generate a fresh QR.");
|
|
2185
|
+
} finally {
|
|
2186
|
+
if (!completed) await request("cancel").catch(() => {
|
|
2187
|
+
});
|
|
2188
|
+
}
|
|
2189
|
+
}
|
|
2190
|
+
|
|
2141
2191
|
// src/terminal-qr.ts
|
|
2142
2192
|
var import_qrcode_terminal = __toESM(require_main(), 1);
|
|
2143
2193
|
function terminalQr(input2) {
|
|
@@ -2221,15 +2271,50 @@ function cell(top, bottom) {
|
|
|
2221
2271
|
};
|
|
2222
2272
|
}
|
|
2223
2273
|
|
|
2274
|
+
// src/diagnostics.ts
|
|
2275
|
+
import { readFileSync as readFileSync4 } from "node:fs";
|
|
2276
|
+
import { join as join4 } from "node:path";
|
|
2277
|
+
function readBuild(path) {
|
|
2278
|
+
try {
|
|
2279
|
+
const value = JSON.parse(readFileSync4(path, "utf8")).build;
|
|
2280
|
+
return typeof value === "string" && value.length > 0 ? value : null;
|
|
2281
|
+
} catch {
|
|
2282
|
+
return null;
|
|
2283
|
+
}
|
|
2284
|
+
}
|
|
2285
|
+
function compareBuilds(expected, actual) {
|
|
2286
|
+
return !expected || !actual ? "unknown" : expected === actual ? "match" : "mismatch";
|
|
2287
|
+
}
|
|
2288
|
+
function inspectHooks(home, codexHome, hooks2) {
|
|
2289
|
+
const quote = (value) => `'${value.replace(/'/g, `'"'"'`)}'`;
|
|
2290
|
+
const events = ["SessionStart", "SessionEnd", "PreToolUse", "PermissionRequest"];
|
|
2291
|
+
let claude = false;
|
|
2292
|
+
let codex = false;
|
|
2293
|
+
try {
|
|
2294
|
+
const settings = JSON.parse(readFileSync4(join4(home, ".claude", "settings.json"), "utf8"));
|
|
2295
|
+
const command = `${quote(process.execPath)} ${quote(join4(hooks2, "longleash-hook.mjs"))}`;
|
|
2296
|
+
claude = settings.disableAllHooks !== true && events.every((event) => Array.isArray(settings.hooks?.[event]) && settings.hooks[event].some((entry) => Array.isArray(entry.hooks) && entry.hooks.some((hook) => hook.command === command || hook.command === `${command} --observe`)));
|
|
2297
|
+
} catch {
|
|
2298
|
+
}
|
|
2299
|
+
try {
|
|
2300
|
+
const config = readFileSync4(join4(codexHome, "config.toml"), "utf8");
|
|
2301
|
+
const command = `${quote(process.execPath)} ${quote(join4(hooks2, "longleash-codex-hook.mjs"))}`;
|
|
2302
|
+
const block = config.split("# >>> LongLeash \u2014 managed block, edits between these markers are overwritten")[1]?.split("# <<< LongLeash")[0] ?? "";
|
|
2303
|
+
codex = events.every((event) => block.split("\n").some((line) => line.startsWith(`${event} = `) && line.includes(`command = ${JSON.stringify(event === "PreToolUse" ? `${command} --observe` : command)}`)));
|
|
2304
|
+
} catch {
|
|
2305
|
+
}
|
|
2306
|
+
return { claude, codex };
|
|
2307
|
+
}
|
|
2308
|
+
|
|
2224
2309
|
// src/cli.ts
|
|
2225
2310
|
var here = dirname4(fileURLToPath(import.meta.url));
|
|
2226
2311
|
var packageRoot = resolve4(here, "..");
|
|
2227
|
-
var manifest = JSON.parse(
|
|
2312
|
+
var manifest = JSON.parse(readFileSync5(join5(packageRoot, "package.json"), "utf8"));
|
|
2228
2313
|
var VERSION = manifest.version;
|
|
2229
|
-
var runtime =
|
|
2230
|
-
var daemonEntry =
|
|
2231
|
-
var hooks =
|
|
2232
|
-
var devicesEntry =
|
|
2314
|
+
var runtime = join5(packageRoot, "runtime", "daemon");
|
|
2315
|
+
var daemonEntry = join5(runtime, "bin", "longleashd.mjs");
|
|
2316
|
+
var hooks = join5(runtime, "hooks");
|
|
2317
|
+
var devicesEntry = join5(runtime, "bin", "longleash-devices.mjs");
|
|
2233
2318
|
async function main() {
|
|
2234
2319
|
const args = process.argv.slice(2);
|
|
2235
2320
|
const command = args[0];
|
|
@@ -2505,16 +2590,34 @@ function printServiceState(state, healthy) {
|
|
|
2505
2590
|
console.log("");
|
|
2506
2591
|
}
|
|
2507
2592
|
async function pair() {
|
|
2508
|
-
const
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2593
|
+
const controller = new AbortController();
|
|
2594
|
+
const cancel = () => controller.abort();
|
|
2595
|
+
process.once("SIGINT", cancel);
|
|
2596
|
+
process.once("SIGTERM", cancel);
|
|
2597
|
+
const terminal = input.isTTY && output.isTTY ? createInterface({ input, output }) : null;
|
|
2598
|
+
terminal?.on("SIGINT", cancel);
|
|
2599
|
+
terminal?.on("close", cancel);
|
|
2600
|
+
try {
|
|
2601
|
+
await runVerifiedPairing({
|
|
2602
|
+
interactive: Boolean(terminal),
|
|
2603
|
+
request: localDaemonRequest,
|
|
2604
|
+
signal: controller.signal,
|
|
2605
|
+
showQr: (url) => {
|
|
2606
|
+
console.log("\nScan this with your phone:\n");
|
|
2607
|
+
console.log(terminalQr(url));
|
|
2608
|
+
console.log(`
|
|
2609
|
+
${url}
|
|
2516
2610
|
`);
|
|
2517
|
-
|
|
2611
|
+
},
|
|
2612
|
+
print: (text) => console.log(text),
|
|
2613
|
+
ask: (prompt, signal) => terminal.question(prompt, { signal })
|
|
2614
|
+
});
|
|
2615
|
+
return 0;
|
|
2616
|
+
} finally {
|
|
2617
|
+
terminal?.close();
|
|
2618
|
+
process.off("SIGINT", cancel);
|
|
2619
|
+
process.off("SIGTERM", cancel);
|
|
2620
|
+
}
|
|
2518
2621
|
}
|
|
2519
2622
|
async function runDaemon(explicitRoots) {
|
|
2520
2623
|
if (!existsSync3(daemonEntry)) throw new Error("The npm package is incomplete: daemon runtime is missing.");
|
|
@@ -2551,22 +2654,32 @@ async function doctor(json) {
|
|
|
2551
2654
|
} catch (error) {
|
|
2552
2655
|
configError = message(error);
|
|
2553
2656
|
}
|
|
2554
|
-
const endpointPath = join4(process.env.LONGLEASH_DATA ?? join4(homedir4(), ".longleash"), "hook-endpoint.json");
|
|
2555
2657
|
let daemon = { reachable: false };
|
|
2556
2658
|
try {
|
|
2557
|
-
const
|
|
2558
|
-
if (
|
|
2559
|
-
const
|
|
2560
|
-
|
|
2561
|
-
signal: AbortSignal.timeout(1500)
|
|
2562
|
-
});
|
|
2563
|
-
if (response.ok) {
|
|
2564
|
-
const health = await response.json();
|
|
2565
|
-
daemon = { reachable: true, ...health.build ? { build: health.build } : {} };
|
|
2566
|
-
}
|
|
2659
|
+
const response = await localDaemonRequest("/health", { method: "GET" }, 1500);
|
|
2660
|
+
if (response.ok) {
|
|
2661
|
+
const health = await response.json();
|
|
2662
|
+
daemon = { reachable: health.name === "longleash", ...health.build ? { build: health.build } : {}, ...health.pairingVersion ? { pairingVersion: health.pairingVersion } : {} };
|
|
2567
2663
|
}
|
|
2568
2664
|
} catch {
|
|
2569
2665
|
}
|
|
2666
|
+
const localBuild = readBuild(join5(packageRoot, "runtime", "app", "dist", "build.json"));
|
|
2667
|
+
let relayBuild = null;
|
|
2668
|
+
if (typeof config.relayUrl === "string") {
|
|
2669
|
+
try {
|
|
2670
|
+
const url = new URL(config.relayUrl);
|
|
2671
|
+
url.protocol = url.protocol === "wss:" ? "https:" : "http:";
|
|
2672
|
+
url.pathname = "/build.json";
|
|
2673
|
+
url.search = "";
|
|
2674
|
+
url.hash = "";
|
|
2675
|
+
const response = await fetch(url, { signal: AbortSignal.timeout(3e3), headers: { "cache-control": "no-cache" } });
|
|
2676
|
+
const value = response.ok ? await response.json() : null;
|
|
2677
|
+
if (typeof value?.build === "string") relayBuild = value.build;
|
|
2678
|
+
} catch {
|
|
2679
|
+
}
|
|
2680
|
+
}
|
|
2681
|
+
const builds = { local: localBuild, daemon: compareBuilds(localBuild, daemon.build ?? null), relay: typeof config.relayUrl === "string" ? compareBuilds(localBuild, relayBuild) : "off", relayBuild };
|
|
2682
|
+
const hookConfig = inspectHooks(homedir4(), process.env.CODEX_HOME || join5(homedir4(), ".codex"), hooks);
|
|
2570
2683
|
const report = {
|
|
2571
2684
|
package: { name: "@longleash/cli", version: VERSION, root: packageRoot },
|
|
2572
2685
|
runtime: { node: process.version, platform: process.platform, architecture: process.arch },
|
|
@@ -2577,7 +2690,9 @@ async function doctor(json) {
|
|
|
2577
2690
|
allowedRoots: configuredRoots(config),
|
|
2578
2691
|
relay: typeof config.relayUrl === "string" ? config.relayUrl : "off"
|
|
2579
2692
|
},
|
|
2580
|
-
daemon
|
|
2693
|
+
daemon,
|
|
2694
|
+
builds,
|
|
2695
|
+
hooks: hookConfig
|
|
2581
2696
|
};
|
|
2582
2697
|
if (json) console.log(JSON.stringify(report, null, 2));
|
|
2583
2698
|
else {
|
|
@@ -2588,6 +2703,11 @@ LongLeash ${VERSION}`);
|
|
|
2588
2703
|
console.log(` config ${configError ?? (configuredRoots(config).length > 0 ? "valid" : "not configured")}`);
|
|
2589
2704
|
console.log(` relay ${report.config.relay}`);
|
|
2590
2705
|
console.log(` daemon ${daemon.reachable ? `reachable \xB7 build ${daemon.build ?? "unknown"}` : "not running"}`);
|
|
2706
|
+
console.log(` code builds ${builds.daemon} \xB7 packaged ${localBuild ?? "unknown"}`);
|
|
2707
|
+
console.log(` app builds ${builds.relay} \xB7 relay ${relayBuild ?? "unavailable"}`);
|
|
2708
|
+
console.log(` pairing ${daemon.pairingVersion === 2 ? "verified v2" : "unavailable/old \u2014 update and restart the daemon"}`);
|
|
2709
|
+
for (const agent of ["claude", "codex"]) console.log(` ${agent} hooks ${hookConfig[agent] ? "configured for this runtime" : "missing/stale \u2014 run longleash hooks"}`);
|
|
2710
|
+
console.log(" Hook configuration does not prove provider trust. Restart agents after updates and test one new session.");
|
|
2591
2711
|
console.log("");
|
|
2592
2712
|
}
|
|
2593
2713
|
return configError === null ? 0 : 1;
|
|
@@ -2595,8 +2715,8 @@ LongLeash ${VERSION}`);
|
|
|
2595
2715
|
async function runHooks(args) {
|
|
2596
2716
|
const remove = args.includes("--remove");
|
|
2597
2717
|
let failed = false;
|
|
2598
|
-
if (commandAvailable("claude") || remove) failed = await runNode(
|
|
2599
|
-
if (commandAvailable("codex") || remove) failed = await runNode(
|
|
2718
|
+
if (commandAvailable("claude") || remove) failed = await runNode(join5(hooks, "install-hooks.mjs"), remove ? ["--remove"] : []) !== 0 || failed;
|
|
2719
|
+
if (commandAvailable("codex") || remove) failed = await runNode(join5(hooks, "install-codex-hooks.mjs"), remove ? ["--remove"] : []) !== 0 || failed;
|
|
2600
2720
|
return failed ? 1 : 0;
|
|
2601
2721
|
}
|
|
2602
2722
|
async function update(target) {
|
|
@@ -2653,10 +2773,10 @@ async function waitForDaemon(timeoutMs) {
|
|
|
2653
2773
|
return false;
|
|
2654
2774
|
}
|
|
2655
2775
|
async function localDaemonRequest(path, init, timeoutMs = 5e3) {
|
|
2656
|
-
const endpointPath =
|
|
2776
|
+
const endpointPath = join5(process.env.LONGLEASH_DATA ?? join5(homedir4(), ".longleash"), "hook-endpoint.json");
|
|
2657
2777
|
let endpoint;
|
|
2658
2778
|
try {
|
|
2659
|
-
endpoint = JSON.parse(
|
|
2779
|
+
endpoint = JSON.parse(readFileSync5(endpointPath, "utf8"));
|
|
2660
2780
|
} catch {
|
|
2661
2781
|
throw new Error("LongLeash is not reachable. Start it with `longleash service start` or `longleash run`.");
|
|
2662
2782
|
}
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@longleash/cli",
|
|
3
|
-
"version": "0.1.0-rc.
|
|
3
|
+
"version": "0.1.0-rc.12",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@longleash/cli",
|
|
9
|
-
"version": "0.1.0-rc.
|
|
9
|
+
"version": "0.1.0-rc.12",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"os": [
|
|
12
12
|
"darwin",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"@fastify/websocket": "11.3.0",
|
|
20
20
|
"@modelcontextprotocol/sdk": "1.30.0",
|
|
21
21
|
"better-sqlite3": "12.11.1",
|
|
22
|
-
"fastify": "5.
|
|
22
|
+
"fastify": "5.12.5",
|
|
23
23
|
"qrcode-terminal": "0.12.0",
|
|
24
24
|
"web-push": "3.6.7",
|
|
25
25
|
"ws": "8.21.1",
|
|
@@ -241,9 +241,9 @@
|
|
|
241
241
|
}
|
|
242
242
|
},
|
|
243
243
|
"node_modules/@fastify/ajv-compiler/node_modules/fast-uri": {
|
|
244
|
-
"version": "4.1
|
|
245
|
-
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-4.1.
|
|
246
|
-
"integrity": "sha512-
|
|
244
|
+
"version": "4.2.1",
|
|
245
|
+
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-4.2.1.tgz",
|
|
246
|
+
"integrity": "sha512-TmHQgewjHtMq1E5QKA0tOE0yeYGQs25KZC/ziJpubRtWI15W92e6vPFydWOeZBVROSHBYw/QhD9d5OefdD6LDg==",
|
|
247
247
|
"funding": [
|
|
248
248
|
{
|
|
249
249
|
"type": "github",
|
|
@@ -327,9 +327,9 @@
|
|
|
327
327
|
}
|
|
328
328
|
},
|
|
329
329
|
"node_modules/@fastify/proxy-addr": {
|
|
330
|
-
"version": "5.1.
|
|
331
|
-
"resolved": "https://registry.npmjs.org/@fastify/proxy-addr/-/proxy-addr-5.1.
|
|
332
|
-
"integrity": "sha512-
|
|
330
|
+
"version": "5.1.1",
|
|
331
|
+
"resolved": "https://registry.npmjs.org/@fastify/proxy-addr/-/proxy-addr-5.1.1.tgz",
|
|
332
|
+
"integrity": "sha512-zv07Y9GEuDsJPegZoDFd4SDWaZOW8N2pa0GSrYmKpId/tjt1Hgo3BjZBVjdVpfVrHaA+Qv5jawtS2O50J5xM9g==",
|
|
333
333
|
"funding": [
|
|
334
334
|
{
|
|
335
335
|
"type": "github",
|
|
@@ -416,9 +416,9 @@
|
|
|
416
416
|
}
|
|
417
417
|
},
|
|
418
418
|
"node_modules/@hono/node-server": {
|
|
419
|
-
"version": "2.1.
|
|
420
|
-
"resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-2.1.
|
|
421
|
-
"integrity": "sha512-
|
|
419
|
+
"version": "2.1.3",
|
|
420
|
+
"resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-2.1.3.tgz",
|
|
421
|
+
"integrity": "sha512-TA//nWMqPhbfdfneACk6t5a9eqbS9lABEPyKn0/xZTah3H3U2XaVg85rJFl0/Fyit0I552YDHgXGVSf3GwqbUw==",
|
|
422
422
|
"license": "MIT",
|
|
423
423
|
"engines": {
|
|
424
424
|
"node": ">=20"
|
|
@@ -697,9 +697,9 @@
|
|
|
697
697
|
}
|
|
698
698
|
},
|
|
699
699
|
"node_modules/brace-expansion": {
|
|
700
|
-
"version": "5.0.
|
|
701
|
-
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.
|
|
702
|
-
"integrity": "sha512-
|
|
700
|
+
"version": "5.0.12",
|
|
701
|
+
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.12.tgz",
|
|
702
|
+
"integrity": "sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ==",
|
|
703
703
|
"license": "MIT",
|
|
704
704
|
"dependencies": {
|
|
705
705
|
"balanced-match": "^4.0.2"
|
|
@@ -1099,9 +1099,9 @@
|
|
|
1099
1099
|
}
|
|
1100
1100
|
},
|
|
1101
1101
|
"node_modules/express-rate-limit": {
|
|
1102
|
-
"version": "8.
|
|
1103
|
-
"resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.
|
|
1104
|
-
"integrity": "sha512-
|
|
1102
|
+
"version": "8.7.0",
|
|
1103
|
+
"resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.7.0.tgz",
|
|
1104
|
+
"integrity": "sha512-hOwV7WOxXfjRpAM1DSJWZDXx3GhplwD8IfwuwvogD8i1Qnkgosw/H45s4ZnFAUHDAhPjlY9hLBvJhKmGMyY26g==",
|
|
1105
1105
|
"license": "MIT",
|
|
1106
1106
|
"dependencies": {
|
|
1107
1107
|
"debug": "^4.4.3",
|
|
@@ -1167,9 +1167,9 @@
|
|
|
1167
1167
|
}
|
|
1168
1168
|
},
|
|
1169
1169
|
"node_modules/fast-json-stringify/node_modules/fast-uri": {
|
|
1170
|
-
"version": "4.1
|
|
1171
|
-
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-4.1.
|
|
1172
|
-
"integrity": "sha512-
|
|
1170
|
+
"version": "4.2.1",
|
|
1171
|
+
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-4.2.1.tgz",
|
|
1172
|
+
"integrity": "sha512-TmHQgewjHtMq1E5QKA0tOE0yeYGQs25KZC/ziJpubRtWI15W92e6vPFydWOeZBVROSHBYw/QhD9d5OefdD6LDg==",
|
|
1173
1173
|
"funding": [
|
|
1174
1174
|
{
|
|
1175
1175
|
"type": "github",
|
|
@@ -1198,9 +1198,9 @@
|
|
|
1198
1198
|
"license": "Unlicense"
|
|
1199
1199
|
},
|
|
1200
1200
|
"node_modules/fast-uri": {
|
|
1201
|
-
"version": "3.1.
|
|
1202
|
-
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.
|
|
1203
|
-
"integrity": "sha512-
|
|
1201
|
+
"version": "3.1.8",
|
|
1202
|
+
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.8.tgz",
|
|
1203
|
+
"integrity": "sha512-GZMtZUTNRpOVIECoXwLNZS5xUGE+mVNbTB8h/7Rwh2TFWcBQiPzTgyZi05BF9UMZKkLJv8XBRJTlU7zg8+ZfMg==",
|
|
1204
1204
|
"funding": [
|
|
1205
1205
|
{
|
|
1206
1206
|
"type": "github",
|
|
@@ -1214,9 +1214,9 @@
|
|
|
1214
1214
|
"license": "BSD-3-Clause"
|
|
1215
1215
|
},
|
|
1216
1216
|
"node_modules/fastify": {
|
|
1217
|
-
"version": "5.
|
|
1218
|
-
"resolved": "https://registry.npmjs.org/fastify/-/fastify-5.
|
|
1219
|
-
"integrity": "sha512-
|
|
1217
|
+
"version": "5.12.5",
|
|
1218
|
+
"resolved": "https://registry.npmjs.org/fastify/-/fastify-5.12.5.tgz",
|
|
1219
|
+
"integrity": "sha512-OB2k1dlxs5/NAABqeKV2FUHkSD2BbENsCak8yULVcymn3fHIPDVa9TI3SDnJSWYSllZmSYuZXy2gTnsT+Sut1A==",
|
|
1220
1220
|
"funding": [
|
|
1221
1221
|
{
|
|
1222
1222
|
"type": "github",
|
|
@@ -1239,7 +1239,7 @@
|
|
|
1239
1239
|
"find-my-way": "^9.6.0",
|
|
1240
1240
|
"light-my-request": "^6.0.0",
|
|
1241
1241
|
"pino": "^9.14.0 || ^10.1.0",
|
|
1242
|
-
"process-warning": "^5.
|
|
1242
|
+
"process-warning": "^5.1.0",
|
|
1243
1243
|
"rfdc": "^1.3.1",
|
|
1244
1244
|
"secure-json-parse": "^4.0.0",
|
|
1245
1245
|
"semver": "^7.6.0",
|
|
@@ -1263,9 +1263,9 @@
|
|
|
1263
1263
|
"license": "MIT"
|
|
1264
1264
|
},
|
|
1265
1265
|
"node_modules/fastq": {
|
|
1266
|
-
"version": "1.20.
|
|
1267
|
-
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.
|
|
1268
|
-
"integrity": "sha512-
|
|
1266
|
+
"version": "1.20.3",
|
|
1267
|
+
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.3.tgz",
|
|
1268
|
+
"integrity": "sha512-XKv5nnLs6nLF71NgiKJLIZFLkPyIEuOselLG7ujZnGrRfQK8HpvY+WqKhAJUAdLomwVHErVS4LfxFlPq0/FTAw==",
|
|
1269
1269
|
"license": "ISC",
|
|
1270
1270
|
"dependencies": {
|
|
1271
1271
|
"reusify": "^1.0.4"
|
|
@@ -1299,9 +1299,9 @@
|
|
|
1299
1299
|
}
|
|
1300
1300
|
},
|
|
1301
1301
|
"node_modules/find-my-way": {
|
|
1302
|
-
"version": "9.
|
|
1303
|
-
"resolved": "https://registry.npmjs.org/find-my-way/-/find-my-way-9.
|
|
1304
|
-
"integrity": "sha512-
|
|
1302
|
+
"version": "9.9.0",
|
|
1303
|
+
"resolved": "https://registry.npmjs.org/find-my-way/-/find-my-way-9.9.0.tgz",
|
|
1304
|
+
"integrity": "sha512-sJsgZ1sQH2UDuowPuMKg8az7Qc8F0jnj+SKkFWU/+T0xcFlgV5skgXOGUqmQzOdmW6ALA7AhJINWx3qFBkbLHA==",
|
|
1305
1305
|
"license": "MIT",
|
|
1306
1306
|
"dependencies": {
|
|
1307
1307
|
"fast-deep-equal": "^3.1.3",
|
|
@@ -1442,9 +1442,9 @@
|
|
|
1442
1442
|
}
|
|
1443
1443
|
},
|
|
1444
1444
|
"node_modules/hono": {
|
|
1445
|
-
"version": "4.13.
|
|
1446
|
-
"resolved": "https://registry.npmjs.org/hono/-/hono-4.13.
|
|
1447
|
-
"integrity": "sha512-
|
|
1445
|
+
"version": "4.13.13",
|
|
1446
|
+
"resolved": "https://registry.npmjs.org/hono/-/hono-4.13.13.tgz",
|
|
1447
|
+
"integrity": "sha512-CQ46U0ZkAGmbT/4UxdzzGJpacP2IeKgY4a5/tOI9AABbpOMfK739wfDXmv1usCk+3RkKj1hQy4/fjhiwa2xlrA==",
|
|
1448
1448
|
"license": "MIT",
|
|
1449
1449
|
"engines": {
|
|
1450
1450
|
"node": ">=16.9.0"
|
|
@@ -1541,9 +1541,9 @@
|
|
|
1541
1541
|
"license": "ISC"
|
|
1542
1542
|
},
|
|
1543
1543
|
"node_modules/ip-address": {
|
|
1544
|
-
"version": "10.
|
|
1545
|
-
"resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.
|
|
1546
|
-
"integrity": "sha512-
|
|
1544
|
+
"version": "10.7.3",
|
|
1545
|
+
"resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.7.3.tgz",
|
|
1546
|
+
"integrity": "sha512-A1kdq/tSb5QjvKvAMgIoEvDBIgL7qaqVP/jkvSwYYRZ9iEzvPpopxp2wQfu3SuZRHtpHNxMn8Fs0bS+gf5Xmwg==",
|
|
1547
1547
|
"license": "MIT",
|
|
1548
1548
|
"engines": {
|
|
1549
1549
|
"node": ">= 12"
|
|
@@ -1571,9 +1571,9 @@
|
|
|
1571
1571
|
"license": "ISC"
|
|
1572
1572
|
},
|
|
1573
1573
|
"node_modules/jose": {
|
|
1574
|
-
"version": "6.2.
|
|
1575
|
-
"resolved": "https://registry.npmjs.org/jose/-/jose-6.2.
|
|
1576
|
-
"integrity": "sha512-
|
|
1574
|
+
"version": "6.2.12",
|
|
1575
|
+
"resolved": "https://registry.npmjs.org/jose/-/jose-6.2.12.tgz",
|
|
1576
|
+
"integrity": "sha512-9NiFmJEex0sy2Dk58j2UGBSHgUs2ypF9eZSu4L6vjOX3Dp96Sw1F3uL+H+D1sx02jZZdzUT0HgvCy59CuvXcWw==",
|
|
1577
1577
|
"license": "MIT",
|
|
1578
1578
|
"funding": {
|
|
1579
1579
|
"url": "https://github.com/sponsors/panva"
|
|
@@ -1695,9 +1695,9 @@
|
|
|
1695
1695
|
"license": "MIT"
|
|
1696
1696
|
},
|
|
1697
1697
|
"node_modules/lru-cache": {
|
|
1698
|
-
"version": "11.5.
|
|
1699
|
-
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.
|
|
1700
|
-
"integrity": "sha512-
|
|
1698
|
+
"version": "11.5.3",
|
|
1699
|
+
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.3.tgz",
|
|
1700
|
+
"integrity": "sha512-U4N8FgzmWxc8k1VH8Kr6lQg18U7Fjvby6wXHVRX/ZZ7IwWbRMgrRbP0Wrb5q5NVinryp4SQampHKdvtecItxUg==",
|
|
1701
1701
|
"license": "BlueOak-1.0.0",
|
|
1702
1702
|
"engines": {
|
|
1703
1703
|
"node": "20 || >=22"
|
|
@@ -1844,18 +1844,38 @@
|
|
|
1844
1844
|
"license": "MIT"
|
|
1845
1845
|
},
|
|
1846
1846
|
"node_modules/negotiator": {
|
|
1847
|
-
"version": "1.
|
|
1848
|
-
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.
|
|
1849
|
-
"integrity": "sha512-
|
|
1847
|
+
"version": "1.1.0",
|
|
1848
|
+
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.1.0.tgz",
|
|
1849
|
+
"integrity": "sha512-NMPBRMJgiQHjbd8phG3Vebdx4kZ1H121rbl5IkMqeOsahptB9BKo/d7oJ3zTXqTgagn2bWlNSXkh0QUGM31RYg==",
|
|
1850
1850
|
"license": "MIT",
|
|
1851
|
+
"dependencies": {
|
|
1852
|
+
"content-type": "^2.1.0"
|
|
1853
|
+
},
|
|
1851
1854
|
"engines": {
|
|
1852
|
-
"node": ">=
|
|
1855
|
+
"node": ">=18"
|
|
1856
|
+
},
|
|
1857
|
+
"funding": {
|
|
1858
|
+
"type": "opencollective",
|
|
1859
|
+
"url": "https://opencollective.com/express"
|
|
1860
|
+
}
|
|
1861
|
+
},
|
|
1862
|
+
"node_modules/negotiator/node_modules/content-type": {
|
|
1863
|
+
"version": "2.1.0",
|
|
1864
|
+
"resolved": "https://registry.npmjs.org/content-type/-/content-type-2.1.0.tgz",
|
|
1865
|
+
"integrity": "sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag==",
|
|
1866
|
+
"license": "MIT",
|
|
1867
|
+
"engines": {
|
|
1868
|
+
"node": ">=18"
|
|
1869
|
+
},
|
|
1870
|
+
"funding": {
|
|
1871
|
+
"type": "opencollective",
|
|
1872
|
+
"url": "https://opencollective.com/express"
|
|
1853
1873
|
}
|
|
1854
1874
|
},
|
|
1855
1875
|
"node_modules/node-abi": {
|
|
1856
|
-
"version": "3.
|
|
1857
|
-
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.
|
|
1858
|
-
"integrity": "sha512-
|
|
1876
|
+
"version": "3.96.0",
|
|
1877
|
+
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.96.0.tgz",
|
|
1878
|
+
"integrity": "sha512-rebQ/lz7i0EkoLzUVSrKRzA69zMkwLp95kKMWoMDkkM00Suxz0D7zEQPwRml5fQum24mj7bPvmlgLAmu2JCiYg==",
|
|
1859
1879
|
"license": "MIT",
|
|
1860
1880
|
"dependencies": {
|
|
1861
1881
|
"semver": "^7.3.5"
|
|
@@ -1960,9 +1980,9 @@
|
|
|
1960
1980
|
}
|
|
1961
1981
|
},
|
|
1962
1982
|
"node_modules/pino": {
|
|
1963
|
-
"version": "10.
|
|
1964
|
-
"resolved": "https://registry.npmjs.org/pino/-/pino-10.
|
|
1965
|
-
"integrity": "sha512-
|
|
1983
|
+
"version": "10.4.0",
|
|
1984
|
+
"resolved": "https://registry.npmjs.org/pino/-/pino-10.4.0.tgz",
|
|
1985
|
+
"integrity": "sha512-bk1ZMTwG/Vymx+zPoa28MhNzucFvXJWp3csrSuxuHPSMeUettaCoQ5Jvg07mtC4JGNpcfTwz41oVCnNgBK9+vA==",
|
|
1966
1986
|
"license": "MIT",
|
|
1967
1987
|
"dependencies": {
|
|
1968
1988
|
"@pinojs/redact": "^0.4.0",
|
|
@@ -1972,7 +1992,7 @@
|
|
|
1972
1992
|
"pino-std-serializers": "^7.0.0",
|
|
1973
1993
|
"process-warning": "^5.0.0",
|
|
1974
1994
|
"quick-format-unescaped": "^4.0.3",
|
|
1975
|
-
"real-require": "^0.
|
|
1995
|
+
"real-require": "^1.0.0",
|
|
1976
1996
|
"safe-stable-stringify": "^2.3.1",
|
|
1977
1997
|
"sonic-boom": "^4.0.1",
|
|
1978
1998
|
"thread-stream": "^4.0.0"
|
|
@@ -2049,9 +2069,9 @@
|
|
|
2049
2069
|
"license": "MIT"
|
|
2050
2070
|
},
|
|
2051
2071
|
"node_modules/proxy-addr": {
|
|
2052
|
-
"version": "2.0.
|
|
2053
|
-
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.
|
|
2054
|
-
"integrity": "sha512-
|
|
2072
|
+
"version": "2.0.8",
|
|
2073
|
+
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.8.tgz",
|
|
2074
|
+
"integrity": "sha512-5nnx0yGyVUcY6t9RnWcARWtwT9F1D8O9rt08htPvnd49W1IgZtmLkhu9WfMzQj1cFxjHIO6connUNVW5k7AVyQ==",
|
|
2055
2075
|
"license": "MIT",
|
|
2056
2076
|
"dependencies": {
|
|
2057
2077
|
"forwarded": "0.2.0",
|
|
@@ -2059,6 +2079,10 @@
|
|
|
2059
2079
|
},
|
|
2060
2080
|
"engines": {
|
|
2061
2081
|
"node": ">= 0.10"
|
|
2082
|
+
},
|
|
2083
|
+
"funding": {
|
|
2084
|
+
"type": "opencollective",
|
|
2085
|
+
"url": "https://opencollective.com/express"
|
|
2062
2086
|
}
|
|
2063
2087
|
},
|
|
2064
2088
|
"node_modules/proxy-addr/node_modules/ipaddr.js": {
|
|
@@ -2089,9 +2113,9 @@
|
|
|
2089
2113
|
}
|
|
2090
2114
|
},
|
|
2091
2115
|
"node_modules/qs": {
|
|
2092
|
-
"version": "6.
|
|
2093
|
-
"resolved": "https://registry.npmjs.org/qs/-/qs-6.
|
|
2094
|
-
"integrity": "sha512-
|
|
2116
|
+
"version": "6.16.0",
|
|
2117
|
+
"resolved": "https://registry.npmjs.org/qs/-/qs-6.16.0.tgz",
|
|
2118
|
+
"integrity": "sha512-h6fhOIaRrID2CbEY2fqs+7t+UXZo+MLAnU5gRIq85uFtdiUPCdsApMlHhXogKVM4HM2DVbIjGNTTYH2OcmP1vA==",
|
|
2095
2119
|
"license": "BSD-3-Clause",
|
|
2096
2120
|
"dependencies": {
|
|
2097
2121
|
"es-define-property": "^1.0.1",
|
|
@@ -2168,13 +2192,10 @@
|
|
|
2168
2192
|
}
|
|
2169
2193
|
},
|
|
2170
2194
|
"node_modules/real-require": {
|
|
2171
|
-
"version": "0.
|
|
2172
|
-
"resolved": "https://registry.npmjs.org/real-require/-/real-require-0.
|
|
2173
|
-
"integrity": "sha512-
|
|
2174
|
-
"license": "MIT"
|
|
2175
|
-
"engines": {
|
|
2176
|
-
"node": ">= 12.13.0"
|
|
2177
|
-
}
|
|
2195
|
+
"version": "1.0.0",
|
|
2196
|
+
"resolved": "https://registry.npmjs.org/real-require/-/real-require-1.0.0.tgz",
|
|
2197
|
+
"integrity": "sha512-P4nbQYQfePJxRSmY+v/KINxVucm4NF3p3s7pJveMTtom52FR4YGltUQLB8idDXwDDWW+eYrWDFbuzUnjoWHF7g==",
|
|
2198
|
+
"license": "MIT"
|
|
2178
2199
|
},
|
|
2179
2200
|
"node_modules/require-from-string": {
|
|
2180
2201
|
"version": "2.0.2",
|
|
@@ -2525,9 +2546,9 @@
|
|
|
2525
2546
|
}
|
|
2526
2547
|
},
|
|
2527
2548
|
"node_modules/standardwebhooks": {
|
|
2528
|
-
"version": "1.
|
|
2529
|
-
"resolved": "https://registry.npmjs.org/standardwebhooks/-/standardwebhooks-1.
|
|
2530
|
-
"integrity": "sha512-
|
|
2549
|
+
"version": "1.1.1",
|
|
2550
|
+
"resolved": "https://registry.npmjs.org/standardwebhooks/-/standardwebhooks-1.1.1.tgz",
|
|
2551
|
+
"integrity": "sha512-bCbX9ZEyFkWPsRz7Bl3NuQUJohmwGSev/yhr7vhaGPlc4AfIrspIRa6cPTBuI1ItmrTDJ4d/S2hCsfe4+vQGnQ==",
|
|
2531
2552
|
"license": "MIT",
|
|
2532
2553
|
"dependencies": {
|
|
2533
2554
|
"@stablelib/base64": "^1.0.0",
|
|
@@ -2607,12 +2628,6 @@
|
|
|
2607
2628
|
"node": ">=20"
|
|
2608
2629
|
}
|
|
2609
2630
|
},
|
|
2610
|
-
"node_modules/thread-stream/node_modules/real-require": {
|
|
2611
|
-
"version": "1.0.0",
|
|
2612
|
-
"resolved": "https://registry.npmjs.org/real-require/-/real-require-1.0.0.tgz",
|
|
2613
|
-
"integrity": "sha512-P4nbQYQfePJxRSmY+v/KINxVucm4NF3p3s7pJveMTtom52FR4YGltUQLB8idDXwDDWW+eYrWDFbuzUnjoWHF7g==",
|
|
2614
|
-
"license": "MIT"
|
|
2615
|
-
},
|
|
2616
2631
|
"node_modules/toad-cache": {
|
|
2617
2632
|
"version": "3.7.4",
|
|
2618
2633
|
"resolved": "https://registry.npmjs.org/toad-cache/-/toad-cache-3.7.4.tgz",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@longleash/cli",
|
|
3
|
-
"version": "0.1.0-rc.
|
|
3
|
+
"version": "0.1.0-rc.12",
|
|
4
4
|
"description": "Securely control Claude Code and Codex sessions on your laptop from your phone.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
"@fastify/websocket": "11.3.0",
|
|
60
60
|
"@modelcontextprotocol/sdk": "1.30.0",
|
|
61
61
|
"better-sqlite3": "12.11.1",
|
|
62
|
-
"fastify": "5.
|
|
62
|
+
"fastify": "5.12.5",
|
|
63
63
|
"qrcode-terminal": "0.12.0",
|
|
64
64
|
"web-push": "3.6.7",
|
|
65
65
|
"ws": "8.21.1",
|