@agentrix/shared 2.2.4 → 2.2.6
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/errors-BdwSwKpv.d.cts +2602 -0
- package/dist/errors-myQvpVrM.cjs +95 -0
- package/dist/index.cjs +264 -570
- package/dist/index.d.cts +1360 -3945
- package/dist/node.cjs +254 -0
- package/dist/node.d.cts +52 -0
- package/package.json +7 -1
package/dist/index.cjs
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var zod = require('zod');
|
|
4
|
-
var node_fs = require('node:fs');
|
|
5
|
-
var node_path = require('node:path');
|
|
6
|
-
var os = require('node:os');
|
|
7
4
|
var tweetnacl = require('tweetnacl');
|
|
8
5
|
var base64js = require('base64-js');
|
|
6
|
+
var CryptoJS = require('crypto-js');
|
|
7
|
+
var errors = require('./errors-myQvpVrM.cjs');
|
|
9
8
|
|
|
10
9
|
function _interopNamespaceDefault(e) {
|
|
11
10
|
var n = Object.create(null);
|
|
@@ -24,7 +23,6 @@ function _interopNamespaceDefault(e) {
|
|
|
24
23
|
return Object.freeze(n);
|
|
25
24
|
}
|
|
26
25
|
|
|
27
|
-
var os__namespace = /*#__PURE__*/_interopNamespaceDefault(os);
|
|
28
26
|
var base64js__namespace = /*#__PURE__*/_interopNamespaceDefault(base64js);
|
|
29
27
|
|
|
30
28
|
const ApiErrorSchema = zod.z.object({
|
|
@@ -1352,6 +1350,235 @@ const RpcResponseSchema = zod.z.object({
|
|
|
1352
1350
|
}).optional()
|
|
1353
1351
|
});
|
|
1354
1352
|
|
|
1353
|
+
async function hmac_sha512(key, data) {
|
|
1354
|
+
const keyWordArray = CryptoJS.lib.WordArray.create(key);
|
|
1355
|
+
const dataWordArray = CryptoJS.lib.WordArray.create(data);
|
|
1356
|
+
const hmac = CryptoJS.HmacSHA512(dataWordArray, keyWordArray);
|
|
1357
|
+
const words = hmac.words;
|
|
1358
|
+
const sigBytes = hmac.sigBytes;
|
|
1359
|
+
const result = new Uint8Array(sigBytes);
|
|
1360
|
+
for (let i = 0; i < sigBytes; i++) {
|
|
1361
|
+
const byte = words[i >>> 2] >>> 24 - i % 4 * 8 & 255;
|
|
1362
|
+
result[i] = byte;
|
|
1363
|
+
}
|
|
1364
|
+
return result;
|
|
1365
|
+
}
|
|
1366
|
+
|
|
1367
|
+
async function deriveSecretKeyTreeRoot(seed, usage) {
|
|
1368
|
+
const I = await hmac_sha512(new TextEncoder().encode(usage + " Master Seed"), seed);
|
|
1369
|
+
return {
|
|
1370
|
+
key: I.slice(0, 32),
|
|
1371
|
+
chainCode: I.slice(32)
|
|
1372
|
+
};
|
|
1373
|
+
}
|
|
1374
|
+
async function deriveSecretKeyTreeChild(chainCode, index) {
|
|
1375
|
+
const data = new Uint8Array([0, ...new TextEncoder().encode(index)]);
|
|
1376
|
+
const I = await hmac_sha512(chainCode, data);
|
|
1377
|
+
return {
|
|
1378
|
+
key: I.subarray(0, 32),
|
|
1379
|
+
chainCode: I.subarray(32)
|
|
1380
|
+
};
|
|
1381
|
+
}
|
|
1382
|
+
async function deriveKey(master, usage, path) {
|
|
1383
|
+
let state = await deriveSecretKeyTreeRoot(master, usage);
|
|
1384
|
+
let remaining = [...path];
|
|
1385
|
+
while (remaining.length > 0) {
|
|
1386
|
+
let index = remaining[0];
|
|
1387
|
+
remaining = remaining.slice(1);
|
|
1388
|
+
state = await deriveSecretKeyTreeChild(state.chainCode, index);
|
|
1389
|
+
}
|
|
1390
|
+
return state.key;
|
|
1391
|
+
}
|
|
1392
|
+
|
|
1393
|
+
function encodeBase64(buffer, variant = "base64") {
|
|
1394
|
+
if (variant === "base64url") {
|
|
1395
|
+
return encodeBase64Url(buffer);
|
|
1396
|
+
}
|
|
1397
|
+
return base64js__namespace.fromByteArray(buffer);
|
|
1398
|
+
}
|
|
1399
|
+
function encodeBase64Url(buffer) {
|
|
1400
|
+
return base64js__namespace.fromByteArray(buffer).replaceAll("+", "-").replaceAll("/", "_").replaceAll("=", "");
|
|
1401
|
+
}
|
|
1402
|
+
function decodeBase64(base64, variant = "base64") {
|
|
1403
|
+
if (!base64) {
|
|
1404
|
+
throw new Error("Invalid base64 input: must be a non-empty string");
|
|
1405
|
+
}
|
|
1406
|
+
const cleaned = base64.replace(/\s/g, "");
|
|
1407
|
+
if (!cleaned) {
|
|
1408
|
+
throw new Error("Invalid base64 input: empty after removing whitespace");
|
|
1409
|
+
}
|
|
1410
|
+
try {
|
|
1411
|
+
if (variant === "base64url") {
|
|
1412
|
+
let base64Standard = cleaned.replace(/-/g, "+").replace(/_/g, "/");
|
|
1413
|
+
const padding = (4 - base64Standard.length % 4) % 4;
|
|
1414
|
+
if (padding > 0) {
|
|
1415
|
+
base64Standard += "=".repeat(padding);
|
|
1416
|
+
}
|
|
1417
|
+
return base64js__namespace.toByteArray(base64Standard);
|
|
1418
|
+
}
|
|
1419
|
+
return base64js__namespace.toByteArray(cleaned);
|
|
1420
|
+
} catch (error) {
|
|
1421
|
+
throw new Error(`Failed to decode base64 (variant: ${variant}): ${error instanceof Error ? error.message : String(error)}`);
|
|
1422
|
+
}
|
|
1423
|
+
}
|
|
1424
|
+
function getRandomBytes(size) {
|
|
1425
|
+
return tweetnacl.randomBytes(size);
|
|
1426
|
+
}
|
|
1427
|
+
function generateAESKey() {
|
|
1428
|
+
return getRandomBytes(tweetnacl.secretbox.keyLength);
|
|
1429
|
+
}
|
|
1430
|
+
function generateAESKeyBase64(variant = "base64") {
|
|
1431
|
+
const key = generateAESKey();
|
|
1432
|
+
return encodeBase64(key, variant);
|
|
1433
|
+
}
|
|
1434
|
+
function encryptAES(data, dataKey) {
|
|
1435
|
+
if (dataKey.length !== tweetnacl.secretbox.keyLength) {
|
|
1436
|
+
throw new Error(`Invalid key length: expected ${tweetnacl.secretbox.keyLength}, got ${dataKey.length}`);
|
|
1437
|
+
}
|
|
1438
|
+
const nonce = getRandomBytes(tweetnacl.secretbox.nonceLength);
|
|
1439
|
+
const plaintext = new TextEncoder().encode(JSON.stringify(data));
|
|
1440
|
+
const encrypted = tweetnacl.secretbox(plaintext, nonce, dataKey);
|
|
1441
|
+
const bundle = new Uint8Array(1 + nonce.length + encrypted.length);
|
|
1442
|
+
bundle.set([0], 0);
|
|
1443
|
+
bundle.set(nonce, 1);
|
|
1444
|
+
bundle.set(encrypted, 1 + nonce.length);
|
|
1445
|
+
return bundle;
|
|
1446
|
+
}
|
|
1447
|
+
function decryptAES(bundle, dataKey) {
|
|
1448
|
+
if (dataKey.length !== tweetnacl.secretbox.keyLength) {
|
|
1449
|
+
return null;
|
|
1450
|
+
}
|
|
1451
|
+
if (bundle.length < 1) {
|
|
1452
|
+
return null;
|
|
1453
|
+
}
|
|
1454
|
+
if (bundle[0] !== 0) {
|
|
1455
|
+
return null;
|
|
1456
|
+
}
|
|
1457
|
+
const minLength = 1 + tweetnacl.secretbox.nonceLength + tweetnacl.secretbox.overheadLength;
|
|
1458
|
+
if (bundle.length < minLength) {
|
|
1459
|
+
return null;
|
|
1460
|
+
}
|
|
1461
|
+
const nonce = bundle.slice(1, 1 + tweetnacl.secretbox.nonceLength);
|
|
1462
|
+
const ciphertext = bundle.slice(1 + tweetnacl.secretbox.nonceLength);
|
|
1463
|
+
try {
|
|
1464
|
+
const decrypted = tweetnacl.secretbox.open(ciphertext, nonce, dataKey);
|
|
1465
|
+
if (!decrypted) {
|
|
1466
|
+
return null;
|
|
1467
|
+
}
|
|
1468
|
+
return JSON.parse(new TextDecoder().decode(decrypted));
|
|
1469
|
+
} catch (error) {
|
|
1470
|
+
return null;
|
|
1471
|
+
}
|
|
1472
|
+
}
|
|
1473
|
+
async function createKeyPairWithUit8Array(masterSecret) {
|
|
1474
|
+
const contentDataKey = await deriveKey(masterSecret, "Agentrix EnCoder", ["content"]);
|
|
1475
|
+
return tweetnacl.box.keyPair.fromSecretKey(contentDataKey);
|
|
1476
|
+
}
|
|
1477
|
+
async function createKeyPair(masterSecret, variant = "base64") {
|
|
1478
|
+
return await createKeyPairWithUit8Array(decodeBase64(masterSecret, variant));
|
|
1479
|
+
}
|
|
1480
|
+
function decryptWithEphemeralKey(encryptedBundle, secretKey) {
|
|
1481
|
+
const ephemeralPublicKey = encryptedBundle.slice(0, 32);
|
|
1482
|
+
const nonce = encryptedBundle.slice(32, 32 + tweetnacl.box.nonceLength);
|
|
1483
|
+
const encrypted = encryptedBundle.slice(32 + tweetnacl.box.nonceLength);
|
|
1484
|
+
const decrypted = tweetnacl.box.open(encrypted, nonce, ephemeralPublicKey, secretKey);
|
|
1485
|
+
if (!decrypted) {
|
|
1486
|
+
return null;
|
|
1487
|
+
}
|
|
1488
|
+
return decrypted;
|
|
1489
|
+
}
|
|
1490
|
+
function encryptWithEphemeralKey(data, publicKey) {
|
|
1491
|
+
const ephemeralKeyPair = tweetnacl.box.keyPair();
|
|
1492
|
+
const nonce = getRandomBytes(tweetnacl.box.nonceLength);
|
|
1493
|
+
const encrypted = tweetnacl.box(data, nonce, publicKey, ephemeralKeyPair.secretKey);
|
|
1494
|
+
const result = new Uint8Array(ephemeralKeyPair.publicKey.length + nonce.length + encrypted.length);
|
|
1495
|
+
result.set(ephemeralKeyPair.publicKey, 0);
|
|
1496
|
+
result.set(nonce, ephemeralKeyPair.publicKey.length);
|
|
1497
|
+
result.set(encrypted, ephemeralKeyPair.publicKey.length + nonce.length);
|
|
1498
|
+
return result;
|
|
1499
|
+
}
|
|
1500
|
+
function encryptSdkMessage(message, dataKey) {
|
|
1501
|
+
const encryptedWithVersion = encryptAES(message, dataKey);
|
|
1502
|
+
const encryptedWithoutVersion = encryptedWithVersion.slice(1);
|
|
1503
|
+
return encodeBase64(encryptedWithoutVersion);
|
|
1504
|
+
}
|
|
1505
|
+
function decryptSdkMessage(encryptedMessage, dataKey) {
|
|
1506
|
+
try {
|
|
1507
|
+
const encryptedWithoutVersion = decodeBase64(encryptedMessage);
|
|
1508
|
+
const encryptedWithVersion = new Uint8Array(1 + encryptedWithoutVersion.length);
|
|
1509
|
+
encryptedWithVersion.set([0], 0);
|
|
1510
|
+
encryptedWithVersion.set(encryptedWithoutVersion, 1);
|
|
1511
|
+
return decryptAES(encryptedWithVersion, dataKey);
|
|
1512
|
+
} catch (error) {
|
|
1513
|
+
return null;
|
|
1514
|
+
}
|
|
1515
|
+
}
|
|
1516
|
+
function encryptMachineEncryptionKey(machinePublicKey, aesKey, userPublicKey) {
|
|
1517
|
+
if (machinePublicKey.length !== 32) {
|
|
1518
|
+
throw new Error(`Invalid machine public key length: expected 32, got ${machinePublicKey.length}`);
|
|
1519
|
+
}
|
|
1520
|
+
if (aesKey.length !== tweetnacl.secretbox.keyLength) {
|
|
1521
|
+
throw new Error(`Invalid AES key length: expected ${tweetnacl.secretbox.keyLength}, got ${aesKey.length}`);
|
|
1522
|
+
}
|
|
1523
|
+
if (userPublicKey.length !== 32) {
|
|
1524
|
+
throw new Error(`Invalid user public key length: expected 32, got ${userPublicKey.length}`);
|
|
1525
|
+
}
|
|
1526
|
+
const combined = new Uint8Array(machinePublicKey.length + aesKey.length);
|
|
1527
|
+
combined.set(machinePublicKey, 0);
|
|
1528
|
+
combined.set(aesKey, machinePublicKey.length);
|
|
1529
|
+
const encrypted = encryptWithEphemeralKey(combined, userPublicKey);
|
|
1530
|
+
return encodeBase64(encrypted);
|
|
1531
|
+
}
|
|
1532
|
+
function decryptMachineEncryptionKey(encryptedData, userPrivateKey) {
|
|
1533
|
+
if (userPrivateKey.length !== 32) {
|
|
1534
|
+
return null;
|
|
1535
|
+
}
|
|
1536
|
+
try {
|
|
1537
|
+
const encryptedBundle = decodeBase64(encryptedData);
|
|
1538
|
+
const decrypted = decryptWithEphemeralKey(encryptedBundle, userPrivateKey);
|
|
1539
|
+
if (!decrypted) {
|
|
1540
|
+
return null;
|
|
1541
|
+
}
|
|
1542
|
+
const expectedLength = 32 + tweetnacl.secretbox.keyLength;
|
|
1543
|
+
if (decrypted.length !== expectedLength) {
|
|
1544
|
+
return null;
|
|
1545
|
+
}
|
|
1546
|
+
const machinePublicKey = decrypted.slice(0, 32);
|
|
1547
|
+
const aesKey = decrypted.slice(32);
|
|
1548
|
+
return { machinePublicKey, aesKey };
|
|
1549
|
+
} catch (error) {
|
|
1550
|
+
return null;
|
|
1551
|
+
}
|
|
1552
|
+
}
|
|
1553
|
+
function createTaskEncryptionPayload(machineEncryptionKey) {
|
|
1554
|
+
const taskDataKey = generateAESKey();
|
|
1555
|
+
return {
|
|
1556
|
+
taskDataKey,
|
|
1557
|
+
dataEncryptionKey: encodeBase64(
|
|
1558
|
+
encryptWithEphemeralKey(taskDataKey, machineEncryptionKey.machinePublicKey)
|
|
1559
|
+
),
|
|
1560
|
+
ownerEncryptedDataKey: encodeBase64(
|
|
1561
|
+
encryptAES(encodeBase64(taskDataKey), machineEncryptionKey.aesKey)
|
|
1562
|
+
)
|
|
1563
|
+
};
|
|
1564
|
+
}
|
|
1565
|
+
function encryptFileContent(fileContentBase64, dataKey) {
|
|
1566
|
+
const encryptedWithVersion = encryptAES(fileContentBase64, dataKey);
|
|
1567
|
+
const encryptedWithoutVersion = encryptedWithVersion.slice(1);
|
|
1568
|
+
return encodeBase64(encryptedWithoutVersion);
|
|
1569
|
+
}
|
|
1570
|
+
function decryptFileContent(encryptedContent, dataKey) {
|
|
1571
|
+
try {
|
|
1572
|
+
const encryptedWithoutVersion = decodeBase64(encryptedContent);
|
|
1573
|
+
const encryptedWithVersion = new Uint8Array(1 + encryptedWithoutVersion.length);
|
|
1574
|
+
encryptedWithVersion.set([0], 0);
|
|
1575
|
+
encryptedWithVersion.set(encryptedWithoutVersion, 1);
|
|
1576
|
+
return decryptAES(encryptedWithVersion, dataKey);
|
|
1577
|
+
} catch (error) {
|
|
1578
|
+
return null;
|
|
1579
|
+
}
|
|
1580
|
+
}
|
|
1581
|
+
|
|
1355
1582
|
const AskUserOptionSchema = zod.z.object({
|
|
1356
1583
|
label: zod.z.string(),
|
|
1357
1584
|
// Option label (1-5 words)
|
|
@@ -1400,8 +1627,11 @@ function isCompanionHeartbeatMessage(message) {
|
|
|
1400
1627
|
function isCompanionReminderMessage(message) {
|
|
1401
1628
|
return typeof message === "object" && message !== null && "type" in message && message.type === "companion_reminder";
|
|
1402
1629
|
}
|
|
1630
|
+
function isSubTaskAskUserMessage(message) {
|
|
1631
|
+
return typeof message === "object" && message !== null && "type" in message && message.type === "sub_task_ask_user";
|
|
1632
|
+
}
|
|
1403
1633
|
function isSDKMessage(message) {
|
|
1404
|
-
return typeof message === "object" && message !== null && "type" in message && message.type !== "ask_user" && message.type !== "ask_user_response" && message.type !== "companion_heartbeat" && message.type !== "companion_reminder";
|
|
1634
|
+
return typeof message === "object" && message !== null && "type" in message && message.type !== "ask_user" && message.type !== "ask_user_response" && message.type !== "companion_heartbeat" && message.type !== "companion_reminder" && message.type !== "sub_task_ask_user";
|
|
1405
1635
|
}
|
|
1406
1636
|
function isSDKUserMessage(message) {
|
|
1407
1637
|
return isSDKMessage(message) && message.type === "user";
|
|
@@ -1410,7 +1640,10 @@ const EventBaseSchema = zod.z.object({
|
|
|
1410
1640
|
eventId: zod.z.string()
|
|
1411
1641
|
});
|
|
1412
1642
|
const createEventId = () => {
|
|
1413
|
-
|
|
1643
|
+
const bytes = getRandomBytes(16);
|
|
1644
|
+
const hex = Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
1645
|
+
const uuid = `${hex.slice(0, 8)}-${hex.slice(8, 12)}-4${hex.slice(13, 16)}-${(parseInt(hex.slice(16, 18), 16) & 63 | 128).toString(16).padStart(2, "0")}${hex.slice(18, 20)}-${hex.slice(20, 32)}`;
|
|
1646
|
+
return `event-${uuid}`;
|
|
1414
1647
|
};
|
|
1415
1648
|
const EventAckSchema = EventBaseSchema.extend({
|
|
1416
1649
|
status: zod.z.enum(["success", "failed"]),
|
|
@@ -2050,308 +2283,21 @@ function workerAuth(token, machineId, taskId) {
|
|
|
2050
2283
|
};
|
|
2051
2284
|
}
|
|
2052
2285
|
|
|
2053
|
-
|
|
2054
|
-
function setAgentContext(context) {
|
|
2055
|
-
agentContext = context;
|
|
2056
|
-
}
|
|
2057
|
-
function getAgentContext() {
|
|
2058
|
-
if (!agentContext) {
|
|
2059
|
-
throw new Error("Agent context not initialized. Call setAgentContext() first.");
|
|
2060
|
-
}
|
|
2061
|
-
return agentContext;
|
|
2062
|
-
}
|
|
2063
|
-
|
|
2064
|
-
const FRAMEWORK_TYPES = ["claude", "codex"];
|
|
2065
|
-
|
|
2066
|
-
const AgentMetadataSchema = zod.z.object({
|
|
2286
|
+
const CompanionWorkspaceFileSchema = zod.z.object({
|
|
2067
2287
|
name: zod.z.string(),
|
|
2068
|
-
|
|
2069
|
-
|
|
2288
|
+
path: zod.z.string(),
|
|
2289
|
+
// relative to workspace root
|
|
2290
|
+
size: zod.z.number(),
|
|
2291
|
+
modifiedAt: zod.z.number(),
|
|
2292
|
+
isDirectory: zod.z.boolean()
|
|
2070
2293
|
});
|
|
2071
|
-
const
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
//
|
|
2077
|
-
|
|
2078
|
-
systemPrompt: zod.z.object({
|
|
2079
|
-
path: zod.z.string(),
|
|
2080
|
-
mode: zod.z.enum(["append", "replace"]).optional().default("append")
|
|
2081
|
-
}).optional(),
|
|
2082
|
-
settings: zod.z.object({
|
|
2083
|
-
permissionMode: zod.z.enum(["default", "acceptEdits", "bypassPermissions", "plan"]).optional(),
|
|
2084
|
-
allowedTools: zod.z.array(zod.z.string()).optional()
|
|
2085
|
-
}).optional(),
|
|
2086
|
-
pullRequestPrompt: zod.z.object({
|
|
2087
|
-
path: zod.z.string(),
|
|
2088
|
-
mode: zod.z.enum(["append", "replace"]).optional().default("append")
|
|
2089
|
-
}).optional(),
|
|
2090
|
-
// SDK MCP Tools - scripts that export createSdkMcpServer()
|
|
2091
|
-
sdkMcpTools: zod.z.array(zod.z.string()).optional()
|
|
2092
|
-
});
|
|
2093
|
-
|
|
2094
|
-
class AgentError extends Error {
|
|
2095
|
-
constructor(message) {
|
|
2096
|
-
super(message);
|
|
2097
|
-
this.name = "AgentError";
|
|
2098
|
-
}
|
|
2099
|
-
}
|
|
2100
|
-
class AgentNotFoundError extends AgentError {
|
|
2101
|
-
constructor(agentId) {
|
|
2102
|
-
super(`Agent not found: ${agentId}`);
|
|
2103
|
-
this.name = "AgentNotFoundError";
|
|
2104
|
-
}
|
|
2105
|
-
}
|
|
2106
|
-
class AgentConfigValidationError extends AgentError {
|
|
2107
|
-
constructor(message, errors) {
|
|
2108
|
-
super(message);
|
|
2109
|
-
this.errors = errors;
|
|
2110
|
-
this.name = "AgentConfigValidationError";
|
|
2111
|
-
}
|
|
2112
|
-
}
|
|
2113
|
-
class FrameworkNotSupportedError extends AgentError {
|
|
2114
|
-
constructor(agentId, framework) {
|
|
2115
|
-
super(`Agent "${agentId}" does not support framework: ${framework}`);
|
|
2116
|
-
this.name = "FrameworkNotSupportedError";
|
|
2117
|
-
}
|
|
2118
|
-
}
|
|
2119
|
-
class AgentLoadError extends AgentError {
|
|
2120
|
-
constructor(message, cause) {
|
|
2121
|
-
super(message);
|
|
2122
|
-
this.cause = cause;
|
|
2123
|
-
this.name = "AgentLoadError";
|
|
2124
|
-
}
|
|
2125
|
-
}
|
|
2126
|
-
class MissingAgentFileError extends AgentError {
|
|
2127
|
-
constructor(filePath) {
|
|
2128
|
-
super(`Required agent file missing: ${filePath}`);
|
|
2129
|
-
this.name = "MissingAgentFileError";
|
|
2130
|
-
}
|
|
2131
|
-
}
|
|
2132
|
-
|
|
2133
|
-
function validateAgentDirectory(agentDir) {
|
|
2134
|
-
const errors = [];
|
|
2135
|
-
const warnings = [];
|
|
2136
|
-
if (!node_fs.existsSync(agentDir)) {
|
|
2137
|
-
errors.push(`Agent directory does not exist: ${agentDir}`);
|
|
2138
|
-
return { valid: false, errors, warnings };
|
|
2139
|
-
}
|
|
2140
|
-
if (!node_fs.statSync(agentDir).isDirectory()) {
|
|
2141
|
-
errors.push(`Path is not a directory: ${agentDir}`);
|
|
2142
|
-
return { valid: false, errors, warnings };
|
|
2143
|
-
}
|
|
2144
|
-
const agentJsonPath = node_path.join(agentDir, "agent.json");
|
|
2145
|
-
if (!node_fs.existsSync(agentJsonPath)) {
|
|
2146
|
-
errors.push("Missing required file: agent.json");
|
|
2147
|
-
}
|
|
2148
|
-
const readmePath = node_path.join(agentDir, "README.md");
|
|
2149
|
-
if (!node_fs.existsSync(readmePath)) {
|
|
2150
|
-
warnings.push("Missing README.md (recommended)");
|
|
2151
|
-
}
|
|
2152
|
-
return {
|
|
2153
|
-
valid: errors.length === 0,
|
|
2154
|
-
errors,
|
|
2155
|
-
warnings
|
|
2156
|
-
};
|
|
2157
|
-
}
|
|
2158
|
-
function validateFrameworkDirectory(frameworkDir, framework) {
|
|
2159
|
-
const errors = [];
|
|
2160
|
-
const warnings = [];
|
|
2161
|
-
if (!node_fs.existsSync(frameworkDir)) {
|
|
2162
|
-
errors.push(`Framework directory does not exist: ${frameworkDir}`);
|
|
2163
|
-
return { valid: false, errors, warnings };
|
|
2164
|
-
}
|
|
2165
|
-
const configPath = node_path.join(frameworkDir, "config.json");
|
|
2166
|
-
if (!node_fs.existsSync(configPath)) {
|
|
2167
|
-
errors.push(`Missing required file: ${framework}/config.json`);
|
|
2168
|
-
}
|
|
2169
|
-
if (framework === "claude") {
|
|
2170
|
-
const mcpServersDir = node_path.join(frameworkDir, "mcp-servers");
|
|
2171
|
-
if (!node_fs.existsSync(mcpServersDir)) {
|
|
2172
|
-
warnings.push("Missing mcp-servers directory (optional)");
|
|
2173
|
-
}
|
|
2174
|
-
const skillsDir = node_path.join(frameworkDir, "skills");
|
|
2175
|
-
if (!node_fs.existsSync(skillsDir)) {
|
|
2176
|
-
warnings.push("Missing skills directory (optional)");
|
|
2177
|
-
}
|
|
2178
|
-
}
|
|
2179
|
-
return {
|
|
2180
|
-
valid: errors.length === 0,
|
|
2181
|
-
errors,
|
|
2182
|
-
warnings
|
|
2183
|
-
};
|
|
2184
|
-
}
|
|
2185
|
-
function assertFileExists(filePath, description) {
|
|
2186
|
-
if (!node_fs.existsSync(filePath)) {
|
|
2187
|
-
throw new MissingAgentFileError(description || filePath);
|
|
2188
|
-
}
|
|
2189
|
-
}
|
|
2190
|
-
function assertAgentExists(agentDir, agentId) {
|
|
2191
|
-
if (!node_fs.existsSync(agentDir)) {
|
|
2192
|
-
throw new AgentNotFoundError(agentId);
|
|
2193
|
-
}
|
|
2194
|
-
}
|
|
2195
|
-
|
|
2196
|
-
function discoverPlugins(pluginsDir) {
|
|
2197
|
-
if (!node_fs.existsSync(pluginsDir)) {
|
|
2198
|
-
return [];
|
|
2199
|
-
}
|
|
2200
|
-
return node_fs.readdirSync(pluginsDir, { withFileTypes: true }).filter((dirent) => dirent.isDirectory()).map((dirent) => node_path.join(pluginsDir, dirent.name)).filter((pluginPath) => isValidPluginDirectory(pluginPath));
|
|
2201
|
-
}
|
|
2202
|
-
function isValidPluginDirectory(pluginDir) {
|
|
2203
|
-
const manifestPath = node_path.join(pluginDir, ".claude-plugin", "plugin.json");
|
|
2204
|
-
return node_fs.existsSync(manifestPath);
|
|
2205
|
-
}
|
|
2206
|
-
|
|
2207
|
-
async function loadAgentConfig(options) {
|
|
2208
|
-
const { agentId, framework, validateOnly = false, agentDir: providedAgentDir } = options;
|
|
2209
|
-
const agentContext = getAgentContext();
|
|
2210
|
-
const agentDir = providedAgentDir || agentContext.resolveAgentDir(agentId);
|
|
2211
|
-
assertAgentExists(agentDir, agentId);
|
|
2212
|
-
const validation = validateAgentDirectory(agentDir);
|
|
2213
|
-
if (!validation.valid) {
|
|
2214
|
-
throw new AgentConfigValidationError(
|
|
2215
|
-
`Agent directory validation failed for "${agentId}"`,
|
|
2216
|
-
validation.errors
|
|
2217
|
-
);
|
|
2218
|
-
}
|
|
2219
|
-
if (validation.warnings.length > 0) {
|
|
2220
|
-
console.warn(`[AGENT] Warnings for agent "${agentId}":`, validation.warnings);
|
|
2221
|
-
}
|
|
2222
|
-
const metadata = await loadAgentMetadata(agentDir);
|
|
2223
|
-
const frameworkDirName = framework === "claude" ? "claude" : `.${framework}`;
|
|
2224
|
-
const frameworkDir = node_path.join(agentDir, frameworkDirName);
|
|
2225
|
-
if (!node_fs.existsSync(frameworkDir)) {
|
|
2226
|
-
throw new FrameworkNotSupportedError(agentId, framework);
|
|
2227
|
-
}
|
|
2228
|
-
if (validateOnly) {
|
|
2229
|
-
return {
|
|
2230
|
-
metadata,
|
|
2231
|
-
framework
|
|
2232
|
-
};
|
|
2233
|
-
}
|
|
2234
|
-
if (framework === "claude") {
|
|
2235
|
-
const claudeConfig = await loadClaudeConfiguration(agentDir);
|
|
2236
|
-
return {
|
|
2237
|
-
metadata,
|
|
2238
|
-
framework,
|
|
2239
|
-
claude: claudeConfig
|
|
2240
|
-
};
|
|
2241
|
-
}
|
|
2242
|
-
throw new AgentLoadError(`Framework "${framework}" loader not implemented`);
|
|
2243
|
-
}
|
|
2244
|
-
async function loadAgentMetadata(agentDir) {
|
|
2245
|
-
const agentJsonPath = node_path.join(agentDir, "agent.json");
|
|
2246
|
-
assertFileExists(agentJsonPath, "agent.json");
|
|
2247
|
-
try {
|
|
2248
|
-
const content = node_fs.readFileSync(agentJsonPath, "utf-8");
|
|
2249
|
-
const rawData = JSON.parse(content);
|
|
2250
|
-
const metadata = AgentMetadataSchema.parse(rawData);
|
|
2251
|
-
return metadata;
|
|
2252
|
-
} catch (error) {
|
|
2253
|
-
if (error instanceof SyntaxError) {
|
|
2254
|
-
throw new AgentConfigValidationError("Invalid JSON in agent.json");
|
|
2255
|
-
}
|
|
2256
|
-
throw new AgentConfigValidationError(
|
|
2257
|
-
`Invalid agent metadata: ${error instanceof Error ? error.message : String(error)}`
|
|
2258
|
-
);
|
|
2259
|
-
}
|
|
2260
|
-
}
|
|
2261
|
-
async function loadClaudeConfiguration(agentDir, metadata) {
|
|
2262
|
-
const claudeDir = node_path.join(agentDir, "claude");
|
|
2263
|
-
const validation = validateFrameworkDirectory(claudeDir, "claude");
|
|
2264
|
-
if (!validation.valid) {
|
|
2265
|
-
throw new AgentConfigValidationError(
|
|
2266
|
-
"Claude framework directory validation failed",
|
|
2267
|
-
validation.errors
|
|
2268
|
-
);
|
|
2269
|
-
}
|
|
2270
|
-
const config = await loadClaudeConfig(claudeDir);
|
|
2271
|
-
let systemPrompt;
|
|
2272
|
-
if (config.systemPrompt) {
|
|
2273
|
-
systemPrompt = await loadSystemPrompt(claudeDir, config.systemPrompt.path);
|
|
2274
|
-
}
|
|
2275
|
-
let prPromptTemplate;
|
|
2276
|
-
if (config.pullRequestPrompt) {
|
|
2277
|
-
prPromptTemplate = await loadSystemPrompt(claudeDir, config.pullRequestPrompt.path);
|
|
2278
|
-
}
|
|
2279
|
-
const pluginsDir = node_path.join(claudeDir, "plugins");
|
|
2280
|
-
const plugins = discoverPlugins(pluginsDir);
|
|
2281
|
-
return {
|
|
2282
|
-
config,
|
|
2283
|
-
systemPrompt,
|
|
2284
|
-
prPromptTemplate,
|
|
2285
|
-
plugins
|
|
2286
|
-
};
|
|
2287
|
-
}
|
|
2288
|
-
async function loadClaudeConfig(claudeDir) {
|
|
2289
|
-
const configPath = node_path.join(claudeDir, "config.json");
|
|
2290
|
-
assertFileExists(configPath, "claude/config.json");
|
|
2291
|
-
try {
|
|
2292
|
-
const content = node_fs.readFileSync(configPath, "utf-8");
|
|
2293
|
-
const rawConfig = JSON.parse(content);
|
|
2294
|
-
const config = ClaudeConfigSchema.parse(rawConfig);
|
|
2295
|
-
return config;
|
|
2296
|
-
} catch (error) {
|
|
2297
|
-
if (error instanceof SyntaxError) {
|
|
2298
|
-
throw new AgentConfigValidationError(
|
|
2299
|
-
"Invalid JSON in claude/config.json"
|
|
2300
|
-
);
|
|
2301
|
-
}
|
|
2302
|
-
throw new AgentConfigValidationError(
|
|
2303
|
-
`Invalid Claude configuration: ${error instanceof Error ? error.message : String(error)}`
|
|
2304
|
-
);
|
|
2305
|
-
}
|
|
2306
|
-
}
|
|
2307
|
-
async function loadSystemPrompt(claudeDir, promptFile) {
|
|
2308
|
-
const promptPath = node_path.join(claudeDir, promptFile);
|
|
2309
|
-
if (!node_fs.existsSync(promptPath)) {
|
|
2310
|
-
throw new MissingAgentFileError(`claude/${promptFile}`);
|
|
2311
|
-
}
|
|
2312
|
-
try {
|
|
2313
|
-
return node_fs.readFileSync(promptPath, "utf-8");
|
|
2314
|
-
} catch (error) {
|
|
2315
|
-
throw new AgentLoadError(
|
|
2316
|
-
`Failed to read system prompt: ${error instanceof Error ? error.message : String(error)}`
|
|
2317
|
-
);
|
|
2318
|
-
}
|
|
2319
|
-
}
|
|
2320
|
-
function replacePromptPlaceholders(template, cwd, extra) {
|
|
2321
|
-
const vars = {
|
|
2322
|
-
WORKING_DIR: cwd,
|
|
2323
|
-
PLATFORM: process.platform,
|
|
2324
|
-
OS_VERSION: `${os__namespace.type()} ${os__namespace.release()}`,
|
|
2325
|
-
DATE: (/* @__PURE__ */ new Date()).toISOString().split("T")[0],
|
|
2326
|
-
...extra
|
|
2327
|
-
};
|
|
2328
|
-
let result = template.replace(
|
|
2329
|
-
/\{\{#if\s+(\w+)\s*(==|!=)\s*(\w+)\}\}([\s\S]*?)\{\{\/if\}\}/g,
|
|
2330
|
-
(_match, key, op, expected, content) => {
|
|
2331
|
-
const actual = vars[key] ?? "";
|
|
2332
|
-
const matches = op === "==" ? actual === expected : actual !== expected;
|
|
2333
|
-
return matches ? content : "";
|
|
2334
|
-
}
|
|
2335
|
-
);
|
|
2336
|
-
for (const [key, value] of Object.entries(vars)) {
|
|
2337
|
-
result = result.replace(new RegExp(`\\{\\{${key}\\}\\}`, "g"), value);
|
|
2338
|
-
}
|
|
2339
|
-
return result;
|
|
2340
|
-
}
|
|
2341
|
-
|
|
2342
|
-
const CompanionWorkspaceFileSchema = zod.z.object({
|
|
2343
|
-
name: zod.z.string(),
|
|
2344
|
-
path: zod.z.string(),
|
|
2345
|
-
// relative to workspace root
|
|
2346
|
-
size: zod.z.number(),
|
|
2347
|
-
modifiedAt: zod.z.number(),
|
|
2348
|
-
isDirectory: zod.z.boolean()
|
|
2349
|
-
});
|
|
2350
|
-
const RegisterCompanionRequestSchema = zod.z.object({
|
|
2351
|
-
machineId: zod.z.string().min(1),
|
|
2352
|
-
// Optional: provision companion chat virtual task E2EE keys (local mode sharing).
|
|
2353
|
-
dataEncryptionKey: zod.z.string().optional(),
|
|
2354
|
-
ownerEncryptedDataKey: zod.z.string().optional()
|
|
2294
|
+
const RegisterCompanionRequestSchema = zod.z.object({
|
|
2295
|
+
machineId: zod.z.string().min(1),
|
|
2296
|
+
// Optional: provision companion chat virtual task E2EE keys (local mode sharing).
|
|
2297
|
+
dataEncryptionKey: zod.z.string().optional(),
|
|
2298
|
+
ownerEncryptedDataKey: zod.z.string().optional(),
|
|
2299
|
+
// Optional: preferred language for companion bootstrap/kickoff copy.
|
|
2300
|
+
preferredLanguage: zod.z.enum(["en", "zh-Hans"]).optional()
|
|
2355
2301
|
});
|
|
2356
2302
|
const RegisterCompanionResponseSchema = zod.z.object({
|
|
2357
2303
|
agentId: zod.z.string(),
|
|
@@ -2365,252 +2311,6 @@ const CompanionEnsureResponseSchema = zod.z.object({
|
|
|
2365
2311
|
homeDir: zod.z.string()
|
|
2366
2312
|
});
|
|
2367
2313
|
|
|
2368
|
-
const cryptoModule = typeof globalThis.crypto !== "undefined" ? globalThis.crypto : (async () => {
|
|
2369
|
-
try {
|
|
2370
|
-
const nodeCrypto = await import('node:crypto');
|
|
2371
|
-
return nodeCrypto.webcrypto;
|
|
2372
|
-
} catch {
|
|
2373
|
-
throw new Error("Web Crypto API not available");
|
|
2374
|
-
}
|
|
2375
|
-
})();
|
|
2376
|
-
async function getCrypto() {
|
|
2377
|
-
if (typeof cryptoModule === "object" && cryptoModule !== null && "subtle" in cryptoModule) {
|
|
2378
|
-
return cryptoModule;
|
|
2379
|
-
}
|
|
2380
|
-
return await cryptoModule;
|
|
2381
|
-
}
|
|
2382
|
-
async function hmac_sha512(key, data) {
|
|
2383
|
-
const crypto = await getCrypto();
|
|
2384
|
-
const cryptoKey = await crypto.subtle.importKey(
|
|
2385
|
-
"raw",
|
|
2386
|
-
key,
|
|
2387
|
-
{ name: "HMAC", hash: "SHA-512" },
|
|
2388
|
-
false,
|
|
2389
|
-
["sign"]
|
|
2390
|
-
);
|
|
2391
|
-
const signature = await crypto.subtle.sign(
|
|
2392
|
-
"HMAC",
|
|
2393
|
-
cryptoKey,
|
|
2394
|
-
data
|
|
2395
|
-
);
|
|
2396
|
-
return new Uint8Array(signature);
|
|
2397
|
-
}
|
|
2398
|
-
|
|
2399
|
-
async function deriveSecretKeyTreeRoot(seed, usage) {
|
|
2400
|
-
const I = await hmac_sha512(new TextEncoder().encode(usage + " Master Seed"), seed);
|
|
2401
|
-
return {
|
|
2402
|
-
key: I.slice(0, 32),
|
|
2403
|
-
chainCode: I.slice(32)
|
|
2404
|
-
};
|
|
2405
|
-
}
|
|
2406
|
-
async function deriveSecretKeyTreeChild(chainCode, index) {
|
|
2407
|
-
const data = new Uint8Array([0, ...new TextEncoder().encode(index)]);
|
|
2408
|
-
const I = await hmac_sha512(chainCode, data);
|
|
2409
|
-
return {
|
|
2410
|
-
key: I.subarray(0, 32),
|
|
2411
|
-
chainCode: I.subarray(32)
|
|
2412
|
-
};
|
|
2413
|
-
}
|
|
2414
|
-
async function deriveKey(master, usage, path) {
|
|
2415
|
-
let state = await deriveSecretKeyTreeRoot(master, usage);
|
|
2416
|
-
let remaining = [...path];
|
|
2417
|
-
while (remaining.length > 0) {
|
|
2418
|
-
let index = remaining[0];
|
|
2419
|
-
remaining = remaining.slice(1);
|
|
2420
|
-
state = await deriveSecretKeyTreeChild(state.chainCode, index);
|
|
2421
|
-
}
|
|
2422
|
-
return state.key;
|
|
2423
|
-
}
|
|
2424
|
-
|
|
2425
|
-
function encodeBase64(buffer, variant = "base64") {
|
|
2426
|
-
if (variant === "base64url") {
|
|
2427
|
-
return encodeBase64Url(buffer);
|
|
2428
|
-
}
|
|
2429
|
-
return base64js__namespace.fromByteArray(buffer);
|
|
2430
|
-
}
|
|
2431
|
-
function encodeBase64Url(buffer) {
|
|
2432
|
-
return base64js__namespace.fromByteArray(buffer).replaceAll("+", "-").replaceAll("/", "_").replaceAll("=", "");
|
|
2433
|
-
}
|
|
2434
|
-
function decodeBase64(base64, variant = "base64") {
|
|
2435
|
-
if (!base64) {
|
|
2436
|
-
throw new Error("Invalid base64 input: must be a non-empty string");
|
|
2437
|
-
}
|
|
2438
|
-
const cleaned = base64.replace(/\s/g, "");
|
|
2439
|
-
if (!cleaned) {
|
|
2440
|
-
throw new Error("Invalid base64 input: empty after removing whitespace");
|
|
2441
|
-
}
|
|
2442
|
-
try {
|
|
2443
|
-
if (variant === "base64url") {
|
|
2444
|
-
let base64Standard = cleaned.replace(/-/g, "+").replace(/_/g, "/");
|
|
2445
|
-
const padding = (4 - base64Standard.length % 4) % 4;
|
|
2446
|
-
if (padding > 0) {
|
|
2447
|
-
base64Standard += "=".repeat(padding);
|
|
2448
|
-
}
|
|
2449
|
-
return base64js__namespace.toByteArray(base64Standard);
|
|
2450
|
-
}
|
|
2451
|
-
return base64js__namespace.toByteArray(cleaned);
|
|
2452
|
-
} catch (error) {
|
|
2453
|
-
throw new Error(`Failed to decode base64 (variant: ${variant}): ${error instanceof Error ? error.message : String(error)}`);
|
|
2454
|
-
}
|
|
2455
|
-
}
|
|
2456
|
-
function getRandomBytes(size) {
|
|
2457
|
-
return tweetnacl.randomBytes(size);
|
|
2458
|
-
}
|
|
2459
|
-
function generateAESKey() {
|
|
2460
|
-
return getRandomBytes(tweetnacl.secretbox.keyLength);
|
|
2461
|
-
}
|
|
2462
|
-
function generateAESKeyBase64(variant = "base64") {
|
|
2463
|
-
const key = generateAESKey();
|
|
2464
|
-
return encodeBase64(key, variant);
|
|
2465
|
-
}
|
|
2466
|
-
function encryptAES(data, dataKey) {
|
|
2467
|
-
if (dataKey.length !== tweetnacl.secretbox.keyLength) {
|
|
2468
|
-
throw new Error(`Invalid key length: expected ${tweetnacl.secretbox.keyLength}, got ${dataKey.length}`);
|
|
2469
|
-
}
|
|
2470
|
-
const nonce = getRandomBytes(tweetnacl.secretbox.nonceLength);
|
|
2471
|
-
const plaintext = new TextEncoder().encode(JSON.stringify(data));
|
|
2472
|
-
const encrypted = tweetnacl.secretbox(plaintext, nonce, dataKey);
|
|
2473
|
-
const bundle = new Uint8Array(1 + nonce.length + encrypted.length);
|
|
2474
|
-
bundle.set([0], 0);
|
|
2475
|
-
bundle.set(nonce, 1);
|
|
2476
|
-
bundle.set(encrypted, 1 + nonce.length);
|
|
2477
|
-
return bundle;
|
|
2478
|
-
}
|
|
2479
|
-
function decryptAES(bundle, dataKey) {
|
|
2480
|
-
if (dataKey.length !== tweetnacl.secretbox.keyLength) {
|
|
2481
|
-
return null;
|
|
2482
|
-
}
|
|
2483
|
-
if (bundle.length < 1) {
|
|
2484
|
-
return null;
|
|
2485
|
-
}
|
|
2486
|
-
if (bundle[0] !== 0) {
|
|
2487
|
-
return null;
|
|
2488
|
-
}
|
|
2489
|
-
const minLength = 1 + tweetnacl.secretbox.nonceLength + tweetnacl.secretbox.overheadLength;
|
|
2490
|
-
if (bundle.length < minLength) {
|
|
2491
|
-
return null;
|
|
2492
|
-
}
|
|
2493
|
-
const nonce = bundle.slice(1, 1 + tweetnacl.secretbox.nonceLength);
|
|
2494
|
-
const ciphertext = bundle.slice(1 + tweetnacl.secretbox.nonceLength);
|
|
2495
|
-
try {
|
|
2496
|
-
const decrypted = tweetnacl.secretbox.open(ciphertext, nonce, dataKey);
|
|
2497
|
-
if (!decrypted) {
|
|
2498
|
-
return null;
|
|
2499
|
-
}
|
|
2500
|
-
return JSON.parse(new TextDecoder().decode(decrypted));
|
|
2501
|
-
} catch (error) {
|
|
2502
|
-
return null;
|
|
2503
|
-
}
|
|
2504
|
-
}
|
|
2505
|
-
async function createKeyPairWithUit8Array(masterSecret) {
|
|
2506
|
-
const contentDataKey = await deriveKey(masterSecret, "Agentrix EnCoder", ["content"]);
|
|
2507
|
-
return tweetnacl.box.keyPair.fromSecretKey(contentDataKey);
|
|
2508
|
-
}
|
|
2509
|
-
async function createKeyPair(masterSecret, variant = "base64") {
|
|
2510
|
-
return await createKeyPairWithUit8Array(decodeBase64(masterSecret, variant));
|
|
2511
|
-
}
|
|
2512
|
-
function decryptWithEphemeralKey(encryptedBundle, secretKey) {
|
|
2513
|
-
const ephemeralPublicKey = encryptedBundle.slice(0, 32);
|
|
2514
|
-
const nonce = encryptedBundle.slice(32, 32 + tweetnacl.box.nonceLength);
|
|
2515
|
-
const encrypted = encryptedBundle.slice(32 + tweetnacl.box.nonceLength);
|
|
2516
|
-
const decrypted = tweetnacl.box.open(encrypted, nonce, ephemeralPublicKey, secretKey);
|
|
2517
|
-
if (!decrypted) {
|
|
2518
|
-
return null;
|
|
2519
|
-
}
|
|
2520
|
-
return decrypted;
|
|
2521
|
-
}
|
|
2522
|
-
function encryptWithEphemeralKey(data, publicKey) {
|
|
2523
|
-
const ephemeralKeyPair = tweetnacl.box.keyPair();
|
|
2524
|
-
const nonce = getRandomBytes(tweetnacl.box.nonceLength);
|
|
2525
|
-
const encrypted = tweetnacl.box(data, nonce, publicKey, ephemeralKeyPair.secretKey);
|
|
2526
|
-
const result = new Uint8Array(ephemeralKeyPair.publicKey.length + nonce.length + encrypted.length);
|
|
2527
|
-
result.set(ephemeralKeyPair.publicKey, 0);
|
|
2528
|
-
result.set(nonce, ephemeralKeyPair.publicKey.length);
|
|
2529
|
-
result.set(encrypted, ephemeralKeyPair.publicKey.length + nonce.length);
|
|
2530
|
-
return result;
|
|
2531
|
-
}
|
|
2532
|
-
function encryptSdkMessage(message, dataKey) {
|
|
2533
|
-
const encryptedWithVersion = encryptAES(message, dataKey);
|
|
2534
|
-
const encryptedWithoutVersion = encryptedWithVersion.slice(1);
|
|
2535
|
-
return encodeBase64(encryptedWithoutVersion);
|
|
2536
|
-
}
|
|
2537
|
-
function decryptSdkMessage(encryptedMessage, dataKey) {
|
|
2538
|
-
try {
|
|
2539
|
-
const encryptedWithoutVersion = decodeBase64(encryptedMessage);
|
|
2540
|
-
const encryptedWithVersion = new Uint8Array(1 + encryptedWithoutVersion.length);
|
|
2541
|
-
encryptedWithVersion.set([0], 0);
|
|
2542
|
-
encryptedWithVersion.set(encryptedWithoutVersion, 1);
|
|
2543
|
-
return decryptAES(encryptedWithVersion, dataKey);
|
|
2544
|
-
} catch (error) {
|
|
2545
|
-
return null;
|
|
2546
|
-
}
|
|
2547
|
-
}
|
|
2548
|
-
function encryptMachineEncryptionKey(machinePublicKey, aesKey, userPublicKey) {
|
|
2549
|
-
if (machinePublicKey.length !== 32) {
|
|
2550
|
-
throw new Error(`Invalid machine public key length: expected 32, got ${machinePublicKey.length}`);
|
|
2551
|
-
}
|
|
2552
|
-
if (aesKey.length !== tweetnacl.secretbox.keyLength) {
|
|
2553
|
-
throw new Error(`Invalid AES key length: expected ${tweetnacl.secretbox.keyLength}, got ${aesKey.length}`);
|
|
2554
|
-
}
|
|
2555
|
-
if (userPublicKey.length !== 32) {
|
|
2556
|
-
throw new Error(`Invalid user public key length: expected 32, got ${userPublicKey.length}`);
|
|
2557
|
-
}
|
|
2558
|
-
const combined = new Uint8Array(machinePublicKey.length + aesKey.length);
|
|
2559
|
-
combined.set(machinePublicKey, 0);
|
|
2560
|
-
combined.set(aesKey, machinePublicKey.length);
|
|
2561
|
-
const encrypted = encryptWithEphemeralKey(combined, userPublicKey);
|
|
2562
|
-
return encodeBase64(encrypted);
|
|
2563
|
-
}
|
|
2564
|
-
function decryptMachineEncryptionKey(encryptedData, userPrivateKey) {
|
|
2565
|
-
if (userPrivateKey.length !== 32) {
|
|
2566
|
-
return null;
|
|
2567
|
-
}
|
|
2568
|
-
try {
|
|
2569
|
-
const encryptedBundle = decodeBase64(encryptedData);
|
|
2570
|
-
const decrypted = decryptWithEphemeralKey(encryptedBundle, userPrivateKey);
|
|
2571
|
-
if (!decrypted) {
|
|
2572
|
-
return null;
|
|
2573
|
-
}
|
|
2574
|
-
const expectedLength = 32 + tweetnacl.secretbox.keyLength;
|
|
2575
|
-
if (decrypted.length !== expectedLength) {
|
|
2576
|
-
return null;
|
|
2577
|
-
}
|
|
2578
|
-
const machinePublicKey = decrypted.slice(0, 32);
|
|
2579
|
-
const aesKey = decrypted.slice(32);
|
|
2580
|
-
return { machinePublicKey, aesKey };
|
|
2581
|
-
} catch (error) {
|
|
2582
|
-
return null;
|
|
2583
|
-
}
|
|
2584
|
-
}
|
|
2585
|
-
function createTaskEncryptionPayload(machineEncryptionKey) {
|
|
2586
|
-
const taskDataKey = generateAESKey();
|
|
2587
|
-
return {
|
|
2588
|
-
taskDataKey,
|
|
2589
|
-
dataEncryptionKey: encodeBase64(
|
|
2590
|
-
encryptWithEphemeralKey(taskDataKey, machineEncryptionKey.machinePublicKey)
|
|
2591
|
-
),
|
|
2592
|
-
ownerEncryptedDataKey: encodeBase64(
|
|
2593
|
-
encryptAES(encodeBase64(taskDataKey), machineEncryptionKey.aesKey)
|
|
2594
|
-
)
|
|
2595
|
-
};
|
|
2596
|
-
}
|
|
2597
|
-
function encryptFileContent(fileContentBase64, dataKey) {
|
|
2598
|
-
const encryptedWithVersion = encryptAES(fileContentBase64, dataKey);
|
|
2599
|
-
const encryptedWithoutVersion = encryptedWithVersion.slice(1);
|
|
2600
|
-
return encodeBase64(encryptedWithoutVersion);
|
|
2601
|
-
}
|
|
2602
|
-
function decryptFileContent(encryptedContent, dataKey) {
|
|
2603
|
-
try {
|
|
2604
|
-
const encryptedWithoutVersion = decodeBase64(encryptedContent);
|
|
2605
|
-
const encryptedWithVersion = new Uint8Array(1 + encryptedWithoutVersion.length);
|
|
2606
|
-
encryptedWithVersion.set([0], 0);
|
|
2607
|
-
encryptedWithVersion.set(encryptedWithoutVersion, 1);
|
|
2608
|
-
return decryptAES(encryptedWithVersion, dataKey);
|
|
2609
|
-
} catch (error) {
|
|
2610
|
-
return null;
|
|
2611
|
-
}
|
|
2612
|
-
}
|
|
2613
|
-
|
|
2614
2314
|
const RTC_CHUNK_HEADER_SIZE = 16;
|
|
2615
2315
|
const RtcChunkFlags = {
|
|
2616
2316
|
Start: 1,
|
|
@@ -2963,15 +2663,21 @@ function getFileExtension(filePath) {
|
|
|
2963
2663
|
return filePath.substring(lastDot).toLowerCase();
|
|
2964
2664
|
}
|
|
2965
2665
|
|
|
2666
|
+
exports.AgentConfigValidationError = errors.AgentConfigValidationError;
|
|
2667
|
+
exports.AgentError = errors.AgentError;
|
|
2668
|
+
exports.AgentLoadError = errors.AgentLoadError;
|
|
2669
|
+
exports.AgentMetadataSchema = errors.AgentMetadataSchema;
|
|
2670
|
+
exports.AgentNotFoundError = errors.AgentNotFoundError;
|
|
2671
|
+
exports.ClaudeConfigSchema = errors.ClaudeConfigSchema;
|
|
2672
|
+
exports.FRAMEWORK_TYPES = errors.FRAMEWORK_TYPES;
|
|
2673
|
+
exports.FrameworkNotSupportedError = errors.FrameworkNotSupportedError;
|
|
2674
|
+
exports.MissingAgentFileError = errors.MissingAgentFileError;
|
|
2675
|
+
exports.getAgentContext = errors.getAgentContext;
|
|
2676
|
+
exports.setAgentContext = errors.setAgentContext;
|
|
2966
2677
|
exports.ActiveAgentSchema = ActiveAgentSchema;
|
|
2967
2678
|
exports.AddChatMemberRequestSchema = AddChatMemberRequestSchema;
|
|
2968
2679
|
exports.AddChatMemberResponseSchema = AddChatMemberResponseSchema;
|
|
2969
|
-
exports.AgentConfigValidationError = AgentConfigValidationError;
|
|
2970
2680
|
exports.AgentCustomConfigSchema = AgentCustomConfigSchema;
|
|
2971
|
-
exports.AgentError = AgentError;
|
|
2972
|
-
exports.AgentLoadError = AgentLoadError;
|
|
2973
|
-
exports.AgentMetadataSchema = AgentMetadataSchema;
|
|
2974
|
-
exports.AgentNotFoundError = AgentNotFoundError;
|
|
2975
2681
|
exports.AgentPermissionsSchema = AgentPermissionsSchema;
|
|
2976
2682
|
exports.AgentSchema = AgentSchema;
|
|
2977
2683
|
exports.AgentTypeSchema = AgentTypeSchema;
|
|
@@ -3005,7 +2711,6 @@ exports.ChatTypeSchema = ChatTypeSchema;
|
|
|
3005
2711
|
exports.ChatWithMembersSchema = ChatWithMembersSchema;
|
|
3006
2712
|
exports.ChatWorkersStatusRequestSchema = ChatWorkersStatusRequestSchema;
|
|
3007
2713
|
exports.ChatWorkersStatusResponseSchema = ChatWorkersStatusResponseSchema;
|
|
3008
|
-
exports.ClaudeConfigSchema = ClaudeConfigSchema;
|
|
3009
2714
|
exports.CloudJoinApprovalRequestSchema = CloudJoinApprovalRequestSchema;
|
|
3010
2715
|
exports.CloudJoinRequestSchema = CloudJoinRequestSchema;
|
|
3011
2716
|
exports.CloudJoinResultQuerySchema = CloudJoinResultQuerySchema;
|
|
@@ -3061,14 +2766,12 @@ exports.ENTRY_FILE_PATTERNS = ENTRY_FILE_PATTERNS;
|
|
|
3061
2766
|
exports.EnvironmentVariableSchema = EnvironmentVariableSchema;
|
|
3062
2767
|
exports.EventAckSchema = EventAckSchema;
|
|
3063
2768
|
exports.EventSchemaMap = EventSchemaMap;
|
|
3064
|
-
exports.FRAMEWORK_TYPES = FRAMEWORK_TYPES;
|
|
3065
2769
|
exports.FileItemSchema = FileItemSchema;
|
|
3066
2770
|
exports.FileStatsSchema = FileStatsSchema;
|
|
3067
2771
|
exports.FileVisibilitySchema = FileVisibilitySchema;
|
|
3068
2772
|
exports.FillEventsRequestSchema = FillEventsRequestSchema;
|
|
3069
2773
|
exports.FindTaskByAgentRequestSchema = FindTaskByAgentRequestSchema;
|
|
3070
2774
|
exports.FindTaskByAgentResponseSchema = FindTaskByAgentResponseSchema;
|
|
3071
|
-
exports.FrameworkNotSupportedError = FrameworkNotSupportedError;
|
|
3072
2775
|
exports.GetAgentResponseSchema = GetAgentResponseSchema;
|
|
3073
2776
|
exports.GetChatResponseSchema = GetChatResponseSchema;
|
|
3074
2777
|
exports.GetEnvironmentVariablesResponseSchema = GetEnvironmentVariablesResponseSchema;
|
|
@@ -3129,7 +2832,6 @@ exports.MachineRtcRequestSchema = MachineRtcRequestSchema;
|
|
|
3129
2832
|
exports.MachineRtcResponseSchema = MachineRtcResponseSchema;
|
|
3130
2833
|
exports.MergePullRequestEventSchema = MergePullRequestEventSchema;
|
|
3131
2834
|
exports.MergeRequestEventSchema = MergeRequestEventSchema;
|
|
3132
|
-
exports.MissingAgentFileError = MissingAgentFileError;
|
|
3133
2835
|
exports.OAuthAccountInfoSchema = OAuthAccountInfoSchema;
|
|
3134
2836
|
exports.OAuthBindCallbackResponseSchema = OAuthBindCallbackResponseSchema;
|
|
3135
2837
|
exports.OAuthBindQuerySchema = OAuthBindQuerySchema;
|
|
@@ -3250,8 +2952,6 @@ exports.WorkerStatusRequestSchema = WorkerStatusRequestSchema;
|
|
|
3250
2952
|
exports.WorkerStatusValueSchema = WorkerStatusValueSchema;
|
|
3251
2953
|
exports.WorkspaceFileRequestSchema = WorkspaceFileRequestSchema;
|
|
3252
2954
|
exports.WorkspaceFileResponseSchema = WorkspaceFileResponseSchema;
|
|
3253
|
-
exports.assertAgentExists = assertAgentExists;
|
|
3254
|
-
exports.assertFileExists = assertFileExists;
|
|
3255
2955
|
exports.baseTaskSchema = baseTaskSchema;
|
|
3256
2956
|
exports.buildRtcChunkFrame = buildRtcChunkFrame;
|
|
3257
2957
|
exports.cancelTaskRequestSchema = cancelTaskRequestSchema;
|
|
@@ -3270,7 +2970,6 @@ exports.decryptMachineEncryptionKey = decryptMachineEncryptionKey;
|
|
|
3270
2970
|
exports.decryptSdkMessage = decryptSdkMessage;
|
|
3271
2971
|
exports.decryptWithEphemeralKey = decryptWithEphemeralKey;
|
|
3272
2972
|
exports.detectPreview = detectPreview;
|
|
3273
|
-
exports.discoverPlugins = discoverPlugins;
|
|
3274
2973
|
exports.encodeBase64 = encodeBase64;
|
|
3275
2974
|
exports.encodeBase64Url = encodeBase64Url;
|
|
3276
2975
|
exports.encodeRtcChunkHeader = encodeRtcChunkHeader;
|
|
@@ -3281,7 +2980,6 @@ exports.encryptSdkMessage = encryptSdkMessage;
|
|
|
3281
2980
|
exports.encryptWithEphemeralKey = encryptWithEphemeralKey;
|
|
3282
2981
|
exports.generateAESKey = generateAESKey;
|
|
3283
2982
|
exports.generateAESKeyBase64 = generateAESKeyBase64;
|
|
3284
|
-
exports.getAgentContext = getAgentContext;
|
|
3285
2983
|
exports.getRandomBytes = getRandomBytes;
|
|
3286
2984
|
exports.isAskUserMessage = isAskUserMessage;
|
|
3287
2985
|
exports.isAskUserResponseMessage = isAskUserResponseMessage;
|
|
@@ -3289,18 +2987,14 @@ exports.isCompanionHeartbeatMessage = isCompanionHeartbeatMessage;
|
|
|
3289
2987
|
exports.isCompanionReminderMessage = isCompanionReminderMessage;
|
|
3290
2988
|
exports.isSDKMessage = isSDKMessage;
|
|
3291
2989
|
exports.isSDKUserMessage = isSDKUserMessage;
|
|
3292
|
-
exports.
|
|
2990
|
+
exports.isSubTaskAskUserMessage = isSubTaskAskUserMessage;
|
|
3293
2991
|
exports.machineAuth = machineAuth;
|
|
3294
2992
|
exports.permissionResponseRequestSchema = permissionResponseRequestSchema;
|
|
3295
|
-
exports.replacePromptPlaceholders = replacePromptPlaceholders;
|
|
3296
2993
|
exports.resumeTaskRequestSchema = resumeTaskRequestSchema;
|
|
3297
2994
|
exports.resumeTaskSchema = resumeTaskSchema;
|
|
3298
|
-
exports.setAgentContext = setAgentContext;
|
|
3299
2995
|
exports.splitRtcChunkFrame = splitRtcChunkFrame;
|
|
3300
2996
|
exports.startTaskSchema = startTaskSchema;
|
|
3301
2997
|
exports.stopTaskRequestSchema = stopTaskRequestSchema;
|
|
3302
2998
|
exports.userAuth = userAuth;
|
|
3303
|
-
exports.validateAgentDirectory = validateAgentDirectory;
|
|
3304
|
-
exports.validateFrameworkDirectory = validateFrameworkDirectory;
|
|
3305
2999
|
exports.workerAuth = workerAuth;
|
|
3306
3000
|
exports.workerTaskEvents = workerTaskEvents;
|