@moxt-ai/mobius 0.0.28 → 0.0.29
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/acp-readiness-probe.d.ts.map +1 -1
- package/dist/agent-catalog/acp-readiness-probe.js +2 -2
- package/dist/agent-catalog/acp-readiness-probe.js.map +1 -1
- package/dist/agent-catalog/agent-specification.d.ts +3 -0
- package/dist/agent-catalog/agent-specification.d.ts.map +1 -1
- package/dist/agent-catalog/agent-specification.js +3 -0
- package/dist/agent-catalog/agent-specification.js.map +1 -1
- package/dist/agent-catalog/agents/copilot-cli-agent.d.ts +18 -0
- package/dist/agent-catalog/agents/copilot-cli-agent.d.ts.map +1 -0
- package/dist/agent-catalog/agents/copilot-cli-agent.js +29 -0
- package/dist/agent-catalog/agents/copilot-cli-agent.js.map +1 -0
- package/dist/agent-catalog/agents/gemini-cli-agent.d.ts +14 -0
- package/dist/agent-catalog/agents/gemini-cli-agent.d.ts.map +1 -0
- package/dist/agent-catalog/agents/gemini-cli-agent.js +30 -0
- package/dist/agent-catalog/agents/gemini-cli-agent.js.map +1 -0
- package/dist/agent-catalog/agents/hermes-agent.d.ts +18 -0
- package/dist/agent-catalog/agents/hermes-agent.d.ts.map +1 -0
- package/dist/agent-catalog/agents/hermes-agent.js +32 -0
- package/dist/agent-catalog/agents/hermes-agent.js.map +1 -0
- package/dist/agent-catalog/agents/resolve-user-local-executable.d.ts +4 -0
- package/dist/agent-catalog/agents/resolve-user-local-executable.d.ts.map +1 -0
- package/dist/agent-catalog/agents/resolve-user-local-executable.js +14 -0
- package/dist/agent-catalog/agents/resolve-user-local-executable.js.map +1 -0
- package/dist/agent-catalog/agents/supported-agent-specifications.d.ts.map +1 -1
- package/dist/agent-catalog/agents/supported-agent-specifications.js +6 -0
- package/dist/agent-catalog/agents/supported-agent-specifications.js.map +1 -1
- package/dist/agent-catalog/discover-agent.d.ts.map +1 -1
- package/dist/agent-catalog/discover-agent.js +2 -2
- package/dist/agent-catalog/discover-agent.js.map +1 -1
- package/dist/agent-catalog/discover-local-agents.d.ts +3 -0
- package/dist/agent-catalog/discover-local-agents.d.ts.map +1 -1
- package/dist/agent-catalog/discover-local-agents.js +3 -0
- package/dist/agent-catalog/discover-local-agents.js.map +1 -1
- package/dist/agent-catalog/executable-discovery.d.ts +1 -2
- package/dist/agent-catalog/executable-discovery.d.ts.map +1 -1
- package/dist/agent-catalog/executable-discovery.js +4 -6
- package/dist/agent-catalog/executable-discovery.js.map +1 -1
- package/dist/agent-catalog/version-output.d.ts +2 -0
- package/dist/agent-catalog/version-output.d.ts.map +1 -0
- package/dist/agent-catalog/version-output.js +4 -0
- package/dist/agent-catalog/version-output.js.map +1 -0
- package/dist/cli.js +372 -233
- package/dist/cli.js.map +4 -4
- package/dist/index.js +361 -224
- package/dist/index.js.map +4 -4
- package/dist/runtime.js +373 -234
- package/dist/runtime.js.map +4 -4
- package/package.json +1 -1
package/dist/runtime.js
CHANGED
|
@@ -6,7 +6,7 @@ var __export = (target, all) => {
|
|
|
6
6
|
|
|
7
7
|
// src/runtime.ts
|
|
8
8
|
import { mkdir as mkdir5, realpath as realpath9, stat as stat9 } from "node:fs/promises";
|
|
9
|
-
import { dirname as dirname8, join as
|
|
9
|
+
import { dirname as dirname8, join as join18, resolve as resolve5 } from "node:path";
|
|
10
10
|
|
|
11
11
|
// src/agent-catalog/local-agent.ts
|
|
12
12
|
import { realpathSync, statSync } from "node:fs";
|
|
@@ -1029,6 +1029,13 @@ var ManagedNpmPackageInstaller = class {
|
|
|
1029
1029
|
|
|
1030
1030
|
// src/agent-catalog/agent-specification.ts
|
|
1031
1031
|
import { join as join3 } from "node:path";
|
|
1032
|
+
|
|
1033
|
+
// src/agent-catalog/version-output.ts
|
|
1034
|
+
function normalizeVersionOutput(output2) {
|
|
1035
|
+
return output2.trim().split(/\r?\n/, 1)[0]?.trim().slice(0, 128) ?? "";
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1038
|
+
// src/agent-catalog/agent-specification.ts
|
|
1032
1039
|
var VERSION_PROBE_TIMEOUT_MILLISECONDS = 3e3;
|
|
1033
1040
|
var ACP_PROBE_TIMEOUT_MILLISECONDS = 5e3;
|
|
1034
1041
|
var DEFAULT_PROMPT_TIMEOUT_MILLISECONDS = 30 * 60 * 1e3;
|
|
@@ -1037,6 +1044,8 @@ var LocalAgentSpecification = class {
|
|
|
1037
1044
|
authenticationCommand = () => "";
|
|
1038
1045
|
adapterVersionArguments = ["--version"];
|
|
1039
1046
|
agentVersionArguments = ["--version"];
|
|
1047
|
+
normalizeAdapterVersion = normalizeVersionOutput;
|
|
1048
|
+
normalizeAgentVersion = normalizeVersionOutput;
|
|
1040
1049
|
promptTimeoutMilliseconds = DEFAULT_PROMPT_TIMEOUT_MILLISECONDS;
|
|
1041
1050
|
versionProbeTimeoutMilliseconds = VERSION_PROBE_TIMEOUT_MILLISECONDS;
|
|
1042
1051
|
resolveManagedAgent = async (stateDirectory, platform, signal) => {
|
|
@@ -1148,6 +1157,20 @@ var AgentProbeError = class extends Error {
|
|
|
1148
1157
|
}
|
|
1149
1158
|
};
|
|
1150
1159
|
|
|
1160
|
+
// src/agent-catalog/agents/resolve-user-local-executable.ts
|
|
1161
|
+
import { isAbsolute as isAbsolute2, join as join4 } from "node:path";
|
|
1162
|
+
async function resolveUserLocalExecutable(executableName, context) {
|
|
1163
|
+
context.signal.throwIfAborted();
|
|
1164
|
+
const platform = context.platform ?? process.platform;
|
|
1165
|
+
const homeDirectory = context.environment["HOME"];
|
|
1166
|
+
if (platform === "win32" || homeDirectory === void 0 || !isAbsolute2(homeDirectory)) {
|
|
1167
|
+
return [];
|
|
1168
|
+
}
|
|
1169
|
+
const executable = await resolveExecutablePath(join4(homeDirectory, ".local", "bin", executableName), platform);
|
|
1170
|
+
context.signal.throwIfAborted();
|
|
1171
|
+
return executable === null ? [] : [executable];
|
|
1172
|
+
}
|
|
1173
|
+
|
|
1151
1174
|
// src/agent-catalog/agents/verify-session-creation.ts
|
|
1152
1175
|
import { methods } from "@agentclientprotocol/sdk";
|
|
1153
1176
|
async function verifySessionCreation(connection, capabilities, defaultWorkspace, signal, label) {
|
|
@@ -1172,6 +1195,37 @@ async function verifySessionCreation(connection, capabilities, defaultWorkspace,
|
|
|
1172
1195
|
}
|
|
1173
1196
|
}
|
|
1174
1197
|
|
|
1198
|
+
// src/agent-catalog/agents/copilot-cli-agent.ts
|
|
1199
|
+
var COPILOT_CLI_TESTED_VERSION = "1.0.83";
|
|
1200
|
+
var CopilotCliAgentSpecification = class extends DirectAcpAgentDefinition {
|
|
1201
|
+
acpProbeTimeoutMilliseconds = 2e4;
|
|
1202
|
+
adapterVersion = COPILOT_CLI_TESTED_VERSION;
|
|
1203
|
+
authenticationCommand = () => "copilot login";
|
|
1204
|
+
agentExecutable = "copilot";
|
|
1205
|
+
id = "github-copilot-cli";
|
|
1206
|
+
label = "GitHub Copilot CLI";
|
|
1207
|
+
versionProbeTimeoutMilliseconds = 1e4;
|
|
1208
|
+
constructor() {
|
|
1209
|
+
super(
|
|
1210
|
+
"MOBIUS_COPILOT_PATH",
|
|
1211
|
+
["--no-auto-update", "--acp", "--stdio"],
|
|
1212
|
+
["agents", "github-copilot-cli", COPILOT_CLI_TESTED_VERSION, "bin", "copilot"]
|
|
1213
|
+
);
|
|
1214
|
+
}
|
|
1215
|
+
createLaunchEnvironment = async (_agent, _context) => Object.freeze({ COPILOT_AUTO_UPDATE: "false" });
|
|
1216
|
+
resolveInstalledAgentExecutables = async (context) => await resolveUserLocalExecutable(this.agentExecutable, context);
|
|
1217
|
+
verifyAcp = async (connection, initialized, defaultWorkspace, signal) => {
|
|
1218
|
+
const capabilities = initialized.agentCapabilities ?? {};
|
|
1219
|
+
if (capabilities.loadSession !== true || capabilities.sessionCapabilities?.list == null || (initialized.authMethods ?? []).length === 0) {
|
|
1220
|
+
throw new AgentProbeError(
|
|
1221
|
+
"acp_incompatible",
|
|
1222
|
+
"GitHub Copilot CLI reported an unsupported ACP capability set"
|
|
1223
|
+
);
|
|
1224
|
+
}
|
|
1225
|
+
await verifySessionCreation(connection, capabilities, defaultWorkspace, signal, this.label);
|
|
1226
|
+
};
|
|
1227
|
+
};
|
|
1228
|
+
|
|
1175
1229
|
// src/agent-catalog/agents/cursor-cli-agent.ts
|
|
1176
1230
|
var CURSOR_CLI_TESTED_VERSION = "2026.09.02-c22c1a3";
|
|
1177
1231
|
var CursorCliAgentSpecification = class extends DirectAcpAgentDefinition {
|
|
@@ -1198,7 +1252,7 @@ var CursorCliAgentSpecification = class extends DirectAcpAgentDefinition {
|
|
|
1198
1252
|
|
|
1199
1253
|
// src/agent-catalog/agents/deepseek-harness-agent.ts
|
|
1200
1254
|
import { realpath as realpath3, stat as stat3 } from "node:fs/promises";
|
|
1201
|
-
import { isAbsolute as
|
|
1255
|
+
import { isAbsolute as isAbsolute3, join as join6, normalize } from "node:path";
|
|
1202
1256
|
|
|
1203
1257
|
// src/agent-installation/deepseek-managed-package.ts
|
|
1204
1258
|
var DeepSeekHarnessManagedPackage = class extends SriManagedNpmPackageDefinition {
|
|
@@ -1216,18 +1270,18 @@ var DEEPSEEK_HARNESS_PACKAGE = new DeepSeekHarnessManagedPackage(
|
|
|
1216
1270
|
|
|
1217
1271
|
// src/storage/state-directory.ts
|
|
1218
1272
|
import { homedir } from "node:os";
|
|
1219
|
-
import { join as
|
|
1273
|
+
import { join as join5, resolve as resolve2 } from "node:path";
|
|
1220
1274
|
function readStateDirectory(environment = process.env) {
|
|
1221
1275
|
const configured = environment["MOBIUS_STATE_DIRECTORY"]?.trim();
|
|
1222
1276
|
if (configured !== void 0 && configured.length > 0) {
|
|
1223
1277
|
return resolve2(configured);
|
|
1224
1278
|
}
|
|
1225
|
-
return
|
|
1279
|
+
return join5(homedir(), ".mobius");
|
|
1226
1280
|
}
|
|
1227
1281
|
|
|
1228
1282
|
// src/agent-catalog/agents/deepseek-harness-agent.ts
|
|
1229
1283
|
async function validateAgentHome(path2) {
|
|
1230
|
-
if (!
|
|
1284
|
+
if (!isAbsolute3(path2) || normalize(path2) !== path2) {
|
|
1231
1285
|
throw new AgentProbeError("agent_environment_invalid", "The configured Agent home is invalid");
|
|
1232
1286
|
}
|
|
1233
1287
|
try {
|
|
@@ -1277,7 +1331,7 @@ var DeepSeekHarnessAgentSpecification = class extends DirectAcpAgentDefinition {
|
|
|
1277
1331
|
context.signal
|
|
1278
1332
|
);
|
|
1279
1333
|
if (managed.path === agent.path) {
|
|
1280
|
-
selectedHome =
|
|
1334
|
+
selectedHome = join6(readStateDirectory(context.environment), "agents", this.id, "home");
|
|
1281
1335
|
}
|
|
1282
1336
|
} catch {
|
|
1283
1337
|
context.signal.throwIfAborted();
|
|
@@ -1293,7 +1347,7 @@ var DeepSeekHarnessAgentSpecification = class extends DirectAcpAgentDefinition {
|
|
|
1293
1347
|
resolveManagedAgent = async (stateDirectory, _platform, signal) => {
|
|
1294
1348
|
signal.throwIfAborted();
|
|
1295
1349
|
const executable = await validateManagedNpmPackage(
|
|
1296
|
-
|
|
1350
|
+
join6(stateDirectory, "agents", this.id, DEEPSEEK_HARNESS_PACKAGE.version),
|
|
1297
1351
|
DEEPSEEK_HARNESS_PACKAGE
|
|
1298
1352
|
);
|
|
1299
1353
|
signal.throwIfAborted();
|
|
@@ -1313,9 +1367,41 @@ var DeepSeekHarnessAgentSpecification = class extends DirectAcpAgentDefinition {
|
|
|
1313
1367
|
};
|
|
1314
1368
|
};
|
|
1315
1369
|
|
|
1370
|
+
// src/agent-catalog/agents/gemini-cli-agent.ts
|
|
1371
|
+
var GEMINI_CLI_TESTED_VERSION = "0.59.0";
|
|
1372
|
+
var GeminiCliAgentSpecification = class extends DirectAcpAgentDefinition {
|
|
1373
|
+
acpProbeTimeoutMilliseconds = 2e4;
|
|
1374
|
+
adapterVersion = GEMINI_CLI_TESTED_VERSION;
|
|
1375
|
+
authenticationCommand = () => "gemini";
|
|
1376
|
+
agentExecutable = "gemini";
|
|
1377
|
+
id = "gemini-cli";
|
|
1378
|
+
label = "Gemini CLI";
|
|
1379
|
+
versionProbeTimeoutMilliseconds = 1e4;
|
|
1380
|
+
constructor() {
|
|
1381
|
+
super(
|
|
1382
|
+
"MOBIUS_GEMINI_PATH",
|
|
1383
|
+
["--acp"],
|
|
1384
|
+
[
|
|
1385
|
+
"agents",
|
|
1386
|
+
"gemini-cli",
|
|
1387
|
+
GEMINI_CLI_TESTED_VERSION,
|
|
1388
|
+
"bin",
|
|
1389
|
+
process.platform === "win32" ? "gemini.cmd" : "gemini"
|
|
1390
|
+
]
|
|
1391
|
+
);
|
|
1392
|
+
}
|
|
1393
|
+
verifyAcp = async (connection, initialized, defaultWorkspace, signal) => {
|
|
1394
|
+
const capabilities = initialized.agentCapabilities ?? {};
|
|
1395
|
+
if (capabilities.loadSession !== true || (initialized.authMethods ?? []).length === 0) {
|
|
1396
|
+
throw new AgentProbeError("acp_incompatible", "Gemini CLI reported an unsupported ACP capability set");
|
|
1397
|
+
}
|
|
1398
|
+
await verifySessionCreation(connection, capabilities, defaultWorkspace, signal, this.label);
|
|
1399
|
+
};
|
|
1400
|
+
};
|
|
1401
|
+
|
|
1316
1402
|
// src/agent-catalog/agents/grok-build-agent.ts
|
|
1317
1403
|
import { realpath as realpath4 } from "node:fs/promises";
|
|
1318
|
-
import { isAbsolute as
|
|
1404
|
+
import { isAbsolute as isAbsolute4, join as join7, relative as relative2, sep as sep2 } from "node:path";
|
|
1319
1405
|
|
|
1320
1406
|
// src/agent-installation/grok-managed-package.ts
|
|
1321
1407
|
var GROK_BUILD_MANAGED_VERSION = "1.0.21";
|
|
@@ -1378,7 +1464,7 @@ function grokBuildManagedPackage(platform, architecture) {
|
|
|
1378
1464
|
// src/agent-catalog/agents/grok-build-agent.ts
|
|
1379
1465
|
function isContainedPath2(root, candidate) {
|
|
1380
1466
|
const difference = relative2(root, candidate);
|
|
1381
|
-
return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${sep2}`) && !
|
|
1467
|
+
return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${sep2}`) && !isAbsolute4(difference);
|
|
1382
1468
|
}
|
|
1383
1469
|
var GrokBuildAgentSpecification = class extends DirectAcpAgentDefinition {
|
|
1384
1470
|
adapterVersion = GROK_BUILD_MANAGED_VERSION;
|
|
@@ -1406,7 +1492,7 @@ var GrokBuildAgentSpecification = class extends DirectAcpAgentDefinition {
|
|
|
1406
1492
|
if (managed.path === agent.path) {
|
|
1407
1493
|
return Object.freeze({
|
|
1408
1494
|
GROK_HOME: await realpath4(
|
|
1409
|
-
|
|
1495
|
+
join7(stateDirectory, "agents", this.id, GROK_BUILD_MANAGED_VERSION, "home")
|
|
1410
1496
|
)
|
|
1411
1497
|
});
|
|
1412
1498
|
}
|
|
@@ -1417,9 +1503,9 @@ var GrokBuildAgentSpecification = class extends DirectAcpAgentDefinition {
|
|
|
1417
1503
|
};
|
|
1418
1504
|
resolveManagedAgent = async (stateDirectory, platform, signal) => {
|
|
1419
1505
|
signal.throwIfAborted();
|
|
1420
|
-
const versionRoot = await realpath4(
|
|
1421
|
-
await validateManagedNpmPackage(
|
|
1422
|
-
const executable = await resolveExecutablePath(
|
|
1506
|
+
const versionRoot = await realpath4(join7(stateDirectory, "agents", this.id, GROK_BUILD_MANAGED_VERSION));
|
|
1507
|
+
await validateManagedNpmPackage(join7(versionRoot, "package"), grokBuildManagedPackage(platform, process.arch));
|
|
1508
|
+
const executable = await resolveExecutablePath(join7(versionRoot, "home", "bin", "grok"), platform);
|
|
1423
1509
|
signal.throwIfAborted();
|
|
1424
1510
|
if (executable === null || !isContainedPath2(versionRoot, executable.path)) {
|
|
1425
1511
|
throw new AgentProbeError("managed_agent_invalid", "The managed Grok Build executable is invalid");
|
|
@@ -1436,14 +1522,39 @@ var GrokBuildAgentSpecification = class extends DirectAcpAgentDefinition {
|
|
|
1436
1522
|
};
|
|
1437
1523
|
};
|
|
1438
1524
|
|
|
1525
|
+
// src/agent-catalog/agents/hermes-agent.ts
|
|
1526
|
+
var HERMES_TESTED_VERSION = "0.21.1";
|
|
1527
|
+
var HermesAgentSpecification = class extends DirectAcpAgentDefinition {
|
|
1528
|
+
acpProbeTimeoutMilliseconds = 2e4;
|
|
1529
|
+
adapterVersion = HERMES_TESTED_VERSION;
|
|
1530
|
+
adapterVersionArguments = ["acp", "--version"];
|
|
1531
|
+
authenticationCommand = () => "hermes acp --setup";
|
|
1532
|
+
agentExecutable = "hermes";
|
|
1533
|
+
agentVersionArguments = ["acp", "--version"];
|
|
1534
|
+
id = "hermes";
|
|
1535
|
+
label = "Hermes Agent";
|
|
1536
|
+
constructor() {
|
|
1537
|
+
super("MOBIUS_HERMES_PATH", ["acp"], ["agents", "hermes", HERMES_TESTED_VERSION, "bin", "hermes"]);
|
|
1538
|
+
}
|
|
1539
|
+
resolveInstalledAgentExecutables = async (context) => await resolveUserLocalExecutable(this.agentExecutable, context);
|
|
1540
|
+
verifyAcp = async (connection, initialized, defaultWorkspace, signal) => {
|
|
1541
|
+
const capabilities = initialized.agentCapabilities ?? {};
|
|
1542
|
+
const session = capabilities.sessionCapabilities;
|
|
1543
|
+
if (capabilities.loadSession !== true || session?.fork == null || session.list == null || session.resume == null || (initialized.authMethods ?? []).length === 0) {
|
|
1544
|
+
throw new AgentProbeError("acp_incompatible", "Hermes Agent reported an unsupported ACP capability set");
|
|
1545
|
+
}
|
|
1546
|
+
await verifySessionCreation(connection, capabilities, defaultWorkspace, signal, this.label);
|
|
1547
|
+
};
|
|
1548
|
+
};
|
|
1549
|
+
|
|
1439
1550
|
// src/agent-catalog/agents/opencode-agent.ts
|
|
1440
|
-
import { join as
|
|
1551
|
+
import { join as join9 } from "node:path";
|
|
1441
1552
|
|
|
1442
1553
|
// src/agent-installation/managed-agent-archive.ts
|
|
1443
1554
|
import { createHash } from "node:crypto";
|
|
1444
1555
|
import { createReadStream } from "node:fs";
|
|
1445
1556
|
import { chmod, copyFile, mkdir as mkdir2, mkdtemp as mkdtemp2, open as open2, realpath as realpath5, rename as rename2, rm as rm2, stat as stat4, writeFile } from "node:fs/promises";
|
|
1446
|
-
import { dirname as dirname2, isAbsolute as
|
|
1557
|
+
import { dirname as dirname2, isAbsolute as isAbsolute5, join as join8, relative as relative3, sep as sep3 } from "node:path";
|
|
1447
1558
|
|
|
1448
1559
|
// src/agent-installation/verified-download.ts
|
|
1449
1560
|
import { fetch } from "undici";
|
|
@@ -1549,7 +1660,7 @@ function isRecord3(value) {
|
|
|
1549
1660
|
}
|
|
1550
1661
|
function isContainedPath3(root, candidate) {
|
|
1551
1662
|
const difference = relative3(root, candidate);
|
|
1552
|
-
return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${sep3}`) && !
|
|
1663
|
+
return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${sep3}`) && !isAbsolute5(difference);
|
|
1553
1664
|
}
|
|
1554
1665
|
async function hashFile(path2, signal) {
|
|
1555
1666
|
signal.throwIfAborted();
|
|
@@ -1628,11 +1739,11 @@ async function validateManagedAgentArchive(root, definition, signal) {
|
|
|
1628
1739
|
if (!rootMetadata.isDirectory() || typeof process.getuid === "function" && rootMetadata.uid !== process.getuid()) {
|
|
1629
1740
|
throw new Error("Managed Agent root is not user-owned");
|
|
1630
1741
|
}
|
|
1631
|
-
const manifest = await readManifest(
|
|
1742
|
+
const manifest = await readManifest(join8(rootPath, "archive.json"));
|
|
1632
1743
|
if (manifest["archiveSha256"] !== definition.archiveSha256 || manifest["archiveUrl"] !== definition.archiveUrl.toString() || manifest["version"] !== definition.version || typeof manifest["executableSha256"] !== "string") {
|
|
1633
1744
|
throw new Error("Managed Agent archive identity is invalid");
|
|
1634
1745
|
}
|
|
1635
|
-
const executable = await resolveExecutablePath(
|
|
1746
|
+
const executable = await resolveExecutablePath(join8(rootPath, "bin", definition.executableName));
|
|
1636
1747
|
if (executable === null || !isContainedPath3(rootPath, executable.path) || await hashFile(executable.path, signal) !== manifest["executableSha256"]) {
|
|
1637
1748
|
throw new Error("Managed Agent executable is invalid");
|
|
1638
1749
|
}
|
|
@@ -1724,7 +1835,7 @@ var OpenCodeAgentSpecification = class extends DirectAcpAgentDefinition {
|
|
|
1724
1835
|
}
|
|
1725
1836
|
createLaunchEnvironment = async (_agent, _context) => Object.freeze({ OPENCODE_DISABLE_AUTOUPDATE: "1" });
|
|
1726
1837
|
resolveManagedAgent = async (stateDirectory, platform, signal) => await validateManagedAgentArchive(
|
|
1727
|
-
|
|
1838
|
+
join9(stateDirectory, "agents", this.id, OPENCODE_MANAGED_VERSION),
|
|
1728
1839
|
openCodeManagedArchive(platform, process.arch),
|
|
1729
1840
|
signal
|
|
1730
1841
|
);
|
|
@@ -1742,7 +1853,7 @@ var OpenCodeAgentSpecification = class extends DirectAcpAgentDefinition {
|
|
|
1742
1853
|
};
|
|
1743
1854
|
|
|
1744
1855
|
// src/agent-catalog/agents/pi-agent.ts
|
|
1745
|
-
import { join as
|
|
1856
|
+
import { join as join10 } from "node:path";
|
|
1746
1857
|
import {
|
|
1747
1858
|
methods as methods2
|
|
1748
1859
|
} from "@agentclientprotocol/sdk";
|
|
@@ -1801,7 +1912,7 @@ var PiAgentSpecification = class extends BridgedAcpAgentDefinition {
|
|
|
1801
1912
|
resolveManagedAgent = async (stateDirectory, _platform, signal) => {
|
|
1802
1913
|
signal.throwIfAborted();
|
|
1803
1914
|
const executable = await validateManagedNpmPackage(
|
|
1804
|
-
|
|
1915
|
+
join10(stateDirectory, "agents", this.id, PI_AGENT_PACKAGE.version),
|
|
1805
1916
|
PI_AGENT_PACKAGE
|
|
1806
1917
|
);
|
|
1807
1918
|
signal.throwIfAborted();
|
|
@@ -1839,7 +1950,7 @@ var PiAgentSpecification = class extends BridgedAcpAgentDefinition {
|
|
|
1839
1950
|
};
|
|
1840
1951
|
|
|
1841
1952
|
// src/agent-catalog/agents/workbuddy-agent.ts
|
|
1842
|
-
import { isAbsolute as
|
|
1953
|
+
import { isAbsolute as isAbsolute6, join as join11 } from "node:path";
|
|
1843
1954
|
|
|
1844
1955
|
// src/agent-installation/workbuddy-managed-package.ts
|
|
1845
1956
|
var WORKBUDDY_MANAGED_VERSION = "2.146.0";
|
|
@@ -1892,7 +2003,7 @@ var WorkBuddyAgentSpecification = class extends DirectAcpAgentDefinition {
|
|
|
1892
2003
|
resolveManagedAgent = async (stateDirectory, _platform, signal) => {
|
|
1893
2004
|
signal.throwIfAborted();
|
|
1894
2005
|
const executable = await validateManagedNpmPackage(
|
|
1895
|
-
|
|
2006
|
+
join11(stateDirectory, "agents", this.id, WORKBUDDY_MANAGED_VERSION),
|
|
1896
2007
|
WORKBUDDY_MANAGED_PACKAGE
|
|
1897
2008
|
);
|
|
1898
2009
|
signal.throwIfAborted();
|
|
@@ -1903,10 +2014,10 @@ var WorkBuddyAgentSpecification = class extends DirectAcpAgentDefinition {
|
|
|
1903
2014
|
if ((context.platform ?? process.platform) !== "darwin") {
|
|
1904
2015
|
return [];
|
|
1905
2016
|
}
|
|
1906
|
-
const requestedPaths = [
|
|
2017
|
+
const requestedPaths = [join11("/Applications", ...WORKBUDDY_MACOS_EXECUTABLE_PATH)];
|
|
1907
2018
|
const homeDirectory = context.environment["HOME"];
|
|
1908
|
-
if (homeDirectory !== void 0 &&
|
|
1909
|
-
requestedPaths.unshift(
|
|
2019
|
+
if (homeDirectory !== void 0 && isAbsolute6(homeDirectory)) {
|
|
2020
|
+
requestedPaths.unshift(join11(homeDirectory, "Applications", ...WORKBUDDY_MACOS_EXECUTABLE_PATH));
|
|
1910
2021
|
}
|
|
1911
2022
|
const executables = [];
|
|
1912
2023
|
for (const requestedPath of requestedPaths) {
|
|
@@ -1932,12 +2043,15 @@ function supportedLocalAgentSpecifications() {
|
|
|
1932
2043
|
return Object.freeze([
|
|
1933
2044
|
new CodexAgentSpecification(),
|
|
1934
2045
|
new ClaudeCodeAgentSpecification(),
|
|
2046
|
+
new CopilotCliAgentSpecification(),
|
|
1935
2047
|
new PiAgentSpecification(),
|
|
1936
2048
|
new DeepSeekHarnessAgentSpecification(),
|
|
2049
|
+
new HermesAgentSpecification(),
|
|
1937
2050
|
new OpenCodeAgentSpecification(),
|
|
1938
2051
|
new CursorCliAgentSpecification(),
|
|
1939
2052
|
new GrokBuildAgentSpecification(),
|
|
1940
|
-
new WorkBuddyAgentSpecification()
|
|
2053
|
+
new WorkBuddyAgentSpecification(),
|
|
2054
|
+
new GeminiCliAgentSpecification()
|
|
1941
2055
|
]);
|
|
1942
2056
|
}
|
|
1943
2057
|
|
|
@@ -1977,11 +2091,173 @@ var createAcpClient = (handler) => client({ name: "mobius" }).onRequest(
|
|
|
1977
2091
|
outcome: { outcome: "cancelled" }
|
|
1978
2092
|
})).onNotification("cursor/update_todos", discardExtensionParams, async () => Promise.resolve()).onNotification("cursor/task", discardExtensionParams, async () => Promise.resolve()).onNotification("cursor/generate_image", discardExtensionParams, async () => Promise.resolve());
|
|
1979
2093
|
|
|
2094
|
+
// src/agent-catalog/acp-readiness-probe.ts
|
|
2095
|
+
var ACP_OUTPUT_LIMIT_BYTES = 1024 * 1024;
|
|
2096
|
+
var VerifiedAcpReadiness = class {
|
|
2097
|
+
adapterVersion;
|
|
2098
|
+
capabilities;
|
|
2099
|
+
constructor(adapterVersion, capabilities) {
|
|
2100
|
+
this.adapterVersion = adapterVersion;
|
|
2101
|
+
this.capabilities = capabilities;
|
|
2102
|
+
}
|
|
2103
|
+
};
|
|
2104
|
+
var DiscoveryAcpHandler = class {
|
|
2105
|
+
onElicitation = (_request, _signal) => Promise.reject(new Error("ACP probe does not accept elicitations"));
|
|
2106
|
+
onElicitationComplete = (_notification) => Promise.resolve();
|
|
2107
|
+
onPermission = (_request, _signal) => Promise.reject(new Error("ACP probe does not grant permissions"));
|
|
2108
|
+
onUpdate = (_notification) => Promise.resolve();
|
|
2109
|
+
};
|
|
2110
|
+
function readableAcpStream(input2) {
|
|
2111
|
+
let byteLength = 0;
|
|
2112
|
+
let open5 = true;
|
|
2113
|
+
return new ReadableStream({
|
|
2114
|
+
start(controller) {
|
|
2115
|
+
input2.on("data", (chunk) => {
|
|
2116
|
+
if (!open5) {
|
|
2117
|
+
return;
|
|
2118
|
+
}
|
|
2119
|
+
if (!(chunk instanceof Uint8Array)) {
|
|
2120
|
+
open5 = false;
|
|
2121
|
+
controller.error(new Error("ACP adapter produced invalid output"));
|
|
2122
|
+
return;
|
|
2123
|
+
}
|
|
2124
|
+
byteLength += chunk.byteLength;
|
|
2125
|
+
if (byteLength > ACP_OUTPUT_LIMIT_BYTES) {
|
|
2126
|
+
open5 = false;
|
|
2127
|
+
controller.error(new Error("ACP adapter output limit exceeded"));
|
|
2128
|
+
return;
|
|
2129
|
+
}
|
|
2130
|
+
controller.enqueue(new Uint8Array(chunk));
|
|
2131
|
+
});
|
|
2132
|
+
input2.once("end", () => {
|
|
2133
|
+
if (open5) {
|
|
2134
|
+
open5 = false;
|
|
2135
|
+
controller.close();
|
|
2136
|
+
}
|
|
2137
|
+
});
|
|
2138
|
+
input2.once("error", (error61) => {
|
|
2139
|
+
if (open5) {
|
|
2140
|
+
open5 = false;
|
|
2141
|
+
controller.error(error61);
|
|
2142
|
+
}
|
|
2143
|
+
});
|
|
2144
|
+
},
|
|
2145
|
+
cancel() {
|
|
2146
|
+
open5 = false;
|
|
2147
|
+
}
|
|
2148
|
+
});
|
|
2149
|
+
}
|
|
2150
|
+
function writableAcpStream(output2) {
|
|
2151
|
+
return new WritableStream({
|
|
2152
|
+
write(chunk) {
|
|
2153
|
+
return new Promise((resolveWrite, rejectWrite) => {
|
|
2154
|
+
output2.write(chunk, (error61) => {
|
|
2155
|
+
if (error61) {
|
|
2156
|
+
rejectWrite(error61);
|
|
2157
|
+
return;
|
|
2158
|
+
}
|
|
2159
|
+
resolveWrite();
|
|
2160
|
+
});
|
|
2161
|
+
});
|
|
2162
|
+
}
|
|
2163
|
+
});
|
|
2164
|
+
}
|
|
2165
|
+
async function probeAcpReadiness(specification, agent, environment, defaultWorkspace, signal) {
|
|
2166
|
+
signal.throwIfAborted();
|
|
2167
|
+
const controller = new AbortController();
|
|
2168
|
+
let timedOut = false;
|
|
2169
|
+
const timeout = setTimeout(() => {
|
|
2170
|
+
timedOut = true;
|
|
2171
|
+
controller.abort(new Error("ACP probe timed out"));
|
|
2172
|
+
}, specification.acpProbeTimeoutMilliseconds);
|
|
2173
|
+
const abort = () => controller.abort(signal.reason);
|
|
2174
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
2175
|
+
if (signal.aborted) {
|
|
2176
|
+
abort();
|
|
2177
|
+
}
|
|
2178
|
+
const child = spawn2(agent.adapterPath, [...agent.arguments], {
|
|
2179
|
+
cwd: defaultWorkspace,
|
|
2180
|
+
detached: process.platform !== "win32",
|
|
2181
|
+
env: { ...environment, ...agent.environment },
|
|
2182
|
+
shell: false,
|
|
2183
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
2184
|
+
});
|
|
2185
|
+
const processExit = new Promise((_resolve, reject) => {
|
|
2186
|
+
const rejectExit = () => reject(new Error("ACP adapter exited during initialization"));
|
|
2187
|
+
child.once("error", reject);
|
|
2188
|
+
child.once("exit", rejectExit);
|
|
2189
|
+
if (child.exitCode !== null || child.signalCode !== null) {
|
|
2190
|
+
rejectExit();
|
|
2191
|
+
}
|
|
2192
|
+
});
|
|
2193
|
+
const stdin = child.stdin;
|
|
2194
|
+
const stdout = child.stdout;
|
|
2195
|
+
const stderr = child.stderr;
|
|
2196
|
+
if (stdin === null || stdout === null || stderr === null) {
|
|
2197
|
+
await stopProcessTree(child);
|
|
2198
|
+
throw new AgentProbeError("acp_incompatible", "ACP adapter streams are unavailable");
|
|
2199
|
+
}
|
|
2200
|
+
let stderrBytes = 0;
|
|
2201
|
+
const consumeStderr = (chunk) => {
|
|
2202
|
+
stderrBytes += chunk.byteLength;
|
|
2203
|
+
if (stderrBytes > ACP_OUTPUT_LIMIT_BYTES) {
|
|
2204
|
+
controller.abort(new Error("ACP adapter output limit exceeded"));
|
|
2205
|
+
}
|
|
2206
|
+
};
|
|
2207
|
+
stderr.on("data", consumeStderr);
|
|
2208
|
+
const connection = createAcpClient(new DiscoveryAcpHandler()).connect(
|
|
2209
|
+
ndJsonStream(writableAcpStream(stdin), readableAcpStream(stdout))
|
|
2210
|
+
);
|
|
2211
|
+
try {
|
|
2212
|
+
const initialized = await Promise.race([
|
|
2213
|
+
connection.agent.request(
|
|
2214
|
+
methods4.agent.initialize,
|
|
2215
|
+
{
|
|
2216
|
+
clientCapabilities: {},
|
|
2217
|
+
clientInfo: { name: "mobius", version: "0.0.3" },
|
|
2218
|
+
protocolVersion: PROTOCOL_VERSION
|
|
2219
|
+
},
|
|
2220
|
+
{ cancellationSignal: controller.signal }
|
|
2221
|
+
),
|
|
2222
|
+
processExit
|
|
2223
|
+
]);
|
|
2224
|
+
if (initialized.protocolVersion !== PROTOCOL_VERSION) {
|
|
2225
|
+
throw new AgentProbeError("acp_incompatible", "ACP adapter selected an unsupported protocol version");
|
|
2226
|
+
}
|
|
2227
|
+
await specification.verifyAcp(connection, initialized, defaultWorkspace, controller.signal);
|
|
2228
|
+
return new VerifiedAcpReadiness(
|
|
2229
|
+
normalizeVersionOutput(initialized.agentInfo?.version ?? ""),
|
|
2230
|
+
normalizeAcpCapabilities(initialized)
|
|
2231
|
+
);
|
|
2232
|
+
} catch (error61) {
|
|
2233
|
+
if (signal.aborted) {
|
|
2234
|
+
signal.throwIfAborted();
|
|
2235
|
+
}
|
|
2236
|
+
if (timedOut) {
|
|
2237
|
+
throw new AgentProbeError("adapter_probe_timeout", "ACP adapter probe timed out", { cause: error61 });
|
|
2238
|
+
}
|
|
2239
|
+
if (error61 instanceof AgentProbeError) {
|
|
2240
|
+
throw error61;
|
|
2241
|
+
}
|
|
2242
|
+
if (error61 instanceof RequestError && error61.code === -32e3 && specification.authenticationCommand().length > 0) {
|
|
2243
|
+
throw new AgentProbeError("authentication_required", "Agent authentication is required", { cause: error61 });
|
|
2244
|
+
}
|
|
2245
|
+
throw new AgentProbeError("acp_incompatible", "ACP adapter initialization failed", { cause: error61 });
|
|
2246
|
+
} finally {
|
|
2247
|
+
clearTimeout(timeout);
|
|
2248
|
+
signal.removeEventListener("abort", abort);
|
|
2249
|
+
connection.close();
|
|
2250
|
+
stdin.end();
|
|
2251
|
+
stderr.removeListener("data", consumeStderr);
|
|
2252
|
+
await stopProcessTree(child);
|
|
2253
|
+
}
|
|
2254
|
+
}
|
|
2255
|
+
|
|
1980
2256
|
// src/agent-catalog/executable-discovery.ts
|
|
1981
|
-
import { isAbsolute as
|
|
2257
|
+
import { isAbsolute as isAbsolute7, join as join13 } from "node:path";
|
|
1982
2258
|
|
|
1983
2259
|
// src/agent-installation/managed-adapter-installer.ts
|
|
1984
|
-
import { join as
|
|
2260
|
+
import { join as join12 } from "node:path";
|
|
1985
2261
|
var ManagedAdapterInstallError = class extends Error {
|
|
1986
2262
|
code;
|
|
1987
2263
|
constructor(code, message, options = {}) {
|
|
@@ -2038,7 +2314,7 @@ var ManagedAdapterInstaller = class {
|
|
|
2038
2314
|
this.#stateDirectory = options.stateDirectory;
|
|
2039
2315
|
}
|
|
2040
2316
|
install = async (specification, signal) => {
|
|
2041
|
-
const root =
|
|
2317
|
+
const root = join12(this.#stateDirectory, "adapters", specification.id, specification.adapterVersion);
|
|
2042
2318
|
try {
|
|
2043
2319
|
return await this.#npmInstaller.install(
|
|
2044
2320
|
root,
|
|
@@ -2072,7 +2348,7 @@ async function resolveManagedAdapterExecutable(specification, context) {
|
|
|
2072
2348
|
let managed;
|
|
2073
2349
|
try {
|
|
2074
2350
|
managed = await validateManagedAdapter(
|
|
2075
|
-
|
|
2351
|
+
join13(readStateDirectory(context.environment), "adapters", specification.id, specification.adapterVersion),
|
|
2076
2352
|
specification
|
|
2077
2353
|
);
|
|
2078
2354
|
} catch {
|
|
@@ -2083,7 +2359,7 @@ async function resolveManagedAdapterExecutable(specification, context) {
|
|
|
2083
2359
|
async function resolveSpecificationExecutables(executableName, overrideVariable, resolveInstalled, resolveManaged, context) {
|
|
2084
2360
|
const override = context.environment[overrideVariable];
|
|
2085
2361
|
if (override !== void 0) {
|
|
2086
|
-
if (override.length === 0 || !
|
|
2362
|
+
if (override.length === 0 || !isAbsolute7(override)) {
|
|
2087
2363
|
return [];
|
|
2088
2364
|
}
|
|
2089
2365
|
const executable = await resolveExecutablePath(override, context.platform);
|
|
@@ -2137,10 +2413,7 @@ async function resolveAdapterExecutable(specification, context) {
|
|
|
2137
2413
|
const executables = await resolveAdapterExecutables(specification, context);
|
|
2138
2414
|
return executables[0] ?? null;
|
|
2139
2415
|
}
|
|
2140
|
-
function
|
|
2141
|
-
return output2.trim().split(/\r?\n/, 1)[0]?.trim().slice(0, 128) ?? "";
|
|
2142
|
-
}
|
|
2143
|
-
async function probeVersion(executable, arguments_, environment, defaultWorkspace, signal, timeoutMilliseconds) {
|
|
2416
|
+
async function probeVersion(executable, arguments_, environment, defaultWorkspace, signal, timeoutMilliseconds, normalize4 = normalizeVersionOutput) {
|
|
2144
2417
|
const result = await runBoundedProcess({
|
|
2145
2418
|
arguments: arguments_,
|
|
2146
2419
|
command: executable.path,
|
|
@@ -2149,7 +2422,7 @@ async function probeVersion(executable, arguments_, environment, defaultWorkspac
|
|
|
2149
2422
|
signal,
|
|
2150
2423
|
timeoutMilliseconds
|
|
2151
2424
|
});
|
|
2152
|
-
const version2 =
|
|
2425
|
+
const version2 = normalize4(result.stdout || result.stderr);
|
|
2153
2426
|
if (version2.length === 0) {
|
|
2154
2427
|
throw new ProcessExecutionError("process_exit_failed", "The executable did not report a version");
|
|
2155
2428
|
}
|
|
@@ -2173,7 +2446,8 @@ async function findVerifiedAgentExecutable(specification, context) {
|
|
|
2173
2446
|
context.environment,
|
|
2174
2447
|
context.defaultWorkspace,
|
|
2175
2448
|
context.signal,
|
|
2176
|
-
specification.versionProbeTimeoutMilliseconds
|
|
2449
|
+
specification.versionProbeTimeoutMilliseconds,
|
|
2450
|
+
specification.normalizeAgentVersion
|
|
2177
2451
|
);
|
|
2178
2452
|
return new VerifiedAgentExecutable(executable, version2);
|
|
2179
2453
|
} catch {
|
|
@@ -2185,168 +2459,6 @@ async function findVerifiedAgentExecutable(specification, context) {
|
|
|
2185
2459
|
return null;
|
|
2186
2460
|
}
|
|
2187
2461
|
|
|
2188
|
-
// src/agent-catalog/acp-readiness-probe.ts
|
|
2189
|
-
var ACP_OUTPUT_LIMIT_BYTES = 1024 * 1024;
|
|
2190
|
-
var VerifiedAcpReadiness = class {
|
|
2191
|
-
adapterVersion;
|
|
2192
|
-
capabilities;
|
|
2193
|
-
constructor(adapterVersion, capabilities) {
|
|
2194
|
-
this.adapterVersion = adapterVersion;
|
|
2195
|
-
this.capabilities = capabilities;
|
|
2196
|
-
}
|
|
2197
|
-
};
|
|
2198
|
-
var DiscoveryAcpHandler = class {
|
|
2199
|
-
onElicitation = (_request, _signal) => Promise.reject(new Error("ACP probe does not accept elicitations"));
|
|
2200
|
-
onElicitationComplete = (_notification) => Promise.resolve();
|
|
2201
|
-
onPermission = (_request, _signal) => Promise.reject(new Error("ACP probe does not grant permissions"));
|
|
2202
|
-
onUpdate = (_notification) => Promise.resolve();
|
|
2203
|
-
};
|
|
2204
|
-
function readableAcpStream(input2) {
|
|
2205
|
-
let byteLength = 0;
|
|
2206
|
-
let open5 = true;
|
|
2207
|
-
return new ReadableStream({
|
|
2208
|
-
start(controller) {
|
|
2209
|
-
input2.on("data", (chunk) => {
|
|
2210
|
-
if (!open5) {
|
|
2211
|
-
return;
|
|
2212
|
-
}
|
|
2213
|
-
if (!(chunk instanceof Uint8Array)) {
|
|
2214
|
-
open5 = false;
|
|
2215
|
-
controller.error(new Error("ACP adapter produced invalid output"));
|
|
2216
|
-
return;
|
|
2217
|
-
}
|
|
2218
|
-
byteLength += chunk.byteLength;
|
|
2219
|
-
if (byteLength > ACP_OUTPUT_LIMIT_BYTES) {
|
|
2220
|
-
open5 = false;
|
|
2221
|
-
controller.error(new Error("ACP adapter output limit exceeded"));
|
|
2222
|
-
return;
|
|
2223
|
-
}
|
|
2224
|
-
controller.enqueue(new Uint8Array(chunk));
|
|
2225
|
-
});
|
|
2226
|
-
input2.once("end", () => {
|
|
2227
|
-
if (open5) {
|
|
2228
|
-
open5 = false;
|
|
2229
|
-
controller.close();
|
|
2230
|
-
}
|
|
2231
|
-
});
|
|
2232
|
-
input2.once("error", (error61) => {
|
|
2233
|
-
if (open5) {
|
|
2234
|
-
open5 = false;
|
|
2235
|
-
controller.error(error61);
|
|
2236
|
-
}
|
|
2237
|
-
});
|
|
2238
|
-
},
|
|
2239
|
-
cancel() {
|
|
2240
|
-
open5 = false;
|
|
2241
|
-
}
|
|
2242
|
-
});
|
|
2243
|
-
}
|
|
2244
|
-
function writableAcpStream(output2) {
|
|
2245
|
-
return new WritableStream({
|
|
2246
|
-
write(chunk) {
|
|
2247
|
-
return new Promise((resolveWrite, rejectWrite) => {
|
|
2248
|
-
output2.write(chunk, (error61) => {
|
|
2249
|
-
if (error61) {
|
|
2250
|
-
rejectWrite(error61);
|
|
2251
|
-
return;
|
|
2252
|
-
}
|
|
2253
|
-
resolveWrite();
|
|
2254
|
-
});
|
|
2255
|
-
});
|
|
2256
|
-
}
|
|
2257
|
-
});
|
|
2258
|
-
}
|
|
2259
|
-
async function probeAcpReadiness(specification, agent, environment, defaultWorkspace, signal) {
|
|
2260
|
-
signal.throwIfAborted();
|
|
2261
|
-
const controller = new AbortController();
|
|
2262
|
-
let timedOut = false;
|
|
2263
|
-
const timeout = setTimeout(() => {
|
|
2264
|
-
timedOut = true;
|
|
2265
|
-
controller.abort(new Error("ACP probe timed out"));
|
|
2266
|
-
}, specification.acpProbeTimeoutMilliseconds);
|
|
2267
|
-
const abort = () => controller.abort(signal.reason);
|
|
2268
|
-
signal.addEventListener("abort", abort, { once: true });
|
|
2269
|
-
if (signal.aborted) {
|
|
2270
|
-
abort();
|
|
2271
|
-
}
|
|
2272
|
-
const child = spawn2(agent.adapterPath, [...agent.arguments], {
|
|
2273
|
-
cwd: defaultWorkspace,
|
|
2274
|
-
detached: process.platform !== "win32",
|
|
2275
|
-
env: { ...environment, ...agent.environment },
|
|
2276
|
-
shell: false,
|
|
2277
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
2278
|
-
});
|
|
2279
|
-
const processExit = new Promise((_resolve, reject) => {
|
|
2280
|
-
const rejectExit = () => reject(new Error("ACP adapter exited during initialization"));
|
|
2281
|
-
child.once("error", reject);
|
|
2282
|
-
child.once("exit", rejectExit);
|
|
2283
|
-
if (child.exitCode !== null || child.signalCode !== null) {
|
|
2284
|
-
rejectExit();
|
|
2285
|
-
}
|
|
2286
|
-
});
|
|
2287
|
-
const stdin = child.stdin;
|
|
2288
|
-
const stdout = child.stdout;
|
|
2289
|
-
const stderr = child.stderr;
|
|
2290
|
-
if (stdin === null || stdout === null || stderr === null) {
|
|
2291
|
-
await stopProcessTree(child);
|
|
2292
|
-
throw new AgentProbeError("acp_incompatible", "ACP adapter streams are unavailable");
|
|
2293
|
-
}
|
|
2294
|
-
let stderrBytes = 0;
|
|
2295
|
-
const consumeStderr = (chunk) => {
|
|
2296
|
-
stderrBytes += chunk.byteLength;
|
|
2297
|
-
if (stderrBytes > ACP_OUTPUT_LIMIT_BYTES) {
|
|
2298
|
-
controller.abort(new Error("ACP adapter output limit exceeded"));
|
|
2299
|
-
}
|
|
2300
|
-
};
|
|
2301
|
-
stderr.on("data", consumeStderr);
|
|
2302
|
-
const connection = createAcpClient(new DiscoveryAcpHandler()).connect(
|
|
2303
|
-
ndJsonStream(writableAcpStream(stdin), readableAcpStream(stdout))
|
|
2304
|
-
);
|
|
2305
|
-
try {
|
|
2306
|
-
const initialized = await Promise.race([
|
|
2307
|
-
connection.agent.request(
|
|
2308
|
-
methods4.agent.initialize,
|
|
2309
|
-
{
|
|
2310
|
-
clientCapabilities: {},
|
|
2311
|
-
clientInfo: { name: "mobius", version: "0.0.3" },
|
|
2312
|
-
protocolVersion: PROTOCOL_VERSION
|
|
2313
|
-
},
|
|
2314
|
-
{ cancellationSignal: controller.signal }
|
|
2315
|
-
),
|
|
2316
|
-
processExit
|
|
2317
|
-
]);
|
|
2318
|
-
if (initialized.protocolVersion !== PROTOCOL_VERSION) {
|
|
2319
|
-
throw new AgentProbeError("acp_incompatible", "ACP adapter selected an unsupported protocol version");
|
|
2320
|
-
}
|
|
2321
|
-
await specification.verifyAcp(connection, initialized, defaultWorkspace, controller.signal);
|
|
2322
|
-
return new VerifiedAcpReadiness(
|
|
2323
|
-
normalizedVersion(initialized.agentInfo?.version ?? ""),
|
|
2324
|
-
normalizeAcpCapabilities(initialized)
|
|
2325
|
-
);
|
|
2326
|
-
} catch (error61) {
|
|
2327
|
-
if (signal.aborted) {
|
|
2328
|
-
signal.throwIfAborted();
|
|
2329
|
-
}
|
|
2330
|
-
if (timedOut) {
|
|
2331
|
-
throw new AgentProbeError("adapter_probe_timeout", "ACP adapter probe timed out", { cause: error61 });
|
|
2332
|
-
}
|
|
2333
|
-
if (error61 instanceof AgentProbeError) {
|
|
2334
|
-
throw error61;
|
|
2335
|
-
}
|
|
2336
|
-
if (error61 instanceof RequestError && error61.code === -32e3 && specification.authenticationCommand().length > 0) {
|
|
2337
|
-
throw new AgentProbeError("authentication_required", "Agent authentication is required", { cause: error61 });
|
|
2338
|
-
}
|
|
2339
|
-
throw new AgentProbeError("acp_incompatible", "ACP adapter initialization failed", { cause: error61 });
|
|
2340
|
-
} finally {
|
|
2341
|
-
clearTimeout(timeout);
|
|
2342
|
-
signal.removeEventListener("abort", abort);
|
|
2343
|
-
connection.close();
|
|
2344
|
-
stdin.end();
|
|
2345
|
-
stderr.removeListener("data", consumeStderr);
|
|
2346
|
-
await stopProcessTree(child);
|
|
2347
|
-
}
|
|
2348
|
-
}
|
|
2349
|
-
|
|
2350
2462
|
// src/agent-catalog/discover-agent.ts
|
|
2351
2463
|
function agentProbeFailure(specification, error61) {
|
|
2352
2464
|
if (error61 instanceof AgentProbeError) {
|
|
@@ -2390,7 +2502,8 @@ async function discoverAgent(specification, context) {
|
|
|
2390
2502
|
context.environment,
|
|
2391
2503
|
context.defaultWorkspace,
|
|
2392
2504
|
context.signal,
|
|
2393
|
-
specification.versionProbeTimeoutMilliseconds
|
|
2505
|
+
specification.versionProbeTimeoutMilliseconds,
|
|
2506
|
+
specification.normalizeAgentVersion
|
|
2394
2507
|
);
|
|
2395
2508
|
} catch (error61) {
|
|
2396
2509
|
if (context.signal.aborted) {
|
|
@@ -2426,7 +2539,8 @@ async function discoverAgent(specification, context) {
|
|
|
2426
2539
|
},
|
|
2427
2540
|
context.defaultWorkspace,
|
|
2428
2541
|
context.signal,
|
|
2429
|
-
specification.versionProbeTimeoutMilliseconds
|
|
2542
|
+
specification.versionProbeTimeoutMilliseconds,
|
|
2543
|
+
specification.normalizeAdapterVersion
|
|
2430
2544
|
);
|
|
2431
2545
|
}
|
|
2432
2546
|
} catch (error61) {
|
|
@@ -2549,7 +2663,7 @@ var AuditStore = class {
|
|
|
2549
2663
|
};
|
|
2550
2664
|
|
|
2551
2665
|
// src/config.ts
|
|
2552
|
-
import { join as
|
|
2666
|
+
import { join as join14 } from "node:path";
|
|
2553
2667
|
|
|
2554
2668
|
// ../../node_modules/.pnpm/zod@4.5.4/node_modules/zod/v4/classic/external.js
|
|
2555
2669
|
var external_exports = {};
|
|
@@ -21419,6 +21533,28 @@ function date4(params) {
|
|
|
21419
21533
|
|
|
21420
21534
|
// ../protocol/src/prompt-usage.ts
|
|
21421
21535
|
var TOKEN_COUNT = external_exports.number().int().nonnegative();
|
|
21536
|
+
function normalizeQuotaTokenCount(value) {
|
|
21537
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
21538
|
+
return value;
|
|
21539
|
+
}
|
|
21540
|
+
if (Reflect.has(value, "inputTokens") || Reflect.has(value, "outputTokens") || Reflect.has(value, "totalTokens")) {
|
|
21541
|
+
return value;
|
|
21542
|
+
}
|
|
21543
|
+
if (!Reflect.has(value, "input_tokens") && !Reflect.has(value, "output_tokens")) {
|
|
21544
|
+
return value;
|
|
21545
|
+
}
|
|
21546
|
+
const inputTokens = Reflect.get(value, "input_tokens");
|
|
21547
|
+
const outputTokens = Reflect.get(value, "output_tokens");
|
|
21548
|
+
const reportedTotal = Reflect.get(value, "total_tokens");
|
|
21549
|
+
return {
|
|
21550
|
+
cachedInputTokens: Reflect.get(value, "cached_input_tokens"),
|
|
21551
|
+
cachedWriteTokens: Reflect.get(value, "cached_write_tokens"),
|
|
21552
|
+
inputTokens,
|
|
21553
|
+
outputTokens,
|
|
21554
|
+
reasoningOutputTokens: Reflect.get(value, "reasoning_output_tokens"),
|
|
21555
|
+
totalTokens: reportedTotal === void 0 && typeof inputTokens === "number" && typeof outputTokens === "number" ? inputTokens + outputTokens : reportedTotal
|
|
21556
|
+
};
|
|
21557
|
+
}
|
|
21422
21558
|
var promptUsageSchema = external_exports.object({
|
|
21423
21559
|
cachedReadTokens: TOKEN_COUNT.nullish(),
|
|
21424
21560
|
cachedWriteTokens: TOKEN_COUNT.nullish(),
|
|
@@ -21427,14 +21563,17 @@ var promptUsageSchema = external_exports.object({
|
|
|
21427
21563
|
thoughtTokens: TOKEN_COUNT.nullish(),
|
|
21428
21564
|
totalTokens: TOKEN_COUNT
|
|
21429
21565
|
}).readonly();
|
|
21430
|
-
var quotaTokenCountSchema = external_exports.
|
|
21431
|
-
|
|
21432
|
-
|
|
21433
|
-
|
|
21434
|
-
|
|
21435
|
-
|
|
21436
|
-
|
|
21437
|
-
|
|
21566
|
+
var quotaTokenCountSchema = external_exports.preprocess(
|
|
21567
|
+
normalizeQuotaTokenCount,
|
|
21568
|
+
external_exports.object({
|
|
21569
|
+
cachedInputTokens: TOKEN_COUNT.optional(),
|
|
21570
|
+
cachedWriteTokens: TOKEN_COUNT.optional(),
|
|
21571
|
+
inputTokens: TOKEN_COUNT,
|
|
21572
|
+
outputTokens: TOKEN_COUNT,
|
|
21573
|
+
reasoningOutputTokens: TOKEN_COUNT.optional(),
|
|
21574
|
+
totalTokens: TOKEN_COUNT
|
|
21575
|
+
}).readonly()
|
|
21576
|
+
);
|
|
21438
21577
|
var promptMetadataSchema = external_exports.object({
|
|
21439
21578
|
quota: external_exports.object({
|
|
21440
21579
|
model_usage: external_exports.array(
|
|
@@ -23062,7 +23201,7 @@ var decodeSessionEventRejection = (encoded) => decode5(encoded, eventRejectionSc
|
|
|
23062
23201
|
// src/config.ts
|
|
23063
23202
|
function loadDefaultWorkspace(environment = process.env) {
|
|
23064
23203
|
const { MOBIUS_DEFAULT_WORKSPACE: configuredWorkspace } = environment;
|
|
23065
|
-
return configuredWorkspace ??
|
|
23204
|
+
return configuredWorkspace ?? join14(readStateDirectory(environment), "workspace");
|
|
23066
23205
|
}
|
|
23067
23206
|
function createDaemonConfig(connection, agents = [], installableAgents = []) {
|
|
23068
23207
|
return {
|
|
@@ -23079,7 +23218,7 @@ function createDaemonConfig(connection, agents = [], installableAgents = []) {
|
|
|
23079
23218
|
|
|
23080
23219
|
// src/run-daemon.ts
|
|
23081
23220
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
23082
|
-
import { basename as basename4, join as
|
|
23221
|
+
import { basename as basename4, join as join16 } from "node:path";
|
|
23083
23222
|
import { styleText } from "node:util";
|
|
23084
23223
|
import { fetch as fetch6, WebSocket as WebSocket2 } from "undici";
|
|
23085
23224
|
|
|
@@ -23094,7 +23233,7 @@ import {
|
|
|
23094
23233
|
|
|
23095
23234
|
// src/authorization/local-raster.ts
|
|
23096
23235
|
import { readFile, realpath as realpath6, stat as stat5 } from "node:fs/promises";
|
|
23097
|
-
import { basename, isAbsolute as
|
|
23236
|
+
import { basename, isAbsolute as isAbsolute8, normalize as normalize2, relative as relative4, sep as sep4 } from "node:path";
|
|
23098
23237
|
import { fileURLToPath } from "node:url";
|
|
23099
23238
|
var MAX_LOCAL_RASTER_BYTES = 3e6;
|
|
23100
23239
|
var PNG_SIGNATURE = Uint8Array.of(137, 80, 78, 71);
|
|
@@ -23137,17 +23276,17 @@ function sniffRasterMime(bytes) {
|
|
|
23137
23276
|
}
|
|
23138
23277
|
function isInsideRoot(root, target) {
|
|
23139
23278
|
const relation = relative4(root, target);
|
|
23140
|
-
return relation !== ".." && !relation.startsWith(`..${sep4}`) && !
|
|
23279
|
+
return relation !== ".." && !relation.startsWith(`..${sep4}`) && !isAbsolute8(relation);
|
|
23141
23280
|
}
|
|
23142
23281
|
async function resolveCanonicalPath(requested, signal) {
|
|
23143
23282
|
signal.throwIfAborted();
|
|
23144
|
-
if (!
|
|
23283
|
+
if (!isAbsolute8(requested) || requested.includes("\0") || normalize2(requested) !== requested) {
|
|
23145
23284
|
return null;
|
|
23146
23285
|
}
|
|
23147
23286
|
try {
|
|
23148
23287
|
const target = await realpath6(requested);
|
|
23149
23288
|
signal.throwIfAborted();
|
|
23150
|
-
if (!
|
|
23289
|
+
if (!isAbsolute8(target) || normalize2(target) !== target) {
|
|
23151
23290
|
return null;
|
|
23152
23291
|
}
|
|
23153
23292
|
return target;
|
|
@@ -27677,7 +27816,7 @@ var LocalAuthorizationError = class extends Error {
|
|
|
27677
27816
|
// src/authorization/workspace-directory.ts
|
|
27678
27817
|
import { readdir, realpath as realpath7, stat as stat6 } from "node:fs/promises";
|
|
27679
27818
|
import { homedir as homedir2 } from "node:os";
|
|
27680
|
-
import { basename as basename2, dirname as dirname5, isAbsolute as
|
|
27819
|
+
import { basename as basename2, dirname as dirname5, isAbsolute as isAbsolute9, join as join15, normalize as normalize3, relative as relative5 } from "node:path";
|
|
27681
27820
|
var WorkspaceDirectoryListing = class {
|
|
27682
27821
|
directoryId;
|
|
27683
27822
|
directoryLabel;
|
|
@@ -27729,7 +27868,7 @@ var WorkspaceDirectoryService = class {
|
|
|
27729
27868
|
}
|
|
27730
27869
|
if (id.startsWith("path-")) {
|
|
27731
27870
|
const path2 = decodePath(id, "path-");
|
|
27732
|
-
if (
|
|
27871
|
+
if (isAbsolute9(path2)) {
|
|
27733
27872
|
return path2;
|
|
27734
27873
|
}
|
|
27735
27874
|
}
|
|
@@ -27737,7 +27876,7 @@ var WorkspaceDirectoryService = class {
|
|
|
27737
27876
|
};
|
|
27738
27877
|
resolvePath = async (requested, signal) => {
|
|
27739
27878
|
signal.throwIfAborted();
|
|
27740
|
-
if (!
|
|
27879
|
+
if (!isAbsolute9(requested) || requested.includes("\0") || normalize3(requested) !== requested) {
|
|
27741
27880
|
throw new LocalAuthorizationError("The local directory path is invalid");
|
|
27742
27881
|
}
|
|
27743
27882
|
try {
|
|
@@ -27745,7 +27884,7 @@ var WorkspaceDirectoryService = class {
|
|
|
27745
27884
|
signal.throwIfAborted();
|
|
27746
27885
|
const metadata = await stat6(target);
|
|
27747
27886
|
signal.throwIfAborted();
|
|
27748
|
-
if (!
|
|
27887
|
+
if (!isAbsolute9(target) || normalize3(target) !== target || !metadata.isDirectory()) {
|
|
27749
27888
|
throw new LocalAuthorizationError("The selected location is not a directory");
|
|
27750
27889
|
}
|
|
27751
27890
|
return target;
|
|
@@ -27761,7 +27900,7 @@ var WorkspaceDirectoryService = class {
|
|
|
27761
27900
|
};
|
|
27762
27901
|
label = (path2) => {
|
|
27763
27902
|
const suffix = relative5(homedir2(), path2);
|
|
27764
|
-
return suffix === "" ? "~" : !
|
|
27903
|
+
return suffix === "" ? "~" : !isAbsolute9(suffix) && suffix !== ".." && !suffix.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`) ? `~/${suffix.replaceAll("\\", "/")}` : path2;
|
|
27765
27904
|
};
|
|
27766
27905
|
identify = async (bindingId, requestedPath, signal) => {
|
|
27767
27906
|
this.authorizeMachine(bindingId);
|
|
@@ -27791,7 +27930,7 @@ var WorkspaceDirectoryService = class {
|
|
|
27791
27930
|
continue;
|
|
27792
27931
|
}
|
|
27793
27932
|
try {
|
|
27794
|
-
const path2 = await this.resolvePath(
|
|
27933
|
+
const path2 = await this.resolvePath(join15(target, child.name), signal);
|
|
27795
27934
|
entries.push({ directoryId: encodePath(path2), name: child.name });
|
|
27796
27935
|
} catch (cause) {
|
|
27797
27936
|
signal.throwIfAborted();
|
|
@@ -28302,7 +28441,7 @@ var BotExecutionContextRegistry = class {
|
|
|
28302
28441
|
// src/bots/bot-outbound-ipc.ts
|
|
28303
28442
|
import { chmod as chmod2, mkdir as mkdir3, unlink } from "node:fs/promises";
|
|
28304
28443
|
import { createServer } from "node:net";
|
|
28305
|
-
import { dirname as dirname6, isAbsolute as
|
|
28444
|
+
import { dirname as dirname6, isAbsolute as isAbsolute10 } from "node:path";
|
|
28306
28445
|
import { fetch as fetch4 } from "undici";
|
|
28307
28446
|
var BOT_IPC_REQUEST_LIMIT = 32 * 1024;
|
|
28308
28447
|
var BOT_IPC_TIMEOUT_MILLISECONDS = 2e4;
|
|
@@ -28400,7 +28539,7 @@ var BotOutboundIpcServer = class {
|
|
|
28400
28539
|
#usesFilesystemSocket;
|
|
28401
28540
|
constructor(socketPath, relayUrl, registry2) {
|
|
28402
28541
|
const usesFilesystemSocket = !socketPath.startsWith(WINDOWS_NAMED_PIPE_PREFIX);
|
|
28403
|
-
if (usesFilesystemSocket && !
|
|
28542
|
+
if (usesFilesystemSocket && !isAbsolute10(socketPath)) {
|
|
28404
28543
|
throw new Error("The Bot IPC path must be absolute");
|
|
28405
28544
|
}
|
|
28406
28545
|
this.#registry = registry2;
|
|
@@ -30340,7 +30479,7 @@ function botIpcSocketPath() {
|
|
|
30340
30479
|
if (process.platform === "win32") {
|
|
30341
30480
|
return `\\\\.\\pipe\\mobius-bot-${randomUUID4()}`;
|
|
30342
30481
|
}
|
|
30343
|
-
return
|
|
30482
|
+
return join16("/tmp", `mobius-bot-${randomUUID4()}.sock`);
|
|
30344
30483
|
}
|
|
30345
30484
|
var DaemonAcpObserver = class {
|
|
30346
30485
|
#config;
|
|
@@ -32288,7 +32427,7 @@ async function runDaemon(config2, audit, signal, timer = systemDaemonTimer) {
|
|
|
32288
32427
|
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
32289
32428
|
import { mkdir as mkdir4, open as open4, realpath as realpath8, rename as rename3, stat as stat8, writeFile as writeFile2 } from "node:fs/promises";
|
|
32290
32429
|
import { hostname as hostname3 } from "node:os";
|
|
32291
|
-
import { basename as basename5, join as
|
|
32430
|
+
import { basename as basename5, join as join17, resolve as resolve4 } from "node:path";
|
|
32292
32431
|
import { fetch as fetch7 } from "undici";
|
|
32293
32432
|
var PAIRING_TIMEOUT_MILLISECONDS = 2e4;
|
|
32294
32433
|
var PAIRING_CODE_PATTERN = /^[A-HJ-NP-Z2-9]{4}(?:-[A-HJ-NP-Z2-9]{4}){4}$/;
|
|
@@ -32443,10 +32582,10 @@ async function claimPairing(options, defaultWorkspace, localAgents, installableA
|
|
|
32443
32582
|
return options.pairingId.length > 0 ? decodePairingResponse(value, "runtimeCredential", REDEEM_RESPONSE_KEYS) : decodePairingResponse(value, "daemonToken", CLAIM_RESPONSE_KEYS);
|
|
32444
32583
|
}
|
|
32445
32584
|
async function persistConnection(channelId, relayOrigin, runtimeCredential2, defaultWorkspace, environment) {
|
|
32446
|
-
const connectionsDirectory =
|
|
32585
|
+
const connectionsDirectory = join17(readStateDirectory(environment), "connections");
|
|
32447
32586
|
await mkdir4(connectionsDirectory, { mode: 448, recursive: true });
|
|
32448
|
-
const connectionPath =
|
|
32449
|
-
const temporaryPath =
|
|
32587
|
+
const connectionPath = join17(connectionsDirectory, `${channelId}.json`);
|
|
32588
|
+
const temporaryPath = join17(connectionsDirectory, `.${channelId}.${randomUUID5()}.tmp`);
|
|
32450
32589
|
await writeFile2(
|
|
32451
32590
|
temporaryPath,
|
|
32452
32591
|
`${JSON.stringify(
|
|
@@ -32484,7 +32623,7 @@ function decodeSavedConnection(value, expectedChannelId) {
|
|
|
32484
32623
|
};
|
|
32485
32624
|
}
|
|
32486
32625
|
async function readSavedConnection(channelId, environment) {
|
|
32487
|
-
const connectionPath =
|
|
32626
|
+
const connectionPath = join17(readStateDirectory(environment), "connections", `${channelId}.json`);
|
|
32488
32627
|
let encoded = "";
|
|
32489
32628
|
const handle = await open4(connectionPath, "r");
|
|
32490
32629
|
try {
|
|
@@ -32520,7 +32659,7 @@ function buildPairedDaemon(connection, connectionPath, inventory, environment) {
|
|
|
32520
32659
|
const relayUrl = mobiusApiUrl(connection.relayOrigin, "/v1/runtimes/connect");
|
|
32521
32660
|
relayUrl.protocol = relayUrl.protocol === "https:" ? "wss:" : "ws:";
|
|
32522
32661
|
relayUrl.searchParams.set("token", connection.runtimeCredential);
|
|
32523
|
-
const auditDatabasePath =
|
|
32662
|
+
const auditDatabasePath = join17(readStateDirectory(environment), "audit", `${connection.channelId}.sqlite`);
|
|
32524
32663
|
return {
|
|
32525
32664
|
channelUrl: new URL(`/channels/${encodeURIComponent(connection.channelId)}`, connection.relayOrigin).toString(),
|
|
32526
32665
|
config: createDaemonConfig(
|
|
@@ -32579,7 +32718,7 @@ async function pairMobiusRuntime(options, signal, environment = process.env) {
|
|
|
32579
32718
|
}
|
|
32580
32719
|
async function resumeMobiusRuntime(channelId, signal, environment = process.env) {
|
|
32581
32720
|
const normalizedChannelId = validatePairingId(channelId);
|
|
32582
|
-
const connectionPath =
|
|
32721
|
+
const connectionPath = join17(readStateDirectory(environment), "connections", `${normalizedChannelId}.json`);
|
|
32583
32722
|
const connection = await readSavedConnection(normalizedChannelId, environment);
|
|
32584
32723
|
const inventory = await discoverLocalAgentInventory({
|
|
32585
32724
|
defaultWorkspace: connection.defaultWorkspace,
|
|
@@ -32654,7 +32793,7 @@ function loadMobiusRuntimeConnection(environment = process.env) {
|
|
|
32654
32793
|
throw new MobiusRuntimeConfigurationError("MOBIUS_CHANNEL_ID is invalid");
|
|
32655
32794
|
}
|
|
32656
32795
|
return Object.freeze({
|
|
32657
|
-
auditDatabasePath: environment["MOBIUS_AUDIT_DATABASE"]?.trim() ||
|
|
32796
|
+
auditDatabasePath: environment["MOBIUS_AUDIT_DATABASE"]?.trim() || join18(readStateDirectory(environment), "audit", `${channelId}.sqlite`),
|
|
32658
32797
|
channelId,
|
|
32659
32798
|
defaultWorkspace: loadDefaultWorkspace(environment),
|
|
32660
32799
|
relayUrl: requiredEnvironmentValue(environment, "MOBIUS_RELAY_URL"),
|