@knid/agentx 0.1.1 → 0.1.3
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/index.js +93 -112
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -11,7 +11,7 @@ import { Command } from "commander";
|
|
|
11
11
|
|
|
12
12
|
// src/runtime/runner.ts
|
|
13
13
|
import { execa } from "execa";
|
|
14
|
-
import { unlinkSync, existsSync as
|
|
14
|
+
import { unlinkSync as unlinkSync2, existsSync as existsSync6, readFileSync as readFileSync5 } from "fs";
|
|
15
15
|
|
|
16
16
|
// src/config/agent-config.ts
|
|
17
17
|
import { readFileSync, existsSync } from "fs";
|
|
@@ -314,19 +314,6 @@ function buildPromptWithPipe(prompt, pipedContent) {
|
|
|
314
314
|
${prompt}`;
|
|
315
315
|
}
|
|
316
316
|
|
|
317
|
-
// src/runtime/output-formatter.ts
|
|
318
|
-
function formatOutput(data, format) {
|
|
319
|
-
if (format === "json") {
|
|
320
|
-
try {
|
|
321
|
-
const parsed = JSON.parse(data);
|
|
322
|
-
return JSON.stringify(parsed, null, 2);
|
|
323
|
-
} catch {
|
|
324
|
-
return JSON.stringify({ output: data });
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
return data;
|
|
328
|
-
}
|
|
329
|
-
|
|
330
317
|
// src/telemetry/reporter.ts
|
|
331
318
|
function sendTelemetry(event) {
|
|
332
319
|
try {
|
|
@@ -346,6 +333,92 @@ function sendTelemetry(event) {
|
|
|
346
333
|
}
|
|
347
334
|
}
|
|
348
335
|
|
|
336
|
+
// src/secrets/store.ts
|
|
337
|
+
import { readFileSync as readFileSync4, writeFileSync as writeFileSync3, existsSync as existsSync5, unlinkSync, mkdirSync as mkdirSync3 } from "fs";
|
|
338
|
+
import { join as join4 } from "path";
|
|
339
|
+
|
|
340
|
+
// src/secrets/encrypt.ts
|
|
341
|
+
import { createCipheriv, createDecipheriv, randomBytes, scryptSync } from "crypto";
|
|
342
|
+
import { execFileSync } from "child_process";
|
|
343
|
+
import { readFileSync as readFileSync3, existsSync as existsSync4 } from "fs";
|
|
344
|
+
import { platform, hostname, homedir as homedir2 } from "os";
|
|
345
|
+
var ALGORITHM = "aes-256-gcm";
|
|
346
|
+
var IV_LENGTH = 12;
|
|
347
|
+
var KEY_LENGTH = 32;
|
|
348
|
+
var SALT = "agentx-salt";
|
|
349
|
+
function getMachineId() {
|
|
350
|
+
const os = platform();
|
|
351
|
+
if (os === "linux" && existsSync4("/etc/machine-id")) {
|
|
352
|
+
return readFileSync3("/etc/machine-id", "utf-8").trim();
|
|
353
|
+
}
|
|
354
|
+
if (os === "darwin") {
|
|
355
|
+
try {
|
|
356
|
+
const output = execFileSync(
|
|
357
|
+
"ioreg",
|
|
358
|
+
["-rd1", "-c", "IOPlatformExpertDevice"],
|
|
359
|
+
{ encoding: "utf-8" }
|
|
360
|
+
);
|
|
361
|
+
const match = output.match(/"IOPlatformUUID"\s*=\s*"([^"]+)"/);
|
|
362
|
+
if (match) return match[1];
|
|
363
|
+
} catch {
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
return `${hostname()}-${homedir2()}`;
|
|
367
|
+
}
|
|
368
|
+
function deriveKey() {
|
|
369
|
+
const machineId = getMachineId();
|
|
370
|
+
return scryptSync(machineId, SALT, KEY_LENGTH);
|
|
371
|
+
}
|
|
372
|
+
async function encrypt(secrets) {
|
|
373
|
+
const key = deriveKey();
|
|
374
|
+
const iv = randomBytes(IV_LENGTH);
|
|
375
|
+
const cipher = createCipheriv(ALGORITHM, key, iv);
|
|
376
|
+
const plaintext = JSON.stringify(secrets);
|
|
377
|
+
const encrypted = Buffer.concat([cipher.update(plaintext, "utf-8"), cipher.final()]);
|
|
378
|
+
const tag = cipher.getAuthTag();
|
|
379
|
+
return {
|
|
380
|
+
iv: iv.toString("hex"),
|
|
381
|
+
tag: tag.toString("hex"),
|
|
382
|
+
data: encrypted.toString("hex")
|
|
383
|
+
};
|
|
384
|
+
}
|
|
385
|
+
async function decrypt(store) {
|
|
386
|
+
const key = deriveKey();
|
|
387
|
+
const iv = Buffer.from(store.iv, "hex");
|
|
388
|
+
const tag = Buffer.from(store.tag, "hex");
|
|
389
|
+
const data = Buffer.from(store.data, "hex");
|
|
390
|
+
const decipher = createDecipheriv(ALGORITHM, key, iv);
|
|
391
|
+
decipher.setAuthTag(tag);
|
|
392
|
+
const decrypted = Buffer.concat([decipher.update(data), decipher.final()]);
|
|
393
|
+
return JSON.parse(decrypted.toString("utf-8"));
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
// src/secrets/store.ts
|
|
397
|
+
function getSecretsFilePath(agentName, secretsDir) {
|
|
398
|
+
return join4(secretsDir, `${agentName}.enc.json`);
|
|
399
|
+
}
|
|
400
|
+
async function saveSecrets(agentName, secrets, secretsDir = SECRETS_DIR) {
|
|
401
|
+
mkdirSync3(secretsDir, { recursive: true });
|
|
402
|
+
const encrypted = await encrypt(secrets);
|
|
403
|
+
const filePath = getSecretsFilePath(agentName, secretsDir);
|
|
404
|
+
writeFileSync3(filePath, JSON.stringify(encrypted, null, 2), "utf-8");
|
|
405
|
+
}
|
|
406
|
+
async function loadSecrets(agentName, secretsDir = SECRETS_DIR) {
|
|
407
|
+
const filePath = getSecretsFilePath(agentName, secretsDir);
|
|
408
|
+
if (!existsSync5(filePath)) {
|
|
409
|
+
return {};
|
|
410
|
+
}
|
|
411
|
+
const raw = readFileSync4(filePath, "utf-8");
|
|
412
|
+
const store = JSON.parse(raw);
|
|
413
|
+
return decrypt(store);
|
|
414
|
+
}
|
|
415
|
+
async function deleteSecrets(agentName, secretsDir = SECRETS_DIR) {
|
|
416
|
+
const filePath = getSecretsFilePath(agentName, secretsDir);
|
|
417
|
+
if (existsSync5(filePath)) {
|
|
418
|
+
unlinkSync(filePath);
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
|
|
349
422
|
// src/runtime/runner.ts
|
|
350
423
|
function buildClaudeArgs(options) {
|
|
351
424
|
const args = [];
|
|
@@ -375,7 +448,7 @@ async function runAgent(agentName, options) {
|
|
|
375
448
|
);
|
|
376
449
|
let mcpConfigPath;
|
|
377
450
|
if (manifest.mcp_servers && Object.keys(manifest.mcp_servers).length > 0) {
|
|
378
|
-
const secrets =
|
|
451
|
+
const secrets = await loadSecrets(manifest.name);
|
|
379
452
|
const resolved = resolveMCPConfig(manifest.mcp_servers, secrets);
|
|
380
453
|
mcpConfigPath = await writeTempMCPConfig(resolved);
|
|
381
454
|
}
|
|
@@ -390,7 +463,7 @@ async function runAgent(agentName, options) {
|
|
|
390
463
|
finalPrompt = buildPromptWithPipe(finalPrompt, pipedContent);
|
|
391
464
|
}
|
|
392
465
|
if (options.file) {
|
|
393
|
-
const fileContent =
|
|
466
|
+
const fileContent = readFileSync5(options.file, "utf-8");
|
|
394
467
|
finalPrompt = buildPromptWithPipe(finalPrompt, fileContent);
|
|
395
468
|
}
|
|
396
469
|
}
|
|
@@ -416,18 +489,14 @@ async function runAgent(agentName, options) {
|
|
|
416
489
|
});
|
|
417
490
|
return "";
|
|
418
491
|
}
|
|
419
|
-
|
|
420
|
-
const output = formatOutput(result.stdout, options.outputFormat ?? "text");
|
|
421
|
-
if (!options.quiet) {
|
|
422
|
-
process.stdout.write(output);
|
|
423
|
-
}
|
|
492
|
+
await execa(claudePath, claudeArgs, { stdio: "inherit" });
|
|
424
493
|
sendTelemetry({
|
|
425
494
|
agent: agentFullName,
|
|
426
495
|
version: manifest.version,
|
|
427
496
|
success: true,
|
|
428
497
|
duration_ms: Date.now() - startTime
|
|
429
498
|
});
|
|
430
|
-
return
|
|
499
|
+
return "";
|
|
431
500
|
} catch (error) {
|
|
432
501
|
sendTelemetry({
|
|
433
502
|
agent: agentFullName,
|
|
@@ -438,9 +507,9 @@ async function runAgent(agentName, options) {
|
|
|
438
507
|
});
|
|
439
508
|
throw error;
|
|
440
509
|
} finally {
|
|
441
|
-
if (mcpConfigPath &&
|
|
510
|
+
if (mcpConfigPath && existsSync6(mcpConfigPath)) {
|
|
442
511
|
try {
|
|
443
|
-
|
|
512
|
+
unlinkSync2(mcpConfigPath);
|
|
444
513
|
} catch {
|
|
445
514
|
}
|
|
446
515
|
}
|
|
@@ -496,94 +565,6 @@ import { Command as Command2 } from "commander";
|
|
|
496
565
|
|
|
497
566
|
// src/secrets/configure-flow.ts
|
|
498
567
|
import * as p from "@clack/prompts";
|
|
499
|
-
|
|
500
|
-
// src/secrets/store.ts
|
|
501
|
-
import { readFileSync as readFileSync5, writeFileSync as writeFileSync3, existsSync as existsSync6, unlinkSync as unlinkSync2, mkdirSync as mkdirSync3 } from "fs";
|
|
502
|
-
import { join as join4 } from "path";
|
|
503
|
-
|
|
504
|
-
// src/secrets/encrypt.ts
|
|
505
|
-
import { createCipheriv, createDecipheriv, randomBytes, scryptSync } from "crypto";
|
|
506
|
-
import { execFileSync } from "child_process";
|
|
507
|
-
import { readFileSync as readFileSync4, existsSync as existsSync5 } from "fs";
|
|
508
|
-
import { platform, hostname, homedir as homedir2 } from "os";
|
|
509
|
-
var ALGORITHM = "aes-256-gcm";
|
|
510
|
-
var IV_LENGTH = 12;
|
|
511
|
-
var KEY_LENGTH = 32;
|
|
512
|
-
var SALT = "agentx-salt";
|
|
513
|
-
function getMachineId() {
|
|
514
|
-
const os = platform();
|
|
515
|
-
if (os === "linux" && existsSync5("/etc/machine-id")) {
|
|
516
|
-
return readFileSync4("/etc/machine-id", "utf-8").trim();
|
|
517
|
-
}
|
|
518
|
-
if (os === "darwin") {
|
|
519
|
-
try {
|
|
520
|
-
const output = execFileSync(
|
|
521
|
-
"ioreg",
|
|
522
|
-
["-rd1", "-c", "IOPlatformExpertDevice"],
|
|
523
|
-
{ encoding: "utf-8" }
|
|
524
|
-
);
|
|
525
|
-
const match = output.match(/"IOPlatformUUID"\s*=\s*"([^"]+)"/);
|
|
526
|
-
if (match) return match[1];
|
|
527
|
-
} catch {
|
|
528
|
-
}
|
|
529
|
-
}
|
|
530
|
-
return `${hostname()}-${homedir2()}`;
|
|
531
|
-
}
|
|
532
|
-
function deriveKey() {
|
|
533
|
-
const machineId = getMachineId();
|
|
534
|
-
return scryptSync(machineId, SALT, KEY_LENGTH);
|
|
535
|
-
}
|
|
536
|
-
async function encrypt(secrets) {
|
|
537
|
-
const key = deriveKey();
|
|
538
|
-
const iv = randomBytes(IV_LENGTH);
|
|
539
|
-
const cipher = createCipheriv(ALGORITHM, key, iv);
|
|
540
|
-
const plaintext = JSON.stringify(secrets);
|
|
541
|
-
const encrypted = Buffer.concat([cipher.update(plaintext, "utf-8"), cipher.final()]);
|
|
542
|
-
const tag = cipher.getAuthTag();
|
|
543
|
-
return {
|
|
544
|
-
iv: iv.toString("hex"),
|
|
545
|
-
tag: tag.toString("hex"),
|
|
546
|
-
data: encrypted.toString("hex")
|
|
547
|
-
};
|
|
548
|
-
}
|
|
549
|
-
async function decrypt(store) {
|
|
550
|
-
const key = deriveKey();
|
|
551
|
-
const iv = Buffer.from(store.iv, "hex");
|
|
552
|
-
const tag = Buffer.from(store.tag, "hex");
|
|
553
|
-
const data = Buffer.from(store.data, "hex");
|
|
554
|
-
const decipher = createDecipheriv(ALGORITHM, key, iv);
|
|
555
|
-
decipher.setAuthTag(tag);
|
|
556
|
-
const decrypted = Buffer.concat([decipher.update(data), decipher.final()]);
|
|
557
|
-
return JSON.parse(decrypted.toString("utf-8"));
|
|
558
|
-
}
|
|
559
|
-
|
|
560
|
-
// src/secrets/store.ts
|
|
561
|
-
function getSecretsFilePath(agentName, secretsDir) {
|
|
562
|
-
return join4(secretsDir, `${agentName}.enc.json`);
|
|
563
|
-
}
|
|
564
|
-
async function saveSecrets(agentName, secrets, secretsDir = SECRETS_DIR) {
|
|
565
|
-
mkdirSync3(secretsDir, { recursive: true });
|
|
566
|
-
const encrypted = await encrypt(secrets);
|
|
567
|
-
const filePath = getSecretsFilePath(agentName, secretsDir);
|
|
568
|
-
writeFileSync3(filePath, JSON.stringify(encrypted, null, 2), "utf-8");
|
|
569
|
-
}
|
|
570
|
-
async function loadSecrets(agentName, secretsDir = SECRETS_DIR) {
|
|
571
|
-
const filePath = getSecretsFilePath(agentName, secretsDir);
|
|
572
|
-
if (!existsSync6(filePath)) {
|
|
573
|
-
return {};
|
|
574
|
-
}
|
|
575
|
-
const raw = readFileSync5(filePath, "utf-8");
|
|
576
|
-
const store = JSON.parse(raw);
|
|
577
|
-
return decrypt(store);
|
|
578
|
-
}
|
|
579
|
-
async function deleteSecrets(agentName, secretsDir = SECRETS_DIR) {
|
|
580
|
-
const filePath = getSecretsFilePath(agentName, secretsDir);
|
|
581
|
-
if (existsSync6(filePath)) {
|
|
582
|
-
unlinkSync2(filePath);
|
|
583
|
-
}
|
|
584
|
-
}
|
|
585
|
-
|
|
586
|
-
// src/secrets/configure-flow.ts
|
|
587
568
|
async function runConfigureFlow(options) {
|
|
588
569
|
const { agentName, declarations, secretsDir } = options;
|
|
589
570
|
if (declarations.length === 0) {
|