@moxt-ai/mobius 0.0.24 → 0.0.25
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/agent-catalog/publish-agent-catalog.d.ts.map +1 -1
- package/dist/agent-catalog/publish-agent-catalog.js +12 -7
- package/dist/agent-catalog/publish-agent-catalog.js.map +1 -1
- package/dist/cli.js +220 -118
- package/dist/cli.js.map +4 -4
- package/dist/config.d.ts +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +3 -3
- package/dist/config.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +281 -82
- package/dist/index.js.map +4 -4
- package/dist/pairing/pair-local-machine.d.ts +8 -0
- package/dist/pairing/pair-local-machine.d.ts.map +1 -1
- package/dist/pairing/pair-local-machine.js +64 -37
- package/dist/pairing/pair-local-machine.js.map +1 -1
- package/dist/prompt-artifact-resolver.d.ts.map +1 -1
- package/dist/prompt-artifact-resolver.js +11 -3
- package/dist/prompt-artifact-resolver.js.map +1 -1
- package/dist/relay-connection/connect.d.ts.map +1 -1
- package/dist/relay-connection/connect.js +9 -1
- package/dist/relay-connection/connect.js.map +1 -1
- package/dist/run-daemon.d.ts.map +1 -1
- package/dist/run-daemon.js +11 -3
- package/dist/run-daemon.js.map +1 -1
- package/dist/runtime.d.ts +23 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +31046 -0
- package/dist/runtime.js.map +7 -0
- package/package.json +6 -2
package/dist/index.js
CHANGED
|
@@ -21107,9 +21107,9 @@ function readStateDirectory(environment = process.env) {
|
|
|
21107
21107
|
}
|
|
21108
21108
|
|
|
21109
21109
|
// src/config.ts
|
|
21110
|
-
function loadDefaultWorkspace() {
|
|
21111
|
-
const { MOBIUS_DEFAULT_WORKSPACE: configuredWorkspace } =
|
|
21112
|
-
return configuredWorkspace ?? join3(readStateDirectory(), "workspace");
|
|
21110
|
+
function loadDefaultWorkspace(environment = process.env) {
|
|
21111
|
+
const { MOBIUS_DEFAULT_WORKSPACE: configuredWorkspace } = environment;
|
|
21112
|
+
return configuredWorkspace ?? join3(readStateDirectory(environment), "workspace");
|
|
21113
21113
|
}
|
|
21114
21114
|
function createDaemonConfig(connection, agents = [], installableAgents = []) {
|
|
21115
21115
|
return {
|
|
@@ -22462,7 +22462,7 @@ function createWritableAcpStream(output2) {
|
|
|
22462
22462
|
if (outputFailure !== void 0) {
|
|
22463
22463
|
return Promise.reject(outputFailure);
|
|
22464
22464
|
}
|
|
22465
|
-
return new Promise((
|
|
22465
|
+
return new Promise((resolve6, reject) => {
|
|
22466
22466
|
pendingWriteFailures.add(reject);
|
|
22467
22467
|
output2.write(chunk, (error61) => {
|
|
22468
22468
|
pendingWriteFailures.delete(reject);
|
|
@@ -22475,7 +22475,7 @@ function createWritableAcpStream(output2) {
|
|
|
22475
22475
|
reject(outputFailure);
|
|
22476
22476
|
return;
|
|
22477
22477
|
}
|
|
22478
|
-
|
|
22478
|
+
resolve6();
|
|
22479
22479
|
});
|
|
22480
22480
|
});
|
|
22481
22481
|
}
|
|
@@ -22882,9 +22882,9 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
22882
22882
|
stderr.on("data", (chunk) => {
|
|
22883
22883
|
process.stderr.write(`[${agent.id}-acp] ${chunk}`);
|
|
22884
22884
|
});
|
|
22885
|
-
this.#processExit = new Promise((
|
|
22886
|
-
this.#child.once("error",
|
|
22887
|
-
this.#child.once("exit",
|
|
22885
|
+
this.#processExit = new Promise((resolve6) => {
|
|
22886
|
+
this.#child.once("error", resolve6);
|
|
22887
|
+
this.#child.once("exit", resolve6);
|
|
22888
22888
|
});
|
|
22889
22889
|
const stream = ndJsonStream(createWritableAcpStream(stdin), readableWebStream(stdout));
|
|
22890
22890
|
this.#connection = createAcpClient(this).connect(stream);
|
|
@@ -25123,7 +25123,7 @@ function decodeResponse(encoded) {
|
|
|
25123
25123
|
}
|
|
25124
25124
|
async function requestLocalBotService(socketPath, payload, signal) {
|
|
25125
25125
|
signal.throwIfAborted();
|
|
25126
|
-
return await new Promise((
|
|
25126
|
+
return await new Promise((resolve6, reject) => {
|
|
25127
25127
|
const socket = createConnection(socketPath);
|
|
25128
25128
|
const chunks = [];
|
|
25129
25129
|
let length = 0;
|
|
@@ -25172,7 +25172,7 @@ async function requestLocalBotService(socketPath, payload, signal) {
|
|
|
25172
25172
|
finished = true;
|
|
25173
25173
|
signal.removeEventListener("abort", abort);
|
|
25174
25174
|
try {
|
|
25175
|
-
|
|
25175
|
+
resolve6(decodeResponse(Buffer.concat(chunks).toString("utf8")));
|
|
25176
25176
|
} catch (error61) {
|
|
25177
25177
|
reject(error61);
|
|
25178
25178
|
} finally {
|
|
@@ -25326,12 +25326,12 @@ var BotOutboundIpcServer = class {
|
|
|
25326
25326
|
}
|
|
25327
25327
|
});
|
|
25328
25328
|
}
|
|
25329
|
-
await new Promise((
|
|
25329
|
+
await new Promise((resolve6, reject) => {
|
|
25330
25330
|
const fail = (error61) => reject(error61);
|
|
25331
25331
|
this.#server.once("error", fail);
|
|
25332
25332
|
this.#server.listen(this.#socketPath, () => {
|
|
25333
25333
|
this.#server.removeListener("error", fail);
|
|
25334
|
-
|
|
25334
|
+
resolve6();
|
|
25335
25335
|
});
|
|
25336
25336
|
});
|
|
25337
25337
|
if (this.#usesFilesystemSocket) {
|
|
@@ -25344,10 +25344,10 @@ var BotOutboundIpcServer = class {
|
|
|
25344
25344
|
};
|
|
25345
25345
|
close = async () => {
|
|
25346
25346
|
if (this.#server.listening) {
|
|
25347
|
-
await new Promise((
|
|
25347
|
+
await new Promise((resolve6, reject) => {
|
|
25348
25348
|
this.#server.close((error61) => {
|
|
25349
25349
|
if (error61 === void 0) {
|
|
25350
|
-
|
|
25350
|
+
resolve6();
|
|
25351
25351
|
return;
|
|
25352
25352
|
}
|
|
25353
25353
|
reject(error61);
|
|
@@ -27270,7 +27270,9 @@ var IDENTIFIER_PATTERN6 = /^[a-zA-Z0-9][a-zA-Z0-9._:-]{0,127}$/;
|
|
|
27270
27270
|
var TOKEN_PATTERN2 = /^[a-zA-Z0-9_-]{32,256}$/;
|
|
27271
27271
|
var MAX_CONNECTION_FILE_LENGTH = 16 * 1024;
|
|
27272
27272
|
var CLAIM_RESPONSE_KEYS = ["channelId", "daemonToken", "runtimeId"];
|
|
27273
|
-
var
|
|
27273
|
+
var REDEEM_RESPONSE_KEYS = ["channelId", "runtimeCredential", "runtimeId"];
|
|
27274
|
+
var LEGACY_SAVED_CONNECTION_KEYS = ["defaultWorkspace", "channelId", "daemonToken", "relayOrigin"];
|
|
27275
|
+
var SAVED_CONNECTION_KEYS = ["defaultWorkspace", "channelId", "relayOrigin", "runtimeCredential"];
|
|
27274
27276
|
var PairingClientError = class extends Error {
|
|
27275
27277
|
code;
|
|
27276
27278
|
constructor(code, message, options = {}) {
|
|
@@ -27307,7 +27309,7 @@ function readSingleOption(arguments_, option2) {
|
|
|
27307
27309
|
function assertKnownArguments(arguments_) {
|
|
27308
27310
|
for (let index = 0; index < arguments_.length; index += 2) {
|
|
27309
27311
|
const option2 = arguments_[index];
|
|
27310
|
-
if (option2 !== "--url" && option2 !== "--code" && option2 !== "--workspace") {
|
|
27312
|
+
if (option2 !== "--url" && option2 !== "--code" && option2 !== "--pairing" && option2 !== "--workspace") {
|
|
27311
27313
|
throw new PairingClientError("invalid_arguments", `Unknown pairing option: ${option2 ?? "missing option"}`);
|
|
27312
27314
|
}
|
|
27313
27315
|
}
|
|
@@ -27347,10 +27349,17 @@ function parsePairCommand(arguments_) {
|
|
|
27347
27349
|
assertKnownArguments(arguments_);
|
|
27348
27350
|
return {
|
|
27349
27351
|
code: parsePairingCode(readSingleOption(arguments_, "--code")),
|
|
27352
|
+
pairingId: arguments_.includes("--pairing") ? validatePairingId(readSingleOption(arguments_, "--pairing")) : "",
|
|
27350
27353
|
relayOrigin: parseRelayOrigin(readSingleOption(arguments_, "--url")),
|
|
27351
27354
|
workspace: arguments_.includes("--workspace") ? readSingleOption(arguments_, "--workspace") : loadDefaultWorkspace()
|
|
27352
27355
|
};
|
|
27353
27356
|
}
|
|
27357
|
+
function validatePairingId(value) {
|
|
27358
|
+
if (!IDENTIFIER_PATTERN6.test(value)) {
|
|
27359
|
+
throw new PairingClientError("invalid_pairing_id", "The Runtime pairing ID is invalid");
|
|
27360
|
+
}
|
|
27361
|
+
return value;
|
|
27362
|
+
}
|
|
27354
27363
|
function parseChannelArgument(arguments_) {
|
|
27355
27364
|
if (arguments_.length !== 2 || arguments_[0] !== "--channel") {
|
|
27356
27365
|
throw new PairingClientError("invalid_arguments", "Usage: mobius start --channel <channel-id>");
|
|
@@ -27407,17 +27416,17 @@ function readRelayError(value) {
|
|
|
27407
27416
|
}
|
|
27408
27417
|
return new PairingClientError("pairing_failed", "The relay could not pair this machine");
|
|
27409
27418
|
}
|
|
27410
|
-
function
|
|
27411
|
-
if (!isRecord11(value) || !hasExactKeys(value,
|
|
27419
|
+
function decodePairingResponse(value, credentialField, expectedKeys) {
|
|
27420
|
+
if (!isRecord11(value) || !hasExactKeys(value, expectedKeys)) {
|
|
27412
27421
|
throw new PairingClientError("invalid_relay_response", "The relay returned an invalid pairing response");
|
|
27413
27422
|
}
|
|
27414
27423
|
const channelId = value["channelId"];
|
|
27415
|
-
const
|
|
27424
|
+
const runtimeCredential = value[credentialField];
|
|
27416
27425
|
const runtimeId = value["runtimeId"];
|
|
27417
|
-
if (typeof channelId !== "string" || !IDENTIFIER_PATTERN6.test(channelId) || typeof
|
|
27426
|
+
if (typeof channelId !== "string" || !IDENTIFIER_PATTERN6.test(channelId) || typeof runtimeCredential !== "string" || !TOKEN_PATTERN2.test(runtimeCredential) || typeof runtimeId !== "string" || !IDENTIFIER_PATTERN6.test(runtimeId)) {
|
|
27418
27427
|
throw new PairingClientError("invalid_relay_response", "The relay returned an invalid pairing response");
|
|
27419
27428
|
}
|
|
27420
|
-
return { channelId,
|
|
27429
|
+
return { channelId, runtimeCredential, runtimeId };
|
|
27421
27430
|
}
|
|
27422
27431
|
async function claimPairing(options, defaultWorkspace, localAgents, installableAgents, signal) {
|
|
27423
27432
|
const agents = localAgents.map((agent) => ({
|
|
@@ -27427,7 +27436,7 @@ async function claimPairing(options, defaultWorkspace, localAgents, installableA
|
|
|
27427
27436
|
id: agent.id,
|
|
27428
27437
|
label: agent.label
|
|
27429
27438
|
}));
|
|
27430
|
-
const endpoint = mobiusApiUrl(options.relayOrigin, "/pairings/claim");
|
|
27439
|
+
const endpoint = options.pairingId.length > 0 ? mobiusApiUrl(options.relayOrigin, `/v1/runtime-pairings/${encodeURIComponent(options.pairingId)}/redeem`) : mobiusApiUrl(options.relayOrigin, "/pairings/claim");
|
|
27431
27440
|
let response;
|
|
27432
27441
|
try {
|
|
27433
27442
|
response = await fetch3(endpoint, {
|
|
@@ -27450,10 +27459,10 @@ async function claimPairing(options, defaultWorkspace, localAgents, installableA
|
|
|
27450
27459
|
if (!response.ok) {
|
|
27451
27460
|
throw readRelayError(value);
|
|
27452
27461
|
}
|
|
27453
|
-
return
|
|
27462
|
+
return options.pairingId.length > 0 ? decodePairingResponse(value, "runtimeCredential", REDEEM_RESPONSE_KEYS) : decodePairingResponse(value, "daemonToken", CLAIM_RESPONSE_KEYS);
|
|
27454
27463
|
}
|
|
27455
|
-
async function persistConnection(channelId, relayOrigin,
|
|
27456
|
-
const connectionsDirectory = join14(readStateDirectory(), "connections");
|
|
27464
|
+
async function persistConnection(channelId, relayOrigin, runtimeCredential, defaultWorkspace, environment) {
|
|
27465
|
+
const connectionsDirectory = join14(readStateDirectory(environment), "connections");
|
|
27457
27466
|
await mkdir4(connectionsDirectory, { mode: 448, recursive: true });
|
|
27458
27467
|
const connectionPath = join14(connectionsDirectory, `${channelId}.json`);
|
|
27459
27468
|
const temporaryPath = join14(connectionsDirectory, `.${channelId}.${randomUUID3()}.tmp`);
|
|
@@ -27463,8 +27472,8 @@ async function persistConnection(channelId, relayOrigin, daemonToken2, defaultWo
|
|
|
27463
27472
|
{
|
|
27464
27473
|
defaultWorkspace,
|
|
27465
27474
|
channelId,
|
|
27466
|
-
|
|
27467
|
-
|
|
27475
|
+
relayOrigin: relayOrigin.toString(),
|
|
27476
|
+
runtimeCredential
|
|
27468
27477
|
},
|
|
27469
27478
|
null,
|
|
27470
27479
|
2
|
|
@@ -27476,25 +27485,25 @@ async function persistConnection(channelId, relayOrigin, daemonToken2, defaultWo
|
|
|
27476
27485
|
return connectionPath;
|
|
27477
27486
|
}
|
|
27478
27487
|
function decodeSavedConnection(value, expectedChannelId) {
|
|
27479
|
-
if (!isRecord11(value) || !hasExactKeys(value, SAVED_CONNECTION_KEYS)) {
|
|
27488
|
+
if (!isRecord11(value) || !hasExactKeys(value, SAVED_CONNECTION_KEYS) && !hasExactKeys(value, LEGACY_SAVED_CONNECTION_KEYS)) {
|
|
27480
27489
|
throw new PairingClientError("invalid_connection", "The saved connection is invalid");
|
|
27481
27490
|
}
|
|
27482
27491
|
const defaultWorkspace = value["defaultWorkspace"];
|
|
27483
27492
|
const channelId = value["channelId"];
|
|
27484
|
-
const
|
|
27493
|
+
const runtimeCredential = value["runtimeCredential"] ?? value["daemonToken"];
|
|
27485
27494
|
const relayOrigin = value["relayOrigin"];
|
|
27486
|
-
if (typeof defaultWorkspace !== "string" || typeof channelId !== "string" || channelId !== expectedChannelId || !IDENTIFIER_PATTERN6.test(channelId) || typeof
|
|
27495
|
+
if (typeof defaultWorkspace !== "string" || typeof channelId !== "string" || channelId !== expectedChannelId || !IDENTIFIER_PATTERN6.test(channelId) || typeof runtimeCredential !== "string" || !TOKEN_PATTERN2.test(runtimeCredential) || typeof relayOrigin !== "string") {
|
|
27487
27496
|
throw new PairingClientError("invalid_connection", "The saved connection is invalid");
|
|
27488
27497
|
}
|
|
27489
27498
|
return {
|
|
27490
27499
|
defaultWorkspace,
|
|
27491
27500
|
channelId,
|
|
27492
|
-
|
|
27493
|
-
|
|
27501
|
+
relayOrigin: parseRelayOrigin(relayOrigin),
|
|
27502
|
+
runtimeCredential
|
|
27494
27503
|
};
|
|
27495
27504
|
}
|
|
27496
|
-
async function readSavedConnection(channelId) {
|
|
27497
|
-
const connectionPath = join14(readStateDirectory(), "connections", `${channelId}.json`);
|
|
27505
|
+
async function readSavedConnection(channelId, environment) {
|
|
27506
|
+
const connectionPath = join14(readStateDirectory(environment), "connections", `${channelId}.json`);
|
|
27498
27507
|
let encoded = "";
|
|
27499
27508
|
const handle = await open4(connectionPath, "r");
|
|
27500
27509
|
try {
|
|
@@ -27516,8 +27525,8 @@ async function readSavedConnection(channelId) {
|
|
|
27516
27525
|
return {
|
|
27517
27526
|
defaultWorkspace: await resolveDefaultWorkspace(connection.defaultWorkspace),
|
|
27518
27527
|
channelId: connection.channelId,
|
|
27519
|
-
|
|
27520
|
-
|
|
27528
|
+
relayOrigin: connection.relayOrigin,
|
|
27529
|
+
runtimeCredential: connection.runtimeCredential
|
|
27521
27530
|
};
|
|
27522
27531
|
}
|
|
27523
27532
|
function assertInventoryUsable(inventory) {
|
|
@@ -27525,15 +27534,12 @@ function assertInventoryUsable(inventory) {
|
|
|
27525
27534
|
throw new PairingClientError("no_supported_agent", "No supported Agent is available for local discovery");
|
|
27526
27535
|
}
|
|
27527
27536
|
}
|
|
27528
|
-
function buildPairedDaemon(connection, connectionPath, inventory) {
|
|
27537
|
+
function buildPairedDaemon(connection, connectionPath, inventory, environment) {
|
|
27529
27538
|
assertInventoryUsable(inventory);
|
|
27530
|
-
const relayUrl = mobiusApiUrl(
|
|
27531
|
-
connection.relayOrigin,
|
|
27532
|
-
`/channels/${encodeURIComponent(connection.channelId)}/daemon`
|
|
27533
|
-
);
|
|
27539
|
+
const relayUrl = mobiusApiUrl(connection.relayOrigin, "/v1/runtimes/connect");
|
|
27534
27540
|
relayUrl.protocol = relayUrl.protocol === "https:" ? "wss:" : "ws:";
|
|
27535
|
-
relayUrl.searchParams.set("token", connection.
|
|
27536
|
-
const auditDatabasePath = join14(readStateDirectory(), "audit", `${connection.channelId}.sqlite`);
|
|
27541
|
+
relayUrl.searchParams.set("token", connection.runtimeCredential);
|
|
27542
|
+
const auditDatabasePath = join14(readStateDirectory(environment), "audit", `${connection.channelId}.sqlite`);
|
|
27537
27543
|
return {
|
|
27538
27544
|
channelUrl: new URL(`/channels/${encodeURIComponent(connection.channelId)}`, connection.relayOrigin).toString(),
|
|
27539
27545
|
config: createDaemonConfig(
|
|
@@ -27549,12 +27555,11 @@ function buildPairedDaemon(connection, connectionPath, inventory) {
|
|
|
27549
27555
|
connectionPath
|
|
27550
27556
|
};
|
|
27551
27557
|
}
|
|
27552
|
-
async function
|
|
27553
|
-
const options = parsePairCommand(arguments_);
|
|
27558
|
+
async function pairRuntime(options, signal, environment) {
|
|
27554
27559
|
const defaultWorkspace = await resolveDefaultWorkspace(options.workspace);
|
|
27555
27560
|
const inventory = await discoverLocalAgentInventory({
|
|
27556
27561
|
defaultWorkspace,
|
|
27557
|
-
environment
|
|
27562
|
+
environment,
|
|
27558
27563
|
signal
|
|
27559
27564
|
});
|
|
27560
27565
|
assertInventoryUsable(inventory);
|
|
@@ -27563,30 +27568,50 @@ async function pairLocalMachine(arguments_, signal = new AbortController().signa
|
|
|
27563
27568
|
const connectionPath = await persistConnection(
|
|
27564
27569
|
claim2.channelId,
|
|
27565
27570
|
options.relayOrigin,
|
|
27566
|
-
claim2.
|
|
27567
|
-
defaultWorkspace
|
|
27571
|
+
claim2.runtimeCredential,
|
|
27572
|
+
defaultWorkspace,
|
|
27573
|
+
environment
|
|
27568
27574
|
);
|
|
27569
27575
|
return buildPairedDaemon(
|
|
27570
27576
|
{
|
|
27571
27577
|
defaultWorkspace,
|
|
27572
27578
|
channelId: claim2.channelId,
|
|
27573
|
-
|
|
27574
|
-
|
|
27579
|
+
relayOrigin: options.relayOrigin,
|
|
27580
|
+
runtimeCredential: claim2.runtimeCredential
|
|
27575
27581
|
},
|
|
27576
27582
|
connectionPath,
|
|
27577
|
-
inventory
|
|
27583
|
+
inventory,
|
|
27584
|
+
environment
|
|
27578
27585
|
);
|
|
27579
27586
|
}
|
|
27580
|
-
async function
|
|
27581
|
-
|
|
27582
|
-
|
|
27583
|
-
|
|
27587
|
+
async function pairMobiusRuntime(options, signal, environment = process.env) {
|
|
27588
|
+
return await pairRuntime(
|
|
27589
|
+
{
|
|
27590
|
+
code: parsePairingCode(options.pairingCode),
|
|
27591
|
+
pairingId: validatePairingId(options.pairingId),
|
|
27592
|
+
relayOrigin: parseRelayOrigin(options.relayOrigin),
|
|
27593
|
+
workspace: options.defaultWorkspace
|
|
27594
|
+
},
|
|
27595
|
+
signal,
|
|
27596
|
+
environment
|
|
27597
|
+
);
|
|
27598
|
+
}
|
|
27599
|
+
async function pairLocalMachine(arguments_, signal = new AbortController().signal) {
|
|
27600
|
+
return await pairRuntime(parsePairCommand(arguments_), signal, process.env);
|
|
27601
|
+
}
|
|
27602
|
+
async function resumeMobiusRuntime(channelId, signal, environment = process.env) {
|
|
27603
|
+
const normalizedChannelId = validatePairingId(channelId);
|
|
27604
|
+
const connectionPath = join14(readStateDirectory(environment), "connections", `${normalizedChannelId}.json`);
|
|
27605
|
+
const connection = await readSavedConnection(normalizedChannelId, environment);
|
|
27584
27606
|
const inventory = await discoverLocalAgentInventory({
|
|
27585
27607
|
defaultWorkspace: connection.defaultWorkspace,
|
|
27586
|
-
environment
|
|
27608
|
+
environment,
|
|
27587
27609
|
signal
|
|
27588
27610
|
});
|
|
27589
|
-
return buildPairedDaemon(connection, connectionPath, inventory);
|
|
27611
|
+
return buildPairedDaemon(connection, connectionPath, inventory, environment);
|
|
27612
|
+
}
|
|
27613
|
+
async function resumeLocalMachine(arguments_, signal = new AbortController().signal) {
|
|
27614
|
+
return await resumeMobiusRuntime(parseChannelArgument(arguments_), signal, process.env);
|
|
27590
27615
|
}
|
|
27591
27616
|
|
|
27592
27617
|
// src/run-daemon.ts
|
|
@@ -27605,14 +27630,19 @@ var AgentCatalogPublishError = class extends Error {
|
|
|
27605
27630
|
this.name = "AgentCatalogPublishError";
|
|
27606
27631
|
}
|
|
27607
27632
|
};
|
|
27608
|
-
function catalogEndpoint(
|
|
27609
|
-
const endpoint = new URL(relayUrl);
|
|
27633
|
+
function catalogEndpoint(config2) {
|
|
27634
|
+
const endpoint = new URL(config2.relayUrl);
|
|
27610
27635
|
endpoint.protocol = endpoint.protocol === "wss:" ? "https:" : "http:";
|
|
27611
|
-
if (
|
|
27612
|
-
|
|
27636
|
+
if (endpoint.pathname.endsWith("/daemon")) {
|
|
27637
|
+
endpoint.pathname = `${endpoint.pathname.slice(0, -"/daemon".length)}/catalog`;
|
|
27638
|
+
return endpoint;
|
|
27613
27639
|
}
|
|
27614
|
-
|
|
27615
|
-
|
|
27640
|
+
const runtimePath = "/v1/runtimes/connect";
|
|
27641
|
+
if (endpoint.pathname.endsWith(runtimePath)) {
|
|
27642
|
+
endpoint.pathname = `${endpoint.pathname.slice(0, -runtimePath.length)}/channels/${encodeURIComponent(config2.channelId)}/catalog`;
|
|
27643
|
+
return endpoint;
|
|
27644
|
+
}
|
|
27645
|
+
throw new AgentCatalogPublishError("The Relay URL is invalid");
|
|
27616
27646
|
}
|
|
27617
27647
|
async function publishAgentCatalog(config2, signal) {
|
|
27618
27648
|
signal.throwIfAborted();
|
|
@@ -27621,7 +27651,7 @@ async function publishAgentCatalog(config2, signal) {
|
|
|
27621
27651
|
let response;
|
|
27622
27652
|
const catalog = config2.catalog.read();
|
|
27623
27653
|
try {
|
|
27624
|
-
response = await fetch4(catalogEndpoint(config2
|
|
27654
|
+
response = await fetch4(catalogEndpoint(config2), {
|
|
27625
27655
|
body: JSON.stringify({
|
|
27626
27656
|
agents: catalog.agents.map((agent) => ({
|
|
27627
27657
|
agentPath: agent.agentIdentity.requestedPath,
|
|
@@ -28991,10 +29021,17 @@ function parseReference(resource) {
|
|
|
28991
29021
|
function downloadUrl(config2, command, reference) {
|
|
28992
29022
|
const url2 = new URL(config2.relayUrl);
|
|
28993
29023
|
url2.protocol = url2.protocol === "wss:" ? "https:" : "http:";
|
|
28994
|
-
|
|
28995
|
-
|
|
29024
|
+
let channelPath = "";
|
|
29025
|
+
if (url2.pathname.endsWith("/daemon")) {
|
|
29026
|
+
channelPath = url2.pathname.slice(0, -"/daemon".length);
|
|
29027
|
+
} else {
|
|
29028
|
+
const runtimePath = "/v1/runtimes/connect";
|
|
29029
|
+
if (!url2.pathname.endsWith(runtimePath)) {
|
|
29030
|
+
throw new PromptArtifactError("artifact_endpoint_invalid", "The Relay artifact endpoint is invalid");
|
|
29031
|
+
}
|
|
29032
|
+
channelPath = `${url2.pathname.slice(0, -runtimePath.length)}/channels/${encodeURIComponent(config2.channelId)}`;
|
|
28996
29033
|
}
|
|
28997
|
-
url2.pathname = `${
|
|
29034
|
+
url2.pathname = `${channelPath}/sessions/${encodeURIComponent(command.sessionId)}/commands/${encodeURIComponent(command.commandId)}/artifacts/${encodeURIComponent(reference.artifactId)}/content`;
|
|
28998
29035
|
url2.searchParams.delete("liveness");
|
|
28999
29036
|
return url2;
|
|
29000
29037
|
}
|
|
@@ -29152,9 +29189,17 @@ var RelayConnectionError = class extends Error {
|
|
|
29152
29189
|
};
|
|
29153
29190
|
function connectRelay(url2, signal) {
|
|
29154
29191
|
signal.throwIfAborted();
|
|
29155
|
-
return new Promise((
|
|
29156
|
-
const
|
|
29157
|
-
|
|
29192
|
+
return new Promise((resolve6, reject) => {
|
|
29193
|
+
const endpoint = new URL(url2);
|
|
29194
|
+
const headers = {};
|
|
29195
|
+
if (endpoint.pathname.endsWith("/v1/runtimes/connect")) {
|
|
29196
|
+
const runtimeCredential = endpoint.searchParams.get("token") ?? "";
|
|
29197
|
+
endpoint.searchParams.delete("token");
|
|
29198
|
+
headers["authorization"] = `Bearer ${runtimeCredential}`;
|
|
29199
|
+
}
|
|
29200
|
+
const socket = new WebSocket(endpoint, {
|
|
29201
|
+
dispatcher: environmentProxyDispatcher,
|
|
29202
|
+
headers
|
|
29158
29203
|
});
|
|
29159
29204
|
let finished = false;
|
|
29160
29205
|
const timeout = setTimeout(onTimeout, CONNECTION_TIMEOUT_MILLISECONDS);
|
|
@@ -29193,7 +29238,7 @@ function connectRelay(url2, signal) {
|
|
|
29193
29238
|
}
|
|
29194
29239
|
finished = true;
|
|
29195
29240
|
cleanup();
|
|
29196
|
-
|
|
29241
|
+
resolve6(socket);
|
|
29197
29242
|
};
|
|
29198
29243
|
function onTimeout() {
|
|
29199
29244
|
fail(new RelayConnectionError("relay_connection_timeout", "Relay connection timed out"));
|
|
@@ -29775,10 +29820,17 @@ var ActiveTurnReconciliationError = class extends Error {
|
|
|
29775
29820
|
function activeTurnReconciliationEndpoint(config2, turn) {
|
|
29776
29821
|
const endpoint = new URL(config2.relayUrl);
|
|
29777
29822
|
endpoint.protocol = endpoint.protocol === "wss:" ? "https:" : "http:";
|
|
29778
|
-
|
|
29779
|
-
|
|
29823
|
+
let channelPath = "";
|
|
29824
|
+
if (endpoint.pathname.endsWith("/daemon")) {
|
|
29825
|
+
channelPath = endpoint.pathname.slice(0, -"/daemon".length);
|
|
29826
|
+
} else {
|
|
29827
|
+
const runtimePath = "/v1/runtimes/connect";
|
|
29828
|
+
if (!endpoint.pathname.endsWith(runtimePath)) {
|
|
29829
|
+
throw new ActiveTurnReconciliationError("The Relay URL is invalid");
|
|
29830
|
+
}
|
|
29831
|
+
channelPath = `${endpoint.pathname.slice(0, -runtimePath.length)}/channels/${encodeURIComponent(config2.channelId)}`;
|
|
29780
29832
|
}
|
|
29781
|
-
endpoint.pathname = `${
|
|
29833
|
+
endpoint.pathname = `${channelPath}/sessions/${encodeURIComponent(turn.command.sessionId)}/attempts/${encodeURIComponent(turn.attemptId)}/reconciliation`;
|
|
29782
29834
|
endpoint.searchParams.delete("liveness");
|
|
29783
29835
|
return endpoint;
|
|
29784
29836
|
}
|
|
@@ -30391,12 +30443,12 @@ function waitForRelayRetry(signal, timer) {
|
|
|
30391
30443
|
if (signal.aborted) {
|
|
30392
30444
|
return Promise.resolve();
|
|
30393
30445
|
}
|
|
30394
|
-
return new Promise((
|
|
30446
|
+
return new Promise((resolve6) => {
|
|
30395
30447
|
const retry = timer.schedule(finish, RELAY_RECONNECT_DELAY_MILLISECONDS);
|
|
30396
30448
|
function finish() {
|
|
30397
30449
|
retry.cancel();
|
|
30398
30450
|
signal.removeEventListener("abort", finish);
|
|
30399
|
-
|
|
30451
|
+
resolve6();
|
|
30400
30452
|
}
|
|
30401
30453
|
signal.addEventListener("abort", finish, { once: true });
|
|
30402
30454
|
});
|
|
@@ -30433,7 +30485,7 @@ async function runRelayConnection(config2, directories, audit, sessions, install
|
|
|
30433
30485
|
const nativeRequests = /* @__PURE__ */ new Map();
|
|
30434
30486
|
installationObserver.connect(socket);
|
|
30435
30487
|
try {
|
|
30436
|
-
await new Promise((
|
|
30488
|
+
await new Promise((resolve6, reject) => {
|
|
30437
30489
|
let finished = false;
|
|
30438
30490
|
const cleanup = () => {
|
|
30439
30491
|
connectionRefresh.close();
|
|
@@ -30452,7 +30504,7 @@ async function runRelayConnection(config2, directories, audit, sessions, install
|
|
|
30452
30504
|
}
|
|
30453
30505
|
finished = true;
|
|
30454
30506
|
cleanup();
|
|
30455
|
-
|
|
30507
|
+
resolve6();
|
|
30456
30508
|
};
|
|
30457
30509
|
const rejectConnection = () => {
|
|
30458
30510
|
if (finished) {
|
|
@@ -30632,7 +30684,7 @@ async function runRelayConnection(config2, directories, audit, sessions, install
|
|
|
30632
30684
|
try {
|
|
30633
30685
|
operationSignal.throwIfAborted();
|
|
30634
30686
|
if (previous.length > 0) {
|
|
30635
|
-
await new Promise((
|
|
30687
|
+
await new Promise((resolve7, reject2) => {
|
|
30636
30688
|
const cancel = () => reject2(operationSignal.reason);
|
|
30637
30689
|
operationSignal.addEventListener("abort", cancel, {
|
|
30638
30690
|
once: true
|
|
@@ -30640,7 +30692,7 @@ async function runRelayConnection(config2, directories, audit, sessions, install
|
|
|
30640
30692
|
void Promise.all(previous.map((request) => request.completion)).then(
|
|
30641
30693
|
() => {
|
|
30642
30694
|
operationSignal.removeEventListener("abort", cancel);
|
|
30643
|
-
|
|
30695
|
+
resolve7();
|
|
30644
30696
|
},
|
|
30645
30697
|
(error61) => {
|
|
30646
30698
|
operationSignal.removeEventListener("abort", cancel);
|
|
@@ -30714,13 +30766,13 @@ async function runRelayConnection(config2, directories, audit, sessions, install
|
|
|
30714
30766
|
try {
|
|
30715
30767
|
operationSignal.throwIfAborted();
|
|
30716
30768
|
if (previous.length > 0) {
|
|
30717
|
-
await new Promise((
|
|
30769
|
+
await new Promise((resolve7, reject2) => {
|
|
30718
30770
|
const cancel = () => reject2(operationSignal.reason);
|
|
30719
30771
|
operationSignal.addEventListener("abort", cancel, { once: true });
|
|
30720
30772
|
void Promise.all(previous.map((request) => request.completion)).then(
|
|
30721
30773
|
() => {
|
|
30722
30774
|
operationSignal.removeEventListener("abort", cancel);
|
|
30723
|
-
|
|
30775
|
+
resolve7();
|
|
30724
30776
|
},
|
|
30725
30777
|
(error61) => {
|
|
30726
30778
|
operationSignal.removeEventListener("abort", cancel);
|
|
@@ -31102,6 +31154,147 @@ async function runDaemon(config2, audit, signal, timer = systemDaemonTimer) {
|
|
|
31102
31154
|
}
|
|
31103
31155
|
}
|
|
31104
31156
|
}
|
|
31157
|
+
|
|
31158
|
+
// src/runtime.ts
|
|
31159
|
+
import { mkdir as mkdir5, realpath as realpath8, stat as stat8 } from "node:fs/promises";
|
|
31160
|
+
import { dirname as dirname8, join as join17, resolve as resolve5 } from "node:path";
|
|
31161
|
+
var APP_CREDENTIAL_PATTERN = /^mapp_[a-zA-Z0-9_-]{22}_[a-zA-Z0-9_-]{43}$/;
|
|
31162
|
+
var CONVERSATION_CREDENTIAL_PATTERN = /^mconv_[a-zA-Z0-9_-]{22}_[a-zA-Z0-9_-]{43}$/;
|
|
31163
|
+
var IDENTIFIER_PATTERN8 = /^[a-zA-Z0-9][a-zA-Z0-9._:-]{0,127}$/;
|
|
31164
|
+
var RUNTIME_CREDENTIAL_PATTERN = /^[a-zA-Z0-9_-]{32,256}$/;
|
|
31165
|
+
var MobiusRuntimeConfigurationError = class extends Error {
|
|
31166
|
+
code = "runtime_configuration_invalid";
|
|
31167
|
+
constructor(message, options = {}) {
|
|
31168
|
+
super(message, options);
|
|
31169
|
+
this.name = "MobiusRuntimeConfigurationError";
|
|
31170
|
+
}
|
|
31171
|
+
};
|
|
31172
|
+
var MobiusRuntimeState = class {
|
|
31173
|
+
};
|
|
31174
|
+
var IdleMobiusRuntimeState = class extends MobiusRuntimeState {
|
|
31175
|
+
};
|
|
31176
|
+
var RunningMobiusRuntimeState = class extends MobiusRuntimeState {
|
|
31177
|
+
};
|
|
31178
|
+
var FinishedMobiusRuntimeState = class extends MobiusRuntimeState {
|
|
31179
|
+
};
|
|
31180
|
+
function validateRuntimeRelay(relayUrl) {
|
|
31181
|
+
if (relayUrl.protocol !== "ws:" && relayUrl.protocol !== "wss:") {
|
|
31182
|
+
throw new MobiusRuntimeConfigurationError("The Runtime relay URL must use WebSocket transport");
|
|
31183
|
+
}
|
|
31184
|
+
const credential = relayUrl.searchParams.get("token") ?? "";
|
|
31185
|
+
if (credential.length === 0) {
|
|
31186
|
+
throw new MobiusRuntimeConfigurationError("The Runtime relay credential is required");
|
|
31187
|
+
}
|
|
31188
|
+
if (APP_CREDENTIAL_PATTERN.test(credential)) {
|
|
31189
|
+
throw new MobiusRuntimeConfigurationError("An AppCredential cannot be held by a local Runtime");
|
|
31190
|
+
}
|
|
31191
|
+
if (CONVERSATION_CREDENTIAL_PATTERN.test(credential)) {
|
|
31192
|
+
throw new MobiusRuntimeConfigurationError("A ConversationAccessToken cannot be held by a local Runtime");
|
|
31193
|
+
}
|
|
31194
|
+
if (!RUNTIME_CREDENTIAL_PATTERN.test(credential)) {
|
|
31195
|
+
throw new MobiusRuntimeConfigurationError("The Runtime relay credential is invalid");
|
|
31196
|
+
}
|
|
31197
|
+
}
|
|
31198
|
+
function validateRuntimeConfiguration(config2) {
|
|
31199
|
+
validateRuntimeRelay(config2.relayUrl);
|
|
31200
|
+
}
|
|
31201
|
+
function requiredEnvironmentValue(environment, name) {
|
|
31202
|
+
const value = environment[name]?.trim();
|
|
31203
|
+
if (value === void 0 || value.length === 0) {
|
|
31204
|
+
throw new MobiusRuntimeConfigurationError(`${name} is required`);
|
|
31205
|
+
}
|
|
31206
|
+
return value;
|
|
31207
|
+
}
|
|
31208
|
+
function relayUrlFromConnection(connection) {
|
|
31209
|
+
let relayUrl;
|
|
31210
|
+
try {
|
|
31211
|
+
relayUrl = new URL(connection.relayUrl);
|
|
31212
|
+
} catch (error61) {
|
|
31213
|
+
throw new MobiusRuntimeConfigurationError("The Runtime relay URL is invalid", { cause: error61 });
|
|
31214
|
+
}
|
|
31215
|
+
relayUrl.searchParams.set("token", connection.runtimeCredential);
|
|
31216
|
+
validateRuntimeRelay(relayUrl);
|
|
31217
|
+
return relayUrl;
|
|
31218
|
+
}
|
|
31219
|
+
function loadMobiusRuntimeConnection(environment = process.env) {
|
|
31220
|
+
const channelId = requiredEnvironmentValue(environment, "MOBIUS_CHANNEL_ID");
|
|
31221
|
+
if (!IDENTIFIER_PATTERN8.test(channelId)) {
|
|
31222
|
+
throw new MobiusRuntimeConfigurationError("MOBIUS_CHANNEL_ID is invalid");
|
|
31223
|
+
}
|
|
31224
|
+
return Object.freeze({
|
|
31225
|
+
auditDatabasePath: environment["MOBIUS_AUDIT_DATABASE"]?.trim() || join17(readStateDirectory(environment), "audit", `${channelId}.sqlite`),
|
|
31226
|
+
channelId,
|
|
31227
|
+
defaultWorkspace: loadDefaultWorkspace(environment),
|
|
31228
|
+
relayUrl: requiredEnvironmentValue(environment, "MOBIUS_RELAY_URL"),
|
|
31229
|
+
runtimeCredential: requiredEnvironmentValue(environment, "MOBIUS_RELAY_TOKEN")
|
|
31230
|
+
});
|
|
31231
|
+
}
|
|
31232
|
+
async function resolveWorkspace(path2) {
|
|
31233
|
+
const requested = resolve5(path2);
|
|
31234
|
+
try {
|
|
31235
|
+
await mkdir5(requested, { recursive: true, mode: 448 });
|
|
31236
|
+
const resolved = await realpath8(requested);
|
|
31237
|
+
const metadata = await stat8(resolved);
|
|
31238
|
+
if (!metadata.isDirectory()) {
|
|
31239
|
+
throw new MobiusRuntimeConfigurationError("The Runtime workspace is not a directory");
|
|
31240
|
+
}
|
|
31241
|
+
return resolved;
|
|
31242
|
+
} catch (error61) {
|
|
31243
|
+
if (error61 instanceof MobiusRuntimeConfigurationError) {
|
|
31244
|
+
throw error61;
|
|
31245
|
+
}
|
|
31246
|
+
throw new MobiusRuntimeConfigurationError("The Runtime workspace cannot be resolved", { cause: error61 });
|
|
31247
|
+
}
|
|
31248
|
+
}
|
|
31249
|
+
async function createMobiusRuntimeEngine(connection, signal, environment = process.env) {
|
|
31250
|
+
signal.throwIfAborted();
|
|
31251
|
+
const relayUrl = relayUrlFromConnection(connection);
|
|
31252
|
+
const defaultWorkspace = await resolveWorkspace(connection.defaultWorkspace);
|
|
31253
|
+
const auditDatabasePath = resolve5(connection.auditDatabasePath);
|
|
31254
|
+
await mkdir5(dirname8(auditDatabasePath), { recursive: true, mode: 448 });
|
|
31255
|
+
const inventory = await discoverLocalAgentInventory({
|
|
31256
|
+
defaultWorkspace,
|
|
31257
|
+
environment,
|
|
31258
|
+
signal
|
|
31259
|
+
});
|
|
31260
|
+
if (inventory.available.length + inventory.installable.length === 0) {
|
|
31261
|
+
throw new MobiusRuntimeConfigurationError("No supported Agent is available for the local Runtime");
|
|
31262
|
+
}
|
|
31263
|
+
return new MobiusRuntimeEngine(
|
|
31264
|
+
createDaemonConfig(
|
|
31265
|
+
{
|
|
31266
|
+
auditDatabasePath,
|
|
31267
|
+
channelId: connection.channelId,
|
|
31268
|
+
defaultWorkspace,
|
|
31269
|
+
relayUrl
|
|
31270
|
+
},
|
|
31271
|
+
inventory.readyAgents(),
|
|
31272
|
+
inventory.installable
|
|
31273
|
+
)
|
|
31274
|
+
);
|
|
31275
|
+
}
|
|
31276
|
+
var MobiusRuntimeEngine = class {
|
|
31277
|
+
#config;
|
|
31278
|
+
#state = new IdleMobiusRuntimeState();
|
|
31279
|
+
constructor(config2) {
|
|
31280
|
+
validateRuntimeConfiguration(config2);
|
|
31281
|
+
this.#config = config2;
|
|
31282
|
+
}
|
|
31283
|
+
run = async (signal) => {
|
|
31284
|
+
if (!(this.#state instanceof IdleMobiusRuntimeState)) {
|
|
31285
|
+
throw new MobiusRuntimeConfigurationError("A Mobius Runtime engine can only be started once");
|
|
31286
|
+
}
|
|
31287
|
+
signal.throwIfAborted();
|
|
31288
|
+
this.#state = new RunningMobiusRuntimeState();
|
|
31289
|
+
const audit = new AuditStore(this.#config.auditDatabasePath);
|
|
31290
|
+
try {
|
|
31291
|
+
await runDaemon(this.#config, audit, signal);
|
|
31292
|
+
} finally {
|
|
31293
|
+
audit.close();
|
|
31294
|
+
this.#state = new FinishedMobiusRuntimeState();
|
|
31295
|
+
}
|
|
31296
|
+
};
|
|
31297
|
+
};
|
|
31105
31298
|
export {
|
|
31106
31299
|
AcpExecutionError,
|
|
31107
31300
|
AuditStore,
|
|
@@ -31109,12 +31302,18 @@ export {
|
|
|
31109
31302
|
BotMessageCommandError,
|
|
31110
31303
|
BotOutboundIpcServer,
|
|
31111
31304
|
LocalAuthorizationError,
|
|
31305
|
+
MobiusRuntimeConfigurationError,
|
|
31306
|
+
MobiusRuntimeEngine,
|
|
31112
31307
|
PairingClientError,
|
|
31113
31308
|
createAcpClient,
|
|
31309
|
+
createMobiusRuntimeEngine,
|
|
31114
31310
|
executeBotMessageCommand,
|
|
31115
31311
|
loadDaemonConfig,
|
|
31312
|
+
loadMobiusRuntimeConnection,
|
|
31116
31313
|
pairLocalMachine,
|
|
31314
|
+
pairMobiusRuntime,
|
|
31117
31315
|
resumeLocalMachine,
|
|
31316
|
+
resumeMobiusRuntime,
|
|
31118
31317
|
runAcpPrompt,
|
|
31119
31318
|
runDaemon
|
|
31120
31319
|
};
|