@agentrix/shared 2.2.3 → 2.2.5
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-myQvpVrM.cjs +95 -0
- package/dist/errors-vTk-66-R.d.cts +2602 -0
- package/dist/index.cjs +266 -556
- package/dist/index.d.cts +2065 -4636
- 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,305 +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)
|
|
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()
|
|
2352
2301
|
});
|
|
2353
2302
|
const RegisterCompanionResponseSchema = zod.z.object({
|
|
2354
2303
|
agentId: zod.z.string(),
|
|
@@ -2359,243 +2308,9 @@ const RegisterCompanionResponseSchema = zod.z.object({
|
|
|
2359
2308
|
});
|
|
2360
2309
|
const CompanionEnsureResponseSchema = zod.z.object({
|
|
2361
2310
|
agentDir: zod.z.string(),
|
|
2362
|
-
|
|
2311
|
+
homeDir: zod.z.string()
|
|
2363
2312
|
});
|
|
2364
2313
|
|
|
2365
|
-
const cryptoModule = typeof globalThis.crypto !== "undefined" ? globalThis.crypto : (async () => {
|
|
2366
|
-
try {
|
|
2367
|
-
const nodeCrypto = await import('node:crypto');
|
|
2368
|
-
return nodeCrypto.webcrypto;
|
|
2369
|
-
} catch {
|
|
2370
|
-
throw new Error("Web Crypto API not available");
|
|
2371
|
-
}
|
|
2372
|
-
})();
|
|
2373
|
-
async function getCrypto() {
|
|
2374
|
-
if (typeof cryptoModule === "object" && cryptoModule !== null && "subtle" in cryptoModule) {
|
|
2375
|
-
return cryptoModule;
|
|
2376
|
-
}
|
|
2377
|
-
return await cryptoModule;
|
|
2378
|
-
}
|
|
2379
|
-
async function hmac_sha512(key, data) {
|
|
2380
|
-
const crypto = await getCrypto();
|
|
2381
|
-
const cryptoKey = await crypto.subtle.importKey(
|
|
2382
|
-
"raw",
|
|
2383
|
-
key,
|
|
2384
|
-
{ name: "HMAC", hash: "SHA-512" },
|
|
2385
|
-
false,
|
|
2386
|
-
["sign"]
|
|
2387
|
-
);
|
|
2388
|
-
const signature = await crypto.subtle.sign(
|
|
2389
|
-
"HMAC",
|
|
2390
|
-
cryptoKey,
|
|
2391
|
-
data
|
|
2392
|
-
);
|
|
2393
|
-
return new Uint8Array(signature);
|
|
2394
|
-
}
|
|
2395
|
-
|
|
2396
|
-
async function deriveSecretKeyTreeRoot(seed, usage) {
|
|
2397
|
-
const I = await hmac_sha512(new TextEncoder().encode(usage + " Master Seed"), seed);
|
|
2398
|
-
return {
|
|
2399
|
-
key: I.slice(0, 32),
|
|
2400
|
-
chainCode: I.slice(32)
|
|
2401
|
-
};
|
|
2402
|
-
}
|
|
2403
|
-
async function deriveSecretKeyTreeChild(chainCode, index) {
|
|
2404
|
-
const data = new Uint8Array([0, ...new TextEncoder().encode(index)]);
|
|
2405
|
-
const I = await hmac_sha512(chainCode, data);
|
|
2406
|
-
return {
|
|
2407
|
-
key: I.subarray(0, 32),
|
|
2408
|
-
chainCode: I.subarray(32)
|
|
2409
|
-
};
|
|
2410
|
-
}
|
|
2411
|
-
async function deriveKey(master, usage, path) {
|
|
2412
|
-
let state = await deriveSecretKeyTreeRoot(master, usage);
|
|
2413
|
-
let remaining = [...path];
|
|
2414
|
-
while (remaining.length > 0) {
|
|
2415
|
-
let index = remaining[0];
|
|
2416
|
-
remaining = remaining.slice(1);
|
|
2417
|
-
state = await deriveSecretKeyTreeChild(state.chainCode, index);
|
|
2418
|
-
}
|
|
2419
|
-
return state.key;
|
|
2420
|
-
}
|
|
2421
|
-
|
|
2422
|
-
function encodeBase64(buffer, variant = "base64") {
|
|
2423
|
-
if (variant === "base64url") {
|
|
2424
|
-
return encodeBase64Url(buffer);
|
|
2425
|
-
}
|
|
2426
|
-
return base64js__namespace.fromByteArray(buffer);
|
|
2427
|
-
}
|
|
2428
|
-
function encodeBase64Url(buffer) {
|
|
2429
|
-
return base64js__namespace.fromByteArray(buffer).replaceAll("+", "-").replaceAll("/", "_").replaceAll("=", "");
|
|
2430
|
-
}
|
|
2431
|
-
function decodeBase64(base64, variant = "base64") {
|
|
2432
|
-
if (!base64) {
|
|
2433
|
-
throw new Error("Invalid base64 input: must be a non-empty string");
|
|
2434
|
-
}
|
|
2435
|
-
const cleaned = base64.replace(/\s/g, "");
|
|
2436
|
-
if (!cleaned) {
|
|
2437
|
-
throw new Error("Invalid base64 input: empty after removing whitespace");
|
|
2438
|
-
}
|
|
2439
|
-
try {
|
|
2440
|
-
if (variant === "base64url") {
|
|
2441
|
-
let base64Standard = cleaned.replace(/-/g, "+").replace(/_/g, "/");
|
|
2442
|
-
const padding = (4 - base64Standard.length % 4) % 4;
|
|
2443
|
-
if (padding > 0) {
|
|
2444
|
-
base64Standard += "=".repeat(padding);
|
|
2445
|
-
}
|
|
2446
|
-
return base64js__namespace.toByteArray(base64Standard);
|
|
2447
|
-
}
|
|
2448
|
-
return base64js__namespace.toByteArray(cleaned);
|
|
2449
|
-
} catch (error) {
|
|
2450
|
-
throw new Error(`Failed to decode base64 (variant: ${variant}): ${error instanceof Error ? error.message : String(error)}`);
|
|
2451
|
-
}
|
|
2452
|
-
}
|
|
2453
|
-
function getRandomBytes(size) {
|
|
2454
|
-
return tweetnacl.randomBytes(size);
|
|
2455
|
-
}
|
|
2456
|
-
function generateAESKey() {
|
|
2457
|
-
return getRandomBytes(tweetnacl.secretbox.keyLength);
|
|
2458
|
-
}
|
|
2459
|
-
function generateAESKeyBase64(variant = "base64") {
|
|
2460
|
-
const key = generateAESKey();
|
|
2461
|
-
return encodeBase64(key, variant);
|
|
2462
|
-
}
|
|
2463
|
-
function encryptAES(data, dataKey) {
|
|
2464
|
-
if (dataKey.length !== tweetnacl.secretbox.keyLength) {
|
|
2465
|
-
throw new Error(`Invalid key length: expected ${tweetnacl.secretbox.keyLength}, got ${dataKey.length}`);
|
|
2466
|
-
}
|
|
2467
|
-
const nonce = getRandomBytes(tweetnacl.secretbox.nonceLength);
|
|
2468
|
-
const plaintext = new TextEncoder().encode(JSON.stringify(data));
|
|
2469
|
-
const encrypted = tweetnacl.secretbox(plaintext, nonce, dataKey);
|
|
2470
|
-
const bundle = new Uint8Array(1 + nonce.length + encrypted.length);
|
|
2471
|
-
bundle.set([0], 0);
|
|
2472
|
-
bundle.set(nonce, 1);
|
|
2473
|
-
bundle.set(encrypted, 1 + nonce.length);
|
|
2474
|
-
return bundle;
|
|
2475
|
-
}
|
|
2476
|
-
function decryptAES(bundle, dataKey) {
|
|
2477
|
-
if (dataKey.length !== tweetnacl.secretbox.keyLength) {
|
|
2478
|
-
return null;
|
|
2479
|
-
}
|
|
2480
|
-
if (bundle.length < 1) {
|
|
2481
|
-
return null;
|
|
2482
|
-
}
|
|
2483
|
-
if (bundle[0] !== 0) {
|
|
2484
|
-
return null;
|
|
2485
|
-
}
|
|
2486
|
-
const minLength = 1 + tweetnacl.secretbox.nonceLength + tweetnacl.secretbox.overheadLength;
|
|
2487
|
-
if (bundle.length < minLength) {
|
|
2488
|
-
return null;
|
|
2489
|
-
}
|
|
2490
|
-
const nonce = bundle.slice(1, 1 + tweetnacl.secretbox.nonceLength);
|
|
2491
|
-
const ciphertext = bundle.slice(1 + tweetnacl.secretbox.nonceLength);
|
|
2492
|
-
try {
|
|
2493
|
-
const decrypted = tweetnacl.secretbox.open(ciphertext, nonce, dataKey);
|
|
2494
|
-
if (!decrypted) {
|
|
2495
|
-
return null;
|
|
2496
|
-
}
|
|
2497
|
-
return JSON.parse(new TextDecoder().decode(decrypted));
|
|
2498
|
-
} catch (error) {
|
|
2499
|
-
return null;
|
|
2500
|
-
}
|
|
2501
|
-
}
|
|
2502
|
-
async function createKeyPairWithUit8Array(masterSecret) {
|
|
2503
|
-
const contentDataKey = await deriveKey(masterSecret, "Agentrix EnCoder", ["content"]);
|
|
2504
|
-
return tweetnacl.box.keyPair.fromSecretKey(contentDataKey);
|
|
2505
|
-
}
|
|
2506
|
-
async function createKeyPair(masterSecret, variant = "base64") {
|
|
2507
|
-
return await createKeyPairWithUit8Array(decodeBase64(masterSecret, variant));
|
|
2508
|
-
}
|
|
2509
|
-
function decryptWithEphemeralKey(encryptedBundle, secretKey) {
|
|
2510
|
-
const ephemeralPublicKey = encryptedBundle.slice(0, 32);
|
|
2511
|
-
const nonce = encryptedBundle.slice(32, 32 + tweetnacl.box.nonceLength);
|
|
2512
|
-
const encrypted = encryptedBundle.slice(32 + tweetnacl.box.nonceLength);
|
|
2513
|
-
const decrypted = tweetnacl.box.open(encrypted, nonce, ephemeralPublicKey, secretKey);
|
|
2514
|
-
if (!decrypted) {
|
|
2515
|
-
return null;
|
|
2516
|
-
}
|
|
2517
|
-
return decrypted;
|
|
2518
|
-
}
|
|
2519
|
-
function encryptWithEphemeralKey(data, publicKey) {
|
|
2520
|
-
const ephemeralKeyPair = tweetnacl.box.keyPair();
|
|
2521
|
-
const nonce = getRandomBytes(tweetnacl.box.nonceLength);
|
|
2522
|
-
const encrypted = tweetnacl.box(data, nonce, publicKey, ephemeralKeyPair.secretKey);
|
|
2523
|
-
const result = new Uint8Array(ephemeralKeyPair.publicKey.length + nonce.length + encrypted.length);
|
|
2524
|
-
result.set(ephemeralKeyPair.publicKey, 0);
|
|
2525
|
-
result.set(nonce, ephemeralKeyPair.publicKey.length);
|
|
2526
|
-
result.set(encrypted, ephemeralKeyPair.publicKey.length + nonce.length);
|
|
2527
|
-
return result;
|
|
2528
|
-
}
|
|
2529
|
-
function encryptSdkMessage(message, dataKey) {
|
|
2530
|
-
const encryptedWithVersion = encryptAES(message, dataKey);
|
|
2531
|
-
const encryptedWithoutVersion = encryptedWithVersion.slice(1);
|
|
2532
|
-
return encodeBase64(encryptedWithoutVersion);
|
|
2533
|
-
}
|
|
2534
|
-
function decryptSdkMessage(encryptedMessage, dataKey) {
|
|
2535
|
-
try {
|
|
2536
|
-
const encryptedWithoutVersion = decodeBase64(encryptedMessage);
|
|
2537
|
-
const encryptedWithVersion = new Uint8Array(1 + encryptedWithoutVersion.length);
|
|
2538
|
-
encryptedWithVersion.set([0], 0);
|
|
2539
|
-
encryptedWithVersion.set(encryptedWithoutVersion, 1);
|
|
2540
|
-
return decryptAES(encryptedWithVersion, dataKey);
|
|
2541
|
-
} catch (error) {
|
|
2542
|
-
return null;
|
|
2543
|
-
}
|
|
2544
|
-
}
|
|
2545
|
-
function encryptMachineEncryptionKey(machinePublicKey, aesKey, userPublicKey) {
|
|
2546
|
-
if (machinePublicKey.length !== 32) {
|
|
2547
|
-
throw new Error(`Invalid machine public key length: expected 32, got ${machinePublicKey.length}`);
|
|
2548
|
-
}
|
|
2549
|
-
if (aesKey.length !== tweetnacl.secretbox.keyLength) {
|
|
2550
|
-
throw new Error(`Invalid AES key length: expected ${tweetnacl.secretbox.keyLength}, got ${aesKey.length}`);
|
|
2551
|
-
}
|
|
2552
|
-
if (userPublicKey.length !== 32) {
|
|
2553
|
-
throw new Error(`Invalid user public key length: expected 32, got ${userPublicKey.length}`);
|
|
2554
|
-
}
|
|
2555
|
-
const combined = new Uint8Array(machinePublicKey.length + aesKey.length);
|
|
2556
|
-
combined.set(machinePublicKey, 0);
|
|
2557
|
-
combined.set(aesKey, machinePublicKey.length);
|
|
2558
|
-
const encrypted = encryptWithEphemeralKey(combined, userPublicKey);
|
|
2559
|
-
return encodeBase64(encrypted);
|
|
2560
|
-
}
|
|
2561
|
-
function decryptMachineEncryptionKey(encryptedData, userPrivateKey) {
|
|
2562
|
-
if (userPrivateKey.length !== 32) {
|
|
2563
|
-
return null;
|
|
2564
|
-
}
|
|
2565
|
-
try {
|
|
2566
|
-
const encryptedBundle = decodeBase64(encryptedData);
|
|
2567
|
-
const decrypted = decryptWithEphemeralKey(encryptedBundle, userPrivateKey);
|
|
2568
|
-
if (!decrypted) {
|
|
2569
|
-
return null;
|
|
2570
|
-
}
|
|
2571
|
-
const expectedLength = 32 + tweetnacl.secretbox.keyLength;
|
|
2572
|
-
if (decrypted.length !== expectedLength) {
|
|
2573
|
-
return null;
|
|
2574
|
-
}
|
|
2575
|
-
const machinePublicKey = decrypted.slice(0, 32);
|
|
2576
|
-
const aesKey = decrypted.slice(32);
|
|
2577
|
-
return { machinePublicKey, aesKey };
|
|
2578
|
-
} catch (error) {
|
|
2579
|
-
return null;
|
|
2580
|
-
}
|
|
2581
|
-
}
|
|
2582
|
-
function encryptFileContent(fileContentBase64, dataKey) {
|
|
2583
|
-
const encryptedWithVersion = encryptAES(fileContentBase64, dataKey);
|
|
2584
|
-
const encryptedWithoutVersion = encryptedWithVersion.slice(1);
|
|
2585
|
-
return encodeBase64(encryptedWithoutVersion);
|
|
2586
|
-
}
|
|
2587
|
-
function decryptFileContent(encryptedContent, dataKey) {
|
|
2588
|
-
try {
|
|
2589
|
-
const encryptedWithoutVersion = decodeBase64(encryptedContent);
|
|
2590
|
-
const encryptedWithVersion = new Uint8Array(1 + encryptedWithoutVersion.length);
|
|
2591
|
-
encryptedWithVersion.set([0], 0);
|
|
2592
|
-
encryptedWithVersion.set(encryptedWithoutVersion, 1);
|
|
2593
|
-
return decryptAES(encryptedWithVersion, dataKey);
|
|
2594
|
-
} catch (error) {
|
|
2595
|
-
return null;
|
|
2596
|
-
}
|
|
2597
|
-
}
|
|
2598
|
-
|
|
2599
2314
|
const RTC_CHUNK_HEADER_SIZE = 16;
|
|
2600
2315
|
const RtcChunkFlags = {
|
|
2601
2316
|
Start: 1,
|
|
@@ -2948,15 +2663,21 @@ function getFileExtension(filePath) {
|
|
|
2948
2663
|
return filePath.substring(lastDot).toLowerCase();
|
|
2949
2664
|
}
|
|
2950
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;
|
|
2951
2677
|
exports.ActiveAgentSchema = ActiveAgentSchema;
|
|
2952
2678
|
exports.AddChatMemberRequestSchema = AddChatMemberRequestSchema;
|
|
2953
2679
|
exports.AddChatMemberResponseSchema = AddChatMemberResponseSchema;
|
|
2954
|
-
exports.AgentConfigValidationError = AgentConfigValidationError;
|
|
2955
2680
|
exports.AgentCustomConfigSchema = AgentCustomConfigSchema;
|
|
2956
|
-
exports.AgentError = AgentError;
|
|
2957
|
-
exports.AgentLoadError = AgentLoadError;
|
|
2958
|
-
exports.AgentMetadataSchema = AgentMetadataSchema;
|
|
2959
|
-
exports.AgentNotFoundError = AgentNotFoundError;
|
|
2960
2681
|
exports.AgentPermissionsSchema = AgentPermissionsSchema;
|
|
2961
2682
|
exports.AgentSchema = AgentSchema;
|
|
2962
2683
|
exports.AgentTypeSchema = AgentTypeSchema;
|
|
@@ -2990,7 +2711,6 @@ exports.ChatTypeSchema = ChatTypeSchema;
|
|
|
2990
2711
|
exports.ChatWithMembersSchema = ChatWithMembersSchema;
|
|
2991
2712
|
exports.ChatWorkersStatusRequestSchema = ChatWorkersStatusRequestSchema;
|
|
2992
2713
|
exports.ChatWorkersStatusResponseSchema = ChatWorkersStatusResponseSchema;
|
|
2993
|
-
exports.ClaudeConfigSchema = ClaudeConfigSchema;
|
|
2994
2714
|
exports.CloudJoinApprovalRequestSchema = CloudJoinApprovalRequestSchema;
|
|
2995
2715
|
exports.CloudJoinRequestSchema = CloudJoinRequestSchema;
|
|
2996
2716
|
exports.CloudJoinResultQuerySchema = CloudJoinResultQuerySchema;
|
|
@@ -3046,14 +2766,12 @@ exports.ENTRY_FILE_PATTERNS = ENTRY_FILE_PATTERNS;
|
|
|
3046
2766
|
exports.EnvironmentVariableSchema = EnvironmentVariableSchema;
|
|
3047
2767
|
exports.EventAckSchema = EventAckSchema;
|
|
3048
2768
|
exports.EventSchemaMap = EventSchemaMap;
|
|
3049
|
-
exports.FRAMEWORK_TYPES = FRAMEWORK_TYPES;
|
|
3050
2769
|
exports.FileItemSchema = FileItemSchema;
|
|
3051
2770
|
exports.FileStatsSchema = FileStatsSchema;
|
|
3052
2771
|
exports.FileVisibilitySchema = FileVisibilitySchema;
|
|
3053
2772
|
exports.FillEventsRequestSchema = FillEventsRequestSchema;
|
|
3054
2773
|
exports.FindTaskByAgentRequestSchema = FindTaskByAgentRequestSchema;
|
|
3055
2774
|
exports.FindTaskByAgentResponseSchema = FindTaskByAgentResponseSchema;
|
|
3056
|
-
exports.FrameworkNotSupportedError = FrameworkNotSupportedError;
|
|
3057
2775
|
exports.GetAgentResponseSchema = GetAgentResponseSchema;
|
|
3058
2776
|
exports.GetChatResponseSchema = GetChatResponseSchema;
|
|
3059
2777
|
exports.GetEnvironmentVariablesResponseSchema = GetEnvironmentVariablesResponseSchema;
|
|
@@ -3114,7 +2832,6 @@ exports.MachineRtcRequestSchema = MachineRtcRequestSchema;
|
|
|
3114
2832
|
exports.MachineRtcResponseSchema = MachineRtcResponseSchema;
|
|
3115
2833
|
exports.MergePullRequestEventSchema = MergePullRequestEventSchema;
|
|
3116
2834
|
exports.MergeRequestEventSchema = MergeRequestEventSchema;
|
|
3117
|
-
exports.MissingAgentFileError = MissingAgentFileError;
|
|
3118
2835
|
exports.OAuthAccountInfoSchema = OAuthAccountInfoSchema;
|
|
3119
2836
|
exports.OAuthBindCallbackResponseSchema = OAuthBindCallbackResponseSchema;
|
|
3120
2837
|
exports.OAuthBindQuerySchema = OAuthBindQuerySchema;
|
|
@@ -3235,8 +2952,6 @@ exports.WorkerStatusRequestSchema = WorkerStatusRequestSchema;
|
|
|
3235
2952
|
exports.WorkerStatusValueSchema = WorkerStatusValueSchema;
|
|
3236
2953
|
exports.WorkspaceFileRequestSchema = WorkspaceFileRequestSchema;
|
|
3237
2954
|
exports.WorkspaceFileResponseSchema = WorkspaceFileResponseSchema;
|
|
3238
|
-
exports.assertAgentExists = assertAgentExists;
|
|
3239
|
-
exports.assertFileExists = assertFileExists;
|
|
3240
2955
|
exports.baseTaskSchema = baseTaskSchema;
|
|
3241
2956
|
exports.buildRtcChunkFrame = buildRtcChunkFrame;
|
|
3242
2957
|
exports.cancelTaskRequestSchema = cancelTaskRequestSchema;
|
|
@@ -3245,6 +2960,7 @@ exports.createEventId = createEventId;
|
|
|
3245
2960
|
exports.createKeyPair = createKeyPair;
|
|
3246
2961
|
exports.createKeyPairWithUit8Array = createKeyPairWithUit8Array;
|
|
3247
2962
|
exports.createMergeRequestSchema = createMergeRequestSchema;
|
|
2963
|
+
exports.createTaskEncryptionPayload = createTaskEncryptionPayload;
|
|
3248
2964
|
exports.createTaskSchema = createTaskSchema;
|
|
3249
2965
|
exports.decodeBase64 = decodeBase64;
|
|
3250
2966
|
exports.decodeRtcChunkHeader = decodeRtcChunkHeader;
|
|
@@ -3254,7 +2970,6 @@ exports.decryptMachineEncryptionKey = decryptMachineEncryptionKey;
|
|
|
3254
2970
|
exports.decryptSdkMessage = decryptSdkMessage;
|
|
3255
2971
|
exports.decryptWithEphemeralKey = decryptWithEphemeralKey;
|
|
3256
2972
|
exports.detectPreview = detectPreview;
|
|
3257
|
-
exports.discoverPlugins = discoverPlugins;
|
|
3258
2973
|
exports.encodeBase64 = encodeBase64;
|
|
3259
2974
|
exports.encodeBase64Url = encodeBase64Url;
|
|
3260
2975
|
exports.encodeRtcChunkHeader = encodeRtcChunkHeader;
|
|
@@ -3265,7 +2980,6 @@ exports.encryptSdkMessage = encryptSdkMessage;
|
|
|
3265
2980
|
exports.encryptWithEphemeralKey = encryptWithEphemeralKey;
|
|
3266
2981
|
exports.generateAESKey = generateAESKey;
|
|
3267
2982
|
exports.generateAESKeyBase64 = generateAESKeyBase64;
|
|
3268
|
-
exports.getAgentContext = getAgentContext;
|
|
3269
2983
|
exports.getRandomBytes = getRandomBytes;
|
|
3270
2984
|
exports.isAskUserMessage = isAskUserMessage;
|
|
3271
2985
|
exports.isAskUserResponseMessage = isAskUserResponseMessage;
|
|
@@ -3273,18 +2987,14 @@ exports.isCompanionHeartbeatMessage = isCompanionHeartbeatMessage;
|
|
|
3273
2987
|
exports.isCompanionReminderMessage = isCompanionReminderMessage;
|
|
3274
2988
|
exports.isSDKMessage = isSDKMessage;
|
|
3275
2989
|
exports.isSDKUserMessage = isSDKUserMessage;
|
|
3276
|
-
exports.
|
|
2990
|
+
exports.isSubTaskAskUserMessage = isSubTaskAskUserMessage;
|
|
3277
2991
|
exports.machineAuth = machineAuth;
|
|
3278
2992
|
exports.permissionResponseRequestSchema = permissionResponseRequestSchema;
|
|
3279
|
-
exports.replacePromptPlaceholders = replacePromptPlaceholders;
|
|
3280
2993
|
exports.resumeTaskRequestSchema = resumeTaskRequestSchema;
|
|
3281
2994
|
exports.resumeTaskSchema = resumeTaskSchema;
|
|
3282
|
-
exports.setAgentContext = setAgentContext;
|
|
3283
2995
|
exports.splitRtcChunkFrame = splitRtcChunkFrame;
|
|
3284
2996
|
exports.startTaskSchema = startTaskSchema;
|
|
3285
2997
|
exports.stopTaskRequestSchema = stopTaskRequestSchema;
|
|
3286
2998
|
exports.userAuth = userAuth;
|
|
3287
|
-
exports.validateAgentDirectory = validateAgentDirectory;
|
|
3288
|
-
exports.validateFrameworkDirectory = validateFrameworkDirectory;
|
|
3289
2999
|
exports.workerAuth = workerAuth;
|
|
3290
3000
|
exports.workerTaskEvents = workerTaskEvents;
|