local-commander-agent 0.3.45 → 0.3.47
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -0
- package/README.md +1 -1
- package/bin/localcommander.mjs +17 -0
- package/bin/posix.mjs +84 -66
- package/package.json +4 -4
- package/runtime/JobHost.exe +0 -0
- package/runtime/LocalCommanderAgent.exe +0 -0
- package/runtime/OwnerBridge.exe +0 -0
- package/runtime/agent.mjs +1717 -340
package/runtime/agent.mjs
CHANGED
|
@@ -2125,7 +2125,7 @@ var require_extension = __commonJS({
|
|
|
2125
2125
|
if (dest[name2] === void 0) dest[name2] = [elem];
|
|
2126
2126
|
else dest[name2].push(elem);
|
|
2127
2127
|
}
|
|
2128
|
-
function
|
|
2128
|
+
function parse4(header) {
|
|
2129
2129
|
const offers = /* @__PURE__ */ Object.create(null);
|
|
2130
2130
|
let params = /* @__PURE__ */ Object.create(null);
|
|
2131
2131
|
let mustUnescape = false;
|
|
@@ -2265,7 +2265,7 @@ var require_extension = __commonJS({
|
|
|
2265
2265
|
}).join(", ");
|
|
2266
2266
|
}).join(", ");
|
|
2267
2267
|
}
|
|
2268
|
-
module.exports = { format, parse:
|
|
2268
|
+
module.exports = { format, parse: parse4 };
|
|
2269
2269
|
}
|
|
2270
2270
|
});
|
|
2271
2271
|
|
|
@@ -2276,9 +2276,9 @@ var require_websocket = __commonJS({
|
|
|
2276
2276
|
var EventEmitter = __require("events");
|
|
2277
2277
|
var https2 = __require("https");
|
|
2278
2278
|
var http2 = __require("http");
|
|
2279
|
-
var
|
|
2279
|
+
var net3 = __require("net");
|
|
2280
2280
|
var tls2 = __require("tls");
|
|
2281
|
-
var { randomBytes:
|
|
2281
|
+
var { randomBytes: randomBytes11, createHash: createHash21 } = __require("crypto");
|
|
2282
2282
|
var { Duplex, Readable } = __require("stream");
|
|
2283
2283
|
var { URL: URL2 } = __require("url");
|
|
2284
2284
|
var PerMessageDeflate2 = require_permessage_deflate();
|
|
@@ -2299,7 +2299,7 @@ var require_websocket = __commonJS({
|
|
|
2299
2299
|
var {
|
|
2300
2300
|
EventTarget: { addEventListener, removeEventListener }
|
|
2301
2301
|
} = require_event_target();
|
|
2302
|
-
var { format, parse:
|
|
2302
|
+
var { format, parse: parse4 } = require_extension();
|
|
2303
2303
|
var { toBuffer } = require_buffer_util();
|
|
2304
2304
|
var kAborted = /* @__PURE__ */ Symbol("kAborted");
|
|
2305
2305
|
var protocolVersions = [8, 13];
|
|
@@ -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 = randomBytes11(16).toString("base64");
|
|
2833
2833
|
const request = isSecure ? https2.request : http2.request;
|
|
2834
2834
|
const protocolSet = /* @__PURE__ */ new Set();
|
|
2835
2835
|
let perMessageDeflate;
|
|
@@ -2989,7 +2989,7 @@ var require_websocket = __commonJS({
|
|
|
2989
2989
|
}
|
|
2990
2990
|
let extensions;
|
|
2991
2991
|
try {
|
|
2992
|
-
extensions =
|
|
2992
|
+
extensions = parse4(secWebSocketExtensions);
|
|
2993
2993
|
} catch (err) {
|
|
2994
2994
|
const message2 = "Invalid Sec-WebSocket-Extensions header";
|
|
2995
2995
|
abortHandshake(websocket, socket, message2);
|
|
@@ -3033,12 +3033,12 @@ var require_websocket = __commonJS({
|
|
|
3033
3033
|
}
|
|
3034
3034
|
function netConnect2(options) {
|
|
3035
3035
|
options.path = options.socketPath;
|
|
3036
|
-
return
|
|
3036
|
+
return net3.connect(options);
|
|
3037
3037
|
}
|
|
3038
3038
|
function tlsConnect(options) {
|
|
3039
3039
|
options.path = void 0;
|
|
3040
3040
|
if (!options.servername && options.servername !== "") {
|
|
3041
|
-
options.servername =
|
|
3041
|
+
options.servername = net3.isIP(options.host) ? "" : options.host;
|
|
3042
3042
|
}
|
|
3043
3043
|
return tls2.connect(options);
|
|
3044
3044
|
}
|
|
@@ -3281,7 +3281,7 @@ var require_subprotocol = __commonJS({
|
|
|
3281
3281
|
"../../node_modules/ws/lib/subprotocol.js"(exports, module) {
|
|
3282
3282
|
"use strict";
|
|
3283
3283
|
var { tokenChars } = require_validation();
|
|
3284
|
-
function
|
|
3284
|
+
function parse4(header) {
|
|
3285
3285
|
const protocols = /* @__PURE__ */ new Set();
|
|
3286
3286
|
let start = -1;
|
|
3287
3287
|
let end = -1;
|
|
@@ -3317,7 +3317,7 @@ var require_subprotocol = __commonJS({
|
|
|
3317
3317
|
protocols.add(protocol2);
|
|
3318
3318
|
return protocols;
|
|
3319
3319
|
}
|
|
3320
|
-
module.exports = { parse:
|
|
3320
|
+
module.exports = { parse: parse4 };
|
|
3321
3321
|
}
|
|
3322
3322
|
});
|
|
3323
3323
|
|
|
@@ -4541,10 +4541,10 @@ function mergeDefs(...defs) {
|
|
|
4541
4541
|
function cloneDef(schema) {
|
|
4542
4542
|
return mergeDefs(schema._zod.def);
|
|
4543
4543
|
}
|
|
4544
|
-
function getElementAtPath(obj,
|
|
4545
|
-
if (!
|
|
4544
|
+
function getElementAtPath(obj, path30) {
|
|
4545
|
+
if (!path30)
|
|
4546
4546
|
return obj;
|
|
4547
|
-
return
|
|
4547
|
+
return path30.reduce((acc, key) => acc?.[key], obj);
|
|
4548
4548
|
}
|
|
4549
4549
|
function promiseAllObject(promisesObj) {
|
|
4550
4550
|
const keys = Object.keys(promisesObj);
|
|
@@ -4884,11 +4884,11 @@ function explicitlyAborted(x, startIndex = 0) {
|
|
|
4884
4884
|
}
|
|
4885
4885
|
return false;
|
|
4886
4886
|
}
|
|
4887
|
-
function prefixIssues(
|
|
4887
|
+
function prefixIssues(path30, issues) {
|
|
4888
4888
|
return issues.map((iss) => {
|
|
4889
4889
|
var _a3;
|
|
4890
4890
|
(_a3 = iss).path ?? (_a3.path = []);
|
|
4891
|
-
iss.path.unshift(
|
|
4891
|
+
iss.path.unshift(path30);
|
|
4892
4892
|
return iss;
|
|
4893
4893
|
});
|
|
4894
4894
|
}
|
|
@@ -5338,16 +5338,16 @@ function flattenError(error62, mapper = (issue2) => issue2.message) {
|
|
|
5338
5338
|
}
|
|
5339
5339
|
function formatError(error62, mapper = (issue2) => issue2.message) {
|
|
5340
5340
|
const fieldErrors = { _errors: [] };
|
|
5341
|
-
const processError = (error63,
|
|
5341
|
+
const processError = (error63, path30 = []) => {
|
|
5342
5342
|
for (const issue2 of error63.issues) {
|
|
5343
5343
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
5344
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
5344
|
+
issue2.errors.map((issues) => processError({ issues }, [...path30, ...issue2.path]));
|
|
5345
5345
|
} else if (issue2.code === "invalid_key") {
|
|
5346
|
-
processError({ issues: issue2.issues }, [...
|
|
5346
|
+
processError({ issues: issue2.issues }, [...path30, ...issue2.path]);
|
|
5347
5347
|
} else if (issue2.code === "invalid_element") {
|
|
5348
|
-
processError({ issues: issue2.issues }, [...
|
|
5348
|
+
processError({ issues: issue2.issues }, [...path30, ...issue2.path]);
|
|
5349
5349
|
} else {
|
|
5350
|
-
const fullpath = [...
|
|
5350
|
+
const fullpath = [...path30, ...issue2.path];
|
|
5351
5351
|
if (fullpath.length === 0) {
|
|
5352
5352
|
fieldErrors._errors.push(mapper(issue2));
|
|
5353
5353
|
} else {
|
|
@@ -5386,17 +5386,17 @@ function formatError(error62, mapper = (issue2) => issue2.message) {
|
|
|
5386
5386
|
}
|
|
5387
5387
|
function treeifyError(error62, mapper = (issue2) => issue2.message) {
|
|
5388
5388
|
const result2 = { errors: [] };
|
|
5389
|
-
const processError = (error63,
|
|
5389
|
+
const processError = (error63, path30 = []) => {
|
|
5390
5390
|
var _a3;
|
|
5391
5391
|
for (const issue2 of error63.issues) {
|
|
5392
5392
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
5393
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
5393
|
+
issue2.errors.map((issues) => processError({ issues }, [...path30, ...issue2.path]));
|
|
5394
5394
|
} else if (issue2.code === "invalid_key") {
|
|
5395
|
-
processError({ issues: issue2.issues }, [...
|
|
5395
|
+
processError({ issues: issue2.issues }, [...path30, ...issue2.path]);
|
|
5396
5396
|
} else if (issue2.code === "invalid_element") {
|
|
5397
|
-
processError({ issues: issue2.issues }, [...
|
|
5397
|
+
processError({ issues: issue2.issues }, [...path30, ...issue2.path]);
|
|
5398
5398
|
} else {
|
|
5399
|
-
const fullpath = [...
|
|
5399
|
+
const fullpath = [...path30, ...issue2.path];
|
|
5400
5400
|
if (fullpath.length === 0) {
|
|
5401
5401
|
result2.errors.push(mapper(issue2));
|
|
5402
5402
|
continue;
|
|
@@ -5435,8 +5435,8 @@ function treeifyError(error62, mapper = (issue2) => issue2.message) {
|
|
|
5435
5435
|
}
|
|
5436
5436
|
function toDotPath(_path) {
|
|
5437
5437
|
const segs = [];
|
|
5438
|
-
const
|
|
5439
|
-
for (const seg of
|
|
5438
|
+
const path30 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
5439
|
+
for (const seg of path30) {
|
|
5440
5440
|
if (typeof seg === "number")
|
|
5441
5441
|
segs.push(`[${seg}]`);
|
|
5442
5442
|
else if (typeof seg === "symbol")
|
|
@@ -5570,18 +5570,18 @@ var validateAsync = async (schema, value, _ctx) => {
|
|
|
5570
5570
|
return result2.issues.length === 0;
|
|
5571
5571
|
};
|
|
5572
5572
|
var _encode = (_Err) => {
|
|
5573
|
-
const
|
|
5573
|
+
const parse4 = _parse(_Err);
|
|
5574
5574
|
const fn = (schema, value, _ctx, _params) => {
|
|
5575
5575
|
const ctx = _ctx ? { ..._ctx, direction: "backward" } : { direction: "backward" };
|
|
5576
|
-
return
|
|
5576
|
+
return parse4(schema, value, ctx, finalizeParams(fn, _params));
|
|
5577
5577
|
};
|
|
5578
5578
|
return fn;
|
|
5579
5579
|
};
|
|
5580
5580
|
var encode = /* @__PURE__ */ _encode($ZodRealError);
|
|
5581
5581
|
var _decode = (_Err) => {
|
|
5582
|
-
const
|
|
5582
|
+
const parse4 = _parse(_Err);
|
|
5583
5583
|
const fn = (schema, value, _ctx, _params) => {
|
|
5584
|
-
return
|
|
5584
|
+
return parse4(schema, value, _ctx, finalizeParams(fn, _params));
|
|
5585
5585
|
};
|
|
5586
5586
|
return fn;
|
|
5587
5587
|
};
|
|
@@ -22538,13 +22538,13 @@ function resolveRef(ref, ctx) {
|
|
|
22538
22538
|
if (!ref.startsWith("#")) {
|
|
22539
22539
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
22540
22540
|
}
|
|
22541
|
-
const
|
|
22542
|
-
if (
|
|
22541
|
+
const path30 = ref.slice(1).split("/").filter(Boolean);
|
|
22542
|
+
if (path30.length === 0) {
|
|
22543
22543
|
return ctx.rootSchema;
|
|
22544
22544
|
}
|
|
22545
22545
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
22546
|
-
if (
|
|
22547
|
-
const key =
|
|
22546
|
+
if (path30[0] === defsKey) {
|
|
22547
|
+
const key = path30[1] === void 0 ? void 0 : decodeJSONPointerSegment(path30[1]);
|
|
22548
22548
|
if (!key || !ctx.defs[key]) {
|
|
22549
22549
|
throw new Error(`Reference not found: ${ref}`);
|
|
22550
22550
|
}
|
|
@@ -23179,7 +23179,7 @@ function visit(schema, fnOrHandlers) {
|
|
|
23179
23179
|
return h ? h(node2, rewritten) : node2;
|
|
23180
23180
|
};
|
|
23181
23181
|
const cache2 = /* @__PURE__ */ new Map();
|
|
23182
|
-
function
|
|
23182
|
+
function run2(s) {
|
|
23183
23183
|
const cached2 = cache2.get(s);
|
|
23184
23184
|
if (cached2 === RESOLVING) {
|
|
23185
23185
|
return new $ZodLazy({
|
|
@@ -23205,21 +23205,21 @@ function visit(schema, fnOrHandlers) {
|
|
|
23205
23205
|
let changed = false;
|
|
23206
23206
|
const newShape = {};
|
|
23207
23207
|
for (const k of keys) {
|
|
23208
|
-
const mapped =
|
|
23208
|
+
const mapped = run2(oldShape[k]);
|
|
23209
23209
|
if (mapped !== oldShape[k])
|
|
23210
23210
|
changed = true;
|
|
23211
23211
|
newShape[k] = mapped;
|
|
23212
23212
|
}
|
|
23213
23213
|
let newCatchall = def.catchall;
|
|
23214
23214
|
if (def.catchall) {
|
|
23215
|
-
newCatchall =
|
|
23215
|
+
newCatchall = run2(def.catchall);
|
|
23216
23216
|
if (newCatchall !== def.catchall)
|
|
23217
23217
|
changed = true;
|
|
23218
23218
|
}
|
|
23219
23219
|
return changed ? clone(s, { ...def, shape: newShape, catchall: newCatchall }) : s;
|
|
23220
23220
|
}
|
|
23221
23221
|
case "array": {
|
|
23222
|
-
const mapped =
|
|
23222
|
+
const mapped = run2(def.element);
|
|
23223
23223
|
return mapped === def.element ? s : clone(s, { ...def, element: mapped });
|
|
23224
23224
|
}
|
|
23225
23225
|
case "tuple": {
|
|
@@ -23227,14 +23227,14 @@ function visit(schema, fnOrHandlers) {
|
|
|
23227
23227
|
let changed = false;
|
|
23228
23228
|
const newItems = [];
|
|
23229
23229
|
for (const item of oldItems) {
|
|
23230
|
-
const mapped =
|
|
23230
|
+
const mapped = run2(item);
|
|
23231
23231
|
if (mapped !== item)
|
|
23232
23232
|
changed = true;
|
|
23233
23233
|
newItems.push(mapped);
|
|
23234
23234
|
}
|
|
23235
23235
|
let newRest = def.rest;
|
|
23236
23236
|
if (def.rest) {
|
|
23237
|
-
newRest =
|
|
23237
|
+
newRest = run2(def.rest);
|
|
23238
23238
|
if (newRest !== def.rest)
|
|
23239
23239
|
changed = true;
|
|
23240
23240
|
}
|
|
@@ -23242,12 +23242,12 @@ function visit(schema, fnOrHandlers) {
|
|
|
23242
23242
|
}
|
|
23243
23243
|
case "record":
|
|
23244
23244
|
case "map": {
|
|
23245
|
-
const newKey =
|
|
23246
|
-
const newVal =
|
|
23245
|
+
const newKey = run2(def.keyType);
|
|
23246
|
+
const newVal = run2(def.valueType);
|
|
23247
23247
|
return newKey === def.keyType && newVal === def.valueType ? s : clone(s, { ...def, keyType: newKey, valueType: newVal });
|
|
23248
23248
|
}
|
|
23249
23249
|
case "set": {
|
|
23250
|
-
const newVal =
|
|
23250
|
+
const newVal = run2(def.valueType);
|
|
23251
23251
|
return newVal === def.valueType ? s : clone(s, { ...def, valueType: newVal });
|
|
23252
23252
|
}
|
|
23253
23253
|
case "union": {
|
|
@@ -23255,7 +23255,7 @@ function visit(schema, fnOrHandlers) {
|
|
|
23255
23255
|
let changed = false;
|
|
23256
23256
|
const newOptions = [];
|
|
23257
23257
|
for (const opt of oldOptions) {
|
|
23258
|
-
const mapped =
|
|
23258
|
+
const mapped = run2(opt);
|
|
23259
23259
|
if (mapped !== opt)
|
|
23260
23260
|
changed = true;
|
|
23261
23261
|
newOptions.push(mapped);
|
|
@@ -23263,8 +23263,8 @@ function visit(schema, fnOrHandlers) {
|
|
|
23263
23263
|
return changed ? clone(s, { ...def, options: newOptions }) : s;
|
|
23264
23264
|
}
|
|
23265
23265
|
case "intersection": {
|
|
23266
|
-
const newLeft =
|
|
23267
|
-
const newRight =
|
|
23266
|
+
const newLeft = run2(def.left);
|
|
23267
|
+
const newRight = run2(def.right);
|
|
23268
23268
|
return newLeft === def.left && newRight === def.right ? s : clone(s, { ...def, left: newLeft, right: newRight });
|
|
23269
23269
|
}
|
|
23270
23270
|
case "optional":
|
|
@@ -23276,23 +23276,23 @@ function visit(schema, fnOrHandlers) {
|
|
|
23276
23276
|
case "nonoptional":
|
|
23277
23277
|
case "promise":
|
|
23278
23278
|
case "success": {
|
|
23279
|
-
const newInner =
|
|
23279
|
+
const newInner = run2(def.innerType);
|
|
23280
23280
|
return newInner === def.innerType ? s : clone(s, { ...def, innerType: newInner });
|
|
23281
23281
|
}
|
|
23282
23282
|
case "pipe": {
|
|
23283
|
-
const newIn =
|
|
23284
|
-
const newOut =
|
|
23283
|
+
const newIn = run2(def.in);
|
|
23284
|
+
const newOut = run2(def.out);
|
|
23285
23285
|
return newIn === def.in && newOut === def.out ? s : clone(s, { ...def, in: newIn, out: newOut });
|
|
23286
23286
|
}
|
|
23287
23287
|
case "function": {
|
|
23288
|
-
const newInput =
|
|
23289
|
-
const newOutput =
|
|
23288
|
+
const newInput = run2(def.input);
|
|
23289
|
+
const newOutput = run2(def.output);
|
|
23290
23290
|
return newInput === def.input && newOutput === def.output ? s : clone(s, { ...def, input: newInput, output: newOutput });
|
|
23291
23291
|
}
|
|
23292
23292
|
case "lazy": {
|
|
23293
23293
|
const original = def.getter;
|
|
23294
23294
|
const { _cachedInner, ...rest } = def;
|
|
23295
|
-
return clone(s, { ...rest, getter: () =>
|
|
23295
|
+
return clone(s, { ...rest, getter: () => run2(original()) });
|
|
23296
23296
|
}
|
|
23297
23297
|
// A leaf by choice: `parts` are regex fragments, not data positions.
|
|
23298
23298
|
case "template_literal":
|
|
@@ -23323,7 +23323,7 @@ function visit(schema, fnOrHandlers) {
|
|
|
23323
23323
|
}
|
|
23324
23324
|
}
|
|
23325
23325
|
}
|
|
23326
|
-
return
|
|
23326
|
+
return run2(schema);
|
|
23327
23327
|
}
|
|
23328
23328
|
|
|
23329
23329
|
// ../../node_modules/zod/v4/classic/deep-partial.js
|
|
@@ -25164,8 +25164,8 @@ async function openNetworkPanel(binaryDirectory, identity) {
|
|
|
25164
25164
|
}
|
|
25165
25165
|
|
|
25166
25166
|
// agent/src/main.ts
|
|
25167
|
-
import
|
|
25168
|
-
import
|
|
25167
|
+
import path29 from "node:path";
|
|
25168
|
+
import os8 from "node:os";
|
|
25169
25169
|
|
|
25170
25170
|
// agent/src/posix-store.ts
|
|
25171
25171
|
import { constants } from "node:fs";
|
|
@@ -25584,7 +25584,7 @@ async function acquirePosixJournalGuard(directory, helper) {
|
|
|
25584
25584
|
}
|
|
25585
25585
|
|
|
25586
25586
|
// agent/src/main.ts
|
|
25587
|
-
import { mkdir as mkdir14, open as open13, readFile as
|
|
25587
|
+
import { mkdir as mkdir14, open as open13, readFile as readFile12, realpath as realpath10, rm as rm10 } from "node:fs/promises";
|
|
25588
25588
|
import { fileURLToPath } from "node:url";
|
|
25589
25589
|
|
|
25590
25590
|
// packages/operations/src/crypto.ts
|
|
@@ -25721,13 +25721,13 @@ var exec2 = promisify2(execFile2);
|
|
|
25721
25721
|
async function darwinSupervisorLiveness(helper, pids, records = []) {
|
|
25722
25722
|
if (process.platform !== "darwin" || !process.getuid?.() || process.getuid() !== process.geteuid?.()) return null;
|
|
25723
25723
|
const remaining = new Set(pids), uid = process.getuid(), deadline = Date.now() + 1e4, env = buildChildEnvironment(process.env);
|
|
25724
|
-
const
|
|
25724
|
+
const run2 = (file2, args) => exec2(
|
|
25725
25725
|
file2,
|
|
25726
25726
|
args,
|
|
25727
25727
|
{ env, timeout: Math.max(1, Math.min(7e3, deadline - Date.now())), maxBuffer: 8192, encoding: "utf8", windowsHide: true }
|
|
25728
25728
|
);
|
|
25729
25729
|
try {
|
|
25730
|
-
const boot = (await
|
|
25730
|
+
const boot = (await run2("/usr/sbin/sysctl", ["-n", "kern.bootsessionuuid"])).stdout.trim();
|
|
25731
25731
|
if (!bootSession.test(boot)) return null;
|
|
25732
25732
|
for (const pid of remaining) {
|
|
25733
25733
|
if (Date.now() >= deadline) break;
|
|
@@ -25736,9 +25736,9 @@ async function darwinSupervisorLiveness(helper, pids, records = []) {
|
|
|
25736
25736
|
const proof2 = matches2[0].containment;
|
|
25737
25737
|
if (!validDarwinContainment(proof2) || proof2.uid !== uid || proof2.bootSession !== boot) continue;
|
|
25738
25738
|
try {
|
|
25739
|
-
await
|
|
25740
|
-
if ((await
|
|
25741
|
-
await
|
|
25739
|
+
await run2(helper, ["--reap", proof2.coalition]);
|
|
25740
|
+
if ((await run2(helper, ["--count", proof2.coalition])).stdout.trim() !== "0") continue;
|
|
25741
|
+
await run2("/bin/launchctl", ["bootout", "gui/" + uid + "/" + proof2.label]).catch(() => {
|
|
25742
25742
|
});
|
|
25743
25743
|
remaining.delete(pid);
|
|
25744
25744
|
} catch {
|
|
@@ -26445,10 +26445,12 @@ var ToolCallSchema = external_exports.discriminatedUnion("name", [
|
|
|
26445
26445
|
external_exports.object({ name: external_exports.literal("git_log"), args: external_exports.object({ path: path5.optional(), limit: external_exports.number().int().min(1).max(50).default(15) }).strict() }).strict(),
|
|
26446
26446
|
external_exports.object({ name: external_exports.literal("project_snapshot"), args: external_exports.object({ path: path5.optional(), startup: external_exports.boolean().optional(), taskId: external_exports.string().regex(/^[A-Za-z0-9_-]{1,100}$/).optional() }).strict() }).strict(),
|
|
26447
26447
|
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: path5.optional(), timeoutMs: external_exports.number().int().min(100).max(864e5).default(6e4) }).strict() }).strict(),
|
|
26448
|
+
// Still image of the device's primary display; the agent requires an owner Full Access workspace.
|
|
26449
|
+
external_exports.object({ name: external_exports.literal("take_screenshot"), args: external_exports.object({}).strict() }).strict(),
|
|
26448
26450
|
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()
|
|
26449
26451
|
]);
|
|
26450
26452
|
function scopeForTool(call) {
|
|
26451
|
-
if (call.name === "command_run") return "commands:execute";
|
|
26453
|
+
if (call.name === "command_run" || call.name === "take_screenshot") return "commands:execute";
|
|
26452
26454
|
if (call.name === "localhost_request") return "localhost:access";
|
|
26453
26455
|
return call.name === "fs_write" || call.name === "fs_replace" ? "files:write" : "files:read";
|
|
26454
26456
|
}
|
|
@@ -26464,10 +26466,12 @@ var ServerFrameSchema = external_exports.discriminatedUnion("type", [
|
|
|
26464
26466
|
external_exports.object({ type: external_exports.literal("workspace_ack"), version: external_exports.literal(1), requestId: uuid11, workspaceGrantId: uuid11, accepted: external_exports.boolean(), code: external_exports.string().max(64).optional() }).strict(),
|
|
26465
26467
|
external_exports.object({ type: external_exports.literal("revoke"), version: external_exports.literal(1), reason: external_exports.enum(["device_revoked", "account_revoked", "server_shutdown", "connection_replaced"]) }).strict()
|
|
26466
26468
|
]);
|
|
26469
|
+
var WORKSPACE_ACCESS_MODE_CAPABILITY = "workspaceAccessModeV1";
|
|
26470
|
+
var WorkspaceAccessModeSchema = external_exports.enum(["full", "scoped"]);
|
|
26467
26471
|
var ClientFrameSchema = external_exports.discriminatedUnion("type", [
|
|
26468
26472
|
external_exports.object({ type: external_exports.literal("ready"), version: external_exports.literal(1), safeSlots: external_exports.number().int().min(1).max(128), platform: external_exports.literal("win32"), agentVersion: external_exports.string().regex(/^[A-Za-z0-9._+-]{1,64}$/), supervisor: external_exports.boolean() }).strict(),
|
|
26469
26473
|
external_exports.object({ type: external_exports.literal("heartbeat"), version: external_exports.literal(1), connectionEpoch: epoch2 }).strict(),
|
|
26470
|
-
external_exports.object({ type: external_exports.literal("workspace_grant"), version: external_exports.literal(1), requestId: uuid11, workspaceGrantId: uuid11, rootHash: hash3, displayName: external_exports.string().min(1).max(120), policyVersion: external_exports.number().int().min(1).max(2147483647) }).strict(),
|
|
26474
|
+
external_exports.object({ type: external_exports.literal("workspace_grant"), version: external_exports.literal(1), requestId: uuid11, workspaceGrantId: uuid11, rootHash: hash3, displayName: external_exports.string().min(1).max(120), policyVersion: external_exports.number().int().min(1).max(2147483647), accessMode: WorkspaceAccessModeSchema.optional() }).strict(),
|
|
26471
26475
|
external_exports.object({ type: external_exports.literal("workspace_revoke"), version: external_exports.literal(1), requestId: uuid11, workspaceGrantId: uuid11 }).strict(),
|
|
26472
26476
|
external_exports.object({ type: external_exports.literal("prepared"), version: external_exports.literal(1), binding: ExecutionBindingSchema }).strict(),
|
|
26473
26477
|
external_exports.object({ type: external_exports.literal("accepted"), version: external_exports.literal(1), binding: ExecutionBindingSchema }).strict(),
|
|
@@ -26552,6 +26556,7 @@ function guardAction(binding2, tool, config2, observedAt) {
|
|
|
26552
26556
|
throw Error("GUARD_IDENTITY_REQUIRED");
|
|
26553
26557
|
}
|
|
26554
26558
|
const name2 = tool.call.name;
|
|
26559
|
+
if (name2 === "take_screenshot") throw Error("GUARD_ACTION_UNSUPPORTED");
|
|
26555
26560
|
const kind = name2 === "command_run" ? "execute" : name2 === "localhost_request" ? "localhost-access" : name2 === "fs_write" || name2 === "fs_replace" ? "write" : name2.startsWith("git_") ? "git-read" : "read";
|
|
26556
26561
|
const resourceKind = kind === "execute" ? "workspace" : kind === "localhost-access" ? "localhost-service" : kind === "git-read" ? "git-repository" : name2 === "fs_read" || kind === "write" ? "file" : "workspace";
|
|
26557
26562
|
return { payloadHash: guardHash(tool.effective), request: BoundActionRequestSchema.parse({
|
|
@@ -27027,9 +27032,9 @@ var NativeJournal = class _NativeJournal {
|
|
|
27027
27032
|
if (!validPid(pid)) throw failure2("JOURNAL_INPUT_INVALID");
|
|
27028
27033
|
if (e.state !== "running" || !e.supervisors) throw failure2("JOURNAL_STATE_INVALID");
|
|
27029
27034
|
if (containment !== void 0) {
|
|
27030
|
-
const
|
|
27031
|
-
if (!
|
|
27032
|
-
if (
|
|
27035
|
+
const linux2 = validLinuxContainment(containment), darwin = !linux2 && validDarwinContainment(containment);
|
|
27036
|
+
if (!linux2 && !darwin || !e.supervisors.includes(pid) || e.linuxSupervisors?.some((s) => s.pid === pid) || e.darwinSupervisors?.some((s) => s.pid === pid)) throw failure2("JOURNAL_INPUT_INVALID");
|
|
27037
|
+
if (linux2) (e.linuxSupervisors ??= []).push({ pid, containment: clone2(containment) });
|
|
27033
27038
|
else (e.darwinSupervisors ??= []).push({ pid, containment: clone2(containment) });
|
|
27034
27039
|
} else {
|
|
27035
27040
|
if (e.supervisors.length >= MAX_SUPERVISORS) throw failure2("JOURNAL_SUPERVISOR_LIMIT");
|
|
@@ -27233,6 +27238,7 @@ import { constants as constants4 } from "node:fs";
|
|
|
27233
27238
|
|
|
27234
27239
|
// agent/src/posix-consent.ts
|
|
27235
27240
|
import { openSync, closeSync } from "node:fs";
|
|
27241
|
+
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
27236
27242
|
import { isatty, ReadStream, WriteStream } from "node:tty";
|
|
27237
27243
|
import { createInterface } from "node:readline/promises";
|
|
27238
27244
|
import path8 from "node:path";
|
|
@@ -27335,7 +27341,7 @@ async function planPermissionChange(current2, programs, input2) {
|
|
|
27335
27341
|
}
|
|
27336
27342
|
|
|
27337
27343
|
// agent/src/posix-consent.ts
|
|
27338
|
-
async function terminal2(
|
|
27344
|
+
async function terminal2(run2, timeoutMs2, signal) {
|
|
27339
27345
|
if (!process.getuid || process.getuid() === 0 || process.geteuid?.() !== process.getuid() || signal?.aborted) throw Error("OWNER_REVIEW_UNAVAILABLE");
|
|
27340
27346
|
let readFd;
|
|
27341
27347
|
try {
|
|
@@ -27371,7 +27377,7 @@ async function terminal2(run, timeoutMs2, signal) {
|
|
|
27371
27377
|
};
|
|
27372
27378
|
input2.on("data", bound);
|
|
27373
27379
|
try {
|
|
27374
|
-
return await
|
|
27380
|
+
return await run2(async (prompt) => {
|
|
27375
27381
|
if (stop.signal.aborted) throw Error("OWNER_REVIEW_CANCELLED");
|
|
27376
27382
|
return review.question(prompt, { signal: stop.signal });
|
|
27377
27383
|
});
|
|
@@ -27400,16 +27406,41 @@ async function choosePosixFolder() {
|
|
|
27400
27406
|
return await ask("Read/write folder: " + permissionLabel(folder) + "\nType APPROVE to accept: ") === "APPROVE" ? folder : null;
|
|
27401
27407
|
}, 12e4);
|
|
27402
27408
|
}
|
|
27409
|
+
var ACCESS_TEXT = "Local Commander lets your AI work on this computer.\n\nFull Access: files, commands and localhost with your account's rights (not an OS sandbox).\nChoose Folder: read and write one folder only.\n\nThis replaces the previous selection and lasts until you change or revoke it.";
|
|
27410
|
+
function selection(folder, full) {
|
|
27411
|
+
if (!path8.isAbsolute(folder) || folder.length > 4096 || /[\u0000-\u001f]/.test(folder)) throw Error("WORKSPACE_INVALID");
|
|
27412
|
+
return { mode: full ? "all-drives" : "folders", paths: [full ? "/" : folder] };
|
|
27413
|
+
}
|
|
27414
|
+
function macDialog() {
|
|
27415
|
+
const script = [
|
|
27416
|
+
"on run argv",
|
|
27417
|
+
'set answer to button returned of (display dialog (item 1 of argv) with title "Local Commander" buttons {"Cancel", "Choose Folder\uFFFD", "Full Access"} default button "Full Access" cancel button "Cancel" with icon note)',
|
|
27418
|
+
'if answer is "Full Access" then return "full"',
|
|
27419
|
+
'return "folder:" & POSIX path of (choose folder with prompt "Choose the folder Local Commander may read and write")',
|
|
27420
|
+
"end run"
|
|
27421
|
+
];
|
|
27422
|
+
const result2 = spawnSync2(
|
|
27423
|
+
"/usr/bin/osascript",
|
|
27424
|
+
[...script.flatMap((line) => ["-e", line]), ACCESS_TEXT],
|
|
27425
|
+
{ encoding: "utf8", timeout: 24e4, maxBuffer: 16384, shell: false }
|
|
27426
|
+
);
|
|
27427
|
+
if (result2.error) return void 0;
|
|
27428
|
+
if (result2.status !== 0) return /\(-128\)/.test(result2.stderr) ? null : void 0;
|
|
27429
|
+
const out = result2.stdout.replace(/\n$/, "");
|
|
27430
|
+
if (out === "full") return selection("/", true);
|
|
27431
|
+
if (out.startsWith("folder:")) return selection(out.slice(7).replace(/(.)\/$/, "$1"), false);
|
|
27432
|
+
return void 0;
|
|
27433
|
+
}
|
|
27403
27434
|
async function choosePosixAccess() {
|
|
27435
|
+
if (process.platform === "darwin") {
|
|
27436
|
+
const chosen = macDialog();
|
|
27437
|
+
if (chosen !== void 0) return chosen;
|
|
27438
|
+
}
|
|
27404
27439
|
return terminal2(async (ask) => {
|
|
27405
|
-
|
|
27406
|
-
|
|
27407
|
-
if (
|
|
27408
|
-
|
|
27409
|
-
if (!path8.isAbsolute(folder) || folder.length > 4096 || /[\u0000-\u001f]/.test(folder)) throw Error("WORKSPACE_INVALID");
|
|
27410
|
-
const summary = choice === "2" ? "Full Access allows programs to use your account's capabilities across this computer. This is not an OS sandbox." : "Allow reading and writing files in " + permissionLabel(folder) + ".";
|
|
27411
|
-
if (await ask(summary + "\nThis replaces the previous folder/command/localhost selection and persists until revoked.\nType APPROVE to accept: ") !== "APPROVE") return null;
|
|
27412
|
-
return { mode: choice === "2" ? "all-drives" : "folders", paths: [folder] };
|
|
27440
|
+
const answer = await ask("\n" + ACCESS_TEXT + "\n\nPress Enter for Full Access, type a folder path for one folder, or n to cancel: ");
|
|
27441
|
+
if (answer === "") return selection("/", true);
|
|
27442
|
+
if (/^(n|no|cancel)$/i.test(answer)) return null;
|
|
27443
|
+
return selection(answer, false);
|
|
27413
27444
|
}, 24e4);
|
|
27414
27445
|
}
|
|
27415
27446
|
|
|
@@ -28876,9 +28907,9 @@ var HostMemory = class {
|
|
|
28876
28907
|
};
|
|
28877
28908
|
|
|
28878
28909
|
// agent/src/tools.ts
|
|
28879
|
-
import { constants as
|
|
28880
|
-
import { lstat as
|
|
28881
|
-
import
|
|
28910
|
+
import { constants as constants8 } from "node:fs";
|
|
28911
|
+
import { lstat as lstat8, open as open6, readdir as readdir5, realpath as realpath7, rename as rename4, rm as rm6 } from "node:fs/promises";
|
|
28912
|
+
import path18 from "node:path";
|
|
28882
28913
|
import { createHash as createHash14, randomUUID as randomUUID7 } from "node:crypto";
|
|
28883
28914
|
|
|
28884
28915
|
// src/guard.ts
|
|
@@ -29322,6 +29353,1249 @@ async function runSupervised(helper, request, options = {}) {
|
|
|
29322
29353
|
});
|
|
29323
29354
|
}
|
|
29324
29355
|
|
|
29356
|
+
// agent/src/screen-capture.ts
|
|
29357
|
+
import { execFile as execFile4 } from "node:child_process";
|
|
29358
|
+
import { randomBytes as randomBytes6 } from "node:crypto";
|
|
29359
|
+
import { constants as constants7 } from "node:fs";
|
|
29360
|
+
import { access as access3, lstat as lstat7, mkdtemp, readFile as readFile6, readdir as readdir4, rm as rm5, unlink as unlink2 } from "node:fs/promises";
|
|
29361
|
+
import os4 from "node:os";
|
|
29362
|
+
import path17 from "node:path";
|
|
29363
|
+
|
|
29364
|
+
// agent/src/dbus-portal.ts
|
|
29365
|
+
import net from "node:net";
|
|
29366
|
+
function sessionBusSocket(address) {
|
|
29367
|
+
for (const entry of (address ?? "").split(";")) {
|
|
29368
|
+
if (!entry.startsWith("unix:")) continue;
|
|
29369
|
+
for (const part of entry.slice(5).split(",")) {
|
|
29370
|
+
const at = part.indexOf("="), key = part.slice(0, at), value = decodeURIComponent(part.slice(at + 1));
|
|
29371
|
+
if (at > 0 && value && key === "path") return value;
|
|
29372
|
+
if (at > 0 && value && key === "abstract") return "\0" + value;
|
|
29373
|
+
}
|
|
29374
|
+
}
|
|
29375
|
+
return null;
|
|
29376
|
+
}
|
|
29377
|
+
var Writer = class {
|
|
29378
|
+
bytes = [];
|
|
29379
|
+
align(n) {
|
|
29380
|
+
while (this.bytes.length % n) this.bytes.push(0);
|
|
29381
|
+
}
|
|
29382
|
+
byte(v) {
|
|
29383
|
+
this.bytes.push(v & 255);
|
|
29384
|
+
}
|
|
29385
|
+
u32(v) {
|
|
29386
|
+
this.align(4);
|
|
29387
|
+
this.bytes.push(v & 255, v >>> 8 & 255, v >>> 16 & 255, v >>> 24 & 255);
|
|
29388
|
+
}
|
|
29389
|
+
str(v) {
|
|
29390
|
+
const b = Buffer.from(v, "utf8");
|
|
29391
|
+
this.u32(b.length);
|
|
29392
|
+
this.bytes.push(...b, 0);
|
|
29393
|
+
}
|
|
29394
|
+
sig(v) {
|
|
29395
|
+
this.byte(v.length);
|
|
29396
|
+
this.bytes.push(...Buffer.from(v, "ascii"), 0);
|
|
29397
|
+
}
|
|
29398
|
+
/** Basic value or variant: `s`, `o`, `g`, `u`, `b`, `v` ([signature, value]). */
|
|
29399
|
+
put(type, value) {
|
|
29400
|
+
if (type === "s" || type === "o") this.str(String(value));
|
|
29401
|
+
else if (type === "g") this.sig(String(value));
|
|
29402
|
+
else if (type === "u") this.u32(Number(value));
|
|
29403
|
+
else if (type === "b") this.u32(value ? 1 : 0);
|
|
29404
|
+
else if (type === "v") {
|
|
29405
|
+
const [inner, v] = value;
|
|
29406
|
+
this.sig(inner);
|
|
29407
|
+
this.put(inner, v);
|
|
29408
|
+
} else throw Error("type " + type);
|
|
29409
|
+
}
|
|
29410
|
+
/** a{sv} */
|
|
29411
|
+
dict(entries) {
|
|
29412
|
+
this.u32(0);
|
|
29413
|
+
const lengthAt = this.bytes.length - 4;
|
|
29414
|
+
this.align(8);
|
|
29415
|
+
const start = this.bytes.length;
|
|
29416
|
+
for (const [key, value] of entries) {
|
|
29417
|
+
this.align(8);
|
|
29418
|
+
this.str(key);
|
|
29419
|
+
this.put("v", value);
|
|
29420
|
+
}
|
|
29421
|
+
const length = this.bytes.length - start;
|
|
29422
|
+
this.bytes.splice(lengthAt, 4, length & 255, length >>> 8 & 255, length >>> 16 & 255, length >>> 24 & 255);
|
|
29423
|
+
}
|
|
29424
|
+
};
|
|
29425
|
+
var Reader = class {
|
|
29426
|
+
constructor(data, at, le) {
|
|
29427
|
+
this.data = data;
|
|
29428
|
+
this.at = at;
|
|
29429
|
+
this.le = le;
|
|
29430
|
+
}
|
|
29431
|
+
data;
|
|
29432
|
+
at;
|
|
29433
|
+
le;
|
|
29434
|
+
align(n) {
|
|
29435
|
+
this.at = Math.ceil(this.at / n) * n;
|
|
29436
|
+
}
|
|
29437
|
+
u32() {
|
|
29438
|
+
this.align(4);
|
|
29439
|
+
const v = this.le ? this.data.readUInt32LE(this.at) : this.data.readUInt32BE(this.at);
|
|
29440
|
+
this.at += 4;
|
|
29441
|
+
return v;
|
|
29442
|
+
}
|
|
29443
|
+
/** Reads one complete type from `sig` starting at `i`; returns the value and the index after the type. */
|
|
29444
|
+
read(sig2, i) {
|
|
29445
|
+
const c = sig2[i];
|
|
29446
|
+
const fixed = { y: 1, n: 2, q: 2, b: 4, i: 4, u: 4, h: 4, x: 8, t: 8, d: 8 };
|
|
29447
|
+
if (c in fixed) {
|
|
29448
|
+
const size = fixed[c];
|
|
29449
|
+
this.align(size);
|
|
29450
|
+
const v = size === 1 ? this.data[this.at] : size === 2 ? this.le ? this.data.readUInt16LE(this.at) : this.data.readUInt16BE(this.at) : size === 4 ? this.le ? this.data.readUInt32LE(this.at) : this.data.readUInt32BE(this.at) : null;
|
|
29451
|
+
this.at += size;
|
|
29452
|
+
return [c === "b" ? v === 1 : v, i + 1];
|
|
29453
|
+
}
|
|
29454
|
+
if (c === "s" || c === "o") {
|
|
29455
|
+
const n = this.u32(), v = this.data.toString("utf8", this.at, this.at + n);
|
|
29456
|
+
this.at += n + 1;
|
|
29457
|
+
return [v, i + 1];
|
|
29458
|
+
}
|
|
29459
|
+
if (c === "g") {
|
|
29460
|
+
const n = this.data[this.at], v = this.data.toString("ascii", this.at + 1, this.at + 1 + n);
|
|
29461
|
+
this.at += n + 2;
|
|
29462
|
+
return [v, i + 1];
|
|
29463
|
+
}
|
|
29464
|
+
if (c === "v") {
|
|
29465
|
+
const [inner] = this.read("g", 0);
|
|
29466
|
+
return [this.read(inner, 0)[0], i + 1];
|
|
29467
|
+
}
|
|
29468
|
+
if (c === "(" || c === "{") {
|
|
29469
|
+
this.align(8);
|
|
29470
|
+
const close = c === "(" ? ")" : "}", values = [];
|
|
29471
|
+
let j = i + 1;
|
|
29472
|
+
while (sig2[j] !== close) {
|
|
29473
|
+
const [v, next] = this.read(sig2, j);
|
|
29474
|
+
values.push(v);
|
|
29475
|
+
j = next;
|
|
29476
|
+
}
|
|
29477
|
+
return [values, j + 1];
|
|
29478
|
+
}
|
|
29479
|
+
if (c === "a") {
|
|
29480
|
+
const n = this.u32(), element = sig2[i + 1];
|
|
29481
|
+
this.align("xtd({".includes(element) ? 8 : element === "n" || element === "q" ? 2 : element === "y" || element === "g" || element === "v" ? 1 : 4);
|
|
29482
|
+
const end = this.at + n, values = [];
|
|
29483
|
+
let next = skip(sig2, i + 1);
|
|
29484
|
+
while (this.at < end) {
|
|
29485
|
+
const [v, j] = this.read(sig2, i + 1);
|
|
29486
|
+
values.push(v);
|
|
29487
|
+
next = j;
|
|
29488
|
+
}
|
|
29489
|
+
return [values, next];
|
|
29490
|
+
}
|
|
29491
|
+
throw Error("signature " + sig2);
|
|
29492
|
+
}
|
|
29493
|
+
};
|
|
29494
|
+
function skip(sig2, i) {
|
|
29495
|
+
const c = sig2[i];
|
|
29496
|
+
if (c === "a") return skip(sig2, i + 1);
|
|
29497
|
+
if (c === "(" || c === "{") {
|
|
29498
|
+
let j = i + 1;
|
|
29499
|
+
while (sig2[j] !== (c === "(" ? ")" : "}")) j = skip(sig2, j);
|
|
29500
|
+
return j + 1;
|
|
29501
|
+
}
|
|
29502
|
+
return i + 1;
|
|
29503
|
+
}
|
|
29504
|
+
function parse3(data) {
|
|
29505
|
+
const le = data[0] === 108, r = new Reader(data, 4, le), bodyLength = r.u32(), serial = r.u32();
|
|
29506
|
+
const [fields] = r.read("a(yv)", 0);
|
|
29507
|
+
const message2 = { type: data[1], serial, signature: "", body: [] };
|
|
29508
|
+
for (const [code, value] of fields) {
|
|
29509
|
+
if (code === 1) message2.path = String(value);
|
|
29510
|
+
else if (code === 2) message2.interface = String(value);
|
|
29511
|
+
else if (code === 3) message2.member = String(value);
|
|
29512
|
+
else if (code === 4) message2.errorName = String(value);
|
|
29513
|
+
else if (code === 5) message2.replySerial = Number(value);
|
|
29514
|
+
else if (code === 8) message2.signature = String(value);
|
|
29515
|
+
}
|
|
29516
|
+
r.align(8);
|
|
29517
|
+
const end = r.at + bodyLength;
|
|
29518
|
+
for (let i = 0; i < message2.signature.length && r.at < end; ) {
|
|
29519
|
+
const [v, next] = r.read(message2.signature, i);
|
|
29520
|
+
message2.body.push(v);
|
|
29521
|
+
i = next;
|
|
29522
|
+
}
|
|
29523
|
+
return message2;
|
|
29524
|
+
}
|
|
29525
|
+
function frameLength(data) {
|
|
29526
|
+
if (data.length < 16) return 0;
|
|
29527
|
+
const le = data[0] === 108, u = (at) => le ? data.readUInt32LE(at) : data.readUInt32BE(at);
|
|
29528
|
+
const length = Math.ceil((16 + u(12)) / 8) * 8 + u(4);
|
|
29529
|
+
return data.length >= length ? length : 0;
|
|
29530
|
+
}
|
|
29531
|
+
async function portalScreenshot(socket, uid, token, signal) {
|
|
29532
|
+
const connection = net.createConnection({ path: socket });
|
|
29533
|
+
try {
|
|
29534
|
+
return await new Promise((resolve, reject) => {
|
|
29535
|
+
let serial = 0, buffer = Buffer.alloc(0), authenticated = false, requestPath = "";
|
|
29536
|
+
const pending = /* @__PURE__ */ new Map();
|
|
29537
|
+
const fail7 = (error62) => reject(error62 instanceof Error ? error62 : Error(String(error62)));
|
|
29538
|
+
const abort = () => fail7(Error("ABORTED"));
|
|
29539
|
+
if (signal.aborted) return abort();
|
|
29540
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
29541
|
+
connection.on("error", fail7);
|
|
29542
|
+
connection.on("close", () => fail7(Error("CLOSED")));
|
|
29543
|
+
const call = (destination, path30, iface, member, signature = "", body = () => {
|
|
29544
|
+
}) => new Promise((done, failed) => {
|
|
29545
|
+
const payload2 = new Writer();
|
|
29546
|
+
body(payload2);
|
|
29547
|
+
const header = new Writer(), fields = [[1, "o", path30], [2, "s", iface], [3, "s", member], [6, "s", destination]];
|
|
29548
|
+
if (signature) fields.push([8, "g", signature]);
|
|
29549
|
+
header.byte(108);
|
|
29550
|
+
header.byte(1);
|
|
29551
|
+
header.byte(0);
|
|
29552
|
+
header.byte(1);
|
|
29553
|
+
header.u32(payload2.bytes.length);
|
|
29554
|
+
header.u32(++serial);
|
|
29555
|
+
header.u32(0);
|
|
29556
|
+
const lengthAt = header.bytes.length - 4;
|
|
29557
|
+
header.align(8);
|
|
29558
|
+
const start = header.bytes.length;
|
|
29559
|
+
for (const [code, type, value] of fields) {
|
|
29560
|
+
header.align(8);
|
|
29561
|
+
header.byte(code);
|
|
29562
|
+
header.sig(type);
|
|
29563
|
+
header.put(type, value);
|
|
29564
|
+
}
|
|
29565
|
+
const length = header.bytes.length - start;
|
|
29566
|
+
header.bytes.splice(lengthAt, 4, length & 255, length >>> 8 & 255, length >>> 16 & 255, length >>> 24 & 255);
|
|
29567
|
+
header.align(8);
|
|
29568
|
+
pending.set(serial, (reply) => reply.type === 3 ? failed(Error(reply.errorName ?? "DBUS_ERROR")) : done(reply));
|
|
29569
|
+
connection.write(Buffer.from([...header.bytes, ...payload2.bytes]));
|
|
29570
|
+
});
|
|
29571
|
+
const bus = (member, signature, body) => call("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", member, signature, body);
|
|
29572
|
+
connection.on("data", (chunk) => {
|
|
29573
|
+
try {
|
|
29574
|
+
receive(chunk);
|
|
29575
|
+
} catch (error62) {
|
|
29576
|
+
fail7(error62);
|
|
29577
|
+
}
|
|
29578
|
+
});
|
|
29579
|
+
const receive = (chunk) => {
|
|
29580
|
+
buffer = Buffer.concat([buffer, chunk]);
|
|
29581
|
+
if (buffer.length > 1048576) return fail7(Error("OVERSIZED"));
|
|
29582
|
+
if (!authenticated) {
|
|
29583
|
+
const end = buffer.indexOf("\r\n");
|
|
29584
|
+
if (end < 0) return;
|
|
29585
|
+
const line = buffer.toString("ascii", 0, end);
|
|
29586
|
+
buffer = buffer.subarray(end + 2);
|
|
29587
|
+
if (!line.startsWith("OK ")) return fail7(Error("AUTH"));
|
|
29588
|
+
authenticated = true;
|
|
29589
|
+
connection.write("BEGIN\r\n");
|
|
29590
|
+
void (async () => {
|
|
29591
|
+
const unique = String((await bus("Hello")).body[0]);
|
|
29592
|
+
requestPath = "/org/freedesktop/portal/desktop/request/" + unique.slice(1).replace(/\./g, "_") + "/" + token;
|
|
29593
|
+
await bus("AddMatch", "s", (w) => w.put("s", "type='signal',interface='org.freedesktop.portal.Request',member='Response',path='" + requestPath + "'"));
|
|
29594
|
+
const handle = await call(
|
|
29595
|
+
"org.freedesktop.portal.Desktop",
|
|
29596
|
+
"/org/freedesktop/portal/desktop",
|
|
29597
|
+
"org.freedesktop.portal.Screenshot",
|
|
29598
|
+
"Screenshot",
|
|
29599
|
+
"sa{sv}",
|
|
29600
|
+
(w) => {
|
|
29601
|
+
w.put("s", "");
|
|
29602
|
+
w.dict([["handle_token", ["s", token]], ["interactive", ["b", false]]]);
|
|
29603
|
+
}
|
|
29604
|
+
);
|
|
29605
|
+
if (handle.body[0] !== requestPath) {
|
|
29606
|
+
requestPath = String(handle.body[0]);
|
|
29607
|
+
await bus("AddMatch", "s", (w) => w.put("s", "type='signal',interface='org.freedesktop.portal.Request',member='Response',path='" + requestPath + "'"));
|
|
29608
|
+
}
|
|
29609
|
+
})().catch(fail7);
|
|
29610
|
+
}
|
|
29611
|
+
for (let length = frameLength(buffer); authenticated && length; length = frameLength(buffer)) {
|
|
29612
|
+
const message2 = parse3(buffer.subarray(0, length));
|
|
29613
|
+
buffer = buffer.subarray(length);
|
|
29614
|
+
if ((message2.type === 2 || message2.type === 3) && message2.replySerial !== void 0) {
|
|
29615
|
+
pending.get(message2.replySerial)?.(message2);
|
|
29616
|
+
pending.delete(message2.replySerial);
|
|
29617
|
+
} else if (message2.type === 4 && message2.member === "Response" && message2.path === requestPath && message2.signature === "ua{sv}") {
|
|
29618
|
+
const results2 = message2.body[1], uri = results2.find(([key]) => key === "uri")?.[1];
|
|
29619
|
+
resolve({ code: Number(message2.body[0]), uri: typeof uri === "string" ? uri : void 0 });
|
|
29620
|
+
}
|
|
29621
|
+
}
|
|
29622
|
+
};
|
|
29623
|
+
connection.on("connect", () => connection.write("\0AUTH EXTERNAL " + Buffer.from(String(uid), "ascii").toString("hex") + "\r\n"));
|
|
29624
|
+
});
|
|
29625
|
+
} finally {
|
|
29626
|
+
connection.destroy();
|
|
29627
|
+
}
|
|
29628
|
+
}
|
|
29629
|
+
|
|
29630
|
+
// agent/src/screen-image.ts
|
|
29631
|
+
import { inflateSync } from "node:zlib";
|
|
29632
|
+
var MAX_EDGE = 16384;
|
|
29633
|
+
var MAX_PIXELS = 67108864;
|
|
29634
|
+
function sizeOk(width, height) {
|
|
29635
|
+
return Number.isSafeInteger(width) && Number.isSafeInteger(height) && width > 0 && height > 0 && width <= MAX_EDGE && height <= MAX_EDGE && width * height <= MAX_PIXELS;
|
|
29636
|
+
}
|
|
29637
|
+
function decodePng(data) {
|
|
29638
|
+
if (data.length < 33 || data.readUInt32BE(0) !== 2303741511 || data.readUInt32BE(4) !== 218765834) return null;
|
|
29639
|
+
let width = 0, height = 0, channels = 0;
|
|
29640
|
+
const idat = [];
|
|
29641
|
+
for (let at = 8; at + 12 <= data.length; ) {
|
|
29642
|
+
const length = data.readUInt32BE(at), type = data.toString("latin1", at + 4, at + 8), body = at + 8;
|
|
29643
|
+
if (body + length + 4 > data.length) return null;
|
|
29644
|
+
if (type === "IHDR") {
|
|
29645
|
+
if (length !== 13) return null;
|
|
29646
|
+
width = data.readUInt32BE(body);
|
|
29647
|
+
height = data.readUInt32BE(body + 4);
|
|
29648
|
+
const depth = data[body + 8], color = data[body + 9], interlace = data[body + 12];
|
|
29649
|
+
channels = color === 0 ? 1 : color === 2 ? 3 : color === 4 ? 2 : color === 6 ? 4 : 0;
|
|
29650
|
+
if (depth !== 8 || !channels || interlace !== 0 || data[body + 10] !== 0 || data[body + 11] !== 0 || !sizeOk(width, height)) return null;
|
|
29651
|
+
} else if (type === "IDAT") idat.push(data.subarray(body, body + length));
|
|
29652
|
+
else if (type === "IEND") break;
|
|
29653
|
+
at = body + length + 4;
|
|
29654
|
+
}
|
|
29655
|
+
if (!channels || !idat.length) return null;
|
|
29656
|
+
const stride = width * channels, expected = (stride + 1) * height;
|
|
29657
|
+
let raw;
|
|
29658
|
+
try {
|
|
29659
|
+
raw = inflateSync(Buffer.concat(idat), { maxOutputLength: expected });
|
|
29660
|
+
} catch {
|
|
29661
|
+
return null;
|
|
29662
|
+
}
|
|
29663
|
+
if (raw.length !== expected) return null;
|
|
29664
|
+
const rgb = Buffer.alloc(width * height * 3);
|
|
29665
|
+
let previous = Buffer.alloc(stride), current2 = Buffer.alloc(stride);
|
|
29666
|
+
for (let y = 0; y < height; y++) {
|
|
29667
|
+
const filter = raw[y * (stride + 1)], line = raw.subarray(y * (stride + 1) + 1, (y + 1) * (stride + 1));
|
|
29668
|
+
for (let x = 0; x < stride; x++) {
|
|
29669
|
+
const a = x >= channels ? current2[x - channels] : 0, b = previous[x], c = x >= channels ? previous[x - channels] : 0;
|
|
29670
|
+
let value = line[x];
|
|
29671
|
+
if (filter === 1) value += a;
|
|
29672
|
+
else if (filter === 2) value += b;
|
|
29673
|
+
else if (filter === 3) value += a + b >> 1;
|
|
29674
|
+
else if (filter === 4) {
|
|
29675
|
+
const p = a + b - c, pa = Math.abs(p - a), pb = Math.abs(p - b), pc = Math.abs(p - c);
|
|
29676
|
+
value += pa <= pb && pa <= pc ? a : pb <= pc ? b : c;
|
|
29677
|
+
} else if (filter !== 0) return null;
|
|
29678
|
+
current2[x] = value & 255;
|
|
29679
|
+
}
|
|
29680
|
+
for (let x = 0, o = y * width * 3; x < width; x++, o += 3) {
|
|
29681
|
+
const i = x * channels;
|
|
29682
|
+
if (channels <= 2) rgb[o] = rgb[o + 1] = rgb[o + 2] = current2[i];
|
|
29683
|
+
else {
|
|
29684
|
+
rgb[o] = current2[i];
|
|
29685
|
+
rgb[o + 1] = current2[i + 1];
|
|
29686
|
+
rgb[o + 2] = current2[i + 2];
|
|
29687
|
+
}
|
|
29688
|
+
}
|
|
29689
|
+
[previous, current2] = [current2, previous];
|
|
29690
|
+
}
|
|
29691
|
+
return { width, height, rgb };
|
|
29692
|
+
}
|
|
29693
|
+
function decodeXwd(data) {
|
|
29694
|
+
if (data.length < 100) return null;
|
|
29695
|
+
const field = (index) => data.readUInt32BE(index * 4);
|
|
29696
|
+
const headerSize = field(0), version2 = field(1), format = field(2), width = field(4), height = field(5), byteOrder = field(7);
|
|
29697
|
+
const bitsPerPixel = field(11), bytesPerLine = field(12), visualClass = field(13), masks = [field(14), field(15), field(16)], colors = field(19);
|
|
29698
|
+
if (version2 !== 7 || format !== 2 || headerSize < 100 || ![4, 5].includes(visualClass) || ![24, 32].includes(bitsPerPixel) || !sizeOk(width, height) || colors > 65536) return null;
|
|
29699
|
+
const pixelBytes = bitsPerPixel / 8, start = headerSize + colors * 12;
|
|
29700
|
+
if (bytesPerLine < width * pixelBytes || start + bytesPerLine * height > data.length || masks.some((mask) => !mask)) return null;
|
|
29701
|
+
const shifts = masks.map((mask) => {
|
|
29702
|
+
let shift = 0;
|
|
29703
|
+
while (!(mask >>> shift & 1)) shift++;
|
|
29704
|
+
return shift;
|
|
29705
|
+
});
|
|
29706
|
+
const scales = masks.map((mask, i) => 255 / (mask >>> shifts[i]));
|
|
29707
|
+
const rgb = Buffer.alloc(width * height * 3);
|
|
29708
|
+
for (let y = 0; y < height; y++) for (let x = 0, at = start + y * bytesPerLine, o = y * width * 3; x < width; x++, at += pixelBytes, o += 3) {
|
|
29709
|
+
const pixel = pixelBytes === 4 ? byteOrder === 0 ? data.readUInt32LE(at) : data.readUInt32BE(at) : byteOrder === 0 ? data[at] | data[at + 1] << 8 | data[at + 2] << 16 : data[at] << 16 | data[at + 1] << 8 | data[at + 2];
|
|
29710
|
+
for (let c = 0; c < 3; c++) rgb[o + c] = Math.round(((pixel & masks[c]) >>> 0 >>> shifts[c]) * scales[c]);
|
|
29711
|
+
}
|
|
29712
|
+
return { width, height, rgb };
|
|
29713
|
+
}
|
|
29714
|
+
function downscale(image, edge) {
|
|
29715
|
+
const scale = Math.min(1, edge / Math.max(image.width, image.height));
|
|
29716
|
+
if (scale >= 1) return image;
|
|
29717
|
+
const width = Math.max(1, Math.round(image.width * scale)), height = Math.max(1, Math.round(image.height * scale));
|
|
29718
|
+
const xs = Array.from({ length: width + 1 }, (_, x) => Math.min(image.width, Math.floor(x * image.width / width)));
|
|
29719
|
+
const ys = Array.from({ length: height + 1 }, (_, y) => Math.min(image.height, Math.floor(y * image.height / height)));
|
|
29720
|
+
const rgb = Buffer.alloc(width * height * 3), sums = new Float64Array(width * 3);
|
|
29721
|
+
for (let y = 0; y < height; y++) {
|
|
29722
|
+
sums.fill(0);
|
|
29723
|
+
for (let sy = ys[y]; sy < ys[y + 1]; sy++) for (let x = 0; x < width; x++) for (let sx = xs[x]; sx < xs[x + 1]; sx++) {
|
|
29724
|
+
const i = (sy * image.width + sx) * 3;
|
|
29725
|
+
sums[x * 3] = sums[x * 3] + image.rgb[i];
|
|
29726
|
+
sums[x * 3 + 1] = sums[x * 3 + 1] + image.rgb[i + 1];
|
|
29727
|
+
sums[x * 3 + 2] = sums[x * 3 + 2] + image.rgb[i + 2];
|
|
29728
|
+
}
|
|
29729
|
+
for (let x = 0; x < width; x++) {
|
|
29730
|
+
const count3 = (ys[y + 1] - ys[y]) * (xs[x + 1] - xs[x]);
|
|
29731
|
+
for (let c = 0; c < 3; c++) rgb[(y * width + x) * 3 + c] = Math.round(sums[x * 3 + c] / count3);
|
|
29732
|
+
}
|
|
29733
|
+
}
|
|
29734
|
+
return { width, height, rgb };
|
|
29735
|
+
}
|
|
29736
|
+
var ZIGZAG = [
|
|
29737
|
+
0,
|
|
29738
|
+
1,
|
|
29739
|
+
5,
|
|
29740
|
+
6,
|
|
29741
|
+
14,
|
|
29742
|
+
15,
|
|
29743
|
+
27,
|
|
29744
|
+
28,
|
|
29745
|
+
2,
|
|
29746
|
+
4,
|
|
29747
|
+
7,
|
|
29748
|
+
13,
|
|
29749
|
+
16,
|
|
29750
|
+
26,
|
|
29751
|
+
29,
|
|
29752
|
+
42,
|
|
29753
|
+
3,
|
|
29754
|
+
8,
|
|
29755
|
+
12,
|
|
29756
|
+
17,
|
|
29757
|
+
25,
|
|
29758
|
+
30,
|
|
29759
|
+
41,
|
|
29760
|
+
43,
|
|
29761
|
+
9,
|
|
29762
|
+
11,
|
|
29763
|
+
18,
|
|
29764
|
+
24,
|
|
29765
|
+
31,
|
|
29766
|
+
40,
|
|
29767
|
+
44,
|
|
29768
|
+
53,
|
|
29769
|
+
10,
|
|
29770
|
+
19,
|
|
29771
|
+
23,
|
|
29772
|
+
32,
|
|
29773
|
+
39,
|
|
29774
|
+
45,
|
|
29775
|
+
52,
|
|
29776
|
+
54,
|
|
29777
|
+
20,
|
|
29778
|
+
22,
|
|
29779
|
+
33,
|
|
29780
|
+
38,
|
|
29781
|
+
46,
|
|
29782
|
+
51,
|
|
29783
|
+
55,
|
|
29784
|
+
60,
|
|
29785
|
+
21,
|
|
29786
|
+
34,
|
|
29787
|
+
37,
|
|
29788
|
+
47,
|
|
29789
|
+
50,
|
|
29790
|
+
56,
|
|
29791
|
+
59,
|
|
29792
|
+
61,
|
|
29793
|
+
35,
|
|
29794
|
+
36,
|
|
29795
|
+
48,
|
|
29796
|
+
49,
|
|
29797
|
+
57,
|
|
29798
|
+
58,
|
|
29799
|
+
62,
|
|
29800
|
+
63
|
|
29801
|
+
];
|
|
29802
|
+
var LUMA_QUANT = [
|
|
29803
|
+
16,
|
|
29804
|
+
11,
|
|
29805
|
+
10,
|
|
29806
|
+
16,
|
|
29807
|
+
24,
|
|
29808
|
+
40,
|
|
29809
|
+
51,
|
|
29810
|
+
61,
|
|
29811
|
+
12,
|
|
29812
|
+
12,
|
|
29813
|
+
14,
|
|
29814
|
+
19,
|
|
29815
|
+
26,
|
|
29816
|
+
58,
|
|
29817
|
+
60,
|
|
29818
|
+
55,
|
|
29819
|
+
14,
|
|
29820
|
+
13,
|
|
29821
|
+
16,
|
|
29822
|
+
24,
|
|
29823
|
+
40,
|
|
29824
|
+
57,
|
|
29825
|
+
69,
|
|
29826
|
+
56,
|
|
29827
|
+
14,
|
|
29828
|
+
17,
|
|
29829
|
+
22,
|
|
29830
|
+
29,
|
|
29831
|
+
51,
|
|
29832
|
+
87,
|
|
29833
|
+
80,
|
|
29834
|
+
62,
|
|
29835
|
+
18,
|
|
29836
|
+
22,
|
|
29837
|
+
37,
|
|
29838
|
+
56,
|
|
29839
|
+
68,
|
|
29840
|
+
109,
|
|
29841
|
+
103,
|
|
29842
|
+
77,
|
|
29843
|
+
24,
|
|
29844
|
+
35,
|
|
29845
|
+
55,
|
|
29846
|
+
64,
|
|
29847
|
+
81,
|
|
29848
|
+
104,
|
|
29849
|
+
113,
|
|
29850
|
+
92,
|
|
29851
|
+
49,
|
|
29852
|
+
64,
|
|
29853
|
+
78,
|
|
29854
|
+
87,
|
|
29855
|
+
103,
|
|
29856
|
+
121,
|
|
29857
|
+
120,
|
|
29858
|
+
101,
|
|
29859
|
+
72,
|
|
29860
|
+
92,
|
|
29861
|
+
95,
|
|
29862
|
+
98,
|
|
29863
|
+
112,
|
|
29864
|
+
100,
|
|
29865
|
+
103,
|
|
29866
|
+
99
|
|
29867
|
+
];
|
|
29868
|
+
var CHROMA_QUANT = [17, 18, 24, 47, 99, 99, 99, 99, 18, 21, 26, 66, 99, 99, 99, 99, 24, 26, 56, 99, 99, 99, 99, 99, 47, 66, ...Array(38).fill(99)];
|
|
29869
|
+
var AC_LUMA_VALUES = [
|
|
29870
|
+
1,
|
|
29871
|
+
2,
|
|
29872
|
+
3,
|
|
29873
|
+
0,
|
|
29874
|
+
4,
|
|
29875
|
+
17,
|
|
29876
|
+
5,
|
|
29877
|
+
18,
|
|
29878
|
+
33,
|
|
29879
|
+
49,
|
|
29880
|
+
65,
|
|
29881
|
+
6,
|
|
29882
|
+
19,
|
|
29883
|
+
81,
|
|
29884
|
+
97,
|
|
29885
|
+
7,
|
|
29886
|
+
34,
|
|
29887
|
+
113,
|
|
29888
|
+
20,
|
|
29889
|
+
50,
|
|
29890
|
+
129,
|
|
29891
|
+
145,
|
|
29892
|
+
161,
|
|
29893
|
+
8,
|
|
29894
|
+
35,
|
|
29895
|
+
66,
|
|
29896
|
+
177,
|
|
29897
|
+
193,
|
|
29898
|
+
21,
|
|
29899
|
+
82,
|
|
29900
|
+
209,
|
|
29901
|
+
240,
|
|
29902
|
+
36,
|
|
29903
|
+
51,
|
|
29904
|
+
98,
|
|
29905
|
+
114,
|
|
29906
|
+
130,
|
|
29907
|
+
9,
|
|
29908
|
+
10,
|
|
29909
|
+
22,
|
|
29910
|
+
23,
|
|
29911
|
+
24,
|
|
29912
|
+
25,
|
|
29913
|
+
26,
|
|
29914
|
+
37,
|
|
29915
|
+
38,
|
|
29916
|
+
39,
|
|
29917
|
+
40,
|
|
29918
|
+
41,
|
|
29919
|
+
42,
|
|
29920
|
+
52,
|
|
29921
|
+
53,
|
|
29922
|
+
54,
|
|
29923
|
+
55,
|
|
29924
|
+
56,
|
|
29925
|
+
57,
|
|
29926
|
+
58,
|
|
29927
|
+
67,
|
|
29928
|
+
68,
|
|
29929
|
+
69,
|
|
29930
|
+
70,
|
|
29931
|
+
71,
|
|
29932
|
+
72,
|
|
29933
|
+
73,
|
|
29934
|
+
74,
|
|
29935
|
+
83,
|
|
29936
|
+
84,
|
|
29937
|
+
85,
|
|
29938
|
+
86,
|
|
29939
|
+
87,
|
|
29940
|
+
88,
|
|
29941
|
+
89,
|
|
29942
|
+
90,
|
|
29943
|
+
99,
|
|
29944
|
+
100,
|
|
29945
|
+
101,
|
|
29946
|
+
102,
|
|
29947
|
+
103,
|
|
29948
|
+
104,
|
|
29949
|
+
105,
|
|
29950
|
+
106,
|
|
29951
|
+
115,
|
|
29952
|
+
116,
|
|
29953
|
+
117,
|
|
29954
|
+
118,
|
|
29955
|
+
119,
|
|
29956
|
+
120,
|
|
29957
|
+
121,
|
|
29958
|
+
122,
|
|
29959
|
+
131,
|
|
29960
|
+
132,
|
|
29961
|
+
133,
|
|
29962
|
+
134,
|
|
29963
|
+
135,
|
|
29964
|
+
136,
|
|
29965
|
+
137,
|
|
29966
|
+
138,
|
|
29967
|
+
146,
|
|
29968
|
+
147,
|
|
29969
|
+
148,
|
|
29970
|
+
149,
|
|
29971
|
+
150,
|
|
29972
|
+
151,
|
|
29973
|
+
152,
|
|
29974
|
+
153,
|
|
29975
|
+
154,
|
|
29976
|
+
162,
|
|
29977
|
+
163,
|
|
29978
|
+
164,
|
|
29979
|
+
165,
|
|
29980
|
+
166,
|
|
29981
|
+
167,
|
|
29982
|
+
168,
|
|
29983
|
+
169,
|
|
29984
|
+
170,
|
|
29985
|
+
178,
|
|
29986
|
+
179,
|
|
29987
|
+
180,
|
|
29988
|
+
181,
|
|
29989
|
+
182,
|
|
29990
|
+
183,
|
|
29991
|
+
184,
|
|
29992
|
+
185,
|
|
29993
|
+
186,
|
|
29994
|
+
194,
|
|
29995
|
+
195,
|
|
29996
|
+
196,
|
|
29997
|
+
197,
|
|
29998
|
+
198,
|
|
29999
|
+
199,
|
|
30000
|
+
200,
|
|
30001
|
+
201,
|
|
30002
|
+
202,
|
|
30003
|
+
210,
|
|
30004
|
+
211,
|
|
30005
|
+
212,
|
|
30006
|
+
213,
|
|
30007
|
+
214,
|
|
30008
|
+
215,
|
|
30009
|
+
216,
|
|
30010
|
+
217,
|
|
30011
|
+
218,
|
|
30012
|
+
225,
|
|
30013
|
+
226,
|
|
30014
|
+
227,
|
|
30015
|
+
228,
|
|
30016
|
+
229,
|
|
30017
|
+
230,
|
|
30018
|
+
231,
|
|
30019
|
+
232,
|
|
30020
|
+
233,
|
|
30021
|
+
234,
|
|
30022
|
+
241,
|
|
30023
|
+
242,
|
|
30024
|
+
243,
|
|
30025
|
+
244,
|
|
30026
|
+
245,
|
|
30027
|
+
246,
|
|
30028
|
+
247,
|
|
30029
|
+
248,
|
|
30030
|
+
249,
|
|
30031
|
+
250
|
|
30032
|
+
];
|
|
30033
|
+
var AC_CHROMA_VALUES = [
|
|
30034
|
+
0,
|
|
30035
|
+
1,
|
|
30036
|
+
2,
|
|
30037
|
+
3,
|
|
30038
|
+
17,
|
|
30039
|
+
4,
|
|
30040
|
+
5,
|
|
30041
|
+
33,
|
|
30042
|
+
49,
|
|
30043
|
+
6,
|
|
30044
|
+
18,
|
|
30045
|
+
65,
|
|
30046
|
+
81,
|
|
30047
|
+
7,
|
|
30048
|
+
97,
|
|
30049
|
+
113,
|
|
30050
|
+
19,
|
|
30051
|
+
34,
|
|
30052
|
+
50,
|
|
30053
|
+
129,
|
|
30054
|
+
8,
|
|
30055
|
+
20,
|
|
30056
|
+
66,
|
|
30057
|
+
145,
|
|
30058
|
+
161,
|
|
30059
|
+
177,
|
|
30060
|
+
193,
|
|
30061
|
+
9,
|
|
30062
|
+
35,
|
|
30063
|
+
51,
|
|
30064
|
+
82,
|
|
30065
|
+
240,
|
|
30066
|
+
21,
|
|
30067
|
+
98,
|
|
30068
|
+
114,
|
|
30069
|
+
209,
|
|
30070
|
+
10,
|
|
30071
|
+
22,
|
|
30072
|
+
36,
|
|
30073
|
+
52,
|
|
30074
|
+
225,
|
|
30075
|
+
37,
|
|
30076
|
+
241,
|
|
30077
|
+
23,
|
|
30078
|
+
24,
|
|
30079
|
+
25,
|
|
30080
|
+
26,
|
|
30081
|
+
38,
|
|
30082
|
+
39,
|
|
30083
|
+
40,
|
|
30084
|
+
41,
|
|
30085
|
+
42,
|
|
30086
|
+
53,
|
|
30087
|
+
54,
|
|
30088
|
+
55,
|
|
30089
|
+
56,
|
|
30090
|
+
57,
|
|
30091
|
+
58,
|
|
30092
|
+
67,
|
|
30093
|
+
68,
|
|
30094
|
+
69,
|
|
30095
|
+
70,
|
|
30096
|
+
71,
|
|
30097
|
+
72,
|
|
30098
|
+
73,
|
|
30099
|
+
74,
|
|
30100
|
+
83,
|
|
30101
|
+
84,
|
|
30102
|
+
85,
|
|
30103
|
+
86,
|
|
30104
|
+
87,
|
|
30105
|
+
88,
|
|
30106
|
+
89,
|
|
30107
|
+
90,
|
|
30108
|
+
99,
|
|
30109
|
+
100,
|
|
30110
|
+
101,
|
|
30111
|
+
102,
|
|
30112
|
+
103,
|
|
30113
|
+
104,
|
|
30114
|
+
105,
|
|
30115
|
+
106,
|
|
30116
|
+
115,
|
|
30117
|
+
116,
|
|
30118
|
+
117,
|
|
30119
|
+
118,
|
|
30120
|
+
119,
|
|
30121
|
+
120,
|
|
30122
|
+
121,
|
|
30123
|
+
122,
|
|
30124
|
+
130,
|
|
30125
|
+
131,
|
|
30126
|
+
132,
|
|
30127
|
+
133,
|
|
30128
|
+
134,
|
|
30129
|
+
135,
|
|
30130
|
+
136,
|
|
30131
|
+
137,
|
|
30132
|
+
138,
|
|
30133
|
+
146,
|
|
30134
|
+
147,
|
|
30135
|
+
148,
|
|
30136
|
+
149,
|
|
30137
|
+
150,
|
|
30138
|
+
151,
|
|
30139
|
+
152,
|
|
30140
|
+
153,
|
|
30141
|
+
154,
|
|
30142
|
+
162,
|
|
30143
|
+
163,
|
|
30144
|
+
164,
|
|
30145
|
+
165,
|
|
30146
|
+
166,
|
|
30147
|
+
167,
|
|
30148
|
+
168,
|
|
30149
|
+
169,
|
|
30150
|
+
170,
|
|
30151
|
+
178,
|
|
30152
|
+
179,
|
|
30153
|
+
180,
|
|
30154
|
+
181,
|
|
30155
|
+
182,
|
|
30156
|
+
183,
|
|
30157
|
+
184,
|
|
30158
|
+
185,
|
|
30159
|
+
186,
|
|
30160
|
+
194,
|
|
30161
|
+
195,
|
|
30162
|
+
196,
|
|
30163
|
+
197,
|
|
30164
|
+
198,
|
|
30165
|
+
199,
|
|
30166
|
+
200,
|
|
30167
|
+
201,
|
|
30168
|
+
202,
|
|
30169
|
+
210,
|
|
30170
|
+
211,
|
|
30171
|
+
212,
|
|
30172
|
+
213,
|
|
30173
|
+
214,
|
|
30174
|
+
215,
|
|
30175
|
+
216,
|
|
30176
|
+
217,
|
|
30177
|
+
218,
|
|
30178
|
+
226,
|
|
30179
|
+
227,
|
|
30180
|
+
228,
|
|
30181
|
+
229,
|
|
30182
|
+
230,
|
|
30183
|
+
231,
|
|
30184
|
+
232,
|
|
30185
|
+
233,
|
|
30186
|
+
234,
|
|
30187
|
+
242,
|
|
30188
|
+
243,
|
|
30189
|
+
244,
|
|
30190
|
+
245,
|
|
30191
|
+
246,
|
|
30192
|
+
247,
|
|
30193
|
+
248,
|
|
30194
|
+
249,
|
|
30195
|
+
250
|
|
30196
|
+
];
|
|
30197
|
+
var DC_VALUES = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
|
|
30198
|
+
var HUFFMAN = [
|
|
30199
|
+
[0, [0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0], DC_VALUES],
|
|
30200
|
+
[16, [0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 125], AC_LUMA_VALUES],
|
|
30201
|
+
[1, [0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0], DC_VALUES],
|
|
30202
|
+
[17, [0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 119], AC_CHROMA_VALUES]
|
|
30203
|
+
];
|
|
30204
|
+
var CODES = HUFFMAN.map(([, counts, values]) => {
|
|
30205
|
+
const table2 = [];
|
|
30206
|
+
let code = 0, at = 0;
|
|
30207
|
+
counts.forEach((count3, index) => {
|
|
30208
|
+
for (let i = 0; i < count3; i++) table2[values[at++]] = [code++, index + 1];
|
|
30209
|
+
code <<= 1;
|
|
30210
|
+
});
|
|
30211
|
+
return table2;
|
|
30212
|
+
});
|
|
30213
|
+
var AAN = [1, 1.387039845, 1.306562965, 1.175875602, 1, 0.785694958, 0.5411961, 0.275899379];
|
|
30214
|
+
function quantTables(quality) {
|
|
30215
|
+
const factor = quality < 50 ? 5e3 / quality : 200 - quality * 2;
|
|
30216
|
+
const scaled = (base) => base.map((value) => Math.min(255, Math.max(1, Math.floor((value * factor + 50) / 100))));
|
|
30217
|
+
const divisors = (table2) => Float64Array.from(table2, (value, k) => 1 / (value * AAN[k >> 3] * AAN[k & 7] * 8));
|
|
30218
|
+
const luma = scaled(LUMA_QUANT), chroma = scaled(CHROMA_QUANT);
|
|
30219
|
+
return { luma, chroma, lumaDivisors: divisors(luma), chromaDivisors: divisors(chroma) };
|
|
30220
|
+
}
|
|
30221
|
+
var BitWriter = class {
|
|
30222
|
+
buffer = Buffer.alloc(65536);
|
|
30223
|
+
length = 0;
|
|
30224
|
+
bits = 0;
|
|
30225
|
+
count = 0;
|
|
30226
|
+
byte(value) {
|
|
30227
|
+
if (this.length === this.buffer.length) {
|
|
30228
|
+
const next = Buffer.alloc(this.buffer.length * 2);
|
|
30229
|
+
this.buffer.copy(next);
|
|
30230
|
+
this.buffer = next;
|
|
30231
|
+
}
|
|
30232
|
+
this.buffer[this.length++] = value;
|
|
30233
|
+
}
|
|
30234
|
+
bytes(values) {
|
|
30235
|
+
for (const value of values) this.byte(value);
|
|
30236
|
+
}
|
|
30237
|
+
write(code, length) {
|
|
30238
|
+
this.bits = (this.bits << length | code) >>> 0;
|
|
30239
|
+
this.count += length;
|
|
30240
|
+
while (this.count >= 8) {
|
|
30241
|
+
const value = this.bits >>> this.count - 8 & 255;
|
|
30242
|
+
this.byte(value);
|
|
30243
|
+
if (value === 255) this.byte(0);
|
|
30244
|
+
this.count -= 8;
|
|
30245
|
+
this.bits &= (1 << this.count) - 1;
|
|
30246
|
+
}
|
|
30247
|
+
}
|
|
30248
|
+
flush() {
|
|
30249
|
+
if (this.count > 0) this.write((1 << 8 - this.count) - 1, 8 - this.count);
|
|
30250
|
+
}
|
|
30251
|
+
result() {
|
|
30252
|
+
return Buffer.from(this.buffer.subarray(0, this.length));
|
|
30253
|
+
}
|
|
30254
|
+
};
|
|
30255
|
+
function transform2(block, divisors, out) {
|
|
30256
|
+
for (let pass = 0; pass < 2; pass++) for (let i = 0; i < 8; i++) {
|
|
30257
|
+
const step = pass ? 8 : 1, base = pass ? i : i * 8, at = (k) => base + k * step;
|
|
30258
|
+
const d0 = block[at(0)], d1 = block[at(1)], d2 = block[at(2)], d3 = block[at(3)], d4 = block[at(4)], d5 = block[at(5)], d6 = block[at(6)], d7 = block[at(7)];
|
|
30259
|
+
const t0 = d0 + d7, t7 = d0 - d7, t1 = d1 + d6, t6 = d1 - d6, t2 = d2 + d5, t5 = d2 - d5, t3 = d3 + d4, t4 = d3 - d4;
|
|
30260
|
+
const t10 = t0 + t3, t13 = t0 - t3, t11 = t1 + t2, t12 = t1 - t2;
|
|
30261
|
+
block[at(0)] = t10 + t11;
|
|
30262
|
+
block[at(4)] = t10 - t11;
|
|
30263
|
+
const z1 = (t12 + t13) * 0.707106781;
|
|
30264
|
+
block[at(2)] = t13 + z1;
|
|
30265
|
+
block[at(6)] = t13 - z1;
|
|
30266
|
+
const o10 = t4 + t5, o11 = t5 + t6, o12 = t6 + t7;
|
|
30267
|
+
const z5 = (o10 - o12) * 0.382683433, z2 = 0.5411961 * o10 + z5, z4 = 1.306562965 * o12 + z5, z3 = o11 * 0.707106781;
|
|
30268
|
+
const z11 = t7 + z3, z13 = t7 - z3;
|
|
30269
|
+
block[at(5)] = z13 + z2;
|
|
30270
|
+
block[at(3)] = z13 - z2;
|
|
30271
|
+
block[at(1)] = z11 + z4;
|
|
30272
|
+
block[at(7)] = z11 - z4;
|
|
30273
|
+
}
|
|
30274
|
+
for (let k = 0; k < 64; k++) out[ZIGZAG[k]] = Math.round(block[k] * divisors[k]);
|
|
30275
|
+
}
|
|
30276
|
+
function magnitude(value) {
|
|
30277
|
+
const absolute2 = Math.abs(value);
|
|
30278
|
+
let length = 0;
|
|
30279
|
+
while (absolute2 >> length) length++;
|
|
30280
|
+
return [value < 0 ? value + (1 << length) - 1 : value, length];
|
|
30281
|
+
}
|
|
30282
|
+
function encodeJpeg(image, quality) {
|
|
30283
|
+
const { width, height, rgb } = image, tables = quantTables(Math.min(100, Math.max(1, Math.round(quality))));
|
|
30284
|
+
const out = new BitWriter(), word = (value) => [value >> 8, value & 255];
|
|
30285
|
+
out.bytes([255, 216, 255, 224, 0, 16, 74, 70, 73, 70, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0]);
|
|
30286
|
+
out.bytes([255, 219, 0, 132]);
|
|
30287
|
+
for (const [id2, table2] of [[0, tables.luma], [1, tables.chroma]]) {
|
|
30288
|
+
const zig = new Array(64);
|
|
30289
|
+
table2.forEach((value, k) => {
|
|
30290
|
+
zig[ZIGZAG[k]] = value;
|
|
30291
|
+
});
|
|
30292
|
+
out.bytes([id2, ...zig]);
|
|
30293
|
+
}
|
|
30294
|
+
out.bytes([255, 192, 0, 17, 8, ...word(height), ...word(width), 3, 1, 34, 0, 2, 17, 1, 3, 17, 1]);
|
|
30295
|
+
out.bytes([255, 196, ...word(2 + HUFFMAN.reduce((sum, [, , values]) => sum + 17 + values.length, 0))]);
|
|
30296
|
+
for (const [id2, counts, values] of HUFFMAN) out.bytes([id2, ...counts, ...values]);
|
|
30297
|
+
out.bytes([255, 218, 0, 12, 3, 1, 0, 2, 17, 3, 17, 0, 63, 0]);
|
|
30298
|
+
const block = new Float64Array(64), coefficients = new Int32Array(64), dc = [0, 0, 0];
|
|
30299
|
+
const Y = new Float64Array(256), Cb = new Float64Array(256), Cr = new Float64Array(256);
|
|
30300
|
+
const encode5 = (component, divisors) => {
|
|
30301
|
+
transform2(block, divisors, coefficients);
|
|
30302
|
+
const dcCodes = CODES[component ? 2 : 0], acCodes = CODES[component ? 3 : 1];
|
|
30303
|
+
const diff = coefficients[0] - dc[component];
|
|
30304
|
+
dc[component] = coefficients[0];
|
|
30305
|
+
const [bits, size] = magnitude(diff);
|
|
30306
|
+
out.write(...dcCodes[size]);
|
|
30307
|
+
if (size) out.write(bits, size);
|
|
30308
|
+
let last = 63;
|
|
30309
|
+
while (last > 0 && coefficients[last] === 0) last--;
|
|
30310
|
+
for (let k = 1, zeros = 0; k <= last; k++) {
|
|
30311
|
+
if (coefficients[k] === 0) {
|
|
30312
|
+
zeros++;
|
|
30313
|
+
continue;
|
|
30314
|
+
}
|
|
30315
|
+
while (zeros >= 16) {
|
|
30316
|
+
out.write(...acCodes[240]);
|
|
30317
|
+
zeros -= 16;
|
|
30318
|
+
}
|
|
30319
|
+
const [value, length] = magnitude(coefficients[k]);
|
|
30320
|
+
out.write(...acCodes[(zeros << 4) + length]);
|
|
30321
|
+
out.write(value, length);
|
|
30322
|
+
zeros = 0;
|
|
30323
|
+
}
|
|
30324
|
+
if (last < 63) out.write(...acCodes[0]);
|
|
30325
|
+
};
|
|
30326
|
+
for (let my = 0; my < height; my += 16) for (let mx = 0; mx < width; mx += 16) {
|
|
30327
|
+
for (let y = 0; y < 16; y++) for (let x = 0; x < 16; x++) {
|
|
30328
|
+
const i = (Math.min(height - 1, my + y) * width + Math.min(width - 1, mx + x)) * 3, r = rgb[i], g = rgb[i + 1], b = rgb[i + 2];
|
|
30329
|
+
Y[y * 16 + x] = 0.299 * r + 0.587 * g + 0.114 * b - 128;
|
|
30330
|
+
Cb[y * 16 + x] = -0.168736 * r - 0.331264 * g + 0.5 * b;
|
|
30331
|
+
Cr[y * 16 + x] = 0.5 * r - 0.418688 * g - 0.081312 * b;
|
|
30332
|
+
}
|
|
30333
|
+
for (const [ox, oy] of [[0, 0], [8, 0], [0, 8], [8, 8]]) {
|
|
30334
|
+
for (let y = 0; y < 8; y++) for (let x = 0; x < 8; x++) block[y * 8 + x] = Y[(oy + y) * 16 + ox + x];
|
|
30335
|
+
encode5(0, tables.lumaDivisors);
|
|
30336
|
+
}
|
|
30337
|
+
for (const [component, plane] of [[1, Cb], [2, Cr]]) {
|
|
30338
|
+
for (let y = 0; y < 8; y++) for (let x = 0; x < 8; x++) {
|
|
30339
|
+
const at = y * 32 + x * 2;
|
|
30340
|
+
block[y * 8 + x] = (plane[at] + plane[at + 1] + plane[at + 16] + plane[at + 17]) / 4;
|
|
30341
|
+
}
|
|
30342
|
+
encode5(component, tables.chromaDivisors);
|
|
30343
|
+
}
|
|
30344
|
+
}
|
|
30345
|
+
out.flush();
|
|
30346
|
+
out.bytes([255, 217]);
|
|
30347
|
+
return out.result();
|
|
30348
|
+
}
|
|
30349
|
+
function fitJpeg(image, maxEdge, maxBytes) {
|
|
30350
|
+
for (const edge of [maxEdge, 1280, 1024, 800, 640]) {
|
|
30351
|
+
const scaled = downscale(image, edge);
|
|
30352
|
+
for (const quality of [75, 60, 45, 35]) {
|
|
30353
|
+
const data = encodeJpeg(scaled, quality);
|
|
30354
|
+
if (data.length <= maxBytes) return { data, width: scaled.width, height: scaled.height };
|
|
30355
|
+
}
|
|
30356
|
+
}
|
|
30357
|
+
return null;
|
|
30358
|
+
}
|
|
30359
|
+
|
|
30360
|
+
// agent/src/screen-capture.ts
|
|
30361
|
+
var SCREENSHOT_MAX_JPEG_BYTES = 131072;
|
|
30362
|
+
var SCREENSHOT_MAX_EDGE = 1568;
|
|
30363
|
+
function screenshotEnabled(env = process.env) {
|
|
30364
|
+
return env.LC_SCREENSHOT_ENABLED === "true";
|
|
30365
|
+
}
|
|
30366
|
+
var SCREENSHOT_ACCEPTANCE_FILE = "screenshot-acceptance-enabled";
|
|
30367
|
+
var SCREENSHOT_OWNER_OFF_FILE = "screenshot-disabled-by-owner";
|
|
30368
|
+
var ScreenCaptureError = class extends Error {
|
|
30369
|
+
constructor(code, detail) {
|
|
30370
|
+
super(code);
|
|
30371
|
+
this.code = code;
|
|
30372
|
+
this.detail = detail;
|
|
30373
|
+
this.name = "ScreenCaptureError";
|
|
30374
|
+
}
|
|
30375
|
+
code;
|
|
30376
|
+
detail;
|
|
30377
|
+
};
|
|
30378
|
+
var KNOWN = /^(SCREEN_UNAVAILABLE|SCREEN_LOCKED|SCREEN_ENCODER_UNAVAILABLE|SCREENSHOT_TOO_LARGE|ARGUMENT_INVALID)$/;
|
|
30379
|
+
function jpegSize(data) {
|
|
30380
|
+
if (data.length < 4 || data[0] !== 255 || data[1] !== 216 || data[data.length - 2] !== 255 || data[data.length - 1] !== 217) return null;
|
|
30381
|
+
for (let at = 2; at + 9 < data.length; ) {
|
|
30382
|
+
if (data[at] !== 255) return null;
|
|
30383
|
+
const marker = data[at + 1], length = data.readUInt16BE(at + 2);
|
|
30384
|
+
if (marker >= 192 && marker <= 207 && ![196, 200, 204].includes(marker)) {
|
|
30385
|
+
const height = data.readUInt16BE(at + 5), width = data.readUInt16BE(at + 7);
|
|
30386
|
+
return width > 0 && height > 0 ? { width, height } : null;
|
|
30387
|
+
}
|
|
30388
|
+
at += 2 + length;
|
|
30389
|
+
}
|
|
30390
|
+
return null;
|
|
30391
|
+
}
|
|
30392
|
+
function run(file2, args, signal, maxBuffer = 65536, env = buildChildEnvironment(process.env, process.platform)) {
|
|
30393
|
+
return new Promise((resolve, reject) => {
|
|
30394
|
+
execFile4(
|
|
30395
|
+
file2,
|
|
30396
|
+
args,
|
|
30397
|
+
{ encoding: "buffer", timeout: 15e3, maxBuffer, windowsHide: true, shell: false, env, signal },
|
|
30398
|
+
(error62, stdout, stderr) => error62 ? reject(Object.assign(error62, { stdout, stderr })) : resolve({ stdout, stderr })
|
|
30399
|
+
);
|
|
30400
|
+
});
|
|
30401
|
+
}
|
|
30402
|
+
async function windows(bridge, signal) {
|
|
30403
|
+
if (!path17.isAbsolute(bridge)) throw new ScreenCaptureError("SCREEN_UNAVAILABLE");
|
|
30404
|
+
let stdout;
|
|
30405
|
+
try {
|
|
30406
|
+
({ stdout } = await run(bridge, ["screenshot", String(SCREENSHOT_MAX_EDGE), String(SCREENSHOT_MAX_JPEG_BYTES)], signal, 262144));
|
|
30407
|
+
} catch (error62) {
|
|
30408
|
+
if (signal.aborted) throw new ScreenCaptureError("CANCELLED");
|
|
30409
|
+
const code = /^\{"error":"([A-Z_]+)"\}$/.exec(String(error62.stderr ?? ""))?.[1];
|
|
30410
|
+
throw new ScreenCaptureError(code && KNOWN.test(code) ? code : "SCREEN_UNAVAILABLE");
|
|
30411
|
+
}
|
|
30412
|
+
try {
|
|
30413
|
+
const value = JSON.parse(stdout.toString("utf8"));
|
|
30414
|
+
const data = Buffer.from(value.data, "base64"), size = jpegSize(data);
|
|
30415
|
+
if (!size || size.width !== value.width || size.height !== value.height || !Number.isSafeInteger(value.sourceWidth) || !Number.isSafeInteger(value.sourceHeight)) throw Error();
|
|
30416
|
+
return { data, width: size.width, height: size.height, sourceWidth: value.sourceWidth, sourceHeight: value.sourceHeight };
|
|
30417
|
+
} catch {
|
|
30418
|
+
throw new ScreenCaptureError("SCREEN_UNAVAILABLE");
|
|
30419
|
+
}
|
|
30420
|
+
}
|
|
30421
|
+
async function mac3(signal) {
|
|
30422
|
+
try {
|
|
30423
|
+
const preflight = await run("/usr/bin/osascript", ["-l", "JavaScript", "-e", "ObjC.import('CoreGraphics'); $.CGPreflightScreenCaptureAccess()"], signal);
|
|
30424
|
+
if (preflight.stdout.toString("utf8").trim() !== "true") {
|
|
30425
|
+
await run("/usr/bin/osascript", ["-l", "JavaScript", "-e", "ObjC.import('CoreGraphics'); $.CGRequestScreenCaptureAccess()"], signal).catch(() => {
|
|
30426
|
+
});
|
|
30427
|
+
throw new ScreenCaptureError("SCREEN_RECORDING_PERMISSION_REQUIRED");
|
|
30428
|
+
}
|
|
30429
|
+
} catch (error62) {
|
|
30430
|
+
if (error62 instanceof ScreenCaptureError) throw error62;
|
|
30431
|
+
throw new ScreenCaptureError(signal.aborted ? "CANCELLED" : "SCREEN_UNAVAILABLE");
|
|
30432
|
+
}
|
|
30433
|
+
const folder = await mkdtemp(path17.join(os4.tmpdir(), "lc-screen-"));
|
|
30434
|
+
try {
|
|
30435
|
+
const full = path17.join(folder, "full.png"), small = path17.join(folder, "small.jpg");
|
|
30436
|
+
try {
|
|
30437
|
+
await run("/usr/sbin/screencapture", ["-x", "-m", "-t", "png", full], signal);
|
|
30438
|
+
} catch {
|
|
30439
|
+
throw new ScreenCaptureError(signal.aborted ? "CANCELLED" : "SCREEN_UNAVAILABLE");
|
|
30440
|
+
}
|
|
30441
|
+
const source = (await run("/usr/bin/sips", ["-g", "pixelWidth", "-g", "pixelHeight", full], signal)).stdout.toString("utf8");
|
|
30442
|
+
const sourceWidth = Number(/pixelWidth: (\d+)/.exec(source)?.[1]), sourceHeight = Number(/pixelHeight: (\d+)/.exec(source)?.[1]);
|
|
30443
|
+
if (!sourceWidth || !sourceHeight) throw new ScreenCaptureError("SCREEN_UNAVAILABLE");
|
|
30444
|
+
for (const edge of [SCREENSHOT_MAX_EDGE, 1280, 1024, 800, 640]) {
|
|
30445
|
+
const target = Math.min(edge, Math.max(sourceWidth, sourceHeight));
|
|
30446
|
+
for (const quality of [75, 60, 45, 35]) {
|
|
30447
|
+
await run("/usr/bin/sips", ["-Z", String(target), "-s", "format", "jpeg", "-s", "formatOptions", String(quality), full, "--out", small], signal);
|
|
30448
|
+
const data = await readFile6(small), size = jpegSize(data);
|
|
30449
|
+
if (!size) throw new ScreenCaptureError("SCREEN_UNAVAILABLE");
|
|
30450
|
+
if (data.length <= SCREENSHOT_MAX_JPEG_BYTES) return { data, ...size, sourceWidth, sourceHeight };
|
|
30451
|
+
}
|
|
30452
|
+
}
|
|
30453
|
+
throw new ScreenCaptureError("SCREENSHOT_TOO_LARGE");
|
|
30454
|
+
} catch (error62) {
|
|
30455
|
+
if (error62 instanceof ScreenCaptureError) throw error62;
|
|
30456
|
+
throw new ScreenCaptureError(signal.aborted ? "CANCELLED" : "SCREEN_UNAVAILABLE");
|
|
30457
|
+
} finally {
|
|
30458
|
+
await rm5(folder, { recursive: true, force: true }).catch(() => {
|
|
30459
|
+
});
|
|
30460
|
+
}
|
|
30461
|
+
}
|
|
30462
|
+
var SESSION_KEYS = ["DISPLAY", "WAYLAND_DISPLAY", "XAUTHORITY", "XDG_RUNTIME_DIR", "DBUS_SESSION_BUS_ADDRESS", "XDG_SESSION_TYPE", "XDG_CURRENT_DESKTOP"];
|
|
30463
|
+
var SESSION_VALUE = /^[A-Za-z0-9_.:,;=@+/-]{1,256}$/;
|
|
30464
|
+
var LINUX_SOURCE_BYTES = 150994944;
|
|
30465
|
+
async function linuxTool(name2) {
|
|
30466
|
+
for (const directory of ["/usr/bin", "/bin", "/usr/local/bin"]) {
|
|
30467
|
+
const file2 = path17.posix.join(directory, name2);
|
|
30468
|
+
try {
|
|
30469
|
+
await access3(file2, constants7.X_OK);
|
|
30470
|
+
return file2;
|
|
30471
|
+
} catch {
|
|
30472
|
+
}
|
|
30473
|
+
}
|
|
30474
|
+
return null;
|
|
30475
|
+
}
|
|
30476
|
+
async function linuxSession(signal) {
|
|
30477
|
+
const session = {}, uid = process.getuid?.();
|
|
30478
|
+
const take = (key, value) => {
|
|
30479
|
+
if (value && !session[key] && SESSION_VALUE.test(value)) session[key] = value;
|
|
30480
|
+
};
|
|
30481
|
+
const base = buildChildEnvironment(process.env, "linux");
|
|
30482
|
+
for (const key of SESSION_KEYS) take(key, process.env[key]);
|
|
30483
|
+
if (!session.DISPLAY && !session.WAYLAND_DISPLAY) {
|
|
30484
|
+
const systemctl = await linuxTool("systemctl");
|
|
30485
|
+
if (systemctl) try {
|
|
30486
|
+
const { stdout } = await run(systemctl, ["--user", "show-environment"], signal, 262144, base);
|
|
30487
|
+
for (const line of stdout.toString("utf8").split("\n")) {
|
|
30488
|
+
const at = line.indexOf("=");
|
|
30489
|
+
if (at > 0 && SESSION_KEYS.includes(line.slice(0, at))) take(line.slice(0, at), line.slice(at + 1));
|
|
30490
|
+
}
|
|
30491
|
+
} catch {
|
|
30492
|
+
if (signal.aborted) throw new ScreenCaptureError("CANCELLED");
|
|
30493
|
+
}
|
|
30494
|
+
}
|
|
30495
|
+
if (uid !== void 0) take("XDG_RUNTIME_DIR", "/run/user/" + uid);
|
|
30496
|
+
if (!session.DISPLAY && !session.WAYLAND_DISPLAY) {
|
|
30497
|
+
if (session.XDG_RUNTIME_DIR) for (const name2 of ["wayland-0", "wayland-1"]) {
|
|
30498
|
+
const socket = await lstat7(path17.posix.join(session.XDG_RUNTIME_DIR, name2)).catch(() => null);
|
|
30499
|
+
if (socket?.isSocket() && socket.uid === uid) {
|
|
30500
|
+
session.WAYLAND_DISPLAY = name2;
|
|
30501
|
+
break;
|
|
30502
|
+
}
|
|
30503
|
+
}
|
|
30504
|
+
if (!session.WAYLAND_DISPLAY) {
|
|
30505
|
+
const servers = [];
|
|
30506
|
+
for (const name2 of await readdir4("/tmp/.X11-unix").catch(() => [])) {
|
|
30507
|
+
const n = /^X(\d{1,4})$/.exec(name2)?.[1], socket = n ? await lstat7("/tmp/.X11-unix/" + name2).catch(() => null) : null;
|
|
30508
|
+
if (n && socket?.isSocket()) servers.push({ n: Number(n), own: socket.uid === uid });
|
|
30509
|
+
}
|
|
30510
|
+
const server = servers.sort((a, b) => Number(b.own) - Number(a.own) || a.n - b.n)[0];
|
|
30511
|
+
if (server) session.DISPLAY = ":" + server.n;
|
|
30512
|
+
}
|
|
30513
|
+
}
|
|
30514
|
+
if (session.DISPLAY && !session.XAUTHORITY) {
|
|
30515
|
+
const file2 = path17.posix.join(os4.homedir(), ".Xauthority");
|
|
30516
|
+
if ((await lstat7(file2).catch(() => null))?.isFile()) take("XAUTHORITY", file2);
|
|
30517
|
+
}
|
|
30518
|
+
if (session.XDG_RUNTIME_DIR) take("DBUS_SESSION_BUS_ADDRESS", "unix:path=" + session.XDG_RUNTIME_DIR + "/bus");
|
|
30519
|
+
const wayland = !!session.WAYLAND_DISPLAY || session.XDG_SESSION_TYPE === "wayland";
|
|
30520
|
+
return { env: { ...base, ...session }, wayland, x11: !wayland && !!session.DISPLAY };
|
|
30521
|
+
}
|
|
30522
|
+
async function busSocket(env) {
|
|
30523
|
+
const socket = sessionBusSocket(env.DBUS_SESSION_BUS_ADDRESS);
|
|
30524
|
+
if (!socket || socket.startsWith("\0")) return socket;
|
|
30525
|
+
return (await lstat7(socket).catch(() => null))?.isSocket() ? socket : null;
|
|
30526
|
+
}
|
|
30527
|
+
async function portalCapture(socket, signal) {
|
|
30528
|
+
const token = "lc" + randomBytes6(8).toString("hex"), started = Date.now(), uid = process.getuid?.();
|
|
30529
|
+
if (uid === void 0) throw new ScreenCaptureError("SCREEN_UNAVAILABLE");
|
|
30530
|
+
let answer;
|
|
30531
|
+
try {
|
|
30532
|
+
answer = await portalScreenshot(socket, uid, token, AbortSignal.any([signal, AbortSignal.timeout(3e4)]));
|
|
30533
|
+
} catch {
|
|
30534
|
+
throw new ScreenCaptureError(signal.aborted ? "CANCELLED" : "SCREEN_UNAVAILABLE");
|
|
30535
|
+
}
|
|
30536
|
+
const { code, uri } = answer;
|
|
30537
|
+
if (code === 1) throw new ScreenCaptureError("SCREEN_RECORDING_PERMISSION_REQUIRED");
|
|
30538
|
+
if (code !== 0 || !uri?.startsWith("file://")) throw new ScreenCaptureError("SCREEN_UNAVAILABLE");
|
|
30539
|
+
const file2 = decodeURIComponent(new URL(uri).pathname), info = await lstat7(file2);
|
|
30540
|
+
const fresh = info.isFile() && info.uid === uid && info.mtimeMs >= started - 5e3;
|
|
30541
|
+
try {
|
|
30542
|
+
if (!fresh || info.size > LINUX_SOURCE_BYTES) throw new ScreenCaptureError("SCREEN_UNAVAILABLE");
|
|
30543
|
+
return await readFile6(file2);
|
|
30544
|
+
} finally {
|
|
30545
|
+
if (fresh) await unlink2(file2).catch(() => {
|
|
30546
|
+
});
|
|
30547
|
+
}
|
|
30548
|
+
}
|
|
30549
|
+
async function linux(signal) {
|
|
30550
|
+
const session = await linuxSession(signal);
|
|
30551
|
+
if (!session.wayland && !session.x11) throw new ScreenCaptureError("SCREENSHOT_UNSUPPORTED", { reason: "NO_DISPLAY" });
|
|
30552
|
+
const output2 = (args) => async (tool) => (await run(tool, args, signal, LINUX_SOURCE_BYTES, session.env)).stdout;
|
|
30553
|
+
const portal = (socket) => portalCapture(socket, signal);
|
|
30554
|
+
const methods = session.wayland ? [["grim", "grim", output2(["-t", "png", "-"])], ["portal", "", portal]] : [
|
|
30555
|
+
["xwd", "xwd", output2(["-root", "-silent"])],
|
|
30556
|
+
["import", "import", output2(["-silent", "-window", "root", "png:-"])],
|
|
30557
|
+
["maim", "maim", output2(["-f", "png"])],
|
|
30558
|
+
["portal", "", portal]
|
|
30559
|
+
];
|
|
30560
|
+
const tried = [];
|
|
30561
|
+
for (const [name2, program, capture2] of methods) {
|
|
30562
|
+
const tool = program ? await linuxTool(program) : await busSocket(session.env);
|
|
30563
|
+
if (!tool) {
|
|
30564
|
+
tried.push(name2 + ":missing");
|
|
30565
|
+
continue;
|
|
30566
|
+
}
|
|
30567
|
+
let image;
|
|
30568
|
+
try {
|
|
30569
|
+
const source = await capture2(tool);
|
|
30570
|
+
image = decodePng(source) ?? decodeXwd(source);
|
|
30571
|
+
} catch (error62) {
|
|
30572
|
+
if (signal.aborted) throw new ScreenCaptureError("CANCELLED");
|
|
30573
|
+
if (error62 instanceof ScreenCaptureError && error62.code === "SCREEN_RECORDING_PERMISSION_REQUIRED") throw error62;
|
|
30574
|
+
tried.push(name2 + ":failed");
|
|
30575
|
+
continue;
|
|
30576
|
+
}
|
|
30577
|
+
if (!image) {
|
|
30578
|
+
tried.push(name2 + ":unreadable");
|
|
30579
|
+
continue;
|
|
30580
|
+
}
|
|
30581
|
+
const fitted = fitJpeg(image, SCREENSHOT_MAX_EDGE, SCREENSHOT_MAX_JPEG_BYTES);
|
|
30582
|
+
if (!fitted) throw new ScreenCaptureError("SCREENSHOT_TOO_LARGE");
|
|
30583
|
+
return { ...fitted, sourceWidth: image.width, sourceHeight: image.height };
|
|
30584
|
+
}
|
|
30585
|
+
throw new ScreenCaptureError("SCREENSHOT_UNSUPPORTED", {
|
|
30586
|
+
reason: tried.every((entry) => entry.endsWith(":missing")) ? "NO_CAPTURE_TOOL" : "CAPTURE_FAILED",
|
|
30587
|
+
session: session.wayland ? "wayland" : "x11",
|
|
30588
|
+
tried
|
|
30589
|
+
});
|
|
30590
|
+
}
|
|
30591
|
+
async function captureScreen(options) {
|
|
30592
|
+
if (options.signal.aborted) throw new ScreenCaptureError("CANCELLED");
|
|
30593
|
+
if (process.platform === "win32") return windows(options.ownerBridgePath, options.signal);
|
|
30594
|
+
if (process.platform === "darwin") return mac3(options.signal);
|
|
30595
|
+
if (process.platform === "linux") return linux(options.signal);
|
|
30596
|
+
throw new ScreenCaptureError("SCREENSHOT_UNSUPPORTED", { reason: "PLATFORM_UNSUPPORTED" });
|
|
30597
|
+
}
|
|
30598
|
+
|
|
29325
30599
|
// agent/src/tools.ts
|
|
29326
30600
|
var NativeToolError = class extends Error {
|
|
29327
30601
|
constructor(code) {
|
|
@@ -29352,7 +30626,7 @@ function stopped(signal) {
|
|
|
29352
30626
|
if (signal.aborted) fail3("CANCELLED");
|
|
29353
30627
|
}
|
|
29354
30628
|
async function readBoundedFile(file2, maxBytes, bridge, signal) {
|
|
29355
|
-
const stat2 = await
|
|
30629
|
+
const stat2 = await lstat8(file2);
|
|
29356
30630
|
if (!stat2.isFile() || stat2.isSymbolicLink() || stat2.size > maxBytes) fail3("FILE_UNSUPPORTED_OR_TOO_LARGE");
|
|
29357
30631
|
if (process.platform === "win32") {
|
|
29358
30632
|
if (maxBytes <= 1048576 || stat2.size <= 1048576) return readWindowsFile(bridge, file2, Math.min(maxBytes, 1048576), signal);
|
|
@@ -29360,7 +30634,7 @@ async function readBoundedFile(file2, maxBytes, bridge, signal) {
|
|
|
29360
30634
|
if (read.truncated) fail3("FILE_UNSUPPORTED_OR_TOO_LARGE");
|
|
29361
30635
|
return read.data;
|
|
29362
30636
|
}
|
|
29363
|
-
const handle = await open6(file2,
|
|
30637
|
+
const handle = await open6(file2, constants8.O_RDONLY | (constants8.O_NOFOLLOW ?? 0));
|
|
29364
30638
|
try {
|
|
29365
30639
|
const current2 = await handle.stat();
|
|
29366
30640
|
if (!current2.isFile() || current2.size > maxBytes) fail3("FILE_UNSUPPORTED_OR_TOO_LARGE");
|
|
@@ -29412,13 +30686,13 @@ var NativeTools = class {
|
|
|
29412
30686
|
constructor(options) {
|
|
29413
30687
|
this.options = options;
|
|
29414
30688
|
this.options = structuredClone(options);
|
|
29415
|
-
this.memory = new HostMemory(
|
|
30689
|
+
this.memory = new HostMemory(path18.join(options.stateDirectory, "host-memory.json"), Object.keys(options.programs), Object.fromEntries(Object.entries(options.programs).map(([name2, program]) => [name2, program.executable])));
|
|
29416
30690
|
}
|
|
29417
30691
|
options;
|
|
29418
30692
|
memory;
|
|
29419
30693
|
async readFile(file2, maxBytes, signal) {
|
|
29420
30694
|
try {
|
|
29421
|
-
return await readBoundedFile(file2, maxBytes, this.options.ownerBridgePath ??
|
|
30695
|
+
return await readBoundedFile(file2, maxBytes, this.options.ownerBridgePath ?? path18.join(path18.dirname(this.options.helperPath), "OwnerBridge.exe"), signal);
|
|
29422
30696
|
} catch (error62) {
|
|
29423
30697
|
if (error62.code === "ENOENT") throw error62;
|
|
29424
30698
|
if (error62 instanceof Error && /^[A-Z_]{1,40}$/.test(error62.message)) fail3(error62.message);
|
|
@@ -29428,31 +30702,31 @@ var NativeTools = class {
|
|
|
29428
30702
|
/** Windows only: up to 64 files of at most 1 MiB in one bridge process, each with its own result. */
|
|
29429
30703
|
async readFiles(files, maxTotalBytes, signal) {
|
|
29430
30704
|
try {
|
|
29431
|
-
return await readWindowsFiles(this.options.ownerBridgePath ??
|
|
30705
|
+
return await readWindowsFiles(this.options.ownerBridgePath ?? path18.join(path18.dirname(this.options.helperPath), "OwnerBridge.exe"), files, 1048576, maxTotalBytes, signal);
|
|
29432
30706
|
} catch (error62) {
|
|
29433
30707
|
if (error62 instanceof Error && /^[A-Z_]{1,40}$/.test(error62.message)) fail3(error62.message);
|
|
29434
30708
|
throw error62;
|
|
29435
30709
|
}
|
|
29436
30710
|
}
|
|
29437
|
-
async prepare(workspace2, candidate,
|
|
30711
|
+
async prepare(workspace2, candidate, selection2) {
|
|
29438
30712
|
let prepared;
|
|
29439
30713
|
try {
|
|
29440
30714
|
let projectRoot;
|
|
29441
|
-
if (
|
|
29442
|
-
const target = ProjectTargetBindingSchema.parse(
|
|
30715
|
+
if (selection2) {
|
|
30716
|
+
const target = ProjectTargetBindingSchema.parse(selection2);
|
|
29443
30717
|
if (workspace2.rootHash !== target.workspaceRootHash) fail3("PROJECT_IDENTITY_MISMATCH");
|
|
29444
30718
|
const identity = await this.prepareTool(workspace2, { name: "project_identity", args: { path: target.relativePath } });
|
|
29445
30719
|
const proof2 = JSON.parse((await identity.run(AbortSignal.timeout(15e3))).stdout);
|
|
29446
30720
|
if (!proof2.repositoryFingerprint) fail3("PROJECT_IDENTITY_UNKNOWN");
|
|
29447
30721
|
if (proof2.repositoryFingerprint !== target.repositoryFingerprint) fail3("PROJECT_IDENTITY_MISMATCH");
|
|
29448
|
-
projectRoot =
|
|
30722
|
+
projectRoot = path18.resolve(workspace2.root, target.relativePath);
|
|
29449
30723
|
const common = identity.claims.find((claim2) => claim2.namespace === "git")?.path;
|
|
29450
30724
|
if (common) workspace2 = { ...workspace2, gitCommonDir: common };
|
|
29451
30725
|
}
|
|
29452
30726
|
prepared = await this.prepareTool(workspace2, candidate, projectRoot);
|
|
29453
30727
|
} catch (error62) {
|
|
29454
30728
|
const parsed = ToolCallSchema.safeParse(candidate);
|
|
29455
|
-
if (parsed.success && parsed.data.name === "command_run") await this.memory.record({ ...parsed.data.args, cwd:
|
|
30729
|
+
if (parsed.success && parsed.data.name === "command_run") await this.memory.record({ ...parsed.data.args, cwd: path18.resolve(workspace2.root, parsed.data.args.cwd ?? ".") }, void 0, error62).catch(() => {
|
|
29456
30730
|
});
|
|
29457
30731
|
throw error62;
|
|
29458
30732
|
}
|
|
@@ -29472,17 +30746,17 @@ var NativeTools = class {
|
|
|
29472
30746
|
try {
|
|
29473
30747
|
const canonical2 = await realpath7(workspace2.root);
|
|
29474
30748
|
if (!equalPath3(canonical2, workspace2.root) || hash6(process.platform === "win32" ? canonical2.toLowerCase() : canonical2) !== workspace2.rootHash) fail3("WORKSPACE_CHANGED");
|
|
29475
|
-
const runtimeDirectory =
|
|
30749
|
+
const runtimeDirectory = path18.dirname(this.options.helperPath);
|
|
29476
30750
|
const protectedPaths = [
|
|
29477
30751
|
this.options.stateDirectory,
|
|
29478
30752
|
this.options.helperPath,
|
|
29479
|
-
...["agent.mjs", "node.exe", "OwnerBridge.exe", "LocalCommanderAgent.exe", "node", "owner-store", "posix-host", "job-host.mjs", "lifecycle.mjs", "manifest.json"].map((name2) =>
|
|
30753
|
+
...["agent.mjs", "node.exe", "OwnerBridge.exe", "LocalCommanderAgent.exe", "node", "owner-store", "posix-host", "job-host.mjs", "lifecycle.mjs", "manifest.json"].map((name2) => path18.join(runtimeDirectory, name2))
|
|
29480
30754
|
];
|
|
29481
30755
|
if (this.options.ownerBridgePath) protectedPaths.push(this.options.ownerBridgePath);
|
|
29482
|
-
if (process.platform === "win32" && process.env.LOCALAPPDATA &&
|
|
29483
|
-
protectedPaths.push(
|
|
30756
|
+
if (process.platform === "win32" && process.env.LOCALAPPDATA && path18.isAbsolute(process.env.LOCALAPPDATA)) {
|
|
30757
|
+
protectedPaths.push(path18.join(process.env.LOCALAPPDATA, "LocalCommander"));
|
|
29484
30758
|
}
|
|
29485
|
-
if (process.platform !== "win32") protectedPaths.push(
|
|
30759
|
+
if (process.platform !== "win32") protectedPaths.push(path18.join(process.env.LC_AGENT_DATA_DIR || posixDataHome(), "LocalCommander"));
|
|
29486
30760
|
guard = await PathGuard.create([canonical2], false, { protectedPaths });
|
|
29487
30761
|
if (projectRoot) {
|
|
29488
30762
|
const selected = await guard.resolveDirectory(projectRoot);
|
|
@@ -29571,7 +30845,7 @@ var NativeTools = class {
|
|
|
29571
30845
|
}
|
|
29572
30846
|
if (taken === first - 1 && first <= end) fail3("OUTPUT_LIMIT_EXCEEDED");
|
|
29573
30847
|
const remaining = lines.length - (lines.length > 1 && lines.at(-1) === "" ? 1 : 0);
|
|
29574
|
-
return result({ path:
|
|
30848
|
+
return result({ path: path18.relative(workspace2.root, filename), sha256: hash6(bytes3), startLine: first, endLine: Math.min(taken === first - 1 ? last : taken, lines.length), totalLines: lines.length, content: lines.slice(first - 1, taken).join("\n"), truncated: taken < remaining });
|
|
29575
30849
|
} };
|
|
29576
30850
|
}
|
|
29577
30851
|
if (call.name === "fs_write" || call.name === "fs_replace") {
|
|
@@ -29614,8 +30888,8 @@ var NativeTools = class {
|
|
|
29614
30888
|
bytes3 = encodeText(pieces.join(newText), original.encoding);
|
|
29615
30889
|
}
|
|
29616
30890
|
if (bytes3.length > MAX_FILE_WRITE_BYTES) fail3("FILE_WRITE_LIMIT");
|
|
29617
|
-
const temp =
|
|
29618
|
-
const handle = await open6(temp,
|
|
30891
|
+
const temp = path18.join(path18.dirname(target), ".lc-write-" + randomUUID7() + ".tmp");
|
|
30892
|
+
const handle = await open6(temp, constants8.O_CREAT | constants8.O_EXCL | constants8.O_WRONLY, 384);
|
|
29619
30893
|
try {
|
|
29620
30894
|
await handle.writeFile(bytes3);
|
|
29621
30895
|
await handle.sync();
|
|
@@ -29631,7 +30905,7 @@ var NativeTools = class {
|
|
|
29631
30905
|
break;
|
|
29632
30906
|
} catch (error62) {
|
|
29633
30907
|
if (process.platform !== "win32" || !["EPERM", "EBUSY", "EACCES"].includes(error62.code ?? "")) throw error62;
|
|
29634
|
-
if (attempt === 4) fail3((await
|
|
30908
|
+
if (attempt === 4) fail3((await lstat8(target)).mode & 128 ? "FILE_IN_USE" : "FILE_READ_ONLY");
|
|
29635
30909
|
await delay2(50 << attempt);
|
|
29636
30910
|
stopped(signal);
|
|
29637
30911
|
}
|
|
@@ -29646,18 +30920,18 @@ var NativeTools = class {
|
|
|
29646
30920
|
}
|
|
29647
30921
|
for (let attempt = 0; attempt < 3; attempt++) {
|
|
29648
30922
|
try {
|
|
29649
|
-
await
|
|
30923
|
+
await rm6(temp);
|
|
29650
30924
|
break;
|
|
29651
30925
|
} catch {
|
|
29652
30926
|
await delay2(100);
|
|
29653
30927
|
}
|
|
29654
30928
|
}
|
|
29655
30929
|
}
|
|
29656
|
-
return result({ path:
|
|
30930
|
+
return result({ path: path18.relative(workspace2.root, target), bytes: bytes3.length, sha256: hash6(bytes3), ...call.name === "fs_replace" ? { replacements } : {} });
|
|
29657
30931
|
} catch (e) {
|
|
29658
30932
|
await handle.close().catch(() => {
|
|
29659
30933
|
});
|
|
29660
|
-
await
|
|
30934
|
+
await rm6(temp, { force: true }).catch(() => {
|
|
29661
30935
|
});
|
|
29662
30936
|
throw e;
|
|
29663
30937
|
}
|
|
@@ -29679,7 +30953,7 @@ var NativeTools = class {
|
|
|
29679
30953
|
const lines = decodeText(bytes3).text.split(/\r?\n/);
|
|
29680
30954
|
scanned++;
|
|
29681
30955
|
for (let i = 0; i < lines.length && matches2.length < call.args.maxResults; i++) if ((call.args.caseSensitive ? lines[i] : lines[i].toLowerCase()).includes(query)) {
|
|
29682
|
-
const match = { path:
|
|
30956
|
+
const match = { path: path18.relative(workspace2.root, filename), line: i + 1, text: lines[i].slice(0, 500) };
|
|
29683
30957
|
if ((room -= Buffer.byteLength(JSON.stringify(match)) + 1) < 0) {
|
|
29684
30958
|
incomplete = true;
|
|
29685
30959
|
break;
|
|
@@ -29722,7 +30996,7 @@ var NativeTools = class {
|
|
|
29722
30996
|
continue;
|
|
29723
30997
|
}
|
|
29724
30998
|
try {
|
|
29725
|
-
const filename = await guard.resolveExisting(
|
|
30999
|
+
const filename = await guard.resolveExisting(path18.join(base, entry.path));
|
|
29726
31000
|
guard.assertSafeFile(filename);
|
|
29727
31001
|
if (!batched) {
|
|
29728
31002
|
searchFile(filename, await this.readFile(filename, 1048576, signal));
|
|
@@ -29746,6 +31020,42 @@ var NativeTools = class {
|
|
|
29746
31020
|
return result({ matches: matches2, scannedFiles: scanned, truncated: listing.truncated || incomplete || matches2.length >= call.args.maxResults || scanned >= 300 });
|
|
29747
31021
|
} };
|
|
29748
31022
|
}
|
|
31023
|
+
if (call.name === "take_screenshot") {
|
|
31024
|
+
if (!screenshotEnabled() && !await lstat8(path18.join(this.options.stateDirectory, SCREENSHOT_ACCEPTANCE_FILE)).then((s) => s.isFile(), () => false)) fail3("SCREENSHOT_DISABLED");
|
|
31025
|
+
if (!workspace2.fullAccess) fail3("FULL_ACCESS_REQUIRED");
|
|
31026
|
+
if (await lstat8(path18.join(this.options.stateDirectory, SCREENSHOT_OWNER_OFF_FILE)).then(() => true, (error62) => error62.code !== "ENOENT")) fail3("SCREENSHOT_DISABLED_BY_OWNER");
|
|
31027
|
+
const bridge = this.options.ownerBridgePath ?? path18.join(path18.dirname(this.options.helperPath), "OwnerBridge.exe");
|
|
31028
|
+
return { call, claims: [{ path: path18.join(this.options.stateDirectory, "screen-capture"), mode: "read" }], run: async (signal) => {
|
|
31029
|
+
let shot;
|
|
31030
|
+
try {
|
|
31031
|
+
shot = await captureScreen({ ownerBridgePath: bridge, signal });
|
|
31032
|
+
} catch (error62) {
|
|
31033
|
+
if (error62 instanceof ScreenCaptureError && error62.detail) return {
|
|
31034
|
+
exitCode: 1,
|
|
31035
|
+
timedOut: false,
|
|
31036
|
+
cancelled: false,
|
|
31037
|
+
treeTerminated: true,
|
|
31038
|
+
stdout: JSON.stringify({ type: "screenshot_error", resultCode: error62.code, ...error62.detail }),
|
|
31039
|
+
stderr: "",
|
|
31040
|
+
stdoutTruncated: false,
|
|
31041
|
+
stderrTruncated: false,
|
|
31042
|
+
resultCode: error62.code
|
|
31043
|
+
};
|
|
31044
|
+
fail3(error62 instanceof Error && /^[A-Z_]{1,40}$/.test(error62.message) ? error62.message : "SCREEN_UNAVAILABLE");
|
|
31045
|
+
}
|
|
31046
|
+
return result({
|
|
31047
|
+
type: "screenshot",
|
|
31048
|
+
mimeType: "image/jpeg",
|
|
31049
|
+
width: shot.width,
|
|
31050
|
+
height: shot.height,
|
|
31051
|
+
sourceWidth: shot.sourceWidth,
|
|
31052
|
+
sourceHeight: shot.sourceHeight,
|
|
31053
|
+
bytes: shot.data.length,
|
|
31054
|
+
capturedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
31055
|
+
data: shot.data.toString("base64")
|
|
31056
|
+
});
|
|
31057
|
+
} };
|
|
31058
|
+
}
|
|
29749
31059
|
if (call.name === "localhost_request") {
|
|
29750
31060
|
const url2 = new URL(call.args.url), port = Number(url2.port || (url2.protocol === "https:" ? 443 : 80));
|
|
29751
31061
|
if (!["http:", "https:"].includes(url2.protocol) || !["localhost", "127.0.0.1", "[::1]"].includes(url2.hostname) || url2.username || url2.password || url2.hash || (workspace2.fullAccess ? workspace2.deniedLocalhostPorts?.includes(port) : !workspace2.localhostPorts.includes(port)) || this.options.protectedPorts?.includes(port)) fail3("LOCALHOST_NOT_ALLOWED");
|
|
@@ -29816,9 +31126,9 @@ var NativeTools = class {
|
|
|
29816
31126
|
else if (call.name === "git_diff") {
|
|
29817
31127
|
argv = ["diff", "--no-ext-diff", "--no-textconv", ...call.args.staged ? ["--cached"] : []];
|
|
29818
31128
|
if (call.args.file) {
|
|
29819
|
-
const file2 = await resolve(
|
|
29820
|
-
const relative =
|
|
29821
|
-
if (relative.startsWith(".." +
|
|
31129
|
+
const file2 = await resolve(path18.resolve(cwd, call.args.file));
|
|
31130
|
+
const relative = path18.relative(cwd, file2);
|
|
31131
|
+
if (relative.startsWith(".." + path18.sep) || relative === ".." || path18.isAbsolute(relative)) fail3("PATH_NOT_ALLOWED");
|
|
29822
31132
|
argv.push("--", relative);
|
|
29823
31133
|
} else argv.push("--stat");
|
|
29824
31134
|
} else fail3("TOOL_MISSING");
|
|
@@ -29829,7 +31139,7 @@ var NativeTools = class {
|
|
|
29829
31139
|
const listing = await this.list(guard, cwd, 1, call.args.startup ? 20 : 150, signal);
|
|
29830
31140
|
let packageInfo = null;
|
|
29831
31141
|
try {
|
|
29832
|
-
const name2 = await guard.resolveExisting(
|
|
31142
|
+
const name2 = await guard.resolveExisting(path18.join(cwd, "package.json"));
|
|
29833
31143
|
guard.assertSafeFile(name2);
|
|
29834
31144
|
const value = JSON.parse(utf8(await this.readFile(name2, 64e3, signal)));
|
|
29835
31145
|
packageInfo = { name: typeof value.name === "string" ? value.name : null, version: typeof value.version === "string" ? value.version : null, scripts: value.scripts && typeof value.scripts === "object" ? Object.keys(value.scripts).slice(0, 100) : [] };
|
|
@@ -29849,7 +31159,7 @@ var NativeTools = class {
|
|
|
29849
31159
|
}
|
|
29850
31160
|
const contextFile = async (relative, limit, optional2 = false) => {
|
|
29851
31161
|
try {
|
|
29852
|
-
const file2 = await guard.resolveExisting(
|
|
31162
|
+
const file2 = await guard.resolveExisting(path18.join(primary, relative));
|
|
29853
31163
|
guard.assertSafeFile(file2);
|
|
29854
31164
|
return utf8(await this.readFile(file2, limit, signal));
|
|
29855
31165
|
} catch (error62) {
|
|
@@ -29882,19 +31192,19 @@ var NativeTools = class {
|
|
|
29882
31192
|
} };
|
|
29883
31193
|
}
|
|
29884
31194
|
async resolveProgram(name2, workspace2, args) {
|
|
29885
|
-
const entry = Object.entries(this.options.programs).find(([key, value]) => equalPath3(key, name2) ||
|
|
31195
|
+
const entry = Object.entries(this.options.programs).find(([key, value]) => equalPath3(key, name2) || path18.isAbsolute(name2) && equalPath3(value.executable, path18.resolve(name2)));
|
|
29886
31196
|
if (workspace2.fullAccess) {
|
|
29887
|
-
const commandKey = (value) => process.platform === "win32" ?
|
|
31197
|
+
const commandKey = (value) => process.platform === "win32" ? path18.basename(value).toLowerCase().replace(/\.(exe|com|cmd|bat)$/i, "") : path18.basename(value);
|
|
29888
31198
|
const denied = new Set((workspace2.deniedCommands ?? []).map(commandKey));
|
|
29889
31199
|
if (denied.has(commandKey(name2)) || entry && denied.has(commandKey(entry[0]))) fail3("COMMAND_NOT_ALLOWED");
|
|
29890
|
-
const extension2 =
|
|
29891
|
-
const candidate = entry?.[1].executable ?? (process.platform !== "win32" ? await resolvePosixExecutable(name2) :
|
|
31200
|
+
const extension2 = path18.extname(name2).toLowerCase();
|
|
31201
|
+
const candidate = entry?.[1].executable ?? (process.platform !== "win32" ? await resolvePosixExecutable(name2) : path18.isAbsolute(name2) ? name2 : /^[\w.-]+$/.test(name2) ? resolveWindowsLauncher(
|
|
29892
31202
|
commandKey(name2),
|
|
29893
31203
|
[".exe", ".com", ".cmd", ".bat"].includes(extension2) ? { ...process.env, PATHEXT: extension2 } : process.env
|
|
29894
31204
|
)?.file : void 0);
|
|
29895
|
-
if (!candidate || !
|
|
31205
|
+
if (!candidate || !path18.isAbsolute(candidate)) fail3("COMMAND_NOT_FOUND");
|
|
29896
31206
|
const executable = await realpath7(candidate).catch(() => fail3("COMMAND_NOT_FOUND"));
|
|
29897
|
-
if (!(await
|
|
31207
|
+
if (!(await lstat8(executable)).isFile()) fail3("COMMAND_NOT_FOUND");
|
|
29898
31208
|
if (denied.has(commandKey(executable))) fail3("COMMAND_NOT_ALLOWED");
|
|
29899
31209
|
for (const key of workspace2.deniedCommands ?? []) {
|
|
29900
31210
|
const configured = this.options.programs[key]?.executable;
|
|
@@ -29907,7 +31217,7 @@ var NativeTools = class {
|
|
|
29907
31217
|
if (/\.(cmd|bat)$/i.test(executable)) {
|
|
29908
31218
|
if ([executable, ...args].some((value) => /[&|<>^%!"\r\n]/.test(value))) fail3("INVALID_SCRIPT_ARGUMENTS");
|
|
29909
31219
|
const literal2 = (value) => "'" + value.replaceAll("'", "''") + "'";
|
|
29910
|
-
const shell =
|
|
31220
|
+
const shell = path18.join(process.env.SystemRoot ?? "C:\\Windows", "System32", "WindowsPowerShell", "v1.0", "powershell.exe");
|
|
29911
31221
|
if (denied.has("powershell") || denied.has("cmd")) fail3("COMMAND_NOT_ALLOWED");
|
|
29912
31222
|
const script = "& " + literal2(executable) + " @(" + args.map(literal2).join(",") + "); exit $LASTEXITCODE";
|
|
29913
31223
|
return { executable: shell, args: ["-NoProfile", "-NonInteractive", "-EncodedCommand", Buffer.from(script, "utf16le").toString("base64")] };
|
|
@@ -29915,7 +31225,7 @@ var NativeTools = class {
|
|
|
29915
31225
|
if (!/\.(exe|com)$/i.test(executable)) fail3("COMMAND_NOT_ALLOWED");
|
|
29916
31226
|
return { executable, args: [...entry?.[1].prefixArgs ?? [], ...args] };
|
|
29917
31227
|
}
|
|
29918
|
-
if (!entry || !workspace2.allowedCommands.some((v) => equalPath3(v, entry[0])) || !
|
|
31228
|
+
if (!entry || !workspace2.allowedCommands.some((v) => equalPath3(v, entry[0])) || !path18.isAbsolute(entry[1].executable)) fail3("COMMAND_NOT_ALLOWED");
|
|
29919
31229
|
return { executable: entry[1].executable, args: [...entry[1].prefixArgs ?? [], ...args] };
|
|
29920
31230
|
}
|
|
29921
31231
|
async memoryContext(workspace2) {
|
|
@@ -29930,13 +31240,13 @@ var NativeTools = class {
|
|
|
29930
31240
|
async gitExecution(cwd, args) {
|
|
29931
31241
|
if (!["win32", "linux", "darwin"].includes(process.platform)) fail3("COMMAND_NOT_ALLOWED");
|
|
29932
31242
|
const configured = this.options.programs.git;
|
|
29933
|
-
const candidates = configured ? [configured.executable] : process.platform === "win32" ? [[process.env.ProgramFiles, "Git"], [process.env["ProgramFiles(x86)"], "Git"], [process.env.LOCALAPPDATA, "Programs/Git"]].filter(([root]) => root &&
|
|
31243
|
+
const candidates = configured ? [configured.executable] : process.platform === "win32" ? [[process.env.ProgramFiles, "Git"], [process.env["ProgramFiles(x86)"], "Git"], [process.env.LOCALAPPDATA, "Programs/Git"]].filter(([root]) => root && path18.isAbsolute(root)).map(([root, suffix]) => path18.join(root, suffix, "cmd", "git.exe")) : ["/usr/bin/git", "/usr/local/bin/git", "/opt/homebrew/bin/git"];
|
|
29934
31244
|
for (const source of candidates) {
|
|
29935
|
-
if (!
|
|
31245
|
+
if (!path18.isAbsolute(source)) continue;
|
|
29936
31246
|
const candidate = process.platform === "win32" ? source : await resolvePosixExecutable(source);
|
|
29937
31247
|
if (!candidate) continue;
|
|
29938
31248
|
try {
|
|
29939
|
-
const stat2 = await
|
|
31249
|
+
const stat2 = await lstat8(candidate);
|
|
29940
31250
|
if (!stat2.isFile() || stat2.isSymbolicLink() || !equalPath3(candidate, await realpath7(candidate))) continue;
|
|
29941
31251
|
} catch {
|
|
29942
31252
|
continue;
|
|
@@ -29954,7 +31264,7 @@ var NativeTools = class {
|
|
|
29954
31264
|
const current2 = queue.shift();
|
|
29955
31265
|
let names;
|
|
29956
31266
|
try {
|
|
29957
|
-
names = await
|
|
31267
|
+
names = await readdir5(current2.path, { withFileTypes: true });
|
|
29958
31268
|
} catch (error62) {
|
|
29959
31269
|
if (current2.level === 0) throw error62;
|
|
29960
31270
|
continue;
|
|
@@ -29966,7 +31276,7 @@ var NativeTools = class {
|
|
|
29966
31276
|
break;
|
|
29967
31277
|
}
|
|
29968
31278
|
if (item.isSymbolicLink() || excluded.has(item.name.toLowerCase())) continue;
|
|
29969
|
-
const candidate =
|
|
31279
|
+
const candidate = path18.join(current2.path, item.name);
|
|
29970
31280
|
let resolved;
|
|
29971
31281
|
try {
|
|
29972
31282
|
resolved = await guard.resolveExisting(candidate);
|
|
@@ -29976,11 +31286,11 @@ var NativeTools = class {
|
|
|
29976
31286
|
}
|
|
29977
31287
|
if (!equalPath3(candidate, resolved)) continue;
|
|
29978
31288
|
if (item.isDirectory()) {
|
|
29979
|
-
entries.push({ path:
|
|
31289
|
+
entries.push({ path: path18.relative(root, resolved), type: "directory" });
|
|
29980
31290
|
if (current2.level < depth) queue.push({ path: resolved, level: current2.level + 1 });
|
|
29981
31291
|
} else if (item.isFile()) {
|
|
29982
|
-
const stat2 = await
|
|
29983
|
-
if (stat2) entries.push({ path:
|
|
31292
|
+
const stat2 = await lstat8(resolved).catch(() => null);
|
|
31293
|
+
if (stat2) entries.push({ path: path18.relative(root, resolved), type: "file", size: stat2.size });
|
|
29984
31294
|
}
|
|
29985
31295
|
}
|
|
29986
31296
|
if (truncated) break;
|
|
@@ -29990,49 +31300,49 @@ var NativeTools = class {
|
|
|
29990
31300
|
async gitCommonDir(cwd, workspace2, guard) {
|
|
29991
31301
|
let directory = cwd;
|
|
29992
31302
|
while (guard.isWithin(directory, workspace2.root)) {
|
|
29993
|
-
const dotGit =
|
|
31303
|
+
const dotGit = path18.join(directory, ".git");
|
|
29994
31304
|
try {
|
|
29995
|
-
const stat2 = await
|
|
31305
|
+
const stat2 = await lstat8(dotGit);
|
|
29996
31306
|
if (stat2.isSymbolicLink()) fail3("GIT_METADATA_CHANGED");
|
|
29997
31307
|
let gitDir;
|
|
29998
31308
|
if (stat2.isDirectory()) gitDir = await realpath7(dotGit);
|
|
29999
31309
|
else {
|
|
30000
31310
|
const content = utf8(await this.readFile(dotGit, 4096)).trim();
|
|
30001
31311
|
if (!content.startsWith("gitdir: ")) fail3("GIT_METADATA_CHANGED");
|
|
30002
|
-
gitDir = await realpath7(
|
|
31312
|
+
gitDir = await realpath7(path18.resolve(directory, content.slice(8)));
|
|
30003
31313
|
}
|
|
30004
31314
|
if (guard.isWithin(gitDir, this.options.stateDirectory) || !guard.isWithin(gitDir, workspace2.root) && (!workspace2.gitCommonDir || !guard.isWithin(gitDir, workspace2.gitCommonDir))) fail3("GIT_COMMON_DIRECTORY_NOT_APPROVED");
|
|
30005
31315
|
let common = gitDir;
|
|
30006
31316
|
try {
|
|
30007
|
-
const content = utf8(await this.readFile(
|
|
31317
|
+
const content = utf8(await this.readFile(path18.join(gitDir, "commondir"), 4096)).trim();
|
|
30008
31318
|
if (!content) fail3("GIT_METADATA_CHANGED");
|
|
30009
|
-
common = await realpath7(
|
|
31319
|
+
common = await realpath7(path18.resolve(gitDir, content));
|
|
30010
31320
|
} catch (e) {
|
|
30011
31321
|
if (e.code !== "ENOENT") throw e;
|
|
30012
31322
|
}
|
|
30013
|
-
if (!(await
|
|
31323
|
+
if (!(await lstat8(common)).isDirectory() || guard.isWithin(common, this.options.stateDirectory)) fail3("GIT_METADATA_CHANGED");
|
|
30014
31324
|
if (!guard.isWithin(common, workspace2.root) && (!workspace2.gitCommonDir || !equalPath3(common, workspace2.gitCommonDir))) fail3("GIT_COMMON_DIRECTORY_NOT_APPROVED");
|
|
30015
31325
|
return common;
|
|
30016
31326
|
} catch (e) {
|
|
30017
31327
|
if (e.code !== "ENOENT") throw e;
|
|
30018
31328
|
}
|
|
30019
31329
|
if (equalPath3(directory, workspace2.root)) break;
|
|
30020
|
-
directory =
|
|
31330
|
+
directory = path18.dirname(directory);
|
|
30021
31331
|
}
|
|
30022
31332
|
return null;
|
|
30023
31333
|
}
|
|
30024
31334
|
};
|
|
30025
31335
|
|
|
30026
31336
|
// agent/src/scheduler.ts
|
|
30027
|
-
import
|
|
30028
|
-
import
|
|
31337
|
+
import path19 from "node:path";
|
|
31338
|
+
import os5 from "node:os";
|
|
30029
31339
|
function canonical(value) {
|
|
30030
|
-
const p =
|
|
31340
|
+
const p = path19.resolve(value);
|
|
30031
31341
|
return process.platform === "win32" ? p.toLowerCase() : p;
|
|
30032
31342
|
}
|
|
30033
31343
|
function ancestor(a, b) {
|
|
30034
|
-
const relative =
|
|
30035
|
-
return relative === "" || !
|
|
31344
|
+
const relative = path19.relative(a, b);
|
|
31345
|
+
return relative === "" || !path19.isAbsolute(relative) && relative !== ".." && !relative.startsWith(".." + path19.sep);
|
|
30036
31346
|
}
|
|
30037
31347
|
function claimsConflict(a, b) {
|
|
30038
31348
|
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))));
|
|
@@ -30040,7 +31350,7 @@ function claimsConflict(a, b) {
|
|
|
30040
31350
|
var NativeScheduler = class {
|
|
30041
31351
|
constructor(options = {}) {
|
|
30042
31352
|
this.options = options;
|
|
30043
|
-
const capacity = Math.max(1, Math.min(16, Math.floor(Math.max(2,
|
|
31353
|
+
const capacity = Math.max(1, Math.min(16, Math.floor(Math.max(2, os5.availableParallelism?.() ?? os5.cpus().length) / 2)));
|
|
30044
31354
|
this.safeSlots = options.safeSlots ?? capacity;
|
|
30045
31355
|
this.maxQueued = options.maxQueued ?? 32;
|
|
30046
31356
|
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");
|
|
@@ -30058,16 +31368,16 @@ var NativeScheduler = class {
|
|
|
30058
31368
|
} catch {
|
|
30059
31369
|
}
|
|
30060
31370
|
}
|
|
30061
|
-
schedule(id2, claims, deadlineAt,
|
|
31371
|
+
schedule(id2, claims, deadlineAt, run2, signal) {
|
|
30062
31372
|
if (!this.accepting) return Promise.reject(Error("AGENT_PAUSED"));
|
|
30063
31373
|
if (!id2 || id2.length > 100 || this.active.has(id2) || this.waiting.some((j) => j.id === id2)) return Promise.reject(Error("DUPLICATE_SCHEDULED_EXECUTION"));
|
|
30064
|
-
if (!Array.isArray(claims) || !claims.length || claims.length > 32 || claims.some((c) => !c || !
|
|
31374
|
+
if (!Array.isArray(claims) || !claims.length || claims.length > 32 || claims.some((c) => !c || !path19.isAbsolute(c.path) || !["read", "write"].includes(c.mode))) return Promise.reject(Error("INVALID_RESOURCE_CLAIM"));
|
|
30065
31375
|
const deadline = deadlineAt.getTime();
|
|
30066
31376
|
if (!Number.isFinite(deadline) || deadline <= Date.now()) return Promise.reject(Error("ADMISSION_DEADLINE_EXPIRED"));
|
|
30067
31377
|
if (signal?.aborted) return Promise.reject(Error("CANCELLED_BEFORE_ACCEPTANCE"));
|
|
30068
31378
|
if (this.waiting.length >= this.maxQueued) return Promise.reject(Error("RESOURCE_BUSY"));
|
|
30069
31379
|
return new Promise((resolve, reject) => {
|
|
30070
|
-
const job = { id: id2, claims: claims.map((c) => ({ ...c, path: canonical(c.path) })), deadline, run, signal, resolve, reject };
|
|
31380
|
+
const job = { id: id2, claims: claims.map((c) => ({ ...c, path: canonical(c.path) })), deadline, run: run2, signal, resolve, reject };
|
|
30071
31381
|
const remove = (reason) => {
|
|
30072
31382
|
const index = this.waiting.indexOf(job);
|
|
30073
31383
|
if (index < 0) return;
|
|
@@ -30766,7 +32076,45 @@ function journalBinding(entry, binding2) {
|
|
|
30766
32076
|
function journalResult(value, code) {
|
|
30767
32077
|
return { ...value, resultCode: code ?? (value.treeTerminated ? value.cancelled ? "CANCELLED" : value.timedOut ? "TIMEOUT" : value.exitCode === 0 ? "SUCCESS" : "USER_PROGRAM_FAILED" : "EXECUTION_UNKNOWN") };
|
|
30768
32078
|
}
|
|
30769
|
-
var knownCodes = /* @__PURE__ */ new Set([
|
|
32079
|
+
var knownCodes = /* @__PURE__ */ new Set([
|
|
32080
|
+
"PROJECT_IDENTITY_UNKNOWN",
|
|
32081
|
+
"PROJECT_IDENTITY_MISMATCH",
|
|
32082
|
+
"INVALID_TOOL_ARGUMENTS",
|
|
32083
|
+
"LOCAL_PERMISSION_REQUIRED",
|
|
32084
|
+
"PATH_NOT_ALLOWED",
|
|
32085
|
+
"FILE_CHANGED",
|
|
32086
|
+
"FILE_NOT_FOUND",
|
|
32087
|
+
"FILE_ALREADY_EXISTS",
|
|
32088
|
+
"REPLACEMENT_NOT_UNIQUE",
|
|
32089
|
+
"OUTPUT_LIMIT_EXCEEDED",
|
|
32090
|
+
"BINARY_FILE_NOT_SUPPORTED",
|
|
32091
|
+
"FILE_UNSUPPORTED_OR_TOO_LARGE",
|
|
32092
|
+
"INVALID_LINE_RANGE",
|
|
32093
|
+
"FILE_IN_USE",
|
|
32094
|
+
"FILE_READ_ONLY",
|
|
32095
|
+
"FILE_WRITE_LIMIT",
|
|
32096
|
+
"GIT_METADATA_CHANGED",
|
|
32097
|
+
"GIT_COMMON_DIRECTORY_NOT_APPROVED",
|
|
32098
|
+
"GIT_NOT_INSTALLED",
|
|
32099
|
+
"LOCALHOST_NOT_ALLOWED",
|
|
32100
|
+
"COMMAND_NOT_ALLOWED",
|
|
32101
|
+
"WORKSPACE_CHANGED",
|
|
32102
|
+
"WORKSPACE_UNAVAILABLE",
|
|
32103
|
+
"RESOURCE_BUSY",
|
|
32104
|
+
"AGENT_PAUSED",
|
|
32105
|
+
"CANCELLED_BEFORE_ACCEPTANCE",
|
|
32106
|
+
"ADMISSION_DEADLINE_EXPIRED",
|
|
32107
|
+
// take_screenshot refusals (#434, #486): without these the client sees TOOL_FAILED.
|
|
32108
|
+
"FULL_ACCESS_REQUIRED",
|
|
32109
|
+
"SCREENSHOT_DISABLED",
|
|
32110
|
+
"SCREENSHOT_DISABLED_BY_OWNER",
|
|
32111
|
+
"SCREENSHOT_UNSUPPORTED",
|
|
32112
|
+
"SCREENSHOT_TOO_LARGE",
|
|
32113
|
+
"SCREEN_UNAVAILABLE",
|
|
32114
|
+
"SCREEN_LOCKED",
|
|
32115
|
+
"SCREEN_ENCODER_UNAVAILABLE",
|
|
32116
|
+
"SCREEN_RECORDING_PERMISSION_REQUIRED"
|
|
32117
|
+
]);
|
|
30770
32118
|
function safeCode(error62) {
|
|
30771
32119
|
const code = error62 instanceof NativeToolError ? error62.code : error62 instanceof Error ? error62.message : "";
|
|
30772
32120
|
return knownCodes.has(code) || /^GUARD_[A-Z_]{1,30}$/.test(code) ? code : "TOOL_FAILED";
|
|
@@ -30777,6 +32125,14 @@ function resultOutcome(result2) {
|
|
|
30777
32125
|
if (!result2.treeTerminated || result2.exitCode === null) return "unknown";
|
|
30778
32126
|
return result2.exitCode === 0 ? "success" : "failed";
|
|
30779
32127
|
}
|
|
32128
|
+
function screenshotMetadata(stdout) {
|
|
32129
|
+
try {
|
|
32130
|
+
const { data: _data, ...metadata } = JSON.parse(stdout);
|
|
32131
|
+
return JSON.stringify(metadata);
|
|
32132
|
+
} catch {
|
|
32133
|
+
return "";
|
|
32134
|
+
}
|
|
32135
|
+
}
|
|
30780
32136
|
async function outboundResult(call, result2, binding2, optional2, ledger) {
|
|
30781
32137
|
const shaped = call.name === "command_run" ? shapeCommandResultForAgentDetailed({ command: call.args.command, args: call.args.args, cwd: call.args.cwd ?? "." }, result2) : { result: result2, telemetry: unshapedResultTelemetry(result2) };
|
|
30782
32138
|
if (ledger) {
|
|
@@ -30829,7 +32185,7 @@ var NativeRuntime = class {
|
|
|
30829
32185
|
}
|
|
30830
32186
|
if (frame.type === "result" && this.options.contentAudit) {
|
|
30831
32187
|
const call = this.contexts.get(frame.binding.executionId)?.tool.call;
|
|
30832
|
-
if (call) try {
|
|
32188
|
+
if (call && call.name !== "take_screenshot") try {
|
|
30833
32189
|
this.options.contentAudit.record(frame.binding, call, frame.result);
|
|
30834
32190
|
} catch {
|
|
30835
32191
|
}
|
|
@@ -30966,8 +32322,10 @@ var NativeRuntime = class {
|
|
|
30966
32322
|
const checked = ResultSchema.parse(output2);
|
|
30967
32323
|
const { resultCode, ...journalOutput } = checked;
|
|
30968
32324
|
if (context.guardPermit) await this.options.guard.result(context.guardPermit, checked);
|
|
30969
|
-
const
|
|
30970
|
-
this.
|
|
32325
|
+
const image = runnable.call.name === "take_screenshot" ? journalOutput.stdout : void 0;
|
|
32326
|
+
const final = await this.options.journal.finish(binding2.executionId, image === void 0 ? journalOutput : { ...journalOutput, stdout: screenshotMetadata(image) }, resultCode);
|
|
32327
|
+
const outbound = await outboundResult(runnable.call, journalResult(final.result, resultCode), binding2, this.optionalTelemetry, this.options.efficiencyLedger);
|
|
32328
|
+
this.send({ type: "result", version: 1, binding: binding2, result: image === void 0 ? outbound : { ...outbound, stdout: image } });
|
|
30971
32329
|
}, abort.signal);
|
|
30972
32330
|
context.task = work.catch(async (error62) => {
|
|
30973
32331
|
if (!context.accepted) {
|
|
@@ -31189,10 +32547,10 @@ var NativeRelayBridge = class {
|
|
|
31189
32547
|
};
|
|
31190
32548
|
|
|
31191
32549
|
// agent/src/local-direct.ts
|
|
31192
|
-
import
|
|
31193
|
-
import
|
|
31194
|
-
import { createHmac as createHmac2, hkdfSync, randomBytes as
|
|
31195
|
-
import { mkdir as mkdir7, readFile as
|
|
32550
|
+
import net2 from "node:net";
|
|
32551
|
+
import path20 from "node:path";
|
|
32552
|
+
import { createHmac as createHmac2, hkdfSync, randomBytes as randomBytes7, randomUUID as randomUUID8, timingSafeEqual as timingSafeEqual3 } from "node:crypto";
|
|
32553
|
+
import { mkdir as mkdir7, readFile as readFile8, rename as rename5, rm as rm7, writeFile as writeFile3 } from "node:fs/promises";
|
|
31196
32554
|
var LocalDirectError = class extends Error {
|
|
31197
32555
|
constructor(code) {
|
|
31198
32556
|
super(code);
|
|
@@ -31210,11 +32568,11 @@ var ADMISSION_MS = 6e4;
|
|
|
31210
32568
|
var MAX_IN_FLIGHT = 16;
|
|
31211
32569
|
var MAX_CONNECTIONS = 32;
|
|
31212
32570
|
function localDirectDirectory(appData) {
|
|
31213
|
-
return
|
|
32571
|
+
return path20.join(appData, "LocalCommander", "LocalMcp");
|
|
31214
32572
|
}
|
|
31215
32573
|
async function localDirectEnabled(directory) {
|
|
31216
32574
|
try {
|
|
31217
|
-
return JSON.parse(await
|
|
32575
|
+
return JSON.parse(await readFile8(path20.join(directory, "settings.json"), "utf8"))?.enabled === true;
|
|
31218
32576
|
} catch {
|
|
31219
32577
|
return false;
|
|
31220
32578
|
}
|
|
@@ -31228,7 +32586,7 @@ function sameProof(candidate, expected) {
|
|
|
31228
32586
|
const a = Buffer.from(candidate), b = Buffer.from(expected);
|
|
31229
32587
|
return a.length === b.length && timingSafeEqual3(a, b);
|
|
31230
32588
|
}
|
|
31231
|
-
var nonce = () =>
|
|
32589
|
+
var nonce = () => randomBytes7(32).toString("base64url");
|
|
31232
32590
|
var NONCE = /^[A-Za-z0-9_-]{43}$/;
|
|
31233
32591
|
function codeOf(error62) {
|
|
31234
32592
|
const code = error62 instanceof NativeToolError || error62 instanceof LocalDirectError ? error62.code : error62 instanceof Error ? error62.message : "";
|
|
@@ -31287,7 +32645,7 @@ var Lines = class {
|
|
|
31287
32645
|
async function readEndpoint(directory) {
|
|
31288
32646
|
let value;
|
|
31289
32647
|
try {
|
|
31290
|
-
value = JSON.parse(await
|
|
32648
|
+
value = JSON.parse(await readFile8(path20.join(directory, "endpoint.json"), "utf8"));
|
|
31291
32649
|
} catch {
|
|
31292
32650
|
fail4("LOCAL_AGENT_NOT_RUNNING");
|
|
31293
32651
|
}
|
|
@@ -31304,13 +32662,13 @@ var LocalDirectServer = class _LocalDirectServer {
|
|
|
31304
32662
|
sockets = /* @__PURE__ */ new Set();
|
|
31305
32663
|
/** Listens only while the owner has enabled direct local access; null otherwise. */
|
|
31306
32664
|
static async start(options) {
|
|
31307
|
-
const endpointFile =
|
|
32665
|
+
const endpointFile = path20.join(options.directory, "endpoint.json");
|
|
31308
32666
|
if (!await localDirectEnabled(options.directory)) {
|
|
31309
|
-
await
|
|
32667
|
+
await rm7(endpointFile, { force: true }).catch(() => {
|
|
31310
32668
|
});
|
|
31311
32669
|
return null;
|
|
31312
32670
|
}
|
|
31313
|
-
const server =
|
|
32671
|
+
const server = net2.createServer(), self = new _LocalDirectServer(server, options);
|
|
31314
32672
|
server.on("connection", (socket) => self.accept(socket));
|
|
31315
32673
|
await new Promise((resolve, reject) => {
|
|
31316
32674
|
server.once("error", reject);
|
|
@@ -31332,7 +32690,7 @@ var LocalDirectServer = class _LocalDirectServer {
|
|
|
31332
32690
|
for (const socket of this.sockets) socket.destroy();
|
|
31333
32691
|
await new Promise((resolve) => this.server.close(() => resolve()));
|
|
31334
32692
|
try {
|
|
31335
|
-
if ((await readEndpoint(this.options.directory)).pid === process.pid) await
|
|
32693
|
+
if ((await readEndpoint(this.options.directory)).pid === process.pid) await rm7(path20.join(this.options.directory, "endpoint.json"), { force: true });
|
|
31336
32694
|
} catch {
|
|
31337
32695
|
}
|
|
31338
32696
|
}
|
|
@@ -31467,7 +32825,7 @@ var LocalDirectClient = class _LocalDirectClient {
|
|
|
31467
32825
|
static async connect(options) {
|
|
31468
32826
|
if (!await localDirectEnabled(options.directory)) fail4("LOCAL_ACCESS_DISABLED");
|
|
31469
32827
|
const endpoint2 = await readEndpoint(options.directory);
|
|
31470
|
-
const socket =
|
|
32828
|
+
const socket = net2.createConnection({ host: "127.0.0.1", port: endpoint2.port });
|
|
31471
32829
|
let handler = () => {
|
|
31472
32830
|
};
|
|
31473
32831
|
const lines = new Lines(socket, (frame) => handler(frame));
|
|
@@ -35187,9 +36545,9 @@ var rev2026Codec = {
|
|
|
35187
36545
|
});
|
|
35188
36546
|
const parsed = buildSchemas2026().RequestMetaEnvelopeSchema.safeParse(meta3);
|
|
35189
36547
|
if (!parsed.success) for (const issue2 of parsed.error.issues) {
|
|
35190
|
-
const
|
|
35191
|
-
const key =
|
|
35192
|
-
if (
|
|
36548
|
+
const path30 = issue2.path.map(String);
|
|
36549
|
+
const key = path30.length > 0 ? path30.join(".") : "_meta";
|
|
36550
|
+
if (path30.length === 1 && issues.some((existing) => existing.key === key && existing.problem === "missing")) continue;
|
|
35193
36551
|
issues.push({
|
|
35194
36552
|
key,
|
|
35195
36553
|
problem: issue2.message
|
|
@@ -35491,29 +36849,29 @@ var PERMITTED_X_MCP_HEADER_TYPES = /* @__PURE__ */ new Set([
|
|
|
35491
36849
|
function scanXMcpHeaderDeclarations(inputSchema) {
|
|
35492
36850
|
const declarations = [];
|
|
35493
36851
|
const seenLower = /* @__PURE__ */ new Map();
|
|
35494
|
-
const visit2 = (node2,
|
|
36852
|
+
const visit2 = (node2, path30, reachable) => {
|
|
35495
36853
|
if (node2 === null || typeof node2 !== "object") return void 0;
|
|
35496
36854
|
const schema = node2;
|
|
35497
36855
|
if (X_MCP_HEADER_KEY in schema) {
|
|
35498
|
-
if (!reachable ||
|
|
36856
|
+
if (!reachable || path30.length === 0) return `${pathName(path30)}: x-mcp-header is only permitted on properties statically reachable via a chain of 'properties' keys (not under items, additionalProperties, oneOf/anyOf/allOf/not, if/then/else, or $ref)`;
|
|
35499
36857
|
const raw = schema[X_MCP_HEADER_KEY];
|
|
35500
|
-
if (typeof raw !== "string" || raw.length === 0) return `${pathName(
|
|
35501
|
-
if (!RFC9110_TOKEN.test(raw)) return `${pathName(
|
|
36858
|
+
if (typeof raw !== "string" || raw.length === 0) return `${pathName(path30)}: x-mcp-header MUST be a non-empty string`;
|
|
36859
|
+
if (!RFC9110_TOKEN.test(raw)) return `${pathName(path30)}: x-mcp-header '${raw}' is not a valid RFC 9110 token (no spaces, control characters or HTTP delimiters)`;
|
|
35502
36860
|
const type = typeof schema.type === "string" ? schema.type : void 0;
|
|
35503
|
-
if (type === void 0 || !PERMITTED_X_MCP_HEADER_TYPES.has(type)) return `${pathName(
|
|
36861
|
+
if (type === void 0 || !PERMITTED_X_MCP_HEADER_TYPES.has(type)) return `${pathName(path30)}: x-mcp-header is only permitted on primitive-typed properties (string, integer, boolean); got ${type ?? "<none>"}`;
|
|
35504
36862
|
const lower = raw.toLowerCase();
|
|
35505
36863
|
const prior = seenLower.get(lower);
|
|
35506
36864
|
if (prior !== void 0) return `x-mcp-header '${raw}' is not case-insensitively unique (also declared as '${prior}')`;
|
|
35507
36865
|
seenLower.set(lower, raw);
|
|
35508
36866
|
declarations.push({
|
|
35509
|
-
path:
|
|
36867
|
+
path: path30,
|
|
35510
36868
|
headerName: raw,
|
|
35511
36869
|
type
|
|
35512
36870
|
});
|
|
35513
36871
|
}
|
|
35514
36872
|
const properties = schema.properties;
|
|
35515
36873
|
if (properties !== null && typeof properties === "object") for (const [key, child] of Object.entries(properties)) {
|
|
35516
|
-
const fault$1 = visit2(child, [...
|
|
36874
|
+
const fault$1 = visit2(child, [...path30, key], reachable);
|
|
35517
36875
|
if (fault$1 !== void 0) return fault$1;
|
|
35518
36876
|
}
|
|
35519
36877
|
for (const k of NON_REACHABLE_SUBSCHEMA_KEYWORDS) {
|
|
@@ -35521,7 +36879,7 @@ function scanXMcpHeaderDeclarations(inputSchema) {
|
|
|
35521
36879
|
if (sub === void 0) continue;
|
|
35522
36880
|
const branches = Array.isArray(sub) ? sub : sub !== null && typeof sub === "object" && OBJECT_VALUED_SUBSCHEMA_KEYWORDS.has(k) ? Object.values(sub) : [sub];
|
|
35523
36881
|
for (const branch of branches) {
|
|
35524
|
-
const fault$1 = visit2(branch, [...
|
|
36882
|
+
const fault$1 = visit2(branch, [...path30, `<${k}>`], false);
|
|
35525
36883
|
if (fault$1 !== void 0) return fault$1;
|
|
35526
36884
|
}
|
|
35527
36885
|
}
|
|
@@ -35561,8 +36919,8 @@ var OBJECT_VALUED_SUBSCHEMA_KEYWORDS = /* @__PURE__ */ new Set([
|
|
|
35561
36919
|
"$defs",
|
|
35562
36920
|
"definitions"
|
|
35563
36921
|
]);
|
|
35564
|
-
function pathName(
|
|
35565
|
-
return
|
|
36922
|
+
function pathName(path30) {
|
|
36923
|
+
return path30.length === 0 ? "<root>" : path30.join(".");
|
|
35566
36924
|
}
|
|
35567
36925
|
var HEADER_MISMATCH_ERROR_CODE = -32020;
|
|
35568
36926
|
var INBOUND_VALIDATION_LADDER = [
|
|
@@ -35812,7 +37170,7 @@ var PROPERTY_KEYS_BY_TYPE = {
|
|
|
35812
37170
|
array: shapeKeys([UntitledMultiSelectEnumSchemaSchema, TitledMultiSelectEnumSchemaSchema])
|
|
35813
37171
|
};
|
|
35814
37172
|
var SUPPORTED_STRING_FORMATS = new Set(StringSchemaSchema.shape.format.unwrap().options);
|
|
35815
|
-
function walkProperty(node2,
|
|
37173
|
+
function walkProperty(node2, path30, vendor, unsupported) {
|
|
35816
37174
|
if (!isJsonObject(node2)) return node2;
|
|
35817
37175
|
const allowedKeys = typeof node2.type === "string" && Object.hasOwn(PROPERTY_KEYS_BY_TYPE, node2.type) ? PROPERTY_KEYS_BY_TYPE[node2.type] : void 0;
|
|
35818
37176
|
if (allowedKeys === void 0) return node2;
|
|
@@ -35820,8 +37178,8 @@ function walkProperty(node2, path29, vendor, unsupported) {
|
|
|
35820
37178
|
for (const [key, value] of Object.entries(node2)) if (allowedKeys.has(key) || isAnnotationOnlyJsonSchemaKeyword(key)) pruned[key] = value;
|
|
35821
37179
|
else if (key === "pattern" && node2.type === "string" && typeof node2.format === "string") {
|
|
35822
37180
|
if (!SUPPORTED_STRING_FORMATS.has(node2.format)) pruned[key] = value;
|
|
35823
|
-
else if (typeof value !== "string" || !isLibraryFormatPattern(node2.format, value, vendor)) unsupported.push(`${
|
|
35824
|
-
} else unsupported.push(`${
|
|
37181
|
+
else if (typeof value !== "string" || !isLibraryFormatPattern(node2.format, value, vendor)) unsupported.push(`${path30}.${key}`);
|
|
37182
|
+
} else unsupported.push(`${path30}.${key}`);
|
|
35825
37183
|
return pruned;
|
|
35826
37184
|
}
|
|
35827
37185
|
function walkRequestedSchema(converted, vendor) {
|
|
@@ -35838,11 +37196,11 @@ function describeUnsupportedProperties(pruned, fallback) {
|
|
|
35838
37196
|
const offenders = Object.entries(pruned.properties).filter(([, node2]) => !parseSchema(PrimitiveSchemaDefinitionSchema, node2).success).map(([name2]) => `properties.${name2}`);
|
|
35839
37197
|
return offenders.length > 0 ? offenders.join(", ") : fallback;
|
|
35840
37198
|
}
|
|
35841
|
-
function findDroppedConstraintPaths(original, parsed,
|
|
35842
|
-
if (Array.isArray(original) && Array.isArray(parsed)) return original.flatMap((item, index) => findDroppedConstraintPaths(item, parsed[index], `${
|
|
37199
|
+
function findDroppedConstraintPaths(original, parsed, path30 = "") {
|
|
37200
|
+
if (Array.isArray(original) && Array.isArray(parsed)) return original.flatMap((item, index) => findDroppedConstraintPaths(item, parsed[index], `${path30}[${index}]`));
|
|
35843
37201
|
if (!isJsonObject(original) || !isJsonObject(parsed)) return [];
|
|
35844
37202
|
return Object.entries(original).flatMap(([key, value]) => {
|
|
35845
|
-
const childPath =
|
|
37203
|
+
const childPath = path30 ? `${path30}.${key}` : key;
|
|
35846
37204
|
if (!Object.prototype.hasOwnProperty.call(parsed, key)) return isAnnotationOnlyJsonSchemaKeyword(key) ? [] : [childPath];
|
|
35847
37205
|
return findDroppedConstraintPaths(value, parsed[key], childPath);
|
|
35848
37206
|
});
|
|
@@ -36990,8 +38348,8 @@ var require_content_type = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
36990
38348
|
var PARAM_REGEXP = /; *([!#$%&'*+.^_`|~0-9A-Za-z-]+) *= *("(?:[\u000b\u0020\u0021\u0023-\u005b\u005d-\u007e\u0080-\u00ff]|\\[\u000b\u0020-\u00ff])*"|[!#$%&'*+.^_`|~0-9A-Za-z-]+) */g;
|
|
36991
38349
|
var QESC_REGEXP = /\\([\u000b\u0020-\u00ff])/g;
|
|
36992
38350
|
var TYPE_REGEXP = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+\/[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;
|
|
36993
|
-
exports.parse =
|
|
36994
|
-
function
|
|
38351
|
+
exports.parse = parse4;
|
|
38352
|
+
function parse4(string4) {
|
|
36995
38353
|
if (!string4) throw new TypeError("argument string is required");
|
|
36996
38354
|
var header = typeof string4 === "object" ? getcontenttype(string4) : string4;
|
|
36997
38355
|
if (typeof header !== "string") throw new TypeError("argument string is required to be a string");
|
|
@@ -37515,9 +38873,9 @@ var require_codegen = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
37515
38873
|
const rhs = this.rhs === void 0 ? "" : ` = ${this.rhs}`;
|
|
37516
38874
|
return `${varKind} ${this.name}${rhs};` + _n;
|
|
37517
38875
|
}
|
|
37518
|
-
optimizeNames(names,
|
|
38876
|
+
optimizeNames(names, constants11) {
|
|
37519
38877
|
if (!names[this.name.str]) return;
|
|
37520
|
-
if (this.rhs) this.rhs = optimizeExpr(this.rhs, names,
|
|
38878
|
+
if (this.rhs) this.rhs = optimizeExpr(this.rhs, names, constants11);
|
|
37521
38879
|
return this;
|
|
37522
38880
|
}
|
|
37523
38881
|
get names() {
|
|
@@ -37534,9 +38892,9 @@ var require_codegen = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
37534
38892
|
render({ _n }) {
|
|
37535
38893
|
return `${this.lhs} = ${this.rhs};` + _n;
|
|
37536
38894
|
}
|
|
37537
|
-
optimizeNames(names,
|
|
38895
|
+
optimizeNames(names, constants11) {
|
|
37538
38896
|
if (this.lhs instanceof code_1.Name && !names[this.lhs.str] && !this.sideEffects) return;
|
|
37539
|
-
this.rhs = optimizeExpr(this.rhs, names,
|
|
38897
|
+
this.rhs = optimizeExpr(this.rhs, names, constants11);
|
|
37540
38898
|
return this;
|
|
37541
38899
|
}
|
|
37542
38900
|
get names() {
|
|
@@ -37595,8 +38953,8 @@ var require_codegen = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
37595
38953
|
optimizeNodes() {
|
|
37596
38954
|
return `${this.code}` ? this : void 0;
|
|
37597
38955
|
}
|
|
37598
|
-
optimizeNames(names,
|
|
37599
|
-
this.code = optimizeExpr(this.code, names,
|
|
38956
|
+
optimizeNames(names, constants11) {
|
|
38957
|
+
this.code = optimizeExpr(this.code, names, constants11);
|
|
37600
38958
|
return this;
|
|
37601
38959
|
}
|
|
37602
38960
|
get names() {
|
|
@@ -37622,12 +38980,12 @@ var require_codegen = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
37622
38980
|
}
|
|
37623
38981
|
return nodes.length > 0 ? this : void 0;
|
|
37624
38982
|
}
|
|
37625
|
-
optimizeNames(names,
|
|
38983
|
+
optimizeNames(names, constants11) {
|
|
37626
38984
|
const { nodes } = this;
|
|
37627
38985
|
let i = nodes.length;
|
|
37628
38986
|
while (i--) {
|
|
37629
38987
|
const n = nodes[i];
|
|
37630
|
-
if (n.optimizeNames(names,
|
|
38988
|
+
if (n.optimizeNames(names, constants11)) continue;
|
|
37631
38989
|
subtractNames(names, n.names);
|
|
37632
38990
|
nodes.splice(i, 1);
|
|
37633
38991
|
}
|
|
@@ -37674,11 +39032,11 @@ var require_codegen = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
37674
39032
|
if (cond === false || !this.nodes.length) return void 0;
|
|
37675
39033
|
return this;
|
|
37676
39034
|
}
|
|
37677
|
-
optimizeNames(names,
|
|
39035
|
+
optimizeNames(names, constants11) {
|
|
37678
39036
|
var _a3;
|
|
37679
|
-
this.else = (_a3 = this.else) === null || _a3 === void 0 ? void 0 : _a3.optimizeNames(names,
|
|
37680
|
-
if (!(super.optimizeNames(names,
|
|
37681
|
-
this.condition = optimizeExpr(this.condition, names,
|
|
39037
|
+
this.else = (_a3 = this.else) === null || _a3 === void 0 ? void 0 : _a3.optimizeNames(names, constants11);
|
|
39038
|
+
if (!(super.optimizeNames(names, constants11) || this.else)) return;
|
|
39039
|
+
this.condition = optimizeExpr(this.condition, names, constants11);
|
|
37682
39040
|
return this;
|
|
37683
39041
|
}
|
|
37684
39042
|
get names() {
|
|
@@ -37700,9 +39058,9 @@ var require_codegen = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
37700
39058
|
render(opts) {
|
|
37701
39059
|
return `for(${this.iteration})` + super.render(opts);
|
|
37702
39060
|
}
|
|
37703
|
-
optimizeNames(names,
|
|
37704
|
-
if (!super.optimizeNames(names,
|
|
37705
|
-
this.iteration = optimizeExpr(this.iteration, names,
|
|
39061
|
+
optimizeNames(names, constants11) {
|
|
39062
|
+
if (!super.optimizeNames(names, constants11)) return;
|
|
39063
|
+
this.iteration = optimizeExpr(this.iteration, names, constants11);
|
|
37706
39064
|
return this;
|
|
37707
39065
|
}
|
|
37708
39066
|
get names() {
|
|
@@ -37737,9 +39095,9 @@ var require_codegen = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
37737
39095
|
render(opts) {
|
|
37738
39096
|
return `for(${this.varKind} ${this.name} ${this.loop} ${this.iterable})` + super.render(opts);
|
|
37739
39097
|
}
|
|
37740
|
-
optimizeNames(names,
|
|
37741
|
-
if (!super.optimizeNames(names,
|
|
37742
|
-
this.iterable = optimizeExpr(this.iterable, names,
|
|
39098
|
+
optimizeNames(names, constants11) {
|
|
39099
|
+
if (!super.optimizeNames(names, constants11)) return;
|
|
39100
|
+
this.iterable = optimizeExpr(this.iterable, names, constants11);
|
|
37743
39101
|
return this;
|
|
37744
39102
|
}
|
|
37745
39103
|
get names() {
|
|
@@ -37778,11 +39136,11 @@ var require_codegen = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
37778
39136
|
(_b = this.finally) === null || _b === void 0 || _b.optimizeNodes();
|
|
37779
39137
|
return this;
|
|
37780
39138
|
}
|
|
37781
|
-
optimizeNames(names,
|
|
39139
|
+
optimizeNames(names, constants11) {
|
|
37782
39140
|
var _a3, _b;
|
|
37783
|
-
super.optimizeNames(names,
|
|
37784
|
-
(_a3 = this.catch) === null || _a3 === void 0 || _a3.optimizeNames(names,
|
|
37785
|
-
(_b = this.finally) === null || _b === void 0 || _b.optimizeNames(names,
|
|
39141
|
+
super.optimizeNames(names, constants11);
|
|
39142
|
+
(_a3 = this.catch) === null || _a3 === void 0 || _a3.optimizeNames(names, constants11);
|
|
39143
|
+
(_b = this.finally) === null || _b === void 0 || _b.optimizeNames(names, constants11);
|
|
37786
39144
|
return this;
|
|
37787
39145
|
}
|
|
37788
39146
|
get names() {
|
|
@@ -38031,7 +39389,7 @@ var require_codegen = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
38031
39389
|
function addExprNames(names, from) {
|
|
38032
39390
|
return from instanceof code_1._CodeOrName ? addNames(names, from.names) : names;
|
|
38033
39391
|
}
|
|
38034
|
-
function optimizeExpr(expr, names,
|
|
39392
|
+
function optimizeExpr(expr, names, constants11) {
|
|
38035
39393
|
if (expr instanceof code_1.Name) return replaceName(expr);
|
|
38036
39394
|
if (!canOptimize(expr)) return expr;
|
|
38037
39395
|
return new code_1._Code(expr._items.reduce((items, c) => {
|
|
@@ -38041,13 +39399,13 @@ var require_codegen = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
38041
39399
|
return items;
|
|
38042
39400
|
}, []));
|
|
38043
39401
|
function replaceName(n) {
|
|
38044
|
-
const c =
|
|
39402
|
+
const c = constants11[n.str];
|
|
38045
39403
|
if (c === void 0 || names[n.str] !== 1) return n;
|
|
38046
39404
|
delete names[n.str];
|
|
38047
39405
|
return c;
|
|
38048
39406
|
}
|
|
38049
39407
|
function canOptimize(e) {
|
|
38050
|
-
return e instanceof code_1._Code && e._items.some((c) => c instanceof code_1.Name && names[c.str] === 1 &&
|
|
39408
|
+
return e instanceof code_1._Code && e._items.some((c) => c instanceof code_1.Name && names[c.str] === 1 && constants11[c.str] !== void 0);
|
|
38051
39409
|
}
|
|
38052
39410
|
}
|
|
38053
39411
|
function subtractNames(names, from) {
|
|
@@ -39918,8 +41276,8 @@ var require_utils = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
39918
41276
|
for (let i = 0; i < str.length; i++) if (str[i] === token) ind++;
|
|
39919
41277
|
return ind;
|
|
39920
41278
|
}
|
|
39921
|
-
function removeDotSegments(
|
|
39922
|
-
let input2 =
|
|
41279
|
+
function removeDotSegments(path30) {
|
|
41280
|
+
let input2 = path30;
|
|
39923
41281
|
const output2 = [];
|
|
39924
41282
|
let nextSlash = -1;
|
|
39925
41283
|
let len = 0;
|
|
@@ -40072,8 +41430,8 @@ var require_schemes = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
40072
41430
|
wsComponent.secure = void 0;
|
|
40073
41431
|
}
|
|
40074
41432
|
if (wsComponent.resourceName) {
|
|
40075
|
-
const [
|
|
40076
|
-
wsComponent.path =
|
|
41433
|
+
const [path30, query] = wsComponent.resourceName.split("?");
|
|
41434
|
+
wsComponent.path = path30 && path30 !== "/" ? path30 : void 0;
|
|
40077
41435
|
wsComponent.query = query;
|
|
40078
41436
|
wsComponent.resourceName = void 0;
|
|
40079
41437
|
}
|
|
@@ -40179,21 +41537,21 @@ var require_fast_uri = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
40179
41537
|
const { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizeComponentEncoding, isIPv4, nonSimpleDomain } = require_utils();
|
|
40180
41538
|
const { SCHEMES, getSchemeHandler } = require_schemes();
|
|
40181
41539
|
function normalize(uri, options) {
|
|
40182
|
-
if (typeof uri === "string") uri = serialize(
|
|
40183
|
-
else if (typeof uri === "object") uri =
|
|
41540
|
+
if (typeof uri === "string") uri = serialize(parse4(uri, options), options);
|
|
41541
|
+
else if (typeof uri === "object") uri = parse4(serialize(uri, options), options);
|
|
40184
41542
|
return uri;
|
|
40185
41543
|
}
|
|
40186
41544
|
function resolve(baseURI, relativeURI, options) {
|
|
40187
41545
|
const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
|
|
40188
|
-
const resolved = resolveComponent(
|
|
41546
|
+
const resolved = resolveComponent(parse4(baseURI, schemelessOptions), parse4(relativeURI, schemelessOptions), schemelessOptions, true);
|
|
40189
41547
|
schemelessOptions.skipEscape = true;
|
|
40190
41548
|
return serialize(resolved, schemelessOptions);
|
|
40191
41549
|
}
|
|
40192
41550
|
function resolveComponent(base, relative, options, skipNormalization) {
|
|
40193
41551
|
const target = {};
|
|
40194
41552
|
if (!skipNormalization) {
|
|
40195
|
-
base =
|
|
40196
|
-
relative =
|
|
41553
|
+
base = parse4(serialize(base, options), options);
|
|
41554
|
+
relative = parse4(serialize(relative, options), options);
|
|
40197
41555
|
}
|
|
40198
41556
|
options = options || {};
|
|
40199
41557
|
if (!options.tolerant && relative.scheme) {
|
|
@@ -40237,7 +41595,7 @@ var require_fast_uri = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
40237
41595
|
function equal(uriA, uriB, options) {
|
|
40238
41596
|
if (typeof uriA === "string") {
|
|
40239
41597
|
uriA = unescape(uriA);
|
|
40240
|
-
uriA = serialize(normalizeComponentEncoding(
|
|
41598
|
+
uriA = serialize(normalizeComponentEncoding(parse4(uriA, options), true), {
|
|
40241
41599
|
...options,
|
|
40242
41600
|
skipEscape: true
|
|
40243
41601
|
});
|
|
@@ -40247,7 +41605,7 @@ var require_fast_uri = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
40247
41605
|
});
|
|
40248
41606
|
if (typeof uriB === "string") {
|
|
40249
41607
|
uriB = unescape(uriB);
|
|
40250
|
-
uriB = serialize(normalizeComponentEncoding(
|
|
41608
|
+
uriB = serialize(normalizeComponentEncoding(parse4(uriB, options), true), {
|
|
40251
41609
|
...options,
|
|
40252
41610
|
skipEscape: true
|
|
40253
41611
|
});
|
|
@@ -40300,7 +41658,7 @@ var require_fast_uri = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
40300
41658
|
return uriTokens.join("");
|
|
40301
41659
|
}
|
|
40302
41660
|
const URI_PARSE = /^(?:([^#/:?]+):)?(?:\/\/((?:([^#/?@]*)@)?(\[[^#/?\]]+\]|[^#/:?]*)(?::(\d*))?))?([^#?]*)(?:\?([^#]*))?(?:#((?:.|[\n\r])*))?/u;
|
|
40303
|
-
function
|
|
41661
|
+
function parse4(uri, opts) {
|
|
40304
41662
|
const options = Object.assign({}, opts);
|
|
40305
41663
|
const parsed = {
|
|
40306
41664
|
scheme: void 0,
|
|
@@ -40361,7 +41719,7 @@ var require_fast_uri = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
40361
41719
|
resolveComponent,
|
|
40362
41720
|
equal,
|
|
40363
41721
|
serialize,
|
|
40364
|
-
parse:
|
|
41722
|
+
parse: parse4
|
|
40365
41723
|
};
|
|
40366
41724
|
module.exports = fastUri;
|
|
40367
41725
|
module.exports.default = fastUri;
|
|
@@ -45640,7 +46998,8 @@ var DESCRIPTIONS = {
|
|
|
45640
46998
|
git_diff: ["Git diff of the repository at a workspace-relative path.", { readOnlyHint: true, openWorldHint: false }],
|
|
45641
46999
|
git_log: ["Recent Git commits of the repository at a workspace-relative path.", { readOnlyHint: true, openWorldHint: false }],
|
|
45642
47000
|
project_snapshot: ["Compact project overview: Git state and, with startup, AGENTS.md policy and task continuation.", { readOnlyHint: true, openWorldHint: false }],
|
|
45643
|
-
command_run: ["Run one executable with an argument array (no shell parsing), hidden, with captured output. Uses this
|
|
47001
|
+
command_run: ["Run one executable with an argument array (no shell parsing), hidden, with captured output. Uses this user account's rights within the owner's grant.", { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: true }],
|
|
47002
|
+
take_screenshot: ["Take a still image of this computer's primary screen, returned as a JPEG image. It contains everything visible on the screen, including any open passwords, keys or private messages. Needs a Full Access workspace; the lock screen is never captured.", { readOnlyHint: true, openWorldHint: false }],
|
|
45644
47003
|
localhost_request: ["HTTP request to a service on this computer (localhost only).", { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: false }]
|
|
45645
47004
|
};
|
|
45646
47005
|
var workspace = external_exports.string().min(1).max(4096).optional().describe("Workspace grant id, root path (for example D:\\) or display name from workspace_list. Optional when only one workspace is approved.");
|
|
@@ -45653,6 +47012,14 @@ function failure4(error62) {
|
|
|
45653
47012
|
return text2(code + hint, true);
|
|
45654
47013
|
}
|
|
45655
47014
|
function render(name2, result2) {
|
|
47015
|
+
if (name2 === "take_screenshot" && result2.resultCode === "SUCCESS") {
|
|
47016
|
+
try {
|
|
47017
|
+
const { data, mimeType, ...metadata } = JSON.parse(result2.stdout);
|
|
47018
|
+
if (typeof data === "string" && data && mimeType === "image/jpeg") return { content: [{ type: "image", data, mimeType }, { type: "text", text: JSON.stringify(metadata) }] };
|
|
47019
|
+
} catch {
|
|
47020
|
+
}
|
|
47021
|
+
return text2(JSON.stringify({ resultCode: "SCREEN_UNAVAILABLE" }), true);
|
|
47022
|
+
}
|
|
45656
47023
|
if (name2 !== "command_run" && result2.resultCode === "SUCCESS") return text2(result2.stdout);
|
|
45657
47024
|
const { exitCode, resultCode, timedOut, cancelled, stdout, stderr, stdoutTruncated, stderrTruncated } = result2;
|
|
45658
47025
|
return text2(
|
|
@@ -45673,7 +47040,7 @@ async function serveLocalMcp(options) {
|
|
|
45673
47040
|
return connecting;
|
|
45674
47041
|
};
|
|
45675
47042
|
const server = new McpServer({ name: "local-commander-local", version: options.agentVersion }, {
|
|
45676
|
-
instructions: "Local Commander direct access to this computer, through the owner's approved workspaces. Paths are relative to the selected workspace root; call workspace_list to see roots. Commands run hidden with this
|
|
47043
|
+
instructions: "Local Commander direct access to this computer, through the owner's approved workspaces. Paths are relative to the selected workspace root; call workspace_list to see roots. Commands run hidden with this user account's rights; owner denials still apply."
|
|
45677
47044
|
});
|
|
45678
47045
|
server.registerTool(
|
|
45679
47046
|
"workspace_list",
|
|
@@ -45688,7 +47055,7 @@ async function serveLocalMcp(options) {
|
|
|
45688
47055
|
);
|
|
45689
47056
|
for (const option of ToolCallSchema.options) {
|
|
45690
47057
|
const name2 = option.shape.name.value, entry = DESCRIPTIONS[name2];
|
|
45691
|
-
if (!entry) continue;
|
|
47058
|
+
if (!entry || name2 === "take_screenshot" && !screenshotEnabled()) continue;
|
|
45692
47059
|
const inputSchema = option.shape.args.extend({ workspace });
|
|
45693
47060
|
const callback = async (input2, ctx) => {
|
|
45694
47061
|
const { workspace: selected, ...args } = input2;
|
|
@@ -46154,6 +47521,7 @@ async function connectOnce(options) {
|
|
|
46154
47521
|
const incidents = Array.isArray(readyFrame.capabilities) && readyFrame.capabilities.includes("incidentBatchV1");
|
|
46155
47522
|
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;
|
|
46156
47523
|
const nativeStatus = Array.isArray(readyFrame.capabilities) && readyFrame.capabilities.includes(NATIVE_STATUS_CAPABILITY) && options.status;
|
|
47524
|
+
const accessModes = Array.isArray(readyFrame.capabilities) && readyFrame.capabilities.includes(WORKSPACE_ACCESS_MODE_CAPABILITY);
|
|
46157
47525
|
const reportStatus = () => {
|
|
46158
47526
|
if (!nativeStatus) return;
|
|
46159
47527
|
const { safeSlots, active, queued, paused } = nativeStatus();
|
|
@@ -46380,7 +47748,16 @@ async function connectOnce(options) {
|
|
|
46380
47748
|
registerWorkspace: (workspace2) => {
|
|
46381
47749
|
if (pendingWorkspace.size >= 32) return Promise.reject(new RelayClientError("RELAY_PENDING_LIMIT"));
|
|
46382
47750
|
const requestId = randomUUID10();
|
|
46383
|
-
const event = {
|
|
47751
|
+
const event = {
|
|
47752
|
+
type: "workspace_grant",
|
|
47753
|
+
version: 1,
|
|
47754
|
+
requestId,
|
|
47755
|
+
workspaceGrantId: workspace2.workspaceGrantId,
|
|
47756
|
+
rootHash: workspace2.rootHash,
|
|
47757
|
+
displayName: workspace2.displayName,
|
|
47758
|
+
policyVersion: workspace2.policyVersion,
|
|
47759
|
+
...accessModes ? { accessMode: workspace2.fullAccess === true ? "full" : "scoped" } : {}
|
|
47760
|
+
};
|
|
46384
47761
|
return new Promise((resolve, reject) => {
|
|
46385
47762
|
const timer = setTimeout(() => {
|
|
46386
47763
|
pendingWorkspace.delete(requestId);
|
|
@@ -46427,16 +47804,16 @@ async function connectOnce(options) {
|
|
|
46427
47804
|
// agent/src/machine-identity.ts
|
|
46428
47805
|
import { spawn as spawn5 } from "node:child_process";
|
|
46429
47806
|
import { createHash as createHash16 } from "node:crypto";
|
|
46430
|
-
import
|
|
47807
|
+
import os6 from "node:os";
|
|
46431
47808
|
import { open as open7 } from "node:fs/promises";
|
|
46432
|
-
import { constants as
|
|
46433
|
-
import
|
|
47809
|
+
import { constants as constants9 } from "node:fs";
|
|
47810
|
+
import path21 from "node:path";
|
|
46434
47811
|
var MACHINE_GUID = /^\s*MachineGuid\s+REG_SZ\s+([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})\s*$/m;
|
|
46435
47812
|
async function readMachineGuid(timeoutMs2 = 5e3) {
|
|
46436
47813
|
if (process.platform === "linux") {
|
|
46437
47814
|
let handle;
|
|
46438
47815
|
try {
|
|
46439
|
-
handle = await open7("/etc/machine-id",
|
|
47816
|
+
handle = await open7("/etc/machine-id", constants9.O_RDONLY | constants9.O_NOFOLLOW);
|
|
46440
47817
|
const stat2 = await handle.stat();
|
|
46441
47818
|
if (!stat2.isFile() || stat2.size > 128) return null;
|
|
46442
47819
|
const data = Buffer.alloc(129);
|
|
@@ -46451,7 +47828,7 @@ async function readMachineGuid(timeoutMs2 = 5e3) {
|
|
|
46451
47828
|
}
|
|
46452
47829
|
}
|
|
46453
47830
|
if (!["win32", "darwin"].includes(process.platform)) return null;
|
|
46454
|
-
const reg = process.platform === "darwin" ? "/usr/sbin/ioreg" :
|
|
47831
|
+
const reg = process.platform === "darwin" ? "/usr/sbin/ioreg" : path21.join(process.env.SystemRoot || "C:\\Windows", "System32", "reg.exe");
|
|
46455
47832
|
const args = process.platform === "darwin" ? ["-rd1", "-c", "IOPlatformExpertDevice"] : ["query", "HKLM\\SOFTWARE\\Microsoft\\Cryptography", "/v", "MachineGuid", "/reg:64"];
|
|
46456
47833
|
const pattern = process.platform === "darwin" ? /"IOPlatformUUID"\s*=\s*"([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})"/ : MACHINE_GUID;
|
|
46457
47834
|
return new Promise((resolve) => {
|
|
@@ -46485,7 +47862,7 @@ async function readComputerName(timeoutMs2 = 5e3) {
|
|
|
46485
47862
|
if (process.platform === "linux") {
|
|
46486
47863
|
let handle;
|
|
46487
47864
|
try {
|
|
46488
|
-
handle = await open7("/etc/hostname",
|
|
47865
|
+
handle = await open7("/etc/hostname", constants9.O_RDONLY | constants9.O_NOFOLLOW);
|
|
46489
47866
|
const data = Buffer.alloc(257), { bytesRead } = await handle.read(data, 0, data.length, 0);
|
|
46490
47867
|
const name2 = data.subarray(0, bytesRead).toString("utf8").trim();
|
|
46491
47868
|
if (bytesRead <= 256 && valid(name2)) return name2;
|
|
@@ -46523,9 +47900,9 @@ async function readComputerName(timeoutMs2 = 5e3) {
|
|
|
46523
47900
|
});
|
|
46524
47901
|
if (valid(name2)) return name2;
|
|
46525
47902
|
}
|
|
46526
|
-
return
|
|
47903
|
+
return os6.hostname();
|
|
46527
47904
|
}
|
|
46528
|
-
function machineProof(deviceId, machineGuid, computerName =
|
|
47905
|
+
function machineProof(deviceId, machineGuid, computerName = os6.hostname()) {
|
|
46529
47906
|
const name2 = computerName.slice(0, 120);
|
|
46530
47907
|
if (!name2 || name2.trim() !== name2 || /[\u0000-\u001f\u007f]/.test(name2)) return null;
|
|
46531
47908
|
const fingerprint3 = createHash16("sha256").update("lcmcp-machine-v1\0" + deviceId.toLowerCase() + "\0" + machineGuid.toLowerCase() + "\0" + name2.toUpperCase(), "utf8").digest("hex");
|
|
@@ -46566,8 +47943,8 @@ function canonicalOrigin2(value) {
|
|
|
46566
47943
|
fail6("ORIGIN_INVALID");
|
|
46567
47944
|
}
|
|
46568
47945
|
}
|
|
46569
|
-
function endpoint(origin,
|
|
46570
|
-
return origin +
|
|
47946
|
+
function endpoint(origin, path30) {
|
|
47947
|
+
return origin + path30;
|
|
46571
47948
|
}
|
|
46572
47949
|
function uuid21(value, code) {
|
|
46573
47950
|
if (typeof value !== "string" || !UUID3.test(value)) fail6(code);
|
|
@@ -47068,29 +48445,29 @@ async function deliverGuardEvidence(target, packet, options = {}) {
|
|
|
47068
48445
|
}
|
|
47069
48446
|
|
|
47070
48447
|
// agent/src/optimization-ledger.ts
|
|
47071
|
-
import { constants as
|
|
47072
|
-
import { lstat as
|
|
47073
|
-
import
|
|
48448
|
+
import { constants as constants10 } from "node:fs";
|
|
48449
|
+
import { lstat as lstat9, mkdir as mkdir8, open as open8, readFile as readFile9, realpath as realpath8 } from "node:fs/promises";
|
|
48450
|
+
import path22 from "node:path";
|
|
47074
48451
|
var MAX_LEDGER_BYTES = 64 * 1024 * 1024;
|
|
47075
48452
|
var MAX_NOTICE_LEDGER_BYTES = 8 * 1024 * 1024;
|
|
47076
48453
|
function failure5(code) {
|
|
47077
48454
|
return Object.assign(new Error(code), { code });
|
|
47078
48455
|
}
|
|
47079
48456
|
async function safeDirectory2(directory) {
|
|
47080
|
-
const absolute2 =
|
|
48457
|
+
const absolute2 = path22.resolve(directory);
|
|
47081
48458
|
let current2 = absolute2;
|
|
47082
48459
|
for (; ; ) {
|
|
47083
48460
|
try {
|
|
47084
|
-
if ((await
|
|
48461
|
+
if ((await lstat9(current2)).isSymbolicLink()) throw failure5("OPTIMIZATION_LEDGER_DIRECTORY_INVALID");
|
|
47085
48462
|
} catch (error62) {
|
|
47086
48463
|
if (error62.code !== "ENOENT") throw error62;
|
|
47087
48464
|
}
|
|
47088
|
-
const parent =
|
|
48465
|
+
const parent = path22.dirname(current2);
|
|
47089
48466
|
if (parent === current2) break;
|
|
47090
48467
|
current2 = parent;
|
|
47091
48468
|
}
|
|
47092
48469
|
await mkdir8(absolute2, { recursive: true, mode: 448 });
|
|
47093
|
-
const stat2 = await
|
|
48470
|
+
const stat2 = await lstat9(absolute2);
|
|
47094
48471
|
if (!stat2.isDirectory() || stat2.isSymbolicLink()) throw failure5("OPTIMIZATION_LEDGER_DIRECTORY_INVALID");
|
|
47095
48472
|
return realpath8(absolute2);
|
|
47096
48473
|
}
|
|
@@ -47120,29 +48497,29 @@ var OptimizationLedger = class _OptimizationLedger {
|
|
|
47120
48497
|
closed = false;
|
|
47121
48498
|
static async open(directory) {
|
|
47122
48499
|
const dir = await safeDirectory2(directory);
|
|
47123
|
-
const filename =
|
|
47124
|
-
const noticesFilename =
|
|
48500
|
+
const filename = path22.join(dir, "live-efficiency.v1.jsonl");
|
|
48501
|
+
const noticesFilename = path22.join(dir, "live-efficiency-notices.v1.jsonl");
|
|
47125
48502
|
let existing = "";
|
|
47126
48503
|
try {
|
|
47127
|
-
const stat2 = await
|
|
48504
|
+
const stat2 = await lstat9(filename);
|
|
47128
48505
|
if (!stat2.isFile() || stat2.isSymbolicLink() || stat2.size > MAX_LEDGER_BYTES) {
|
|
47129
48506
|
throw failure5("OPTIMIZATION_LEDGER_INVALID");
|
|
47130
48507
|
}
|
|
47131
|
-
existing = await
|
|
48508
|
+
existing = await readFile9(filename, "utf8");
|
|
47132
48509
|
} catch (error62) {
|
|
47133
48510
|
if (error62.code !== "ENOENT") throw error62;
|
|
47134
48511
|
}
|
|
47135
48512
|
const handle = await open8(
|
|
47136
48513
|
filename,
|
|
47137
|
-
|
|
48514
|
+
constants10.O_CREAT | constants10.O_APPEND | constants10.O_WRONLY | (constants10.O_NOFOLLOW ?? 0),
|
|
47138
48515
|
384
|
|
47139
48516
|
);
|
|
47140
48517
|
const ledger = new _OptimizationLedger(filename, handle, noticesFilename);
|
|
47141
48518
|
try {
|
|
47142
48519
|
try {
|
|
47143
|
-
const noticeStat = await
|
|
48520
|
+
const noticeStat = await lstat9(noticesFilename);
|
|
47144
48521
|
if (!noticeStat.isFile() || noticeStat.isSymbolicLink() || noticeStat.size > MAX_NOTICE_LEDGER_BYTES) throw failure5("OPTIMIZATION_NOTICE_LEDGER_INVALID");
|
|
47145
|
-
const notices = await
|
|
48522
|
+
const notices = await readFile9(noticesFilename, "utf8");
|
|
47146
48523
|
for (const line of notices.split("\n")) {
|
|
47147
48524
|
if (!line) continue;
|
|
47148
48525
|
const parsed = JSON.parse(line);
|
|
@@ -47222,7 +48599,7 @@ var OptimizationLedger = class _OptimizationLedger {
|
|
|
47222
48599
|
const marker = JSON.stringify({ sessionId: event.sessionId, checkpointCalls, deliveredAt: (/* @__PURE__ */ new Date()).toISOString() }) + "\n";
|
|
47223
48600
|
let currentBytes = 0;
|
|
47224
48601
|
try {
|
|
47225
|
-
const stat2 = await
|
|
48602
|
+
const stat2 = await lstat9(this.noticesFilename);
|
|
47226
48603
|
if (!stat2.isFile() || stat2.isSymbolicLink()) throw failure5("OPTIMIZATION_NOTICE_LEDGER_INVALID");
|
|
47227
48604
|
currentBytes = stat2.size;
|
|
47228
48605
|
} catch (error62) {
|
|
@@ -47231,7 +48608,7 @@ var OptimizationLedger = class _OptimizationLedger {
|
|
|
47231
48608
|
if (currentBytes + Buffer.byteLength(marker, "utf8") > MAX_NOTICE_LEDGER_BYTES) throw failure5("OPTIMIZATION_NOTICE_LEDGER_CAPACITY_EXCEEDED");
|
|
47232
48609
|
const markerHandle = await open8(
|
|
47233
48610
|
this.noticesFilename,
|
|
47234
|
-
|
|
48611
|
+
constants10.O_CREAT | constants10.O_APPEND | constants10.O_WRONLY | (constants10.O_NOFOLLOW ?? 0),
|
|
47235
48612
|
384
|
|
47236
48613
|
);
|
|
47237
48614
|
try {
|
|
@@ -47270,9 +48647,9 @@ var OptimizationLedger = class _OptimizationLedger {
|
|
|
47270
48647
|
|
|
47271
48648
|
// agent/src/monitor.ts
|
|
47272
48649
|
import { createHash as createHash17, randomUUID as randomUUID12 } from "node:crypto";
|
|
47273
|
-
import { lstat as
|
|
47274
|
-
import
|
|
47275
|
-
import
|
|
48650
|
+
import { lstat as lstat10, mkdir as mkdir9, open as open9, rename as rename6, rm as rm8 } from "node:fs/promises";
|
|
48651
|
+
import path23 from "node:path";
|
|
48652
|
+
import os7 from "node:os";
|
|
47276
48653
|
|
|
47277
48654
|
// packages/agent-cli/bin/monitor-savings.mjs
|
|
47278
48655
|
var count = (value) => Number.isSafeInteger(value) && value >= 0 && value <= 1e15;
|
|
@@ -47294,7 +48671,7 @@ function lifetimeSavingsView(raw) {
|
|
|
47294
48671
|
// agent/src/monitor.ts
|
|
47295
48672
|
function commandSummary2(tool) {
|
|
47296
48673
|
if (tool.name !== "command_run") return { name: tool.name, command: tool.name };
|
|
47297
|
-
const candidate =
|
|
48674
|
+
const candidate = path23.win32.basename(tool.args.command).replace(/\.(exe|cmd|bat|com)$/i, "").toLowerCase();
|
|
47298
48675
|
const name2 = ["node", "npm", "npx", "git", "rg", "powershell", "pwsh", "cmd", "tsc", "python", "dotnet"].includes(candidate) ? candidate : "command";
|
|
47299
48676
|
let command = name2;
|
|
47300
48677
|
if (name2 === "node" && tool.args.args.includes("--test") && !tool.args.args.some((arg) => ["-e", "--eval", "-p", "--print"].includes(arg))) command += " --test";
|
|
@@ -47307,9 +48684,9 @@ function commandSummary2(tool) {
|
|
|
47307
48684
|
var ProductionMonitor = class {
|
|
47308
48685
|
constructor(directory, stateDirectory, agentVersion3) {
|
|
47309
48686
|
this.agentVersion = agentVersion3;
|
|
47310
|
-
const key = createHash17("sha256").update(
|
|
47311
|
-
this.file =
|
|
47312
|
-
this.transportFile =
|
|
48687
|
+
const key = createHash17("sha256").update(path23.resolve(stateDirectory).toLowerCase()).digest("hex");
|
|
48688
|
+
this.file = path23.join(directory, key + ".json");
|
|
48689
|
+
this.transportFile = path23.join(directory, key + ".transport");
|
|
47313
48690
|
}
|
|
47314
48691
|
agentVersion;
|
|
47315
48692
|
instanceId = randomUUID12();
|
|
@@ -47320,7 +48697,7 @@ var ProductionMonitor = class {
|
|
|
47320
48697
|
measured = /* @__PURE__ */ new Set();
|
|
47321
48698
|
polls = { status: 0, output: 0 };
|
|
47322
48699
|
efficiencyCalls = 0;
|
|
47323
|
-
computer =
|
|
48700
|
+
computer = os7.hostname().replace(/[^A-Za-z0-9._-]/g, "_").slice(0, 64) || "PC";
|
|
47324
48701
|
sequence = 0;
|
|
47325
48702
|
connection = {
|
|
47326
48703
|
state: "starting",
|
|
@@ -47501,7 +48878,7 @@ var ProductionMonitor = class {
|
|
|
47501
48878
|
schemaVersion: 1,
|
|
47502
48879
|
instanceId: this.instanceId,
|
|
47503
48880
|
pid: process.pid,
|
|
47504
|
-
savingsSourceId:
|
|
48881
|
+
savingsSourceId: path23.basename(this.file, ".json"),
|
|
47505
48882
|
lifetimeSavings: this.lifetimeSavings && { ...this.lifetimeSavings },
|
|
47506
48883
|
computer: this.computer,
|
|
47507
48884
|
processName: "lc-agent",
|
|
@@ -47535,9 +48912,9 @@ var ProductionMonitor = class {
|
|
|
47535
48912
|
return this.writing;
|
|
47536
48913
|
}
|
|
47537
48914
|
async write(file2, contents) {
|
|
47538
|
-
const directory =
|
|
48915
|
+
const directory = path23.dirname(file2);
|
|
47539
48916
|
await mkdir9(directory, { recursive: true, mode: 448 });
|
|
47540
|
-
const stat2 = await
|
|
48917
|
+
const stat2 = await lstat10(directory);
|
|
47541
48918
|
if (!stat2.isDirectory() || stat2.isSymbolicLink()) throw Error("MONITOR_DIRECTORY_INVALID");
|
|
47542
48919
|
const temporary = file2 + "." + this.instanceId + ".tmp";
|
|
47543
48920
|
const handle = await open9(temporary, "wx", 384);
|
|
@@ -47549,7 +48926,7 @@ var ProductionMonitor = class {
|
|
|
47549
48926
|
}
|
|
47550
48927
|
await rename6(temporary, file2);
|
|
47551
48928
|
} finally {
|
|
47552
|
-
await
|
|
48929
|
+
await rm8(temporary, { force: true });
|
|
47553
48930
|
}
|
|
47554
48931
|
}
|
|
47555
48932
|
async close() {
|
|
@@ -47960,27 +49337,27 @@ var NativeFabricObserver = class {
|
|
|
47960
49337
|
};
|
|
47961
49338
|
|
|
47962
49339
|
// agent/src/native-fabric-startup.ts
|
|
47963
|
-
import { lstat as
|
|
47964
|
-
import
|
|
49340
|
+
import { lstat as lstat12, mkdir as mkdir12, open as open11, readFile as readFile10 } from "node:fs/promises";
|
|
49341
|
+
import path26 from "node:path";
|
|
47965
49342
|
|
|
47966
49343
|
// src/agent-fabric-service.ts
|
|
47967
|
-
import { lstat as
|
|
49344
|
+
import { lstat as lstat11, mkdir as mkdir11, realpath as realpath9 } from "node:fs/promises";
|
|
47968
49345
|
import { watch } from "node:fs";
|
|
47969
|
-
import
|
|
49346
|
+
import path25 from "node:path";
|
|
47970
49347
|
|
|
47971
49348
|
// src/agent-runtime-identity.ts
|
|
47972
|
-
import { createHash as createHash19, randomBytes as
|
|
49349
|
+
import { createHash as createHash19, randomBytes as randomBytes8, randomUUID as randomUUID14, timingSafeEqual as timingSafeEqual4 } from "node:crypto";
|
|
47973
49350
|
|
|
47974
49351
|
// src/agent-fabric-state.ts
|
|
47975
49352
|
import { randomUUID as randomUUID13 } from "node:crypto";
|
|
47976
|
-
import { mkdir as mkdir10, open as open10, rename as rename7, unlink as
|
|
47977
|
-
import
|
|
49353
|
+
import { mkdir as mkdir10, open as open10, rename as rename7, unlink as unlink3 } from "node:fs/promises";
|
|
49354
|
+
import path24 from "node:path";
|
|
47978
49355
|
var queues = /* @__PURE__ */ new Map();
|
|
47979
49356
|
var FabricStateFile = class {
|
|
47980
|
-
constructor(file2, maxBytes,
|
|
49357
|
+
constructor(file2, maxBytes, parse4) {
|
|
47981
49358
|
this.maxBytes = maxBytes;
|
|
47982
|
-
this.parse =
|
|
47983
|
-
this.file =
|
|
49359
|
+
this.parse = parse4;
|
|
49360
|
+
this.file = path24.resolve(file2);
|
|
47984
49361
|
}
|
|
47985
49362
|
maxBytes;
|
|
47986
49363
|
parse;
|
|
@@ -48024,7 +49401,7 @@ var FabricStateFile = class {
|
|
|
48024
49401
|
}
|
|
48025
49402
|
update(fn, create) {
|
|
48026
49403
|
return this.serial(async () => {
|
|
48027
|
-
if (create) await mkdir10(
|
|
49404
|
+
if (create) await mkdir10(path24.dirname(this.file), { recursive: true });
|
|
48028
49405
|
const lockPath = this.file + ".lock";
|
|
48029
49406
|
const token = randomUUID13();
|
|
48030
49407
|
const lock = await open10(lockPath, "wx", 384).catch((error62) => {
|
|
@@ -48055,7 +49432,7 @@ var FabricStateFile = class {
|
|
|
48055
49432
|
}
|
|
48056
49433
|
await rename7(temporary, this.file);
|
|
48057
49434
|
} finally {
|
|
48058
|
-
await
|
|
49435
|
+
await unlink3(temporary).catch((error62) => {
|
|
48059
49436
|
if (error62.code !== "ENOENT") throw error62;
|
|
48060
49437
|
});
|
|
48061
49438
|
}
|
|
@@ -48069,7 +49446,7 @@ var FabricStateFile = class {
|
|
|
48069
49446
|
} finally {
|
|
48070
49447
|
await current2.close();
|
|
48071
49448
|
}
|
|
48072
|
-
await
|
|
49449
|
+
await unlink3(lockPath);
|
|
48073
49450
|
}
|
|
48074
49451
|
});
|
|
48075
49452
|
}
|
|
@@ -48123,7 +49500,7 @@ var AgentRuntimeIdentityStore = class {
|
|
|
48123
49500
|
return this.serial((state) => {
|
|
48124
49501
|
if (state.bindings.length >= MAX_BINDINGS) throw Error("RUNTIME_IDENTITY_LIMIT");
|
|
48125
49502
|
const runtimeId = "rt-" + randomUUID14();
|
|
48126
|
-
const runtimeKey =
|
|
49503
|
+
const runtimeKey = randomBytes8(32).toString("base64url");
|
|
48127
49504
|
const now = this.now();
|
|
48128
49505
|
state.bindings.push({ runtimeId, keyHash: encodedDigest(runtimeKey), createdAt: now, lastUsedAt: now, revoked: false });
|
|
48129
49506
|
return { runtimeId, runtimeKey };
|
|
@@ -48668,9 +50045,9 @@ var WorkerRequest = external_exports.discriminatedUnion("operation", [
|
|
|
48668
50045
|
var AgentFabricService = class _AgentFabricService {
|
|
48669
50046
|
constructor(directory, controllerId) {
|
|
48670
50047
|
this.directory = directory;
|
|
48671
|
-
this.identities = new AgentRuntimeIdentityStore(
|
|
50048
|
+
this.identities = new AgentRuntimeIdentityStore(path25.join(directory, "identities.json"));
|
|
48672
50049
|
this.mailbox = new AgentWorkerMailbox(
|
|
48673
|
-
|
|
50050
|
+
path25.join(directory, "mailbox.json"),
|
|
48674
50051
|
controllerId,
|
|
48675
50052
|
this.identities,
|
|
48676
50053
|
void 0,
|
|
@@ -48685,21 +50062,21 @@ var AgentFabricService = class _AgentFabricService {
|
|
|
48685
50062
|
closed = false;
|
|
48686
50063
|
static async open(directory, controllerId, device = null, initialize = true) {
|
|
48687
50064
|
const expected = Binding.parse({ version: 1, controllerId, device, initialized: false });
|
|
48688
|
-
const absolute2 =
|
|
48689
|
-
for (let current2 = absolute2; ; current2 =
|
|
50065
|
+
const absolute2 = path25.resolve(directory);
|
|
50066
|
+
for (let current2 = absolute2; ; current2 = path25.dirname(current2)) {
|
|
48690
50067
|
try {
|
|
48691
|
-
if ((await
|
|
50068
|
+
if ((await lstat11(current2)).isSymbolicLink()) throw Error("FABRIC_DIRECTORY_INVALID");
|
|
48692
50069
|
} catch (error62) {
|
|
48693
50070
|
if (error62.code !== "ENOENT") throw error62;
|
|
48694
50071
|
}
|
|
48695
|
-
if (
|
|
50072
|
+
if (path25.dirname(current2) === current2) break;
|
|
48696
50073
|
}
|
|
48697
50074
|
if (initialize) await mkdir11(absolute2, { recursive: true, mode: 448 });
|
|
48698
|
-
if (!(await
|
|
50075
|
+
if (!(await lstat11(absolute2)).isDirectory() || (await realpath9(absolute2)).toLowerCase() !== absolute2.toLowerCase())
|
|
48699
50076
|
throw Error("FABRIC_DIRECTORY_INVALID");
|
|
48700
50077
|
const present = /* @__PURE__ */ new Set();
|
|
48701
50078
|
for (const name2 of ["binding.json", "mailbox.json", "identities.json"]) {
|
|
48702
|
-
const file2 = await
|
|
50079
|
+
const file2 = await lstat11(path25.join(absolute2, name2)).catch((error62) => {
|
|
48703
50080
|
if (error62.code === "ENOENT") return null;
|
|
48704
50081
|
throw error62;
|
|
48705
50082
|
});
|
|
@@ -48707,7 +50084,7 @@ var AgentFabricService = class _AgentFabricService {
|
|
|
48707
50084
|
if (file2) present.add(name2);
|
|
48708
50085
|
}
|
|
48709
50086
|
if (!present.has("binding.json") && present.size) throw Error("FABRIC_BINDING_MISSING");
|
|
48710
|
-
const binding2 = new FabricStateFile(
|
|
50087
|
+
const binding2 = new FabricStateFile(path25.join(absolute2, "binding.json"), 2048, (value) => Binding.parse(value));
|
|
48711
50088
|
const service2 = new _AgentFabricService(absolute2, controllerId);
|
|
48712
50089
|
await binding2.update(async (state) => {
|
|
48713
50090
|
if (state.controllerId !== expected.controllerId || JSON.stringify(state.device) !== JSON.stringify(expected.device))
|
|
@@ -48722,7 +50099,7 @@ var AgentFabricService = class _AgentFabricService {
|
|
|
48722
50099
|
state.initialized = true;
|
|
48723
50100
|
}
|
|
48724
50101
|
const snapshot2 = await service2.mailbox.snapshot();
|
|
48725
|
-
if (snapshot2.workers.some((worker) => worker.runtimeId !== null)) await
|
|
50102
|
+
if (snapshot2.workers.some((worker) => worker.runtimeId !== null)) await lstat11(path25.join(absolute2, "identities.json"));
|
|
48726
50103
|
}, initialize ? () => expected : void 0);
|
|
48727
50104
|
return service2;
|
|
48728
50105
|
}
|
|
@@ -48809,19 +50186,19 @@ var Delivery = external_exports.strictObject({ capability: external_exports.stri
|
|
|
48809
50186
|
async function openNativeFabric(stateDirectory, enrollment, box, initialize = true) {
|
|
48810
50187
|
const controllerId = "device-" + external_exports.string().uuid().parse(enrollment.deviceId).toLowerCase();
|
|
48811
50188
|
const tenantId = external_exports.string().uuid().parse(enrollment.tenantId).toLowerCase();
|
|
48812
|
-
const parent =
|
|
50189
|
+
const parent = path26.join(stateDirectory, ".local-commander"), marker = path26.join(parent, "fabric-established.json");
|
|
48813
50190
|
try {
|
|
48814
50191
|
await mkdir12(parent, { mode: 448 });
|
|
48815
50192
|
} catch (error62) {
|
|
48816
50193
|
if (error62.code !== "EEXIST") throw error62;
|
|
48817
50194
|
}
|
|
48818
|
-
const parentInfo = await
|
|
50195
|
+
const parentInfo = await lstat12(parent);
|
|
48819
50196
|
if (!parentInfo.isDirectory() || parentInfo.isSymbolicLink()) throw Error("FABRIC_DIRECTORY_INVALID");
|
|
48820
50197
|
const expected = JSON.stringify({ version: 1, controllerId, tenantId });
|
|
48821
50198
|
let fresh = false;
|
|
48822
50199
|
try {
|
|
48823
|
-
const info = await
|
|
48824
|
-
if (!info.isFile() || info.isSymbolicLink() || info.size > 2048 || await
|
|
50200
|
+
const info = await lstat12(marker);
|
|
50201
|
+
if (!info.isFile() || info.isSymbolicLink() || info.size > 2048 || await readFile10(marker, "utf8") !== expected)
|
|
48825
50202
|
throw Error("FABRIC_BINDING_CHANGED");
|
|
48826
50203
|
} catch (error62) {
|
|
48827
50204
|
if (error62.code !== "ENOENT" || !initialize) throw error62;
|
|
@@ -48835,22 +50212,22 @@ async function openNativeFabric(stateDirectory, enrollment, box, initialize = tr
|
|
|
48835
50212
|
fresh = true;
|
|
48836
50213
|
}
|
|
48837
50214
|
const service2 = await AgentFabricService.open(
|
|
48838
|
-
|
|
50215
|
+
path26.join(stateDirectory, ".local-commander", "fabric"),
|
|
48839
50216
|
controllerId,
|
|
48840
50217
|
{ deviceId: enrollment.deviceId.toLowerCase(), enrollmentEvidenceRef: "enrollment-" + tenantId },
|
|
48841
50218
|
fresh
|
|
48842
50219
|
);
|
|
48843
50220
|
const purpose = "native-fabric:" + tenantId + ":" + controllerId;
|
|
48844
|
-
const credentialFile = (workerId) =>
|
|
50221
|
+
const credentialFile = (workerId) => path26.join(service2.directory, external_exports.string().uuid().parse(workerId) + ".capability");
|
|
48845
50222
|
const decode4 = (value) => {
|
|
48846
50223
|
const credential = Credential.parse(JSON.parse(box.open(Buffer.from(value, "base64"), purpose).toString("utf8")));
|
|
48847
50224
|
if (credential.controllerId !== controllerId) throw Error("FABRIC_WORKER_DENIED");
|
|
48848
50225
|
return credential;
|
|
48849
50226
|
};
|
|
48850
50227
|
async function capability(workerId) {
|
|
48851
|
-
const file2 = credentialFile(workerId), info = await
|
|
50228
|
+
const file2 = credentialFile(workerId), info = await lstat12(file2);
|
|
48852
50229
|
if (!info.isFile() || info.isSymbolicLink() || info.size > 4096) throw Error("FABRIC_CREDENTIAL_UNKNOWN");
|
|
48853
|
-
const encoded = await
|
|
50230
|
+
const encoded = await readFile10(file2, "utf8");
|
|
48854
50231
|
if (decode4(encoded).workerId !== workerId) throw Error("FABRIC_WORKER_DENIED");
|
|
48855
50232
|
return encoded;
|
|
48856
50233
|
}
|
|
@@ -48942,7 +50319,7 @@ async function readFabricRequest(input2 = process.stdin) {
|
|
|
48942
50319
|
|
|
48943
50320
|
// agent/src/supervisor-liveness.ts
|
|
48944
50321
|
import { spawn as spawn6 } from "node:child_process";
|
|
48945
|
-
import
|
|
50322
|
+
import path27 from "node:path";
|
|
48946
50323
|
import { setTimeout as delay3 } from "node:timers/promises";
|
|
48947
50324
|
var ROW = /^"([^"]+)","(\d{1,10})"/;
|
|
48948
50325
|
function parseTasklist(output2, image) {
|
|
@@ -48957,7 +50334,7 @@ function parseTasklist(output2, image) {
|
|
|
48957
50334
|
}
|
|
48958
50335
|
function listProcesses(image, timeoutMs2 = 5e3) {
|
|
48959
50336
|
if (process.platform !== "win32" || !/^[A-Za-z0-9._-]{1,64}\.exe$/i.test(image)) return Promise.resolve(null);
|
|
48960
|
-
const tasklist =
|
|
50337
|
+
const tasklist = path27.join(process.env.SystemRoot || "C:\\Windows", "System32", "tasklist.exe");
|
|
48961
50338
|
return new Promise((resolve) => {
|
|
48962
50339
|
let output2 = "", settled = false;
|
|
48963
50340
|
const finish = (value) => {
|
|
@@ -48986,8 +50363,8 @@ function listProcesses(image, timeoutMs2 = 5e3) {
|
|
|
48986
50363
|
}
|
|
48987
50364
|
function supervisorLiveness(helperPath, options = {}) {
|
|
48988
50365
|
if (process.platform === "linux" && !options.list) return linuxSupervisorLiveness;
|
|
48989
|
-
if (process.platform === "darwin" && !options.list) return (pids, _linux, darwin) => darwinSupervisorLiveness(
|
|
48990
|
-
const image =
|
|
50366
|
+
if (process.platform === "darwin" && !options.list) return (pids, _linux, darwin) => darwinSupervisorLiveness(path27.join(path27.dirname(helperPath), "posix-host"), pids, darwin);
|
|
50367
|
+
const image = path27.basename(helperPath), waitMs = options.waitMs ?? 1e4, pollMs = options.pollMs ?? 500, list = options.list ?? listProcesses;
|
|
48991
50368
|
return async (pids) => {
|
|
48992
50369
|
const deadline = Date.now() + waitMs;
|
|
48993
50370
|
for (; ; ) {
|
|
@@ -49002,14 +50379,14 @@ function supervisorLiveness(helperPath, options = {}) {
|
|
|
49002
50379
|
|
|
49003
50380
|
// agent/src/content-audit.ts
|
|
49004
50381
|
import { createReadStream } from "node:fs";
|
|
49005
|
-
import { appendFile, lstat as
|
|
49006
|
-
import
|
|
50382
|
+
import { appendFile, lstat as lstat13, mkdir as mkdir13, open as open12, readdir as readdir6, readFile as readFile11, rename as rename8, rm as rm9, writeFile as writeFile4 } from "node:fs/promises";
|
|
50383
|
+
import path28 from "node:path";
|
|
49007
50384
|
import { performance as performance3 } from "node:perf_hooks";
|
|
49008
50385
|
import { createInterface as createInterface2 } from "node:readline";
|
|
49009
|
-
import { randomBytes as
|
|
50386
|
+
import { randomBytes as randomBytes10 } from "node:crypto";
|
|
49010
50387
|
|
|
49011
50388
|
// src/audit-crypto.ts
|
|
49012
|
-
import { createCipheriv as createCipheriv3, createDecipheriv as createDecipheriv3, createHash as createHash20, randomBytes as
|
|
50389
|
+
import { createCipheriv as createCipheriv3, createDecipheriv as createDecipheriv3, createHash as createHash20, randomBytes as randomBytes9 } from "node:crypto";
|
|
49013
50390
|
import { promisify as promisify3 } from "node:util";
|
|
49014
50391
|
import { gunzipSync, gzip, gzipSync } from "node:zlib";
|
|
49015
50392
|
var gzipAsync = promisify3(gzip);
|
|
@@ -49061,7 +50438,7 @@ async function encryptAuditRecordAsync(record2, keyInput, keyId2) {
|
|
|
49061
50438
|
function sealCompressed(compressed, keyInput, keyId2) {
|
|
49062
50439
|
const key = parseAuditRecoveryKey(keyInput);
|
|
49063
50440
|
const kid = keyId2?.trim() || auditRecoveryKeyId(key);
|
|
49064
|
-
const iv =
|
|
50441
|
+
const iv = randomBytes9(IV_BYTES);
|
|
49065
50442
|
try {
|
|
49066
50443
|
const cipher = createCipheriv3("aes-256-gcm", key, iv, { authTagLength: TAG_BYTES });
|
|
49067
50444
|
cipher.setAAD(additionalData(kid));
|
|
@@ -49172,17 +50549,17 @@ var FILE = /^(full|metrics)-(\d{4}-\d{2}-\d{2})\.jsonl$/;
|
|
|
49172
50549
|
var PAUSED_FILE = "paused.json";
|
|
49173
50550
|
var DAY_MS = 864e5;
|
|
49174
50551
|
function contentAuditDirectory(stateDir) {
|
|
49175
|
-
return
|
|
50552
|
+
return path28.join(path28.dirname(path28.resolve(stateDir)), "Audit");
|
|
49176
50553
|
}
|
|
49177
50554
|
async function plainDirectory(dir) {
|
|
49178
50555
|
await mkdir13(dir, { recursive: true, mode: 448 });
|
|
49179
|
-
const info = await
|
|
50556
|
+
const info = await lstat13(dir);
|
|
49180
50557
|
if (info.isSymbolicLink() || !info.isDirectory()) throw Error("AUDIT_DIRECTORY_INVALID");
|
|
49181
50558
|
}
|
|
49182
50559
|
async function auditFiles(dir) {
|
|
49183
50560
|
let names;
|
|
49184
50561
|
try {
|
|
49185
|
-
names = await
|
|
50562
|
+
names = await readdir6(dir);
|
|
49186
50563
|
} catch (error62) {
|
|
49187
50564
|
if (error62.code === "ENOENT") return [];
|
|
49188
50565
|
throw error62;
|
|
@@ -49191,18 +50568,18 @@ async function auditFiles(dir) {
|
|
|
49191
50568
|
for (const name2 of names) {
|
|
49192
50569
|
const match = FILE.exec(name2);
|
|
49193
50570
|
if (!match) continue;
|
|
49194
|
-
const info = await
|
|
50571
|
+
const info = await lstat13(path28.join(dir, name2));
|
|
49195
50572
|
if (info.isFile()) files.push({ name: name2, kind: match[1], day: match[2], bytes: info.size });
|
|
49196
50573
|
}
|
|
49197
50574
|
return files.sort((a, b) => a.name.localeCompare(b.name));
|
|
49198
50575
|
}
|
|
49199
50576
|
async function writeJsonAtomic(file2, value) {
|
|
49200
|
-
const temp = `${file2}.${
|
|
50577
|
+
const temp = `${file2}.${randomBytes10(6).toString("hex")}.tmp`;
|
|
49201
50578
|
try {
|
|
49202
50579
|
await writeFile4(temp, JSON.stringify(value) + "\n", { flag: "wx", mode: 384 });
|
|
49203
50580
|
await rename8(temp, file2);
|
|
49204
50581
|
} finally {
|
|
49205
|
-
await
|
|
50582
|
+
await rm9(temp, { force: true }).catch(() => {
|
|
49206
50583
|
});
|
|
49207
50584
|
}
|
|
49208
50585
|
}
|
|
@@ -49229,7 +50606,7 @@ var ContentAudit = class _ContentAudit {
|
|
|
49229
50606
|
skipped = 0;
|
|
49230
50607
|
closed = false;
|
|
49231
50608
|
static async open(options) {
|
|
49232
|
-
const dir =
|
|
50609
|
+
const dir = path28.resolve(options.directory);
|
|
49233
50610
|
await plainDirectory(dir);
|
|
49234
50611
|
const audit = new _ContentAudit(
|
|
49235
50612
|
dir,
|
|
@@ -49238,7 +50615,7 @@ var ContentAudit = class _ContentAudit {
|
|
|
49238
50615
|
{ retentionDays: options.retentionDays ?? AUDIT_RETENTION_DAYS, maxBytes: options.maxBytes ?? AUDIT_MAX_BYTES },
|
|
49239
50616
|
options.now ?? (() => /* @__PURE__ */ new Date())
|
|
49240
50617
|
);
|
|
49241
|
-
await
|
|
50618
|
+
await rm9(path28.join(dir, PAUSED_FILE), { force: true });
|
|
49242
50619
|
await audit.rollover(audit.now());
|
|
49243
50620
|
if (audit.usedBytes >= audit.limits.maxBytes) await audit.pause("QUOTA_EXCEEDED");
|
|
49244
50621
|
return audit;
|
|
@@ -49308,8 +50685,8 @@ var ContentAudit = class _ContentAudit {
|
|
|
49308
50685
|
await this.pause("QUOTA_EXCEEDED");
|
|
49309
50686
|
return;
|
|
49310
50687
|
}
|
|
49311
|
-
await appendFile(
|
|
49312
|
-
await appendFile(
|
|
50688
|
+
await appendFile(path28.join(this.dir, `full-${day}.jsonl`), line, { mode: 384 });
|
|
50689
|
+
await appendFile(path28.join(this.dir, `metrics-${day}.jsonl`), metrics, { mode: 384 });
|
|
49313
50690
|
this.usedBytes += bytes3;
|
|
49314
50691
|
}
|
|
49315
50692
|
/** Daily retention runs on the first write of a new day; no timer or background scan. */
|
|
@@ -49318,7 +50695,7 @@ var ContentAudit = class _ContentAudit {
|
|
|
49318
50695
|
const cutoff = new Date(at.getTime() - this.limits.retentionDays * DAY_MS).toISOString().slice(0, 10);
|
|
49319
50696
|
let used = 0;
|
|
49320
50697
|
for (const file2 of await auditFiles(this.dir)) {
|
|
49321
|
-
if (file2.day <= cutoff) await
|
|
50698
|
+
if (file2.day <= cutoff) await rm9(path28.join(this.dir, file2.name), { force: true });
|
|
49322
50699
|
else used += file2.bytes;
|
|
49323
50700
|
}
|
|
49324
50701
|
this.usedBytes = used;
|
|
@@ -49326,7 +50703,7 @@ var ContentAudit = class _ContentAudit {
|
|
|
49326
50703
|
async pause(reason) {
|
|
49327
50704
|
if (this.paused) return;
|
|
49328
50705
|
this.paused = reason;
|
|
49329
|
-
await writeJsonAtomic(
|
|
50706
|
+
await writeJsonAtomic(path28.join(this.dir, PAUSED_FILE), { reason, at: this.now().toISOString() });
|
|
49330
50707
|
}
|
|
49331
50708
|
};
|
|
49332
50709
|
function percentiles(values) {
|
|
@@ -49348,13 +50725,13 @@ async function* jsonLines(file2) {
|
|
|
49348
50725
|
}
|
|
49349
50726
|
var count2 = (value) => typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : 0;
|
|
49350
50727
|
async function summarizeContentAudit(directory, key) {
|
|
49351
|
-
const dir =
|
|
50728
|
+
const dir = path28.resolve(directory);
|
|
49352
50729
|
const files = await auditFiles(dir);
|
|
49353
50730
|
const days = /* @__PURE__ */ new Map();
|
|
49354
50731
|
const sizes = [];
|
|
49355
50732
|
const timings = [];
|
|
49356
50733
|
for (const file2 of files.filter((f) => f.kind === "metrics")) {
|
|
49357
|
-
for await (const line of jsonLines(
|
|
50734
|
+
for await (const line of jsonLines(path28.join(dir, file2.name))) {
|
|
49358
50735
|
let day = days.get(file2.day);
|
|
49359
50736
|
if (!day) {
|
|
49360
50737
|
day = { day: file2.day, records: 0, failed: 0, rawBytes: 0, sanitizedBytes: 0, compressedBytes: 0, envelopeBytes: 0 };
|
|
@@ -49374,7 +50751,7 @@ async function summarizeContentAudit(directory, key) {
|
|
|
49374
50751
|
}
|
|
49375
50752
|
let paused = null;
|
|
49376
50753
|
try {
|
|
49377
|
-
const value = JSON.parse(await
|
|
50754
|
+
const value = JSON.parse(await readFile11(path28.join(dir, PAUSED_FILE), "utf8"));
|
|
49378
50755
|
if (typeof value.reason === "string" && typeof value.at === "string") paused = { reason: value.reason.slice(0, 40), at: value.at.slice(0, 40) };
|
|
49379
50756
|
} catch {
|
|
49380
50757
|
}
|
|
@@ -49382,7 +50759,7 @@ async function summarizeContentAudit(directory, key) {
|
|
|
49382
50759
|
const newest = files.filter((f) => f.kind === "full").at(-1);
|
|
49383
50760
|
if (key && newest) {
|
|
49384
50761
|
const tail = [];
|
|
49385
|
-
for await (const line of jsonLines(
|
|
50762
|
+
for await (const line of jsonLines(path28.join(dir, newest.name))) {
|
|
49386
50763
|
tail.push(line);
|
|
49387
50764
|
if (tail.length > 5) tail.shift();
|
|
49388
50765
|
}
|
|
@@ -49416,10 +50793,10 @@ async function summarizeContentAudit(directory, key) {
|
|
|
49416
50793
|
};
|
|
49417
50794
|
}
|
|
49418
50795
|
async function restoreContentAudit(input2, output2, key) {
|
|
49419
|
-
const handle = await open12(
|
|
50796
|
+
const handle = await open12(path28.resolve(output2), "wx", 384);
|
|
49420
50797
|
let records = 0, failed = 0;
|
|
49421
50798
|
try {
|
|
49422
|
-
for await (const line of jsonLines(
|
|
50799
|
+
for await (const line of jsonLines(path28.resolve(input2))) {
|
|
49423
50800
|
try {
|
|
49424
50801
|
await handle.appendFile(JSON.stringify(decryptAuditRecord(line, key)) + "\n");
|
|
49425
50802
|
records += 1;
|
|
@@ -49434,7 +50811,7 @@ async function restoreContentAudit(input2, output2, key) {
|
|
|
49434
50811
|
}
|
|
49435
50812
|
|
|
49436
50813
|
// agent/src/main.ts
|
|
49437
|
-
var AGENT_VERSION2 = true ? "0.3.
|
|
50814
|
+
var AGENT_VERSION2 = true ? "0.3.47" : "0.3.2";
|
|
49438
50815
|
var NETWORK_PUBLIC_KEY = true ? "-----BEGIN PUBLIC KEY-----\nMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAvmu+81vWtJBQDZNHcAIW\nzCSxpG+R9RBsum2df5mP2cOW+wyUDTpnYquFge1qgI5YYTF96j0xCyXL8B9FeNWs\n939opWNmv53j+CQlS4cEIQhBbZSCu0eC4icsVEzBhvf68MB+E668SOtZBcVTEnyh\n96PTcupxS10rQJBWDinbKBXRC2gvGYeu01rWa/nsrndy4vAYP5t3yQtdOC8e8mr0\n+2Mg2Qhiq+KiTCtDd+L9oXvoLqqJYbzUIveNGha25AWxF1Weblp0gOM87hell5gV\nK7q4ZLUq/wBRGYNmQRdLyV7/WRE1FFPSW21/SBZQ/5aU4UqJU/MjMcrJUrnRKngz\nYKmo0czkxS3N7Q2KVxomgR1AQSuQFKMrboZYKjShADp9RIYUxzs7cYg51Of5PnHh\n6Ax+VevDGfzjMD+yHuyxYZqCtX4OwgolJxz63UQbzKlris+8xb5lLYTbIuz90Pss\nn6HK/F5May25c6oMmS3nh/NsiZopL1OvdtWKTt1L4WlRAgMBAAE=\n-----END PUBLIC KEY-----\n" : "";
|
|
49439
50816
|
var AI_CONNECTION_SHIPPED = false;
|
|
49440
50817
|
function processAlive(pid) {
|
|
@@ -49448,7 +50825,7 @@ function processAlive(pid) {
|
|
|
49448
50825
|
}
|
|
49449
50826
|
async function claimAgentProcess(stateDir, runtimeDir, version2) {
|
|
49450
50827
|
await mkdir14(stateDir, { recursive: true });
|
|
49451
|
-
const file2 =
|
|
50828
|
+
const file2 = path29.join(stateDir, "agent-process.json");
|
|
49452
50829
|
for (let attempt = 0; attempt < 2; attempt += 1) {
|
|
49453
50830
|
try {
|
|
49454
50831
|
const handle = await open13(file2, "wx", 384);
|
|
@@ -49459,8 +50836,8 @@ async function claimAgentProcess(stateDir, runtimeDir, version2) {
|
|
|
49459
50836
|
}
|
|
49460
50837
|
return async () => {
|
|
49461
50838
|
try {
|
|
49462
|
-
const current2 = JSON.parse(await
|
|
49463
|
-
if (current2.pid === process.pid) await
|
|
50839
|
+
const current2 = JSON.parse(await readFile12(file2, "utf8"));
|
|
50840
|
+
if (current2.pid === process.pid) await rm10(file2, { force: true });
|
|
49464
50841
|
} catch {
|
|
49465
50842
|
}
|
|
49466
50843
|
};
|
|
@@ -49468,12 +50845,12 @@ async function claimAgentProcess(stateDir, runtimeDir, version2) {
|
|
|
49468
50845
|
if (!error62 || typeof error62 !== "object" || !("code" in error62) || error62.code !== "EEXIST") throw error62;
|
|
49469
50846
|
let stale = true;
|
|
49470
50847
|
try {
|
|
49471
|
-
const current2 = JSON.parse(await
|
|
50848
|
+
const current2 = JSON.parse(await readFile12(file2, "utf8"));
|
|
49472
50849
|
stale = typeof current2.pid !== "number" || !processAlive(current2.pid);
|
|
49473
50850
|
} catch {
|
|
49474
50851
|
}
|
|
49475
50852
|
if (!stale) throw Error("AGENT_ALREADY_RUNNING");
|
|
49476
|
-
await
|
|
50853
|
+
await rm10(file2, { force: true });
|
|
49477
50854
|
}
|
|
49478
50855
|
}
|
|
49479
50856
|
throw Error("AGENT_ALREADY_RUNNING");
|
|
@@ -49724,10 +51101,10 @@ async function openContentAudit(store, stateDir) {
|
|
|
49724
51101
|
async function main() {
|
|
49725
51102
|
if (!["win32", "linux", "darwin"].includes(process.platform)) throw Error("PLATFORM_UNSUPPORTED");
|
|
49726
51103
|
const appData = process.env.LC_AGENT_DATA_DIR ?? (process.platform === "win32" ? process.env.LOCALAPPDATA : posixDataHome());
|
|
49727
|
-
if (!appData || !
|
|
49728
|
-
const stateDir = process.env.LC_AGENT_STATE_DIR ??
|
|
49729
|
-
const binaryDir =
|
|
49730
|
-
const ownerBridgePath = process.env.LC_OWNER_BRIDGE ??
|
|
51104
|
+
if (!appData || !path29.isAbsolute(appData)) throw Error("APP_DATA_MISSING");
|
|
51105
|
+
const stateDir = process.env.LC_AGENT_STATE_DIR ?? path29.join(appData, "LocalCommander", "Agent");
|
|
51106
|
+
const binaryDir = path29.dirname(process.platform === "win32" ? process.execPath : await realpath10(process.execPath));
|
|
51107
|
+
const ownerBridgePath = process.env.LC_OWNER_BRIDGE ?? path29.join(binaryDir, process.platform === "win32" ? "OwnerBridge.exe" : "owner-store");
|
|
49731
51108
|
const store = await WindowsPrivateStore.open(stateDir, ownerBridgePath);
|
|
49732
51109
|
const command = process.argv[2] ?? "run";
|
|
49733
51110
|
if (process.platform !== "win32" && (command.startsWith("guard-") || command.startsWith("network-"))) throw Error("FEATURE_PLATFORM_UNSUPPORTED");
|
|
@@ -49737,7 +51114,7 @@ async function main() {
|
|
|
49737
51114
|
const pairing = new PairingClient(store, { controlPlaneOrigin: origin, agentVersion: AGENT_VERSION2 });
|
|
49738
51115
|
const begun = await pairing.begin();
|
|
49739
51116
|
process.stdout.write(JSON.stringify({ approvalUrl: begun.approvalUrl, confirmationCode: begun.confirmationCode, expiresAt: begun.expiresAt.toISOString() }) + "\n");
|
|
49740
|
-
await pairing.waitAndComplete(begun,
|
|
51117
|
+
await pairing.waitAndComplete(begun, os8.hostname().slice(0, 120));
|
|
49741
51118
|
process.stdout.write("DEVICE_PAIRED\n");
|
|
49742
51119
|
return;
|
|
49743
51120
|
}
|
|
@@ -49822,7 +51199,7 @@ async function main() {
|
|
|
49822
51199
|
}
|
|
49823
51200
|
if (command === "efficiency-report") {
|
|
49824
51201
|
if (args.length) throw Error("AGENT_COMMAND_INVALID");
|
|
49825
|
-
const ledger = await OptimizationLedger.open(
|
|
51202
|
+
const ledger = await OptimizationLedger.open(path29.join(stateDir, "optimization"));
|
|
49826
51203
|
try {
|
|
49827
51204
|
process.stdout.write(JSON.stringify(await ledger.report(), null, 2) + "\n");
|
|
49828
51205
|
} finally {
|
|
@@ -49832,7 +51209,7 @@ async function main() {
|
|
|
49832
51209
|
}
|
|
49833
51210
|
if (command === "guard-configure") {
|
|
49834
51211
|
if (args.length !== 1) throw Error("AGENT_COMMAND_INVALID");
|
|
49835
|
-
const filename = await (await import("node:fs/promises")).realpath(
|
|
51212
|
+
const filename = await (await import("node:fs/promises")).realpath(path29.resolve(args[0]));
|
|
49836
51213
|
const input2 = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(await readWindowsFile(ownerBridgePath, filename, 2e5)));
|
|
49837
51214
|
if (!input2 || typeof input2 !== "object" || Object.keys(input2).sort().join(",") !== "compact,settings") throw Error("GUARD_CONFIGURATION_INVALID");
|
|
49838
51215
|
await store.configureGuard(input2.settings, input2.compact);
|
|
@@ -49851,7 +51228,7 @@ async function main() {
|
|
|
49851
51228
|
}
|
|
49852
51229
|
if (command === "guard-evidence") {
|
|
49853
51230
|
if (args.length) throw Error("AGENT_COMMAND_INVALID");
|
|
49854
|
-
const journal = await NativeJournal.open(
|
|
51231
|
+
const journal = await NativeJournal.open(path29.join(stateDir, "journal"), new SecretBox({ "1": await store.loadDataKey() }));
|
|
49855
51232
|
try {
|
|
49856
51233
|
process.stdout.write(JSON.stringify(await journal.guardEvidence()) + "\n");
|
|
49857
51234
|
} finally {
|
|
@@ -49863,7 +51240,7 @@ async function main() {
|
|
|
49863
51240
|
if (args.length !== (command === "guard-export" ? 0 : 1)) throw Error("AGENT_COMMAND_INVALID");
|
|
49864
51241
|
const identity = await store.load();
|
|
49865
51242
|
if (!identity?.enrollment) throw Error("ENROLLMENT_MISSING");
|
|
49866
|
-
const journal = await NativeJournal.open(
|
|
51243
|
+
const journal = await NativeJournal.open(path29.join(stateDir, "journal"), new SecretBox({ "1": await store.loadDataKey() }));
|
|
49867
51244
|
try {
|
|
49868
51245
|
const { tenantId, deviceId } = identity.enrollment;
|
|
49869
51246
|
const records = (await journal.guardEvidence()).filter((record2) => record2.tenantId === tenantId && record2.deviceId === deviceId);
|
|
@@ -49941,27 +51318,27 @@ async function main() {
|
|
|
49941
51318
|
if (args.length) throw Error("AGENT_COMMAND_INVALID");
|
|
49942
51319
|
if (!(await store.load())?.enrollment) throw Error("ENROLLMENT_MISSING");
|
|
49943
51320
|
const releaseProcess = await claimAgentProcess(stateDir, binaryDir, AGENT_VERSION2);
|
|
49944
|
-
const monitor = new ProductionMonitor(
|
|
51321
|
+
const monitor = new ProductionMonitor(path29.join(appData, "LocalCommander", "Monitor"), stateDir, AGENT_VERSION2);
|
|
49945
51322
|
const publishMonitor = () => monitor.flush().catch(() => {
|
|
49946
51323
|
process.stderr.write("MONITOR_WRITE_FAILED\n");
|
|
49947
51324
|
});
|
|
49948
51325
|
await publishMonitor();
|
|
49949
51326
|
try {
|
|
49950
51327
|
const journal = await NativeJournal.open(
|
|
49951
|
-
|
|
51328
|
+
path29.join(stateDir, "journal"),
|
|
49952
51329
|
new SecretBox({ "1": await store.loadDataKey() }),
|
|
49953
|
-
process.platform === "win32" ? {} : { lockHelper:
|
|
51330
|
+
process.platform === "win32" ? {} : { lockHelper: path29.join(binaryDir, "posix-host") }
|
|
49954
51331
|
);
|
|
49955
51332
|
const ledgerLoss = () => {
|
|
49956
51333
|
process.stderr.write("OPTIMIZATION_TELEMETRY_INCOMPLETE\n");
|
|
49957
51334
|
};
|
|
49958
51335
|
const efficiencyLedger = await new OptionalWork(ledgerLoss, 1e3, 1).run(
|
|
49959
|
-
() => OptimizationLedger.open(
|
|
51336
|
+
() => OptimizationLedger.open(path29.join(stateDir, "optimization")),
|
|
49960
51337
|
void 0,
|
|
49961
51338
|
(ledger) => ledger.close()
|
|
49962
51339
|
);
|
|
49963
51340
|
try {
|
|
49964
|
-
const helperPath = process.env.LC_JOB_HOST ??
|
|
51341
|
+
const helperPath = process.env.LC_JOB_HOST ?? path29.join(binaryDir, process.platform === "win32" ? "JobHost.exe" : "job-host.mjs");
|
|
49965
51342
|
const tools = new NativeTools({ stateDirectory: stateDir, helperPath, ownerBridgePath, programs: await store.loadPrograms() });
|
|
49966
51343
|
const stop = new AbortController();
|
|
49967
51344
|
process.once("SIGINT", () => stop.abort());
|
|
@@ -50032,7 +51409,7 @@ async function main() {
|
|
|
50032
51409
|
await releaseProcess();
|
|
50033
51410
|
}
|
|
50034
51411
|
}
|
|
50035
|
-
var entrypoint = process.argv[1] && (process.platform === "win32" ?
|
|
51412
|
+
var entrypoint = process.argv[1] && (process.platform === "win32" ? path29.resolve(process.argv[1]) : await realpath10(process.argv[1]).catch(() => null));
|
|
50036
51413
|
if (entrypoint === fileURLToPath(import.meta.url)) {
|
|
50037
51414
|
void main().catch((error62) => {
|
|
50038
51415
|
const code = error62 instanceof Error && /^[A-Z0-9_]{1,64}$/.test(error62.message) ? error62.message : "AGENT_START_FAILED";
|