@integrity-labs/agt-cli 0.27.135 → 0.27.136
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/bin/agt.js +4 -4
- package/dist/{chunk-HC7B2OVZ.js → chunk-4B6KOQQL.js} +537 -531
- package/dist/chunk-4B6KOQQL.js.map +1 -0
- package/dist/{chunk-XKX2HEQY.js → chunk-75QM5THV.js} +2 -2
- package/dist/{chunk-KZGU4X3A.js → chunk-HDWKI7W3.js} +2016 -2016
- package/dist/chunk-HDWKI7W3.js.map +1 -0
- package/dist/{claude-pair-runtime-I7SKUE2Q.js → claude-pair-runtime-A5IITZ6J.js} +2 -2
- package/dist/lib/manager-worker.js +15 -13
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/mcp/index.js +67 -1
- package/dist/{persistent-session-56AY3LH6.js → persistent-session-5N5NFU27.js} +3 -3
- package/dist/{responsiveness-probe-L6B7WINR.js → responsiveness-probe-6L6WKHK5.js} +3 -3
- package/package.json +1 -1
- package/dist/chunk-HC7B2OVZ.js.map +0 -1
- package/dist/chunk-KZGU4X3A.js.map +0 -1
- /package/dist/{chunk-XKX2HEQY.js.map → chunk-75QM5THV.js.map} +0 -0
- /package/dist/{claude-pair-runtime-I7SKUE2Q.js.map → claude-pair-runtime-A5IITZ6J.js.map} +0 -0
- /package/dist/{persistent-session-56AY3LH6.js.map → persistent-session-5N5NFU27.js.map} +0 -0
- /package/dist/{responsiveness-probe-L6B7WINR.js.map → responsiveness-probe-6L6WKHK5.js.map} +0 -0
|
@@ -9,7 +9,65 @@ import {
|
|
|
9
9
|
parseDeliveryTarget,
|
|
10
10
|
registerFramework,
|
|
11
11
|
wrapScheduledTaskPrompt
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-HDWKI7W3.js";
|
|
13
|
+
|
|
14
|
+
// ../../packages/core/dist/provisioning/provisioner.js
|
|
15
|
+
import { createHash } from "crypto";
|
|
16
|
+
function sha256(content) {
|
|
17
|
+
return createHash("sha256").update(content, "utf8").digest("hex");
|
|
18
|
+
}
|
|
19
|
+
function provision(input, frameworkId = "openclaw") {
|
|
20
|
+
const adapter = getFramework(frameworkId);
|
|
21
|
+
const artifacts = adapter.buildArtifacts(input);
|
|
22
|
+
const charterHash = sha256(input.charterContent);
|
|
23
|
+
const toolsHash = sha256(input.toolsContent);
|
|
24
|
+
const teamDir = `.augmented/${input.agent.code_name}`;
|
|
25
|
+
return {
|
|
26
|
+
teamDir,
|
|
27
|
+
artifacts,
|
|
28
|
+
charterHash,
|
|
29
|
+
toolsHash
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// ../../packages/core/dist/provisioning/hook-env.js
|
|
34
|
+
function augmentedHookPath(currentPath) {
|
|
35
|
+
const extras = [
|
|
36
|
+
"/home/linuxbrew/.linuxbrew/bin",
|
|
37
|
+
"/opt/homebrew/bin",
|
|
38
|
+
"/usr/local/bin",
|
|
39
|
+
"/usr/bin",
|
|
40
|
+
"/bin"
|
|
41
|
+
];
|
|
42
|
+
const seen = /* @__PURE__ */ new Set();
|
|
43
|
+
const parts = [];
|
|
44
|
+
const push = (p) => {
|
|
45
|
+
if (!p || seen.has(p))
|
|
46
|
+
return;
|
|
47
|
+
seen.add(p);
|
|
48
|
+
parts.push(p);
|
|
49
|
+
};
|
|
50
|
+
for (const p of (currentPath ?? "").split(":"))
|
|
51
|
+
push(p);
|
|
52
|
+
for (const p of extras)
|
|
53
|
+
push(p);
|
|
54
|
+
return parts.join(":");
|
|
55
|
+
}
|
|
56
|
+
function extractCommandNotFound(stderr) {
|
|
57
|
+
if (!stderr)
|
|
58
|
+
return null;
|
|
59
|
+
const SAFE_CMD = /^[A-Za-z][A-Za-z0-9._-]{0,63}$/;
|
|
60
|
+
for (const line of stderr.split(/\r?\n/)) {
|
|
61
|
+
const m = line.match(/^(?:bash|sh): (?:line \d+: )?([^:\s]+): command not found$/);
|
|
62
|
+
if (m?.[1]) {
|
|
63
|
+
const rawCmd = m[1].trim();
|
|
64
|
+
const cmd = rawCmd.split("/").pop() ?? rawCmd;
|
|
65
|
+
if (SAFE_CMD.test(cmd))
|
|
66
|
+
return cmd;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
13
71
|
|
|
14
72
|
// ../../packages/core/dist/integrations/registry.js
|
|
15
73
|
var INTEGRATION_REGISTRY = [
|
|
@@ -421,52 +479,370 @@ function getIntegration(id) {
|
|
|
421
479
|
return integrationMap.get(id);
|
|
422
480
|
}
|
|
423
481
|
|
|
424
|
-
// ../../packages/core/dist/provisioning/
|
|
425
|
-
function
|
|
426
|
-
|
|
427
|
-
"/home/linuxbrew/.linuxbrew/bin",
|
|
428
|
-
"/opt/homebrew/bin",
|
|
429
|
-
"/usr/local/bin",
|
|
430
|
-
"/usr/bin",
|
|
431
|
-
"/bin"
|
|
432
|
-
];
|
|
433
|
-
const seen = /* @__PURE__ */ new Set();
|
|
434
|
-
const parts = [];
|
|
435
|
-
const push = (p) => {
|
|
436
|
-
if (!p || seen.has(p))
|
|
437
|
-
return;
|
|
438
|
-
seen.add(p);
|
|
439
|
-
parts.push(p);
|
|
440
|
-
};
|
|
441
|
-
for (const p of (currentPath ?? "").split(":"))
|
|
442
|
-
push(p);
|
|
443
|
-
for (const p of extras)
|
|
444
|
-
push(p);
|
|
445
|
-
return parts.join(":");
|
|
482
|
+
// ../../packages/core/dist/provisioning/env-integrations-file.js
|
|
483
|
+
function shellQuote(value) {
|
|
484
|
+
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
446
485
|
}
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
486
|
+
var CHANNEL_SECRET_ENV_KEYS = [
|
|
487
|
+
"SLACK_BOT_TOKEN",
|
|
488
|
+
"SLACK_APP_TOKEN",
|
|
489
|
+
"TELEGRAM_BOT_TOKEN",
|
|
490
|
+
"MSTEAMS_CLIENT_SECRET"
|
|
491
|
+
];
|
|
492
|
+
var MCP_SERVER_SECRET_ENV_KEYS = [
|
|
493
|
+
"COMPOSIO_API_KEY",
|
|
494
|
+
"PIPEDREAM_CLIENT_SECRET"
|
|
495
|
+
];
|
|
496
|
+
var PRESERVED_ENV_KEYS = [
|
|
497
|
+
...CHANNEL_SECRET_ENV_KEYS,
|
|
498
|
+
...MCP_SERVER_SECRET_ENV_KEYS
|
|
499
|
+
];
|
|
500
|
+
var HEADER = "# Augmented integrations \u2014 auto-generated, do not edit";
|
|
501
|
+
function parseEnvFileEntries(content) {
|
|
502
|
+
const out = /* @__PURE__ */ new Map();
|
|
503
|
+
for (const line of content.split("\n")) {
|
|
504
|
+
if (!line || line.startsWith("#") || !line.includes("="))
|
|
505
|
+
continue;
|
|
506
|
+
const eqIdx = line.indexOf("=");
|
|
507
|
+
out.set(line.slice(0, eqIdx), line.slice(eqIdx + 1));
|
|
508
|
+
}
|
|
509
|
+
return out;
|
|
510
|
+
}
|
|
511
|
+
function renderEnvIntegrations(entries) {
|
|
512
|
+
const lines = [HEADER];
|
|
513
|
+
for (const [key, rendered] of entries)
|
|
514
|
+
lines.push(`${key}=${rendered}`);
|
|
515
|
+
return lines.join("\n") + "\n";
|
|
516
|
+
}
|
|
517
|
+
function mergeEnvIntegrationsContent(existing, args) {
|
|
518
|
+
const current = existing === null ? /* @__PURE__ */ new Map() : parseEnvFileEntries(existing);
|
|
519
|
+
let next;
|
|
520
|
+
if (args.mode === "upsert") {
|
|
521
|
+
next = new Map(current);
|
|
522
|
+
for (const [key, raw] of Object.entries(args.updates)) {
|
|
523
|
+
if (raw === null)
|
|
524
|
+
next.delete(key);
|
|
525
|
+
else
|
|
526
|
+
next.set(key, shellQuote(raw));
|
|
527
|
+
}
|
|
528
|
+
} else {
|
|
529
|
+
next = /* @__PURE__ */ new Map();
|
|
530
|
+
for (const [key, raw] of Object.entries(args.updates)) {
|
|
531
|
+
if (raw !== null)
|
|
532
|
+
next.set(key, shellQuote(raw));
|
|
533
|
+
}
|
|
534
|
+
const preserve = args.preserveKeys ?? PRESERVED_ENV_KEYS;
|
|
535
|
+
for (const key of preserve) {
|
|
536
|
+
if (key in args.updates)
|
|
537
|
+
continue;
|
|
538
|
+
if (!next.has(key) && current.has(key)) {
|
|
539
|
+
next.set(key, current.get(key));
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
return renderEnvIntegrations(next);
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
// ../../packages/core/dist/provisioning/mcp-config-guards.js
|
|
547
|
+
import { chmodSync, existsSync, readFileSync, renameSync, writeFileSync, unlinkSync } from "fs";
|
|
548
|
+
|
|
549
|
+
// ../../packages/core/dist/provisioning/mcp-secret-lint.js
|
|
550
|
+
var LITERAL_SECRET_PATTERNS = [
|
|
551
|
+
// Slack bot token — `xoxb-<workspace>-<...>`
|
|
552
|
+
{ name: "slack_bot_token", re: /^xoxb-/ },
|
|
553
|
+
// Slack app-level token (Socket Mode) — `xapp-<...>`
|
|
554
|
+
{ name: "slack_app_token", re: /^xapp-/ },
|
|
555
|
+
// AGT host API key — `tlk_<...>` (see claudecode-plugin-augmented README).
|
|
556
|
+
{ name: "agt_host_api_key", re: /^tlk_/ },
|
|
557
|
+
// Composio / generic api-key prefix — `ak_<...>`
|
|
558
|
+
{ name: "composio_api_key", re: /^ak_/ },
|
|
559
|
+
// Telegram bot token — `<bot id>:AA<...>` (BotFather format). ENG-5901
|
|
560
|
+
// PR 4: the original `\d{10}:AAE` (from the issue AC) was too narrow —
|
|
561
|
+
// live tokens on agt-aws-1 carry `AA` + a varying third character
|
|
562
|
+
// (don/scout/stirling all had AA-not-E tokens the lint and migration
|
|
563
|
+
// missed). Bot ids are 8–12 digits; the token part always starts `AA`.
|
|
564
|
+
{ name: "telegram_bot_token", re: /^\d{8,12}:AA[A-Za-z0-9_-]/ },
|
|
565
|
+
// ENG-5901 extension beyond the original AC's five patterns: a literal
|
|
566
|
+
// JWT (`eyJ...`) is the shape of a leaked AGT_API_KEY, which the
|
|
567
|
+
// value-prefix patterns above would otherwise miss. Header values often
|
|
568
|
+
// carry it behind `Bearer ` (or a copy-pasted `Authorization: Bearer `),
|
|
569
|
+
// so those prefixes are optionally consumed (CodeRabbit #1731).
|
|
570
|
+
// Templates (`Bearer ${AGT_API_KEY}`) and concrete non-secret values
|
|
571
|
+
// (UUIDs, hosts) never put `eyJ` after the prefix, so this stays
|
|
572
|
+
// false-positive-safe inside .mcp.json.
|
|
573
|
+
{ name: "jwt_agt_api_key", re: /^(?:authorization:\s*)?(?:bearer\s+)?eyJ[A-Za-z0-9_-]+\./i }
|
|
574
|
+
];
|
|
575
|
+
function matchLiteralSecret(value) {
|
|
576
|
+
for (const { name, re } of LITERAL_SECRET_PATTERNS) {
|
|
577
|
+
if (re.test(value))
|
|
578
|
+
return name;
|
|
579
|
+
}
|
|
580
|
+
return null;
|
|
581
|
+
}
|
|
582
|
+
function scanRecord(server, record, location, findings) {
|
|
583
|
+
if (!record)
|
|
584
|
+
return;
|
|
585
|
+
for (const [field, value] of Object.entries(record)) {
|
|
586
|
+
if (typeof value !== "string")
|
|
587
|
+
continue;
|
|
588
|
+
const pattern = matchLiteralSecret(value);
|
|
589
|
+
if (pattern)
|
|
590
|
+
findings.push({ server, field, location, pattern });
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
function scanConfigForLiteralSecrets(config) {
|
|
594
|
+
const findings = [];
|
|
595
|
+
if (typeof config !== "object" || config === null)
|
|
596
|
+
return findings;
|
|
597
|
+
const servers = config.mcpServers;
|
|
598
|
+
if (typeof servers !== "object" || servers === null)
|
|
599
|
+
return findings;
|
|
600
|
+
for (const [server, raw] of Object.entries(servers)) {
|
|
601
|
+
if (typeof raw !== "object" || raw === null)
|
|
602
|
+
continue;
|
|
603
|
+
const entry = raw;
|
|
604
|
+
scanRecord(server, entry.env, "env", findings);
|
|
605
|
+
scanRecord(server, entry.headers, "header", findings);
|
|
606
|
+
}
|
|
607
|
+
return findings;
|
|
608
|
+
}
|
|
609
|
+
function formatLiteralSecretRejection(f) {
|
|
610
|
+
return `[mcp-write] [literal-secret-rejected] field=${f.field} server=${f.server} location=${f.location} pattern=${f.pattern}`;
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
// ../../packages/core/dist/provisioning/mcp-config-guards.js
|
|
614
|
+
var MCP_FILE_MODE = 384;
|
|
615
|
+
var lastRejectionFingerprintByPath = /* @__PURE__ */ new Map();
|
|
616
|
+
var REQUIRED_ENV_RULES_BY_SERVER = {
|
|
617
|
+
"cloud-broker": [
|
|
618
|
+
{ key: "AGT_HOST", mustBeConcrete: false },
|
|
619
|
+
{ key: "AGT_API_KEY", mustBeConcrete: false },
|
|
620
|
+
// ENG-4744: this is the bug shape — writer used to omit this
|
|
621
|
+
// entirely, or render it as a literal `${AGT_AGENT_ID}` instead
|
|
622
|
+
// of the agent's real UUID. The broker has no way to substitute
|
|
623
|
+
// it post-spawn, so a placeholder here = silently broken agent.
|
|
624
|
+
{ key: "AGT_AGENT_ID", mustBeConcrete: true }
|
|
625
|
+
]
|
|
626
|
+
};
|
|
627
|
+
var PLACEHOLDER_RE = /\$\{[^}]+\}/;
|
|
628
|
+
function validateRenderedMcpConfig(config) {
|
|
629
|
+
const errors = [];
|
|
630
|
+
if (typeof config !== "object" || config === null || Array.isArray(config)) {
|
|
631
|
+
return {
|
|
632
|
+
ok: false,
|
|
633
|
+
errors: [
|
|
634
|
+
{
|
|
635
|
+
kind: "invalid_json_shape",
|
|
636
|
+
server: "*",
|
|
637
|
+
message: "config root must be a non-null object"
|
|
638
|
+
}
|
|
639
|
+
]
|
|
640
|
+
};
|
|
641
|
+
}
|
|
642
|
+
const root = config;
|
|
643
|
+
if (root.mcpServers === void 0) {
|
|
644
|
+
return { ok: true };
|
|
645
|
+
}
|
|
646
|
+
if (typeof root.mcpServers !== "object" || root.mcpServers === null) {
|
|
647
|
+
return {
|
|
648
|
+
ok: false,
|
|
649
|
+
errors: [
|
|
650
|
+
{
|
|
651
|
+
kind: "invalid_json_shape",
|
|
652
|
+
server: "*",
|
|
653
|
+
message: "mcpServers must be an object"
|
|
654
|
+
}
|
|
655
|
+
]
|
|
656
|
+
};
|
|
657
|
+
}
|
|
658
|
+
if (Array.isArray(root.mcpServers)) {
|
|
659
|
+
return {
|
|
660
|
+
ok: false,
|
|
661
|
+
errors: [
|
|
662
|
+
{
|
|
663
|
+
kind: "invalid_json_shape",
|
|
664
|
+
server: "*",
|
|
665
|
+
message: "mcpServers must be an object"
|
|
666
|
+
}
|
|
667
|
+
]
|
|
668
|
+
};
|
|
669
|
+
}
|
|
670
|
+
for (const [serverKey, raw] of Object.entries(root.mcpServers)) {
|
|
671
|
+
if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
|
|
672
|
+
errors.push({
|
|
673
|
+
kind: "invalid_json_shape",
|
|
674
|
+
server: serverKey,
|
|
675
|
+
message: `entry must be an object`
|
|
676
|
+
});
|
|
677
|
+
continue;
|
|
678
|
+
}
|
|
679
|
+
const entry = raw;
|
|
680
|
+
const entryRecord = entry;
|
|
681
|
+
if (typeof entryRecord["url"] === "string") {
|
|
682
|
+
const type = entryRecord["type"];
|
|
683
|
+
if (type !== "http" && type !== "sse") {
|
|
684
|
+
errors.push({
|
|
685
|
+
kind: "remote_mcp_missing_type",
|
|
686
|
+
server: serverKey,
|
|
687
|
+
message: `url-based entry must include \`type: "http"\` or \`type: "sse"\` (Claude Code MCP schema requires it)`
|
|
688
|
+
});
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
const rules = REQUIRED_ENV_RULES_BY_SERVER[serverKey];
|
|
692
|
+
if (rules) {
|
|
693
|
+
const env = entry.env ?? {};
|
|
694
|
+
for (const rule of rules) {
|
|
695
|
+
const value = env[rule.key];
|
|
696
|
+
if (typeof value !== "string" || value.length === 0) {
|
|
697
|
+
errors.push({
|
|
698
|
+
kind: "missing_required_env",
|
|
699
|
+
server: serverKey,
|
|
700
|
+
message: `missing required env key: ${rule.key}`
|
|
701
|
+
});
|
|
702
|
+
continue;
|
|
703
|
+
}
|
|
704
|
+
if (rule.mustBeConcrete && PLACEHOLDER_RE.test(value)) {
|
|
705
|
+
errors.push({
|
|
706
|
+
kind: "unexpanded_placeholder",
|
|
707
|
+
server: serverKey,
|
|
708
|
+
message: `env.${rule.key} contains an unexpanded \${...} placeholder; expected a concrete value`
|
|
709
|
+
});
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
return errors.length === 0 ? { ok: true } : { ok: false, errors };
|
|
715
|
+
}
|
|
716
|
+
function formatValidationErrors(errors) {
|
|
717
|
+
return errors.map((e) => `${e.server}:${e.kind}=${e.message}`).join("; ");
|
|
718
|
+
}
|
|
719
|
+
function safeWriteJsonAtomic(path, content, opts = {}) {
|
|
720
|
+
const keepBackup = opts.keepBackup !== false;
|
|
721
|
+
const rename = opts.renamer ?? renameSync;
|
|
722
|
+
const tmpPath = `${path}.new`;
|
|
723
|
+
const bakPath = `${path}.bak`;
|
|
724
|
+
let movedOriginalToBackup = false;
|
|
725
|
+
try {
|
|
726
|
+
writeFileSync(tmpPath, content);
|
|
727
|
+
if (opts.mode !== void 0) {
|
|
728
|
+
chmodSync(tmpPath, opts.mode);
|
|
729
|
+
}
|
|
730
|
+
} catch (err) {
|
|
731
|
+
try {
|
|
732
|
+
if (existsSync(tmpPath))
|
|
733
|
+
unlinkSync(tmpPath);
|
|
734
|
+
} catch {
|
|
735
|
+
}
|
|
736
|
+
throw err;
|
|
737
|
+
}
|
|
738
|
+
try {
|
|
739
|
+
if (keepBackup && existsSync(path)) {
|
|
740
|
+
rename(path, bakPath);
|
|
741
|
+
movedOriginalToBackup = true;
|
|
742
|
+
}
|
|
743
|
+
rename(tmpPath, path);
|
|
744
|
+
} catch (err) {
|
|
745
|
+
try {
|
|
746
|
+
if (existsSync(tmpPath))
|
|
747
|
+
unlinkSync(tmpPath);
|
|
748
|
+
} catch {
|
|
749
|
+
}
|
|
750
|
+
if (movedOriginalToBackup && !existsSync(path) && existsSync(bakPath)) {
|
|
751
|
+
try {
|
|
752
|
+
renameSync(bakPath, path);
|
|
753
|
+
} catch {
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
throw err;
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
function safeWriteMcpJson(path, config) {
|
|
760
|
+
const validation = validateRenderedMcpConfig(config);
|
|
761
|
+
if (!validation.ok) {
|
|
762
|
+
return { written: false, errors: validation.errors };
|
|
763
|
+
}
|
|
764
|
+
const secretFindings = scanConfigForLiteralSecrets(config);
|
|
765
|
+
if (secretFindings.length > 0) {
|
|
766
|
+
const fingerprint = secretFindings.map((f) => `${f.server}.${f.field}.${f.location}`).sort().join("|");
|
|
767
|
+
if (lastRejectionFingerprintByPath.get(path) !== fingerprint) {
|
|
768
|
+
lastRejectionFingerprintByPath.set(path, fingerprint);
|
|
769
|
+
for (const f of secretFindings) {
|
|
770
|
+
process.stderr.write(`${formatLiteralSecretRejection(f)}
|
|
771
|
+
`);
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
return {
|
|
775
|
+
written: false,
|
|
776
|
+
errors: secretFindings.map((f) => ({
|
|
777
|
+
kind: "literal_secret",
|
|
778
|
+
server: f.server,
|
|
779
|
+
message: `literal secret in ${f.location} field '${f.field}' (pattern ${f.pattern}); expected a \${VAR} template`
|
|
780
|
+
}))
|
|
781
|
+
};
|
|
782
|
+
}
|
|
783
|
+
lastRejectionFingerprintByPath.delete(path);
|
|
784
|
+
safeWriteJsonAtomic(path, JSON.stringify(config, null, 2), { mode: MCP_FILE_MODE });
|
|
785
|
+
return { written: true, errors: [] };
|
|
786
|
+
}
|
|
787
|
+
var SECRET_FIELD_NAME_RE = /TOKEN|KEY|SECRET|BEARER|PASSWORD/i;
|
|
788
|
+
function collectSecretFields(config) {
|
|
789
|
+
const out = /* @__PURE__ */ new Map();
|
|
790
|
+
if (typeof config !== "object" || config === null)
|
|
791
|
+
return out;
|
|
792
|
+
const servers = config.mcpServers;
|
|
793
|
+
if (typeof servers !== "object" || servers === null)
|
|
794
|
+
return out;
|
|
795
|
+
for (const [server, raw] of Object.entries(servers)) {
|
|
796
|
+
if (typeof raw !== "object" || raw === null)
|
|
797
|
+
continue;
|
|
798
|
+
const entry = raw;
|
|
799
|
+
for (const [block, location] of [
|
|
800
|
+
[entry.env, "env"],
|
|
801
|
+
[entry.headers, "header"]
|
|
802
|
+
]) {
|
|
803
|
+
if (!block)
|
|
804
|
+
continue;
|
|
805
|
+
for (const [field, value] of Object.entries(block)) {
|
|
806
|
+
if (typeof value !== "string")
|
|
807
|
+
continue;
|
|
808
|
+
if (!SECRET_FIELD_NAME_RE.test(field))
|
|
809
|
+
continue;
|
|
810
|
+
out.set(`${server}\0${field}`, { location, value });
|
|
811
|
+
}
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
return out;
|
|
815
|
+
}
|
|
816
|
+
function mcpMirrorParityErrors(provision2, project) {
|
|
817
|
+
const a = collectSecretFields(provision2);
|
|
818
|
+
const b = collectSecretFields(project);
|
|
819
|
+
const mismatches = [];
|
|
820
|
+
const keys = /* @__PURE__ */ new Set([...a.keys(), ...b.keys()]);
|
|
821
|
+
for (const key of keys) {
|
|
822
|
+
const [server, field] = key.split("\0");
|
|
823
|
+
const pv = a.get(key);
|
|
824
|
+
const pj = b.get(key);
|
|
825
|
+
if (pv && !pj) {
|
|
826
|
+
mismatches.push({ server, field, location: pv.location, reason: "missing-in-project" });
|
|
827
|
+
} else if (!pv && pj) {
|
|
828
|
+
mismatches.push({ server, field, location: pj.location, reason: "missing-in-provision" });
|
|
829
|
+
} else if (pv && pj && pv.value !== pj.value) {
|
|
830
|
+
mismatches.push({ server, field, location: pv.location, reason: "value-diverges" });
|
|
458
831
|
}
|
|
459
832
|
}
|
|
460
|
-
return
|
|
833
|
+
return mismatches;
|
|
834
|
+
}
|
|
835
|
+
function formatMirrorMismatch(m) {
|
|
836
|
+
return `[mcp-mirror] [parity-violation] server=${m.server} field=${m.field} location=${m.location} reason=${m.reason}`;
|
|
461
837
|
}
|
|
462
838
|
|
|
463
839
|
// ../../packages/core/dist/provisioning/frameworks/openclaw/index.js
|
|
464
840
|
import { execFile, spawn } from "child_process";
|
|
465
|
-
import { readFileSync as
|
|
841
|
+
import { readFileSync as readFileSync3, writeFileSync as writeFileSync3, mkdirSync as mkdirSync2, existsSync as existsSync3, unlinkSync as unlinkSync3, chmodSync as chmodSync3, renameSync as renameSync3, symlinkSync } from "fs";
|
|
466
842
|
import { join as join2, dirname as dirname2, resolve } from "path";
|
|
467
843
|
|
|
468
844
|
// ../../packages/core/dist/integrations/xurl-config.js
|
|
469
|
-
import { chmodSync, existsSync, mkdirSync, readFileSync, renameSync, unlinkSync, writeFileSync } from "fs";
|
|
845
|
+
import { chmodSync as chmodSync2, existsSync as existsSync2, mkdirSync, readFileSync as readFileSync2, renameSync as renameSync2, unlinkSync as unlinkSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
470
846
|
import { homedir } from "os";
|
|
471
847
|
import { dirname, join } from "path";
|
|
472
848
|
import { parse as parseYaml, stringify as stringifyYaml } from "yaml";
|
|
@@ -594,10 +970,10 @@ function writeXurlStoreForIntegrations(integrations, filePath = getXurlStorePath
|
|
|
594
970
|
if (Object.keys(agtApps).length === 0)
|
|
595
971
|
return null;
|
|
596
972
|
let existing = null;
|
|
597
|
-
if (
|
|
973
|
+
if (existsSync2(filePath)) {
|
|
598
974
|
let raw;
|
|
599
975
|
try {
|
|
600
|
-
raw =
|
|
976
|
+
raw = readFileSync2(filePath, "utf-8");
|
|
601
977
|
} catch {
|
|
602
978
|
return null;
|
|
603
979
|
}
|
|
@@ -610,18 +986,18 @@ function writeXurlStoreForIntegrations(integrations, filePath = getXurlStorePath
|
|
|
610
986
|
const merged = mergeXurlStore(existing, agtApps);
|
|
611
987
|
mkdirSync(dirname(filePath), { recursive: true });
|
|
612
988
|
const tmpPath = `${filePath}.tmp-${process.pid}-${Date.now()}`;
|
|
613
|
-
|
|
989
|
+
writeFileSync2(tmpPath, serializeXurlStore(merged), { mode: XURL_FILE_MODE });
|
|
614
990
|
try {
|
|
615
|
-
|
|
991
|
+
renameSync2(tmpPath, filePath);
|
|
616
992
|
} catch (err) {
|
|
617
993
|
try {
|
|
618
|
-
|
|
994
|
+
unlinkSync2(tmpPath);
|
|
619
995
|
} catch {
|
|
620
996
|
}
|
|
621
997
|
throw err;
|
|
622
998
|
}
|
|
623
999
|
try {
|
|
624
|
-
|
|
1000
|
+
chmodSync2(filePath, XURL_FILE_MODE);
|
|
625
1001
|
} catch {
|
|
626
1002
|
}
|
|
627
1003
|
return filePath;
|
|
@@ -1044,9 +1420,9 @@ function writeIntegrationTokenFile(codeName, integrations) {
|
|
|
1044
1420
|
if (Object.keys(tokens).length === 0)
|
|
1045
1421
|
return;
|
|
1046
1422
|
mkdirSync2(dir, { recursive: true });
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1423
|
+
writeFileSync3(tmpFilePath, JSON.stringify(tokens, null, 2));
|
|
1424
|
+
chmodSync3(tmpFilePath, 384);
|
|
1425
|
+
renameSync3(tmpFilePath, tokenFilePath);
|
|
1050
1426
|
}
|
|
1051
1427
|
function getOpenClawConfigPath(profile) {
|
|
1052
1428
|
const homeDir = getHomeDir();
|
|
@@ -1060,7 +1436,7 @@ function modifyOpenClawConfig(fn, profile) {
|
|
|
1060
1436
|
let originalContent;
|
|
1061
1437
|
let config;
|
|
1062
1438
|
try {
|
|
1063
|
-
originalContent =
|
|
1439
|
+
originalContent = readFileSync3(configFile, "utf-8");
|
|
1064
1440
|
config = JSON.parse(originalContent);
|
|
1065
1441
|
} catch {
|
|
1066
1442
|
return;
|
|
@@ -1071,7 +1447,7 @@ function modifyOpenClawConfig(fn, profile) {
|
|
|
1071
1447
|
const newContent = JSON.stringify(config, null, 2);
|
|
1072
1448
|
if (newContent === originalContent)
|
|
1073
1449
|
return;
|
|
1074
|
-
|
|
1450
|
+
writeFileSync3(configFile, newContent);
|
|
1075
1451
|
}
|
|
1076
1452
|
var AUGMENTED_DIR = join2(getHomeDir(), ".augmented");
|
|
1077
1453
|
function getGatewayPidPath(codeName) {
|
|
@@ -1085,7 +1461,7 @@ function getGatewayPortsPath() {
|
|
|
1085
1461
|
}
|
|
1086
1462
|
function readGatewayPid(codeName) {
|
|
1087
1463
|
try {
|
|
1088
|
-
const raw =
|
|
1464
|
+
const raw = readFileSync3(getGatewayPidPath(codeName), "utf-8").trim();
|
|
1089
1465
|
const pid = parseInt(raw, 10);
|
|
1090
1466
|
return isNaN(pid) ? null : pid;
|
|
1091
1467
|
} catch {
|
|
@@ -1133,7 +1509,7 @@ function execPromise(cmd, args) {
|
|
|
1133
1509
|
}
|
|
1134
1510
|
function readGatewayPorts() {
|
|
1135
1511
|
try {
|
|
1136
|
-
return JSON.parse(
|
|
1512
|
+
return JSON.parse(readFileSync3(getGatewayPortsPath(), "utf-8"));
|
|
1137
1513
|
} catch {
|
|
1138
1514
|
return {};
|
|
1139
1515
|
}
|
|
@@ -1369,7 +1745,7 @@ ${entry.content}`
|
|
|
1369
1745
|
const configFile = getOpenClawConfigPath(codeName);
|
|
1370
1746
|
let raw;
|
|
1371
1747
|
try {
|
|
1372
|
-
raw =
|
|
1748
|
+
raw = readFileSync3(configFile, "utf-8");
|
|
1373
1749
|
} catch {
|
|
1374
1750
|
return false;
|
|
1375
1751
|
}
|
|
@@ -1438,7 +1814,7 @@ ${entry.content}`
|
|
|
1438
1814
|
const authFile = join2(authDir, "auth-profiles.json");
|
|
1439
1815
|
let existing = {};
|
|
1440
1816
|
try {
|
|
1441
|
-
existing = JSON.parse(
|
|
1817
|
+
existing = JSON.parse(readFileSync3(authFile, "utf-8"));
|
|
1442
1818
|
} catch {
|
|
1443
1819
|
}
|
|
1444
1820
|
const existingProfiles = existing["profiles"] ?? {};
|
|
@@ -1460,7 +1836,7 @@ ${entry.content}`
|
|
|
1460
1836
|
usageStats: existing["usageStats"] ?? {}
|
|
1461
1837
|
};
|
|
1462
1838
|
mkdirSync2(authDir, { recursive: true });
|
|
1463
|
-
|
|
1839
|
+
writeFileSync3(authFile, JSON.stringify(output, null, 2));
|
|
1464
1840
|
},
|
|
1465
1841
|
async startGateway(codeName, port) {
|
|
1466
1842
|
const agentAugDir = join2(AUGMENTED_DIR, codeName);
|
|
@@ -1497,7 +1873,7 @@ ${entry.content}`
|
|
|
1497
1873
|
}
|
|
1498
1874
|
}
|
|
1499
1875
|
}
|
|
1500
|
-
|
|
1876
|
+
writeFileSync3(pidPath, String(gatewayPid));
|
|
1501
1877
|
return { pid: gatewayPid, port };
|
|
1502
1878
|
},
|
|
1503
1879
|
async stopGateway(codeName) {
|
|
@@ -1506,7 +1882,7 @@ ${entry.content}`
|
|
|
1506
1882
|
return false;
|
|
1507
1883
|
if (!isProcessAlive(pid)) {
|
|
1508
1884
|
try {
|
|
1509
|
-
|
|
1885
|
+
unlinkSync3(getGatewayPidPath(codeName));
|
|
1510
1886
|
} catch {
|
|
1511
1887
|
}
|
|
1512
1888
|
return false;
|
|
@@ -1521,7 +1897,7 @@ ${entry.content}`
|
|
|
1521
1897
|
await new Promise((r) => setTimeout(r, 200));
|
|
1522
1898
|
if (!isProcessAlive(pid)) {
|
|
1523
1899
|
try {
|
|
1524
|
-
|
|
1900
|
+
unlinkSync3(getGatewayPidPath(codeName));
|
|
1525
1901
|
} catch {
|
|
1526
1902
|
}
|
|
1527
1903
|
return true;
|
|
@@ -1532,7 +1908,7 @@ ${entry.content}`
|
|
|
1532
1908
|
} catch {
|
|
1533
1909
|
}
|
|
1534
1910
|
try {
|
|
1535
|
-
|
|
1911
|
+
unlinkSync3(getGatewayPidPath(codeName));
|
|
1536
1912
|
} catch {
|
|
1537
1913
|
}
|
|
1538
1914
|
return true;
|
|
@@ -1549,7 +1925,7 @@ ${entry.content}`
|
|
|
1549
1925
|
if (portPid) {
|
|
1550
1926
|
try {
|
|
1551
1927
|
const pidPath = getGatewayPidPath(codeName);
|
|
1552
|
-
|
|
1928
|
+
writeFileSync3(pidPath, String(portPid));
|
|
1553
1929
|
} catch {
|
|
1554
1930
|
}
|
|
1555
1931
|
return { running: true, pid: portPid, port };
|
|
@@ -1557,7 +1933,7 @@ ${entry.content}`
|
|
|
1557
1933
|
}
|
|
1558
1934
|
if (pid) {
|
|
1559
1935
|
try {
|
|
1560
|
-
|
|
1936
|
+
unlinkSync3(getGatewayPidPath(codeName));
|
|
1561
1937
|
} catch {
|
|
1562
1938
|
}
|
|
1563
1939
|
}
|
|
@@ -1570,13 +1946,13 @@ ${entry.content}`
|
|
|
1570
1946
|
const profileConfigPath = join2(profileDir, "openclaw.json");
|
|
1571
1947
|
let sharedConfig;
|
|
1572
1948
|
try {
|
|
1573
|
-
sharedConfig = JSON.parse(
|
|
1949
|
+
sharedConfig = JSON.parse(readFileSync3(sharedConfigPath, "utf-8"));
|
|
1574
1950
|
} catch {
|
|
1575
1951
|
sharedConfig = {};
|
|
1576
1952
|
}
|
|
1577
|
-
if (
|
|
1953
|
+
if (existsSync3(profileConfigPath)) {
|
|
1578
1954
|
try {
|
|
1579
|
-
const existing = JSON.parse(
|
|
1955
|
+
const existing = JSON.parse(readFileSync3(profileConfigPath, "utf-8"));
|
|
1580
1956
|
let changed = false;
|
|
1581
1957
|
if (!existing["gateway"]) {
|
|
1582
1958
|
if (sharedConfig["gateway"]) {
|
|
@@ -1594,7 +1970,7 @@ ${entry.content}`
|
|
|
1594
1970
|
changed = true;
|
|
1595
1971
|
}
|
|
1596
1972
|
if (changed) {
|
|
1597
|
-
|
|
1973
|
+
writeFileSync3(profileConfigPath, JSON.stringify(existing, null, 2));
|
|
1598
1974
|
}
|
|
1599
1975
|
} catch {
|
|
1600
1976
|
}
|
|
@@ -1641,13 +2017,13 @@ ${entry.content}`
|
|
|
1641
2017
|
}
|
|
1642
2018
|
};
|
|
1643
2019
|
mkdirSync2(profileDir, { recursive: true });
|
|
1644
|
-
|
|
2020
|
+
writeFileSync3(profileConfigPath, JSON.stringify(profileConfig, null, 2));
|
|
1645
2021
|
const agentAuthDir = join2(profileDir, "agents", codeName, "agent");
|
|
1646
2022
|
const mainAgentDir = join2(profileDir, "agents", "main", "agent");
|
|
1647
2023
|
try {
|
|
1648
2024
|
mkdirSync2(agentAuthDir, { recursive: true });
|
|
1649
2025
|
mkdirSync2(join2(profileDir, "agents", "main"), { recursive: true });
|
|
1650
|
-
if (!
|
|
2026
|
+
if (!existsSync3(mainAgentDir)) {
|
|
1651
2027
|
symlinkSync(agentAuthDir, mainAgentDir, "dir");
|
|
1652
2028
|
}
|
|
1653
2029
|
} catch {
|
|
@@ -1661,7 +2037,7 @@ ${entry.content}`
|
|
|
1661
2037
|
const authFile = join2(authDir, "auth-profiles.json");
|
|
1662
2038
|
let existing = {};
|
|
1663
2039
|
try {
|
|
1664
|
-
existing = JSON.parse(
|
|
2040
|
+
existing = JSON.parse(readFileSync3(authFile, "utf-8"));
|
|
1665
2041
|
} catch {
|
|
1666
2042
|
}
|
|
1667
2043
|
const existingProfiles = existing["profiles"] ?? {};
|
|
@@ -1673,7 +2049,7 @@ ${entry.content}`
|
|
|
1673
2049
|
usageStats: existing["usageStats"] ?? {}
|
|
1674
2050
|
};
|
|
1675
2051
|
mkdirSync2(authDir, { recursive: true });
|
|
1676
|
-
|
|
2052
|
+
writeFileSync3(authFile, JSON.stringify(output, null, 2));
|
|
1677
2053
|
}
|
|
1678
2054
|
if (integrationConfig.toolAllow.length > 0) {
|
|
1679
2055
|
modifyOpenClawConfig((config) => {
|
|
@@ -1796,7 +2172,7 @@ ${entry.content}`
|
|
|
1796
2172
|
for (const file of files) {
|
|
1797
2173
|
const filePath = join2(skillDir, file.relativePath);
|
|
1798
2174
|
mkdirSync2(dirname2(filePath), { recursive: true });
|
|
1799
|
-
|
|
2175
|
+
writeFileSync3(filePath, file.content);
|
|
1800
2176
|
}
|
|
1801
2177
|
},
|
|
1802
2178
|
writeMcpServer(codeName, serverId, config) {
|
|
@@ -1892,7 +2268,7 @@ ${entry.content}`
|
|
|
1892
2268
|
readGatewayToken(codeName) {
|
|
1893
2269
|
const homeDir = getHomeDir();
|
|
1894
2270
|
try {
|
|
1895
|
-
const config = JSON.parse(
|
|
2271
|
+
const config = JSON.parse(readFileSync3(join2(homeDir, `.openclaw-${codeName}`, "openclaw.json"), "utf-8"));
|
|
1896
2272
|
return config?.gateway?.auth?.token;
|
|
1897
2273
|
} catch {
|
|
1898
2274
|
return void 0;
|
|
@@ -2033,7 +2409,7 @@ ${entry.content}`
|
|
|
2033
2409
|
registerFramework(openclawAdapter);
|
|
2034
2410
|
|
|
2035
2411
|
// ../../packages/core/dist/provisioning/frameworks/nemoclaw/index.js
|
|
2036
|
-
import { readFileSync as
|
|
2412
|
+
import { readFileSync as readFileSync4, writeFileSync as writeFileSync4, mkdirSync as mkdirSync3, existsSync as existsSync4, chmodSync as chmodSync4 } from "fs";
|
|
2037
2413
|
import { join as join3, dirname as dirname3, resolve as resolve2, sep } from "path";
|
|
2038
2414
|
import { homedir as homedir2 } from "os";
|
|
2039
2415
|
import { execFile as execFile2 } from "child_process";
|
|
@@ -2056,9 +2432,9 @@ function ensureDir(dir) {
|
|
|
2056
2432
|
}
|
|
2057
2433
|
function readDeploymentTarget(codeName) {
|
|
2058
2434
|
const targetFile = join3(getConfigDir(codeName), "target.json");
|
|
2059
|
-
if (!
|
|
2435
|
+
if (!existsSync4(targetFile))
|
|
2060
2436
|
return null;
|
|
2061
|
-
return JSON.parse(
|
|
2437
|
+
return JSON.parse(readFileSync4(targetFile, "utf-8"));
|
|
2062
2438
|
}
|
|
2063
2439
|
async function sshExec(target, command, options) {
|
|
2064
2440
|
const sshArgs = [
|
|
@@ -2096,7 +2472,7 @@ async function syncLocalAssetsToRemote(codeName) {
|
|
|
2096
2472
|
if (!target)
|
|
2097
2473
|
return;
|
|
2098
2474
|
const localAssetsDir = getConfigDir(codeName);
|
|
2099
|
-
if (!
|
|
2475
|
+
if (!existsSync4(localAssetsDir))
|
|
2100
2476
|
return;
|
|
2101
2477
|
const remoteDir = `/opt/augmented/${codeName}`;
|
|
2102
2478
|
const remoteAssetsDir = `${remoteDir}/assets`;
|
|
@@ -2200,7 +2576,7 @@ var nemoClawAdapter = {
|
|
|
2200
2576
|
await scpPush(target, blueprintPath, `${remoteDir}/blueprint.json`);
|
|
2201
2577
|
for (const file of ["CHARTER.md", "TOOLS.md"]) {
|
|
2202
2578
|
const localPath = join3(teamDir, file);
|
|
2203
|
-
if (
|
|
2579
|
+
if (existsSync4(localPath)) {
|
|
2204
2580
|
await scpPush(target, localPath, `${remoteDir}/${file}`);
|
|
2205
2581
|
}
|
|
2206
2582
|
}
|
|
@@ -2229,7 +2605,7 @@ var nemoClawAdapter = {
|
|
|
2229
2605
|
const configDir = getConfigDir(codeName);
|
|
2230
2606
|
ensureDir(configDir);
|
|
2231
2607
|
const authFile = join3(configDir, "auth-profiles.json");
|
|
2232
|
-
const existing =
|
|
2608
|
+
const existing = existsSync4(authFile) ? JSON.parse(readFileSync4(authFile, "utf-8")) : {};
|
|
2233
2609
|
for (const profile of profiles) {
|
|
2234
2610
|
const previous = existing[profile.profile_name];
|
|
2235
2611
|
existing[profile.profile_name] = {
|
|
@@ -2240,7 +2616,7 @@ var nemoClawAdapter = {
|
|
|
2240
2616
|
...profile.metadata
|
|
2241
2617
|
};
|
|
2242
2618
|
}
|
|
2243
|
-
|
|
2619
|
+
writeFileSync4(authFile, JSON.stringify(existing, null, 2), { mode: 384 });
|
|
2244
2620
|
syncLocalAssetsToRemote(codeName).catch(() => {
|
|
2245
2621
|
});
|
|
2246
2622
|
},
|
|
@@ -2262,7 +2638,7 @@ var nemoClawAdapter = {
|
|
|
2262
2638
|
}
|
|
2263
2639
|
const configDir = getConfigDir(codeName);
|
|
2264
2640
|
ensureDir(configDir);
|
|
2265
|
-
|
|
2641
|
+
writeFileSync4(join3(configDir, "gateway.json"), JSON.stringify({
|
|
2266
2642
|
pid: result.pid,
|
|
2267
2643
|
port: result.port,
|
|
2268
2644
|
host: target.host,
|
|
@@ -2299,7 +2675,7 @@ var nemoClawAdapter = {
|
|
|
2299
2675
|
readGatewayToken(codeName) {
|
|
2300
2676
|
try {
|
|
2301
2677
|
const gatewayFile = join3(getConfigDir(codeName), "gateway.json");
|
|
2302
|
-
const config = JSON.parse(
|
|
2678
|
+
const config = JSON.parse(readFileSync4(gatewayFile, "utf-8"));
|
|
2303
2679
|
return config?.token;
|
|
2304
2680
|
} catch {
|
|
2305
2681
|
return void 0;
|
|
@@ -2314,364 +2690,71 @@ var nemoClawAdapter = {
|
|
|
2314
2690
|
const creds = decryptIntegrationCredentials(integration.credentials);
|
|
2315
2691
|
const apiKey = creds.api_key ?? creds.access_token;
|
|
2316
2692
|
if (apiKey) {
|
|
2317
|
-
const envKey = `INTEGRATION_${integration.definition_id.toUpperCase().replace(/-/g, "_")}_KEY`;
|
|
2318
|
-
env[envKey] = apiKey;
|
|
2319
|
-
}
|
|
2320
|
-
}
|
|
2321
|
-
writeFileSync3(envFile, JSON.stringify(env, null, 2), { mode: 384 });
|
|
2322
|
-
syncLocalAssetsToRemote(codeName).catch(() => {
|
|
2323
|
-
});
|
|
2324
|
-
},
|
|
2325
|
-
installSkillFiles(codeName, skillId, files) {
|
|
2326
|
-
if (!/^[a-zA-Z0-9_-]+$/.test(skillId)) {
|
|
2327
|
-
throw new Error(`Invalid skill ID: ${skillId}`);
|
|
2328
|
-
}
|
|
2329
|
-
const skillDir = resolve2(getConfigDir(codeName), "skills", skillId);
|
|
2330
|
-
for (const file of files) {
|
|
2331
|
-
const filePath = resolve2(skillDir, file.relativePath);
|
|
2332
|
-
if (!filePath.startsWith(`${skillDir}${sep}`)) {
|
|
2333
|
-
throw new Error(`Invalid skill path: ${file.relativePath}`);
|
|
2334
|
-
}
|
|
2335
|
-
mkdirSync3(dirname3(filePath), { recursive: true });
|
|
2336
|
-
writeFileSync3(filePath, file.content);
|
|
2337
|
-
}
|
|
2338
|
-
syncLocalAssetsToRemote(codeName).catch(() => {
|
|
2339
|
-
});
|
|
2340
|
-
},
|
|
2341
|
-
writeMcpServer(codeName, serverId, config) {
|
|
2342
|
-
const configDir = getConfigDir(codeName);
|
|
2343
|
-
ensureDir(configDir);
|
|
2344
|
-
const mcpFile = join3(configDir, "mcp-servers.json");
|
|
2345
|
-
const existing = existsSync3(mcpFile) ? JSON.parse(readFileSync3(mcpFile, "utf-8")) : {};
|
|
2346
|
-
existing[serverId] = config;
|
|
2347
|
-
writeFileSync3(mcpFile, JSON.stringify(existing, null, 2), { mode: 384 });
|
|
2348
|
-
chmodSync3(mcpFile, 384);
|
|
2349
|
-
syncLocalAssetsToRemote(codeName).catch(() => {
|
|
2350
|
-
});
|
|
2351
|
-
},
|
|
2352
|
-
async syncScheduledTasks(codeName, tasks, gatewayPort) {
|
|
2353
|
-
const target = readDeploymentTarget(codeName);
|
|
2354
|
-
if (!target)
|
|
2355
|
-
return;
|
|
2356
|
-
const configDir = getConfigDir(codeName);
|
|
2357
|
-
ensureDir(configDir);
|
|
2358
|
-
const tasksFile = join3(configDir, "scheduled-tasks.json");
|
|
2359
|
-
writeFileSync3(tasksFile, JSON.stringify(tasks, null, 2));
|
|
2360
|
-
try {
|
|
2361
|
-
const remoteDir = `/opt/augmented/${codeName}`;
|
|
2362
|
-
await scpPush(target, tasksFile, `${remoteDir}/scheduled-tasks.json`);
|
|
2363
|
-
await sshExec(target, `nemoclaw cron sync ${codeName} --config ${remoteDir}/scheduled-tasks.json`);
|
|
2364
|
-
} catch {
|
|
2365
|
-
}
|
|
2366
|
-
}
|
|
2367
|
-
};
|
|
2368
|
-
function extractAllowedDomains(input) {
|
|
2369
|
-
const domains = /* @__PURE__ */ new Set();
|
|
2370
|
-
const controlPlaneHost = process.env["AGT_HOST"] ? new URL(process.env["AGT_HOST"]).hostname : "api.agt.localhost";
|
|
2371
|
-
domains.add(controlPlaneHost);
|
|
2372
|
-
for (const tool of input.toolsFrontmatter.tools) {
|
|
2373
|
-
if (tool.network?.allowlist_domains) {
|
|
2374
|
-
for (const domain of tool.network.allowlist_domains) {
|
|
2375
|
-
domains.add(domain);
|
|
2376
|
-
}
|
|
2377
|
-
}
|
|
2378
|
-
}
|
|
2379
|
-
return [...domains];
|
|
2380
|
-
}
|
|
2381
|
-
registerFramework(nemoClawAdapter);
|
|
2382
|
-
|
|
2383
|
-
// ../../packages/core/dist/provisioning/mcp-config-guards.js
|
|
2384
|
-
import { chmodSync as chmodSync4, existsSync as existsSync4, readFileSync as readFileSync4, renameSync as renameSync3, writeFileSync as writeFileSync4, unlinkSync as unlinkSync3 } from "fs";
|
|
2385
|
-
|
|
2386
|
-
// ../../packages/core/dist/provisioning/mcp-secret-lint.js
|
|
2387
|
-
var LITERAL_SECRET_PATTERNS = [
|
|
2388
|
-
// Slack bot token — `xoxb-<workspace>-<...>`
|
|
2389
|
-
{ name: "slack_bot_token", re: /^xoxb-/ },
|
|
2390
|
-
// Slack app-level token (Socket Mode) — `xapp-<...>`
|
|
2391
|
-
{ name: "slack_app_token", re: /^xapp-/ },
|
|
2392
|
-
// AGT host API key — `tlk_<...>` (see claudecode-plugin-augmented README).
|
|
2393
|
-
{ name: "agt_host_api_key", re: /^tlk_/ },
|
|
2394
|
-
// Composio / generic api-key prefix — `ak_<...>`
|
|
2395
|
-
{ name: "composio_api_key", re: /^ak_/ },
|
|
2396
|
-
// Telegram bot token — `<bot id>:AA<...>` (BotFather format). ENG-5901
|
|
2397
|
-
// PR 4: the original `\d{10}:AAE` (from the issue AC) was too narrow —
|
|
2398
|
-
// live tokens on agt-aws-1 carry `AA` + a varying third character
|
|
2399
|
-
// (don/scout/stirling all had AA-not-E tokens the lint and migration
|
|
2400
|
-
// missed). Bot ids are 8–12 digits; the token part always starts `AA`.
|
|
2401
|
-
{ name: "telegram_bot_token", re: /^\d{8,12}:AA[A-Za-z0-9_-]/ },
|
|
2402
|
-
// ENG-5901 extension beyond the original AC's five patterns: a literal
|
|
2403
|
-
// JWT (`eyJ...`) is the shape of a leaked AGT_API_KEY, which the
|
|
2404
|
-
// value-prefix patterns above would otherwise miss. Header values often
|
|
2405
|
-
// carry it behind `Bearer ` (or a copy-pasted `Authorization: Bearer `),
|
|
2406
|
-
// so those prefixes are optionally consumed (CodeRabbit #1731).
|
|
2407
|
-
// Templates (`Bearer ${AGT_API_KEY}`) and concrete non-secret values
|
|
2408
|
-
// (UUIDs, hosts) never put `eyJ` after the prefix, so this stays
|
|
2409
|
-
// false-positive-safe inside .mcp.json.
|
|
2410
|
-
{ name: "jwt_agt_api_key", re: /^(?:authorization:\s*)?(?:bearer\s+)?eyJ[A-Za-z0-9_-]+\./i }
|
|
2411
|
-
];
|
|
2412
|
-
function matchLiteralSecret(value) {
|
|
2413
|
-
for (const { name, re } of LITERAL_SECRET_PATTERNS) {
|
|
2414
|
-
if (re.test(value))
|
|
2415
|
-
return name;
|
|
2416
|
-
}
|
|
2417
|
-
return null;
|
|
2418
|
-
}
|
|
2419
|
-
function scanRecord(server, record, location, findings) {
|
|
2420
|
-
if (!record)
|
|
2421
|
-
return;
|
|
2422
|
-
for (const [field, value] of Object.entries(record)) {
|
|
2423
|
-
if (typeof value !== "string")
|
|
2424
|
-
continue;
|
|
2425
|
-
const pattern = matchLiteralSecret(value);
|
|
2426
|
-
if (pattern)
|
|
2427
|
-
findings.push({ server, field, location, pattern });
|
|
2428
|
-
}
|
|
2429
|
-
}
|
|
2430
|
-
function scanConfigForLiteralSecrets(config) {
|
|
2431
|
-
const findings = [];
|
|
2432
|
-
if (typeof config !== "object" || config === null)
|
|
2433
|
-
return findings;
|
|
2434
|
-
const servers = config.mcpServers;
|
|
2435
|
-
if (typeof servers !== "object" || servers === null)
|
|
2436
|
-
return findings;
|
|
2437
|
-
for (const [server, raw] of Object.entries(servers)) {
|
|
2438
|
-
if (typeof raw !== "object" || raw === null)
|
|
2439
|
-
continue;
|
|
2440
|
-
const entry = raw;
|
|
2441
|
-
scanRecord(server, entry.env, "env", findings);
|
|
2442
|
-
scanRecord(server, entry.headers, "header", findings);
|
|
2443
|
-
}
|
|
2444
|
-
return findings;
|
|
2445
|
-
}
|
|
2446
|
-
function formatLiteralSecretRejection(f) {
|
|
2447
|
-
return `[mcp-write] [literal-secret-rejected] field=${f.field} server=${f.server} location=${f.location} pattern=${f.pattern}`;
|
|
2448
|
-
}
|
|
2449
|
-
|
|
2450
|
-
// ../../packages/core/dist/provisioning/mcp-config-guards.js
|
|
2451
|
-
var MCP_FILE_MODE = 384;
|
|
2452
|
-
var lastRejectionFingerprintByPath = /* @__PURE__ */ new Map();
|
|
2453
|
-
var REQUIRED_ENV_RULES_BY_SERVER = {
|
|
2454
|
-
"cloud-broker": [
|
|
2455
|
-
{ key: "AGT_HOST", mustBeConcrete: false },
|
|
2456
|
-
{ key: "AGT_API_KEY", mustBeConcrete: false },
|
|
2457
|
-
// ENG-4744: this is the bug shape — writer used to omit this
|
|
2458
|
-
// entirely, or render it as a literal `${AGT_AGENT_ID}` instead
|
|
2459
|
-
// of the agent's real UUID. The broker has no way to substitute
|
|
2460
|
-
// it post-spawn, so a placeholder here = silently broken agent.
|
|
2461
|
-
{ key: "AGT_AGENT_ID", mustBeConcrete: true }
|
|
2462
|
-
]
|
|
2463
|
-
};
|
|
2464
|
-
var PLACEHOLDER_RE = /\$\{[^}]+\}/;
|
|
2465
|
-
function validateRenderedMcpConfig(config) {
|
|
2466
|
-
const errors = [];
|
|
2467
|
-
if (typeof config !== "object" || config === null || Array.isArray(config)) {
|
|
2468
|
-
return {
|
|
2469
|
-
ok: false,
|
|
2470
|
-
errors: [
|
|
2471
|
-
{
|
|
2472
|
-
kind: "invalid_json_shape",
|
|
2473
|
-
server: "*",
|
|
2474
|
-
message: "config root must be a non-null object"
|
|
2475
|
-
}
|
|
2476
|
-
]
|
|
2477
|
-
};
|
|
2478
|
-
}
|
|
2479
|
-
const root = config;
|
|
2480
|
-
if (root.mcpServers === void 0) {
|
|
2481
|
-
return { ok: true };
|
|
2482
|
-
}
|
|
2483
|
-
if (typeof root.mcpServers !== "object" || root.mcpServers === null) {
|
|
2484
|
-
return {
|
|
2485
|
-
ok: false,
|
|
2486
|
-
errors: [
|
|
2487
|
-
{
|
|
2488
|
-
kind: "invalid_json_shape",
|
|
2489
|
-
server: "*",
|
|
2490
|
-
message: "mcpServers must be an object"
|
|
2491
|
-
}
|
|
2492
|
-
]
|
|
2493
|
-
};
|
|
2494
|
-
}
|
|
2495
|
-
if (Array.isArray(root.mcpServers)) {
|
|
2496
|
-
return {
|
|
2497
|
-
ok: false,
|
|
2498
|
-
errors: [
|
|
2499
|
-
{
|
|
2500
|
-
kind: "invalid_json_shape",
|
|
2501
|
-
server: "*",
|
|
2502
|
-
message: "mcpServers must be an object"
|
|
2503
|
-
}
|
|
2504
|
-
]
|
|
2505
|
-
};
|
|
2506
|
-
}
|
|
2507
|
-
for (const [serverKey, raw] of Object.entries(root.mcpServers)) {
|
|
2508
|
-
if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
|
|
2509
|
-
errors.push({
|
|
2510
|
-
kind: "invalid_json_shape",
|
|
2511
|
-
server: serverKey,
|
|
2512
|
-
message: `entry must be an object`
|
|
2513
|
-
});
|
|
2514
|
-
continue;
|
|
2515
|
-
}
|
|
2516
|
-
const entry = raw;
|
|
2517
|
-
const entryRecord = entry;
|
|
2518
|
-
if (typeof entryRecord["url"] === "string") {
|
|
2519
|
-
const type = entryRecord["type"];
|
|
2520
|
-
if (type !== "http" && type !== "sse") {
|
|
2521
|
-
errors.push({
|
|
2522
|
-
kind: "remote_mcp_missing_type",
|
|
2523
|
-
server: serverKey,
|
|
2524
|
-
message: `url-based entry must include \`type: "http"\` or \`type: "sse"\` (Claude Code MCP schema requires it)`
|
|
2525
|
-
});
|
|
2526
|
-
}
|
|
2527
|
-
}
|
|
2528
|
-
const rules = REQUIRED_ENV_RULES_BY_SERVER[serverKey];
|
|
2529
|
-
if (rules) {
|
|
2530
|
-
const env = entry.env ?? {};
|
|
2531
|
-
for (const rule of rules) {
|
|
2532
|
-
const value = env[rule.key];
|
|
2533
|
-
if (typeof value !== "string" || value.length === 0) {
|
|
2534
|
-
errors.push({
|
|
2535
|
-
kind: "missing_required_env",
|
|
2536
|
-
server: serverKey,
|
|
2537
|
-
message: `missing required env key: ${rule.key}`
|
|
2538
|
-
});
|
|
2539
|
-
continue;
|
|
2540
|
-
}
|
|
2541
|
-
if (rule.mustBeConcrete && PLACEHOLDER_RE.test(value)) {
|
|
2542
|
-
errors.push({
|
|
2543
|
-
kind: "unexpanded_placeholder",
|
|
2544
|
-
server: serverKey,
|
|
2545
|
-
message: `env.${rule.key} contains an unexpanded \${...} placeholder; expected a concrete value`
|
|
2546
|
-
});
|
|
2547
|
-
}
|
|
2548
|
-
}
|
|
2549
|
-
}
|
|
2550
|
-
}
|
|
2551
|
-
return errors.length === 0 ? { ok: true } : { ok: false, errors };
|
|
2552
|
-
}
|
|
2553
|
-
function formatValidationErrors(errors) {
|
|
2554
|
-
return errors.map((e) => `${e.server}:${e.kind}=${e.message}`).join("; ");
|
|
2555
|
-
}
|
|
2556
|
-
function safeWriteJsonAtomic(path, content, opts = {}) {
|
|
2557
|
-
const keepBackup = opts.keepBackup !== false;
|
|
2558
|
-
const rename = opts.renamer ?? renameSync3;
|
|
2559
|
-
const tmpPath = `${path}.new`;
|
|
2560
|
-
const bakPath = `${path}.bak`;
|
|
2561
|
-
let movedOriginalToBackup = false;
|
|
2562
|
-
try {
|
|
2563
|
-
writeFileSync4(tmpPath, content);
|
|
2564
|
-
if (opts.mode !== void 0) {
|
|
2565
|
-
chmodSync4(tmpPath, opts.mode);
|
|
2566
|
-
}
|
|
2567
|
-
} catch (err) {
|
|
2568
|
-
try {
|
|
2569
|
-
if (existsSync4(tmpPath))
|
|
2570
|
-
unlinkSync3(tmpPath);
|
|
2571
|
-
} catch {
|
|
2572
|
-
}
|
|
2573
|
-
throw err;
|
|
2574
|
-
}
|
|
2575
|
-
try {
|
|
2576
|
-
if (keepBackup && existsSync4(path)) {
|
|
2577
|
-
rename(path, bakPath);
|
|
2578
|
-
movedOriginalToBackup = true;
|
|
2693
|
+
const envKey = `INTEGRATION_${integration.definition_id.toUpperCase().replace(/-/g, "_")}_KEY`;
|
|
2694
|
+
env[envKey] = apiKey;
|
|
2695
|
+
}
|
|
2579
2696
|
}
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2697
|
+
writeFileSync4(envFile, JSON.stringify(env, null, 2), { mode: 384 });
|
|
2698
|
+
syncLocalAssetsToRemote(codeName).catch(() => {
|
|
2699
|
+
});
|
|
2700
|
+
},
|
|
2701
|
+
installSkillFiles(codeName, skillId, files) {
|
|
2702
|
+
if (!/^[a-zA-Z0-9_-]+$/.test(skillId)) {
|
|
2703
|
+
throw new Error(`Invalid skill ID: ${skillId}`);
|
|
2586
2704
|
}
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
}
|
|
2705
|
+
const skillDir = resolve2(getConfigDir(codeName), "skills", skillId);
|
|
2706
|
+
for (const file of files) {
|
|
2707
|
+
const filePath = resolve2(skillDir, file.relativePath);
|
|
2708
|
+
if (!filePath.startsWith(`${skillDir}${sep}`)) {
|
|
2709
|
+
throw new Error(`Invalid skill path: ${file.relativePath}`);
|
|
2591
2710
|
}
|
|
2711
|
+
mkdirSync3(dirname3(filePath), { recursive: true });
|
|
2712
|
+
writeFileSync4(filePath, file.content);
|
|
2592
2713
|
}
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
}
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2714
|
+
syncLocalAssetsToRemote(codeName).catch(() => {
|
|
2715
|
+
});
|
|
2716
|
+
},
|
|
2717
|
+
writeMcpServer(codeName, serverId, config) {
|
|
2718
|
+
const configDir = getConfigDir(codeName);
|
|
2719
|
+
ensureDir(configDir);
|
|
2720
|
+
const mcpFile = join3(configDir, "mcp-servers.json");
|
|
2721
|
+
const existing = existsSync4(mcpFile) ? JSON.parse(readFileSync4(mcpFile, "utf-8")) : {};
|
|
2722
|
+
existing[serverId] = config;
|
|
2723
|
+
writeFileSync4(mcpFile, JSON.stringify(existing, null, 2), { mode: 384 });
|
|
2724
|
+
chmodSync4(mcpFile, 384);
|
|
2725
|
+
syncLocalAssetsToRemote(codeName).catch(() => {
|
|
2726
|
+
});
|
|
2727
|
+
},
|
|
2728
|
+
async syncScheduledTasks(codeName, tasks, gatewayPort) {
|
|
2729
|
+
const target = readDeploymentTarget(codeName);
|
|
2730
|
+
if (!target)
|
|
2731
|
+
return;
|
|
2732
|
+
const configDir = getConfigDir(codeName);
|
|
2733
|
+
ensureDir(configDir);
|
|
2734
|
+
const tasksFile = join3(configDir, "scheduled-tasks.json");
|
|
2735
|
+
writeFileSync4(tasksFile, JSON.stringify(tasks, null, 2));
|
|
2736
|
+
try {
|
|
2737
|
+
const remoteDir = `/opt/augmented/${codeName}`;
|
|
2738
|
+
await scpPush(target, tasksFile, `${remoteDir}/scheduled-tasks.json`);
|
|
2739
|
+
await sshExec(target, `nemoclaw cron sync ${codeName} --config ${remoteDir}/scheduled-tasks.json`);
|
|
2740
|
+
} catch {
|
|
2610
2741
|
}
|
|
2611
|
-
return {
|
|
2612
|
-
written: false,
|
|
2613
|
-
errors: secretFindings.map((f) => ({
|
|
2614
|
-
kind: "literal_secret",
|
|
2615
|
-
server: f.server,
|
|
2616
|
-
message: `literal secret in ${f.location} field '${f.field}' (pattern ${f.pattern}); expected a \${VAR} template`
|
|
2617
|
-
}))
|
|
2618
|
-
};
|
|
2619
2742
|
}
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
const servers = config.mcpServers;
|
|
2630
|
-
if (typeof servers !== "object" || servers === null)
|
|
2631
|
-
return out;
|
|
2632
|
-
for (const [server, raw] of Object.entries(servers)) {
|
|
2633
|
-
if (typeof raw !== "object" || raw === null)
|
|
2634
|
-
continue;
|
|
2635
|
-
const entry = raw;
|
|
2636
|
-
for (const [block, location] of [
|
|
2637
|
-
[entry.env, "env"],
|
|
2638
|
-
[entry.headers, "header"]
|
|
2639
|
-
]) {
|
|
2640
|
-
if (!block)
|
|
2641
|
-
continue;
|
|
2642
|
-
for (const [field, value] of Object.entries(block)) {
|
|
2643
|
-
if (typeof value !== "string")
|
|
2644
|
-
continue;
|
|
2645
|
-
if (!SECRET_FIELD_NAME_RE.test(field))
|
|
2646
|
-
continue;
|
|
2647
|
-
out.set(`${server}\0${field}`, { location, value });
|
|
2743
|
+
};
|
|
2744
|
+
function extractAllowedDomains(input) {
|
|
2745
|
+
const domains = /* @__PURE__ */ new Set();
|
|
2746
|
+
const controlPlaneHost = process.env["AGT_HOST"] ? new URL(process.env["AGT_HOST"]).hostname : "api.agt.localhost";
|
|
2747
|
+
domains.add(controlPlaneHost);
|
|
2748
|
+
for (const tool of input.toolsFrontmatter.tools) {
|
|
2749
|
+
if (tool.network?.allowlist_domains) {
|
|
2750
|
+
for (const domain of tool.network.allowlist_domains) {
|
|
2751
|
+
domains.add(domain);
|
|
2648
2752
|
}
|
|
2649
2753
|
}
|
|
2650
2754
|
}
|
|
2651
|
-
return
|
|
2652
|
-
}
|
|
2653
|
-
function mcpMirrorParityErrors(provision2, project) {
|
|
2654
|
-
const a = collectSecretFields(provision2);
|
|
2655
|
-
const b = collectSecretFields(project);
|
|
2656
|
-
const mismatches = [];
|
|
2657
|
-
const keys = /* @__PURE__ */ new Set([...a.keys(), ...b.keys()]);
|
|
2658
|
-
for (const key of keys) {
|
|
2659
|
-
const [server, field] = key.split("\0");
|
|
2660
|
-
const pv = a.get(key);
|
|
2661
|
-
const pj = b.get(key);
|
|
2662
|
-
if (pv && !pj) {
|
|
2663
|
-
mismatches.push({ server, field, location: pv.location, reason: "missing-in-project" });
|
|
2664
|
-
} else if (!pv && pj) {
|
|
2665
|
-
mismatches.push({ server, field, location: pj.location, reason: "missing-in-provision" });
|
|
2666
|
-
} else if (pv && pj && pv.value !== pj.value) {
|
|
2667
|
-
mismatches.push({ server, field, location: pv.location, reason: "value-diverges" });
|
|
2668
|
-
}
|
|
2669
|
-
}
|
|
2670
|
-
return mismatches;
|
|
2671
|
-
}
|
|
2672
|
-
function formatMirrorMismatch(m) {
|
|
2673
|
-
return `[mcp-mirror] [parity-violation] server=${m.server} field=${m.field} location=${m.location} reason=${m.reason}`;
|
|
2755
|
+
return [...domains];
|
|
2674
2756
|
}
|
|
2757
|
+
registerFramework(nemoClawAdapter);
|
|
2675
2758
|
|
|
2676
2759
|
// ../../packages/core/dist/provisioning/frameworks/claudecode/identity.js
|
|
2677
2760
|
function buildMemorySection(hasQmd) {
|
|
@@ -3787,70 +3870,6 @@ The marginal cost of completeness is near zero. Do the whole thing.
|
|
|
3787
3870
|
${frontmatter.environment === "prod" ? "- Production environment: exercise extra caution with all operations.\n" : ""}`;
|
|
3788
3871
|
}
|
|
3789
3872
|
|
|
3790
|
-
// ../../packages/core/dist/provisioning/env-integrations-file.js
|
|
3791
|
-
function shellQuote(value) {
|
|
3792
|
-
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
3793
|
-
}
|
|
3794
|
-
var CHANNEL_SECRET_ENV_KEYS = [
|
|
3795
|
-
"SLACK_BOT_TOKEN",
|
|
3796
|
-
"SLACK_APP_TOKEN",
|
|
3797
|
-
"TELEGRAM_BOT_TOKEN",
|
|
3798
|
-
"MSTEAMS_CLIENT_SECRET"
|
|
3799
|
-
];
|
|
3800
|
-
var MCP_SERVER_SECRET_ENV_KEYS = [
|
|
3801
|
-
"COMPOSIO_API_KEY",
|
|
3802
|
-
"PIPEDREAM_CLIENT_SECRET"
|
|
3803
|
-
];
|
|
3804
|
-
var PRESERVED_ENV_KEYS = [
|
|
3805
|
-
...CHANNEL_SECRET_ENV_KEYS,
|
|
3806
|
-
...MCP_SERVER_SECRET_ENV_KEYS
|
|
3807
|
-
];
|
|
3808
|
-
var HEADER = "# Augmented integrations \u2014 auto-generated, do not edit";
|
|
3809
|
-
function parseEnvFileEntries(content) {
|
|
3810
|
-
const out = /* @__PURE__ */ new Map();
|
|
3811
|
-
for (const line of content.split("\n")) {
|
|
3812
|
-
if (!line || line.startsWith("#") || !line.includes("="))
|
|
3813
|
-
continue;
|
|
3814
|
-
const eqIdx = line.indexOf("=");
|
|
3815
|
-
out.set(line.slice(0, eqIdx), line.slice(eqIdx + 1));
|
|
3816
|
-
}
|
|
3817
|
-
return out;
|
|
3818
|
-
}
|
|
3819
|
-
function renderEnvIntegrations(entries) {
|
|
3820
|
-
const lines = [HEADER];
|
|
3821
|
-
for (const [key, rendered] of entries)
|
|
3822
|
-
lines.push(`${key}=${rendered}`);
|
|
3823
|
-
return lines.join("\n") + "\n";
|
|
3824
|
-
}
|
|
3825
|
-
function mergeEnvIntegrationsContent(existing, args) {
|
|
3826
|
-
const current = existing === null ? /* @__PURE__ */ new Map() : parseEnvFileEntries(existing);
|
|
3827
|
-
let next;
|
|
3828
|
-
if (args.mode === "upsert") {
|
|
3829
|
-
next = new Map(current);
|
|
3830
|
-
for (const [key, raw] of Object.entries(args.updates)) {
|
|
3831
|
-
if (raw === null)
|
|
3832
|
-
next.delete(key);
|
|
3833
|
-
else
|
|
3834
|
-
next.set(key, shellQuote(raw));
|
|
3835
|
-
}
|
|
3836
|
-
} else {
|
|
3837
|
-
next = /* @__PURE__ */ new Map();
|
|
3838
|
-
for (const [key, raw] of Object.entries(args.updates)) {
|
|
3839
|
-
if (raw !== null)
|
|
3840
|
-
next.set(key, shellQuote(raw));
|
|
3841
|
-
}
|
|
3842
|
-
const preserve = args.preserveKeys ?? PRESERVED_ENV_KEYS;
|
|
3843
|
-
for (const key of preserve) {
|
|
3844
|
-
if (key in args.updates)
|
|
3845
|
-
continue;
|
|
3846
|
-
if (!next.has(key) && current.has(key)) {
|
|
3847
|
-
next.set(key, current.get(key));
|
|
3848
|
-
}
|
|
3849
|
-
}
|
|
3850
|
-
}
|
|
3851
|
-
return renderEnvIntegrations(next);
|
|
3852
|
-
}
|
|
3853
|
-
|
|
3854
3873
|
// ../../packages/core/dist/provisioning/frameworks/claudecode/index.js
|
|
3855
3874
|
import { readFileSync as readFileSync5, writeFileSync as writeFileSync5, mkdirSync as mkdirSync4, existsSync as existsSync5, chmodSync as chmodSync5, readdirSync, rmSync, copyFileSync } from "fs";
|
|
3856
3875
|
import { join as join4, relative, dirname as dirname4 } from "path";
|
|
@@ -5054,6 +5073,12 @@ function buildMcpJson(input) {
|
|
|
5054
5073
|
// dashboard links) in tool replies. Falls back to NEXT_PUBLIC_APP_URL
|
|
5055
5074
|
// / AGT_CONSOLE_URL — same chain consoleUrl uses for kanban links.
|
|
5056
5075
|
AGT_APP_URL: process.env["AGT_APP_URL"] ?? process.env["NEXT_PUBLIC_APP_URL"] ?? process.env["AGT_CONSOLE_URL"] ?? "",
|
|
5076
|
+
// ENG-6229: arms the in-session `request_restart` self-restart tool.
|
|
5077
|
+
// Read at provision time from the manager's env (like AGT_HOST above),
|
|
5078
|
+
// NOT a per-spawn `${...}` template — it's a host-level gate. Empty by
|
|
5079
|
+
// default ⇒ the tool isn't registered at all (ships dark). When an
|
|
5080
|
+
// operator sets it on the host, the next /host/refresh bakes it in.
|
|
5081
|
+
AGT_AGENT_SELF_RESTART_ENABLED: process.env["AGT_AGENT_SELF_RESTART_ENABLED"] ?? "",
|
|
5057
5082
|
// Include PATH/HOME so the MCP subprocess can resolve binaries
|
|
5058
5083
|
PATH: process.env["PATH"] ?? "",
|
|
5059
5084
|
HOME: process.env["HOME"] ?? ""
|
|
@@ -6785,22 +6810,6 @@ var ManagedAgentsAdapter = {
|
|
|
6785
6810
|
};
|
|
6786
6811
|
registerFramework(ManagedAgentsAdapter);
|
|
6787
6812
|
|
|
6788
|
-
// src/lib/globals.ts
|
|
6789
|
-
import chalk from "chalk";
|
|
6790
|
-
var _jsonMode = false;
|
|
6791
|
-
function setJsonMode(enabled) {
|
|
6792
|
-
_jsonMode = enabled;
|
|
6793
|
-
if (enabled) {
|
|
6794
|
-
chalk.level = 0;
|
|
6795
|
-
}
|
|
6796
|
-
}
|
|
6797
|
-
function isJsonMode() {
|
|
6798
|
-
return _jsonMode;
|
|
6799
|
-
}
|
|
6800
|
-
function jsonOutput(data) {
|
|
6801
|
-
console.log(JSON.stringify(data, null, 2));
|
|
6802
|
-
}
|
|
6803
|
-
|
|
6804
6813
|
// src/lib/config.ts
|
|
6805
6814
|
import { readFileSync as readFileSync6, writeFileSync as writeFileSync6, mkdirSync as mkdirSync5, existsSync as existsSync6 } from "fs";
|
|
6806
6815
|
import { join as join6 } from "path";
|
|
@@ -7052,23 +7061,20 @@ async function getHostId() {
|
|
|
7052
7061
|
return hostId;
|
|
7053
7062
|
}
|
|
7054
7063
|
|
|
7055
|
-
//
|
|
7056
|
-
import
|
|
7057
|
-
|
|
7058
|
-
|
|
7064
|
+
// src/lib/globals.ts
|
|
7065
|
+
import chalk from "chalk";
|
|
7066
|
+
var _jsonMode = false;
|
|
7067
|
+
function setJsonMode(enabled) {
|
|
7068
|
+
_jsonMode = enabled;
|
|
7069
|
+
if (enabled) {
|
|
7070
|
+
chalk.level = 0;
|
|
7071
|
+
}
|
|
7059
7072
|
}
|
|
7060
|
-
function
|
|
7061
|
-
|
|
7062
|
-
|
|
7063
|
-
|
|
7064
|
-
|
|
7065
|
-
const teamDir = `.augmented/${input.agent.code_name}`;
|
|
7066
|
-
return {
|
|
7067
|
-
teamDir,
|
|
7068
|
-
artifacts,
|
|
7069
|
-
charterHash,
|
|
7070
|
-
toolsHash
|
|
7071
|
-
};
|
|
7073
|
+
function isJsonMode() {
|
|
7074
|
+
return _jsonMode;
|
|
7075
|
+
}
|
|
7076
|
+
function jsonOutput(data) {
|
|
7077
|
+
console.log(JSON.stringify(data, null, 2));
|
|
7072
7078
|
}
|
|
7073
7079
|
|
|
7074
7080
|
// src/commands/manager.ts
|
|
@@ -7684,20 +7690,18 @@ async function managerUninstallSystemUnitCommand() {
|
|
|
7684
7690
|
}
|
|
7685
7691
|
|
|
7686
7692
|
export {
|
|
7687
|
-
|
|
7693
|
+
provision,
|
|
7688
7694
|
extractCommandNotFound,
|
|
7695
|
+
getIntegration,
|
|
7696
|
+
CHANNEL_SECRET_ENV_KEYS,
|
|
7689
7697
|
LITERAL_SECRET_PATTERNS,
|
|
7690
7698
|
safeWriteJsonAtomic,
|
|
7691
7699
|
INTEGRATIONS_SECTION_START,
|
|
7692
7700
|
INTEGRATIONS_SECTION_END,
|
|
7693
7701
|
estimateActiveTasksTokens,
|
|
7694
|
-
CHANNEL_SECRET_ENV_KEYS,
|
|
7695
7702
|
provisionStopHook,
|
|
7696
7703
|
provisionIsolationHook,
|
|
7697
7704
|
provisionOrientHook,
|
|
7698
|
-
setJsonMode,
|
|
7699
|
-
isJsonMode,
|
|
7700
|
-
jsonOutput,
|
|
7701
7705
|
getApiKey,
|
|
7702
7706
|
getActiveTeam,
|
|
7703
7707
|
setActiveTeam,
|
|
@@ -7708,14 +7712,16 @@ export {
|
|
|
7708
7712
|
ApiError,
|
|
7709
7713
|
api,
|
|
7710
7714
|
getHostId,
|
|
7715
|
+
getManagerPaths,
|
|
7716
|
+
startWatchdog,
|
|
7711
7717
|
success,
|
|
7712
7718
|
error,
|
|
7713
7719
|
warn,
|
|
7714
7720
|
info,
|
|
7715
7721
|
table,
|
|
7716
|
-
|
|
7717
|
-
|
|
7718
|
-
|
|
7722
|
+
setJsonMode,
|
|
7723
|
+
isJsonMode,
|
|
7724
|
+
jsonOutput,
|
|
7719
7725
|
managerStartCommand,
|
|
7720
7726
|
SUPERVISOR_RESTART_EXIT_CODE,
|
|
7721
7727
|
managerStopCommand,
|
|
@@ -7725,4 +7731,4 @@ export {
|
|
|
7725
7731
|
managerInstallSystemUnitCommand,
|
|
7726
7732
|
managerUninstallSystemUnitCommand
|
|
7727
7733
|
};
|
|
7728
|
-
//# sourceMappingURL=chunk-
|
|
7734
|
+
//# sourceMappingURL=chunk-4B6KOQQL.js.map
|