@moxt-ai/mobius 0.0.27 → 0.0.28
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/activity.d.ts +1 -0
- package/dist/acp/activity.d.ts.map +1 -1
- package/dist/acp/activity.js +14 -1
- package/dist/acp/activity.js.map +1 -1
- package/dist/acp/session-history.d.ts.map +1 -1
- package/dist/acp/session-history.js +10 -16
- package/dist/acp/session-history.js.map +1 -1
- package/dist/acp/session-manager.d.ts +7 -0
- package/dist/acp/session-manager.d.ts.map +1 -1
- package/dist/acp/session-manager.js +65 -11
- package/dist/acp/session-manager.js.map +1 -1
- package/dist/artifacts/runtime-artifact-uploader.d.ts +12 -0
- package/dist/artifacts/runtime-artifact-uploader.d.ts.map +1 -0
- package/dist/artifacts/runtime-artifact-uploader.js +157 -0
- package/dist/artifacts/runtime-artifact-uploader.js.map +1 -0
- package/dist/authorization/local-raster.d.ts +10 -0
- package/dist/authorization/local-raster.d.ts.map +1 -0
- package/dist/authorization/local-raster.js +134 -0
- package/dist/authorization/local-raster.js.map +1 -0
- package/dist/cli.js +826 -113
- package/dist/cli.js.map +4 -4
- package/dist/index.js +849 -137
- package/dist/index.js.map +4 -4
- package/dist/native-sessions/codex-history.d.ts.map +1 -1
- package/dist/native-sessions/codex-history.js +11 -11
- package/dist/native-sessions/codex-history.js.map +1 -1
- package/dist/native-sessions/history-images.d.ts +3 -0
- package/dist/native-sessions/history-images.d.ts.map +1 -0
- package/dist/native-sessions/history-images.js +74 -0
- package/dist/native-sessions/history-images.js.map +1 -0
- package/dist/run-daemon.d.ts.map +1 -1
- package/dist/run-daemon.js +30 -7
- package/dist/run-daemon.js.map +1 -1
- package/dist/runtime.js +845 -133
- package/dist/runtime.js.map +4 -4
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -16087,8 +16087,8 @@ function rewriteKeyNames(ctx) {
|
|
|
16087
16087
|
bySchema.set(entry.schema, entry);
|
|
16088
16088
|
}
|
|
16089
16089
|
const rewrites = /* @__PURE__ */ new Map();
|
|
16090
|
-
for (const
|
|
16091
|
-
const seen = ctx.seen.get(
|
|
16090
|
+
for (const record3 of pendingRecords.get(ctx) ?? []) {
|
|
16091
|
+
const seen = ctx.seen.get(record3);
|
|
16092
16092
|
const names = (seen?.def ?? seen?.schema)?.propertyNames;
|
|
16093
16093
|
if (!names || names === true || rewrites.has(names))
|
|
16094
16094
|
continue;
|
|
@@ -19045,6 +19045,7 @@ var elicitationFieldSchema = external_exports.strictObject({
|
|
|
19045
19045
|
type: external_exports.enum(["boolean", "integer", "multiselect", "number", "select", "string"])
|
|
19046
19046
|
}).readonly();
|
|
19047
19047
|
var displayContentSchema = external_exports.strictObject({
|
|
19048
|
+
artifactId: external_exports.string().max(128).default(""),
|
|
19048
19049
|
data: external_exports.string().max(4e6),
|
|
19049
19050
|
mimeType: external_exports.string().max(255),
|
|
19050
19051
|
name: external_exports.string().max(500),
|
|
@@ -19057,6 +19058,7 @@ var displayContentSchema = external_exports.strictObject({
|
|
|
19057
19058
|
uri: external_exports.string().max(4096)
|
|
19058
19059
|
}).readonly();
|
|
19059
19060
|
var recordedDisplayContentSchema = external_exports.strictObject({
|
|
19061
|
+
artifactId: external_exports.string().max(128).default(""),
|
|
19060
19062
|
data: external_exports.string().max(4e6),
|
|
19061
19063
|
mimeType: external_exports.string().max(255),
|
|
19062
19064
|
name: external_exports.string().max(500),
|
|
@@ -21201,6 +21203,212 @@ import {
|
|
|
21201
21203
|
RequestError
|
|
21202
21204
|
} from "@agentclientprotocol/sdk";
|
|
21203
21205
|
|
|
21206
|
+
// src/authorization/local-raster.ts
|
|
21207
|
+
import { readFile, realpath as realpath2, stat as stat2 } from "node:fs/promises";
|
|
21208
|
+
import { basename, isAbsolute, normalize, relative, sep } from "node:path";
|
|
21209
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
21210
|
+
var MAX_LOCAL_RASTER_BYTES = 3e6;
|
|
21211
|
+
var PNG_SIGNATURE = Uint8Array.of(137, 80, 78, 71);
|
|
21212
|
+
var JPEG_SIGNATURE = Uint8Array.of(255, 216, 255);
|
|
21213
|
+
var GIF87_SIGNATURE = new TextEncoder().encode("GIF87a");
|
|
21214
|
+
var GIF89_SIGNATURE = new TextEncoder().encode("GIF89a");
|
|
21215
|
+
var RIFF_SIGNATURE = new TextEncoder().encode("RIFF");
|
|
21216
|
+
var WEBP_SIGNATURE = new TextEncoder().encode("WEBP");
|
|
21217
|
+
var LocalRasterImage = class {
|
|
21218
|
+
bytes;
|
|
21219
|
+
mimeType;
|
|
21220
|
+
name;
|
|
21221
|
+
constructor(name, mimeType, bytes) {
|
|
21222
|
+
this.bytes = bytes;
|
|
21223
|
+
this.mimeType = mimeType;
|
|
21224
|
+
this.name = name;
|
|
21225
|
+
}
|
|
21226
|
+
base64 = () => Buffer.from(this.bytes).toString("base64");
|
|
21227
|
+
};
|
|
21228
|
+
function startsWith(bytes, signature, offset = 0) {
|
|
21229
|
+
if (bytes.byteLength < offset + signature.byteLength) {
|
|
21230
|
+
return false;
|
|
21231
|
+
}
|
|
21232
|
+
return signature.every((value, index) => bytes[offset + index] === value);
|
|
21233
|
+
}
|
|
21234
|
+
function sniffRasterMime(bytes) {
|
|
21235
|
+
if (startsWith(bytes, PNG_SIGNATURE)) {
|
|
21236
|
+
return "image/png";
|
|
21237
|
+
}
|
|
21238
|
+
if (startsWith(bytes, JPEG_SIGNATURE)) {
|
|
21239
|
+
return "image/jpeg";
|
|
21240
|
+
}
|
|
21241
|
+
if (startsWith(bytes, GIF87_SIGNATURE) || startsWith(bytes, GIF89_SIGNATURE)) {
|
|
21242
|
+
return "image/gif";
|
|
21243
|
+
}
|
|
21244
|
+
if (startsWith(bytes, RIFF_SIGNATURE) && startsWith(bytes, WEBP_SIGNATURE, 8)) {
|
|
21245
|
+
return "image/webp";
|
|
21246
|
+
}
|
|
21247
|
+
return null;
|
|
21248
|
+
}
|
|
21249
|
+
function isInsideRoot(root, target) {
|
|
21250
|
+
const relation = relative(root, target);
|
|
21251
|
+
return relation !== ".." && !relation.startsWith(`..${sep}`) && !isAbsolute(relation);
|
|
21252
|
+
}
|
|
21253
|
+
async function resolveCanonicalPath(requested, signal) {
|
|
21254
|
+
signal.throwIfAborted();
|
|
21255
|
+
if (!isAbsolute(requested) || requested.includes("\0") || normalize(requested) !== requested) {
|
|
21256
|
+
return null;
|
|
21257
|
+
}
|
|
21258
|
+
try {
|
|
21259
|
+
const target = await realpath2(requested);
|
|
21260
|
+
signal.throwIfAborted();
|
|
21261
|
+
if (!isAbsolute(target) || normalize(target) !== target) {
|
|
21262
|
+
return null;
|
|
21263
|
+
}
|
|
21264
|
+
return target;
|
|
21265
|
+
} catch (cause) {
|
|
21266
|
+
signal.throwIfAborted();
|
|
21267
|
+
if (cause instanceof Error && cause.name === "AbortError") {
|
|
21268
|
+
throw cause;
|
|
21269
|
+
}
|
|
21270
|
+
return null;
|
|
21271
|
+
}
|
|
21272
|
+
}
|
|
21273
|
+
function parseLocalImageUri(uri) {
|
|
21274
|
+
const trimmed = uri.trim();
|
|
21275
|
+
if (trimmed.length === 0 || trimmed.length > 2048 || trimmed.includes("\0")) {
|
|
21276
|
+
return null;
|
|
21277
|
+
}
|
|
21278
|
+
if (trimmed.startsWith("data:")) {
|
|
21279
|
+
return null;
|
|
21280
|
+
}
|
|
21281
|
+
if (trimmed.startsWith("file:")) {
|
|
21282
|
+
try {
|
|
21283
|
+
const url2 = new URL(trimmed);
|
|
21284
|
+
if (url2.protocol !== "file:" || url2.host.length > 0) {
|
|
21285
|
+
return null;
|
|
21286
|
+
}
|
|
21287
|
+
return fileURLToPath2(url2);
|
|
21288
|
+
} catch {
|
|
21289
|
+
return null;
|
|
21290
|
+
}
|
|
21291
|
+
}
|
|
21292
|
+
if (/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(trimmed)) {
|
|
21293
|
+
return null;
|
|
21294
|
+
}
|
|
21295
|
+
return trimmed;
|
|
21296
|
+
}
|
|
21297
|
+
async function readAuthorizedRaster(uri, roots, signal) {
|
|
21298
|
+
signal.throwIfAborted();
|
|
21299
|
+
const requested = parseLocalImageUri(uri);
|
|
21300
|
+
if (requested === null) {
|
|
21301
|
+
return null;
|
|
21302
|
+
}
|
|
21303
|
+
const target = await resolveCanonicalPath(requested, signal);
|
|
21304
|
+
if (target === null) {
|
|
21305
|
+
return null;
|
|
21306
|
+
}
|
|
21307
|
+
const targetMetadata = await stat2(target);
|
|
21308
|
+
signal.throwIfAborted();
|
|
21309
|
+
if (!targetMetadata.isFile() || targetMetadata.size < 1 || targetMetadata.size > MAX_LOCAL_RASTER_BYTES) {
|
|
21310
|
+
return null;
|
|
21311
|
+
}
|
|
21312
|
+
const authorizedRoots = [];
|
|
21313
|
+
for (const root of roots) {
|
|
21314
|
+
const directory = await resolveCanonicalPath(root, signal);
|
|
21315
|
+
if (directory === null) {
|
|
21316
|
+
continue;
|
|
21317
|
+
}
|
|
21318
|
+
const metadata = await stat2(directory);
|
|
21319
|
+
signal.throwIfAborted();
|
|
21320
|
+
if (metadata.isDirectory()) {
|
|
21321
|
+
authorizedRoots.push(directory);
|
|
21322
|
+
}
|
|
21323
|
+
}
|
|
21324
|
+
if (!authorizedRoots.some((root) => isInsideRoot(root, target))) {
|
|
21325
|
+
return null;
|
|
21326
|
+
}
|
|
21327
|
+
const bytes = new Uint8Array(await readFile(target));
|
|
21328
|
+
signal.throwIfAborted();
|
|
21329
|
+
if (bytes.byteLength < 1 || bytes.byteLength > MAX_LOCAL_RASTER_BYTES) {
|
|
21330
|
+
return null;
|
|
21331
|
+
}
|
|
21332
|
+
const mimeType = sniffRasterMime(bytes);
|
|
21333
|
+
if (mimeType === null) {
|
|
21334
|
+
return null;
|
|
21335
|
+
}
|
|
21336
|
+
return new LocalRasterImage(basename(target) || "Image", mimeType, bytes);
|
|
21337
|
+
}
|
|
21338
|
+
|
|
21339
|
+
// src/native-sessions/history-images.ts
|
|
21340
|
+
var IMAGE_MARKER = /\[@image\]\(([^)\r\n]*)(?:\)|$)/g;
|
|
21341
|
+
async function embedLocalHistoryImages(history, roots, signal) {
|
|
21342
|
+
if (history.status !== "available") {
|
|
21343
|
+
return history;
|
|
21344
|
+
}
|
|
21345
|
+
const messages = [];
|
|
21346
|
+
let imageCharacters = 0;
|
|
21347
|
+
for (const message of history.messages) {
|
|
21348
|
+
signal.throwIfAborted();
|
|
21349
|
+
const resolved = await resolveMessageImages(message, roots, imageCharacters, signal);
|
|
21350
|
+
imageCharacters += (resolved.images ?? []).reduce((size, image) => size + image.data.length, 0);
|
|
21351
|
+
messages.push(resolved);
|
|
21352
|
+
}
|
|
21353
|
+
return {
|
|
21354
|
+
...history,
|
|
21355
|
+
messages
|
|
21356
|
+
};
|
|
21357
|
+
}
|
|
21358
|
+
async function resolveMessageImages(message, roots, usedCharacters, signal) {
|
|
21359
|
+
const images = [...message.images ?? []];
|
|
21360
|
+
let imageCharacters = images.reduce((size, image) => size + image.data.length, 0);
|
|
21361
|
+
const text = await replaceImageMarkers(message.text, async (uri) => {
|
|
21362
|
+
if (images.length >= 8 || usedCharacters + imageCharacters >= SESSION_HISTORY_IMAGE_CHARACTER_LIMIT) {
|
|
21363
|
+
return "[Image unavailable]";
|
|
21364
|
+
}
|
|
21365
|
+
const embedded = parseNativeHistoryText(`[@image](${uri})`).images[0];
|
|
21366
|
+
if (embedded !== void 0) {
|
|
21367
|
+
if (usedCharacters + imageCharacters + embedded.data.length > SESSION_HISTORY_IMAGE_CHARACTER_LIMIT) {
|
|
21368
|
+
return "[Image unavailable]";
|
|
21369
|
+
}
|
|
21370
|
+
images.push(embedded);
|
|
21371
|
+
imageCharacters += embedded.data.length;
|
|
21372
|
+
return "";
|
|
21373
|
+
}
|
|
21374
|
+
const local = await readAuthorizedRaster(uri, roots, signal);
|
|
21375
|
+
if (local === null) {
|
|
21376
|
+
return "[Image unavailable]";
|
|
21377
|
+
}
|
|
21378
|
+
const data = local.base64();
|
|
21379
|
+
if (usedCharacters + imageCharacters + data.length > SESSION_HISTORY_IMAGE_CHARACTER_LIMIT) {
|
|
21380
|
+
return "[Image unavailable]";
|
|
21381
|
+
}
|
|
21382
|
+
images.push({
|
|
21383
|
+
data,
|
|
21384
|
+
mimeType: local.mimeType,
|
|
21385
|
+
name: local.name
|
|
21386
|
+
});
|
|
21387
|
+
imageCharacters += data.length;
|
|
21388
|
+
return "";
|
|
21389
|
+
});
|
|
21390
|
+
return {
|
|
21391
|
+
...message,
|
|
21392
|
+
text,
|
|
21393
|
+
...images.length > 0 ? { images } : {}
|
|
21394
|
+
};
|
|
21395
|
+
}
|
|
21396
|
+
async function replaceImageMarkers(text, replace) {
|
|
21397
|
+
const matches = [...text.matchAll(IMAGE_MARKER)];
|
|
21398
|
+
if (matches.length === 0) {
|
|
21399
|
+
return text;
|
|
21400
|
+
}
|
|
21401
|
+
let cursor = 0;
|
|
21402
|
+
let rewritten = "";
|
|
21403
|
+
for (const match of matches) {
|
|
21404
|
+
const index = match.index ?? 0;
|
|
21405
|
+
rewritten += text.slice(cursor, index);
|
|
21406
|
+
rewritten += await replace(match[1] ?? "");
|
|
21407
|
+
cursor = index + match[0].length;
|
|
21408
|
+
}
|
|
21409
|
+
return `${rewritten}${text.slice(cursor)}`;
|
|
21410
|
+
}
|
|
21411
|
+
|
|
21204
21412
|
// src/acp/activity.ts
|
|
21205
21413
|
var TRUNCATION_MARKER = "\n\u2026 output truncated by Mobius";
|
|
21206
21414
|
function isRecord4(value) {
|
|
@@ -21298,6 +21506,7 @@ function readContentOutputDetail(content) {
|
|
|
21298
21506
|
function summarizeDisplayContent(content) {
|
|
21299
21507
|
return {
|
|
21300
21508
|
...content,
|
|
21509
|
+
artifactId: truncate(content.artifactId, 128),
|
|
21301
21510
|
data: truncate(content.data, AGENT_ACTIVITY_DETAIL_LIMIT),
|
|
21302
21511
|
mimeType: truncate(content.mimeType, 255),
|
|
21303
21512
|
name: truncate(content.name, 500),
|
|
@@ -21310,7 +21519,7 @@ function summarizeDisplayContent(content) {
|
|
|
21310
21519
|
};
|
|
21311
21520
|
}
|
|
21312
21521
|
function contentFitsRecordingEnvelope(content) {
|
|
21313
|
-
return content.data.length <= AGENT_ACTIVITY_RECORDED_FIELD_LIMIT && content.mimeType.length <= 255 && content.name.length <= 500 && content.newText.length <= AGENT_ACTIVITY_RECORDED_FIELD_LIMIT && content.oldText.length <= AGENT_ACTIVITY_RECORDED_FIELD_LIMIT && content.path.length <= 2048 && content.terminalId.length <= 255 && content.text.length <= AGENT_ACTIVITY_RECORDED_FIELD_LIMIT && content.uri.length <= 4096;
|
|
21522
|
+
return content.artifactId.length <= 128 && content.data.length <= AGENT_ACTIVITY_RECORDED_FIELD_LIMIT && content.mimeType.length <= 255 && content.name.length <= 500 && content.newText.length <= AGENT_ACTIVITY_RECORDED_FIELD_LIMIT && content.oldText.length <= AGENT_ACTIVITY_RECORDED_FIELD_LIMIT && content.path.length <= 2048 && content.terminalId.length <= 255 && content.text.length <= AGENT_ACTIVITY_RECORDED_FIELD_LIMIT && content.uri.length <= 4096;
|
|
21314
21523
|
}
|
|
21315
21524
|
function encodedByteLength(value) {
|
|
21316
21525
|
return new TextEncoder().encode(JSON.stringify(value)).byteLength;
|
|
@@ -21336,6 +21545,7 @@ function recordedDetail(activity) {
|
|
|
21336
21545
|
}
|
|
21337
21546
|
function emptyDisplayContent(type) {
|
|
21338
21547
|
return {
|
|
21548
|
+
artifactId: "",
|
|
21339
21549
|
data: "",
|
|
21340
21550
|
mimeType: "",
|
|
21341
21551
|
name: "",
|
|
@@ -21348,6 +21558,16 @@ function emptyDisplayContent(type) {
|
|
|
21348
21558
|
uri: ""
|
|
21349
21559
|
};
|
|
21350
21560
|
}
|
|
21561
|
+
function imageDisplayContent(mimeType, name, data, artifactId = "", uri = "") {
|
|
21562
|
+
return {
|
|
21563
|
+
...emptyDisplayContent("image"),
|
|
21564
|
+
artifactId,
|
|
21565
|
+
data,
|
|
21566
|
+
mimeType,
|
|
21567
|
+
name,
|
|
21568
|
+
uri
|
|
21569
|
+
};
|
|
21570
|
+
}
|
|
21351
21571
|
function normalizeContentBlock(content) {
|
|
21352
21572
|
if (content.type === "text") {
|
|
21353
21573
|
return { ...emptyDisplayContent("text"), text: content.text };
|
|
@@ -22139,7 +22359,6 @@ var AcpHistoryReplay = class {
|
|
|
22139
22359
|
#messages = [];
|
|
22140
22360
|
#lastMessageId = null;
|
|
22141
22361
|
#characters = 0;
|
|
22142
|
-
#imageCharacters = 0;
|
|
22143
22362
|
#truncated = false;
|
|
22144
22363
|
record = (update) => {
|
|
22145
22364
|
if (update.sessionUpdate !== "user_message_chunk" && update.sessionUpdate !== "agent_message_chunk") {
|
|
@@ -22150,40 +22369,30 @@ var AcpHistoryReplay = class {
|
|
|
22150
22369
|
}
|
|
22151
22370
|
const role = update.sessionUpdate === "user_message_chunk" ? "user" : "assistant";
|
|
22152
22371
|
const content = update.content;
|
|
22153
|
-
const
|
|
22154
|
-
|
|
22155
|
-
);
|
|
22156
|
-
const text = parsed.text;
|
|
22157
|
-
if (text.length === 0 && parsed.images.length === 0) {
|
|
22372
|
+
const text = content.type === "text" ? content.text : content.type === "image" ? content.data.length > 0 ? `[@image](data:${content.mimeType};base64,${content.data})` : content.uri != null && content.uri.length > 0 ? `[@image](${content.uri})` : "[image attachment]" : `[${content.type} attachment]`;
|
|
22373
|
+
if (text.length === 0) {
|
|
22158
22374
|
return;
|
|
22159
22375
|
}
|
|
22160
22376
|
const previous = this.#messages.at(-1);
|
|
22161
22377
|
const id = update.messageId ?? null;
|
|
22162
22378
|
const continuation = previous?.role === role && id === this.#lastMessageId;
|
|
22163
22379
|
const combined = continuation ? `${previous.text}${text}` : text;
|
|
22164
|
-
const allImages = continuation ? [...previous.images ?? [], ...parsed.images] : parsed.images;
|
|
22165
|
-
const images = allImages.slice(0, 8);
|
|
22166
|
-
this.#truncated ||= images.length < allImages.length;
|
|
22167
22380
|
if (continuation) {
|
|
22168
22381
|
this.#messages.pop();
|
|
22169
22382
|
this.#characters -= previous.text.length;
|
|
22170
|
-
this.#imageCharacters -= (previous.images ?? []).reduce((size, image) => size + image.data.length, 0);
|
|
22171
22383
|
}
|
|
22172
22384
|
const bounded = combined.slice(-SESSION_HISTORY_CHARACTER_LIMIT);
|
|
22173
22385
|
this.#truncated ||= bounded.length < combined.length;
|
|
22174
22386
|
this.#messages.push({
|
|
22175
22387
|
role,
|
|
22176
|
-
text: bounded
|
|
22177
|
-
...images.length > 0 ? { images } : {}
|
|
22388
|
+
text: bounded
|
|
22178
22389
|
});
|
|
22179
22390
|
this.#characters += bounded.length;
|
|
22180
|
-
this.#imageCharacters += images.reduce((size, image) => size + image.data.length, 0);
|
|
22181
22391
|
this.#lastMessageId = id;
|
|
22182
|
-
while (this.#messages.length > SESSION_HISTORY_PREVIEW_MESSAGE_LIMIT || this.#characters > SESSION_HISTORY_CHARACTER_LIMIT
|
|
22392
|
+
while (this.#messages.length > SESSION_HISTORY_PREVIEW_MESSAGE_LIMIT || this.#characters > SESSION_HISTORY_CHARACTER_LIMIT) {
|
|
22183
22393
|
const removed = this.#messages.shift();
|
|
22184
22394
|
if (removed !== void 0) {
|
|
22185
22395
|
this.#characters -= removed.text.length;
|
|
22186
|
-
this.#imageCharacters -= (removed.images ?? []).reduce((size, image) => size + image.data.length, 0);
|
|
22187
22396
|
}
|
|
22188
22397
|
this.#truncated = true;
|
|
22189
22398
|
}
|
|
@@ -22406,6 +22615,10 @@ var MAX_PRE_SESSION_UPDATES = 100;
|
|
|
22406
22615
|
var MAX_PRE_SESSION_UPDATE_BYTES = 1024 * 1024;
|
|
22407
22616
|
var SESSION_CONTROL_COMMAND_ID = "session-control";
|
|
22408
22617
|
var NullAcpSessionObserver = class {
|
|
22618
|
+
importLocalImage = (_sessionId, _image, signal) => {
|
|
22619
|
+
signal.throwIfAborted();
|
|
22620
|
+
return Promise.resolve("");
|
|
22621
|
+
};
|
|
22409
22622
|
onCommands = () => Promise.resolve();
|
|
22410
22623
|
onConfig = () => Promise.resolve();
|
|
22411
22624
|
onContent = () => Promise.resolve();
|
|
@@ -23028,11 +23241,75 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
23028
23241
|
);
|
|
23029
23242
|
await this.#updateTail;
|
|
23030
23243
|
signal.throwIfAborted();
|
|
23031
|
-
return
|
|
23244
|
+
return await embedLocalHistoryImages(
|
|
23245
|
+
history.snapshot(),
|
|
23246
|
+
[this.#cwd, ...this.#additionalDirectories],
|
|
23247
|
+
signal
|
|
23248
|
+
);
|
|
23032
23249
|
} finally {
|
|
23033
23250
|
this.#replay = { kind: "idle" };
|
|
23034
23251
|
}
|
|
23035
23252
|
};
|
|
23253
|
+
imageRoots = () => [this.#cwd, ...this.#additionalDirectories];
|
|
23254
|
+
emitAgentText = async (text, messageId) => {
|
|
23255
|
+
const signal = AbortSignal.timeout(2e4);
|
|
23256
|
+
const parts = text.split(/(\[@image\]\([^)\r\n]*(?:\)|$))/);
|
|
23257
|
+
let leftover = "";
|
|
23258
|
+
for (const part of parts) {
|
|
23259
|
+
const marker = /^\[@image\]\(([^)\r\n]*)(?:\)|$)/.exec(part);
|
|
23260
|
+
if (marker === null) {
|
|
23261
|
+
leftover += part;
|
|
23262
|
+
continue;
|
|
23263
|
+
}
|
|
23264
|
+
if (leftover.length > 0) {
|
|
23265
|
+
await this.#turn.onText(leftover, messageId);
|
|
23266
|
+
leftover = "";
|
|
23267
|
+
}
|
|
23268
|
+
const raster = await readAuthorizedRaster(marker[1] ?? "", this.imageRoots(), signal);
|
|
23269
|
+
if (raster === null) {
|
|
23270
|
+
leftover += "[Image unavailable]";
|
|
23271
|
+
continue;
|
|
23272
|
+
}
|
|
23273
|
+
await this.emitRaster(raster, messageId, signal);
|
|
23274
|
+
}
|
|
23275
|
+
if (leftover.length > 0) {
|
|
23276
|
+
await this.#turn.onText(leftover, messageId);
|
|
23277
|
+
}
|
|
23278
|
+
};
|
|
23279
|
+
emitAgentContent = async (content, messageId) => {
|
|
23280
|
+
if (content.type === "image" && content.data.length === 0 && content.uri.length > 0) {
|
|
23281
|
+
const signal = AbortSignal.timeout(2e4);
|
|
23282
|
+
const raster = await readAuthorizedRaster(content.uri, this.imageRoots(), signal);
|
|
23283
|
+
if (raster !== null) {
|
|
23284
|
+
await this.emitRaster(raster, messageId, signal);
|
|
23285
|
+
return;
|
|
23286
|
+
}
|
|
23287
|
+
}
|
|
23288
|
+
await this.#getObserver().onContent({
|
|
23289
|
+
commandId: this.#turn.commandId,
|
|
23290
|
+
content,
|
|
23291
|
+
contentId: `content-${crypto.randomUUID()}`,
|
|
23292
|
+
kind: AGENT_CONTENT_KIND,
|
|
23293
|
+
messageId,
|
|
23294
|
+
sessionId: this.#mobiusSessionId
|
|
23295
|
+
});
|
|
23296
|
+
};
|
|
23297
|
+
emitRaster = async (raster, messageId, signal) => {
|
|
23298
|
+
const artifactId = await this.#getObserver().importLocalImage(this.#mobiusSessionId, raster, signal);
|
|
23299
|
+
await this.#getObserver().onContent({
|
|
23300
|
+
commandId: this.#turn.commandId,
|
|
23301
|
+
content: imageDisplayContent(
|
|
23302
|
+
raster.mimeType,
|
|
23303
|
+
raster.name,
|
|
23304
|
+
artifactId.length > 0 ? "" : raster.base64(),
|
|
23305
|
+
artifactId
|
|
23306
|
+
),
|
|
23307
|
+
contentId: `content-${crypto.randomUUID()}`,
|
|
23308
|
+
kind: AGENT_CONTENT_KIND,
|
|
23309
|
+
messageId,
|
|
23310
|
+
sessionId: this.#mobiusSessionId
|
|
23311
|
+
});
|
|
23312
|
+
};
|
|
23036
23313
|
async #initializeAgent(signal) {
|
|
23037
23314
|
const initialized = await this.race(
|
|
23038
23315
|
this.#connection.agent.request(
|
|
@@ -23735,18 +24012,14 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
23735
24012
|
);
|
|
23736
24013
|
} else {
|
|
23737
24014
|
await this.#turn.activities.finishNarrative();
|
|
23738
|
-
await this
|
|
24015
|
+
await this.emitAgentText(update.content.text, truncate3(update.messageId ?? "", 255));
|
|
23739
24016
|
}
|
|
23740
24017
|
} else {
|
|
23741
24018
|
await this.#turn.activities.finishNarrative();
|
|
23742
|
-
await this
|
|
23743
|
-
|
|
23744
|
-
|
|
23745
|
-
|
|
23746
|
-
kind: AGENT_CONTENT_KIND,
|
|
23747
|
-
messageId: truncate3(update.messageId ?? "", 255),
|
|
23748
|
-
sessionId: this.#mobiusSessionId
|
|
23749
|
-
});
|
|
24019
|
+
await this.emitAgentContent(
|
|
24020
|
+
normalizeContentBlock(update.content),
|
|
24021
|
+
truncate3(update.messageId ?? "", 255)
|
|
24022
|
+
);
|
|
23750
24023
|
}
|
|
23751
24024
|
return;
|
|
23752
24025
|
}
|
|
@@ -24612,7 +24885,7 @@ var AuditStore = class {
|
|
|
24612
24885
|
this.database.exec("ALTER TABLE audit_events ADD COLUMN details_json TEXT NOT NULL DEFAULT '{}'");
|
|
24613
24886
|
}
|
|
24614
24887
|
}
|
|
24615
|
-
record(
|
|
24888
|
+
record(record3) {
|
|
24616
24889
|
this.database.prepare(
|
|
24617
24890
|
`
|
|
24618
24891
|
INSERT INTO audit_events (
|
|
@@ -24625,10 +24898,10 @@ var AuditStore = class {
|
|
|
24625
24898
|
`
|
|
24626
24899
|
).run(
|
|
24627
24900
|
(/* @__PURE__ */ new Date()).toISOString(),
|
|
24628
|
-
|
|
24629
|
-
|
|
24630
|
-
|
|
24631
|
-
JSON.stringify(
|
|
24901
|
+
record3.event,
|
|
24902
|
+
record3.commandId,
|
|
24903
|
+
record3.sessionId,
|
|
24904
|
+
JSON.stringify(record3.details ?? {})
|
|
24632
24905
|
);
|
|
24633
24906
|
}
|
|
24634
24907
|
close() {
|
|
@@ -24650,7 +24923,7 @@ import { randomBytes } from "node:crypto";
|
|
|
24650
24923
|
|
|
24651
24924
|
// src/bots/local-bot-grant-store.ts
|
|
24652
24925
|
import { createHash, randomUUID } from "node:crypto";
|
|
24653
|
-
import { stat as
|
|
24926
|
+
import { stat as stat3 } from "node:fs/promises";
|
|
24654
24927
|
import { DatabaseSync as DatabaseSync3 } from "node:sqlite";
|
|
24655
24928
|
var LOCAL_BOT_GRANT_LIFETIME_MILLISECONDS = 90 * 24 * 60 * 60 * 1e3;
|
|
24656
24929
|
var LocalBotAuthorizationError = class extends Error {
|
|
@@ -24708,7 +24981,7 @@ function agentDigest(agent) {
|
|
|
24708
24981
|
);
|
|
24709
24982
|
}
|
|
24710
24983
|
async function workspaceDigest(path2) {
|
|
24711
|
-
const metadata = await
|
|
24984
|
+
const metadata = await stat3(path2);
|
|
24712
24985
|
if (!metadata.isDirectory()) {
|
|
24713
24986
|
throw new LocalBotAuthorizationError("binding_incompatible", "The Bot workspace is not a directory");
|
|
24714
24987
|
}
|
|
@@ -25246,7 +25519,7 @@ async function executeBotMessageCommand(arguments_, environment, signal) {
|
|
|
25246
25519
|
// src/bots/bot-outbound-ipc.ts
|
|
25247
25520
|
import { chmod, mkdir, unlink } from "node:fs/promises";
|
|
25248
25521
|
import { createServer } from "node:net";
|
|
25249
|
-
import { dirname as dirname3, isAbsolute } from "node:path";
|
|
25522
|
+
import { dirname as dirname3, isAbsolute as isAbsolute2 } from "node:path";
|
|
25250
25523
|
import { fetch } from "undici";
|
|
25251
25524
|
var BOT_IPC_REQUEST_LIMIT = 32 * 1024;
|
|
25252
25525
|
var BOT_IPC_TIMEOUT_MILLISECONDS2 = 2e4;
|
|
@@ -25344,7 +25617,7 @@ var BotOutboundIpcServer = class {
|
|
|
25344
25617
|
#usesFilesystemSocket;
|
|
25345
25618
|
constructor(socketPath, relayUrl, registry2) {
|
|
25346
25619
|
const usesFilesystemSocket = !socketPath.startsWith(WINDOWS_NAMED_PIPE_PREFIX);
|
|
25347
|
-
if (usesFilesystemSocket && !
|
|
25620
|
+
if (usesFilesystemSocket && !isAbsolute2(socketPath)) {
|
|
25348
25621
|
throw new Error("The Bot IPC path must be absolute");
|
|
25349
25622
|
}
|
|
25350
25623
|
this.#registry = registry2;
|
|
@@ -25484,9 +25757,9 @@ var BotOutboundIpcServer = class {
|
|
|
25484
25757
|
|
|
25485
25758
|
// src/pairing/pair-local-machine.ts
|
|
25486
25759
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
25487
|
-
import { mkdir as mkdir4, open as open4, realpath as
|
|
25760
|
+
import { mkdir as mkdir4, open as open4, realpath as realpath7, rename as rename3, stat as stat7, writeFile as writeFile2 } from "node:fs/promises";
|
|
25488
25761
|
import { hostname as hostname3 } from "node:os";
|
|
25489
|
-
import { basename, join as join14, resolve as resolve3 } from "node:path";
|
|
25762
|
+
import { basename as basename2, join as join14, resolve as resolve3 } from "node:path";
|
|
25490
25763
|
import { fetch as fetch3 } from "undici";
|
|
25491
25764
|
|
|
25492
25765
|
// src/agent-catalog/agent-discovery.ts
|
|
@@ -25595,8 +25868,8 @@ var LocalAgentInventory = class {
|
|
|
25595
25868
|
};
|
|
25596
25869
|
|
|
25597
25870
|
// src/agent-installation/managed-npm-package.ts
|
|
25598
|
-
import { mkdir as mkdir2, mkdtemp, open as open2, realpath as
|
|
25599
|
-
import { delimiter, dirname as dirname4, isAbsolute as
|
|
25871
|
+
import { mkdir as mkdir2, mkdtemp, open as open2, realpath as realpath3, rename, rm, stat as stat4 } from "node:fs/promises";
|
|
25872
|
+
import { delimiter, dirname as dirname4, isAbsolute as isAbsolute3, join as join4, relative as relative2, sep as sep2 } from "node:path";
|
|
25600
25873
|
var INSTALL_TIMEOUT_MILLISECONDS = 5 * 60 * 1e3;
|
|
25601
25874
|
var PACKAGE_METADATA_LIMIT_BYTES = 64 * 1024;
|
|
25602
25875
|
var PACKAGE_LOCK_LIMIT_BYTES = 8 * 1024 * 1024;
|
|
@@ -25650,8 +25923,8 @@ function packagePath(root, packageName) {
|
|
|
25650
25923
|
return join4(root, "node_modules", ...packageName.split("/"));
|
|
25651
25924
|
}
|
|
25652
25925
|
function isContainedPath(root, candidate) {
|
|
25653
|
-
const difference =
|
|
25654
|
-
return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${
|
|
25926
|
+
const difference = relative2(root, candidate);
|
|
25927
|
+
return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${sep2}`) && !isAbsolute3(difference);
|
|
25655
25928
|
}
|
|
25656
25929
|
async function readJsonRecord(path2, maximumBytes) {
|
|
25657
25930
|
try {
|
|
@@ -25752,7 +26025,7 @@ function verifyPackageLockEntry(lock, definition, verifyDependencyClosure) {
|
|
|
25752
26025
|
}
|
|
25753
26026
|
}
|
|
25754
26027
|
async function verifyRequiredDependency(rootPath, lock, definition) {
|
|
25755
|
-
const dependencyRoot = await
|
|
26028
|
+
const dependencyRoot = await realpath3(packagePath(rootPath, definition.packageName));
|
|
25756
26029
|
if (!isContainedPath(rootPath, dependencyRoot)) {
|
|
25757
26030
|
throw new ManagedNpmPackageError(
|
|
25758
26031
|
"managed_package_verification_failed",
|
|
@@ -25781,8 +26054,8 @@ async function validateManagedNpmPackage(root, definition) {
|
|
|
25781
26054
|
}
|
|
25782
26055
|
}
|
|
25783
26056
|
async function validateManagedNpmPackageContents(root, definition) {
|
|
25784
|
-
const rootPath = await
|
|
25785
|
-
const packageRoot = await
|
|
26057
|
+
const rootPath = await realpath3(root);
|
|
26058
|
+
const packageRoot = await realpath3(packagePath(rootPath, definition.packageName));
|
|
25786
26059
|
if (!isContainedPath(rootPath, packageRoot)) {
|
|
25787
26060
|
throw new ManagedNpmPackageError(
|
|
25788
26061
|
"managed_package_verification_failed",
|
|
@@ -25817,7 +26090,7 @@ var ManagedNpmPackageInstaller = class {
|
|
|
25817
26090
|
install = async (root, definition, environment, signal) => {
|
|
25818
26091
|
signal.throwIfAborted();
|
|
25819
26092
|
try {
|
|
25820
|
-
const metadata = await
|
|
26093
|
+
const metadata = await stat4(root);
|
|
25821
26094
|
if (metadata.isDirectory()) {
|
|
25822
26095
|
return await validateManagedNpmPackage(root, definition);
|
|
25823
26096
|
}
|
|
@@ -26084,8 +26357,8 @@ var CursorCliAgentSpecification = class extends DirectAcpAgentDefinition {
|
|
|
26084
26357
|
};
|
|
26085
26358
|
|
|
26086
26359
|
// src/agent-catalog/agents/deepseek-harness-agent.ts
|
|
26087
|
-
import { realpath as
|
|
26088
|
-
import { isAbsolute as
|
|
26360
|
+
import { realpath as realpath4, stat as stat5 } from "node:fs/promises";
|
|
26361
|
+
import { isAbsolute as isAbsolute4, join as join6, normalize as normalize2 } from "node:path";
|
|
26089
26362
|
|
|
26090
26363
|
// src/agent-installation/deepseek-managed-package.ts
|
|
26091
26364
|
var DeepSeekHarnessManagedPackage = class extends SriManagedNpmPackageDefinition {
|
|
@@ -26103,12 +26376,12 @@ var DEEPSEEK_HARNESS_PACKAGE = new DeepSeekHarnessManagedPackage(
|
|
|
26103
26376
|
|
|
26104
26377
|
// src/agent-catalog/agents/deepseek-harness-agent.ts
|
|
26105
26378
|
async function validateAgentHome(path2) {
|
|
26106
|
-
if (!
|
|
26379
|
+
if (!isAbsolute4(path2) || normalize2(path2) !== path2) {
|
|
26107
26380
|
throw new AgentProbeError("agent_environment_invalid", "The configured Agent home is invalid");
|
|
26108
26381
|
}
|
|
26109
26382
|
try {
|
|
26110
|
-
const resolved = await
|
|
26111
|
-
const metadata = await
|
|
26383
|
+
const resolved = await realpath4(path2);
|
|
26384
|
+
const metadata = await stat5(resolved);
|
|
26112
26385
|
if (!metadata.isDirectory() || typeof process.getuid === "function" && metadata.uid !== process.getuid()) {
|
|
26113
26386
|
throw new Error("Agent home is not a user-owned directory");
|
|
26114
26387
|
}
|
|
@@ -26190,8 +26463,8 @@ var DeepSeekHarnessAgentSpecification = class extends DirectAcpAgentDefinition {
|
|
|
26190
26463
|
};
|
|
26191
26464
|
|
|
26192
26465
|
// src/agent-catalog/agents/grok-build-agent.ts
|
|
26193
|
-
import { realpath as
|
|
26194
|
-
import { isAbsolute as
|
|
26466
|
+
import { realpath as realpath5 } from "node:fs/promises";
|
|
26467
|
+
import { isAbsolute as isAbsolute5, join as join7, relative as relative3, sep as sep3 } from "node:path";
|
|
26195
26468
|
|
|
26196
26469
|
// src/agent-installation/grok-managed-package.ts
|
|
26197
26470
|
var GROK_BUILD_MANAGED_VERSION = "1.0.21";
|
|
@@ -26253,8 +26526,8 @@ function grokBuildManagedPackage(platform, architecture) {
|
|
|
26253
26526
|
|
|
26254
26527
|
// src/agent-catalog/agents/grok-build-agent.ts
|
|
26255
26528
|
function isContainedPath2(root, candidate) {
|
|
26256
|
-
const difference =
|
|
26257
|
-
return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${
|
|
26529
|
+
const difference = relative3(root, candidate);
|
|
26530
|
+
return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${sep3}`) && !isAbsolute5(difference);
|
|
26258
26531
|
}
|
|
26259
26532
|
var GrokBuildAgentSpecification = class extends DirectAcpAgentDefinition {
|
|
26260
26533
|
adapterVersion = GROK_BUILD_MANAGED_VERSION;
|
|
@@ -26281,7 +26554,7 @@ var GrokBuildAgentSpecification = class extends DirectAcpAgentDefinition {
|
|
|
26281
26554
|
);
|
|
26282
26555
|
if (managed.path === agent.path) {
|
|
26283
26556
|
return Object.freeze({
|
|
26284
|
-
GROK_HOME: await
|
|
26557
|
+
GROK_HOME: await realpath5(
|
|
26285
26558
|
join7(stateDirectory, "agents", this.id, GROK_BUILD_MANAGED_VERSION, "home")
|
|
26286
26559
|
)
|
|
26287
26560
|
});
|
|
@@ -26293,7 +26566,7 @@ var GrokBuildAgentSpecification = class extends DirectAcpAgentDefinition {
|
|
|
26293
26566
|
};
|
|
26294
26567
|
resolveManagedAgent = async (stateDirectory, platform, signal) => {
|
|
26295
26568
|
signal.throwIfAborted();
|
|
26296
|
-
const versionRoot = await
|
|
26569
|
+
const versionRoot = await realpath5(join7(stateDirectory, "agents", this.id, GROK_BUILD_MANAGED_VERSION));
|
|
26297
26570
|
await validateManagedNpmPackage(join7(versionRoot, "package"), grokBuildManagedPackage(platform, process.arch));
|
|
26298
26571
|
const executable = await resolveExecutablePath(join7(versionRoot, "home", "bin", "grok"), platform);
|
|
26299
26572
|
signal.throwIfAborted();
|
|
@@ -26318,8 +26591,8 @@ import { join as join9 } from "node:path";
|
|
|
26318
26591
|
// src/agent-installation/managed-agent-archive.ts
|
|
26319
26592
|
import { createHash as createHash2 } from "node:crypto";
|
|
26320
26593
|
import { createReadStream } from "node:fs";
|
|
26321
|
-
import { chmod as chmod2, copyFile, mkdir as mkdir3, mkdtemp as mkdtemp2, open as open3, realpath as
|
|
26322
|
-
import { dirname as dirname5, isAbsolute as
|
|
26594
|
+
import { chmod as chmod2, copyFile, mkdir as mkdir3, mkdtemp as mkdtemp2, open as open3, realpath as realpath6, rename as rename2, rm as rm2, stat as stat6, writeFile } from "node:fs/promises";
|
|
26595
|
+
import { dirname as dirname5, isAbsolute as isAbsolute6, join as join8, relative as relative4, sep as sep4 } from "node:path";
|
|
26323
26596
|
|
|
26324
26597
|
// src/agent-installation/verified-download.ts
|
|
26325
26598
|
import { fetch as fetch2 } from "undici";
|
|
@@ -26424,8 +26697,8 @@ function isRecord10(value) {
|
|
|
26424
26697
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
26425
26698
|
}
|
|
26426
26699
|
function isContainedPath3(root, candidate) {
|
|
26427
|
-
const difference =
|
|
26428
|
-
return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${
|
|
26700
|
+
const difference = relative4(root, candidate);
|
|
26701
|
+
return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${sep4}`) && !isAbsolute6(difference);
|
|
26429
26702
|
}
|
|
26430
26703
|
async function hashFile(path2, signal) {
|
|
26431
26704
|
signal.throwIfAborted();
|
|
@@ -26499,8 +26772,8 @@ async function readManifest(path2) {
|
|
|
26499
26772
|
}
|
|
26500
26773
|
async function validateManagedAgentArchive(root, definition, signal) {
|
|
26501
26774
|
try {
|
|
26502
|
-
const rootPath = await
|
|
26503
|
-
const rootMetadata = await
|
|
26775
|
+
const rootPath = await realpath6(root);
|
|
26776
|
+
const rootMetadata = await stat6(rootPath);
|
|
26504
26777
|
if (!rootMetadata.isDirectory() || typeof process.getuid === "function" && rootMetadata.uid !== process.getuid()) {
|
|
26505
26778
|
throw new Error("Managed Agent root is not user-owned");
|
|
26506
26779
|
}
|
|
@@ -26715,7 +26988,7 @@ var PiAgentSpecification = class extends BridgedAcpAgentDefinition {
|
|
|
26715
26988
|
};
|
|
26716
26989
|
|
|
26717
26990
|
// src/agent-catalog/agents/workbuddy-agent.ts
|
|
26718
|
-
import { isAbsolute as
|
|
26991
|
+
import { isAbsolute as isAbsolute7, join as join11 } from "node:path";
|
|
26719
26992
|
|
|
26720
26993
|
// src/agent-installation/workbuddy-managed-package.ts
|
|
26721
26994
|
var WORKBUDDY_MANAGED_VERSION = "2.146.0";
|
|
@@ -26781,7 +27054,7 @@ var WorkBuddyAgentSpecification = class extends DirectAcpAgentDefinition {
|
|
|
26781
27054
|
}
|
|
26782
27055
|
const requestedPaths = [join11("/Applications", ...WORKBUDDY_MACOS_EXECUTABLE_PATH)];
|
|
26783
27056
|
const homeDirectory = context.environment["HOME"];
|
|
26784
|
-
if (homeDirectory !== void 0 &&
|
|
27057
|
+
if (homeDirectory !== void 0 && isAbsolute7(homeDirectory)) {
|
|
26785
27058
|
requestedPaths.unshift(join11(homeDirectory, "Applications", ...WORKBUDDY_MACOS_EXECUTABLE_PATH));
|
|
26786
27059
|
}
|
|
26787
27060
|
const executables = [];
|
|
@@ -26827,7 +27100,7 @@ import {
|
|
|
26827
27100
|
} from "@agentclientprotocol/sdk";
|
|
26828
27101
|
|
|
26829
27102
|
// src/agent-catalog/executable-discovery.ts
|
|
26830
|
-
import { isAbsolute as
|
|
27103
|
+
import { isAbsolute as isAbsolute8, join as join13 } from "node:path";
|
|
26831
27104
|
|
|
26832
27105
|
// src/agent-installation/managed-adapter-installer.ts
|
|
26833
27106
|
import { join as join12 } from "node:path";
|
|
@@ -26932,7 +27205,7 @@ async function resolveManagedAdapterExecutable(specification, context) {
|
|
|
26932
27205
|
async function resolveSpecificationExecutables(executableName, overrideVariable, resolveInstalled, resolveManaged, context) {
|
|
26933
27206
|
const override = context.environment[overrideVariable];
|
|
26934
27207
|
if (override !== void 0) {
|
|
26935
|
-
if (override.length === 0 || !
|
|
27208
|
+
if (override.length === 0 || !isAbsolute8(override)) {
|
|
26936
27209
|
return [];
|
|
26937
27210
|
}
|
|
26938
27211
|
const executable = await resolveExecutablePath(override, context.platform);
|
|
@@ -27460,8 +27733,8 @@ async function resolveDefaultWorkspace(path2) {
|
|
|
27460
27733
|
const requestedWorkspace = resolve3(path2);
|
|
27461
27734
|
try {
|
|
27462
27735
|
await mkdir4(requestedWorkspace, { recursive: true, mode: 448 });
|
|
27463
|
-
const defaultWorkspace = await
|
|
27464
|
-
const metadata = await
|
|
27736
|
+
const defaultWorkspace = await realpath7(requestedWorkspace);
|
|
27737
|
+
const metadata = await stat7(defaultWorkspace);
|
|
27465
27738
|
if (!metadata.isDirectory()) {
|
|
27466
27739
|
throw new PairingClientError("invalid_workspace", "The default workspace is not a directory");
|
|
27467
27740
|
}
|
|
@@ -27531,7 +27804,7 @@ async function claimPairing(options, defaultWorkspace, localAgents, installableA
|
|
|
27531
27804
|
installableAgents,
|
|
27532
27805
|
machineName: hostname3(),
|
|
27533
27806
|
pairingCode: options.code,
|
|
27534
|
-
workspaceName:
|
|
27807
|
+
workspaceName: basename2(defaultWorkspace) || "Local workspace"
|
|
27535
27808
|
}),
|
|
27536
27809
|
dispatcher: environmentProxyDispatcher,
|
|
27537
27810
|
headers: { "content-type": "application/json" },
|
|
@@ -27702,9 +27975,9 @@ async function resumeLocalMachine(arguments_, signal = new AbortController().sig
|
|
|
27702
27975
|
|
|
27703
27976
|
// src/run-daemon.ts
|
|
27704
27977
|
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
27705
|
-
import { basename as
|
|
27978
|
+
import { basename as basename5, join as join16 } from "node:path";
|
|
27706
27979
|
import { styleText } from "node:util";
|
|
27707
|
-
import { fetch as
|
|
27980
|
+
import { fetch as fetch7, WebSocket as WebSocket2 } from "undici";
|
|
27708
27981
|
|
|
27709
27982
|
// src/agent-catalog/publish-agent-catalog.ts
|
|
27710
27983
|
import { fetch as fetch4 } from "undici";
|
|
@@ -28247,10 +28520,406 @@ var FixedInstallationExecutor = class {
|
|
|
28247
28520
|
};
|
|
28248
28521
|
};
|
|
28249
28522
|
|
|
28523
|
+
// src/artifacts/runtime-artifact-uploader.ts
|
|
28524
|
+
import { createHash as createHash3 } from "node:crypto";
|
|
28525
|
+
|
|
28526
|
+
// ../mobius-sdk/src/errors.ts
|
|
28527
|
+
var MobiusError = class extends Error {
|
|
28528
|
+
code;
|
|
28529
|
+
constructor(code, message, options = {}) {
|
|
28530
|
+
super(message, options);
|
|
28531
|
+
this.code = code;
|
|
28532
|
+
this.name = "MobiusError";
|
|
28533
|
+
}
|
|
28534
|
+
};
|
|
28535
|
+
var MobiusProtocolError = class extends MobiusError {
|
|
28536
|
+
constructor(message, options = {}) {
|
|
28537
|
+
super("invalid_service_response", message, options);
|
|
28538
|
+
this.name = "MobiusProtocolError";
|
|
28539
|
+
}
|
|
28540
|
+
};
|
|
28541
|
+
var MobiusValidationError = class extends MobiusError {
|
|
28542
|
+
constructor(message, options = {}) {
|
|
28543
|
+
super("invalid_request", message, options);
|
|
28544
|
+
this.name = "MobiusValidationError";
|
|
28545
|
+
}
|
|
28546
|
+
};
|
|
28547
|
+
|
|
28548
|
+
// ../mobius-sdk/src/resources.ts
|
|
28549
|
+
var IDENTIFIER_PATTERN7 = /^[a-zA-Z0-9][a-zA-Z0-9._:-]{0,127}$/;
|
|
28550
|
+
function invalidResponse(message) {
|
|
28551
|
+
return new MobiusProtocolError(message);
|
|
28552
|
+
}
|
|
28553
|
+
function isRecord12(value) {
|
|
28554
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
28555
|
+
}
|
|
28556
|
+
function record2(value, name) {
|
|
28557
|
+
if (!isRecord12(value)) {
|
|
28558
|
+
throw invalidResponse(`The service returned an invalid ${name}`);
|
|
28559
|
+
}
|
|
28560
|
+
return value;
|
|
28561
|
+
}
|
|
28562
|
+
function stringField(value, field, maximumLength = 85e5) {
|
|
28563
|
+
const candidate = value[field];
|
|
28564
|
+
if (typeof candidate !== "string" || candidate.length > maximumLength) {
|
|
28565
|
+
throw invalidResponse(`The service returned an invalid ${field}`);
|
|
28566
|
+
}
|
|
28567
|
+
return candidate;
|
|
28568
|
+
}
|
|
28569
|
+
function identifierField(value, field) {
|
|
28570
|
+
const candidate = stringField(value, field, 128);
|
|
28571
|
+
if (!IDENTIFIER_PATTERN7.test(candidate)) {
|
|
28572
|
+
throw invalidResponse(`The service returned an invalid ${field}`);
|
|
28573
|
+
}
|
|
28574
|
+
return candidate;
|
|
28575
|
+
}
|
|
28576
|
+
function integerField(value, field) {
|
|
28577
|
+
const candidate = value[field];
|
|
28578
|
+
if (typeof candidate !== "number" || !Number.isSafeInteger(candidate) || candidate < 0) {
|
|
28579
|
+
throw invalidResponse(`The service returned an invalid ${field}`);
|
|
28580
|
+
}
|
|
28581
|
+
return candidate;
|
|
28582
|
+
}
|
|
28583
|
+
function validateTimestamp(value, field) {
|
|
28584
|
+
if (Number.isNaN(Date.parse(value))) {
|
|
28585
|
+
throw invalidResponse(`The service returned an invalid ${field}`);
|
|
28586
|
+
}
|
|
28587
|
+
return value;
|
|
28588
|
+
}
|
|
28589
|
+
var MobiusArtifactUploadRequest = class {
|
|
28590
|
+
byteLength;
|
|
28591
|
+
mediaType;
|
|
28592
|
+
name;
|
|
28593
|
+
sha256;
|
|
28594
|
+
constructor(name, mediaType, byteLength, sha256) {
|
|
28595
|
+
if (name.length < 1 || name.length > 500 || name.includes("\0") || mediaType.length < 1 || mediaType.length > 255 || mediaType.includes("\r") || mediaType.includes("\n") || !Number.isSafeInteger(byteLength) || byteLength < 1 || !/^[a-f0-9]{64}$/.test(sha256)) {
|
|
28596
|
+
throw new MobiusValidationError("The artifact upload request is invalid");
|
|
28597
|
+
}
|
|
28598
|
+
this.byteLength = byteLength;
|
|
28599
|
+
this.mediaType = mediaType;
|
|
28600
|
+
this.name = name;
|
|
28601
|
+
this.sha256 = sha256;
|
|
28602
|
+
}
|
|
28603
|
+
};
|
|
28604
|
+
var MobiusArtifact = class {
|
|
28605
|
+
artifactId;
|
|
28606
|
+
byteLength;
|
|
28607
|
+
createdAt;
|
|
28608
|
+
mediaType;
|
|
28609
|
+
name;
|
|
28610
|
+
sessionId;
|
|
28611
|
+
sha256;
|
|
28612
|
+
constructor(sessionId, artifactId, name, mediaType, byteLength, sha256, createdAt) {
|
|
28613
|
+
this.artifactId = artifactId;
|
|
28614
|
+
this.byteLength = byteLength;
|
|
28615
|
+
this.createdAt = createdAt;
|
|
28616
|
+
this.mediaType = mediaType;
|
|
28617
|
+
this.name = name;
|
|
28618
|
+
this.sessionId = sessionId;
|
|
28619
|
+
this.sha256 = sha256;
|
|
28620
|
+
}
|
|
28621
|
+
};
|
|
28622
|
+
var MobiusUploadingArtifact = class extends MobiusArtifact {
|
|
28623
|
+
expiresAt;
|
|
28624
|
+
state = "uploading";
|
|
28625
|
+
constructor(sessionId, artifactId, name, mediaType, byteLength, sha256, createdAt, expiresAt) {
|
|
28626
|
+
super(sessionId, artifactId, name, mediaType, byteLength, sha256, createdAt);
|
|
28627
|
+
this.expiresAt = expiresAt;
|
|
28628
|
+
}
|
|
28629
|
+
};
|
|
28630
|
+
var MobiusArtifactUpload = class extends MobiusUploadingArtifact {
|
|
28631
|
+
uploadToken;
|
|
28632
|
+
constructor(artifact, uploadToken) {
|
|
28633
|
+
super(
|
|
28634
|
+
artifact.sessionId,
|
|
28635
|
+
artifact.artifactId,
|
|
28636
|
+
artifact.name,
|
|
28637
|
+
artifact.mediaType,
|
|
28638
|
+
artifact.byteLength,
|
|
28639
|
+
artifact.sha256,
|
|
28640
|
+
artifact.createdAt,
|
|
28641
|
+
artifact.expiresAt
|
|
28642
|
+
);
|
|
28643
|
+
this.uploadToken = uploadToken;
|
|
28644
|
+
}
|
|
28645
|
+
};
|
|
28646
|
+
var MobiusAvailableArtifact = class extends MobiusArtifact {
|
|
28647
|
+
availableAt;
|
|
28648
|
+
state = "available";
|
|
28649
|
+
constructor(sessionId, artifactId, name, mediaType, byteLength, sha256, createdAt, availableAt) {
|
|
28650
|
+
super(sessionId, artifactId, name, mediaType, byteLength, sha256, createdAt);
|
|
28651
|
+
this.availableAt = availableAt;
|
|
28652
|
+
}
|
|
28653
|
+
};
|
|
28654
|
+
var MobiusExpiredArtifact = class extends MobiusArtifact {
|
|
28655
|
+
expiredAt;
|
|
28656
|
+
state = "expired";
|
|
28657
|
+
constructor(sessionId, artifactId, name, mediaType, byteLength, sha256, createdAt, expiredAt) {
|
|
28658
|
+
super(sessionId, artifactId, name, mediaType, byteLength, sha256, createdAt);
|
|
28659
|
+
this.expiredAt = expiredAt;
|
|
28660
|
+
}
|
|
28661
|
+
};
|
|
28662
|
+
function artifactFields(value) {
|
|
28663
|
+
const sha256 = stringField(value, "sha256", 64);
|
|
28664
|
+
if (!/^[a-f0-9]{64}$/.test(sha256)) {
|
|
28665
|
+
throw invalidResponse("The service returned an invalid artifact digest");
|
|
28666
|
+
}
|
|
28667
|
+
return {
|
|
28668
|
+
artifactId: identifierField(value, "artifactId"),
|
|
28669
|
+
byteLength: integerField(value, "byteLength"),
|
|
28670
|
+
createdAt: validateTimestamp(stringField(value, "createdAt", 128), "createdAt"),
|
|
28671
|
+
mediaType: stringField(value, "mediaType", 255),
|
|
28672
|
+
name: stringField(value, "name", 500),
|
|
28673
|
+
sessionId: identifierField(value, "sessionId"),
|
|
28674
|
+
sha256
|
|
28675
|
+
};
|
|
28676
|
+
}
|
|
28677
|
+
function uploadingArtifact(value) {
|
|
28678
|
+
const fields = artifactFields(value);
|
|
28679
|
+
return new MobiusUploadingArtifact(
|
|
28680
|
+
fields.sessionId,
|
|
28681
|
+
fields.artifactId,
|
|
28682
|
+
fields.name,
|
|
28683
|
+
fields.mediaType,
|
|
28684
|
+
fields.byteLength,
|
|
28685
|
+
fields.sha256,
|
|
28686
|
+
fields.createdAt,
|
|
28687
|
+
validateTimestamp(stringField(value, "expiresAt", 128), "expiresAt")
|
|
28688
|
+
);
|
|
28689
|
+
}
|
|
28690
|
+
function decodeMobiusArtifactUpload(value) {
|
|
28691
|
+
const artifact = record2(value, "artifact upload authorization");
|
|
28692
|
+
return new MobiusArtifactUpload(uploadingArtifact(artifact), stringField(artifact, "uploadToken", 256));
|
|
28693
|
+
}
|
|
28694
|
+
function decodeMobiusArtifact(value) {
|
|
28695
|
+
const artifact = record2(value, "artifact");
|
|
28696
|
+
const state = stringField(artifact, "state", 32);
|
|
28697
|
+
if (state === "uploading") {
|
|
28698
|
+
return uploadingArtifact(artifact);
|
|
28699
|
+
}
|
|
28700
|
+
const fields = artifactFields(artifact);
|
|
28701
|
+
if (state === "available") {
|
|
28702
|
+
return new MobiusAvailableArtifact(
|
|
28703
|
+
fields.sessionId,
|
|
28704
|
+
fields.artifactId,
|
|
28705
|
+
fields.name,
|
|
28706
|
+
fields.mediaType,
|
|
28707
|
+
fields.byteLength,
|
|
28708
|
+
fields.sha256,
|
|
28709
|
+
fields.createdAt,
|
|
28710
|
+
validateTimestamp(stringField(artifact, "availableAt", 128), "availableAt")
|
|
28711
|
+
);
|
|
28712
|
+
}
|
|
28713
|
+
if (state === "expired") {
|
|
28714
|
+
return new MobiusExpiredArtifact(
|
|
28715
|
+
fields.sessionId,
|
|
28716
|
+
fields.artifactId,
|
|
28717
|
+
fields.name,
|
|
28718
|
+
fields.mediaType,
|
|
28719
|
+
fields.byteLength,
|
|
28720
|
+
fields.sha256,
|
|
28721
|
+
fields.createdAt,
|
|
28722
|
+
validateTimestamp(stringField(artifact, "expiredAt", 128), "expiredAt")
|
|
28723
|
+
);
|
|
28724
|
+
}
|
|
28725
|
+
throw invalidResponse("The service returned an invalid artifact state");
|
|
28726
|
+
}
|
|
28727
|
+
function decodeMobiusAvailableArtifact(value) {
|
|
28728
|
+
const artifact = decodeMobiusArtifact(value);
|
|
28729
|
+
if (!(artifact instanceof MobiusAvailableArtifact)) {
|
|
28730
|
+
throw invalidResponse("The service did not make the artifact available");
|
|
28731
|
+
}
|
|
28732
|
+
return artifact;
|
|
28733
|
+
}
|
|
28734
|
+
var MobiusRuntimePairingLifecycle = Object.freeze({
|
|
28735
|
+
Expired: "expired",
|
|
28736
|
+
Paired: "paired",
|
|
28737
|
+
Pending: "pending",
|
|
28738
|
+
Revoked: "revoked"
|
|
28739
|
+
});
|
|
28740
|
+
|
|
28741
|
+
// src/artifacts/runtime-artifact-uploader.ts
|
|
28742
|
+
import { fetch as fetch5 } from "undici";
|
|
28743
|
+
var UPLOAD_TIMEOUT_MILLISECONDS = 2e4;
|
|
28744
|
+
var RuntimeArtifactUploadError = class extends Error {
|
|
28745
|
+
code;
|
|
28746
|
+
constructor(code, message, options = {}) {
|
|
28747
|
+
super(message, options);
|
|
28748
|
+
this.code = code;
|
|
28749
|
+
this.name = "RuntimeArtifactUploadError";
|
|
28750
|
+
}
|
|
28751
|
+
};
|
|
28752
|
+
var UploadedRuntimeArtifact = class {
|
|
28753
|
+
artifactId;
|
|
28754
|
+
byteLength;
|
|
28755
|
+
mimeType;
|
|
28756
|
+
name;
|
|
28757
|
+
sha256;
|
|
28758
|
+
constructor(artifactId, name, mimeType, byteLength, sha256) {
|
|
28759
|
+
this.artifactId = artifactId;
|
|
28760
|
+
this.byteLength = byteLength;
|
|
28761
|
+
this.mimeType = mimeType;
|
|
28762
|
+
this.name = name;
|
|
28763
|
+
this.sha256 = sha256;
|
|
28764
|
+
}
|
|
28765
|
+
};
|
|
28766
|
+
function daemonToken2(config2) {
|
|
28767
|
+
const token = config2.relayUrl.searchParams.get("token");
|
|
28768
|
+
if (token === null || token.length < 32) {
|
|
28769
|
+
throw new RuntimeArtifactUploadError("artifact_endpoint_invalid", "The Relay daemon token is missing");
|
|
28770
|
+
}
|
|
28771
|
+
return token;
|
|
28772
|
+
}
|
|
28773
|
+
function channelOrigin(config2) {
|
|
28774
|
+
const url2 = new URL(config2.relayUrl);
|
|
28775
|
+
url2.protocol = url2.protocol === "wss:" ? "https:" : "http:";
|
|
28776
|
+
let channelPath = "";
|
|
28777
|
+
if (url2.pathname.endsWith("/daemon")) {
|
|
28778
|
+
channelPath = url2.pathname.slice(0, -"/daemon".length);
|
|
28779
|
+
} else {
|
|
28780
|
+
const runtimePath = `${MOBIUS_API_PREFIX}/v1/runtimes/connect`;
|
|
28781
|
+
if (!url2.pathname.endsWith("/v1/runtimes/connect") && !url2.pathname.endsWith(runtimePath)) {
|
|
28782
|
+
throw new RuntimeArtifactUploadError("artifact_endpoint_invalid", "The Relay artifact endpoint is invalid");
|
|
28783
|
+
}
|
|
28784
|
+
channelPath = `${url2.pathname.replace(/\/v1\/runtimes\/connect$/, "")}/channels/${encodeURIComponent(config2.channelId)}`;
|
|
28785
|
+
}
|
|
28786
|
+
url2.pathname = channelPath;
|
|
28787
|
+
url2.search = "";
|
|
28788
|
+
url2.hash = "";
|
|
28789
|
+
return url2;
|
|
28790
|
+
}
|
|
28791
|
+
function uploadError(code, message, cause) {
|
|
28792
|
+
return new RuntimeArtifactUploadError(code, message, cause === void 0 ? {} : { cause });
|
|
28793
|
+
}
|
|
28794
|
+
function translateSdkError(cause) {
|
|
28795
|
+
if (cause instanceof MobiusValidationError) {
|
|
28796
|
+
throw uploadError("artifact_upload_failed", cause.message, cause);
|
|
28797
|
+
}
|
|
28798
|
+
if (cause instanceof MobiusProtocolError) {
|
|
28799
|
+
throw uploadError("artifact_upload_failed", "The Relay returned an invalid upload response", cause);
|
|
28800
|
+
}
|
|
28801
|
+
throw cause;
|
|
28802
|
+
}
|
|
28803
|
+
async function readJson(response) {
|
|
28804
|
+
try {
|
|
28805
|
+
return await response.json();
|
|
28806
|
+
} catch (cause) {
|
|
28807
|
+
throw uploadError("artifact_upload_failed", "The Relay returned an invalid upload response", cause);
|
|
28808
|
+
}
|
|
28809
|
+
}
|
|
28810
|
+
async function readAuthorization(response) {
|
|
28811
|
+
try {
|
|
28812
|
+
return decodeMobiusArtifactUpload(await readJson(response));
|
|
28813
|
+
} catch (cause) {
|
|
28814
|
+
translateSdkError(cause);
|
|
28815
|
+
}
|
|
28816
|
+
}
|
|
28817
|
+
function sessionArtifactUrl(origin, sessionId, resourcePath, token) {
|
|
28818
|
+
const url2 = new URL(`${origin.pathname}/sessions/${encodeURIComponent(sessionId)}/${resourcePath}`, origin);
|
|
28819
|
+
url2.searchParams.set("token", token);
|
|
28820
|
+
return url2;
|
|
28821
|
+
}
|
|
28822
|
+
async function postLease(url2, request, signal) {
|
|
28823
|
+
return await fetch5(url2, {
|
|
28824
|
+
dispatcher: environmentProxyDispatcher,
|
|
28825
|
+
headers: { "content-type": "application/json" },
|
|
28826
|
+
method: "POST",
|
|
28827
|
+
body: JSON.stringify(request),
|
|
28828
|
+
signal
|
|
28829
|
+
});
|
|
28830
|
+
}
|
|
28831
|
+
async function putContent(url2, authorization, bytes, signal) {
|
|
28832
|
+
return await fetch5(url2, {
|
|
28833
|
+
dispatcher: environmentProxyDispatcher,
|
|
28834
|
+
headers: {
|
|
28835
|
+
"content-type": authorization.mediaType,
|
|
28836
|
+
"x-mobius-upload-token": authorization.uploadToken
|
|
28837
|
+
},
|
|
28838
|
+
method: "PUT",
|
|
28839
|
+
body: bytes,
|
|
28840
|
+
signal
|
|
28841
|
+
});
|
|
28842
|
+
}
|
|
28843
|
+
async function uploadRuntimeArtifact(config2, sessionId, image, signal) {
|
|
28844
|
+
signal.throwIfAborted();
|
|
28845
|
+
let request;
|
|
28846
|
+
try {
|
|
28847
|
+
request = new MobiusArtifactUploadRequest(
|
|
28848
|
+
image.name,
|
|
28849
|
+
image.mimeType,
|
|
28850
|
+
image.bytes.byteLength,
|
|
28851
|
+
createHash3("sha256").update(image.bytes).digest("hex")
|
|
28852
|
+
);
|
|
28853
|
+
} catch (cause) {
|
|
28854
|
+
translateSdkError(cause);
|
|
28855
|
+
}
|
|
28856
|
+
const timeoutSignal = AbortSignal.timeout(UPLOAD_TIMEOUT_MILLISECONDS);
|
|
28857
|
+
const requestSignal = AbortSignal.any([signal, timeoutSignal]);
|
|
28858
|
+
const origin = channelOrigin(config2);
|
|
28859
|
+
const token = daemonToken2(config2);
|
|
28860
|
+
let created;
|
|
28861
|
+
try {
|
|
28862
|
+
created = await postLease(
|
|
28863
|
+
sessionArtifactUrl(origin, sessionId, "artifacts/uploads", token),
|
|
28864
|
+
request,
|
|
28865
|
+
requestSignal
|
|
28866
|
+
);
|
|
28867
|
+
} catch (cause) {
|
|
28868
|
+
signal.throwIfAborted();
|
|
28869
|
+
throw uploadError(
|
|
28870
|
+
timeoutSignal.aborted ? "artifact_upload_timeout" : "artifact_upload_failed",
|
|
28871
|
+
timeoutSignal.aborted ? "The artifact upload authorization timed out" : "The artifact upload could not start",
|
|
28872
|
+
cause
|
|
28873
|
+
);
|
|
28874
|
+
}
|
|
28875
|
+
if (!created.ok) {
|
|
28876
|
+
await created.body?.cancel();
|
|
28877
|
+
throw uploadError("artifact_upload_rejected", "The Relay rejected the artifact upload");
|
|
28878
|
+
}
|
|
28879
|
+
const authorization = await readAuthorization(created);
|
|
28880
|
+
let uploaded;
|
|
28881
|
+
try {
|
|
28882
|
+
uploaded = await putContent(
|
|
28883
|
+
sessionArtifactUrl(
|
|
28884
|
+
origin,
|
|
28885
|
+
sessionId,
|
|
28886
|
+
`artifacts/${encodeURIComponent(authorization.artifactId)}/content`,
|
|
28887
|
+
token
|
|
28888
|
+
),
|
|
28889
|
+
authorization,
|
|
28890
|
+
image.bytes,
|
|
28891
|
+
requestSignal
|
|
28892
|
+
);
|
|
28893
|
+
} catch (cause) {
|
|
28894
|
+
signal.throwIfAborted();
|
|
28895
|
+
throw uploadError(
|
|
28896
|
+
timeoutSignal.aborted ? "artifact_upload_timeout" : "artifact_upload_failed",
|
|
28897
|
+
timeoutSignal.aborted ? "The artifact upload timed out" : "The artifact content could not be uploaded",
|
|
28898
|
+
cause
|
|
28899
|
+
);
|
|
28900
|
+
}
|
|
28901
|
+
if (!uploaded.ok) {
|
|
28902
|
+
await uploaded.body?.cancel();
|
|
28903
|
+
throw uploadError("artifact_upload_rejected", "The Relay rejected the artifact content");
|
|
28904
|
+
}
|
|
28905
|
+
try {
|
|
28906
|
+
const available = decodeMobiusAvailableArtifact(await readJson(uploaded));
|
|
28907
|
+
return new UploadedRuntimeArtifact(
|
|
28908
|
+
available.artifactId,
|
|
28909
|
+
available.name,
|
|
28910
|
+
available.mediaType,
|
|
28911
|
+
available.byteLength,
|
|
28912
|
+
available.sha256
|
|
28913
|
+
);
|
|
28914
|
+
} catch (cause) {
|
|
28915
|
+
translateSdkError(cause);
|
|
28916
|
+
}
|
|
28917
|
+
}
|
|
28918
|
+
|
|
28250
28919
|
// src/authorization/workspace-directory.ts
|
|
28251
|
-
import { readdir, realpath as
|
|
28920
|
+
import { readdir, realpath as realpath8, stat as stat8 } from "node:fs/promises";
|
|
28252
28921
|
import { homedir as homedir2 } from "node:os";
|
|
28253
|
-
import { basename as
|
|
28922
|
+
import { basename as basename3, dirname as dirname6, isAbsolute as isAbsolute9, join as join15, normalize as normalize3, relative as relative5 } from "node:path";
|
|
28254
28923
|
var WorkspaceDirectoryListing = class {
|
|
28255
28924
|
directoryId;
|
|
28256
28925
|
directoryLabel;
|
|
@@ -28276,7 +28945,7 @@ function decodePath(value, prefix) {
|
|
|
28276
28945
|
throw new LocalAuthorizationError("The directory identifier is invalid");
|
|
28277
28946
|
}
|
|
28278
28947
|
const decoded = Buffer.from(encoded, "base64url").toString("utf8");
|
|
28279
|
-
if (Buffer.from(decoded, "utf8").toString("base64url") !== encoded || decoded.includes("\0") ||
|
|
28948
|
+
if (Buffer.from(decoded, "utf8").toString("base64url") !== encoded || decoded.includes("\0") || normalize3(decoded) !== decoded) {
|
|
28280
28949
|
throw new LocalAuthorizationError("The directory identifier is invalid");
|
|
28281
28950
|
}
|
|
28282
28951
|
return decoded;
|
|
@@ -28302,7 +28971,7 @@ var WorkspaceDirectoryService = class {
|
|
|
28302
28971
|
}
|
|
28303
28972
|
if (id.startsWith("path-")) {
|
|
28304
28973
|
const path2 = decodePath(id, "path-");
|
|
28305
|
-
if (
|
|
28974
|
+
if (isAbsolute9(path2)) {
|
|
28306
28975
|
return path2;
|
|
28307
28976
|
}
|
|
28308
28977
|
}
|
|
@@ -28310,15 +28979,15 @@ var WorkspaceDirectoryService = class {
|
|
|
28310
28979
|
};
|
|
28311
28980
|
resolvePath = async (requested, signal) => {
|
|
28312
28981
|
signal.throwIfAborted();
|
|
28313
|
-
if (!
|
|
28982
|
+
if (!isAbsolute9(requested) || requested.includes("\0") || normalize3(requested) !== requested) {
|
|
28314
28983
|
throw new LocalAuthorizationError("The local directory path is invalid");
|
|
28315
28984
|
}
|
|
28316
28985
|
try {
|
|
28317
|
-
const target = await
|
|
28986
|
+
const target = await realpath8(requested);
|
|
28318
28987
|
signal.throwIfAborted();
|
|
28319
|
-
const metadata = await
|
|
28988
|
+
const metadata = await stat8(target);
|
|
28320
28989
|
signal.throwIfAborted();
|
|
28321
|
-
if (!
|
|
28990
|
+
if (!isAbsolute9(target) || normalize3(target) !== target || !metadata.isDirectory()) {
|
|
28322
28991
|
throw new LocalAuthorizationError("The selected location is not a directory");
|
|
28323
28992
|
}
|
|
28324
28993
|
return target;
|
|
@@ -28333,8 +29002,8 @@ var WorkspaceDirectoryService = class {
|
|
|
28333
29002
|
}
|
|
28334
29003
|
};
|
|
28335
29004
|
label = (path2) => {
|
|
28336
|
-
const suffix =
|
|
28337
|
-
return suffix === "" ? "~" : !
|
|
29005
|
+
const suffix = relative5(homedir2(), path2);
|
|
29006
|
+
return suffix === "" ? "~" : !isAbsolute9(suffix) && suffix !== ".." && !suffix.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`) ? `~/${suffix.replaceAll("\\", "/")}` : path2;
|
|
28338
29007
|
};
|
|
28339
29008
|
identify = async (bindingId, requestedPath, signal) => {
|
|
28340
29009
|
this.authorizeMachine(bindingId);
|
|
@@ -28342,7 +29011,7 @@ var WorkspaceDirectoryService = class {
|
|
|
28342
29011
|
return {
|
|
28343
29012
|
path: path2,
|
|
28344
29013
|
directoryId: encodePath(path2),
|
|
28345
|
-
name:
|
|
29014
|
+
name: basename3(path2) || path2,
|
|
28346
29015
|
label: this.label(path2)
|
|
28347
29016
|
};
|
|
28348
29017
|
};
|
|
@@ -28436,7 +29105,7 @@ var EmbeddedBotContextApplicator = class {
|
|
|
28436
29105
|
|
|
28437
29106
|
// src/native-sessions/service.ts
|
|
28438
29107
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
28439
|
-
import { basename as
|
|
29108
|
+
import { basename as basename4 } from "node:path";
|
|
28440
29109
|
|
|
28441
29110
|
// src/native-sessions/codex-history.ts
|
|
28442
29111
|
import { spawn as spawn4 } from "node:child_process";
|
|
@@ -28469,7 +29138,6 @@ function decodeHistory(thread, value) {
|
|
|
28469
29138
|
const page = turnsSchema.parse(value);
|
|
28470
29139
|
const messages = [];
|
|
28471
29140
|
let characters = 0;
|
|
28472
|
-
let imageCharacters = 0;
|
|
28473
29141
|
let truncated = page.nextCursor != null;
|
|
28474
29142
|
for (const turn of page.data.toReversed()) {
|
|
28475
29143
|
for (const item of turn.items) {
|
|
@@ -28477,22 +29145,19 @@ function decodeHistory(thread, value) {
|
|
|
28477
29145
|
let message;
|
|
28478
29146
|
if (type === "userMessage") {
|
|
28479
29147
|
const { content } = userMessageSchema.parse(item);
|
|
28480
|
-
const
|
|
28481
|
-
|
|
28482
|
-
|
|
28483
|
-
|
|
28484
|
-
|
|
28485
|
-
|
|
28486
|
-
|
|
28487
|
-
|
|
28488
|
-
|
|
28489
|
-
|
|
28490
|
-
}).join("")
|
|
28491
|
-
);
|
|
29148
|
+
const text2 = content.map((block) => {
|
|
29149
|
+
const { type: type2 } = itemTypeSchema.parse(block);
|
|
29150
|
+
if (type2 === "text") {
|
|
29151
|
+
return textSchema.parse(block).text;
|
|
29152
|
+
}
|
|
29153
|
+
if (type2 === "image") {
|
|
29154
|
+
return `[@image](${imageSchema.parse(block).url})`;
|
|
29155
|
+
}
|
|
29156
|
+
return "[Attachment]";
|
|
29157
|
+
}).join("");
|
|
28492
29158
|
message = {
|
|
28493
29159
|
role: "user",
|
|
28494
|
-
text:
|
|
28495
|
-
...parsed.images.length > 0 ? { images: parsed.images } : {}
|
|
29160
|
+
text: text2
|
|
28496
29161
|
};
|
|
28497
29162
|
} else if (type === "agentMessage") {
|
|
28498
29163
|
const agent = agentMessageSchema.parse(item);
|
|
@@ -28510,12 +29175,10 @@ function decodeHistory(thread, value) {
|
|
|
28510
29175
|
truncated ||= text.length < message.text.length;
|
|
28511
29176
|
messages.push({ ...message, text });
|
|
28512
29177
|
characters += text.length;
|
|
28513
|
-
|
|
28514
|
-
while (messages.length > SESSION_HISTORY_PREVIEW_MESSAGE_LIMIT || characters > SESSION_HISTORY_CHARACTER_LIMIT || imageCharacters > SESSION_HISTORY_IMAGE_CHARACTER_LIMIT) {
|
|
29178
|
+
while (messages.length > SESSION_HISTORY_PREVIEW_MESSAGE_LIMIT || characters > SESSION_HISTORY_CHARACTER_LIMIT) {
|
|
28515
29179
|
const removed = messages.shift();
|
|
28516
29180
|
if (removed !== void 0) {
|
|
28517
29181
|
characters -= removed.text.length;
|
|
28518
|
-
imageCharacters -= (removed.images ?? []).reduce((size, image) => size + image.data.length, 0);
|
|
28519
29182
|
}
|
|
28520
29183
|
truncated = true;
|
|
28521
29184
|
}
|
|
@@ -28673,7 +29336,11 @@ async function readCodexHistory(agent, cwd, nativeSessionId, signal) {
|
|
|
28673
29336
|
params: { clientInfo: { name: "mobius_history", version: "1.0.0" } }
|
|
28674
29337
|
});
|
|
28675
29338
|
}
|
|
28676
|
-
|
|
29339
|
+
const snapshot = await response.promise;
|
|
29340
|
+
return {
|
|
29341
|
+
...snapshot,
|
|
29342
|
+
history: await embedLocalHistoryImages(snapshot.history, [cwd, snapshot.cwd], signal)
|
|
29343
|
+
};
|
|
28677
29344
|
} finally {
|
|
28678
29345
|
clearTimeout(timeout);
|
|
28679
29346
|
signal.removeEventListener("abort", abort);
|
|
@@ -28927,7 +29594,7 @@ var NativeSessionService = class {
|
|
|
28927
29594
|
}
|
|
28928
29595
|
resolvedPaths.add(path2);
|
|
28929
29596
|
additionalDirectories.push(path2);
|
|
28930
|
-
additionalEntries.push({ directoryId: directoryId2, name:
|
|
29597
|
+
additionalEntries.push({ directoryId: directoryId2, name: basename4(path2) });
|
|
28931
29598
|
}
|
|
28932
29599
|
const listing = await this.#directories.list(this.#config.bindingId, command.directoryId, signal);
|
|
28933
29600
|
const opened = await this.#sessions.forkSessionAtTurn(
|
|
@@ -29066,13 +29733,13 @@ var NativeSessionService = class {
|
|
|
29066
29733
|
};
|
|
29067
29734
|
|
|
29068
29735
|
// src/prompt-artifact-resolver.ts
|
|
29069
|
-
import { createHash as
|
|
29070
|
-
import { fetch as
|
|
29736
|
+
import { createHash as createHash4 } from "node:crypto";
|
|
29737
|
+
import { fetch as fetch6 } from "undici";
|
|
29071
29738
|
var ARTIFACT_SCHEME = "mobius-artifact:";
|
|
29072
29739
|
var ARTIFACT_DOWNLOAD_TIMEOUT_MILLISECONDS = 2e4;
|
|
29073
29740
|
var MAX_AGENT_IMAGE_BASE64_LENGTH = 4e6;
|
|
29074
29741
|
var MAX_AGENT_RESOURCE_BYTE_LENGTH = 1e6;
|
|
29075
|
-
var
|
|
29742
|
+
var IDENTIFIER_PATTERN8 = /^[a-zA-Z0-9][a-zA-Z0-9._:-]{0,127}$/;
|
|
29076
29743
|
var PromptArtifactError = class extends Error {
|
|
29077
29744
|
code;
|
|
29078
29745
|
constructor(code, message, options = {}) {
|
|
@@ -29115,7 +29782,7 @@ function parseReference(resource) {
|
|
|
29115
29782
|
const encodedByteLength2 = url2.searchParams.get("byteLength") ?? "";
|
|
29116
29783
|
const sha256 = url2.searchParams.get("sha256") ?? "";
|
|
29117
29784
|
const byteLength = Number(encodedByteLength2);
|
|
29118
|
-
if (url2.protocol !== ARTIFACT_SCHEME || url2.hash.length > 0 || resource.type !== "link" || resource.text.length > 0 || !
|
|
29785
|
+
if (url2.protocol !== ARTIFACT_SCHEME || url2.hash.length > 0 || resource.type !== "link" || resource.text.length > 0 || !IDENTIFIER_PATTERN8.test(artifactId) || keys.length !== 2 || keys[0] !== "byteLength" || keys[1] !== "sha256" || !/^[1-9][0-9]*$/.test(encodedByteLength2) || !Number.isSafeInteger(byteLength) || !/^[a-f0-9]{64}$/.test(sha256)) {
|
|
29119
29786
|
throw new PromptArtifactError("artifact_reference_invalid", "The prompt artifact reference is invalid");
|
|
29120
29787
|
}
|
|
29121
29788
|
return new PromptArtifactReference(artifactId, byteLength, sha256, resource);
|
|
@@ -29181,7 +29848,7 @@ async function download(config2, command, reference, signal) {
|
|
|
29181
29848
|
const requestSignal = AbortSignal.any([signal, timeoutSignal]);
|
|
29182
29849
|
let response;
|
|
29183
29850
|
try {
|
|
29184
|
-
response = await
|
|
29851
|
+
response = await fetch6(downloadUrl(config2, command, reference), {
|
|
29185
29852
|
dispatcher: environmentProxyDispatcher,
|
|
29186
29853
|
headers: {
|
|
29187
29854
|
accept: reference.resource.mimeType,
|
|
@@ -29205,7 +29872,7 @@ async function download(config2, command, reference, signal) {
|
|
|
29205
29872
|
);
|
|
29206
29873
|
}
|
|
29207
29874
|
const bytes = await responseBytes(response, reference.byteLength, requestSignal);
|
|
29208
|
-
if (
|
|
29875
|
+
if (createHash4("sha256").update(bytes).digest("hex") !== reference.sha256) {
|
|
29209
29876
|
throw new PromptArtifactError(
|
|
29210
29877
|
"artifact_integrity_failed",
|
|
29211
29878
|
"The prompt artifact failed integrity validation"
|
|
@@ -30241,10 +30908,23 @@ function botIpcSocketPath() {
|
|
|
30241
30908
|
return join16("/tmp", `mobius-bot-${randomUUID6()}.sock`);
|
|
30242
30909
|
}
|
|
30243
30910
|
var DaemonAcpObserver = class {
|
|
30911
|
+
#config;
|
|
30244
30912
|
#record;
|
|
30245
|
-
constructor(
|
|
30246
|
-
this.#
|
|
30913
|
+
constructor(config2, record3) {
|
|
30914
|
+
this.#config = config2;
|
|
30915
|
+
this.#record = record3;
|
|
30247
30916
|
}
|
|
30917
|
+
importLocalImage = async (sessionId, image, signal) => {
|
|
30918
|
+
try {
|
|
30919
|
+
return (await uploadRuntimeArtifact(this.#config, sessionId, image, signal)).artifactId;
|
|
30920
|
+
} catch (cause) {
|
|
30921
|
+
signal.throwIfAborted();
|
|
30922
|
+
if (cause instanceof Error && cause.name === "AbortError") {
|
|
30923
|
+
throw cause;
|
|
30924
|
+
}
|
|
30925
|
+
return "";
|
|
30926
|
+
}
|
|
30927
|
+
};
|
|
30248
30928
|
onCommands = (event) => {
|
|
30249
30929
|
this.#record(event.sessionId, encodeSessionCommandsUpdatedEvent(event));
|
|
30250
30930
|
return Promise.resolve();
|
|
@@ -30454,7 +31134,7 @@ async function reconcileActiveTurn(config2, turn, signal) {
|
|
|
30454
31134
|
const requestSignal = AbortSignal.any([signal, timeoutSignal]);
|
|
30455
31135
|
let response;
|
|
30456
31136
|
try {
|
|
30457
|
-
response = await
|
|
31137
|
+
response = await fetch7(activeTurnReconciliationEndpoint(config2, turn), {
|
|
30458
31138
|
body: JSON.stringify({ outcome: { kind: "running" } }),
|
|
30459
31139
|
dispatcher: environmentProxyDispatcher,
|
|
30460
31140
|
headers: { ...runtimeAuthorization(config2.relayUrl), "content-type": "application/json" },
|
|
@@ -30770,7 +31450,7 @@ async function resolveSessionDirectories(directories, bindingId, directoryId2, a
|
|
|
30770
31450
|
additionalDirectories.push(directory);
|
|
30771
31451
|
additionalDirectoryEntries.push({
|
|
30772
31452
|
directoryId: additionalDirectoryId,
|
|
30773
|
-
name:
|
|
31453
|
+
name: basename5(directory)
|
|
30774
31454
|
});
|
|
30775
31455
|
}
|
|
30776
31456
|
return new ResolvedSessionDirectories(cwd, additionalDirectories, additionalDirectoryEntries);
|
|
@@ -31281,8 +31961,7 @@ async function runRelayConnection(config2, directories, audit, sessions, install
|
|
|
31281
31961
|
rejectConnection(failure);
|
|
31282
31962
|
};
|
|
31283
31963
|
const processingDeliveryIds = /* @__PURE__ */ new Set();
|
|
31284
|
-
const processDeliveredPrompt = async (delivery) => {
|
|
31285
|
-
const command = decodeSessionPromptCommand(delivery.payload);
|
|
31964
|
+
const processDeliveredPrompt = async (delivery, command, trackActiveAttempt, execute) => {
|
|
31286
31965
|
if (command.sessionId !== delivery.sessionId) {
|
|
31287
31966
|
throw new Error("Runtime delivery Session identity does not match its payload");
|
|
31288
31967
|
}
|
|
@@ -31310,22 +31989,11 @@ async function runRelayConnection(config2, directories, audit, sessions, install
|
|
|
31310
31989
|
}
|
|
31311
31990
|
const turn = new ActiveDaemonTurn(command, receipt.attemptId);
|
|
31312
31991
|
activeTurns.set(command.commandId, turn);
|
|
31313
|
-
if (
|
|
31992
|
+
if (trackActiveAttempt) {
|
|
31314
31993
|
activeAttemptIds.set(command.sessionId, receipt.attemptId);
|
|
31315
31994
|
}
|
|
31316
31995
|
try {
|
|
31317
|
-
await
|
|
31318
|
-
outbox,
|
|
31319
|
-
publisher,
|
|
31320
|
-
command,
|
|
31321
|
-
config2,
|
|
31322
|
-
directories,
|
|
31323
|
-
audit,
|
|
31324
|
-
sessions,
|
|
31325
|
-
receipt.attemptId,
|
|
31326
|
-
timer,
|
|
31327
|
-
turn.signal
|
|
31328
|
-
);
|
|
31996
|
+
await execute(receipt.attemptId, turn.signal);
|
|
31329
31997
|
} finally {
|
|
31330
31998
|
activeTurns.delete(command.commandId);
|
|
31331
31999
|
if (activeAttemptIds.get(command.sessionId) === receipt.attemptId) {
|
|
@@ -31404,8 +32072,50 @@ async function runRelayConnection(config2, directories, audit, sessions, install
|
|
|
31404
32072
|
}
|
|
31405
32073
|
return;
|
|
31406
32074
|
}
|
|
32075
|
+
if (kind === BOT_SESSION_PROMPT_KIND) {
|
|
32076
|
+
const command = decodeBotSessionPromptCommand(delivery.payload);
|
|
32077
|
+
await processDeliveredPrompt(
|
|
32078
|
+
delivery,
|
|
32079
|
+
command,
|
|
32080
|
+
true,
|
|
32081
|
+
(attemptId, executionSignal) => executeBotPrompt(
|
|
32082
|
+
outbox,
|
|
32083
|
+
publisher,
|
|
32084
|
+
command,
|
|
32085
|
+
config2,
|
|
32086
|
+
directories,
|
|
32087
|
+
audit,
|
|
32088
|
+
sessions,
|
|
32089
|
+
grants,
|
|
32090
|
+
contexts,
|
|
32091
|
+
applicator,
|
|
32092
|
+
ipc,
|
|
32093
|
+
attemptId,
|
|
32094
|
+
timer,
|
|
32095
|
+
executionSignal
|
|
32096
|
+
)
|
|
32097
|
+
);
|
|
32098
|
+
return;
|
|
32099
|
+
}
|
|
31407
32100
|
if (kind === SESSION_PROMPT_KIND) {
|
|
31408
|
-
|
|
32101
|
+
const command = decodeSessionPromptCommand(delivery.payload);
|
|
32102
|
+
await processDeliveredPrompt(
|
|
32103
|
+
delivery,
|
|
32104
|
+
command,
|
|
32105
|
+
command.disposition !== SessionPromptDisposition.Steer,
|
|
32106
|
+
(attemptId, executionSignal) => executePrompt(
|
|
32107
|
+
outbox,
|
|
32108
|
+
publisher,
|
|
32109
|
+
command,
|
|
32110
|
+
config2,
|
|
32111
|
+
directories,
|
|
32112
|
+
audit,
|
|
32113
|
+
sessions,
|
|
32114
|
+
attemptId,
|
|
32115
|
+
timer,
|
|
32116
|
+
executionSignal
|
|
32117
|
+
)
|
|
32118
|
+
);
|
|
31409
32119
|
return;
|
|
31410
32120
|
}
|
|
31411
32121
|
throw new Error("Runtime delivery contains an unsupported protocol message");
|
|
@@ -31443,6 +32153,8 @@ async function runRelayConnection(config2, directories, audit, sessions, install
|
|
|
31443
32153
|
payloadSessionId = decodeSessionElicitationRespondCommand(delivery.payload).sessionId;
|
|
31444
32154
|
} else if (payloadKind === SESSION_PROMPT_KIND) {
|
|
31445
32155
|
payloadSessionId = decodeSessionPromptCommand(delivery.payload).sessionId;
|
|
32156
|
+
} else if (payloadKind === BOT_SESSION_PROMPT_KIND) {
|
|
32157
|
+
payloadSessionId = decodeBotSessionPromptCommand(delivery.payload).sessionId;
|
|
31446
32158
|
} else {
|
|
31447
32159
|
throw new Error("Runtime delivery contains an unsupported protocol message");
|
|
31448
32160
|
}
|
|
@@ -32040,7 +32752,7 @@ async function runDaemon(config2, audit, signal, timer = systemDaemonTimer) {
|
|
|
32040
32752
|
}
|
|
32041
32753
|
publisher.recordAttempt(sessionId, payload, attemptId);
|
|
32042
32754
|
};
|
|
32043
|
-
const sessions = new AcpSessionManager(new DaemonAcpObserver(recordSessionEvent), sessionStore);
|
|
32755
|
+
const sessions = new AcpSessionManager(new DaemonAcpObserver(config2, recordSessionEvent), sessionStore);
|
|
32044
32756
|
const directories = new WorkspaceDirectoryService(config2.bindingId, config2.defaultWorkspace);
|
|
32045
32757
|
const installationObserver = new DaemonInstallationObserver();
|
|
32046
32758
|
const diagnostics = new RelayConnectionDiagnostics(audit, config2.channelId, config2.relayUrl);
|
|
@@ -32138,11 +32850,11 @@ async function runDaemon(config2, audit, signal, timer = systemDaemonTimer) {
|
|
|
32138
32850
|
}
|
|
32139
32851
|
|
|
32140
32852
|
// src/runtime.ts
|
|
32141
|
-
import { mkdir as mkdir5, realpath as
|
|
32853
|
+
import { mkdir as mkdir5, realpath as realpath9, stat as stat9 } from "node:fs/promises";
|
|
32142
32854
|
import { dirname as dirname8, join as join17, resolve as resolve5 } from "node:path";
|
|
32143
32855
|
var APP_CREDENTIAL_PATTERN = /^mapp_[a-zA-Z0-9_-]{22}_[a-zA-Z0-9_-]{43}$/;
|
|
32144
32856
|
var CONVERSATION_CREDENTIAL_PATTERN = /^mconv_[a-zA-Z0-9_-]{22}_[a-zA-Z0-9_-]{43}$/;
|
|
32145
|
-
var
|
|
32857
|
+
var IDENTIFIER_PATTERN9 = /^[a-zA-Z0-9][a-zA-Z0-9._:-]{0,127}$/;
|
|
32146
32858
|
var RUNTIME_CREDENTIAL_PATTERN = /^[a-zA-Z0-9_-]{32,256}$/;
|
|
32147
32859
|
var MobiusRuntimeConfigurationError = class extends Error {
|
|
32148
32860
|
code = "runtime_configuration_invalid";
|
|
@@ -32200,7 +32912,7 @@ function relayUrlFromConnection(connection) {
|
|
|
32200
32912
|
}
|
|
32201
32913
|
function loadMobiusRuntimeConnection(environment = process.env) {
|
|
32202
32914
|
const channelId = requiredEnvironmentValue(environment, "MOBIUS_CHANNEL_ID");
|
|
32203
|
-
if (!
|
|
32915
|
+
if (!IDENTIFIER_PATTERN9.test(channelId)) {
|
|
32204
32916
|
throw new MobiusRuntimeConfigurationError("MOBIUS_CHANNEL_ID is invalid");
|
|
32205
32917
|
}
|
|
32206
32918
|
return Object.freeze({
|
|
@@ -32215,8 +32927,8 @@ async function resolveWorkspace(path2) {
|
|
|
32215
32927
|
const requested = resolve5(path2);
|
|
32216
32928
|
try {
|
|
32217
32929
|
await mkdir5(requested, { recursive: true, mode: 448 });
|
|
32218
|
-
const resolved = await
|
|
32219
|
-
const metadata = await
|
|
32930
|
+
const resolved = await realpath9(requested);
|
|
32931
|
+
const metadata = await stat9(resolved);
|
|
32220
32932
|
if (!metadata.isDirectory()) {
|
|
32221
32933
|
throw new MobiusRuntimeConfigurationError("The Runtime workspace is not a directory");
|
|
32222
32934
|
}
|