@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/cli.js
CHANGED
|
@@ -3381,7 +3381,7 @@ var program = new Command();
|
|
|
3381
3381
|
// package.json
|
|
3382
3382
|
var package_default = {
|
|
3383
3383
|
name: "@moxt-ai/mobius",
|
|
3384
|
-
version: "0.0.
|
|
3384
|
+
version: "0.0.168",
|
|
3385
3385
|
description: "Mobius CLI for pairing and running local AI agent services.",
|
|
3386
3386
|
type: "module",
|
|
3387
3387
|
bin: {
|
|
@@ -30745,7 +30745,7 @@ function createDaemonConfig(connection, agents = [], installableAgents = [], loc
|
|
|
30745
30745
|
// src/daemon-manager.ts
|
|
30746
30746
|
import { spawn as spawn6 } from "node:child_process";
|
|
30747
30747
|
import { createHash as createHash9, randomBytes } from "node:crypto";
|
|
30748
|
-
import { readFile as
|
|
30748
|
+
import { readFile as readFile3, unlink as unlink2, writeFile as writeFile5 } from "node:fs/promises";
|
|
30749
30749
|
import { createConnection, createServer } from "node:net";
|
|
30750
30750
|
import { tmpdir } from "node:os";
|
|
30751
30751
|
import { join as join20 } from "node:path";
|
|
@@ -40507,13 +40507,13 @@ var AgentSession = class _AgentSession {
|
|
|
40507
40507
|
};
|
|
40508
40508
|
#processUpdate = async (notification) => {
|
|
40509
40509
|
this.assertNativeSession(notification.sessionId);
|
|
40510
|
-
const update = notification.update;
|
|
40511
40510
|
const externalized = await this.#contentExternalizer.update(
|
|
40512
40511
|
this.#mobiusSessionId,
|
|
40513
|
-
update,
|
|
40512
|
+
notification.update,
|
|
40514
40513
|
AbortSignal.timeout(3e4)
|
|
40515
40514
|
);
|
|
40516
|
-
const
|
|
40515
|
+
const update = externalized.agent;
|
|
40516
|
+
const rawUpdate = decodeAcpSessionUpdateV2(JSON.stringify(externalized.event));
|
|
40517
40517
|
if (this.#sessionLoad.kind === "capturing") {
|
|
40518
40518
|
await this.#sessionLoad.history.record(update, rawUpdate);
|
|
40519
40519
|
} else {
|
|
@@ -40939,7 +40939,19 @@ function decodeBase64(data) {
|
|
|
40939
40939
|
if (data.length > MAXIMUM_ENCODED_CONTENT_CHARACTERS || data.length % 4 !== 0 || !/^[A-Za-z0-9+/]*={0,2}$/u.test(data)) {
|
|
40940
40940
|
throw new Error("The ACP embedded content is not valid bounded base64");
|
|
40941
40941
|
}
|
|
40942
|
-
|
|
40942
|
+
const bytes = Buffer.from(data, "base64");
|
|
40943
|
+
if (bytes.toString("base64") !== data) {
|
|
40944
|
+
throw new Error("The ACP embedded content is not canonical base64");
|
|
40945
|
+
}
|
|
40946
|
+
return bytes;
|
|
40947
|
+
}
|
|
40948
|
+
var embeddedImageSchema = external_exports.looseObject({
|
|
40949
|
+
type: external_exports.literal("image"),
|
|
40950
|
+
data: external_exports.string(),
|
|
40951
|
+
mimeType: external_exports.string()
|
|
40952
|
+
});
|
|
40953
|
+
function isRecord10(value) {
|
|
40954
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
40943
40955
|
}
|
|
40944
40956
|
var AcpContentExternalizer = class {
|
|
40945
40957
|
#store;
|
|
@@ -40950,32 +40962,45 @@ var AcpContentExternalizer = class {
|
|
|
40950
40962
|
switch (content.type) {
|
|
40951
40963
|
case "text":
|
|
40952
40964
|
case "resource_link":
|
|
40953
|
-
return content;
|
|
40965
|
+
return { agent: content, event: content };
|
|
40954
40966
|
case "image": {
|
|
40955
40967
|
if (content.data.length === 0) {
|
|
40956
|
-
return content;
|
|
40968
|
+
return { agent: content, event: content };
|
|
40969
|
+
}
|
|
40970
|
+
try {
|
|
40971
|
+
const bytes = decodeBase64(content.data);
|
|
40972
|
+
if (sniffRasterMime(bytes) !== content.mimeType) {
|
|
40973
|
+
throw new Error("Embedded image bytes do not match a supported image MIME type");
|
|
40974
|
+
}
|
|
40975
|
+
const stored = await this.#store.put({
|
|
40976
|
+
bytes,
|
|
40977
|
+
kind: "image",
|
|
40978
|
+
mediaType: content.mimeType,
|
|
40979
|
+
name: "image",
|
|
40980
|
+
sessionId,
|
|
40981
|
+
signal
|
|
40982
|
+
});
|
|
40983
|
+
return {
|
|
40984
|
+
agent: { ...content, data: "", uri: `mobius-content:image:${stored.key}` },
|
|
40985
|
+
event: {
|
|
40986
|
+
_meta: content._meta,
|
|
40987
|
+
annotations: content.annotations,
|
|
40988
|
+
byteLength: stored.byteLength,
|
|
40989
|
+
imageKey: stored.key,
|
|
40990
|
+
mimeType: content.mimeType,
|
|
40991
|
+
type: "external_image",
|
|
40992
|
+
uri: content.uri
|
|
40993
|
+
}
|
|
40994
|
+
};
|
|
40995
|
+
} catch {
|
|
40996
|
+
signal.throwIfAborted();
|
|
40997
|
+
const unavailable = { type: "text", text: "[Image unavailable]" };
|
|
40998
|
+
return { agent: unavailable, event: unavailable };
|
|
40957
40999
|
}
|
|
40958
|
-
const stored = await this.#store.put({
|
|
40959
|
-
bytes: decodeBase64(content.data),
|
|
40960
|
-
kind: "image",
|
|
40961
|
-
mediaType: content.mimeType,
|
|
40962
|
-
name: "image",
|
|
40963
|
-
sessionId,
|
|
40964
|
-
signal
|
|
40965
|
-
});
|
|
40966
|
-
return {
|
|
40967
|
-
_meta: content._meta,
|
|
40968
|
-
annotations: content.annotations,
|
|
40969
|
-
byteLength: stored.byteLength,
|
|
40970
|
-
imageKey: stored.key,
|
|
40971
|
-
mimeType: content.mimeType,
|
|
40972
|
-
type: "external_image",
|
|
40973
|
-
uri: content.uri
|
|
40974
|
-
};
|
|
40975
41000
|
}
|
|
40976
41001
|
case "audio": {
|
|
40977
41002
|
if (content.data.length === 0) {
|
|
40978
|
-
return content;
|
|
41003
|
+
return { agent: content, event: content };
|
|
40979
41004
|
}
|
|
40980
41005
|
const stored = await this.#store.put({
|
|
40981
41006
|
bytes: decodeBase64(content.data),
|
|
@@ -40986,12 +41011,15 @@ var AcpContentExternalizer = class {
|
|
|
40986
41011
|
signal
|
|
40987
41012
|
});
|
|
40988
41013
|
return {
|
|
40989
|
-
|
|
40990
|
-
|
|
40991
|
-
|
|
40992
|
-
|
|
40993
|
-
|
|
40994
|
-
|
|
41014
|
+
agent: content,
|
|
41015
|
+
event: {
|
|
41016
|
+
_meta: content._meta,
|
|
41017
|
+
annotations: content.annotations,
|
|
41018
|
+
audioKey: stored.key,
|
|
41019
|
+
byteLength: stored.byteLength,
|
|
41020
|
+
mimeType: content.mimeType,
|
|
41021
|
+
type: "external_audio"
|
|
41022
|
+
}
|
|
40995
41023
|
};
|
|
40996
41024
|
}
|
|
40997
41025
|
case "resource": {
|
|
@@ -40999,7 +41027,7 @@ var AcpContentExternalizer = class {
|
|
|
40999
41027
|
const encoding = "text" in embedded ? "text" : "binary";
|
|
41000
41028
|
const bytes = "text" in embedded ? Buffer.from(embedded.text, "utf8") : decodeBase64(embedded.blob);
|
|
41001
41029
|
if (bytes.byteLength === 0) {
|
|
41002
|
-
return content;
|
|
41030
|
+
return { agent: content, event: content };
|
|
41003
41031
|
}
|
|
41004
41032
|
const mediaType = embedded.mimeType ?? "application/octet-stream";
|
|
41005
41033
|
const stored = await this.#store.put({
|
|
@@ -41011,43 +41039,111 @@ var AcpContentExternalizer = class {
|
|
|
41011
41039
|
signal
|
|
41012
41040
|
});
|
|
41013
41041
|
return {
|
|
41014
|
-
|
|
41015
|
-
|
|
41016
|
-
|
|
41017
|
-
|
|
41018
|
-
|
|
41019
|
-
|
|
41020
|
-
|
|
41021
|
-
|
|
41042
|
+
agent: content,
|
|
41043
|
+
event: {
|
|
41044
|
+
_meta: content._meta,
|
|
41045
|
+
annotations: content.annotations,
|
|
41046
|
+
byteLength: stored.byteLength,
|
|
41047
|
+
encoding,
|
|
41048
|
+
mimeType: embedded.mimeType,
|
|
41049
|
+
resourceKey: stored.key,
|
|
41050
|
+
type: "external_resource",
|
|
41051
|
+
uri: embedded.uri
|
|
41052
|
+
}
|
|
41022
41053
|
};
|
|
41023
41054
|
}
|
|
41024
41055
|
}
|
|
41025
41056
|
}
|
|
41026
|
-
async #
|
|
41027
|
-
|
|
41057
|
+
async #rawOutput(sessionId, value, images, signal, depth = 0) {
|
|
41058
|
+
signal.throwIfAborted();
|
|
41059
|
+
if (depth > 16) {
|
|
41060
|
+
throw new Error("ACP tool output exceeds the maximum nesting depth");
|
|
41061
|
+
}
|
|
41062
|
+
if (Array.isArray(value)) {
|
|
41063
|
+
const result2 = [];
|
|
41064
|
+
for (const item of value) {
|
|
41065
|
+
result2.push(await this.#rawOutput(sessionId, item, images, signal, depth + 1));
|
|
41066
|
+
}
|
|
41067
|
+
return result2;
|
|
41068
|
+
}
|
|
41069
|
+
if (!isRecord10(value)) {
|
|
41070
|
+
return value;
|
|
41071
|
+
}
|
|
41072
|
+
const image = embeddedImageSchema.safeParse(value);
|
|
41073
|
+
if (image.success && image.data.data.length > 0) {
|
|
41074
|
+
const prepared = await this.#content(sessionId, image.data, signal);
|
|
41075
|
+
if (isRecord10(prepared.event) && typeof prepared.event["imageKey"] === "string") {
|
|
41076
|
+
images.set(prepared.event["imageKey"], prepared);
|
|
41077
|
+
} else {
|
|
41078
|
+
images.set(`unavailable:${images.size}`, prepared);
|
|
41079
|
+
}
|
|
41080
|
+
return prepared.event;
|
|
41081
|
+
}
|
|
41082
|
+
const result = {};
|
|
41083
|
+
for (const [key, item] of Object.entries(value)) {
|
|
41084
|
+
result[key] = await this.#rawOutput(sessionId, item, images, signal, depth + 1);
|
|
41085
|
+
}
|
|
41086
|
+
return result;
|
|
41087
|
+
}
|
|
41088
|
+
async #toolUpdate(sessionId, update, signal) {
|
|
41089
|
+
const images = /* @__PURE__ */ new Map();
|
|
41090
|
+
const rawOutput = update.rawOutput === void 0 ? void 0 : await this.#rawOutput(sessionId, update.rawOutput, images, signal);
|
|
41091
|
+
const originalJson = images.size === 0 ? void 0 : JSON.stringify(update.rawOutput);
|
|
41092
|
+
const rewrittenJson = images.size === 0 ? void 0 : JSON.stringify(rawOutput);
|
|
41093
|
+
const agentContent = [];
|
|
41094
|
+
const eventContent = [];
|
|
41095
|
+
for (const item of update.content ?? []) {
|
|
41096
|
+
if (item.type !== "content") {
|
|
41097
|
+
agentContent.push(item);
|
|
41098
|
+
eventContent.push(item);
|
|
41099
|
+
continue;
|
|
41100
|
+
}
|
|
41101
|
+
const content = item.content.type === "text" && item.content.text === originalJson && rewrittenJson !== void 0 ? { ...item.content, text: rewrittenJson } : item.content;
|
|
41102
|
+
const prepared = await this.#content(sessionId, content, signal);
|
|
41103
|
+
agentContent.push({ ...item, content: prepared.agent });
|
|
41104
|
+
eventContent.push({ ...item, content: prepared.event });
|
|
41105
|
+
if (isRecord10(prepared.event) && typeof prepared.event["imageKey"] === "string") {
|
|
41106
|
+
images.delete(prepared.event["imageKey"]);
|
|
41107
|
+
}
|
|
41108
|
+
}
|
|
41109
|
+
for (const prepared of images.values()) {
|
|
41110
|
+
agentContent.push({ type: "content", content: prepared.agent });
|
|
41111
|
+
eventContent.push({ type: "content", content: prepared.event });
|
|
41112
|
+
}
|
|
41113
|
+
const output2 = update.rawOutput === void 0 ? {} : { rawOutput };
|
|
41114
|
+
const hasContent = update.content !== void 0 && update.content !== null || agentContent.length > 0;
|
|
41115
|
+
return {
|
|
41116
|
+
agent: { ...update, ...output2, ...hasContent ? { content: agentContent } : {} },
|
|
41117
|
+
event: { ...update, ...output2, ...hasContent ? { content: eventContent } : {} }
|
|
41118
|
+
};
|
|
41028
41119
|
}
|
|
41029
41120
|
update = async (sessionId, update, signal) => {
|
|
41030
41121
|
switch (update.sessionUpdate) {
|
|
41031
41122
|
case "user_message_chunk":
|
|
41032
41123
|
case "agent_message_chunk":
|
|
41033
41124
|
case "agent_thought_chunk":
|
|
41034
|
-
case "compaction_summary_chunk":
|
|
41035
|
-
|
|
41125
|
+
case "compaction_summary_chunk": {
|
|
41126
|
+
const content = await this.#content(sessionId, update.content, signal);
|
|
41127
|
+
return {
|
|
41128
|
+
agent: { ...update, content: content.agent },
|
|
41129
|
+
event: { ...update, content: content.event }
|
|
41130
|
+
};
|
|
41131
|
+
}
|
|
41036
41132
|
case "tool_call":
|
|
41037
41133
|
case "tool_call_update":
|
|
41038
|
-
return
|
|
41039
|
-
|
|
41040
|
-
|
|
41041
|
-
|
|
41042
|
-
|
|
41043
|
-
|
|
41044
|
-
|
|
41045
|
-
|
|
41046
|
-
|
|
41047
|
-
summary:
|
|
41048
|
-
|
|
41049
|
-
)
|
|
41134
|
+
return await this.#toolUpdate(sessionId, update, signal);
|
|
41135
|
+
case "compaction_update": {
|
|
41136
|
+
if (update.summary === void 0 || update.summary === null) {
|
|
41137
|
+
return { agent: update, event: update };
|
|
41138
|
+
}
|
|
41139
|
+
const content = await Promise.all(
|
|
41140
|
+
update.summary.map(async (item) => await this.#content(sessionId, item, signal))
|
|
41141
|
+
);
|
|
41142
|
+
return {
|
|
41143
|
+
agent: { ...update, summary: content.map((item) => item.agent) },
|
|
41144
|
+
event: { ...update, summary: content.map((item) => item.event) }
|
|
41050
41145
|
};
|
|
41146
|
+
}
|
|
41051
41147
|
case "plan":
|
|
41052
41148
|
case "plan_update":
|
|
41053
41149
|
case "plan_removed":
|
|
@@ -41056,16 +41152,17 @@ var AcpContentExternalizer = class {
|
|
|
41056
41152
|
case "config_option_update":
|
|
41057
41153
|
case "session_info_update":
|
|
41058
41154
|
case "usage_update":
|
|
41059
|
-
return update;
|
|
41155
|
+
return { agent: update, event: update };
|
|
41060
41156
|
}
|
|
41061
41157
|
};
|
|
41062
41158
|
};
|
|
41063
41159
|
|
|
41064
41160
|
// src/external-content/local-external-content-store.ts
|
|
41065
41161
|
import { createHash as createHash3, randomUUID as randomUUID2 } from "node:crypto";
|
|
41066
|
-
import { lstat, mkdir as mkdir6,
|
|
41162
|
+
import { lstat, mkdir as mkdir6, readdir as readdir3, realpath as realpath8, rename as rename4, rm as rm3, stat as stat7, utimes, writeFile as writeFile4 } from "node:fs/promises";
|
|
41067
41163
|
import { dirname as dirname5, join as join16 } from "node:path";
|
|
41068
41164
|
var contentRequest = /^mobius-content:(image|audio|resource):([a-f0-9]{64})$/u;
|
|
41165
|
+
var CONTENT_LIFETIME_MILLISECONDS = 24 * 60 * 60 * 1e3;
|
|
41069
41166
|
var metadataSchema2 = external_exports.strictObject({
|
|
41070
41167
|
kind: external_exports.enum(["image", "audio", "resource"]),
|
|
41071
41168
|
mediaType: external_exports.string().min(1).max(2048).regex(/^[\u0020-\u007e]+$/u),
|
|
@@ -41081,9 +41178,6 @@ var UnretainedExternalContentStore = class {
|
|
|
41081
41178
|
return Promise.resolve(null);
|
|
41082
41179
|
};
|
|
41083
41180
|
};
|
|
41084
|
-
function sessionScope(sessionId) {
|
|
41085
|
-
return createHash3("sha256").update(sessionId).digest("hex");
|
|
41086
|
-
}
|
|
41087
41181
|
async function atomicWrite(path3, bytes, signal) {
|
|
41088
41182
|
const temporary = `${path3}.${randomUUID2()}.tmp`;
|
|
41089
41183
|
try {
|
|
@@ -41096,55 +41190,134 @@ async function atomicWrite(path3, bytes, signal) {
|
|
|
41096
41190
|
}
|
|
41097
41191
|
var LocalExternalContentStore = class {
|
|
41098
41192
|
#root;
|
|
41193
|
+
#entries = /* @__PURE__ */ new Map();
|
|
41194
|
+
#operations = /* @__PURE__ */ new Set();
|
|
41195
|
+
#lifetime = new AbortController();
|
|
41196
|
+
#expirationTimer;
|
|
41197
|
+
#cleanup = Promise.resolve();
|
|
41099
41198
|
constructor(stateDirectory) {
|
|
41100
|
-
this.#root = join16(stateDirectory, "tmp", "session-content");
|
|
41101
|
-
|
|
41102
|
-
|
|
41103
|
-
|
|
41199
|
+
this.#root = join16(stateDirectory, "tmp", "session-content", randomUUID2());
|
|
41200
|
+
this.#expirationTimer = setInterval(() => {
|
|
41201
|
+
void this.#expire().catch(() => void 0);
|
|
41202
|
+
}, 6e4);
|
|
41203
|
+
this.#expirationTimer.unref();
|
|
41204
|
+
}
|
|
41205
|
+
#expire = () => {
|
|
41206
|
+
this.#cleanup = this.#cleanup.catch(() => void 0).then(async () => {
|
|
41207
|
+
await mkdir6(this.#root, { mode: 448, recursive: true });
|
|
41208
|
+
const now = /* @__PURE__ */ new Date();
|
|
41209
|
+
await utimes(this.#root, now, now);
|
|
41210
|
+
for (const directory of await readdir3(dirname5(this.#root), { withFileTypes: true })) {
|
|
41211
|
+
if (!directory.isDirectory() || !/^[a-f0-9-]{36}$/u.test(directory.name)) {
|
|
41212
|
+
continue;
|
|
41213
|
+
}
|
|
41214
|
+
const path3 = join16(dirname5(this.#root), directory.name);
|
|
41215
|
+
if (path3 === this.#root) {
|
|
41216
|
+
continue;
|
|
41217
|
+
}
|
|
41218
|
+
const modified = await stat7(path3).then(
|
|
41219
|
+
(entry) => entry.mtimeMs,
|
|
41220
|
+
() => Date.now()
|
|
41221
|
+
);
|
|
41222
|
+
if (modified + CONTENT_LIFETIME_MILLISECONDS <= Date.now()) {
|
|
41223
|
+
await rm3(path3, { force: true, recursive: true });
|
|
41224
|
+
}
|
|
41225
|
+
}
|
|
41226
|
+
for (const [request, entry] of this.#entries) {
|
|
41227
|
+
if (entry.expiresAt > Date.now()) {
|
|
41228
|
+
continue;
|
|
41229
|
+
}
|
|
41230
|
+
await rm3(entry.path, { force: true });
|
|
41231
|
+
this.#entries.delete(request);
|
|
41232
|
+
}
|
|
41233
|
+
});
|
|
41234
|
+
return this.#cleanup;
|
|
41235
|
+
};
|
|
41236
|
+
#track = async (operation) => {
|
|
41237
|
+
this.#lifetime.signal.throwIfAborted();
|
|
41238
|
+
const pending = operation();
|
|
41239
|
+
this.#operations.add(pending);
|
|
41240
|
+
try {
|
|
41241
|
+
return await pending;
|
|
41242
|
+
} finally {
|
|
41243
|
+
this.#operations.delete(pending);
|
|
41244
|
+
}
|
|
41245
|
+
};
|
|
41246
|
+
put = (input2) => this.#track(() => this.#put(input2));
|
|
41247
|
+
#put = async ({ bytes, kind, mediaType, name, sessionId, signal }) => {
|
|
41248
|
+
const active = AbortSignal.any([signal, this.#lifetime.signal]);
|
|
41249
|
+
active.throwIfAborted();
|
|
41250
|
+
const metadata = metadataSchema2.parse({ kind, mediaType, name });
|
|
41104
41251
|
const key = createHash3("sha256").update(bytes).digest("hex");
|
|
41105
|
-
const
|
|
41252
|
+
const request = `mobius-content:${kind}:${key}`;
|
|
41253
|
+
const existing = this.#entries.get(request);
|
|
41254
|
+
if (existing !== void 0 && existing.expiresAt > Date.now()) {
|
|
41255
|
+
this.#entries.set(request, {
|
|
41256
|
+
...existing,
|
|
41257
|
+
expiresAt: Date.now() + CONTENT_LIFETIME_MILLISECONDS,
|
|
41258
|
+
sessions: /* @__PURE__ */ new Set([...existing.sessions, sessionId])
|
|
41259
|
+
});
|
|
41260
|
+
return { byteLength: existing.byteLength, key };
|
|
41261
|
+
}
|
|
41262
|
+
await this.#expire();
|
|
41263
|
+
active.throwIfAborted();
|
|
41264
|
+
const directory = join16(this.#root, kind);
|
|
41106
41265
|
await mkdir6(directory, { mode: 448, recursive: true });
|
|
41107
|
-
|
|
41266
|
+
active.throwIfAborted();
|
|
41108
41267
|
const path3 = join16(directory, key);
|
|
41109
|
-
|
|
41110
|
-
await
|
|
41111
|
-
|
|
41112
|
-
|
|
41113
|
-
|
|
41114
|
-
|
|
41268
|
+
const write = atomicWrite(path3, bytes, active);
|
|
41269
|
+
await write;
|
|
41270
|
+
active.throwIfAborted();
|
|
41271
|
+
const retained = this.#entries.get(request);
|
|
41272
|
+
this.#entries.set(request, {
|
|
41273
|
+
byteLength: bytes.byteLength,
|
|
41274
|
+
expiresAt: Date.now() + CONTENT_LIFETIME_MILLISECONDS,
|
|
41275
|
+
mediaType: metadata.mediaType,
|
|
41276
|
+
name: metadata.name,
|
|
41277
|
+
path: path3,
|
|
41278
|
+
sessions: /* @__PURE__ */ new Set([...retained?.sessions ?? [], sessionId])
|
|
41279
|
+
});
|
|
41115
41280
|
return { byteLength: bytes.byteLength, key };
|
|
41116
41281
|
};
|
|
41117
|
-
resolve =
|
|
41118
|
-
|
|
41119
|
-
|
|
41282
|
+
resolve = (sessionId, request, signal) => this.#track(() => this.#resolve(sessionId, request, AbortSignal.any([signal, this.#lifetime.signal])));
|
|
41283
|
+
#resolve = async (sessionId, request, signal) => {
|
|
41284
|
+
signal.throwIfAborted();
|
|
41285
|
+
this.#lifetime.signal.throwIfAborted();
|
|
41286
|
+
if (!contentRequest.test(request)) {
|
|
41120
41287
|
return null;
|
|
41121
41288
|
}
|
|
41122
|
-
const
|
|
41123
|
-
|
|
41124
|
-
|
|
41289
|
+
const entry = this.#entries.get(request);
|
|
41290
|
+
if (entry === void 0 || !entry.sessions.has(sessionId)) {
|
|
41291
|
+
return null;
|
|
41292
|
+
}
|
|
41293
|
+
if (entry.expiresAt <= Date.now()) {
|
|
41294
|
+
await this.#expire();
|
|
41295
|
+
signal.throwIfAborted();
|
|
41125
41296
|
return null;
|
|
41126
41297
|
}
|
|
41127
|
-
const directory = join16(this.#root, sessionScope(sessionId), kind);
|
|
41128
|
-
const path3 = join16(directory, key);
|
|
41129
41298
|
try {
|
|
41130
|
-
const [resolvedDirectory, resolvedPath, file2
|
|
41131
|
-
realpath8(
|
|
41132
|
-
realpath8(
|
|
41133
|
-
lstat(
|
|
41134
|
-
readFile3(`${path3}.json`, "utf8").then((value) => metadataSchema2.parse(JSON.parse(value)))
|
|
41299
|
+
const [resolvedDirectory, resolvedPath, file2] = await Promise.all([
|
|
41300
|
+
realpath8(dirname5(entry.path)),
|
|
41301
|
+
realpath8(entry.path),
|
|
41302
|
+
lstat(entry.path)
|
|
41135
41303
|
]);
|
|
41136
41304
|
signal.throwIfAborted();
|
|
41137
|
-
if (!file2.isFile() || dirname5(resolvedPath) !== resolvedDirectory
|
|
41305
|
+
if (!file2.isFile() || file2.isSymbolicLink() || dirname5(resolvedPath) !== resolvedDirectory) {
|
|
41138
41306
|
return null;
|
|
41139
41307
|
}
|
|
41140
|
-
|
|
41141
|
-
signal.throwIfAborted();
|
|
41142
|
-
return { mediaType: metadata.mediaType, name: metadata.name, path: resolvedPath };
|
|
41308
|
+
return { mediaType: entry.mediaType, name: entry.name, path: resolvedPath };
|
|
41143
41309
|
} catch {
|
|
41144
41310
|
signal.throwIfAborted();
|
|
41145
41311
|
return null;
|
|
41146
41312
|
}
|
|
41147
41313
|
};
|
|
41314
|
+
[Symbol.asyncDispose] = async () => {
|
|
41315
|
+
clearInterval(this.#expirationTimer);
|
|
41316
|
+
this.#lifetime.abort();
|
|
41317
|
+
await Promise.allSettled([...this.#operations, this.#cleanup]);
|
|
41318
|
+
this.#entries.clear();
|
|
41319
|
+
await rm3(this.#root, { force: true, recursive: true });
|
|
41320
|
+
};
|
|
41148
41321
|
};
|
|
41149
41322
|
|
|
41150
41323
|
// src/native-sessions/chat-agent.ts
|
|
@@ -42066,7 +42239,7 @@ var AgentCatalogPublishError = class extends Error {
|
|
|
42066
42239
|
this.name = "AgentCatalogPublishError";
|
|
42067
42240
|
}
|
|
42068
42241
|
};
|
|
42069
|
-
function
|
|
42242
|
+
function isRecord11(value) {
|
|
42070
42243
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
42071
42244
|
}
|
|
42072
42245
|
function isSafeRelayErrorMessage(value) {
|
|
@@ -42079,7 +42252,7 @@ async function rejectedCatalogError(response) {
|
|
|
42079
42252
|
} catch {
|
|
42080
42253
|
return new AgentCatalogPublishError("The Relay rejected the Agent catalog update");
|
|
42081
42254
|
}
|
|
42082
|
-
if (!
|
|
42255
|
+
if (!isRecord11(value) || !isRecord11(value["error"])) {
|
|
42083
42256
|
return new AgentCatalogPublishError("The Relay rejected the Agent catalog update");
|
|
42084
42257
|
}
|
|
42085
42258
|
const code = value["error"]["code"];
|
|
@@ -42610,7 +42783,7 @@ var FixedInstallationExecutor = class {
|
|
|
42610
42783
|
};
|
|
42611
42784
|
|
|
42612
42785
|
// src/authorization/workspace-directory.ts
|
|
42613
|
-
import { readdir as
|
|
42786
|
+
import { readdir as readdir4, realpath as realpath9, stat as stat8 } from "node:fs/promises";
|
|
42614
42787
|
import { homedir as homedir2 } from "node:os";
|
|
42615
42788
|
import { basename as basename4, dirname as dirname6, isAbsolute as isAbsolute9, join as join17, normalize as normalize3, relative as relative4 } from "node:path";
|
|
42616
42789
|
|
|
@@ -42730,7 +42903,7 @@ var WorkspaceDirectoryService = class {
|
|
|
42730
42903
|
list = async (bindingId, id, signal) => {
|
|
42731
42904
|
const target = await this.resolve(bindingId, id, signal);
|
|
42732
42905
|
try {
|
|
42733
|
-
const children = await
|
|
42906
|
+
const children = await readdir4(target, { withFileTypes: true });
|
|
42734
42907
|
signal.throwIfAborted();
|
|
42735
42908
|
const entries = [];
|
|
42736
42909
|
for (const child2 of children) {
|
|
@@ -48429,7 +48602,7 @@ async function runDaemon(config2, audit, signal, timer = systemDaemonTimer, opti
|
|
|
48429
48602
|
const sessionStore = new SqliteAcpSessionStore(
|
|
48430
48603
|
join19(stateDirectory, "sessions", `${createHash8("sha256").update(config2.channelId).digest("hex")}.sqlite`)
|
|
48431
48604
|
);
|
|
48432
|
-
|
|
48605
|
+
await using externalContent = new LocalExternalContentStore(stateDirectory);
|
|
48433
48606
|
const operations = new DaemonOperationState();
|
|
48434
48607
|
const publisher = new DaemonSessionEventPublisher(sessionStore);
|
|
48435
48608
|
const eventLogV2 = new DaemonSessionEventLogV2(publisher, sessionStore);
|
|
@@ -48697,7 +48870,7 @@ async function acquireManagerLock(stateDirectory) {
|
|
|
48697
48870
|
if (!isNodeError2(cause, "EEXIST")) {
|
|
48698
48871
|
throw cause;
|
|
48699
48872
|
}
|
|
48700
|
-
const encoded = await
|
|
48873
|
+
const encoded = await readFile3(path3, "utf8").catch(() => "");
|
|
48701
48874
|
const pid = Number(encoded.trim());
|
|
48702
48875
|
if (Number.isSafeInteger(pid) && pid > 1) {
|
|
48703
48876
|
try {
|
|
@@ -48714,7 +48887,7 @@ async function acquireManagerLock(stateDirectory) {
|
|
|
48714
48887
|
}
|
|
48715
48888
|
return null;
|
|
48716
48889
|
}
|
|
48717
|
-
function
|
|
48890
|
+
function isRecord12(value) {
|
|
48718
48891
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
48719
48892
|
}
|
|
48720
48893
|
function controlSocketPath(stateDirectory) {
|
|
@@ -48727,7 +48900,7 @@ function controlTokenPath(stateDirectory) {
|
|
|
48727
48900
|
async function readOrCreateControlToken(stateDirectory) {
|
|
48728
48901
|
const path3 = controlTokenPath(stateDirectory);
|
|
48729
48902
|
try {
|
|
48730
|
-
return (await
|
|
48903
|
+
return (await readFile3(path3, "utf8")).trim();
|
|
48731
48904
|
} catch (cause) {
|
|
48732
48905
|
if (!isNodeError2(cause, "ENOENT")) {
|
|
48733
48906
|
throw cause;
|
|
@@ -48742,14 +48915,14 @@ async function readOrCreateControlToken(stateDirectory) {
|
|
|
48742
48915
|
if (!isNodeError2(cause, "EEXIST")) {
|
|
48743
48916
|
throw cause;
|
|
48744
48917
|
}
|
|
48745
|
-
return (await
|
|
48918
|
+
return (await readFile3(path3, "utf8")).trim();
|
|
48746
48919
|
}
|
|
48747
48920
|
}
|
|
48748
48921
|
function isNodeError2(error62, code) {
|
|
48749
48922
|
return typeof error62 === "object" && error62 !== null && "code" in error62 && error62.code === code;
|
|
48750
48923
|
}
|
|
48751
48924
|
function decodeCommand(value, expectedToken) {
|
|
48752
|
-
if (!
|
|
48925
|
+
if (!isRecord12(value) || value["token"] !== expectedToken || typeof value["kind"] !== "string") {
|
|
48753
48926
|
throw new Error("The manager request is invalid");
|
|
48754
48927
|
}
|
|
48755
48928
|
if (value["kind"] === "list" || value["kind"] === "stop") {
|
|
@@ -48768,7 +48941,7 @@ function decodeCommand(value, expectedToken) {
|
|
|
48768
48941
|
throw new Error("The manager command is unsupported");
|
|
48769
48942
|
}
|
|
48770
48943
|
function decodeResponse(value) {
|
|
48771
|
-
if (!
|
|
48944
|
+
if (!isRecord12(value) || typeof value["kind"] !== "string") {
|
|
48772
48945
|
throw new Error("The Mobius manager returned an invalid response");
|
|
48773
48946
|
}
|
|
48774
48947
|
if (value["kind"] === "error" && typeof value["code"] === "string" && typeof value["message"] === "string") {
|
|
@@ -48795,7 +48968,7 @@ function decodeResponse(value) {
|
|
|
48795
48968
|
throw new Error("The Mobius manager returned an invalid response");
|
|
48796
48969
|
}
|
|
48797
48970
|
function isManagedRuntimeSummary(value) {
|
|
48798
|
-
return
|
|
48971
|
+
return isRecord12(value) && typeof value["appId"] === "string" && typeof value["connectionId"] === "string" && typeof value["runtimeId"] === "string" && typeof value["workspace"] === "string" && ["starting", "online", "reconnecting", "failed", "stopped"].includes(String(value["status"]));
|
|
48799
48972
|
}
|
|
48800
48973
|
function summary(connection, status) {
|
|
48801
48974
|
return {
|
|
@@ -49054,7 +49227,7 @@ async function waitForManagerExit(stateDirectory, signal) {
|
|
|
49054
49227
|
const deadline = AbortSignal.any([signal, AbortSignal.timeout(1e4)]);
|
|
49055
49228
|
while (!deadline.aborted) {
|
|
49056
49229
|
try {
|
|
49057
|
-
await
|
|
49230
|
+
await readFile3(join20(stateDirectory, "manager.lock"), "utf8");
|
|
49058
49231
|
} catch (cause) {
|
|
49059
49232
|
if (isNodeError2(cause, "ENOENT")) {
|
|
49060
49233
|
return;
|