@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/runtime.js
CHANGED
|
@@ -36140,13 +36140,13 @@ var AgentSession = class _AgentSession {
|
|
|
36140
36140
|
};
|
|
36141
36141
|
#processUpdate = async (notification) => {
|
|
36142
36142
|
this.assertNativeSession(notification.sessionId);
|
|
36143
|
-
const update = notification.update;
|
|
36144
36143
|
const externalized = await this.#contentExternalizer.update(
|
|
36145
36144
|
this.#mobiusSessionId,
|
|
36146
|
-
update,
|
|
36145
|
+
notification.update,
|
|
36147
36146
|
AbortSignal.timeout(3e4)
|
|
36148
36147
|
);
|
|
36149
|
-
const
|
|
36148
|
+
const update = externalized.agent;
|
|
36149
|
+
const rawUpdate = decodeAcpSessionUpdateV2(JSON.stringify(externalized.event));
|
|
36150
36150
|
if (this.#sessionLoad.kind === "capturing") {
|
|
36151
36151
|
await this.#sessionLoad.history.record(update, rawUpdate);
|
|
36152
36152
|
} else {
|
|
@@ -36572,7 +36572,19 @@ function decodeBase64(data) {
|
|
|
36572
36572
|
if (data.length > MAXIMUM_ENCODED_CONTENT_CHARACTERS || data.length % 4 !== 0 || !/^[A-Za-z0-9+/]*={0,2}$/u.test(data)) {
|
|
36573
36573
|
throw new Error("The ACP embedded content is not valid bounded base64");
|
|
36574
36574
|
}
|
|
36575
|
-
|
|
36575
|
+
const bytes = Buffer.from(data, "base64");
|
|
36576
|
+
if (bytes.toString("base64") !== data) {
|
|
36577
|
+
throw new Error("The ACP embedded content is not canonical base64");
|
|
36578
|
+
}
|
|
36579
|
+
return bytes;
|
|
36580
|
+
}
|
|
36581
|
+
var embeddedImageSchema = external_exports.looseObject({
|
|
36582
|
+
type: external_exports.literal("image"),
|
|
36583
|
+
data: external_exports.string(),
|
|
36584
|
+
mimeType: external_exports.string()
|
|
36585
|
+
});
|
|
36586
|
+
function isRecord8(value) {
|
|
36587
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
36576
36588
|
}
|
|
36577
36589
|
var AcpContentExternalizer = class {
|
|
36578
36590
|
#store;
|
|
@@ -36583,32 +36595,45 @@ var AcpContentExternalizer = class {
|
|
|
36583
36595
|
switch (content.type) {
|
|
36584
36596
|
case "text":
|
|
36585
36597
|
case "resource_link":
|
|
36586
|
-
return content;
|
|
36598
|
+
return { agent: content, event: content };
|
|
36587
36599
|
case "image": {
|
|
36588
36600
|
if (content.data.length === 0) {
|
|
36589
|
-
return content;
|
|
36601
|
+
return { agent: content, event: content };
|
|
36602
|
+
}
|
|
36603
|
+
try {
|
|
36604
|
+
const bytes = decodeBase64(content.data);
|
|
36605
|
+
if (sniffRasterMime(bytes) !== content.mimeType) {
|
|
36606
|
+
throw new Error("Embedded image bytes do not match a supported image MIME type");
|
|
36607
|
+
}
|
|
36608
|
+
const stored = await this.#store.put({
|
|
36609
|
+
bytes,
|
|
36610
|
+
kind: "image",
|
|
36611
|
+
mediaType: content.mimeType,
|
|
36612
|
+
name: "image",
|
|
36613
|
+
sessionId,
|
|
36614
|
+
signal
|
|
36615
|
+
});
|
|
36616
|
+
return {
|
|
36617
|
+
agent: { ...content, data: "", uri: `mobius-content:image:${stored.key}` },
|
|
36618
|
+
event: {
|
|
36619
|
+
_meta: content._meta,
|
|
36620
|
+
annotations: content.annotations,
|
|
36621
|
+
byteLength: stored.byteLength,
|
|
36622
|
+
imageKey: stored.key,
|
|
36623
|
+
mimeType: content.mimeType,
|
|
36624
|
+
type: "external_image",
|
|
36625
|
+
uri: content.uri
|
|
36626
|
+
}
|
|
36627
|
+
};
|
|
36628
|
+
} catch {
|
|
36629
|
+
signal.throwIfAborted();
|
|
36630
|
+
const unavailable = { type: "text", text: "[Image unavailable]" };
|
|
36631
|
+
return { agent: unavailable, event: unavailable };
|
|
36590
36632
|
}
|
|
36591
|
-
const stored = await this.#store.put({
|
|
36592
|
-
bytes: decodeBase64(content.data),
|
|
36593
|
-
kind: "image",
|
|
36594
|
-
mediaType: content.mimeType,
|
|
36595
|
-
name: "image",
|
|
36596
|
-
sessionId,
|
|
36597
|
-
signal
|
|
36598
|
-
});
|
|
36599
|
-
return {
|
|
36600
|
-
_meta: content._meta,
|
|
36601
|
-
annotations: content.annotations,
|
|
36602
|
-
byteLength: stored.byteLength,
|
|
36603
|
-
imageKey: stored.key,
|
|
36604
|
-
mimeType: content.mimeType,
|
|
36605
|
-
type: "external_image",
|
|
36606
|
-
uri: content.uri
|
|
36607
|
-
};
|
|
36608
36633
|
}
|
|
36609
36634
|
case "audio": {
|
|
36610
36635
|
if (content.data.length === 0) {
|
|
36611
|
-
return content;
|
|
36636
|
+
return { agent: content, event: content };
|
|
36612
36637
|
}
|
|
36613
36638
|
const stored = await this.#store.put({
|
|
36614
36639
|
bytes: decodeBase64(content.data),
|
|
@@ -36619,12 +36644,15 @@ var AcpContentExternalizer = class {
|
|
|
36619
36644
|
signal
|
|
36620
36645
|
});
|
|
36621
36646
|
return {
|
|
36622
|
-
|
|
36623
|
-
|
|
36624
|
-
|
|
36625
|
-
|
|
36626
|
-
|
|
36627
|
-
|
|
36647
|
+
agent: content,
|
|
36648
|
+
event: {
|
|
36649
|
+
_meta: content._meta,
|
|
36650
|
+
annotations: content.annotations,
|
|
36651
|
+
audioKey: stored.key,
|
|
36652
|
+
byteLength: stored.byteLength,
|
|
36653
|
+
mimeType: content.mimeType,
|
|
36654
|
+
type: "external_audio"
|
|
36655
|
+
}
|
|
36628
36656
|
};
|
|
36629
36657
|
}
|
|
36630
36658
|
case "resource": {
|
|
@@ -36632,7 +36660,7 @@ var AcpContentExternalizer = class {
|
|
|
36632
36660
|
const encoding = "text" in embedded ? "text" : "binary";
|
|
36633
36661
|
const bytes = "text" in embedded ? Buffer.from(embedded.text, "utf8") : decodeBase64(embedded.blob);
|
|
36634
36662
|
if (bytes.byteLength === 0) {
|
|
36635
|
-
return content;
|
|
36663
|
+
return { agent: content, event: content };
|
|
36636
36664
|
}
|
|
36637
36665
|
const mediaType = embedded.mimeType ?? "application/octet-stream";
|
|
36638
36666
|
const stored = await this.#store.put({
|
|
@@ -36644,43 +36672,111 @@ var AcpContentExternalizer = class {
|
|
|
36644
36672
|
signal
|
|
36645
36673
|
});
|
|
36646
36674
|
return {
|
|
36647
|
-
|
|
36648
|
-
|
|
36649
|
-
|
|
36650
|
-
|
|
36651
|
-
|
|
36652
|
-
|
|
36653
|
-
|
|
36654
|
-
|
|
36675
|
+
agent: content,
|
|
36676
|
+
event: {
|
|
36677
|
+
_meta: content._meta,
|
|
36678
|
+
annotations: content.annotations,
|
|
36679
|
+
byteLength: stored.byteLength,
|
|
36680
|
+
encoding,
|
|
36681
|
+
mimeType: embedded.mimeType,
|
|
36682
|
+
resourceKey: stored.key,
|
|
36683
|
+
type: "external_resource",
|
|
36684
|
+
uri: embedded.uri
|
|
36685
|
+
}
|
|
36655
36686
|
};
|
|
36656
36687
|
}
|
|
36657
36688
|
}
|
|
36658
36689
|
}
|
|
36659
|
-
async #
|
|
36660
|
-
|
|
36690
|
+
async #rawOutput(sessionId, value, images, signal, depth = 0) {
|
|
36691
|
+
signal.throwIfAborted();
|
|
36692
|
+
if (depth > 16) {
|
|
36693
|
+
throw new Error("ACP tool output exceeds the maximum nesting depth");
|
|
36694
|
+
}
|
|
36695
|
+
if (Array.isArray(value)) {
|
|
36696
|
+
const result2 = [];
|
|
36697
|
+
for (const item of value) {
|
|
36698
|
+
result2.push(await this.#rawOutput(sessionId, item, images, signal, depth + 1));
|
|
36699
|
+
}
|
|
36700
|
+
return result2;
|
|
36701
|
+
}
|
|
36702
|
+
if (!isRecord8(value)) {
|
|
36703
|
+
return value;
|
|
36704
|
+
}
|
|
36705
|
+
const image = embeddedImageSchema.safeParse(value);
|
|
36706
|
+
if (image.success && image.data.data.length > 0) {
|
|
36707
|
+
const prepared = await this.#content(sessionId, image.data, signal);
|
|
36708
|
+
if (isRecord8(prepared.event) && typeof prepared.event["imageKey"] === "string") {
|
|
36709
|
+
images.set(prepared.event["imageKey"], prepared);
|
|
36710
|
+
} else {
|
|
36711
|
+
images.set(`unavailable:${images.size}`, prepared);
|
|
36712
|
+
}
|
|
36713
|
+
return prepared.event;
|
|
36714
|
+
}
|
|
36715
|
+
const result = {};
|
|
36716
|
+
for (const [key, item] of Object.entries(value)) {
|
|
36717
|
+
result[key] = await this.#rawOutput(sessionId, item, images, signal, depth + 1);
|
|
36718
|
+
}
|
|
36719
|
+
return result;
|
|
36720
|
+
}
|
|
36721
|
+
async #toolUpdate(sessionId, update, signal) {
|
|
36722
|
+
const images = /* @__PURE__ */ new Map();
|
|
36723
|
+
const rawOutput = update.rawOutput === void 0 ? void 0 : await this.#rawOutput(sessionId, update.rawOutput, images, signal);
|
|
36724
|
+
const originalJson = images.size === 0 ? void 0 : JSON.stringify(update.rawOutput);
|
|
36725
|
+
const rewrittenJson = images.size === 0 ? void 0 : JSON.stringify(rawOutput);
|
|
36726
|
+
const agentContent = [];
|
|
36727
|
+
const eventContent = [];
|
|
36728
|
+
for (const item of update.content ?? []) {
|
|
36729
|
+
if (item.type !== "content") {
|
|
36730
|
+
agentContent.push(item);
|
|
36731
|
+
eventContent.push(item);
|
|
36732
|
+
continue;
|
|
36733
|
+
}
|
|
36734
|
+
const content = item.content.type === "text" && item.content.text === originalJson && rewrittenJson !== void 0 ? { ...item.content, text: rewrittenJson } : item.content;
|
|
36735
|
+
const prepared = await this.#content(sessionId, content, signal);
|
|
36736
|
+
agentContent.push({ ...item, content: prepared.agent });
|
|
36737
|
+
eventContent.push({ ...item, content: prepared.event });
|
|
36738
|
+
if (isRecord8(prepared.event) && typeof prepared.event["imageKey"] === "string") {
|
|
36739
|
+
images.delete(prepared.event["imageKey"]);
|
|
36740
|
+
}
|
|
36741
|
+
}
|
|
36742
|
+
for (const prepared of images.values()) {
|
|
36743
|
+
agentContent.push({ type: "content", content: prepared.agent });
|
|
36744
|
+
eventContent.push({ type: "content", content: prepared.event });
|
|
36745
|
+
}
|
|
36746
|
+
const output2 = update.rawOutput === void 0 ? {} : { rawOutput };
|
|
36747
|
+
const hasContent = update.content !== void 0 && update.content !== null || agentContent.length > 0;
|
|
36748
|
+
return {
|
|
36749
|
+
agent: { ...update, ...output2, ...hasContent ? { content: agentContent } : {} },
|
|
36750
|
+
event: { ...update, ...output2, ...hasContent ? { content: eventContent } : {} }
|
|
36751
|
+
};
|
|
36661
36752
|
}
|
|
36662
36753
|
update = async (sessionId, update, signal) => {
|
|
36663
36754
|
switch (update.sessionUpdate) {
|
|
36664
36755
|
case "user_message_chunk":
|
|
36665
36756
|
case "agent_message_chunk":
|
|
36666
36757
|
case "agent_thought_chunk":
|
|
36667
|
-
case "compaction_summary_chunk":
|
|
36668
|
-
|
|
36758
|
+
case "compaction_summary_chunk": {
|
|
36759
|
+
const content = await this.#content(sessionId, update.content, signal);
|
|
36760
|
+
return {
|
|
36761
|
+
agent: { ...update, content: content.agent },
|
|
36762
|
+
event: { ...update, content: content.event }
|
|
36763
|
+
};
|
|
36764
|
+
}
|
|
36669
36765
|
case "tool_call":
|
|
36670
36766
|
case "tool_call_update":
|
|
36671
|
-
return
|
|
36672
|
-
|
|
36673
|
-
|
|
36674
|
-
|
|
36675
|
-
|
|
36676
|
-
|
|
36677
|
-
|
|
36678
|
-
|
|
36679
|
-
|
|
36680
|
-
summary:
|
|
36681
|
-
|
|
36682
|
-
)
|
|
36767
|
+
return await this.#toolUpdate(sessionId, update, signal);
|
|
36768
|
+
case "compaction_update": {
|
|
36769
|
+
if (update.summary === void 0 || update.summary === null) {
|
|
36770
|
+
return { agent: update, event: update };
|
|
36771
|
+
}
|
|
36772
|
+
const content = await Promise.all(
|
|
36773
|
+
update.summary.map(async (item) => await this.#content(sessionId, item, signal))
|
|
36774
|
+
);
|
|
36775
|
+
return {
|
|
36776
|
+
agent: { ...update, summary: content.map((item) => item.agent) },
|
|
36777
|
+
event: { ...update, summary: content.map((item) => item.event) }
|
|
36683
36778
|
};
|
|
36779
|
+
}
|
|
36684
36780
|
case "plan":
|
|
36685
36781
|
case "plan_update":
|
|
36686
36782
|
case "plan_removed":
|
|
@@ -36689,16 +36785,17 @@ var AcpContentExternalizer = class {
|
|
|
36689
36785
|
case "config_option_update":
|
|
36690
36786
|
case "session_info_update":
|
|
36691
36787
|
case "usage_update":
|
|
36692
|
-
return update;
|
|
36788
|
+
return { agent: update, event: update };
|
|
36693
36789
|
}
|
|
36694
36790
|
};
|
|
36695
36791
|
};
|
|
36696
36792
|
|
|
36697
36793
|
// src/external-content/local-external-content-store.ts
|
|
36698
36794
|
import { createHash as createHash2, randomUUID } from "node:crypto";
|
|
36699
|
-
import { lstat, mkdir as mkdir4,
|
|
36795
|
+
import { lstat, mkdir as mkdir4, readdir as readdir2, realpath as realpath7, rename as rename3, rm as rm3, stat as stat6, utimes, writeFile as writeFile3 } from "node:fs/promises";
|
|
36700
36796
|
import { dirname as dirname4, join as join15 } from "node:path";
|
|
36701
36797
|
var contentRequest = /^mobius-content:(image|audio|resource):([a-f0-9]{64})$/u;
|
|
36798
|
+
var CONTENT_LIFETIME_MILLISECONDS = 24 * 60 * 60 * 1e3;
|
|
36702
36799
|
var metadataSchema2 = external_exports.strictObject({
|
|
36703
36800
|
kind: external_exports.enum(["image", "audio", "resource"]),
|
|
36704
36801
|
mediaType: external_exports.string().min(1).max(2048).regex(/^[\u0020-\u007e]+$/u),
|
|
@@ -36714,9 +36811,6 @@ var UnretainedExternalContentStore = class {
|
|
|
36714
36811
|
return Promise.resolve(null);
|
|
36715
36812
|
};
|
|
36716
36813
|
};
|
|
36717
|
-
function sessionScope(sessionId) {
|
|
36718
|
-
return createHash2("sha256").update(sessionId).digest("hex");
|
|
36719
|
-
}
|
|
36720
36814
|
async function atomicWrite(path2, bytes, signal) {
|
|
36721
36815
|
const temporary = `${path2}.${randomUUID()}.tmp`;
|
|
36722
36816
|
try {
|
|
@@ -36729,55 +36823,134 @@ async function atomicWrite(path2, bytes, signal) {
|
|
|
36729
36823
|
}
|
|
36730
36824
|
var LocalExternalContentStore = class {
|
|
36731
36825
|
#root;
|
|
36826
|
+
#entries = /* @__PURE__ */ new Map();
|
|
36827
|
+
#operations = /* @__PURE__ */ new Set();
|
|
36828
|
+
#lifetime = new AbortController();
|
|
36829
|
+
#expirationTimer;
|
|
36830
|
+
#cleanup = Promise.resolve();
|
|
36732
36831
|
constructor(stateDirectory) {
|
|
36733
|
-
this.#root = join15(stateDirectory, "tmp", "session-content");
|
|
36734
|
-
|
|
36735
|
-
|
|
36736
|
-
|
|
36832
|
+
this.#root = join15(stateDirectory, "tmp", "session-content", randomUUID());
|
|
36833
|
+
this.#expirationTimer = setInterval(() => {
|
|
36834
|
+
void this.#expire().catch(() => void 0);
|
|
36835
|
+
}, 6e4);
|
|
36836
|
+
this.#expirationTimer.unref();
|
|
36837
|
+
}
|
|
36838
|
+
#expire = () => {
|
|
36839
|
+
this.#cleanup = this.#cleanup.catch(() => void 0).then(async () => {
|
|
36840
|
+
await mkdir4(this.#root, { mode: 448, recursive: true });
|
|
36841
|
+
const now = /* @__PURE__ */ new Date();
|
|
36842
|
+
await utimes(this.#root, now, now);
|
|
36843
|
+
for (const directory of await readdir2(dirname4(this.#root), { withFileTypes: true })) {
|
|
36844
|
+
if (!directory.isDirectory() || !/^[a-f0-9-]{36}$/u.test(directory.name)) {
|
|
36845
|
+
continue;
|
|
36846
|
+
}
|
|
36847
|
+
const path2 = join15(dirname4(this.#root), directory.name);
|
|
36848
|
+
if (path2 === this.#root) {
|
|
36849
|
+
continue;
|
|
36850
|
+
}
|
|
36851
|
+
const modified = await stat6(path2).then(
|
|
36852
|
+
(entry) => entry.mtimeMs,
|
|
36853
|
+
() => Date.now()
|
|
36854
|
+
);
|
|
36855
|
+
if (modified + CONTENT_LIFETIME_MILLISECONDS <= Date.now()) {
|
|
36856
|
+
await rm3(path2, { force: true, recursive: true });
|
|
36857
|
+
}
|
|
36858
|
+
}
|
|
36859
|
+
for (const [request, entry] of this.#entries) {
|
|
36860
|
+
if (entry.expiresAt > Date.now()) {
|
|
36861
|
+
continue;
|
|
36862
|
+
}
|
|
36863
|
+
await rm3(entry.path, { force: true });
|
|
36864
|
+
this.#entries.delete(request);
|
|
36865
|
+
}
|
|
36866
|
+
});
|
|
36867
|
+
return this.#cleanup;
|
|
36868
|
+
};
|
|
36869
|
+
#track = async (operation) => {
|
|
36870
|
+
this.#lifetime.signal.throwIfAborted();
|
|
36871
|
+
const pending = operation();
|
|
36872
|
+
this.#operations.add(pending);
|
|
36873
|
+
try {
|
|
36874
|
+
return await pending;
|
|
36875
|
+
} finally {
|
|
36876
|
+
this.#operations.delete(pending);
|
|
36877
|
+
}
|
|
36878
|
+
};
|
|
36879
|
+
put = (input2) => this.#track(() => this.#put(input2));
|
|
36880
|
+
#put = async ({ bytes, kind, mediaType, name, sessionId, signal }) => {
|
|
36881
|
+
const active = AbortSignal.any([signal, this.#lifetime.signal]);
|
|
36882
|
+
active.throwIfAborted();
|
|
36883
|
+
const metadata = metadataSchema2.parse({ kind, mediaType, name });
|
|
36737
36884
|
const key = createHash2("sha256").update(bytes).digest("hex");
|
|
36738
|
-
const
|
|
36885
|
+
const request = `mobius-content:${kind}:${key}`;
|
|
36886
|
+
const existing = this.#entries.get(request);
|
|
36887
|
+
if (existing !== void 0 && existing.expiresAt > Date.now()) {
|
|
36888
|
+
this.#entries.set(request, {
|
|
36889
|
+
...existing,
|
|
36890
|
+
expiresAt: Date.now() + CONTENT_LIFETIME_MILLISECONDS,
|
|
36891
|
+
sessions: /* @__PURE__ */ new Set([...existing.sessions, sessionId])
|
|
36892
|
+
});
|
|
36893
|
+
return { byteLength: existing.byteLength, key };
|
|
36894
|
+
}
|
|
36895
|
+
await this.#expire();
|
|
36896
|
+
active.throwIfAborted();
|
|
36897
|
+
const directory = join15(this.#root, kind);
|
|
36739
36898
|
await mkdir4(directory, { mode: 448, recursive: true });
|
|
36740
|
-
|
|
36899
|
+
active.throwIfAborted();
|
|
36741
36900
|
const path2 = join15(directory, key);
|
|
36742
|
-
|
|
36743
|
-
await
|
|
36744
|
-
|
|
36745
|
-
|
|
36746
|
-
|
|
36747
|
-
|
|
36901
|
+
const write = atomicWrite(path2, bytes, active);
|
|
36902
|
+
await write;
|
|
36903
|
+
active.throwIfAborted();
|
|
36904
|
+
const retained = this.#entries.get(request);
|
|
36905
|
+
this.#entries.set(request, {
|
|
36906
|
+
byteLength: bytes.byteLength,
|
|
36907
|
+
expiresAt: Date.now() + CONTENT_LIFETIME_MILLISECONDS,
|
|
36908
|
+
mediaType: metadata.mediaType,
|
|
36909
|
+
name: metadata.name,
|
|
36910
|
+
path: path2,
|
|
36911
|
+
sessions: /* @__PURE__ */ new Set([...retained?.sessions ?? [], sessionId])
|
|
36912
|
+
});
|
|
36748
36913
|
return { byteLength: bytes.byteLength, key };
|
|
36749
36914
|
};
|
|
36750
|
-
resolve =
|
|
36751
|
-
|
|
36752
|
-
|
|
36915
|
+
resolve = (sessionId, request, signal) => this.#track(() => this.#resolve(sessionId, request, AbortSignal.any([signal, this.#lifetime.signal])));
|
|
36916
|
+
#resolve = async (sessionId, request, signal) => {
|
|
36917
|
+
signal.throwIfAborted();
|
|
36918
|
+
this.#lifetime.signal.throwIfAborted();
|
|
36919
|
+
if (!contentRequest.test(request)) {
|
|
36753
36920
|
return null;
|
|
36754
36921
|
}
|
|
36755
|
-
const
|
|
36756
|
-
|
|
36757
|
-
|
|
36922
|
+
const entry = this.#entries.get(request);
|
|
36923
|
+
if (entry === void 0 || !entry.sessions.has(sessionId)) {
|
|
36924
|
+
return null;
|
|
36925
|
+
}
|
|
36926
|
+
if (entry.expiresAt <= Date.now()) {
|
|
36927
|
+
await this.#expire();
|
|
36928
|
+
signal.throwIfAborted();
|
|
36758
36929
|
return null;
|
|
36759
36930
|
}
|
|
36760
|
-
const directory = join15(this.#root, sessionScope(sessionId), kind);
|
|
36761
|
-
const path2 = join15(directory, key);
|
|
36762
36931
|
try {
|
|
36763
|
-
const [resolvedDirectory, resolvedPath, file2
|
|
36764
|
-
realpath7(
|
|
36765
|
-
realpath7(
|
|
36766
|
-
lstat(
|
|
36767
|
-
readFile3(`${path2}.json`, "utf8").then((value) => metadataSchema2.parse(JSON.parse(value)))
|
|
36932
|
+
const [resolvedDirectory, resolvedPath, file2] = await Promise.all([
|
|
36933
|
+
realpath7(dirname4(entry.path)),
|
|
36934
|
+
realpath7(entry.path),
|
|
36935
|
+
lstat(entry.path)
|
|
36768
36936
|
]);
|
|
36769
36937
|
signal.throwIfAborted();
|
|
36770
|
-
if (!file2.isFile() || dirname4(resolvedPath) !== resolvedDirectory
|
|
36938
|
+
if (!file2.isFile() || file2.isSymbolicLink() || dirname4(resolvedPath) !== resolvedDirectory) {
|
|
36771
36939
|
return null;
|
|
36772
36940
|
}
|
|
36773
|
-
|
|
36774
|
-
signal.throwIfAborted();
|
|
36775
|
-
return { mediaType: metadata.mediaType, name: metadata.name, path: resolvedPath };
|
|
36941
|
+
return { mediaType: entry.mediaType, name: entry.name, path: resolvedPath };
|
|
36776
36942
|
} catch {
|
|
36777
36943
|
signal.throwIfAborted();
|
|
36778
36944
|
return null;
|
|
36779
36945
|
}
|
|
36780
36946
|
};
|
|
36947
|
+
[Symbol.asyncDispose] = async () => {
|
|
36948
|
+
clearInterval(this.#expirationTimer);
|
|
36949
|
+
this.#lifetime.abort();
|
|
36950
|
+
await Promise.allSettled([...this.#operations, this.#cleanup]);
|
|
36951
|
+
this.#entries.clear();
|
|
36952
|
+
await rm3(this.#root, { force: true, recursive: true });
|
|
36953
|
+
};
|
|
36781
36954
|
};
|
|
36782
36955
|
|
|
36783
36956
|
// src/native-sessions/chat-agent.ts
|
|
@@ -37699,7 +37872,7 @@ var AgentCatalogPublishError = class extends Error {
|
|
|
37699
37872
|
this.name = "AgentCatalogPublishError";
|
|
37700
37873
|
}
|
|
37701
37874
|
};
|
|
37702
|
-
function
|
|
37875
|
+
function isRecord9(value) {
|
|
37703
37876
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
37704
37877
|
}
|
|
37705
37878
|
function isSafeRelayErrorMessage(value) {
|
|
@@ -37712,7 +37885,7 @@ async function rejectedCatalogError(response) {
|
|
|
37712
37885
|
} catch {
|
|
37713
37886
|
return new AgentCatalogPublishError("The Relay rejected the Agent catalog update");
|
|
37714
37887
|
}
|
|
37715
|
-
if (!
|
|
37888
|
+
if (!isRecord9(value) || !isRecord9(value["error"])) {
|
|
37716
37889
|
return new AgentCatalogPublishError("The Relay rejected the Agent catalog update");
|
|
37717
37890
|
}
|
|
37718
37891
|
const code = value["error"]["code"];
|
|
@@ -38243,7 +38416,7 @@ var FixedInstallationExecutor = class {
|
|
|
38243
38416
|
};
|
|
38244
38417
|
|
|
38245
38418
|
// src/authorization/workspace-directory.ts
|
|
38246
|
-
import { readdir as
|
|
38419
|
+
import { readdir as readdir3, realpath as realpath8, stat as stat7 } from "node:fs/promises";
|
|
38247
38420
|
import { homedir as homedir2 } from "node:os";
|
|
38248
38421
|
import { basename as basename3, dirname as dirname5, isAbsolute as isAbsolute9, join as join16, normalize as normalize3, relative as relative4 } from "node:path";
|
|
38249
38422
|
|
|
@@ -38363,7 +38536,7 @@ var WorkspaceDirectoryService = class {
|
|
|
38363
38536
|
list = async (bindingId, id, signal) => {
|
|
38364
38537
|
const target = await this.resolve(bindingId, id, signal);
|
|
38365
38538
|
try {
|
|
38366
|
-
const children = await
|
|
38539
|
+
const children = await readdir3(target, { withFileTypes: true });
|
|
38367
38540
|
signal.throwIfAborted();
|
|
38368
38541
|
const entries = [];
|
|
38369
38542
|
for (const child2 of children) {
|
|
@@ -44062,7 +44235,7 @@ async function runDaemon(config2, audit, signal, timer = systemDaemonTimer, opti
|
|
|
44062
44235
|
const sessionStore = new SqliteAcpSessionStore(
|
|
44063
44236
|
join18(stateDirectory, "sessions", `${createHash7("sha256").update(config2.channelId).digest("hex")}.sqlite`)
|
|
44064
44237
|
);
|
|
44065
|
-
|
|
44238
|
+
await using externalContent = new LocalExternalContentStore(stateDirectory);
|
|
44066
44239
|
const operations = new DaemonOperationState();
|
|
44067
44240
|
const publisher = new DaemonSessionEventPublisher(sessionStore);
|
|
44068
44241
|
const eventLogV2 = new DaemonSessionEventLogV2(publisher, sessionStore);
|
|
@@ -44262,7 +44435,7 @@ import { fetch as fetch4 } from "undici";
|
|
|
44262
44435
|
|
|
44263
44436
|
// src/storage/runtime-installation-store.ts
|
|
44264
44437
|
import { createHash as createHash8, randomUUID as randomUUID8 } from "node:crypto";
|
|
44265
|
-
import { mkdir as mkdir5, open as open5, readdir as
|
|
44438
|
+
import { mkdir as mkdir5, open as open5, readdir as readdir4, rename as rename4, unlink, writeFile as writeFile4 } from "node:fs/promises";
|
|
44266
44439
|
import { dirname as dirname6, join as join19, resolve as resolve6 } from "node:path";
|
|
44267
44440
|
var APPLICATION_ID_PATTERN = /^[a-z][a-z0-9]*(?:[.-][a-z0-9]+){1,31}$/;
|
|
44268
44441
|
var CONNECTION_ID_PATTERN = /^mcn_[a-f0-9]{32}$/;
|
|
@@ -44327,7 +44500,7 @@ var VerifiedRuntimeConnection = class {
|
|
|
44327
44500
|
this.runtimeId = runtimeId;
|
|
44328
44501
|
}
|
|
44329
44502
|
};
|
|
44330
|
-
function
|
|
44503
|
+
function isRecord10(value) {
|
|
44331
44504
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
44332
44505
|
}
|
|
44333
44506
|
function hasExactKeys(value, expectedKeys) {
|
|
@@ -44400,7 +44573,7 @@ function channelIndexFileName(channelId) {
|
|
|
44400
44573
|
return `mci_${createHash8("sha256").update(channelId).digest("hex")}.json`;
|
|
44401
44574
|
}
|
|
44402
44575
|
function decodeInstallationPointer(value) {
|
|
44403
|
-
if (!
|
|
44576
|
+
if (!isRecord10(value) || !hasExactKeys(value, INSTALLATION_POINTER_KEYS) || value["version"] !== 1) {
|
|
44404
44577
|
throw new RuntimeInstallationStoreError("invalid_installation", "The local installation record is invalid");
|
|
44405
44578
|
}
|
|
44406
44579
|
const storedInstallationId = value["installationId"];
|
|
@@ -44410,7 +44583,7 @@ function decodeInstallationPointer(value) {
|
|
|
44410
44583
|
return { installationId: validateInstallationId(storedInstallationId) };
|
|
44411
44584
|
}
|
|
44412
44585
|
function decodeChannelIndex(value) {
|
|
44413
|
-
if (!
|
|
44586
|
+
if (!isRecord10(value) || !hasExactKeys(value, CHANNEL_INDEX_KEYS) || value["version"] !== 1) {
|
|
44414
44587
|
throw new RuntimeInstallationStoreError("invalid_connection", "The saved Runtime connection is invalid");
|
|
44415
44588
|
}
|
|
44416
44589
|
const applicationId = value["applicationId"];
|
|
@@ -44460,7 +44633,7 @@ function decodeVerifiedConnection(value) {
|
|
|
44460
44633
|
);
|
|
44461
44634
|
}
|
|
44462
44635
|
function decodeConnection(value) {
|
|
44463
|
-
if (!
|
|
44636
|
+
if (!isRecord10(value)) {
|
|
44464
44637
|
throw new RuntimeInstallationStoreError("invalid_connection", "The saved Runtime connection is invalid");
|
|
44465
44638
|
}
|
|
44466
44639
|
return decodeVerifiedConnection(value);
|
|
@@ -44641,7 +44814,7 @@ var RuntimeInstallationStore = class _RuntimeInstallationStore {
|
|
|
44641
44814
|
signal.throwIfAborted();
|
|
44642
44815
|
let entries;
|
|
44643
44816
|
try {
|
|
44644
|
-
entries = await
|
|
44817
|
+
entries = await readdir4(this.#connectionDirectory);
|
|
44645
44818
|
} catch (cause) {
|
|
44646
44819
|
if (isNodeError(cause, "ENOENT")) {
|
|
44647
44820
|
return [];
|
|
@@ -44777,7 +44950,7 @@ var PairingClientError = class extends Error {
|
|
|
44777
44950
|
this.name = "PairingClientError";
|
|
44778
44951
|
}
|
|
44779
44952
|
};
|
|
44780
|
-
function
|
|
44953
|
+
function isRecord11(value) {
|
|
44781
44954
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
44782
44955
|
}
|
|
44783
44956
|
function hasExactKeys2(value, expectedKeys) {
|
|
@@ -44855,9 +45028,9 @@ async function readJsonResponse(response) {
|
|
|
44855
45028
|
}
|
|
44856
45029
|
}
|
|
44857
45030
|
function readRelayError(value) {
|
|
44858
|
-
if (
|
|
45031
|
+
if (isRecord11(value)) {
|
|
44859
45032
|
const error62 = value["error"];
|
|
44860
|
-
if (
|
|
45033
|
+
if (isRecord11(error62)) {
|
|
44861
45034
|
const code = error62["code"];
|
|
44862
45035
|
const message = error62["message"];
|
|
44863
45036
|
if (typeof code === "string" && typeof message === "string") {
|
|
@@ -44868,7 +45041,7 @@ function readRelayError(value) {
|
|
|
44868
45041
|
return new PairingClientError("pairing_failed", "The relay could not pair this machine");
|
|
44869
45042
|
}
|
|
44870
45043
|
function decodePairingResponse(value, credentialField, expectedKeys) {
|
|
44871
|
-
if (!
|
|
45044
|
+
if (!isRecord11(value) || !hasExactKeys2(value, expectedKeys)) {
|
|
44872
45045
|
throw new PairingClientError("invalid_relay_response", "The relay returned an invalid pairing response");
|
|
44873
45046
|
}
|
|
44874
45047
|
const appId = value["appId"];
|