@moxt-ai/mobius 0.0.369 → 0.0.371
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/{chunk-3GFBCVGZ.js → chunk-23EBYYOU.js} +68 -9
- package/dist/{chunk-3GFBCVGZ.js.map → chunk-23EBYYOU.js.map} +3 -3
- package/dist/{chunk-2RHEJMMU.js → chunk-MS57BIBB.js} +2 -2
- package/dist/{chunk-2RHEJMMU.js.map → chunk-MS57BIBB.js.map} +1 -1
- package/dist/{chunk-PG7W3R2P.js → chunk-XQEFITZA.js} +2 -2
- package/dist/cli/handler/diagnose/config.d.ts +23 -0
- package/dist/cli/handler/diagnose/config.d.ts.map +1 -0
- package/dist/cli/handler/diagnose/config.js +55 -0
- package/dist/cli/handler/diagnose/config.js.map +1 -0
- package/dist/cli/handler/diagnose/index.d.ts +4 -0
- package/dist/cli/handler/diagnose/index.d.ts.map +1 -0
- package/dist/cli/handler/diagnose/index.js +314 -0
- package/dist/cli/handler/diagnose/index.js.map +1 -0
- package/dist/cli/handler/diagnose/routes.d.ts +16 -0
- package/dist/cli/handler/diagnose/routes.d.ts.map +1 -0
- package/dist/cli/handler/diagnose/routes.js +89 -0
- package/dist/cli/handler/diagnose/routes.js.map +1 -0
- package/dist/cli/handler/diagnose/worker.d.ts +3 -0
- package/dist/cli/handler/diagnose/worker.d.ts.map +1 -0
- package/dist/cli/handler/diagnose/worker.js +95 -0
- package/dist/cli/handler/diagnose/worker.js.map +1 -0
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +2 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/{cli-5UCO7ZEY.js → cli-FDG4YLBN.js} +626 -39
- package/dist/{cli-5UCO7ZEY.js.map → cli-FDG4YLBN.js.map} +4 -4
- package/dist/cli.js +3 -3
- package/dist/engine/runtime/relay/connect.d.ts +1 -1
- package/dist/engine/runtime/relay/connect.d.ts.map +1 -1
- package/dist/engine/runtime/relay/connect.js +35 -2
- package/dist/engine/runtime/relay/connect.js.map +1 -1
- package/dist/engine/runtime/relay/diagnostics.d.ts +2 -0
- package/dist/engine/runtime/relay/diagnostics.d.ts.map +1 -1
- package/dist/engine/runtime/relay/diagnostics.js +26 -3
- package/dist/engine/runtime/relay/diagnostics.js.map +1 -1
- package/dist/engine/runtime/relay/run-relay-connection.d.ts.map +1 -1
- package/dist/engine/runtime/relay/run-relay-connection.js +3 -1
- package/dist/engine/runtime/relay/run-relay-connection.js.map +1 -1
- package/dist/engine.js +2 -2
- package/dist/storage/diagnostics/relay-probe-files.d.ts +7 -0
- package/dist/storage/diagnostics/relay-probe-files.d.ts.map +1 -0
- package/dist/storage/diagnostics/relay-probe-files.js +40 -0
- package/dist/storage/diagnostics/relay-probe-files.js.map +1 -0
- package/package.json +1 -1
- /package/dist/{chunk-PG7W3R2P.js.map → chunk-XQEFITZA.js.map} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
require_semver
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-XQEFITZA.js";
|
|
4
4
|
import {
|
|
5
5
|
BoundedLineLog,
|
|
6
6
|
MissingAdapter,
|
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
canonicalPath,
|
|
18
18
|
decodeIdentifier,
|
|
19
19
|
decodeRuntimeUpgradeVersion,
|
|
20
|
+
describeRelayFailure,
|
|
20
21
|
discoverLocalAgentInventory,
|
|
21
22
|
ensurePrivateDirectory,
|
|
22
23
|
external_exports,
|
|
@@ -35,13 +36,13 @@ import {
|
|
|
35
36
|
unhandledRejectionLogFilename,
|
|
36
37
|
validateLocalPath,
|
|
37
38
|
validatePairingId
|
|
38
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-23EBYYOU.js";
|
|
39
40
|
import {
|
|
40
41
|
__callDispose,
|
|
41
42
|
__toESM,
|
|
42
43
|
__using,
|
|
43
44
|
package_default
|
|
44
|
-
} from "./chunk-
|
|
45
|
+
} from "./chunk-MS57BIBB.js";
|
|
45
46
|
|
|
46
47
|
// ../../node_modules/.pnpm/commander@15.0.0/node_modules/commander/lib/error.js
|
|
47
48
|
var CommanderError = class extends Error {
|
|
@@ -1343,9 +1344,9 @@ var Command = class _Command extends EventEmitter {
|
|
|
1343
1344
|
* @param {object} [configuration] - configuration options
|
|
1344
1345
|
* @return {(Command | object)} `this` command for chaining, or stored configuration
|
|
1345
1346
|
*/
|
|
1346
|
-
configureHelp(
|
|
1347
|
-
if (
|
|
1348
|
-
this._helpConfiguration =
|
|
1347
|
+
configureHelp(configuration2) {
|
|
1348
|
+
if (configuration2 === void 0) return this._helpConfiguration;
|
|
1349
|
+
this._helpConfiguration = configuration2;
|
|
1349
1350
|
return this;
|
|
1350
1351
|
}
|
|
1351
1352
|
/**
|
|
@@ -1370,11 +1371,11 @@ var Command = class _Command extends EventEmitter {
|
|
|
1370
1371
|
* @param {object} [configuration] - configuration options
|
|
1371
1372
|
* @return {(Command | object)} `this` command for chaining, or stored configuration
|
|
1372
1373
|
*/
|
|
1373
|
-
configureOutput(
|
|
1374
|
-
if (
|
|
1374
|
+
configureOutput(configuration2) {
|
|
1375
|
+
if (configuration2 === void 0) return this._outputConfiguration;
|
|
1375
1376
|
this._outputConfiguration = {
|
|
1376
1377
|
...this._outputConfiguration,
|
|
1377
|
-
...
|
|
1378
|
+
...configuration2
|
|
1378
1379
|
};
|
|
1379
1380
|
return this;
|
|
1380
1381
|
}
|
|
@@ -3984,7 +3985,7 @@ function controlSocketPath(stateDirectory, endpoint = "manager") {
|
|
|
3984
3985
|
}
|
|
3985
3986
|
async function readSocketMessage(socket, signal) {
|
|
3986
3987
|
signal.throwIfAborted();
|
|
3987
|
-
return await new Promise((
|
|
3988
|
+
return await new Promise((resolve6, reject) => {
|
|
3988
3989
|
let encoded = "";
|
|
3989
3990
|
const finish = (error, value) => {
|
|
3990
3991
|
signal.removeEventListener("abort", abort);
|
|
@@ -3992,7 +3993,7 @@ async function readSocketMessage(socket, signal) {
|
|
|
3992
3993
|
socket.removeAllListeners("error");
|
|
3993
3994
|
socket.removeAllListeners("end");
|
|
3994
3995
|
if (error === void 0) {
|
|
3995
|
-
|
|
3996
|
+
resolve6(value);
|
|
3996
3997
|
} else {
|
|
3997
3998
|
reject(error);
|
|
3998
3999
|
}
|
|
@@ -4028,14 +4029,14 @@ async function sendLocalRequest(stateDirectory, endpoint, command, signal) {
|
|
|
4028
4029
|
deadline.throwIfAborted();
|
|
4029
4030
|
const socket = createConnection(controlSocketPath(stateDirectory, endpoint));
|
|
4030
4031
|
try {
|
|
4031
|
-
await new Promise((
|
|
4032
|
+
await new Promise((resolve6, reject) => {
|
|
4032
4033
|
const abort = () => {
|
|
4033
4034
|
socket.destroy();
|
|
4034
4035
|
reject(deadline.reason);
|
|
4035
4036
|
};
|
|
4036
4037
|
socket.once("connect", () => {
|
|
4037
4038
|
deadline.removeEventListener("abort", abort);
|
|
4038
|
-
|
|
4039
|
+
resolve6();
|
|
4039
4040
|
});
|
|
4040
4041
|
socket.once("error", reject);
|
|
4041
4042
|
deadline.addEventListener("abort", abort, { once: true });
|
|
@@ -4089,21 +4090,21 @@ async function serveLocalControl(stateDirectory, endpoint, signal, handle, onLis
|
|
|
4089
4090
|
});
|
|
4090
4091
|
try {
|
|
4091
4092
|
await platform.prepareControlSocket(path2);
|
|
4092
|
-
await new Promise((
|
|
4093
|
-
server.once("listening",
|
|
4093
|
+
await new Promise((resolve6, reject) => {
|
|
4094
|
+
server.once("listening", resolve6);
|
|
4094
4095
|
server.once("error", reject);
|
|
4095
4096
|
server.listen(path2);
|
|
4096
4097
|
});
|
|
4097
4098
|
await platform.secureControlSocket(path2);
|
|
4098
4099
|
await onListening();
|
|
4099
4100
|
if (!signal.aborted) {
|
|
4100
|
-
await new Promise((
|
|
4101
|
+
await new Promise((resolve6) => signal.addEventListener("abort", () => resolve6(), { once: true }));
|
|
4101
4102
|
}
|
|
4102
4103
|
} finally {
|
|
4103
4104
|
for (const socket of sockets) {
|
|
4104
4105
|
socket.destroy();
|
|
4105
4106
|
}
|
|
4106
|
-
await new Promise((
|
|
4107
|
+
await new Promise((resolve6) => server.close(() => resolve6()));
|
|
4107
4108
|
await Promise.allSettled(requests);
|
|
4108
4109
|
await platform.removeControlSocket(path2).catch(() => void 0);
|
|
4109
4110
|
}
|
|
@@ -4893,13 +4894,13 @@ async function waitForManagerExit(stateDirectory, signal) {
|
|
|
4893
4894
|
if (!await managerLockExists(stateDirectory)) {
|
|
4894
4895
|
return;
|
|
4895
4896
|
}
|
|
4896
|
-
await new Promise((
|
|
4897
|
+
await new Promise((resolve6, reject) => {
|
|
4897
4898
|
const timeout = setTimeout(finish, 20);
|
|
4898
4899
|
const abort = () => finish(deadline.reason);
|
|
4899
4900
|
function finish(cause) {
|
|
4900
4901
|
clearTimeout(timeout);
|
|
4901
4902
|
deadline.removeEventListener("abort", abort);
|
|
4902
|
-
cause === void 0 ?
|
|
4903
|
+
cause === void 0 ? resolve6() : reject(cause);
|
|
4903
4904
|
}
|
|
4904
4905
|
deadline.addEventListener("abort", abort, { once: true });
|
|
4905
4906
|
});
|
|
@@ -4963,13 +4964,13 @@ async function ensureManager(stateDirectory, launch, signal) {
|
|
|
4963
4964
|
await launchManager(launch);
|
|
4964
4965
|
managerStarted = true;
|
|
4965
4966
|
}
|
|
4966
|
-
await new Promise((
|
|
4967
|
+
await new Promise((resolve6, reject) => {
|
|
4967
4968
|
const timeout = setTimeout(finish, 50);
|
|
4968
4969
|
const abort = () => finish(signal.reason);
|
|
4969
4970
|
function finish(cause2) {
|
|
4970
4971
|
clearTimeout(timeout);
|
|
4971
4972
|
signal.removeEventListener("abort", abort);
|
|
4972
|
-
cause2 === void 0 ?
|
|
4973
|
+
cause2 === void 0 ? resolve6() : reject(cause2);
|
|
4973
4974
|
}
|
|
4974
4975
|
signal.addEventListener("abort", abort, { once: true });
|
|
4975
4976
|
});
|
|
@@ -5171,11 +5172,11 @@ async function checkDaemonReleaseUpgrade(signal, activity) {
|
|
|
5171
5172
|
const _reservation = __using(_stack, reservation);
|
|
5172
5173
|
signal.throwIfAborted();
|
|
5173
5174
|
await requestInstalledDaemonReleaseSwitch(control.stateDirectory, launch, signal);
|
|
5174
|
-
await new Promise((
|
|
5175
|
+
await new Promise((resolve6) => {
|
|
5175
5176
|
if (signal.aborted) {
|
|
5176
|
-
|
|
5177
|
+
resolve6();
|
|
5177
5178
|
} else {
|
|
5178
|
-
signal.addEventListener("abort", () =>
|
|
5179
|
+
signal.addEventListener("abort", () => resolve6(), { once: true });
|
|
5179
5180
|
}
|
|
5180
5181
|
});
|
|
5181
5182
|
} catch (_) {
|
|
@@ -5444,12 +5445,597 @@ function registerDaemonProcessLifecycleHandlers(program2, context) {
|
|
|
5444
5445
|
registerUpgradeCommand(program2, context);
|
|
5445
5446
|
}
|
|
5446
5447
|
|
|
5448
|
+
// src/cli/handler/diagnose/index.ts
|
|
5449
|
+
import { fork } from "node:child_process";
|
|
5450
|
+
import { join as join13, resolve as resolve3 } from "node:path";
|
|
5451
|
+
|
|
5452
|
+
// src/storage/diagnostics/relay-probe-files.ts
|
|
5453
|
+
import { mkdir, readFile as readFile6, rm as rm2, stat as stat2, writeFile as writeFile4 } from "node:fs/promises";
|
|
5454
|
+
import { join as join11 } from "node:path";
|
|
5455
|
+
var ProbeConfigurationFileError = class extends Error {
|
|
5456
|
+
code = "probe_config_invalid";
|
|
5457
|
+
};
|
|
5458
|
+
async function readPrivateProbeConfiguration(path2, signal) {
|
|
5459
|
+
signal.throwIfAborted();
|
|
5460
|
+
const metadata = await stat2(path2);
|
|
5461
|
+
if (!metadata.isFile() || metadata.size > 16384 || process.platform !== "win32" && (metadata.mode & 63) !== 0) {
|
|
5462
|
+
throw new ProbeConfigurationFileError(
|
|
5463
|
+
"The pairing configuration must be a private, small regular file (mode 0600)"
|
|
5464
|
+
);
|
|
5465
|
+
}
|
|
5466
|
+
try {
|
|
5467
|
+
return JSON.parse(await readFile6(path2, { encoding: "utf8", signal }));
|
|
5468
|
+
} catch {
|
|
5469
|
+
signal.throwIfAborted();
|
|
5470
|
+
throw new ProbeConfigurationFileError("The pairing configuration is not valid JSON");
|
|
5471
|
+
}
|
|
5472
|
+
}
|
|
5473
|
+
async function createProbeOutput(directory) {
|
|
5474
|
+
await mkdir(directory, { mode: 448 });
|
|
5475
|
+
}
|
|
5476
|
+
async function ensureProbeDirectory(directory) {
|
|
5477
|
+
await mkdir(directory, { recursive: true, mode: 448 });
|
|
5478
|
+
}
|
|
5479
|
+
async function writeProbeReport(directory, report) {
|
|
5480
|
+
await writeFile4(join11(directory, "report.json"), `${JSON.stringify(report, null, 2)}
|
|
5481
|
+
`, { mode: 384 });
|
|
5482
|
+
}
|
|
5483
|
+
async function writeProbeEvents(directory, events) {
|
|
5484
|
+
await writeFile4(join11(directory, "transport.jsonl"), events.map((event) => JSON.stringify(event)).join("\n"), {
|
|
5485
|
+
mode: 384
|
|
5486
|
+
});
|
|
5487
|
+
}
|
|
5488
|
+
async function removeProbeState(directory) {
|
|
5489
|
+
await rm2(join11(directory, "state"), { recursive: true, force: true });
|
|
5490
|
+
}
|
|
5491
|
+
|
|
5492
|
+
// src/cli/handler/diagnose/config.ts
|
|
5493
|
+
var pairing = external_exports.object({ pairingId: external_exports.string().min(1).max(128), pairingCode: external_exports.string().min(1).max(128) }).readonly();
|
|
5494
|
+
var configuration = external_exports.object({ relayOrigin: external_exports.url(), direct: pairing, proxy: pairing }).readonly();
|
|
5495
|
+
var RelayProbeError = class extends Error {
|
|
5496
|
+
code;
|
|
5497
|
+
constructor(code, message) {
|
|
5498
|
+
super(message);
|
|
5499
|
+
this.code = code;
|
|
5500
|
+
}
|
|
5501
|
+
};
|
|
5502
|
+
async function readProbeConfiguration(path2, signal) {
|
|
5503
|
+
const value = await readPrivateProbeConfiguration(path2, signal);
|
|
5504
|
+
const parsed = configuration.safeParse(value);
|
|
5505
|
+
if (!parsed.success) {
|
|
5506
|
+
throw new RelayProbeError(
|
|
5507
|
+
"probe_config_invalid",
|
|
5508
|
+
"Expected relayOrigin and direct/proxy pairingId and pairingCode"
|
|
5509
|
+
);
|
|
5510
|
+
}
|
|
5511
|
+
const config = parsed.data;
|
|
5512
|
+
const origin = new URL(config.relayOrigin);
|
|
5513
|
+
if (!["https:", "http:"].includes(origin.protocol) || origin.protocol === "http:" && !["127.0.0.1", "localhost"].includes(origin.hostname) || origin.username || origin.password || origin.search || origin.hash || origin.pathname !== "/") {
|
|
5514
|
+
throw new RelayProbeError(
|
|
5515
|
+
"probe_origin_invalid",
|
|
5516
|
+
"relayOrigin must use HTTPS (or loopback HTTP), without credentials or query parameters"
|
|
5517
|
+
);
|
|
5518
|
+
}
|
|
5519
|
+
if (config.direct.pairingId === config.proxy.pairingId || config.direct.pairingCode === config.proxy.pairingCode) {
|
|
5520
|
+
throw new RelayProbeError("probe_pairings_reused", "Direct and proxy probes require distinct, unused pairings");
|
|
5521
|
+
}
|
|
5522
|
+
return config;
|
|
5523
|
+
}
|
|
5524
|
+
function configuredProbeProxy() {
|
|
5525
|
+
const value = process.env["https_proxy"] || process.env["HTTPS_PROXY"] || process.env["http_proxy"] || process.env["HTTP_PROXY"];
|
|
5526
|
+
let proxy;
|
|
5527
|
+
try {
|
|
5528
|
+
proxy = new URL(value ?? "");
|
|
5529
|
+
} catch {
|
|
5530
|
+
throw new RelayProbeError("probe_proxy_missing", "Set HTTPS_PROXY or HTTP_PROXY to an HTTP or HTTPS proxy");
|
|
5531
|
+
}
|
|
5532
|
+
if (!["http:", "https:"].includes(proxy.protocol)) {
|
|
5533
|
+
throw new RelayProbeError("probe_proxy_invalid", "The comparison requires an HTTP or HTTPS proxy");
|
|
5534
|
+
}
|
|
5535
|
+
return proxy;
|
|
5536
|
+
}
|
|
5537
|
+
function failureCode(error) {
|
|
5538
|
+
const code = error instanceof Error ? Reflect.get(error, "code") : void 0;
|
|
5539
|
+
return typeof code === "string" && /^[A-Za-z0-9_-]{1,128}$/u.test(code) ? code : "probe_failed";
|
|
5540
|
+
}
|
|
5541
|
+
|
|
5542
|
+
// src/cli/handler/diagnose/routes.ts
|
|
5543
|
+
import { execFile } from "node:child_process";
|
|
5544
|
+
import { lookup } from "node:dns/promises";
|
|
5545
|
+
import { isIP } from "node:net";
|
|
5546
|
+
import { promisify } from "node:util";
|
|
5547
|
+
var execute = promisify(execFile);
|
|
5548
|
+
var routeEvidenceSchema = external_exports.object({
|
|
5549
|
+
hostname: external_exports.string(),
|
|
5550
|
+
addresses: external_exports.array(external_exports.string()),
|
|
5551
|
+
routes: external_exports.array(
|
|
5552
|
+
external_exports.object({ address: external_exports.string(), interface: external_exports.string(), gateway: external_exports.string(), tunnelInterface: external_exports.boolean() })
|
|
5553
|
+
),
|
|
5554
|
+
failures: external_exports.array(external_exports.string()),
|
|
5555
|
+
omittedAddresses: external_exports.number().int().nonnegative()
|
|
5556
|
+
});
|
|
5557
|
+
async function addresses(hostname, signal) {
|
|
5558
|
+
if (isIP(hostname) !== 0) {
|
|
5559
|
+
return [hostname];
|
|
5560
|
+
}
|
|
5561
|
+
const aborted = Promise.withResolvers();
|
|
5562
|
+
const abort = () => aborted.reject(signal.reason);
|
|
5563
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
5564
|
+
try {
|
|
5565
|
+
signal.throwIfAborted();
|
|
5566
|
+
const found = await Promise.race([lookup(hostname, { all: true }), aborted.promise]);
|
|
5567
|
+
return [...new Set(found.map((item) => item.address))];
|
|
5568
|
+
} finally {
|
|
5569
|
+
signal.removeEventListener("abort", abort);
|
|
5570
|
+
}
|
|
5571
|
+
}
|
|
5572
|
+
async function collectRouteEvidence(hostname, cancellation) {
|
|
5573
|
+
const signal = AbortSignal.any([cancellation, AbortSignal.timeout(5e3)]);
|
|
5574
|
+
const evidence = { hostname, addresses: [], routes: [], failures: [], omittedAddresses: 0 };
|
|
5575
|
+
try {
|
|
5576
|
+
const resolved = await addresses(hostname.replace(/^\[|\]$/gu, ""), signal);
|
|
5577
|
+
evidence.addresses.push(...resolved.slice(0, 8));
|
|
5578
|
+
evidence.omittedAddresses = Math.max(0, resolved.length - evidence.addresses.length);
|
|
5579
|
+
await Promise.all(
|
|
5580
|
+
evidence.addresses.map(async (address) => {
|
|
5581
|
+
try {
|
|
5582
|
+
let networkInterface = "";
|
|
5583
|
+
let gateway = "";
|
|
5584
|
+
if (process.platform === "darwin") {
|
|
5585
|
+
const { stdout } = await execute(
|
|
5586
|
+
"/sbin/route",
|
|
5587
|
+
["-n", "get", ...isIP(address) === 6 ? ["-inet6"] : [], address],
|
|
5588
|
+
{
|
|
5589
|
+
signal,
|
|
5590
|
+
timeout: 2e3,
|
|
5591
|
+
maxBuffer: 32768
|
|
5592
|
+
}
|
|
5593
|
+
);
|
|
5594
|
+
networkInterface = stdout.match(/^\s*interface:\s*(\S+)/mu)?.[1] ?? "";
|
|
5595
|
+
gateway = stdout.match(/^\s*gateway:\s*(\S+)/mu)?.[1] ?? "";
|
|
5596
|
+
} else if (process.platform === "linux") {
|
|
5597
|
+
const { stdout } = await execute("ip", ["-json", "route", "get", address], {
|
|
5598
|
+
signal,
|
|
5599
|
+
timeout: 2e3,
|
|
5600
|
+
maxBuffer: 32768
|
|
5601
|
+
});
|
|
5602
|
+
const result = external_exports.array(external_exports.object({ dev: external_exports.string(), gateway: external_exports.string().optional() })).parse(JSON.parse(stdout));
|
|
5603
|
+
networkInterface = result[0]?.dev ?? "";
|
|
5604
|
+
gateway = result[0]?.gateway ?? "";
|
|
5605
|
+
} else {
|
|
5606
|
+
evidence.failures.push("route_platform_unsupported");
|
|
5607
|
+
return;
|
|
5608
|
+
}
|
|
5609
|
+
if (networkInterface.length === 0) {
|
|
5610
|
+
throw new RelayProbeError(
|
|
5611
|
+
"route_interface_unavailable",
|
|
5612
|
+
"The route did not identify an interface"
|
|
5613
|
+
);
|
|
5614
|
+
}
|
|
5615
|
+
evidence.routes.push({
|
|
5616
|
+
address,
|
|
5617
|
+
interface: networkInterface,
|
|
5618
|
+
gateway,
|
|
5619
|
+
tunnelInterface: /^(?:utun|tun|tap|wg|tailscale)/u.test(networkInterface)
|
|
5620
|
+
});
|
|
5621
|
+
} catch (error) {
|
|
5622
|
+
cancellation.throwIfAborted();
|
|
5623
|
+
evidence.failures.push(failureCode(error));
|
|
5624
|
+
}
|
|
5625
|
+
})
|
|
5626
|
+
);
|
|
5627
|
+
} catch (error) {
|
|
5628
|
+
cancellation.throwIfAborted();
|
|
5629
|
+
evidence.failures.push(failureCode(error));
|
|
5630
|
+
}
|
|
5631
|
+
return evidence;
|
|
5632
|
+
}
|
|
5633
|
+
|
|
5634
|
+
// src/cli/handler/diagnose/worker.ts
|
|
5635
|
+
import { join as join12 } from "node:path";
|
|
5636
|
+
async function runRelayProbeWorker(configPath, role, directory, signal) {
|
|
5637
|
+
if (!process.send) {
|
|
5638
|
+
throw new Error("The relay probe worker requires its coordinator");
|
|
5639
|
+
}
|
|
5640
|
+
const notify = (message) => {
|
|
5641
|
+
if (process.connected) {
|
|
5642
|
+
process.send?.({ ...message, role }, (error) => {
|
|
5643
|
+
if (error !== null) {
|
|
5644
|
+
controller.abort();
|
|
5645
|
+
}
|
|
5646
|
+
});
|
|
5647
|
+
}
|
|
5648
|
+
};
|
|
5649
|
+
const controller = new AbortController();
|
|
5650
|
+
const stopped = AbortSignal.any([signal, controller.signal]);
|
|
5651
|
+
const start = Promise.withResolvers();
|
|
5652
|
+
const onMessage = (value) => {
|
|
5653
|
+
const message = external_exports.object({ action: external_exports.enum(["start", "stop"]) }).safeParse(value);
|
|
5654
|
+
if (!message.success) {
|
|
5655
|
+
return;
|
|
5656
|
+
}
|
|
5657
|
+
if (message.data.action === "start") {
|
|
5658
|
+
start.resolve();
|
|
5659
|
+
} else {
|
|
5660
|
+
controller.abort();
|
|
5661
|
+
}
|
|
5662
|
+
};
|
|
5663
|
+
const abort = () => {
|
|
5664
|
+
controller.abort();
|
|
5665
|
+
start.resolve();
|
|
5666
|
+
};
|
|
5667
|
+
process.on("message", onMessage);
|
|
5668
|
+
process.once("disconnect", abort);
|
|
5669
|
+
stopped.addEventListener("abort", abort, { once: true });
|
|
5670
|
+
let routesBefore = [];
|
|
5671
|
+
try {
|
|
5672
|
+
const config = await readProbeConfiguration(configPath, stopped);
|
|
5673
|
+
const origin = new URL(config.relayOrigin);
|
|
5674
|
+
const proxy = role === "proxy" ? configuredProbeProxy() : null;
|
|
5675
|
+
routesBefore = await Promise.all([
|
|
5676
|
+
collectRouteEvidence(origin.hostname, stopped),
|
|
5677
|
+
...proxy === null ? [] : [collectRouteEvidence(proxy.hostname, stopped)]
|
|
5678
|
+
]);
|
|
5679
|
+
const workspace = join12(directory, "workspace");
|
|
5680
|
+
await ensureProbeDirectory(workspace);
|
|
5681
|
+
const engine = new MobiusRuntimeEngine({
|
|
5682
|
+
engineDataDir: join12(directory, "state"),
|
|
5683
|
+
agentLaunchEnvironment: { HOME: join12(directory, "home"), PATH: "" }
|
|
5684
|
+
});
|
|
5685
|
+
const pairing2 = config[role];
|
|
5686
|
+
const connection = await engine.pair(
|
|
5687
|
+
{
|
|
5688
|
+
relayOrigin: origin.href,
|
|
5689
|
+
pairingId: pairing2.pairingId,
|
|
5690
|
+
pairingCode: pairing2.pairingCode,
|
|
5691
|
+
defaultWorkspace: workspace
|
|
5692
|
+
},
|
|
5693
|
+
stopped
|
|
5694
|
+
);
|
|
5695
|
+
notify({ kind: "prepared", channelId: connection.channelId, runtimeId: connection.runtimeId, routesBefore });
|
|
5696
|
+
await start.promise;
|
|
5697
|
+
if (!stopped.aborted) {
|
|
5698
|
+
await engine.runLoop({
|
|
5699
|
+
connection: { kind: "saved", connectionId: connection.connectionId },
|
|
5700
|
+
signal: stopped,
|
|
5701
|
+
onConnectionStatus: (status) => notify({ kind: "status", status, timestamp: (/* @__PURE__ */ new Date()).toISOString() })
|
|
5702
|
+
});
|
|
5703
|
+
}
|
|
5704
|
+
const routesAfter = await Promise.all([
|
|
5705
|
+
collectRouteEvidence(origin.hostname, AbortSignal.timeout(6e3)),
|
|
5706
|
+
...proxy === null ? [] : [collectRouteEvidence(proxy.hostname, AbortSignal.timeout(6e3))]
|
|
5707
|
+
]);
|
|
5708
|
+
notify({ kind: "finished", routesAfter });
|
|
5709
|
+
} catch (error) {
|
|
5710
|
+
if (!stopped.aborted) {
|
|
5711
|
+
notify({ kind: "failed", code: failureCode(error), details: describeRelayFailure(error), routesBefore });
|
|
5712
|
+
process.exitCode = 1;
|
|
5713
|
+
}
|
|
5714
|
+
} finally {
|
|
5715
|
+
stopped.removeEventListener("abort", abort);
|
|
5716
|
+
process.off("message", onMessage);
|
|
5717
|
+
process.off("disconnect", abort);
|
|
5718
|
+
if (process.connected) {
|
|
5719
|
+
process.disconnect();
|
|
5720
|
+
}
|
|
5721
|
+
}
|
|
5722
|
+
}
|
|
5723
|
+
|
|
5724
|
+
// src/cli/handler/diagnose/index.ts
|
|
5725
|
+
var workerMessage = external_exports.discriminatedUnion("kind", [
|
|
5726
|
+
external_exports.object({
|
|
5727
|
+
kind: external_exports.literal("prepared"),
|
|
5728
|
+
role: external_exports.enum(["direct", "proxy"]),
|
|
5729
|
+
channelId: external_exports.string(),
|
|
5730
|
+
runtimeId: external_exports.string(),
|
|
5731
|
+
routesBefore: external_exports.array(routeEvidenceSchema)
|
|
5732
|
+
}),
|
|
5733
|
+
external_exports.object({
|
|
5734
|
+
kind: external_exports.literal("status"),
|
|
5735
|
+
role: external_exports.enum(["direct", "proxy"]),
|
|
5736
|
+
status: external_exports.string(),
|
|
5737
|
+
timestamp: external_exports.string()
|
|
5738
|
+
}),
|
|
5739
|
+
external_exports.object({
|
|
5740
|
+
kind: external_exports.literal("finished"),
|
|
5741
|
+
role: external_exports.enum(["direct", "proxy"]),
|
|
5742
|
+
routesAfter: external_exports.array(routeEvidenceSchema)
|
|
5743
|
+
}),
|
|
5744
|
+
external_exports.object({
|
|
5745
|
+
kind: external_exports.literal("failed"),
|
|
5746
|
+
role: external_exports.enum(["direct", "proxy"]),
|
|
5747
|
+
code: external_exports.string(),
|
|
5748
|
+
details: external_exports.record(external_exports.string(), external_exports.string()),
|
|
5749
|
+
routesBefore: external_exports.array(routeEvidenceSchema)
|
|
5750
|
+
})
|
|
5751
|
+
]);
|
|
5752
|
+
var ProbeLeg = class {
|
|
5753
|
+
role;
|
|
5754
|
+
#child;
|
|
5755
|
+
#directory;
|
|
5756
|
+
#prepared = Promise.withResolvers();
|
|
5757
|
+
closed;
|
|
5758
|
+
#channelId = "";
|
|
5759
|
+
#runtimeId = "";
|
|
5760
|
+
#routesBefore = [];
|
|
5761
|
+
#routesAfter = [];
|
|
5762
|
+
#onlineCount = 0;
|
|
5763
|
+
#lastStatus = "starting";
|
|
5764
|
+
#events = [];
|
|
5765
|
+
#preparationFailures = [];
|
|
5766
|
+
#omittedEvents = 0;
|
|
5767
|
+
constructor(role, config, directory, proxy) {
|
|
5768
|
+
this.role = role;
|
|
5769
|
+
this.#directory = directory;
|
|
5770
|
+
const entrypoint = process.argv[1];
|
|
5771
|
+
if (entrypoint === void 0) {
|
|
5772
|
+
throw new RelayProbeError("probe_entrypoint_missing", "Cannot locate the Mobius CLI entrypoint");
|
|
5773
|
+
}
|
|
5774
|
+
const environment = {
|
|
5775
|
+
HOME: join13(directory, "home"),
|
|
5776
|
+
PATH: process.env["PATH"] ?? "",
|
|
5777
|
+
MOBIUS_STATE_DIRECTORY: join13(directory, "state")
|
|
5778
|
+
};
|
|
5779
|
+
for (const name of [
|
|
5780
|
+
"SystemRoot",
|
|
5781
|
+
"WINDIR",
|
|
5782
|
+
"TMPDIR",
|
|
5783
|
+
"TMP",
|
|
5784
|
+
"TEMP",
|
|
5785
|
+
"NODE_EXTRA_CA_CERTS",
|
|
5786
|
+
"SSL_CERT_FILE",
|
|
5787
|
+
"SSL_CERT_DIR"
|
|
5788
|
+
]) {
|
|
5789
|
+
if (process.env[name] !== void 0) {
|
|
5790
|
+
environment[name] = process.env[name];
|
|
5791
|
+
}
|
|
5792
|
+
}
|
|
5793
|
+
environment["NO_PROXY"] = environment["no_proxy"] = role === "direct" ? "*" : "";
|
|
5794
|
+
if (role === "proxy") {
|
|
5795
|
+
environment["HTTPS_PROXY"] = environment["HTTP_PROXY"] = proxy.href;
|
|
5796
|
+
}
|
|
5797
|
+
this.#child = fork(
|
|
5798
|
+
resolve3(entrypoint),
|
|
5799
|
+
["_relay-probe-worker", "--config", config, "--role", role, "--directory", directory],
|
|
5800
|
+
{ env: environment, silent: true, windowsHide: true }
|
|
5801
|
+
);
|
|
5802
|
+
this.#child.stdout?.resume();
|
|
5803
|
+
let pending = "";
|
|
5804
|
+
this.#child.stderr?.on("data", (data) => {
|
|
5805
|
+
pending += data.toString();
|
|
5806
|
+
const lines = pending.split("\n");
|
|
5807
|
+
pending = lines.pop() ?? "";
|
|
5808
|
+
for (const line of lines) {
|
|
5809
|
+
if (line.startsWith("Mobius relay diagnostic ")) {
|
|
5810
|
+
process.stderr.write(`${role}: ${line}
|
|
5811
|
+
`);
|
|
5812
|
+
try {
|
|
5813
|
+
const event = external_exports.record(external_exports.string(), external_exports.string()).safeParse(JSON.parse(line.slice("Mobius relay diagnostic ".length)));
|
|
5814
|
+
if (event.success && event.data["channelId"] === this.#channelId) {
|
|
5815
|
+
this.#events.push(event.data);
|
|
5816
|
+
if (this.#events.length > 2e3) {
|
|
5817
|
+
this.#events.shift();
|
|
5818
|
+
this.#omittedEvents += 1;
|
|
5819
|
+
}
|
|
5820
|
+
}
|
|
5821
|
+
} catch {
|
|
5822
|
+
}
|
|
5823
|
+
}
|
|
5824
|
+
}
|
|
5825
|
+
if (pending.length > 32768) {
|
|
5826
|
+
pending = "";
|
|
5827
|
+
}
|
|
5828
|
+
});
|
|
5829
|
+
this.#child.on("message", (value) => {
|
|
5830
|
+
const message = workerMessage.safeParse(value);
|
|
5831
|
+
if (!message.success || message.data.role !== role) {
|
|
5832
|
+
return;
|
|
5833
|
+
}
|
|
5834
|
+
const event = message.data;
|
|
5835
|
+
switch (event.kind) {
|
|
5836
|
+
case "prepared":
|
|
5837
|
+
this.#channelId = event.channelId;
|
|
5838
|
+
this.#runtimeId = event.runtimeId;
|
|
5839
|
+
this.#routesBefore = event.routesBefore;
|
|
5840
|
+
this.#prepared.resolve(event);
|
|
5841
|
+
break;
|
|
5842
|
+
case "status":
|
|
5843
|
+
if (event.status === "online" && this.#lastStatus !== "online") {
|
|
5844
|
+
this.#onlineCount += 1;
|
|
5845
|
+
}
|
|
5846
|
+
this.#lastStatus = event.status;
|
|
5847
|
+
break;
|
|
5848
|
+
case "finished":
|
|
5849
|
+
this.#routesAfter = event.routesAfter;
|
|
5850
|
+
break;
|
|
5851
|
+
case "failed":
|
|
5852
|
+
this.#routesBefore = event.routesBefore;
|
|
5853
|
+
this.#preparationFailures.push(event.details);
|
|
5854
|
+
this.#prepared.reject(new RelayProbeError(event.code, `The ${role} probe failed`));
|
|
5855
|
+
break;
|
|
5856
|
+
}
|
|
5857
|
+
});
|
|
5858
|
+
this.closed = new Promise((done) => {
|
|
5859
|
+
this.#child.once("error", (error) => {
|
|
5860
|
+
this.#prepared.reject(error);
|
|
5861
|
+
done(1);
|
|
5862
|
+
});
|
|
5863
|
+
this.#child.once("close", (code) => {
|
|
5864
|
+
this.#prepared.reject(
|
|
5865
|
+
new RelayProbeError("probe_worker_exited", `The ${role} probe exited before preparation`)
|
|
5866
|
+
);
|
|
5867
|
+
done(code);
|
|
5868
|
+
});
|
|
5869
|
+
});
|
|
5870
|
+
void this.#prepared.promise.catch(() => void 0);
|
|
5871
|
+
}
|
|
5872
|
+
prepare = async () => await this.#prepared.promise;
|
|
5873
|
+
start = () => {
|
|
5874
|
+
if (this.#child.connected) {
|
|
5875
|
+
this.#child.send({ action: "start" }, () => void 0);
|
|
5876
|
+
}
|
|
5877
|
+
};
|
|
5878
|
+
stop = () => {
|
|
5879
|
+
if (this.#child.connected) {
|
|
5880
|
+
this.#child.send({ action: "stop" }, () => void 0);
|
|
5881
|
+
}
|
|
5882
|
+
};
|
|
5883
|
+
kill = () => {
|
|
5884
|
+
this.#child.kill("SIGKILL");
|
|
5885
|
+
};
|
|
5886
|
+
report = async () => {
|
|
5887
|
+
const events = this.#events;
|
|
5888
|
+
await writeProbeEvents(this.#directory, events);
|
|
5889
|
+
return {
|
|
5890
|
+
role: this.role,
|
|
5891
|
+
channelId: this.#channelId,
|
|
5892
|
+
runtimeId: this.#runtimeId,
|
|
5893
|
+
onlineCount: this.#onlineCount,
|
|
5894
|
+
routesBefore: this.#routesBefore,
|
|
5895
|
+
routesAfter: this.#routesAfter,
|
|
5896
|
+
transportFailures: events.filter((event) => event["event"] === "relay_transport_failed"),
|
|
5897
|
+
preparationFailures: this.#preparationFailures,
|
|
5898
|
+
disconnects: events.filter((event) => event["event"] === "relay_connection_closed"),
|
|
5899
|
+
exitCode: await this.closed,
|
|
5900
|
+
omittedEvents: this.#omittedEvents
|
|
5901
|
+
};
|
|
5902
|
+
};
|
|
5903
|
+
};
|
|
5904
|
+
async function compare(configPath, output, duration, context) {
|
|
5905
|
+
const config = await readProbeConfiguration(configPath, context.shutdownSignal);
|
|
5906
|
+
const proxy = configuredProbeProxy();
|
|
5907
|
+
const directory = resolve3(output);
|
|
5908
|
+
await createProbeOutput(directory);
|
|
5909
|
+
const legs = [];
|
|
5910
|
+
let startedAt = null;
|
|
5911
|
+
let endedAt = null;
|
|
5912
|
+
let completed = false;
|
|
5913
|
+
let failure = null;
|
|
5914
|
+
const deadline = AbortSignal.timeout(6e4);
|
|
5915
|
+
let durationTimer;
|
|
5916
|
+
let abortPreparation = () => void 0;
|
|
5917
|
+
try {
|
|
5918
|
+
for (const role of ["direct", "proxy"]) {
|
|
5919
|
+
context.shutdownSignal.throwIfAborted();
|
|
5920
|
+
const legDirectory = join13(directory, role);
|
|
5921
|
+
await ensureProbeDirectory(join13(legDirectory, "home"));
|
|
5922
|
+
legs.push(new ProbeLeg(role, resolve3(configPath), legDirectory, proxy));
|
|
5923
|
+
}
|
|
5924
|
+
const cancelled = Promise.withResolvers();
|
|
5925
|
+
context.shutdownSignal.throwIfAborted();
|
|
5926
|
+
abortPreparation = () => cancelled.reject(new RelayProbeError("probe_cancelled", "Relay comparison preparation was cancelled"));
|
|
5927
|
+
context.shutdownSignal.addEventListener("abort", abortPreparation, { once: true });
|
|
5928
|
+
deadline.addEventListener("abort", abortPreparation, { once: true });
|
|
5929
|
+
const prepared = await Promise.race([Promise.all(legs.map((leg) => leg.prepare())), cancelled.promise]);
|
|
5930
|
+
context.shutdownSignal.throwIfAborted();
|
|
5931
|
+
if (prepared[0]?.channelId === prepared[1]?.channelId || prepared[0]?.runtimeId === prepared[1]?.runtimeId) {
|
|
5932
|
+
throw new RelayProbeError(
|
|
5933
|
+
"probe_runtime_reused",
|
|
5934
|
+
"The Relay returned the same Runtime for distinct pairings"
|
|
5935
|
+
);
|
|
5936
|
+
}
|
|
5937
|
+
context.shutdownSignal.removeEventListener("abort", abortPreparation);
|
|
5938
|
+
deadline.removeEventListener("abort", abortPreparation);
|
|
5939
|
+
startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
5940
|
+
const finish = Promise.withResolvers();
|
|
5941
|
+
const stop = () => finish.resolve();
|
|
5942
|
+
context.shutdownSignal.addEventListener("abort", stop, { once: true });
|
|
5943
|
+
durationTimer = setTimeout(() => {
|
|
5944
|
+
completed = true;
|
|
5945
|
+
finish.resolve();
|
|
5946
|
+
}, duration * 1e3);
|
|
5947
|
+
for (const leg of legs) {
|
|
5948
|
+
leg.start();
|
|
5949
|
+
}
|
|
5950
|
+
try {
|
|
5951
|
+
await Promise.race([
|
|
5952
|
+
finish.promise,
|
|
5953
|
+
...legs.map(
|
|
5954
|
+
(leg) => leg.closed.then(() => {
|
|
5955
|
+
throw new RelayProbeError(
|
|
5956
|
+
"probe_worker_exited",
|
|
5957
|
+
`The ${leg.role} probe exited during comparison`
|
|
5958
|
+
);
|
|
5959
|
+
})
|
|
5960
|
+
)
|
|
5961
|
+
]);
|
|
5962
|
+
} finally {
|
|
5963
|
+
context.shutdownSignal.removeEventListener("abort", stop);
|
|
5964
|
+
}
|
|
5965
|
+
} catch (error) {
|
|
5966
|
+
if (!context.shutdownSignal.aborted) {
|
|
5967
|
+
failure = failureCode(error);
|
|
5968
|
+
process.exitCode = 1;
|
|
5969
|
+
}
|
|
5970
|
+
} finally {
|
|
5971
|
+
endedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
5972
|
+
if (durationTimer !== void 0) {
|
|
5973
|
+
clearTimeout(durationTimer);
|
|
5974
|
+
}
|
|
5975
|
+
context.shutdownSignal.removeEventListener("abort", abortPreparation);
|
|
5976
|
+
deadline.removeEventListener("abort", abortPreparation);
|
|
5977
|
+
for (const leg of legs) {
|
|
5978
|
+
leg.stop();
|
|
5979
|
+
}
|
|
5980
|
+
const force = setTimeout(() => {
|
|
5981
|
+
for (const leg of legs) {
|
|
5982
|
+
leg.kill();
|
|
5983
|
+
}
|
|
5984
|
+
}, 1e4);
|
|
5985
|
+
try {
|
|
5986
|
+
await Promise.all(legs.map((leg) => leg.closed));
|
|
5987
|
+
const reports = await Promise.all(legs.map((leg) => leg.report()));
|
|
5988
|
+
if (reports.some((leg) => leg.exitCode !== 0 || leg.onlineCount === 0)) {
|
|
5989
|
+
process.exitCode = 1;
|
|
5990
|
+
failure ??= "probe_not_ready";
|
|
5991
|
+
}
|
|
5992
|
+
const report = {
|
|
5993
|
+
version: context.version,
|
|
5994
|
+
targetOrigin: new URL(config.relayOrigin).origin,
|
|
5995
|
+
proxyOrigin: proxy.origin,
|
|
5996
|
+
requestedDurationSeconds: duration,
|
|
5997
|
+
startedAt,
|
|
5998
|
+
endedAt,
|
|
5999
|
+
completed,
|
|
6000
|
+
failure,
|
|
6001
|
+
directMeans: "No explicit HTTP proxy; operating-system TUN/VPN routing still applies",
|
|
6002
|
+
legs: reports
|
|
6003
|
+
};
|
|
6004
|
+
await writeProbeReport(directory, report);
|
|
6005
|
+
process.stdout.write(`${join13(directory, "report.json")}
|
|
6006
|
+
`);
|
|
6007
|
+
} finally {
|
|
6008
|
+
clearTimeout(force);
|
|
6009
|
+
await Promise.all(legs.map((leg) => removeProbeState(join13(directory, leg.role))));
|
|
6010
|
+
}
|
|
6011
|
+
}
|
|
6012
|
+
}
|
|
6013
|
+
function registerDiagnoseCommand(program2, context) {
|
|
6014
|
+
program2.command("diagnose").description("collect isolated network diagnostics").command("relay").description("compare fresh direct and proxied Runtime channels over the same observation window").requiredOption(
|
|
6015
|
+
"--config <path>",
|
|
6016
|
+
"private JSON with relayOrigin and distinct direct/proxy pairingId and pairingCode"
|
|
6017
|
+
).requiredOption("--output <directory>", "new directory for sanitized report.json and transport logs").option("--duration <seconds>", "observation duration after both pairings are prepared", "600").action(async (options) => {
|
|
6018
|
+
const duration = Number(options.duration);
|
|
6019
|
+
if (!Number.isSafeInteger(duration) || duration < 1 || duration > 86400) {
|
|
6020
|
+
throw new RelayProbeError(
|
|
6021
|
+
"probe_duration_invalid",
|
|
6022
|
+
"--duration must be a whole number from 1 to 86400 seconds"
|
|
6023
|
+
);
|
|
6024
|
+
}
|
|
6025
|
+
await compare(options.config, options.output, duration, context);
|
|
6026
|
+
});
|
|
6027
|
+
program2.command("_relay-probe-worker", { hidden: true }).requiredOption("--config <path>").requiredOption("--role <role>").requiredOption("--directory <path>").action(async (options) => {
|
|
6028
|
+
const role = external_exports.enum(["direct", "proxy"]).parse(options.role);
|
|
6029
|
+
await runRelayProbeWorker(options.config, role, options.directory, context.shutdownSignal);
|
|
6030
|
+
});
|
|
6031
|
+
}
|
|
6032
|
+
|
|
5447
6033
|
// src/cli/handler/logs/logic/collect-local-logs.ts
|
|
5448
|
-
import { join as
|
|
6034
|
+
import { join as join15, relative as relative4, resolve as resolve4 } from "node:path";
|
|
5449
6035
|
|
|
5450
6036
|
// src/storage/logs/log-files.ts
|
|
5451
|
-
import { lstat as lstat2, readdir, readFile as
|
|
5452
|
-
import { join as
|
|
6037
|
+
import { lstat as lstat2, readdir, readFile as readFile7 } from "node:fs/promises";
|
|
6038
|
+
import { join as join14, relative as relative3 } from "node:path";
|
|
5453
6039
|
var LOG_FILE_NAME_PATTERN = /^[\w.-]{1,128}\.log$/u;
|
|
5454
6040
|
var INSTALLATIONS_DIRECTORY = "installations";
|
|
5455
6041
|
var VERSIONS_DIRECTORY = "versions";
|
|
@@ -5457,17 +6043,17 @@ function isAbsent(cause) {
|
|
|
5457
6043
|
return typeof cause === "object" && cause !== null && Reflect.get(cause, "code") === "ENOENT";
|
|
5458
6044
|
}
|
|
5459
6045
|
async function findLogDirectories(root, unreadable, signal) {
|
|
5460
|
-
const versions =
|
|
5461
|
-
const installationsRoots = [
|
|
6046
|
+
const versions = join14(root, VERSIONS_DIRECTORY);
|
|
6047
|
+
const installationsRoots = [join14(root, INSTALLATIONS_DIRECTORY)];
|
|
5462
6048
|
for (const version of await listDirectories(versions, root, unreadable, signal)) {
|
|
5463
|
-
installationsRoots.push(
|
|
6049
|
+
installationsRoots.push(join14(versions, version, INSTALLATIONS_DIRECTORY));
|
|
5464
6050
|
}
|
|
5465
6051
|
const found = [];
|
|
5466
6052
|
for (const installations of installationsRoots) {
|
|
5467
6053
|
for (const dataDirectory of await listDirectories(installations, root, unreadable, signal)) {
|
|
5468
|
-
const application =
|
|
6054
|
+
const application = join14(installations, dataDirectory);
|
|
5469
6055
|
for (const installationId of await listDirectories(application, root, unreadable, signal)) {
|
|
5470
|
-
const logs =
|
|
6056
|
+
const logs = join14(application, installationId, "logs");
|
|
5471
6057
|
const status = await directoryStatus(logs);
|
|
5472
6058
|
if (status === "listed") {
|
|
5473
6059
|
found.push(logs);
|
|
@@ -5525,7 +6111,7 @@ async function readOwnedLogFile(path2, signal) {
|
|
|
5525
6111
|
return { kind: "skipped" };
|
|
5526
6112
|
}
|
|
5527
6113
|
try {
|
|
5528
|
-
return { kind: "read", content: await
|
|
6114
|
+
return { kind: "read", content: await readFile7(path2, { encoding: "utf8", signal }) };
|
|
5529
6115
|
} catch (cause) {
|
|
5530
6116
|
if (signal.aborted) {
|
|
5531
6117
|
throw cause;
|
|
@@ -5540,14 +6126,14 @@ function ownedByCurrentUser(metadata) {
|
|
|
5540
6126
|
// src/cli/handler/logs/logic/collect-local-logs.ts
|
|
5541
6127
|
async function collectLocalDaemonLogs(stateDirectory, tailLines, signal) {
|
|
5542
6128
|
signal.throwIfAborted();
|
|
5543
|
-
const root =
|
|
6129
|
+
const root = resolve4(stateDirectory);
|
|
5544
6130
|
const entries = [];
|
|
5545
6131
|
const unreadable = [];
|
|
5546
6132
|
const directories = await findLogDirectories(root, unreadable, signal);
|
|
5547
6133
|
for (const directory of directories) {
|
|
5548
6134
|
const names = await listLogFiles(directory, root, unreadable);
|
|
5549
6135
|
for (const name of names) {
|
|
5550
|
-
const path2 =
|
|
6136
|
+
const path2 = join15(directory, name);
|
|
5551
6137
|
const reported = relative4(root, path2);
|
|
5552
6138
|
const read = await readOwnedLogFile(path2, signal);
|
|
5553
6139
|
if (read.kind === "unreadable") {
|
|
@@ -5569,7 +6155,7 @@ async function collectLocalDaemonLogs(stateDirectory, tailLines, signal) {
|
|
|
5569
6155
|
return { entries, unreadable: [...unreadable].sort() };
|
|
5570
6156
|
}
|
|
5571
6157
|
function defaultStateDirectory(environment = process.env) {
|
|
5572
|
-
return
|
|
6158
|
+
return resolve4(readStateDirectory(environment));
|
|
5573
6159
|
}
|
|
5574
6160
|
|
|
5575
6161
|
// src/cli/handler/logs/index.ts
|
|
@@ -5634,7 +6220,7 @@ ${sections.join("\n")}`;
|
|
|
5634
6220
|
}
|
|
5635
6221
|
|
|
5636
6222
|
// src/cli/handler/pair/list.ts
|
|
5637
|
-
import { resolve as
|
|
6223
|
+
import { resolve as resolve5 } from "node:path";
|
|
5638
6224
|
|
|
5639
6225
|
// src/cli/handler/pair/logic/pair-list-output.ts
|
|
5640
6226
|
function savedPairSummary(connection) {
|
|
@@ -5685,7 +6271,7 @@ async function writePairList(path2, pairs, signal) {
|
|
|
5685
6271
|
function registerPairListCommand(command, context) {
|
|
5686
6272
|
command.command("list").description("list saved pairings").addOption(valueOption("--output-json <existing-file.json>", "write JSON to an existing file")).action(async (options) => {
|
|
5687
6273
|
const installation = await openMobiusCliInstallation(context.shutdownSignal, process.env);
|
|
5688
|
-
const outputPath = options.outputJson === void 0 ? null :
|
|
6274
|
+
const outputPath = options.outputJson === void 0 ? null : resolve5(options.outputJson);
|
|
5689
6275
|
const pairs = (await installation.listConnections(context.shutdownSignal)).map(savedPairSummary).sort(
|
|
5690
6276
|
(left, right) => left.appId.localeCompare(right.appId) || left.connectionId.localeCompare(right.connectionId)
|
|
5691
6277
|
);
|
|
@@ -5818,6 +6404,7 @@ function createProgram(cliContext) {
|
|
|
5818
6404
|
registerVersionHandler(program2, cliContext);
|
|
5819
6405
|
registerAgentsHandler(program2, cliContext);
|
|
5820
6406
|
registerLogsCommand(program2, cliContext);
|
|
6407
|
+
registerDiagnoseCommand(program2, cliContext);
|
|
5821
6408
|
registerInternalRuntimeHandlers(program2, cliContext);
|
|
5822
6409
|
registerPairHandlers(program2, cliContext);
|
|
5823
6410
|
registerDaemonProcessLifecycleHandlers(program2, cliContext);
|
|
@@ -5856,4 +6443,4 @@ async function runCLI() {
|
|
|
5856
6443
|
export {
|
|
5857
6444
|
runCLI
|
|
5858
6445
|
};
|
|
5859
|
-
//# sourceMappingURL=cli-
|
|
6446
|
+
//# sourceMappingURL=cli-FDG4YLBN.js.map
|