@integrity-labs/agt-cli 0.27.136 → 0.27.138
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-HDWKI7W3.js → chunk-PDDU4Z5V.js} +2045 -2028
- package/dist/chunk-PDDU4Z5V.js.map +1 -0
- package/dist/{chunk-75QM5THV.js → chunk-RT37WJXI.js} +17 -2
- package/dist/{chunk-75QM5THV.js.map → chunk-RT37WJXI.js.map} +1 -1
- package/dist/{chunk-4B6KOQQL.js → chunk-SCZVYC5P.js} +522 -522
- package/dist/chunk-SCZVYC5P.js.map +1 -0
- package/dist/{claude-pair-runtime-A5IITZ6J.js → claude-pair-runtime-CNTCM57R.js} +2 -2
- package/dist/lib/manager-worker.js +41 -14
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/mcp/slack-channel.js +146 -69
- package/dist/mcp/telegram-channel.js +178 -49
- package/dist/{persistent-session-5N5NFU27.js → persistent-session-WWEAEEL4.js} +3 -3
- package/dist/{responsiveness-probe-6L6WKHK5.js → responsiveness-probe-MCKI22FY.js} +3 -3
- package/package.json +1 -1
- package/dist/chunk-4B6KOQQL.js.map +0 -1
- package/dist/chunk-HDWKI7W3.js.map +0 -1
- /package/dist/{claude-pair-runtime-A5IITZ6J.js.map → claude-pair-runtime-CNTCM57R.js.map} +0 -0
- /package/dist/{persistent-session-5N5NFU27.js.map → persistent-session-WWEAEEL4.js.map} +0 -0
- /package/dist/{responsiveness-probe-6L6WKHK5.js.map → responsiveness-probe-MCKI22FY.js.map} +0 -0
|
@@ -9,65 +9,7 @@ import {
|
|
|
9
9
|
parseDeliveryTarget,
|
|
10
10
|
registerFramework,
|
|
11
11
|
wrapScheduledTaskPrompt
|
|
12
|
-
} from "./chunk-
|
|
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
|
-
}
|
|
12
|
+
} from "./chunk-PDDU4Z5V.js";
|
|
71
13
|
|
|
72
14
|
// ../../packages/core/dist/integrations/registry.js
|
|
73
15
|
var INTEGRATION_REGISTRY = [
|
|
@@ -479,370 +421,52 @@ function getIntegration(id) {
|
|
|
479
421
|
return integrationMap.get(id);
|
|
480
422
|
}
|
|
481
423
|
|
|
482
|
-
// ../../packages/core/dist/provisioning/env
|
|
483
|
-
function
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
}
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
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" });
|
|
424
|
+
// ../../packages/core/dist/provisioning/hook-env.js
|
|
425
|
+
function augmentedHookPath(currentPath) {
|
|
426
|
+
const extras = [
|
|
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(":");
|
|
446
|
+
}
|
|
447
|
+
function extractCommandNotFound(stderr) {
|
|
448
|
+
if (!stderr)
|
|
449
|
+
return null;
|
|
450
|
+
const SAFE_CMD = /^[A-Za-z][A-Za-z0-9._-]{0,63}$/;
|
|
451
|
+
for (const line of stderr.split(/\r?\n/)) {
|
|
452
|
+
const m = line.match(/^(?:bash|sh): (?:line \d+: )?([^:\s]+): command not found$/);
|
|
453
|
+
if (m?.[1]) {
|
|
454
|
+
const rawCmd = m[1].trim();
|
|
455
|
+
const cmd = rawCmd.split("/").pop() ?? rawCmd;
|
|
456
|
+
if (SAFE_CMD.test(cmd))
|
|
457
|
+
return cmd;
|
|
831
458
|
}
|
|
832
459
|
}
|
|
833
|
-
return
|
|
834
|
-
}
|
|
835
|
-
function formatMirrorMismatch(m) {
|
|
836
|
-
return `[mcp-mirror] [parity-violation] server=${m.server} field=${m.field} location=${m.location} reason=${m.reason}`;
|
|
460
|
+
return null;
|
|
837
461
|
}
|
|
838
462
|
|
|
839
463
|
// ../../packages/core/dist/provisioning/frameworks/openclaw/index.js
|
|
840
464
|
import { execFile, spawn } from "child_process";
|
|
841
|
-
import { readFileSync as
|
|
465
|
+
import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2, existsSync as existsSync2, unlinkSync as unlinkSync2, chmodSync as chmodSync2, renameSync as renameSync2, symlinkSync } from "fs";
|
|
842
466
|
import { join as join2, dirname as dirname2, resolve } from "path";
|
|
843
467
|
|
|
844
468
|
// ../../packages/core/dist/integrations/xurl-config.js
|
|
845
|
-
import { chmodSync
|
|
469
|
+
import { chmodSync, existsSync, mkdirSync, readFileSync, renameSync, unlinkSync, writeFileSync } from "fs";
|
|
846
470
|
import { homedir } from "os";
|
|
847
471
|
import { dirname, join } from "path";
|
|
848
472
|
import { parse as parseYaml, stringify as stringifyYaml } from "yaml";
|
|
@@ -970,10 +594,10 @@ function writeXurlStoreForIntegrations(integrations, filePath = getXurlStorePath
|
|
|
970
594
|
if (Object.keys(agtApps).length === 0)
|
|
971
595
|
return null;
|
|
972
596
|
let existing = null;
|
|
973
|
-
if (
|
|
597
|
+
if (existsSync(filePath)) {
|
|
974
598
|
let raw;
|
|
975
599
|
try {
|
|
976
|
-
raw =
|
|
600
|
+
raw = readFileSync(filePath, "utf-8");
|
|
977
601
|
} catch {
|
|
978
602
|
return null;
|
|
979
603
|
}
|
|
@@ -986,18 +610,18 @@ function writeXurlStoreForIntegrations(integrations, filePath = getXurlStorePath
|
|
|
986
610
|
const merged = mergeXurlStore(existing, agtApps);
|
|
987
611
|
mkdirSync(dirname(filePath), { recursive: true });
|
|
988
612
|
const tmpPath = `${filePath}.tmp-${process.pid}-${Date.now()}`;
|
|
989
|
-
|
|
613
|
+
writeFileSync(tmpPath, serializeXurlStore(merged), { mode: XURL_FILE_MODE });
|
|
990
614
|
try {
|
|
991
|
-
|
|
615
|
+
renameSync(tmpPath, filePath);
|
|
992
616
|
} catch (err) {
|
|
993
617
|
try {
|
|
994
|
-
|
|
618
|
+
unlinkSync(tmpPath);
|
|
995
619
|
} catch {
|
|
996
620
|
}
|
|
997
621
|
throw err;
|
|
998
622
|
}
|
|
999
623
|
try {
|
|
1000
|
-
|
|
624
|
+
chmodSync(filePath, XURL_FILE_MODE);
|
|
1001
625
|
} catch {
|
|
1002
626
|
}
|
|
1003
627
|
return filePath;
|
|
@@ -1420,9 +1044,9 @@ function writeIntegrationTokenFile(codeName, integrations) {
|
|
|
1420
1044
|
if (Object.keys(tokens).length === 0)
|
|
1421
1045
|
return;
|
|
1422
1046
|
mkdirSync2(dir, { recursive: true });
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1047
|
+
writeFileSync2(tmpFilePath, JSON.stringify(tokens, null, 2));
|
|
1048
|
+
chmodSync2(tmpFilePath, 384);
|
|
1049
|
+
renameSync2(tmpFilePath, tokenFilePath);
|
|
1426
1050
|
}
|
|
1427
1051
|
function getOpenClawConfigPath(profile) {
|
|
1428
1052
|
const homeDir = getHomeDir();
|
|
@@ -1436,7 +1060,7 @@ function modifyOpenClawConfig(fn, profile) {
|
|
|
1436
1060
|
let originalContent;
|
|
1437
1061
|
let config;
|
|
1438
1062
|
try {
|
|
1439
|
-
originalContent =
|
|
1063
|
+
originalContent = readFileSync2(configFile, "utf-8");
|
|
1440
1064
|
config = JSON.parse(originalContent);
|
|
1441
1065
|
} catch {
|
|
1442
1066
|
return;
|
|
@@ -1447,7 +1071,7 @@ function modifyOpenClawConfig(fn, profile) {
|
|
|
1447
1071
|
const newContent = JSON.stringify(config, null, 2);
|
|
1448
1072
|
if (newContent === originalContent)
|
|
1449
1073
|
return;
|
|
1450
|
-
|
|
1074
|
+
writeFileSync2(configFile, newContent);
|
|
1451
1075
|
}
|
|
1452
1076
|
var AUGMENTED_DIR = join2(getHomeDir(), ".augmented");
|
|
1453
1077
|
function getGatewayPidPath(codeName) {
|
|
@@ -1461,7 +1085,7 @@ function getGatewayPortsPath() {
|
|
|
1461
1085
|
}
|
|
1462
1086
|
function readGatewayPid(codeName) {
|
|
1463
1087
|
try {
|
|
1464
|
-
const raw =
|
|
1088
|
+
const raw = readFileSync2(getGatewayPidPath(codeName), "utf-8").trim();
|
|
1465
1089
|
const pid = parseInt(raw, 10);
|
|
1466
1090
|
return isNaN(pid) ? null : pid;
|
|
1467
1091
|
} catch {
|
|
@@ -1509,7 +1133,7 @@ function execPromise(cmd, args) {
|
|
|
1509
1133
|
}
|
|
1510
1134
|
function readGatewayPorts() {
|
|
1511
1135
|
try {
|
|
1512
|
-
return JSON.parse(
|
|
1136
|
+
return JSON.parse(readFileSync2(getGatewayPortsPath(), "utf-8"));
|
|
1513
1137
|
} catch {
|
|
1514
1138
|
return {};
|
|
1515
1139
|
}
|
|
@@ -1745,7 +1369,7 @@ ${entry.content}`
|
|
|
1745
1369
|
const configFile = getOpenClawConfigPath(codeName);
|
|
1746
1370
|
let raw;
|
|
1747
1371
|
try {
|
|
1748
|
-
raw =
|
|
1372
|
+
raw = readFileSync2(configFile, "utf-8");
|
|
1749
1373
|
} catch {
|
|
1750
1374
|
return false;
|
|
1751
1375
|
}
|
|
@@ -1814,7 +1438,7 @@ ${entry.content}`
|
|
|
1814
1438
|
const authFile = join2(authDir, "auth-profiles.json");
|
|
1815
1439
|
let existing = {};
|
|
1816
1440
|
try {
|
|
1817
|
-
existing = JSON.parse(
|
|
1441
|
+
existing = JSON.parse(readFileSync2(authFile, "utf-8"));
|
|
1818
1442
|
} catch {
|
|
1819
1443
|
}
|
|
1820
1444
|
const existingProfiles = existing["profiles"] ?? {};
|
|
@@ -1836,7 +1460,7 @@ ${entry.content}`
|
|
|
1836
1460
|
usageStats: existing["usageStats"] ?? {}
|
|
1837
1461
|
};
|
|
1838
1462
|
mkdirSync2(authDir, { recursive: true });
|
|
1839
|
-
|
|
1463
|
+
writeFileSync2(authFile, JSON.stringify(output, null, 2));
|
|
1840
1464
|
},
|
|
1841
1465
|
async startGateway(codeName, port) {
|
|
1842
1466
|
const agentAugDir = join2(AUGMENTED_DIR, codeName);
|
|
@@ -1873,7 +1497,7 @@ ${entry.content}`
|
|
|
1873
1497
|
}
|
|
1874
1498
|
}
|
|
1875
1499
|
}
|
|
1876
|
-
|
|
1500
|
+
writeFileSync2(pidPath, String(gatewayPid));
|
|
1877
1501
|
return { pid: gatewayPid, port };
|
|
1878
1502
|
},
|
|
1879
1503
|
async stopGateway(codeName) {
|
|
@@ -1882,7 +1506,7 @@ ${entry.content}`
|
|
|
1882
1506
|
return false;
|
|
1883
1507
|
if (!isProcessAlive(pid)) {
|
|
1884
1508
|
try {
|
|
1885
|
-
|
|
1509
|
+
unlinkSync2(getGatewayPidPath(codeName));
|
|
1886
1510
|
} catch {
|
|
1887
1511
|
}
|
|
1888
1512
|
return false;
|
|
@@ -1897,7 +1521,7 @@ ${entry.content}`
|
|
|
1897
1521
|
await new Promise((r) => setTimeout(r, 200));
|
|
1898
1522
|
if (!isProcessAlive(pid)) {
|
|
1899
1523
|
try {
|
|
1900
|
-
|
|
1524
|
+
unlinkSync2(getGatewayPidPath(codeName));
|
|
1901
1525
|
} catch {
|
|
1902
1526
|
}
|
|
1903
1527
|
return true;
|
|
@@ -1908,7 +1532,7 @@ ${entry.content}`
|
|
|
1908
1532
|
} catch {
|
|
1909
1533
|
}
|
|
1910
1534
|
try {
|
|
1911
|
-
|
|
1535
|
+
unlinkSync2(getGatewayPidPath(codeName));
|
|
1912
1536
|
} catch {
|
|
1913
1537
|
}
|
|
1914
1538
|
return true;
|
|
@@ -1925,7 +1549,7 @@ ${entry.content}`
|
|
|
1925
1549
|
if (portPid) {
|
|
1926
1550
|
try {
|
|
1927
1551
|
const pidPath = getGatewayPidPath(codeName);
|
|
1928
|
-
|
|
1552
|
+
writeFileSync2(pidPath, String(portPid));
|
|
1929
1553
|
} catch {
|
|
1930
1554
|
}
|
|
1931
1555
|
return { running: true, pid: portPid, port };
|
|
@@ -1933,7 +1557,7 @@ ${entry.content}`
|
|
|
1933
1557
|
}
|
|
1934
1558
|
if (pid) {
|
|
1935
1559
|
try {
|
|
1936
|
-
|
|
1560
|
+
unlinkSync2(getGatewayPidPath(codeName));
|
|
1937
1561
|
} catch {
|
|
1938
1562
|
}
|
|
1939
1563
|
}
|
|
@@ -1946,13 +1570,13 @@ ${entry.content}`
|
|
|
1946
1570
|
const profileConfigPath = join2(profileDir, "openclaw.json");
|
|
1947
1571
|
let sharedConfig;
|
|
1948
1572
|
try {
|
|
1949
|
-
sharedConfig = JSON.parse(
|
|
1573
|
+
sharedConfig = JSON.parse(readFileSync2(sharedConfigPath, "utf-8"));
|
|
1950
1574
|
} catch {
|
|
1951
1575
|
sharedConfig = {};
|
|
1952
1576
|
}
|
|
1953
|
-
if (
|
|
1577
|
+
if (existsSync2(profileConfigPath)) {
|
|
1954
1578
|
try {
|
|
1955
|
-
const existing = JSON.parse(
|
|
1579
|
+
const existing = JSON.parse(readFileSync2(profileConfigPath, "utf-8"));
|
|
1956
1580
|
let changed = false;
|
|
1957
1581
|
if (!existing["gateway"]) {
|
|
1958
1582
|
if (sharedConfig["gateway"]) {
|
|
@@ -1970,7 +1594,7 @@ ${entry.content}`
|
|
|
1970
1594
|
changed = true;
|
|
1971
1595
|
}
|
|
1972
1596
|
if (changed) {
|
|
1973
|
-
|
|
1597
|
+
writeFileSync2(profileConfigPath, JSON.stringify(existing, null, 2));
|
|
1974
1598
|
}
|
|
1975
1599
|
} catch {
|
|
1976
1600
|
}
|
|
@@ -2017,13 +1641,13 @@ ${entry.content}`
|
|
|
2017
1641
|
}
|
|
2018
1642
|
};
|
|
2019
1643
|
mkdirSync2(profileDir, { recursive: true });
|
|
2020
|
-
|
|
1644
|
+
writeFileSync2(profileConfigPath, JSON.stringify(profileConfig, null, 2));
|
|
2021
1645
|
const agentAuthDir = join2(profileDir, "agents", codeName, "agent");
|
|
2022
1646
|
const mainAgentDir = join2(profileDir, "agents", "main", "agent");
|
|
2023
1647
|
try {
|
|
2024
1648
|
mkdirSync2(agentAuthDir, { recursive: true });
|
|
2025
1649
|
mkdirSync2(join2(profileDir, "agents", "main"), { recursive: true });
|
|
2026
|
-
if (!
|
|
1650
|
+
if (!existsSync2(mainAgentDir)) {
|
|
2027
1651
|
symlinkSync(agentAuthDir, mainAgentDir, "dir");
|
|
2028
1652
|
}
|
|
2029
1653
|
} catch {
|
|
@@ -2037,7 +1661,7 @@ ${entry.content}`
|
|
|
2037
1661
|
const authFile = join2(authDir, "auth-profiles.json");
|
|
2038
1662
|
let existing = {};
|
|
2039
1663
|
try {
|
|
2040
|
-
existing = JSON.parse(
|
|
1664
|
+
existing = JSON.parse(readFileSync2(authFile, "utf-8"));
|
|
2041
1665
|
} catch {
|
|
2042
1666
|
}
|
|
2043
1667
|
const existingProfiles = existing["profiles"] ?? {};
|
|
@@ -2049,7 +1673,7 @@ ${entry.content}`
|
|
|
2049
1673
|
usageStats: existing["usageStats"] ?? {}
|
|
2050
1674
|
};
|
|
2051
1675
|
mkdirSync2(authDir, { recursive: true });
|
|
2052
|
-
|
|
1676
|
+
writeFileSync2(authFile, JSON.stringify(output, null, 2));
|
|
2053
1677
|
}
|
|
2054
1678
|
if (integrationConfig.toolAllow.length > 0) {
|
|
2055
1679
|
modifyOpenClawConfig((config) => {
|
|
@@ -2172,7 +1796,7 @@ ${entry.content}`
|
|
|
2172
1796
|
for (const file of files) {
|
|
2173
1797
|
const filePath = join2(skillDir, file.relativePath);
|
|
2174
1798
|
mkdirSync2(dirname2(filePath), { recursive: true });
|
|
2175
|
-
|
|
1799
|
+
writeFileSync2(filePath, file.content);
|
|
2176
1800
|
}
|
|
2177
1801
|
},
|
|
2178
1802
|
writeMcpServer(codeName, serverId, config) {
|
|
@@ -2268,7 +1892,7 @@ ${entry.content}`
|
|
|
2268
1892
|
readGatewayToken(codeName) {
|
|
2269
1893
|
const homeDir = getHomeDir();
|
|
2270
1894
|
try {
|
|
2271
|
-
const config = JSON.parse(
|
|
1895
|
+
const config = JSON.parse(readFileSync2(join2(homeDir, `.openclaw-${codeName}`, "openclaw.json"), "utf-8"));
|
|
2272
1896
|
return config?.gateway?.auth?.token;
|
|
2273
1897
|
} catch {
|
|
2274
1898
|
return void 0;
|
|
@@ -2409,7 +2033,7 @@ ${entry.content}`
|
|
|
2409
2033
|
registerFramework(openclawAdapter);
|
|
2410
2034
|
|
|
2411
2035
|
// ../../packages/core/dist/provisioning/frameworks/nemoclaw/index.js
|
|
2412
|
-
import { readFileSync as
|
|
2036
|
+
import { readFileSync as readFileSync3, writeFileSync as writeFileSync3, mkdirSync as mkdirSync3, existsSync as existsSync3, chmodSync as chmodSync3 } from "fs";
|
|
2413
2037
|
import { join as join3, dirname as dirname3, resolve as resolve2, sep } from "path";
|
|
2414
2038
|
import { homedir as homedir2 } from "os";
|
|
2415
2039
|
import { execFile as execFile2 } from "child_process";
|
|
@@ -2432,9 +2056,9 @@ function ensureDir(dir) {
|
|
|
2432
2056
|
}
|
|
2433
2057
|
function readDeploymentTarget(codeName) {
|
|
2434
2058
|
const targetFile = join3(getConfigDir(codeName), "target.json");
|
|
2435
|
-
if (!
|
|
2059
|
+
if (!existsSync3(targetFile))
|
|
2436
2060
|
return null;
|
|
2437
|
-
return JSON.parse(
|
|
2061
|
+
return JSON.parse(readFileSync3(targetFile, "utf-8"));
|
|
2438
2062
|
}
|
|
2439
2063
|
async function sshExec(target, command, options) {
|
|
2440
2064
|
const sshArgs = [
|
|
@@ -2472,7 +2096,7 @@ async function syncLocalAssetsToRemote(codeName) {
|
|
|
2472
2096
|
if (!target)
|
|
2473
2097
|
return;
|
|
2474
2098
|
const localAssetsDir = getConfigDir(codeName);
|
|
2475
|
-
if (!
|
|
2099
|
+
if (!existsSync3(localAssetsDir))
|
|
2476
2100
|
return;
|
|
2477
2101
|
const remoteDir = `/opt/augmented/${codeName}`;
|
|
2478
2102
|
const remoteAssetsDir = `${remoteDir}/assets`;
|
|
@@ -2576,7 +2200,7 @@ var nemoClawAdapter = {
|
|
|
2576
2200
|
await scpPush(target, blueprintPath, `${remoteDir}/blueprint.json`);
|
|
2577
2201
|
for (const file of ["CHARTER.md", "TOOLS.md"]) {
|
|
2578
2202
|
const localPath = join3(teamDir, file);
|
|
2579
|
-
if (
|
|
2203
|
+
if (existsSync3(localPath)) {
|
|
2580
2204
|
await scpPush(target, localPath, `${remoteDir}/${file}`);
|
|
2581
2205
|
}
|
|
2582
2206
|
}
|
|
@@ -2605,7 +2229,7 @@ var nemoClawAdapter = {
|
|
|
2605
2229
|
const configDir = getConfigDir(codeName);
|
|
2606
2230
|
ensureDir(configDir);
|
|
2607
2231
|
const authFile = join3(configDir, "auth-profiles.json");
|
|
2608
|
-
const existing =
|
|
2232
|
+
const existing = existsSync3(authFile) ? JSON.parse(readFileSync3(authFile, "utf-8")) : {};
|
|
2609
2233
|
for (const profile of profiles) {
|
|
2610
2234
|
const previous = existing[profile.profile_name];
|
|
2611
2235
|
existing[profile.profile_name] = {
|
|
@@ -2616,7 +2240,7 @@ var nemoClawAdapter = {
|
|
|
2616
2240
|
...profile.metadata
|
|
2617
2241
|
};
|
|
2618
2242
|
}
|
|
2619
|
-
|
|
2243
|
+
writeFileSync3(authFile, JSON.stringify(existing, null, 2), { mode: 384 });
|
|
2620
2244
|
syncLocalAssetsToRemote(codeName).catch(() => {
|
|
2621
2245
|
});
|
|
2622
2246
|
},
|
|
@@ -2638,7 +2262,7 @@ var nemoClawAdapter = {
|
|
|
2638
2262
|
}
|
|
2639
2263
|
const configDir = getConfigDir(codeName);
|
|
2640
2264
|
ensureDir(configDir);
|
|
2641
|
-
|
|
2265
|
+
writeFileSync3(join3(configDir, "gateway.json"), JSON.stringify({
|
|
2642
2266
|
pid: result.pid,
|
|
2643
2267
|
port: result.port,
|
|
2644
2268
|
host: target.host,
|
|
@@ -2675,7 +2299,7 @@ var nemoClawAdapter = {
|
|
|
2675
2299
|
readGatewayToken(codeName) {
|
|
2676
2300
|
try {
|
|
2677
2301
|
const gatewayFile = join3(getConfigDir(codeName), "gateway.json");
|
|
2678
|
-
const config = JSON.parse(
|
|
2302
|
+
const config = JSON.parse(readFileSync3(gatewayFile, "utf-8"));
|
|
2679
2303
|
return config?.token;
|
|
2680
2304
|
} catch {
|
|
2681
2305
|
return void 0;
|
|
@@ -2694,7 +2318,7 @@ var nemoClawAdapter = {
|
|
|
2694
2318
|
env[envKey] = apiKey;
|
|
2695
2319
|
}
|
|
2696
2320
|
}
|
|
2697
|
-
|
|
2321
|
+
writeFileSync3(envFile, JSON.stringify(env, null, 2), { mode: 384 });
|
|
2698
2322
|
syncLocalAssetsToRemote(codeName).catch(() => {
|
|
2699
2323
|
});
|
|
2700
2324
|
},
|
|
@@ -2702,59 +2326,352 @@ var nemoClawAdapter = {
|
|
|
2702
2326
|
if (!/^[a-zA-Z0-9_-]+$/.test(skillId)) {
|
|
2703
2327
|
throw new Error(`Invalid skill ID: ${skillId}`);
|
|
2704
2328
|
}
|
|
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}`);
|
|
2710
|
-
}
|
|
2711
|
-
mkdirSync3(dirname3(filePath), { recursive: true });
|
|
2712
|
-
|
|
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 {
|
|
2713
2572
|
}
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
|
|
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));
|
|
2573
|
+
throw err;
|
|
2574
|
+
}
|
|
2575
|
+
try {
|
|
2576
|
+
if (keepBackup && existsSync4(path)) {
|
|
2577
|
+
rename(path, bakPath);
|
|
2578
|
+
movedOriginalToBackup = true;
|
|
2579
|
+
}
|
|
2580
|
+
rename(tmpPath, path);
|
|
2581
|
+
} catch (err) {
|
|
2736
2582
|
try {
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
await sshExec(target, `nemoclaw cron sync ${codeName} --config ${remoteDir}/scheduled-tasks.json`);
|
|
2583
|
+
if (existsSync4(tmpPath))
|
|
2584
|
+
unlinkSync3(tmpPath);
|
|
2740
2585
|
} catch {
|
|
2741
2586
|
}
|
|
2587
|
+
if (movedOriginalToBackup && !existsSync4(path) && existsSync4(bakPath)) {
|
|
2588
|
+
try {
|
|
2589
|
+
renameSync3(bakPath, path);
|
|
2590
|
+
} catch {
|
|
2591
|
+
}
|
|
2592
|
+
}
|
|
2593
|
+
throw err;
|
|
2742
2594
|
}
|
|
2743
|
-
}
|
|
2744
|
-
function
|
|
2745
|
-
const
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
|
|
2595
|
+
}
|
|
2596
|
+
function safeWriteMcpJson(path, config) {
|
|
2597
|
+
const validation = validateRenderedMcpConfig(config);
|
|
2598
|
+
if (!validation.ok) {
|
|
2599
|
+
return { written: false, errors: validation.errors };
|
|
2600
|
+
}
|
|
2601
|
+
const secretFindings = scanConfigForLiteralSecrets(config);
|
|
2602
|
+
if (secretFindings.length > 0) {
|
|
2603
|
+
const fingerprint = secretFindings.map((f) => `${f.server}.${f.field}.${f.location}`).sort().join("|");
|
|
2604
|
+
if (lastRejectionFingerprintByPath.get(path) !== fingerprint) {
|
|
2605
|
+
lastRejectionFingerprintByPath.set(path, fingerprint);
|
|
2606
|
+
for (const f of secretFindings) {
|
|
2607
|
+
process.stderr.write(`${formatLiteralSecretRejection(f)}
|
|
2608
|
+
`);
|
|
2752
2609
|
}
|
|
2753
2610
|
}
|
|
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
|
+
};
|
|
2754
2619
|
}
|
|
2755
|
-
|
|
2620
|
+
lastRejectionFingerprintByPath.delete(path);
|
|
2621
|
+
safeWriteJsonAtomic(path, JSON.stringify(config, null, 2), { mode: MCP_FILE_MODE });
|
|
2622
|
+
return { written: true, errors: [] };
|
|
2623
|
+
}
|
|
2624
|
+
var SECRET_FIELD_NAME_RE = /TOKEN|KEY|SECRET|BEARER|PASSWORD/i;
|
|
2625
|
+
function collectSecretFields(config) {
|
|
2626
|
+
const out = /* @__PURE__ */ new Map();
|
|
2627
|
+
if (typeof config !== "object" || config === null)
|
|
2628
|
+
return out;
|
|
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 });
|
|
2648
|
+
}
|
|
2649
|
+
}
|
|
2650
|
+
}
|
|
2651
|
+
return out;
|
|
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}`;
|
|
2756
2674
|
}
|
|
2757
|
-
registerFramework(nemoClawAdapter);
|
|
2758
2675
|
|
|
2759
2676
|
// ../../packages/core/dist/provisioning/frameworks/claudecode/identity.js
|
|
2760
2677
|
function buildMemorySection(hasQmd) {
|
|
@@ -3870,6 +3787,70 @@ The marginal cost of completeness is near zero. Do the whole thing.
|
|
|
3870
3787
|
${frontmatter.environment === "prod" ? "- Production environment: exercise extra caution with all operations.\n" : ""}`;
|
|
3871
3788
|
}
|
|
3872
3789
|
|
|
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
|
+
|
|
3873
3854
|
// ../../packages/core/dist/provisioning/frameworks/claudecode/index.js
|
|
3874
3855
|
import { readFileSync as readFileSync5, writeFileSync as writeFileSync5, mkdirSync as mkdirSync4, existsSync as existsSync5, chmodSync as chmodSync5, readdirSync, rmSync, copyFileSync } from "fs";
|
|
3875
3856
|
import { join as join4, relative, dirname as dirname4 } from "path";
|
|
@@ -6810,6 +6791,22 @@ var ManagedAgentsAdapter = {
|
|
|
6810
6791
|
};
|
|
6811
6792
|
registerFramework(ManagedAgentsAdapter);
|
|
6812
6793
|
|
|
6794
|
+
// src/lib/globals.ts
|
|
6795
|
+
import chalk from "chalk";
|
|
6796
|
+
var _jsonMode = false;
|
|
6797
|
+
function setJsonMode(enabled) {
|
|
6798
|
+
_jsonMode = enabled;
|
|
6799
|
+
if (enabled) {
|
|
6800
|
+
chalk.level = 0;
|
|
6801
|
+
}
|
|
6802
|
+
}
|
|
6803
|
+
function isJsonMode() {
|
|
6804
|
+
return _jsonMode;
|
|
6805
|
+
}
|
|
6806
|
+
function jsonOutput(data) {
|
|
6807
|
+
console.log(JSON.stringify(data, null, 2));
|
|
6808
|
+
}
|
|
6809
|
+
|
|
6813
6810
|
// src/lib/config.ts
|
|
6814
6811
|
import { readFileSync as readFileSync6, writeFileSync as writeFileSync6, mkdirSync as mkdirSync5, existsSync as existsSync6 } from "fs";
|
|
6815
6812
|
import { join as join6 } from "path";
|
|
@@ -7061,20 +7058,23 @@ async function getHostId() {
|
|
|
7061
7058
|
return hostId;
|
|
7062
7059
|
}
|
|
7063
7060
|
|
|
7064
|
-
//
|
|
7065
|
-
import
|
|
7066
|
-
|
|
7067
|
-
|
|
7068
|
-
_jsonMode = enabled;
|
|
7069
|
-
if (enabled) {
|
|
7070
|
-
chalk.level = 0;
|
|
7071
|
-
}
|
|
7072
|
-
}
|
|
7073
|
-
function isJsonMode() {
|
|
7074
|
-
return _jsonMode;
|
|
7061
|
+
// ../../packages/core/dist/provisioning/provisioner.js
|
|
7062
|
+
import { createHash } from "crypto";
|
|
7063
|
+
function sha256(content) {
|
|
7064
|
+
return createHash("sha256").update(content, "utf8").digest("hex");
|
|
7075
7065
|
}
|
|
7076
|
-
function
|
|
7077
|
-
|
|
7066
|
+
function provision(input, frameworkId = "openclaw") {
|
|
7067
|
+
const adapter = getFramework(frameworkId);
|
|
7068
|
+
const artifacts = adapter.buildArtifacts(input);
|
|
7069
|
+
const charterHash = sha256(input.charterContent);
|
|
7070
|
+
const toolsHash = sha256(input.toolsContent);
|
|
7071
|
+
const teamDir = `.augmented/${input.agent.code_name}`;
|
|
7072
|
+
return {
|
|
7073
|
+
teamDir,
|
|
7074
|
+
artifacts,
|
|
7075
|
+
charterHash,
|
|
7076
|
+
toolsHash
|
|
7077
|
+
};
|
|
7078
7078
|
}
|
|
7079
7079
|
|
|
7080
7080
|
// src/commands/manager.ts
|
|
@@ -7690,18 +7690,20 @@ async function managerUninstallSystemUnitCommand() {
|
|
|
7690
7690
|
}
|
|
7691
7691
|
|
|
7692
7692
|
export {
|
|
7693
|
-
provision,
|
|
7694
|
-
extractCommandNotFound,
|
|
7695
7693
|
getIntegration,
|
|
7696
|
-
|
|
7694
|
+
extractCommandNotFound,
|
|
7697
7695
|
LITERAL_SECRET_PATTERNS,
|
|
7698
7696
|
safeWriteJsonAtomic,
|
|
7699
7697
|
INTEGRATIONS_SECTION_START,
|
|
7700
7698
|
INTEGRATIONS_SECTION_END,
|
|
7701
7699
|
estimateActiveTasksTokens,
|
|
7700
|
+
CHANNEL_SECRET_ENV_KEYS,
|
|
7702
7701
|
provisionStopHook,
|
|
7703
7702
|
provisionIsolationHook,
|
|
7704
7703
|
provisionOrientHook,
|
|
7704
|
+
setJsonMode,
|
|
7705
|
+
isJsonMode,
|
|
7706
|
+
jsonOutput,
|
|
7705
7707
|
getApiKey,
|
|
7706
7708
|
getActiveTeam,
|
|
7707
7709
|
setActiveTeam,
|
|
@@ -7712,16 +7714,14 @@ export {
|
|
|
7712
7714
|
ApiError,
|
|
7713
7715
|
api,
|
|
7714
7716
|
getHostId,
|
|
7715
|
-
getManagerPaths,
|
|
7716
|
-
startWatchdog,
|
|
7717
7717
|
success,
|
|
7718
7718
|
error,
|
|
7719
7719
|
warn,
|
|
7720
7720
|
info,
|
|
7721
7721
|
table,
|
|
7722
|
-
|
|
7723
|
-
|
|
7724
|
-
|
|
7722
|
+
provision,
|
|
7723
|
+
getManagerPaths,
|
|
7724
|
+
startWatchdog,
|
|
7725
7725
|
managerStartCommand,
|
|
7726
7726
|
SUPERVISOR_RESTART_EXIT_CODE,
|
|
7727
7727
|
managerStopCommand,
|
|
@@ -7731,4 +7731,4 @@ export {
|
|
|
7731
7731
|
managerInstallSystemUnitCommand,
|
|
7732
7732
|
managerUninstallSystemUnitCommand
|
|
7733
7733
|
};
|
|
7734
|
-
//# sourceMappingURL=chunk-
|
|
7734
|
+
//# sourceMappingURL=chunk-SCZVYC5P.js.map
|