local-commander-agent 0.3.7 → 0.3.9-issue11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -11
- package/bin/localcommander.mjs +30 -6
- package/bin/monitor.mjs +196 -17
- package/package.json +1 -1
- package/runtime/JobHost.exe +0 -0
- package/runtime/LocalCommanderAgent.exe +0 -0
- package/runtime/OwnerBridge.exe +0 -0
- package/runtime/agent.mjs +2116 -267
package/runtime/agent.mjs
CHANGED
|
@@ -2278,7 +2278,7 @@ var require_websocket = __commonJS({
|
|
|
2278
2278
|
var http = __require("http");
|
|
2279
2279
|
var net = __require("net");
|
|
2280
2280
|
var tls = __require("tls");
|
|
2281
|
-
var { randomBytes:
|
|
2281
|
+
var { randomBytes: randomBytes5, createHash: createHash13 } = __require("crypto");
|
|
2282
2282
|
var { Duplex, Readable } = __require("stream");
|
|
2283
2283
|
var { URL: URL2 } = __require("url");
|
|
2284
2284
|
var PerMessageDeflate2 = require_permessage_deflate();
|
|
@@ -2829,7 +2829,7 @@ var require_websocket = __commonJS({
|
|
|
2829
2829
|
}
|
|
2830
2830
|
}
|
|
2831
2831
|
const defaultPort = isSecure ? 443 : 80;
|
|
2832
|
-
const key =
|
|
2832
|
+
const key = randomBytes5(16).toString("base64");
|
|
2833
2833
|
const request = isSecure ? https.request : http.request;
|
|
2834
2834
|
const protocolSet = /* @__PURE__ */ new Set();
|
|
2835
2835
|
let perMessageDeflate;
|
|
@@ -2959,8 +2959,8 @@ var require_websocket = __commonJS({
|
|
|
2959
2959
|
abortHandshake(websocket, socket, "Invalid Upgrade header");
|
|
2960
2960
|
return;
|
|
2961
2961
|
}
|
|
2962
|
-
const
|
|
2963
|
-
if (res.headers["sec-websocket-accept"] !==
|
|
2962
|
+
const digest5 = createHash13("sha1").update(key + GUID).digest("base64");
|
|
2963
|
+
if (res.headers["sec-websocket-accept"] !== digest5) {
|
|
2964
2964
|
abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
|
|
2965
2965
|
return;
|
|
2966
2966
|
}
|
|
@@ -3240,7 +3240,7 @@ var require_stream = __commonJS({
|
|
|
3240
3240
|
};
|
|
3241
3241
|
duplex._final = function(callback) {
|
|
3242
3242
|
if (ws.readyState === ws.CONNECTING) {
|
|
3243
|
-
ws.once("open", function
|
|
3243
|
+
ws.once("open", function open10() {
|
|
3244
3244
|
duplex._final(callback);
|
|
3245
3245
|
});
|
|
3246
3246
|
return;
|
|
@@ -3261,7 +3261,7 @@ var require_stream = __commonJS({
|
|
|
3261
3261
|
};
|
|
3262
3262
|
duplex._write = function(chunk, encoding, callback) {
|
|
3263
3263
|
if (ws.readyState === ws.CONNECTING) {
|
|
3264
|
-
ws.once("open", function
|
|
3264
|
+
ws.once("open", function open10() {
|
|
3265
3265
|
duplex._write(chunk, encoding, callback);
|
|
3266
3266
|
});
|
|
3267
3267
|
return;
|
|
@@ -3328,7 +3328,7 @@ var require_websocket_server = __commonJS({
|
|
|
3328
3328
|
var EventEmitter = __require("events");
|
|
3329
3329
|
var http = __require("http");
|
|
3330
3330
|
var { Duplex } = __require("stream");
|
|
3331
|
-
var { createHash:
|
|
3331
|
+
var { createHash: createHash13 } = __require("crypto");
|
|
3332
3332
|
var extension2 = require_extension();
|
|
3333
3333
|
var PerMessageDeflate2 = require_permessage_deflate();
|
|
3334
3334
|
var subprotocol2 = require_subprotocol();
|
|
@@ -3635,12 +3635,12 @@ var require_websocket_server = __commonJS({
|
|
|
3635
3635
|
);
|
|
3636
3636
|
}
|
|
3637
3637
|
if (this._state > RUNNING) return abortHandshake(socket, 503);
|
|
3638
|
-
const
|
|
3638
|
+
const digest5 = createHash13("sha1").update(key + GUID).digest("base64");
|
|
3639
3639
|
const headers = [
|
|
3640
3640
|
"HTTP/1.1 101 Switching Protocols",
|
|
3641
3641
|
"Upgrade: websocket",
|
|
3642
3642
|
"Connection: Upgrade",
|
|
3643
|
-
`Sec-WebSocket-Accept: ${
|
|
3643
|
+
`Sec-WebSocket-Accept: ${digest5}`
|
|
3644
3644
|
];
|
|
3645
3645
|
const ws = new this.options.WebSocket(null, void 0, this.options);
|
|
3646
3646
|
if (protocols.size) {
|
|
@@ -3723,9 +3723,9 @@ var require_websocket_server = __commonJS({
|
|
|
3723
3723
|
});
|
|
3724
3724
|
|
|
3725
3725
|
// agent/src/main.ts
|
|
3726
|
-
import
|
|
3727
|
-
import
|
|
3728
|
-
import { mkdir as
|
|
3726
|
+
import path17 from "node:path";
|
|
3727
|
+
import os4 from "node:os";
|
|
3728
|
+
import { mkdir as mkdir9, open as open9, readFile as readFile6, rm as rm5 } from "node:fs/promises";
|
|
3729
3729
|
import { fileURLToPath } from "node:url";
|
|
3730
3730
|
|
|
3731
3731
|
// packages/operations/src/crypto.ts
|
|
@@ -3733,9 +3733,9 @@ import { createCipheriv, createDecipheriv, createHmac, randomBytes, timingSafeEq
|
|
|
3733
3733
|
var SecretBox = class {
|
|
3734
3734
|
constructor(keys, activeId = 1) {
|
|
3735
3735
|
this.activeId = activeId;
|
|
3736
|
-
for (const [
|
|
3737
|
-
const n = Number(
|
|
3738
|
-
if (!Number.isInteger(n) || n < 1 || n > 255 || String(n) !==
|
|
3736
|
+
for (const [id2, value] of Object.entries(keys)) {
|
|
3737
|
+
const n = Number(id2);
|
|
3738
|
+
if (!Number.isInteger(n) || n < 1 || n > 255 || String(n) !== id2 || !Buffer.isBuffer(value) || value.length !== 32) throw Error("INVALID_DATA_KEY");
|
|
3739
3739
|
this.keys.set(n, Buffer.from(value));
|
|
3740
3740
|
}
|
|
3741
3741
|
if (!this.keys.has(activeId)) throw Error("ACTIVE_DATA_KEY_MISSING");
|
|
@@ -4674,18 +4674,18 @@ function mergeDefs(...defs) {
|
|
|
4674
4674
|
function cloneDef(schema) {
|
|
4675
4675
|
return mergeDefs(schema._zod.def);
|
|
4676
4676
|
}
|
|
4677
|
-
function getElementAtPath(obj,
|
|
4678
|
-
if (!
|
|
4677
|
+
function getElementAtPath(obj, path18) {
|
|
4678
|
+
if (!path18)
|
|
4679
4679
|
return obj;
|
|
4680
|
-
return
|
|
4680
|
+
return path18.reduce((acc, key) => acc?.[key], obj);
|
|
4681
4681
|
}
|
|
4682
4682
|
function promiseAllObject(promisesObj) {
|
|
4683
4683
|
const keys = Object.keys(promisesObj);
|
|
4684
4684
|
const promises = keys.map((key) => promisesObj[key]);
|
|
4685
|
-
return Promise.all(promises).then((
|
|
4685
|
+
return Promise.all(promises).then((results2) => {
|
|
4686
4686
|
const resolvedObj = {};
|
|
4687
4687
|
for (let i = 0; i < keys.length; i++) {
|
|
4688
|
-
resolvedObj[keys[i]] =
|
|
4688
|
+
resolvedObj[keys[i]] = results2[i];
|
|
4689
4689
|
}
|
|
4690
4690
|
return resolvedObj;
|
|
4691
4691
|
});
|
|
@@ -5017,11 +5017,11 @@ function explicitlyAborted(x, startIndex = 0) {
|
|
|
5017
5017
|
}
|
|
5018
5018
|
return false;
|
|
5019
5019
|
}
|
|
5020
|
-
function prefixIssues(
|
|
5020
|
+
function prefixIssues(path18, issues) {
|
|
5021
5021
|
return issues.map((iss) => {
|
|
5022
5022
|
var _a3;
|
|
5023
5023
|
(_a3 = iss).path ?? (_a3.path = []);
|
|
5024
|
-
iss.path.unshift(
|
|
5024
|
+
iss.path.unshift(path18);
|
|
5025
5025
|
return iss;
|
|
5026
5026
|
});
|
|
5027
5027
|
}
|
|
@@ -5471,16 +5471,16 @@ function flattenError(error62, mapper = (issue2) => issue2.message) {
|
|
|
5471
5471
|
}
|
|
5472
5472
|
function formatError(error62, mapper = (issue2) => issue2.message) {
|
|
5473
5473
|
const fieldErrors = { _errors: [] };
|
|
5474
|
-
const processError = (error63,
|
|
5474
|
+
const processError = (error63, path18 = []) => {
|
|
5475
5475
|
for (const issue2 of error63.issues) {
|
|
5476
5476
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
5477
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
5477
|
+
issue2.errors.map((issues) => processError({ issues }, [...path18, ...issue2.path]));
|
|
5478
5478
|
} else if (issue2.code === "invalid_key") {
|
|
5479
|
-
processError({ issues: issue2.issues }, [...
|
|
5479
|
+
processError({ issues: issue2.issues }, [...path18, ...issue2.path]);
|
|
5480
5480
|
} else if (issue2.code === "invalid_element") {
|
|
5481
|
-
processError({ issues: issue2.issues }, [...
|
|
5481
|
+
processError({ issues: issue2.issues }, [...path18, ...issue2.path]);
|
|
5482
5482
|
} else {
|
|
5483
|
-
const fullpath = [...
|
|
5483
|
+
const fullpath = [...path18, ...issue2.path];
|
|
5484
5484
|
if (fullpath.length === 0) {
|
|
5485
5485
|
fieldErrors._errors.push(mapper(issue2));
|
|
5486
5486
|
} else {
|
|
@@ -5519,17 +5519,17 @@ function formatError(error62, mapper = (issue2) => issue2.message) {
|
|
|
5519
5519
|
}
|
|
5520
5520
|
function treeifyError(error62, mapper = (issue2) => issue2.message) {
|
|
5521
5521
|
const result2 = { errors: [] };
|
|
5522
|
-
const processError = (error63,
|
|
5522
|
+
const processError = (error63, path18 = []) => {
|
|
5523
5523
|
var _a3;
|
|
5524
5524
|
for (const issue2 of error63.issues) {
|
|
5525
5525
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
5526
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
5526
|
+
issue2.errors.map((issues) => processError({ issues }, [...path18, ...issue2.path]));
|
|
5527
5527
|
} else if (issue2.code === "invalid_key") {
|
|
5528
|
-
processError({ issues: issue2.issues }, [...
|
|
5528
|
+
processError({ issues: issue2.issues }, [...path18, ...issue2.path]);
|
|
5529
5529
|
} else if (issue2.code === "invalid_element") {
|
|
5530
|
-
processError({ issues: issue2.issues }, [...
|
|
5530
|
+
processError({ issues: issue2.issues }, [...path18, ...issue2.path]);
|
|
5531
5531
|
} else {
|
|
5532
|
-
const fullpath = [...
|
|
5532
|
+
const fullpath = [...path18, ...issue2.path];
|
|
5533
5533
|
if (fullpath.length === 0) {
|
|
5534
5534
|
result2.errors.push(mapper(issue2));
|
|
5535
5535
|
continue;
|
|
@@ -5568,8 +5568,8 @@ function treeifyError(error62, mapper = (issue2) => issue2.message) {
|
|
|
5568
5568
|
}
|
|
5569
5569
|
function toDotPath(_path) {
|
|
5570
5570
|
const segs = [];
|
|
5571
|
-
const
|
|
5572
|
-
for (const seg of
|
|
5571
|
+
const path18 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
5572
|
+
for (const seg of path18) {
|
|
5573
5573
|
if (typeof seg === "number")
|
|
5574
5574
|
segs.push(`[${seg}]`);
|
|
5575
5575
|
else if (typeof seg === "symbol")
|
|
@@ -7437,15 +7437,15 @@ var $ZodObjectJIT = /* @__PURE__ */ $constructor("$ZodObjectJIT", (inst, def) =>
|
|
|
7437
7437
|
const syms = normalized.symbolKeys;
|
|
7438
7438
|
const doc = new Doc(["payload", "ctx"], { shape, inst, memo: memo2, syms });
|
|
7439
7439
|
const parseStr = (k) => `shape[${k}]._zod.run({ value: input[${k}], issues: [] }, ctx)`;
|
|
7440
|
-
const prefixStr = (
|
|
7441
|
-
let ${
|
|
7442
|
-
for (let i = 0; i < ${
|
|
7443
|
-
const iss = ${
|
|
7440
|
+
const prefixStr = (id2, k) => `
|
|
7441
|
+
let ${id2}_ab = false;
|
|
7442
|
+
for (let i = 0; i < ${id2}.issues.length; i++) {
|
|
7443
|
+
const iss = ${id2}.issues[i];
|
|
7444
7444
|
iss.path = iss.path ? [${k}, ...iss.path] : [${k}];
|
|
7445
7445
|
payload.issues.push(iss);
|
|
7446
|
-
if (iss.continue !== true) ${
|
|
7446
|
+
if (iss.continue !== true) ${id2}_ab = true;
|
|
7447
7447
|
}
|
|
7448
|
-
if (${
|
|
7448
|
+
if (${id2}_ab && ctx && ctx.abortEarly) {
|
|
7449
7449
|
payload.value = newResult;
|
|
7450
7450
|
return payload;
|
|
7451
7451
|
}`;
|
|
@@ -7459,34 +7459,34 @@ var $ZodObjectJIT = /* @__PURE__ */ $constructor("$ZodObjectJIT", (inst, def) =>
|
|
|
7459
7459
|
for (const key of normalized.allKeys) {
|
|
7460
7460
|
if (key === "__proto__")
|
|
7461
7461
|
continue;
|
|
7462
|
-
const
|
|
7462
|
+
const id2 = ids[key];
|
|
7463
7463
|
const k = typeof key === "symbol" ? `syms[${syms.indexOf(key)}]` : esc(key);
|
|
7464
7464
|
const isPresent = `${k} in input`;
|
|
7465
7465
|
const schema = shape[key];
|
|
7466
7466
|
const optin = schema?._zod?.optin;
|
|
7467
7467
|
const isOptionalIn = optin !== void 0;
|
|
7468
7468
|
const isOptionalOut = schema?._zod?.optout === "optional";
|
|
7469
|
-
doc.write(`const ${
|
|
7469
|
+
doc.write(`const ${id2} = ${parseStr(k)};`);
|
|
7470
7470
|
if (isOptionalIn && isOptionalOut) {
|
|
7471
|
-
const assign = optin === "optional" ? `${
|
|
7471
|
+
const assign = optin === "optional" ? `${id2}_present` : `${id2}.value !== undefined || ${id2}_present`;
|
|
7472
7472
|
doc.write(`
|
|
7473
|
-
const ${
|
|
7474
|
-
if (!${
|
|
7475
|
-
if (${
|
|
7473
|
+
const ${id2}_present = ${isPresent};
|
|
7474
|
+
if (!${id2}.issues.length || ${id2}_present) {
|
|
7475
|
+
if (${id2}.issues.length) {${prefixStr(id2, k)}
|
|
7476
7476
|
}
|
|
7477
7477
|
|
|
7478
7478
|
if (${assign}) {
|
|
7479
|
-
newResult[${k}] = ${
|
|
7479
|
+
newResult[${k}] = ${id2}.value;
|
|
7480
7480
|
}
|
|
7481
7481
|
}
|
|
7482
7482
|
|
|
7483
7483
|
`);
|
|
7484
7484
|
} else if (!isOptionalIn) {
|
|
7485
7485
|
doc.write(`
|
|
7486
|
-
const ${
|
|
7487
|
-
if (${
|
|
7486
|
+
const ${id2}_present = ${isPresent};
|
|
7487
|
+
if (${id2}.issues.length) {${prefixStr(id2, k)}
|
|
7488
7488
|
}
|
|
7489
|
-
if (!${
|
|
7489
|
+
if (!${id2}_present && !${id2}.issues.length) {
|
|
7490
7490
|
payload.issues.push({
|
|
7491
7491
|
code: "invalid_type",
|
|
7492
7492
|
expected: "nonoptional",
|
|
@@ -7499,22 +7499,22 @@ var $ZodObjectJIT = /* @__PURE__ */ $constructor("$ZodObjectJIT", (inst, def) =>
|
|
|
7499
7499
|
}
|
|
7500
7500
|
}
|
|
7501
7501
|
|
|
7502
|
-
if (${
|
|
7503
|
-
newResult[${k}] = ${
|
|
7502
|
+
if (${id2}_present) {
|
|
7503
|
+
newResult[${k}] = ${id2}.value;
|
|
7504
7504
|
}
|
|
7505
7505
|
|
|
7506
7506
|
`);
|
|
7507
7507
|
} else {
|
|
7508
7508
|
doc.write(`
|
|
7509
|
-
if (${
|
|
7509
|
+
if (${id2}.issues.length) {${prefixStr(id2, k)}
|
|
7510
7510
|
}
|
|
7511
7511
|
`);
|
|
7512
7512
|
if (optin === "defaulted") {
|
|
7513
|
-
doc.write(`newResult[${k}] = ${
|
|
7513
|
+
doc.write(`newResult[${k}] = ${id2}.value;`);
|
|
7514
7514
|
} else {
|
|
7515
7515
|
doc.write(`
|
|
7516
|
-
if (${
|
|
7517
|
-
newResult[${k}] = ${
|
|
7516
|
+
if (${id2}.value !== undefined || ${isPresent}) {
|
|
7517
|
+
newResult[${k}] = ${id2}.value;
|
|
7518
7518
|
}
|
|
7519
7519
|
`);
|
|
7520
7520
|
}
|
|
@@ -7554,14 +7554,14 @@ var $ZodObjectJIT = /* @__PURE__ */ $constructor("$ZodObjectJIT", (inst, def) =>
|
|
|
7554
7554
|
return superParse(payload, ctx);
|
|
7555
7555
|
};
|
|
7556
7556
|
});
|
|
7557
|
-
function handleUnionResults(
|
|
7558
|
-
for (const result2 of
|
|
7557
|
+
function handleUnionResults(results2, final, inst, ctx) {
|
|
7558
|
+
for (const result2 of results2) {
|
|
7559
7559
|
if (result2.issues.length === 0) {
|
|
7560
7560
|
final.value = result2.value;
|
|
7561
7561
|
return final;
|
|
7562
7562
|
}
|
|
7563
7563
|
}
|
|
7564
|
-
const nonaborted =
|
|
7564
|
+
const nonaborted = results2.filter((r) => !aborted(r));
|
|
7565
7565
|
if (nonaborted.length === 1) {
|
|
7566
7566
|
final.value = nonaborted[0].value;
|
|
7567
7567
|
return nonaborted[0];
|
|
@@ -7570,7 +7570,7 @@ function handleUnionResults(results, final, inst, ctx) {
|
|
|
7570
7570
|
code: "invalid_union",
|
|
7571
7571
|
input: final.value,
|
|
7572
7572
|
inst,
|
|
7573
|
-
errors:
|
|
7573
|
+
errors: results2.map((result2) => result2.issues.map((iss) => finalizeIssue(iss, ctx, config())))
|
|
7574
7574
|
});
|
|
7575
7575
|
return final;
|
|
7576
7576
|
}
|
|
@@ -7597,36 +7597,36 @@ var $ZodUnion = /* @__PURE__ */ $constructor("$ZodUnion", (inst, def) => {
|
|
|
7597
7597
|
return first(payload, ctx);
|
|
7598
7598
|
}
|
|
7599
7599
|
let async = false;
|
|
7600
|
-
const
|
|
7600
|
+
const results2 = [];
|
|
7601
7601
|
for (const option of def.options) {
|
|
7602
7602
|
const result2 = option._zod.run({
|
|
7603
7603
|
value: payload.value,
|
|
7604
7604
|
issues: []
|
|
7605
7605
|
}, ctx);
|
|
7606
7606
|
if (result2 instanceof Promise) {
|
|
7607
|
-
|
|
7607
|
+
results2.push(result2);
|
|
7608
7608
|
async = true;
|
|
7609
7609
|
} else {
|
|
7610
7610
|
if (result2.issues.length === 0)
|
|
7611
7611
|
return result2;
|
|
7612
|
-
|
|
7612
|
+
results2.push(result2);
|
|
7613
7613
|
}
|
|
7614
7614
|
}
|
|
7615
7615
|
if (!async)
|
|
7616
|
-
return handleUnionResults(results, payload, inst, ctx);
|
|
7617
|
-
return Promise.all(results).then((results2) => {
|
|
7618
7616
|
return handleUnionResults(results2, payload, inst, ctx);
|
|
7617
|
+
return Promise.all(results2).then((results3) => {
|
|
7618
|
+
return handleUnionResults(results3, payload, inst, ctx);
|
|
7619
7619
|
});
|
|
7620
7620
|
};
|
|
7621
7621
|
});
|
|
7622
|
-
function handleExclusiveUnionResults(
|
|
7622
|
+
function handleExclusiveUnionResults(results2, final, inst, ctx) {
|
|
7623
7623
|
const matches2 = [];
|
|
7624
|
-
for (let i = 0; i <
|
|
7625
|
-
if (
|
|
7624
|
+
for (let i = 0; i < results2.length; i++) {
|
|
7625
|
+
if (results2[i].issues.length === 0)
|
|
7626
7626
|
matches2.push(i);
|
|
7627
7627
|
}
|
|
7628
7628
|
if (matches2.length === 1) {
|
|
7629
|
-
final.value =
|
|
7629
|
+
final.value = results2[matches2[0]].value;
|
|
7630
7630
|
return final;
|
|
7631
7631
|
}
|
|
7632
7632
|
if (matches2.length === 0) {
|
|
@@ -7634,7 +7634,7 @@ function handleExclusiveUnionResults(results, final, inst, ctx) {
|
|
|
7634
7634
|
code: "invalid_union",
|
|
7635
7635
|
input: final.value,
|
|
7636
7636
|
inst,
|
|
7637
|
-
errors:
|
|
7637
|
+
errors: results2.map((result2) => result2.issues.map((iss) => finalizeIssue(iss, ctx, config())))
|
|
7638
7638
|
});
|
|
7639
7639
|
} else {
|
|
7640
7640
|
final.issues.push({
|
|
@@ -7657,23 +7657,23 @@ var $ZodXor = /* @__PURE__ */ $constructor("$ZodXor", (inst, def) => {
|
|
|
7657
7657
|
return first(payload, ctx);
|
|
7658
7658
|
}
|
|
7659
7659
|
let async = false;
|
|
7660
|
-
const
|
|
7660
|
+
const results2 = [];
|
|
7661
7661
|
for (const option of def.options) {
|
|
7662
7662
|
const result2 = option._zod.run({
|
|
7663
7663
|
value: payload.value,
|
|
7664
7664
|
issues: []
|
|
7665
7665
|
}, ctx);
|
|
7666
7666
|
if (result2 instanceof Promise) {
|
|
7667
|
-
|
|
7667
|
+
results2.push(result2);
|
|
7668
7668
|
async = true;
|
|
7669
7669
|
} else {
|
|
7670
|
-
|
|
7670
|
+
results2.push(result2);
|
|
7671
7671
|
}
|
|
7672
7672
|
}
|
|
7673
7673
|
if (!async)
|
|
7674
|
-
return handleExclusiveUnionResults(results, payload, inst, ctx);
|
|
7675
|
-
return Promise.all(results).then((results2) => {
|
|
7676
7674
|
return handleExclusiveUnionResults(results2, payload, inst, ctx);
|
|
7675
|
+
return Promise.all(results2).then((results3) => {
|
|
7676
|
+
return handleExclusiveUnionResults(results3, payload, inst, ctx);
|
|
7677
7677
|
});
|
|
7678
7678
|
};
|
|
7679
7679
|
});
|
|
@@ -19532,26 +19532,26 @@ function extractDefs(ctx, schema) {
|
|
|
19532
19532
|
return;
|
|
19533
19533
|
const idToSchema = /* @__PURE__ */ new Map();
|
|
19534
19534
|
for (const entry of ctx.seen.entries()) {
|
|
19535
|
-
const
|
|
19536
|
-
if (
|
|
19537
|
-
const existing = idToSchema.get(
|
|
19535
|
+
const id2 = ctx.metadataRegistry.get(entry[0])?.id;
|
|
19536
|
+
if (id2) {
|
|
19537
|
+
const existing = idToSchema.get(id2);
|
|
19538
19538
|
if (existing && existing !== entry[0]) {
|
|
19539
|
-
throw new Error(`Duplicate schema id "${
|
|
19539
|
+
throw new Error(`Duplicate schema id "${id2}" detected during JSON Schema conversion. Two different schemas cannot share the same id when converted together.`);
|
|
19540
19540
|
}
|
|
19541
|
-
idToSchema.set(
|
|
19541
|
+
idToSchema.set(id2, entry[0]);
|
|
19542
19542
|
}
|
|
19543
19543
|
}
|
|
19544
19544
|
const makeURI = (entry) => {
|
|
19545
19545
|
const defsSegment = ctx.target === "draft-2020-12" ? "$defs" : "definitions";
|
|
19546
19546
|
if (ctx.external) {
|
|
19547
19547
|
const externalId = ctx.external.registry.get(entry[0])?.id;
|
|
19548
|
-
const uriGenerator = ctx.external.uri ?? ((
|
|
19548
|
+
const uriGenerator = ctx.external.uri ?? ((id3) => id3);
|
|
19549
19549
|
if (externalId) {
|
|
19550
19550
|
return { ref: uriGenerator(externalId) };
|
|
19551
19551
|
}
|
|
19552
|
-
const
|
|
19553
|
-
entry[1].defId =
|
|
19554
|
-
return { defId:
|
|
19552
|
+
const id2 = entry[1].defId ?? entry[1].schema.id ?? `schema${ctx.counter++}`;
|
|
19553
|
+
entry[1].defId = id2;
|
|
19554
|
+
return { defId: id2, ref: `${uriGenerator("__shared")}#/${defsSegment}/${encodeJSONPointerSegment(id2)}` };
|
|
19555
19555
|
}
|
|
19556
19556
|
const uriPrefix = `#`;
|
|
19557
19557
|
const defUriPrefix = `${uriPrefix}/${defsSegment}/`;
|
|
@@ -19599,8 +19599,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
19599
19599
|
continue;
|
|
19600
19600
|
}
|
|
19601
19601
|
}
|
|
19602
|
-
const
|
|
19603
|
-
if (
|
|
19602
|
+
const id2 = ctx.metadataRegistry.get(entry[0])?.id;
|
|
19603
|
+
if (id2) {
|
|
19604
19604
|
extractToDef(entry);
|
|
19605
19605
|
continue;
|
|
19606
19606
|
}
|
|
@@ -19833,10 +19833,10 @@ function finalize(ctx, schema) {
|
|
|
19833
19833
|
} else {
|
|
19834
19834
|
}
|
|
19835
19835
|
if (ctx.external?.uri) {
|
|
19836
|
-
const
|
|
19837
|
-
if (!
|
|
19836
|
+
const id2 = ctx.external.registry.get(schema)?.id;
|
|
19837
|
+
if (!id2)
|
|
19838
19838
|
throw new Error("Schema is missing an `id` property");
|
|
19839
|
-
result2.$id = ctx.external.uri(
|
|
19839
|
+
result2.$id = ctx.external.uri(id2);
|
|
19840
19840
|
}
|
|
19841
19841
|
assignProps(result2, root.defId ? root.schema : root.def ?? root.schema);
|
|
19842
19842
|
const rootMetaId = ctx.metadataRegistry.get(schema)?.id;
|
|
@@ -20442,7 +20442,7 @@ function stringifyKeyNames(bySchema, json2, visited) {
|
|
|
20442
20442
|
const values = json2.enum ?? (json2.const !== void 0 ? [json2.const] : void 0);
|
|
20443
20443
|
if (!numericType && !values?.some((v) => typeof v === "number"))
|
|
20444
20444
|
return json2;
|
|
20445
|
-
const { minimum, maximum, exclusiveMinimum, exclusiveMaximum, multipleOf, format, id, ...rest } = json2;
|
|
20445
|
+
const { minimum, maximum, exclusiveMinimum, exclusiveMaximum, multipleOf, format, id: id2, ...rest } = json2;
|
|
20446
20446
|
if (rest.enum)
|
|
20447
20447
|
rest.enum = rest.enum.map((v) => typeof v === "number" ? String(v) : v);
|
|
20448
20448
|
else if (typeof rest.const === "number")
|
|
@@ -22671,13 +22671,13 @@ function resolveRef(ref, ctx) {
|
|
|
22671
22671
|
if (!ref.startsWith("#")) {
|
|
22672
22672
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
22673
22673
|
}
|
|
22674
|
-
const
|
|
22675
|
-
if (
|
|
22674
|
+
const path18 = ref.slice(1).split("/").filter(Boolean);
|
|
22675
|
+
if (path18.length === 0) {
|
|
22676
22676
|
return ctx.rootSchema;
|
|
22677
22677
|
}
|
|
22678
22678
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
22679
|
-
if (
|
|
22680
|
-
const key =
|
|
22679
|
+
if (path18[0] === defsKey) {
|
|
22680
|
+
const key = path18[1] === void 0 ? void 0 : decodeJSONPointerSegment(path18[1]);
|
|
22681
22681
|
if (!key || !ctx.defs[key]) {
|
|
22682
22682
|
throw new Error(`Reference not found: ${ref}`);
|
|
22683
22683
|
}
|
|
@@ -24438,6 +24438,9 @@ var hash2 = external_exports.string().regex(/^[a-f0-9]{64}$/);
|
|
|
24438
24438
|
var epoch = external_exports.string().regex(/^[1-9]\d{0,18}$/).refine((v) => BigInt(v) <= 9223372036854775807n);
|
|
24439
24439
|
var text = external_exports.string().max(32767).refine((v) => !v.includes("\0"));
|
|
24440
24440
|
var timestamp = external_exports.iso.datetime({ offset: false });
|
|
24441
|
+
var EfficiencyProfileSchema = external_exports.object({
|
|
24442
|
+
model: external_exports.string().regex(/^[A-Za-z0-9][A-Za-z0-9._:/+-]{0,79}$/)
|
|
24443
|
+
}).strict();
|
|
24441
24444
|
var path = text.min(1);
|
|
24442
24445
|
var ToolCallSchema = external_exports.discriminatedUnion("name", [
|
|
24443
24446
|
external_exports.object({ name: external_exports.literal("fs_list"), args: external_exports.object({ path: path.optional(), recursive: external_exports.boolean().default(false), maxDepth: external_exports.number().int().min(0).max(8).default(3), maxEntries: external_exports.number().int().min(1).max(1e3).default(200) }).strict() }).strict(),
|
|
@@ -24448,7 +24451,7 @@ var ToolCallSchema = external_exports.discriminatedUnion("name", [
|
|
|
24448
24451
|
external_exports.object({ name: external_exports.literal("git_status"), args: external_exports.object({ path: path.optional() }).strict() }).strict(),
|
|
24449
24452
|
external_exports.object({ name: external_exports.literal("git_diff"), args: external_exports.object({ path: path.optional(), file: path.optional(), staged: external_exports.boolean().default(false) }).strict() }).strict(),
|
|
24450
24453
|
external_exports.object({ name: external_exports.literal("git_log"), args: external_exports.object({ path: path.optional(), limit: external_exports.number().int().min(1).max(50).default(15) }).strict() }).strict(),
|
|
24451
|
-
external_exports.object({ name: external_exports.literal("project_snapshot"), args: external_exports.object({ path: path.optional() }).strict() }).strict(),
|
|
24454
|
+
external_exports.object({ name: external_exports.literal("project_snapshot"), args: external_exports.object({ path: path.optional(), startup: external_exports.boolean().optional(), taskId: external_exports.string().regex(/^[A-Za-z0-9_-]{1,100}$/).optional() }).strict() }).strict(),
|
|
24452
24455
|
external_exports.object({ name: external_exports.literal("command_run"), args: external_exports.object({ command: external_exports.string().min(1).max(260).refine((v) => !/[\r\n\0]/.test(v)), args: external_exports.array(external_exports.string().max(8192).refine((v) => !v.includes("\0"))).max(128).default([]), cwd: path.optional(), timeoutMs: external_exports.number().int().min(100).max(864e5).default(6e4) }).strict() }).strict(),
|
|
24453
24456
|
external_exports.object({ name: external_exports.literal("localhost_request"), args: external_exports.object({ url: external_exports.string().url().max(2048), method: external_exports.enum(["GET", "HEAD", "POST", "PUT", "PATCH", "DELETE"]).default("GET"), headers: external_exports.record(external_exports.string().max(128), external_exports.string().max(2048)).optional(), body: external_exports.string().max(6e4).optional() }).strict() }).strict()
|
|
24454
24457
|
]);
|
|
@@ -24483,6 +24486,8 @@ var ClientFrameSchema = external_exports.discriminatedUnion("type", [
|
|
|
24483
24486
|
]);
|
|
24484
24487
|
var TerminalMetricsSchema = external_exports.object({ stdoutBytes: external_exports.number().int().min(0).max(4194304), stderrBytes: external_exports.number().int().min(0).max(4194304), outputTruncated: external_exports.boolean() }).strict();
|
|
24485
24488
|
var TERMINAL_METRICS_CAPABILITY = "terminalMetrics";
|
|
24489
|
+
var NATIVE_CAPACITY_CAPABILITY = "nativeCapacity";
|
|
24490
|
+
var NativeCapacitySchema = external_exports.object({ type: external_exports.literal("nativeCapacity"), protocolVersion: external_exports.literal(1), connectionEpoch: epoch, safeSlots: external_exports.number().int().min(1).max(32), agentVersion: external_exports.string().regex(/^[A-Za-z0-9._+-]{1,64}$/) }).strict();
|
|
24486
24491
|
var TerminalEventSchema = external_exports.object({ type: external_exports.literal("executionResult"), protocolVersion: external_exports.literal(1), requestId: uuid8, tenantId: uuid8, deviceId: uuid8, connectionEpoch: epoch, binding: ExecutionBindingSchema, state: external_exports.enum(["finished", "failed", "cancelled", "unknown"]), resultCode: external_exports.string().regex(/^[A-Z0-9_]{1,40}$/), metrics: TerminalMetricsSchema.optional() }).strict();
|
|
24487
24492
|
var TerminalEventAckSchema = external_exports.object({ type: external_exports.literal("executionResultAck"), protocolVersion: external_exports.literal(1), requestId: uuid8, ok: external_exports.boolean() }).strict();
|
|
24488
24493
|
function canonicalJson(value) {
|
|
@@ -24621,9 +24626,9 @@ var GuardEvidenceRecordSchema = external_exports.object({
|
|
|
24621
24626
|
function verifyGuardEvidence(input2) {
|
|
24622
24627
|
const events = external_exports.array(GuardEventSchema).min(1).max(12).parse(input2);
|
|
24623
24628
|
let previous = "0".repeat(64);
|
|
24624
|
-
for (const { hash:
|
|
24625
|
-
if (record2.previousHash !== previous || guardHash(record2) !==
|
|
24626
|
-
previous =
|
|
24629
|
+
for (const { hash: digest5, ...record2 } of events) {
|
|
24630
|
+
if (record2.previousHash !== previous || guardHash(record2) !== digest5 || record2.event.content.mode !== "none") throw Error("GUARD_EVIDENCE_INVALID");
|
|
24631
|
+
previous = digest5;
|
|
24627
24632
|
}
|
|
24628
24633
|
return events;
|
|
24629
24634
|
}
|
|
@@ -24795,17 +24800,17 @@ var NativeJournal = class _NativeJournal {
|
|
|
24795
24800
|
});
|
|
24796
24801
|
return next;
|
|
24797
24802
|
}
|
|
24798
|
-
file(
|
|
24799
|
-
return path2.join(this.dir,
|
|
24803
|
+
file(id2) {
|
|
24804
|
+
return path2.join(this.dir, id2 + ".entry");
|
|
24800
24805
|
}
|
|
24801
|
-
need(
|
|
24802
|
-
if (!uuid11.test(
|
|
24803
|
-
const e = this.entries.get(
|
|
24806
|
+
need(id2) {
|
|
24807
|
+
if (!uuid11.test(id2)) throw failure2("JOURNAL_INPUT_INVALID");
|
|
24808
|
+
const e = this.entries.get(id2);
|
|
24804
24809
|
if (!e) throw failure2("EXECUTION_UNKNOWN");
|
|
24805
24810
|
return clone2(e);
|
|
24806
24811
|
}
|
|
24807
|
-
async readOwned(
|
|
24808
|
-
const filename = this.file(
|
|
24812
|
+
async readOwned(id2) {
|
|
24813
|
+
const filename = this.file(id2), stat = await lstat(filename);
|
|
24809
24814
|
if (!stat.isFile() || stat.isSymbolicLink() || stat.size > MAX_ENVELOPE) throw failure2("JOURNAL_CORRUPT");
|
|
24810
24815
|
const handle = await open2(filename, constants.O_RDONLY | (constants.O_NOFOLLOW ?? 0));
|
|
24811
24816
|
try {
|
|
@@ -24821,30 +24826,30 @@ var NativeJournal = class _NativeJournal {
|
|
|
24821
24826
|
if (names.length > this.options.maxEntries + 256) throw failure2("JOURNAL_CAPACITY_EXCEEDED");
|
|
24822
24827
|
for (const name2 of names) {
|
|
24823
24828
|
if (!name2.endsWith(".entry")) continue;
|
|
24824
|
-
const
|
|
24825
|
-
if (!uuid11.test(
|
|
24826
|
-
const envelope = await this.readOwned(
|
|
24829
|
+
const id2 = name2.slice(0, -6);
|
|
24830
|
+
if (!uuid11.test(id2)) throw failure2("JOURNAL_CORRUPT");
|
|
24831
|
+
const envelope = await this.readOwned(id2);
|
|
24827
24832
|
this.totalBytes += envelope.length;
|
|
24828
24833
|
if (this.totalBytes > this.options.maxBytes || this.entries.size >= this.options.maxEntries) throw failure2("JOURNAL_CAPACITY_EXCEEDED");
|
|
24829
24834
|
let entry;
|
|
24830
24835
|
try {
|
|
24831
|
-
entry = JSON.parse(this.box.open(envelope, "execution:" +
|
|
24836
|
+
entry = JSON.parse(this.box.open(envelope, "execution:" + id2).toString("utf8"));
|
|
24832
24837
|
const binding2 = Object.fromEntries(bindingKeys.map((k) => [k, entry[k]]));
|
|
24833
24838
|
validateInput(binding2);
|
|
24834
|
-
if (entry.executionId !==
|
|
24839
|
+
if (entry.executionId !== id2 || !states.has(entry.state) || !canonicalTime(entry.createdAt) || !canonicalTime(entry.updatedAt) || Date.parse(entry.updatedAt) < Date.parse(entry.createdAt)) throw Error();
|
|
24835
24840
|
if (entry.result) boundedResult(entry.result);
|
|
24836
24841
|
if (entry.resultCode !== void 0 && (typeof entry.resultCode !== "string" || !/^[A-Z0-9_]{1,40}$/.test(entry.resultCode))) throw Error();
|
|
24837
24842
|
if (entry.reportedAt !== void 0 && (!entry.resultCode || !canonicalTime(entry.reportedAt))) throw Error();
|
|
24838
24843
|
if (entry.guardEvents) {
|
|
24839
24844
|
verifyGuardEvidence(entry.guardEvents);
|
|
24840
|
-
if (entry.guardEvents.some((record2) => record2.event.requestId !==
|
|
24845
|
+
if (entry.guardEvents.some((record2) => record2.event.requestId !== id2)) throw Error();
|
|
24841
24846
|
}
|
|
24842
24847
|
} catch {
|
|
24843
24848
|
throw failure2("JOURNAL_CORRUPT");
|
|
24844
24849
|
}
|
|
24845
|
-
this.entries.set(
|
|
24846
|
-
this.sizes.set(
|
|
24847
|
-
this.digests.set(
|
|
24850
|
+
this.entries.set(id2, entry);
|
|
24851
|
+
this.sizes.set(id2, envelope.length);
|
|
24852
|
+
this.digests.set(id2, digest2(envelope));
|
|
24848
24853
|
}
|
|
24849
24854
|
}
|
|
24850
24855
|
async persist(entry) {
|
|
@@ -24909,9 +24914,9 @@ var NativeJournal = class _NativeJournal {
|
|
|
24909
24914
|
return { entry: clone2(entry), created: true };
|
|
24910
24915
|
});
|
|
24911
24916
|
}
|
|
24912
|
-
accept(
|
|
24917
|
+
accept(id2, payloadHash) {
|
|
24913
24918
|
return this.enqueue(async () => {
|
|
24914
|
-
const e = this.need(
|
|
24919
|
+
const e = this.need(id2);
|
|
24915
24920
|
if (e.payloadHash !== payloadHash) throw failure2("IDEMPOTENCY_CONFLICT");
|
|
24916
24921
|
if (e.state !== "prepared") throw failure2("EXECUTION_ALREADY_ACCEPTED");
|
|
24917
24922
|
if (Date.parse(e.deadlineAt) <= this.now().getTime()) throw failure2("JOURNAL_DEADLINE_EXPIRED");
|
|
@@ -24921,9 +24926,9 @@ var NativeJournal = class _NativeJournal {
|
|
|
24921
24926
|
return clone2(e);
|
|
24922
24927
|
});
|
|
24923
24928
|
}
|
|
24924
|
-
running(
|
|
24929
|
+
running(id2) {
|
|
24925
24930
|
return this.enqueue(async () => {
|
|
24926
|
-
const e = this.need(
|
|
24931
|
+
const e = this.need(id2);
|
|
24927
24932
|
if (e.state !== "accepted") throw failure2("JOURNAL_STATE_INVALID");
|
|
24928
24933
|
e.state = "running";
|
|
24929
24934
|
e.updatedAt = this.now().toISOString();
|
|
@@ -24931,11 +24936,11 @@ var NativeJournal = class _NativeJournal {
|
|
|
24931
24936
|
return clone2(e);
|
|
24932
24937
|
});
|
|
24933
24938
|
}
|
|
24934
|
-
finish(
|
|
24939
|
+
finish(id2, value, resultCode) {
|
|
24935
24940
|
const result2 = boundedResult(value);
|
|
24936
24941
|
if (resultCode !== void 0 && !/^[A-Z0-9_]{1,40}$/.test(resultCode)) throw failure2("JOURNAL_RESULT_INVALID");
|
|
24937
24942
|
return this.enqueue(async () => {
|
|
24938
|
-
const e = this.need(
|
|
24943
|
+
const e = this.need(id2);
|
|
24939
24944
|
if (terminal.has(e.state)) {
|
|
24940
24945
|
if (JSON.stringify(e.result) !== JSON.stringify(result2) || resultCode !== void 0 && e.resultCode !== resultCode) throw failure2("IDEMPOTENCY_CONFLICT");
|
|
24941
24946
|
return e;
|
|
@@ -24950,15 +24955,15 @@ var NativeJournal = class _NativeJournal {
|
|
|
24950
24955
|
return clone2(e);
|
|
24951
24956
|
});
|
|
24952
24957
|
}
|
|
24953
|
-
reject(
|
|
24954
|
-
return this.finishPrepared(
|
|
24958
|
+
reject(id2) {
|
|
24959
|
+
return this.finishPrepared(id2, "rejected");
|
|
24955
24960
|
}
|
|
24956
|
-
cancelPrepared(
|
|
24957
|
-
return this.finishPrepared(
|
|
24961
|
+
cancelPrepared(id2) {
|
|
24962
|
+
return this.finishPrepared(id2, "cancelled");
|
|
24958
24963
|
}
|
|
24959
|
-
finishPrepared(
|
|
24964
|
+
finishPrepared(id2, state) {
|
|
24960
24965
|
return this.enqueue(async () => {
|
|
24961
|
-
const e = this.need(
|
|
24966
|
+
const e = this.need(id2);
|
|
24962
24967
|
if (e.state === state) return e;
|
|
24963
24968
|
if (e.state !== "prepared") throw failure2("JOURNAL_STATE_INVALID");
|
|
24964
24969
|
e.state = state;
|
|
@@ -24967,18 +24972,18 @@ var NativeJournal = class _NativeJournal {
|
|
|
24967
24972
|
return clone2(e);
|
|
24968
24973
|
});
|
|
24969
24974
|
}
|
|
24970
|
-
get(
|
|
24975
|
+
get(id2) {
|
|
24971
24976
|
return this.enqueue(async () => {
|
|
24972
|
-
if (!uuid11.test(
|
|
24973
|
-
const e = this.entries.get(
|
|
24977
|
+
if (!uuid11.test(id2)) throw failure2("JOURNAL_INPUT_INVALID");
|
|
24978
|
+
const e = this.entries.get(id2);
|
|
24974
24979
|
return e ? clone2(e) : null;
|
|
24975
24980
|
});
|
|
24976
24981
|
}
|
|
24977
|
-
appendGuardEvidence(
|
|
24982
|
+
appendGuardEvidence(id2, input2) {
|
|
24978
24983
|
const snapshot2 = clone2(input2);
|
|
24979
24984
|
return this.enqueue(async () => {
|
|
24980
|
-
const entry = this.need(
|
|
24981
|
-
if (snapshot2.event.requestId !==
|
|
24985
|
+
const entry = this.need(id2);
|
|
24986
|
+
if (snapshot2.event.requestId !== id2) throw failure2("GUARD_EVIDENCE_INVALID");
|
|
24982
24987
|
entry.guardEvents = appendGuardEvent(entry.guardEvents ?? [], snapshot2);
|
|
24983
24988
|
entry.updatedAt = this.now().toISOString();
|
|
24984
24989
|
await this.persist(entry);
|
|
@@ -25009,9 +25014,9 @@ var NativeJournal = class _NativeJournal {
|
|
|
25009
25014
|
listUnreportedResults() {
|
|
25010
25015
|
return this.enqueue(async () => [...this.entries.values()].filter((e) => !e.reportedAt && e.resultCode && e.workspaceGrantId && e.policyVersion && ["finished", "failed", "cancelled", "unknown"].includes(e.state)).map(clone2));
|
|
25011
25016
|
}
|
|
25012
|
-
markReported(
|
|
25017
|
+
markReported(id2, resultCode) {
|
|
25013
25018
|
return this.enqueue(async () => {
|
|
25014
|
-
const e = this.need(
|
|
25019
|
+
const e = this.need(id2);
|
|
25015
25020
|
if (!e.resultCode || e.resultCode !== resultCode || !e.workspaceGrantId || !e.policyVersion || !["finished", "failed", "cancelled", "unknown"].includes(e.state)) throw failure2("JOURNAL_STATE_INVALID");
|
|
25016
25021
|
if (e.reportedAt) return;
|
|
25017
25022
|
e.reportedAt = this.now().toISOString();
|
|
@@ -25579,19 +25584,19 @@ function issueApproval(ledgerInput, context, authorityInput, now, expiresAt) {
|
|
|
25579
25584
|
}
|
|
25580
25585
|
function consumeApproval(ledgerInput, context, approvalId, now) {
|
|
25581
25586
|
try {
|
|
25582
|
-
const ledger = current(ledgerInput, now), bound = binding(ledger, context, now),
|
|
25583
|
-
const grant = ledger.grants.find((candidate) => candidate.approvalId ===
|
|
25587
|
+
const ledger = current(ledgerInput, now), bound = binding(ledger, context, now), id2 = uuid14.parse(approvalId);
|
|
25588
|
+
const grant = ledger.grants.find((candidate) => candidate.approvalId === id2);
|
|
25584
25589
|
if (!grant || grant.state !== "active" || grant.bindingHash !== bound.bindingHash || grant.uses === Number.MAX_SAFE_INTEGER || Date.parse(now) < Date.parse(grant.issuedAt) || grant.scope === "once" && (grant.requestId !== bound.request.requestId || grant.decisionId !== bound.decision.decisionId)) throw Error();
|
|
25585
25590
|
const consumed = { ...grant, uses: grant.uses + 1, state: grant.scope === "once" ? "consumed" : "active" };
|
|
25586
|
-
return { ledger: { ...ledger, grants: ledger.grants.map((candidate) => candidate.approvalId ===
|
|
25591
|
+
return { ledger: { ...ledger, grants: ledger.grants.map((candidate) => candidate.approvalId === id2 ? consumed : candidate) }, grant: consumed };
|
|
25587
25592
|
} catch {
|
|
25588
25593
|
throw Error("APPROVAL_INVALID");
|
|
25589
25594
|
}
|
|
25590
25595
|
}
|
|
25591
25596
|
function revokeApproval(ledgerInput, approvalId, now) {
|
|
25592
25597
|
try {
|
|
25593
|
-
const ledger = current(ledgerInput, now),
|
|
25594
|
-
return { ...ledger, grants: ledger.grants.map((grant) => grant.approvalId ===
|
|
25598
|
+
const ledger = current(ledgerInput, now), id2 = uuid14.parse(approvalId);
|
|
25599
|
+
return { ...ledger, grants: ledger.grants.map((grant) => grant.approvalId === id2 && grant.state === "active" ? { ...grant, state: "revoked" } : grant) };
|
|
25595
25600
|
} catch {
|
|
25596
25601
|
throw Error("APPROVAL_INVALID");
|
|
25597
25602
|
}
|
|
@@ -25686,7 +25691,7 @@ function validateState(value) {
|
|
|
25686
25691
|
const workspaces = value.workspaces ?? [];
|
|
25687
25692
|
const programs = value.programs ?? {};
|
|
25688
25693
|
const pendingWorkspaceRevokes = value.pendingWorkspaceRevokes ?? [];
|
|
25689
|
-
if (!Array.isArray(pendingWorkspaceRevokes) || pendingWorkspaceRevokes.length > 32 || pendingWorkspaceRevokes.some((
|
|
25694
|
+
if (!Array.isArray(pendingWorkspaceRevokes) || pendingWorkspaceRevokes.length > 32 || pendingWorkspaceRevokes.some((id2) => typeof id2 !== "string" || !UUID.test(id2) || id2 !== id2.toLowerCase()) || new Set(pendingWorkspaceRevokes).size !== pendingWorkspaceRevokes.length) throw fail("STATE_CORRUPT");
|
|
25690
25695
|
if (!programs || typeof programs !== "object" || Array.isArray(programs) || Object.keys(programs).length > 32 || Object.entries(programs).some(([name2, executable]) => !/^[a-z0-9_.-]{1,64}$/.test(name2) || typeof executable !== "string" || !path5.isAbsolute(executable) || executable.length > 4096 || /[\u0000-\u001f]/.test(executable))) throw fail("STATE_CORRUPT");
|
|
25691
25696
|
if (!Array.isArray(workspaces) || workspaces.length > 32 || workspaces.some((w) => !w || !UUID.test(w.workspaceGrantId) || typeof w.root !== "string" || !path5.isAbsolute(w.root) || w.root.length > 4096 || /[\u0000-\u001f]/.test(w.root) || !/^[a-f0-9]{64}$/.test(w.rootHash) || typeof w.displayName !== "string" || !w.displayName || w.displayName.length > 120 || w.policyVersion !== 1 || !w.permissions || w.permissions.readFiles !== true || typeof w.permissions.writeFiles !== "boolean" || typeof w.permissions.executeCommands !== "boolean" || typeof w.permissions.localhost !== "boolean" || !Array.isArray(w.allowedCommands) || w.allowedCommands.length > 32 || w.allowedCommands.some((name2) => typeof name2 !== "string" || !Object.hasOwn(programs, name2)) || new Set(w.allowedCommands).size !== w.allowedCommands.length || w.permissions.executeCommands !== (w.fullAccess === true || w.allowedCommands.length > 0) || !Array.isArray(w.localhostPorts) || w.localhostPorts.length > 32 || w.localhostPorts.some((port) => !Number.isInteger(port) || port < 1 || port > 65535) || new Set(w.localhostPorts).size !== w.localhostPorts.length || w.permissions.localhost !== (w.fullAccess === true || w.localhostPorts.length > 0))) throw fail("STATE_CORRUPT");
|
|
25692
25697
|
if (new Set(workspaces.map((w) => w.workspaceGrantId)).size !== workspaces.length || new Set(workspaces.map((w) => w.rootHash)).size !== workspaces.length) throw fail("STATE_CORRUPT");
|
|
@@ -25764,13 +25769,13 @@ var WindowsPrivateStore = class _WindowsPrivateStore {
|
|
|
25764
25769
|
} catch (error62) {
|
|
25765
25770
|
if (error62.code !== "ENOENT") throw error62;
|
|
25766
25771
|
}
|
|
25767
|
-
const approved = /* @__PURE__ */ new Set([MARKER, "owner-state.dat", "owner-state.lock", "journal", "agent-process.json", "optimization"]);
|
|
25772
|
+
const approved = /* @__PURE__ */ new Set([MARKER, "owner-state.dat", "owner-state.lock", "journal", "agent-process.json", "optimization", ".local-commander"]);
|
|
25768
25773
|
if (names.length && !names.includes(MARKER)) throw fail("STORE_DIRECTORY_UNKNOWN");
|
|
25769
25774
|
if (names.some((name2) => !approved.has(name2))) throw fail("STORE_DIRECTORY_UNKNOWN");
|
|
25770
|
-
for (const name2 of ["agent-process.json", "optimization"]) {
|
|
25775
|
+
for (const name2 of ["agent-process.json", "optimization", ".local-commander"]) {
|
|
25771
25776
|
if (!names.includes(name2)) continue;
|
|
25772
25777
|
const filename = path5.join(absolute2, name2), stat = await lstat3(filename);
|
|
25773
|
-
if (stat.isSymbolicLink() || (name2
|
|
25778
|
+
if (stat.isSymbolicLink() || (name2 !== "agent-process.json" ? !stat.isDirectory() : !stat.isFile() || stat.size < 1 || stat.size > 8192)) throw fail("STORE_DIRECTORY_INVALID");
|
|
25774
25779
|
if (name2 === "agent-process.json") {
|
|
25775
25780
|
let value;
|
|
25776
25781
|
try {
|
|
@@ -26180,16 +26185,16 @@ var WindowsPrivateStore = class _WindowsPrivateStore {
|
|
|
26180
26185
|
if (typeof workspaceGrantId !== "string" || !UUID.test(workspaceGrantId)) throw fail("WORKSPACE_INVALID");
|
|
26181
26186
|
const state = await this.readState();
|
|
26182
26187
|
if (!state?.enrollment) throw fail("ENROLLMENT_REQUIRED");
|
|
26183
|
-
const
|
|
26184
|
-
const workspace = state.workspaces?.find((w) => w.workspaceGrantId ===
|
|
26188
|
+
const id2 = workspaceGrantId.toLowerCase();
|
|
26189
|
+
const workspace = state.workspaces?.find((w) => w.workspaceGrantId === id2);
|
|
26185
26190
|
if (!workspace) {
|
|
26186
|
-
if (state.pendingWorkspaceRevokes?.includes(
|
|
26191
|
+
if (state.pendingWorkspaceRevokes?.includes(id2)) return;
|
|
26187
26192
|
throw fail("WORKSPACE_UNKNOWN");
|
|
26188
26193
|
}
|
|
26189
26194
|
if ((state.pendingWorkspaceRevokes?.length ?? 0) >= 32) throw fail("WORKSPACE_REVOKE_LIMIT");
|
|
26190
26195
|
const before = await this.rawHash();
|
|
26191
|
-
state.workspaces = state.workspaces.filter((w) => w.workspaceGrantId !==
|
|
26192
|
-
state.pendingWorkspaceRevokes = [...state.pendingWorkspaceRevokes ?? [],
|
|
26196
|
+
state.workspaces = state.workspaces.filter((w) => w.workspaceGrantId !== id2);
|
|
26197
|
+
state.pendingWorkspaceRevokes = [...state.pendingWorkspaceRevokes ?? [], id2];
|
|
26193
26198
|
for (const name2 of Object.keys(state.programs ?? {})) if (!state.workspaces.some((w) => w.allowedCommands.includes(name2) || w.deniedCommands?.includes(name2))) delete state.programs[name2];
|
|
26194
26199
|
await this.writeState(state, before);
|
|
26195
26200
|
}));
|
|
@@ -26199,7 +26204,7 @@ var WindowsPrivateStore = class _WindowsPrivateStore {
|
|
|
26199
26204
|
const state = await this.readState();
|
|
26200
26205
|
if (!state?.pendingWorkspaceRevokes?.includes(workspaceGrantId)) return;
|
|
26201
26206
|
const before = await this.rawHash();
|
|
26202
|
-
state.pendingWorkspaceRevokes = state.pendingWorkspaceRevokes.filter((
|
|
26207
|
+
state.pendingWorkspaceRevokes = state.pendingWorkspaceRevokes.filter((id2) => id2 !== workspaceGrantId);
|
|
26203
26208
|
await this.writeState(state, before);
|
|
26204
26209
|
}));
|
|
26205
26210
|
}
|
|
@@ -26979,6 +26984,7 @@ var NativeTools = class {
|
|
|
26979
26984
|
const cwd = await resolve(call.args.path, true), common = await this.gitCommonDir(cwd, workspace, guard);
|
|
26980
26985
|
const claims = readClaim(cwd);
|
|
26981
26986
|
if (common) claims.push({ path: common, namespace: "git", mode: "read" });
|
|
26987
|
+
if (call.name === "project_snapshot" && call.args.startup) claims.push({ path: workspace.root, mode: "read" });
|
|
26982
26988
|
let argv;
|
|
26983
26989
|
if (call.name === "project_snapshot" || call.name === "git_status") argv = ["status", "--short", "--branch"];
|
|
26984
26990
|
else if (call.name === "git_log") argv = ["log", "-" + call.args.limit, "--format=%H%x09%aI%x09%s"];
|
|
@@ -26995,7 +27001,7 @@ var NativeTools = class {
|
|
|
26995
27001
|
const runGit = (signal, onStarted, onOutput) => runSupervised(this.options.helperPath, { ...execution, timeoutMs: 1e4, maxProcesses: 8 }, { signal, maxOutputBytes: 9e4, onStarted, onOutput });
|
|
26996
27002
|
return { call, claims, ...execution ? { execution } : {}, run: async (signal, onStarted, onOutput) => {
|
|
26997
27003
|
if (call.name === "project_snapshot") {
|
|
26998
|
-
const listing = await this.list(guard, cwd, 1, 150, signal);
|
|
27004
|
+
const listing = await this.list(guard, cwd, 1, call.args.startup ? 20 : 150, signal);
|
|
26999
27005
|
let packageInfo = null;
|
|
27000
27006
|
try {
|
|
27001
27007
|
const name2 = await guard.resolveExisting(path10.join(cwd, "package.json"));
|
|
@@ -27006,6 +27012,41 @@ var NativeTools = class {
|
|
|
27006
27012
|
if (error62 instanceof NativeToolError && ["FILE_READ_FAILED", "CANCELLED"].includes(error62.code)) throw error62;
|
|
27007
27013
|
}
|
|
27008
27014
|
const status = common ? await runGit(signal) : null;
|
|
27015
|
+
if (call.args.startup) {
|
|
27016
|
+
let primary = cwd;
|
|
27017
|
+
if (common) {
|
|
27018
|
+
const git = await this.gitExecution(cwd, ["worktree", "list", "--porcelain"]);
|
|
27019
|
+
const worktrees = await runSupervised(this.options.helperPath, { ...git, timeoutMs: 1e4, maxProcesses: 8 }, { signal, maxOutputBytes: 16384 });
|
|
27020
|
+
if (worktrees.exitCode !== 0) fail2("GIT_FAILED");
|
|
27021
|
+
const first = /^worktree (.+)$/m.exec(worktrees.stdout)?.[1]?.trim();
|
|
27022
|
+
if (!first) fail2("GIT_FAILED");
|
|
27023
|
+
primary = await guard.resolveExisting(first);
|
|
27024
|
+
}
|
|
27025
|
+
const contextFile = async (relative, limit, optional2 = false) => {
|
|
27026
|
+
try {
|
|
27027
|
+
const file2 = await guard.resolveExisting(path10.join(primary, relative));
|
|
27028
|
+
guard.assertSafeFile(file2);
|
|
27029
|
+
return utf8(await this.readFile(file2, limit, signal));
|
|
27030
|
+
} catch (error62) {
|
|
27031
|
+
if (optional2 && error62.code === "ENOENT") return null;
|
|
27032
|
+
throw error62;
|
|
27033
|
+
}
|
|
27034
|
+
};
|
|
27035
|
+
const policy = await contextFile("AGENTS.md", 16384);
|
|
27036
|
+
if (!policy?.trim()) fail2("AGENT_INSTRUCTIONS_INVALID");
|
|
27037
|
+
const board = call.args.taskId ? await contextFile("planning/ACTIVE_WORK.md", 1048576, true) : null;
|
|
27038
|
+
const entry = board?.split(/(?=^#{2,3} )/m).find((section) => new RegExp(`^#{2,3}\\s+${call.args.taskId}(?:\\s|/|$)`).test(section));
|
|
27039
|
+
const log = call.args.taskId ? await contextFile(`planning/tasks/${call.args.taskId}.md`, 262144, true) : null;
|
|
27040
|
+
return result({
|
|
27041
|
+
root: cwd,
|
|
27042
|
+
primary,
|
|
27043
|
+
package: packageInfo,
|
|
27044
|
+
git: status?.stdout ?? null,
|
|
27045
|
+
files: listing,
|
|
27046
|
+
instructions: { source: "AGENTS.md", sha256: hash5(policy), text: policy },
|
|
27047
|
+
task: call.args.taskId ? { taskId: call.args.taskId, entry: entry?.slice(0, 4096) ?? null, continuation: log?.slice(-4096) ?? null, truncated: !!entry && entry.length > 4096 || !!log && log.length > 4096 } : null
|
|
27048
|
+
});
|
|
27049
|
+
}
|
|
27009
27050
|
return result({ root: workspace.displayName, files: listing, package: packageInfo, git: status?.stdout ?? null });
|
|
27010
27051
|
}
|
|
27011
27052
|
if (!common) fail2("NOT_A_GIT_REPOSITORY");
|
|
@@ -27149,32 +27190,42 @@ function claimsConflict(a, b) {
|
|
|
27149
27190
|
return a.some((x) => b.some((y) => (x.namespace ?? "filesystem") === (y.namespace ?? "filesystem") && (x.mode === "write" || y.mode === "write") && (ancestor(x.path, y.path) || ancestor(y.path, x.path))));
|
|
27150
27191
|
}
|
|
27151
27192
|
var NativeScheduler = class {
|
|
27152
|
-
safeSlots;
|
|
27153
|
-
active = /* @__PURE__ */ new Map();
|
|
27154
|
-
waiting = [];
|
|
27155
|
-
accepting = true;
|
|
27156
27193
|
constructor(options = {}) {
|
|
27194
|
+
this.options = options;
|
|
27157
27195
|
const capacity = Math.max(1, Math.min(16, Math.floor(Math.max(2, os2.availableParallelism?.() ?? os2.cpus().length) / 2)));
|
|
27158
27196
|
this.safeSlots = options.safeSlots ?? capacity;
|
|
27159
27197
|
this.maxQueued = options.maxQueued ?? 128;
|
|
27160
27198
|
if (!Number.isInteger(this.safeSlots) || this.safeSlots < 1 || this.safeSlots > 32 || !Number.isInteger(this.maxQueued) || this.maxQueued < 1 || this.maxQueued > 256) throw Error("INVALID_SCHEDULER_LIMIT");
|
|
27161
27199
|
}
|
|
27200
|
+
options;
|
|
27201
|
+
safeSlots;
|
|
27202
|
+
active = /* @__PURE__ */ new Map();
|
|
27203
|
+
waiting = [];
|
|
27204
|
+
accepting = true;
|
|
27162
27205
|
maxQueued;
|
|
27163
|
-
|
|
27206
|
+
observe(event) {
|
|
27207
|
+
try {
|
|
27208
|
+
void Promise.resolve(this.options.onEvent?.(event)).catch(() => {
|
|
27209
|
+
});
|
|
27210
|
+
} catch {
|
|
27211
|
+
}
|
|
27212
|
+
}
|
|
27213
|
+
schedule(id2, claims, deadlineAt, run, signal) {
|
|
27164
27214
|
if (!this.accepting) return Promise.reject(Error("AGENT_PAUSED"));
|
|
27165
|
-
if (!
|
|
27215
|
+
if (!id2 || id2.length > 100 || this.active.has(id2) || this.waiting.some((j) => j.id === id2)) return Promise.reject(Error("DUPLICATE_SCHEDULED_EXECUTION"));
|
|
27166
27216
|
if (!Array.isArray(claims) || !claims.length || claims.length > 32 || claims.some((c) => !c || !path11.isAbsolute(c.path) || !["read", "write"].includes(c.mode))) return Promise.reject(Error("INVALID_RESOURCE_CLAIM"));
|
|
27167
27217
|
const deadline = deadlineAt.getTime();
|
|
27168
27218
|
if (!Number.isFinite(deadline) || deadline <= Date.now()) return Promise.reject(Error("ADMISSION_DEADLINE_EXPIRED"));
|
|
27169
27219
|
if (signal?.aborted) return Promise.reject(Error("CANCELLED_BEFORE_ACCEPTANCE"));
|
|
27170
27220
|
if (this.waiting.length >= this.maxQueued) return Promise.reject(Error("RESOURCE_BUSY"));
|
|
27171
27221
|
return new Promise((resolve, reject) => {
|
|
27172
|
-
const job = { id, claims: claims.map((c) => ({ ...c, path: canonical(c.path) })), deadline, run, signal, resolve, reject };
|
|
27222
|
+
const job = { id: id2, claims: claims.map((c) => ({ ...c, path: canonical(c.path) })), deadline, run, signal, resolve, reject };
|
|
27173
27223
|
const remove = (reason) => {
|
|
27174
27224
|
const index = this.waiting.indexOf(job);
|
|
27175
27225
|
if (index < 0) return;
|
|
27176
27226
|
this.waiting.splice(index, 1);
|
|
27177
27227
|
this.cleanup(job);
|
|
27228
|
+
this.observe({ kind: "queue_rejected", executionId: id2, code: reason, terminalProof: true });
|
|
27178
27229
|
reject(Error(reason));
|
|
27179
27230
|
this.pump();
|
|
27180
27231
|
};
|
|
@@ -27182,6 +27233,7 @@ var NativeScheduler = class {
|
|
|
27182
27233
|
job.timer = setTimeout(() => remove("ADMISSION_DEADLINE_EXPIRED"), Math.min(2147483647, Math.max(1, deadline - Date.now())));
|
|
27183
27234
|
signal?.addEventListener("abort", job.aborted, { once: true });
|
|
27184
27235
|
this.waiting.push(job);
|
|
27236
|
+
this.observe({ kind: "queued", executionId: id2, deadlineAt: deadline });
|
|
27185
27237
|
this.pump();
|
|
27186
27238
|
});
|
|
27187
27239
|
}
|
|
@@ -27193,9 +27245,11 @@ var NativeScheduler = class {
|
|
|
27193
27245
|
for (let i = 0; i < this.waiting.length && this.active.size < this.safeSlots; ) {
|
|
27194
27246
|
const job = this.waiting[i];
|
|
27195
27247
|
if (!this.accepting || job.signal?.aborted || job.deadline <= Date.now()) {
|
|
27248
|
+
const code = !this.accepting ? "AGENT_PAUSED" : job.signal?.aborted ? "CANCELLED_BEFORE_ACCEPTANCE" : "ADMISSION_DEADLINE_EXPIRED";
|
|
27196
27249
|
this.waiting.splice(i, 1);
|
|
27197
27250
|
this.cleanup(job);
|
|
27198
|
-
|
|
27251
|
+
this.observe({ kind: "queue_rejected", executionId: job.id, code, terminalProof: true });
|
|
27252
|
+
job.reject(Error(code));
|
|
27199
27253
|
continue;
|
|
27200
27254
|
}
|
|
27201
27255
|
if ([...this.active.values()].some((claims) => claimsConflict(claims, job.claims))) {
|
|
@@ -27209,8 +27263,10 @@ var NativeScheduler = class {
|
|
|
27209
27263
|
this.waiting.splice(i, 1);
|
|
27210
27264
|
this.cleanup(job);
|
|
27211
27265
|
this.active.set(job.id, job.claims);
|
|
27266
|
+
this.observe({ kind: "admitted", executionId: job.id, deadlineAt: job.deadline });
|
|
27212
27267
|
void Promise.resolve().then(job.run).then(job.resolve, job.reject).finally(() => {
|
|
27213
27268
|
this.active.delete(job.id);
|
|
27269
|
+
this.observe({ kind: "released", executionId: job.id });
|
|
27214
27270
|
this.pump();
|
|
27215
27271
|
});
|
|
27216
27272
|
}
|
|
@@ -27792,6 +27848,7 @@ var NativeRuntime = class {
|
|
|
27792
27848
|
connection = null;
|
|
27793
27849
|
transport = null;
|
|
27794
27850
|
contexts = /* @__PURE__ */ new Map();
|
|
27851
|
+
completedResults = /* @__PURE__ */ new Map();
|
|
27795
27852
|
paused = false;
|
|
27796
27853
|
closing = false;
|
|
27797
27854
|
connected(connection, send) {
|
|
@@ -27808,6 +27865,15 @@ var NativeRuntime = class {
|
|
|
27808
27865
|
this.options.onActivity?.();
|
|
27809
27866
|
}
|
|
27810
27867
|
send(frame) {
|
|
27868
|
+
if (frame.type === "result") {
|
|
27869
|
+
this.completedResults.set(frame.binding.executionId, frame.result);
|
|
27870
|
+
if (this.completedResults.size > 64) this.completedResults.delete(this.completedResults.keys().next().value);
|
|
27871
|
+
}
|
|
27872
|
+
try {
|
|
27873
|
+
void Promise.resolve(this.options.onFrame?.(frame)).catch(() => {
|
|
27874
|
+
});
|
|
27875
|
+
} catch {
|
|
27876
|
+
}
|
|
27811
27877
|
try {
|
|
27812
27878
|
return this.transport?.(frame) ?? false;
|
|
27813
27879
|
} catch {
|
|
@@ -28002,7 +28068,7 @@ var NativeRuntime = class {
|
|
|
28002
28068
|
const fresh = await this.options.journal.get(binding2.executionId);
|
|
28003
28069
|
let result2;
|
|
28004
28070
|
if (fresh?.result) {
|
|
28005
|
-
result2 = context ? await outboundResult(context.tool.call, journalResult(fresh.result), binding2, this.options.efficiencyLedger) : journalResult(fresh.result);
|
|
28071
|
+
result2 = this.completedResults.get(binding2.executionId) ?? (context ? await outboundResult(context.tool.call, journalResult(fresh.result), binding2, this.options.efficiencyLedger) : journalResult(fresh.result));
|
|
28006
28072
|
if (frame.action === "output" && this.options.efficiencyLedger) {
|
|
28007
28073
|
const notice = await this.options.efficiencyLedger.consumeNoticeForExecution?.(binding2.executionId).catch(() => null);
|
|
28008
28074
|
if (notice) result2 = { ...result2, efficiencyNotice: notice };
|
|
@@ -28071,18 +28137,18 @@ var NativeRelayBridge = class {
|
|
|
28071
28137
|
async flushTerminal() {
|
|
28072
28138
|
if (!this.connection) return;
|
|
28073
28139
|
for (const event of await this.journal.listUnreportedResults()) {
|
|
28074
|
-
const
|
|
28140
|
+
const id2 = event.executionId, connection = this.connection;
|
|
28075
28141
|
if (!connection || event.tenantId !== connection.tenantId || event.deviceId !== connection.deviceId || !event.workspaceGrantId || !event.policyVersion || !event.resultCode) continue;
|
|
28076
|
-
if (this.terminalSending.has(
|
|
28077
|
-
this.terminalSending.add(
|
|
28142
|
+
if (this.terminalSending.has(id2)) continue;
|
|
28143
|
+
this.terminalSending.add(id2);
|
|
28078
28144
|
try {
|
|
28079
|
-
const binding2 = { tenantId: event.tenantId, deviceId: event.deviceId, grantId: event.grantId, sessionId: event.sessionId, operationId: event.operationId, executionId:
|
|
28145
|
+
const binding2 = { tenantId: event.tenantId, deviceId: event.deviceId, grantId: event.grantId, sessionId: event.sessionId, operationId: event.operationId, executionId: id2, connectionEpoch: event.connectionEpoch, workspaceGrantId: event.workspaceGrantId, policyVersion: event.policyVersion, payloadHash: event.payloadHash, deadlineAt: event.deadlineAt, ...event.accountId ? { accountId: event.accountId } : {} };
|
|
28080
28146
|
if (!["finished", "failed", "cancelled", "unknown"].includes(event.state)) continue;
|
|
28081
28147
|
await this.sendTerminal(binding2, event.state, event.resultCode, terminalMetrics(event.result));
|
|
28082
|
-
await this.journal.markReported(
|
|
28148
|
+
await this.journal.markReported(id2, event.resultCode);
|
|
28083
28149
|
} catch {
|
|
28084
28150
|
} finally {
|
|
28085
|
-
this.terminalSending.delete(
|
|
28151
|
+
this.terminalSending.delete(id2);
|
|
28086
28152
|
}
|
|
28087
28153
|
}
|
|
28088
28154
|
}
|
|
@@ -28144,7 +28210,7 @@ var NativeRelayBridge = class {
|
|
|
28144
28210
|
};
|
|
28145
28211
|
|
|
28146
28212
|
// agent/src/relay-client.ts
|
|
28147
|
-
import { createPrivateKey as createPrivateKey2, randomUUID as
|
|
28213
|
+
import { createPrivateKey as createPrivateKey2, randomUUID as randomUUID6, sign } from "node:crypto";
|
|
28148
28214
|
|
|
28149
28215
|
// ../../node_modules/ws/wrapper.mjs
|
|
28150
28216
|
var import_stream = __toESM(require_stream(), 1);
|
|
@@ -28157,6 +28223,160 @@ var import_websocket = __toESM(require_websocket(), 1);
|
|
|
28157
28223
|
var import_websocket_server = __toESM(require_websocket_server(), 1);
|
|
28158
28224
|
var wrapper_default = import_websocket.default;
|
|
28159
28225
|
|
|
28226
|
+
// agent/src/native-incident-producer.ts
|
|
28227
|
+
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
28228
|
+
var uuid16 = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
28229
|
+
var results = /* @__PURE__ */ new Set(["accepted", "duplicate", "invalid", "stale", "unconfirmed", "capacity", "retry", "disabled", "busy"]);
|
|
28230
|
+
function nativeIncidentAck(candidate) {
|
|
28231
|
+
if (candidate.type !== "incidentBatchAck" || candidate.protocolVersion !== 1 || Object.keys(candidate).some((key) => !["type", "protocolVersion", "batchId", "result"].includes(key)) || typeof candidate.result !== "string" || !results.has(candidate.result) || candidate.batchId !== void 0 && (typeof candidate.batchId !== "string" || !uuid16.test(candidate.batchId))) return;
|
|
28232
|
+
return { result: candidate.result, ...candidate.batchId ? { batchId: String(candidate.batchId).toLowerCase() } : {} };
|
|
28233
|
+
}
|
|
28234
|
+
var NativeIncidentProducer = class {
|
|
28235
|
+
constructor(supervisor, references) {
|
|
28236
|
+
this.supervisor = supervisor;
|
|
28237
|
+
this.references = references;
|
|
28238
|
+
try {
|
|
28239
|
+
this.unsubscribe = supervisor.subscribe(() => this.activity());
|
|
28240
|
+
} catch {
|
|
28241
|
+
this.unsubscribe = () => {
|
|
28242
|
+
};
|
|
28243
|
+
this.rejected++;
|
|
28244
|
+
}
|
|
28245
|
+
}
|
|
28246
|
+
supervisor;
|
|
28247
|
+
references;
|
|
28248
|
+
sender;
|
|
28249
|
+
batch;
|
|
28250
|
+
inFlight = false;
|
|
28251
|
+
queued = false;
|
|
28252
|
+
nextSend = 0;
|
|
28253
|
+
closed = false;
|
|
28254
|
+
rejected = 0;
|
|
28255
|
+
overflow = 0;
|
|
28256
|
+
carry;
|
|
28257
|
+
unsubscribe;
|
|
28258
|
+
connected(sender) {
|
|
28259
|
+
this.disconnected();
|
|
28260
|
+
this.sender = sender;
|
|
28261
|
+
this.nextSend = 0;
|
|
28262
|
+
this.activity();
|
|
28263
|
+
}
|
|
28264
|
+
disconnected() {
|
|
28265
|
+
this.sender = void 0;
|
|
28266
|
+
this.inFlight = false;
|
|
28267
|
+
this.supervisor.cancelDeadline("incident-ack");
|
|
28268
|
+
this.supervisor.cancelDeadline("incident-send");
|
|
28269
|
+
}
|
|
28270
|
+
activity() {
|
|
28271
|
+
if (this.closed || !this.sender || this.queued || this.inFlight) return;
|
|
28272
|
+
this.queued = true;
|
|
28273
|
+
queueMicrotask(() => {
|
|
28274
|
+
this.queued = false;
|
|
28275
|
+
try {
|
|
28276
|
+
this.flush();
|
|
28277
|
+
} catch {
|
|
28278
|
+
this.rejected++;
|
|
28279
|
+
}
|
|
28280
|
+
});
|
|
28281
|
+
}
|
|
28282
|
+
ack(ack) {
|
|
28283
|
+
if (!this.inFlight || !this.batch || ack.batchId !== this.batch.batchId) return;
|
|
28284
|
+
this.supervisor.cancelDeadline("incident-ack");
|
|
28285
|
+
this.inFlight = false;
|
|
28286
|
+
if (ack.result === "accepted" || ack.result === "duplicate") {
|
|
28287
|
+
this.batch = void 0;
|
|
28288
|
+
this.activity();
|
|
28289
|
+
} else if (ack.result === "invalid") {
|
|
28290
|
+
this.batch = void 0;
|
|
28291
|
+
this.rejected++;
|
|
28292
|
+
} else if (ack.result === "stale" || ack.result === "disabled") this.disconnected();
|
|
28293
|
+
}
|
|
28294
|
+
classify(event, occurrences) {
|
|
28295
|
+
const incident = event.incident;
|
|
28296
|
+
if (!incident) return;
|
|
28297
|
+
const executionId = incident.executionId && uuid16.test(incident.executionId) ? incident.executionId.toLowerCase() : void 0;
|
|
28298
|
+
let refs = {};
|
|
28299
|
+
try {
|
|
28300
|
+
const confirmed = executionId && this.references?.(executionId);
|
|
28301
|
+
if (confirmed && confirmed.executionId === executionId && uuid16.test(confirmed.workerId)) {
|
|
28302
|
+
refs = { workerId: confirmed.workerId.toLowerCase(), ...confirmed.taskId && uuid16.test(confirmed.taskId) ? { taskId: confirmed.taskId.toLowerCase() } : {} };
|
|
28303
|
+
}
|
|
28304
|
+
} catch {
|
|
28305
|
+
}
|
|
28306
|
+
return {
|
|
28307
|
+
eventId: randomUUID5(),
|
|
28308
|
+
code: incident.code === "RELAY_DISCONNECTED" ? "relay_error" : incident.code === "LOCAL_QUEUE_EXPIRED" && executionId ? "queue_expired" : incident.code === "EXECUTION_UNKNOWN" && executionId ? "execution_unknown" : "supervisor_error",
|
|
28309
|
+
phase: event.kind === "incident_resolved" ? "resolved" : event.kind === "incident_open" ? "open" : "update",
|
|
28310
|
+
occurredAt: new Date(event.lastSeen).toISOString(),
|
|
28311
|
+
occurrences,
|
|
28312
|
+
...executionId ? { executionId } : {},
|
|
28313
|
+
...refs
|
|
28314
|
+
};
|
|
28315
|
+
}
|
|
28316
|
+
prepare() {
|
|
28317
|
+
const events = [];
|
|
28318
|
+
for (let inspected = 0; inspected < 256 && events.length < 31; inspected++) {
|
|
28319
|
+
if (!this.carry) {
|
|
28320
|
+
const taken = this.supervisor.buffer.take(1);
|
|
28321
|
+
this.overflow = Math.min(Number.MAX_SAFE_INTEGER, this.overflow + taken.dropped);
|
|
28322
|
+
const event2 = taken.events[0];
|
|
28323
|
+
if (!event2) break;
|
|
28324
|
+
if (!event2.incident) continue;
|
|
28325
|
+
this.carry = { event: event2, remaining: event2.kind === "incident_resolved" ? 1 : event2.count };
|
|
28326
|
+
}
|
|
28327
|
+
const occurrences = Math.min(1e4, this.carry.remaining);
|
|
28328
|
+
const event = this.classify(this.carry.event, occurrences);
|
|
28329
|
+
if (event) events.push(event);
|
|
28330
|
+
this.carry.remaining -= occurrences;
|
|
28331
|
+
if (this.carry.remaining <= 0) this.carry = void 0;
|
|
28332
|
+
}
|
|
28333
|
+
if (this.overflow) {
|
|
28334
|
+
const occurrences = Math.min(1e4, this.overflow);
|
|
28335
|
+
this.overflow -= occurrences;
|
|
28336
|
+
events.push({ eventId: randomUUID5(), code: "buffer_overflow", phase: "open", occurredAt: (/* @__PURE__ */ new Date()).toISOString(), occurrences });
|
|
28337
|
+
}
|
|
28338
|
+
if (!events.length) return;
|
|
28339
|
+
return { batchId: randomUUID5(), events };
|
|
28340
|
+
}
|
|
28341
|
+
flush() {
|
|
28342
|
+
if (this.closed || !this.sender || this.inFlight) return;
|
|
28343
|
+
this.batch ??= this.prepare();
|
|
28344
|
+
if (!this.batch) return;
|
|
28345
|
+
if (Date.now() < this.nextSend) {
|
|
28346
|
+
this.supervisor.watchDeadline("incident-send", this.nextSend, () => this.flush());
|
|
28347
|
+
return;
|
|
28348
|
+
}
|
|
28349
|
+
this.supervisor.cancelDeadline("incident-send");
|
|
28350
|
+
if (Buffer.byteLength(JSON.stringify(this.batch)) + 128 > 16384) {
|
|
28351
|
+
this.batch = void 0;
|
|
28352
|
+
this.rejected++;
|
|
28353
|
+
return;
|
|
28354
|
+
}
|
|
28355
|
+
this.inFlight = true;
|
|
28356
|
+
this.nextSend = Date.now() + 1e3;
|
|
28357
|
+
try {
|
|
28358
|
+
this.supervisor.watchDeadline("incident-ack", Date.now() + 1e4, () => {
|
|
28359
|
+
this.inFlight = false;
|
|
28360
|
+
});
|
|
28361
|
+
if (!this.sender(this.batch)) {
|
|
28362
|
+
this.inFlight = false;
|
|
28363
|
+
this.supervisor.cancelDeadline("incident-ack");
|
|
28364
|
+
}
|
|
28365
|
+
} catch {
|
|
28366
|
+
this.inFlight = false;
|
|
28367
|
+
this.supervisor.cancelDeadline("incident-ack");
|
|
28368
|
+
}
|
|
28369
|
+
}
|
|
28370
|
+
snapshot() {
|
|
28371
|
+
return { pendingBatch: !!this.batch, pendingEvents: this.batch?.events.length ?? 0, inFlight: this.inFlight, rejected: this.rejected };
|
|
28372
|
+
}
|
|
28373
|
+
close() {
|
|
28374
|
+
this.closed = true;
|
|
28375
|
+
this.disconnected();
|
|
28376
|
+
this.unsubscribe();
|
|
28377
|
+
}
|
|
28378
|
+
};
|
|
28379
|
+
|
|
28160
28380
|
// agent/src/relay-client.ts
|
|
28161
28381
|
var RelayClientError = class extends Error {
|
|
28162
28382
|
constructor(code) {
|
|
@@ -28192,7 +28412,7 @@ function relayUrlFromEnrollment(enrollment) {
|
|
|
28192
28412
|
url2.pathname = "/api/agent/relay";
|
|
28193
28413
|
return url2.toString();
|
|
28194
28414
|
}
|
|
28195
|
-
function
|
|
28415
|
+
function uuid17(value, code) {
|
|
28196
28416
|
if (typeof value !== "string" || !UUID2.test(value)) fail3(code);
|
|
28197
28417
|
return value.toLowerCase();
|
|
28198
28418
|
}
|
|
@@ -28322,41 +28542,43 @@ function sendJson(socket, value, maxBytes) {
|
|
|
28322
28542
|
function validateChallenge(frame, expectedProtocol) {
|
|
28323
28543
|
if (frame.type !== "challenge") fail3("RELAY_HANDSHAKE_INVALID");
|
|
28324
28544
|
protocol(frame.protocolVersion, expectedProtocol);
|
|
28325
|
-
|
|
28545
|
+
uuid17(frame.gatewayId, "RELAY_HANDSHAKE_INVALID");
|
|
28326
28546
|
if (typeof frame.nonce !== "string" || frame.nonce.length < 32 || frame.nonce.length > 512 || /[\u0000-\u001f\u007f]/u.test(frame.nonce)) fail3("RELAY_HANDSHAKE_INVALID");
|
|
28327
28547
|
if (typeof frame.expiresAt !== "string" || !Number.isFinite(Date.parse(frame.expiresAt)) || Date.parse(frame.expiresAt) <= Date.now()) fail3("RELAY_HANDSHAKE_INVALID");
|
|
28328
28548
|
return {
|
|
28329
|
-
challengeId:
|
|
28549
|
+
challengeId: uuid17(frame.challengeId, "RELAY_HANDSHAKE_INVALID"),
|
|
28330
28550
|
nonce: frame.nonce
|
|
28331
28551
|
};
|
|
28332
28552
|
}
|
|
28333
28553
|
function validateReady(frame, enrollment, expectedProtocol) {
|
|
28334
28554
|
if (frame.type !== "connected") fail3("RELAY_HANDSHAKE_INVALID");
|
|
28335
28555
|
protocol(frame.protocolVersion, expectedProtocol);
|
|
28336
|
-
if (
|
|
28337
|
-
if (
|
|
28556
|
+
if (uuid17(frame.tenantId, "RELAY_HANDSHAKE_INVALID") !== enrollment.tenantId.toLowerCase()) fail3("RELAY_ID_MISMATCH");
|
|
28557
|
+
if (uuid17(frame.deviceId, "RELAY_HANDSHAKE_INVALID") !== enrollment.deviceId.toLowerCase()) fail3("RELAY_ID_MISMATCH");
|
|
28338
28558
|
const terminalMetrics2 = Array.isArray(frame.capabilities) && frame.capabilities.includes(TERMINAL_METRICS_CAPABILITY);
|
|
28339
28559
|
return { connectionEpoch: epoch2(frame.connectionEpoch), terminalMetrics: terminalMetrics2 };
|
|
28340
28560
|
}
|
|
28341
28561
|
function validateRequest(frame, enrollment, expectedProtocol, connectionEpoch) {
|
|
28342
28562
|
if (frame.type !== "relayFrame") fail3("RELAY_REQUEST_INVALID");
|
|
28343
28563
|
protocol(frame.protocolVersion, expectedProtocol);
|
|
28344
|
-
const tenantId =
|
|
28345
|
-
const deviceId =
|
|
28564
|
+
const tenantId = uuid17(frame.tenantId, "RELAY_REQUEST_INVALID");
|
|
28565
|
+
const deviceId = uuid17(frame.deviceId, "RELAY_REQUEST_INVALID");
|
|
28346
28566
|
if (tenantId !== enrollment.tenantId.toLowerCase() || deviceId !== enrollment.deviceId.toLowerCase()) fail3("RELAY_ID_MISMATCH");
|
|
28347
28567
|
if (epoch2(frame.connectionEpoch) !== connectionEpoch) fail3("RELAY_EPOCH_MISMATCH");
|
|
28348
28568
|
const kind = frame.kind;
|
|
28349
28569
|
if (typeof kind !== "string" || !REQUEST_KINDS.has(kind)) fail3("RELAY_REQUEST_INVALID");
|
|
28350
28570
|
return {
|
|
28351
|
-
requestId:
|
|
28571
|
+
requestId: uuid17(frame.requestId, "RELAY_REQUEST_INVALID"),
|
|
28352
28572
|
tenantId,
|
|
28353
28573
|
deviceId,
|
|
28354
28574
|
connectionEpoch,
|
|
28355
|
-
operationId:
|
|
28356
|
-
executionId:
|
|
28575
|
+
operationId: uuid17(frame.operationId, "RELAY_REQUEST_INVALID"),
|
|
28576
|
+
executionId: uuid17(frame.executionId, "RELAY_REQUEST_INVALID"),
|
|
28357
28577
|
kind,
|
|
28358
28578
|
payload: frame.payload,
|
|
28359
|
-
deadlineAt: isoDate(frame.deadlineAt)
|
|
28579
|
+
deadlineAt: isoDate(frame.deadlineAt),
|
|
28580
|
+
// Invalid optional diagnostics never reject otherwise valid execution work.
|
|
28581
|
+
...EfficiencyProfileSchema.safeParse(frame.efficiencyProfile).success ? { efficiencyProfile: EfficiencyProfileSchema.parse(frame.efficiencyProfile) } : {}
|
|
28360
28582
|
};
|
|
28361
28583
|
}
|
|
28362
28584
|
function closedPromise(socket) {
|
|
@@ -28393,8 +28615,8 @@ async function connectOnce(options) {
|
|
|
28393
28615
|
const identity = await options.store.load();
|
|
28394
28616
|
if (!identity || !identity.enrollment) fail3("ENROLLMENT_MISSING");
|
|
28395
28617
|
const enrollment = identity.enrollment;
|
|
28396
|
-
const tenantId =
|
|
28397
|
-
const deviceId =
|
|
28618
|
+
const tenantId = uuid17(enrollment.tenantId, "ENROLLMENT_INVALID");
|
|
28619
|
+
const deviceId = uuid17(enrollment.deviceId, "ENROLLMENT_INVALID");
|
|
28398
28620
|
const url2 = relayUrlFromEnrollment(enrollment);
|
|
28399
28621
|
const socket = new wrapper_default(url2, [], {
|
|
28400
28622
|
followRedirects: false,
|
|
@@ -28429,7 +28651,21 @@ async function connectOnce(options) {
|
|
|
28429
28651
|
nonce: challenge.nonce,
|
|
28430
28652
|
signature
|
|
28431
28653
|
}, maxFrameBytes);
|
|
28432
|
-
const
|
|
28654
|
+
const readyFrame = await waitForMessage(socket, maxFrameBytes, connectTimeoutMs, "RELAY_HANDSHAKE_TIMEOUT");
|
|
28655
|
+
const { connectionEpoch, terminalMetrics: terminalMetrics2 } = validateReady(readyFrame, enrollment, protocolVersion2);
|
|
28656
|
+
const incidents = Array.isArray(readyFrame.capabilities) && readyFrame.capabilities.includes("incidentBatchV1");
|
|
28657
|
+
const monitorHeartbeat = Array.isArray(readyFrame.capabilities) && readyFrame.capabilities.includes("monitorHeartbeatV1") && typeof readyFrame.heartbeatMs === "number" && Number.isInteger(readyFrame.heartbeatMs) && readyFrame.heartbeatMs >= 1e3 && readyFrame.heartbeatMs <= 6e4 ? readyFrame.heartbeatMs : void 0;
|
|
28658
|
+
if (monitorHeartbeat) socket.on("ping", (data) => {
|
|
28659
|
+
if (data.toString() !== "lcmcp-monitor:" + connectionEpoch) return;
|
|
28660
|
+
try {
|
|
28661
|
+
void Promise.resolve(options.onMonitorHeartbeat?.()).catch(() => {
|
|
28662
|
+
});
|
|
28663
|
+
} catch {
|
|
28664
|
+
}
|
|
28665
|
+
});
|
|
28666
|
+
if (Array.isArray(readyFrame.capabilities) && readyFrame.capabilities.includes(NATIVE_CAPACITY_CAPABILITY)) {
|
|
28667
|
+
sendJson(socket, NativeCapacitySchema.parse({ type: "nativeCapacity", protocolVersion: protocolVersion2, connectionEpoch, safeSlots: options.safeSlots ?? 1, agentVersion: options.agentVersion }), maxFrameBytes);
|
|
28668
|
+
}
|
|
28433
28669
|
socket.off("message", bufferDuringReady);
|
|
28434
28670
|
if (handshakeOverflow) fail3("RELAY_FRAME_TOO_LARGE");
|
|
28435
28671
|
handshakeBuffer.shift();
|
|
@@ -28453,6 +28689,17 @@ async function connectOnce(options) {
|
|
|
28453
28689
|
void (async () => {
|
|
28454
28690
|
try {
|
|
28455
28691
|
const frame = parseFrame(data, maxFrameBytes);
|
|
28692
|
+
if (frame.type === "incidentBatchAck") {
|
|
28693
|
+
const ack = nativeIncidentAck(frame);
|
|
28694
|
+
if (incidents && ack) {
|
|
28695
|
+
try {
|
|
28696
|
+
void Promise.resolve(options.onIncidentAck?.(ack)).catch(() => {
|
|
28697
|
+
});
|
|
28698
|
+
} catch {
|
|
28699
|
+
}
|
|
28700
|
+
}
|
|
28701
|
+
return;
|
|
28702
|
+
}
|
|
28456
28703
|
if (frame.type === "executionResultAck") {
|
|
28457
28704
|
const ack = TerminalEventAckSchema.safeParse(frame);
|
|
28458
28705
|
if (!ack.success || !pendingTerminal.has(ack.data.requestId)) fail3("RELAY_FRAME_INVALID");
|
|
@@ -28514,9 +28761,19 @@ async function connectOnce(options) {
|
|
|
28514
28761
|
heartbeat: () => {
|
|
28515
28762
|
if (socket.readyState !== wrapper_default.OPEN) fail3("RELAY_SOCKET_CLOSED");
|
|
28516
28763
|
},
|
|
28764
|
+
...monitorHeartbeat ? { monitorFreshnessMs: monitorHeartbeat * 3 } : {},
|
|
28765
|
+
...incidents ? { sendIncidentBatch: (batch) => {
|
|
28766
|
+
try {
|
|
28767
|
+
if (socket.readyState !== wrapper_default.OPEN) return false;
|
|
28768
|
+
sendJson(socket, { type: "incidentBatch", protocolVersion: 1, batchId: batch.batchId, connectionEpoch, events: batch.events }, Math.min(maxFrameBytes, 16384));
|
|
28769
|
+
return true;
|
|
28770
|
+
} catch {
|
|
28771
|
+
return false;
|
|
28772
|
+
}
|
|
28773
|
+
} } : {},
|
|
28517
28774
|
sendTerminal: (binding2, state, resultCode, metrics) => {
|
|
28518
28775
|
if (pendingTerminal.size >= 64) return Promise.reject(new RelayClientError("RELAY_PENDING_LIMIT"));
|
|
28519
|
-
const requestId =
|
|
28776
|
+
const requestId = randomUUID6();
|
|
28520
28777
|
const event = { type: "executionResult", protocolVersion: 1, requestId, tenantId, deviceId, connectionEpoch, binding: binding2, state, resultCode, ...terminalMetrics2 && metrics ? { metrics } : {} };
|
|
28521
28778
|
return new Promise((resolve, reject) => {
|
|
28522
28779
|
const timer = setTimeout(() => {
|
|
@@ -28535,7 +28792,7 @@ async function connectOnce(options) {
|
|
|
28535
28792
|
},
|
|
28536
28793
|
registerWorkspace: (workspace) => {
|
|
28537
28794
|
if (pendingWorkspace.size >= 32) return Promise.reject(new RelayClientError("RELAY_PENDING_LIMIT"));
|
|
28538
|
-
const requestId =
|
|
28795
|
+
const requestId = randomUUID6();
|
|
28539
28796
|
const event = { type: "workspace_grant", version: 1, requestId, workspaceGrantId: workspace.workspaceGrantId, rootHash: workspace.rootHash, displayName: workspace.displayName, policyVersion: workspace.policyVersion };
|
|
28540
28797
|
return new Promise((resolve, reject) => {
|
|
28541
28798
|
const timer = setTimeout(() => {
|
|
@@ -28554,7 +28811,7 @@ async function connectOnce(options) {
|
|
|
28554
28811
|
},
|
|
28555
28812
|
revokeWorkspace: (workspaceGrantId) => {
|
|
28556
28813
|
if (pendingWorkspace.size >= 32) return Promise.reject(new RelayClientError("RELAY_PENDING_LIMIT"));
|
|
28557
|
-
const requestId =
|
|
28814
|
+
const requestId = randomUUID6();
|
|
28558
28815
|
const event = { type: "workspace_revoke", version: 1, requestId, workspaceGrantId };
|
|
28559
28816
|
return new Promise((resolve, reject) => {
|
|
28560
28817
|
const timer = setTimeout(() => {
|
|
@@ -28614,10 +28871,10 @@ function canonicalOrigin2(value) {
|
|
|
28614
28871
|
fail4("ORIGIN_INVALID");
|
|
28615
28872
|
}
|
|
28616
28873
|
}
|
|
28617
|
-
function endpoint(origin,
|
|
28618
|
-
return origin +
|
|
28874
|
+
function endpoint(origin, path18) {
|
|
28875
|
+
return origin + path18;
|
|
28619
28876
|
}
|
|
28620
|
-
function
|
|
28877
|
+
function uuid18(value, code) {
|
|
28621
28878
|
if (typeof value !== "string" || !UUID3.test(value)) fail4(code);
|
|
28622
28879
|
return value.toLowerCase();
|
|
28623
28880
|
}
|
|
@@ -28737,7 +28994,7 @@ var PairingClient = class {
|
|
|
28737
28994
|
publicKey: identity.publicKeyPem,
|
|
28738
28995
|
agentVersion: this.version
|
|
28739
28996
|
}));
|
|
28740
|
-
const pairingId =
|
|
28997
|
+
const pairingId = uuid18(response.pairingId, "PAIRING_RESPONSE_INVALID");
|
|
28741
28998
|
const expiresAt = parseDate(response.expiresAt, "PAIRING_RESPONSE_INVALID");
|
|
28742
28999
|
const now = this.nowMs();
|
|
28743
29000
|
if (expiresAt.getTime() <= now || expiresAt.getTime() - now > 30 * 6e4) fail4("PAIRING_RESPONSE_INVALID");
|
|
@@ -28771,7 +29028,7 @@ var PairingClient = class {
|
|
|
28771
29028
|
}
|
|
28772
29029
|
async completeOnce(beginResult, approved, displayNameValue) {
|
|
28773
29030
|
const pairing = this.validateBeginResult(beginResult);
|
|
28774
|
-
const tenantId =
|
|
29031
|
+
const tenantId = uuid18(approved.tenantId, "PAIRING_RESPONSE_INVALID");
|
|
28775
29032
|
const email3 = accountEmail(approved.accountEmail);
|
|
28776
29033
|
const name2 = displayName(displayNameValue);
|
|
28777
29034
|
const identity = await this.currentIdentity();
|
|
@@ -28785,15 +29042,15 @@ var PairingClient = class {
|
|
|
28785
29042
|
displayName: name2,
|
|
28786
29043
|
agentVersion: this.version
|
|
28787
29044
|
}));
|
|
28788
|
-
const completedTenant =
|
|
29045
|
+
const completedTenant = uuid18(response.tenantId, "PAIRING_RESPONSE_INVALID");
|
|
28789
29046
|
if (completedTenant !== tenantId) fail4("PAIRING_RESPONSE_INVALID");
|
|
28790
|
-
const deviceId =
|
|
29047
|
+
const deviceId = uuid18(response.deviceId, "PAIRING_RESPONSE_INVALID");
|
|
28791
29048
|
const enrollment = {
|
|
28792
29049
|
tenantId,
|
|
28793
29050
|
deviceId,
|
|
28794
29051
|
serverOrigin: this.origin,
|
|
28795
29052
|
accountEmail: email3,
|
|
28796
|
-
...response.accountId !== void 0 ? { accountId:
|
|
29053
|
+
...response.accountId !== void 0 ? { accountId: uuid18(response.accountId, "PAIRING_RESPONSE_INVALID") } : {}
|
|
28797
29054
|
};
|
|
28798
29055
|
await this.store.saveEnrollment(enrollment);
|
|
28799
29056
|
return { ...enrollment };
|
|
@@ -28807,7 +29064,7 @@ var PairingClient = class {
|
|
|
28807
29064
|
state: response.state,
|
|
28808
29065
|
expiresAt: parseDate(response.expiresAt, "PAIRING_RESPONSE_INVALID")
|
|
28809
29066
|
};
|
|
28810
|
-
if (response.tenantId !== void 0) result2.tenantId =
|
|
29067
|
+
if (response.tenantId !== void 0) result2.tenantId = uuid18(response.tenantId, "PAIRING_RESPONSE_INVALID");
|
|
28811
29068
|
if (response.accountEmail !== void 0) result2.accountEmail = accountEmail(response.accountEmail);
|
|
28812
29069
|
return result2;
|
|
28813
29070
|
}
|
|
@@ -28819,10 +29076,10 @@ var PairingClient = class {
|
|
|
28819
29076
|
}
|
|
28820
29077
|
validateBeginResult(value) {
|
|
28821
29078
|
return {
|
|
28822
|
-
pairingId:
|
|
29079
|
+
pairingId: uuid18(value.pairingId, "PAIRING_INVALID"),
|
|
28823
29080
|
pairingSecret: pairingSecret(value.pairingSecret),
|
|
28824
29081
|
confirmationCode: confirmationCode(value.confirmationCode),
|
|
28825
|
-
approvalUrl: approvalUrl(value.approvalUrl, this.origin,
|
|
29082
|
+
approvalUrl: approvalUrl(value.approvalUrl, this.origin, uuid18(value.pairingId, "PAIRING_INVALID")),
|
|
28826
29083
|
expiresAt: value.expiresAt instanceof Date ? new Date(value.expiresAt.getTime()) : parseDate(value.expiresAt, "PAIRING_INVALID"),
|
|
28827
29084
|
keyFingerprint: fingerprint2(value.keyFingerprint)
|
|
28828
29085
|
};
|
|
@@ -28854,7 +29111,7 @@ var PairingClient = class {
|
|
|
28854
29111
|
};
|
|
28855
29112
|
|
|
28856
29113
|
// agent/src/guard.ts
|
|
28857
|
-
import { randomUUID as
|
|
29114
|
+
import { randomUUID as randomUUID7 } from "node:crypto";
|
|
28858
29115
|
var NativeGuard = class _NativeGuard {
|
|
28859
29116
|
constructor(config2, store, journal) {
|
|
28860
29117
|
this.config = config2;
|
|
@@ -28878,7 +29135,7 @@ var NativeGuard = class _NativeGuard {
|
|
|
28878
29135
|
return this.journal.appendGuardEvidence(action.request.requestId, {
|
|
28879
29136
|
event: {
|
|
28880
29137
|
protocolVersion: 1,
|
|
28881
|
-
evidenceId:
|
|
29138
|
+
evidenceId: randomUUID7(),
|
|
28882
29139
|
requestId: action.request.requestId,
|
|
28883
29140
|
decisionId: decision.decisionId,
|
|
28884
29141
|
occurredAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -28904,12 +29161,12 @@ var NativeGuard = class _NativeGuard {
|
|
|
28904
29161
|
try {
|
|
28905
29162
|
action = guardAction(binding2, tool, this.config, now);
|
|
28906
29163
|
} catch {
|
|
28907
|
-
const decisionId2 =
|
|
29164
|
+
const decisionId2 = randomUUID7();
|
|
28908
29165
|
for (const phase of ["request", "decision", "result"]) await this.journal.appendGuardEvidence(binding2.executionId, {
|
|
28909
29166
|
payloadHash: guardHash(tool.effective ?? tool.call),
|
|
28910
29167
|
event: {
|
|
28911
29168
|
protocolVersion: 1,
|
|
28912
|
-
evidenceId:
|
|
29169
|
+
evidenceId: randomUUID7(),
|
|
28913
29170
|
requestId: binding2.executionId,
|
|
28914
29171
|
decisionId: decisionId2,
|
|
28915
29172
|
occurredAt: now,
|
|
@@ -28930,7 +29187,7 @@ var NativeGuard = class _NativeGuard {
|
|
|
28930
29187
|
}
|
|
28931
29188
|
const permit = { action, expiresAt: binding2.deadlineAt, decision: {
|
|
28932
29189
|
protocolVersion: 1,
|
|
28933
|
-
decisionId:
|
|
29190
|
+
decisionId: randomUUID7(),
|
|
28934
29191
|
requestId: binding2.executionId,
|
|
28935
29192
|
policyId: this.config.policyId,
|
|
28936
29193
|
policyVersion: "unavailable",
|
|
@@ -29292,9 +29549,22 @@ var OptimizationLedger = class _OptimizationLedger {
|
|
|
29292
29549
|
};
|
|
29293
29550
|
|
|
29294
29551
|
// agent/src/monitor.ts
|
|
29295
|
-
import { createHash as createHash10, randomUUID as
|
|
29552
|
+
import { createHash as createHash10, randomUUID as randomUUID8 } from "node:crypto";
|
|
29296
29553
|
import { lstat as lstat7, mkdir as mkdir5, open as open6, rename as rename4, rm as rm4 } from "node:fs/promises";
|
|
29297
29554
|
import path13 from "node:path";
|
|
29555
|
+
import os3 from "node:os";
|
|
29556
|
+
function commandSummary(tool) {
|
|
29557
|
+
if (tool.name !== "command_run") return { name: tool.name, command: tool.name };
|
|
29558
|
+
const candidate = path13.win32.basename(tool.args.command).replace(/\.(exe|cmd|bat|com)$/i, "").toLowerCase();
|
|
29559
|
+
const name2 = ["node", "npm", "npx", "git", "rg", "powershell", "pwsh", "cmd", "tsc", "python", "dotnet"].includes(candidate) ? candidate : "command";
|
|
29560
|
+
let command = name2;
|
|
29561
|
+
if (name2 === "node" && tool.args.args.includes("--test") && !tool.args.args.some((arg) => ["-e", "--eval", "-p", "--print"].includes(arg))) command += " --test";
|
|
29562
|
+
else if (name2 === "git" && ["status", "diff", "log", "show", "fetch", "pull", "push", "commit"].includes(tool.args.args[0] ?? "")) command += " " + tool.args.args[0];
|
|
29563
|
+
else if (name2 === "npm" && ["test", "install", "ci", "pack", "publish"].includes(tool.args.args[0] ?? "")) command += " " + tool.args.args[0];
|
|
29564
|
+
else if (name2 === "npm" && tool.args.args[0] === "run" && ["test", "build", "typecheck", "lint", "dev", "start"].includes(tool.args.args[1] ?? "")) command += " run " + tool.args.args[1];
|
|
29565
|
+
else if (tool.args.args.length) command += " [args]";
|
|
29566
|
+
return { name: name2, command };
|
|
29567
|
+
}
|
|
29298
29568
|
var ProductionMonitor = class {
|
|
29299
29569
|
constructor(directory, stateDirectory, agentVersion3) {
|
|
29300
29570
|
this.agentVersion = agentVersion3;
|
|
@@ -29302,9 +29572,15 @@ var ProductionMonitor = class {
|
|
|
29302
29572
|
this.file = path13.join(directory, key + ".json");
|
|
29303
29573
|
}
|
|
29304
29574
|
agentVersion;
|
|
29305
|
-
instanceId =
|
|
29575
|
+
instanceId = randomUUID8();
|
|
29306
29576
|
events = [];
|
|
29307
29577
|
sessions = /* @__PURE__ */ new Map();
|
|
29578
|
+
executions = /* @__PURE__ */ new Map();
|
|
29579
|
+
models = /* @__PURE__ */ new Map();
|
|
29580
|
+
measured = /* @__PURE__ */ new Set();
|
|
29581
|
+
polls = { status: 0, output: 0 };
|
|
29582
|
+
efficiencyCalls = 0;
|
|
29583
|
+
computer = os3.hostname().replace(/[^A-Za-z0-9._-]/g, "_").slice(0, 64) || "PC";
|
|
29308
29584
|
sequence = 0;
|
|
29309
29585
|
connection = {
|
|
29310
29586
|
state: "starting",
|
|
@@ -29312,6 +29588,9 @@ var ProductionMonitor = class {
|
|
|
29312
29588
|
epoch: null
|
|
29313
29589
|
};
|
|
29314
29590
|
writing = null;
|
|
29591
|
+
dirty = false;
|
|
29592
|
+
freshnessMs = 1e4;
|
|
29593
|
+
transportAt = null;
|
|
29315
29594
|
file;
|
|
29316
29595
|
record(event, details = {}) {
|
|
29317
29596
|
this.events.push({ seq: ++this.sequence, at: (/* @__PURE__ */ new Date()).toISOString(), event, ...details });
|
|
@@ -29335,8 +29614,13 @@ var ProductionMonitor = class {
|
|
|
29335
29614
|
this.connection.epoch = connection.connectionEpoch;
|
|
29336
29615
|
}
|
|
29337
29616
|
this.connection.state = state;
|
|
29617
|
+
this.freshnessMs = state === "connected" ? connection?.monitorFreshnessMs ?? 1e4 : 1e4;
|
|
29618
|
+
this.transportAt = state === "connected" && connection?.monitorFreshnessMs ? (/* @__PURE__ */ new Date()).toISOString() : null;
|
|
29338
29619
|
this.record(state);
|
|
29339
29620
|
}
|
|
29621
|
+
transportActivity() {
|
|
29622
|
+
if (this.transportAt !== null) this.transportAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
29623
|
+
}
|
|
29340
29624
|
request(request) {
|
|
29341
29625
|
const payload = request.payload;
|
|
29342
29626
|
const parsed = ExecutionBindingSchema.safeParse(payload?.binding);
|
|
@@ -29351,6 +29635,23 @@ var ProductionMonitor = class {
|
|
|
29351
29635
|
});
|
|
29352
29636
|
if (this.sessions.size > 32) this.sessions.delete(this.sessions.keys().next().value);
|
|
29353
29637
|
const tool = ToolCallSchema.safeParse(payload?.tool);
|
|
29638
|
+
if (request.kind === "status" || request.kind === "output") this.polls[request.kind]++;
|
|
29639
|
+
if (request.kind === "execute" && tool.success && !this.executions.has(binding2.executionId)) {
|
|
29640
|
+
const profile = EfficiencyProfileSchema.safeParse(request.efficiencyProfile);
|
|
29641
|
+
this.executions.set(binding2.executionId, {
|
|
29642
|
+
executionId: binding2.executionId,
|
|
29643
|
+
sessionId: binding2.sessionId,
|
|
29644
|
+
...commandSummary(tool.data),
|
|
29645
|
+
state: "requested",
|
|
29646
|
+
pid: null,
|
|
29647
|
+
profile: profile.success ? profile.data : null,
|
|
29648
|
+
originalBytes: null,
|
|
29649
|
+
sentBytes: null,
|
|
29650
|
+
savedBytes: null,
|
|
29651
|
+
reason: null
|
|
29652
|
+
});
|
|
29653
|
+
if (this.executions.size > 64) this.executions.delete(this.executions.keys().next().value);
|
|
29654
|
+
}
|
|
29354
29655
|
this.record(request.kind, {
|
|
29355
29656
|
sessionId: binding2.sessionId,
|
|
29356
29657
|
executionId: binding2.executionId,
|
|
@@ -29358,12 +29659,53 @@ var ProductionMonitor = class {
|
|
|
29358
29659
|
});
|
|
29359
29660
|
}
|
|
29360
29661
|
result(binding2, state, code) {
|
|
29662
|
+
const execution = this.executions.get(binding2.executionId);
|
|
29663
|
+
if (execution) execution.state = ["finished", "failed", "cancelled", "unknown"].includes(state) ? state : "unknown";
|
|
29361
29664
|
this.record(["finished", "failed", "cancelled", "unknown"].includes(state) ? state : "result", {
|
|
29362
29665
|
sessionId: binding2.sessionId,
|
|
29363
29666
|
executionId: binding2.executionId,
|
|
29364
29667
|
code: code === "SUCCESS" || ErrorCodeSchema.safeParse(code).success ? code : "RESULT"
|
|
29365
29668
|
});
|
|
29366
29669
|
}
|
|
29670
|
+
frame(frame) {
|
|
29671
|
+
if (!("binding" in frame)) return;
|
|
29672
|
+
const execution = this.executions.get(frame.binding.executionId);
|
|
29673
|
+
if (!execution) return;
|
|
29674
|
+
if (["prepared", "accepted", "running"].includes(frame.type)) execution.state = frame.type;
|
|
29675
|
+
if (frame.type === "running" && frame.pid) execution.pid = frame.pid;
|
|
29676
|
+
if (frame.type === "not_accepted") execution.state = frame.provedNotStarted ? "rejected" : "unknown";
|
|
29677
|
+
if (frame.type === "result") {
|
|
29678
|
+
const result2 = frame.result;
|
|
29679
|
+
execution.state = !result2.treeTerminated ? "unknown" : result2.cancelled ? "cancelled" : result2.timedOut || result2.exitCode !== 0 ? "failed" : "finished";
|
|
29680
|
+
}
|
|
29681
|
+
if (frame.type === "control_result") execution.state = frame.state;
|
|
29682
|
+
}
|
|
29683
|
+
efficiency(input2) {
|
|
29684
|
+
const parsed = LiveEfficiencyEventSchema.safeParse(input2);
|
|
29685
|
+
if (!parsed.success || this.measured.has(parsed.data.executionId)) return;
|
|
29686
|
+
const event = parsed.data, execution = this.executions.get(event.executionId);
|
|
29687
|
+
if (!execution || execution.sessionId !== event.sessionId) return;
|
|
29688
|
+
this.measured.add(event.executionId);
|
|
29689
|
+
if (this.measured.size > 64) this.measured.delete(this.measured.values().next().value);
|
|
29690
|
+
execution.originalBytes = event.originalStdoutBytes;
|
|
29691
|
+
execution.sentBytes = event.sentStdoutBytes;
|
|
29692
|
+
execution.savedBytes = event.savedStdoutBytes;
|
|
29693
|
+
execution.reason = event.reason;
|
|
29694
|
+
const profile = execution.profile;
|
|
29695
|
+
let key = profile?.model ?? "";
|
|
29696
|
+
if (!this.models.has(key) && this.models.size >= 31) key = "";
|
|
29697
|
+
const group = this.models.get(key) ?? { model: key || null, calls: 0, savedBytes: 0, sentBytes: 0 };
|
|
29698
|
+
group.calls++;
|
|
29699
|
+
group.savedBytes += event.savedStdoutBytes;
|
|
29700
|
+
group.sentBytes += event.sentStdoutBytes;
|
|
29701
|
+
this.models.set(key, group);
|
|
29702
|
+
this.efficiencyCalls++;
|
|
29703
|
+
this.record(event.applied ? "compacted" : "passthrough", {
|
|
29704
|
+
sessionId: event.sessionId,
|
|
29705
|
+
executionId: event.executionId,
|
|
29706
|
+
tool: event.toolName
|
|
29707
|
+
});
|
|
29708
|
+
}
|
|
29367
29709
|
requestFailed() {
|
|
29368
29710
|
this.record("request_failed");
|
|
29369
29711
|
}
|
|
@@ -29389,32 +29731,47 @@ var ProductionMonitor = class {
|
|
|
29389
29731
|
schemaVersion: 1,
|
|
29390
29732
|
instanceId: this.instanceId,
|
|
29391
29733
|
pid: process.pid,
|
|
29734
|
+
computer: this.computer,
|
|
29735
|
+
processName: "lc-agent",
|
|
29392
29736
|
agentVersion: this.agentVersion,
|
|
29393
29737
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
29738
|
+
freshnessMs: this.freshnessMs,
|
|
29739
|
+
...this.transportAt ? { transportAt: this.transportAt } : {},
|
|
29394
29740
|
connection: { ...this.connection },
|
|
29395
29741
|
sessions: [...this.sessions.values()].map((session) => ({ ...session })),
|
|
29396
|
-
events: this.events.map((event) => ({ ...event }))
|
|
29742
|
+
events: this.events.map((event) => ({ ...event })),
|
|
29743
|
+
executions: [...this.executions.values()].map((execution) => ({ ...execution, profile: execution.profile && { ...execution.profile } })),
|
|
29744
|
+
efficiency: {
|
|
29745
|
+
scope: "this_run",
|
|
29746
|
+
calls: this.efficiencyCalls,
|
|
29747
|
+
polls: { ...this.polls },
|
|
29748
|
+
models: [...this.models.values()].map((group) => ({ ...group }))
|
|
29749
|
+
}
|
|
29397
29750
|
};
|
|
29398
29751
|
}
|
|
29399
29752
|
flush() {
|
|
29753
|
+
this.dirty = true;
|
|
29400
29754
|
if (this.writing) return this.writing;
|
|
29401
29755
|
this.writing = (async () => {
|
|
29402
|
-
|
|
29403
|
-
|
|
29404
|
-
|
|
29405
|
-
|
|
29406
|
-
|
|
29407
|
-
|
|
29408
|
-
|
|
29756
|
+
do {
|
|
29757
|
+
this.dirty = false;
|
|
29758
|
+
const directory = path13.dirname(this.file);
|
|
29759
|
+
await mkdir5(directory, { recursive: true, mode: 448 });
|
|
29760
|
+
const stat = await lstat7(directory);
|
|
29761
|
+
if (!stat.isDirectory() || stat.isSymbolicLink()) throw Error("MONITOR_DIRECTORY_INVALID");
|
|
29762
|
+
const temporary = this.file + "." + this.instanceId + ".tmp";
|
|
29763
|
+
const handle = await open6(temporary, "wx", 384);
|
|
29409
29764
|
try {
|
|
29410
|
-
|
|
29765
|
+
try {
|
|
29766
|
+
await handle.writeFile(JSON.stringify(this.snapshot()) + "\n");
|
|
29767
|
+
} finally {
|
|
29768
|
+
await handle.close();
|
|
29769
|
+
}
|
|
29770
|
+
await rename4(temporary, this.file);
|
|
29411
29771
|
} finally {
|
|
29412
|
-
await
|
|
29772
|
+
await rm4(temporary, { force: true });
|
|
29413
29773
|
}
|
|
29414
|
-
|
|
29415
|
-
} finally {
|
|
29416
|
-
await rm4(temporary, { force: true });
|
|
29417
|
-
}
|
|
29774
|
+
} while (this.dirty);
|
|
29418
29775
|
})().finally(() => {
|
|
29419
29776
|
this.writing = null;
|
|
29420
29777
|
});
|
|
@@ -29427,8 +29784,1389 @@ var ProductionMonitor = class {
|
|
|
29427
29784
|
}
|
|
29428
29785
|
};
|
|
29429
29786
|
|
|
29787
|
+
// agent/src/native-event-buffer.ts
|
|
29788
|
+
import { createHash as createHash11 } from "node:crypto";
|
|
29789
|
+
function nativeFingerprint(code, executionId = "") {
|
|
29790
|
+
return createHash11("sha256").update(code + "\0" + executionId).digest("hex");
|
|
29791
|
+
}
|
|
29792
|
+
var NativeEventBuffer = class {
|
|
29793
|
+
pending = /* @__PURE__ */ new Map();
|
|
29794
|
+
dropped = 0;
|
|
29795
|
+
record(input2, at) {
|
|
29796
|
+
const key = input2.kind + ":" + input2.fingerprint + (input2.incident ? ":" + input2.incident.generation : "");
|
|
29797
|
+
const previous = this.pending.get(key);
|
|
29798
|
+
const event = {
|
|
29799
|
+
...input2,
|
|
29800
|
+
...input2.incident ? { incident: { ...input2.incident } } : {},
|
|
29801
|
+
firstSeen: previous?.firstSeen ?? at,
|
|
29802
|
+
lastSeen: at,
|
|
29803
|
+
count: Math.min(Number.MAX_SAFE_INTEGER, (previous?.count ?? 0) + 1)
|
|
29804
|
+
};
|
|
29805
|
+
this.pending.set(key, event);
|
|
29806
|
+
if (this.pending.size > 256) {
|
|
29807
|
+
this.pending.delete(this.pending.keys().next().value);
|
|
29808
|
+
this.dropped++;
|
|
29809
|
+
}
|
|
29810
|
+
}
|
|
29811
|
+
take(limit = 64) {
|
|
29812
|
+
if (!Number.isInteger(limit) || limit < 1 || limit > 128) throw Error("NATIVE_EVENT_BATCH_LIMIT");
|
|
29813
|
+
const events = [];
|
|
29814
|
+
for (const [key, event] of this.pending) {
|
|
29815
|
+
events.push({ ...event, ...event.incident ? { incident: { ...event.incident } } : {} });
|
|
29816
|
+
this.pending.delete(key);
|
|
29817
|
+
if (events.length === limit) break;
|
|
29818
|
+
}
|
|
29819
|
+
const dropped = this.dropped;
|
|
29820
|
+
this.dropped = 0;
|
|
29821
|
+
return { events, dropped };
|
|
29822
|
+
}
|
|
29823
|
+
get size() {
|
|
29824
|
+
return this.pending.size;
|
|
29825
|
+
}
|
|
29826
|
+
};
|
|
29827
|
+
|
|
29828
|
+
// agent/src/native-event-supervisor.ts
|
|
29829
|
+
var eventKinds = /* @__PURE__ */ new Set(["queued", "admitted", "released", "queue_rejected", "prepared", "accepted", "running", "result", "not_accepted", "connected", "disconnected", "mailbox_expired"]);
|
|
29830
|
+
var codes = /* @__PURE__ */ new Set(["SUCCESS", "EXECUTION_UNKNOWN", "ADMISSION_DEADLINE_EXPIRED", "CANCELLED_BEFORE_ACCEPTANCE", "RESOURCE_BUSY", "AGENT_PAUSED", "PREPARATION_EXPIRED", "CANCELLED", "TIMEOUT", "USER_PROGRAM_FAILED", "TOOL_FAILED", "MAILBOX_EXPIRED"]);
|
|
29831
|
+
var NativeEventSupervisor = class {
|
|
29832
|
+
constructor(onChange) {
|
|
29833
|
+
this.onChange = onChange;
|
|
29834
|
+
}
|
|
29835
|
+
onChange;
|
|
29836
|
+
buffer = new NativeEventBuffer();
|
|
29837
|
+
incidents = /* @__PURE__ */ new Map();
|
|
29838
|
+
active = /* @__PURE__ */ new Map();
|
|
29839
|
+
heap = [];
|
|
29840
|
+
positions = /* @__PURE__ */ new Map();
|
|
29841
|
+
timer;
|
|
29842
|
+
closed = false;
|
|
29843
|
+
wasConnected = false;
|
|
29844
|
+
omitted = 0;
|
|
29845
|
+
generation = 0;
|
|
29846
|
+
consumer;
|
|
29847
|
+
observe(input2) {
|
|
29848
|
+
try {
|
|
29849
|
+
if (this.closed || !input2 || !eventKinds.has(input2.kind)) return;
|
|
29850
|
+
const id2 = input2.executionId;
|
|
29851
|
+
if (id2 !== void 0 && (typeof id2 !== "string" || !/^[A-Za-z0-9_-]{1,100}$/.test(id2))) return;
|
|
29852
|
+
const at = Date.now();
|
|
29853
|
+
const code = input2.code === void 0 ? void 0 : codes.has(input2.code) ? input2.code : "TOOL_FAILED";
|
|
29854
|
+
const pid = Number.isSafeInteger(input2.pid) && input2.pid > 0 ? input2.pid : void 0;
|
|
29855
|
+
this.buffer.record({
|
|
29856
|
+
kind: input2.kind,
|
|
29857
|
+
fingerprint: nativeFingerprint(input2.kind, id2),
|
|
29858
|
+
...id2 ? { executionId: id2 } : {},
|
|
29859
|
+
...code ? { code } : {},
|
|
29860
|
+
...pid ? { pid } : {}
|
|
29861
|
+
}, at);
|
|
29862
|
+
if (input2.kind === "connected") {
|
|
29863
|
+
this.wasConnected = true;
|
|
29864
|
+
this.resolve(void 0, at, "RELAY_DISCONNECTED");
|
|
29865
|
+
}
|
|
29866
|
+
if (input2.kind === "mailbox_expired") this.incident("MAILBOX_EXPIRED", void 0, "warning", at);
|
|
29867
|
+
if (input2.kind === "disconnected" && this.wasConnected) this.incident("RELAY_DISCONNECTED", void 0, "warning", at);
|
|
29868
|
+
if (id2) {
|
|
29869
|
+
if (["queued", "prepared", "accepted", "running"].includes(input2.kind)) {
|
|
29870
|
+
if (!this.active.has(id2) && this.active.size >= 320) this.omitted++;
|
|
29871
|
+
else {
|
|
29872
|
+
this.active.set(id2, input2.kind);
|
|
29873
|
+
if (Number.isFinite(input2.deadlineAt) && input2.deadlineAt > 0 && !this.positions.has(id2)) this.insert({ id: id2, at: input2.deadlineAt });
|
|
29874
|
+
}
|
|
29875
|
+
}
|
|
29876
|
+
if (input2.kind === "result" || input2.kind === "not_accepted" || input2.kind === "queue_rejected") {
|
|
29877
|
+
this.active.delete(id2);
|
|
29878
|
+
this.remove(id2);
|
|
29879
|
+
if (input2.kind === "queue_rejected" && code === "ADMISSION_DEADLINE_EXPIRED" && input2.terminalProof === true) this.incident("LOCAL_QUEUE_EXPIRED", id2, "warning", at);
|
|
29880
|
+
if (input2.terminalProof === true) this.resolve(id2, at);
|
|
29881
|
+
else if (input2.kind !== "queue_rejected") this.incident("EXECUTION_UNKNOWN", id2, "error", at);
|
|
29882
|
+
}
|
|
29883
|
+
}
|
|
29884
|
+
this.arm();
|
|
29885
|
+
this.changed();
|
|
29886
|
+
} catch {
|
|
29887
|
+
}
|
|
29888
|
+
}
|
|
29889
|
+
frame(frame) {
|
|
29890
|
+
try {
|
|
29891
|
+
if (!("binding" in frame)) return;
|
|
29892
|
+
const base = { executionId: frame.binding.executionId, deadlineAt: Date.parse(frame.binding.deadlineAt) };
|
|
29893
|
+
if (frame.type === "prepared" || frame.type === "accepted" || frame.type === "running") {
|
|
29894
|
+
this.observe({ ...base, kind: frame.type, ...frame.type === "running" && frame.pid ? { pid: frame.pid } : {} });
|
|
29895
|
+
} else if (frame.type === "not_accepted") {
|
|
29896
|
+
this.observe({ ...base, kind: "not_accepted", code: frame.code, terminalProof: frame.provedNotStarted });
|
|
29897
|
+
} else if (frame.type === "result") {
|
|
29898
|
+
this.observe({
|
|
29899
|
+
...base,
|
|
29900
|
+
kind: "result",
|
|
29901
|
+
code: frame.result.resultCode,
|
|
29902
|
+
terminalProof: frame.result.treeTerminated && frame.result.resultCode !== "EXECUTION_UNKNOWN"
|
|
29903
|
+
});
|
|
29904
|
+
} else if (frame.type === "control_result" && frame.result && frame.result.resultCode !== "IN_PROGRESS") {
|
|
29905
|
+
this.observe({
|
|
29906
|
+
...base,
|
|
29907
|
+
kind: "result",
|
|
29908
|
+
code: frame.result.resultCode,
|
|
29909
|
+
terminalProof: frame.result.treeTerminated && frame.result.resultCode !== "EXECUTION_UNKNOWN"
|
|
29910
|
+
});
|
|
29911
|
+
}
|
|
29912
|
+
} catch {
|
|
29913
|
+
}
|
|
29914
|
+
}
|
|
29915
|
+
subscribe(consumer) {
|
|
29916
|
+
if (this.consumer || this.closed) throw Error("NATIVE_EVENT_CONSUMER_UNAVAILABLE");
|
|
29917
|
+
this.consumer = consumer;
|
|
29918
|
+
return () => {
|
|
29919
|
+
if (this.consumer === consumer) this.consumer = void 0;
|
|
29920
|
+
};
|
|
29921
|
+
}
|
|
29922
|
+
watchDeadline(key, at, expired) {
|
|
29923
|
+
if (this.closed || !/^[a-z-]{1,64}$/.test(key) || !Number.isFinite(at)) return;
|
|
29924
|
+
const id2 = "watch:" + key;
|
|
29925
|
+
if (!this.positions.has(id2) && this.heap.filter((value) => value.expired).length >= 8) throw Error("NATIVE_OBSERVER_DEADLINE_LIMIT");
|
|
29926
|
+
this.remove(id2);
|
|
29927
|
+
this.insert({ id: id2, at, expired });
|
|
29928
|
+
this.arm();
|
|
29929
|
+
}
|
|
29930
|
+
cancelDeadline(key) {
|
|
29931
|
+
this.remove("watch:" + key);
|
|
29932
|
+
this.arm();
|
|
29933
|
+
}
|
|
29934
|
+
changed() {
|
|
29935
|
+
try {
|
|
29936
|
+
void Promise.resolve(this.onChange?.()).catch(() => {
|
|
29937
|
+
});
|
|
29938
|
+
} catch {
|
|
29939
|
+
}
|
|
29940
|
+
try {
|
|
29941
|
+
this.consumer?.();
|
|
29942
|
+
} catch {
|
|
29943
|
+
}
|
|
29944
|
+
}
|
|
29945
|
+
incident(code, id2, severity, at) {
|
|
29946
|
+
const fingerprint3 = nativeFingerprint(code, id2), old = this.incidents.get(fingerprint3);
|
|
29947
|
+
const incident = {
|
|
29948
|
+
fingerprint: fingerprint3,
|
|
29949
|
+
...id2 ? { executionId: id2 } : {},
|
|
29950
|
+
code,
|
|
29951
|
+
severity,
|
|
29952
|
+
state: "open",
|
|
29953
|
+
generation: old?.state === "open" ? old.generation : ++this.generation,
|
|
29954
|
+
firstSeen: old?.state === "open" ? old.firstSeen : at,
|
|
29955
|
+
lastSeen: at,
|
|
29956
|
+
count: old?.state === "open" ? Math.min(Number.MAX_SAFE_INTEGER, old.count + 1) : 1
|
|
29957
|
+
};
|
|
29958
|
+
this.incidents.delete(fingerprint3);
|
|
29959
|
+
this.incidents.set(fingerprint3, incident);
|
|
29960
|
+
if (this.incidents.size > 128) {
|
|
29961
|
+
this.incidents.delete(this.incidents.keys().next().value);
|
|
29962
|
+
this.omitted++;
|
|
29963
|
+
}
|
|
29964
|
+
this.buffer.record({ kind: old?.state === "open" ? "incident_update" : "incident_open", fingerprint: fingerprint3, incident }, at);
|
|
29965
|
+
}
|
|
29966
|
+
resolve(id2, at, code) {
|
|
29967
|
+
for (const incident of this.incidents.values()) {
|
|
29968
|
+
if (incident.executionId !== id2 || incident.state !== "open" || code && incident.code !== code) continue;
|
|
29969
|
+
incident.state = "resolved";
|
|
29970
|
+
incident.lastSeen = at;
|
|
29971
|
+
this.buffer.record({ kind: "incident_resolved", fingerprint: incident.fingerprint, incident }, at);
|
|
29972
|
+
}
|
|
29973
|
+
}
|
|
29974
|
+
swap(a, b) {
|
|
29975
|
+
[this.heap[a], this.heap[b]] = [this.heap[b], this.heap[a]];
|
|
29976
|
+
this.positions.set(this.heap[a].id, a);
|
|
29977
|
+
this.positions.set(this.heap[b].id, b);
|
|
29978
|
+
}
|
|
29979
|
+
up(index) {
|
|
29980
|
+
while (index > 0) {
|
|
29981
|
+
const parent = index - 1 >> 1;
|
|
29982
|
+
if (this.heap[parent].at <= this.heap[index].at) break;
|
|
29983
|
+
this.swap(parent, index);
|
|
29984
|
+
index = parent;
|
|
29985
|
+
}
|
|
29986
|
+
return index;
|
|
29987
|
+
}
|
|
29988
|
+
down(index) {
|
|
29989
|
+
for (; ; ) {
|
|
29990
|
+
let next = index, left = index * 2 + 1, right = left + 1;
|
|
29991
|
+
if (left < this.heap.length && this.heap[left].at < this.heap[next].at) next = left;
|
|
29992
|
+
if (right < this.heap.length && this.heap[right].at < this.heap[next].at) next = right;
|
|
29993
|
+
if (next === index) return;
|
|
29994
|
+
this.swap(index, next);
|
|
29995
|
+
index = next;
|
|
29996
|
+
}
|
|
29997
|
+
}
|
|
29998
|
+
insert(deadline) {
|
|
29999
|
+
this.positions.set(deadline.id, this.heap.length);
|
|
30000
|
+
this.heap.push(deadline);
|
|
30001
|
+
this.up(this.heap.length - 1);
|
|
30002
|
+
}
|
|
30003
|
+
remove(id2) {
|
|
30004
|
+
const index = this.positions.get(id2);
|
|
30005
|
+
if (index === void 0) return;
|
|
30006
|
+
const last = this.heap.pop();
|
|
30007
|
+
this.positions.delete(id2);
|
|
30008
|
+
if (index < this.heap.length) {
|
|
30009
|
+
this.heap[index] = last;
|
|
30010
|
+
this.positions.set(last.id, index);
|
|
30011
|
+
this.down(this.up(index));
|
|
30012
|
+
}
|
|
30013
|
+
}
|
|
30014
|
+
arm() {
|
|
30015
|
+
clearTimeout(this.timer);
|
|
30016
|
+
this.timer = void 0;
|
|
30017
|
+
if (this.closed || !this.heap.length) return;
|
|
30018
|
+
this.timer = setTimeout(() => {
|
|
30019
|
+
this.timer = void 0;
|
|
30020
|
+
try {
|
|
30021
|
+
const at = Date.now();
|
|
30022
|
+
let observed = false;
|
|
30023
|
+
while (this.heap.length && this.heap[0].at <= at) {
|
|
30024
|
+
const deadline = this.heap[0], id2 = deadline.id;
|
|
30025
|
+
this.remove(id2);
|
|
30026
|
+
if (deadline.expired) {
|
|
30027
|
+
try {
|
|
30028
|
+
deadline.expired();
|
|
30029
|
+
} catch {
|
|
30030
|
+
}
|
|
30031
|
+
continue;
|
|
30032
|
+
}
|
|
30033
|
+
const state = this.active.get(id2);
|
|
30034
|
+
if (state) {
|
|
30035
|
+
observed = true;
|
|
30036
|
+
this.incident(state === "queued" || state === "prepared" ? "LOCAL_ADMISSION_OVERDUE" : "LOCAL_EXECUTION_OVERDUE", id2, state === "queued" || state === "prepared" ? "warning" : "error", at);
|
|
30037
|
+
}
|
|
30038
|
+
}
|
|
30039
|
+
if (observed) this.changed();
|
|
30040
|
+
} catch {
|
|
30041
|
+
} finally {
|
|
30042
|
+
this.arm();
|
|
30043
|
+
}
|
|
30044
|
+
}, Math.min(2147483647, Math.max(1, this.heap[0].at - Date.now())));
|
|
30045
|
+
this.timer.unref();
|
|
30046
|
+
}
|
|
30047
|
+
snapshot() {
|
|
30048
|
+
return {
|
|
30049
|
+
active: this.active.size,
|
|
30050
|
+
deadlines: this.heap.length,
|
|
30051
|
+
timerArmed: !!this.timer,
|
|
30052
|
+
pendingEvents: this.buffer.size,
|
|
30053
|
+
omitted: this.omitted,
|
|
30054
|
+
incidents: [...this.incidents.values()].map((value) => ({ ...value }))
|
|
30055
|
+
};
|
|
30056
|
+
}
|
|
30057
|
+
close() {
|
|
30058
|
+
this.closed = true;
|
|
30059
|
+
clearTimeout(this.timer);
|
|
30060
|
+
this.timer = void 0;
|
|
30061
|
+
this.heap.length = 0;
|
|
30062
|
+
this.positions.clear();
|
|
30063
|
+
this.active.clear();
|
|
30064
|
+
this.consumer = void 0;
|
|
30065
|
+
}
|
|
30066
|
+
};
|
|
30067
|
+
|
|
30068
|
+
// agent/src/native-fabric-observer.ts
|
|
30069
|
+
var uuid19 = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
30070
|
+
var NativeFabricObserver = class {
|
|
30071
|
+
constructor(supervisor, source) {
|
|
30072
|
+
this.supervisor = supervisor;
|
|
30073
|
+
this.source = source;
|
|
30074
|
+
try {
|
|
30075
|
+
this.unsubscribe = source.subscribe?.(() => this.activity());
|
|
30076
|
+
} catch {
|
|
30077
|
+
}
|
|
30078
|
+
}
|
|
30079
|
+
supervisor;
|
|
30080
|
+
source;
|
|
30081
|
+
referencesByExecution = /* @__PURE__ */ new Map();
|
|
30082
|
+
reportedExpired = /* @__PURE__ */ new Set();
|
|
30083
|
+
deviceId;
|
|
30084
|
+
generation = 0;
|
|
30085
|
+
reading = false;
|
|
30086
|
+
dirty = false;
|
|
30087
|
+
closed = false;
|
|
30088
|
+
unsubscribe;
|
|
30089
|
+
connected(authenticatedDeviceId) {
|
|
30090
|
+
this.disconnected();
|
|
30091
|
+
if (uuid19.test(authenticatedDeviceId)) this.deviceId = authenticatedDeviceId.toLowerCase();
|
|
30092
|
+
this.activity();
|
|
30093
|
+
}
|
|
30094
|
+
disconnected() {
|
|
30095
|
+
this.deviceId = void 0;
|
|
30096
|
+
this.generation++;
|
|
30097
|
+
this.referencesByExecution.clear();
|
|
30098
|
+
this.supervisor.cancelDeadline("fabric-expiry");
|
|
30099
|
+
this.supervisor.cancelDeadline("fabric-read");
|
|
30100
|
+
}
|
|
30101
|
+
references(executionId) {
|
|
30102
|
+
const refs = this.referencesByExecution.get(executionId.toLowerCase());
|
|
30103
|
+
return refs && { ...refs };
|
|
30104
|
+
}
|
|
30105
|
+
activity() {
|
|
30106
|
+
if (this.closed || !this.deviceId) return;
|
|
30107
|
+
this.dirty = true;
|
|
30108
|
+
if (this.reading) return;
|
|
30109
|
+
this.reading = true;
|
|
30110
|
+
this.dirty = false;
|
|
30111
|
+
const generation = this.generation, deviceId = this.deviceId;
|
|
30112
|
+
let expired = false;
|
|
30113
|
+
try {
|
|
30114
|
+
this.supervisor.watchDeadline("fabric-read", Date.now() + 5e3, () => {
|
|
30115
|
+
expired = true;
|
|
30116
|
+
this.referencesByExecution.clear();
|
|
30117
|
+
this.supervisor.cancelDeadline("fabric-expiry");
|
|
30118
|
+
});
|
|
30119
|
+
} catch {
|
|
30120
|
+
this.reading = false;
|
|
30121
|
+
return;
|
|
30122
|
+
}
|
|
30123
|
+
void Promise.resolve().then(() => this.source.mailbox.snapshot()).then((state) => {
|
|
30124
|
+
if (this.closed || expired || generation !== this.generation) return;
|
|
30125
|
+
if (state.workers.length > 64 || state.assignments.length > 256 || state.messages.length > 1024) throw Error("FABRIC_BOUND_INVALID");
|
|
30126
|
+
const workers = new Set(state.workers.filter((w) => w.device?.deviceId.toLowerCase() === deviceId && uuid19.test(w.workerId)).map((w) => w.workerId));
|
|
30127
|
+
const assignments = new Map(state.assignments.filter((a) => workers.has(a.workerId)).map((a) => [a.assignmentId, a]));
|
|
30128
|
+
const refs = /* @__PURE__ */ new Map();
|
|
30129
|
+
for (const a of assignments.values()) {
|
|
30130
|
+
const id2 = a.execution?.executionId;
|
|
30131
|
+
if (!id2 || !uuid19.test(id2)) continue;
|
|
30132
|
+
if (refs.has(id2.toLowerCase())) throw Error("FABRIC_EXECUTION_CONFLICT");
|
|
30133
|
+
refs.set(id2.toLowerCase(), {
|
|
30134
|
+
executionId: id2.toLowerCase(),
|
|
30135
|
+
workerId: a.workerId.toLowerCase(),
|
|
30136
|
+
...uuid19.test(a.taskId) ? { taskId: a.taskId.toLowerCase() } : {}
|
|
30137
|
+
});
|
|
30138
|
+
}
|
|
30139
|
+
this.referencesByExecution.clear();
|
|
30140
|
+
for (const [id2, value] of refs) this.referencesByExecution.set(id2, value);
|
|
30141
|
+
const retained = new Set(state.messages.map((m) => m.messageId));
|
|
30142
|
+
for (const id2 of this.reportedExpired) if (!retained.has(id2)) this.reportedExpired.delete(id2);
|
|
30143
|
+
const now = Date.now();
|
|
30144
|
+
let next;
|
|
30145
|
+
for (const m of state.messages) {
|
|
30146
|
+
const a = assignments.get(m.assignmentId), expiry = Date.parse(m.expiresAt);
|
|
30147
|
+
if (!a || m.acknowledgedAt || !Number.isFinite(expiry)) continue;
|
|
30148
|
+
if (expiry > now) {
|
|
30149
|
+
next = next === void 0 ? expiry : Math.min(next, expiry);
|
|
30150
|
+
continue;
|
|
30151
|
+
}
|
|
30152
|
+
if (this.reportedExpired.has(m.messageId)) continue;
|
|
30153
|
+
this.reportedExpired.add(m.messageId);
|
|
30154
|
+
this.supervisor.observe({ kind: "mailbox_expired", code: "MAILBOX_EXPIRED" });
|
|
30155
|
+
try {
|
|
30156
|
+
void Promise.resolve(this.source.onExpired?.({ workerId: a.workerId, assignmentId: a.assignmentId, messageId: m.messageId })).catch(() => {
|
|
30157
|
+
});
|
|
30158
|
+
} catch {
|
|
30159
|
+
}
|
|
30160
|
+
}
|
|
30161
|
+
if (next === void 0) this.supervisor.cancelDeadline("fabric-expiry");
|
|
30162
|
+
else this.supervisor.watchDeadline("fabric-expiry", next, () => this.activity());
|
|
30163
|
+
}).catch(() => {
|
|
30164
|
+
if (generation === this.generation) {
|
|
30165
|
+
this.referencesByExecution.clear();
|
|
30166
|
+
this.supervisor.cancelDeadline("fabric-expiry");
|
|
30167
|
+
}
|
|
30168
|
+
}).finally(() => {
|
|
30169
|
+
this.reading = false;
|
|
30170
|
+
if (generation === this.generation) this.supervisor.cancelDeadline("fabric-read");
|
|
30171
|
+
if (this.dirty) this.activity();
|
|
30172
|
+
});
|
|
30173
|
+
}
|
|
30174
|
+
snapshot() {
|
|
30175
|
+
return { references: this.referencesByExecution.size, reading: this.reading, reportedExpired: this.reportedExpired.size };
|
|
30176
|
+
}
|
|
30177
|
+
close() {
|
|
30178
|
+
this.closed = true;
|
|
30179
|
+
this.disconnected();
|
|
30180
|
+
try {
|
|
30181
|
+
this.unsubscribe?.();
|
|
30182
|
+
} catch {
|
|
30183
|
+
}
|
|
30184
|
+
}
|
|
30185
|
+
};
|
|
30186
|
+
|
|
30187
|
+
// agent/src/native-fabric-startup.ts
|
|
30188
|
+
import { lstat as lstat9, mkdir as mkdir8, open as open8, readFile as readFile5 } from "node:fs/promises";
|
|
30189
|
+
import path16 from "node:path";
|
|
30190
|
+
|
|
30191
|
+
// src/agent-fabric-service.ts
|
|
30192
|
+
import { lstat as lstat8, mkdir as mkdir7, realpath as realpath7 } from "node:fs/promises";
|
|
30193
|
+
import { watch } from "node:fs";
|
|
30194
|
+
import path15 from "node:path";
|
|
30195
|
+
|
|
30196
|
+
// src/agent-runtime-identity.ts
|
|
30197
|
+
import { createHash as createHash12, randomBytes as randomBytes4, randomUUID as randomUUID10, timingSafeEqual as timingSafeEqual2 } from "node:crypto";
|
|
30198
|
+
|
|
30199
|
+
// src/agent-fabric-state.ts
|
|
30200
|
+
import { randomUUID as randomUUID9 } from "node:crypto";
|
|
30201
|
+
import { mkdir as mkdir6, open as open7, rename as rename5, unlink } from "node:fs/promises";
|
|
30202
|
+
import path14 from "node:path";
|
|
30203
|
+
var queues = /* @__PURE__ */ new Map();
|
|
30204
|
+
var FabricStateFile = class {
|
|
30205
|
+
constructor(file2, maxBytes, parse3) {
|
|
30206
|
+
this.maxBytes = maxBytes;
|
|
30207
|
+
this.parse = parse3;
|
|
30208
|
+
this.file = path14.resolve(file2);
|
|
30209
|
+
}
|
|
30210
|
+
maxBytes;
|
|
30211
|
+
parse;
|
|
30212
|
+
file;
|
|
30213
|
+
serial(fn) {
|
|
30214
|
+
const key = process.platform === "win32" ? this.file.toLowerCase() : this.file;
|
|
30215
|
+
const result2 = (queues.get(key) ?? Promise.resolve()).then(fn);
|
|
30216
|
+
const tail = result2.then(() => {
|
|
30217
|
+
}, () => {
|
|
30218
|
+
});
|
|
30219
|
+
queues.set(key, tail);
|
|
30220
|
+
void tail.then(() => {
|
|
30221
|
+
if (queues.get(key) === tail) queues.delete(key);
|
|
30222
|
+
});
|
|
30223
|
+
return result2;
|
|
30224
|
+
}
|
|
30225
|
+
async load() {
|
|
30226
|
+
const handle = await open7(this.file, "r");
|
|
30227
|
+
try {
|
|
30228
|
+
const info = await handle.stat();
|
|
30229
|
+
if (!info.isFile() || info.size > this.maxBytes) throw Error("FABRIC_STATE_LIMIT");
|
|
30230
|
+
const bytes3 = Buffer.alloc(this.maxBytes + 1);
|
|
30231
|
+
let length = 0;
|
|
30232
|
+
while (length < bytes3.length) {
|
|
30233
|
+
const read = await handle.read(bytes3, length, bytes3.length - length, null);
|
|
30234
|
+
if (!read.bytesRead) break;
|
|
30235
|
+
length += read.bytesRead;
|
|
30236
|
+
}
|
|
30237
|
+
if (length > this.maxBytes) throw Error("FABRIC_STATE_LIMIT");
|
|
30238
|
+
try {
|
|
30239
|
+
return this.parse(JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes3.subarray(0, length))));
|
|
30240
|
+
} catch {
|
|
30241
|
+
throw Error("FABRIC_STATE_CORRUPT");
|
|
30242
|
+
}
|
|
30243
|
+
} finally {
|
|
30244
|
+
await handle.close();
|
|
30245
|
+
}
|
|
30246
|
+
}
|
|
30247
|
+
read() {
|
|
30248
|
+
return this.serial(() => this.load());
|
|
30249
|
+
}
|
|
30250
|
+
update(fn, create) {
|
|
30251
|
+
return this.serial(async () => {
|
|
30252
|
+
if (create) await mkdir6(path14.dirname(this.file), { recursive: true });
|
|
30253
|
+
const lockPath = this.file + ".lock";
|
|
30254
|
+
const token = randomUUID9();
|
|
30255
|
+
const lock = await open7(lockPath, "wx", 384).catch((error62) => {
|
|
30256
|
+
if (error62.code === "EEXIST") throw Error("FABRIC_STATE_BUSY");
|
|
30257
|
+
throw error62;
|
|
30258
|
+
});
|
|
30259
|
+
try {
|
|
30260
|
+
await lock.writeFile(JSON.stringify({ token, pid: process.pid, createdAt: (/* @__PURE__ */ new Date()).toISOString() }));
|
|
30261
|
+
await lock.datasync();
|
|
30262
|
+
let state;
|
|
30263
|
+
try {
|
|
30264
|
+
state = await this.load();
|
|
30265
|
+
} catch (error62) {
|
|
30266
|
+
if (error62.code !== "ENOENT" || !create) throw error62;
|
|
30267
|
+
state = create();
|
|
30268
|
+
}
|
|
30269
|
+
const result2 = await fn(state);
|
|
30270
|
+
const encoded = JSON.stringify(this.parse(state));
|
|
30271
|
+
if (Buffer.byteLength(encoded) > this.maxBytes) throw Error("FABRIC_STATE_LIMIT");
|
|
30272
|
+
const temporary = this.file + "." + token + ".tmp";
|
|
30273
|
+
const handle = await open7(temporary, "wx", 384);
|
|
30274
|
+
try {
|
|
30275
|
+
try {
|
|
30276
|
+
await handle.writeFile(encoded, "utf8");
|
|
30277
|
+
await handle.datasync();
|
|
30278
|
+
} finally {
|
|
30279
|
+
await handle.close();
|
|
30280
|
+
}
|
|
30281
|
+
await rename5(temporary, this.file);
|
|
30282
|
+
} finally {
|
|
30283
|
+
await unlink(temporary).catch((error62) => {
|
|
30284
|
+
if (error62.code !== "ENOENT") throw error62;
|
|
30285
|
+
});
|
|
30286
|
+
}
|
|
30287
|
+
return result2;
|
|
30288
|
+
} finally {
|
|
30289
|
+
await lock.close();
|
|
30290
|
+
const current2 = await open7(lockPath, "r");
|
|
30291
|
+
try {
|
|
30292
|
+
if ((await current2.stat()).size > 1024 || JSON.parse(await current2.readFile("utf8")).token !== token)
|
|
30293
|
+
throw Error("FABRIC_STATE_LOCK_CHANGED");
|
|
30294
|
+
} finally {
|
|
30295
|
+
await current2.close();
|
|
30296
|
+
}
|
|
30297
|
+
await unlink(lockPath);
|
|
30298
|
+
}
|
|
30299
|
+
});
|
|
30300
|
+
}
|
|
30301
|
+
};
|
|
30302
|
+
|
|
30303
|
+
// src/agent-runtime-identity.ts
|
|
30304
|
+
var id = external_exports.string().regex(/^rt-[0-9a-f-]{36}$/);
|
|
30305
|
+
var hash6 = external_exports.string().regex(/^[a-f0-9]{64}$/);
|
|
30306
|
+
var MAX_BINDINGS = 128;
|
|
30307
|
+
var MAX_BYTES = 128 * 1024;
|
|
30308
|
+
var BindingSchema = external_exports.strictObject({
|
|
30309
|
+
runtimeId: id,
|
|
30310
|
+
keyHash: hash6,
|
|
30311
|
+
createdAt: external_exports.number().int().positive(),
|
|
30312
|
+
lastUsedAt: external_exports.number().int().positive(),
|
|
30313
|
+
revoked: external_exports.boolean()
|
|
30314
|
+
});
|
|
30315
|
+
var StateSchema = external_exports.strictObject({
|
|
30316
|
+
version: external_exports.literal(1),
|
|
30317
|
+
bindings: external_exports.array(BindingSchema).max(MAX_BINDINGS)
|
|
30318
|
+
});
|
|
30319
|
+
function digest4(value) {
|
|
30320
|
+
return createHash12("sha256").update(value, "utf8").digest();
|
|
30321
|
+
}
|
|
30322
|
+
function encodedDigest(value) {
|
|
30323
|
+
return digest4(value).toString("hex");
|
|
30324
|
+
}
|
|
30325
|
+
function validKey(value) {
|
|
30326
|
+
return typeof value === "string" && /^[A-Za-z0-9_-]{43}$/.test(value);
|
|
30327
|
+
}
|
|
30328
|
+
var AgentRuntimeIdentityStore = class {
|
|
30329
|
+
constructor(file2, now = Date.now) {
|
|
30330
|
+
this.now = now;
|
|
30331
|
+
this.state = new FabricStateFile(file2, MAX_BYTES, (value) => {
|
|
30332
|
+
const state = StateSchema.parse(value);
|
|
30333
|
+
if (new Set(state.bindings.map((item) => item.runtimeId)).size !== state.bindings.length)
|
|
30334
|
+
throw Error("RUNTIME_IDENTITY_STATE_CORRUPT");
|
|
30335
|
+
return state;
|
|
30336
|
+
});
|
|
30337
|
+
}
|
|
30338
|
+
now;
|
|
30339
|
+
state;
|
|
30340
|
+
serial(fn) {
|
|
30341
|
+
return this.state.update(fn, () => ({ version: 1, bindings: [] })).catch((error62) => {
|
|
30342
|
+
if (error62 instanceof Error && error62.message.startsWith("FABRIC_STATE_"))
|
|
30343
|
+
throw Error(error62.message.replace("FABRIC_STATE_", "RUNTIME_IDENTITY_STATE_"));
|
|
30344
|
+
throw error62;
|
|
30345
|
+
});
|
|
30346
|
+
}
|
|
30347
|
+
issue() {
|
|
30348
|
+
return this.serial((state) => {
|
|
30349
|
+
if (state.bindings.length >= MAX_BINDINGS) throw Error("RUNTIME_IDENTITY_LIMIT");
|
|
30350
|
+
const runtimeId = "rt-" + randomUUID10();
|
|
30351
|
+
const runtimeKey = randomBytes4(32).toString("base64url");
|
|
30352
|
+
const now = this.now();
|
|
30353
|
+
state.bindings.push({ runtimeId, keyHash: encodedDigest(runtimeKey), createdAt: now, lastUsedAt: now, revoked: false });
|
|
30354
|
+
return { runtimeId, runtimeKey };
|
|
30355
|
+
});
|
|
30356
|
+
}
|
|
30357
|
+
authenticate(runtimeId, runtimeKey) {
|
|
30358
|
+
return this.serial((state) => {
|
|
30359
|
+
if (!id.safeParse(runtimeId).success || !validKey(runtimeKey)) throw Error("RUNTIME_IDENTITY_INVALID");
|
|
30360
|
+
const binding2 = state.bindings.find((item) => item.runtimeId === runtimeId);
|
|
30361
|
+
if (!binding2 || binding2.revoked) throw Error("RUNTIME_IDENTITY_DENIED");
|
|
30362
|
+
const expected = Buffer.from(binding2.keyHash, "hex");
|
|
30363
|
+
const actual = digest4(runtimeKey);
|
|
30364
|
+
if (expected.length !== actual.length || !timingSafeEqual2(expected, actual)) throw Error("RUNTIME_IDENTITY_DENIED");
|
|
30365
|
+
binding2.lastUsedAt = this.now();
|
|
30366
|
+
});
|
|
30367
|
+
}
|
|
30368
|
+
revoke(runtimeId, runtimeKey) {
|
|
30369
|
+
return this.serial((state) => {
|
|
30370
|
+
if (!id.safeParse(runtimeId).success || !validKey(runtimeKey)) throw Error("RUNTIME_IDENTITY_INVALID");
|
|
30371
|
+
const binding2 = state.bindings.find((item) => item.runtimeId === runtimeId);
|
|
30372
|
+
if (!binding2 || binding2.revoked) throw Error("RUNTIME_IDENTITY_DENIED");
|
|
30373
|
+
const expected = Buffer.from(binding2.keyHash, "hex");
|
|
30374
|
+
const actual = digest4(runtimeKey);
|
|
30375
|
+
if (expected.length !== actual.length || !timingSafeEqual2(expected, actual)) throw Error("RUNTIME_IDENTITY_DENIED");
|
|
30376
|
+
binding2.revoked = true;
|
|
30377
|
+
binding2.lastUsedAt = this.now();
|
|
30378
|
+
});
|
|
30379
|
+
}
|
|
30380
|
+
};
|
|
30381
|
+
|
|
30382
|
+
// src/agent-fabric-mailbox.ts
|
|
30383
|
+
import { randomUUID as randomUUID12 } from "node:crypto";
|
|
30384
|
+
|
|
30385
|
+
// src/agent-fabric-timeline.ts
|
|
30386
|
+
import { randomUUID as randomUUID11 } from "node:crypto";
|
|
30387
|
+
import { performance } from "node:perf_hooks";
|
|
30388
|
+
var FabricId = external_exports.string().regex(/^[A-Za-z0-9][A-Za-z0-9_.:-]{0,95}$/);
|
|
30389
|
+
var FabricUtc = external_exports.string().datetime({ precision: 3 }).refine((value) => new Date(value).toISOString() === value);
|
|
30390
|
+
var FabricStampSchema = external_exports.strictObject({
|
|
30391
|
+
atUtc: FabricUtc,
|
|
30392
|
+
clockId: FabricId,
|
|
30393
|
+
monotonicMs: external_exports.number().finite().nonnegative().max(Number.MAX_SAFE_INTEGER)
|
|
30394
|
+
});
|
|
30395
|
+
var processClockId = "clock-" + randomUUID11();
|
|
30396
|
+
function createFabricClock() {
|
|
30397
|
+
return () => ({ atUtc: (/* @__PURE__ */ new Date()).toISOString(), clockId: processClockId, monotonicMs: performance.now() });
|
|
30398
|
+
}
|
|
30399
|
+
var FABRIC_STAGES = ["admitted", "queued", "worker_started", "execution_started", "execution_finished", "result_received", "result_delivered"];
|
|
30400
|
+
var MarkSchema = external_exports.strictObject({
|
|
30401
|
+
stamp: FabricStampSchema,
|
|
30402
|
+
source: external_exports.enum(["cloud", "controller", "native", "adapter"]),
|
|
30403
|
+
evidenceRef: FabricId
|
|
30404
|
+
});
|
|
30405
|
+
var FabricTimelineSchema = external_exports.strictObject({
|
|
30406
|
+
admitted: MarkSchema.nullable().default(null),
|
|
30407
|
+
queued: MarkSchema.nullable().default(null),
|
|
30408
|
+
worker_started: MarkSchema.nullable().default(null),
|
|
30409
|
+
execution_started: MarkSchema.nullable().default(null),
|
|
30410
|
+
execution_finished: MarkSchema.nullable().default(null),
|
|
30411
|
+
result_received: MarkSchema.nullable().default(null),
|
|
30412
|
+
result_delivered: MarkSchema.nullable().default(null)
|
|
30413
|
+
});
|
|
30414
|
+
function markFabricTimeline(timeline, stage, input2) {
|
|
30415
|
+
if (!FABRIC_STAGES.includes(stage)) throw Error("FABRIC_TIMING_STAGE_INVALID");
|
|
30416
|
+
const mark = MarkSchema.parse(input2), previous = timeline[stage];
|
|
30417
|
+
if (previous) {
|
|
30418
|
+
if (JSON.stringify(previous) !== JSON.stringify(mark)) throw Error("FABRIC_TIMING_CONFLICT");
|
|
30419
|
+
return;
|
|
30420
|
+
}
|
|
30421
|
+
const next = { ...timeline, [stage]: mark };
|
|
30422
|
+
const clocks = /* @__PURE__ */ new Map();
|
|
30423
|
+
for (const name2 of FABRIC_STAGES) {
|
|
30424
|
+
const stamp = next[name2]?.stamp;
|
|
30425
|
+
if (!stamp) continue;
|
|
30426
|
+
const before = clocks.get(stamp.clockId);
|
|
30427
|
+
if (before !== void 0 && stamp.monotonicMs < before) throw Error("FABRIC_TIMING_ORDER_INVALID");
|
|
30428
|
+
clocks.set(stamp.clockId, stamp.monotonicMs);
|
|
30429
|
+
}
|
|
30430
|
+
timeline[stage] = mark;
|
|
30431
|
+
}
|
|
30432
|
+
|
|
30433
|
+
// src/controller-runtime-router.ts
|
|
30434
|
+
var LOCAL_RUNTIME_PROVIDERS = ["chatgpt", "claude", "cursor"];
|
|
30435
|
+
|
|
30436
|
+
// src/agent-fabric-worker.ts
|
|
30437
|
+
var fact = (value) => external_exports.strictObject({
|
|
30438
|
+
value,
|
|
30439
|
+
confirmedAt: FabricUtc,
|
|
30440
|
+
evidenceRef: FabricId,
|
|
30441
|
+
source: external_exports.enum(["registered_integration", "adapter_receipt"])
|
|
30442
|
+
});
|
|
30443
|
+
var WorkerAttributionSchema = external_exports.strictObject({
|
|
30444
|
+
provider: fact(external_exports.enum(["openai", "anthropic", "cursor"])).nullable().default(null),
|
|
30445
|
+
runtime: fact(external_exports.enum(["codex", "claude-code", "cursor-agent"])).nullable().default(null),
|
|
30446
|
+
model: fact(external_exports.string().regex(/^[A-Za-z0-9][A-Za-z0-9_.:/-]{0,127}$/)).nullable().default(null)
|
|
30447
|
+
});
|
|
30448
|
+
var FabricWorkerSchema = external_exports.strictObject({
|
|
30449
|
+
workerId: external_exports.string().uuid(),
|
|
30450
|
+
key: FabricId,
|
|
30451
|
+
controllerId: FabricId,
|
|
30452
|
+
parentWorkerId: external_exports.string().uuid().nullable(),
|
|
30453
|
+
device: external_exports.strictObject({ deviceId: FabricId, enrollmentEvidenceRef: FabricId }).nullable(),
|
|
30454
|
+
runtimeId: external_exports.string().regex(/^rt-[0-9a-f-]{36}$/).nullable(),
|
|
30455
|
+
attribution: WorkerAttributionSchema,
|
|
30456
|
+
createdAt: FabricUtc,
|
|
30457
|
+
updatedAt: FabricUtc
|
|
30458
|
+
});
|
|
30459
|
+
var FabricPayloadRefSchema = external_exports.strictObject({
|
|
30460
|
+
id: FabricId,
|
|
30461
|
+
sha256: external_exports.string().regex(/^[a-f0-9]{64}$/),
|
|
30462
|
+
bytes: external_exports.number().int().min(0).max(4 * 1024 * 1024)
|
|
30463
|
+
});
|
|
30464
|
+
var FabricExecutionLinkSchema = external_exports.strictObject({
|
|
30465
|
+
sessionId: FabricId.nullable(),
|
|
30466
|
+
pid: external_exports.number().int().positive().max(4294967295).nullable(),
|
|
30467
|
+
executionId: external_exports.string().uuid().toLowerCase().nullable().default(null),
|
|
30468
|
+
confirmedAt: FabricUtc,
|
|
30469
|
+
evidenceRef: FabricId
|
|
30470
|
+
}).refine((link) => link.sessionId !== null || link.pid !== null || link.executionId !== null);
|
|
30471
|
+
var FabricAssignmentSchema = external_exports.strictObject({
|
|
30472
|
+
assignmentId: external_exports.string().uuid(),
|
|
30473
|
+
workerId: external_exports.string().uuid(),
|
|
30474
|
+
taskId: FabricId,
|
|
30475
|
+
runId: external_exports.string().regex(/^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$/),
|
|
30476
|
+
role: external_exports.enum(["implementer", "verifier"]),
|
|
30477
|
+
selectedRuntime: external_exports.enum(LOCAL_RUNTIME_PROVIDERS),
|
|
30478
|
+
payloadRef: FabricPayloadRefSchema,
|
|
30479
|
+
phase: external_exports.enum(["assigned", "launching", "running", "unknown", "exited", "not_started"]),
|
|
30480
|
+
createdAt: FabricUtc,
|
|
30481
|
+
updatedAt: FabricUtc,
|
|
30482
|
+
timeline: FabricTimelineSchema,
|
|
30483
|
+
attribution: WorkerAttributionSchema,
|
|
30484
|
+
execution: FabricExecutionLinkSchema.nullable()
|
|
30485
|
+
});
|
|
30486
|
+
function assignmentActive(assignment) {
|
|
30487
|
+
return assignment.phase !== "exited" && assignment.phase !== "not_started";
|
|
30488
|
+
}
|
|
30489
|
+
|
|
30490
|
+
// src/agent-fabric-mailbox.ts
|
|
30491
|
+
var MAX_WORKERS = 64;
|
|
30492
|
+
var MAX_ASSIGNMENTS = 256;
|
|
30493
|
+
var MAX_MESSAGES = 1024;
|
|
30494
|
+
var MAX_TTL_MS = 864e5;
|
|
30495
|
+
var Control = external_exports.enum(["CANCEL", "WAKE"]);
|
|
30496
|
+
var Report = external_exports.enum(["PROGRESS", "BLOCKED", "RESULT"]);
|
|
30497
|
+
var MessageSchema = external_exports.strictObject({
|
|
30498
|
+
messageId: external_exports.string().uuid(),
|
|
30499
|
+
key: FabricId,
|
|
30500
|
+
assignmentId: external_exports.string().uuid(),
|
|
30501
|
+
origin: external_exports.enum(["controller", "worker", "adapter"]),
|
|
30502
|
+
direction: external_exports.enum(["to_worker", "to_controller"]),
|
|
30503
|
+
kind: external_exports.enum(["ASSIGN", ...Control.options, ...Report.options]),
|
|
30504
|
+
payloadRef: FabricPayloadRefSchema,
|
|
30505
|
+
createdAt: FabricUtc,
|
|
30506
|
+
expiresAt: FabricUtc,
|
|
30507
|
+
acknowledgedAt: FabricUtc.nullable()
|
|
30508
|
+
});
|
|
30509
|
+
var StateSchema2 = external_exports.strictObject({
|
|
30510
|
+
version: external_exports.literal(2),
|
|
30511
|
+
controllerId: FabricId,
|
|
30512
|
+
workers: external_exports.array(FabricWorkerSchema).max(MAX_WORKERS),
|
|
30513
|
+
assignments: external_exports.array(FabricAssignmentSchema).max(MAX_ASSIGNMENTS),
|
|
30514
|
+
messages: external_exports.array(MessageSchema).max(MAX_MESSAGES)
|
|
30515
|
+
});
|
|
30516
|
+
var Registration = external_exports.strictObject({
|
|
30517
|
+
key: FabricId,
|
|
30518
|
+
parentWorkerId: external_exports.string().uuid().nullable().default(null),
|
|
30519
|
+
device: FabricWorkerSchema.shape.device.default(null)
|
|
30520
|
+
});
|
|
30521
|
+
var AssignmentInput = FabricAssignmentSchema.pick({
|
|
30522
|
+
workerId: true,
|
|
30523
|
+
taskId: true,
|
|
30524
|
+
runId: true,
|
|
30525
|
+
role: true,
|
|
30526
|
+
selectedRuntime: true,
|
|
30527
|
+
payloadRef: true
|
|
30528
|
+
});
|
|
30529
|
+
var MessageInput = external_exports.strictObject({
|
|
30530
|
+
key: FabricId,
|
|
30531
|
+
payloadRef: FabricPayloadRefSchema,
|
|
30532
|
+
ttlMs: external_exports.number().int().min(1e3).max(MAX_TTL_MS).default(6e4)
|
|
30533
|
+
});
|
|
30534
|
+
var ConfirmInput = external_exports.strictObject({
|
|
30535
|
+
provider: WorkerAttributionSchema.shape.provider.removeDefault().optional(),
|
|
30536
|
+
runtime: WorkerAttributionSchema.shape.runtime.removeDefault().optional(),
|
|
30537
|
+
model: WorkerAttributionSchema.shape.model.removeDefault().optional()
|
|
30538
|
+
});
|
|
30539
|
+
function parseState(value) {
|
|
30540
|
+
const state = StateSchema2.parse(value);
|
|
30541
|
+
for (const values of [
|
|
30542
|
+
state.workers.map((w) => w.workerId),
|
|
30543
|
+
state.workers.map((w) => w.key),
|
|
30544
|
+
state.assignments.map((a) => a.assignmentId),
|
|
30545
|
+
state.assignments.map((a) => JSON.stringify([a.runId, a.selectedRuntime])),
|
|
30546
|
+
state.assignments.flatMap((a) => a.execution?.executionId ? [a.execution.executionId] : []),
|
|
30547
|
+
state.messages.map((m) => m.messageId),
|
|
30548
|
+
state.messages.map((m) => JSON.stringify([m.assignmentId, m.origin, m.key]))
|
|
30549
|
+
])
|
|
30550
|
+
if (new Set(values).size !== values.length) throw Error("FABRIC_STATE_CORRUPT");
|
|
30551
|
+
for (const worker of state.workers) {
|
|
30552
|
+
if (worker.controllerId !== state.controllerId) throw Error("FABRIC_STATE_CORRUPT");
|
|
30553
|
+
const seen = /* @__PURE__ */ new Set([worker.workerId]);
|
|
30554
|
+
let parent = worker.parentWorkerId;
|
|
30555
|
+
while (parent) {
|
|
30556
|
+
if (seen.has(parent)) throw Error("FABRIC_STATE_CORRUPT");
|
|
30557
|
+
seen.add(parent);
|
|
30558
|
+
const ancestor2 = state.workers.find((w) => w.workerId === parent);
|
|
30559
|
+
if (!ancestor2) throw Error("FABRIC_STATE_CORRUPT");
|
|
30560
|
+
parent = ancestor2.parentWorkerId;
|
|
30561
|
+
}
|
|
30562
|
+
}
|
|
30563
|
+
const activeWorkers = /* @__PURE__ */ new Set(), activeRuns = /* @__PURE__ */ new Set();
|
|
30564
|
+
for (const assignment of state.assignments) {
|
|
30565
|
+
if (!state.workers.some((w) => w.workerId === assignment.workerId)) throw Error("FABRIC_STATE_CORRUPT");
|
|
30566
|
+
if (assignmentActive(assignment)) {
|
|
30567
|
+
if (activeWorkers.has(assignment.workerId) || activeRuns.has(assignment.runId)) throw Error("FABRIC_STATE_CORRUPT");
|
|
30568
|
+
activeWorkers.add(assignment.workerId);
|
|
30569
|
+
activeRuns.add(assignment.runId);
|
|
30570
|
+
}
|
|
30571
|
+
const validated = FabricTimelineSchema.parse({});
|
|
30572
|
+
for (const [stage, mark] of Object.entries(assignment.timeline))
|
|
30573
|
+
if (mark) markFabricTimeline(validated, stage, mark);
|
|
30574
|
+
}
|
|
30575
|
+
for (const message2 of state.messages) {
|
|
30576
|
+
if (!state.assignments.some((a) => a.assignmentId === message2.assignmentId) || message2.expiresAt <= message2.createdAt || Date.parse(message2.expiresAt) - Date.parse(message2.createdAt) > MAX_TTL_MS || message2.direction === "to_worker" !== ["ASSIGN", "CANCEL", "WAKE"].includes(message2.kind) || message2.direction === "to_worker" !== (message2.origin === "controller") || message2.origin === "adapter" && message2.kind !== "RESULT") throw Error("FABRIC_STATE_CORRUPT");
|
|
30577
|
+
}
|
|
30578
|
+
return state;
|
|
30579
|
+
}
|
|
30580
|
+
var AgentWorkerMailbox = class {
|
|
30581
|
+
constructor(file2, controllerId, identities, clock = createFabricClock(), notify) {
|
|
30582
|
+
this.identities = identities;
|
|
30583
|
+
this.clock = clock;
|
|
30584
|
+
this.notify = notify;
|
|
30585
|
+
this.controllerId = FabricId.parse(controllerId);
|
|
30586
|
+
this.state = new FabricStateFile(file2, 2 * 1024 * 1024, (value) => {
|
|
30587
|
+
const state = parseState(value);
|
|
30588
|
+
if (state.controllerId !== this.controllerId) throw Error("FABRIC_CONTROLLER_MISMATCH");
|
|
30589
|
+
return state;
|
|
30590
|
+
});
|
|
30591
|
+
}
|
|
30592
|
+
identities;
|
|
30593
|
+
clock;
|
|
30594
|
+
notify;
|
|
30595
|
+
state;
|
|
30596
|
+
controllerId;
|
|
30597
|
+
initialize() {
|
|
30598
|
+
let created = false;
|
|
30599
|
+
return this.state.update(() => {
|
|
30600
|
+
if (!created) throw Error("FABRIC_STATE_EXISTS");
|
|
30601
|
+
}, () => {
|
|
30602
|
+
created = true;
|
|
30603
|
+
return { version: 2, controllerId: this.controllerId, workers: [], assignments: [], messages: [] };
|
|
30604
|
+
});
|
|
30605
|
+
}
|
|
30606
|
+
worker(state, id2) {
|
|
30607
|
+
const worker = state.workers.find((w) => w.workerId === id2);
|
|
30608
|
+
if (!worker) throw Error("FABRIC_WORKER_UNKNOWN");
|
|
30609
|
+
return worker;
|
|
30610
|
+
}
|
|
30611
|
+
assignment(state, id2) {
|
|
30612
|
+
const assignment = state.assignments.find((a) => a.assignmentId === id2);
|
|
30613
|
+
if (!assignment) throw Error("FABRIC_ASSIGNMENT_UNKNOWN");
|
|
30614
|
+
return assignment;
|
|
30615
|
+
}
|
|
30616
|
+
bound(state, workerId, credential) {
|
|
30617
|
+
const worker = this.worker(state, workerId);
|
|
30618
|
+
if (worker.runtimeId !== credential.runtimeId) throw Error("FABRIC_WORKER_DENIED");
|
|
30619
|
+
return worker;
|
|
30620
|
+
}
|
|
30621
|
+
emit(state, message2) {
|
|
30622
|
+
const assignment = this.assignment(state, message2.assignmentId);
|
|
30623
|
+
try {
|
|
30624
|
+
void Promise.resolve(this.notify?.({
|
|
30625
|
+
controllerId: this.controllerId,
|
|
30626
|
+
workerId: assignment.workerId,
|
|
30627
|
+
assignmentId: assignment.assignmentId,
|
|
30628
|
+
messageId: message2.messageId,
|
|
30629
|
+
direction: message2.direction,
|
|
30630
|
+
kind: message2.kind,
|
|
30631
|
+
origin: message2.origin,
|
|
30632
|
+
expiresAt: message2.expiresAt
|
|
30633
|
+
})).catch(() => {
|
|
30634
|
+
});
|
|
30635
|
+
} catch {
|
|
30636
|
+
}
|
|
30637
|
+
}
|
|
30638
|
+
register(input2) {
|
|
30639
|
+
const registration = Registration.parse(input2);
|
|
30640
|
+
return this.state.update((state) => {
|
|
30641
|
+
const existing = state.workers.find((w) => w.key === registration.key);
|
|
30642
|
+
if (existing) {
|
|
30643
|
+
if (existing.parentWorkerId !== registration.parentWorkerId || JSON.stringify(existing.device) !== JSON.stringify(registration.device))
|
|
30644
|
+
throw Error("FABRIC_WORKER_ID_CONFLICT");
|
|
30645
|
+
return existing;
|
|
30646
|
+
}
|
|
30647
|
+
if (state.workers.length >= MAX_WORKERS) throw Error("FABRIC_WORKER_LIMIT");
|
|
30648
|
+
if (registration.parentWorkerId) this.worker(state, registration.parentWorkerId);
|
|
30649
|
+
const now = this.clock().atUtc;
|
|
30650
|
+
const worker = {
|
|
30651
|
+
...registration,
|
|
30652
|
+
workerId: randomUUID12(),
|
|
30653
|
+
controllerId: this.controllerId,
|
|
30654
|
+
runtimeId: null,
|
|
30655
|
+
attribution: WorkerAttributionSchema.parse({}),
|
|
30656
|
+
createdAt: now,
|
|
30657
|
+
updatedAt: now
|
|
30658
|
+
};
|
|
30659
|
+
state.workers.push(worker);
|
|
30660
|
+
return worker;
|
|
30661
|
+
});
|
|
30662
|
+
}
|
|
30663
|
+
async bindRuntime(workerId, credential) {
|
|
30664
|
+
await this.identities.authenticate(credential.runtimeId, credential.runtimeKey);
|
|
30665
|
+
await this.state.update((state) => {
|
|
30666
|
+
const worker = this.worker(state, workerId);
|
|
30667
|
+
if (worker.runtimeId !== credential.runtimeId) {
|
|
30668
|
+
worker.runtimeId = credential.runtimeId;
|
|
30669
|
+
worker.attribution = WorkerAttributionSchema.parse({});
|
|
30670
|
+
worker.updatedAt = this.clock().atUtc;
|
|
30671
|
+
}
|
|
30672
|
+
});
|
|
30673
|
+
}
|
|
30674
|
+
append(state, assignment, kind, origin, input2) {
|
|
30675
|
+
const request = MessageInput.parse(input2);
|
|
30676
|
+
const direction = origin === "controller" ? "to_worker" : "to_controller";
|
|
30677
|
+
if (kind === "RESULT" && request.key !== "result") throw Error("FABRIC_RESULT_KEY_INVALID");
|
|
30678
|
+
const existing = state.messages.find((m) => m.assignmentId === assignment.assignmentId && m.origin === origin && m.key === request.key);
|
|
30679
|
+
if (existing) {
|
|
30680
|
+
if (existing.kind !== kind || JSON.stringify(existing.payloadRef) !== JSON.stringify(request.payloadRef) || Date.parse(existing.expiresAt) - Date.parse(existing.createdAt) !== request.ttlMs) throw Error("FABRIC_MESSAGE_ID_CONFLICT");
|
|
30681
|
+
return { message: existing, added: false };
|
|
30682
|
+
}
|
|
30683
|
+
if (state.messages.length >= MAX_MESSAGES) throw Error("FABRIC_MESSAGE_LIMIT");
|
|
30684
|
+
const now = this.clock();
|
|
30685
|
+
const message2 = {
|
|
30686
|
+
messageId: randomUUID12(),
|
|
30687
|
+
key: request.key,
|
|
30688
|
+
assignmentId: assignment.assignmentId,
|
|
30689
|
+
direction,
|
|
30690
|
+
origin,
|
|
30691
|
+
kind,
|
|
30692
|
+
payloadRef: request.payloadRef,
|
|
30693
|
+
createdAt: now.atUtc,
|
|
30694
|
+
expiresAt: new Date(Date.parse(now.atUtc) + request.ttlMs).toISOString(),
|
|
30695
|
+
acknowledgedAt: null
|
|
30696
|
+
};
|
|
30697
|
+
state.messages.push(message2);
|
|
30698
|
+
if (origin === "adapter") markFabricTimeline(assignment.timeline, "result_received", { stamp: now, source: "controller", evidenceRef: message2.messageId });
|
|
30699
|
+
return { message: message2, added: true };
|
|
30700
|
+
}
|
|
30701
|
+
async assign(input2) {
|
|
30702
|
+
const request = AssignmentInput.parse(input2);
|
|
30703
|
+
const saved = await this.state.update((state) => {
|
|
30704
|
+
this.worker(state, request.workerId);
|
|
30705
|
+
const existing = state.assignments.find((a) => a.runId === request.runId && a.selectedRuntime === request.selectedRuntime);
|
|
30706
|
+
if (existing) {
|
|
30707
|
+
if (JSON.stringify(AssignmentInput.strip().parse(existing)) !== JSON.stringify(request)) throw Error("FABRIC_ASSIGNMENT_ID_CONFLICT");
|
|
30708
|
+
return { state, assignment: existing, notice: null };
|
|
30709
|
+
}
|
|
30710
|
+
if (state.assignments.length >= MAX_ASSIGNMENTS) throw Error("FABRIC_ASSIGNMENT_LIMIT");
|
|
30711
|
+
if (state.assignments.some((a) => assignmentActive(a) && (a.workerId === request.workerId || a.runId === request.runId)))
|
|
30712
|
+
throw Error("FABRIC_WORKER_BUSY");
|
|
30713
|
+
const now = this.clock().atUtc;
|
|
30714
|
+
const assignment = {
|
|
30715
|
+
...request,
|
|
30716
|
+
assignmentId: randomUUID12(),
|
|
30717
|
+
phase: "assigned",
|
|
30718
|
+
createdAt: now,
|
|
30719
|
+
updatedAt: now,
|
|
30720
|
+
timeline: FabricTimelineSchema.parse({}),
|
|
30721
|
+
attribution: WorkerAttributionSchema.parse({}),
|
|
30722
|
+
execution: null
|
|
30723
|
+
};
|
|
30724
|
+
const worker = this.worker(state, request.workerId);
|
|
30725
|
+
worker.attribution = WorkerAttributionSchema.parse({});
|
|
30726
|
+
worker.updatedAt = now;
|
|
30727
|
+
state.assignments.push(assignment);
|
|
30728
|
+
const { message: message2 } = this.append(state, assignment, "ASSIGN", "controller", { key: "assign", payloadRef: request.payloadRef });
|
|
30729
|
+
return { state, assignment, notice: message2 };
|
|
30730
|
+
});
|
|
30731
|
+
if (saved.notice) this.emit(saved.state, saved.notice);
|
|
30732
|
+
return saved.assignment;
|
|
30733
|
+
}
|
|
30734
|
+
async control(assignmentId, kind, input2) {
|
|
30735
|
+
Control.parse(kind);
|
|
30736
|
+
const saved = await this.state.update((state) => {
|
|
30737
|
+
const assignment = this.assignment(state, assignmentId);
|
|
30738
|
+
if (!assignmentActive(assignment)) throw Error("FABRIC_ASSIGNMENT_INACTIVE");
|
|
30739
|
+
return { state, ...this.append(state, assignment, kind, "controller", input2) };
|
|
30740
|
+
});
|
|
30741
|
+
if (saved.added) this.emit(saved.state, saved.message);
|
|
30742
|
+
return saved.message;
|
|
30743
|
+
}
|
|
30744
|
+
async report(workerId, credential, assignmentId, kind, input2) {
|
|
30745
|
+
Report.parse(kind);
|
|
30746
|
+
await this.identities.authenticate(credential.runtimeId, credential.runtimeKey);
|
|
30747
|
+
const saved = await this.state.update((state) => {
|
|
30748
|
+
this.bound(state, workerId, credential);
|
|
30749
|
+
const assignment = this.assignment(state, assignmentId);
|
|
30750
|
+
if (assignment.workerId !== workerId || assignment.phase === "not_started") throw Error("FABRIC_ASSIGNMENT_DENIED");
|
|
30751
|
+
return { state, ...this.append(state, assignment, kind, "worker", input2) };
|
|
30752
|
+
});
|
|
30753
|
+
if (saved.added) this.emit(saved.state, saved.message);
|
|
30754
|
+
return saved.message;
|
|
30755
|
+
}
|
|
30756
|
+
pending(state, direction, workerId) {
|
|
30757
|
+
const now = this.clock().atUtc;
|
|
30758
|
+
return state.messages.filter((m) => m.direction === direction && !m.acknowledgedAt && m.expiresAt > now && (direction !== "to_worker" || state.assignments.some((a) => a.assignmentId === m.assignmentId && a.workerId === workerId && assignmentActive(a))));
|
|
30759
|
+
}
|
|
30760
|
+
async inbox(workerId, credential, limit = 32) {
|
|
30761
|
+
external_exports.number().int().min(1).max(64).parse(limit);
|
|
30762
|
+
await this.identities.authenticate(credential.runtimeId, credential.runtimeKey);
|
|
30763
|
+
const state = await this.state.read();
|
|
30764
|
+
this.bound(state, workerId, credential);
|
|
30765
|
+
return this.pending(state, "to_worker", workerId).slice(0, limit);
|
|
30766
|
+
}
|
|
30767
|
+
async controllerInbox(limit = 32) {
|
|
30768
|
+
external_exports.number().int().min(1).max(64).parse(limit);
|
|
30769
|
+
return this.pending(await this.state.read(), "to_controller").slice(0, limit);
|
|
30770
|
+
}
|
|
30771
|
+
acknowledge(state, messageId, direction, workerId) {
|
|
30772
|
+
const message2 = state.messages.find((m) => m.messageId === messageId && m.direction === direction);
|
|
30773
|
+
if (!message2) return false;
|
|
30774
|
+
const assignment = this.assignment(state, message2.assignmentId);
|
|
30775
|
+
if (direction === "to_worker" && assignment.workerId !== workerId) return false;
|
|
30776
|
+
if (message2.acknowledgedAt) return true;
|
|
30777
|
+
const now = this.clock();
|
|
30778
|
+
if (message2.expiresAt <= now.atUtc) return false;
|
|
30779
|
+
message2.acknowledgedAt = now.atUtc;
|
|
30780
|
+
if (message2.origin === "adapter") markFabricTimeline(assignment.timeline, "result_delivered", { stamp: now, source: "controller", evidenceRef: message2.messageId });
|
|
30781
|
+
return true;
|
|
30782
|
+
}
|
|
30783
|
+
async ack(workerId, credential, messageId) {
|
|
30784
|
+
await this.identities.authenticate(credential.runtimeId, credential.runtimeKey);
|
|
30785
|
+
return this.state.update((state) => {
|
|
30786
|
+
this.bound(state, workerId, credential);
|
|
30787
|
+
return this.acknowledge(state, messageId, "to_worker", workerId);
|
|
30788
|
+
});
|
|
30789
|
+
}
|
|
30790
|
+
controllerAck(messageId) {
|
|
30791
|
+
return this.state.update((state) => this.acknowledge(state, messageId, "to_controller"));
|
|
30792
|
+
}
|
|
30793
|
+
async adapterResult(assignmentId, payloadRef) {
|
|
30794
|
+
const saved = await this.state.update((state) => {
|
|
30795
|
+
const assignment = this.assignment(state, assignmentId);
|
|
30796
|
+
if (assignment.phase !== "exited") throw Error("FABRIC_RESULT_UNCONFIRMED");
|
|
30797
|
+
return { state, ...this.append(state, assignment, "RESULT", "adapter", { key: "result", payloadRef }) };
|
|
30798
|
+
});
|
|
30799
|
+
if (saved.added) this.emit(saved.state, saved.message);
|
|
30800
|
+
}
|
|
30801
|
+
claimLaunch(assignmentId) {
|
|
30802
|
+
return this.state.update((state) => {
|
|
30803
|
+
const assignment = this.assignment(state, assignmentId);
|
|
30804
|
+
if (assignment.phase !== "assigned" && assignment.phase !== "not_started") return false;
|
|
30805
|
+
assignment.phase = "launching";
|
|
30806
|
+
assignment.updatedAt = this.clock().atUtc;
|
|
30807
|
+
return true;
|
|
30808
|
+
});
|
|
30809
|
+
}
|
|
30810
|
+
timing(assignmentId, stage, mark) {
|
|
30811
|
+
return this.state.update((state) => {
|
|
30812
|
+
markFabricTimeline(this.assignment(state, assignmentId).timeline, stage, mark);
|
|
30813
|
+
});
|
|
30814
|
+
}
|
|
30815
|
+
confirmExecution(assignmentId, input2) {
|
|
30816
|
+
const execution = FabricExecutionLinkSchema.parse(input2);
|
|
30817
|
+
return this.state.update((state) => {
|
|
30818
|
+
const assignment = this.assignment(state, assignmentId);
|
|
30819
|
+
if (assignment.execution && JSON.stringify(assignment.execution) !== JSON.stringify(execution)) throw Error("FABRIC_EXECUTION_CONFLICT");
|
|
30820
|
+
if (execution.executionId && state.assignments.some((a) => a.assignmentId !== assignmentId && a.execution?.executionId === execution.executionId))
|
|
30821
|
+
throw Error("FABRIC_EXECUTION_CONFLICT");
|
|
30822
|
+
assignment.execution = execution;
|
|
30823
|
+
});
|
|
30824
|
+
}
|
|
30825
|
+
/** Trusted transport adapter passes its authenticated device, never a worker-reported label.
|
|
30826
|
+
* References remain device-reported diagnostics in the cloud, not ownership/authentication. */
|
|
30827
|
+
async incidentReferences(deviceId, executionId) {
|
|
30828
|
+
FabricId.parse(deviceId);
|
|
30829
|
+
const execution = external_exports.string().uuid().toLowerCase().parse(executionId);
|
|
30830
|
+
const state = await this.state.read();
|
|
30831
|
+
const assignment = state.assignments.find((a) => a.execution?.executionId === execution);
|
|
30832
|
+
if (!assignment || this.worker(state, assignment.workerId).device?.deviceId !== deviceId) return null;
|
|
30833
|
+
const task = external_exports.string().uuid().toLowerCase().safeParse(assignment.taskId);
|
|
30834
|
+
return { executionId: execution, workerId: assignment.workerId, ...task.success ? { taskId: task.data } : {} };
|
|
30835
|
+
}
|
|
30836
|
+
confirmAttribution(assignmentId, input2) {
|
|
30837
|
+
const confirmed = ConfirmInput.parse(input2);
|
|
30838
|
+
for (const key of ["provider", "runtime", "model"])
|
|
30839
|
+
if (confirmed[key] === void 0) delete confirmed[key];
|
|
30840
|
+
return this.state.update((state) => {
|
|
30841
|
+
const assignment = this.assignment(state, assignmentId);
|
|
30842
|
+
for (const key of ["provider", "runtime", "model"])
|
|
30843
|
+
if (assignment.attribution[key] && confirmed[key] !== void 0 && JSON.stringify(assignment.attribution[key]) !== JSON.stringify(confirmed[key])) throw Error("FABRIC_ATTRIBUTION_CONFLICT");
|
|
30844
|
+
Object.assign(assignment.attribution, confirmed);
|
|
30845
|
+
const latest = state.assignments.filter((a) => a.workerId === assignment.workerId).at(-1);
|
|
30846
|
+
if (latest?.assignmentId === assignmentId) Object.assign(this.worker(state, assignment.workerId).attribution, confirmed);
|
|
30847
|
+
});
|
|
30848
|
+
}
|
|
30849
|
+
phase(assignmentId, next) {
|
|
30850
|
+
return this.state.update((state) => {
|
|
30851
|
+
const assignment = this.assignment(state, assignmentId);
|
|
30852
|
+
const allowed = {
|
|
30853
|
+
assigned: ["launching", "not_started", "unknown"],
|
|
30854
|
+
launching: ["running", "not_started", "unknown", "exited"],
|
|
30855
|
+
running: ["unknown", "exited"],
|
|
30856
|
+
unknown: ["exited"],
|
|
30857
|
+
exited: [],
|
|
30858
|
+
not_started: ["launching"]
|
|
30859
|
+
};
|
|
30860
|
+
if (assignment.phase === next) return;
|
|
30861
|
+
if (!allowed[assignment.phase].includes(next)) throw Error("FABRIC_ASSIGNMENT_PHASE_INVALID");
|
|
30862
|
+
assignment.phase = next;
|
|
30863
|
+
assignment.updatedAt = this.clock().atUtc;
|
|
30864
|
+
});
|
|
30865
|
+
}
|
|
30866
|
+
async snapshot() {
|
|
30867
|
+
const state = await this.state.read(), now = this.clock().atUtc;
|
|
30868
|
+
const nextExpiry = state.messages.filter((m) => !m.acknowledgedAt && m.expiresAt > now).reduce((next, m) => next === null || m.expiresAt < next ? m.expiresAt : next, null);
|
|
30869
|
+
return { ...state, nextExpiry };
|
|
30870
|
+
}
|
|
30871
|
+
};
|
|
30872
|
+
|
|
30873
|
+
// src/agent-fabric-service.ts
|
|
30874
|
+
var Binding = external_exports.strictObject({
|
|
30875
|
+
version: external_exports.literal(1),
|
|
30876
|
+
controllerId: FabricId,
|
|
30877
|
+
device: FabricWorkerSchema.shape.device,
|
|
30878
|
+
initialized: external_exports.boolean()
|
|
30879
|
+
});
|
|
30880
|
+
var WorkerRequest = external_exports.discriminatedUnion("operation", [
|
|
30881
|
+
external_exports.strictObject({ operation: external_exports.literal("inbox"), workerId: external_exports.string().uuid(), limit: external_exports.number().int().min(1).max(64).default(32) }),
|
|
30882
|
+
external_exports.strictObject({ operation: external_exports.literal("ack"), workerId: external_exports.string().uuid(), messageId: external_exports.string().uuid() }),
|
|
30883
|
+
external_exports.strictObject({
|
|
30884
|
+
operation: external_exports.literal("report"),
|
|
30885
|
+
workerId: external_exports.string().uuid(),
|
|
30886
|
+
assignmentId: external_exports.string().uuid(),
|
|
30887
|
+
kind: external_exports.enum(["PROGRESS", "BLOCKED", "RESULT"]),
|
|
30888
|
+
key: FabricId,
|
|
30889
|
+
payloadRef: FabricPayloadRefSchema,
|
|
30890
|
+
ttlMs: external_exports.number().int().min(1e3).max(864e5).default(6e4)
|
|
30891
|
+
})
|
|
30892
|
+
]);
|
|
30893
|
+
var AgentFabricService = class _AgentFabricService {
|
|
30894
|
+
constructor(directory, controllerId) {
|
|
30895
|
+
this.directory = directory;
|
|
30896
|
+
this.identities = new AgentRuntimeIdentityStore(path15.join(directory, "identities.json"));
|
|
30897
|
+
this.mailbox = new AgentWorkerMailbox(
|
|
30898
|
+
path15.join(directory, "mailbox.json"),
|
|
30899
|
+
controllerId,
|
|
30900
|
+
this.identities,
|
|
30901
|
+
void 0,
|
|
30902
|
+
() => this.changed()
|
|
30903
|
+
);
|
|
30904
|
+
}
|
|
30905
|
+
directory;
|
|
30906
|
+
identities;
|
|
30907
|
+
mailbox;
|
|
30908
|
+
listeners = /* @__PURE__ */ new Set();
|
|
30909
|
+
watcher;
|
|
30910
|
+
closed = false;
|
|
30911
|
+
static async open(directory, controllerId, device = null, initialize = true) {
|
|
30912
|
+
const expected = Binding.parse({ version: 1, controllerId, device, initialized: false });
|
|
30913
|
+
const absolute2 = path15.resolve(directory);
|
|
30914
|
+
for (let current2 = absolute2; ; current2 = path15.dirname(current2)) {
|
|
30915
|
+
try {
|
|
30916
|
+
if ((await lstat8(current2)).isSymbolicLink()) throw Error("FABRIC_DIRECTORY_INVALID");
|
|
30917
|
+
} catch (error62) {
|
|
30918
|
+
if (error62.code !== "ENOENT") throw error62;
|
|
30919
|
+
}
|
|
30920
|
+
if (path15.dirname(current2) === current2) break;
|
|
30921
|
+
}
|
|
30922
|
+
if (initialize) await mkdir7(absolute2, { recursive: true, mode: 448 });
|
|
30923
|
+
if (!(await lstat8(absolute2)).isDirectory() || (await realpath7(absolute2)).toLowerCase() !== absolute2.toLowerCase())
|
|
30924
|
+
throw Error("FABRIC_DIRECTORY_INVALID");
|
|
30925
|
+
const present = /* @__PURE__ */ new Set();
|
|
30926
|
+
for (const name2 of ["binding.json", "mailbox.json", "identities.json"]) {
|
|
30927
|
+
const file2 = await lstat8(path15.join(absolute2, name2)).catch((error62) => {
|
|
30928
|
+
if (error62.code === "ENOENT") return null;
|
|
30929
|
+
throw error62;
|
|
30930
|
+
});
|
|
30931
|
+
if (file2 && (!file2.isFile() || file2.isSymbolicLink())) throw Error("FABRIC_FILE_INVALID");
|
|
30932
|
+
if (file2) present.add(name2);
|
|
30933
|
+
}
|
|
30934
|
+
if (!present.has("binding.json") && present.size) throw Error("FABRIC_BINDING_MISSING");
|
|
30935
|
+
const binding2 = new FabricStateFile(path15.join(absolute2, "binding.json"), 2048, (value) => Binding.parse(value));
|
|
30936
|
+
const service = new _AgentFabricService(absolute2, controllerId);
|
|
30937
|
+
await binding2.update(async (state) => {
|
|
30938
|
+
if (state.controllerId !== expected.controllerId || JSON.stringify(state.device) !== JSON.stringify(expected.device))
|
|
30939
|
+
throw Error("FABRIC_BINDING_CHANGED");
|
|
30940
|
+
if (!state.initialized) {
|
|
30941
|
+
if (!initialize) throw Error("FABRIC_INITIALIZATION_INCOMPLETE");
|
|
30942
|
+
try {
|
|
30943
|
+
await service.mailbox.initialize();
|
|
30944
|
+
} catch (error62) {
|
|
30945
|
+
if (!(error62 instanceof Error) || error62.message !== "FABRIC_STATE_EXISTS") throw error62;
|
|
30946
|
+
}
|
|
30947
|
+
state.initialized = true;
|
|
30948
|
+
}
|
|
30949
|
+
const snapshot2 = await service.mailbox.snapshot();
|
|
30950
|
+
if (snapshot2.workers.some((worker) => worker.runtimeId !== null)) await lstat8(path15.join(absolute2, "identities.json"));
|
|
30951
|
+
}, initialize ? () => expected : void 0);
|
|
30952
|
+
return service;
|
|
30953
|
+
}
|
|
30954
|
+
changed() {
|
|
30955
|
+
for (const callback of this.listeners) {
|
|
30956
|
+
try {
|
|
30957
|
+
callback();
|
|
30958
|
+
} catch {
|
|
30959
|
+
}
|
|
30960
|
+
}
|
|
30961
|
+
}
|
|
30962
|
+
subscribe = (callback) => {
|
|
30963
|
+
if (this.closed || this.listeners.size >= 32) throw Error("FABRIC_OBSERVER_LIMIT");
|
|
30964
|
+
this.listeners.add(callback);
|
|
30965
|
+
try {
|
|
30966
|
+
if (!this.watcher) {
|
|
30967
|
+
this.watcher = watch(this.directory, { persistent: false }, (_event, file2) => {
|
|
30968
|
+
if (file2?.toString().toLowerCase() === "mailbox.json") this.changed();
|
|
30969
|
+
});
|
|
30970
|
+
this.watcher.on("error", () => {
|
|
30971
|
+
this.watcher?.close();
|
|
30972
|
+
this.watcher = void 0;
|
|
30973
|
+
});
|
|
30974
|
+
}
|
|
30975
|
+
} catch {
|
|
30976
|
+
}
|
|
30977
|
+
return () => {
|
|
30978
|
+
this.listeners.delete(callback);
|
|
30979
|
+
if (!this.listeners.size) {
|
|
30980
|
+
this.watcher?.close();
|
|
30981
|
+
this.watcher = void 0;
|
|
30982
|
+
}
|
|
30983
|
+
};
|
|
30984
|
+
};
|
|
30985
|
+
async worker(input2, credential) {
|
|
30986
|
+
const request = WorkerRequest.parse(input2);
|
|
30987
|
+
if (request.operation === "inbox") return this.mailbox.inbox(request.workerId, credential, request.limit);
|
|
30988
|
+
if (request.operation === "ack") return this.mailbox.ack(request.workerId, credential, request.messageId);
|
|
30989
|
+
return this.mailbox.report(
|
|
30990
|
+
request.workerId,
|
|
30991
|
+
credential,
|
|
30992
|
+
request.assignmentId,
|
|
30993
|
+
request.kind,
|
|
30994
|
+
{ key: request.key, payloadRef: request.payloadRef, ttlMs: request.ttlMs }
|
|
30995
|
+
);
|
|
30996
|
+
}
|
|
30997
|
+
close() {
|
|
30998
|
+
this.closed = true;
|
|
30999
|
+
this.watcher?.close();
|
|
31000
|
+
this.watcher = void 0;
|
|
31001
|
+
this.listeners.clear();
|
|
31002
|
+
}
|
|
31003
|
+
};
|
|
31004
|
+
|
|
31005
|
+
// agent/src/native-fabric-startup.ts
|
|
31006
|
+
var Credential = external_exports.strictObject({
|
|
31007
|
+
workerId: external_exports.string().uuid(),
|
|
31008
|
+
controllerId: FabricId,
|
|
31009
|
+
runtimeId: external_exports.string().regex(/^rt-[0-9a-f-]{36}$/),
|
|
31010
|
+
runtimeKey: external_exports.string().regex(/^[A-Za-z0-9_-]{43}$/)
|
|
31011
|
+
});
|
|
31012
|
+
var OwnerRequest = external_exports.discriminatedUnion("operation", [
|
|
31013
|
+
external_exports.strictObject({ operation: external_exports.literal("status") }),
|
|
31014
|
+
external_exports.strictObject({ operation: external_exports.literal("register"), key: FabricId, parentWorkerId: external_exports.string().uuid().nullable().default(null) }),
|
|
31015
|
+
external_exports.strictObject({ operation: external_exports.literal("revoke"), workerId: external_exports.string().uuid() }),
|
|
31016
|
+
external_exports.strictObject({ operation: external_exports.literal("assign"), ...FabricAssignmentSchema.pick({
|
|
31017
|
+
workerId: true,
|
|
31018
|
+
taskId: true,
|
|
31019
|
+
runId: true,
|
|
31020
|
+
role: true,
|
|
31021
|
+
selectedRuntime: true,
|
|
31022
|
+
payloadRef: true
|
|
31023
|
+
}).shape }),
|
|
31024
|
+
external_exports.strictObject({
|
|
31025
|
+
operation: external_exports.literal("control"),
|
|
31026
|
+
assignmentId: external_exports.string().uuid(),
|
|
31027
|
+
kind: external_exports.enum(["WAKE", "CANCEL"]),
|
|
31028
|
+
key: FabricId,
|
|
31029
|
+
payloadRef: FabricPayloadRefSchema,
|
|
31030
|
+
ttlMs: external_exports.number().int().min(1e3).max(864e5).default(6e4)
|
|
31031
|
+
})
|
|
31032
|
+
]);
|
|
31033
|
+
var Delivery = external_exports.strictObject({ capability: external_exports.string().regex(/^[A-Za-z0-9+/]+={0,2}$/).max(4096), request: external_exports.unknown() });
|
|
31034
|
+
async function openNativeFabric(stateDirectory, enrollment, box, initialize = true) {
|
|
31035
|
+
const controllerId = "device-" + external_exports.string().uuid().parse(enrollment.deviceId).toLowerCase();
|
|
31036
|
+
const tenantId = external_exports.string().uuid().parse(enrollment.tenantId).toLowerCase();
|
|
31037
|
+
const parent = path16.join(stateDirectory, ".local-commander"), marker = path16.join(parent, "fabric-established.json");
|
|
31038
|
+
try {
|
|
31039
|
+
await mkdir8(parent, { mode: 448 });
|
|
31040
|
+
} catch (error62) {
|
|
31041
|
+
if (error62.code !== "EEXIST") throw error62;
|
|
31042
|
+
}
|
|
31043
|
+
const parentInfo = await lstat9(parent);
|
|
31044
|
+
if (!parentInfo.isDirectory() || parentInfo.isSymbolicLink()) throw Error("FABRIC_DIRECTORY_INVALID");
|
|
31045
|
+
const expected = JSON.stringify({ version: 1, controllerId, tenantId });
|
|
31046
|
+
let fresh = false;
|
|
31047
|
+
try {
|
|
31048
|
+
const info = await lstat9(marker);
|
|
31049
|
+
if (!info.isFile() || info.isSymbolicLink() || info.size > 2048 || await readFile5(marker, "utf8") !== expected)
|
|
31050
|
+
throw Error("FABRIC_BINDING_CHANGED");
|
|
31051
|
+
} catch (error62) {
|
|
31052
|
+
if (error62.code !== "ENOENT" || !initialize) throw error62;
|
|
31053
|
+
const file2 = await open8(marker, "wx", 384);
|
|
31054
|
+
try {
|
|
31055
|
+
await file2.writeFile(expected);
|
|
31056
|
+
await file2.datasync();
|
|
31057
|
+
} finally {
|
|
31058
|
+
await file2.close();
|
|
31059
|
+
}
|
|
31060
|
+
fresh = true;
|
|
31061
|
+
}
|
|
31062
|
+
const service = await AgentFabricService.open(
|
|
31063
|
+
path16.join(stateDirectory, ".local-commander", "fabric"),
|
|
31064
|
+
controllerId,
|
|
31065
|
+
{ deviceId: enrollment.deviceId.toLowerCase(), enrollmentEvidenceRef: "enrollment-" + tenantId },
|
|
31066
|
+
fresh
|
|
31067
|
+
);
|
|
31068
|
+
const purpose = "native-fabric:" + tenantId + ":" + controllerId;
|
|
31069
|
+
const credentialFile = (workerId) => path16.join(service.directory, external_exports.string().uuid().parse(workerId) + ".capability");
|
|
31070
|
+
const decode4 = (value) => {
|
|
31071
|
+
const credential = Credential.parse(JSON.parse(box.open(Buffer.from(value, "base64"), purpose).toString("utf8")));
|
|
31072
|
+
if (credential.controllerId !== controllerId) throw Error("FABRIC_WORKER_DENIED");
|
|
31073
|
+
return credential;
|
|
31074
|
+
};
|
|
31075
|
+
async function capability(workerId) {
|
|
31076
|
+
const file2 = credentialFile(workerId), info = await lstat9(file2);
|
|
31077
|
+
if (!info.isFile() || info.isSymbolicLink() || info.size > 4096) throw Error("FABRIC_CREDENTIAL_UNKNOWN");
|
|
31078
|
+
const encoded = await readFile5(file2, "utf8");
|
|
31079
|
+
if (decode4(encoded).workerId !== workerId) throw Error("FABRIC_WORKER_DENIED");
|
|
31080
|
+
return encoded;
|
|
31081
|
+
}
|
|
31082
|
+
return {
|
|
31083
|
+
service,
|
|
31084
|
+
source: { mailbox: service.mailbox, subscribe: service.subscribe },
|
|
31085
|
+
async owner(input2) {
|
|
31086
|
+
const request = OwnerRequest.parse(input2);
|
|
31087
|
+
if (request.operation === "status") return service.mailbox.snapshot();
|
|
31088
|
+
if (request.operation === "revoke") {
|
|
31089
|
+
const credential = decode4(await capability(request.workerId));
|
|
31090
|
+
await service.identities.revoke(credential.runtimeId, credential.runtimeKey);
|
|
31091
|
+
return { revoked: true };
|
|
31092
|
+
}
|
|
31093
|
+
if (request.operation === "register") {
|
|
31094
|
+
const worker = await service.mailbox.register({
|
|
31095
|
+
key: request.key,
|
|
31096
|
+
parentWorkerId: request.parentWorkerId,
|
|
31097
|
+
device: { deviceId: enrollment.deviceId.toLowerCase(), enrollmentEvidenceRef: "enrollment-" + tenantId }
|
|
31098
|
+
});
|
|
31099
|
+
const previous = await capability(worker.workerId).catch((error62) => {
|
|
31100
|
+
if (error62.code === "ENOENT" && !worker.runtimeId) return void 0;
|
|
31101
|
+
throw Error("FABRIC_CREDENTIAL_UNKNOWN");
|
|
31102
|
+
});
|
|
31103
|
+
if (previous) {
|
|
31104
|
+
const credential = decode4(previous);
|
|
31105
|
+
await service.identities.authenticate(credential.runtimeId, credential.runtimeKey);
|
|
31106
|
+
if (worker.runtimeId && worker.runtimeId !== credential.runtimeId) throw Error("FABRIC_CREDENTIAL_UNKNOWN");
|
|
31107
|
+
if (!worker.runtimeId) await service.mailbox.bindRuntime(worker.workerId, credential);
|
|
31108
|
+
} else {
|
|
31109
|
+
const credential = await service.identities.issue();
|
|
31110
|
+
const encoded = box.seal(Buffer.from(JSON.stringify({ ...credential, workerId: worker.workerId, controllerId })), purpose).toString("base64");
|
|
31111
|
+
const file2 = await open8(credentialFile(worker.workerId), "wx", 384);
|
|
31112
|
+
try {
|
|
31113
|
+
await file2.writeFile(encoded);
|
|
31114
|
+
await file2.datasync();
|
|
31115
|
+
} finally {
|
|
31116
|
+
await file2.close();
|
|
31117
|
+
}
|
|
31118
|
+
await service.mailbox.bindRuntime(worker.workerId, credential);
|
|
31119
|
+
}
|
|
31120
|
+
return { workerId: worker.workerId, credentialFile: credentialFile(worker.workerId) };
|
|
31121
|
+
}
|
|
31122
|
+
if (request.operation === "assign") {
|
|
31123
|
+
const { operation: _, ...assignment } = request;
|
|
31124
|
+
return service.mailbox.assign(assignment);
|
|
31125
|
+
}
|
|
31126
|
+
return service.mailbox.control(
|
|
31127
|
+
request.assignmentId,
|
|
31128
|
+
request.kind,
|
|
31129
|
+
{ key: request.key, payloadRef: request.payloadRef, ttlMs: request.ttlMs }
|
|
31130
|
+
);
|
|
31131
|
+
},
|
|
31132
|
+
async confirmExecution(assignmentId, executionId, journal) {
|
|
31133
|
+
const receipt = await journal.get(external_exports.string().uuid().parse(executionId));
|
|
31134
|
+
if (!receipt || receipt.tenantId !== tenantId || receipt.deviceId !== enrollment.deviceId.toLowerCase())
|
|
31135
|
+
throw Error("FABRIC_EXECUTION_UNCONFIRMED");
|
|
31136
|
+
await service.mailbox.confirmExecution(external_exports.string().uuid().parse(assignmentId), {
|
|
31137
|
+
executionId: receipt.executionId,
|
|
31138
|
+
sessionId: receipt.sessionId,
|
|
31139
|
+
pid: null,
|
|
31140
|
+
confirmedAt: receipt.createdAt,
|
|
31141
|
+
evidenceRef: receipt.operationId
|
|
31142
|
+
});
|
|
31143
|
+
},
|
|
31144
|
+
async worker(input2) {
|
|
31145
|
+
const delivery = Delivery.parse(input2), credential = decode4(delivery.capability);
|
|
31146
|
+
if (!delivery.request || typeof delivery.request !== "object" || Array.isArray(delivery.request) || delivery.request.workerId !== credential.workerId) throw Error("FABRIC_WORKER_DENIED");
|
|
31147
|
+
return service.worker(delivery.request, credential);
|
|
31148
|
+
},
|
|
31149
|
+
close: () => service.close()
|
|
31150
|
+
};
|
|
31151
|
+
}
|
|
31152
|
+
async function readFabricRequest(input2 = process.stdin) {
|
|
31153
|
+
const chunks = [];
|
|
31154
|
+
let bytes3 = 0;
|
|
31155
|
+
for await (const chunk of input2) {
|
|
31156
|
+
const value = Buffer.from(chunk);
|
|
31157
|
+
bytes3 += value.length;
|
|
31158
|
+
if (bytes3 > 16384) throw Error("FABRIC_REQUEST_LIMIT");
|
|
31159
|
+
chunks.push(value);
|
|
31160
|
+
}
|
|
31161
|
+
try {
|
|
31162
|
+
return JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(Buffer.concat(chunks)));
|
|
31163
|
+
} catch {
|
|
31164
|
+
throw Error("FABRIC_REQUEST_INVALID");
|
|
31165
|
+
}
|
|
31166
|
+
}
|
|
31167
|
+
|
|
29430
31168
|
// agent/src/main.ts
|
|
29431
|
-
var AGENT_VERSION2 = true ? "0.3.
|
|
31169
|
+
var AGENT_VERSION2 = true ? "0.3.9-issue11.1" : "0.3.2";
|
|
29432
31170
|
function processAlive(pid) {
|
|
29433
31171
|
if (!Number.isInteger(pid) || pid <= 0) return false;
|
|
29434
31172
|
try {
|
|
@@ -29439,11 +31177,11 @@ function processAlive(pid) {
|
|
|
29439
31177
|
}
|
|
29440
31178
|
}
|
|
29441
31179
|
async function claimAgentProcess(stateDir, runtimeDir, version2) {
|
|
29442
|
-
await
|
|
29443
|
-
const file2 =
|
|
31180
|
+
await mkdir9(stateDir, { recursive: true });
|
|
31181
|
+
const file2 = path17.join(stateDir, "agent-process.json");
|
|
29444
31182
|
for (let attempt = 0; attempt < 2; attempt += 1) {
|
|
29445
31183
|
try {
|
|
29446
|
-
const handle = await
|
|
31184
|
+
const handle = await open9(file2, "wx", 384);
|
|
29447
31185
|
try {
|
|
29448
31186
|
await handle.writeFile(JSON.stringify({ pid: process.pid, runtimeDir, version: version2, startedAt: (/* @__PURE__ */ new Date()).toISOString() }) + "\n", "utf8");
|
|
29449
31187
|
} finally {
|
|
@@ -29451,7 +31189,7 @@ async function claimAgentProcess(stateDir, runtimeDir, version2) {
|
|
|
29451
31189
|
}
|
|
29452
31190
|
return async () => {
|
|
29453
31191
|
try {
|
|
29454
|
-
const current2 = JSON.parse(await
|
|
31192
|
+
const current2 = JSON.parse(await readFile6(file2, "utf8"));
|
|
29455
31193
|
if (current2.pid === process.pid) await rm5(file2, { force: true });
|
|
29456
31194
|
} catch {
|
|
29457
31195
|
}
|
|
@@ -29460,7 +31198,7 @@ async function claimAgentProcess(stateDir, runtimeDir, version2) {
|
|
|
29460
31198
|
if (!error62 || typeof error62 !== "object" || !("code" in error62) || error62.code !== "EEXIST") throw error62;
|
|
29461
31199
|
let stale = true;
|
|
29462
31200
|
try {
|
|
29463
|
-
const current2 = JSON.parse(await
|
|
31201
|
+
const current2 = JSON.parse(await readFile6(file2, "utf8"));
|
|
29464
31202
|
stale = typeof current2.pid !== "number" || !processAlive(current2.pid);
|
|
29465
31203
|
} catch {
|
|
29466
31204
|
}
|
|
@@ -29484,23 +31222,65 @@ function aborted2(signal, ms) {
|
|
|
29484
31222
|
}
|
|
29485
31223
|
async function runAgent(options) {
|
|
29486
31224
|
const delay = options.reconnectDelayMs ?? 2e3;
|
|
31225
|
+
const monitor = (update) => {
|
|
31226
|
+
try {
|
|
31227
|
+
update();
|
|
31228
|
+
void options.monitor?.flush().catch(() => {
|
|
31229
|
+
});
|
|
31230
|
+
} catch {
|
|
31231
|
+
}
|
|
31232
|
+
};
|
|
29487
31233
|
try {
|
|
29488
31234
|
if (!Number.isInteger(delay) || delay < 0 || delay > 3e4) throw Error("RECONNECT_DELAY_INVALID");
|
|
29489
31235
|
const identity = await options.store.load();
|
|
29490
31236
|
if (!identity?.enrollment) throw Error("ENROLLMENT_MISSING");
|
|
29491
|
-
|
|
31237
|
+
const origin = identity.enrollment.serverOrigin;
|
|
31238
|
+
monitor(() => options.monitor?.configureOrigin(origin));
|
|
29492
31239
|
await options.journal.recoverAfterRestart();
|
|
29493
31240
|
await options.store.loadWorkspaces();
|
|
29494
31241
|
} catch (error62) {
|
|
29495
31242
|
await options.journal.close();
|
|
29496
31243
|
throw error62;
|
|
29497
31244
|
}
|
|
29498
|
-
const
|
|
31245
|
+
const ledger = options.efficiencyLedger;
|
|
31246
|
+
const efficiencyLedger = ledger && {
|
|
31247
|
+
record: async (input2) => {
|
|
31248
|
+
const recorded = await ledger.record(input2);
|
|
31249
|
+
if (recorded) monitor(() => options.monitor?.efficiency(input2));
|
|
31250
|
+
return recorded;
|
|
31251
|
+
},
|
|
31252
|
+
...ledger.consumeNoticeForExecution ? { consumeNoticeForExecution: ledger.consumeNoticeForExecution.bind(ledger) } : {}
|
|
31253
|
+
};
|
|
31254
|
+
const supervisor = options.supervisor ?? new NativeEventSupervisor();
|
|
31255
|
+
const fabric = options.fabric && new NativeFabricObserver(supervisor, options.fabric);
|
|
31256
|
+
const incidentProducer = new NativeIncidentProducer(supervisor, (executionId) => fabric?.references(executionId));
|
|
31257
|
+
const runtime = new NativeRuntime({
|
|
31258
|
+
journal: options.journal,
|
|
31259
|
+
tools: options.tools,
|
|
31260
|
+
scheduler: new NativeScheduler({ onEvent: (event) => supervisor.observe(event) }),
|
|
31261
|
+
onFrame: (frame) => {
|
|
31262
|
+
supervisor.frame(frame);
|
|
31263
|
+
fabric?.activity();
|
|
31264
|
+
monitor(() => options.monitor?.frame(frame));
|
|
31265
|
+
},
|
|
31266
|
+
workspaces: () => options.store.loadWorkspaces(Boolean(options.guard)),
|
|
31267
|
+
guard: options.guard,
|
|
31268
|
+
efficiencyLedger
|
|
31269
|
+
});
|
|
29499
31270
|
let connection = null;
|
|
31271
|
+
let legacyMonitorTimer;
|
|
29500
31272
|
const bridge = new NativeRelayBridge(runtime, (binding2, state, code, metrics) => {
|
|
29501
|
-
|
|
31273
|
+
supervisor.observe({
|
|
31274
|
+
kind: "result",
|
|
31275
|
+
executionId: binding2.executionId,
|
|
31276
|
+
code,
|
|
31277
|
+
terminalProof: state !== "unknown" && code !== "EXECUTION_UNKNOWN"
|
|
31278
|
+
});
|
|
31279
|
+
monitor(() => options.monitor?.result(binding2, state, code));
|
|
29502
31280
|
if (!connection) throw Error("RELAY_SOCKET_CLOSED");
|
|
29503
|
-
return connection.sendTerminal(binding2, state, code, metrics)
|
|
31281
|
+
return connection.sendTerminal(binding2, state, code, metrics).then(() => {
|
|
31282
|
+
incidentProducer.activity();
|
|
31283
|
+
});
|
|
29504
31284
|
}, options.journal);
|
|
29505
31285
|
const connect = options.connect ?? ((connectionOptions) => connectOnce(connectionOptions));
|
|
29506
31286
|
try {
|
|
@@ -29510,27 +31290,45 @@ async function runAgent(options) {
|
|
|
29510
31290
|
ready = resolve;
|
|
29511
31291
|
});
|
|
29512
31292
|
try {
|
|
29513
|
-
options.monitor?.setConnection("connecting");
|
|
29514
|
-
connection = await connect({
|
|
29515
|
-
|
|
29516
|
-
options.
|
|
29517
|
-
|
|
29518
|
-
|
|
29519
|
-
|
|
29520
|
-
|
|
29521
|
-
|
|
29522
|
-
|
|
29523
|
-
|
|
29524
|
-
|
|
29525
|
-
|
|
31293
|
+
monitor(() => options.monitor?.setConnection("connecting"));
|
|
31294
|
+
connection = await connect({
|
|
31295
|
+
store: options.store,
|
|
31296
|
+
agentVersion: options.agentVersion,
|
|
31297
|
+
safeSlots: runtime.status().safeSlots,
|
|
31298
|
+
onIncidentAck: (ack) => incidentProducer.ack(ack),
|
|
31299
|
+
handleRequest: async (request) => {
|
|
31300
|
+
await readyPromise;
|
|
31301
|
+
monitor(() => {
|
|
31302
|
+
options.monitor?.transportActivity();
|
|
31303
|
+
options.monitor?.request(request);
|
|
31304
|
+
});
|
|
31305
|
+
try {
|
|
31306
|
+
const result2 = await bridge.handle(request);
|
|
31307
|
+
monitor(() => options.monitor?.response(result2));
|
|
31308
|
+
return result2;
|
|
31309
|
+
} catch (error62) {
|
|
31310
|
+
monitor(() => options.monitor?.requestFailed());
|
|
31311
|
+
throw error62;
|
|
31312
|
+
}
|
|
31313
|
+
},
|
|
31314
|
+
onMonitorHeartbeat: () => monitor(() => options.monitor?.transportActivity())
|
|
31315
|
+
});
|
|
31316
|
+
fabric?.connected(connection.deviceId);
|
|
29526
31317
|
await bridge.connected(connection);
|
|
29527
|
-
|
|
31318
|
+
incidentProducer.connected(connection.sendIncidentBatch);
|
|
31319
|
+
supervisor.observe({ kind: "connected" });
|
|
31320
|
+
monitor(() => options.monitor?.setConnection("connected", connection));
|
|
31321
|
+
if (options.monitor && !connection.monitorFreshnessMs) {
|
|
31322
|
+
legacyMonitorTimer = setInterval(() => monitor(() => {
|
|
31323
|
+
}), 2e3);
|
|
31324
|
+
legacyMonitorTimer.unref();
|
|
31325
|
+
}
|
|
29528
31326
|
ready();
|
|
29529
31327
|
if (options.signal.aborted) connection.close("agent_shutdown");
|
|
29530
31328
|
else {
|
|
29531
|
-
for (const
|
|
29532
|
-
await connection.revokeWorkspace(
|
|
29533
|
-
await options.store.acknowledgeWorkspaceRevoke(
|
|
31329
|
+
for (const id2 of await options.store.loadPendingWorkspaceRevokes()) {
|
|
31330
|
+
await connection.revokeWorkspace(id2);
|
|
31331
|
+
await options.store.acknowledgeWorkspaceRevoke(id2);
|
|
29534
31332
|
}
|
|
29535
31333
|
for (const workspace of await options.store.loadWorkspaces()) {
|
|
29536
31334
|
if ((await options.store.loadWorkspaces()).some((current2) => current2.workspaceGrantId === workspace.workspaceGrantId)) await connection.registerWorkspace(workspace);
|
|
@@ -29546,11 +31344,16 @@ async function runAgent(options) {
|
|
|
29546
31344
|
}
|
|
29547
31345
|
} catch (error62) {
|
|
29548
31346
|
ready();
|
|
29549
|
-
options.monitor?.connectionFailed(error62);
|
|
31347
|
+
monitor(() => options.monitor?.connectionFailed(error62));
|
|
29550
31348
|
if (error62 instanceof RelayClientError && ["RELAY_CONNECT_FAILED", "RELAY_CONNECT_CLOSED", "RELAY_CONNECT_TIMEOUT", "RELAY_HANDSHAKE_TIMEOUT"].includes(error62.code)) {
|
|
29551
31349
|
} else throw error62;
|
|
29552
31350
|
} finally {
|
|
29553
|
-
|
|
31351
|
+
fabric?.disconnected();
|
|
31352
|
+
clearInterval(legacyMonitorTimer);
|
|
31353
|
+
legacyMonitorTimer = void 0;
|
|
31354
|
+
incidentProducer.disconnected();
|
|
31355
|
+
if (!options.signal.aborted) supervisor.observe({ kind: "disconnected" });
|
|
31356
|
+
monitor(() => options.monitor?.setConnection("disconnected"));
|
|
29554
31357
|
connection?.close("agent_disconnect");
|
|
29555
31358
|
await bridge.disconnected();
|
|
29556
31359
|
connection = null;
|
|
@@ -29558,17 +31361,23 @@ async function runAgent(options) {
|
|
|
29558
31361
|
if (!options.signal.aborted) await aborted2(options.signal, delay);
|
|
29559
31362
|
}
|
|
29560
31363
|
} finally {
|
|
29561
|
-
|
|
29562
|
-
|
|
31364
|
+
try {
|
|
31365
|
+
await runtime.close();
|
|
31366
|
+
} finally {
|
|
31367
|
+
fabric?.close();
|
|
31368
|
+
incidentProducer.close();
|
|
31369
|
+
supervisor.close();
|
|
31370
|
+
await options.journal.close();
|
|
31371
|
+
}
|
|
29563
31372
|
}
|
|
29564
31373
|
}
|
|
29565
31374
|
async function main() {
|
|
29566
31375
|
if (process.platform !== "win32") throw Error("WINDOWS_REQUIRED");
|
|
29567
31376
|
const appData = process.env.LOCALAPPDATA;
|
|
29568
|
-
if (!appData || !
|
|
29569
|
-
const stateDir = process.env.LC_AGENT_STATE_DIR ??
|
|
29570
|
-
const binaryDir =
|
|
29571
|
-
const ownerBridgePath = process.env.LC_OWNER_BRIDGE ??
|
|
31377
|
+
if (!appData || !path17.isAbsolute(appData)) throw Error("APP_DATA_MISSING");
|
|
31378
|
+
const stateDir = process.env.LC_AGENT_STATE_DIR ?? path17.join(appData, "LocalCommander", "Agent");
|
|
31379
|
+
const binaryDir = path17.dirname(process.execPath);
|
|
31380
|
+
const ownerBridgePath = process.env.LC_OWNER_BRIDGE ?? path17.join(binaryDir, "OwnerBridge.exe");
|
|
29572
31381
|
const store = await WindowsPrivateStore.open(stateDir, ownerBridgePath);
|
|
29573
31382
|
const command = process.argv[2] ?? "run";
|
|
29574
31383
|
if (command === "pair") {
|
|
@@ -29577,7 +31386,7 @@ async function main() {
|
|
|
29577
31386
|
const pairing = new PairingClient(store, { controlPlaneOrigin: origin, agentVersion: AGENT_VERSION2 });
|
|
29578
31387
|
const begun = await pairing.begin();
|
|
29579
31388
|
process.stdout.write(JSON.stringify({ approvalUrl: begun.approvalUrl, confirmationCode: begun.confirmationCode, expiresAt: begun.expiresAt.toISOString() }) + "\n");
|
|
29580
|
-
await pairing.waitAndComplete(begun,
|
|
31389
|
+
await pairing.waitAndComplete(begun, os4.hostname().slice(0, 120));
|
|
29581
31390
|
process.stdout.write("DEVICE_PAIRED\n");
|
|
29582
31391
|
return;
|
|
29583
31392
|
}
|
|
@@ -29617,9 +31426,28 @@ async function main() {
|
|
|
29617
31426
|
return;
|
|
29618
31427
|
}
|
|
29619
31428
|
const args = process.argv.slice(3);
|
|
31429
|
+
if (command === "fabric-owner" || command === "fabric-worker") {
|
|
31430
|
+
if (args.length) throw Error("AGENT_COMMAND_INVALID");
|
|
31431
|
+
const enrollment = (await store.load())?.enrollment;
|
|
31432
|
+
if (!enrollment) throw Error("ENROLLMENT_MISSING");
|
|
31433
|
+
const input2 = await readFabricRequest();
|
|
31434
|
+
const fabric = await openNativeFabric(
|
|
31435
|
+
stateDir,
|
|
31436
|
+
enrollment,
|
|
31437
|
+
new SecretBox({ "1": await store.loadDataKey() }),
|
|
31438
|
+
command === "fabric-owner"
|
|
31439
|
+
);
|
|
31440
|
+
try {
|
|
31441
|
+
const result2 = command === "fabric-owner" ? await fabric.owner(input2) : await fabric.worker(input2);
|
|
31442
|
+
process.stdout.write(JSON.stringify(result2) + "\n");
|
|
31443
|
+
} finally {
|
|
31444
|
+
fabric.close();
|
|
31445
|
+
}
|
|
31446
|
+
return;
|
|
31447
|
+
}
|
|
29620
31448
|
if (command === "efficiency-report") {
|
|
29621
31449
|
if (args.length) throw Error("AGENT_COMMAND_INVALID");
|
|
29622
|
-
const ledger = await OptimizationLedger.open(
|
|
31450
|
+
const ledger = await OptimizationLedger.open(path17.join(stateDir, "optimization"));
|
|
29623
31451
|
try {
|
|
29624
31452
|
process.stdout.write(JSON.stringify(await ledger.report(), null, 2) + "\n");
|
|
29625
31453
|
} finally {
|
|
@@ -29629,7 +31457,7 @@ async function main() {
|
|
|
29629
31457
|
}
|
|
29630
31458
|
if (command === "guard-configure") {
|
|
29631
31459
|
if (args.length !== 1) throw Error("AGENT_COMMAND_INVALID");
|
|
29632
|
-
const filename = await (await import("node:fs/promises")).realpath(
|
|
31460
|
+
const filename = await (await import("node:fs/promises")).realpath(path17.resolve(args[0]));
|
|
29633
31461
|
const input2 = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(await readWindowsFile(ownerBridgePath, filename, 2e5)));
|
|
29634
31462
|
if (!input2 || typeof input2 !== "object" || Object.keys(input2).sort().join(",") !== "compact,settings") throw Error("GUARD_CONFIGURATION_INVALID");
|
|
29635
31463
|
await store.configureGuard(input2.settings, input2.compact);
|
|
@@ -29648,7 +31476,7 @@ async function main() {
|
|
|
29648
31476
|
}
|
|
29649
31477
|
if (command === "guard-evidence") {
|
|
29650
31478
|
if (args.length) throw Error("AGENT_COMMAND_INVALID");
|
|
29651
|
-
const journal = await NativeJournal.open(
|
|
31479
|
+
const journal = await NativeJournal.open(path17.join(stateDir, "journal"), new SecretBox({ "1": await store.loadDataKey() }));
|
|
29652
31480
|
try {
|
|
29653
31481
|
process.stdout.write(JSON.stringify(await journal.guardEvidence()) + "\n");
|
|
29654
31482
|
} finally {
|
|
@@ -29660,7 +31488,7 @@ async function main() {
|
|
|
29660
31488
|
if (args.length !== (command === "guard-export" ? 0 : 1)) throw Error("AGENT_COMMAND_INVALID");
|
|
29661
31489
|
const identity = await store.load();
|
|
29662
31490
|
if (!identity?.enrollment) throw Error("ENROLLMENT_MISSING");
|
|
29663
|
-
const journal = await NativeJournal.open(
|
|
31491
|
+
const journal = await NativeJournal.open(path17.join(stateDir, "journal"), new SecretBox({ "1": await store.loadDataKey() }));
|
|
29664
31492
|
try {
|
|
29665
31493
|
const { tenantId, deviceId } = identity.enrollment;
|
|
29666
31494
|
const records = (await journal.guardEvidence()).filter((record2) => record2.tenantId === tenantId && record2.deviceId === deviceId);
|
|
@@ -29698,41 +31526,62 @@ async function main() {
|
|
|
29698
31526
|
if (args.length) throw Error("AGENT_COMMAND_INVALID");
|
|
29699
31527
|
if (!(await store.load())?.enrollment) throw Error("ENROLLMENT_MISSING");
|
|
29700
31528
|
const releaseProcess = await claimAgentProcess(stateDir, binaryDir, AGENT_VERSION2);
|
|
29701
|
-
const monitor = new ProductionMonitor(
|
|
31529
|
+
const monitor = new ProductionMonitor(path17.join(appData, "LocalCommander", "Monitor"), stateDir, AGENT_VERSION2);
|
|
29702
31530
|
const publishMonitor = () => monitor.flush().catch(() => {
|
|
29703
31531
|
process.stderr.write("MONITOR_WRITE_FAILED\n");
|
|
29704
31532
|
});
|
|
29705
31533
|
await publishMonitor();
|
|
29706
|
-
const monitorTimer = setInterval(() => {
|
|
29707
|
-
void publishMonitor();
|
|
29708
|
-
}, 2e3);
|
|
29709
31534
|
try {
|
|
29710
|
-
const journal = await NativeJournal.open(
|
|
29711
|
-
const efficiencyLedger = await OptimizationLedger.open(
|
|
31535
|
+
const journal = await NativeJournal.open(path17.join(stateDir, "journal"), new SecretBox({ "1": await store.loadDataKey() }));
|
|
31536
|
+
const efficiencyLedger = await OptimizationLedger.open(path17.join(stateDir, "optimization"));
|
|
29712
31537
|
try {
|
|
29713
|
-
const tools = new NativeTools({ stateDirectory: stateDir, helperPath: process.env.LC_JOB_HOST ??
|
|
31538
|
+
const tools = new NativeTools({ stateDirectory: stateDir, helperPath: process.env.LC_JOB_HOST ?? path17.join(binaryDir, "JobHost.exe"), ownerBridgePath, programs: await store.loadPrograms() });
|
|
29714
31539
|
const stop = new AbortController();
|
|
29715
31540
|
process.once("SIGINT", () => stop.abort());
|
|
29716
31541
|
process.once("SIGTERM", () => stop.abort());
|
|
29717
31542
|
const guard = await NativeGuard.open(store, journal);
|
|
29718
|
-
|
|
29719
|
-
|
|
31543
|
+
const enrollment = (await store.load()).enrollment;
|
|
31544
|
+
const fabric = await openNativeFabric(stateDir, enrollment, new SecretBox({ "1": await store.loadDataKey() })).catch(() => {
|
|
31545
|
+
process.stderr.write("FABRIC_STARTUP_FAILED\n");
|
|
31546
|
+
return void 0;
|
|
31547
|
+
});
|
|
31548
|
+
try {
|
|
31549
|
+
await runAgent({
|
|
31550
|
+
store,
|
|
31551
|
+
journal,
|
|
31552
|
+
tools,
|
|
31553
|
+
signal: stop.signal,
|
|
31554
|
+
agentVersion: AGENT_VERSION2,
|
|
31555
|
+
guard,
|
|
31556
|
+
efficiencyLedger,
|
|
31557
|
+
monitor,
|
|
31558
|
+
...fabric ? { fabric: fabric.source } : {}
|
|
31559
|
+
});
|
|
31560
|
+
} finally {
|
|
31561
|
+
fabric?.close();
|
|
31562
|
+
}
|
|
31563
|
+
try {
|
|
31564
|
+
monitor.setConnection("stopped");
|
|
31565
|
+
} catch {
|
|
31566
|
+
}
|
|
29720
31567
|
} finally {
|
|
29721
31568
|
await efficiencyLedger.close();
|
|
29722
31569
|
await journal.close();
|
|
29723
31570
|
}
|
|
29724
31571
|
} catch (error62) {
|
|
29725
|
-
|
|
31572
|
+
try {
|
|
31573
|
+
monitor.setConnection("failed");
|
|
31574
|
+
} catch {
|
|
31575
|
+
}
|
|
29726
31576
|
throw error62;
|
|
29727
31577
|
} finally {
|
|
29728
|
-
clearInterval(monitorTimer);
|
|
29729
31578
|
await monitor.close().catch(() => {
|
|
29730
31579
|
process.stderr.write("MONITOR_WRITE_FAILED\n");
|
|
29731
31580
|
});
|
|
29732
31581
|
await releaseProcess();
|
|
29733
31582
|
}
|
|
29734
31583
|
}
|
|
29735
|
-
if (process.argv[1] &&
|
|
31584
|
+
if (process.argv[1] && path17.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
|
|
29736
31585
|
void main().catch((error62) => {
|
|
29737
31586
|
const code = error62 instanceof Error && /^[A-Z0-9_]{1,64}$/.test(error62.message) ? error62.message : "AGENT_START_FAILED";
|
|
29738
31587
|
process.stderr.write(code + "\n");
|