@moxt-ai/mobius 0.0.167 → 0.0.168
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/acp/agent-session.js +3 -3
- package/dist/acp/agent-session.js.map +1 -1
- package/dist/authorization/local-raster.d.ts +1 -0
- package/dist/authorization/local-raster.d.ts.map +1 -1
- package/dist/authorization/local-raster.js +1 -1
- package/dist/authorization/local-raster.js.map +1 -1
- package/dist/cli.js +277 -104
- package/dist/cli.js.map +3 -3
- package/dist/external-content/acp-content-externalizer.d.ts +5 -1
- package/dist/external-content/acp-content-externalizer.d.ts.map +1 -1
- package/dist/external-content/acp-content-externalizer.js +158 -56
- package/dist/external-content/acp-content-externalizer.js.map +1 -1
- package/dist/external-content/local-external-content-store.d.ts +3 -1
- package/dist/external-content/local-external-content-store.d.ts.map +1 -1
- package/dist/external-content/local-external-content-store.js +114 -28
- package/dist/external-content/local-external-content-store.js.map +1 -1
- package/dist/index.js +285 -112
- package/dist/index.js.map +3 -3
- package/dist/run-daemon.js +206 -142
- package/dist/run-daemon.js.map +1 -1
- package/dist/runtime.js +277 -104
- package/dist/runtime.js.map +3 -3
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -31949,13 +31949,13 @@ var AgentSession = class _AgentSession {
|
|
|
31949
31949
|
};
|
|
31950
31950
|
#processUpdate = async (notification) => {
|
|
31951
31951
|
this.assertNativeSession(notification.sessionId);
|
|
31952
|
-
const update = notification.update;
|
|
31953
31952
|
const externalized = await this.#contentExternalizer.update(
|
|
31954
31953
|
this.#mobiusSessionId,
|
|
31955
|
-
update,
|
|
31954
|
+
notification.update,
|
|
31956
31955
|
AbortSignal.timeout(3e4)
|
|
31957
31956
|
);
|
|
31958
|
-
const
|
|
31957
|
+
const update = externalized.agent;
|
|
31958
|
+
const rawUpdate = decodeAcpSessionUpdateV2(JSON.stringify(externalized.event));
|
|
31959
31959
|
if (this.#sessionLoad.kind === "capturing") {
|
|
31960
31960
|
await this.#sessionLoad.history.record(update, rawUpdate);
|
|
31961
31961
|
} else {
|
|
@@ -32381,7 +32381,19 @@ function decodeBase64(data) {
|
|
|
32381
32381
|
if (data.length > MAXIMUM_ENCODED_CONTENT_CHARACTERS || data.length % 4 !== 0 || !/^[A-Za-z0-9+/]*={0,2}$/u.test(data)) {
|
|
32382
32382
|
throw new Error("The ACP embedded content is not valid bounded base64");
|
|
32383
32383
|
}
|
|
32384
|
-
|
|
32384
|
+
const bytes = Buffer.from(data, "base64");
|
|
32385
|
+
if (bytes.toString("base64") !== data) {
|
|
32386
|
+
throw new Error("The ACP embedded content is not canonical base64");
|
|
32387
|
+
}
|
|
32388
|
+
return bytes;
|
|
32389
|
+
}
|
|
32390
|
+
var embeddedImageSchema = external_exports.looseObject({
|
|
32391
|
+
type: external_exports.literal("image"),
|
|
32392
|
+
data: external_exports.string(),
|
|
32393
|
+
mimeType: external_exports.string()
|
|
32394
|
+
});
|
|
32395
|
+
function isRecord6(value) {
|
|
32396
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
32385
32397
|
}
|
|
32386
32398
|
var AcpContentExternalizer = class {
|
|
32387
32399
|
#store;
|
|
@@ -32392,32 +32404,45 @@ var AcpContentExternalizer = class {
|
|
|
32392
32404
|
switch (content.type) {
|
|
32393
32405
|
case "text":
|
|
32394
32406
|
case "resource_link":
|
|
32395
|
-
return content;
|
|
32407
|
+
return { agent: content, event: content };
|
|
32396
32408
|
case "image": {
|
|
32397
32409
|
if (content.data.length === 0) {
|
|
32398
|
-
return content;
|
|
32410
|
+
return { agent: content, event: content };
|
|
32411
|
+
}
|
|
32412
|
+
try {
|
|
32413
|
+
const bytes = decodeBase64(content.data);
|
|
32414
|
+
if (sniffRasterMime(bytes) !== content.mimeType) {
|
|
32415
|
+
throw new Error("Embedded image bytes do not match a supported image MIME type");
|
|
32416
|
+
}
|
|
32417
|
+
const stored = await this.#store.put({
|
|
32418
|
+
bytes,
|
|
32419
|
+
kind: "image",
|
|
32420
|
+
mediaType: content.mimeType,
|
|
32421
|
+
name: "image",
|
|
32422
|
+
sessionId,
|
|
32423
|
+
signal
|
|
32424
|
+
});
|
|
32425
|
+
return {
|
|
32426
|
+
agent: { ...content, data: "", uri: `mobius-content:image:${stored.key}` },
|
|
32427
|
+
event: {
|
|
32428
|
+
_meta: content._meta,
|
|
32429
|
+
annotations: content.annotations,
|
|
32430
|
+
byteLength: stored.byteLength,
|
|
32431
|
+
imageKey: stored.key,
|
|
32432
|
+
mimeType: content.mimeType,
|
|
32433
|
+
type: "external_image",
|
|
32434
|
+
uri: content.uri
|
|
32435
|
+
}
|
|
32436
|
+
};
|
|
32437
|
+
} catch {
|
|
32438
|
+
signal.throwIfAborted();
|
|
32439
|
+
const unavailable = { type: "text", text: "[Image unavailable]" };
|
|
32440
|
+
return { agent: unavailable, event: unavailable };
|
|
32399
32441
|
}
|
|
32400
|
-
const stored = await this.#store.put({
|
|
32401
|
-
bytes: decodeBase64(content.data),
|
|
32402
|
-
kind: "image",
|
|
32403
|
-
mediaType: content.mimeType,
|
|
32404
|
-
name: "image",
|
|
32405
|
-
sessionId,
|
|
32406
|
-
signal
|
|
32407
|
-
});
|
|
32408
|
-
return {
|
|
32409
|
-
_meta: content._meta,
|
|
32410
|
-
annotations: content.annotations,
|
|
32411
|
-
byteLength: stored.byteLength,
|
|
32412
|
-
imageKey: stored.key,
|
|
32413
|
-
mimeType: content.mimeType,
|
|
32414
|
-
type: "external_image",
|
|
32415
|
-
uri: content.uri
|
|
32416
|
-
};
|
|
32417
32442
|
}
|
|
32418
32443
|
case "audio": {
|
|
32419
32444
|
if (content.data.length === 0) {
|
|
32420
|
-
return content;
|
|
32445
|
+
return { agent: content, event: content };
|
|
32421
32446
|
}
|
|
32422
32447
|
const stored = await this.#store.put({
|
|
32423
32448
|
bytes: decodeBase64(content.data),
|
|
@@ -32428,12 +32453,15 @@ var AcpContentExternalizer = class {
|
|
|
32428
32453
|
signal
|
|
32429
32454
|
});
|
|
32430
32455
|
return {
|
|
32431
|
-
|
|
32432
|
-
|
|
32433
|
-
|
|
32434
|
-
|
|
32435
|
-
|
|
32436
|
-
|
|
32456
|
+
agent: content,
|
|
32457
|
+
event: {
|
|
32458
|
+
_meta: content._meta,
|
|
32459
|
+
annotations: content.annotations,
|
|
32460
|
+
audioKey: stored.key,
|
|
32461
|
+
byteLength: stored.byteLength,
|
|
32462
|
+
mimeType: content.mimeType,
|
|
32463
|
+
type: "external_audio"
|
|
32464
|
+
}
|
|
32437
32465
|
};
|
|
32438
32466
|
}
|
|
32439
32467
|
case "resource": {
|
|
@@ -32441,7 +32469,7 @@ var AcpContentExternalizer = class {
|
|
|
32441
32469
|
const encoding = "text" in embedded ? "text" : "binary";
|
|
32442
32470
|
const bytes = "text" in embedded ? Buffer.from(embedded.text, "utf8") : decodeBase64(embedded.blob);
|
|
32443
32471
|
if (bytes.byteLength === 0) {
|
|
32444
|
-
return content;
|
|
32472
|
+
return { agent: content, event: content };
|
|
32445
32473
|
}
|
|
32446
32474
|
const mediaType = embedded.mimeType ?? "application/octet-stream";
|
|
32447
32475
|
const stored = await this.#store.put({
|
|
@@ -32453,43 +32481,111 @@ var AcpContentExternalizer = class {
|
|
|
32453
32481
|
signal
|
|
32454
32482
|
});
|
|
32455
32483
|
return {
|
|
32456
|
-
|
|
32457
|
-
|
|
32458
|
-
|
|
32459
|
-
|
|
32460
|
-
|
|
32461
|
-
|
|
32462
|
-
|
|
32463
|
-
|
|
32484
|
+
agent: content,
|
|
32485
|
+
event: {
|
|
32486
|
+
_meta: content._meta,
|
|
32487
|
+
annotations: content.annotations,
|
|
32488
|
+
byteLength: stored.byteLength,
|
|
32489
|
+
encoding,
|
|
32490
|
+
mimeType: embedded.mimeType,
|
|
32491
|
+
resourceKey: stored.key,
|
|
32492
|
+
type: "external_resource",
|
|
32493
|
+
uri: embedded.uri
|
|
32494
|
+
}
|
|
32464
32495
|
};
|
|
32465
32496
|
}
|
|
32466
32497
|
}
|
|
32467
32498
|
}
|
|
32468
|
-
async #
|
|
32469
|
-
|
|
32499
|
+
async #rawOutput(sessionId, value, images, signal, depth = 0) {
|
|
32500
|
+
signal.throwIfAborted();
|
|
32501
|
+
if (depth > 16) {
|
|
32502
|
+
throw new Error("ACP tool output exceeds the maximum nesting depth");
|
|
32503
|
+
}
|
|
32504
|
+
if (Array.isArray(value)) {
|
|
32505
|
+
const result2 = [];
|
|
32506
|
+
for (const item of value) {
|
|
32507
|
+
result2.push(await this.#rawOutput(sessionId, item, images, signal, depth + 1));
|
|
32508
|
+
}
|
|
32509
|
+
return result2;
|
|
32510
|
+
}
|
|
32511
|
+
if (!isRecord6(value)) {
|
|
32512
|
+
return value;
|
|
32513
|
+
}
|
|
32514
|
+
const image = embeddedImageSchema.safeParse(value);
|
|
32515
|
+
if (image.success && image.data.data.length > 0) {
|
|
32516
|
+
const prepared = await this.#content(sessionId, image.data, signal);
|
|
32517
|
+
if (isRecord6(prepared.event) && typeof prepared.event["imageKey"] === "string") {
|
|
32518
|
+
images.set(prepared.event["imageKey"], prepared);
|
|
32519
|
+
} else {
|
|
32520
|
+
images.set(`unavailable:${images.size}`, prepared);
|
|
32521
|
+
}
|
|
32522
|
+
return prepared.event;
|
|
32523
|
+
}
|
|
32524
|
+
const result = {};
|
|
32525
|
+
for (const [key, item] of Object.entries(value)) {
|
|
32526
|
+
result[key] = await this.#rawOutput(sessionId, item, images, signal, depth + 1);
|
|
32527
|
+
}
|
|
32528
|
+
return result;
|
|
32529
|
+
}
|
|
32530
|
+
async #toolUpdate(sessionId, update, signal) {
|
|
32531
|
+
const images = /* @__PURE__ */ new Map();
|
|
32532
|
+
const rawOutput = update.rawOutput === void 0 ? void 0 : await this.#rawOutput(sessionId, update.rawOutput, images, signal);
|
|
32533
|
+
const originalJson = images.size === 0 ? void 0 : JSON.stringify(update.rawOutput);
|
|
32534
|
+
const rewrittenJson = images.size === 0 ? void 0 : JSON.stringify(rawOutput);
|
|
32535
|
+
const agentContent = [];
|
|
32536
|
+
const eventContent = [];
|
|
32537
|
+
for (const item of update.content ?? []) {
|
|
32538
|
+
if (item.type !== "content") {
|
|
32539
|
+
agentContent.push(item);
|
|
32540
|
+
eventContent.push(item);
|
|
32541
|
+
continue;
|
|
32542
|
+
}
|
|
32543
|
+
const content = item.content.type === "text" && item.content.text === originalJson && rewrittenJson !== void 0 ? { ...item.content, text: rewrittenJson } : item.content;
|
|
32544
|
+
const prepared = await this.#content(sessionId, content, signal);
|
|
32545
|
+
agentContent.push({ ...item, content: prepared.agent });
|
|
32546
|
+
eventContent.push({ ...item, content: prepared.event });
|
|
32547
|
+
if (isRecord6(prepared.event) && typeof prepared.event["imageKey"] === "string") {
|
|
32548
|
+
images.delete(prepared.event["imageKey"]);
|
|
32549
|
+
}
|
|
32550
|
+
}
|
|
32551
|
+
for (const prepared of images.values()) {
|
|
32552
|
+
agentContent.push({ type: "content", content: prepared.agent });
|
|
32553
|
+
eventContent.push({ type: "content", content: prepared.event });
|
|
32554
|
+
}
|
|
32555
|
+
const output2 = update.rawOutput === void 0 ? {} : { rawOutput };
|
|
32556
|
+
const hasContent = update.content !== void 0 && update.content !== null || agentContent.length > 0;
|
|
32557
|
+
return {
|
|
32558
|
+
agent: { ...update, ...output2, ...hasContent ? { content: agentContent } : {} },
|
|
32559
|
+
event: { ...update, ...output2, ...hasContent ? { content: eventContent } : {} }
|
|
32560
|
+
};
|
|
32470
32561
|
}
|
|
32471
32562
|
update = async (sessionId, update, signal) => {
|
|
32472
32563
|
switch (update.sessionUpdate) {
|
|
32473
32564
|
case "user_message_chunk":
|
|
32474
32565
|
case "agent_message_chunk":
|
|
32475
32566
|
case "agent_thought_chunk":
|
|
32476
|
-
case "compaction_summary_chunk":
|
|
32477
|
-
|
|
32567
|
+
case "compaction_summary_chunk": {
|
|
32568
|
+
const content = await this.#content(sessionId, update.content, signal);
|
|
32569
|
+
return {
|
|
32570
|
+
agent: { ...update, content: content.agent },
|
|
32571
|
+
event: { ...update, content: content.event }
|
|
32572
|
+
};
|
|
32573
|
+
}
|
|
32478
32574
|
case "tool_call":
|
|
32479
32575
|
case "tool_call_update":
|
|
32480
|
-
return
|
|
32481
|
-
|
|
32482
|
-
|
|
32483
|
-
|
|
32484
|
-
|
|
32485
|
-
|
|
32486
|
-
|
|
32487
|
-
|
|
32488
|
-
|
|
32489
|
-
summary:
|
|
32490
|
-
|
|
32491
|
-
)
|
|
32576
|
+
return await this.#toolUpdate(sessionId, update, signal);
|
|
32577
|
+
case "compaction_update": {
|
|
32578
|
+
if (update.summary === void 0 || update.summary === null) {
|
|
32579
|
+
return { agent: update, event: update };
|
|
32580
|
+
}
|
|
32581
|
+
const content = await Promise.all(
|
|
32582
|
+
update.summary.map(async (item) => await this.#content(sessionId, item, signal))
|
|
32583
|
+
);
|
|
32584
|
+
return {
|
|
32585
|
+
agent: { ...update, summary: content.map((item) => item.agent) },
|
|
32586
|
+
event: { ...update, summary: content.map((item) => item.event) }
|
|
32492
32587
|
};
|
|
32588
|
+
}
|
|
32493
32589
|
case "plan":
|
|
32494
32590
|
case "plan_update":
|
|
32495
32591
|
case "plan_removed":
|
|
@@ -32498,16 +32594,17 @@ var AcpContentExternalizer = class {
|
|
|
32498
32594
|
case "config_option_update":
|
|
32499
32595
|
case "session_info_update":
|
|
32500
32596
|
case "usage_update":
|
|
32501
|
-
return update;
|
|
32597
|
+
return { agent: update, event: update };
|
|
32502
32598
|
}
|
|
32503
32599
|
};
|
|
32504
32600
|
};
|
|
32505
32601
|
|
|
32506
32602
|
// src/external-content/local-external-content-store.ts
|
|
32507
32603
|
import { createHash, randomUUID } from "node:crypto";
|
|
32508
|
-
import { lstat, mkdir,
|
|
32604
|
+
import { lstat, mkdir, readdir as readdir2, realpath as realpath3, rename, rm, stat as stat3, utimes, writeFile } from "node:fs/promises";
|
|
32509
32605
|
import { dirname as dirname2, join as join4 } from "node:path";
|
|
32510
32606
|
var contentRequest = /^mobius-content:(image|audio|resource):([a-f0-9]{64})$/u;
|
|
32607
|
+
var CONTENT_LIFETIME_MILLISECONDS = 24 * 60 * 60 * 1e3;
|
|
32511
32608
|
var metadataSchema2 = external_exports.strictObject({
|
|
32512
32609
|
kind: external_exports.enum(["image", "audio", "resource"]),
|
|
32513
32610
|
mediaType: external_exports.string().min(1).max(2048).regex(/^[\u0020-\u007e]+$/u),
|
|
@@ -32523,9 +32620,6 @@ var UnretainedExternalContentStore = class {
|
|
|
32523
32620
|
return Promise.resolve(null);
|
|
32524
32621
|
};
|
|
32525
32622
|
};
|
|
32526
|
-
function sessionScope(sessionId) {
|
|
32527
|
-
return createHash("sha256").update(sessionId).digest("hex");
|
|
32528
|
-
}
|
|
32529
32623
|
async function atomicWrite(path2, bytes, signal) {
|
|
32530
32624
|
const temporary = `${path2}.${randomUUID()}.tmp`;
|
|
32531
32625
|
try {
|
|
@@ -32538,55 +32632,134 @@ async function atomicWrite(path2, bytes, signal) {
|
|
|
32538
32632
|
}
|
|
32539
32633
|
var LocalExternalContentStore = class {
|
|
32540
32634
|
#root;
|
|
32635
|
+
#entries = /* @__PURE__ */ new Map();
|
|
32636
|
+
#operations = /* @__PURE__ */ new Set();
|
|
32637
|
+
#lifetime = new AbortController();
|
|
32638
|
+
#expirationTimer;
|
|
32639
|
+
#cleanup = Promise.resolve();
|
|
32541
32640
|
constructor(stateDirectory) {
|
|
32542
|
-
this.#root = join4(stateDirectory, "tmp", "session-content");
|
|
32543
|
-
|
|
32544
|
-
|
|
32545
|
-
|
|
32641
|
+
this.#root = join4(stateDirectory, "tmp", "session-content", randomUUID());
|
|
32642
|
+
this.#expirationTimer = setInterval(() => {
|
|
32643
|
+
void this.#expire().catch(() => void 0);
|
|
32644
|
+
}, 6e4);
|
|
32645
|
+
this.#expirationTimer.unref();
|
|
32646
|
+
}
|
|
32647
|
+
#expire = () => {
|
|
32648
|
+
this.#cleanup = this.#cleanup.catch(() => void 0).then(async () => {
|
|
32649
|
+
await mkdir(this.#root, { mode: 448, recursive: true });
|
|
32650
|
+
const now = /* @__PURE__ */ new Date();
|
|
32651
|
+
await utimes(this.#root, now, now);
|
|
32652
|
+
for (const directory of await readdir2(dirname2(this.#root), { withFileTypes: true })) {
|
|
32653
|
+
if (!directory.isDirectory() || !/^[a-f0-9-]{36}$/u.test(directory.name)) {
|
|
32654
|
+
continue;
|
|
32655
|
+
}
|
|
32656
|
+
const path2 = join4(dirname2(this.#root), directory.name);
|
|
32657
|
+
if (path2 === this.#root) {
|
|
32658
|
+
continue;
|
|
32659
|
+
}
|
|
32660
|
+
const modified = await stat3(path2).then(
|
|
32661
|
+
(entry) => entry.mtimeMs,
|
|
32662
|
+
() => Date.now()
|
|
32663
|
+
);
|
|
32664
|
+
if (modified + CONTENT_LIFETIME_MILLISECONDS <= Date.now()) {
|
|
32665
|
+
await rm(path2, { force: true, recursive: true });
|
|
32666
|
+
}
|
|
32667
|
+
}
|
|
32668
|
+
for (const [request, entry] of this.#entries) {
|
|
32669
|
+
if (entry.expiresAt > Date.now()) {
|
|
32670
|
+
continue;
|
|
32671
|
+
}
|
|
32672
|
+
await rm(entry.path, { force: true });
|
|
32673
|
+
this.#entries.delete(request);
|
|
32674
|
+
}
|
|
32675
|
+
});
|
|
32676
|
+
return this.#cleanup;
|
|
32677
|
+
};
|
|
32678
|
+
#track = async (operation) => {
|
|
32679
|
+
this.#lifetime.signal.throwIfAborted();
|
|
32680
|
+
const pending = operation();
|
|
32681
|
+
this.#operations.add(pending);
|
|
32682
|
+
try {
|
|
32683
|
+
return await pending;
|
|
32684
|
+
} finally {
|
|
32685
|
+
this.#operations.delete(pending);
|
|
32686
|
+
}
|
|
32687
|
+
};
|
|
32688
|
+
put = (input2) => this.#track(() => this.#put(input2));
|
|
32689
|
+
#put = async ({ bytes, kind, mediaType, name, sessionId, signal }) => {
|
|
32690
|
+
const active = AbortSignal.any([signal, this.#lifetime.signal]);
|
|
32691
|
+
active.throwIfAborted();
|
|
32692
|
+
const metadata = metadataSchema2.parse({ kind, mediaType, name });
|
|
32546
32693
|
const key = createHash("sha256").update(bytes).digest("hex");
|
|
32547
|
-
const
|
|
32694
|
+
const request = `mobius-content:${kind}:${key}`;
|
|
32695
|
+
const existing = this.#entries.get(request);
|
|
32696
|
+
if (existing !== void 0 && existing.expiresAt > Date.now()) {
|
|
32697
|
+
this.#entries.set(request, {
|
|
32698
|
+
...existing,
|
|
32699
|
+
expiresAt: Date.now() + CONTENT_LIFETIME_MILLISECONDS,
|
|
32700
|
+
sessions: /* @__PURE__ */ new Set([...existing.sessions, sessionId])
|
|
32701
|
+
});
|
|
32702
|
+
return { byteLength: existing.byteLength, key };
|
|
32703
|
+
}
|
|
32704
|
+
await this.#expire();
|
|
32705
|
+
active.throwIfAborted();
|
|
32706
|
+
const directory = join4(this.#root, kind);
|
|
32548
32707
|
await mkdir(directory, { mode: 448, recursive: true });
|
|
32549
|
-
|
|
32708
|
+
active.throwIfAborted();
|
|
32550
32709
|
const path2 = join4(directory, key);
|
|
32551
|
-
|
|
32552
|
-
await
|
|
32553
|
-
|
|
32554
|
-
|
|
32555
|
-
|
|
32556
|
-
|
|
32710
|
+
const write = atomicWrite(path2, bytes, active);
|
|
32711
|
+
await write;
|
|
32712
|
+
active.throwIfAborted();
|
|
32713
|
+
const retained = this.#entries.get(request);
|
|
32714
|
+
this.#entries.set(request, {
|
|
32715
|
+
byteLength: bytes.byteLength,
|
|
32716
|
+
expiresAt: Date.now() + CONTENT_LIFETIME_MILLISECONDS,
|
|
32717
|
+
mediaType: metadata.mediaType,
|
|
32718
|
+
name: metadata.name,
|
|
32719
|
+
path: path2,
|
|
32720
|
+
sessions: /* @__PURE__ */ new Set([...retained?.sessions ?? [], sessionId])
|
|
32721
|
+
});
|
|
32557
32722
|
return { byteLength: bytes.byteLength, key };
|
|
32558
32723
|
};
|
|
32559
|
-
resolve =
|
|
32560
|
-
|
|
32561
|
-
|
|
32724
|
+
resolve = (sessionId, request, signal) => this.#track(() => this.#resolve(sessionId, request, AbortSignal.any([signal, this.#lifetime.signal])));
|
|
32725
|
+
#resolve = async (sessionId, request, signal) => {
|
|
32726
|
+
signal.throwIfAborted();
|
|
32727
|
+
this.#lifetime.signal.throwIfAborted();
|
|
32728
|
+
if (!contentRequest.test(request)) {
|
|
32562
32729
|
return null;
|
|
32563
32730
|
}
|
|
32564
|
-
const
|
|
32565
|
-
|
|
32566
|
-
|
|
32731
|
+
const entry = this.#entries.get(request);
|
|
32732
|
+
if (entry === void 0 || !entry.sessions.has(sessionId)) {
|
|
32733
|
+
return null;
|
|
32734
|
+
}
|
|
32735
|
+
if (entry.expiresAt <= Date.now()) {
|
|
32736
|
+
await this.#expire();
|
|
32737
|
+
signal.throwIfAborted();
|
|
32567
32738
|
return null;
|
|
32568
32739
|
}
|
|
32569
|
-
const directory = join4(this.#root, sessionScope(sessionId), kind);
|
|
32570
|
-
const path2 = join4(directory, key);
|
|
32571
32740
|
try {
|
|
32572
|
-
const [resolvedDirectory, resolvedPath, file2
|
|
32573
|
-
realpath3(
|
|
32574
|
-
realpath3(
|
|
32575
|
-
lstat(
|
|
32576
|
-
readFile3(`${path2}.json`, "utf8").then((value) => metadataSchema2.parse(JSON.parse(value)))
|
|
32741
|
+
const [resolvedDirectory, resolvedPath, file2] = await Promise.all([
|
|
32742
|
+
realpath3(dirname2(entry.path)),
|
|
32743
|
+
realpath3(entry.path),
|
|
32744
|
+
lstat(entry.path)
|
|
32577
32745
|
]);
|
|
32578
32746
|
signal.throwIfAborted();
|
|
32579
|
-
if (!file2.isFile() || dirname2(resolvedPath) !== resolvedDirectory
|
|
32747
|
+
if (!file2.isFile() || file2.isSymbolicLink() || dirname2(resolvedPath) !== resolvedDirectory) {
|
|
32580
32748
|
return null;
|
|
32581
32749
|
}
|
|
32582
|
-
|
|
32583
|
-
signal.throwIfAborted();
|
|
32584
|
-
return { mediaType: metadata.mediaType, name: metadata.name, path: resolvedPath };
|
|
32750
|
+
return { mediaType: entry.mediaType, name: entry.name, path: resolvedPath };
|
|
32585
32751
|
} catch {
|
|
32586
32752
|
signal.throwIfAborted();
|
|
32587
32753
|
return null;
|
|
32588
32754
|
}
|
|
32589
32755
|
};
|
|
32756
|
+
[Symbol.asyncDispose] = async () => {
|
|
32757
|
+
clearInterval(this.#expirationTimer);
|
|
32758
|
+
this.#lifetime.abort();
|
|
32759
|
+
await Promise.allSettled([...this.#operations, this.#cleanup]);
|
|
32760
|
+
this.#entries.clear();
|
|
32761
|
+
await rm(this.#root, { force: true, recursive: true });
|
|
32762
|
+
};
|
|
32590
32763
|
};
|
|
32591
32764
|
|
|
32592
32765
|
// src/native-sessions/chat-agent.ts
|
|
@@ -33722,7 +33895,7 @@ var ManagedNpmPackageError = class extends Error {
|
|
|
33722
33895
|
this.name = "ManagedNpmPackageError";
|
|
33723
33896
|
}
|
|
33724
33897
|
};
|
|
33725
|
-
function
|
|
33898
|
+
function isRecord7(value) {
|
|
33726
33899
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
33727
33900
|
}
|
|
33728
33901
|
function packagePath(root, packageName) {
|
|
@@ -33744,7 +33917,7 @@ async function readJsonRecord(path2, maximumBytes) {
|
|
|
33744
33917
|
);
|
|
33745
33918
|
}
|
|
33746
33919
|
const value = JSON.parse(await handle.readFile({ encoding: "utf8" }));
|
|
33747
|
-
if (!
|
|
33920
|
+
if (!isRecord7(value)) {
|
|
33748
33921
|
throw new ManagedNpmPackageError(
|
|
33749
33922
|
"managed_package_verification_failed",
|
|
33750
33923
|
"The managed npm package metadata is invalid"
|
|
@@ -33770,7 +33943,7 @@ function readBinPath(packageMetadata, executableName) {
|
|
|
33770
33943
|
if (typeof bin === "string") {
|
|
33771
33944
|
return bin;
|
|
33772
33945
|
}
|
|
33773
|
-
if (
|
|
33946
|
+
if (isRecord7(bin) && typeof bin[executableName] === "string") {
|
|
33774
33947
|
return bin[executableName];
|
|
33775
33948
|
}
|
|
33776
33949
|
throw new ManagedNpmPackageError(
|
|
@@ -33786,7 +33959,7 @@ function verifyPackageLockEntry(lock, definition, verifyDependencyClosure) {
|
|
|
33786
33959
|
);
|
|
33787
33960
|
}
|
|
33788
33961
|
const packages = lock["packages"];
|
|
33789
|
-
if (!
|
|
33962
|
+
if (!isRecord7(packages)) {
|
|
33790
33963
|
throw new ManagedNpmPackageError(
|
|
33791
33964
|
"managed_package_verification_failed",
|
|
33792
33965
|
"The managed npm package lockfile is invalid"
|
|
@@ -33800,7 +33973,7 @@ function verifyPackageLockEntry(lock, definition, verifyDependencyClosure) {
|
|
|
33800
33973
|
if (verifyDependencyClosure && normalizedKey.length > 0) {
|
|
33801
33974
|
let resolved;
|
|
33802
33975
|
try {
|
|
33803
|
-
if (!normalizedKey.split("/").includes("node_modules") || !
|
|
33976
|
+
if (!normalizedKey.split("/").includes("node_modules") || !isRecord7(candidate) || typeof candidate["version"] !== "string" || candidate["version"].length === 0 || typeof candidate["integrity"] !== "string" || !/^sha512-[A-Za-z0-9+/]{86}==$/.test(candidate["integrity"]) || typeof candidate["resolved"] !== "string") {
|
|
33804
33977
|
throw new Error("Invalid locked dependency");
|
|
33805
33978
|
}
|
|
33806
33979
|
resolved = new URL(candidate["resolved"]);
|
|
@@ -33823,7 +33996,7 @@ function verifyPackageLockEntry(lock, definition, verifyDependencyClosure) {
|
|
|
33823
33996
|
matches += 1;
|
|
33824
33997
|
}
|
|
33825
33998
|
}
|
|
33826
|
-
if (matches !== 1 || !
|
|
33999
|
+
if (matches !== 1 || !isRecord7(entry) || entry["integrity"] !== definition.integrity || entry["resolved"] !== definition.tarballUrl || entry["version"] !== definition.version) {
|
|
33827
34000
|
throw new ManagedNpmPackageError(
|
|
33828
34001
|
"managed_package_verification_failed",
|
|
33829
34002
|
"The managed npm package lockfile does not match the pinned artifact"
|
|
@@ -36513,7 +36686,7 @@ var ManagedAgentArchiveError = class extends Error {
|
|
|
36513
36686
|
this.name = "ManagedAgentArchiveError";
|
|
36514
36687
|
}
|
|
36515
36688
|
};
|
|
36516
|
-
function
|
|
36689
|
+
function isRecord8(value) {
|
|
36517
36690
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
36518
36691
|
}
|
|
36519
36692
|
function isContainedPath3(root, candidate) {
|
|
@@ -36570,7 +36743,7 @@ async function readManifest(path2) {
|
|
|
36570
36743
|
);
|
|
36571
36744
|
}
|
|
36572
36745
|
const parsed = JSON.parse(await handle.readFile({ encoding: "utf8" }));
|
|
36573
|
-
if (!
|
|
36746
|
+
if (!isRecord8(parsed)) {
|
|
36574
36747
|
throw new ManagedAgentArchiveError(
|
|
36575
36748
|
"managed_archive_verification_failed",
|
|
36576
36749
|
"The managed Agent archive manifest is invalid"
|
|
@@ -37721,7 +37894,7 @@ async function discoverLocalAgentInventory(options) {
|
|
|
37721
37894
|
|
|
37722
37895
|
// src/storage/runtime-installation-store.ts
|
|
37723
37896
|
import { createHash as createHash3, randomUUID as randomUUID2 } from "node:crypto";
|
|
37724
|
-
import { mkdir as mkdir5, open as open5, readdir as
|
|
37897
|
+
import { mkdir as mkdir5, open as open5, readdir as readdir3, rename as rename4, unlink, writeFile as writeFile4 } from "node:fs/promises";
|
|
37725
37898
|
import { dirname as dirname5, join as join16, resolve as resolve4 } from "node:path";
|
|
37726
37899
|
var APPLICATION_ID_PATTERN = /^[a-z][a-z0-9]*(?:[.-][a-z0-9]+){1,31}$/;
|
|
37727
37900
|
var CONNECTION_ID_PATTERN = /^mcn_[a-f0-9]{32}$/;
|
|
@@ -37786,7 +37959,7 @@ var VerifiedRuntimeConnection = class {
|
|
|
37786
37959
|
this.runtimeId = runtimeId;
|
|
37787
37960
|
}
|
|
37788
37961
|
};
|
|
37789
|
-
function
|
|
37962
|
+
function isRecord9(value) {
|
|
37790
37963
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
37791
37964
|
}
|
|
37792
37965
|
function hasExactKeys(value, expectedKeys) {
|
|
@@ -37859,7 +38032,7 @@ function channelIndexFileName(channelId) {
|
|
|
37859
38032
|
return `mci_${createHash3("sha256").update(channelId).digest("hex")}.json`;
|
|
37860
38033
|
}
|
|
37861
38034
|
function decodeInstallationPointer(value) {
|
|
37862
|
-
if (!
|
|
38035
|
+
if (!isRecord9(value) || !hasExactKeys(value, INSTALLATION_POINTER_KEYS) || value["version"] !== 1) {
|
|
37863
38036
|
throw new RuntimeInstallationStoreError("invalid_installation", "The local installation record is invalid");
|
|
37864
38037
|
}
|
|
37865
38038
|
const storedInstallationId = value["installationId"];
|
|
@@ -37869,7 +38042,7 @@ function decodeInstallationPointer(value) {
|
|
|
37869
38042
|
return { installationId: validateInstallationId(storedInstallationId) };
|
|
37870
38043
|
}
|
|
37871
38044
|
function decodeChannelIndex(value) {
|
|
37872
|
-
if (!
|
|
38045
|
+
if (!isRecord9(value) || !hasExactKeys(value, CHANNEL_INDEX_KEYS) || value["version"] !== 1) {
|
|
37873
38046
|
throw new RuntimeInstallationStoreError("invalid_connection", "The saved Runtime connection is invalid");
|
|
37874
38047
|
}
|
|
37875
38048
|
const applicationId = value["applicationId"];
|
|
@@ -37919,7 +38092,7 @@ function decodeVerifiedConnection(value) {
|
|
|
37919
38092
|
);
|
|
37920
38093
|
}
|
|
37921
38094
|
function decodeConnection(value) {
|
|
37922
|
-
if (!
|
|
38095
|
+
if (!isRecord9(value)) {
|
|
37923
38096
|
throw new RuntimeInstallationStoreError("invalid_connection", "The saved Runtime connection is invalid");
|
|
37924
38097
|
}
|
|
37925
38098
|
return decodeVerifiedConnection(value);
|
|
@@ -38100,7 +38273,7 @@ var RuntimeInstallationStore = class _RuntimeInstallationStore {
|
|
|
38100
38273
|
signal.throwIfAborted();
|
|
38101
38274
|
let entries;
|
|
38102
38275
|
try {
|
|
38103
|
-
entries = await
|
|
38276
|
+
entries = await readdir3(this.#connectionDirectory);
|
|
38104
38277
|
} catch (cause) {
|
|
38105
38278
|
if (isNodeError(cause, "ENOENT")) {
|
|
38106
38279
|
return [];
|
|
@@ -38237,7 +38410,7 @@ var PairingClientError = class extends Error {
|
|
|
38237
38410
|
this.name = "PairingClientError";
|
|
38238
38411
|
}
|
|
38239
38412
|
};
|
|
38240
|
-
function
|
|
38413
|
+
function isRecord10(value) {
|
|
38241
38414
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
38242
38415
|
}
|
|
38243
38416
|
function hasExactKeys2(value, expectedKeys) {
|
|
@@ -38360,9 +38533,9 @@ async function readJsonResponse(response) {
|
|
|
38360
38533
|
}
|
|
38361
38534
|
}
|
|
38362
38535
|
function readRelayError(value) {
|
|
38363
|
-
if (
|
|
38536
|
+
if (isRecord10(value)) {
|
|
38364
38537
|
const error62 = value["error"];
|
|
38365
|
-
if (
|
|
38538
|
+
if (isRecord10(error62)) {
|
|
38366
38539
|
const code = error62["code"];
|
|
38367
38540
|
const message = error62["message"];
|
|
38368
38541
|
if (typeof code === "string" && typeof message === "string") {
|
|
@@ -38373,7 +38546,7 @@ function readRelayError(value) {
|
|
|
38373
38546
|
return new PairingClientError("pairing_failed", "The relay could not pair this machine");
|
|
38374
38547
|
}
|
|
38375
38548
|
function decodePairingResponse(value, credentialField, expectedKeys) {
|
|
38376
|
-
if (!
|
|
38549
|
+
if (!isRecord10(value) || !hasExactKeys2(value, expectedKeys)) {
|
|
38377
38550
|
throw new PairingClientError("invalid_relay_response", "The relay returned an invalid pairing response");
|
|
38378
38551
|
}
|
|
38379
38552
|
const appId = value["appId"];
|
|
@@ -38588,7 +38761,7 @@ var AgentCatalogPublishError = class extends Error {
|
|
|
38588
38761
|
this.name = "AgentCatalogPublishError";
|
|
38589
38762
|
}
|
|
38590
38763
|
};
|
|
38591
|
-
function
|
|
38764
|
+
function isRecord11(value) {
|
|
38592
38765
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
38593
38766
|
}
|
|
38594
38767
|
function isSafeRelayErrorMessage(value) {
|
|
@@ -38601,7 +38774,7 @@ async function rejectedCatalogError(response) {
|
|
|
38601
38774
|
} catch {
|
|
38602
38775
|
return new AgentCatalogPublishError("The Relay rejected the Agent catalog update");
|
|
38603
38776
|
}
|
|
38604
|
-
if (!
|
|
38777
|
+
if (!isRecord11(value) || !isRecord11(value["error"])) {
|
|
38605
38778
|
return new AgentCatalogPublishError("The Relay rejected the Agent catalog update");
|
|
38606
38779
|
}
|
|
38607
38780
|
const code = value["error"]["code"];
|
|
@@ -39132,7 +39305,7 @@ var FixedInstallationExecutor = class {
|
|
|
39132
39305
|
};
|
|
39133
39306
|
|
|
39134
39307
|
// src/authorization/workspace-directory.ts
|
|
39135
|
-
import { readdir as
|
|
39308
|
+
import { readdir as readdir4, realpath as realpath9, stat as stat8 } from "node:fs/promises";
|
|
39136
39309
|
import { homedir as homedir2 } from "node:os";
|
|
39137
39310
|
import { basename as basename4, dirname as dirname6, isAbsolute as isAbsolute9, join as join17, normalize as normalize3, relative as relative4 } from "node:path";
|
|
39138
39311
|
var WorkspaceDirectoryListing = class {
|
|
@@ -39241,7 +39414,7 @@ var WorkspaceDirectoryService = class {
|
|
|
39241
39414
|
list = async (bindingId, id, signal) => {
|
|
39242
39415
|
const target = await this.resolve(bindingId, id, signal);
|
|
39243
39416
|
try {
|
|
39244
|
-
const children = await
|
|
39417
|
+
const children = await readdir4(target, { withFileTypes: true });
|
|
39245
39418
|
signal.throwIfAborted();
|
|
39246
39419
|
const entries = [];
|
|
39247
39420
|
for (const child2 of children) {
|
|
@@ -44920,7 +45093,7 @@ async function runDaemon(config2, audit, signal, timer = systemDaemonTimer, opti
|
|
|
44920
45093
|
const sessionStore = new SqliteAcpSessionStore(
|
|
44921
45094
|
join19(stateDirectory, "sessions", `${createHash8("sha256").update(config2.channelId).digest("hex")}.sqlite`)
|
|
44922
45095
|
);
|
|
44923
|
-
|
|
45096
|
+
await using externalContent = new LocalExternalContentStore(stateDirectory);
|
|
44924
45097
|
const operations = new DaemonOperationState();
|
|
44925
45098
|
const publisher = new DaemonSessionEventPublisher(sessionStore);
|
|
44926
45099
|
const eventLogV2 = new DaemonSessionEventLogV2(publisher, sessionStore);
|