local-commander-agent 0.3.49 → 0.3.51
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/CHANGELOG.md +12 -1
- package/README.md +216 -216
- package/bin/localcommander.mjs +3 -1
- package/bin/monitor-context.d.mts +7 -7
- package/bin/monitor-savings.d.mts +20 -20
- package/package.json +4 -4
- package/runtime/JobHost.exe +0 -0
- package/runtime/LocalCommanderAgent.exe +0 -0
- package/runtime/OwnerBridge.exe +0 -0
- package/runtime/agent.mjs +380 -249
package/runtime/agent.mjs
CHANGED
|
@@ -4541,10 +4541,10 @@ function mergeDefs(...defs) {
|
|
|
4541
4541
|
function cloneDef(schema) {
|
|
4542
4542
|
return mergeDefs(schema._zod.def);
|
|
4543
4543
|
}
|
|
4544
|
-
function getElementAtPath(obj,
|
|
4545
|
-
if (!
|
|
4544
|
+
function getElementAtPath(obj, path31) {
|
|
4545
|
+
if (!path31)
|
|
4546
4546
|
return obj;
|
|
4547
|
-
return
|
|
4547
|
+
return path31.reduce((acc, key) => acc?.[key], obj);
|
|
4548
4548
|
}
|
|
4549
4549
|
function promiseAllObject(promisesObj) {
|
|
4550
4550
|
const keys = Object.keys(promisesObj);
|
|
@@ -4884,11 +4884,11 @@ function explicitlyAborted(x, startIndex = 0) {
|
|
|
4884
4884
|
}
|
|
4885
4885
|
return false;
|
|
4886
4886
|
}
|
|
4887
|
-
function prefixIssues(
|
|
4887
|
+
function prefixIssues(path31, issues) {
|
|
4888
4888
|
return issues.map((iss) => {
|
|
4889
4889
|
var _a3;
|
|
4890
4890
|
(_a3 = iss).path ?? (_a3.path = []);
|
|
4891
|
-
iss.path.unshift(
|
|
4891
|
+
iss.path.unshift(path31);
|
|
4892
4892
|
return iss;
|
|
4893
4893
|
});
|
|
4894
4894
|
}
|
|
@@ -5158,8 +5158,8 @@ var _E = "captureStackTrace" in Error ? Error : null;
|
|
|
5158
5158
|
function newError(Definition) {
|
|
5159
5159
|
const E = _E;
|
|
5160
5160
|
if (E) {
|
|
5161
|
-
const
|
|
5162
|
-
if (typeof
|
|
5161
|
+
const saved2 = E.stackTraceLimit;
|
|
5162
|
+
if (typeof saved2 === "number") {
|
|
5163
5163
|
try {
|
|
5164
5164
|
E.stackTraceLimit = 0;
|
|
5165
5165
|
} catch {
|
|
@@ -5169,7 +5169,7 @@ function newError(Definition) {
|
|
|
5169
5169
|
try {
|
|
5170
5170
|
return new Definition();
|
|
5171
5171
|
} finally {
|
|
5172
|
-
E.stackTraceLimit =
|
|
5172
|
+
E.stackTraceLimit = saved2;
|
|
5173
5173
|
}
|
|
5174
5174
|
}
|
|
5175
5175
|
}
|
|
@@ -5338,16 +5338,16 @@ function flattenError(error62, mapper = (issue2) => issue2.message) {
|
|
|
5338
5338
|
}
|
|
5339
5339
|
function formatError(error62, mapper = (issue2) => issue2.message) {
|
|
5340
5340
|
const fieldErrors = { _errors: [] };
|
|
5341
|
-
const processError = (error63,
|
|
5341
|
+
const processError = (error63, path31 = []) => {
|
|
5342
5342
|
for (const issue2 of error63.issues) {
|
|
5343
5343
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
5344
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
5344
|
+
issue2.errors.map((issues) => processError({ issues }, [...path31, ...issue2.path]));
|
|
5345
5345
|
} else if (issue2.code === "invalid_key") {
|
|
5346
|
-
processError({ issues: issue2.issues }, [...
|
|
5346
|
+
processError({ issues: issue2.issues }, [...path31, ...issue2.path]);
|
|
5347
5347
|
} else if (issue2.code === "invalid_element") {
|
|
5348
|
-
processError({ issues: issue2.issues }, [...
|
|
5348
|
+
processError({ issues: issue2.issues }, [...path31, ...issue2.path]);
|
|
5349
5349
|
} else {
|
|
5350
|
-
const fullpath = [...
|
|
5350
|
+
const fullpath = [...path31, ...issue2.path];
|
|
5351
5351
|
if (fullpath.length === 0) {
|
|
5352
5352
|
fieldErrors._errors.push(mapper(issue2));
|
|
5353
5353
|
} else {
|
|
@@ -5386,17 +5386,17 @@ function formatError(error62, mapper = (issue2) => issue2.message) {
|
|
|
5386
5386
|
}
|
|
5387
5387
|
function treeifyError(error62, mapper = (issue2) => issue2.message) {
|
|
5388
5388
|
const result2 = { errors: [] };
|
|
5389
|
-
const processError = (error63,
|
|
5389
|
+
const processError = (error63, path31 = []) => {
|
|
5390
5390
|
var _a3;
|
|
5391
5391
|
for (const issue2 of error63.issues) {
|
|
5392
5392
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
5393
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
5393
|
+
issue2.errors.map((issues) => processError({ issues }, [...path31, ...issue2.path]));
|
|
5394
5394
|
} else if (issue2.code === "invalid_key") {
|
|
5395
|
-
processError({ issues: issue2.issues }, [...
|
|
5395
|
+
processError({ issues: issue2.issues }, [...path31, ...issue2.path]);
|
|
5396
5396
|
} else if (issue2.code === "invalid_element") {
|
|
5397
|
-
processError({ issues: issue2.issues }, [...
|
|
5397
|
+
processError({ issues: issue2.issues }, [...path31, ...issue2.path]);
|
|
5398
5398
|
} else {
|
|
5399
|
-
const fullpath = [...
|
|
5399
|
+
const fullpath = [...path31, ...issue2.path];
|
|
5400
5400
|
if (fullpath.length === 0) {
|
|
5401
5401
|
result2.errors.push(mapper(issue2));
|
|
5402
5402
|
continue;
|
|
@@ -5435,8 +5435,8 @@ function treeifyError(error62, mapper = (issue2) => issue2.message) {
|
|
|
5435
5435
|
}
|
|
5436
5436
|
function toDotPath(_path) {
|
|
5437
5437
|
const segs = [];
|
|
5438
|
-
const
|
|
5439
|
-
for (const seg of
|
|
5438
|
+
const path31 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
5439
|
+
for (const seg of path31) {
|
|
5440
5440
|
if (typeof seg === "number")
|
|
5441
5441
|
segs.push(`[${seg}]`);
|
|
5442
5442
|
else if (typeof seg === "symbol")
|
|
@@ -22538,13 +22538,13 @@ function resolveRef(ref, ctx) {
|
|
|
22538
22538
|
if (!ref.startsWith("#")) {
|
|
22539
22539
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
22540
22540
|
}
|
|
22541
|
-
const
|
|
22542
|
-
if (
|
|
22541
|
+
const path31 = ref.slice(1).split("/").filter(Boolean);
|
|
22542
|
+
if (path31.length === 0) {
|
|
22543
22543
|
return ctx.rootSchema;
|
|
22544
22544
|
}
|
|
22545
22545
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
22546
|
-
if (
|
|
22547
|
-
const key =
|
|
22546
|
+
if (path31[0] === defsKey) {
|
|
22547
|
+
const key = path31[1] === void 0 ? void 0 : decodeJSONPointerSegment(path31[1]);
|
|
22548
22548
|
if (!key || !ctx.defs[key]) {
|
|
22549
22549
|
throw new Error(`Reference not found: ${ref}`);
|
|
22550
22550
|
}
|
|
@@ -24917,14 +24917,14 @@ async function loadProxyModeFlag(dir) {
|
|
|
24917
24917
|
}
|
|
24918
24918
|
}
|
|
24919
24919
|
async function writeProxyState(dir, state) {
|
|
24920
|
-
const
|
|
24920
|
+
const file3 = path.join(dir, "proxy.json");
|
|
24921
24921
|
try {
|
|
24922
24922
|
if (!state) {
|
|
24923
|
-
await rm(
|
|
24923
|
+
await rm(file3, { force: true });
|
|
24924
24924
|
return;
|
|
24925
24925
|
}
|
|
24926
24926
|
await mkdir(dir, { recursive: true });
|
|
24927
|
-
await writeFile(
|
|
24927
|
+
await writeFile(file3, JSON.stringify({ ...state, updatedAt: Date.now() }), { mode: 384 });
|
|
24928
24928
|
} catch {
|
|
24929
24929
|
}
|
|
24930
24930
|
}
|
|
@@ -25049,9 +25049,9 @@ async function networkDirectory(stateDirectory) {
|
|
|
25049
25049
|
}
|
|
25050
25050
|
async function networkPrepared(stateDirectory, identity) {
|
|
25051
25051
|
try {
|
|
25052
|
-
const
|
|
25052
|
+
const file3 = networkPath(stateDirectory, "network-prepared.json"), stat2 = await fs.lstat(file3);
|
|
25053
25053
|
if (!stat2.isFile() || stat2.isSymbolicLink() || stat2.size > 1024) return false;
|
|
25054
|
-
const receipt = Receipt.parse(JSON.parse(await fs.readFile(
|
|
25054
|
+
const receipt = Receipt.parse(JSON.parse(await fs.readFile(file3, "utf8"))), e = identity.enrollment;
|
|
25055
25055
|
return !!e && receipt.deviceId === e.deviceId && receipt.tenantId === e.tenantId && receipt.accountId === e.accountId;
|
|
25056
25056
|
} catch {
|
|
25057
25057
|
return false;
|
|
@@ -25131,10 +25131,10 @@ async function setupNetwork(binaryDirectory, stateDirectory, identity) {
|
|
|
25131
25131
|
await elevated(bundle.helper, "setup", requestPath, directory);
|
|
25132
25132
|
await localNetworkControl(e.deviceId);
|
|
25133
25133
|
const receipt = Receipt.parse({ version: 1, deviceId: e.deviceId, tenantId: e.tenantId, accountId: e.accountId, bundleId: bundle.bundleId });
|
|
25134
|
-
const
|
|
25134
|
+
const file3 = path2.join(directory, "network-prepared.json"), temp = file3 + "." + randomUUID2();
|
|
25135
25135
|
await fs.writeFile(temp, JSON.stringify(receipt), { flag: "wx", mode: 384 });
|
|
25136
25136
|
try {
|
|
25137
|
-
await fs.rename(temp,
|
|
25137
|
+
await fs.rename(temp, file3);
|
|
25138
25138
|
} finally {
|
|
25139
25139
|
await fs.rm(temp, { force: true });
|
|
25140
25140
|
}
|
|
@@ -25164,7 +25164,7 @@ async function openNetworkPanel(binaryDirectory, identity) {
|
|
|
25164
25164
|
}
|
|
25165
25165
|
|
|
25166
25166
|
// agent/src/main.ts
|
|
25167
|
-
import
|
|
25167
|
+
import path30 from "node:path";
|
|
25168
25168
|
import os8 from "node:os";
|
|
25169
25169
|
|
|
25170
25170
|
// agent/src/posix-store.ts
|
|
@@ -25584,7 +25584,7 @@ async function acquirePosixJournalGuard(directory, helper) {
|
|
|
25584
25584
|
}
|
|
25585
25585
|
|
|
25586
25586
|
// agent/src/main.ts
|
|
25587
|
-
import { mkdir as
|
|
25587
|
+
import { mkdir as mkdir15, open as open13, readFile as readFile13, realpath as realpath10, rm as rm11 } from "node:fs/promises";
|
|
25588
25588
|
import { fileURLToPath } from "node:url";
|
|
25589
25589
|
|
|
25590
25590
|
// packages/operations/src/crypto.ts
|
|
@@ -25721,8 +25721,8 @@ var exec2 = promisify2(execFile2);
|
|
|
25721
25721
|
async function darwinSupervisorLiveness(helper, pids, records = []) {
|
|
25722
25722
|
if (process.platform !== "darwin" || !process.getuid?.() || process.getuid() !== process.geteuid?.()) return null;
|
|
25723
25723
|
const remaining = new Set(pids), uid = process.getuid(), deadline = Date.now() + 1e4, env = buildChildEnvironment(process.env);
|
|
25724
|
-
const run2 = (
|
|
25725
|
-
|
|
25724
|
+
const run2 = (file3, args) => exec2(
|
|
25725
|
+
file3,
|
|
25726
25726
|
args,
|
|
25727
25727
|
{ env, timeout: Math.max(1, Math.min(7e3, deadline - Date.now())), maxBuffer: 8192, encoding: "utf8", windowsHide: true }
|
|
25728
25728
|
);
|
|
@@ -26490,6 +26490,7 @@ var NATIVE_STATUS_CAPABILITY = "nativeStatusV1";
|
|
|
26490
26490
|
var NativeStatusSchema = NativeCapacitySchema.extend({ type: external_exports.literal("nativeStatus"), active: external_exports.number().int().min(0).max(32), queued: external_exports.number().int().min(0).max(256), paused: external_exports.boolean() }).strict().refine((v) => v.active <= v.safeSlots);
|
|
26491
26491
|
var TerminalEventSchema = external_exports.object({ type: external_exports.literal("executionResult"), protocolVersion: external_exports.literal(1), requestId: uuid11, tenantId: uuid11, deviceId: uuid11, connectionEpoch: epoch2, binding: ExecutionBindingSchema, state: external_exports.enum(["finished", "failed", "cancelled", "unknown", "rejected"]), resultCode: external_exports.string().regex(/^[A-Z0-9_]{1,40}$/), metrics: TerminalMetricsSchema.optional() }).strict();
|
|
26492
26492
|
var HeldLeasesFrameSchema = external_exports.object({ type: external_exports.literal("heldLeases"), protocolVersion: external_exports.literal(1), connectionEpoch: epoch2, bindings: external_exports.array(ExecutionBindingSchema).min(1).max(64) }).strict();
|
|
26493
|
+
var FullLogStateSchema = external_exports.object({ type: external_exports.literal("fullLogState"), protocolVersion: external_exports.literal(1), connectionEpoch: epoch2, enabled: external_exports.boolean().nullable() }).strict();
|
|
26493
26494
|
var TerminalEventAckSchema = external_exports.object({ type: external_exports.literal("executionResultAck"), protocolVersion: external_exports.literal(1), requestId: uuid11, ok: external_exports.boolean() }).strict();
|
|
26494
26495
|
function canonicalJson(value) {
|
|
26495
26496
|
function canonical2(v) {
|
|
@@ -26785,23 +26786,23 @@ var NativeJournal = class _NativeJournal {
|
|
|
26785
26786
|
}
|
|
26786
26787
|
const dir = await safeDirectory(directory), lockPath = path6.join(dir, "journal.lock"), nonce2 = randomBytes4(16).toString("hex");
|
|
26787
26788
|
const guard = options.lockHelper ? await acquirePosixJournalGuard(dir, options.lockHelper) : void 0;
|
|
26788
|
-
let
|
|
26789
|
+
let file3;
|
|
26789
26790
|
try {
|
|
26790
|
-
|
|
26791
|
+
file3 = await open3(lockPath, constants2.O_CREAT | constants2.O_EXCL | constants2.O_WRONLY, 384);
|
|
26791
26792
|
} catch (e) {
|
|
26792
26793
|
await guard?.close();
|
|
26793
26794
|
if (e.code === "EEXIST") throw failure2("JOURNAL_LOCKED");
|
|
26794
26795
|
throw e;
|
|
26795
26796
|
}
|
|
26796
|
-
const journal = new _NativeJournal(dir, box, { path: lockPath, nonce: nonce2, file:
|
|
26797
|
+
const journal = new _NativeJournal(dir, box, { path: lockPath, nonce: nonce2, file: file3, guard }, { maxEntries, maxBytes, retentionMs, now: options.now ?? (() => /* @__PURE__ */ new Date()) });
|
|
26797
26798
|
try {
|
|
26798
|
-
await
|
|
26799
|
-
await
|
|
26799
|
+
await file3.writeFile(JSON.stringify({ pid: process.pid, nonce: nonce2, createdAt: journal.now().toISOString() }));
|
|
26800
|
+
await file3.sync();
|
|
26800
26801
|
await journal.load();
|
|
26801
26802
|
await journal.loadStart(existed);
|
|
26802
26803
|
return journal;
|
|
26803
26804
|
} catch (e) {
|
|
26804
|
-
await
|
|
26805
|
+
await file3.close().catch(() => {
|
|
26805
26806
|
});
|
|
26806
26807
|
try {
|
|
26807
26808
|
const value = JSON.parse(await readFile3(lockPath, "utf8"));
|
|
@@ -28768,9 +28769,9 @@ function resolveWindowsLauncher(commandName, env = process.env) {
|
|
|
28768
28769
|
const dir = entry.trim().replace(/^"(.*)"$/, "$1");
|
|
28769
28770
|
if (!path11.win32.isAbsolute(dir)) continue;
|
|
28770
28771
|
for (const ext of extensions) {
|
|
28771
|
-
const
|
|
28772
|
+
const file3 = path11.win32.join(dir, commandName + ext);
|
|
28772
28773
|
try {
|
|
28773
|
-
if (statSync(
|
|
28774
|
+
if (statSync(file3).isFile()) return { file: file3, shell: ext === ".bat" || ext === ".cmd" };
|
|
28774
28775
|
} catch {
|
|
28775
28776
|
}
|
|
28776
28777
|
}
|
|
@@ -28791,8 +28792,8 @@ var Entry = external_exports.strictObject({
|
|
|
28791
28792
|
});
|
|
28792
28793
|
var State = external_exports.strictObject({ version: external_exports.literal(1), platform: external_exports.string().max(16), entries: external_exports.array(Entry).max(32) });
|
|
28793
28794
|
var HostMemory = class {
|
|
28794
|
-
constructor(
|
|
28795
|
-
this.file =
|
|
28795
|
+
constructor(file3, allowed, programs) {
|
|
28796
|
+
this.file = file3;
|
|
28796
28797
|
this.allowed = allowed;
|
|
28797
28798
|
this.programs = programs;
|
|
28798
28799
|
}
|
|
@@ -28832,9 +28833,9 @@ var HostMemory = class {
|
|
|
28832
28833
|
else if (!this.programs && !available) available = (process.env.PATH ?? "").split(path12.delimiter).some((dir) => {
|
|
28833
28834
|
if (!path12.isAbsolute(dir)) return false;
|
|
28834
28835
|
try {
|
|
28835
|
-
const
|
|
28836
|
-
accessSync(
|
|
28837
|
-
return statSync2(
|
|
28836
|
+
const file3 = path12.join(dir, command);
|
|
28837
|
+
accessSync(file3, constants5.X_OK);
|
|
28838
|
+
return statSync2(file3).isFile();
|
|
28838
28839
|
} catch {
|
|
28839
28840
|
return false;
|
|
28840
28841
|
}
|
|
@@ -28894,13 +28895,13 @@ var HostMemory = class {
|
|
|
28894
28895
|
await mkdir5(directory2, { recursive: true, mode: 448 });
|
|
28895
28896
|
const stat2 = await lstat5(directory2);
|
|
28896
28897
|
if (!stat2.isDirectory() || stat2.isSymbolicLink()) throw Error("HOST_MEMORY_DIRECTORY_INVALID");
|
|
28897
|
-
const
|
|
28898
|
+
const file3 = await open5(temp, "wx", 384);
|
|
28898
28899
|
try {
|
|
28899
|
-
await
|
|
28900
|
-
await
|
|
28900
|
+
await file3.writeFile(encoded);
|
|
28901
|
+
await file3.close();
|
|
28901
28902
|
await rename3(temp, this.file);
|
|
28902
28903
|
} finally {
|
|
28903
|
-
await
|
|
28904
|
+
await file3.close().catch(() => {
|
|
28904
28905
|
});
|
|
28905
28906
|
await rm4(temp, { force: true }).catch(() => {
|
|
28906
28907
|
});
|
|
@@ -29127,11 +29128,11 @@ var PathGuard = class _PathGuard {
|
|
|
29127
29128
|
// src/windows-file-read.ts
|
|
29128
29129
|
import { execFile as execFile3 } from "node:child_process";
|
|
29129
29130
|
import path14 from "node:path";
|
|
29130
|
-
function readWindowsFile(bridge,
|
|
29131
|
-
return invokeRead(bridge,
|
|
29131
|
+
function readWindowsFile(bridge, file3, maxBytes, signal) {
|
|
29132
|
+
return invokeRead(bridge, file3, maxBytes, false, signal);
|
|
29132
29133
|
}
|
|
29133
|
-
async function readWindowsFilePrefix(bridge,
|
|
29134
|
-
const output2 = await invokeRead(bridge,
|
|
29134
|
+
async function readWindowsFilePrefix(bridge, file3, maxBytes, signal) {
|
|
29135
|
+
const output2 = await invokeRead(bridge, file3, maxBytes, true, signal);
|
|
29135
29136
|
try {
|
|
29136
29137
|
const value = JSON.parse(output2.toString("utf8"));
|
|
29137
29138
|
if (!value || Object.keys(value).length !== 4 || typeof value.data !== "string" || !Number.isSafeInteger(value.size) || value.size < 0 || typeof value.modifiedAt !== "string" || new Date(value.modifiedAt).toISOString() !== value.modifiedAt || value.truncated !== value.size > maxBytes) throw Error();
|
|
@@ -29144,7 +29145,7 @@ async function readWindowsFilePrefix(bridge, file2, maxBytes, signal) {
|
|
|
29144
29145
|
}
|
|
29145
29146
|
function readWindowsFiles(bridge, files, maxBytes, maxTotalBytes, signal) {
|
|
29146
29147
|
const input2 = JSON.stringify({ paths: files });
|
|
29147
|
-
if (process.platform !== "win32" || !path14.isAbsolute(bridge) || files.length < 1 || files.length > 64 || files.some((
|
|
29148
|
+
if (process.platform !== "win32" || !path14.isAbsolute(bridge) || files.length < 1 || files.length > 64 || files.some((file3) => !path14.isAbsolute(file3)) || Buffer.byteLength(input2) > 3e5 || !Number.isSafeInteger(maxBytes) || maxBytes < 1 || maxBytes > 1048576 || !Number.isSafeInteger(maxTotalBytes) || maxTotalBytes < 1 || maxTotalBytes > 16777216) {
|
|
29148
29149
|
return Promise.reject(new Error("FILE_READ_ARGUMENT_INVALID"));
|
|
29149
29150
|
}
|
|
29150
29151
|
if (signal?.aborted) return Promise.reject(new Error("CANCELLED"));
|
|
@@ -29181,8 +29182,8 @@ function readWindowsFiles(bridge, files, maxBytes, maxTotalBytes, signal) {
|
|
|
29181
29182
|
child.stdin.end(input2);
|
|
29182
29183
|
});
|
|
29183
29184
|
}
|
|
29184
|
-
function invokeRead(bridge,
|
|
29185
|
-
if (process.platform !== "win32" || !path14.isAbsolute(bridge) || !path14.isAbsolute(
|
|
29185
|
+
function invokeRead(bridge, file3, maxBytes, prefix, signal) {
|
|
29186
|
+
if (process.platform !== "win32" || !path14.isAbsolute(bridge) || !path14.isAbsolute(file3) || !Number.isSafeInteger(maxBytes) || maxBytes < 1 || maxBytes > (prefix ? 16777216 : 1048576)) {
|
|
29186
29187
|
return Promise.reject(new Error("FILE_READ_ARGUMENT_INVALID"));
|
|
29187
29188
|
}
|
|
29188
29189
|
if (signal?.aborted) return Promise.reject(new Error("CANCELLED"));
|
|
@@ -29205,7 +29206,7 @@ function invokeRead(bridge, file2, maxBytes, prefix, signal) {
|
|
|
29205
29206
|
});
|
|
29206
29207
|
child.stdin.on("error", () => {
|
|
29207
29208
|
});
|
|
29208
|
-
child.stdin.end(JSON.stringify({ path:
|
|
29209
|
+
child.stdin.end(JSON.stringify({ path: file3 }));
|
|
29209
29210
|
});
|
|
29210
29211
|
}
|
|
29211
29212
|
|
|
@@ -29545,11 +29546,11 @@ async function portalScreenshot(socket, uid, token, signal) {
|
|
|
29545
29546
|
signal.addEventListener("abort", abort, { once: true });
|
|
29546
29547
|
connection.on("error", fail7);
|
|
29547
29548
|
connection.on("close", () => fail7(Error("CLOSED")));
|
|
29548
|
-
const call = (destination,
|
|
29549
|
+
const call = (destination, path31, iface, member, signature = "", body = () => {
|
|
29549
29550
|
}) => new Promise((done, failed) => {
|
|
29550
29551
|
const payload2 = new Writer();
|
|
29551
29552
|
body(payload2);
|
|
29552
|
-
const header = new Writer(), fields = [[1, "o",
|
|
29553
|
+
const header = new Writer(), fields = [[1, "o", path31], [2, "s", iface], [3, "s", member], [6, "s", destination]];
|
|
29553
29554
|
if (signature) fields.push([8, "g", signature]);
|
|
29554
29555
|
header.byte(108);
|
|
29555
29556
|
header.byte(1);
|
|
@@ -30394,10 +30395,10 @@ function jpegSize(data) {
|
|
|
30394
30395
|
}
|
|
30395
30396
|
return null;
|
|
30396
30397
|
}
|
|
30397
|
-
function run(
|
|
30398
|
+
function run(file3, args, signal, maxBuffer = 65536, env = buildChildEnvironment(process.env, process.platform)) {
|
|
30398
30399
|
return new Promise((resolve, reject) => {
|
|
30399
30400
|
execFile4(
|
|
30400
|
-
|
|
30401
|
+
file3,
|
|
30401
30402
|
args,
|
|
30402
30403
|
{ encoding: "buffer", timeout: 15e3, maxBuffer, windowsHide: true, shell: false, env, signal },
|
|
30403
30404
|
(error62, stdout, stderr) => error62 ? reject(Object.assign(error62, { stdout, stderr })) : resolve({ stdout, stderr })
|
|
@@ -30469,10 +30470,10 @@ var SESSION_VALUE = /^[A-Za-z0-9_.:,;=@+/-]{1,256}$/;
|
|
|
30469
30470
|
var LINUX_SOURCE_BYTES = 150994944;
|
|
30470
30471
|
async function linuxTool(name2) {
|
|
30471
30472
|
for (const directory of ["/usr/bin", "/bin", "/usr/local/bin"]) {
|
|
30472
|
-
const
|
|
30473
|
+
const file3 = path17.posix.join(directory, name2);
|
|
30473
30474
|
try {
|
|
30474
|
-
await access3(
|
|
30475
|
-
return
|
|
30475
|
+
await access3(file3, constants7.X_OK);
|
|
30476
|
+
return file3;
|
|
30476
30477
|
} catch {
|
|
30477
30478
|
}
|
|
30478
30479
|
}
|
|
@@ -30517,8 +30518,8 @@ async function linuxSession(signal) {
|
|
|
30517
30518
|
}
|
|
30518
30519
|
}
|
|
30519
30520
|
if (session.DISPLAY && !session.XAUTHORITY) {
|
|
30520
|
-
const
|
|
30521
|
-
if ((await lstat7(
|
|
30521
|
+
const file3 = path17.posix.join(os4.homedir(), ".Xauthority");
|
|
30522
|
+
if ((await lstat7(file3).catch(() => null))?.isFile()) take("XAUTHORITY", file3);
|
|
30522
30523
|
}
|
|
30523
30524
|
if (session.XDG_RUNTIME_DIR) take("DBUS_SESSION_BUS_ADDRESS", "unix:path=" + session.XDG_RUNTIME_DIR + "/bus");
|
|
30524
30525
|
const wayland = !!session.WAYLAND_DISPLAY || session.XDG_SESSION_TYPE === "wayland";
|
|
@@ -30541,13 +30542,13 @@ async function portalCapture(socket, signal) {
|
|
|
30541
30542
|
const { code, uri } = answer;
|
|
30542
30543
|
if (code === 1) throw new ScreenCaptureError("SCREEN_RECORDING_PERMISSION_REQUIRED");
|
|
30543
30544
|
if (code !== 0 || !uri?.startsWith("file://")) throw new ScreenCaptureError("SCREEN_UNAVAILABLE");
|
|
30544
|
-
const
|
|
30545
|
+
const file3 = decodeURIComponent(new URL(uri).pathname), info = await lstat7(file3);
|
|
30545
30546
|
const fresh = info.isFile() && info.uid === uid && info.mtimeMs >= started - 5e3;
|
|
30546
30547
|
try {
|
|
30547
30548
|
if (!fresh || info.size > LINUX_SOURCE_BYTES) throw new ScreenCaptureError("SCREEN_UNAVAILABLE");
|
|
30548
|
-
return await readFile6(
|
|
30549
|
+
return await readFile6(file3);
|
|
30549
30550
|
} finally {
|
|
30550
|
-
if (fresh) await unlink2(
|
|
30551
|
+
if (fresh) await unlink2(file3).catch(() => {
|
|
30551
30552
|
});
|
|
30552
30553
|
}
|
|
30553
30554
|
}
|
|
@@ -30630,16 +30631,16 @@ function result(body) {
|
|
|
30630
30631
|
function stopped(signal) {
|
|
30631
30632
|
if (signal.aborted) fail3("CANCELLED");
|
|
30632
30633
|
}
|
|
30633
|
-
async function readBoundedFile(
|
|
30634
|
-
const stat2 = await lstat8(
|
|
30634
|
+
async function readBoundedFile(file3, maxBytes, bridge, signal) {
|
|
30635
|
+
const stat2 = await lstat8(file3);
|
|
30635
30636
|
if (!stat2.isFile() || stat2.isSymbolicLink() || stat2.size > maxBytes) fail3("FILE_UNSUPPORTED_OR_TOO_LARGE");
|
|
30636
30637
|
if (process.platform === "win32") {
|
|
30637
|
-
if (maxBytes <= 1048576 || stat2.size <= 1048576) return readWindowsFile(bridge,
|
|
30638
|
-
const read = await readWindowsFilePrefix(bridge,
|
|
30638
|
+
if (maxBytes <= 1048576 || stat2.size <= 1048576) return readWindowsFile(bridge, file3, Math.min(maxBytes, 1048576), signal);
|
|
30639
|
+
const read = await readWindowsFilePrefix(bridge, file3, maxBytes, signal);
|
|
30639
30640
|
if (read.truncated) fail3("FILE_UNSUPPORTED_OR_TOO_LARGE");
|
|
30640
30641
|
return read.data;
|
|
30641
30642
|
}
|
|
30642
|
-
const handle = await open6(
|
|
30643
|
+
const handle = await open6(file3, constants8.O_RDONLY | (constants8.O_NOFOLLOW ?? 0));
|
|
30643
30644
|
try {
|
|
30644
30645
|
const current2 = await handle.stat();
|
|
30645
30646
|
if (!current2.isFile() || current2.size > maxBytes) fail3("FILE_UNSUPPORTED_OR_TOO_LARGE");
|
|
@@ -30695,9 +30696,9 @@ var NativeTools = class {
|
|
|
30695
30696
|
}
|
|
30696
30697
|
options;
|
|
30697
30698
|
memory;
|
|
30698
|
-
async readFile(
|
|
30699
|
+
async readFile(file3, maxBytes, signal) {
|
|
30699
30700
|
try {
|
|
30700
|
-
return await readBoundedFile(
|
|
30701
|
+
return await readBoundedFile(file3, maxBytes, this.options.ownerBridgePath ?? path18.join(path18.dirname(this.options.helperPath), "OwnerBridge.exe"), signal);
|
|
30701
30702
|
} catch (error62) {
|
|
30702
30703
|
if (error62.code === "ENOENT") throw error62;
|
|
30703
30704
|
if (error62 instanceof Error && /^[A-Z_]{1,40}$/.test(error62.message)) fail3(error62.message);
|
|
@@ -31131,8 +31132,8 @@ var NativeTools = class {
|
|
|
31131
31132
|
else if (call.name === "git_diff") {
|
|
31132
31133
|
argv = ["diff", "--no-ext-diff", "--no-textconv", ...call.args.staged ? ["--cached"] : []];
|
|
31133
31134
|
if (call.args.file) {
|
|
31134
|
-
const
|
|
31135
|
-
const relative = path18.relative(cwd,
|
|
31135
|
+
const file3 = await resolve(path18.resolve(cwd, call.args.file));
|
|
31136
|
+
const relative = path18.relative(cwd, file3);
|
|
31136
31137
|
if (relative.startsWith(".." + path18.sep) || relative === ".." || path18.isAbsolute(relative)) fail3("PATH_NOT_ALLOWED");
|
|
31137
31138
|
argv.push("--", relative);
|
|
31138
31139
|
} else argv.push("--stat");
|
|
@@ -31164,9 +31165,9 @@ var NativeTools = class {
|
|
|
31164
31165
|
}
|
|
31165
31166
|
const contextFile = async (relative, limit, optional2 = false) => {
|
|
31166
31167
|
try {
|
|
31167
|
-
const
|
|
31168
|
-
guard.assertSafeFile(
|
|
31169
|
-
return utf8(await this.readFile(
|
|
31168
|
+
const file3 = await guard.resolveExisting(path18.join(primary, relative));
|
|
31169
|
+
guard.assertSafeFile(file3);
|
|
31170
|
+
return utf8(await this.readFile(file3, limit, signal));
|
|
31170
31171
|
} catch (error62) {
|
|
31171
31172
|
if (optional2 && error62.code === "ENOENT") return null;
|
|
31172
31173
|
throw error62;
|
|
@@ -31859,7 +31860,7 @@ function shapeCommandResultForAgentDetailed(input2, result2) {
|
|
|
31859
31860
|
if (parsed.state !== "candidate" && result2.exitCode === 0 && !result2.stdoutTruncated && !result2.stderrTruncated && result2.stderr === "") {
|
|
31860
31861
|
const compact = compactJsonOutput(result2.stdout);
|
|
31861
31862
|
if (compact !== null) {
|
|
31862
|
-
const sent = bytes(compact),
|
|
31863
|
+
const sent = bytes(compact), saved2 = originalBytes - sent;
|
|
31863
31864
|
return Object.freeze({ result: Object.freeze({ ...result2, stdout: compact }), telemetry: Object.freeze({
|
|
31864
31865
|
parserId: "json-whitespace",
|
|
31865
31866
|
parserVersion: "1",
|
|
@@ -31868,8 +31869,8 @@ function shapeCommandResultForAgentDetailed(input2, result2) {
|
|
|
31868
31869
|
reason: "validated_compact",
|
|
31869
31870
|
originalStdoutBytes: originalBytes,
|
|
31870
31871
|
sentStdoutBytes: sent,
|
|
31871
|
-
savedStdoutBytes:
|
|
31872
|
-
reductionPercent: originalBytes === 0 ? 0 :
|
|
31872
|
+
savedStdoutBytes: saved2,
|
|
31873
|
+
reductionPercent: originalBytes === 0 ? 0 : saved2 / originalBytes * 100
|
|
31873
31874
|
}) });
|
|
31874
31875
|
}
|
|
31875
31876
|
}
|
|
@@ -36574,9 +36575,9 @@ var rev2026Codec = {
|
|
|
36574
36575
|
});
|
|
36575
36576
|
const parsed = buildSchemas2026().RequestMetaEnvelopeSchema.safeParse(meta3);
|
|
36576
36577
|
if (!parsed.success) for (const issue2 of parsed.error.issues) {
|
|
36577
|
-
const
|
|
36578
|
-
const key =
|
|
36579
|
-
if (
|
|
36578
|
+
const path31 = issue2.path.map(String);
|
|
36579
|
+
const key = path31.length > 0 ? path31.join(".") : "_meta";
|
|
36580
|
+
if (path31.length === 1 && issues.some((existing) => existing.key === key && existing.problem === "missing")) continue;
|
|
36580
36581
|
issues.push({
|
|
36581
36582
|
key,
|
|
36582
36583
|
problem: issue2.message
|
|
@@ -36878,29 +36879,29 @@ var PERMITTED_X_MCP_HEADER_TYPES = /* @__PURE__ */ new Set([
|
|
|
36878
36879
|
function scanXMcpHeaderDeclarations(inputSchema) {
|
|
36879
36880
|
const declarations = [];
|
|
36880
36881
|
const seenLower = /* @__PURE__ */ new Map();
|
|
36881
|
-
const visit2 = (node2,
|
|
36882
|
+
const visit2 = (node2, path31, reachable) => {
|
|
36882
36883
|
if (node2 === null || typeof node2 !== "object") return void 0;
|
|
36883
36884
|
const schema = node2;
|
|
36884
36885
|
if (X_MCP_HEADER_KEY in schema) {
|
|
36885
|
-
if (!reachable ||
|
|
36886
|
+
if (!reachable || path31.length === 0) return `${pathName(path31)}: x-mcp-header is only permitted on properties statically reachable via a chain of 'properties' keys (not under items, additionalProperties, oneOf/anyOf/allOf/not, if/then/else, or $ref)`;
|
|
36886
36887
|
const raw = schema[X_MCP_HEADER_KEY];
|
|
36887
|
-
if (typeof raw !== "string" || raw.length === 0) return `${pathName(
|
|
36888
|
-
if (!RFC9110_TOKEN.test(raw)) return `${pathName(
|
|
36888
|
+
if (typeof raw !== "string" || raw.length === 0) return `${pathName(path31)}: x-mcp-header MUST be a non-empty string`;
|
|
36889
|
+
if (!RFC9110_TOKEN.test(raw)) return `${pathName(path31)}: x-mcp-header '${raw}' is not a valid RFC 9110 token (no spaces, control characters or HTTP delimiters)`;
|
|
36889
36890
|
const type = typeof schema.type === "string" ? schema.type : void 0;
|
|
36890
|
-
if (type === void 0 || !PERMITTED_X_MCP_HEADER_TYPES.has(type)) return `${pathName(
|
|
36891
|
+
if (type === void 0 || !PERMITTED_X_MCP_HEADER_TYPES.has(type)) return `${pathName(path31)}: x-mcp-header is only permitted on primitive-typed properties (string, integer, boolean); got ${type ?? "<none>"}`;
|
|
36891
36892
|
const lower = raw.toLowerCase();
|
|
36892
36893
|
const prior = seenLower.get(lower);
|
|
36893
36894
|
if (prior !== void 0) return `x-mcp-header '${raw}' is not case-insensitively unique (also declared as '${prior}')`;
|
|
36894
36895
|
seenLower.set(lower, raw);
|
|
36895
36896
|
declarations.push({
|
|
36896
|
-
path:
|
|
36897
|
+
path: path31,
|
|
36897
36898
|
headerName: raw,
|
|
36898
36899
|
type
|
|
36899
36900
|
});
|
|
36900
36901
|
}
|
|
36901
36902
|
const properties = schema.properties;
|
|
36902
36903
|
if (properties !== null && typeof properties === "object") for (const [key, child] of Object.entries(properties)) {
|
|
36903
|
-
const fault$1 = visit2(child, [...
|
|
36904
|
+
const fault$1 = visit2(child, [...path31, key], reachable);
|
|
36904
36905
|
if (fault$1 !== void 0) return fault$1;
|
|
36905
36906
|
}
|
|
36906
36907
|
for (const k of NON_REACHABLE_SUBSCHEMA_KEYWORDS) {
|
|
@@ -36908,7 +36909,7 @@ function scanXMcpHeaderDeclarations(inputSchema) {
|
|
|
36908
36909
|
if (sub === void 0) continue;
|
|
36909
36910
|
const branches = Array.isArray(sub) ? sub : sub !== null && typeof sub === "object" && OBJECT_VALUED_SUBSCHEMA_KEYWORDS.has(k) ? Object.values(sub) : [sub];
|
|
36910
36911
|
for (const branch of branches) {
|
|
36911
|
-
const fault$1 = visit2(branch, [...
|
|
36912
|
+
const fault$1 = visit2(branch, [...path31, `<${k}>`], false);
|
|
36912
36913
|
if (fault$1 !== void 0) return fault$1;
|
|
36913
36914
|
}
|
|
36914
36915
|
}
|
|
@@ -36948,8 +36949,8 @@ var OBJECT_VALUED_SUBSCHEMA_KEYWORDS = /* @__PURE__ */ new Set([
|
|
|
36948
36949
|
"$defs",
|
|
36949
36950
|
"definitions"
|
|
36950
36951
|
]);
|
|
36951
|
-
function pathName(
|
|
36952
|
-
return
|
|
36952
|
+
function pathName(path31) {
|
|
36953
|
+
return path31.length === 0 ? "<root>" : path31.join(".");
|
|
36953
36954
|
}
|
|
36954
36955
|
var HEADER_MISMATCH_ERROR_CODE = -32020;
|
|
36955
36956
|
var INBOUND_VALIDATION_LADDER = [
|
|
@@ -37199,7 +37200,7 @@ var PROPERTY_KEYS_BY_TYPE = {
|
|
|
37199
37200
|
array: shapeKeys([UntitledMultiSelectEnumSchemaSchema, TitledMultiSelectEnumSchemaSchema])
|
|
37200
37201
|
};
|
|
37201
37202
|
var SUPPORTED_STRING_FORMATS = new Set(StringSchemaSchema.shape.format.unwrap().options);
|
|
37202
|
-
function walkProperty(node2,
|
|
37203
|
+
function walkProperty(node2, path31, vendor, unsupported) {
|
|
37203
37204
|
if (!isJsonObject(node2)) return node2;
|
|
37204
37205
|
const allowedKeys = typeof node2.type === "string" && Object.hasOwn(PROPERTY_KEYS_BY_TYPE, node2.type) ? PROPERTY_KEYS_BY_TYPE[node2.type] : void 0;
|
|
37205
37206
|
if (allowedKeys === void 0) return node2;
|
|
@@ -37207,8 +37208,8 @@ function walkProperty(node2, path30, vendor, unsupported) {
|
|
|
37207
37208
|
for (const [key, value] of Object.entries(node2)) if (allowedKeys.has(key) || isAnnotationOnlyJsonSchemaKeyword(key)) pruned[key] = value;
|
|
37208
37209
|
else if (key === "pattern" && node2.type === "string" && typeof node2.format === "string") {
|
|
37209
37210
|
if (!SUPPORTED_STRING_FORMATS.has(node2.format)) pruned[key] = value;
|
|
37210
|
-
else if (typeof value !== "string" || !isLibraryFormatPattern(node2.format, value, vendor)) unsupported.push(`${
|
|
37211
|
-
} else unsupported.push(`${
|
|
37211
|
+
else if (typeof value !== "string" || !isLibraryFormatPattern(node2.format, value, vendor)) unsupported.push(`${path31}.${key}`);
|
|
37212
|
+
} else unsupported.push(`${path31}.${key}`);
|
|
37212
37213
|
return pruned;
|
|
37213
37214
|
}
|
|
37214
37215
|
function walkRequestedSchema(converted, vendor) {
|
|
@@ -37225,11 +37226,11 @@ function describeUnsupportedProperties(pruned, fallback) {
|
|
|
37225
37226
|
const offenders = Object.entries(pruned.properties).filter(([, node2]) => !parseSchema(PrimitiveSchemaDefinitionSchema, node2).success).map(([name2]) => `properties.${name2}`);
|
|
37226
37227
|
return offenders.length > 0 ? offenders.join(", ") : fallback;
|
|
37227
37228
|
}
|
|
37228
|
-
function findDroppedConstraintPaths(original, parsed,
|
|
37229
|
-
if (Array.isArray(original) && Array.isArray(parsed)) return original.flatMap((item, index) => findDroppedConstraintPaths(item, parsed[index], `${
|
|
37229
|
+
function findDroppedConstraintPaths(original, parsed, path31 = "") {
|
|
37230
|
+
if (Array.isArray(original) && Array.isArray(parsed)) return original.flatMap((item, index) => findDroppedConstraintPaths(item, parsed[index], `${path31}[${index}]`));
|
|
37230
37231
|
if (!isJsonObject(original) || !isJsonObject(parsed)) return [];
|
|
37231
37232
|
return Object.entries(original).flatMap(([key, value]) => {
|
|
37232
|
-
const childPath =
|
|
37233
|
+
const childPath = path31 ? `${path31}.${key}` : key;
|
|
37233
37234
|
if (!Object.prototype.hasOwnProperty.call(parsed, key)) return isAnnotationOnlyJsonSchemaKeyword(key) ? [] : [childPath];
|
|
37234
37235
|
return findDroppedConstraintPaths(value, parsed[key], childPath);
|
|
37235
37236
|
});
|
|
@@ -41305,8 +41306,8 @@ var require_utils = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
41305
41306
|
for (let i = 0; i < str.length; i++) if (str[i] === token) ind++;
|
|
41306
41307
|
return ind;
|
|
41307
41308
|
}
|
|
41308
|
-
function removeDotSegments(
|
|
41309
|
-
let input2 =
|
|
41309
|
+
function removeDotSegments(path31) {
|
|
41310
|
+
let input2 = path31;
|
|
41310
41311
|
const output2 = [];
|
|
41311
41312
|
let nextSlash = -1;
|
|
41312
41313
|
let len = 0;
|
|
@@ -41459,8 +41460,8 @@ var require_schemes = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
41459
41460
|
wsComponent.secure = void 0;
|
|
41460
41461
|
}
|
|
41461
41462
|
if (wsComponent.resourceName) {
|
|
41462
|
-
const [
|
|
41463
|
-
wsComponent.path =
|
|
41463
|
+
const [path31, query] = wsComponent.resourceName.split("?");
|
|
41464
|
+
wsComponent.path = path31 && path31 !== "/" ? path31 : void 0;
|
|
41464
41465
|
wsComponent.query = query;
|
|
41465
41466
|
wsComponent.resourceName = void 0;
|
|
41466
41467
|
}
|
|
@@ -47410,9 +47411,9 @@ function waitForMessage(socket, maxBytes, timeoutMs2, timeoutCode) {
|
|
|
47410
47411
|
cleanup();
|
|
47411
47412
|
reject(new RelayClientError(error62.code === "WS_ERR_UNSUPPORTED_MESSAGE_LENGTH" ? "RELAY_FRAME_TOO_LARGE" : "RELAY_SOCKET_FAILED"));
|
|
47412
47413
|
};
|
|
47413
|
-
const onClose = () => {
|
|
47414
|
+
const onClose = (code, reason) => {
|
|
47414
47415
|
cleanup();
|
|
47415
|
-
reject(new RelayClientError("RELAY_SOCKET_CLOSED"));
|
|
47416
|
+
reject(new RelayClientError(code === 1008 && reason.toString("utf8") === "device_quarantined" ? "RELAY_DEVICE_QUARANTINED" : "RELAY_SOCKET_CLOSED"));
|
|
47416
47417
|
};
|
|
47417
47418
|
socket.once("message", onMessage);
|
|
47418
47419
|
socket.once("error", onError);
|
|
@@ -47521,7 +47522,8 @@ async function connectOnce(options) {
|
|
|
47521
47522
|
deviceId,
|
|
47522
47523
|
guardIdentity: true,
|
|
47523
47524
|
...options.aiConnectivity ? { aiConnectivity: true } : {},
|
|
47524
|
-
...options.onHeldLeases ? { heldLeases: true } : {}
|
|
47525
|
+
...options.onHeldLeases ? { heldLeases: true } : {},
|
|
47526
|
+
...options.onFullLogChoice ? { fullLogNotice: true } : {}
|
|
47525
47527
|
}, maxFrameBytes);
|
|
47526
47528
|
const challenge = validateChallenge(await waitForMessage(socket, maxFrameBytes, connectTimeoutMs, "RELAY_HANDSHAKE_TIMEOUT"), protocolVersion2);
|
|
47527
47529
|
const machine = challenge.machineIdentity ? options.machineIdentity?.(deviceId) ?? null : null;
|
|
@@ -47624,6 +47626,17 @@ async function connectOnce(options) {
|
|
|
47624
47626
|
void (async () => {
|
|
47625
47627
|
try {
|
|
47626
47628
|
const frame = parseFrame(data, maxFrameBytes);
|
|
47629
|
+
if (frame.type === "fullLogState") {
|
|
47630
|
+
const state = FullLogStateSchema.safeParse(frame);
|
|
47631
|
+
if (state.success && state.data.connectionEpoch === connectionEpoch) {
|
|
47632
|
+
try {
|
|
47633
|
+
void Promise.resolve(options.onFullLogChoice?.(state.data.enabled)).catch(() => {
|
|
47634
|
+
});
|
|
47635
|
+
} catch {
|
|
47636
|
+
}
|
|
47637
|
+
}
|
|
47638
|
+
return;
|
|
47639
|
+
}
|
|
47627
47640
|
if (frame.type === "aiConnectivityRevoked") {
|
|
47628
47641
|
if (connectivity && frame.protocolVersion === 1 && frame.connectionEpoch === connectionEpoch) notifyConnectivityRevoked();
|
|
47629
47642
|
return;
|
|
@@ -47972,8 +47985,8 @@ function canonicalOrigin2(value) {
|
|
|
47972
47985
|
fail6("ORIGIN_INVALID");
|
|
47973
47986
|
}
|
|
47974
47987
|
}
|
|
47975
|
-
function endpoint(origin,
|
|
47976
|
-
return origin +
|
|
47988
|
+
function endpoint(origin, path31) {
|
|
47989
|
+
return origin + path31;
|
|
47977
47990
|
}
|
|
47978
47991
|
function uuid21(value, code) {
|
|
47979
47992
|
if (typeof value !== "string" || !UUID3.test(value)) fail6(code);
|
|
@@ -48940,12 +48953,12 @@ var ProductionMonitor = class {
|
|
|
48940
48953
|
});
|
|
48941
48954
|
return this.writing;
|
|
48942
48955
|
}
|
|
48943
|
-
async write(
|
|
48944
|
-
const directory = path23.dirname(
|
|
48956
|
+
async write(file3, contents) {
|
|
48957
|
+
const directory = path23.dirname(file3);
|
|
48945
48958
|
await mkdir9(directory, { recursive: true, mode: 448 });
|
|
48946
48959
|
const stat2 = await lstat10(directory);
|
|
48947
48960
|
if (!stat2.isDirectory() || stat2.isSymbolicLink()) throw Error("MONITOR_DIRECTORY_INVALID");
|
|
48948
|
-
const temporary =
|
|
48961
|
+
const temporary = file3 + "." + this.instanceId + ".tmp";
|
|
48949
48962
|
const handle = await open9(temporary, "wx", 384);
|
|
48950
48963
|
try {
|
|
48951
48964
|
try {
|
|
@@ -48953,7 +48966,7 @@ var ProductionMonitor = class {
|
|
|
48953
48966
|
} finally {
|
|
48954
48967
|
await handle.close();
|
|
48955
48968
|
}
|
|
48956
|
-
await rename6(temporary,
|
|
48969
|
+
await rename6(temporary, file3);
|
|
48957
48970
|
} finally {
|
|
48958
48971
|
await rm8(temporary, { force: true });
|
|
48959
48972
|
}
|
|
@@ -48965,6 +48978,108 @@ var ProductionMonitor = class {
|
|
|
48965
48978
|
}
|
|
48966
48979
|
};
|
|
48967
48980
|
|
|
48981
|
+
// agent/src/full-log-notice.ts
|
|
48982
|
+
import { execFile as execFile5 } from "node:child_process";
|
|
48983
|
+
import { randomUUID as randomUUID13 } from "node:crypto";
|
|
48984
|
+
import { lstat as lstat11, mkdir as mkdir10, readFile as readFile10, rename as rename7, rm as rm9, writeFile as writeFile4 } from "node:fs/promises";
|
|
48985
|
+
import path24 from "node:path";
|
|
48986
|
+
import { promisify as promisify3 } from "node:util";
|
|
48987
|
+
var exec3 = promisify3(execFile5);
|
|
48988
|
+
var manageUrl = "https://localcmd.app";
|
|
48989
|
+
var noticeDirectory = (directory) => path24.join(directory, "optimization");
|
|
48990
|
+
var file2 = (directory) => path24.join(noticeDirectory(directory), "full-log-notice.json");
|
|
48991
|
+
async function saved(directory, enrollment) {
|
|
48992
|
+
if (!enrollment) return null;
|
|
48993
|
+
try {
|
|
48994
|
+
const parent = await lstat11(noticeDirectory(directory));
|
|
48995
|
+
if (!parent.isDirectory() || parent.isSymbolicLink()) return null;
|
|
48996
|
+
const info = await lstat11(file2(directory));
|
|
48997
|
+
if (!info.isFile() || info.isSymbolicLink() || info.size > 4096) return null;
|
|
48998
|
+
const value = JSON.parse(await readFile10(file2(directory), "utf8"));
|
|
48999
|
+
if (value.tenantId !== enrollment.tenantId || value.deviceId !== enrollment.deviceId || !(value.enabled === null || typeof value.enabled === "boolean") || !(value.lastNotified === null || typeof value.lastNotified === "boolean") || !Number.isInteger(value.pid) || value.pid <= 0 || !Number.isFinite(Date.parse(value.confirmedAt))) return null;
|
|
49000
|
+
return value;
|
|
49001
|
+
} catch {
|
|
49002
|
+
return null;
|
|
49003
|
+
}
|
|
49004
|
+
}
|
|
49005
|
+
async function readFullLogNotice(directory, enrollment) {
|
|
49006
|
+
const value = await saved(directory, enrollment);
|
|
49007
|
+
let live = false;
|
|
49008
|
+
if (value) {
|
|
49009
|
+
try {
|
|
49010
|
+
const processRecord = JSON.parse(await readFile10(path24.join(directory, "agent-process.json"), "utf8"));
|
|
49011
|
+
if (processRecord.pid === value.pid && Date.parse(processRecord.startedAt) <= Date.parse(value.confirmedAt)) {
|
|
49012
|
+
process.kill(value.pid, 0);
|
|
49013
|
+
live = true;
|
|
49014
|
+
}
|
|
49015
|
+
} catch {
|
|
49016
|
+
}
|
|
49017
|
+
}
|
|
49018
|
+
return { enabled: live ? value.enabled : null, confirmedAt: value?.confirmedAt ?? null, manageUrl };
|
|
49019
|
+
}
|
|
49020
|
+
async function showFullLogNotice(enabled) {
|
|
49021
|
+
const title = "Local Commander: full logs " + (enabled ? "enabled" : "disabled");
|
|
49022
|
+
const body = enabled ? "Your account owner enabled full logs for this computer. Tool requests and responses may be stored for up to 7 days. Review the choice at localcmd.app." : "Your account owner disabled full logs for this computer. Review the choice and deletion status at localcmd.app.";
|
|
49023
|
+
const options = { windowsHide: true, timeout: 12e3, maxBuffer: 4096 };
|
|
49024
|
+
if (process.platform === "win32") {
|
|
49025
|
+
const script = `Add-Type -AssemblyName System.Windows.Forms; Add-Type -AssemblyName System.Drawing; $notice=New-Object System.Windows.Forms.NotifyIcon; try { $notice.Icon=[System.Drawing.SystemIcons]::Information; $notice.Visible=$true; $notice.ShowBalloonTip(8000,'${title}','${body}',[System.Windows.Forms.ToolTipIcon]::Info); Start-Sleep -Seconds 8 } finally { $notice.Dispose() }`;
|
|
49026
|
+
await exec3("powershell.exe", ["-NoLogo", "-NoProfile", "-NonInteractive", "-Command", script], options);
|
|
49027
|
+
} else if (process.platform === "darwin") {
|
|
49028
|
+
await exec3("/usr/bin/osascript", ["-e", `display notification "${body}" with title "${title}"`], options);
|
|
49029
|
+
} else if (process.platform === "linux") {
|
|
49030
|
+
await exec3("notify-send", ["--app-name=Local Commander", title, body], options);
|
|
49031
|
+
}
|
|
49032
|
+
}
|
|
49033
|
+
var FullLogNotice = class {
|
|
49034
|
+
constructor(directory, enrollment, notify = showFullLogNotice) {
|
|
49035
|
+
this.directory = directory;
|
|
49036
|
+
this.enrollment = enrollment;
|
|
49037
|
+
this.notify = notify;
|
|
49038
|
+
}
|
|
49039
|
+
directory;
|
|
49040
|
+
enrollment;
|
|
49041
|
+
notify;
|
|
49042
|
+
pending;
|
|
49043
|
+
writing;
|
|
49044
|
+
update(enabled) {
|
|
49045
|
+
this.pending = enabled;
|
|
49046
|
+
return this.writing ??= this.drain().finally(() => {
|
|
49047
|
+
this.writing = void 0;
|
|
49048
|
+
});
|
|
49049
|
+
}
|
|
49050
|
+
async drain() {
|
|
49051
|
+
await mkdir10(noticeDirectory(this.directory), { mode: 448 }).catch((error62) => {
|
|
49052
|
+
if (error62.code !== "EEXIST") throw error62;
|
|
49053
|
+
});
|
|
49054
|
+
const parent = await lstat11(noticeDirectory(this.directory));
|
|
49055
|
+
if (!parent.isDirectory() || parent.isSymbolicLink()) throw Error("FULL_LOG_NOTICE_DIRECTORY_INVALID");
|
|
49056
|
+
let previous = await saved(this.directory, this.enrollment);
|
|
49057
|
+
while (this.pending !== void 0) {
|
|
49058
|
+
const enabled = this.pending;
|
|
49059
|
+
this.pending = void 0;
|
|
49060
|
+
const changed = enabled !== null && enabled !== previous?.lastNotified && (enabled || previous?.lastNotified === true);
|
|
49061
|
+
const next = {
|
|
49062
|
+
...this.enrollment,
|
|
49063
|
+
enabled,
|
|
49064
|
+
lastNotified: changed ? enabled : previous?.lastNotified ?? null,
|
|
49065
|
+
confirmedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
49066
|
+
pid: process.pid
|
|
49067
|
+
};
|
|
49068
|
+
const temporary = file2(this.directory) + "." + randomUUID13() + ".tmp";
|
|
49069
|
+
try {
|
|
49070
|
+
await writeFile4(temporary, JSON.stringify(next) + "\n", { flag: "wx", mode: 384 });
|
|
49071
|
+
await rename7(temporary, file2(this.directory));
|
|
49072
|
+
} finally {
|
|
49073
|
+
await rm9(temporary, { force: true }).catch(() => {
|
|
49074
|
+
});
|
|
49075
|
+
}
|
|
49076
|
+
previous = next;
|
|
49077
|
+
if (changed) void this.notify(enabled).catch(() => {
|
|
49078
|
+
});
|
|
49079
|
+
}
|
|
49080
|
+
}
|
|
49081
|
+
};
|
|
49082
|
+
|
|
48968
49083
|
// agent/src/native-event-buffer.ts
|
|
48969
49084
|
import { createHash as createHash18 } from "node:crypto";
|
|
48970
49085
|
function nativeFingerprint(code, executionId = "") {
|
|
@@ -49366,27 +49481,27 @@ var NativeFabricObserver = class {
|
|
|
49366
49481
|
};
|
|
49367
49482
|
|
|
49368
49483
|
// agent/src/native-fabric-startup.ts
|
|
49369
|
-
import { lstat as
|
|
49370
|
-
import
|
|
49484
|
+
import { lstat as lstat13, mkdir as mkdir13, open as open11, readFile as readFile11 } from "node:fs/promises";
|
|
49485
|
+
import path27 from "node:path";
|
|
49371
49486
|
|
|
49372
49487
|
// src/agent-fabric-service.ts
|
|
49373
|
-
import { lstat as
|
|
49488
|
+
import { lstat as lstat12, mkdir as mkdir12, realpath as realpath9 } from "node:fs/promises";
|
|
49374
49489
|
import { watch } from "node:fs";
|
|
49375
|
-
import
|
|
49490
|
+
import path26 from "node:path";
|
|
49376
49491
|
|
|
49377
49492
|
// src/agent-runtime-identity.ts
|
|
49378
|
-
import { createHash as createHash19, randomBytes as randomBytes8, randomUUID as
|
|
49493
|
+
import { createHash as createHash19, randomBytes as randomBytes8, randomUUID as randomUUID15, timingSafeEqual as timingSafeEqual4 } from "node:crypto";
|
|
49379
49494
|
|
|
49380
49495
|
// src/agent-fabric-state.ts
|
|
49381
|
-
import { randomUUID as
|
|
49382
|
-
import { mkdir as
|
|
49383
|
-
import
|
|
49496
|
+
import { randomUUID as randomUUID14 } from "node:crypto";
|
|
49497
|
+
import { mkdir as mkdir11, open as open10, rename as rename8, unlink as unlink3 } from "node:fs/promises";
|
|
49498
|
+
import path25 from "node:path";
|
|
49384
49499
|
var queues = /* @__PURE__ */ new Map();
|
|
49385
49500
|
var FabricStateFile = class {
|
|
49386
|
-
constructor(
|
|
49501
|
+
constructor(file3, maxBytes, parse4) {
|
|
49387
49502
|
this.maxBytes = maxBytes;
|
|
49388
49503
|
this.parse = parse4;
|
|
49389
|
-
this.file =
|
|
49504
|
+
this.file = path25.resolve(file3);
|
|
49390
49505
|
}
|
|
49391
49506
|
maxBytes;
|
|
49392
49507
|
parse;
|
|
@@ -49430,9 +49545,9 @@ var FabricStateFile = class {
|
|
|
49430
49545
|
}
|
|
49431
49546
|
update(fn, create) {
|
|
49432
49547
|
return this.serial(async () => {
|
|
49433
|
-
if (create) await
|
|
49548
|
+
if (create) await mkdir11(path25.dirname(this.file), { recursive: true });
|
|
49434
49549
|
const lockPath = this.file + ".lock";
|
|
49435
|
-
const token =
|
|
49550
|
+
const token = randomUUID14();
|
|
49436
49551
|
const lock = await open10(lockPath, "wx", 384).catch((error62) => {
|
|
49437
49552
|
if (error62.code === "EEXIST") throw Error("FABRIC_STATE_BUSY");
|
|
49438
49553
|
throw error62;
|
|
@@ -49459,7 +49574,7 @@ var FabricStateFile = class {
|
|
|
49459
49574
|
} finally {
|
|
49460
49575
|
await handle.close();
|
|
49461
49576
|
}
|
|
49462
|
-
await
|
|
49577
|
+
await rename8(temporary, this.file);
|
|
49463
49578
|
} finally {
|
|
49464
49579
|
await unlink3(temporary).catch((error62) => {
|
|
49465
49580
|
if (error62.code !== "ENOENT") throw error62;
|
|
@@ -49507,9 +49622,9 @@ function validKey(value) {
|
|
|
49507
49622
|
return typeof value === "string" && /^[A-Za-z0-9_-]{43}$/.test(value);
|
|
49508
49623
|
}
|
|
49509
49624
|
var AgentRuntimeIdentityStore = class {
|
|
49510
|
-
constructor(
|
|
49625
|
+
constructor(file3, now = Date.now) {
|
|
49511
49626
|
this.now = now;
|
|
49512
|
-
this.state = new FabricStateFile(
|
|
49627
|
+
this.state = new FabricStateFile(file3, MAX_BYTES, (value) => {
|
|
49513
49628
|
const state = StateSchema.parse(value);
|
|
49514
49629
|
if (new Set(state.bindings.map((item) => item.runtimeId)).size !== state.bindings.length)
|
|
49515
49630
|
throw Error("RUNTIME_IDENTITY_STATE_CORRUPT");
|
|
@@ -49528,7 +49643,7 @@ var AgentRuntimeIdentityStore = class {
|
|
|
49528
49643
|
issue() {
|
|
49529
49644
|
return this.serial((state) => {
|
|
49530
49645
|
if (state.bindings.length >= MAX_BINDINGS) throw Error("RUNTIME_IDENTITY_LIMIT");
|
|
49531
|
-
const runtimeId = "rt-" +
|
|
49646
|
+
const runtimeId = "rt-" + randomUUID15();
|
|
49532
49647
|
const runtimeKey = randomBytes8(32).toString("base64url");
|
|
49533
49648
|
const now = this.now();
|
|
49534
49649
|
state.bindings.push({ runtimeId, keyHash: encodedDigest(runtimeKey), createdAt: now, lastUsedAt: now, revoked: false });
|
|
@@ -49561,10 +49676,10 @@ var AgentRuntimeIdentityStore = class {
|
|
|
49561
49676
|
};
|
|
49562
49677
|
|
|
49563
49678
|
// src/agent-fabric-mailbox.ts
|
|
49564
|
-
import { randomUUID as
|
|
49679
|
+
import { randomUUID as randomUUID17 } from "node:crypto";
|
|
49565
49680
|
|
|
49566
49681
|
// src/agent-fabric-timeline.ts
|
|
49567
|
-
import { randomUUID as
|
|
49682
|
+
import { randomUUID as randomUUID16 } from "node:crypto";
|
|
49568
49683
|
import { performance as performance2 } from "node:perf_hooks";
|
|
49569
49684
|
var FabricId = external_exports.string().regex(/^[A-Za-z0-9][A-Za-z0-9_.:-]{0,95}$/);
|
|
49570
49685
|
var FabricUtc = external_exports.string().datetime({ precision: 3 }).refine((value) => new Date(value).toISOString() === value);
|
|
@@ -49573,7 +49688,7 @@ var FabricStampSchema = external_exports.strictObject({
|
|
|
49573
49688
|
clockId: FabricId,
|
|
49574
49689
|
monotonicMs: external_exports.number().finite().nonnegative().max(Number.MAX_SAFE_INTEGER)
|
|
49575
49690
|
});
|
|
49576
|
-
var processClockId = "clock-" +
|
|
49691
|
+
var processClockId = "clock-" + randomUUID16();
|
|
49577
49692
|
function createFabricClock() {
|
|
49578
49693
|
return () => ({ atUtc: (/* @__PURE__ */ new Date()).toISOString(), clockId: processClockId, monotonicMs: performance2.now() });
|
|
49579
49694
|
}
|
|
@@ -49759,12 +49874,12 @@ function parseState(value) {
|
|
|
49759
49874
|
return state;
|
|
49760
49875
|
}
|
|
49761
49876
|
var AgentWorkerMailbox = class {
|
|
49762
|
-
constructor(
|
|
49877
|
+
constructor(file3, controllerId, identities, clock = createFabricClock(), notify) {
|
|
49763
49878
|
this.identities = identities;
|
|
49764
49879
|
this.clock = clock;
|
|
49765
49880
|
this.notify = notify;
|
|
49766
49881
|
this.controllerId = FabricId.parse(controllerId);
|
|
49767
|
-
this.state = new FabricStateFile(
|
|
49882
|
+
this.state = new FabricStateFile(file3, 2 * 1024 * 1024, (value) => {
|
|
49768
49883
|
const state = parseState(value);
|
|
49769
49884
|
if (state.controllerId !== this.controllerId) throw Error("FABRIC_CONTROLLER_MISMATCH");
|
|
49770
49885
|
return state;
|
|
@@ -49830,7 +49945,7 @@ var AgentWorkerMailbox = class {
|
|
|
49830
49945
|
const now = this.clock().atUtc;
|
|
49831
49946
|
const worker = {
|
|
49832
49947
|
...registration,
|
|
49833
|
-
workerId:
|
|
49948
|
+
workerId: randomUUID17(),
|
|
49834
49949
|
controllerId: this.controllerId,
|
|
49835
49950
|
runtimeId: null,
|
|
49836
49951
|
attribution: WorkerAttributionSchema.parse({}),
|
|
@@ -49864,7 +49979,7 @@ var AgentWorkerMailbox = class {
|
|
|
49864
49979
|
if (state.messages.length >= MAX_MESSAGES) throw Error("FABRIC_MESSAGE_LIMIT");
|
|
49865
49980
|
const now = this.clock();
|
|
49866
49981
|
const message2 = {
|
|
49867
|
-
messageId:
|
|
49982
|
+
messageId: randomUUID17(),
|
|
49868
49983
|
key: request.key,
|
|
49869
49984
|
assignmentId: assignment.assignmentId,
|
|
49870
49985
|
direction,
|
|
@@ -49881,7 +49996,7 @@ var AgentWorkerMailbox = class {
|
|
|
49881
49996
|
}
|
|
49882
49997
|
async assign(input2) {
|
|
49883
49998
|
const request = AssignmentInput.parse(input2);
|
|
49884
|
-
const
|
|
49999
|
+
const saved2 = await this.state.update((state) => {
|
|
49885
50000
|
this.worker(state, request.workerId);
|
|
49886
50001
|
const existing = state.assignments.find((a) => a.runId === request.runId && a.selectedRuntime === request.selectedRuntime);
|
|
49887
50002
|
if (existing) {
|
|
@@ -49894,7 +50009,7 @@ var AgentWorkerMailbox = class {
|
|
|
49894
50009
|
const now = this.clock().atUtc;
|
|
49895
50010
|
const assignment = {
|
|
49896
50011
|
...request,
|
|
49897
|
-
assignmentId:
|
|
50012
|
+
assignmentId: randomUUID17(),
|
|
49898
50013
|
phase: "assigned",
|
|
49899
50014
|
createdAt: now,
|
|
49900
50015
|
updatedAt: now,
|
|
@@ -49909,30 +50024,30 @@ var AgentWorkerMailbox = class {
|
|
|
49909
50024
|
const { message: message2 } = this.append(state, assignment, "ASSIGN", "controller", { key: "assign", payloadRef: request.payloadRef });
|
|
49910
50025
|
return { state, assignment, notice: message2 };
|
|
49911
50026
|
});
|
|
49912
|
-
if (
|
|
49913
|
-
return
|
|
50027
|
+
if (saved2.notice) this.emit(saved2.state, saved2.notice);
|
|
50028
|
+
return saved2.assignment;
|
|
49914
50029
|
}
|
|
49915
50030
|
async control(assignmentId, kind, input2) {
|
|
49916
50031
|
Control.parse(kind);
|
|
49917
|
-
const
|
|
50032
|
+
const saved2 = await this.state.update((state) => {
|
|
49918
50033
|
const assignment = this.assignment(state, assignmentId);
|
|
49919
50034
|
if (!assignmentActive(assignment)) throw Error("FABRIC_ASSIGNMENT_INACTIVE");
|
|
49920
50035
|
return { state, ...this.append(state, assignment, kind, "controller", input2) };
|
|
49921
50036
|
});
|
|
49922
|
-
if (
|
|
49923
|
-
return
|
|
50037
|
+
if (saved2.added) this.emit(saved2.state, saved2.message);
|
|
50038
|
+
return saved2.message;
|
|
49924
50039
|
}
|
|
49925
50040
|
async report(workerId, credential, assignmentId, kind, input2) {
|
|
49926
50041
|
Report.parse(kind);
|
|
49927
50042
|
await this.identities.authenticate(credential.runtimeId, credential.runtimeKey);
|
|
49928
|
-
const
|
|
50043
|
+
const saved2 = await this.state.update((state) => {
|
|
49929
50044
|
this.bound(state, workerId, credential);
|
|
49930
50045
|
const assignment = this.assignment(state, assignmentId);
|
|
49931
50046
|
if (assignment.workerId !== workerId || assignment.phase === "not_started") throw Error("FABRIC_ASSIGNMENT_DENIED");
|
|
49932
50047
|
return { state, ...this.append(state, assignment, kind, "worker", input2) };
|
|
49933
50048
|
});
|
|
49934
|
-
if (
|
|
49935
|
-
return
|
|
50049
|
+
if (saved2.added) this.emit(saved2.state, saved2.message);
|
|
50050
|
+
return saved2.message;
|
|
49936
50051
|
}
|
|
49937
50052
|
pending(state, direction, workerId) {
|
|
49938
50053
|
const now = this.clock().atUtc;
|
|
@@ -49972,12 +50087,12 @@ var AgentWorkerMailbox = class {
|
|
|
49972
50087
|
return this.state.update((state) => this.acknowledge(state, messageId, "to_controller"));
|
|
49973
50088
|
}
|
|
49974
50089
|
async adapterResult(assignmentId, payloadRef) {
|
|
49975
|
-
const
|
|
50090
|
+
const saved2 = await this.state.update((state) => {
|
|
49976
50091
|
const assignment = this.assignment(state, assignmentId);
|
|
49977
50092
|
if (assignment.phase !== "exited") throw Error("FABRIC_RESULT_UNCONFIRMED");
|
|
49978
50093
|
return { state, ...this.append(state, assignment, "RESULT", "adapter", { key: "result", payloadRef }) };
|
|
49979
50094
|
});
|
|
49980
|
-
if (
|
|
50095
|
+
if (saved2.added) this.emit(saved2.state, saved2.message);
|
|
49981
50096
|
}
|
|
49982
50097
|
claimLaunch(assignmentId) {
|
|
49983
50098
|
return this.state.update((state) => {
|
|
@@ -50074,9 +50189,9 @@ var WorkerRequest = external_exports.discriminatedUnion("operation", [
|
|
|
50074
50189
|
var AgentFabricService = class _AgentFabricService {
|
|
50075
50190
|
constructor(directory, controllerId) {
|
|
50076
50191
|
this.directory = directory;
|
|
50077
|
-
this.identities = new AgentRuntimeIdentityStore(
|
|
50192
|
+
this.identities = new AgentRuntimeIdentityStore(path26.join(directory, "identities.json"));
|
|
50078
50193
|
this.mailbox = new AgentWorkerMailbox(
|
|
50079
|
-
|
|
50194
|
+
path26.join(directory, "mailbox.json"),
|
|
50080
50195
|
controllerId,
|
|
50081
50196
|
this.identities,
|
|
50082
50197
|
void 0,
|
|
@@ -50091,29 +50206,29 @@ var AgentFabricService = class _AgentFabricService {
|
|
|
50091
50206
|
closed = false;
|
|
50092
50207
|
static async open(directory, controllerId, device = null, initialize = true) {
|
|
50093
50208
|
const expected = Binding.parse({ version: 1, controllerId, device, initialized: false });
|
|
50094
|
-
const absolute2 =
|
|
50095
|
-
for (let current2 = absolute2; ; current2 =
|
|
50209
|
+
const absolute2 = path26.resolve(directory);
|
|
50210
|
+
for (let current2 = absolute2; ; current2 = path26.dirname(current2)) {
|
|
50096
50211
|
try {
|
|
50097
|
-
if ((await
|
|
50212
|
+
if ((await lstat12(current2)).isSymbolicLink()) throw Error("FABRIC_DIRECTORY_INVALID");
|
|
50098
50213
|
} catch (error62) {
|
|
50099
50214
|
if (error62.code !== "ENOENT") throw error62;
|
|
50100
50215
|
}
|
|
50101
|
-
if (
|
|
50216
|
+
if (path26.dirname(current2) === current2) break;
|
|
50102
50217
|
}
|
|
50103
|
-
if (initialize) await
|
|
50104
|
-
if (!(await
|
|
50218
|
+
if (initialize) await mkdir12(absolute2, { recursive: true, mode: 448 });
|
|
50219
|
+
if (!(await lstat12(absolute2)).isDirectory() || (await realpath9(absolute2)).toLowerCase() !== absolute2.toLowerCase())
|
|
50105
50220
|
throw Error("FABRIC_DIRECTORY_INVALID");
|
|
50106
50221
|
const present = /* @__PURE__ */ new Set();
|
|
50107
50222
|
for (const name2 of ["binding.json", "mailbox.json", "identities.json"]) {
|
|
50108
|
-
const
|
|
50223
|
+
const file3 = await lstat12(path26.join(absolute2, name2)).catch((error62) => {
|
|
50109
50224
|
if (error62.code === "ENOENT") return null;
|
|
50110
50225
|
throw error62;
|
|
50111
50226
|
});
|
|
50112
|
-
if (
|
|
50113
|
-
if (
|
|
50227
|
+
if (file3 && (!file3.isFile() || file3.isSymbolicLink())) throw Error("FABRIC_FILE_INVALID");
|
|
50228
|
+
if (file3) present.add(name2);
|
|
50114
50229
|
}
|
|
50115
50230
|
if (!present.has("binding.json") && present.size) throw Error("FABRIC_BINDING_MISSING");
|
|
50116
|
-
const binding2 = new FabricStateFile(
|
|
50231
|
+
const binding2 = new FabricStateFile(path26.join(absolute2, "binding.json"), 2048, (value) => Binding.parse(value));
|
|
50117
50232
|
const service2 = new _AgentFabricService(absolute2, controllerId);
|
|
50118
50233
|
await binding2.update(async (state) => {
|
|
50119
50234
|
if (state.controllerId !== expected.controllerId || JSON.stringify(state.device) !== JSON.stringify(expected.device))
|
|
@@ -50128,7 +50243,7 @@ var AgentFabricService = class _AgentFabricService {
|
|
|
50128
50243
|
state.initialized = true;
|
|
50129
50244
|
}
|
|
50130
50245
|
const snapshot2 = await service2.mailbox.snapshot();
|
|
50131
|
-
if (snapshot2.workers.some((worker) => worker.runtimeId !== null)) await
|
|
50246
|
+
if (snapshot2.workers.some((worker) => worker.runtimeId !== null)) await lstat12(path26.join(absolute2, "identities.json"));
|
|
50132
50247
|
}, initialize ? () => expected : void 0);
|
|
50133
50248
|
return service2;
|
|
50134
50249
|
}
|
|
@@ -50145,8 +50260,8 @@ var AgentFabricService = class _AgentFabricService {
|
|
|
50145
50260
|
this.listeners.add(callback);
|
|
50146
50261
|
try {
|
|
50147
50262
|
if (!this.watcher) {
|
|
50148
|
-
this.watcher = watch(this.directory, { persistent: false }, (_event,
|
|
50149
|
-
if (
|
|
50263
|
+
this.watcher = watch(this.directory, { persistent: false }, (_event, file3) => {
|
|
50264
|
+
if (file3?.toString().toLowerCase() === "mailbox.json") this.changed();
|
|
50150
50265
|
});
|
|
50151
50266
|
this.watcher.on("error", () => {
|
|
50152
50267
|
this.watcher?.close();
|
|
@@ -50215,48 +50330,48 @@ var Delivery = external_exports.strictObject({ capability: external_exports.stri
|
|
|
50215
50330
|
async function openNativeFabric(stateDirectory, enrollment, box, initialize = true) {
|
|
50216
50331
|
const controllerId = "device-" + external_exports.string().uuid().parse(enrollment.deviceId).toLowerCase();
|
|
50217
50332
|
const tenantId = external_exports.string().uuid().parse(enrollment.tenantId).toLowerCase();
|
|
50218
|
-
const parent =
|
|
50333
|
+
const parent = path27.join(stateDirectory, ".local-commander"), marker = path27.join(parent, "fabric-established.json");
|
|
50219
50334
|
try {
|
|
50220
|
-
await
|
|
50335
|
+
await mkdir13(parent, { mode: 448 });
|
|
50221
50336
|
} catch (error62) {
|
|
50222
50337
|
if (error62.code !== "EEXIST") throw error62;
|
|
50223
50338
|
}
|
|
50224
|
-
const parentInfo = await
|
|
50339
|
+
const parentInfo = await lstat13(parent);
|
|
50225
50340
|
if (!parentInfo.isDirectory() || parentInfo.isSymbolicLink()) throw Error("FABRIC_DIRECTORY_INVALID");
|
|
50226
50341
|
const expected = JSON.stringify({ version: 1, controllerId, tenantId });
|
|
50227
50342
|
let fresh = false;
|
|
50228
50343
|
try {
|
|
50229
|
-
const info = await
|
|
50230
|
-
if (!info.isFile() || info.isSymbolicLink() || info.size > 2048 || await
|
|
50344
|
+
const info = await lstat13(marker);
|
|
50345
|
+
if (!info.isFile() || info.isSymbolicLink() || info.size > 2048 || await readFile11(marker, "utf8") !== expected)
|
|
50231
50346
|
throw Error("FABRIC_BINDING_CHANGED");
|
|
50232
50347
|
} catch (error62) {
|
|
50233
50348
|
if (error62.code !== "ENOENT" || !initialize) throw error62;
|
|
50234
|
-
const
|
|
50349
|
+
const file3 = await open11(marker, "wx", 384);
|
|
50235
50350
|
try {
|
|
50236
|
-
await
|
|
50237
|
-
await
|
|
50351
|
+
await file3.writeFile(expected);
|
|
50352
|
+
await file3.datasync();
|
|
50238
50353
|
} finally {
|
|
50239
|
-
await
|
|
50354
|
+
await file3.close();
|
|
50240
50355
|
}
|
|
50241
50356
|
fresh = true;
|
|
50242
50357
|
}
|
|
50243
50358
|
const service2 = await AgentFabricService.open(
|
|
50244
|
-
|
|
50359
|
+
path27.join(stateDirectory, ".local-commander", "fabric"),
|
|
50245
50360
|
controllerId,
|
|
50246
50361
|
{ deviceId: enrollment.deviceId.toLowerCase(), enrollmentEvidenceRef: "enrollment-" + tenantId },
|
|
50247
50362
|
fresh
|
|
50248
50363
|
);
|
|
50249
50364
|
const purpose = "native-fabric:" + tenantId + ":" + controllerId;
|
|
50250
|
-
const credentialFile = (workerId) =>
|
|
50365
|
+
const credentialFile = (workerId) => path27.join(service2.directory, external_exports.string().uuid().parse(workerId) + ".capability");
|
|
50251
50366
|
const decode4 = (value) => {
|
|
50252
50367
|
const credential = Credential.parse(JSON.parse(box.open(Buffer.from(value, "base64"), purpose).toString("utf8")));
|
|
50253
50368
|
if (credential.controllerId !== controllerId) throw Error("FABRIC_WORKER_DENIED");
|
|
50254
50369
|
return credential;
|
|
50255
50370
|
};
|
|
50256
50371
|
async function capability(workerId) {
|
|
50257
|
-
const
|
|
50372
|
+
const file3 = credentialFile(workerId), info = await lstat13(file3);
|
|
50258
50373
|
if (!info.isFile() || info.isSymbolicLink() || info.size > 4096) throw Error("FABRIC_CREDENTIAL_UNKNOWN");
|
|
50259
|
-
const encoded = await
|
|
50374
|
+
const encoded = await readFile11(file3, "utf8");
|
|
50260
50375
|
if (decode4(encoded).workerId !== workerId) throw Error("FABRIC_WORKER_DENIED");
|
|
50261
50376
|
return encoded;
|
|
50262
50377
|
}
|
|
@@ -50289,12 +50404,12 @@ async function openNativeFabric(stateDirectory, enrollment, box, initialize = tr
|
|
|
50289
50404
|
} else {
|
|
50290
50405
|
const credential = await service2.identities.issue();
|
|
50291
50406
|
const encoded = box.seal(Buffer.from(JSON.stringify({ ...credential, workerId: worker.workerId, controllerId })), purpose).toString("base64");
|
|
50292
|
-
const
|
|
50407
|
+
const file3 = await open11(credentialFile(worker.workerId), "wx", 384);
|
|
50293
50408
|
try {
|
|
50294
|
-
await
|
|
50295
|
-
await
|
|
50409
|
+
await file3.writeFile(encoded);
|
|
50410
|
+
await file3.datasync();
|
|
50296
50411
|
} finally {
|
|
50297
|
-
await
|
|
50412
|
+
await file3.close();
|
|
50298
50413
|
}
|
|
50299
50414
|
await service2.mailbox.bindRuntime(worker.workerId, credential);
|
|
50300
50415
|
}
|
|
@@ -50348,7 +50463,7 @@ async function readFabricRequest(input2 = process.stdin) {
|
|
|
50348
50463
|
|
|
50349
50464
|
// agent/src/supervisor-liveness.ts
|
|
50350
50465
|
import { spawn as spawn6 } from "node:child_process";
|
|
50351
|
-
import
|
|
50466
|
+
import path28 from "node:path";
|
|
50352
50467
|
import { setTimeout as delay3 } from "node:timers/promises";
|
|
50353
50468
|
var ROW = /^"([^"]+)","(\d{1,10})"/;
|
|
50354
50469
|
function parseTasklist(output2, image) {
|
|
@@ -50363,7 +50478,7 @@ function parseTasklist(output2, image) {
|
|
|
50363
50478
|
}
|
|
50364
50479
|
function listProcesses(image, timeoutMs2 = 5e3) {
|
|
50365
50480
|
if (process.platform !== "win32" || !/^[A-Za-z0-9._-]{1,64}\.exe$/i.test(image)) return Promise.resolve(null);
|
|
50366
|
-
const tasklist =
|
|
50481
|
+
const tasklist = path28.join(process.env.SystemRoot || "C:\\Windows", "System32", "tasklist.exe");
|
|
50367
50482
|
return new Promise((resolve) => {
|
|
50368
50483
|
let output2 = "", settled = false;
|
|
50369
50484
|
const finish = (value) => {
|
|
@@ -50392,8 +50507,8 @@ function listProcesses(image, timeoutMs2 = 5e3) {
|
|
|
50392
50507
|
}
|
|
50393
50508
|
function supervisorLiveness(helperPath, options = {}) {
|
|
50394
50509
|
if (process.platform === "linux" && !options.list) return linuxSupervisorLiveness;
|
|
50395
|
-
if (process.platform === "darwin" && !options.list) return (pids, _linux, darwin) => darwinSupervisorLiveness(
|
|
50396
|
-
const image =
|
|
50510
|
+
if (process.platform === "darwin" && !options.list) return (pids, _linux, darwin) => darwinSupervisorLiveness(path28.join(path28.dirname(helperPath), "posix-host"), pids, darwin);
|
|
50511
|
+
const image = path28.basename(helperPath), waitMs = options.waitMs ?? 1e4, pollMs = options.pollMs ?? 500, list = options.list ?? listProcesses;
|
|
50397
50512
|
return async (pids) => {
|
|
50398
50513
|
const deadline = Date.now() + waitMs;
|
|
50399
50514
|
for (; ; ) {
|
|
@@ -50408,17 +50523,17 @@ function supervisorLiveness(helperPath, options = {}) {
|
|
|
50408
50523
|
|
|
50409
50524
|
// agent/src/content-audit.ts
|
|
50410
50525
|
import { createReadStream } from "node:fs";
|
|
50411
|
-
import { appendFile, lstat as
|
|
50412
|
-
import
|
|
50526
|
+
import { appendFile, lstat as lstat14, mkdir as mkdir14, open as open12, readdir as readdir6, readFile as readFile12, rename as rename9, rm as rm10, writeFile as writeFile5 } from "node:fs/promises";
|
|
50527
|
+
import path29 from "node:path";
|
|
50413
50528
|
import { performance as performance3 } from "node:perf_hooks";
|
|
50414
50529
|
import { createInterface as createInterface2 } from "node:readline";
|
|
50415
50530
|
import { randomBytes as randomBytes10 } from "node:crypto";
|
|
50416
50531
|
|
|
50417
50532
|
// src/audit-crypto.ts
|
|
50418
50533
|
import { createCipheriv as createCipheriv3, createDecipheriv as createDecipheriv3, createHash as createHash20, randomBytes as randomBytes9 } from "node:crypto";
|
|
50419
|
-
import { promisify as
|
|
50534
|
+
import { promisify as promisify4 } from "node:util";
|
|
50420
50535
|
import { gunzipSync, gzip, gzipSync } from "node:zlib";
|
|
50421
|
-
var gzipAsync =
|
|
50536
|
+
var gzipAsync = promisify4(gzip);
|
|
50422
50537
|
var AUDIT_ENCRYPTION_ALGORITHM = "A256GCM";
|
|
50423
50538
|
var AUDIT_COMPRESSION = "gzip";
|
|
50424
50539
|
var AUDIT_RECOVERY_KEY_PREFIX = "lca1_";
|
|
@@ -50578,11 +50693,11 @@ var FILE = /^(full|metrics)-(\d{4}-\d{2}-\d{2})\.jsonl$/;
|
|
|
50578
50693
|
var PAUSED_FILE = "paused.json";
|
|
50579
50694
|
var DAY_MS = 864e5;
|
|
50580
50695
|
function contentAuditDirectory(stateDir) {
|
|
50581
|
-
return
|
|
50696
|
+
return path29.join(path29.dirname(path29.resolve(stateDir)), "Audit");
|
|
50582
50697
|
}
|
|
50583
50698
|
async function plainDirectory(dir) {
|
|
50584
|
-
await
|
|
50585
|
-
const info = await
|
|
50699
|
+
await mkdir14(dir, { recursive: true, mode: 448 });
|
|
50700
|
+
const info = await lstat14(dir);
|
|
50586
50701
|
if (info.isSymbolicLink() || !info.isDirectory()) throw Error("AUDIT_DIRECTORY_INVALID");
|
|
50587
50702
|
}
|
|
50588
50703
|
async function auditFiles(dir) {
|
|
@@ -50597,18 +50712,18 @@ async function auditFiles(dir) {
|
|
|
50597
50712
|
for (const name2 of names) {
|
|
50598
50713
|
const match = FILE.exec(name2);
|
|
50599
50714
|
if (!match) continue;
|
|
50600
|
-
const info = await
|
|
50715
|
+
const info = await lstat14(path29.join(dir, name2));
|
|
50601
50716
|
if (info.isFile()) files.push({ name: name2, kind: match[1], day: match[2], bytes: info.size });
|
|
50602
50717
|
}
|
|
50603
50718
|
return files.sort((a, b) => a.name.localeCompare(b.name));
|
|
50604
50719
|
}
|
|
50605
|
-
async function writeJsonAtomic(
|
|
50606
|
-
const temp = `${
|
|
50720
|
+
async function writeJsonAtomic(file3, value) {
|
|
50721
|
+
const temp = `${file3}.${randomBytes10(6).toString("hex")}.tmp`;
|
|
50607
50722
|
try {
|
|
50608
|
-
await
|
|
50609
|
-
await
|
|
50723
|
+
await writeFile5(temp, JSON.stringify(value) + "\n", { flag: "wx", mode: 384 });
|
|
50724
|
+
await rename9(temp, file3);
|
|
50610
50725
|
} finally {
|
|
50611
|
-
await
|
|
50726
|
+
await rm10(temp, { force: true }).catch(() => {
|
|
50612
50727
|
});
|
|
50613
50728
|
}
|
|
50614
50729
|
}
|
|
@@ -50635,7 +50750,7 @@ var ContentAudit = class _ContentAudit {
|
|
|
50635
50750
|
skipped = 0;
|
|
50636
50751
|
closed = false;
|
|
50637
50752
|
static async open(options) {
|
|
50638
|
-
const dir =
|
|
50753
|
+
const dir = path29.resolve(options.directory);
|
|
50639
50754
|
await plainDirectory(dir);
|
|
50640
50755
|
const audit = new _ContentAudit(
|
|
50641
50756
|
dir,
|
|
@@ -50644,7 +50759,7 @@ var ContentAudit = class _ContentAudit {
|
|
|
50644
50759
|
{ retentionDays: options.retentionDays ?? AUDIT_RETENTION_DAYS, maxBytes: options.maxBytes ?? AUDIT_MAX_BYTES },
|
|
50645
50760
|
options.now ?? (() => /* @__PURE__ */ new Date())
|
|
50646
50761
|
);
|
|
50647
|
-
await
|
|
50762
|
+
await rm10(path29.join(dir, PAUSED_FILE), { force: true });
|
|
50648
50763
|
await audit.rollover(audit.now());
|
|
50649
50764
|
if (audit.usedBytes >= audit.limits.maxBytes) await audit.pause("QUOTA_EXCEEDED");
|
|
50650
50765
|
return audit;
|
|
@@ -50714,8 +50829,8 @@ var ContentAudit = class _ContentAudit {
|
|
|
50714
50829
|
await this.pause("QUOTA_EXCEEDED");
|
|
50715
50830
|
return;
|
|
50716
50831
|
}
|
|
50717
|
-
await appendFile(
|
|
50718
|
-
await appendFile(
|
|
50832
|
+
await appendFile(path29.join(this.dir, `full-${day}.jsonl`), line, { mode: 384 });
|
|
50833
|
+
await appendFile(path29.join(this.dir, `metrics-${day}.jsonl`), metrics, { mode: 384 });
|
|
50719
50834
|
this.usedBytes += bytes3;
|
|
50720
50835
|
}
|
|
50721
50836
|
/** Daily retention runs on the first write of a new day; no timer or background scan. */
|
|
@@ -50723,16 +50838,16 @@ var ContentAudit = class _ContentAudit {
|
|
|
50723
50838
|
this.day = at.toISOString().slice(0, 10);
|
|
50724
50839
|
const cutoff = new Date(at.getTime() - this.limits.retentionDays * DAY_MS).toISOString().slice(0, 10);
|
|
50725
50840
|
let used = 0;
|
|
50726
|
-
for (const
|
|
50727
|
-
if (
|
|
50728
|
-
else used +=
|
|
50841
|
+
for (const file3 of await auditFiles(this.dir)) {
|
|
50842
|
+
if (file3.day <= cutoff) await rm10(path29.join(this.dir, file3.name), { force: true });
|
|
50843
|
+
else used += file3.bytes;
|
|
50729
50844
|
}
|
|
50730
50845
|
this.usedBytes = used;
|
|
50731
50846
|
}
|
|
50732
50847
|
async pause(reason) {
|
|
50733
50848
|
if (this.paused) return;
|
|
50734
50849
|
this.paused = reason;
|
|
50735
|
-
await writeJsonAtomic(
|
|
50850
|
+
await writeJsonAtomic(path29.join(this.dir, PAUSED_FILE), { reason, at: this.now().toISOString() });
|
|
50736
50851
|
}
|
|
50737
50852
|
};
|
|
50738
50853
|
function percentiles(values) {
|
|
@@ -50741,8 +50856,8 @@ function percentiles(values) {
|
|
|
50741
50856
|
const at = (fraction) => sorted[Math.min(sorted.length - 1, Math.ceil(fraction * sorted.length) - 1)];
|
|
50742
50857
|
return { p50: at(0.5), p95: at(0.95), max: sorted[sorted.length - 1] };
|
|
50743
50858
|
}
|
|
50744
|
-
async function* jsonLines(
|
|
50745
|
-
const lines = createInterface2({ input: createReadStream(
|
|
50859
|
+
async function* jsonLines(file3) {
|
|
50860
|
+
const lines = createInterface2({ input: createReadStream(file3, { encoding: "utf8" }), crlfDelay: Infinity });
|
|
50746
50861
|
for await (const line of lines) {
|
|
50747
50862
|
if (!line.trim()) continue;
|
|
50748
50863
|
try {
|
|
@@ -50754,17 +50869,17 @@ async function* jsonLines(file2) {
|
|
|
50754
50869
|
}
|
|
50755
50870
|
var count2 = (value) => typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : 0;
|
|
50756
50871
|
async function summarizeContentAudit(directory, key) {
|
|
50757
|
-
const dir =
|
|
50872
|
+
const dir = path29.resolve(directory);
|
|
50758
50873
|
const files = await auditFiles(dir);
|
|
50759
50874
|
const days = /* @__PURE__ */ new Map();
|
|
50760
50875
|
const sizes = [];
|
|
50761
50876
|
const timings = [];
|
|
50762
|
-
for (const
|
|
50763
|
-
for await (const line of jsonLines(
|
|
50764
|
-
let day = days.get(
|
|
50877
|
+
for (const file3 of files.filter((f) => f.kind === "metrics")) {
|
|
50878
|
+
for await (const line of jsonLines(path29.join(dir, file3.name))) {
|
|
50879
|
+
let day = days.get(file3.day);
|
|
50765
50880
|
if (!day) {
|
|
50766
|
-
day = { day:
|
|
50767
|
-
days.set(
|
|
50881
|
+
day = { day: file3.day, records: 0, failed: 0, rawBytes: 0, sanitizedBytes: 0, compressedBytes: 0, envelopeBytes: 0 };
|
|
50882
|
+
days.set(file3.day, day);
|
|
50768
50883
|
}
|
|
50769
50884
|
day.records += 1;
|
|
50770
50885
|
if (line.resultCode !== "SUCCESS") day.failed += 1;
|
|
@@ -50780,7 +50895,7 @@ async function summarizeContentAudit(directory, key) {
|
|
|
50780
50895
|
}
|
|
50781
50896
|
let paused = null;
|
|
50782
50897
|
try {
|
|
50783
|
-
const value = JSON.parse(await
|
|
50898
|
+
const value = JSON.parse(await readFile12(path29.join(dir, PAUSED_FILE), "utf8"));
|
|
50784
50899
|
if (typeof value.reason === "string" && typeof value.at === "string") paused = { reason: value.reason.slice(0, 40), at: value.at.slice(0, 40) };
|
|
50785
50900
|
} catch {
|
|
50786
50901
|
}
|
|
@@ -50788,7 +50903,7 @@ async function summarizeContentAudit(directory, key) {
|
|
|
50788
50903
|
const newest = files.filter((f) => f.kind === "full").at(-1);
|
|
50789
50904
|
if (key && newest) {
|
|
50790
50905
|
const tail = [];
|
|
50791
|
-
for await (const line of jsonLines(
|
|
50906
|
+
for await (const line of jsonLines(path29.join(dir, newest.name))) {
|
|
50792
50907
|
tail.push(line);
|
|
50793
50908
|
if (tail.length > 5) tail.shift();
|
|
50794
50909
|
}
|
|
@@ -50806,7 +50921,7 @@ async function summarizeContentAudit(directory, key) {
|
|
|
50806
50921
|
const rawBytes = total("rawBytes"), envelopeBytes = total("envelopeBytes");
|
|
50807
50922
|
return {
|
|
50808
50923
|
directory: dir,
|
|
50809
|
-
fileBytes: files.reduce((sum,
|
|
50924
|
+
fileBytes: files.reduce((sum, file3) => sum + file3.bytes, 0),
|
|
50810
50925
|
paused,
|
|
50811
50926
|
records: total("records"),
|
|
50812
50927
|
rawBytes,
|
|
@@ -50822,10 +50937,10 @@ async function summarizeContentAudit(directory, key) {
|
|
|
50822
50937
|
};
|
|
50823
50938
|
}
|
|
50824
50939
|
async function restoreContentAudit(input2, output2, key) {
|
|
50825
|
-
const handle = await open12(
|
|
50940
|
+
const handle = await open12(path29.resolve(output2), "wx", 384);
|
|
50826
50941
|
let records = 0, failed = 0;
|
|
50827
50942
|
try {
|
|
50828
|
-
for await (const line of jsonLines(
|
|
50943
|
+
for await (const line of jsonLines(path29.resolve(input2))) {
|
|
50829
50944
|
try {
|
|
50830
50945
|
await handle.appendFile(JSON.stringify(decryptAuditRecord(line, key)) + "\n");
|
|
50831
50946
|
records += 1;
|
|
@@ -50840,9 +50955,10 @@ async function restoreContentAudit(input2, output2, key) {
|
|
|
50840
50955
|
}
|
|
50841
50956
|
|
|
50842
50957
|
// agent/src/main.ts
|
|
50843
|
-
var AGENT_VERSION2 = true ? "0.3.
|
|
50958
|
+
var AGENT_VERSION2 = true ? "0.3.51" : "0.3.2";
|
|
50844
50959
|
var NETWORK_PUBLIC_KEY = true ? "-----BEGIN PUBLIC KEY-----\nMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAvmu+81vWtJBQDZNHcAIW\nzCSxpG+R9RBsum2df5mP2cOW+wyUDTpnYquFge1qgI5YYTF96j0xCyXL8B9FeNWs\n939opWNmv53j+CQlS4cEIQhBbZSCu0eC4icsVEzBhvf68MB+E668SOtZBcVTEnyh\n96PTcupxS10rQJBWDinbKBXRC2gvGYeu01rWa/nsrndy4vAYP5t3yQtdOC8e8mr0\n+2Mg2Qhiq+KiTCtDd+L9oXvoLqqJYbzUIveNGha25AWxF1Weblp0gOM87hell5gV\nK7q4ZLUq/wBRGYNmQRdLyV7/WRE1FFPSW21/SBZQ/5aU4UqJU/MjMcrJUrnRKngz\nYKmo0czkxS3N7Q2KVxomgR1AQSuQFKMrboZYKjShADp9RIYUxzs7cYg51Of5PnHh\n6Ax+VevDGfzjMD+yHuyxYZqCtX4OwgolJxz63UQbzKlris+8xb5lLYTbIuz90Pss\nn6HK/F5May25c6oMmS3nh/NsiZopL1OvdtWKTt1L4WlRAgMBAAE=\n-----END PUBLIC KEY-----\n" : "";
|
|
50845
50960
|
var AI_CONNECTION_SHIPPED = false;
|
|
50961
|
+
var QUARANTINE_RETRY_MS = 6e4;
|
|
50846
50962
|
function processAlive(pid) {
|
|
50847
50963
|
if (!Number.isInteger(pid) || pid <= 0) return false;
|
|
50848
50964
|
try {
|
|
@@ -50853,11 +50969,11 @@ function processAlive(pid) {
|
|
|
50853
50969
|
}
|
|
50854
50970
|
}
|
|
50855
50971
|
async function claimAgentProcess(stateDir, runtimeDir, version2) {
|
|
50856
|
-
await
|
|
50857
|
-
const
|
|
50972
|
+
await mkdir15(stateDir, { recursive: true });
|
|
50973
|
+
const file3 = path30.join(stateDir, "agent-process.json");
|
|
50858
50974
|
for (let attempt = 0; attempt < 2; attempt += 1) {
|
|
50859
50975
|
try {
|
|
50860
|
-
const handle = await open13(
|
|
50976
|
+
const handle = await open13(file3, "wx", 384);
|
|
50861
50977
|
try {
|
|
50862
50978
|
await handle.writeFile(JSON.stringify({ pid: process.pid, runtimeDir, version: version2, startedAt: (/* @__PURE__ */ new Date()).toISOString() }) + "\n", "utf8");
|
|
50863
50979
|
} finally {
|
|
@@ -50865,8 +50981,8 @@ async function claimAgentProcess(stateDir, runtimeDir, version2) {
|
|
|
50865
50981
|
}
|
|
50866
50982
|
return async () => {
|
|
50867
50983
|
try {
|
|
50868
|
-
const current2 = JSON.parse(await
|
|
50869
|
-
if (current2.pid === process.pid) await
|
|
50984
|
+
const current2 = JSON.parse(await readFile13(file3, "utf8"));
|
|
50985
|
+
if (current2.pid === process.pid) await rm11(file3, { force: true });
|
|
50870
50986
|
} catch {
|
|
50871
50987
|
}
|
|
50872
50988
|
};
|
|
@@ -50874,12 +50990,12 @@ async function claimAgentProcess(stateDir, runtimeDir, version2) {
|
|
|
50874
50990
|
if (!error62 || typeof error62 !== "object" || !("code" in error62) || error62.code !== "EEXIST") throw error62;
|
|
50875
50991
|
let stale = true;
|
|
50876
50992
|
try {
|
|
50877
|
-
const current2 = JSON.parse(await
|
|
50993
|
+
const current2 = JSON.parse(await readFile13(file3, "utf8"));
|
|
50878
50994
|
stale = typeof current2.pid !== "number" || !processAlive(current2.pid);
|
|
50879
50995
|
} catch {
|
|
50880
50996
|
}
|
|
50881
50997
|
if (!stale) throw Error("AGENT_ALREADY_RUNNING");
|
|
50882
|
-
await
|
|
50998
|
+
await rm11(file3, { force: true });
|
|
50883
50999
|
}
|
|
50884
51000
|
}
|
|
50885
51001
|
throw Error("AGENT_ALREADY_RUNNING");
|
|
@@ -50988,7 +51104,7 @@ async function runAgent(options) {
|
|
|
50988
51104
|
try {
|
|
50989
51105
|
while (!options.signal.aborted) {
|
|
50990
51106
|
computerName = await readComputerName();
|
|
50991
|
-
let ready;
|
|
51107
|
+
let ready, wait = delay4;
|
|
50992
51108
|
const readyPromise = new Promise((resolve) => {
|
|
50993
51109
|
ready = resolve;
|
|
50994
51110
|
});
|
|
@@ -51002,6 +51118,7 @@ async function runAgent(options) {
|
|
|
51002
51118
|
safeSlots: runtime.status().safeSlots,
|
|
51003
51119
|
status: () => runtime.status(),
|
|
51004
51120
|
onIncidentAck: (ack) => incidentProducer.ack(ack),
|
|
51121
|
+
onFullLogChoice: options.onFullLogChoice,
|
|
51005
51122
|
// After bridge.connected, like requests: the journal has recorded this connection first.
|
|
51006
51123
|
onHeldLeases: (bindings) => {
|
|
51007
51124
|
void readyPromise.then(() => bridge.heldLeases(bindings)).catch(() => {
|
|
@@ -51077,6 +51194,8 @@ async function runAgent(options) {
|
|
|
51077
51194
|
ready();
|
|
51078
51195
|
monitor(() => options.monitor?.connectionFailed(error62));
|
|
51079
51196
|
if (error62 instanceof RelayClientError && ["RELAY_CONNECT_FAILED", "RELAY_CONNECT_CLOSED", "RELAY_CONNECT_TIMEOUT", "RELAY_HANDSHAKE_TIMEOUT"].includes(error62.code)) {
|
|
51197
|
+
} else if (error62 instanceof RelayClientError && error62.code === "RELAY_DEVICE_QUARANTINED") {
|
|
51198
|
+
wait = Math.max(delay4, QUARANTINE_RETRY_MS);
|
|
51080
51199
|
} else throw error62;
|
|
51081
51200
|
} finally {
|
|
51082
51201
|
connectivity?.close();
|
|
@@ -51090,11 +51209,15 @@ async function runAgent(options) {
|
|
|
51090
51209
|
incidentProducer.disconnected();
|
|
51091
51210
|
if (!options.signal.aborted) supervisor.observe({ kind: "disconnected" });
|
|
51092
51211
|
monitor(() => options.monitor?.setConnection("disconnected"));
|
|
51212
|
+
try {
|
|
51213
|
+
options.onFullLogChoice?.(null);
|
|
51214
|
+
} catch {
|
|
51215
|
+
}
|
|
51093
51216
|
connection?.close("agent_disconnect");
|
|
51094
51217
|
await bridge.disconnected();
|
|
51095
51218
|
connection = null;
|
|
51096
51219
|
}
|
|
51097
|
-
if (!options.signal.aborted) await aborted2(options.signal,
|
|
51220
|
+
if (!options.signal.aborted) await aborted2(options.signal, wait);
|
|
51098
51221
|
}
|
|
51099
51222
|
} finally {
|
|
51100
51223
|
try {
|
|
@@ -51130,10 +51253,10 @@ async function openContentAudit(store, stateDir) {
|
|
|
51130
51253
|
async function main() {
|
|
51131
51254
|
if (!["win32", "linux", "darwin"].includes(process.platform)) throw Error("PLATFORM_UNSUPPORTED");
|
|
51132
51255
|
const appData = process.env.LC_AGENT_DATA_DIR ?? (process.platform === "win32" ? process.env.LOCALAPPDATA : posixDataHome());
|
|
51133
|
-
if (!appData || !
|
|
51134
|
-
const stateDir = process.env.LC_AGENT_STATE_DIR ??
|
|
51135
|
-
const binaryDir =
|
|
51136
|
-
const ownerBridgePath = process.env.LC_OWNER_BRIDGE ??
|
|
51256
|
+
if (!appData || !path30.isAbsolute(appData)) throw Error("APP_DATA_MISSING");
|
|
51257
|
+
const stateDir = process.env.LC_AGENT_STATE_DIR ?? path30.join(appData, "LocalCommander", "Agent");
|
|
51258
|
+
const binaryDir = path30.dirname(process.platform === "win32" ? process.execPath : await realpath10(process.execPath));
|
|
51259
|
+
const ownerBridgePath = process.env.LC_OWNER_BRIDGE ?? path30.join(binaryDir, process.platform === "win32" ? "OwnerBridge.exe" : "owner-store");
|
|
51137
51260
|
const store = await WindowsPrivateStore.open(stateDir, ownerBridgePath);
|
|
51138
51261
|
const command = process.argv[2] ?? "run";
|
|
51139
51262
|
if (process.platform !== "win32" && (command.startsWith("guard-") || command.startsWith("network-"))) throw Error("FEATURE_PLATFORM_UNSUPPORTED");
|
|
@@ -51152,7 +51275,8 @@ async function main() {
|
|
|
51152
51275
|
process.stdout.write(JSON.stringify({
|
|
51153
51276
|
paired: !!identity?.enrollment,
|
|
51154
51277
|
accountEmail: identity?.enrollment?.accountEmail ?? null,
|
|
51155
|
-
deviceId: identity?.enrollment?.deviceId ?? null
|
|
51278
|
+
deviceId: identity?.enrollment?.deviceId ?? null,
|
|
51279
|
+
fullLogs: await readFullLogNotice(stateDir, identity?.enrollment)
|
|
51156
51280
|
}) + "\n");
|
|
51157
51281
|
return;
|
|
51158
51282
|
}
|
|
@@ -51228,7 +51352,7 @@ async function main() {
|
|
|
51228
51352
|
}
|
|
51229
51353
|
if (command === "efficiency-report") {
|
|
51230
51354
|
if (args.length) throw Error("AGENT_COMMAND_INVALID");
|
|
51231
|
-
const ledger = await OptimizationLedger.open(
|
|
51355
|
+
const ledger = await OptimizationLedger.open(path30.join(stateDir, "optimization"));
|
|
51232
51356
|
try {
|
|
51233
51357
|
process.stdout.write(JSON.stringify(await ledger.report(), null, 2) + "\n");
|
|
51234
51358
|
} finally {
|
|
@@ -51238,7 +51362,7 @@ async function main() {
|
|
|
51238
51362
|
}
|
|
51239
51363
|
if (command === "guard-configure") {
|
|
51240
51364
|
if (args.length !== 1) throw Error("AGENT_COMMAND_INVALID");
|
|
51241
|
-
const filename = await (await import("node:fs/promises")).realpath(
|
|
51365
|
+
const filename = await (await import("node:fs/promises")).realpath(path30.resolve(args[0]));
|
|
51242
51366
|
const input2 = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(await readWindowsFile(ownerBridgePath, filename, 2e5)));
|
|
51243
51367
|
if (!input2 || typeof input2 !== "object" || Object.keys(input2).sort().join(",") !== "compact,settings") throw Error("GUARD_CONFIGURATION_INVALID");
|
|
51244
51368
|
await store.configureGuard(input2.settings, input2.compact);
|
|
@@ -51257,7 +51381,7 @@ async function main() {
|
|
|
51257
51381
|
}
|
|
51258
51382
|
if (command === "guard-evidence") {
|
|
51259
51383
|
if (args.length) throw Error("AGENT_COMMAND_INVALID");
|
|
51260
|
-
const journal = await NativeJournal.open(
|
|
51384
|
+
const journal = await NativeJournal.open(path30.join(stateDir, "journal"), new SecretBox({ "1": await store.loadDataKey() }));
|
|
51261
51385
|
try {
|
|
51262
51386
|
process.stdout.write(JSON.stringify(await journal.guardEvidence()) + "\n");
|
|
51263
51387
|
} finally {
|
|
@@ -51269,7 +51393,7 @@ async function main() {
|
|
|
51269
51393
|
if (args.length !== (command === "guard-export" ? 0 : 1)) throw Error("AGENT_COMMAND_INVALID");
|
|
51270
51394
|
const identity = await store.load();
|
|
51271
51395
|
if (!identity?.enrollment) throw Error("ENROLLMENT_MISSING");
|
|
51272
|
-
const journal = await NativeJournal.open(
|
|
51396
|
+
const journal = await NativeJournal.open(path30.join(stateDir, "journal"), new SecretBox({ "1": await store.loadDataKey() }));
|
|
51273
51397
|
try {
|
|
51274
51398
|
const { tenantId, deviceId } = identity.enrollment;
|
|
51275
51399
|
const records = (await journal.guardEvidence()).filter((record2) => record2.tenantId === tenantId && record2.deviceId === deviceId);
|
|
@@ -51347,33 +51471,39 @@ async function main() {
|
|
|
51347
51471
|
if (args.length) throw Error("AGENT_COMMAND_INVALID");
|
|
51348
51472
|
if (!(await store.load())?.enrollment) throw Error("ENROLLMENT_MISSING");
|
|
51349
51473
|
const releaseProcess = await claimAgentProcess(stateDir, binaryDir, AGENT_VERSION2);
|
|
51350
|
-
const monitor = new ProductionMonitor(
|
|
51474
|
+
const monitor = new ProductionMonitor(path30.join(appData, "LocalCommander", "Monitor"), stateDir, AGENT_VERSION2);
|
|
51351
51475
|
const publishMonitor = () => monitor.flush().catch(() => {
|
|
51352
51476
|
process.stderr.write("MONITOR_WRITE_FAILED\n");
|
|
51353
51477
|
});
|
|
51354
51478
|
await publishMonitor();
|
|
51355
51479
|
try {
|
|
51356
51480
|
const journal = await NativeJournal.open(
|
|
51357
|
-
|
|
51481
|
+
path30.join(stateDir, "journal"),
|
|
51358
51482
|
new SecretBox({ "1": await store.loadDataKey() }),
|
|
51359
|
-
process.platform === "win32" ? {} : { lockHelper:
|
|
51483
|
+
process.platform === "win32" ? {} : { lockHelper: path30.join(binaryDir, "posix-host") }
|
|
51360
51484
|
);
|
|
51361
51485
|
const ledgerLoss = () => {
|
|
51362
51486
|
process.stderr.write("OPTIMIZATION_TELEMETRY_INCOMPLETE\n");
|
|
51363
51487
|
};
|
|
51364
51488
|
const efficiencyLedger = await new OptionalWork(ledgerLoss, 1e3, 1).run(
|
|
51365
|
-
() => OptimizationLedger.open(
|
|
51489
|
+
() => OptimizationLedger.open(path30.join(stateDir, "optimization")),
|
|
51366
51490
|
void 0,
|
|
51367
51491
|
(ledger) => ledger.close()
|
|
51368
51492
|
);
|
|
51369
51493
|
try {
|
|
51370
|
-
const helperPath = process.env.LC_JOB_HOST ??
|
|
51494
|
+
const helperPath = process.env.LC_JOB_HOST ?? path30.join(binaryDir, process.platform === "win32" ? "JobHost.exe" : "job-host.mjs");
|
|
51371
51495
|
const tools = new NativeTools({ stateDirectory: stateDir, helperPath, ownerBridgePath, programs: await store.loadPrograms() });
|
|
51372
51496
|
const stop = new AbortController();
|
|
51373
51497
|
process.once("SIGINT", () => stop.abort());
|
|
51374
51498
|
process.once("SIGTERM", () => stop.abort());
|
|
51375
51499
|
const guard = await NativeGuard.open(store, journal);
|
|
51376
51500
|
const enrollment = (await store.load()).enrollment;
|
|
51501
|
+
const fullLogNotice = new FullLogNotice(stateDir, enrollment);
|
|
51502
|
+
const onFullLogChoice = (enabled) => {
|
|
51503
|
+
void fullLogNotice.update(enabled).catch(() => {
|
|
51504
|
+
});
|
|
51505
|
+
};
|
|
51506
|
+
onFullLogChoice(null);
|
|
51377
51507
|
const fabric = await openNativeFabric(stateDir, enrollment, new SecretBox({ "1": await store.loadDataKey() })).catch(() => {
|
|
51378
51508
|
process.stderr.write("FABRIC_STARTUP_FAILED\n");
|
|
51379
51509
|
return void 0;
|
|
@@ -51402,6 +51532,7 @@ async function main() {
|
|
|
51402
51532
|
guard,
|
|
51403
51533
|
efficiencyLedger,
|
|
51404
51534
|
monitor,
|
|
51535
|
+
onFullLogChoice,
|
|
51405
51536
|
localDirect: { key: localDirectKey(await store.loadDataKey()), directory: localDirectDirectory(appData) },
|
|
51406
51537
|
supervisorLiveness: supervisorLiveness(helperPath),
|
|
51407
51538
|
...proxyMode ? { proxyMode: { providers: proxyMode.providers, publicKeyPem: NETWORK_PUBLIC_KEY, endpoint: proxyEndpoint, onState: onProxyState } } : {},
|
|
@@ -51438,7 +51569,7 @@ async function main() {
|
|
|
51438
51569
|
await releaseProcess();
|
|
51439
51570
|
}
|
|
51440
51571
|
}
|
|
51441
|
-
var entrypoint = process.argv[1] && (process.platform === "win32" ?
|
|
51572
|
+
var entrypoint = process.argv[1] && (process.platform === "win32" ? path30.resolve(process.argv[1]) : await realpath10(process.argv[1]).catch(() => null));
|
|
51442
51573
|
if (entrypoint === fileURLToPath(import.meta.url)) {
|
|
51443
51574
|
void main().catch((error62) => {
|
|
51444
51575
|
const code = error62 instanceof Error && /^[A-Z0-9_]{1,64}$/.test(error62.message) ? error62.message : "AGENT_START_FAILED";
|