local-commander-agent-linux-arm64 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/package.json +1 -1
- package/runtime/agent.mjs +1717 -340
- package/runtime/lifecycle.mjs +14 -1
- package/runtime/manifest.json +5 -5
- package/runtime/node +0 -0
- package/runtime/posix-host +0 -0
package/runtime/agent.mjs
CHANGED
|
@@ -2138,7 +2138,7 @@ var require_extension = __commonJS({
|
|
|
2138
2138
|
if (dest[name2] === void 0) dest[name2] = [elem];
|
|
2139
2139
|
else dest[name2].push(elem);
|
|
2140
2140
|
}
|
|
2141
|
-
function
|
|
2141
|
+
function parse4(header) {
|
|
2142
2142
|
const offers = /* @__PURE__ */ Object.create(null);
|
|
2143
2143
|
let params = /* @__PURE__ */ Object.create(null);
|
|
2144
2144
|
let mustUnescape = false;
|
|
@@ -2278,7 +2278,7 @@ var require_extension = __commonJS({
|
|
|
2278
2278
|
}).join(", ");
|
|
2279
2279
|
}).join(", ");
|
|
2280
2280
|
}
|
|
2281
|
-
module.exports = { format, parse:
|
|
2281
|
+
module.exports = { format, parse: parse4 };
|
|
2282
2282
|
}
|
|
2283
2283
|
});
|
|
2284
2284
|
|
|
@@ -2289,9 +2289,9 @@ var require_websocket = __commonJS({
|
|
|
2289
2289
|
var EventEmitter = __require("events");
|
|
2290
2290
|
var https2 = __require("https");
|
|
2291
2291
|
var http2 = __require("http");
|
|
2292
|
-
var
|
|
2292
|
+
var net3 = __require("net");
|
|
2293
2293
|
var tls2 = __require("tls");
|
|
2294
|
-
var { randomBytes:
|
|
2294
|
+
var { randomBytes: randomBytes11, createHash: createHash21 } = __require("crypto");
|
|
2295
2295
|
var { Duplex, Readable } = __require("stream");
|
|
2296
2296
|
var { URL: URL2 } = __require("url");
|
|
2297
2297
|
var PerMessageDeflate2 = require_permessage_deflate();
|
|
@@ -2312,7 +2312,7 @@ var require_websocket = __commonJS({
|
|
|
2312
2312
|
var {
|
|
2313
2313
|
EventTarget: { addEventListener, removeEventListener }
|
|
2314
2314
|
} = require_event_target();
|
|
2315
|
-
var { format, parse:
|
|
2315
|
+
var { format, parse: parse4 } = require_extension();
|
|
2316
2316
|
var { toBuffer } = require_buffer_util();
|
|
2317
2317
|
var kAborted = /* @__PURE__ */ Symbol("kAborted");
|
|
2318
2318
|
var protocolVersions = [8, 13];
|
|
@@ -2842,7 +2842,7 @@ var require_websocket = __commonJS({
|
|
|
2842
2842
|
}
|
|
2843
2843
|
}
|
|
2844
2844
|
const defaultPort = isSecure ? 443 : 80;
|
|
2845
|
-
const key =
|
|
2845
|
+
const key = randomBytes11(16).toString("base64");
|
|
2846
2846
|
const request = isSecure ? https2.request : http2.request;
|
|
2847
2847
|
const protocolSet = /* @__PURE__ */ new Set();
|
|
2848
2848
|
let perMessageDeflate;
|
|
@@ -3002,7 +3002,7 @@ var require_websocket = __commonJS({
|
|
|
3002
3002
|
}
|
|
3003
3003
|
let extensions;
|
|
3004
3004
|
try {
|
|
3005
|
-
extensions =
|
|
3005
|
+
extensions = parse4(secWebSocketExtensions);
|
|
3006
3006
|
} catch (err) {
|
|
3007
3007
|
const message2 = "Invalid Sec-WebSocket-Extensions header";
|
|
3008
3008
|
abortHandshake(websocket, socket, message2);
|
|
@@ -3046,12 +3046,12 @@ var require_websocket = __commonJS({
|
|
|
3046
3046
|
}
|
|
3047
3047
|
function netConnect2(options) {
|
|
3048
3048
|
options.path = options.socketPath;
|
|
3049
|
-
return
|
|
3049
|
+
return net3.connect(options);
|
|
3050
3050
|
}
|
|
3051
3051
|
function tlsConnect(options) {
|
|
3052
3052
|
options.path = void 0;
|
|
3053
3053
|
if (!options.servername && options.servername !== "") {
|
|
3054
|
-
options.servername =
|
|
3054
|
+
options.servername = net3.isIP(options.host) ? "" : options.host;
|
|
3055
3055
|
}
|
|
3056
3056
|
return tls2.connect(options);
|
|
3057
3057
|
}
|
|
@@ -3294,7 +3294,7 @@ var require_subprotocol = __commonJS({
|
|
|
3294
3294
|
"node_modules/ws/lib/subprotocol.js"(exports, module) {
|
|
3295
3295
|
"use strict";
|
|
3296
3296
|
var { tokenChars } = require_validation();
|
|
3297
|
-
function
|
|
3297
|
+
function parse4(header) {
|
|
3298
3298
|
const protocols = /* @__PURE__ */ new Set();
|
|
3299
3299
|
let start = -1;
|
|
3300
3300
|
let end = -1;
|
|
@@ -3330,7 +3330,7 @@ var require_subprotocol = __commonJS({
|
|
|
3330
3330
|
protocols.add(protocol2);
|
|
3331
3331
|
return protocols;
|
|
3332
3332
|
}
|
|
3333
|
-
module.exports = { parse:
|
|
3333
|
+
module.exports = { parse: parse4 };
|
|
3334
3334
|
}
|
|
3335
3335
|
});
|
|
3336
3336
|
|
|
@@ -4554,10 +4554,10 @@ function mergeDefs(...defs) {
|
|
|
4554
4554
|
function cloneDef(schema) {
|
|
4555
4555
|
return mergeDefs(schema._zod.def);
|
|
4556
4556
|
}
|
|
4557
|
-
function getElementAtPath(obj,
|
|
4558
|
-
if (!
|
|
4557
|
+
function getElementAtPath(obj, path30) {
|
|
4558
|
+
if (!path30)
|
|
4559
4559
|
return obj;
|
|
4560
|
-
return
|
|
4560
|
+
return path30.reduce((acc, key) => acc?.[key], obj);
|
|
4561
4561
|
}
|
|
4562
4562
|
function promiseAllObject(promisesObj) {
|
|
4563
4563
|
const keys = Object.keys(promisesObj);
|
|
@@ -4897,11 +4897,11 @@ function explicitlyAborted(x, startIndex = 0) {
|
|
|
4897
4897
|
}
|
|
4898
4898
|
return false;
|
|
4899
4899
|
}
|
|
4900
|
-
function prefixIssues(
|
|
4900
|
+
function prefixIssues(path30, issues) {
|
|
4901
4901
|
return issues.map((iss) => {
|
|
4902
4902
|
var _a3;
|
|
4903
4903
|
(_a3 = iss).path ?? (_a3.path = []);
|
|
4904
|
-
iss.path.unshift(
|
|
4904
|
+
iss.path.unshift(path30);
|
|
4905
4905
|
return iss;
|
|
4906
4906
|
});
|
|
4907
4907
|
}
|
|
@@ -5351,16 +5351,16 @@ function flattenError(error62, mapper = (issue2) => issue2.message) {
|
|
|
5351
5351
|
}
|
|
5352
5352
|
function formatError(error62, mapper = (issue2) => issue2.message) {
|
|
5353
5353
|
const fieldErrors = { _errors: [] };
|
|
5354
|
-
const processError = (error63,
|
|
5354
|
+
const processError = (error63, path30 = []) => {
|
|
5355
5355
|
for (const issue2 of error63.issues) {
|
|
5356
5356
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
5357
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
5357
|
+
issue2.errors.map((issues) => processError({ issues }, [...path30, ...issue2.path]));
|
|
5358
5358
|
} else if (issue2.code === "invalid_key") {
|
|
5359
|
-
processError({ issues: issue2.issues }, [...
|
|
5359
|
+
processError({ issues: issue2.issues }, [...path30, ...issue2.path]);
|
|
5360
5360
|
} else if (issue2.code === "invalid_element") {
|
|
5361
|
-
processError({ issues: issue2.issues }, [...
|
|
5361
|
+
processError({ issues: issue2.issues }, [...path30, ...issue2.path]);
|
|
5362
5362
|
} else {
|
|
5363
|
-
const fullpath = [...
|
|
5363
|
+
const fullpath = [...path30, ...issue2.path];
|
|
5364
5364
|
if (fullpath.length === 0) {
|
|
5365
5365
|
fieldErrors._errors.push(mapper(issue2));
|
|
5366
5366
|
} else {
|
|
@@ -5399,17 +5399,17 @@ function formatError(error62, mapper = (issue2) => issue2.message) {
|
|
|
5399
5399
|
}
|
|
5400
5400
|
function treeifyError(error62, mapper = (issue2) => issue2.message) {
|
|
5401
5401
|
const result2 = { errors: [] };
|
|
5402
|
-
const processError = (error63,
|
|
5402
|
+
const processError = (error63, path30 = []) => {
|
|
5403
5403
|
var _a3;
|
|
5404
5404
|
for (const issue2 of error63.issues) {
|
|
5405
5405
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
5406
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
5406
|
+
issue2.errors.map((issues) => processError({ issues }, [...path30, ...issue2.path]));
|
|
5407
5407
|
} else if (issue2.code === "invalid_key") {
|
|
5408
|
-
processError({ issues: issue2.issues }, [...
|
|
5408
|
+
processError({ issues: issue2.issues }, [...path30, ...issue2.path]);
|
|
5409
5409
|
} else if (issue2.code === "invalid_element") {
|
|
5410
|
-
processError({ issues: issue2.issues }, [...
|
|
5410
|
+
processError({ issues: issue2.issues }, [...path30, ...issue2.path]);
|
|
5411
5411
|
} else {
|
|
5412
|
-
const fullpath = [...
|
|
5412
|
+
const fullpath = [...path30, ...issue2.path];
|
|
5413
5413
|
if (fullpath.length === 0) {
|
|
5414
5414
|
result2.errors.push(mapper(issue2));
|
|
5415
5415
|
continue;
|
|
@@ -5448,8 +5448,8 @@ function treeifyError(error62, mapper = (issue2) => issue2.message) {
|
|
|
5448
5448
|
}
|
|
5449
5449
|
function toDotPath(_path) {
|
|
5450
5450
|
const segs = [];
|
|
5451
|
-
const
|
|
5452
|
-
for (const seg of
|
|
5451
|
+
const path30 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
5452
|
+
for (const seg of path30) {
|
|
5453
5453
|
if (typeof seg === "number")
|
|
5454
5454
|
segs.push(`[${seg}]`);
|
|
5455
5455
|
else if (typeof seg === "symbol")
|
|
@@ -5583,18 +5583,18 @@ var validateAsync = async (schema, value, _ctx) => {
|
|
|
5583
5583
|
return result2.issues.length === 0;
|
|
5584
5584
|
};
|
|
5585
5585
|
var _encode = (_Err) => {
|
|
5586
|
-
const
|
|
5586
|
+
const parse4 = _parse(_Err);
|
|
5587
5587
|
const fn = (schema, value, _ctx, _params) => {
|
|
5588
5588
|
const ctx = _ctx ? { ..._ctx, direction: "backward" } : { direction: "backward" };
|
|
5589
|
-
return
|
|
5589
|
+
return parse4(schema, value, ctx, finalizeParams(fn, _params));
|
|
5590
5590
|
};
|
|
5591
5591
|
return fn;
|
|
5592
5592
|
};
|
|
5593
5593
|
var encode = /* @__PURE__ */ _encode($ZodRealError);
|
|
5594
5594
|
var _decode = (_Err) => {
|
|
5595
|
-
const
|
|
5595
|
+
const parse4 = _parse(_Err);
|
|
5596
5596
|
const fn = (schema, value, _ctx, _params) => {
|
|
5597
|
-
return
|
|
5597
|
+
return parse4(schema, value, _ctx, finalizeParams(fn, _params));
|
|
5598
5598
|
};
|
|
5599
5599
|
return fn;
|
|
5600
5600
|
};
|
|
@@ -22551,13 +22551,13 @@ function resolveRef(ref, ctx) {
|
|
|
22551
22551
|
if (!ref.startsWith("#")) {
|
|
22552
22552
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
22553
22553
|
}
|
|
22554
|
-
const
|
|
22555
|
-
if (
|
|
22554
|
+
const path30 = ref.slice(1).split("/").filter(Boolean);
|
|
22555
|
+
if (path30.length === 0) {
|
|
22556
22556
|
return ctx.rootSchema;
|
|
22557
22557
|
}
|
|
22558
22558
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
22559
|
-
if (
|
|
22560
|
-
const key =
|
|
22559
|
+
if (path30[0] === defsKey) {
|
|
22560
|
+
const key = path30[1] === void 0 ? void 0 : decodeJSONPointerSegment(path30[1]);
|
|
22561
22561
|
if (!key || !ctx.defs[key]) {
|
|
22562
22562
|
throw new Error(`Reference not found: ${ref}`);
|
|
22563
22563
|
}
|
|
@@ -23192,7 +23192,7 @@ function visit(schema, fnOrHandlers) {
|
|
|
23192
23192
|
return h ? h(node2, rewritten) : node2;
|
|
23193
23193
|
};
|
|
23194
23194
|
const cache2 = /* @__PURE__ */ new Map();
|
|
23195
|
-
function
|
|
23195
|
+
function run2(s) {
|
|
23196
23196
|
const cached2 = cache2.get(s);
|
|
23197
23197
|
if (cached2 === RESOLVING) {
|
|
23198
23198
|
return new $ZodLazy({
|
|
@@ -23218,21 +23218,21 @@ function visit(schema, fnOrHandlers) {
|
|
|
23218
23218
|
let changed = false;
|
|
23219
23219
|
const newShape = {};
|
|
23220
23220
|
for (const k of keys) {
|
|
23221
|
-
const mapped =
|
|
23221
|
+
const mapped = run2(oldShape[k]);
|
|
23222
23222
|
if (mapped !== oldShape[k])
|
|
23223
23223
|
changed = true;
|
|
23224
23224
|
newShape[k] = mapped;
|
|
23225
23225
|
}
|
|
23226
23226
|
let newCatchall = def.catchall;
|
|
23227
23227
|
if (def.catchall) {
|
|
23228
|
-
newCatchall =
|
|
23228
|
+
newCatchall = run2(def.catchall);
|
|
23229
23229
|
if (newCatchall !== def.catchall)
|
|
23230
23230
|
changed = true;
|
|
23231
23231
|
}
|
|
23232
23232
|
return changed ? clone(s, { ...def, shape: newShape, catchall: newCatchall }) : s;
|
|
23233
23233
|
}
|
|
23234
23234
|
case "array": {
|
|
23235
|
-
const mapped =
|
|
23235
|
+
const mapped = run2(def.element);
|
|
23236
23236
|
return mapped === def.element ? s : clone(s, { ...def, element: mapped });
|
|
23237
23237
|
}
|
|
23238
23238
|
case "tuple": {
|
|
@@ -23240,14 +23240,14 @@ function visit(schema, fnOrHandlers) {
|
|
|
23240
23240
|
let changed = false;
|
|
23241
23241
|
const newItems = [];
|
|
23242
23242
|
for (const item of oldItems) {
|
|
23243
|
-
const mapped =
|
|
23243
|
+
const mapped = run2(item);
|
|
23244
23244
|
if (mapped !== item)
|
|
23245
23245
|
changed = true;
|
|
23246
23246
|
newItems.push(mapped);
|
|
23247
23247
|
}
|
|
23248
23248
|
let newRest = def.rest;
|
|
23249
23249
|
if (def.rest) {
|
|
23250
|
-
newRest =
|
|
23250
|
+
newRest = run2(def.rest);
|
|
23251
23251
|
if (newRest !== def.rest)
|
|
23252
23252
|
changed = true;
|
|
23253
23253
|
}
|
|
@@ -23255,12 +23255,12 @@ function visit(schema, fnOrHandlers) {
|
|
|
23255
23255
|
}
|
|
23256
23256
|
case "record":
|
|
23257
23257
|
case "map": {
|
|
23258
|
-
const newKey =
|
|
23259
|
-
const newVal =
|
|
23258
|
+
const newKey = run2(def.keyType);
|
|
23259
|
+
const newVal = run2(def.valueType);
|
|
23260
23260
|
return newKey === def.keyType && newVal === def.valueType ? s : clone(s, { ...def, keyType: newKey, valueType: newVal });
|
|
23261
23261
|
}
|
|
23262
23262
|
case "set": {
|
|
23263
|
-
const newVal =
|
|
23263
|
+
const newVal = run2(def.valueType);
|
|
23264
23264
|
return newVal === def.valueType ? s : clone(s, { ...def, valueType: newVal });
|
|
23265
23265
|
}
|
|
23266
23266
|
case "union": {
|
|
@@ -23268,7 +23268,7 @@ function visit(schema, fnOrHandlers) {
|
|
|
23268
23268
|
let changed = false;
|
|
23269
23269
|
const newOptions = [];
|
|
23270
23270
|
for (const opt of oldOptions) {
|
|
23271
|
-
const mapped =
|
|
23271
|
+
const mapped = run2(opt);
|
|
23272
23272
|
if (mapped !== opt)
|
|
23273
23273
|
changed = true;
|
|
23274
23274
|
newOptions.push(mapped);
|
|
@@ -23276,8 +23276,8 @@ function visit(schema, fnOrHandlers) {
|
|
|
23276
23276
|
return changed ? clone(s, { ...def, options: newOptions }) : s;
|
|
23277
23277
|
}
|
|
23278
23278
|
case "intersection": {
|
|
23279
|
-
const newLeft =
|
|
23280
|
-
const newRight =
|
|
23279
|
+
const newLeft = run2(def.left);
|
|
23280
|
+
const newRight = run2(def.right);
|
|
23281
23281
|
return newLeft === def.left && newRight === def.right ? s : clone(s, { ...def, left: newLeft, right: newRight });
|
|
23282
23282
|
}
|
|
23283
23283
|
case "optional":
|
|
@@ -23289,23 +23289,23 @@ function visit(schema, fnOrHandlers) {
|
|
|
23289
23289
|
case "nonoptional":
|
|
23290
23290
|
case "promise":
|
|
23291
23291
|
case "success": {
|
|
23292
|
-
const newInner =
|
|
23292
|
+
const newInner = run2(def.innerType);
|
|
23293
23293
|
return newInner === def.innerType ? s : clone(s, { ...def, innerType: newInner });
|
|
23294
23294
|
}
|
|
23295
23295
|
case "pipe": {
|
|
23296
|
-
const newIn =
|
|
23297
|
-
const newOut =
|
|
23296
|
+
const newIn = run2(def.in);
|
|
23297
|
+
const newOut = run2(def.out);
|
|
23298
23298
|
return newIn === def.in && newOut === def.out ? s : clone(s, { ...def, in: newIn, out: newOut });
|
|
23299
23299
|
}
|
|
23300
23300
|
case "function": {
|
|
23301
|
-
const newInput =
|
|
23302
|
-
const newOutput =
|
|
23301
|
+
const newInput = run2(def.input);
|
|
23302
|
+
const newOutput = run2(def.output);
|
|
23303
23303
|
return newInput === def.input && newOutput === def.output ? s : clone(s, { ...def, input: newInput, output: newOutput });
|
|
23304
23304
|
}
|
|
23305
23305
|
case "lazy": {
|
|
23306
23306
|
const original = def.getter;
|
|
23307
23307
|
const { _cachedInner, ...rest } = def;
|
|
23308
|
-
return clone(s, { ...rest, getter: () =>
|
|
23308
|
+
return clone(s, { ...rest, getter: () => run2(original()) });
|
|
23309
23309
|
}
|
|
23310
23310
|
// A leaf by choice: `parts` are regex fragments, not data positions.
|
|
23311
23311
|
case "template_literal":
|
|
@@ -23336,7 +23336,7 @@ function visit(schema, fnOrHandlers) {
|
|
|
23336
23336
|
}
|
|
23337
23337
|
}
|
|
23338
23338
|
}
|
|
23339
|
-
return
|
|
23339
|
+
return run2(schema);
|
|
23340
23340
|
}
|
|
23341
23341
|
|
|
23342
23342
|
// node_modules/zod/v4/classic/deep-partial.js
|
|
@@ -25177,8 +25177,8 @@ async function openNetworkPanel(binaryDirectory, identity) {
|
|
|
25177
25177
|
}
|
|
25178
25178
|
|
|
25179
25179
|
// agent/src/main.ts
|
|
25180
|
-
import
|
|
25181
|
-
import
|
|
25180
|
+
import path29 from "node:path";
|
|
25181
|
+
import os8 from "node:os";
|
|
25182
25182
|
|
|
25183
25183
|
// agent/src/posix-store.ts
|
|
25184
25184
|
import { constants } from "node:fs";
|
|
@@ -25597,7 +25597,7 @@ async function acquirePosixJournalGuard(directory, helper) {
|
|
|
25597
25597
|
}
|
|
25598
25598
|
|
|
25599
25599
|
// agent/src/main.ts
|
|
25600
|
-
import { mkdir as mkdir14, open as open13, readFile as
|
|
25600
|
+
import { mkdir as mkdir14, open as open13, readFile as readFile12, realpath as realpath10, rm as rm10 } from "node:fs/promises";
|
|
25601
25601
|
import { fileURLToPath } from "node:url";
|
|
25602
25602
|
|
|
25603
25603
|
// packages/operations/src/crypto.ts
|
|
@@ -25734,13 +25734,13 @@ var exec2 = promisify2(execFile2);
|
|
|
25734
25734
|
async function darwinSupervisorLiveness(helper, pids, records = []) {
|
|
25735
25735
|
if (process.platform !== "darwin" || !process.getuid?.() || process.getuid() !== process.geteuid?.()) return null;
|
|
25736
25736
|
const remaining = new Set(pids), uid = process.getuid(), deadline = Date.now() + 1e4, env = buildChildEnvironment(process.env);
|
|
25737
|
-
const
|
|
25737
|
+
const run2 = (file2, args) => exec2(
|
|
25738
25738
|
file2,
|
|
25739
25739
|
args,
|
|
25740
25740
|
{ env, timeout: Math.max(1, Math.min(7e3, deadline - Date.now())), maxBuffer: 8192, encoding: "utf8", windowsHide: true }
|
|
25741
25741
|
);
|
|
25742
25742
|
try {
|
|
25743
|
-
const boot = (await
|
|
25743
|
+
const boot = (await run2("/usr/sbin/sysctl", ["-n", "kern.bootsessionuuid"])).stdout.trim();
|
|
25744
25744
|
if (!bootSession.test(boot)) return null;
|
|
25745
25745
|
for (const pid of remaining) {
|
|
25746
25746
|
if (Date.now() >= deadline) break;
|
|
@@ -25749,9 +25749,9 @@ async function darwinSupervisorLiveness(helper, pids, records = []) {
|
|
|
25749
25749
|
const proof2 = matches2[0].containment;
|
|
25750
25750
|
if (!validDarwinContainment(proof2) || proof2.uid !== uid || proof2.bootSession !== boot) continue;
|
|
25751
25751
|
try {
|
|
25752
|
-
await
|
|
25753
|
-
if ((await
|
|
25754
|
-
await
|
|
25752
|
+
await run2(helper, ["--reap", proof2.coalition]);
|
|
25753
|
+
if ((await run2(helper, ["--count", proof2.coalition])).stdout.trim() !== "0") continue;
|
|
25754
|
+
await run2("/bin/launchctl", ["bootout", "gui/" + uid + "/" + proof2.label]).catch(() => {
|
|
25755
25755
|
});
|
|
25756
25756
|
remaining.delete(pid);
|
|
25757
25757
|
} catch {
|
|
@@ -26458,10 +26458,12 @@ var ToolCallSchema = external_exports.discriminatedUnion("name", [
|
|
|
26458
26458
|
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(),
|
|
26459
26459
|
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(),
|
|
26460
26460
|
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(),
|
|
26461
|
+
// Still image of the device's primary display; the agent requires an owner Full Access workspace.
|
|
26462
|
+
external_exports.object({ name: external_exports.literal("take_screenshot"), args: external_exports.object({}).strict() }).strict(),
|
|
26461
26463
|
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()
|
|
26462
26464
|
]);
|
|
26463
26465
|
function scopeForTool(call) {
|
|
26464
|
-
if (call.name === "command_run") return "commands:execute";
|
|
26466
|
+
if (call.name === "command_run" || call.name === "take_screenshot") return "commands:execute";
|
|
26465
26467
|
if (call.name === "localhost_request") return "localhost:access";
|
|
26466
26468
|
return call.name === "fs_write" || call.name === "fs_replace" ? "files:write" : "files:read";
|
|
26467
26469
|
}
|
|
@@ -26477,10 +26479,12 @@ var ServerFrameSchema = external_exports.discriminatedUnion("type", [
|
|
|
26477
26479
|
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(),
|
|
26478
26480
|
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()
|
|
26479
26481
|
]);
|
|
26482
|
+
var WORKSPACE_ACCESS_MODE_CAPABILITY = "workspaceAccessModeV1";
|
|
26483
|
+
var WorkspaceAccessModeSchema = external_exports.enum(["full", "scoped"]);
|
|
26480
26484
|
var ClientFrameSchema = external_exports.discriminatedUnion("type", [
|
|
26481
26485
|
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(),
|
|
26482
26486
|
external_exports.object({ type: external_exports.literal("heartbeat"), version: external_exports.literal(1), connectionEpoch: epoch2 }).strict(),
|
|
26483
|
-
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(),
|
|
26487
|
+
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(),
|
|
26484
26488
|
external_exports.object({ type: external_exports.literal("workspace_revoke"), version: external_exports.literal(1), requestId: uuid11, workspaceGrantId: uuid11 }).strict(),
|
|
26485
26489
|
external_exports.object({ type: external_exports.literal("prepared"), version: external_exports.literal(1), binding: ExecutionBindingSchema }).strict(),
|
|
26486
26490
|
external_exports.object({ type: external_exports.literal("accepted"), version: external_exports.literal(1), binding: ExecutionBindingSchema }).strict(),
|
|
@@ -26565,6 +26569,7 @@ function guardAction(binding2, tool, config2, observedAt) {
|
|
|
26565
26569
|
throw Error("GUARD_IDENTITY_REQUIRED");
|
|
26566
26570
|
}
|
|
26567
26571
|
const name2 = tool.call.name;
|
|
26572
|
+
if (name2 === "take_screenshot") throw Error("GUARD_ACTION_UNSUPPORTED");
|
|
26568
26573
|
const kind = name2 === "command_run" ? "execute" : name2 === "localhost_request" ? "localhost-access" : name2 === "fs_write" || name2 === "fs_replace" ? "write" : name2.startsWith("git_") ? "git-read" : "read";
|
|
26569
26574
|
const resourceKind = kind === "execute" ? "workspace" : kind === "localhost-access" ? "localhost-service" : kind === "git-read" ? "git-repository" : name2 === "fs_read" || kind === "write" ? "file" : "workspace";
|
|
26570
26575
|
return { payloadHash: guardHash(tool.effective), request: BoundActionRequestSchema.parse({
|
|
@@ -27040,9 +27045,9 @@ var NativeJournal = class _NativeJournal {
|
|
|
27040
27045
|
if (!validPid(pid)) throw failure2("JOURNAL_INPUT_INVALID");
|
|
27041
27046
|
if (e.state !== "running" || !e.supervisors) throw failure2("JOURNAL_STATE_INVALID");
|
|
27042
27047
|
if (containment !== void 0) {
|
|
27043
|
-
const
|
|
27044
|
-
if (!
|
|
27045
|
-
if (
|
|
27048
|
+
const linux2 = validLinuxContainment(containment), darwin = !linux2 && validDarwinContainment(containment);
|
|
27049
|
+
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");
|
|
27050
|
+
if (linux2) (e.linuxSupervisors ??= []).push({ pid, containment: clone2(containment) });
|
|
27046
27051
|
else (e.darwinSupervisors ??= []).push({ pid, containment: clone2(containment) });
|
|
27047
27052
|
} else {
|
|
27048
27053
|
if (e.supervisors.length >= MAX_SUPERVISORS) throw failure2("JOURNAL_SUPERVISOR_LIMIT");
|
|
@@ -27246,6 +27251,7 @@ import { constants as constants4 } from "node:fs";
|
|
|
27246
27251
|
|
|
27247
27252
|
// agent/src/posix-consent.ts
|
|
27248
27253
|
import { openSync, closeSync } from "node:fs";
|
|
27254
|
+
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
27249
27255
|
import { isatty, ReadStream, WriteStream } from "node:tty";
|
|
27250
27256
|
import { createInterface } from "node:readline/promises";
|
|
27251
27257
|
import path8 from "node:path";
|
|
@@ -27348,7 +27354,7 @@ async function planPermissionChange(current2, programs, input2) {
|
|
|
27348
27354
|
}
|
|
27349
27355
|
|
|
27350
27356
|
// agent/src/posix-consent.ts
|
|
27351
|
-
async function terminal2(
|
|
27357
|
+
async function terminal2(run2, timeoutMs2, signal) {
|
|
27352
27358
|
if (!process.getuid || process.getuid() === 0 || process.geteuid?.() !== process.getuid() || signal?.aborted) throw Error("OWNER_REVIEW_UNAVAILABLE");
|
|
27353
27359
|
let readFd;
|
|
27354
27360
|
try {
|
|
@@ -27384,7 +27390,7 @@ async function terminal2(run, timeoutMs2, signal) {
|
|
|
27384
27390
|
};
|
|
27385
27391
|
input2.on("data", bound);
|
|
27386
27392
|
try {
|
|
27387
|
-
return await
|
|
27393
|
+
return await run2(async (prompt) => {
|
|
27388
27394
|
if (stop.signal.aborted) throw Error("OWNER_REVIEW_CANCELLED");
|
|
27389
27395
|
return review.question(prompt, { signal: stop.signal });
|
|
27390
27396
|
});
|
|
@@ -27413,16 +27419,41 @@ async function choosePosixFolder() {
|
|
|
27413
27419
|
return await ask("Read/write folder: " + permissionLabel(folder) + "\nType APPROVE to accept: ") === "APPROVE" ? folder : null;
|
|
27414
27420
|
}, 12e4);
|
|
27415
27421
|
}
|
|
27422
|
+
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.";
|
|
27423
|
+
function selection(folder, full) {
|
|
27424
|
+
if (!path8.isAbsolute(folder) || folder.length > 4096 || /[\u0000-\u001f]/.test(folder)) throw Error("WORKSPACE_INVALID");
|
|
27425
|
+
return { mode: full ? "all-drives" : "folders", paths: [full ? "/" : folder] };
|
|
27426
|
+
}
|
|
27427
|
+
function macDialog() {
|
|
27428
|
+
const script = [
|
|
27429
|
+
"on run argv",
|
|
27430
|
+
'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)',
|
|
27431
|
+
'if answer is "Full Access" then return "full"',
|
|
27432
|
+
'return "folder:" & POSIX path of (choose folder with prompt "Choose the folder Local Commander may read and write")',
|
|
27433
|
+
"end run"
|
|
27434
|
+
];
|
|
27435
|
+
const result2 = spawnSync2(
|
|
27436
|
+
"/usr/bin/osascript",
|
|
27437
|
+
[...script.flatMap((line) => ["-e", line]), ACCESS_TEXT],
|
|
27438
|
+
{ encoding: "utf8", timeout: 24e4, maxBuffer: 16384, shell: false }
|
|
27439
|
+
);
|
|
27440
|
+
if (result2.error) return void 0;
|
|
27441
|
+
if (result2.status !== 0) return /\(-128\)/.test(result2.stderr) ? null : void 0;
|
|
27442
|
+
const out = result2.stdout.replace(/\n$/, "");
|
|
27443
|
+
if (out === "full") return selection("/", true);
|
|
27444
|
+
if (out.startsWith("folder:")) return selection(out.slice(7).replace(/(.)\/$/, "$1"), false);
|
|
27445
|
+
return void 0;
|
|
27446
|
+
}
|
|
27416
27447
|
async function choosePosixAccess() {
|
|
27448
|
+
if (process.platform === "darwin") {
|
|
27449
|
+
const chosen = macDialog();
|
|
27450
|
+
if (chosen !== void 0) return chosen;
|
|
27451
|
+
}
|
|
27417
27452
|
return terminal2(async (ask) => {
|
|
27418
|
-
|
|
27419
|
-
|
|
27420
|
-
if (
|
|
27421
|
-
|
|
27422
|
-
if (!path8.isAbsolute(folder) || folder.length > 4096 || /[\u0000-\u001f]/.test(folder)) throw Error("WORKSPACE_INVALID");
|
|
27423
|
-
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) + ".";
|
|
27424
|
-
if (await ask(summary + "\nThis replaces the previous folder/command/localhost selection and persists until revoked.\nType APPROVE to accept: ") !== "APPROVE") return null;
|
|
27425
|
-
return { mode: choice === "2" ? "all-drives" : "folders", paths: [folder] };
|
|
27453
|
+
const answer = await ask("\n" + ACCESS_TEXT + "\n\nPress Enter for Full Access, type a folder path for one folder, or n to cancel: ");
|
|
27454
|
+
if (answer === "") return selection("/", true);
|
|
27455
|
+
if (/^(n|no|cancel)$/i.test(answer)) return null;
|
|
27456
|
+
return selection(answer, false);
|
|
27426
27457
|
}, 24e4);
|
|
27427
27458
|
}
|
|
27428
27459
|
|
|
@@ -28889,9 +28920,9 @@ var HostMemory = class {
|
|
|
28889
28920
|
};
|
|
28890
28921
|
|
|
28891
28922
|
// agent/src/tools.ts
|
|
28892
|
-
import { constants as
|
|
28893
|
-
import { lstat as
|
|
28894
|
-
import
|
|
28923
|
+
import { constants as constants8 } from "node:fs";
|
|
28924
|
+
import { lstat as lstat8, open as open6, readdir as readdir5, realpath as realpath7, rename as rename4, rm as rm6 } from "node:fs/promises";
|
|
28925
|
+
import path18 from "node:path";
|
|
28895
28926
|
import { createHash as createHash14, randomUUID as randomUUID7 } from "node:crypto";
|
|
28896
28927
|
|
|
28897
28928
|
// src/guard.ts
|
|
@@ -29335,6 +29366,1249 @@ async function runSupervised(helper, request, options = {}) {
|
|
|
29335
29366
|
});
|
|
29336
29367
|
}
|
|
29337
29368
|
|
|
29369
|
+
// agent/src/screen-capture.ts
|
|
29370
|
+
import { execFile as execFile4 } from "node:child_process";
|
|
29371
|
+
import { randomBytes as randomBytes6 } from "node:crypto";
|
|
29372
|
+
import { constants as constants7 } from "node:fs";
|
|
29373
|
+
import { access as access3, lstat as lstat7, mkdtemp, readFile as readFile6, readdir as readdir4, rm as rm5, unlink as unlink2 } from "node:fs/promises";
|
|
29374
|
+
import os4 from "node:os";
|
|
29375
|
+
import path17 from "node:path";
|
|
29376
|
+
|
|
29377
|
+
// agent/src/dbus-portal.ts
|
|
29378
|
+
import net from "node:net";
|
|
29379
|
+
function sessionBusSocket(address) {
|
|
29380
|
+
for (const entry of (address ?? "").split(";")) {
|
|
29381
|
+
if (!entry.startsWith("unix:")) continue;
|
|
29382
|
+
for (const part of entry.slice(5).split(",")) {
|
|
29383
|
+
const at = part.indexOf("="), key = part.slice(0, at), value = decodeURIComponent(part.slice(at + 1));
|
|
29384
|
+
if (at > 0 && value && key === "path") return value;
|
|
29385
|
+
if (at > 0 && value && key === "abstract") return "\0" + value;
|
|
29386
|
+
}
|
|
29387
|
+
}
|
|
29388
|
+
return null;
|
|
29389
|
+
}
|
|
29390
|
+
var Writer = class {
|
|
29391
|
+
bytes = [];
|
|
29392
|
+
align(n) {
|
|
29393
|
+
while (this.bytes.length % n) this.bytes.push(0);
|
|
29394
|
+
}
|
|
29395
|
+
byte(v) {
|
|
29396
|
+
this.bytes.push(v & 255);
|
|
29397
|
+
}
|
|
29398
|
+
u32(v) {
|
|
29399
|
+
this.align(4);
|
|
29400
|
+
this.bytes.push(v & 255, v >>> 8 & 255, v >>> 16 & 255, v >>> 24 & 255);
|
|
29401
|
+
}
|
|
29402
|
+
str(v) {
|
|
29403
|
+
const b = Buffer.from(v, "utf8");
|
|
29404
|
+
this.u32(b.length);
|
|
29405
|
+
this.bytes.push(...b, 0);
|
|
29406
|
+
}
|
|
29407
|
+
sig(v) {
|
|
29408
|
+
this.byte(v.length);
|
|
29409
|
+
this.bytes.push(...Buffer.from(v, "ascii"), 0);
|
|
29410
|
+
}
|
|
29411
|
+
/** Basic value or variant: `s`, `o`, `g`, `u`, `b`, `v` ([signature, value]). */
|
|
29412
|
+
put(type, value) {
|
|
29413
|
+
if (type === "s" || type === "o") this.str(String(value));
|
|
29414
|
+
else if (type === "g") this.sig(String(value));
|
|
29415
|
+
else if (type === "u") this.u32(Number(value));
|
|
29416
|
+
else if (type === "b") this.u32(value ? 1 : 0);
|
|
29417
|
+
else if (type === "v") {
|
|
29418
|
+
const [inner, v] = value;
|
|
29419
|
+
this.sig(inner);
|
|
29420
|
+
this.put(inner, v);
|
|
29421
|
+
} else throw Error("type " + type);
|
|
29422
|
+
}
|
|
29423
|
+
/** a{sv} */
|
|
29424
|
+
dict(entries) {
|
|
29425
|
+
this.u32(0);
|
|
29426
|
+
const lengthAt = this.bytes.length - 4;
|
|
29427
|
+
this.align(8);
|
|
29428
|
+
const start = this.bytes.length;
|
|
29429
|
+
for (const [key, value] of entries) {
|
|
29430
|
+
this.align(8);
|
|
29431
|
+
this.str(key);
|
|
29432
|
+
this.put("v", value);
|
|
29433
|
+
}
|
|
29434
|
+
const length = this.bytes.length - start;
|
|
29435
|
+
this.bytes.splice(lengthAt, 4, length & 255, length >>> 8 & 255, length >>> 16 & 255, length >>> 24 & 255);
|
|
29436
|
+
}
|
|
29437
|
+
};
|
|
29438
|
+
var Reader = class {
|
|
29439
|
+
constructor(data, at, le) {
|
|
29440
|
+
this.data = data;
|
|
29441
|
+
this.at = at;
|
|
29442
|
+
this.le = le;
|
|
29443
|
+
}
|
|
29444
|
+
data;
|
|
29445
|
+
at;
|
|
29446
|
+
le;
|
|
29447
|
+
align(n) {
|
|
29448
|
+
this.at = Math.ceil(this.at / n) * n;
|
|
29449
|
+
}
|
|
29450
|
+
u32() {
|
|
29451
|
+
this.align(4);
|
|
29452
|
+
const v = this.le ? this.data.readUInt32LE(this.at) : this.data.readUInt32BE(this.at);
|
|
29453
|
+
this.at += 4;
|
|
29454
|
+
return v;
|
|
29455
|
+
}
|
|
29456
|
+
/** Reads one complete type from `sig` starting at `i`; returns the value and the index after the type. */
|
|
29457
|
+
read(sig2, i) {
|
|
29458
|
+
const c = sig2[i];
|
|
29459
|
+
const fixed = { y: 1, n: 2, q: 2, b: 4, i: 4, u: 4, h: 4, x: 8, t: 8, d: 8 };
|
|
29460
|
+
if (c in fixed) {
|
|
29461
|
+
const size = fixed[c];
|
|
29462
|
+
this.align(size);
|
|
29463
|
+
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;
|
|
29464
|
+
this.at += size;
|
|
29465
|
+
return [c === "b" ? v === 1 : v, i + 1];
|
|
29466
|
+
}
|
|
29467
|
+
if (c === "s" || c === "o") {
|
|
29468
|
+
const n = this.u32(), v = this.data.toString("utf8", this.at, this.at + n);
|
|
29469
|
+
this.at += n + 1;
|
|
29470
|
+
return [v, i + 1];
|
|
29471
|
+
}
|
|
29472
|
+
if (c === "g") {
|
|
29473
|
+
const n = this.data[this.at], v = this.data.toString("ascii", this.at + 1, this.at + 1 + n);
|
|
29474
|
+
this.at += n + 2;
|
|
29475
|
+
return [v, i + 1];
|
|
29476
|
+
}
|
|
29477
|
+
if (c === "v") {
|
|
29478
|
+
const [inner] = this.read("g", 0);
|
|
29479
|
+
return [this.read(inner, 0)[0], i + 1];
|
|
29480
|
+
}
|
|
29481
|
+
if (c === "(" || c === "{") {
|
|
29482
|
+
this.align(8);
|
|
29483
|
+
const close = c === "(" ? ")" : "}", values = [];
|
|
29484
|
+
let j = i + 1;
|
|
29485
|
+
while (sig2[j] !== close) {
|
|
29486
|
+
const [v, next] = this.read(sig2, j);
|
|
29487
|
+
values.push(v);
|
|
29488
|
+
j = next;
|
|
29489
|
+
}
|
|
29490
|
+
return [values, j + 1];
|
|
29491
|
+
}
|
|
29492
|
+
if (c === "a") {
|
|
29493
|
+
const n = this.u32(), element = sig2[i + 1];
|
|
29494
|
+
this.align("xtd({".includes(element) ? 8 : element === "n" || element === "q" ? 2 : element === "y" || element === "g" || element === "v" ? 1 : 4);
|
|
29495
|
+
const end = this.at + n, values = [];
|
|
29496
|
+
let next = skip(sig2, i + 1);
|
|
29497
|
+
while (this.at < end) {
|
|
29498
|
+
const [v, j] = this.read(sig2, i + 1);
|
|
29499
|
+
values.push(v);
|
|
29500
|
+
next = j;
|
|
29501
|
+
}
|
|
29502
|
+
return [values, next];
|
|
29503
|
+
}
|
|
29504
|
+
throw Error("signature " + sig2);
|
|
29505
|
+
}
|
|
29506
|
+
};
|
|
29507
|
+
function skip(sig2, i) {
|
|
29508
|
+
const c = sig2[i];
|
|
29509
|
+
if (c === "a") return skip(sig2, i + 1);
|
|
29510
|
+
if (c === "(" || c === "{") {
|
|
29511
|
+
let j = i + 1;
|
|
29512
|
+
while (sig2[j] !== (c === "(" ? ")" : "}")) j = skip(sig2, j);
|
|
29513
|
+
return j + 1;
|
|
29514
|
+
}
|
|
29515
|
+
return i + 1;
|
|
29516
|
+
}
|
|
29517
|
+
function parse3(data) {
|
|
29518
|
+
const le = data[0] === 108, r = new Reader(data, 4, le), bodyLength = r.u32(), serial = r.u32();
|
|
29519
|
+
const [fields] = r.read("a(yv)", 0);
|
|
29520
|
+
const message2 = { type: data[1], serial, signature: "", body: [] };
|
|
29521
|
+
for (const [code, value] of fields) {
|
|
29522
|
+
if (code === 1) message2.path = String(value);
|
|
29523
|
+
else if (code === 2) message2.interface = String(value);
|
|
29524
|
+
else if (code === 3) message2.member = String(value);
|
|
29525
|
+
else if (code === 4) message2.errorName = String(value);
|
|
29526
|
+
else if (code === 5) message2.replySerial = Number(value);
|
|
29527
|
+
else if (code === 8) message2.signature = String(value);
|
|
29528
|
+
}
|
|
29529
|
+
r.align(8);
|
|
29530
|
+
const end = r.at + bodyLength;
|
|
29531
|
+
for (let i = 0; i < message2.signature.length && r.at < end; ) {
|
|
29532
|
+
const [v, next] = r.read(message2.signature, i);
|
|
29533
|
+
message2.body.push(v);
|
|
29534
|
+
i = next;
|
|
29535
|
+
}
|
|
29536
|
+
return message2;
|
|
29537
|
+
}
|
|
29538
|
+
function frameLength(data) {
|
|
29539
|
+
if (data.length < 16) return 0;
|
|
29540
|
+
const le = data[0] === 108, u = (at) => le ? data.readUInt32LE(at) : data.readUInt32BE(at);
|
|
29541
|
+
const length = Math.ceil((16 + u(12)) / 8) * 8 + u(4);
|
|
29542
|
+
return data.length >= length ? length : 0;
|
|
29543
|
+
}
|
|
29544
|
+
async function portalScreenshot(socket, uid, token, signal) {
|
|
29545
|
+
const connection = net.createConnection({ path: socket });
|
|
29546
|
+
try {
|
|
29547
|
+
return await new Promise((resolve, reject) => {
|
|
29548
|
+
let serial = 0, buffer = Buffer.alloc(0), authenticated = false, requestPath = "";
|
|
29549
|
+
const pending = /* @__PURE__ */ new Map();
|
|
29550
|
+
const fail7 = (error62) => reject(error62 instanceof Error ? error62 : Error(String(error62)));
|
|
29551
|
+
const abort = () => fail7(Error("ABORTED"));
|
|
29552
|
+
if (signal.aborted) return abort();
|
|
29553
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
29554
|
+
connection.on("error", fail7);
|
|
29555
|
+
connection.on("close", () => fail7(Error("CLOSED")));
|
|
29556
|
+
const call = (destination, path30, iface, member, signature = "", body = () => {
|
|
29557
|
+
}) => new Promise((done, failed) => {
|
|
29558
|
+
const payload2 = new Writer();
|
|
29559
|
+
body(payload2);
|
|
29560
|
+
const header = new Writer(), fields = [[1, "o", path30], [2, "s", iface], [3, "s", member], [6, "s", destination]];
|
|
29561
|
+
if (signature) fields.push([8, "g", signature]);
|
|
29562
|
+
header.byte(108);
|
|
29563
|
+
header.byte(1);
|
|
29564
|
+
header.byte(0);
|
|
29565
|
+
header.byte(1);
|
|
29566
|
+
header.u32(payload2.bytes.length);
|
|
29567
|
+
header.u32(++serial);
|
|
29568
|
+
header.u32(0);
|
|
29569
|
+
const lengthAt = header.bytes.length - 4;
|
|
29570
|
+
header.align(8);
|
|
29571
|
+
const start = header.bytes.length;
|
|
29572
|
+
for (const [code, type, value] of fields) {
|
|
29573
|
+
header.align(8);
|
|
29574
|
+
header.byte(code);
|
|
29575
|
+
header.sig(type);
|
|
29576
|
+
header.put(type, value);
|
|
29577
|
+
}
|
|
29578
|
+
const length = header.bytes.length - start;
|
|
29579
|
+
header.bytes.splice(lengthAt, 4, length & 255, length >>> 8 & 255, length >>> 16 & 255, length >>> 24 & 255);
|
|
29580
|
+
header.align(8);
|
|
29581
|
+
pending.set(serial, (reply) => reply.type === 3 ? failed(Error(reply.errorName ?? "DBUS_ERROR")) : done(reply));
|
|
29582
|
+
connection.write(Buffer.from([...header.bytes, ...payload2.bytes]));
|
|
29583
|
+
});
|
|
29584
|
+
const bus = (member, signature, body) => call("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", member, signature, body);
|
|
29585
|
+
connection.on("data", (chunk) => {
|
|
29586
|
+
try {
|
|
29587
|
+
receive(chunk);
|
|
29588
|
+
} catch (error62) {
|
|
29589
|
+
fail7(error62);
|
|
29590
|
+
}
|
|
29591
|
+
});
|
|
29592
|
+
const receive = (chunk) => {
|
|
29593
|
+
buffer = Buffer.concat([buffer, chunk]);
|
|
29594
|
+
if (buffer.length > 1048576) return fail7(Error("OVERSIZED"));
|
|
29595
|
+
if (!authenticated) {
|
|
29596
|
+
const end = buffer.indexOf("\r\n");
|
|
29597
|
+
if (end < 0) return;
|
|
29598
|
+
const line = buffer.toString("ascii", 0, end);
|
|
29599
|
+
buffer = buffer.subarray(end + 2);
|
|
29600
|
+
if (!line.startsWith("OK ")) return fail7(Error("AUTH"));
|
|
29601
|
+
authenticated = true;
|
|
29602
|
+
connection.write("BEGIN\r\n");
|
|
29603
|
+
void (async () => {
|
|
29604
|
+
const unique = String((await bus("Hello")).body[0]);
|
|
29605
|
+
requestPath = "/org/freedesktop/portal/desktop/request/" + unique.slice(1).replace(/\./g, "_") + "/" + token;
|
|
29606
|
+
await bus("AddMatch", "s", (w) => w.put("s", "type='signal',interface='org.freedesktop.portal.Request',member='Response',path='" + requestPath + "'"));
|
|
29607
|
+
const handle = await call(
|
|
29608
|
+
"org.freedesktop.portal.Desktop",
|
|
29609
|
+
"/org/freedesktop/portal/desktop",
|
|
29610
|
+
"org.freedesktop.portal.Screenshot",
|
|
29611
|
+
"Screenshot",
|
|
29612
|
+
"sa{sv}",
|
|
29613
|
+
(w) => {
|
|
29614
|
+
w.put("s", "");
|
|
29615
|
+
w.dict([["handle_token", ["s", token]], ["interactive", ["b", false]]]);
|
|
29616
|
+
}
|
|
29617
|
+
);
|
|
29618
|
+
if (handle.body[0] !== requestPath) {
|
|
29619
|
+
requestPath = String(handle.body[0]);
|
|
29620
|
+
await bus("AddMatch", "s", (w) => w.put("s", "type='signal',interface='org.freedesktop.portal.Request',member='Response',path='" + requestPath + "'"));
|
|
29621
|
+
}
|
|
29622
|
+
})().catch(fail7);
|
|
29623
|
+
}
|
|
29624
|
+
for (let length = frameLength(buffer); authenticated && length; length = frameLength(buffer)) {
|
|
29625
|
+
const message2 = parse3(buffer.subarray(0, length));
|
|
29626
|
+
buffer = buffer.subarray(length);
|
|
29627
|
+
if ((message2.type === 2 || message2.type === 3) && message2.replySerial !== void 0) {
|
|
29628
|
+
pending.get(message2.replySerial)?.(message2);
|
|
29629
|
+
pending.delete(message2.replySerial);
|
|
29630
|
+
} else if (message2.type === 4 && message2.member === "Response" && message2.path === requestPath && message2.signature === "ua{sv}") {
|
|
29631
|
+
const results2 = message2.body[1], uri = results2.find(([key]) => key === "uri")?.[1];
|
|
29632
|
+
resolve({ code: Number(message2.body[0]), uri: typeof uri === "string" ? uri : void 0 });
|
|
29633
|
+
}
|
|
29634
|
+
}
|
|
29635
|
+
};
|
|
29636
|
+
connection.on("connect", () => connection.write("\0AUTH EXTERNAL " + Buffer.from(String(uid), "ascii").toString("hex") + "\r\n"));
|
|
29637
|
+
});
|
|
29638
|
+
} finally {
|
|
29639
|
+
connection.destroy();
|
|
29640
|
+
}
|
|
29641
|
+
}
|
|
29642
|
+
|
|
29643
|
+
// agent/src/screen-image.ts
|
|
29644
|
+
import { inflateSync } from "node:zlib";
|
|
29645
|
+
var MAX_EDGE = 16384;
|
|
29646
|
+
var MAX_PIXELS = 67108864;
|
|
29647
|
+
function sizeOk(width, height) {
|
|
29648
|
+
return Number.isSafeInteger(width) && Number.isSafeInteger(height) && width > 0 && height > 0 && width <= MAX_EDGE && height <= MAX_EDGE && width * height <= MAX_PIXELS;
|
|
29649
|
+
}
|
|
29650
|
+
function decodePng(data) {
|
|
29651
|
+
if (data.length < 33 || data.readUInt32BE(0) !== 2303741511 || data.readUInt32BE(4) !== 218765834) return null;
|
|
29652
|
+
let width = 0, height = 0, channels = 0;
|
|
29653
|
+
const idat = [];
|
|
29654
|
+
for (let at = 8; at + 12 <= data.length; ) {
|
|
29655
|
+
const length = data.readUInt32BE(at), type = data.toString("latin1", at + 4, at + 8), body = at + 8;
|
|
29656
|
+
if (body + length + 4 > data.length) return null;
|
|
29657
|
+
if (type === "IHDR") {
|
|
29658
|
+
if (length !== 13) return null;
|
|
29659
|
+
width = data.readUInt32BE(body);
|
|
29660
|
+
height = data.readUInt32BE(body + 4);
|
|
29661
|
+
const depth = data[body + 8], color = data[body + 9], interlace = data[body + 12];
|
|
29662
|
+
channels = color === 0 ? 1 : color === 2 ? 3 : color === 4 ? 2 : color === 6 ? 4 : 0;
|
|
29663
|
+
if (depth !== 8 || !channels || interlace !== 0 || data[body + 10] !== 0 || data[body + 11] !== 0 || !sizeOk(width, height)) return null;
|
|
29664
|
+
} else if (type === "IDAT") idat.push(data.subarray(body, body + length));
|
|
29665
|
+
else if (type === "IEND") break;
|
|
29666
|
+
at = body + length + 4;
|
|
29667
|
+
}
|
|
29668
|
+
if (!channels || !idat.length) return null;
|
|
29669
|
+
const stride = width * channels, expected = (stride + 1) * height;
|
|
29670
|
+
let raw;
|
|
29671
|
+
try {
|
|
29672
|
+
raw = inflateSync(Buffer.concat(idat), { maxOutputLength: expected });
|
|
29673
|
+
} catch {
|
|
29674
|
+
return null;
|
|
29675
|
+
}
|
|
29676
|
+
if (raw.length !== expected) return null;
|
|
29677
|
+
const rgb = Buffer.alloc(width * height * 3);
|
|
29678
|
+
let previous = Buffer.alloc(stride), current2 = Buffer.alloc(stride);
|
|
29679
|
+
for (let y = 0; y < height; y++) {
|
|
29680
|
+
const filter = raw[y * (stride + 1)], line = raw.subarray(y * (stride + 1) + 1, (y + 1) * (stride + 1));
|
|
29681
|
+
for (let x = 0; x < stride; x++) {
|
|
29682
|
+
const a = x >= channels ? current2[x - channels] : 0, b = previous[x], c = x >= channels ? previous[x - channels] : 0;
|
|
29683
|
+
let value = line[x];
|
|
29684
|
+
if (filter === 1) value += a;
|
|
29685
|
+
else if (filter === 2) value += b;
|
|
29686
|
+
else if (filter === 3) value += a + b >> 1;
|
|
29687
|
+
else if (filter === 4) {
|
|
29688
|
+
const p = a + b - c, pa = Math.abs(p - a), pb = Math.abs(p - b), pc = Math.abs(p - c);
|
|
29689
|
+
value += pa <= pb && pa <= pc ? a : pb <= pc ? b : c;
|
|
29690
|
+
} else if (filter !== 0) return null;
|
|
29691
|
+
current2[x] = value & 255;
|
|
29692
|
+
}
|
|
29693
|
+
for (let x = 0, o = y * width * 3; x < width; x++, o += 3) {
|
|
29694
|
+
const i = x * channels;
|
|
29695
|
+
if (channels <= 2) rgb[o] = rgb[o + 1] = rgb[o + 2] = current2[i];
|
|
29696
|
+
else {
|
|
29697
|
+
rgb[o] = current2[i];
|
|
29698
|
+
rgb[o + 1] = current2[i + 1];
|
|
29699
|
+
rgb[o + 2] = current2[i + 2];
|
|
29700
|
+
}
|
|
29701
|
+
}
|
|
29702
|
+
[previous, current2] = [current2, previous];
|
|
29703
|
+
}
|
|
29704
|
+
return { width, height, rgb };
|
|
29705
|
+
}
|
|
29706
|
+
function decodeXwd(data) {
|
|
29707
|
+
if (data.length < 100) return null;
|
|
29708
|
+
const field = (index) => data.readUInt32BE(index * 4);
|
|
29709
|
+
const headerSize = field(0), version2 = field(1), format = field(2), width = field(4), height = field(5), byteOrder = field(7);
|
|
29710
|
+
const bitsPerPixel = field(11), bytesPerLine = field(12), visualClass = field(13), masks = [field(14), field(15), field(16)], colors = field(19);
|
|
29711
|
+
if (version2 !== 7 || format !== 2 || headerSize < 100 || ![4, 5].includes(visualClass) || ![24, 32].includes(bitsPerPixel) || !sizeOk(width, height) || colors > 65536) return null;
|
|
29712
|
+
const pixelBytes = bitsPerPixel / 8, start = headerSize + colors * 12;
|
|
29713
|
+
if (bytesPerLine < width * pixelBytes || start + bytesPerLine * height > data.length || masks.some((mask) => !mask)) return null;
|
|
29714
|
+
const shifts = masks.map((mask) => {
|
|
29715
|
+
let shift = 0;
|
|
29716
|
+
while (!(mask >>> shift & 1)) shift++;
|
|
29717
|
+
return shift;
|
|
29718
|
+
});
|
|
29719
|
+
const scales = masks.map((mask, i) => 255 / (mask >>> shifts[i]));
|
|
29720
|
+
const rgb = Buffer.alloc(width * height * 3);
|
|
29721
|
+
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) {
|
|
29722
|
+
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];
|
|
29723
|
+
for (let c = 0; c < 3; c++) rgb[o + c] = Math.round(((pixel & masks[c]) >>> 0 >>> shifts[c]) * scales[c]);
|
|
29724
|
+
}
|
|
29725
|
+
return { width, height, rgb };
|
|
29726
|
+
}
|
|
29727
|
+
function downscale(image, edge) {
|
|
29728
|
+
const scale = Math.min(1, edge / Math.max(image.width, image.height));
|
|
29729
|
+
if (scale >= 1) return image;
|
|
29730
|
+
const width = Math.max(1, Math.round(image.width * scale)), height = Math.max(1, Math.round(image.height * scale));
|
|
29731
|
+
const xs = Array.from({ length: width + 1 }, (_, x) => Math.min(image.width, Math.floor(x * image.width / width)));
|
|
29732
|
+
const ys = Array.from({ length: height + 1 }, (_, y) => Math.min(image.height, Math.floor(y * image.height / height)));
|
|
29733
|
+
const rgb = Buffer.alloc(width * height * 3), sums = new Float64Array(width * 3);
|
|
29734
|
+
for (let y = 0; y < height; y++) {
|
|
29735
|
+
sums.fill(0);
|
|
29736
|
+
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++) {
|
|
29737
|
+
const i = (sy * image.width + sx) * 3;
|
|
29738
|
+
sums[x * 3] = sums[x * 3] + image.rgb[i];
|
|
29739
|
+
sums[x * 3 + 1] = sums[x * 3 + 1] + image.rgb[i + 1];
|
|
29740
|
+
sums[x * 3 + 2] = sums[x * 3 + 2] + image.rgb[i + 2];
|
|
29741
|
+
}
|
|
29742
|
+
for (let x = 0; x < width; x++) {
|
|
29743
|
+
const count3 = (ys[y + 1] - ys[y]) * (xs[x + 1] - xs[x]);
|
|
29744
|
+
for (let c = 0; c < 3; c++) rgb[(y * width + x) * 3 + c] = Math.round(sums[x * 3 + c] / count3);
|
|
29745
|
+
}
|
|
29746
|
+
}
|
|
29747
|
+
return { width, height, rgb };
|
|
29748
|
+
}
|
|
29749
|
+
var ZIGZAG = [
|
|
29750
|
+
0,
|
|
29751
|
+
1,
|
|
29752
|
+
5,
|
|
29753
|
+
6,
|
|
29754
|
+
14,
|
|
29755
|
+
15,
|
|
29756
|
+
27,
|
|
29757
|
+
28,
|
|
29758
|
+
2,
|
|
29759
|
+
4,
|
|
29760
|
+
7,
|
|
29761
|
+
13,
|
|
29762
|
+
16,
|
|
29763
|
+
26,
|
|
29764
|
+
29,
|
|
29765
|
+
42,
|
|
29766
|
+
3,
|
|
29767
|
+
8,
|
|
29768
|
+
12,
|
|
29769
|
+
17,
|
|
29770
|
+
25,
|
|
29771
|
+
30,
|
|
29772
|
+
41,
|
|
29773
|
+
43,
|
|
29774
|
+
9,
|
|
29775
|
+
11,
|
|
29776
|
+
18,
|
|
29777
|
+
24,
|
|
29778
|
+
31,
|
|
29779
|
+
40,
|
|
29780
|
+
44,
|
|
29781
|
+
53,
|
|
29782
|
+
10,
|
|
29783
|
+
19,
|
|
29784
|
+
23,
|
|
29785
|
+
32,
|
|
29786
|
+
39,
|
|
29787
|
+
45,
|
|
29788
|
+
52,
|
|
29789
|
+
54,
|
|
29790
|
+
20,
|
|
29791
|
+
22,
|
|
29792
|
+
33,
|
|
29793
|
+
38,
|
|
29794
|
+
46,
|
|
29795
|
+
51,
|
|
29796
|
+
55,
|
|
29797
|
+
60,
|
|
29798
|
+
21,
|
|
29799
|
+
34,
|
|
29800
|
+
37,
|
|
29801
|
+
47,
|
|
29802
|
+
50,
|
|
29803
|
+
56,
|
|
29804
|
+
59,
|
|
29805
|
+
61,
|
|
29806
|
+
35,
|
|
29807
|
+
36,
|
|
29808
|
+
48,
|
|
29809
|
+
49,
|
|
29810
|
+
57,
|
|
29811
|
+
58,
|
|
29812
|
+
62,
|
|
29813
|
+
63
|
|
29814
|
+
];
|
|
29815
|
+
var LUMA_QUANT = [
|
|
29816
|
+
16,
|
|
29817
|
+
11,
|
|
29818
|
+
10,
|
|
29819
|
+
16,
|
|
29820
|
+
24,
|
|
29821
|
+
40,
|
|
29822
|
+
51,
|
|
29823
|
+
61,
|
|
29824
|
+
12,
|
|
29825
|
+
12,
|
|
29826
|
+
14,
|
|
29827
|
+
19,
|
|
29828
|
+
26,
|
|
29829
|
+
58,
|
|
29830
|
+
60,
|
|
29831
|
+
55,
|
|
29832
|
+
14,
|
|
29833
|
+
13,
|
|
29834
|
+
16,
|
|
29835
|
+
24,
|
|
29836
|
+
40,
|
|
29837
|
+
57,
|
|
29838
|
+
69,
|
|
29839
|
+
56,
|
|
29840
|
+
14,
|
|
29841
|
+
17,
|
|
29842
|
+
22,
|
|
29843
|
+
29,
|
|
29844
|
+
51,
|
|
29845
|
+
87,
|
|
29846
|
+
80,
|
|
29847
|
+
62,
|
|
29848
|
+
18,
|
|
29849
|
+
22,
|
|
29850
|
+
37,
|
|
29851
|
+
56,
|
|
29852
|
+
68,
|
|
29853
|
+
109,
|
|
29854
|
+
103,
|
|
29855
|
+
77,
|
|
29856
|
+
24,
|
|
29857
|
+
35,
|
|
29858
|
+
55,
|
|
29859
|
+
64,
|
|
29860
|
+
81,
|
|
29861
|
+
104,
|
|
29862
|
+
113,
|
|
29863
|
+
92,
|
|
29864
|
+
49,
|
|
29865
|
+
64,
|
|
29866
|
+
78,
|
|
29867
|
+
87,
|
|
29868
|
+
103,
|
|
29869
|
+
121,
|
|
29870
|
+
120,
|
|
29871
|
+
101,
|
|
29872
|
+
72,
|
|
29873
|
+
92,
|
|
29874
|
+
95,
|
|
29875
|
+
98,
|
|
29876
|
+
112,
|
|
29877
|
+
100,
|
|
29878
|
+
103,
|
|
29879
|
+
99
|
|
29880
|
+
];
|
|
29881
|
+
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)];
|
|
29882
|
+
var AC_LUMA_VALUES = [
|
|
29883
|
+
1,
|
|
29884
|
+
2,
|
|
29885
|
+
3,
|
|
29886
|
+
0,
|
|
29887
|
+
4,
|
|
29888
|
+
17,
|
|
29889
|
+
5,
|
|
29890
|
+
18,
|
|
29891
|
+
33,
|
|
29892
|
+
49,
|
|
29893
|
+
65,
|
|
29894
|
+
6,
|
|
29895
|
+
19,
|
|
29896
|
+
81,
|
|
29897
|
+
97,
|
|
29898
|
+
7,
|
|
29899
|
+
34,
|
|
29900
|
+
113,
|
|
29901
|
+
20,
|
|
29902
|
+
50,
|
|
29903
|
+
129,
|
|
29904
|
+
145,
|
|
29905
|
+
161,
|
|
29906
|
+
8,
|
|
29907
|
+
35,
|
|
29908
|
+
66,
|
|
29909
|
+
177,
|
|
29910
|
+
193,
|
|
29911
|
+
21,
|
|
29912
|
+
82,
|
|
29913
|
+
209,
|
|
29914
|
+
240,
|
|
29915
|
+
36,
|
|
29916
|
+
51,
|
|
29917
|
+
98,
|
|
29918
|
+
114,
|
|
29919
|
+
130,
|
|
29920
|
+
9,
|
|
29921
|
+
10,
|
|
29922
|
+
22,
|
|
29923
|
+
23,
|
|
29924
|
+
24,
|
|
29925
|
+
25,
|
|
29926
|
+
26,
|
|
29927
|
+
37,
|
|
29928
|
+
38,
|
|
29929
|
+
39,
|
|
29930
|
+
40,
|
|
29931
|
+
41,
|
|
29932
|
+
42,
|
|
29933
|
+
52,
|
|
29934
|
+
53,
|
|
29935
|
+
54,
|
|
29936
|
+
55,
|
|
29937
|
+
56,
|
|
29938
|
+
57,
|
|
29939
|
+
58,
|
|
29940
|
+
67,
|
|
29941
|
+
68,
|
|
29942
|
+
69,
|
|
29943
|
+
70,
|
|
29944
|
+
71,
|
|
29945
|
+
72,
|
|
29946
|
+
73,
|
|
29947
|
+
74,
|
|
29948
|
+
83,
|
|
29949
|
+
84,
|
|
29950
|
+
85,
|
|
29951
|
+
86,
|
|
29952
|
+
87,
|
|
29953
|
+
88,
|
|
29954
|
+
89,
|
|
29955
|
+
90,
|
|
29956
|
+
99,
|
|
29957
|
+
100,
|
|
29958
|
+
101,
|
|
29959
|
+
102,
|
|
29960
|
+
103,
|
|
29961
|
+
104,
|
|
29962
|
+
105,
|
|
29963
|
+
106,
|
|
29964
|
+
115,
|
|
29965
|
+
116,
|
|
29966
|
+
117,
|
|
29967
|
+
118,
|
|
29968
|
+
119,
|
|
29969
|
+
120,
|
|
29970
|
+
121,
|
|
29971
|
+
122,
|
|
29972
|
+
131,
|
|
29973
|
+
132,
|
|
29974
|
+
133,
|
|
29975
|
+
134,
|
|
29976
|
+
135,
|
|
29977
|
+
136,
|
|
29978
|
+
137,
|
|
29979
|
+
138,
|
|
29980
|
+
146,
|
|
29981
|
+
147,
|
|
29982
|
+
148,
|
|
29983
|
+
149,
|
|
29984
|
+
150,
|
|
29985
|
+
151,
|
|
29986
|
+
152,
|
|
29987
|
+
153,
|
|
29988
|
+
154,
|
|
29989
|
+
162,
|
|
29990
|
+
163,
|
|
29991
|
+
164,
|
|
29992
|
+
165,
|
|
29993
|
+
166,
|
|
29994
|
+
167,
|
|
29995
|
+
168,
|
|
29996
|
+
169,
|
|
29997
|
+
170,
|
|
29998
|
+
178,
|
|
29999
|
+
179,
|
|
30000
|
+
180,
|
|
30001
|
+
181,
|
|
30002
|
+
182,
|
|
30003
|
+
183,
|
|
30004
|
+
184,
|
|
30005
|
+
185,
|
|
30006
|
+
186,
|
|
30007
|
+
194,
|
|
30008
|
+
195,
|
|
30009
|
+
196,
|
|
30010
|
+
197,
|
|
30011
|
+
198,
|
|
30012
|
+
199,
|
|
30013
|
+
200,
|
|
30014
|
+
201,
|
|
30015
|
+
202,
|
|
30016
|
+
210,
|
|
30017
|
+
211,
|
|
30018
|
+
212,
|
|
30019
|
+
213,
|
|
30020
|
+
214,
|
|
30021
|
+
215,
|
|
30022
|
+
216,
|
|
30023
|
+
217,
|
|
30024
|
+
218,
|
|
30025
|
+
225,
|
|
30026
|
+
226,
|
|
30027
|
+
227,
|
|
30028
|
+
228,
|
|
30029
|
+
229,
|
|
30030
|
+
230,
|
|
30031
|
+
231,
|
|
30032
|
+
232,
|
|
30033
|
+
233,
|
|
30034
|
+
234,
|
|
30035
|
+
241,
|
|
30036
|
+
242,
|
|
30037
|
+
243,
|
|
30038
|
+
244,
|
|
30039
|
+
245,
|
|
30040
|
+
246,
|
|
30041
|
+
247,
|
|
30042
|
+
248,
|
|
30043
|
+
249,
|
|
30044
|
+
250
|
|
30045
|
+
];
|
|
30046
|
+
var AC_CHROMA_VALUES = [
|
|
30047
|
+
0,
|
|
30048
|
+
1,
|
|
30049
|
+
2,
|
|
30050
|
+
3,
|
|
30051
|
+
17,
|
|
30052
|
+
4,
|
|
30053
|
+
5,
|
|
30054
|
+
33,
|
|
30055
|
+
49,
|
|
30056
|
+
6,
|
|
30057
|
+
18,
|
|
30058
|
+
65,
|
|
30059
|
+
81,
|
|
30060
|
+
7,
|
|
30061
|
+
97,
|
|
30062
|
+
113,
|
|
30063
|
+
19,
|
|
30064
|
+
34,
|
|
30065
|
+
50,
|
|
30066
|
+
129,
|
|
30067
|
+
8,
|
|
30068
|
+
20,
|
|
30069
|
+
66,
|
|
30070
|
+
145,
|
|
30071
|
+
161,
|
|
30072
|
+
177,
|
|
30073
|
+
193,
|
|
30074
|
+
9,
|
|
30075
|
+
35,
|
|
30076
|
+
51,
|
|
30077
|
+
82,
|
|
30078
|
+
240,
|
|
30079
|
+
21,
|
|
30080
|
+
98,
|
|
30081
|
+
114,
|
|
30082
|
+
209,
|
|
30083
|
+
10,
|
|
30084
|
+
22,
|
|
30085
|
+
36,
|
|
30086
|
+
52,
|
|
30087
|
+
225,
|
|
30088
|
+
37,
|
|
30089
|
+
241,
|
|
30090
|
+
23,
|
|
30091
|
+
24,
|
|
30092
|
+
25,
|
|
30093
|
+
26,
|
|
30094
|
+
38,
|
|
30095
|
+
39,
|
|
30096
|
+
40,
|
|
30097
|
+
41,
|
|
30098
|
+
42,
|
|
30099
|
+
53,
|
|
30100
|
+
54,
|
|
30101
|
+
55,
|
|
30102
|
+
56,
|
|
30103
|
+
57,
|
|
30104
|
+
58,
|
|
30105
|
+
67,
|
|
30106
|
+
68,
|
|
30107
|
+
69,
|
|
30108
|
+
70,
|
|
30109
|
+
71,
|
|
30110
|
+
72,
|
|
30111
|
+
73,
|
|
30112
|
+
74,
|
|
30113
|
+
83,
|
|
30114
|
+
84,
|
|
30115
|
+
85,
|
|
30116
|
+
86,
|
|
30117
|
+
87,
|
|
30118
|
+
88,
|
|
30119
|
+
89,
|
|
30120
|
+
90,
|
|
30121
|
+
99,
|
|
30122
|
+
100,
|
|
30123
|
+
101,
|
|
30124
|
+
102,
|
|
30125
|
+
103,
|
|
30126
|
+
104,
|
|
30127
|
+
105,
|
|
30128
|
+
106,
|
|
30129
|
+
115,
|
|
30130
|
+
116,
|
|
30131
|
+
117,
|
|
30132
|
+
118,
|
|
30133
|
+
119,
|
|
30134
|
+
120,
|
|
30135
|
+
121,
|
|
30136
|
+
122,
|
|
30137
|
+
130,
|
|
30138
|
+
131,
|
|
30139
|
+
132,
|
|
30140
|
+
133,
|
|
30141
|
+
134,
|
|
30142
|
+
135,
|
|
30143
|
+
136,
|
|
30144
|
+
137,
|
|
30145
|
+
138,
|
|
30146
|
+
146,
|
|
30147
|
+
147,
|
|
30148
|
+
148,
|
|
30149
|
+
149,
|
|
30150
|
+
150,
|
|
30151
|
+
151,
|
|
30152
|
+
152,
|
|
30153
|
+
153,
|
|
30154
|
+
154,
|
|
30155
|
+
162,
|
|
30156
|
+
163,
|
|
30157
|
+
164,
|
|
30158
|
+
165,
|
|
30159
|
+
166,
|
|
30160
|
+
167,
|
|
30161
|
+
168,
|
|
30162
|
+
169,
|
|
30163
|
+
170,
|
|
30164
|
+
178,
|
|
30165
|
+
179,
|
|
30166
|
+
180,
|
|
30167
|
+
181,
|
|
30168
|
+
182,
|
|
30169
|
+
183,
|
|
30170
|
+
184,
|
|
30171
|
+
185,
|
|
30172
|
+
186,
|
|
30173
|
+
194,
|
|
30174
|
+
195,
|
|
30175
|
+
196,
|
|
30176
|
+
197,
|
|
30177
|
+
198,
|
|
30178
|
+
199,
|
|
30179
|
+
200,
|
|
30180
|
+
201,
|
|
30181
|
+
202,
|
|
30182
|
+
210,
|
|
30183
|
+
211,
|
|
30184
|
+
212,
|
|
30185
|
+
213,
|
|
30186
|
+
214,
|
|
30187
|
+
215,
|
|
30188
|
+
216,
|
|
30189
|
+
217,
|
|
30190
|
+
218,
|
|
30191
|
+
226,
|
|
30192
|
+
227,
|
|
30193
|
+
228,
|
|
30194
|
+
229,
|
|
30195
|
+
230,
|
|
30196
|
+
231,
|
|
30197
|
+
232,
|
|
30198
|
+
233,
|
|
30199
|
+
234,
|
|
30200
|
+
242,
|
|
30201
|
+
243,
|
|
30202
|
+
244,
|
|
30203
|
+
245,
|
|
30204
|
+
246,
|
|
30205
|
+
247,
|
|
30206
|
+
248,
|
|
30207
|
+
249,
|
|
30208
|
+
250
|
|
30209
|
+
];
|
|
30210
|
+
var DC_VALUES = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
|
|
30211
|
+
var HUFFMAN = [
|
|
30212
|
+
[0, [0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0], DC_VALUES],
|
|
30213
|
+
[16, [0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 125], AC_LUMA_VALUES],
|
|
30214
|
+
[1, [0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0], DC_VALUES],
|
|
30215
|
+
[17, [0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 119], AC_CHROMA_VALUES]
|
|
30216
|
+
];
|
|
30217
|
+
var CODES = HUFFMAN.map(([, counts, values]) => {
|
|
30218
|
+
const table2 = [];
|
|
30219
|
+
let code = 0, at = 0;
|
|
30220
|
+
counts.forEach((count3, index) => {
|
|
30221
|
+
for (let i = 0; i < count3; i++) table2[values[at++]] = [code++, index + 1];
|
|
30222
|
+
code <<= 1;
|
|
30223
|
+
});
|
|
30224
|
+
return table2;
|
|
30225
|
+
});
|
|
30226
|
+
var AAN = [1, 1.387039845, 1.306562965, 1.175875602, 1, 0.785694958, 0.5411961, 0.275899379];
|
|
30227
|
+
function quantTables(quality) {
|
|
30228
|
+
const factor = quality < 50 ? 5e3 / quality : 200 - quality * 2;
|
|
30229
|
+
const scaled = (base) => base.map((value) => Math.min(255, Math.max(1, Math.floor((value * factor + 50) / 100))));
|
|
30230
|
+
const divisors = (table2) => Float64Array.from(table2, (value, k) => 1 / (value * AAN[k >> 3] * AAN[k & 7] * 8));
|
|
30231
|
+
const luma = scaled(LUMA_QUANT), chroma = scaled(CHROMA_QUANT);
|
|
30232
|
+
return { luma, chroma, lumaDivisors: divisors(luma), chromaDivisors: divisors(chroma) };
|
|
30233
|
+
}
|
|
30234
|
+
var BitWriter = class {
|
|
30235
|
+
buffer = Buffer.alloc(65536);
|
|
30236
|
+
length = 0;
|
|
30237
|
+
bits = 0;
|
|
30238
|
+
count = 0;
|
|
30239
|
+
byte(value) {
|
|
30240
|
+
if (this.length === this.buffer.length) {
|
|
30241
|
+
const next = Buffer.alloc(this.buffer.length * 2);
|
|
30242
|
+
this.buffer.copy(next);
|
|
30243
|
+
this.buffer = next;
|
|
30244
|
+
}
|
|
30245
|
+
this.buffer[this.length++] = value;
|
|
30246
|
+
}
|
|
30247
|
+
bytes(values) {
|
|
30248
|
+
for (const value of values) this.byte(value);
|
|
30249
|
+
}
|
|
30250
|
+
write(code, length) {
|
|
30251
|
+
this.bits = (this.bits << length | code) >>> 0;
|
|
30252
|
+
this.count += length;
|
|
30253
|
+
while (this.count >= 8) {
|
|
30254
|
+
const value = this.bits >>> this.count - 8 & 255;
|
|
30255
|
+
this.byte(value);
|
|
30256
|
+
if (value === 255) this.byte(0);
|
|
30257
|
+
this.count -= 8;
|
|
30258
|
+
this.bits &= (1 << this.count) - 1;
|
|
30259
|
+
}
|
|
30260
|
+
}
|
|
30261
|
+
flush() {
|
|
30262
|
+
if (this.count > 0) this.write((1 << 8 - this.count) - 1, 8 - this.count);
|
|
30263
|
+
}
|
|
30264
|
+
result() {
|
|
30265
|
+
return Buffer.from(this.buffer.subarray(0, this.length));
|
|
30266
|
+
}
|
|
30267
|
+
};
|
|
30268
|
+
function transform2(block, divisors, out) {
|
|
30269
|
+
for (let pass = 0; pass < 2; pass++) for (let i = 0; i < 8; i++) {
|
|
30270
|
+
const step = pass ? 8 : 1, base = pass ? i : i * 8, at = (k) => base + k * step;
|
|
30271
|
+
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)];
|
|
30272
|
+
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;
|
|
30273
|
+
const t10 = t0 + t3, t13 = t0 - t3, t11 = t1 + t2, t12 = t1 - t2;
|
|
30274
|
+
block[at(0)] = t10 + t11;
|
|
30275
|
+
block[at(4)] = t10 - t11;
|
|
30276
|
+
const z1 = (t12 + t13) * 0.707106781;
|
|
30277
|
+
block[at(2)] = t13 + z1;
|
|
30278
|
+
block[at(6)] = t13 - z1;
|
|
30279
|
+
const o10 = t4 + t5, o11 = t5 + t6, o12 = t6 + t7;
|
|
30280
|
+
const z5 = (o10 - o12) * 0.382683433, z2 = 0.5411961 * o10 + z5, z4 = 1.306562965 * o12 + z5, z3 = o11 * 0.707106781;
|
|
30281
|
+
const z11 = t7 + z3, z13 = t7 - z3;
|
|
30282
|
+
block[at(5)] = z13 + z2;
|
|
30283
|
+
block[at(3)] = z13 - z2;
|
|
30284
|
+
block[at(1)] = z11 + z4;
|
|
30285
|
+
block[at(7)] = z11 - z4;
|
|
30286
|
+
}
|
|
30287
|
+
for (let k = 0; k < 64; k++) out[ZIGZAG[k]] = Math.round(block[k] * divisors[k]);
|
|
30288
|
+
}
|
|
30289
|
+
function magnitude(value) {
|
|
30290
|
+
const absolute2 = Math.abs(value);
|
|
30291
|
+
let length = 0;
|
|
30292
|
+
while (absolute2 >> length) length++;
|
|
30293
|
+
return [value < 0 ? value + (1 << length) - 1 : value, length];
|
|
30294
|
+
}
|
|
30295
|
+
function encodeJpeg(image, quality) {
|
|
30296
|
+
const { width, height, rgb } = image, tables = quantTables(Math.min(100, Math.max(1, Math.round(quality))));
|
|
30297
|
+
const out = new BitWriter(), word = (value) => [value >> 8, value & 255];
|
|
30298
|
+
out.bytes([255, 216, 255, 224, 0, 16, 74, 70, 73, 70, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0]);
|
|
30299
|
+
out.bytes([255, 219, 0, 132]);
|
|
30300
|
+
for (const [id2, table2] of [[0, tables.luma], [1, tables.chroma]]) {
|
|
30301
|
+
const zig = new Array(64);
|
|
30302
|
+
table2.forEach((value, k) => {
|
|
30303
|
+
zig[ZIGZAG[k]] = value;
|
|
30304
|
+
});
|
|
30305
|
+
out.bytes([id2, ...zig]);
|
|
30306
|
+
}
|
|
30307
|
+
out.bytes([255, 192, 0, 17, 8, ...word(height), ...word(width), 3, 1, 34, 0, 2, 17, 1, 3, 17, 1]);
|
|
30308
|
+
out.bytes([255, 196, ...word(2 + HUFFMAN.reduce((sum, [, , values]) => sum + 17 + values.length, 0))]);
|
|
30309
|
+
for (const [id2, counts, values] of HUFFMAN) out.bytes([id2, ...counts, ...values]);
|
|
30310
|
+
out.bytes([255, 218, 0, 12, 3, 1, 0, 2, 17, 3, 17, 0, 63, 0]);
|
|
30311
|
+
const block = new Float64Array(64), coefficients = new Int32Array(64), dc = [0, 0, 0];
|
|
30312
|
+
const Y = new Float64Array(256), Cb = new Float64Array(256), Cr = new Float64Array(256);
|
|
30313
|
+
const encode5 = (component, divisors) => {
|
|
30314
|
+
transform2(block, divisors, coefficients);
|
|
30315
|
+
const dcCodes = CODES[component ? 2 : 0], acCodes = CODES[component ? 3 : 1];
|
|
30316
|
+
const diff = coefficients[0] - dc[component];
|
|
30317
|
+
dc[component] = coefficients[0];
|
|
30318
|
+
const [bits, size] = magnitude(diff);
|
|
30319
|
+
out.write(...dcCodes[size]);
|
|
30320
|
+
if (size) out.write(bits, size);
|
|
30321
|
+
let last = 63;
|
|
30322
|
+
while (last > 0 && coefficients[last] === 0) last--;
|
|
30323
|
+
for (let k = 1, zeros = 0; k <= last; k++) {
|
|
30324
|
+
if (coefficients[k] === 0) {
|
|
30325
|
+
zeros++;
|
|
30326
|
+
continue;
|
|
30327
|
+
}
|
|
30328
|
+
while (zeros >= 16) {
|
|
30329
|
+
out.write(...acCodes[240]);
|
|
30330
|
+
zeros -= 16;
|
|
30331
|
+
}
|
|
30332
|
+
const [value, length] = magnitude(coefficients[k]);
|
|
30333
|
+
out.write(...acCodes[(zeros << 4) + length]);
|
|
30334
|
+
out.write(value, length);
|
|
30335
|
+
zeros = 0;
|
|
30336
|
+
}
|
|
30337
|
+
if (last < 63) out.write(...acCodes[0]);
|
|
30338
|
+
};
|
|
30339
|
+
for (let my = 0; my < height; my += 16) for (let mx = 0; mx < width; mx += 16) {
|
|
30340
|
+
for (let y = 0; y < 16; y++) for (let x = 0; x < 16; x++) {
|
|
30341
|
+
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];
|
|
30342
|
+
Y[y * 16 + x] = 0.299 * r + 0.587 * g + 0.114 * b - 128;
|
|
30343
|
+
Cb[y * 16 + x] = -0.168736 * r - 0.331264 * g + 0.5 * b;
|
|
30344
|
+
Cr[y * 16 + x] = 0.5 * r - 0.418688 * g - 0.081312 * b;
|
|
30345
|
+
}
|
|
30346
|
+
for (const [ox, oy] of [[0, 0], [8, 0], [0, 8], [8, 8]]) {
|
|
30347
|
+
for (let y = 0; y < 8; y++) for (let x = 0; x < 8; x++) block[y * 8 + x] = Y[(oy + y) * 16 + ox + x];
|
|
30348
|
+
encode5(0, tables.lumaDivisors);
|
|
30349
|
+
}
|
|
30350
|
+
for (const [component, plane] of [[1, Cb], [2, Cr]]) {
|
|
30351
|
+
for (let y = 0; y < 8; y++) for (let x = 0; x < 8; x++) {
|
|
30352
|
+
const at = y * 32 + x * 2;
|
|
30353
|
+
block[y * 8 + x] = (plane[at] + plane[at + 1] + plane[at + 16] + plane[at + 17]) / 4;
|
|
30354
|
+
}
|
|
30355
|
+
encode5(component, tables.chromaDivisors);
|
|
30356
|
+
}
|
|
30357
|
+
}
|
|
30358
|
+
out.flush();
|
|
30359
|
+
out.bytes([255, 217]);
|
|
30360
|
+
return out.result();
|
|
30361
|
+
}
|
|
30362
|
+
function fitJpeg(image, maxEdge, maxBytes) {
|
|
30363
|
+
for (const edge of [maxEdge, 1280, 1024, 800, 640]) {
|
|
30364
|
+
const scaled = downscale(image, edge);
|
|
30365
|
+
for (const quality of [75, 60, 45, 35]) {
|
|
30366
|
+
const data = encodeJpeg(scaled, quality);
|
|
30367
|
+
if (data.length <= maxBytes) return { data, width: scaled.width, height: scaled.height };
|
|
30368
|
+
}
|
|
30369
|
+
}
|
|
30370
|
+
return null;
|
|
30371
|
+
}
|
|
30372
|
+
|
|
30373
|
+
// agent/src/screen-capture.ts
|
|
30374
|
+
var SCREENSHOT_MAX_JPEG_BYTES = 131072;
|
|
30375
|
+
var SCREENSHOT_MAX_EDGE = 1568;
|
|
30376
|
+
function screenshotEnabled(env = process.env) {
|
|
30377
|
+
return env.LC_SCREENSHOT_ENABLED === "true";
|
|
30378
|
+
}
|
|
30379
|
+
var SCREENSHOT_ACCEPTANCE_FILE = "screenshot-acceptance-enabled";
|
|
30380
|
+
var SCREENSHOT_OWNER_OFF_FILE = "screenshot-disabled-by-owner";
|
|
30381
|
+
var ScreenCaptureError = class extends Error {
|
|
30382
|
+
constructor(code, detail) {
|
|
30383
|
+
super(code);
|
|
30384
|
+
this.code = code;
|
|
30385
|
+
this.detail = detail;
|
|
30386
|
+
this.name = "ScreenCaptureError";
|
|
30387
|
+
}
|
|
30388
|
+
code;
|
|
30389
|
+
detail;
|
|
30390
|
+
};
|
|
30391
|
+
var KNOWN = /^(SCREEN_UNAVAILABLE|SCREEN_LOCKED|SCREEN_ENCODER_UNAVAILABLE|SCREENSHOT_TOO_LARGE|ARGUMENT_INVALID)$/;
|
|
30392
|
+
function jpegSize(data) {
|
|
30393
|
+
if (data.length < 4 || data[0] !== 255 || data[1] !== 216 || data[data.length - 2] !== 255 || data[data.length - 1] !== 217) return null;
|
|
30394
|
+
for (let at = 2; at + 9 < data.length; ) {
|
|
30395
|
+
if (data[at] !== 255) return null;
|
|
30396
|
+
const marker = data[at + 1], length = data.readUInt16BE(at + 2);
|
|
30397
|
+
if (marker >= 192 && marker <= 207 && ![196, 200, 204].includes(marker)) {
|
|
30398
|
+
const height = data.readUInt16BE(at + 5), width = data.readUInt16BE(at + 7);
|
|
30399
|
+
return width > 0 && height > 0 ? { width, height } : null;
|
|
30400
|
+
}
|
|
30401
|
+
at += 2 + length;
|
|
30402
|
+
}
|
|
30403
|
+
return null;
|
|
30404
|
+
}
|
|
30405
|
+
function run(file2, args, signal, maxBuffer = 65536, env = buildChildEnvironment(process.env, process.platform)) {
|
|
30406
|
+
return new Promise((resolve, reject) => {
|
|
30407
|
+
execFile4(
|
|
30408
|
+
file2,
|
|
30409
|
+
args,
|
|
30410
|
+
{ encoding: "buffer", timeout: 15e3, maxBuffer, windowsHide: true, shell: false, env, signal },
|
|
30411
|
+
(error62, stdout, stderr) => error62 ? reject(Object.assign(error62, { stdout, stderr })) : resolve({ stdout, stderr })
|
|
30412
|
+
);
|
|
30413
|
+
});
|
|
30414
|
+
}
|
|
30415
|
+
async function windows(bridge, signal) {
|
|
30416
|
+
if (!path17.isAbsolute(bridge)) throw new ScreenCaptureError("SCREEN_UNAVAILABLE");
|
|
30417
|
+
let stdout;
|
|
30418
|
+
try {
|
|
30419
|
+
({ stdout } = await run(bridge, ["screenshot", String(SCREENSHOT_MAX_EDGE), String(SCREENSHOT_MAX_JPEG_BYTES)], signal, 262144));
|
|
30420
|
+
} catch (error62) {
|
|
30421
|
+
if (signal.aborted) throw new ScreenCaptureError("CANCELLED");
|
|
30422
|
+
const code = /^\{"error":"([A-Z_]+)"\}$/.exec(String(error62.stderr ?? ""))?.[1];
|
|
30423
|
+
throw new ScreenCaptureError(code && KNOWN.test(code) ? code : "SCREEN_UNAVAILABLE");
|
|
30424
|
+
}
|
|
30425
|
+
try {
|
|
30426
|
+
const value = JSON.parse(stdout.toString("utf8"));
|
|
30427
|
+
const data = Buffer.from(value.data, "base64"), size = jpegSize(data);
|
|
30428
|
+
if (!size || size.width !== value.width || size.height !== value.height || !Number.isSafeInteger(value.sourceWidth) || !Number.isSafeInteger(value.sourceHeight)) throw Error();
|
|
30429
|
+
return { data, width: size.width, height: size.height, sourceWidth: value.sourceWidth, sourceHeight: value.sourceHeight };
|
|
30430
|
+
} catch {
|
|
30431
|
+
throw new ScreenCaptureError("SCREEN_UNAVAILABLE");
|
|
30432
|
+
}
|
|
30433
|
+
}
|
|
30434
|
+
async function mac3(signal) {
|
|
30435
|
+
try {
|
|
30436
|
+
const preflight = await run("/usr/bin/osascript", ["-l", "JavaScript", "-e", "ObjC.import('CoreGraphics'); $.CGPreflightScreenCaptureAccess()"], signal);
|
|
30437
|
+
if (preflight.stdout.toString("utf8").trim() !== "true") {
|
|
30438
|
+
await run("/usr/bin/osascript", ["-l", "JavaScript", "-e", "ObjC.import('CoreGraphics'); $.CGRequestScreenCaptureAccess()"], signal).catch(() => {
|
|
30439
|
+
});
|
|
30440
|
+
throw new ScreenCaptureError("SCREEN_RECORDING_PERMISSION_REQUIRED");
|
|
30441
|
+
}
|
|
30442
|
+
} catch (error62) {
|
|
30443
|
+
if (error62 instanceof ScreenCaptureError) throw error62;
|
|
30444
|
+
throw new ScreenCaptureError(signal.aborted ? "CANCELLED" : "SCREEN_UNAVAILABLE");
|
|
30445
|
+
}
|
|
30446
|
+
const folder = await mkdtemp(path17.join(os4.tmpdir(), "lc-screen-"));
|
|
30447
|
+
try {
|
|
30448
|
+
const full = path17.join(folder, "full.png"), small = path17.join(folder, "small.jpg");
|
|
30449
|
+
try {
|
|
30450
|
+
await run("/usr/sbin/screencapture", ["-x", "-m", "-t", "png", full], signal);
|
|
30451
|
+
} catch {
|
|
30452
|
+
throw new ScreenCaptureError(signal.aborted ? "CANCELLED" : "SCREEN_UNAVAILABLE");
|
|
30453
|
+
}
|
|
30454
|
+
const source = (await run("/usr/bin/sips", ["-g", "pixelWidth", "-g", "pixelHeight", full], signal)).stdout.toString("utf8");
|
|
30455
|
+
const sourceWidth = Number(/pixelWidth: (\d+)/.exec(source)?.[1]), sourceHeight = Number(/pixelHeight: (\d+)/.exec(source)?.[1]);
|
|
30456
|
+
if (!sourceWidth || !sourceHeight) throw new ScreenCaptureError("SCREEN_UNAVAILABLE");
|
|
30457
|
+
for (const edge of [SCREENSHOT_MAX_EDGE, 1280, 1024, 800, 640]) {
|
|
30458
|
+
const target = Math.min(edge, Math.max(sourceWidth, sourceHeight));
|
|
30459
|
+
for (const quality of [75, 60, 45, 35]) {
|
|
30460
|
+
await run("/usr/bin/sips", ["-Z", String(target), "-s", "format", "jpeg", "-s", "formatOptions", String(quality), full, "--out", small], signal);
|
|
30461
|
+
const data = await readFile6(small), size = jpegSize(data);
|
|
30462
|
+
if (!size) throw new ScreenCaptureError("SCREEN_UNAVAILABLE");
|
|
30463
|
+
if (data.length <= SCREENSHOT_MAX_JPEG_BYTES) return { data, ...size, sourceWidth, sourceHeight };
|
|
30464
|
+
}
|
|
30465
|
+
}
|
|
30466
|
+
throw new ScreenCaptureError("SCREENSHOT_TOO_LARGE");
|
|
30467
|
+
} catch (error62) {
|
|
30468
|
+
if (error62 instanceof ScreenCaptureError) throw error62;
|
|
30469
|
+
throw new ScreenCaptureError(signal.aborted ? "CANCELLED" : "SCREEN_UNAVAILABLE");
|
|
30470
|
+
} finally {
|
|
30471
|
+
await rm5(folder, { recursive: true, force: true }).catch(() => {
|
|
30472
|
+
});
|
|
30473
|
+
}
|
|
30474
|
+
}
|
|
30475
|
+
var SESSION_KEYS = ["DISPLAY", "WAYLAND_DISPLAY", "XAUTHORITY", "XDG_RUNTIME_DIR", "DBUS_SESSION_BUS_ADDRESS", "XDG_SESSION_TYPE", "XDG_CURRENT_DESKTOP"];
|
|
30476
|
+
var SESSION_VALUE = /^[A-Za-z0-9_.:,;=@+/-]{1,256}$/;
|
|
30477
|
+
var LINUX_SOURCE_BYTES = 150994944;
|
|
30478
|
+
async function linuxTool(name2) {
|
|
30479
|
+
for (const directory of ["/usr/bin", "/bin", "/usr/local/bin"]) {
|
|
30480
|
+
const file2 = path17.posix.join(directory, name2);
|
|
30481
|
+
try {
|
|
30482
|
+
await access3(file2, constants7.X_OK);
|
|
30483
|
+
return file2;
|
|
30484
|
+
} catch {
|
|
30485
|
+
}
|
|
30486
|
+
}
|
|
30487
|
+
return null;
|
|
30488
|
+
}
|
|
30489
|
+
async function linuxSession(signal) {
|
|
30490
|
+
const session = {}, uid = process.getuid?.();
|
|
30491
|
+
const take = (key, value) => {
|
|
30492
|
+
if (value && !session[key] && SESSION_VALUE.test(value)) session[key] = value;
|
|
30493
|
+
};
|
|
30494
|
+
const base = buildChildEnvironment(process.env, "linux");
|
|
30495
|
+
for (const key of SESSION_KEYS) take(key, process.env[key]);
|
|
30496
|
+
if (!session.DISPLAY && !session.WAYLAND_DISPLAY) {
|
|
30497
|
+
const systemctl = await linuxTool("systemctl");
|
|
30498
|
+
if (systemctl) try {
|
|
30499
|
+
const { stdout } = await run(systemctl, ["--user", "show-environment"], signal, 262144, base);
|
|
30500
|
+
for (const line of stdout.toString("utf8").split("\n")) {
|
|
30501
|
+
const at = line.indexOf("=");
|
|
30502
|
+
if (at > 0 && SESSION_KEYS.includes(line.slice(0, at))) take(line.slice(0, at), line.slice(at + 1));
|
|
30503
|
+
}
|
|
30504
|
+
} catch {
|
|
30505
|
+
if (signal.aborted) throw new ScreenCaptureError("CANCELLED");
|
|
30506
|
+
}
|
|
30507
|
+
}
|
|
30508
|
+
if (uid !== void 0) take("XDG_RUNTIME_DIR", "/run/user/" + uid);
|
|
30509
|
+
if (!session.DISPLAY && !session.WAYLAND_DISPLAY) {
|
|
30510
|
+
if (session.XDG_RUNTIME_DIR) for (const name2 of ["wayland-0", "wayland-1"]) {
|
|
30511
|
+
const socket = await lstat7(path17.posix.join(session.XDG_RUNTIME_DIR, name2)).catch(() => null);
|
|
30512
|
+
if (socket?.isSocket() && socket.uid === uid) {
|
|
30513
|
+
session.WAYLAND_DISPLAY = name2;
|
|
30514
|
+
break;
|
|
30515
|
+
}
|
|
30516
|
+
}
|
|
30517
|
+
if (!session.WAYLAND_DISPLAY) {
|
|
30518
|
+
const servers = [];
|
|
30519
|
+
for (const name2 of await readdir4("/tmp/.X11-unix").catch(() => [])) {
|
|
30520
|
+
const n = /^X(\d{1,4})$/.exec(name2)?.[1], socket = n ? await lstat7("/tmp/.X11-unix/" + name2).catch(() => null) : null;
|
|
30521
|
+
if (n && socket?.isSocket()) servers.push({ n: Number(n), own: socket.uid === uid });
|
|
30522
|
+
}
|
|
30523
|
+
const server = servers.sort((a, b) => Number(b.own) - Number(a.own) || a.n - b.n)[0];
|
|
30524
|
+
if (server) session.DISPLAY = ":" + server.n;
|
|
30525
|
+
}
|
|
30526
|
+
}
|
|
30527
|
+
if (session.DISPLAY && !session.XAUTHORITY) {
|
|
30528
|
+
const file2 = path17.posix.join(os4.homedir(), ".Xauthority");
|
|
30529
|
+
if ((await lstat7(file2).catch(() => null))?.isFile()) take("XAUTHORITY", file2);
|
|
30530
|
+
}
|
|
30531
|
+
if (session.XDG_RUNTIME_DIR) take("DBUS_SESSION_BUS_ADDRESS", "unix:path=" + session.XDG_RUNTIME_DIR + "/bus");
|
|
30532
|
+
const wayland = !!session.WAYLAND_DISPLAY || session.XDG_SESSION_TYPE === "wayland";
|
|
30533
|
+
return { env: { ...base, ...session }, wayland, x11: !wayland && !!session.DISPLAY };
|
|
30534
|
+
}
|
|
30535
|
+
async function busSocket(env) {
|
|
30536
|
+
const socket = sessionBusSocket(env.DBUS_SESSION_BUS_ADDRESS);
|
|
30537
|
+
if (!socket || socket.startsWith("\0")) return socket;
|
|
30538
|
+
return (await lstat7(socket).catch(() => null))?.isSocket() ? socket : null;
|
|
30539
|
+
}
|
|
30540
|
+
async function portalCapture(socket, signal) {
|
|
30541
|
+
const token = "lc" + randomBytes6(8).toString("hex"), started = Date.now(), uid = process.getuid?.();
|
|
30542
|
+
if (uid === void 0) throw new ScreenCaptureError("SCREEN_UNAVAILABLE");
|
|
30543
|
+
let answer;
|
|
30544
|
+
try {
|
|
30545
|
+
answer = await portalScreenshot(socket, uid, token, AbortSignal.any([signal, AbortSignal.timeout(3e4)]));
|
|
30546
|
+
} catch {
|
|
30547
|
+
throw new ScreenCaptureError(signal.aborted ? "CANCELLED" : "SCREEN_UNAVAILABLE");
|
|
30548
|
+
}
|
|
30549
|
+
const { code, uri } = answer;
|
|
30550
|
+
if (code === 1) throw new ScreenCaptureError("SCREEN_RECORDING_PERMISSION_REQUIRED");
|
|
30551
|
+
if (code !== 0 || !uri?.startsWith("file://")) throw new ScreenCaptureError("SCREEN_UNAVAILABLE");
|
|
30552
|
+
const file2 = decodeURIComponent(new URL(uri).pathname), info = await lstat7(file2);
|
|
30553
|
+
const fresh = info.isFile() && info.uid === uid && info.mtimeMs >= started - 5e3;
|
|
30554
|
+
try {
|
|
30555
|
+
if (!fresh || info.size > LINUX_SOURCE_BYTES) throw new ScreenCaptureError("SCREEN_UNAVAILABLE");
|
|
30556
|
+
return await readFile6(file2);
|
|
30557
|
+
} finally {
|
|
30558
|
+
if (fresh) await unlink2(file2).catch(() => {
|
|
30559
|
+
});
|
|
30560
|
+
}
|
|
30561
|
+
}
|
|
30562
|
+
async function linux(signal) {
|
|
30563
|
+
const session = await linuxSession(signal);
|
|
30564
|
+
if (!session.wayland && !session.x11) throw new ScreenCaptureError("SCREENSHOT_UNSUPPORTED", { reason: "NO_DISPLAY" });
|
|
30565
|
+
const output2 = (args) => async (tool) => (await run(tool, args, signal, LINUX_SOURCE_BYTES, session.env)).stdout;
|
|
30566
|
+
const portal = (socket) => portalCapture(socket, signal);
|
|
30567
|
+
const methods = session.wayland ? [["grim", "grim", output2(["-t", "png", "-"])], ["portal", "", portal]] : [
|
|
30568
|
+
["xwd", "xwd", output2(["-root", "-silent"])],
|
|
30569
|
+
["import", "import", output2(["-silent", "-window", "root", "png:-"])],
|
|
30570
|
+
["maim", "maim", output2(["-f", "png"])],
|
|
30571
|
+
["portal", "", portal]
|
|
30572
|
+
];
|
|
30573
|
+
const tried = [];
|
|
30574
|
+
for (const [name2, program, capture2] of methods) {
|
|
30575
|
+
const tool = program ? await linuxTool(program) : await busSocket(session.env);
|
|
30576
|
+
if (!tool) {
|
|
30577
|
+
tried.push(name2 + ":missing");
|
|
30578
|
+
continue;
|
|
30579
|
+
}
|
|
30580
|
+
let image;
|
|
30581
|
+
try {
|
|
30582
|
+
const source = await capture2(tool);
|
|
30583
|
+
image = decodePng(source) ?? decodeXwd(source);
|
|
30584
|
+
} catch (error62) {
|
|
30585
|
+
if (signal.aborted) throw new ScreenCaptureError("CANCELLED");
|
|
30586
|
+
if (error62 instanceof ScreenCaptureError && error62.code === "SCREEN_RECORDING_PERMISSION_REQUIRED") throw error62;
|
|
30587
|
+
tried.push(name2 + ":failed");
|
|
30588
|
+
continue;
|
|
30589
|
+
}
|
|
30590
|
+
if (!image) {
|
|
30591
|
+
tried.push(name2 + ":unreadable");
|
|
30592
|
+
continue;
|
|
30593
|
+
}
|
|
30594
|
+
const fitted = fitJpeg(image, SCREENSHOT_MAX_EDGE, SCREENSHOT_MAX_JPEG_BYTES);
|
|
30595
|
+
if (!fitted) throw new ScreenCaptureError("SCREENSHOT_TOO_LARGE");
|
|
30596
|
+
return { ...fitted, sourceWidth: image.width, sourceHeight: image.height };
|
|
30597
|
+
}
|
|
30598
|
+
throw new ScreenCaptureError("SCREENSHOT_UNSUPPORTED", {
|
|
30599
|
+
reason: tried.every((entry) => entry.endsWith(":missing")) ? "NO_CAPTURE_TOOL" : "CAPTURE_FAILED",
|
|
30600
|
+
session: session.wayland ? "wayland" : "x11",
|
|
30601
|
+
tried
|
|
30602
|
+
});
|
|
30603
|
+
}
|
|
30604
|
+
async function captureScreen(options) {
|
|
30605
|
+
if (options.signal.aborted) throw new ScreenCaptureError("CANCELLED");
|
|
30606
|
+
if (process.platform === "win32") return windows(options.ownerBridgePath, options.signal);
|
|
30607
|
+
if (process.platform === "darwin") return mac3(options.signal);
|
|
30608
|
+
if (process.platform === "linux") return linux(options.signal);
|
|
30609
|
+
throw new ScreenCaptureError("SCREENSHOT_UNSUPPORTED", { reason: "PLATFORM_UNSUPPORTED" });
|
|
30610
|
+
}
|
|
30611
|
+
|
|
29338
30612
|
// agent/src/tools.ts
|
|
29339
30613
|
var NativeToolError = class extends Error {
|
|
29340
30614
|
constructor(code) {
|
|
@@ -29365,7 +30639,7 @@ function stopped(signal) {
|
|
|
29365
30639
|
if (signal.aborted) fail3("CANCELLED");
|
|
29366
30640
|
}
|
|
29367
30641
|
async function readBoundedFile(file2, maxBytes, bridge, signal) {
|
|
29368
|
-
const stat2 = await
|
|
30642
|
+
const stat2 = await lstat8(file2);
|
|
29369
30643
|
if (!stat2.isFile() || stat2.isSymbolicLink() || stat2.size > maxBytes) fail3("FILE_UNSUPPORTED_OR_TOO_LARGE");
|
|
29370
30644
|
if (process.platform === "win32") {
|
|
29371
30645
|
if (maxBytes <= 1048576 || stat2.size <= 1048576) return readWindowsFile(bridge, file2, Math.min(maxBytes, 1048576), signal);
|
|
@@ -29373,7 +30647,7 @@ async function readBoundedFile(file2, maxBytes, bridge, signal) {
|
|
|
29373
30647
|
if (read.truncated) fail3("FILE_UNSUPPORTED_OR_TOO_LARGE");
|
|
29374
30648
|
return read.data;
|
|
29375
30649
|
}
|
|
29376
|
-
const handle = await open6(file2,
|
|
30650
|
+
const handle = await open6(file2, constants8.O_RDONLY | (constants8.O_NOFOLLOW ?? 0));
|
|
29377
30651
|
try {
|
|
29378
30652
|
const current2 = await handle.stat();
|
|
29379
30653
|
if (!current2.isFile() || current2.size > maxBytes) fail3("FILE_UNSUPPORTED_OR_TOO_LARGE");
|
|
@@ -29425,13 +30699,13 @@ var NativeTools = class {
|
|
|
29425
30699
|
constructor(options) {
|
|
29426
30700
|
this.options = options;
|
|
29427
30701
|
this.options = structuredClone(options);
|
|
29428
|
-
this.memory = new HostMemory(
|
|
30702
|
+
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])));
|
|
29429
30703
|
}
|
|
29430
30704
|
options;
|
|
29431
30705
|
memory;
|
|
29432
30706
|
async readFile(file2, maxBytes, signal) {
|
|
29433
30707
|
try {
|
|
29434
|
-
return await readBoundedFile(file2, maxBytes, this.options.ownerBridgePath ??
|
|
30708
|
+
return await readBoundedFile(file2, maxBytes, this.options.ownerBridgePath ?? path18.join(path18.dirname(this.options.helperPath), "OwnerBridge.exe"), signal);
|
|
29435
30709
|
} catch (error62) {
|
|
29436
30710
|
if (error62.code === "ENOENT") throw error62;
|
|
29437
30711
|
if (error62 instanceof Error && /^[A-Z_]{1,40}$/.test(error62.message)) fail3(error62.message);
|
|
@@ -29441,31 +30715,31 @@ var NativeTools = class {
|
|
|
29441
30715
|
/** Windows only: up to 64 files of at most 1 MiB in one bridge process, each with its own result. */
|
|
29442
30716
|
async readFiles(files, maxTotalBytes, signal) {
|
|
29443
30717
|
try {
|
|
29444
|
-
return await readWindowsFiles(this.options.ownerBridgePath ??
|
|
30718
|
+
return await readWindowsFiles(this.options.ownerBridgePath ?? path18.join(path18.dirname(this.options.helperPath), "OwnerBridge.exe"), files, 1048576, maxTotalBytes, signal);
|
|
29445
30719
|
} catch (error62) {
|
|
29446
30720
|
if (error62 instanceof Error && /^[A-Z_]{1,40}$/.test(error62.message)) fail3(error62.message);
|
|
29447
30721
|
throw error62;
|
|
29448
30722
|
}
|
|
29449
30723
|
}
|
|
29450
|
-
async prepare(workspace2, candidate,
|
|
30724
|
+
async prepare(workspace2, candidate, selection2) {
|
|
29451
30725
|
let prepared;
|
|
29452
30726
|
try {
|
|
29453
30727
|
let projectRoot;
|
|
29454
|
-
if (
|
|
29455
|
-
const target = ProjectTargetBindingSchema.parse(
|
|
30728
|
+
if (selection2) {
|
|
30729
|
+
const target = ProjectTargetBindingSchema.parse(selection2);
|
|
29456
30730
|
if (workspace2.rootHash !== target.workspaceRootHash) fail3("PROJECT_IDENTITY_MISMATCH");
|
|
29457
30731
|
const identity = await this.prepareTool(workspace2, { name: "project_identity", args: { path: target.relativePath } });
|
|
29458
30732
|
const proof2 = JSON.parse((await identity.run(AbortSignal.timeout(15e3))).stdout);
|
|
29459
30733
|
if (!proof2.repositoryFingerprint) fail3("PROJECT_IDENTITY_UNKNOWN");
|
|
29460
30734
|
if (proof2.repositoryFingerprint !== target.repositoryFingerprint) fail3("PROJECT_IDENTITY_MISMATCH");
|
|
29461
|
-
projectRoot =
|
|
30735
|
+
projectRoot = path18.resolve(workspace2.root, target.relativePath);
|
|
29462
30736
|
const common = identity.claims.find((claim2) => claim2.namespace === "git")?.path;
|
|
29463
30737
|
if (common) workspace2 = { ...workspace2, gitCommonDir: common };
|
|
29464
30738
|
}
|
|
29465
30739
|
prepared = await this.prepareTool(workspace2, candidate, projectRoot);
|
|
29466
30740
|
} catch (error62) {
|
|
29467
30741
|
const parsed = ToolCallSchema.safeParse(candidate);
|
|
29468
|
-
if (parsed.success && parsed.data.name === "command_run") await this.memory.record({ ...parsed.data.args, cwd:
|
|
30742
|
+
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(() => {
|
|
29469
30743
|
});
|
|
29470
30744
|
throw error62;
|
|
29471
30745
|
}
|
|
@@ -29485,17 +30759,17 @@ var NativeTools = class {
|
|
|
29485
30759
|
try {
|
|
29486
30760
|
const canonical2 = await realpath7(workspace2.root);
|
|
29487
30761
|
if (!equalPath3(canonical2, workspace2.root) || hash6(process.platform === "win32" ? canonical2.toLowerCase() : canonical2) !== workspace2.rootHash) fail3("WORKSPACE_CHANGED");
|
|
29488
|
-
const runtimeDirectory =
|
|
30762
|
+
const runtimeDirectory = path18.dirname(this.options.helperPath);
|
|
29489
30763
|
const protectedPaths = [
|
|
29490
30764
|
this.options.stateDirectory,
|
|
29491
30765
|
this.options.helperPath,
|
|
29492
|
-
...["agent.mjs", "node.exe", "OwnerBridge.exe", "LocalCommanderAgent.exe", "node", "owner-store", "posix-host", "job-host.mjs", "lifecycle.mjs", "manifest.json"].map((name2) =>
|
|
30766
|
+
...["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))
|
|
29493
30767
|
];
|
|
29494
30768
|
if (this.options.ownerBridgePath) protectedPaths.push(this.options.ownerBridgePath);
|
|
29495
|
-
if (process.platform === "win32" && process.env.LOCALAPPDATA &&
|
|
29496
|
-
protectedPaths.push(
|
|
30769
|
+
if (process.platform === "win32" && process.env.LOCALAPPDATA && path18.isAbsolute(process.env.LOCALAPPDATA)) {
|
|
30770
|
+
protectedPaths.push(path18.join(process.env.LOCALAPPDATA, "LocalCommander"));
|
|
29497
30771
|
}
|
|
29498
|
-
if (process.platform !== "win32") protectedPaths.push(
|
|
30772
|
+
if (process.platform !== "win32") protectedPaths.push(path18.join(process.env.LC_AGENT_DATA_DIR || posixDataHome(), "LocalCommander"));
|
|
29499
30773
|
guard = await PathGuard.create([canonical2], false, { protectedPaths });
|
|
29500
30774
|
if (projectRoot) {
|
|
29501
30775
|
const selected = await guard.resolveDirectory(projectRoot);
|
|
@@ -29584,7 +30858,7 @@ var NativeTools = class {
|
|
|
29584
30858
|
}
|
|
29585
30859
|
if (taken === first - 1 && first <= end) fail3("OUTPUT_LIMIT_EXCEEDED");
|
|
29586
30860
|
const remaining = lines.length - (lines.length > 1 && lines.at(-1) === "" ? 1 : 0);
|
|
29587
|
-
return result({ path:
|
|
30861
|
+
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 });
|
|
29588
30862
|
} };
|
|
29589
30863
|
}
|
|
29590
30864
|
if (call.name === "fs_write" || call.name === "fs_replace") {
|
|
@@ -29627,8 +30901,8 @@ var NativeTools = class {
|
|
|
29627
30901
|
bytes3 = encodeText(pieces.join(newText), original.encoding);
|
|
29628
30902
|
}
|
|
29629
30903
|
if (bytes3.length > MAX_FILE_WRITE_BYTES) fail3("FILE_WRITE_LIMIT");
|
|
29630
|
-
const temp =
|
|
29631
|
-
const handle = await open6(temp,
|
|
30904
|
+
const temp = path18.join(path18.dirname(target), ".lc-write-" + randomUUID7() + ".tmp");
|
|
30905
|
+
const handle = await open6(temp, constants8.O_CREAT | constants8.O_EXCL | constants8.O_WRONLY, 384);
|
|
29632
30906
|
try {
|
|
29633
30907
|
await handle.writeFile(bytes3);
|
|
29634
30908
|
await handle.sync();
|
|
@@ -29644,7 +30918,7 @@ var NativeTools = class {
|
|
|
29644
30918
|
break;
|
|
29645
30919
|
} catch (error62) {
|
|
29646
30920
|
if (process.platform !== "win32" || !["EPERM", "EBUSY", "EACCES"].includes(error62.code ?? "")) throw error62;
|
|
29647
|
-
if (attempt === 4) fail3((await
|
|
30921
|
+
if (attempt === 4) fail3((await lstat8(target)).mode & 128 ? "FILE_IN_USE" : "FILE_READ_ONLY");
|
|
29648
30922
|
await delay2(50 << attempt);
|
|
29649
30923
|
stopped(signal);
|
|
29650
30924
|
}
|
|
@@ -29659,18 +30933,18 @@ var NativeTools = class {
|
|
|
29659
30933
|
}
|
|
29660
30934
|
for (let attempt = 0; attempt < 3; attempt++) {
|
|
29661
30935
|
try {
|
|
29662
|
-
await
|
|
30936
|
+
await rm6(temp);
|
|
29663
30937
|
break;
|
|
29664
30938
|
} catch {
|
|
29665
30939
|
await delay2(100);
|
|
29666
30940
|
}
|
|
29667
30941
|
}
|
|
29668
30942
|
}
|
|
29669
|
-
return result({ path:
|
|
30943
|
+
return result({ path: path18.relative(workspace2.root, target), bytes: bytes3.length, sha256: hash6(bytes3), ...call.name === "fs_replace" ? { replacements } : {} });
|
|
29670
30944
|
} catch (e) {
|
|
29671
30945
|
await handle.close().catch(() => {
|
|
29672
30946
|
});
|
|
29673
|
-
await
|
|
30947
|
+
await rm6(temp, { force: true }).catch(() => {
|
|
29674
30948
|
});
|
|
29675
30949
|
throw e;
|
|
29676
30950
|
}
|
|
@@ -29692,7 +30966,7 @@ var NativeTools = class {
|
|
|
29692
30966
|
const lines = decodeText(bytes3).text.split(/\r?\n/);
|
|
29693
30967
|
scanned++;
|
|
29694
30968
|
for (let i = 0; i < lines.length && matches2.length < call.args.maxResults; i++) if ((call.args.caseSensitive ? lines[i] : lines[i].toLowerCase()).includes(query)) {
|
|
29695
|
-
const match = { path:
|
|
30969
|
+
const match = { path: path18.relative(workspace2.root, filename), line: i + 1, text: lines[i].slice(0, 500) };
|
|
29696
30970
|
if ((room -= Buffer.byteLength(JSON.stringify(match)) + 1) < 0) {
|
|
29697
30971
|
incomplete = true;
|
|
29698
30972
|
break;
|
|
@@ -29735,7 +31009,7 @@ var NativeTools = class {
|
|
|
29735
31009
|
continue;
|
|
29736
31010
|
}
|
|
29737
31011
|
try {
|
|
29738
|
-
const filename = await guard.resolveExisting(
|
|
31012
|
+
const filename = await guard.resolveExisting(path18.join(base, entry.path));
|
|
29739
31013
|
guard.assertSafeFile(filename);
|
|
29740
31014
|
if (!batched) {
|
|
29741
31015
|
searchFile(filename, await this.readFile(filename, 1048576, signal));
|
|
@@ -29759,6 +31033,42 @@ var NativeTools = class {
|
|
|
29759
31033
|
return result({ matches: matches2, scannedFiles: scanned, truncated: listing.truncated || incomplete || matches2.length >= call.args.maxResults || scanned >= 300 });
|
|
29760
31034
|
} };
|
|
29761
31035
|
}
|
|
31036
|
+
if (call.name === "take_screenshot") {
|
|
31037
|
+
if (!screenshotEnabled() && !await lstat8(path18.join(this.options.stateDirectory, SCREENSHOT_ACCEPTANCE_FILE)).then((s) => s.isFile(), () => false)) fail3("SCREENSHOT_DISABLED");
|
|
31038
|
+
if (!workspace2.fullAccess) fail3("FULL_ACCESS_REQUIRED");
|
|
31039
|
+
if (await lstat8(path18.join(this.options.stateDirectory, SCREENSHOT_OWNER_OFF_FILE)).then(() => true, (error62) => error62.code !== "ENOENT")) fail3("SCREENSHOT_DISABLED_BY_OWNER");
|
|
31040
|
+
const bridge = this.options.ownerBridgePath ?? path18.join(path18.dirname(this.options.helperPath), "OwnerBridge.exe");
|
|
31041
|
+
return { call, claims: [{ path: path18.join(this.options.stateDirectory, "screen-capture"), mode: "read" }], run: async (signal) => {
|
|
31042
|
+
let shot;
|
|
31043
|
+
try {
|
|
31044
|
+
shot = await captureScreen({ ownerBridgePath: bridge, signal });
|
|
31045
|
+
} catch (error62) {
|
|
31046
|
+
if (error62 instanceof ScreenCaptureError && error62.detail) return {
|
|
31047
|
+
exitCode: 1,
|
|
31048
|
+
timedOut: false,
|
|
31049
|
+
cancelled: false,
|
|
31050
|
+
treeTerminated: true,
|
|
31051
|
+
stdout: JSON.stringify({ type: "screenshot_error", resultCode: error62.code, ...error62.detail }),
|
|
31052
|
+
stderr: "",
|
|
31053
|
+
stdoutTruncated: false,
|
|
31054
|
+
stderrTruncated: false,
|
|
31055
|
+
resultCode: error62.code
|
|
31056
|
+
};
|
|
31057
|
+
fail3(error62 instanceof Error && /^[A-Z_]{1,40}$/.test(error62.message) ? error62.message : "SCREEN_UNAVAILABLE");
|
|
31058
|
+
}
|
|
31059
|
+
return result({
|
|
31060
|
+
type: "screenshot",
|
|
31061
|
+
mimeType: "image/jpeg",
|
|
31062
|
+
width: shot.width,
|
|
31063
|
+
height: shot.height,
|
|
31064
|
+
sourceWidth: shot.sourceWidth,
|
|
31065
|
+
sourceHeight: shot.sourceHeight,
|
|
31066
|
+
bytes: shot.data.length,
|
|
31067
|
+
capturedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
31068
|
+
data: shot.data.toString("base64")
|
|
31069
|
+
});
|
|
31070
|
+
} };
|
|
31071
|
+
}
|
|
29762
31072
|
if (call.name === "localhost_request") {
|
|
29763
31073
|
const url2 = new URL(call.args.url), port = Number(url2.port || (url2.protocol === "https:" ? 443 : 80));
|
|
29764
31074
|
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");
|
|
@@ -29829,9 +31139,9 @@ var NativeTools = class {
|
|
|
29829
31139
|
else if (call.name === "git_diff") {
|
|
29830
31140
|
argv = ["diff", "--no-ext-diff", "--no-textconv", ...call.args.staged ? ["--cached"] : []];
|
|
29831
31141
|
if (call.args.file) {
|
|
29832
|
-
const file2 = await resolve(
|
|
29833
|
-
const relative =
|
|
29834
|
-
if (relative.startsWith(".." +
|
|
31142
|
+
const file2 = await resolve(path18.resolve(cwd, call.args.file));
|
|
31143
|
+
const relative = path18.relative(cwd, file2);
|
|
31144
|
+
if (relative.startsWith(".." + path18.sep) || relative === ".." || path18.isAbsolute(relative)) fail3("PATH_NOT_ALLOWED");
|
|
29835
31145
|
argv.push("--", relative);
|
|
29836
31146
|
} else argv.push("--stat");
|
|
29837
31147
|
} else fail3("TOOL_MISSING");
|
|
@@ -29842,7 +31152,7 @@ var NativeTools = class {
|
|
|
29842
31152
|
const listing = await this.list(guard, cwd, 1, call.args.startup ? 20 : 150, signal);
|
|
29843
31153
|
let packageInfo = null;
|
|
29844
31154
|
try {
|
|
29845
|
-
const name2 = await guard.resolveExisting(
|
|
31155
|
+
const name2 = await guard.resolveExisting(path18.join(cwd, "package.json"));
|
|
29846
31156
|
guard.assertSafeFile(name2);
|
|
29847
31157
|
const value = JSON.parse(utf8(await this.readFile(name2, 64e3, signal)));
|
|
29848
31158
|
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) : [] };
|
|
@@ -29862,7 +31172,7 @@ var NativeTools = class {
|
|
|
29862
31172
|
}
|
|
29863
31173
|
const contextFile = async (relative, limit, optional2 = false) => {
|
|
29864
31174
|
try {
|
|
29865
|
-
const file2 = await guard.resolveExisting(
|
|
31175
|
+
const file2 = await guard.resolveExisting(path18.join(primary, relative));
|
|
29866
31176
|
guard.assertSafeFile(file2);
|
|
29867
31177
|
return utf8(await this.readFile(file2, limit, signal));
|
|
29868
31178
|
} catch (error62) {
|
|
@@ -29895,19 +31205,19 @@ var NativeTools = class {
|
|
|
29895
31205
|
} };
|
|
29896
31206
|
}
|
|
29897
31207
|
async resolveProgram(name2, workspace2, args) {
|
|
29898
|
-
const entry = Object.entries(this.options.programs).find(([key, value]) => equalPath3(key, name2) ||
|
|
31208
|
+
const entry = Object.entries(this.options.programs).find(([key, value]) => equalPath3(key, name2) || path18.isAbsolute(name2) && equalPath3(value.executable, path18.resolve(name2)));
|
|
29899
31209
|
if (workspace2.fullAccess) {
|
|
29900
|
-
const commandKey = (value) => process.platform === "win32" ?
|
|
31210
|
+
const commandKey = (value) => process.platform === "win32" ? path18.basename(value).toLowerCase().replace(/\.(exe|com|cmd|bat)$/i, "") : path18.basename(value);
|
|
29901
31211
|
const denied = new Set((workspace2.deniedCommands ?? []).map(commandKey));
|
|
29902
31212
|
if (denied.has(commandKey(name2)) || entry && denied.has(commandKey(entry[0]))) fail3("COMMAND_NOT_ALLOWED");
|
|
29903
|
-
const extension2 =
|
|
29904
|
-
const candidate = entry?.[1].executable ?? (process.platform !== "win32" ? await resolvePosixExecutable(name2) :
|
|
31213
|
+
const extension2 = path18.extname(name2).toLowerCase();
|
|
31214
|
+
const candidate = entry?.[1].executable ?? (process.platform !== "win32" ? await resolvePosixExecutable(name2) : path18.isAbsolute(name2) ? name2 : /^[\w.-]+$/.test(name2) ? resolveWindowsLauncher(
|
|
29905
31215
|
commandKey(name2),
|
|
29906
31216
|
[".exe", ".com", ".cmd", ".bat"].includes(extension2) ? { ...process.env, PATHEXT: extension2 } : process.env
|
|
29907
31217
|
)?.file : void 0);
|
|
29908
|
-
if (!candidate || !
|
|
31218
|
+
if (!candidate || !path18.isAbsolute(candidate)) fail3("COMMAND_NOT_FOUND");
|
|
29909
31219
|
const executable = await realpath7(candidate).catch(() => fail3("COMMAND_NOT_FOUND"));
|
|
29910
|
-
if (!(await
|
|
31220
|
+
if (!(await lstat8(executable)).isFile()) fail3("COMMAND_NOT_FOUND");
|
|
29911
31221
|
if (denied.has(commandKey(executable))) fail3("COMMAND_NOT_ALLOWED");
|
|
29912
31222
|
for (const key of workspace2.deniedCommands ?? []) {
|
|
29913
31223
|
const configured = this.options.programs[key]?.executable;
|
|
@@ -29920,7 +31230,7 @@ var NativeTools = class {
|
|
|
29920
31230
|
if (/\.(cmd|bat)$/i.test(executable)) {
|
|
29921
31231
|
if ([executable, ...args].some((value) => /[&|<>^%!"\r\n]/.test(value))) fail3("INVALID_SCRIPT_ARGUMENTS");
|
|
29922
31232
|
const literal2 = (value) => "'" + value.replaceAll("'", "''") + "'";
|
|
29923
|
-
const shell =
|
|
31233
|
+
const shell = path18.join(process.env.SystemRoot ?? "C:\\Windows", "System32", "WindowsPowerShell", "v1.0", "powershell.exe");
|
|
29924
31234
|
if (denied.has("powershell") || denied.has("cmd")) fail3("COMMAND_NOT_ALLOWED");
|
|
29925
31235
|
const script = "& " + literal2(executable) + " @(" + args.map(literal2).join(",") + "); exit $LASTEXITCODE";
|
|
29926
31236
|
return { executable: shell, args: ["-NoProfile", "-NonInteractive", "-EncodedCommand", Buffer.from(script, "utf16le").toString("base64")] };
|
|
@@ -29928,7 +31238,7 @@ var NativeTools = class {
|
|
|
29928
31238
|
if (!/\.(exe|com)$/i.test(executable)) fail3("COMMAND_NOT_ALLOWED");
|
|
29929
31239
|
return { executable, args: [...entry?.[1].prefixArgs ?? [], ...args] };
|
|
29930
31240
|
}
|
|
29931
|
-
if (!entry || !workspace2.allowedCommands.some((v) => equalPath3(v, entry[0])) || !
|
|
31241
|
+
if (!entry || !workspace2.allowedCommands.some((v) => equalPath3(v, entry[0])) || !path18.isAbsolute(entry[1].executable)) fail3("COMMAND_NOT_ALLOWED");
|
|
29932
31242
|
return { executable: entry[1].executable, args: [...entry[1].prefixArgs ?? [], ...args] };
|
|
29933
31243
|
}
|
|
29934
31244
|
async memoryContext(workspace2) {
|
|
@@ -29943,13 +31253,13 @@ var NativeTools = class {
|
|
|
29943
31253
|
async gitExecution(cwd, args) {
|
|
29944
31254
|
if (!["win32", "linux", "darwin"].includes(process.platform)) fail3("COMMAND_NOT_ALLOWED");
|
|
29945
31255
|
const configured = this.options.programs.git;
|
|
29946
|
-
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 &&
|
|
31256
|
+
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"];
|
|
29947
31257
|
for (const source of candidates) {
|
|
29948
|
-
if (!
|
|
31258
|
+
if (!path18.isAbsolute(source)) continue;
|
|
29949
31259
|
const candidate = process.platform === "win32" ? source : await resolvePosixExecutable(source);
|
|
29950
31260
|
if (!candidate) continue;
|
|
29951
31261
|
try {
|
|
29952
|
-
const stat2 = await
|
|
31262
|
+
const stat2 = await lstat8(candidate);
|
|
29953
31263
|
if (!stat2.isFile() || stat2.isSymbolicLink() || !equalPath3(candidate, await realpath7(candidate))) continue;
|
|
29954
31264
|
} catch {
|
|
29955
31265
|
continue;
|
|
@@ -29967,7 +31277,7 @@ var NativeTools = class {
|
|
|
29967
31277
|
const current2 = queue.shift();
|
|
29968
31278
|
let names;
|
|
29969
31279
|
try {
|
|
29970
|
-
names = await
|
|
31280
|
+
names = await readdir5(current2.path, { withFileTypes: true });
|
|
29971
31281
|
} catch (error62) {
|
|
29972
31282
|
if (current2.level === 0) throw error62;
|
|
29973
31283
|
continue;
|
|
@@ -29979,7 +31289,7 @@ var NativeTools = class {
|
|
|
29979
31289
|
break;
|
|
29980
31290
|
}
|
|
29981
31291
|
if (item.isSymbolicLink() || excluded.has(item.name.toLowerCase())) continue;
|
|
29982
|
-
const candidate =
|
|
31292
|
+
const candidate = path18.join(current2.path, item.name);
|
|
29983
31293
|
let resolved;
|
|
29984
31294
|
try {
|
|
29985
31295
|
resolved = await guard.resolveExisting(candidate);
|
|
@@ -29989,11 +31299,11 @@ var NativeTools = class {
|
|
|
29989
31299
|
}
|
|
29990
31300
|
if (!equalPath3(candidate, resolved)) continue;
|
|
29991
31301
|
if (item.isDirectory()) {
|
|
29992
|
-
entries.push({ path:
|
|
31302
|
+
entries.push({ path: path18.relative(root, resolved), type: "directory" });
|
|
29993
31303
|
if (current2.level < depth) queue.push({ path: resolved, level: current2.level + 1 });
|
|
29994
31304
|
} else if (item.isFile()) {
|
|
29995
|
-
const stat2 = await
|
|
29996
|
-
if (stat2) entries.push({ path:
|
|
31305
|
+
const stat2 = await lstat8(resolved).catch(() => null);
|
|
31306
|
+
if (stat2) entries.push({ path: path18.relative(root, resolved), type: "file", size: stat2.size });
|
|
29997
31307
|
}
|
|
29998
31308
|
}
|
|
29999
31309
|
if (truncated) break;
|
|
@@ -30003,49 +31313,49 @@ var NativeTools = class {
|
|
|
30003
31313
|
async gitCommonDir(cwd, workspace2, guard) {
|
|
30004
31314
|
let directory = cwd;
|
|
30005
31315
|
while (guard.isWithin(directory, workspace2.root)) {
|
|
30006
|
-
const dotGit =
|
|
31316
|
+
const dotGit = path18.join(directory, ".git");
|
|
30007
31317
|
try {
|
|
30008
|
-
const stat2 = await
|
|
31318
|
+
const stat2 = await lstat8(dotGit);
|
|
30009
31319
|
if (stat2.isSymbolicLink()) fail3("GIT_METADATA_CHANGED");
|
|
30010
31320
|
let gitDir;
|
|
30011
31321
|
if (stat2.isDirectory()) gitDir = await realpath7(dotGit);
|
|
30012
31322
|
else {
|
|
30013
31323
|
const content = utf8(await this.readFile(dotGit, 4096)).trim();
|
|
30014
31324
|
if (!content.startsWith("gitdir: ")) fail3("GIT_METADATA_CHANGED");
|
|
30015
|
-
gitDir = await realpath7(
|
|
31325
|
+
gitDir = await realpath7(path18.resolve(directory, content.slice(8)));
|
|
30016
31326
|
}
|
|
30017
31327
|
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");
|
|
30018
31328
|
let common = gitDir;
|
|
30019
31329
|
try {
|
|
30020
|
-
const content = utf8(await this.readFile(
|
|
31330
|
+
const content = utf8(await this.readFile(path18.join(gitDir, "commondir"), 4096)).trim();
|
|
30021
31331
|
if (!content) fail3("GIT_METADATA_CHANGED");
|
|
30022
|
-
common = await realpath7(
|
|
31332
|
+
common = await realpath7(path18.resolve(gitDir, content));
|
|
30023
31333
|
} catch (e) {
|
|
30024
31334
|
if (e.code !== "ENOENT") throw e;
|
|
30025
31335
|
}
|
|
30026
|
-
if (!(await
|
|
31336
|
+
if (!(await lstat8(common)).isDirectory() || guard.isWithin(common, this.options.stateDirectory)) fail3("GIT_METADATA_CHANGED");
|
|
30027
31337
|
if (!guard.isWithin(common, workspace2.root) && (!workspace2.gitCommonDir || !equalPath3(common, workspace2.gitCommonDir))) fail3("GIT_COMMON_DIRECTORY_NOT_APPROVED");
|
|
30028
31338
|
return common;
|
|
30029
31339
|
} catch (e) {
|
|
30030
31340
|
if (e.code !== "ENOENT") throw e;
|
|
30031
31341
|
}
|
|
30032
31342
|
if (equalPath3(directory, workspace2.root)) break;
|
|
30033
|
-
directory =
|
|
31343
|
+
directory = path18.dirname(directory);
|
|
30034
31344
|
}
|
|
30035
31345
|
return null;
|
|
30036
31346
|
}
|
|
30037
31347
|
};
|
|
30038
31348
|
|
|
30039
31349
|
// agent/src/scheduler.ts
|
|
30040
|
-
import
|
|
30041
|
-
import
|
|
31350
|
+
import path19 from "node:path";
|
|
31351
|
+
import os5 from "node:os";
|
|
30042
31352
|
function canonical(value) {
|
|
30043
|
-
const p =
|
|
31353
|
+
const p = path19.resolve(value);
|
|
30044
31354
|
return process.platform === "win32" ? p.toLowerCase() : p;
|
|
30045
31355
|
}
|
|
30046
31356
|
function ancestor(a, b) {
|
|
30047
|
-
const relative =
|
|
30048
|
-
return relative === "" || !
|
|
31357
|
+
const relative = path19.relative(a, b);
|
|
31358
|
+
return relative === "" || !path19.isAbsolute(relative) && relative !== ".." && !relative.startsWith(".." + path19.sep);
|
|
30049
31359
|
}
|
|
30050
31360
|
function claimsConflict(a, b) {
|
|
30051
31361
|
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))));
|
|
@@ -30053,7 +31363,7 @@ function claimsConflict(a, b) {
|
|
|
30053
31363
|
var NativeScheduler = class {
|
|
30054
31364
|
constructor(options = {}) {
|
|
30055
31365
|
this.options = options;
|
|
30056
|
-
const capacity = Math.max(1, Math.min(16, Math.floor(Math.max(2,
|
|
31366
|
+
const capacity = Math.max(1, Math.min(16, Math.floor(Math.max(2, os5.availableParallelism?.() ?? os5.cpus().length) / 2)));
|
|
30057
31367
|
this.safeSlots = options.safeSlots ?? capacity;
|
|
30058
31368
|
this.maxQueued = options.maxQueued ?? 32;
|
|
30059
31369
|
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");
|
|
@@ -30071,16 +31381,16 @@ var NativeScheduler = class {
|
|
|
30071
31381
|
} catch {
|
|
30072
31382
|
}
|
|
30073
31383
|
}
|
|
30074
|
-
schedule(id2, claims, deadlineAt,
|
|
31384
|
+
schedule(id2, claims, deadlineAt, run2, signal) {
|
|
30075
31385
|
if (!this.accepting) return Promise.reject(Error("AGENT_PAUSED"));
|
|
30076
31386
|
if (!id2 || id2.length > 100 || this.active.has(id2) || this.waiting.some((j) => j.id === id2)) return Promise.reject(Error("DUPLICATE_SCHEDULED_EXECUTION"));
|
|
30077
|
-
if (!Array.isArray(claims) || !claims.length || claims.length > 32 || claims.some((c) => !c || !
|
|
31387
|
+
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"));
|
|
30078
31388
|
const deadline = deadlineAt.getTime();
|
|
30079
31389
|
if (!Number.isFinite(deadline) || deadline <= Date.now()) return Promise.reject(Error("ADMISSION_DEADLINE_EXPIRED"));
|
|
30080
31390
|
if (signal?.aborted) return Promise.reject(Error("CANCELLED_BEFORE_ACCEPTANCE"));
|
|
30081
31391
|
if (this.waiting.length >= this.maxQueued) return Promise.reject(Error("RESOURCE_BUSY"));
|
|
30082
31392
|
return new Promise((resolve, reject) => {
|
|
30083
|
-
const job = { id: id2, claims: claims.map((c) => ({ ...c, path: canonical(c.path) })), deadline, run, signal, resolve, reject };
|
|
31393
|
+
const job = { id: id2, claims: claims.map((c) => ({ ...c, path: canonical(c.path) })), deadline, run: run2, signal, resolve, reject };
|
|
30084
31394
|
const remove = (reason) => {
|
|
30085
31395
|
const index = this.waiting.indexOf(job);
|
|
30086
31396
|
if (index < 0) return;
|
|
@@ -30779,7 +32089,45 @@ function journalBinding(entry, binding2) {
|
|
|
30779
32089
|
function journalResult(value, code) {
|
|
30780
32090
|
return { ...value, resultCode: code ?? (value.treeTerminated ? value.cancelled ? "CANCELLED" : value.timedOut ? "TIMEOUT" : value.exitCode === 0 ? "SUCCESS" : "USER_PROGRAM_FAILED" : "EXECUTION_UNKNOWN") };
|
|
30781
32091
|
}
|
|
30782
|
-
var knownCodes = /* @__PURE__ */ new Set([
|
|
32092
|
+
var knownCodes = /* @__PURE__ */ new Set([
|
|
32093
|
+
"PROJECT_IDENTITY_UNKNOWN",
|
|
32094
|
+
"PROJECT_IDENTITY_MISMATCH",
|
|
32095
|
+
"INVALID_TOOL_ARGUMENTS",
|
|
32096
|
+
"LOCAL_PERMISSION_REQUIRED",
|
|
32097
|
+
"PATH_NOT_ALLOWED",
|
|
32098
|
+
"FILE_CHANGED",
|
|
32099
|
+
"FILE_NOT_FOUND",
|
|
32100
|
+
"FILE_ALREADY_EXISTS",
|
|
32101
|
+
"REPLACEMENT_NOT_UNIQUE",
|
|
32102
|
+
"OUTPUT_LIMIT_EXCEEDED",
|
|
32103
|
+
"BINARY_FILE_NOT_SUPPORTED",
|
|
32104
|
+
"FILE_UNSUPPORTED_OR_TOO_LARGE",
|
|
32105
|
+
"INVALID_LINE_RANGE",
|
|
32106
|
+
"FILE_IN_USE",
|
|
32107
|
+
"FILE_READ_ONLY",
|
|
32108
|
+
"FILE_WRITE_LIMIT",
|
|
32109
|
+
"GIT_METADATA_CHANGED",
|
|
32110
|
+
"GIT_COMMON_DIRECTORY_NOT_APPROVED",
|
|
32111
|
+
"GIT_NOT_INSTALLED",
|
|
32112
|
+
"LOCALHOST_NOT_ALLOWED",
|
|
32113
|
+
"COMMAND_NOT_ALLOWED",
|
|
32114
|
+
"WORKSPACE_CHANGED",
|
|
32115
|
+
"WORKSPACE_UNAVAILABLE",
|
|
32116
|
+
"RESOURCE_BUSY",
|
|
32117
|
+
"AGENT_PAUSED",
|
|
32118
|
+
"CANCELLED_BEFORE_ACCEPTANCE",
|
|
32119
|
+
"ADMISSION_DEADLINE_EXPIRED",
|
|
32120
|
+
// take_screenshot refusals (#434, #486): without these the client sees TOOL_FAILED.
|
|
32121
|
+
"FULL_ACCESS_REQUIRED",
|
|
32122
|
+
"SCREENSHOT_DISABLED",
|
|
32123
|
+
"SCREENSHOT_DISABLED_BY_OWNER",
|
|
32124
|
+
"SCREENSHOT_UNSUPPORTED",
|
|
32125
|
+
"SCREENSHOT_TOO_LARGE",
|
|
32126
|
+
"SCREEN_UNAVAILABLE",
|
|
32127
|
+
"SCREEN_LOCKED",
|
|
32128
|
+
"SCREEN_ENCODER_UNAVAILABLE",
|
|
32129
|
+
"SCREEN_RECORDING_PERMISSION_REQUIRED"
|
|
32130
|
+
]);
|
|
30783
32131
|
function safeCode(error62) {
|
|
30784
32132
|
const code = error62 instanceof NativeToolError ? error62.code : error62 instanceof Error ? error62.message : "";
|
|
30785
32133
|
return knownCodes.has(code) || /^GUARD_[A-Z_]{1,30}$/.test(code) ? code : "TOOL_FAILED";
|
|
@@ -30790,6 +32138,14 @@ function resultOutcome(result2) {
|
|
|
30790
32138
|
if (!result2.treeTerminated || result2.exitCode === null) return "unknown";
|
|
30791
32139
|
return result2.exitCode === 0 ? "success" : "failed";
|
|
30792
32140
|
}
|
|
32141
|
+
function screenshotMetadata(stdout) {
|
|
32142
|
+
try {
|
|
32143
|
+
const { data: _data, ...metadata } = JSON.parse(stdout);
|
|
32144
|
+
return JSON.stringify(metadata);
|
|
32145
|
+
} catch {
|
|
32146
|
+
return "";
|
|
32147
|
+
}
|
|
32148
|
+
}
|
|
30793
32149
|
async function outboundResult(call, result2, binding2, optional2, ledger) {
|
|
30794
32150
|
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) };
|
|
30795
32151
|
if (ledger) {
|
|
@@ -30842,7 +32198,7 @@ var NativeRuntime = class {
|
|
|
30842
32198
|
}
|
|
30843
32199
|
if (frame.type === "result" && this.options.contentAudit) {
|
|
30844
32200
|
const call = this.contexts.get(frame.binding.executionId)?.tool.call;
|
|
30845
|
-
if (call) try {
|
|
32201
|
+
if (call && call.name !== "take_screenshot") try {
|
|
30846
32202
|
this.options.contentAudit.record(frame.binding, call, frame.result);
|
|
30847
32203
|
} catch {
|
|
30848
32204
|
}
|
|
@@ -30979,8 +32335,10 @@ var NativeRuntime = class {
|
|
|
30979
32335
|
const checked = ResultSchema.parse(output2);
|
|
30980
32336
|
const { resultCode, ...journalOutput } = checked;
|
|
30981
32337
|
if (context.guardPermit) await this.options.guard.result(context.guardPermit, checked);
|
|
30982
|
-
const
|
|
30983
|
-
this.
|
|
32338
|
+
const image = runnable.call.name === "take_screenshot" ? journalOutput.stdout : void 0;
|
|
32339
|
+
const final = await this.options.journal.finish(binding2.executionId, image === void 0 ? journalOutput : { ...journalOutput, stdout: screenshotMetadata(image) }, resultCode);
|
|
32340
|
+
const outbound = await outboundResult(runnable.call, journalResult(final.result, resultCode), binding2, this.optionalTelemetry, this.options.efficiencyLedger);
|
|
32341
|
+
this.send({ type: "result", version: 1, binding: binding2, result: image === void 0 ? outbound : { ...outbound, stdout: image } });
|
|
30984
32342
|
}, abort.signal);
|
|
30985
32343
|
context.task = work.catch(async (error62) => {
|
|
30986
32344
|
if (!context.accepted) {
|
|
@@ -31202,10 +32560,10 @@ var NativeRelayBridge = class {
|
|
|
31202
32560
|
};
|
|
31203
32561
|
|
|
31204
32562
|
// agent/src/local-direct.ts
|
|
31205
|
-
import
|
|
31206
|
-
import
|
|
31207
|
-
import { createHmac as createHmac2, hkdfSync, randomBytes as
|
|
31208
|
-
import { mkdir as mkdir7, readFile as
|
|
32563
|
+
import net2 from "node:net";
|
|
32564
|
+
import path20 from "node:path";
|
|
32565
|
+
import { createHmac as createHmac2, hkdfSync, randomBytes as randomBytes7, randomUUID as randomUUID8, timingSafeEqual as timingSafeEqual3 } from "node:crypto";
|
|
32566
|
+
import { mkdir as mkdir7, readFile as readFile8, rename as rename5, rm as rm7, writeFile as writeFile3 } from "node:fs/promises";
|
|
31209
32567
|
var LocalDirectError = class extends Error {
|
|
31210
32568
|
constructor(code) {
|
|
31211
32569
|
super(code);
|
|
@@ -31223,11 +32581,11 @@ var ADMISSION_MS = 6e4;
|
|
|
31223
32581
|
var MAX_IN_FLIGHT = 16;
|
|
31224
32582
|
var MAX_CONNECTIONS = 32;
|
|
31225
32583
|
function localDirectDirectory(appData) {
|
|
31226
|
-
return
|
|
32584
|
+
return path20.join(appData, "LocalCommander", "LocalMcp");
|
|
31227
32585
|
}
|
|
31228
32586
|
async function localDirectEnabled(directory) {
|
|
31229
32587
|
try {
|
|
31230
|
-
return JSON.parse(await
|
|
32588
|
+
return JSON.parse(await readFile8(path20.join(directory, "settings.json"), "utf8"))?.enabled === true;
|
|
31231
32589
|
} catch {
|
|
31232
32590
|
return false;
|
|
31233
32591
|
}
|
|
@@ -31241,7 +32599,7 @@ function sameProof(candidate, expected) {
|
|
|
31241
32599
|
const a = Buffer.from(candidate), b = Buffer.from(expected);
|
|
31242
32600
|
return a.length === b.length && timingSafeEqual3(a, b);
|
|
31243
32601
|
}
|
|
31244
|
-
var nonce = () =>
|
|
32602
|
+
var nonce = () => randomBytes7(32).toString("base64url");
|
|
31245
32603
|
var NONCE = /^[A-Za-z0-9_-]{43}$/;
|
|
31246
32604
|
function codeOf(error62) {
|
|
31247
32605
|
const code = error62 instanceof NativeToolError || error62 instanceof LocalDirectError ? error62.code : error62 instanceof Error ? error62.message : "";
|
|
@@ -31300,7 +32658,7 @@ var Lines = class {
|
|
|
31300
32658
|
async function readEndpoint(directory) {
|
|
31301
32659
|
let value;
|
|
31302
32660
|
try {
|
|
31303
|
-
value = JSON.parse(await
|
|
32661
|
+
value = JSON.parse(await readFile8(path20.join(directory, "endpoint.json"), "utf8"));
|
|
31304
32662
|
} catch {
|
|
31305
32663
|
fail4("LOCAL_AGENT_NOT_RUNNING");
|
|
31306
32664
|
}
|
|
@@ -31317,13 +32675,13 @@ var LocalDirectServer = class _LocalDirectServer {
|
|
|
31317
32675
|
sockets = /* @__PURE__ */ new Set();
|
|
31318
32676
|
/** Listens only while the owner has enabled direct local access; null otherwise. */
|
|
31319
32677
|
static async start(options) {
|
|
31320
|
-
const endpointFile =
|
|
32678
|
+
const endpointFile = path20.join(options.directory, "endpoint.json");
|
|
31321
32679
|
if (!await localDirectEnabled(options.directory)) {
|
|
31322
|
-
await
|
|
32680
|
+
await rm7(endpointFile, { force: true }).catch(() => {
|
|
31323
32681
|
});
|
|
31324
32682
|
return null;
|
|
31325
32683
|
}
|
|
31326
|
-
const server =
|
|
32684
|
+
const server = net2.createServer(), self = new _LocalDirectServer(server, options);
|
|
31327
32685
|
server.on("connection", (socket) => self.accept(socket));
|
|
31328
32686
|
await new Promise((resolve, reject) => {
|
|
31329
32687
|
server.once("error", reject);
|
|
@@ -31345,7 +32703,7 @@ var LocalDirectServer = class _LocalDirectServer {
|
|
|
31345
32703
|
for (const socket of this.sockets) socket.destroy();
|
|
31346
32704
|
await new Promise((resolve) => this.server.close(() => resolve()));
|
|
31347
32705
|
try {
|
|
31348
|
-
if ((await readEndpoint(this.options.directory)).pid === process.pid) await
|
|
32706
|
+
if ((await readEndpoint(this.options.directory)).pid === process.pid) await rm7(path20.join(this.options.directory, "endpoint.json"), { force: true });
|
|
31349
32707
|
} catch {
|
|
31350
32708
|
}
|
|
31351
32709
|
}
|
|
@@ -31480,7 +32838,7 @@ var LocalDirectClient = class _LocalDirectClient {
|
|
|
31480
32838
|
static async connect(options) {
|
|
31481
32839
|
if (!await localDirectEnabled(options.directory)) fail4("LOCAL_ACCESS_DISABLED");
|
|
31482
32840
|
const endpoint2 = await readEndpoint(options.directory);
|
|
31483
|
-
const socket =
|
|
32841
|
+
const socket = net2.createConnection({ host: "127.0.0.1", port: endpoint2.port });
|
|
31484
32842
|
let handler = () => {
|
|
31485
32843
|
};
|
|
31486
32844
|
const lines = new Lines(socket, (frame) => handler(frame));
|
|
@@ -35200,9 +36558,9 @@ var rev2026Codec = {
|
|
|
35200
36558
|
});
|
|
35201
36559
|
const parsed = buildSchemas2026().RequestMetaEnvelopeSchema.safeParse(meta3);
|
|
35202
36560
|
if (!parsed.success) for (const issue2 of parsed.error.issues) {
|
|
35203
|
-
const
|
|
35204
|
-
const key =
|
|
35205
|
-
if (
|
|
36561
|
+
const path30 = issue2.path.map(String);
|
|
36562
|
+
const key = path30.length > 0 ? path30.join(".") : "_meta";
|
|
36563
|
+
if (path30.length === 1 && issues.some((existing) => existing.key === key && existing.problem === "missing")) continue;
|
|
35206
36564
|
issues.push({
|
|
35207
36565
|
key,
|
|
35208
36566
|
problem: issue2.message
|
|
@@ -35504,29 +36862,29 @@ var PERMITTED_X_MCP_HEADER_TYPES = /* @__PURE__ */ new Set([
|
|
|
35504
36862
|
function scanXMcpHeaderDeclarations(inputSchema) {
|
|
35505
36863
|
const declarations = [];
|
|
35506
36864
|
const seenLower = /* @__PURE__ */ new Map();
|
|
35507
|
-
const visit2 = (node2,
|
|
36865
|
+
const visit2 = (node2, path30, reachable) => {
|
|
35508
36866
|
if (node2 === null || typeof node2 !== "object") return void 0;
|
|
35509
36867
|
const schema = node2;
|
|
35510
36868
|
if (X_MCP_HEADER_KEY in schema) {
|
|
35511
|
-
if (!reachable ||
|
|
36869
|
+
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)`;
|
|
35512
36870
|
const raw = schema[X_MCP_HEADER_KEY];
|
|
35513
|
-
if (typeof raw !== "string" || raw.length === 0) return `${pathName(
|
|
35514
|
-
if (!RFC9110_TOKEN.test(raw)) return `${pathName(
|
|
36871
|
+
if (typeof raw !== "string" || raw.length === 0) return `${pathName(path30)}: x-mcp-header MUST be a non-empty string`;
|
|
36872
|
+
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)`;
|
|
35515
36873
|
const type = typeof schema.type === "string" ? schema.type : void 0;
|
|
35516
|
-
if (type === void 0 || !PERMITTED_X_MCP_HEADER_TYPES.has(type)) return `${pathName(
|
|
36874
|
+
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>"}`;
|
|
35517
36875
|
const lower = raw.toLowerCase();
|
|
35518
36876
|
const prior = seenLower.get(lower);
|
|
35519
36877
|
if (prior !== void 0) return `x-mcp-header '${raw}' is not case-insensitively unique (also declared as '${prior}')`;
|
|
35520
36878
|
seenLower.set(lower, raw);
|
|
35521
36879
|
declarations.push({
|
|
35522
|
-
path:
|
|
36880
|
+
path: path30,
|
|
35523
36881
|
headerName: raw,
|
|
35524
36882
|
type
|
|
35525
36883
|
});
|
|
35526
36884
|
}
|
|
35527
36885
|
const properties = schema.properties;
|
|
35528
36886
|
if (properties !== null && typeof properties === "object") for (const [key, child] of Object.entries(properties)) {
|
|
35529
|
-
const fault$1 = visit2(child, [...
|
|
36887
|
+
const fault$1 = visit2(child, [...path30, key], reachable);
|
|
35530
36888
|
if (fault$1 !== void 0) return fault$1;
|
|
35531
36889
|
}
|
|
35532
36890
|
for (const k of NON_REACHABLE_SUBSCHEMA_KEYWORDS) {
|
|
@@ -35534,7 +36892,7 @@ function scanXMcpHeaderDeclarations(inputSchema) {
|
|
|
35534
36892
|
if (sub === void 0) continue;
|
|
35535
36893
|
const branches = Array.isArray(sub) ? sub : sub !== null && typeof sub === "object" && OBJECT_VALUED_SUBSCHEMA_KEYWORDS.has(k) ? Object.values(sub) : [sub];
|
|
35536
36894
|
for (const branch of branches) {
|
|
35537
|
-
const fault$1 = visit2(branch, [...
|
|
36895
|
+
const fault$1 = visit2(branch, [...path30, `<${k}>`], false);
|
|
35538
36896
|
if (fault$1 !== void 0) return fault$1;
|
|
35539
36897
|
}
|
|
35540
36898
|
}
|
|
@@ -35574,8 +36932,8 @@ var OBJECT_VALUED_SUBSCHEMA_KEYWORDS = /* @__PURE__ */ new Set([
|
|
|
35574
36932
|
"$defs",
|
|
35575
36933
|
"definitions"
|
|
35576
36934
|
]);
|
|
35577
|
-
function pathName(
|
|
35578
|
-
return
|
|
36935
|
+
function pathName(path30) {
|
|
36936
|
+
return path30.length === 0 ? "<root>" : path30.join(".");
|
|
35579
36937
|
}
|
|
35580
36938
|
var HEADER_MISMATCH_ERROR_CODE = -32020;
|
|
35581
36939
|
var INBOUND_VALIDATION_LADDER = [
|
|
@@ -35825,7 +37183,7 @@ var PROPERTY_KEYS_BY_TYPE = {
|
|
|
35825
37183
|
array: shapeKeys([UntitledMultiSelectEnumSchemaSchema, TitledMultiSelectEnumSchemaSchema])
|
|
35826
37184
|
};
|
|
35827
37185
|
var SUPPORTED_STRING_FORMATS = new Set(StringSchemaSchema.shape.format.unwrap().options);
|
|
35828
|
-
function walkProperty(node2,
|
|
37186
|
+
function walkProperty(node2, path30, vendor, unsupported) {
|
|
35829
37187
|
if (!isJsonObject(node2)) return node2;
|
|
35830
37188
|
const allowedKeys = typeof node2.type === "string" && Object.hasOwn(PROPERTY_KEYS_BY_TYPE, node2.type) ? PROPERTY_KEYS_BY_TYPE[node2.type] : void 0;
|
|
35831
37189
|
if (allowedKeys === void 0) return node2;
|
|
@@ -35833,8 +37191,8 @@ function walkProperty(node2, path29, vendor, unsupported) {
|
|
|
35833
37191
|
for (const [key, value] of Object.entries(node2)) if (allowedKeys.has(key) || isAnnotationOnlyJsonSchemaKeyword(key)) pruned[key] = value;
|
|
35834
37192
|
else if (key === "pattern" && node2.type === "string" && typeof node2.format === "string") {
|
|
35835
37193
|
if (!SUPPORTED_STRING_FORMATS.has(node2.format)) pruned[key] = value;
|
|
35836
|
-
else if (typeof value !== "string" || !isLibraryFormatPattern(node2.format, value, vendor)) unsupported.push(`${
|
|
35837
|
-
} else unsupported.push(`${
|
|
37194
|
+
else if (typeof value !== "string" || !isLibraryFormatPattern(node2.format, value, vendor)) unsupported.push(`${path30}.${key}`);
|
|
37195
|
+
} else unsupported.push(`${path30}.${key}`);
|
|
35838
37196
|
return pruned;
|
|
35839
37197
|
}
|
|
35840
37198
|
function walkRequestedSchema(converted, vendor) {
|
|
@@ -35851,11 +37209,11 @@ function describeUnsupportedProperties(pruned, fallback) {
|
|
|
35851
37209
|
const offenders = Object.entries(pruned.properties).filter(([, node2]) => !parseSchema(PrimitiveSchemaDefinitionSchema, node2).success).map(([name2]) => `properties.${name2}`);
|
|
35852
37210
|
return offenders.length > 0 ? offenders.join(", ") : fallback;
|
|
35853
37211
|
}
|
|
35854
|
-
function findDroppedConstraintPaths(original, parsed,
|
|
35855
|
-
if (Array.isArray(original) && Array.isArray(parsed)) return original.flatMap((item, index) => findDroppedConstraintPaths(item, parsed[index], `${
|
|
37212
|
+
function findDroppedConstraintPaths(original, parsed, path30 = "") {
|
|
37213
|
+
if (Array.isArray(original) && Array.isArray(parsed)) return original.flatMap((item, index) => findDroppedConstraintPaths(item, parsed[index], `${path30}[${index}]`));
|
|
35856
37214
|
if (!isJsonObject(original) || !isJsonObject(parsed)) return [];
|
|
35857
37215
|
return Object.entries(original).flatMap(([key, value]) => {
|
|
35858
|
-
const childPath =
|
|
37216
|
+
const childPath = path30 ? `${path30}.${key}` : key;
|
|
35859
37217
|
if (!Object.prototype.hasOwnProperty.call(parsed, key)) return isAnnotationOnlyJsonSchemaKeyword(key) ? [] : [childPath];
|
|
35860
37218
|
return findDroppedConstraintPaths(value, parsed[key], childPath);
|
|
35861
37219
|
});
|
|
@@ -37003,8 +38361,8 @@ var require_content_type = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
37003
38361
|
var PARAM_REGEXP = /; *([!#$%&'*+.^_`|~0-9A-Za-z-]+) *= *("(?:[\u000b\u0020\u0021\u0023-\u005b\u005d-\u007e\u0080-\u00ff]|\\[\u000b\u0020-\u00ff])*"|[!#$%&'*+.^_`|~0-9A-Za-z-]+) */g;
|
|
37004
38362
|
var QESC_REGEXP = /\\([\u000b\u0020-\u00ff])/g;
|
|
37005
38363
|
var TYPE_REGEXP = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+\/[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;
|
|
37006
|
-
exports.parse =
|
|
37007
|
-
function
|
|
38364
|
+
exports.parse = parse4;
|
|
38365
|
+
function parse4(string4) {
|
|
37008
38366
|
if (!string4) throw new TypeError("argument string is required");
|
|
37009
38367
|
var header = typeof string4 === "object" ? getcontenttype(string4) : string4;
|
|
37010
38368
|
if (typeof header !== "string") throw new TypeError("argument string is required to be a string");
|
|
@@ -37528,9 +38886,9 @@ var require_codegen = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
37528
38886
|
const rhs = this.rhs === void 0 ? "" : ` = ${this.rhs}`;
|
|
37529
38887
|
return `${varKind} ${this.name}${rhs};` + _n;
|
|
37530
38888
|
}
|
|
37531
|
-
optimizeNames(names,
|
|
38889
|
+
optimizeNames(names, constants11) {
|
|
37532
38890
|
if (!names[this.name.str]) return;
|
|
37533
|
-
if (this.rhs) this.rhs = optimizeExpr(this.rhs, names,
|
|
38891
|
+
if (this.rhs) this.rhs = optimizeExpr(this.rhs, names, constants11);
|
|
37534
38892
|
return this;
|
|
37535
38893
|
}
|
|
37536
38894
|
get names() {
|
|
@@ -37547,9 +38905,9 @@ var require_codegen = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
37547
38905
|
render({ _n }) {
|
|
37548
38906
|
return `${this.lhs} = ${this.rhs};` + _n;
|
|
37549
38907
|
}
|
|
37550
|
-
optimizeNames(names,
|
|
38908
|
+
optimizeNames(names, constants11) {
|
|
37551
38909
|
if (this.lhs instanceof code_1.Name && !names[this.lhs.str] && !this.sideEffects) return;
|
|
37552
|
-
this.rhs = optimizeExpr(this.rhs, names,
|
|
38910
|
+
this.rhs = optimizeExpr(this.rhs, names, constants11);
|
|
37553
38911
|
return this;
|
|
37554
38912
|
}
|
|
37555
38913
|
get names() {
|
|
@@ -37608,8 +38966,8 @@ var require_codegen = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
37608
38966
|
optimizeNodes() {
|
|
37609
38967
|
return `${this.code}` ? this : void 0;
|
|
37610
38968
|
}
|
|
37611
|
-
optimizeNames(names,
|
|
37612
|
-
this.code = optimizeExpr(this.code, names,
|
|
38969
|
+
optimizeNames(names, constants11) {
|
|
38970
|
+
this.code = optimizeExpr(this.code, names, constants11);
|
|
37613
38971
|
return this;
|
|
37614
38972
|
}
|
|
37615
38973
|
get names() {
|
|
@@ -37635,12 +38993,12 @@ var require_codegen = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
37635
38993
|
}
|
|
37636
38994
|
return nodes.length > 0 ? this : void 0;
|
|
37637
38995
|
}
|
|
37638
|
-
optimizeNames(names,
|
|
38996
|
+
optimizeNames(names, constants11) {
|
|
37639
38997
|
const { nodes } = this;
|
|
37640
38998
|
let i = nodes.length;
|
|
37641
38999
|
while (i--) {
|
|
37642
39000
|
const n = nodes[i];
|
|
37643
|
-
if (n.optimizeNames(names,
|
|
39001
|
+
if (n.optimizeNames(names, constants11)) continue;
|
|
37644
39002
|
subtractNames(names, n.names);
|
|
37645
39003
|
nodes.splice(i, 1);
|
|
37646
39004
|
}
|
|
@@ -37687,11 +39045,11 @@ var require_codegen = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
37687
39045
|
if (cond === false || !this.nodes.length) return void 0;
|
|
37688
39046
|
return this;
|
|
37689
39047
|
}
|
|
37690
|
-
optimizeNames(names,
|
|
39048
|
+
optimizeNames(names, constants11) {
|
|
37691
39049
|
var _a3;
|
|
37692
|
-
this.else = (_a3 = this.else) === null || _a3 === void 0 ? void 0 : _a3.optimizeNames(names,
|
|
37693
|
-
if (!(super.optimizeNames(names,
|
|
37694
|
-
this.condition = optimizeExpr(this.condition, names,
|
|
39050
|
+
this.else = (_a3 = this.else) === null || _a3 === void 0 ? void 0 : _a3.optimizeNames(names, constants11);
|
|
39051
|
+
if (!(super.optimizeNames(names, constants11) || this.else)) return;
|
|
39052
|
+
this.condition = optimizeExpr(this.condition, names, constants11);
|
|
37695
39053
|
return this;
|
|
37696
39054
|
}
|
|
37697
39055
|
get names() {
|
|
@@ -37713,9 +39071,9 @@ var require_codegen = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
37713
39071
|
render(opts) {
|
|
37714
39072
|
return `for(${this.iteration})` + super.render(opts);
|
|
37715
39073
|
}
|
|
37716
|
-
optimizeNames(names,
|
|
37717
|
-
if (!super.optimizeNames(names,
|
|
37718
|
-
this.iteration = optimizeExpr(this.iteration, names,
|
|
39074
|
+
optimizeNames(names, constants11) {
|
|
39075
|
+
if (!super.optimizeNames(names, constants11)) return;
|
|
39076
|
+
this.iteration = optimizeExpr(this.iteration, names, constants11);
|
|
37719
39077
|
return this;
|
|
37720
39078
|
}
|
|
37721
39079
|
get names() {
|
|
@@ -37750,9 +39108,9 @@ var require_codegen = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
37750
39108
|
render(opts) {
|
|
37751
39109
|
return `for(${this.varKind} ${this.name} ${this.loop} ${this.iterable})` + super.render(opts);
|
|
37752
39110
|
}
|
|
37753
|
-
optimizeNames(names,
|
|
37754
|
-
if (!super.optimizeNames(names,
|
|
37755
|
-
this.iterable = optimizeExpr(this.iterable, names,
|
|
39111
|
+
optimizeNames(names, constants11) {
|
|
39112
|
+
if (!super.optimizeNames(names, constants11)) return;
|
|
39113
|
+
this.iterable = optimizeExpr(this.iterable, names, constants11);
|
|
37756
39114
|
return this;
|
|
37757
39115
|
}
|
|
37758
39116
|
get names() {
|
|
@@ -37791,11 +39149,11 @@ var require_codegen = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
37791
39149
|
(_b = this.finally) === null || _b === void 0 || _b.optimizeNodes();
|
|
37792
39150
|
return this;
|
|
37793
39151
|
}
|
|
37794
|
-
optimizeNames(names,
|
|
39152
|
+
optimizeNames(names, constants11) {
|
|
37795
39153
|
var _a3, _b;
|
|
37796
|
-
super.optimizeNames(names,
|
|
37797
|
-
(_a3 = this.catch) === null || _a3 === void 0 || _a3.optimizeNames(names,
|
|
37798
|
-
(_b = this.finally) === null || _b === void 0 || _b.optimizeNames(names,
|
|
39154
|
+
super.optimizeNames(names, constants11);
|
|
39155
|
+
(_a3 = this.catch) === null || _a3 === void 0 || _a3.optimizeNames(names, constants11);
|
|
39156
|
+
(_b = this.finally) === null || _b === void 0 || _b.optimizeNames(names, constants11);
|
|
37799
39157
|
return this;
|
|
37800
39158
|
}
|
|
37801
39159
|
get names() {
|
|
@@ -38044,7 +39402,7 @@ var require_codegen = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
38044
39402
|
function addExprNames(names, from) {
|
|
38045
39403
|
return from instanceof code_1._CodeOrName ? addNames(names, from.names) : names;
|
|
38046
39404
|
}
|
|
38047
|
-
function optimizeExpr(expr, names,
|
|
39405
|
+
function optimizeExpr(expr, names, constants11) {
|
|
38048
39406
|
if (expr instanceof code_1.Name) return replaceName(expr);
|
|
38049
39407
|
if (!canOptimize(expr)) return expr;
|
|
38050
39408
|
return new code_1._Code(expr._items.reduce((items, c) => {
|
|
@@ -38054,13 +39412,13 @@ var require_codegen = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
38054
39412
|
return items;
|
|
38055
39413
|
}, []));
|
|
38056
39414
|
function replaceName(n) {
|
|
38057
|
-
const c =
|
|
39415
|
+
const c = constants11[n.str];
|
|
38058
39416
|
if (c === void 0 || names[n.str] !== 1) return n;
|
|
38059
39417
|
delete names[n.str];
|
|
38060
39418
|
return c;
|
|
38061
39419
|
}
|
|
38062
39420
|
function canOptimize(e) {
|
|
38063
|
-
return e instanceof code_1._Code && e._items.some((c) => c instanceof code_1.Name && names[c.str] === 1 &&
|
|
39421
|
+
return e instanceof code_1._Code && e._items.some((c) => c instanceof code_1.Name && names[c.str] === 1 && constants11[c.str] !== void 0);
|
|
38064
39422
|
}
|
|
38065
39423
|
}
|
|
38066
39424
|
function subtractNames(names, from) {
|
|
@@ -39931,8 +41289,8 @@ var require_utils = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
39931
41289
|
for (let i = 0; i < str.length; i++) if (str[i] === token) ind++;
|
|
39932
41290
|
return ind;
|
|
39933
41291
|
}
|
|
39934
|
-
function removeDotSegments(
|
|
39935
|
-
let input2 =
|
|
41292
|
+
function removeDotSegments(path30) {
|
|
41293
|
+
let input2 = path30;
|
|
39936
41294
|
const output2 = [];
|
|
39937
41295
|
let nextSlash = -1;
|
|
39938
41296
|
let len = 0;
|
|
@@ -40085,8 +41443,8 @@ var require_schemes = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
40085
41443
|
wsComponent.secure = void 0;
|
|
40086
41444
|
}
|
|
40087
41445
|
if (wsComponent.resourceName) {
|
|
40088
|
-
const [
|
|
40089
|
-
wsComponent.path =
|
|
41446
|
+
const [path30, query] = wsComponent.resourceName.split("?");
|
|
41447
|
+
wsComponent.path = path30 && path30 !== "/" ? path30 : void 0;
|
|
40090
41448
|
wsComponent.query = query;
|
|
40091
41449
|
wsComponent.resourceName = void 0;
|
|
40092
41450
|
}
|
|
@@ -40192,21 +41550,21 @@ var require_fast_uri = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
40192
41550
|
const { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizeComponentEncoding, isIPv4, nonSimpleDomain } = require_utils();
|
|
40193
41551
|
const { SCHEMES, getSchemeHandler } = require_schemes();
|
|
40194
41552
|
function normalize(uri, options) {
|
|
40195
|
-
if (typeof uri === "string") uri = serialize(
|
|
40196
|
-
else if (typeof uri === "object") uri =
|
|
41553
|
+
if (typeof uri === "string") uri = serialize(parse4(uri, options), options);
|
|
41554
|
+
else if (typeof uri === "object") uri = parse4(serialize(uri, options), options);
|
|
40197
41555
|
return uri;
|
|
40198
41556
|
}
|
|
40199
41557
|
function resolve(baseURI, relativeURI, options) {
|
|
40200
41558
|
const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
|
|
40201
|
-
const resolved = resolveComponent(
|
|
41559
|
+
const resolved = resolveComponent(parse4(baseURI, schemelessOptions), parse4(relativeURI, schemelessOptions), schemelessOptions, true);
|
|
40202
41560
|
schemelessOptions.skipEscape = true;
|
|
40203
41561
|
return serialize(resolved, schemelessOptions);
|
|
40204
41562
|
}
|
|
40205
41563
|
function resolveComponent(base, relative, options, skipNormalization) {
|
|
40206
41564
|
const target = {};
|
|
40207
41565
|
if (!skipNormalization) {
|
|
40208
|
-
base =
|
|
40209
|
-
relative =
|
|
41566
|
+
base = parse4(serialize(base, options), options);
|
|
41567
|
+
relative = parse4(serialize(relative, options), options);
|
|
40210
41568
|
}
|
|
40211
41569
|
options = options || {};
|
|
40212
41570
|
if (!options.tolerant && relative.scheme) {
|
|
@@ -40250,7 +41608,7 @@ var require_fast_uri = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
40250
41608
|
function equal(uriA, uriB, options) {
|
|
40251
41609
|
if (typeof uriA === "string") {
|
|
40252
41610
|
uriA = unescape(uriA);
|
|
40253
|
-
uriA = serialize(normalizeComponentEncoding(
|
|
41611
|
+
uriA = serialize(normalizeComponentEncoding(parse4(uriA, options), true), {
|
|
40254
41612
|
...options,
|
|
40255
41613
|
skipEscape: true
|
|
40256
41614
|
});
|
|
@@ -40260,7 +41618,7 @@ var require_fast_uri = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
40260
41618
|
});
|
|
40261
41619
|
if (typeof uriB === "string") {
|
|
40262
41620
|
uriB = unescape(uriB);
|
|
40263
|
-
uriB = serialize(normalizeComponentEncoding(
|
|
41621
|
+
uriB = serialize(normalizeComponentEncoding(parse4(uriB, options), true), {
|
|
40264
41622
|
...options,
|
|
40265
41623
|
skipEscape: true
|
|
40266
41624
|
});
|
|
@@ -40313,7 +41671,7 @@ var require_fast_uri = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
40313
41671
|
return uriTokens.join("");
|
|
40314
41672
|
}
|
|
40315
41673
|
const URI_PARSE = /^(?:([^#/:?]+):)?(?:\/\/((?:([^#/?@]*)@)?(\[[^#/?\]]+\]|[^#/:?]*)(?::(\d*))?))?([^#?]*)(?:\?([^#]*))?(?:#((?:.|[\n\r])*))?/u;
|
|
40316
|
-
function
|
|
41674
|
+
function parse4(uri, opts) {
|
|
40317
41675
|
const options = Object.assign({}, opts);
|
|
40318
41676
|
const parsed = {
|
|
40319
41677
|
scheme: void 0,
|
|
@@ -40374,7 +41732,7 @@ var require_fast_uri = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
40374
41732
|
resolveComponent,
|
|
40375
41733
|
equal,
|
|
40376
41734
|
serialize,
|
|
40377
|
-
parse:
|
|
41735
|
+
parse: parse4
|
|
40378
41736
|
};
|
|
40379
41737
|
module.exports = fastUri;
|
|
40380
41738
|
module.exports.default = fastUri;
|
|
@@ -45653,7 +47011,8 @@ var DESCRIPTIONS = {
|
|
|
45653
47011
|
git_diff: ["Git diff of the repository at a workspace-relative path.", { readOnlyHint: true, openWorldHint: false }],
|
|
45654
47012
|
git_log: ["Recent Git commits of the repository at a workspace-relative path.", { readOnlyHint: true, openWorldHint: false }],
|
|
45655
47013
|
project_snapshot: ["Compact project overview: Git state and, with startup, AGENTS.md policy and task continuation.", { readOnlyHint: true, openWorldHint: false }],
|
|
45656
|
-
command_run: ["Run one executable with an argument array (no shell parsing), hidden, with captured output. Uses this
|
|
47014
|
+
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 }],
|
|
47015
|
+
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 }],
|
|
45657
47016
|
localhost_request: ["HTTP request to a service on this computer (localhost only).", { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: false }]
|
|
45658
47017
|
};
|
|
45659
47018
|
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.");
|
|
@@ -45666,6 +47025,14 @@ function failure4(error62) {
|
|
|
45666
47025
|
return text2(code + hint, true);
|
|
45667
47026
|
}
|
|
45668
47027
|
function render(name2, result2) {
|
|
47028
|
+
if (name2 === "take_screenshot" && result2.resultCode === "SUCCESS") {
|
|
47029
|
+
try {
|
|
47030
|
+
const { data, mimeType, ...metadata } = JSON.parse(result2.stdout);
|
|
47031
|
+
if (typeof data === "string" && data && mimeType === "image/jpeg") return { content: [{ type: "image", data, mimeType }, { type: "text", text: JSON.stringify(metadata) }] };
|
|
47032
|
+
} catch {
|
|
47033
|
+
}
|
|
47034
|
+
return text2(JSON.stringify({ resultCode: "SCREEN_UNAVAILABLE" }), true);
|
|
47035
|
+
}
|
|
45669
47036
|
if (name2 !== "command_run" && result2.resultCode === "SUCCESS") return text2(result2.stdout);
|
|
45670
47037
|
const { exitCode, resultCode, timedOut, cancelled, stdout, stderr, stdoutTruncated, stderrTruncated } = result2;
|
|
45671
47038
|
return text2(
|
|
@@ -45686,7 +47053,7 @@ async function serveLocalMcp(options) {
|
|
|
45686
47053
|
return connecting;
|
|
45687
47054
|
};
|
|
45688
47055
|
const server = new McpServer({ name: "local-commander-local", version: options.agentVersion }, {
|
|
45689
|
-
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
|
|
47056
|
+
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."
|
|
45690
47057
|
});
|
|
45691
47058
|
server.registerTool(
|
|
45692
47059
|
"workspace_list",
|
|
@@ -45701,7 +47068,7 @@ async function serveLocalMcp(options) {
|
|
|
45701
47068
|
);
|
|
45702
47069
|
for (const option of ToolCallSchema.options) {
|
|
45703
47070
|
const name2 = option.shape.name.value, entry = DESCRIPTIONS[name2];
|
|
45704
|
-
if (!entry) continue;
|
|
47071
|
+
if (!entry || name2 === "take_screenshot" && !screenshotEnabled()) continue;
|
|
45705
47072
|
const inputSchema = option.shape.args.extend({ workspace });
|
|
45706
47073
|
const callback = async (input2, ctx) => {
|
|
45707
47074
|
const { workspace: selected, ...args } = input2;
|
|
@@ -46167,6 +47534,7 @@ async function connectOnce(options) {
|
|
|
46167
47534
|
const incidents = Array.isArray(readyFrame.capabilities) && readyFrame.capabilities.includes("incidentBatchV1");
|
|
46168
47535
|
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;
|
|
46169
47536
|
const nativeStatus = Array.isArray(readyFrame.capabilities) && readyFrame.capabilities.includes(NATIVE_STATUS_CAPABILITY) && options.status;
|
|
47537
|
+
const accessModes = Array.isArray(readyFrame.capabilities) && readyFrame.capabilities.includes(WORKSPACE_ACCESS_MODE_CAPABILITY);
|
|
46170
47538
|
const reportStatus = () => {
|
|
46171
47539
|
if (!nativeStatus) return;
|
|
46172
47540
|
const { safeSlots, active, queued, paused } = nativeStatus();
|
|
@@ -46393,7 +47761,16 @@ async function connectOnce(options) {
|
|
|
46393
47761
|
registerWorkspace: (workspace2) => {
|
|
46394
47762
|
if (pendingWorkspace.size >= 32) return Promise.reject(new RelayClientError("RELAY_PENDING_LIMIT"));
|
|
46395
47763
|
const requestId = randomUUID10();
|
|
46396
|
-
const event = {
|
|
47764
|
+
const event = {
|
|
47765
|
+
type: "workspace_grant",
|
|
47766
|
+
version: 1,
|
|
47767
|
+
requestId,
|
|
47768
|
+
workspaceGrantId: workspace2.workspaceGrantId,
|
|
47769
|
+
rootHash: workspace2.rootHash,
|
|
47770
|
+
displayName: workspace2.displayName,
|
|
47771
|
+
policyVersion: workspace2.policyVersion,
|
|
47772
|
+
...accessModes ? { accessMode: workspace2.fullAccess === true ? "full" : "scoped" } : {}
|
|
47773
|
+
};
|
|
46397
47774
|
return new Promise((resolve, reject) => {
|
|
46398
47775
|
const timer = setTimeout(() => {
|
|
46399
47776
|
pendingWorkspace.delete(requestId);
|
|
@@ -46440,16 +47817,16 @@ async function connectOnce(options) {
|
|
|
46440
47817
|
// agent/src/machine-identity.ts
|
|
46441
47818
|
import { spawn as spawn5 } from "node:child_process";
|
|
46442
47819
|
import { createHash as createHash16 } from "node:crypto";
|
|
46443
|
-
import
|
|
47820
|
+
import os6 from "node:os";
|
|
46444
47821
|
import { open as open7 } from "node:fs/promises";
|
|
46445
|
-
import { constants as
|
|
46446
|
-
import
|
|
47822
|
+
import { constants as constants9 } from "node:fs";
|
|
47823
|
+
import path21 from "node:path";
|
|
46447
47824
|
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;
|
|
46448
47825
|
async function readMachineGuid(timeoutMs2 = 5e3) {
|
|
46449
47826
|
if (process.platform === "linux") {
|
|
46450
47827
|
let handle;
|
|
46451
47828
|
try {
|
|
46452
|
-
handle = await open7("/etc/machine-id",
|
|
47829
|
+
handle = await open7("/etc/machine-id", constants9.O_RDONLY | constants9.O_NOFOLLOW);
|
|
46453
47830
|
const stat2 = await handle.stat();
|
|
46454
47831
|
if (!stat2.isFile() || stat2.size > 128) return null;
|
|
46455
47832
|
const data = Buffer.alloc(129);
|
|
@@ -46464,7 +47841,7 @@ async function readMachineGuid(timeoutMs2 = 5e3) {
|
|
|
46464
47841
|
}
|
|
46465
47842
|
}
|
|
46466
47843
|
if (!["win32", "darwin"].includes(process.platform)) return null;
|
|
46467
|
-
const reg = process.platform === "darwin" ? "/usr/sbin/ioreg" :
|
|
47844
|
+
const reg = process.platform === "darwin" ? "/usr/sbin/ioreg" : path21.join(process.env.SystemRoot || "C:\\Windows", "System32", "reg.exe");
|
|
46468
47845
|
const args = process.platform === "darwin" ? ["-rd1", "-c", "IOPlatformExpertDevice"] : ["query", "HKLM\\SOFTWARE\\Microsoft\\Cryptography", "/v", "MachineGuid", "/reg:64"];
|
|
46469
47846
|
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;
|
|
46470
47847
|
return new Promise((resolve) => {
|
|
@@ -46498,7 +47875,7 @@ async function readComputerName(timeoutMs2 = 5e3) {
|
|
|
46498
47875
|
if (process.platform === "linux") {
|
|
46499
47876
|
let handle;
|
|
46500
47877
|
try {
|
|
46501
|
-
handle = await open7("/etc/hostname",
|
|
47878
|
+
handle = await open7("/etc/hostname", constants9.O_RDONLY | constants9.O_NOFOLLOW);
|
|
46502
47879
|
const data = Buffer.alloc(257), { bytesRead } = await handle.read(data, 0, data.length, 0);
|
|
46503
47880
|
const name2 = data.subarray(0, bytesRead).toString("utf8").trim();
|
|
46504
47881
|
if (bytesRead <= 256 && valid(name2)) return name2;
|
|
@@ -46536,9 +47913,9 @@ async function readComputerName(timeoutMs2 = 5e3) {
|
|
|
46536
47913
|
});
|
|
46537
47914
|
if (valid(name2)) return name2;
|
|
46538
47915
|
}
|
|
46539
|
-
return
|
|
47916
|
+
return os6.hostname();
|
|
46540
47917
|
}
|
|
46541
|
-
function machineProof(deviceId, machineGuid, computerName =
|
|
47918
|
+
function machineProof(deviceId, machineGuid, computerName = os6.hostname()) {
|
|
46542
47919
|
const name2 = computerName.slice(0, 120);
|
|
46543
47920
|
if (!name2 || name2.trim() !== name2 || /[\u0000-\u001f\u007f]/.test(name2)) return null;
|
|
46544
47921
|
const fingerprint3 = createHash16("sha256").update("lcmcp-machine-v1\0" + deviceId.toLowerCase() + "\0" + machineGuid.toLowerCase() + "\0" + name2.toUpperCase(), "utf8").digest("hex");
|
|
@@ -46579,8 +47956,8 @@ function canonicalOrigin2(value) {
|
|
|
46579
47956
|
fail6("ORIGIN_INVALID");
|
|
46580
47957
|
}
|
|
46581
47958
|
}
|
|
46582
|
-
function endpoint(origin,
|
|
46583
|
-
return origin +
|
|
47959
|
+
function endpoint(origin, path30) {
|
|
47960
|
+
return origin + path30;
|
|
46584
47961
|
}
|
|
46585
47962
|
function uuid21(value, code) {
|
|
46586
47963
|
if (typeof value !== "string" || !UUID3.test(value)) fail6(code);
|
|
@@ -47081,29 +48458,29 @@ async function deliverGuardEvidence(target, packet, options = {}) {
|
|
|
47081
48458
|
}
|
|
47082
48459
|
|
|
47083
48460
|
// agent/src/optimization-ledger.ts
|
|
47084
|
-
import { constants as
|
|
47085
|
-
import { lstat as
|
|
47086
|
-
import
|
|
48461
|
+
import { constants as constants10 } from "node:fs";
|
|
48462
|
+
import { lstat as lstat9, mkdir as mkdir8, open as open8, readFile as readFile9, realpath as realpath8 } from "node:fs/promises";
|
|
48463
|
+
import path22 from "node:path";
|
|
47087
48464
|
var MAX_LEDGER_BYTES = 64 * 1024 * 1024;
|
|
47088
48465
|
var MAX_NOTICE_LEDGER_BYTES = 8 * 1024 * 1024;
|
|
47089
48466
|
function failure5(code) {
|
|
47090
48467
|
return Object.assign(new Error(code), { code });
|
|
47091
48468
|
}
|
|
47092
48469
|
async function safeDirectory2(directory) {
|
|
47093
|
-
const absolute2 =
|
|
48470
|
+
const absolute2 = path22.resolve(directory);
|
|
47094
48471
|
let current2 = absolute2;
|
|
47095
48472
|
for (; ; ) {
|
|
47096
48473
|
try {
|
|
47097
|
-
if ((await
|
|
48474
|
+
if ((await lstat9(current2)).isSymbolicLink()) throw failure5("OPTIMIZATION_LEDGER_DIRECTORY_INVALID");
|
|
47098
48475
|
} catch (error62) {
|
|
47099
48476
|
if (error62.code !== "ENOENT") throw error62;
|
|
47100
48477
|
}
|
|
47101
|
-
const parent =
|
|
48478
|
+
const parent = path22.dirname(current2);
|
|
47102
48479
|
if (parent === current2) break;
|
|
47103
48480
|
current2 = parent;
|
|
47104
48481
|
}
|
|
47105
48482
|
await mkdir8(absolute2, { recursive: true, mode: 448 });
|
|
47106
|
-
const stat2 = await
|
|
48483
|
+
const stat2 = await lstat9(absolute2);
|
|
47107
48484
|
if (!stat2.isDirectory() || stat2.isSymbolicLink()) throw failure5("OPTIMIZATION_LEDGER_DIRECTORY_INVALID");
|
|
47108
48485
|
return realpath8(absolute2);
|
|
47109
48486
|
}
|
|
@@ -47133,29 +48510,29 @@ var OptimizationLedger = class _OptimizationLedger {
|
|
|
47133
48510
|
closed = false;
|
|
47134
48511
|
static async open(directory) {
|
|
47135
48512
|
const dir = await safeDirectory2(directory);
|
|
47136
|
-
const filename =
|
|
47137
|
-
const noticesFilename =
|
|
48513
|
+
const filename = path22.join(dir, "live-efficiency.v1.jsonl");
|
|
48514
|
+
const noticesFilename = path22.join(dir, "live-efficiency-notices.v1.jsonl");
|
|
47138
48515
|
let existing = "";
|
|
47139
48516
|
try {
|
|
47140
|
-
const stat2 = await
|
|
48517
|
+
const stat2 = await lstat9(filename);
|
|
47141
48518
|
if (!stat2.isFile() || stat2.isSymbolicLink() || stat2.size > MAX_LEDGER_BYTES) {
|
|
47142
48519
|
throw failure5("OPTIMIZATION_LEDGER_INVALID");
|
|
47143
48520
|
}
|
|
47144
|
-
existing = await
|
|
48521
|
+
existing = await readFile9(filename, "utf8");
|
|
47145
48522
|
} catch (error62) {
|
|
47146
48523
|
if (error62.code !== "ENOENT") throw error62;
|
|
47147
48524
|
}
|
|
47148
48525
|
const handle = await open8(
|
|
47149
48526
|
filename,
|
|
47150
|
-
|
|
48527
|
+
constants10.O_CREAT | constants10.O_APPEND | constants10.O_WRONLY | (constants10.O_NOFOLLOW ?? 0),
|
|
47151
48528
|
384
|
|
47152
48529
|
);
|
|
47153
48530
|
const ledger = new _OptimizationLedger(filename, handle, noticesFilename);
|
|
47154
48531
|
try {
|
|
47155
48532
|
try {
|
|
47156
|
-
const noticeStat = await
|
|
48533
|
+
const noticeStat = await lstat9(noticesFilename);
|
|
47157
48534
|
if (!noticeStat.isFile() || noticeStat.isSymbolicLink() || noticeStat.size > MAX_NOTICE_LEDGER_BYTES) throw failure5("OPTIMIZATION_NOTICE_LEDGER_INVALID");
|
|
47158
|
-
const notices = await
|
|
48535
|
+
const notices = await readFile9(noticesFilename, "utf8");
|
|
47159
48536
|
for (const line of notices.split("\n")) {
|
|
47160
48537
|
if (!line) continue;
|
|
47161
48538
|
const parsed = JSON.parse(line);
|
|
@@ -47235,7 +48612,7 @@ var OptimizationLedger = class _OptimizationLedger {
|
|
|
47235
48612
|
const marker = JSON.stringify({ sessionId: event.sessionId, checkpointCalls, deliveredAt: (/* @__PURE__ */ new Date()).toISOString() }) + "\n";
|
|
47236
48613
|
let currentBytes = 0;
|
|
47237
48614
|
try {
|
|
47238
|
-
const stat2 = await
|
|
48615
|
+
const stat2 = await lstat9(this.noticesFilename);
|
|
47239
48616
|
if (!stat2.isFile() || stat2.isSymbolicLink()) throw failure5("OPTIMIZATION_NOTICE_LEDGER_INVALID");
|
|
47240
48617
|
currentBytes = stat2.size;
|
|
47241
48618
|
} catch (error62) {
|
|
@@ -47244,7 +48621,7 @@ var OptimizationLedger = class _OptimizationLedger {
|
|
|
47244
48621
|
if (currentBytes + Buffer.byteLength(marker, "utf8") > MAX_NOTICE_LEDGER_BYTES) throw failure5("OPTIMIZATION_NOTICE_LEDGER_CAPACITY_EXCEEDED");
|
|
47245
48622
|
const markerHandle = await open8(
|
|
47246
48623
|
this.noticesFilename,
|
|
47247
|
-
|
|
48624
|
+
constants10.O_CREAT | constants10.O_APPEND | constants10.O_WRONLY | (constants10.O_NOFOLLOW ?? 0),
|
|
47248
48625
|
384
|
|
47249
48626
|
);
|
|
47250
48627
|
try {
|
|
@@ -47283,9 +48660,9 @@ var OptimizationLedger = class _OptimizationLedger {
|
|
|
47283
48660
|
|
|
47284
48661
|
// agent/src/monitor.ts
|
|
47285
48662
|
import { createHash as createHash17, randomUUID as randomUUID12 } from "node:crypto";
|
|
47286
|
-
import { lstat as
|
|
47287
|
-
import
|
|
47288
|
-
import
|
|
48663
|
+
import { lstat as lstat10, mkdir as mkdir9, open as open9, rename as rename6, rm as rm8 } from "node:fs/promises";
|
|
48664
|
+
import path23 from "node:path";
|
|
48665
|
+
import os7 from "node:os";
|
|
47289
48666
|
|
|
47290
48667
|
// packages/agent-cli/bin/monitor-savings.mjs
|
|
47291
48668
|
var count = (value) => Number.isSafeInteger(value) && value >= 0 && value <= 1e15;
|
|
@@ -47307,7 +48684,7 @@ function lifetimeSavingsView(raw) {
|
|
|
47307
48684
|
// agent/src/monitor.ts
|
|
47308
48685
|
function commandSummary2(tool) {
|
|
47309
48686
|
if (tool.name !== "command_run") return { name: tool.name, command: tool.name };
|
|
47310
|
-
const candidate =
|
|
48687
|
+
const candidate = path23.win32.basename(tool.args.command).replace(/\.(exe|cmd|bat|com)$/i, "").toLowerCase();
|
|
47311
48688
|
const name2 = ["node", "npm", "npx", "git", "rg", "powershell", "pwsh", "cmd", "tsc", "python", "dotnet"].includes(candidate) ? candidate : "command";
|
|
47312
48689
|
let command = name2;
|
|
47313
48690
|
if (name2 === "node" && tool.args.args.includes("--test") && !tool.args.args.some((arg) => ["-e", "--eval", "-p", "--print"].includes(arg))) command += " --test";
|
|
@@ -47320,9 +48697,9 @@ function commandSummary2(tool) {
|
|
|
47320
48697
|
var ProductionMonitor = class {
|
|
47321
48698
|
constructor(directory, stateDirectory, agentVersion3) {
|
|
47322
48699
|
this.agentVersion = agentVersion3;
|
|
47323
|
-
const key = createHash17("sha256").update(
|
|
47324
|
-
this.file =
|
|
47325
|
-
this.transportFile =
|
|
48700
|
+
const key = createHash17("sha256").update(path23.resolve(stateDirectory).toLowerCase()).digest("hex");
|
|
48701
|
+
this.file = path23.join(directory, key + ".json");
|
|
48702
|
+
this.transportFile = path23.join(directory, key + ".transport");
|
|
47326
48703
|
}
|
|
47327
48704
|
agentVersion;
|
|
47328
48705
|
instanceId = randomUUID12();
|
|
@@ -47333,7 +48710,7 @@ var ProductionMonitor = class {
|
|
|
47333
48710
|
measured = /* @__PURE__ */ new Set();
|
|
47334
48711
|
polls = { status: 0, output: 0 };
|
|
47335
48712
|
efficiencyCalls = 0;
|
|
47336
|
-
computer =
|
|
48713
|
+
computer = os7.hostname().replace(/[^A-Za-z0-9._-]/g, "_").slice(0, 64) || "PC";
|
|
47337
48714
|
sequence = 0;
|
|
47338
48715
|
connection = {
|
|
47339
48716
|
state: "starting",
|
|
@@ -47514,7 +48891,7 @@ var ProductionMonitor = class {
|
|
|
47514
48891
|
schemaVersion: 1,
|
|
47515
48892
|
instanceId: this.instanceId,
|
|
47516
48893
|
pid: process.pid,
|
|
47517
|
-
savingsSourceId:
|
|
48894
|
+
savingsSourceId: path23.basename(this.file, ".json"),
|
|
47518
48895
|
lifetimeSavings: this.lifetimeSavings && { ...this.lifetimeSavings },
|
|
47519
48896
|
computer: this.computer,
|
|
47520
48897
|
processName: "lc-agent",
|
|
@@ -47548,9 +48925,9 @@ var ProductionMonitor = class {
|
|
|
47548
48925
|
return this.writing;
|
|
47549
48926
|
}
|
|
47550
48927
|
async write(file2, contents) {
|
|
47551
|
-
const directory =
|
|
48928
|
+
const directory = path23.dirname(file2);
|
|
47552
48929
|
await mkdir9(directory, { recursive: true, mode: 448 });
|
|
47553
|
-
const stat2 = await
|
|
48930
|
+
const stat2 = await lstat10(directory);
|
|
47554
48931
|
if (!stat2.isDirectory() || stat2.isSymbolicLink()) throw Error("MONITOR_DIRECTORY_INVALID");
|
|
47555
48932
|
const temporary = file2 + "." + this.instanceId + ".tmp";
|
|
47556
48933
|
const handle = await open9(temporary, "wx", 384);
|
|
@@ -47562,7 +48939,7 @@ var ProductionMonitor = class {
|
|
|
47562
48939
|
}
|
|
47563
48940
|
await rename6(temporary, file2);
|
|
47564
48941
|
} finally {
|
|
47565
|
-
await
|
|
48942
|
+
await rm8(temporary, { force: true });
|
|
47566
48943
|
}
|
|
47567
48944
|
}
|
|
47568
48945
|
async close() {
|
|
@@ -47973,27 +49350,27 @@ var NativeFabricObserver = class {
|
|
|
47973
49350
|
};
|
|
47974
49351
|
|
|
47975
49352
|
// agent/src/native-fabric-startup.ts
|
|
47976
|
-
import { lstat as
|
|
47977
|
-
import
|
|
49353
|
+
import { lstat as lstat12, mkdir as mkdir12, open as open11, readFile as readFile10 } from "node:fs/promises";
|
|
49354
|
+
import path26 from "node:path";
|
|
47978
49355
|
|
|
47979
49356
|
// src/agent-fabric-service.ts
|
|
47980
|
-
import { lstat as
|
|
49357
|
+
import { lstat as lstat11, mkdir as mkdir11, realpath as realpath9 } from "node:fs/promises";
|
|
47981
49358
|
import { watch } from "node:fs";
|
|
47982
|
-
import
|
|
49359
|
+
import path25 from "node:path";
|
|
47983
49360
|
|
|
47984
49361
|
// src/agent-runtime-identity.ts
|
|
47985
|
-
import { createHash as createHash19, randomBytes as
|
|
49362
|
+
import { createHash as createHash19, randomBytes as randomBytes8, randomUUID as randomUUID14, timingSafeEqual as timingSafeEqual4 } from "node:crypto";
|
|
47986
49363
|
|
|
47987
49364
|
// src/agent-fabric-state.ts
|
|
47988
49365
|
import { randomUUID as randomUUID13 } from "node:crypto";
|
|
47989
|
-
import { mkdir as mkdir10, open as open10, rename as rename7, unlink as
|
|
47990
|
-
import
|
|
49366
|
+
import { mkdir as mkdir10, open as open10, rename as rename7, unlink as unlink3 } from "node:fs/promises";
|
|
49367
|
+
import path24 from "node:path";
|
|
47991
49368
|
var queues = /* @__PURE__ */ new Map();
|
|
47992
49369
|
var FabricStateFile = class {
|
|
47993
|
-
constructor(file2, maxBytes,
|
|
49370
|
+
constructor(file2, maxBytes, parse4) {
|
|
47994
49371
|
this.maxBytes = maxBytes;
|
|
47995
|
-
this.parse =
|
|
47996
|
-
this.file =
|
|
49372
|
+
this.parse = parse4;
|
|
49373
|
+
this.file = path24.resolve(file2);
|
|
47997
49374
|
}
|
|
47998
49375
|
maxBytes;
|
|
47999
49376
|
parse;
|
|
@@ -48037,7 +49414,7 @@ var FabricStateFile = class {
|
|
|
48037
49414
|
}
|
|
48038
49415
|
update(fn, create) {
|
|
48039
49416
|
return this.serial(async () => {
|
|
48040
|
-
if (create) await mkdir10(
|
|
49417
|
+
if (create) await mkdir10(path24.dirname(this.file), { recursive: true });
|
|
48041
49418
|
const lockPath = this.file + ".lock";
|
|
48042
49419
|
const token = randomUUID13();
|
|
48043
49420
|
const lock = await open10(lockPath, "wx", 384).catch((error62) => {
|
|
@@ -48068,7 +49445,7 @@ var FabricStateFile = class {
|
|
|
48068
49445
|
}
|
|
48069
49446
|
await rename7(temporary, this.file);
|
|
48070
49447
|
} finally {
|
|
48071
|
-
await
|
|
49448
|
+
await unlink3(temporary).catch((error62) => {
|
|
48072
49449
|
if (error62.code !== "ENOENT") throw error62;
|
|
48073
49450
|
});
|
|
48074
49451
|
}
|
|
@@ -48082,7 +49459,7 @@ var FabricStateFile = class {
|
|
|
48082
49459
|
} finally {
|
|
48083
49460
|
await current2.close();
|
|
48084
49461
|
}
|
|
48085
|
-
await
|
|
49462
|
+
await unlink3(lockPath);
|
|
48086
49463
|
}
|
|
48087
49464
|
});
|
|
48088
49465
|
}
|
|
@@ -48136,7 +49513,7 @@ var AgentRuntimeIdentityStore = class {
|
|
|
48136
49513
|
return this.serial((state) => {
|
|
48137
49514
|
if (state.bindings.length >= MAX_BINDINGS) throw Error("RUNTIME_IDENTITY_LIMIT");
|
|
48138
49515
|
const runtimeId = "rt-" + randomUUID14();
|
|
48139
|
-
const runtimeKey =
|
|
49516
|
+
const runtimeKey = randomBytes8(32).toString("base64url");
|
|
48140
49517
|
const now = this.now();
|
|
48141
49518
|
state.bindings.push({ runtimeId, keyHash: encodedDigest(runtimeKey), createdAt: now, lastUsedAt: now, revoked: false });
|
|
48142
49519
|
return { runtimeId, runtimeKey };
|
|
@@ -48681,9 +50058,9 @@ var WorkerRequest = external_exports.discriminatedUnion("operation", [
|
|
|
48681
50058
|
var AgentFabricService = class _AgentFabricService {
|
|
48682
50059
|
constructor(directory, controllerId) {
|
|
48683
50060
|
this.directory = directory;
|
|
48684
|
-
this.identities = new AgentRuntimeIdentityStore(
|
|
50061
|
+
this.identities = new AgentRuntimeIdentityStore(path25.join(directory, "identities.json"));
|
|
48685
50062
|
this.mailbox = new AgentWorkerMailbox(
|
|
48686
|
-
|
|
50063
|
+
path25.join(directory, "mailbox.json"),
|
|
48687
50064
|
controllerId,
|
|
48688
50065
|
this.identities,
|
|
48689
50066
|
void 0,
|
|
@@ -48698,21 +50075,21 @@ var AgentFabricService = class _AgentFabricService {
|
|
|
48698
50075
|
closed = false;
|
|
48699
50076
|
static async open(directory, controllerId, device = null, initialize = true) {
|
|
48700
50077
|
const expected = Binding.parse({ version: 1, controllerId, device, initialized: false });
|
|
48701
|
-
const absolute2 =
|
|
48702
|
-
for (let current2 = absolute2; ; current2 =
|
|
50078
|
+
const absolute2 = path25.resolve(directory);
|
|
50079
|
+
for (let current2 = absolute2; ; current2 = path25.dirname(current2)) {
|
|
48703
50080
|
try {
|
|
48704
|
-
if ((await
|
|
50081
|
+
if ((await lstat11(current2)).isSymbolicLink()) throw Error("FABRIC_DIRECTORY_INVALID");
|
|
48705
50082
|
} catch (error62) {
|
|
48706
50083
|
if (error62.code !== "ENOENT") throw error62;
|
|
48707
50084
|
}
|
|
48708
|
-
if (
|
|
50085
|
+
if (path25.dirname(current2) === current2) break;
|
|
48709
50086
|
}
|
|
48710
50087
|
if (initialize) await mkdir11(absolute2, { recursive: true, mode: 448 });
|
|
48711
|
-
if (!(await
|
|
50088
|
+
if (!(await lstat11(absolute2)).isDirectory() || (await realpath9(absolute2)).toLowerCase() !== absolute2.toLowerCase())
|
|
48712
50089
|
throw Error("FABRIC_DIRECTORY_INVALID");
|
|
48713
50090
|
const present = /* @__PURE__ */ new Set();
|
|
48714
50091
|
for (const name2 of ["binding.json", "mailbox.json", "identities.json"]) {
|
|
48715
|
-
const file2 = await
|
|
50092
|
+
const file2 = await lstat11(path25.join(absolute2, name2)).catch((error62) => {
|
|
48716
50093
|
if (error62.code === "ENOENT") return null;
|
|
48717
50094
|
throw error62;
|
|
48718
50095
|
});
|
|
@@ -48720,7 +50097,7 @@ var AgentFabricService = class _AgentFabricService {
|
|
|
48720
50097
|
if (file2) present.add(name2);
|
|
48721
50098
|
}
|
|
48722
50099
|
if (!present.has("binding.json") && present.size) throw Error("FABRIC_BINDING_MISSING");
|
|
48723
|
-
const binding2 = new FabricStateFile(
|
|
50100
|
+
const binding2 = new FabricStateFile(path25.join(absolute2, "binding.json"), 2048, (value) => Binding.parse(value));
|
|
48724
50101
|
const service2 = new _AgentFabricService(absolute2, controllerId);
|
|
48725
50102
|
await binding2.update(async (state) => {
|
|
48726
50103
|
if (state.controllerId !== expected.controllerId || JSON.stringify(state.device) !== JSON.stringify(expected.device))
|
|
@@ -48735,7 +50112,7 @@ var AgentFabricService = class _AgentFabricService {
|
|
|
48735
50112
|
state.initialized = true;
|
|
48736
50113
|
}
|
|
48737
50114
|
const snapshot2 = await service2.mailbox.snapshot();
|
|
48738
|
-
if (snapshot2.workers.some((worker) => worker.runtimeId !== null)) await
|
|
50115
|
+
if (snapshot2.workers.some((worker) => worker.runtimeId !== null)) await lstat11(path25.join(absolute2, "identities.json"));
|
|
48739
50116
|
}, initialize ? () => expected : void 0);
|
|
48740
50117
|
return service2;
|
|
48741
50118
|
}
|
|
@@ -48822,19 +50199,19 @@ var Delivery = external_exports.strictObject({ capability: external_exports.stri
|
|
|
48822
50199
|
async function openNativeFabric(stateDirectory, enrollment, box, initialize = true) {
|
|
48823
50200
|
const controllerId = "device-" + external_exports.string().uuid().parse(enrollment.deviceId).toLowerCase();
|
|
48824
50201
|
const tenantId = external_exports.string().uuid().parse(enrollment.tenantId).toLowerCase();
|
|
48825
|
-
const parent =
|
|
50202
|
+
const parent = path26.join(stateDirectory, ".local-commander"), marker = path26.join(parent, "fabric-established.json");
|
|
48826
50203
|
try {
|
|
48827
50204
|
await mkdir12(parent, { mode: 448 });
|
|
48828
50205
|
} catch (error62) {
|
|
48829
50206
|
if (error62.code !== "EEXIST") throw error62;
|
|
48830
50207
|
}
|
|
48831
|
-
const parentInfo = await
|
|
50208
|
+
const parentInfo = await lstat12(parent);
|
|
48832
50209
|
if (!parentInfo.isDirectory() || parentInfo.isSymbolicLink()) throw Error("FABRIC_DIRECTORY_INVALID");
|
|
48833
50210
|
const expected = JSON.stringify({ version: 1, controllerId, tenantId });
|
|
48834
50211
|
let fresh = false;
|
|
48835
50212
|
try {
|
|
48836
|
-
const info = await
|
|
48837
|
-
if (!info.isFile() || info.isSymbolicLink() || info.size > 2048 || await
|
|
50213
|
+
const info = await lstat12(marker);
|
|
50214
|
+
if (!info.isFile() || info.isSymbolicLink() || info.size > 2048 || await readFile10(marker, "utf8") !== expected)
|
|
48838
50215
|
throw Error("FABRIC_BINDING_CHANGED");
|
|
48839
50216
|
} catch (error62) {
|
|
48840
50217
|
if (error62.code !== "ENOENT" || !initialize) throw error62;
|
|
@@ -48848,22 +50225,22 @@ async function openNativeFabric(stateDirectory, enrollment, box, initialize = tr
|
|
|
48848
50225
|
fresh = true;
|
|
48849
50226
|
}
|
|
48850
50227
|
const service2 = await AgentFabricService.open(
|
|
48851
|
-
|
|
50228
|
+
path26.join(stateDirectory, ".local-commander", "fabric"),
|
|
48852
50229
|
controllerId,
|
|
48853
50230
|
{ deviceId: enrollment.deviceId.toLowerCase(), enrollmentEvidenceRef: "enrollment-" + tenantId },
|
|
48854
50231
|
fresh
|
|
48855
50232
|
);
|
|
48856
50233
|
const purpose = "native-fabric:" + tenantId + ":" + controllerId;
|
|
48857
|
-
const credentialFile = (workerId) =>
|
|
50234
|
+
const credentialFile = (workerId) => path26.join(service2.directory, external_exports.string().uuid().parse(workerId) + ".capability");
|
|
48858
50235
|
const decode4 = (value) => {
|
|
48859
50236
|
const credential = Credential.parse(JSON.parse(box.open(Buffer.from(value, "base64"), purpose).toString("utf8")));
|
|
48860
50237
|
if (credential.controllerId !== controllerId) throw Error("FABRIC_WORKER_DENIED");
|
|
48861
50238
|
return credential;
|
|
48862
50239
|
};
|
|
48863
50240
|
async function capability(workerId) {
|
|
48864
|
-
const file2 = credentialFile(workerId), info = await
|
|
50241
|
+
const file2 = credentialFile(workerId), info = await lstat12(file2);
|
|
48865
50242
|
if (!info.isFile() || info.isSymbolicLink() || info.size > 4096) throw Error("FABRIC_CREDENTIAL_UNKNOWN");
|
|
48866
|
-
const encoded = await
|
|
50243
|
+
const encoded = await readFile10(file2, "utf8");
|
|
48867
50244
|
if (decode4(encoded).workerId !== workerId) throw Error("FABRIC_WORKER_DENIED");
|
|
48868
50245
|
return encoded;
|
|
48869
50246
|
}
|
|
@@ -48955,7 +50332,7 @@ async function readFabricRequest(input2 = process.stdin) {
|
|
|
48955
50332
|
|
|
48956
50333
|
// agent/src/supervisor-liveness.ts
|
|
48957
50334
|
import { spawn as spawn6 } from "node:child_process";
|
|
48958
|
-
import
|
|
50335
|
+
import path27 from "node:path";
|
|
48959
50336
|
import { setTimeout as delay3 } from "node:timers/promises";
|
|
48960
50337
|
var ROW = /^"([^"]+)","(\d{1,10})"/;
|
|
48961
50338
|
function parseTasklist(output2, image) {
|
|
@@ -48970,7 +50347,7 @@ function parseTasklist(output2, image) {
|
|
|
48970
50347
|
}
|
|
48971
50348
|
function listProcesses(image, timeoutMs2 = 5e3) {
|
|
48972
50349
|
if (process.platform !== "win32" || !/^[A-Za-z0-9._-]{1,64}\.exe$/i.test(image)) return Promise.resolve(null);
|
|
48973
|
-
const tasklist =
|
|
50350
|
+
const tasklist = path27.join(process.env.SystemRoot || "C:\\Windows", "System32", "tasklist.exe");
|
|
48974
50351
|
return new Promise((resolve) => {
|
|
48975
50352
|
let output2 = "", settled = false;
|
|
48976
50353
|
const finish = (value) => {
|
|
@@ -48999,8 +50376,8 @@ function listProcesses(image, timeoutMs2 = 5e3) {
|
|
|
48999
50376
|
}
|
|
49000
50377
|
function supervisorLiveness(helperPath, options = {}) {
|
|
49001
50378
|
if (process.platform === "linux" && !options.list) return linuxSupervisorLiveness;
|
|
49002
|
-
if (process.platform === "darwin" && !options.list) return (pids, _linux, darwin) => darwinSupervisorLiveness(
|
|
49003
|
-
const image =
|
|
50379
|
+
if (process.platform === "darwin" && !options.list) return (pids, _linux, darwin) => darwinSupervisorLiveness(path27.join(path27.dirname(helperPath), "posix-host"), pids, darwin);
|
|
50380
|
+
const image = path27.basename(helperPath), waitMs = options.waitMs ?? 1e4, pollMs = options.pollMs ?? 500, list = options.list ?? listProcesses;
|
|
49004
50381
|
return async (pids) => {
|
|
49005
50382
|
const deadline = Date.now() + waitMs;
|
|
49006
50383
|
for (; ; ) {
|
|
@@ -49015,14 +50392,14 @@ function supervisorLiveness(helperPath, options = {}) {
|
|
|
49015
50392
|
|
|
49016
50393
|
// agent/src/content-audit.ts
|
|
49017
50394
|
import { createReadStream } from "node:fs";
|
|
49018
|
-
import { appendFile, lstat as
|
|
49019
|
-
import
|
|
50395
|
+
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";
|
|
50396
|
+
import path28 from "node:path";
|
|
49020
50397
|
import { performance as performance3 } from "node:perf_hooks";
|
|
49021
50398
|
import { createInterface as createInterface2 } from "node:readline";
|
|
49022
|
-
import { randomBytes as
|
|
50399
|
+
import { randomBytes as randomBytes10 } from "node:crypto";
|
|
49023
50400
|
|
|
49024
50401
|
// src/audit-crypto.ts
|
|
49025
|
-
import { createCipheriv as createCipheriv3, createDecipheriv as createDecipheriv3, createHash as createHash20, randomBytes as
|
|
50402
|
+
import { createCipheriv as createCipheriv3, createDecipheriv as createDecipheriv3, createHash as createHash20, randomBytes as randomBytes9 } from "node:crypto";
|
|
49026
50403
|
import { promisify as promisify3 } from "node:util";
|
|
49027
50404
|
import { gunzipSync, gzip, gzipSync } from "node:zlib";
|
|
49028
50405
|
var gzipAsync = promisify3(gzip);
|
|
@@ -49074,7 +50451,7 @@ async function encryptAuditRecordAsync(record2, keyInput, keyId2) {
|
|
|
49074
50451
|
function sealCompressed(compressed, keyInput, keyId2) {
|
|
49075
50452
|
const key = parseAuditRecoveryKey(keyInput);
|
|
49076
50453
|
const kid = keyId2?.trim() || auditRecoveryKeyId(key);
|
|
49077
|
-
const iv =
|
|
50454
|
+
const iv = randomBytes9(IV_BYTES);
|
|
49078
50455
|
try {
|
|
49079
50456
|
const cipher = createCipheriv3("aes-256-gcm", key, iv, { authTagLength: TAG_BYTES });
|
|
49080
50457
|
cipher.setAAD(additionalData(kid));
|
|
@@ -49185,17 +50562,17 @@ var FILE = /^(full|metrics)-(\d{4}-\d{2}-\d{2})\.jsonl$/;
|
|
|
49185
50562
|
var PAUSED_FILE = "paused.json";
|
|
49186
50563
|
var DAY_MS = 864e5;
|
|
49187
50564
|
function contentAuditDirectory(stateDir) {
|
|
49188
|
-
return
|
|
50565
|
+
return path28.join(path28.dirname(path28.resolve(stateDir)), "Audit");
|
|
49189
50566
|
}
|
|
49190
50567
|
async function plainDirectory(dir) {
|
|
49191
50568
|
await mkdir13(dir, { recursive: true, mode: 448 });
|
|
49192
|
-
const info = await
|
|
50569
|
+
const info = await lstat13(dir);
|
|
49193
50570
|
if (info.isSymbolicLink() || !info.isDirectory()) throw Error("AUDIT_DIRECTORY_INVALID");
|
|
49194
50571
|
}
|
|
49195
50572
|
async function auditFiles(dir) {
|
|
49196
50573
|
let names;
|
|
49197
50574
|
try {
|
|
49198
|
-
names = await
|
|
50575
|
+
names = await readdir6(dir);
|
|
49199
50576
|
} catch (error62) {
|
|
49200
50577
|
if (error62.code === "ENOENT") return [];
|
|
49201
50578
|
throw error62;
|
|
@@ -49204,18 +50581,18 @@ async function auditFiles(dir) {
|
|
|
49204
50581
|
for (const name2 of names) {
|
|
49205
50582
|
const match = FILE.exec(name2);
|
|
49206
50583
|
if (!match) continue;
|
|
49207
|
-
const info = await
|
|
50584
|
+
const info = await lstat13(path28.join(dir, name2));
|
|
49208
50585
|
if (info.isFile()) files.push({ name: name2, kind: match[1], day: match[2], bytes: info.size });
|
|
49209
50586
|
}
|
|
49210
50587
|
return files.sort((a, b) => a.name.localeCompare(b.name));
|
|
49211
50588
|
}
|
|
49212
50589
|
async function writeJsonAtomic(file2, value) {
|
|
49213
|
-
const temp = `${file2}.${
|
|
50590
|
+
const temp = `${file2}.${randomBytes10(6).toString("hex")}.tmp`;
|
|
49214
50591
|
try {
|
|
49215
50592
|
await writeFile4(temp, JSON.stringify(value) + "\n", { flag: "wx", mode: 384 });
|
|
49216
50593
|
await rename8(temp, file2);
|
|
49217
50594
|
} finally {
|
|
49218
|
-
await
|
|
50595
|
+
await rm9(temp, { force: true }).catch(() => {
|
|
49219
50596
|
});
|
|
49220
50597
|
}
|
|
49221
50598
|
}
|
|
@@ -49242,7 +50619,7 @@ var ContentAudit = class _ContentAudit {
|
|
|
49242
50619
|
skipped = 0;
|
|
49243
50620
|
closed = false;
|
|
49244
50621
|
static async open(options) {
|
|
49245
|
-
const dir =
|
|
50622
|
+
const dir = path28.resolve(options.directory);
|
|
49246
50623
|
await plainDirectory(dir);
|
|
49247
50624
|
const audit = new _ContentAudit(
|
|
49248
50625
|
dir,
|
|
@@ -49251,7 +50628,7 @@ var ContentAudit = class _ContentAudit {
|
|
|
49251
50628
|
{ retentionDays: options.retentionDays ?? AUDIT_RETENTION_DAYS, maxBytes: options.maxBytes ?? AUDIT_MAX_BYTES },
|
|
49252
50629
|
options.now ?? (() => /* @__PURE__ */ new Date())
|
|
49253
50630
|
);
|
|
49254
|
-
await
|
|
50631
|
+
await rm9(path28.join(dir, PAUSED_FILE), { force: true });
|
|
49255
50632
|
await audit.rollover(audit.now());
|
|
49256
50633
|
if (audit.usedBytes >= audit.limits.maxBytes) await audit.pause("QUOTA_EXCEEDED");
|
|
49257
50634
|
return audit;
|
|
@@ -49321,8 +50698,8 @@ var ContentAudit = class _ContentAudit {
|
|
|
49321
50698
|
await this.pause("QUOTA_EXCEEDED");
|
|
49322
50699
|
return;
|
|
49323
50700
|
}
|
|
49324
|
-
await appendFile(
|
|
49325
|
-
await appendFile(
|
|
50701
|
+
await appendFile(path28.join(this.dir, `full-${day}.jsonl`), line, { mode: 384 });
|
|
50702
|
+
await appendFile(path28.join(this.dir, `metrics-${day}.jsonl`), metrics, { mode: 384 });
|
|
49326
50703
|
this.usedBytes += bytes3;
|
|
49327
50704
|
}
|
|
49328
50705
|
/** Daily retention runs on the first write of a new day; no timer or background scan. */
|
|
@@ -49331,7 +50708,7 @@ var ContentAudit = class _ContentAudit {
|
|
|
49331
50708
|
const cutoff = new Date(at.getTime() - this.limits.retentionDays * DAY_MS).toISOString().slice(0, 10);
|
|
49332
50709
|
let used = 0;
|
|
49333
50710
|
for (const file2 of await auditFiles(this.dir)) {
|
|
49334
|
-
if (file2.day <= cutoff) await
|
|
50711
|
+
if (file2.day <= cutoff) await rm9(path28.join(this.dir, file2.name), { force: true });
|
|
49335
50712
|
else used += file2.bytes;
|
|
49336
50713
|
}
|
|
49337
50714
|
this.usedBytes = used;
|
|
@@ -49339,7 +50716,7 @@ var ContentAudit = class _ContentAudit {
|
|
|
49339
50716
|
async pause(reason) {
|
|
49340
50717
|
if (this.paused) return;
|
|
49341
50718
|
this.paused = reason;
|
|
49342
|
-
await writeJsonAtomic(
|
|
50719
|
+
await writeJsonAtomic(path28.join(this.dir, PAUSED_FILE), { reason, at: this.now().toISOString() });
|
|
49343
50720
|
}
|
|
49344
50721
|
};
|
|
49345
50722
|
function percentiles(values) {
|
|
@@ -49361,13 +50738,13 @@ async function* jsonLines(file2) {
|
|
|
49361
50738
|
}
|
|
49362
50739
|
var count2 = (value) => typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : 0;
|
|
49363
50740
|
async function summarizeContentAudit(directory, key) {
|
|
49364
|
-
const dir =
|
|
50741
|
+
const dir = path28.resolve(directory);
|
|
49365
50742
|
const files = await auditFiles(dir);
|
|
49366
50743
|
const days = /* @__PURE__ */ new Map();
|
|
49367
50744
|
const sizes = [];
|
|
49368
50745
|
const timings = [];
|
|
49369
50746
|
for (const file2 of files.filter((f) => f.kind === "metrics")) {
|
|
49370
|
-
for await (const line of jsonLines(
|
|
50747
|
+
for await (const line of jsonLines(path28.join(dir, file2.name))) {
|
|
49371
50748
|
let day = days.get(file2.day);
|
|
49372
50749
|
if (!day) {
|
|
49373
50750
|
day = { day: file2.day, records: 0, failed: 0, rawBytes: 0, sanitizedBytes: 0, compressedBytes: 0, envelopeBytes: 0 };
|
|
@@ -49387,7 +50764,7 @@ async function summarizeContentAudit(directory, key) {
|
|
|
49387
50764
|
}
|
|
49388
50765
|
let paused = null;
|
|
49389
50766
|
try {
|
|
49390
|
-
const value = JSON.parse(await
|
|
50767
|
+
const value = JSON.parse(await readFile11(path28.join(dir, PAUSED_FILE), "utf8"));
|
|
49391
50768
|
if (typeof value.reason === "string" && typeof value.at === "string") paused = { reason: value.reason.slice(0, 40), at: value.at.slice(0, 40) };
|
|
49392
50769
|
} catch {
|
|
49393
50770
|
}
|
|
@@ -49395,7 +50772,7 @@ async function summarizeContentAudit(directory, key) {
|
|
|
49395
50772
|
const newest = files.filter((f) => f.kind === "full").at(-1);
|
|
49396
50773
|
if (key && newest) {
|
|
49397
50774
|
const tail = [];
|
|
49398
|
-
for await (const line of jsonLines(
|
|
50775
|
+
for await (const line of jsonLines(path28.join(dir, newest.name))) {
|
|
49399
50776
|
tail.push(line);
|
|
49400
50777
|
if (tail.length > 5) tail.shift();
|
|
49401
50778
|
}
|
|
@@ -49429,10 +50806,10 @@ async function summarizeContentAudit(directory, key) {
|
|
|
49429
50806
|
};
|
|
49430
50807
|
}
|
|
49431
50808
|
async function restoreContentAudit(input2, output2, key) {
|
|
49432
|
-
const handle = await open12(
|
|
50809
|
+
const handle = await open12(path28.resolve(output2), "wx", 384);
|
|
49433
50810
|
let records = 0, failed = 0;
|
|
49434
50811
|
try {
|
|
49435
|
-
for await (const line of jsonLines(
|
|
50812
|
+
for await (const line of jsonLines(path28.resolve(input2))) {
|
|
49436
50813
|
try {
|
|
49437
50814
|
await handle.appendFile(JSON.stringify(decryptAuditRecord(line, key)) + "\n");
|
|
49438
50815
|
records += 1;
|
|
@@ -49447,7 +50824,7 @@ async function restoreContentAudit(input2, output2, key) {
|
|
|
49447
50824
|
}
|
|
49448
50825
|
|
|
49449
50826
|
// agent/src/main.ts
|
|
49450
|
-
var AGENT_VERSION2 = true ? "0.3.
|
|
50827
|
+
var AGENT_VERSION2 = true ? "0.3.47" : "0.3.2";
|
|
49451
50828
|
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" : "";
|
|
49452
50829
|
var AI_CONNECTION_SHIPPED = false;
|
|
49453
50830
|
function processAlive(pid) {
|
|
@@ -49461,7 +50838,7 @@ function processAlive(pid) {
|
|
|
49461
50838
|
}
|
|
49462
50839
|
async function claimAgentProcess(stateDir, runtimeDir, version2) {
|
|
49463
50840
|
await mkdir14(stateDir, { recursive: true });
|
|
49464
|
-
const file2 =
|
|
50841
|
+
const file2 = path29.join(stateDir, "agent-process.json");
|
|
49465
50842
|
for (let attempt = 0; attempt < 2; attempt += 1) {
|
|
49466
50843
|
try {
|
|
49467
50844
|
const handle = await open13(file2, "wx", 384);
|
|
@@ -49472,8 +50849,8 @@ async function claimAgentProcess(stateDir, runtimeDir, version2) {
|
|
|
49472
50849
|
}
|
|
49473
50850
|
return async () => {
|
|
49474
50851
|
try {
|
|
49475
|
-
const current2 = JSON.parse(await
|
|
49476
|
-
if (current2.pid === process.pid) await
|
|
50852
|
+
const current2 = JSON.parse(await readFile12(file2, "utf8"));
|
|
50853
|
+
if (current2.pid === process.pid) await rm10(file2, { force: true });
|
|
49477
50854
|
} catch {
|
|
49478
50855
|
}
|
|
49479
50856
|
};
|
|
@@ -49481,12 +50858,12 @@ async function claimAgentProcess(stateDir, runtimeDir, version2) {
|
|
|
49481
50858
|
if (!error62 || typeof error62 !== "object" || !("code" in error62) || error62.code !== "EEXIST") throw error62;
|
|
49482
50859
|
let stale = true;
|
|
49483
50860
|
try {
|
|
49484
|
-
const current2 = JSON.parse(await
|
|
50861
|
+
const current2 = JSON.parse(await readFile12(file2, "utf8"));
|
|
49485
50862
|
stale = typeof current2.pid !== "number" || !processAlive(current2.pid);
|
|
49486
50863
|
} catch {
|
|
49487
50864
|
}
|
|
49488
50865
|
if (!stale) throw Error("AGENT_ALREADY_RUNNING");
|
|
49489
|
-
await
|
|
50866
|
+
await rm10(file2, { force: true });
|
|
49490
50867
|
}
|
|
49491
50868
|
}
|
|
49492
50869
|
throw Error("AGENT_ALREADY_RUNNING");
|
|
@@ -49737,10 +51114,10 @@ async function openContentAudit(store, stateDir) {
|
|
|
49737
51114
|
async function main() {
|
|
49738
51115
|
if (!["win32", "linux", "darwin"].includes(process.platform)) throw Error("PLATFORM_UNSUPPORTED");
|
|
49739
51116
|
const appData = process.env.LC_AGENT_DATA_DIR ?? (process.platform === "win32" ? process.env.LOCALAPPDATA : posixDataHome());
|
|
49740
|
-
if (!appData || !
|
|
49741
|
-
const stateDir = process.env.LC_AGENT_STATE_DIR ??
|
|
49742
|
-
const binaryDir =
|
|
49743
|
-
const ownerBridgePath = process.env.LC_OWNER_BRIDGE ??
|
|
51117
|
+
if (!appData || !path29.isAbsolute(appData)) throw Error("APP_DATA_MISSING");
|
|
51118
|
+
const stateDir = process.env.LC_AGENT_STATE_DIR ?? path29.join(appData, "LocalCommander", "Agent");
|
|
51119
|
+
const binaryDir = path29.dirname(process.platform === "win32" ? process.execPath : await realpath10(process.execPath));
|
|
51120
|
+
const ownerBridgePath = process.env.LC_OWNER_BRIDGE ?? path29.join(binaryDir, process.platform === "win32" ? "OwnerBridge.exe" : "owner-store");
|
|
49744
51121
|
const store = await WindowsPrivateStore.open(stateDir, ownerBridgePath);
|
|
49745
51122
|
const command = process.argv[2] ?? "run";
|
|
49746
51123
|
if (process.platform !== "win32" && (command.startsWith("guard-") || command.startsWith("network-"))) throw Error("FEATURE_PLATFORM_UNSUPPORTED");
|
|
@@ -49750,7 +51127,7 @@ async function main() {
|
|
|
49750
51127
|
const pairing = new PairingClient(store, { controlPlaneOrigin: origin, agentVersion: AGENT_VERSION2 });
|
|
49751
51128
|
const begun = await pairing.begin();
|
|
49752
51129
|
process.stdout.write(JSON.stringify({ approvalUrl: begun.approvalUrl, confirmationCode: begun.confirmationCode, expiresAt: begun.expiresAt.toISOString() }) + "\n");
|
|
49753
|
-
await pairing.waitAndComplete(begun,
|
|
51130
|
+
await pairing.waitAndComplete(begun, os8.hostname().slice(0, 120));
|
|
49754
51131
|
process.stdout.write("DEVICE_PAIRED\n");
|
|
49755
51132
|
return;
|
|
49756
51133
|
}
|
|
@@ -49835,7 +51212,7 @@ async function main() {
|
|
|
49835
51212
|
}
|
|
49836
51213
|
if (command === "efficiency-report") {
|
|
49837
51214
|
if (args.length) throw Error("AGENT_COMMAND_INVALID");
|
|
49838
|
-
const ledger = await OptimizationLedger.open(
|
|
51215
|
+
const ledger = await OptimizationLedger.open(path29.join(stateDir, "optimization"));
|
|
49839
51216
|
try {
|
|
49840
51217
|
process.stdout.write(JSON.stringify(await ledger.report(), null, 2) + "\n");
|
|
49841
51218
|
} finally {
|
|
@@ -49845,7 +51222,7 @@ async function main() {
|
|
|
49845
51222
|
}
|
|
49846
51223
|
if (command === "guard-configure") {
|
|
49847
51224
|
if (args.length !== 1) throw Error("AGENT_COMMAND_INVALID");
|
|
49848
|
-
const filename = await (await import("node:fs/promises")).realpath(
|
|
51225
|
+
const filename = await (await import("node:fs/promises")).realpath(path29.resolve(args[0]));
|
|
49849
51226
|
const input2 = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(await readWindowsFile(ownerBridgePath, filename, 2e5)));
|
|
49850
51227
|
if (!input2 || typeof input2 !== "object" || Object.keys(input2).sort().join(",") !== "compact,settings") throw Error("GUARD_CONFIGURATION_INVALID");
|
|
49851
51228
|
await store.configureGuard(input2.settings, input2.compact);
|
|
@@ -49864,7 +51241,7 @@ async function main() {
|
|
|
49864
51241
|
}
|
|
49865
51242
|
if (command === "guard-evidence") {
|
|
49866
51243
|
if (args.length) throw Error("AGENT_COMMAND_INVALID");
|
|
49867
|
-
const journal = await NativeJournal.open(
|
|
51244
|
+
const journal = await NativeJournal.open(path29.join(stateDir, "journal"), new SecretBox({ "1": await store.loadDataKey() }));
|
|
49868
51245
|
try {
|
|
49869
51246
|
process.stdout.write(JSON.stringify(await journal.guardEvidence()) + "\n");
|
|
49870
51247
|
} finally {
|
|
@@ -49876,7 +51253,7 @@ async function main() {
|
|
|
49876
51253
|
if (args.length !== (command === "guard-export" ? 0 : 1)) throw Error("AGENT_COMMAND_INVALID");
|
|
49877
51254
|
const identity = await store.load();
|
|
49878
51255
|
if (!identity?.enrollment) throw Error("ENROLLMENT_MISSING");
|
|
49879
|
-
const journal = await NativeJournal.open(
|
|
51256
|
+
const journal = await NativeJournal.open(path29.join(stateDir, "journal"), new SecretBox({ "1": await store.loadDataKey() }));
|
|
49880
51257
|
try {
|
|
49881
51258
|
const { tenantId, deviceId } = identity.enrollment;
|
|
49882
51259
|
const records = (await journal.guardEvidence()).filter((record2) => record2.tenantId === tenantId && record2.deviceId === deviceId);
|
|
@@ -49954,27 +51331,27 @@ async function main() {
|
|
|
49954
51331
|
if (args.length) throw Error("AGENT_COMMAND_INVALID");
|
|
49955
51332
|
if (!(await store.load())?.enrollment) throw Error("ENROLLMENT_MISSING");
|
|
49956
51333
|
const releaseProcess = await claimAgentProcess(stateDir, binaryDir, AGENT_VERSION2);
|
|
49957
|
-
const monitor = new ProductionMonitor(
|
|
51334
|
+
const monitor = new ProductionMonitor(path29.join(appData, "LocalCommander", "Monitor"), stateDir, AGENT_VERSION2);
|
|
49958
51335
|
const publishMonitor = () => monitor.flush().catch(() => {
|
|
49959
51336
|
process.stderr.write("MONITOR_WRITE_FAILED\n");
|
|
49960
51337
|
});
|
|
49961
51338
|
await publishMonitor();
|
|
49962
51339
|
try {
|
|
49963
51340
|
const journal = await NativeJournal.open(
|
|
49964
|
-
|
|
51341
|
+
path29.join(stateDir, "journal"),
|
|
49965
51342
|
new SecretBox({ "1": await store.loadDataKey() }),
|
|
49966
|
-
process.platform === "win32" ? {} : { lockHelper:
|
|
51343
|
+
process.platform === "win32" ? {} : { lockHelper: path29.join(binaryDir, "posix-host") }
|
|
49967
51344
|
);
|
|
49968
51345
|
const ledgerLoss = () => {
|
|
49969
51346
|
process.stderr.write("OPTIMIZATION_TELEMETRY_INCOMPLETE\n");
|
|
49970
51347
|
};
|
|
49971
51348
|
const efficiencyLedger = await new OptionalWork(ledgerLoss, 1e3, 1).run(
|
|
49972
|
-
() => OptimizationLedger.open(
|
|
51349
|
+
() => OptimizationLedger.open(path29.join(stateDir, "optimization")),
|
|
49973
51350
|
void 0,
|
|
49974
51351
|
(ledger) => ledger.close()
|
|
49975
51352
|
);
|
|
49976
51353
|
try {
|
|
49977
|
-
const helperPath = process.env.LC_JOB_HOST ??
|
|
51354
|
+
const helperPath = process.env.LC_JOB_HOST ?? path29.join(binaryDir, process.platform === "win32" ? "JobHost.exe" : "job-host.mjs");
|
|
49978
51355
|
const tools = new NativeTools({ stateDirectory: stateDir, helperPath, ownerBridgePath, programs: await store.loadPrograms() });
|
|
49979
51356
|
const stop = new AbortController();
|
|
49980
51357
|
process.once("SIGINT", () => stop.abort());
|
|
@@ -50045,7 +51422,7 @@ async function main() {
|
|
|
50045
51422
|
await releaseProcess();
|
|
50046
51423
|
}
|
|
50047
51424
|
}
|
|
50048
|
-
var entrypoint = process.argv[1] && (process.platform === "win32" ?
|
|
51425
|
+
var entrypoint = process.argv[1] && (process.platform === "win32" ? path29.resolve(process.argv[1]) : await realpath10(process.argv[1]).catch(() => null));
|
|
50049
51426
|
if (entrypoint === fileURLToPath(import.meta.url)) {
|
|
50050
51427
|
void main().catch((error62) => {
|
|
50051
51428
|
const code = error62 instanceof Error && /^[A-Z0-9_]{1,64}$/.test(error62.message) ? error62.message : "AGENT_START_FAILED";
|