@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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"publish-agent-catalog.d.ts","sourceRoot":"","sources":["../../src/agent-catalog/publish-agent-catalog.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"publish-agent-catalog.d.ts","sourceRoot":"","sources":["../../src/agent-catalog/publish-agent-catalog.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AA6BjD,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAoClG"}
|
|
@@ -8,14 +8,19 @@ class AgentCatalogPublishError extends Error {
|
|
|
8
8
|
this.name = "AgentCatalogPublishError";
|
|
9
9
|
}
|
|
10
10
|
}
|
|
11
|
-
function catalogEndpoint(
|
|
12
|
-
const endpoint = new URL(relayUrl);
|
|
11
|
+
function catalogEndpoint(config) {
|
|
12
|
+
const endpoint = new URL(config.relayUrl);
|
|
13
13
|
endpoint.protocol = endpoint.protocol === "wss:" ? "https:" : "http:";
|
|
14
|
-
if (
|
|
15
|
-
|
|
14
|
+
if (endpoint.pathname.endsWith("/daemon")) {
|
|
15
|
+
endpoint.pathname = `${endpoint.pathname.slice(0, -"/daemon".length)}/catalog`;
|
|
16
|
+
return endpoint;
|
|
16
17
|
}
|
|
17
|
-
|
|
18
|
-
|
|
18
|
+
const runtimePath = "/v1/runtimes/connect";
|
|
19
|
+
if (endpoint.pathname.endsWith(runtimePath)) {
|
|
20
|
+
endpoint.pathname = `${endpoint.pathname.slice(0, -runtimePath.length)}/channels/${encodeURIComponent(config.channelId)}/catalog`;
|
|
21
|
+
return endpoint;
|
|
22
|
+
}
|
|
23
|
+
throw new AgentCatalogPublishError("The Relay URL is invalid");
|
|
19
24
|
}
|
|
20
25
|
export async function publishAgentCatalog(config, signal) {
|
|
21
26
|
signal.throwIfAborted();
|
|
@@ -24,7 +29,7 @@ export async function publishAgentCatalog(config, signal) {
|
|
|
24
29
|
let response;
|
|
25
30
|
const catalog = config.catalog.read();
|
|
26
31
|
try {
|
|
27
|
-
response = await fetch(catalogEndpoint(config
|
|
32
|
+
response = await fetch(catalogEndpoint(config), {
|
|
28
33
|
body: JSON.stringify({
|
|
29
34
|
agents: catalog.agents.map((agent) => ({
|
|
30
35
|
agentPath: agent.agentIdentity.requestedPath,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"publish-agent-catalog.js","sourceRoot":"","sources":["../../src/agent-catalog/publish-agent-catalog.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAG/B,OAAO,EAAE,0BAA0B,EAAE,MAAM,iCAAiC,CAAC;AAE7E,MAAM,mCAAmC,GAAG,MAAM,CAAC;AAEnD,MAAM,wBAAyB,SAAQ,KAAK;IAC/B,IAAI,GAAG,6BAA6B,CAAC;IAE9C,YAAY,OAAe,EAAE,OAAO,GAAiB,EAAE;QACnD,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,0BAA0B,CAAC;IAC3C,CAAC;CACJ;AAED,SAAS,eAAe,CAAC,
|
|
1
|
+
{"version":3,"file":"publish-agent-catalog.js","sourceRoot":"","sources":["../../src/agent-catalog/publish-agent-catalog.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.js
CHANGED
|
@@ -11,7 +11,7 @@ import { mkdir as mkdir5 } from "node:fs/promises";
|
|
|
11
11
|
// package.json
|
|
12
12
|
var package_default = {
|
|
13
13
|
name: "@moxt-ai/mobius",
|
|
14
|
-
version: "0.0.
|
|
14
|
+
version: "0.0.25",
|
|
15
15
|
description: "Mobius CLI for pairing and running local AI agent services.",
|
|
16
16
|
type: "module",
|
|
17
17
|
bin: {
|
|
@@ -21,6 +21,10 @@ var package_default = {
|
|
|
21
21
|
".": {
|
|
22
22
|
types: "./dist/index.d.ts",
|
|
23
23
|
import: "./dist/index.js"
|
|
24
|
+
},
|
|
25
|
+
"./runtime": {
|
|
26
|
+
types: "./dist/runtime.d.ts",
|
|
27
|
+
import: "./dist/runtime.js"
|
|
24
28
|
}
|
|
25
29
|
},
|
|
26
30
|
files: [
|
|
@@ -38,7 +42,7 @@ var package_default = {
|
|
|
38
42
|
directory: "packages/cli"
|
|
39
43
|
},
|
|
40
44
|
scripts: {
|
|
41
|
-
build: "tsc --project tsconfig.build.json && esbuild src/cli.ts src/index.ts --bundle --platform=node --format=esm --sourcemap --outdir=dist --external:@agentclientprotocol/* --external:undici",
|
|
45
|
+
build: "tsc --project tsconfig.build.json && esbuild src/cli.ts src/index.ts src/runtime.ts --bundle --platform=node --format=esm --sourcemap --outdir=dist --external:@agentclientprotocol/* --external:undici",
|
|
42
46
|
dev: "node --watch src/cli.ts",
|
|
43
47
|
prepack: "pnpm build",
|
|
44
48
|
start: "node dist/cli.js",
|
|
@@ -2578,54 +2582,6 @@ async function discoverLocalAgentInventory(options) {
|
|
|
2578
2582
|
return new LocalAgentInventory(discoveries);
|
|
2579
2583
|
}
|
|
2580
2584
|
|
|
2581
|
-
// src/audit/audit-store.ts
|
|
2582
|
-
import { mkdirSync } from "node:fs";
|
|
2583
|
-
import { dirname as dirname3 } from "node:path";
|
|
2584
|
-
import { DatabaseSync } from "node:sqlite";
|
|
2585
|
-
var AuditStore = class {
|
|
2586
|
-
database;
|
|
2587
|
-
constructor(path2) {
|
|
2588
|
-
mkdirSync(dirname3(path2), { recursive: true });
|
|
2589
|
-
this.database = new DatabaseSync(path2);
|
|
2590
|
-
this.database.exec(`
|
|
2591
|
-
CREATE TABLE IF NOT EXISTS audit_events (
|
|
2592
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
2593
|
-
recorded_at TEXT NOT NULL,
|
|
2594
|
-
event TEXT NOT NULL,
|
|
2595
|
-
command_id TEXT NOT NULL,
|
|
2596
|
-
session_id TEXT NOT NULL,
|
|
2597
|
-
details_json TEXT NOT NULL DEFAULT '{}'
|
|
2598
|
-
) STRICT
|
|
2599
|
-
`);
|
|
2600
|
-
const columns = this.database.prepare("PRAGMA table_info(audit_events)").all();
|
|
2601
|
-
if (!columns.some((column) => Reflect.get(column, "name") === "details_json")) {
|
|
2602
|
-
this.database.exec("ALTER TABLE audit_events ADD COLUMN details_json TEXT NOT NULL DEFAULT '{}'");
|
|
2603
|
-
}
|
|
2604
|
-
}
|
|
2605
|
-
record(record2) {
|
|
2606
|
-
this.database.prepare(
|
|
2607
|
-
`
|
|
2608
|
-
INSERT INTO audit_events (
|
|
2609
|
-
recorded_at,
|
|
2610
|
-
event,
|
|
2611
|
-
command_id,
|
|
2612
|
-
session_id,
|
|
2613
|
-
details_json
|
|
2614
|
-
) VALUES (?, ?, ?, ?, ?)
|
|
2615
|
-
`
|
|
2616
|
-
).run(
|
|
2617
|
-
(/* @__PURE__ */ new Date()).toISOString(),
|
|
2618
|
-
record2.event,
|
|
2619
|
-
record2.commandId,
|
|
2620
|
-
record2.sessionId,
|
|
2621
|
-
JSON.stringify(record2.details ?? {})
|
|
2622
|
-
);
|
|
2623
|
-
}
|
|
2624
|
-
close() {
|
|
2625
|
-
this.database.close();
|
|
2626
|
-
}
|
|
2627
|
-
};
|
|
2628
|
-
|
|
2629
2585
|
// src/bots/bot-message-command.ts
|
|
2630
2586
|
import { randomUUID } from "node:crypto";
|
|
2631
2587
|
import { createConnection } from "node:net";
|
|
@@ -23254,9 +23210,9 @@ var decodeSessionEventAcknowledgement = (encoded) => decode5(encoded, eventAckno
|
|
|
23254
23210
|
var decodeSessionEventRejection = (encoded) => decode5(encoded, eventRejectionSchema);
|
|
23255
23211
|
|
|
23256
23212
|
// src/config.ts
|
|
23257
|
-
function loadDefaultWorkspace() {
|
|
23258
|
-
const { MOBIUS_DEFAULT_WORKSPACE: configuredWorkspace } =
|
|
23259
|
-
return configuredWorkspace ?? join13(readStateDirectory(), "workspace");
|
|
23213
|
+
function loadDefaultWorkspace(environment = process.env) {
|
|
23214
|
+
const { MOBIUS_DEFAULT_WORKSPACE: configuredWorkspace } = environment;
|
|
23215
|
+
return configuredWorkspace ?? join13(readStateDirectory(environment), "workspace");
|
|
23260
23216
|
}
|
|
23261
23217
|
function createDaemonConfig(connection, agents = [], installableAgents = []) {
|
|
23262
23218
|
return {
|
|
@@ -23283,7 +23239,9 @@ var IDENTIFIER_PATTERN5 = /^[a-zA-Z0-9][a-zA-Z0-9._:-]{0,127}$/;
|
|
|
23283
23239
|
var TOKEN_PATTERN2 = /^[a-zA-Z0-9_-]{32,256}$/;
|
|
23284
23240
|
var MAX_CONNECTION_FILE_LENGTH = 16 * 1024;
|
|
23285
23241
|
var CLAIM_RESPONSE_KEYS = ["channelId", "daemonToken", "runtimeId"];
|
|
23286
|
-
var
|
|
23242
|
+
var REDEEM_RESPONSE_KEYS = ["channelId", "runtimeCredential", "runtimeId"];
|
|
23243
|
+
var LEGACY_SAVED_CONNECTION_KEYS = ["defaultWorkspace", "channelId", "daemonToken", "relayOrigin"];
|
|
23244
|
+
var SAVED_CONNECTION_KEYS = ["defaultWorkspace", "channelId", "relayOrigin", "runtimeCredential"];
|
|
23287
23245
|
var PairingClientError = class extends Error {
|
|
23288
23246
|
code;
|
|
23289
23247
|
constructor(code, message, options = {}) {
|
|
@@ -23320,7 +23278,7 @@ function readSingleOption(arguments_, option2) {
|
|
|
23320
23278
|
function assertKnownArguments(arguments_) {
|
|
23321
23279
|
for (let index = 0; index < arguments_.length; index += 2) {
|
|
23322
23280
|
const option2 = arguments_[index];
|
|
23323
|
-
if (option2 !== "--url" && option2 !== "--code" && option2 !== "--workspace") {
|
|
23281
|
+
if (option2 !== "--url" && option2 !== "--code" && option2 !== "--pairing" && option2 !== "--workspace") {
|
|
23324
23282
|
throw new PairingClientError("invalid_arguments", `Unknown pairing option: ${option2 ?? "missing option"}`);
|
|
23325
23283
|
}
|
|
23326
23284
|
}
|
|
@@ -23360,10 +23318,17 @@ function parsePairCommand(arguments_) {
|
|
|
23360
23318
|
assertKnownArguments(arguments_);
|
|
23361
23319
|
return {
|
|
23362
23320
|
code: parsePairingCode(readSingleOption(arguments_, "--code")),
|
|
23321
|
+
pairingId: arguments_.includes("--pairing") ? validatePairingId(readSingleOption(arguments_, "--pairing")) : "",
|
|
23363
23322
|
relayOrigin: parseRelayOrigin(readSingleOption(arguments_, "--url")),
|
|
23364
23323
|
workspace: arguments_.includes("--workspace") ? readSingleOption(arguments_, "--workspace") : loadDefaultWorkspace()
|
|
23365
23324
|
};
|
|
23366
23325
|
}
|
|
23326
|
+
function validatePairingId(value) {
|
|
23327
|
+
if (!IDENTIFIER_PATTERN5.test(value)) {
|
|
23328
|
+
throw new PairingClientError("invalid_pairing_id", "The Runtime pairing ID is invalid");
|
|
23329
|
+
}
|
|
23330
|
+
return value;
|
|
23331
|
+
}
|
|
23367
23332
|
function parseChannelArgument(arguments_) {
|
|
23368
23333
|
if (arguments_.length !== 2 || arguments_[0] !== "--channel") {
|
|
23369
23334
|
throw new PairingClientError("invalid_arguments", "Usage: mobius start --channel <channel-id>");
|
|
@@ -23420,17 +23385,17 @@ function readRelayError(value) {
|
|
|
23420
23385
|
}
|
|
23421
23386
|
return new PairingClientError("pairing_failed", "The relay could not pair this machine");
|
|
23422
23387
|
}
|
|
23423
|
-
function
|
|
23424
|
-
if (!isRecord7(value) || !hasExactKeys(value,
|
|
23388
|
+
function decodePairingResponse(value, credentialField, expectedKeys) {
|
|
23389
|
+
if (!isRecord7(value) || !hasExactKeys(value, expectedKeys)) {
|
|
23425
23390
|
throw new PairingClientError("invalid_relay_response", "The relay returned an invalid pairing response");
|
|
23426
23391
|
}
|
|
23427
23392
|
const channelId = value["channelId"];
|
|
23428
|
-
const
|
|
23393
|
+
const runtimeCredential = value[credentialField];
|
|
23429
23394
|
const runtimeId = value["runtimeId"];
|
|
23430
|
-
if (typeof channelId !== "string" || !IDENTIFIER_PATTERN5.test(channelId) || typeof
|
|
23395
|
+
if (typeof channelId !== "string" || !IDENTIFIER_PATTERN5.test(channelId) || typeof runtimeCredential !== "string" || !TOKEN_PATTERN2.test(runtimeCredential) || typeof runtimeId !== "string" || !IDENTIFIER_PATTERN5.test(runtimeId)) {
|
|
23431
23396
|
throw new PairingClientError("invalid_relay_response", "The relay returned an invalid pairing response");
|
|
23432
23397
|
}
|
|
23433
|
-
return { channelId,
|
|
23398
|
+
return { channelId, runtimeCredential, runtimeId };
|
|
23434
23399
|
}
|
|
23435
23400
|
async function claimPairing(options, defaultWorkspace, localAgents, installableAgents, signal) {
|
|
23436
23401
|
const agents = localAgents.map((agent) => ({
|
|
@@ -23440,7 +23405,7 @@ async function claimPairing(options, defaultWorkspace, localAgents, installableA
|
|
|
23440
23405
|
id: agent.id,
|
|
23441
23406
|
label: agent.label
|
|
23442
23407
|
}));
|
|
23443
|
-
const endpoint = mobiusApiUrl(options.relayOrigin, "/pairings/claim");
|
|
23408
|
+
const endpoint = options.pairingId.length > 0 ? mobiusApiUrl(options.relayOrigin, `/v1/runtime-pairings/${encodeURIComponent(options.pairingId)}/redeem`) : mobiusApiUrl(options.relayOrigin, "/pairings/claim");
|
|
23444
23409
|
let response;
|
|
23445
23410
|
try {
|
|
23446
23411
|
response = await fetch2(endpoint, {
|
|
@@ -23463,10 +23428,10 @@ async function claimPairing(options, defaultWorkspace, localAgents, installableA
|
|
|
23463
23428
|
if (!response.ok) {
|
|
23464
23429
|
throw readRelayError(value);
|
|
23465
23430
|
}
|
|
23466
|
-
return
|
|
23431
|
+
return options.pairingId.length > 0 ? decodePairingResponse(value, "runtimeCredential", REDEEM_RESPONSE_KEYS) : decodePairingResponse(value, "daemonToken", CLAIM_RESPONSE_KEYS);
|
|
23467
23432
|
}
|
|
23468
|
-
async function persistConnection(channelId, relayOrigin,
|
|
23469
|
-
const connectionsDirectory = join14(readStateDirectory(), "connections");
|
|
23433
|
+
async function persistConnection(channelId, relayOrigin, runtimeCredential, defaultWorkspace, environment) {
|
|
23434
|
+
const connectionsDirectory = join14(readStateDirectory(environment), "connections");
|
|
23470
23435
|
await mkdir3(connectionsDirectory, { mode: 448, recursive: true });
|
|
23471
23436
|
const connectionPath = join14(connectionsDirectory, `${channelId}.json`);
|
|
23472
23437
|
const temporaryPath = join14(connectionsDirectory, `.${channelId}.${randomUUID2()}.tmp`);
|
|
@@ -23476,8 +23441,8 @@ async function persistConnection(channelId, relayOrigin, daemonToken2, defaultWo
|
|
|
23476
23441
|
{
|
|
23477
23442
|
defaultWorkspace,
|
|
23478
23443
|
channelId,
|
|
23479
|
-
|
|
23480
|
-
|
|
23444
|
+
relayOrigin: relayOrigin.toString(),
|
|
23445
|
+
runtimeCredential
|
|
23481
23446
|
},
|
|
23482
23447
|
null,
|
|
23483
23448
|
2
|
|
@@ -23489,25 +23454,25 @@ async function persistConnection(channelId, relayOrigin, daemonToken2, defaultWo
|
|
|
23489
23454
|
return connectionPath;
|
|
23490
23455
|
}
|
|
23491
23456
|
function decodeSavedConnection(value, expectedChannelId) {
|
|
23492
|
-
if (!isRecord7(value) || !hasExactKeys(value, SAVED_CONNECTION_KEYS)) {
|
|
23457
|
+
if (!isRecord7(value) || !hasExactKeys(value, SAVED_CONNECTION_KEYS) && !hasExactKeys(value, LEGACY_SAVED_CONNECTION_KEYS)) {
|
|
23493
23458
|
throw new PairingClientError("invalid_connection", "The saved connection is invalid");
|
|
23494
23459
|
}
|
|
23495
23460
|
const defaultWorkspace = value["defaultWorkspace"];
|
|
23496
23461
|
const channelId = value["channelId"];
|
|
23497
|
-
const
|
|
23462
|
+
const runtimeCredential = value["runtimeCredential"] ?? value["daemonToken"];
|
|
23498
23463
|
const relayOrigin = value["relayOrigin"];
|
|
23499
|
-
if (typeof defaultWorkspace !== "string" || typeof channelId !== "string" || channelId !== expectedChannelId || !IDENTIFIER_PATTERN5.test(channelId) || typeof
|
|
23464
|
+
if (typeof defaultWorkspace !== "string" || typeof channelId !== "string" || channelId !== expectedChannelId || !IDENTIFIER_PATTERN5.test(channelId) || typeof runtimeCredential !== "string" || !TOKEN_PATTERN2.test(runtimeCredential) || typeof relayOrigin !== "string") {
|
|
23500
23465
|
throw new PairingClientError("invalid_connection", "The saved connection is invalid");
|
|
23501
23466
|
}
|
|
23502
23467
|
return {
|
|
23503
23468
|
defaultWorkspace,
|
|
23504
23469
|
channelId,
|
|
23505
|
-
|
|
23506
|
-
|
|
23470
|
+
relayOrigin: parseRelayOrigin(relayOrigin),
|
|
23471
|
+
runtimeCredential
|
|
23507
23472
|
};
|
|
23508
23473
|
}
|
|
23509
|
-
async function readSavedConnection(channelId) {
|
|
23510
|
-
const connectionPath = join14(readStateDirectory(), "connections", `${channelId}.json`);
|
|
23474
|
+
async function readSavedConnection(channelId, environment) {
|
|
23475
|
+
const connectionPath = join14(readStateDirectory(environment), "connections", `${channelId}.json`);
|
|
23511
23476
|
let encoded = "";
|
|
23512
23477
|
const handle = await open4(connectionPath, "r");
|
|
23513
23478
|
try {
|
|
@@ -23529,8 +23494,8 @@ async function readSavedConnection(channelId) {
|
|
|
23529
23494
|
return {
|
|
23530
23495
|
defaultWorkspace: await resolveDefaultWorkspace(connection.defaultWorkspace),
|
|
23531
23496
|
channelId: connection.channelId,
|
|
23532
|
-
|
|
23533
|
-
|
|
23497
|
+
relayOrigin: connection.relayOrigin,
|
|
23498
|
+
runtimeCredential: connection.runtimeCredential
|
|
23534
23499
|
};
|
|
23535
23500
|
}
|
|
23536
23501
|
function assertInventoryUsable(inventory) {
|
|
@@ -23538,15 +23503,12 @@ function assertInventoryUsable(inventory) {
|
|
|
23538
23503
|
throw new PairingClientError("no_supported_agent", "No supported Agent is available for local discovery");
|
|
23539
23504
|
}
|
|
23540
23505
|
}
|
|
23541
|
-
function buildPairedDaemon(connection, connectionPath, inventory) {
|
|
23506
|
+
function buildPairedDaemon(connection, connectionPath, inventory, environment) {
|
|
23542
23507
|
assertInventoryUsable(inventory);
|
|
23543
|
-
const relayUrl = mobiusApiUrl(
|
|
23544
|
-
connection.relayOrigin,
|
|
23545
|
-
`/channels/${encodeURIComponent(connection.channelId)}/daemon`
|
|
23546
|
-
);
|
|
23508
|
+
const relayUrl = mobiusApiUrl(connection.relayOrigin, "/v1/runtimes/connect");
|
|
23547
23509
|
relayUrl.protocol = relayUrl.protocol === "https:" ? "wss:" : "ws:";
|
|
23548
|
-
relayUrl.searchParams.set("token", connection.
|
|
23549
|
-
const auditDatabasePath = join14(readStateDirectory(), "audit", `${connection.channelId}.sqlite`);
|
|
23510
|
+
relayUrl.searchParams.set("token", connection.runtimeCredential);
|
|
23511
|
+
const auditDatabasePath = join14(readStateDirectory(environment), "audit", `${connection.channelId}.sqlite`);
|
|
23550
23512
|
return {
|
|
23551
23513
|
channelUrl: new URL(`/channels/${encodeURIComponent(connection.channelId)}`, connection.relayOrigin).toString(),
|
|
23552
23514
|
config: createDaemonConfig(
|
|
@@ -23562,12 +23524,11 @@ function buildPairedDaemon(connection, connectionPath, inventory) {
|
|
|
23562
23524
|
connectionPath
|
|
23563
23525
|
};
|
|
23564
23526
|
}
|
|
23565
|
-
async function
|
|
23566
|
-
const options = parsePairCommand(arguments_);
|
|
23527
|
+
async function pairRuntime(options, signal, environment) {
|
|
23567
23528
|
const defaultWorkspace = await resolveDefaultWorkspace(options.workspace);
|
|
23568
23529
|
const inventory = await discoverLocalAgentInventory({
|
|
23569
23530
|
defaultWorkspace,
|
|
23570
|
-
environment
|
|
23531
|
+
environment,
|
|
23571
23532
|
signal
|
|
23572
23533
|
});
|
|
23573
23534
|
assertInventoryUsable(inventory);
|
|
@@ -23576,31 +23537,87 @@ async function pairLocalMachine(arguments_, signal = new AbortController().signa
|
|
|
23576
23537
|
const connectionPath = await persistConnection(
|
|
23577
23538
|
claim2.channelId,
|
|
23578
23539
|
options.relayOrigin,
|
|
23579
|
-
claim2.
|
|
23580
|
-
defaultWorkspace
|
|
23540
|
+
claim2.runtimeCredential,
|
|
23541
|
+
defaultWorkspace,
|
|
23542
|
+
environment
|
|
23581
23543
|
);
|
|
23582
23544
|
return buildPairedDaemon(
|
|
23583
23545
|
{
|
|
23584
23546
|
defaultWorkspace,
|
|
23585
23547
|
channelId: claim2.channelId,
|
|
23586
|
-
|
|
23587
|
-
|
|
23548
|
+
relayOrigin: options.relayOrigin,
|
|
23549
|
+
runtimeCredential: claim2.runtimeCredential
|
|
23588
23550
|
},
|
|
23589
23551
|
connectionPath,
|
|
23590
|
-
inventory
|
|
23552
|
+
inventory,
|
|
23553
|
+
environment
|
|
23591
23554
|
);
|
|
23592
23555
|
}
|
|
23593
|
-
async function
|
|
23594
|
-
|
|
23595
|
-
|
|
23596
|
-
|
|
23556
|
+
async function pairLocalMachine(arguments_, signal = new AbortController().signal) {
|
|
23557
|
+
return await pairRuntime(parsePairCommand(arguments_), signal, process.env);
|
|
23558
|
+
}
|
|
23559
|
+
async function resumeMobiusRuntime(channelId, signal, environment = process.env) {
|
|
23560
|
+
const normalizedChannelId = validatePairingId(channelId);
|
|
23561
|
+
const connectionPath = join14(readStateDirectory(environment), "connections", `${normalizedChannelId}.json`);
|
|
23562
|
+
const connection = await readSavedConnection(normalizedChannelId, environment);
|
|
23597
23563
|
const inventory = await discoverLocalAgentInventory({
|
|
23598
23564
|
defaultWorkspace: connection.defaultWorkspace,
|
|
23599
|
-
environment
|
|
23565
|
+
environment,
|
|
23600
23566
|
signal
|
|
23601
23567
|
});
|
|
23602
|
-
return buildPairedDaemon(connection, connectionPath, inventory);
|
|
23568
|
+
return buildPairedDaemon(connection, connectionPath, inventory, environment);
|
|
23603
23569
|
}
|
|
23570
|
+
async function resumeLocalMachine(arguments_, signal = new AbortController().signal) {
|
|
23571
|
+
return await resumeMobiusRuntime(parseChannelArgument(arguments_), signal, process.env);
|
|
23572
|
+
}
|
|
23573
|
+
|
|
23574
|
+
// src/audit/audit-store.ts
|
|
23575
|
+
import { mkdirSync } from "node:fs";
|
|
23576
|
+
import { dirname as dirname3 } from "node:path";
|
|
23577
|
+
import { DatabaseSync } from "node:sqlite";
|
|
23578
|
+
var AuditStore = class {
|
|
23579
|
+
database;
|
|
23580
|
+
constructor(path2) {
|
|
23581
|
+
mkdirSync(dirname3(path2), { recursive: true });
|
|
23582
|
+
this.database = new DatabaseSync(path2);
|
|
23583
|
+
this.database.exec(`
|
|
23584
|
+
CREATE TABLE IF NOT EXISTS audit_events (
|
|
23585
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
23586
|
+
recorded_at TEXT NOT NULL,
|
|
23587
|
+
event TEXT NOT NULL,
|
|
23588
|
+
command_id TEXT NOT NULL,
|
|
23589
|
+
session_id TEXT NOT NULL,
|
|
23590
|
+
details_json TEXT NOT NULL DEFAULT '{}'
|
|
23591
|
+
) STRICT
|
|
23592
|
+
`);
|
|
23593
|
+
const columns = this.database.prepare("PRAGMA table_info(audit_events)").all();
|
|
23594
|
+
if (!columns.some((column) => Reflect.get(column, "name") === "details_json")) {
|
|
23595
|
+
this.database.exec("ALTER TABLE audit_events ADD COLUMN details_json TEXT NOT NULL DEFAULT '{}'");
|
|
23596
|
+
}
|
|
23597
|
+
}
|
|
23598
|
+
record(record2) {
|
|
23599
|
+
this.database.prepare(
|
|
23600
|
+
`
|
|
23601
|
+
INSERT INTO audit_events (
|
|
23602
|
+
recorded_at,
|
|
23603
|
+
event,
|
|
23604
|
+
command_id,
|
|
23605
|
+
session_id,
|
|
23606
|
+
details_json
|
|
23607
|
+
) VALUES (?, ?, ?, ?, ?)
|
|
23608
|
+
`
|
|
23609
|
+
).run(
|
|
23610
|
+
(/* @__PURE__ */ new Date()).toISOString(),
|
|
23611
|
+
record2.event,
|
|
23612
|
+
record2.commandId,
|
|
23613
|
+
record2.sessionId,
|
|
23614
|
+
JSON.stringify(record2.details ?? {})
|
|
23615
|
+
);
|
|
23616
|
+
}
|
|
23617
|
+
close() {
|
|
23618
|
+
this.database.close();
|
|
23619
|
+
}
|
|
23620
|
+
};
|
|
23604
23621
|
|
|
23605
23622
|
// src/run-daemon.ts
|
|
23606
23623
|
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
@@ -26992,14 +27009,19 @@ var AgentCatalogPublishError = class extends Error {
|
|
|
26992
27009
|
this.name = "AgentCatalogPublishError";
|
|
26993
27010
|
}
|
|
26994
27011
|
};
|
|
26995
|
-
function catalogEndpoint(
|
|
26996
|
-
const endpoint = new URL(relayUrl);
|
|
27012
|
+
function catalogEndpoint(config2) {
|
|
27013
|
+
const endpoint = new URL(config2.relayUrl);
|
|
26997
27014
|
endpoint.protocol = endpoint.protocol === "wss:" ? "https:" : "http:";
|
|
26998
|
-
if (
|
|
26999
|
-
|
|
27015
|
+
if (endpoint.pathname.endsWith("/daemon")) {
|
|
27016
|
+
endpoint.pathname = `${endpoint.pathname.slice(0, -"/daemon".length)}/catalog`;
|
|
27017
|
+
return endpoint;
|
|
27000
27018
|
}
|
|
27001
|
-
|
|
27002
|
-
|
|
27019
|
+
const runtimePath = "/v1/runtimes/connect";
|
|
27020
|
+
if (endpoint.pathname.endsWith(runtimePath)) {
|
|
27021
|
+
endpoint.pathname = `${endpoint.pathname.slice(0, -runtimePath.length)}/channels/${encodeURIComponent(config2.channelId)}/catalog`;
|
|
27022
|
+
return endpoint;
|
|
27023
|
+
}
|
|
27024
|
+
throw new AgentCatalogPublishError("The Relay URL is invalid");
|
|
27003
27025
|
}
|
|
27004
27026
|
async function publishAgentCatalog(config2, signal) {
|
|
27005
27027
|
signal.throwIfAborted();
|
|
@@ -27008,7 +27030,7 @@ async function publishAgentCatalog(config2, signal) {
|
|
|
27008
27030
|
let response;
|
|
27009
27031
|
const catalog = config2.catalog.read();
|
|
27010
27032
|
try {
|
|
27011
|
-
response = await fetch3(catalogEndpoint(config2
|
|
27033
|
+
response = await fetch3(catalogEndpoint(config2), {
|
|
27012
27034
|
body: JSON.stringify({
|
|
27013
27035
|
agents: catalog.agents.map((agent) => ({
|
|
27014
27036
|
agentPath: agent.agentIdentity.requestedPath,
|
|
@@ -29064,10 +29086,17 @@ function parseReference(resource) {
|
|
|
29064
29086
|
function downloadUrl(config2, command, reference) {
|
|
29065
29087
|
const url2 = new URL(config2.relayUrl);
|
|
29066
29088
|
url2.protocol = url2.protocol === "wss:" ? "https:" : "http:";
|
|
29067
|
-
|
|
29068
|
-
|
|
29089
|
+
let channelPath = "";
|
|
29090
|
+
if (url2.pathname.endsWith("/daemon")) {
|
|
29091
|
+
channelPath = url2.pathname.slice(0, -"/daemon".length);
|
|
29092
|
+
} else {
|
|
29093
|
+
const runtimePath = "/v1/runtimes/connect";
|
|
29094
|
+
if (!url2.pathname.endsWith(runtimePath)) {
|
|
29095
|
+
throw new PromptArtifactError("artifact_endpoint_invalid", "The Relay artifact endpoint is invalid");
|
|
29096
|
+
}
|
|
29097
|
+
channelPath = `${url2.pathname.slice(0, -runtimePath.length)}/channels/${encodeURIComponent(config2.channelId)}`;
|
|
29069
29098
|
}
|
|
29070
|
-
url2.pathname = `${
|
|
29099
|
+
url2.pathname = `${channelPath}/sessions/${encodeURIComponent(command.sessionId)}/commands/${encodeURIComponent(command.commandId)}/artifacts/${encodeURIComponent(reference.artifactId)}/content`;
|
|
29071
29100
|
url2.searchParams.delete("liveness");
|
|
29072
29101
|
return url2;
|
|
29073
29102
|
}
|
|
@@ -29226,8 +29255,16 @@ var RelayConnectionError = class extends Error {
|
|
|
29226
29255
|
function connectRelay(url2, signal) {
|
|
29227
29256
|
signal.throwIfAborted();
|
|
29228
29257
|
return new Promise((resolve5, reject) => {
|
|
29229
|
-
const
|
|
29230
|
-
|
|
29258
|
+
const endpoint = new URL(url2);
|
|
29259
|
+
const headers = {};
|
|
29260
|
+
if (endpoint.pathname.endsWith("/v1/runtimes/connect")) {
|
|
29261
|
+
const runtimeCredential = endpoint.searchParams.get("token") ?? "";
|
|
29262
|
+
endpoint.searchParams.delete("token");
|
|
29263
|
+
headers["authorization"] = `Bearer ${runtimeCredential}`;
|
|
29264
|
+
}
|
|
29265
|
+
const socket = new WebSocket(endpoint, {
|
|
29266
|
+
dispatcher: environmentProxyDispatcher,
|
|
29267
|
+
headers
|
|
29231
29268
|
});
|
|
29232
29269
|
let finished = false;
|
|
29233
29270
|
const timeout = setTimeout(onTimeout, CONNECTION_TIMEOUT_MILLISECONDS);
|
|
@@ -29848,10 +29885,17 @@ var ActiveTurnReconciliationError = class extends Error {
|
|
|
29848
29885
|
function activeTurnReconciliationEndpoint(config2, turn) {
|
|
29849
29886
|
const endpoint = new URL(config2.relayUrl);
|
|
29850
29887
|
endpoint.protocol = endpoint.protocol === "wss:" ? "https:" : "http:";
|
|
29851
|
-
|
|
29852
|
-
|
|
29888
|
+
let channelPath = "";
|
|
29889
|
+
if (endpoint.pathname.endsWith("/daemon")) {
|
|
29890
|
+
channelPath = endpoint.pathname.slice(0, -"/daemon".length);
|
|
29891
|
+
} else {
|
|
29892
|
+
const runtimePath = "/v1/runtimes/connect";
|
|
29893
|
+
if (!endpoint.pathname.endsWith(runtimePath)) {
|
|
29894
|
+
throw new ActiveTurnReconciliationError("The Relay URL is invalid");
|
|
29895
|
+
}
|
|
29896
|
+
channelPath = `${endpoint.pathname.slice(0, -runtimePath.length)}/channels/${encodeURIComponent(config2.channelId)}`;
|
|
29853
29897
|
}
|
|
29854
|
-
endpoint.pathname = `${
|
|
29898
|
+
endpoint.pathname = `${channelPath}/sessions/${encodeURIComponent(turn.command.sessionId)}/attempts/${encodeURIComponent(turn.attemptId)}/reconciliation`;
|
|
29855
29899
|
endpoint.searchParams.delete("liveness");
|
|
29856
29900
|
return endpoint;
|
|
29857
29901
|
}
|
|
@@ -31176,6 +31220,69 @@ async function runDaemon(config2, audit, signal, timer = systemDaemonTimer) {
|
|
|
31176
31220
|
}
|
|
31177
31221
|
}
|
|
31178
31222
|
|
|
31223
|
+
// src/runtime.ts
|
|
31224
|
+
var APP_CREDENTIAL_PATTERN = /^mapp_[a-zA-Z0-9_-]{22}_[a-zA-Z0-9_-]{43}$/;
|
|
31225
|
+
var CONVERSATION_CREDENTIAL_PATTERN = /^mconv_[a-zA-Z0-9_-]{22}_[a-zA-Z0-9_-]{43}$/;
|
|
31226
|
+
var RUNTIME_CREDENTIAL_PATTERN = /^[a-zA-Z0-9_-]{32,256}$/;
|
|
31227
|
+
var MobiusRuntimeConfigurationError = class extends Error {
|
|
31228
|
+
code = "runtime_configuration_invalid";
|
|
31229
|
+
constructor(message, options = {}) {
|
|
31230
|
+
super(message, options);
|
|
31231
|
+
this.name = "MobiusRuntimeConfigurationError";
|
|
31232
|
+
}
|
|
31233
|
+
};
|
|
31234
|
+
var MobiusRuntimeState = class {
|
|
31235
|
+
};
|
|
31236
|
+
var IdleMobiusRuntimeState = class extends MobiusRuntimeState {
|
|
31237
|
+
};
|
|
31238
|
+
var RunningMobiusRuntimeState = class extends MobiusRuntimeState {
|
|
31239
|
+
};
|
|
31240
|
+
var FinishedMobiusRuntimeState = class extends MobiusRuntimeState {
|
|
31241
|
+
};
|
|
31242
|
+
function validateRuntimeRelay(relayUrl) {
|
|
31243
|
+
if (relayUrl.protocol !== "ws:" && relayUrl.protocol !== "wss:") {
|
|
31244
|
+
throw new MobiusRuntimeConfigurationError("The Runtime relay URL must use WebSocket transport");
|
|
31245
|
+
}
|
|
31246
|
+
const credential = relayUrl.searchParams.get("token") ?? "";
|
|
31247
|
+
if (credential.length === 0) {
|
|
31248
|
+
throw new MobiusRuntimeConfigurationError("The Runtime relay credential is required");
|
|
31249
|
+
}
|
|
31250
|
+
if (APP_CREDENTIAL_PATTERN.test(credential)) {
|
|
31251
|
+
throw new MobiusRuntimeConfigurationError("An AppCredential cannot be held by a local Runtime");
|
|
31252
|
+
}
|
|
31253
|
+
if (CONVERSATION_CREDENTIAL_PATTERN.test(credential)) {
|
|
31254
|
+
throw new MobiusRuntimeConfigurationError("A ConversationAccessToken cannot be held by a local Runtime");
|
|
31255
|
+
}
|
|
31256
|
+
if (!RUNTIME_CREDENTIAL_PATTERN.test(credential)) {
|
|
31257
|
+
throw new MobiusRuntimeConfigurationError("The Runtime relay credential is invalid");
|
|
31258
|
+
}
|
|
31259
|
+
}
|
|
31260
|
+
function validateRuntimeConfiguration(config2) {
|
|
31261
|
+
validateRuntimeRelay(config2.relayUrl);
|
|
31262
|
+
}
|
|
31263
|
+
var MobiusRuntimeEngine = class {
|
|
31264
|
+
#config;
|
|
31265
|
+
#state = new IdleMobiusRuntimeState();
|
|
31266
|
+
constructor(config2) {
|
|
31267
|
+
validateRuntimeConfiguration(config2);
|
|
31268
|
+
this.#config = config2;
|
|
31269
|
+
}
|
|
31270
|
+
run = async (signal) => {
|
|
31271
|
+
if (!(this.#state instanceof IdleMobiusRuntimeState)) {
|
|
31272
|
+
throw new MobiusRuntimeConfigurationError("A Mobius Runtime engine can only be started once");
|
|
31273
|
+
}
|
|
31274
|
+
signal.throwIfAborted();
|
|
31275
|
+
this.#state = new RunningMobiusRuntimeState();
|
|
31276
|
+
const audit = new AuditStore(this.#config.auditDatabasePath);
|
|
31277
|
+
try {
|
|
31278
|
+
await runDaemon(this.#config, audit, signal);
|
|
31279
|
+
} finally {
|
|
31280
|
+
audit.close();
|
|
31281
|
+
this.#state = new FinishedMobiusRuntimeState();
|
|
31282
|
+
}
|
|
31283
|
+
};
|
|
31284
|
+
};
|
|
31285
|
+
|
|
31179
31286
|
// src/cli.ts
|
|
31180
31287
|
var shutdown = new AbortController();
|
|
31181
31288
|
process.once("SIGINT", () => shutdown.abort());
|
|
@@ -31183,7 +31290,7 @@ process.once("SIGTERM", () => shutdown.abort());
|
|
|
31183
31290
|
var USAGE = `Mobius CLI
|
|
31184
31291
|
|
|
31185
31292
|
Usage:
|
|
31186
|
-
mobius pair --url <relay-url> --code <pairing-code> [--workspace <directory>]
|
|
31293
|
+
mobius pair --url <relay-url> --pairing <runtime-pairing-id> --code <pairing-code> [--workspace <directory>]
|
|
31187
31294
|
mobius start --channel <channel-id>
|
|
31188
31295
|
mobius agents [--json]
|
|
31189
31296
|
mobius bot message send --target <current|alias> --text <message>
|
|
@@ -31256,12 +31363,7 @@ async function main() {
|
|
|
31256
31363
|
process.stdout.write(`Default workspace: ${config2.defaultWorkspace}
|
|
31257
31364
|
|
|
31258
31365
|
`);
|
|
31259
|
-
|
|
31260
|
-
try {
|
|
31261
|
-
await runDaemon(config2, audit, shutdown.signal);
|
|
31262
|
-
} finally {
|
|
31263
|
-
audit.close();
|
|
31264
|
-
}
|
|
31366
|
+
await new MobiusRuntimeEngine(config2).run(shutdown.signal);
|
|
31265
31367
|
}
|
|
31266
31368
|
try {
|
|
31267
31369
|
await main();
|