@moxt-ai/mobius 0.0.369 → 0.0.370
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-PG7W3R2P.js → chunk-AF2SHMNS.js} +2 -2
- package/dist/{chunk-2RHEJMMU.js → chunk-F4ISBXGU.js} +2 -2
- package/dist/{chunk-2RHEJMMU.js.map → chunk-F4ISBXGU.js.map} +1 -1
- package/dist/{chunk-3GFBCVGZ.js → chunk-JYM22ZR6.js} +68 -9
- package/dist/{chunk-3GFBCVGZ.js.map → chunk-JYM22ZR6.js.map} +3 -3
- 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-EY6WXGHE.js} +622 -39
- package/dist/{cli-5UCO7ZEY.js.map → cli-EY6WXGHE.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-AF2SHMNS.js.map} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
require_semver
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-AF2SHMNS.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-JYM22ZR6.js";
|
|
39
40
|
import {
|
|
40
41
|
__callDispose,
|
|
41
42
|
__toESM,
|
|
42
43
|
__using,
|
|
43
44
|
package_default
|
|
44
|
-
} from "./chunk-
|
|
45
|
+
} from "./chunk-F4ISBXGU.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,593 @@ 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("/sbin/route", ["-n", "get", address], {
|
|
5586
|
+
signal,
|
|
5587
|
+
timeout: 2e3,
|
|
5588
|
+
maxBuffer: 32768
|
|
5589
|
+
});
|
|
5590
|
+
networkInterface = stdout.match(/^\s*interface:\s*(\S+)/mu)?.[1] ?? "";
|
|
5591
|
+
gateway = stdout.match(/^\s*gateway:\s*(\S+)/mu)?.[1] ?? "";
|
|
5592
|
+
} else if (process.platform === "linux") {
|
|
5593
|
+
const { stdout } = await execute("ip", ["-json", "route", "get", address], {
|
|
5594
|
+
signal,
|
|
5595
|
+
timeout: 2e3,
|
|
5596
|
+
maxBuffer: 32768
|
|
5597
|
+
});
|
|
5598
|
+
const result = external_exports.array(external_exports.object({ dev: external_exports.string(), gateway: external_exports.string().optional() })).parse(JSON.parse(stdout));
|
|
5599
|
+
networkInterface = result[0]?.dev ?? "";
|
|
5600
|
+
gateway = result[0]?.gateway ?? "";
|
|
5601
|
+
} else {
|
|
5602
|
+
evidence.failures.push("route_platform_unsupported");
|
|
5603
|
+
return;
|
|
5604
|
+
}
|
|
5605
|
+
if (networkInterface.length === 0) {
|
|
5606
|
+
throw new RelayProbeError(
|
|
5607
|
+
"route_interface_unavailable",
|
|
5608
|
+
"The route did not identify an interface"
|
|
5609
|
+
);
|
|
5610
|
+
}
|
|
5611
|
+
evidence.routes.push({
|
|
5612
|
+
address,
|
|
5613
|
+
interface: networkInterface,
|
|
5614
|
+
gateway,
|
|
5615
|
+
tunnelInterface: /^(?:utun|tun|tap|wg|tailscale)/u.test(networkInterface)
|
|
5616
|
+
});
|
|
5617
|
+
} catch (error) {
|
|
5618
|
+
cancellation.throwIfAborted();
|
|
5619
|
+
evidence.failures.push(failureCode(error));
|
|
5620
|
+
}
|
|
5621
|
+
})
|
|
5622
|
+
);
|
|
5623
|
+
} catch (error) {
|
|
5624
|
+
cancellation.throwIfAborted();
|
|
5625
|
+
evidence.failures.push(failureCode(error));
|
|
5626
|
+
}
|
|
5627
|
+
return evidence;
|
|
5628
|
+
}
|
|
5629
|
+
|
|
5630
|
+
// src/cli/handler/diagnose/worker.ts
|
|
5631
|
+
import { join as join12 } from "node:path";
|
|
5632
|
+
async function runRelayProbeWorker(configPath, role, directory, signal) {
|
|
5633
|
+
if (!process.send) {
|
|
5634
|
+
throw new Error("The relay probe worker requires its coordinator");
|
|
5635
|
+
}
|
|
5636
|
+
const notify = (message) => {
|
|
5637
|
+
if (process.connected) {
|
|
5638
|
+
process.send?.({ ...message, role }, (error) => {
|
|
5639
|
+
if (error !== null) {
|
|
5640
|
+
controller.abort();
|
|
5641
|
+
}
|
|
5642
|
+
});
|
|
5643
|
+
}
|
|
5644
|
+
};
|
|
5645
|
+
const controller = new AbortController();
|
|
5646
|
+
const stopped = AbortSignal.any([signal, controller.signal]);
|
|
5647
|
+
const start = Promise.withResolvers();
|
|
5648
|
+
const onMessage = (value) => {
|
|
5649
|
+
const message = external_exports.object({ action: external_exports.enum(["start", "stop"]) }).safeParse(value);
|
|
5650
|
+
if (!message.success) {
|
|
5651
|
+
return;
|
|
5652
|
+
}
|
|
5653
|
+
if (message.data.action === "start") {
|
|
5654
|
+
start.resolve();
|
|
5655
|
+
} else {
|
|
5656
|
+
controller.abort();
|
|
5657
|
+
}
|
|
5658
|
+
};
|
|
5659
|
+
const abort = () => {
|
|
5660
|
+
controller.abort();
|
|
5661
|
+
start.resolve();
|
|
5662
|
+
};
|
|
5663
|
+
process.on("message", onMessage);
|
|
5664
|
+
process.once("disconnect", abort);
|
|
5665
|
+
stopped.addEventListener("abort", abort, { once: true });
|
|
5666
|
+
let routesBefore = [];
|
|
5667
|
+
try {
|
|
5668
|
+
const config = await readProbeConfiguration(configPath, stopped);
|
|
5669
|
+
const origin = new URL(config.relayOrigin);
|
|
5670
|
+
const proxy = role === "proxy" ? configuredProbeProxy() : null;
|
|
5671
|
+
routesBefore = await Promise.all([
|
|
5672
|
+
collectRouteEvidence(origin.hostname, stopped),
|
|
5673
|
+
...proxy === null ? [] : [collectRouteEvidence(proxy.hostname, stopped)]
|
|
5674
|
+
]);
|
|
5675
|
+
const workspace = join12(directory, "workspace");
|
|
5676
|
+
await ensureProbeDirectory(workspace);
|
|
5677
|
+
const engine = new MobiusRuntimeEngine({
|
|
5678
|
+
engineDataDir: join12(directory, "state"),
|
|
5679
|
+
agentLaunchEnvironment: { HOME: join12(directory, "home"), PATH: "" }
|
|
5680
|
+
});
|
|
5681
|
+
const pairing2 = config[role];
|
|
5682
|
+
const connection = await engine.pair(
|
|
5683
|
+
{
|
|
5684
|
+
relayOrigin: origin.href,
|
|
5685
|
+
pairingId: pairing2.pairingId,
|
|
5686
|
+
pairingCode: pairing2.pairingCode,
|
|
5687
|
+
defaultWorkspace: workspace
|
|
5688
|
+
},
|
|
5689
|
+
stopped
|
|
5690
|
+
);
|
|
5691
|
+
notify({ kind: "prepared", channelId: connection.channelId, runtimeId: connection.runtimeId, routesBefore });
|
|
5692
|
+
await start.promise;
|
|
5693
|
+
if (!stopped.aborted) {
|
|
5694
|
+
await engine.runLoop({
|
|
5695
|
+
connection: { kind: "saved", connectionId: connection.connectionId },
|
|
5696
|
+
signal: stopped,
|
|
5697
|
+
onConnectionStatus: (status) => notify({ kind: "status", status, timestamp: (/* @__PURE__ */ new Date()).toISOString() })
|
|
5698
|
+
});
|
|
5699
|
+
}
|
|
5700
|
+
const routesAfter = await Promise.all([
|
|
5701
|
+
collectRouteEvidence(origin.hostname, AbortSignal.timeout(6e3)),
|
|
5702
|
+
...proxy === null ? [] : [collectRouteEvidence(proxy.hostname, AbortSignal.timeout(6e3))]
|
|
5703
|
+
]);
|
|
5704
|
+
notify({ kind: "finished", routesAfter });
|
|
5705
|
+
} catch (error) {
|
|
5706
|
+
if (!stopped.aborted) {
|
|
5707
|
+
notify({ kind: "failed", code: failureCode(error), details: describeRelayFailure(error), routesBefore });
|
|
5708
|
+
process.exitCode = 1;
|
|
5709
|
+
}
|
|
5710
|
+
} finally {
|
|
5711
|
+
stopped.removeEventListener("abort", abort);
|
|
5712
|
+
process.off("message", onMessage);
|
|
5713
|
+
process.off("disconnect", abort);
|
|
5714
|
+
if (process.connected) {
|
|
5715
|
+
process.disconnect();
|
|
5716
|
+
}
|
|
5717
|
+
}
|
|
5718
|
+
}
|
|
5719
|
+
|
|
5720
|
+
// src/cli/handler/diagnose/index.ts
|
|
5721
|
+
var workerMessage = external_exports.discriminatedUnion("kind", [
|
|
5722
|
+
external_exports.object({
|
|
5723
|
+
kind: external_exports.literal("prepared"),
|
|
5724
|
+
role: external_exports.enum(["direct", "proxy"]),
|
|
5725
|
+
channelId: external_exports.string(),
|
|
5726
|
+
runtimeId: external_exports.string(),
|
|
5727
|
+
routesBefore: external_exports.array(routeEvidenceSchema)
|
|
5728
|
+
}),
|
|
5729
|
+
external_exports.object({
|
|
5730
|
+
kind: external_exports.literal("status"),
|
|
5731
|
+
role: external_exports.enum(["direct", "proxy"]),
|
|
5732
|
+
status: external_exports.string(),
|
|
5733
|
+
timestamp: external_exports.string()
|
|
5734
|
+
}),
|
|
5735
|
+
external_exports.object({
|
|
5736
|
+
kind: external_exports.literal("finished"),
|
|
5737
|
+
role: external_exports.enum(["direct", "proxy"]),
|
|
5738
|
+
routesAfter: external_exports.array(routeEvidenceSchema)
|
|
5739
|
+
}),
|
|
5740
|
+
external_exports.object({
|
|
5741
|
+
kind: external_exports.literal("failed"),
|
|
5742
|
+
role: external_exports.enum(["direct", "proxy"]),
|
|
5743
|
+
code: external_exports.string(),
|
|
5744
|
+
details: external_exports.record(external_exports.string(), external_exports.string()),
|
|
5745
|
+
routesBefore: external_exports.array(routeEvidenceSchema)
|
|
5746
|
+
})
|
|
5747
|
+
]);
|
|
5748
|
+
var ProbeLeg = class {
|
|
5749
|
+
role;
|
|
5750
|
+
#child;
|
|
5751
|
+
#directory;
|
|
5752
|
+
#prepared = Promise.withResolvers();
|
|
5753
|
+
closed;
|
|
5754
|
+
#channelId = "";
|
|
5755
|
+
#runtimeId = "";
|
|
5756
|
+
#routesBefore = [];
|
|
5757
|
+
#routesAfter = [];
|
|
5758
|
+
#onlineCount = 0;
|
|
5759
|
+
#lastStatus = "starting";
|
|
5760
|
+
#events = [];
|
|
5761
|
+
#preparationFailures = [];
|
|
5762
|
+
#omittedEvents = 0;
|
|
5763
|
+
constructor(role, config, directory, proxy) {
|
|
5764
|
+
this.role = role;
|
|
5765
|
+
this.#directory = directory;
|
|
5766
|
+
const entrypoint = process.argv[1];
|
|
5767
|
+
if (entrypoint === void 0) {
|
|
5768
|
+
throw new RelayProbeError("probe_entrypoint_missing", "Cannot locate the Mobius CLI entrypoint");
|
|
5769
|
+
}
|
|
5770
|
+
const environment = {
|
|
5771
|
+
HOME: join13(directory, "home"),
|
|
5772
|
+
PATH: process.env["PATH"] ?? "",
|
|
5773
|
+
MOBIUS_STATE_DIRECTORY: join13(directory, "state")
|
|
5774
|
+
};
|
|
5775
|
+
for (const name of [
|
|
5776
|
+
"SystemRoot",
|
|
5777
|
+
"WINDIR",
|
|
5778
|
+
"TMPDIR",
|
|
5779
|
+
"TMP",
|
|
5780
|
+
"TEMP",
|
|
5781
|
+
"NODE_EXTRA_CA_CERTS",
|
|
5782
|
+
"SSL_CERT_FILE",
|
|
5783
|
+
"SSL_CERT_DIR"
|
|
5784
|
+
]) {
|
|
5785
|
+
if (process.env[name] !== void 0) {
|
|
5786
|
+
environment[name] = process.env[name];
|
|
5787
|
+
}
|
|
5788
|
+
}
|
|
5789
|
+
environment["NO_PROXY"] = environment["no_proxy"] = role === "direct" ? "*" : "";
|
|
5790
|
+
if (role === "proxy") {
|
|
5791
|
+
environment["HTTPS_PROXY"] = environment["HTTP_PROXY"] = proxy.href;
|
|
5792
|
+
}
|
|
5793
|
+
this.#child = fork(
|
|
5794
|
+
resolve3(entrypoint),
|
|
5795
|
+
["_relay-probe-worker", "--config", config, "--role", role, "--directory", directory],
|
|
5796
|
+
{ env: environment, silent: true, windowsHide: true }
|
|
5797
|
+
);
|
|
5798
|
+
this.#child.stdout?.resume();
|
|
5799
|
+
let pending = "";
|
|
5800
|
+
this.#child.stderr?.on("data", (data) => {
|
|
5801
|
+
pending += data.toString();
|
|
5802
|
+
const lines = pending.split("\n");
|
|
5803
|
+
pending = lines.pop() ?? "";
|
|
5804
|
+
for (const line of lines) {
|
|
5805
|
+
if (line.startsWith("Mobius relay diagnostic ")) {
|
|
5806
|
+
process.stderr.write(`${role}: ${line}
|
|
5807
|
+
`);
|
|
5808
|
+
try {
|
|
5809
|
+
const event = external_exports.record(external_exports.string(), external_exports.string()).safeParse(JSON.parse(line.slice("Mobius relay diagnostic ".length)));
|
|
5810
|
+
if (event.success && event.data["channelId"] === this.#channelId) {
|
|
5811
|
+
this.#events.push(event.data);
|
|
5812
|
+
if (this.#events.length > 2e3) {
|
|
5813
|
+
this.#events.shift();
|
|
5814
|
+
this.#omittedEvents += 1;
|
|
5815
|
+
}
|
|
5816
|
+
}
|
|
5817
|
+
} catch {
|
|
5818
|
+
}
|
|
5819
|
+
}
|
|
5820
|
+
}
|
|
5821
|
+
if (pending.length > 32768) {
|
|
5822
|
+
pending = "";
|
|
5823
|
+
}
|
|
5824
|
+
});
|
|
5825
|
+
this.#child.on("message", (value) => {
|
|
5826
|
+
const message = workerMessage.safeParse(value);
|
|
5827
|
+
if (!message.success || message.data.role !== role) {
|
|
5828
|
+
return;
|
|
5829
|
+
}
|
|
5830
|
+
const event = message.data;
|
|
5831
|
+
switch (event.kind) {
|
|
5832
|
+
case "prepared":
|
|
5833
|
+
this.#channelId = event.channelId;
|
|
5834
|
+
this.#runtimeId = event.runtimeId;
|
|
5835
|
+
this.#routesBefore = event.routesBefore;
|
|
5836
|
+
this.#prepared.resolve(event);
|
|
5837
|
+
break;
|
|
5838
|
+
case "status":
|
|
5839
|
+
if (event.status === "online" && this.#lastStatus !== "online") {
|
|
5840
|
+
this.#onlineCount += 1;
|
|
5841
|
+
}
|
|
5842
|
+
this.#lastStatus = event.status;
|
|
5843
|
+
break;
|
|
5844
|
+
case "finished":
|
|
5845
|
+
this.#routesAfter = event.routesAfter;
|
|
5846
|
+
break;
|
|
5847
|
+
case "failed":
|
|
5848
|
+
this.#routesBefore = event.routesBefore;
|
|
5849
|
+
this.#preparationFailures.push(event.details);
|
|
5850
|
+
this.#prepared.reject(new RelayProbeError(event.code, `The ${role} probe failed`));
|
|
5851
|
+
break;
|
|
5852
|
+
}
|
|
5853
|
+
});
|
|
5854
|
+
this.closed = new Promise((done) => {
|
|
5855
|
+
this.#child.once("error", (error) => {
|
|
5856
|
+
this.#prepared.reject(error);
|
|
5857
|
+
done(1);
|
|
5858
|
+
});
|
|
5859
|
+
this.#child.once("close", (code) => {
|
|
5860
|
+
this.#prepared.reject(
|
|
5861
|
+
new RelayProbeError("probe_worker_exited", `The ${role} probe exited before preparation`)
|
|
5862
|
+
);
|
|
5863
|
+
done(code);
|
|
5864
|
+
});
|
|
5865
|
+
});
|
|
5866
|
+
void this.#prepared.promise.catch(() => void 0);
|
|
5867
|
+
}
|
|
5868
|
+
prepare = async () => await this.#prepared.promise;
|
|
5869
|
+
start = () => {
|
|
5870
|
+
if (this.#child.connected) {
|
|
5871
|
+
this.#child.send({ action: "start" }, () => void 0);
|
|
5872
|
+
}
|
|
5873
|
+
};
|
|
5874
|
+
stop = () => {
|
|
5875
|
+
if (this.#child.connected) {
|
|
5876
|
+
this.#child.send({ action: "stop" }, () => void 0);
|
|
5877
|
+
}
|
|
5878
|
+
};
|
|
5879
|
+
kill = () => {
|
|
5880
|
+
this.#child.kill("SIGKILL");
|
|
5881
|
+
};
|
|
5882
|
+
report = async () => {
|
|
5883
|
+
const events = this.#events;
|
|
5884
|
+
await writeProbeEvents(this.#directory, events);
|
|
5885
|
+
return {
|
|
5886
|
+
role: this.role,
|
|
5887
|
+
channelId: this.#channelId,
|
|
5888
|
+
runtimeId: this.#runtimeId,
|
|
5889
|
+
onlineCount: this.#onlineCount,
|
|
5890
|
+
routesBefore: this.#routesBefore,
|
|
5891
|
+
routesAfter: this.#routesAfter,
|
|
5892
|
+
transportFailures: events.filter((event) => event["event"] === "relay_transport_failed"),
|
|
5893
|
+
preparationFailures: this.#preparationFailures,
|
|
5894
|
+
disconnects: events.filter((event) => event["event"] === "relay_connection_closed"),
|
|
5895
|
+
exitCode: await this.closed,
|
|
5896
|
+
omittedEvents: this.#omittedEvents
|
|
5897
|
+
};
|
|
5898
|
+
};
|
|
5899
|
+
};
|
|
5900
|
+
async function compare(configPath, output, duration, context) {
|
|
5901
|
+
const config = await readProbeConfiguration(configPath, context.shutdownSignal);
|
|
5902
|
+
const proxy = configuredProbeProxy();
|
|
5903
|
+
const directory = resolve3(output);
|
|
5904
|
+
await createProbeOutput(directory);
|
|
5905
|
+
const legs = [];
|
|
5906
|
+
let startedAt = null;
|
|
5907
|
+
let endedAt = null;
|
|
5908
|
+
let completed = false;
|
|
5909
|
+
let failure = null;
|
|
5910
|
+
const deadline = AbortSignal.timeout(6e4);
|
|
5911
|
+
let durationTimer;
|
|
5912
|
+
let abortPreparation = () => void 0;
|
|
5913
|
+
try {
|
|
5914
|
+
for (const role of ["direct", "proxy"]) {
|
|
5915
|
+
context.shutdownSignal.throwIfAborted();
|
|
5916
|
+
const legDirectory = join13(directory, role);
|
|
5917
|
+
await ensureProbeDirectory(join13(legDirectory, "home"));
|
|
5918
|
+
legs.push(new ProbeLeg(role, resolve3(configPath), legDirectory, proxy));
|
|
5919
|
+
}
|
|
5920
|
+
const cancelled = Promise.withResolvers();
|
|
5921
|
+
context.shutdownSignal.throwIfAborted();
|
|
5922
|
+
abortPreparation = () => cancelled.reject(new RelayProbeError("probe_cancelled", "Relay comparison preparation was cancelled"));
|
|
5923
|
+
context.shutdownSignal.addEventListener("abort", abortPreparation, { once: true });
|
|
5924
|
+
deadline.addEventListener("abort", abortPreparation, { once: true });
|
|
5925
|
+
const prepared = await Promise.race([Promise.all(legs.map((leg) => leg.prepare())), cancelled.promise]);
|
|
5926
|
+
context.shutdownSignal.throwIfAborted();
|
|
5927
|
+
if (prepared[0]?.channelId === prepared[1]?.channelId || prepared[0]?.runtimeId === prepared[1]?.runtimeId) {
|
|
5928
|
+
throw new RelayProbeError(
|
|
5929
|
+
"probe_runtime_reused",
|
|
5930
|
+
"The Relay returned the same Runtime for distinct pairings"
|
|
5931
|
+
);
|
|
5932
|
+
}
|
|
5933
|
+
context.shutdownSignal.removeEventListener("abort", abortPreparation);
|
|
5934
|
+
deadline.removeEventListener("abort", abortPreparation);
|
|
5935
|
+
startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
5936
|
+
const finish = Promise.withResolvers();
|
|
5937
|
+
const stop = () => finish.resolve();
|
|
5938
|
+
context.shutdownSignal.addEventListener("abort", stop, { once: true });
|
|
5939
|
+
durationTimer = setTimeout(() => {
|
|
5940
|
+
completed = true;
|
|
5941
|
+
finish.resolve();
|
|
5942
|
+
}, duration * 1e3);
|
|
5943
|
+
for (const leg of legs) {
|
|
5944
|
+
leg.start();
|
|
5945
|
+
}
|
|
5946
|
+
try {
|
|
5947
|
+
await Promise.race([
|
|
5948
|
+
finish.promise,
|
|
5949
|
+
...legs.map(
|
|
5950
|
+
(leg) => leg.closed.then(() => {
|
|
5951
|
+
throw new RelayProbeError(
|
|
5952
|
+
"probe_worker_exited",
|
|
5953
|
+
`The ${leg.role} probe exited during comparison`
|
|
5954
|
+
);
|
|
5955
|
+
})
|
|
5956
|
+
)
|
|
5957
|
+
]);
|
|
5958
|
+
} finally {
|
|
5959
|
+
context.shutdownSignal.removeEventListener("abort", stop);
|
|
5960
|
+
}
|
|
5961
|
+
} catch (error) {
|
|
5962
|
+
if (!context.shutdownSignal.aborted) {
|
|
5963
|
+
failure = failureCode(error);
|
|
5964
|
+
process.exitCode = 1;
|
|
5965
|
+
}
|
|
5966
|
+
} finally {
|
|
5967
|
+
endedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
5968
|
+
if (durationTimer !== void 0) {
|
|
5969
|
+
clearTimeout(durationTimer);
|
|
5970
|
+
}
|
|
5971
|
+
context.shutdownSignal.removeEventListener("abort", abortPreparation);
|
|
5972
|
+
deadline.removeEventListener("abort", abortPreparation);
|
|
5973
|
+
for (const leg of legs) {
|
|
5974
|
+
leg.stop();
|
|
5975
|
+
}
|
|
5976
|
+
const force = setTimeout(() => {
|
|
5977
|
+
for (const leg of legs) {
|
|
5978
|
+
leg.kill();
|
|
5979
|
+
}
|
|
5980
|
+
}, 1e4);
|
|
5981
|
+
try {
|
|
5982
|
+
await Promise.all(legs.map((leg) => leg.closed));
|
|
5983
|
+
const reports = await Promise.all(legs.map((leg) => leg.report()));
|
|
5984
|
+
if (reports.some((leg) => leg.exitCode !== 0 || leg.onlineCount === 0)) {
|
|
5985
|
+
process.exitCode = 1;
|
|
5986
|
+
failure ??= "probe_not_ready";
|
|
5987
|
+
}
|
|
5988
|
+
const report = {
|
|
5989
|
+
version: context.version,
|
|
5990
|
+
targetOrigin: new URL(config.relayOrigin).origin,
|
|
5991
|
+
proxyOrigin: proxy.origin,
|
|
5992
|
+
requestedDurationSeconds: duration,
|
|
5993
|
+
startedAt,
|
|
5994
|
+
endedAt,
|
|
5995
|
+
completed,
|
|
5996
|
+
failure,
|
|
5997
|
+
directMeans: "No explicit HTTP proxy; operating-system TUN/VPN routing still applies",
|
|
5998
|
+
legs: reports
|
|
5999
|
+
};
|
|
6000
|
+
await writeProbeReport(directory, report);
|
|
6001
|
+
process.stdout.write(`${join13(directory, "report.json")}
|
|
6002
|
+
`);
|
|
6003
|
+
} finally {
|
|
6004
|
+
clearTimeout(force);
|
|
6005
|
+
await Promise.all(legs.map((leg) => removeProbeState(join13(directory, leg.role))));
|
|
6006
|
+
}
|
|
6007
|
+
}
|
|
6008
|
+
}
|
|
6009
|
+
function registerDiagnoseCommand(program2, context) {
|
|
6010
|
+
program2.command("diagnose").description("collect isolated network diagnostics").command("relay").description("compare fresh direct and proxied Runtime channels over the same observation window").requiredOption(
|
|
6011
|
+
"--config <path>",
|
|
6012
|
+
"private JSON with relayOrigin and distinct direct/proxy pairingId and pairingCode"
|
|
6013
|
+
).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) => {
|
|
6014
|
+
const duration = Number(options.duration);
|
|
6015
|
+
if (!Number.isSafeInteger(duration) || duration < 1 || duration > 86400) {
|
|
6016
|
+
throw new RelayProbeError(
|
|
6017
|
+
"probe_duration_invalid",
|
|
6018
|
+
"--duration must be a whole number from 1 to 86400 seconds"
|
|
6019
|
+
);
|
|
6020
|
+
}
|
|
6021
|
+
await compare(options.config, options.output, duration, context);
|
|
6022
|
+
});
|
|
6023
|
+
program2.command("_relay-probe-worker", { hidden: true }).requiredOption("--config <path>").requiredOption("--role <role>").requiredOption("--directory <path>").action(async (options) => {
|
|
6024
|
+
const role = external_exports.enum(["direct", "proxy"]).parse(options.role);
|
|
6025
|
+
await runRelayProbeWorker(options.config, role, options.directory, context.shutdownSignal);
|
|
6026
|
+
});
|
|
6027
|
+
}
|
|
6028
|
+
|
|
5447
6029
|
// src/cli/handler/logs/logic/collect-local-logs.ts
|
|
5448
|
-
import { join as
|
|
6030
|
+
import { join as join15, relative as relative4, resolve as resolve4 } from "node:path";
|
|
5449
6031
|
|
|
5450
6032
|
// src/storage/logs/log-files.ts
|
|
5451
|
-
import { lstat as lstat2, readdir, readFile as
|
|
5452
|
-
import { join as
|
|
6033
|
+
import { lstat as lstat2, readdir, readFile as readFile7 } from "node:fs/promises";
|
|
6034
|
+
import { join as join14, relative as relative3 } from "node:path";
|
|
5453
6035
|
var LOG_FILE_NAME_PATTERN = /^[\w.-]{1,128}\.log$/u;
|
|
5454
6036
|
var INSTALLATIONS_DIRECTORY = "installations";
|
|
5455
6037
|
var VERSIONS_DIRECTORY = "versions";
|
|
@@ -5457,17 +6039,17 @@ function isAbsent(cause) {
|
|
|
5457
6039
|
return typeof cause === "object" && cause !== null && Reflect.get(cause, "code") === "ENOENT";
|
|
5458
6040
|
}
|
|
5459
6041
|
async function findLogDirectories(root, unreadable, signal) {
|
|
5460
|
-
const versions =
|
|
5461
|
-
const installationsRoots = [
|
|
6042
|
+
const versions = join14(root, VERSIONS_DIRECTORY);
|
|
6043
|
+
const installationsRoots = [join14(root, INSTALLATIONS_DIRECTORY)];
|
|
5462
6044
|
for (const version of await listDirectories(versions, root, unreadable, signal)) {
|
|
5463
|
-
installationsRoots.push(
|
|
6045
|
+
installationsRoots.push(join14(versions, version, INSTALLATIONS_DIRECTORY));
|
|
5464
6046
|
}
|
|
5465
6047
|
const found = [];
|
|
5466
6048
|
for (const installations of installationsRoots) {
|
|
5467
6049
|
for (const dataDirectory of await listDirectories(installations, root, unreadable, signal)) {
|
|
5468
|
-
const application =
|
|
6050
|
+
const application = join14(installations, dataDirectory);
|
|
5469
6051
|
for (const installationId of await listDirectories(application, root, unreadable, signal)) {
|
|
5470
|
-
const logs =
|
|
6052
|
+
const logs = join14(application, installationId, "logs");
|
|
5471
6053
|
const status = await directoryStatus(logs);
|
|
5472
6054
|
if (status === "listed") {
|
|
5473
6055
|
found.push(logs);
|
|
@@ -5525,7 +6107,7 @@ async function readOwnedLogFile(path2, signal) {
|
|
|
5525
6107
|
return { kind: "skipped" };
|
|
5526
6108
|
}
|
|
5527
6109
|
try {
|
|
5528
|
-
return { kind: "read", content: await
|
|
6110
|
+
return { kind: "read", content: await readFile7(path2, { encoding: "utf8", signal }) };
|
|
5529
6111
|
} catch (cause) {
|
|
5530
6112
|
if (signal.aborted) {
|
|
5531
6113
|
throw cause;
|
|
@@ -5540,14 +6122,14 @@ function ownedByCurrentUser(metadata) {
|
|
|
5540
6122
|
// src/cli/handler/logs/logic/collect-local-logs.ts
|
|
5541
6123
|
async function collectLocalDaemonLogs(stateDirectory, tailLines, signal) {
|
|
5542
6124
|
signal.throwIfAborted();
|
|
5543
|
-
const root =
|
|
6125
|
+
const root = resolve4(stateDirectory);
|
|
5544
6126
|
const entries = [];
|
|
5545
6127
|
const unreadable = [];
|
|
5546
6128
|
const directories = await findLogDirectories(root, unreadable, signal);
|
|
5547
6129
|
for (const directory of directories) {
|
|
5548
6130
|
const names = await listLogFiles(directory, root, unreadable);
|
|
5549
6131
|
for (const name of names) {
|
|
5550
|
-
const path2 =
|
|
6132
|
+
const path2 = join15(directory, name);
|
|
5551
6133
|
const reported = relative4(root, path2);
|
|
5552
6134
|
const read = await readOwnedLogFile(path2, signal);
|
|
5553
6135
|
if (read.kind === "unreadable") {
|
|
@@ -5569,7 +6151,7 @@ async function collectLocalDaemonLogs(stateDirectory, tailLines, signal) {
|
|
|
5569
6151
|
return { entries, unreadable: [...unreadable].sort() };
|
|
5570
6152
|
}
|
|
5571
6153
|
function defaultStateDirectory(environment = process.env) {
|
|
5572
|
-
return
|
|
6154
|
+
return resolve4(readStateDirectory(environment));
|
|
5573
6155
|
}
|
|
5574
6156
|
|
|
5575
6157
|
// src/cli/handler/logs/index.ts
|
|
@@ -5634,7 +6216,7 @@ ${sections.join("\n")}`;
|
|
|
5634
6216
|
}
|
|
5635
6217
|
|
|
5636
6218
|
// src/cli/handler/pair/list.ts
|
|
5637
|
-
import { resolve as
|
|
6219
|
+
import { resolve as resolve5 } from "node:path";
|
|
5638
6220
|
|
|
5639
6221
|
// src/cli/handler/pair/logic/pair-list-output.ts
|
|
5640
6222
|
function savedPairSummary(connection) {
|
|
@@ -5685,7 +6267,7 @@ async function writePairList(path2, pairs, signal) {
|
|
|
5685
6267
|
function registerPairListCommand(command, context) {
|
|
5686
6268
|
command.command("list").description("list saved pairings").addOption(valueOption("--output-json <existing-file.json>", "write JSON to an existing file")).action(async (options) => {
|
|
5687
6269
|
const installation = await openMobiusCliInstallation(context.shutdownSignal, process.env);
|
|
5688
|
-
const outputPath = options.outputJson === void 0 ? null :
|
|
6270
|
+
const outputPath = options.outputJson === void 0 ? null : resolve5(options.outputJson);
|
|
5689
6271
|
const pairs = (await installation.listConnections(context.shutdownSignal)).map(savedPairSummary).sort(
|
|
5690
6272
|
(left, right) => left.appId.localeCompare(right.appId) || left.connectionId.localeCompare(right.connectionId)
|
|
5691
6273
|
);
|
|
@@ -5818,6 +6400,7 @@ function createProgram(cliContext) {
|
|
|
5818
6400
|
registerVersionHandler(program2, cliContext);
|
|
5819
6401
|
registerAgentsHandler(program2, cliContext);
|
|
5820
6402
|
registerLogsCommand(program2, cliContext);
|
|
6403
|
+
registerDiagnoseCommand(program2, cliContext);
|
|
5821
6404
|
registerInternalRuntimeHandlers(program2, cliContext);
|
|
5822
6405
|
registerPairHandlers(program2, cliContext);
|
|
5823
6406
|
registerDaemonProcessLifecycleHandlers(program2, cliContext);
|
|
@@ -5856,4 +6439,4 @@ async function runCLI() {
|
|
|
5856
6439
|
export {
|
|
5857
6440
|
runCLI
|
|
5858
6441
|
};
|
|
5859
|
-
//# sourceMappingURL=cli-
|
|
6442
|
+
//# sourceMappingURL=cli-EY6WXGHE.js.map
|