@integrity-labs/agt-cli 0.28.658 → 0.28.660
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 +5 -5
- package/dist/{chunk-QIOFZ6EP.js → chunk-ESEOTR5J.js} +653 -403
- package/dist/chunk-ESEOTR5J.js.map +1 -0
- package/dist/{chunk-RASKCVAA.js → chunk-VR3VB3FR.js} +74 -1
- package/dist/chunk-VR3VB3FR.js.map +1 -0
- package/dist/{chunk-LAYT5BNW.js → chunk-Y63W2XP5.js} +2 -2
- package/dist/{claude-pair-runtime-TRRXWBEM.js → claude-pair-runtime-JMESZQPN.js} +2 -2
- package/dist/lib/manager-worker.js +13 -13
- package/dist/mcp/direct-chat-channel.js +63 -0
- package/dist/mcp/index.js +107 -0
- package/dist/mcp/origami.js +63 -0
- package/dist/mcp/slack-channel.js +63 -0
- package/dist/mcp/telegram-channel.js +63 -0
- package/dist/{persistent-session-PG7POJ3L.js → persistent-session-ADS4LIGF.js} +3 -3
- package/dist/{responsiveness-probe-HP6SYFOJ.js → responsiveness-probe-EII7QAGR.js} +3 -3
- package/dist/{session-auth-dead-RIAIWHHV.js → session-auth-dead-TY2WU55Z.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-QIOFZ6EP.js.map +0 -1
- package/dist/chunk-RASKCVAA.js.map +0 -1
- /package/dist/{chunk-LAYT5BNW.js.map → chunk-Y63W2XP5.js.map} +0 -0
- /package/dist/{claude-pair-runtime-TRRXWBEM.js.map → claude-pair-runtime-JMESZQPN.js.map} +0 -0
- /package/dist/{persistent-session-PG7POJ3L.js.map → persistent-session-ADS4LIGF.js.map} +0 -0
- /package/dist/{responsiveness-probe-HP6SYFOJ.js.map → responsiveness-probe-EII7QAGR.js.map} +0 -0
- /package/dist/{session-auth-dead-RIAIWHHV.js.map → session-auth-dead-TY2WU55Z.js.map} +0 -0
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
isolationMode,
|
|
9
9
|
log,
|
|
10
10
|
parseEnvIntegrations
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-Y63W2XP5.js";
|
|
12
12
|
import {
|
|
13
13
|
BIND_FAILURE_QUARANTINE_THRESHOLD,
|
|
14
14
|
INTEGRATIONS_SECTION_END,
|
|
@@ -55,7 +55,7 @@ import {
|
|
|
55
55
|
resolveConnectivityProbe,
|
|
56
56
|
worseConnectivityOutcome,
|
|
57
57
|
wrapScheduledTaskPrompt
|
|
58
|
-
} from "./chunk-
|
|
58
|
+
} from "./chunk-VR3VB3FR.js";
|
|
59
59
|
import {
|
|
60
60
|
parsePsRows
|
|
61
61
|
} from "./chunk-XWVM4KPK.js";
|
|
@@ -469,9 +469,9 @@ function mergeEnvIntegrationsContent(existing, args) {
|
|
|
469
469
|
}
|
|
470
470
|
|
|
471
471
|
// ../../packages/core/dist/provisioning/frameworks/claudecode/index.js
|
|
472
|
-
import { readFileSync as
|
|
473
|
-
import { join as
|
|
474
|
-
import { homedir as
|
|
472
|
+
import { readFileSync as readFileSync4, writeFileSync as writeFileSync4, mkdirSync as mkdirSync3, existsSync as existsSync4, chmodSync as chmodSync4, readdirSync, rmSync as rmSync2, copyFileSync, lstatSync, realpathSync, symlinkSync, readlinkSync, renameSync as renameSync4, opendirSync } from "fs";
|
|
473
|
+
import { join as join3, relative, dirname as dirname3 } from "path";
|
|
474
|
+
import { homedir as homedir3 } from "os";
|
|
475
475
|
import { execFile } from "child_process";
|
|
476
476
|
|
|
477
477
|
// ../../packages/core/dist/integrations/xurl-config.js
|
|
@@ -636,6 +636,255 @@ function writeXurlStoreForIntegrations(integrations, filePath = getXurlStorePath
|
|
|
636
636
|
return filePath;
|
|
637
637
|
}
|
|
638
638
|
|
|
639
|
+
// ../../packages/core/dist/integrations/framer-credentials.js
|
|
640
|
+
import { chmodSync as chmodSync3, existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync3, renameSync as renameSync3, rmSync, statSync, unlinkSync as unlinkSync3, writeFileSync as writeFileSync3 } from "fs";
|
|
641
|
+
import { homedir as homedir2 } from "os";
|
|
642
|
+
import { dirname as dirname2, join as join2 } from "path";
|
|
643
|
+
var FRAMER_PROJECTS_CONFIG_VERSION = 2;
|
|
644
|
+
var BARE_PROJECT_ID = /^[A-Za-z0-9]{20}$/u;
|
|
645
|
+
var SLUGGED_PROJECT_ID = /^.+--([A-Za-z0-9]+)/u;
|
|
646
|
+
function parseFramerProjectId(projectUrlOrId) {
|
|
647
|
+
const input = projectUrlOrId.trim();
|
|
648
|
+
if (!input)
|
|
649
|
+
return null;
|
|
650
|
+
if (BARE_PROJECT_ID.test(input))
|
|
651
|
+
return input;
|
|
652
|
+
try {
|
|
653
|
+
const segments = new URL(input, "https://framer.com").pathname.split("/").filter(Boolean);
|
|
654
|
+
const marker = segments.findIndex((s) => s.toLowerCase() === "projects");
|
|
655
|
+
if (marker < 0)
|
|
656
|
+
return null;
|
|
657
|
+
const raw = segments[marker + 1];
|
|
658
|
+
if (raw === void 0)
|
|
659
|
+
return null;
|
|
660
|
+
const decoded = decodeURIComponent(raw);
|
|
661
|
+
const candidate = decoded.match(SLUGGED_PROJECT_ID)?.[1] ?? decoded;
|
|
662
|
+
return BARE_PROJECT_ID.test(candidate) ? candidate : null;
|
|
663
|
+
} catch {
|
|
664
|
+
return null;
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
function parseExistingConfig(existing) {
|
|
668
|
+
if (!existing || !existing.trim())
|
|
669
|
+
return { kind: "empty" };
|
|
670
|
+
let parsed;
|
|
671
|
+
try {
|
|
672
|
+
parsed = JSON.parse(existing);
|
|
673
|
+
} catch {
|
|
674
|
+
return { kind: "empty" };
|
|
675
|
+
}
|
|
676
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
677
|
+
return { kind: "empty" };
|
|
678
|
+
}
|
|
679
|
+
const candidate = parsed;
|
|
680
|
+
if (candidate.version !== FRAMER_PROJECTS_CONFIG_VERSION) {
|
|
681
|
+
return { kind: "unsupported" };
|
|
682
|
+
}
|
|
683
|
+
const projects = candidate.projects;
|
|
684
|
+
if (typeof projects !== "object" || projects === null || Array.isArray(projects)) {
|
|
685
|
+
return { kind: "empty" };
|
|
686
|
+
}
|
|
687
|
+
return { kind: "ok", projects: { ...projects } };
|
|
688
|
+
}
|
|
689
|
+
function mergeFramerProjectsConfig(existing, inputs, options = {}) {
|
|
690
|
+
const parsed = parseExistingConfig(existing);
|
|
691
|
+
const written = [];
|
|
692
|
+
const skipped = [];
|
|
693
|
+
const removed = [];
|
|
694
|
+
if (parsed.kind === "unsupported") {
|
|
695
|
+
return { content: null, written, skipped: [...inputs], removed, unsupported: true };
|
|
696
|
+
}
|
|
697
|
+
const projects = parsed.kind === "ok" ? { ...parsed.projects } : {};
|
|
698
|
+
for (const input of inputs) {
|
|
699
|
+
const projectId = parseFramerProjectId(input.projectUrlOrId);
|
|
700
|
+
if (!projectId || !input.apiKey) {
|
|
701
|
+
skipped.push(input);
|
|
702
|
+
continue;
|
|
703
|
+
}
|
|
704
|
+
const previous = projects[projectId];
|
|
705
|
+
projects[projectId] = {
|
|
706
|
+
// Preserve vendor-managed bookkeeping (userId, lastUsedAt) the CLI wrote
|
|
707
|
+
// itself — dropping them would make every provisioning pass look to Framer
|
|
708
|
+
// like a brand new client.
|
|
709
|
+
...previous,
|
|
710
|
+
apiKey: input.apiKey,
|
|
711
|
+
...input.name ? { name: input.name } : {}
|
|
712
|
+
};
|
|
713
|
+
written.push(projectId);
|
|
714
|
+
}
|
|
715
|
+
const stillManaged = new Set(written);
|
|
716
|
+
for (const id of options.previouslyManagedIds ?? []) {
|
|
717
|
+
if (!stillManaged.has(id) && id in projects) {
|
|
718
|
+
delete projects[id];
|
|
719
|
+
removed.push(id);
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
if (written.length === 0 && removed.length === 0) {
|
|
723
|
+
return { content: null, written, skipped, removed, unsupported: false };
|
|
724
|
+
}
|
|
725
|
+
const config = {
|
|
726
|
+
version: FRAMER_PROJECTS_CONFIG_VERSION,
|
|
727
|
+
projects
|
|
728
|
+
};
|
|
729
|
+
return {
|
|
730
|
+
content: `${JSON.stringify(config, null, " ")}
|
|
731
|
+
`,
|
|
732
|
+
written,
|
|
733
|
+
skipped,
|
|
734
|
+
removed,
|
|
735
|
+
unsupported: false
|
|
736
|
+
};
|
|
737
|
+
}
|
|
738
|
+
var FRAMER_FILE_MODE = 384;
|
|
739
|
+
var MANAGED_SIDECAR_NAME = ".augmented-managed-projects.json";
|
|
740
|
+
function sidecarPathFor(projectsPath) {
|
|
741
|
+
return join2(dirname2(projectsPath), MANAGED_SIDECAR_NAME);
|
|
742
|
+
}
|
|
743
|
+
function readManagedIds(projectsPath) {
|
|
744
|
+
try {
|
|
745
|
+
const raw = readFileSync3(sidecarPathFor(projectsPath), "utf-8");
|
|
746
|
+
const parsed = JSON.parse(raw);
|
|
747
|
+
if (!Array.isArray(parsed))
|
|
748
|
+
return [];
|
|
749
|
+
return parsed.filter((v) => typeof v === "string");
|
|
750
|
+
} catch {
|
|
751
|
+
return [];
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
function writeManagedIds(projectsPath, ids) {
|
|
755
|
+
const target = sidecarPathFor(projectsPath);
|
|
756
|
+
try {
|
|
757
|
+
if (ids.length === 0) {
|
|
758
|
+
try {
|
|
759
|
+
unlinkSync3(target);
|
|
760
|
+
} catch {
|
|
761
|
+
}
|
|
762
|
+
return;
|
|
763
|
+
}
|
|
764
|
+
writeFileSync3(target, `${JSON.stringify([...ids].sort(), null, " ")}
|
|
765
|
+
`, {
|
|
766
|
+
mode: FRAMER_FILE_MODE
|
|
767
|
+
});
|
|
768
|
+
} catch {
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
var LOCK_STALE_MS = 3e4;
|
|
772
|
+
var LOCK_RETRY_WAIT_MS = 20;
|
|
773
|
+
var LOCK_MAX_ATTEMPTS = 50;
|
|
774
|
+
function withStoreLock(projectsPath, fn) {
|
|
775
|
+
const lockDir = `${projectsPath}.lock`;
|
|
776
|
+
try {
|
|
777
|
+
mkdirSync2(dirname2(projectsPath), { recursive: true, mode: 448 });
|
|
778
|
+
} catch {
|
|
779
|
+
}
|
|
780
|
+
let held = false;
|
|
781
|
+
for (let attempt = 0; attempt < LOCK_MAX_ATTEMPTS && !held; attempt++) {
|
|
782
|
+
try {
|
|
783
|
+
mkdirSync2(lockDir);
|
|
784
|
+
held = true;
|
|
785
|
+
} catch {
|
|
786
|
+
try {
|
|
787
|
+
if (Date.now() - statSync(lockDir).mtimeMs > LOCK_STALE_MS) {
|
|
788
|
+
rmSync(lockDir, { recursive: true, force: true });
|
|
789
|
+
continue;
|
|
790
|
+
}
|
|
791
|
+
} catch {
|
|
792
|
+
continue;
|
|
793
|
+
}
|
|
794
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, LOCK_RETRY_WAIT_MS);
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
if (!held) {
|
|
798
|
+
process.stderr.write(`[framer-credentials] [lock-unavailable] skipped this pass; another writer holds ${lockDir}
|
|
799
|
+
`);
|
|
800
|
+
return { acquired: false };
|
|
801
|
+
}
|
|
802
|
+
try {
|
|
803
|
+
return { acquired: true, value: fn() };
|
|
804
|
+
} finally {
|
|
805
|
+
try {
|
|
806
|
+
rmSync(lockDir, { recursive: true, force: true });
|
|
807
|
+
} catch {
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
function asString2(value) {
|
|
812
|
+
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
813
|
+
}
|
|
814
|
+
function getFramerProjectsPath() {
|
|
815
|
+
const xdg = process.env["XDG_CONFIG_HOME"];
|
|
816
|
+
if (xdg)
|
|
817
|
+
return join2(xdg, "framer", "projects.json");
|
|
818
|
+
const home = process.env["HOME"] ?? process.env["USERPROFILE"] ?? homedir2();
|
|
819
|
+
return join2(home, ".config", "framer", "projects.json");
|
|
820
|
+
}
|
|
821
|
+
function buildFramerCredentialInputs(integrations) {
|
|
822
|
+
const inputs = [];
|
|
823
|
+
for (const integration of integrations) {
|
|
824
|
+
if (integration.definition_id !== "framer")
|
|
825
|
+
continue;
|
|
826
|
+
if (integration.credentialDelivery === "broker")
|
|
827
|
+
continue;
|
|
828
|
+
const apiKey = asString2((integration.credentials ?? {})["api_key"]);
|
|
829
|
+
const cfg = integration.config ?? {};
|
|
830
|
+
const projectUrlOrId = asString2(cfg["project_url"]) ?? asString2(cfg["project_id"]);
|
|
831
|
+
if (!apiKey || !projectUrlOrId)
|
|
832
|
+
continue;
|
|
833
|
+
inputs.push({
|
|
834
|
+
projectUrlOrId,
|
|
835
|
+
apiKey,
|
|
836
|
+
...asString2(cfg["project_name"]) ? { name: asString2(cfg["project_name"]) } : {}
|
|
837
|
+
});
|
|
838
|
+
}
|
|
839
|
+
return inputs;
|
|
840
|
+
}
|
|
841
|
+
function writeFramerStoreForIntegrations(integrations, filePath = getFramerProjectsPath()) {
|
|
842
|
+
const inputs = buildFramerCredentialInputs(integrations);
|
|
843
|
+
const outcome = withStoreLock(filePath, () => {
|
|
844
|
+
const previouslyManagedIds = readManagedIds(filePath);
|
|
845
|
+
if (inputs.length === 0 && previouslyManagedIds.length === 0)
|
|
846
|
+
return null;
|
|
847
|
+
let existing = null;
|
|
848
|
+
if (existsSync3(filePath)) {
|
|
849
|
+
try {
|
|
850
|
+
existing = readFileSync3(filePath, "utf-8");
|
|
851
|
+
} catch {
|
|
852
|
+
return null;
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
const { content, written, removed, unsupported } = mergeFramerProjectsConfig(existing, inputs, { previouslyManagedIds });
|
|
856
|
+
if (unsupported) {
|
|
857
|
+
process.stderr.write("[framer-credentials] [unsupported-store-version] left projects.json untouched\n");
|
|
858
|
+
return null;
|
|
859
|
+
}
|
|
860
|
+
if (!content)
|
|
861
|
+
return null;
|
|
862
|
+
mkdirSync2(dirname2(filePath), { recursive: true, mode: 448 });
|
|
863
|
+
const tmpPath = `${filePath}.tmp-${process.pid}-${Date.now()}`;
|
|
864
|
+
writeFileSync3(tmpPath, content, { mode: FRAMER_FILE_MODE });
|
|
865
|
+
try {
|
|
866
|
+
renameSync3(tmpPath, filePath);
|
|
867
|
+
} catch (err) {
|
|
868
|
+
try {
|
|
869
|
+
unlinkSync3(tmpPath);
|
|
870
|
+
} catch {
|
|
871
|
+
}
|
|
872
|
+
throw err;
|
|
873
|
+
}
|
|
874
|
+
try {
|
|
875
|
+
chmodSync3(filePath, FRAMER_FILE_MODE);
|
|
876
|
+
} catch {
|
|
877
|
+
}
|
|
878
|
+
writeManagedIds(filePath, written);
|
|
879
|
+
if (removed.length > 0) {
|
|
880
|
+
process.stderr.write(`[framer-credentials] [revoked] removed ${removed.length} disconnected project credential(s)
|
|
881
|
+
`);
|
|
882
|
+
}
|
|
883
|
+
return filePath;
|
|
884
|
+
});
|
|
885
|
+
return outcome.acquired ? outcome.value : null;
|
|
886
|
+
}
|
|
887
|
+
|
|
639
888
|
// ../../packages/core/dist/crypto/envelope.js
|
|
640
889
|
import { createHash } from "crypto";
|
|
641
890
|
|
|
@@ -1325,27 +1574,27 @@ var VALID_CODE_NAME = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
|
1325
1574
|
var SECRET_FILE_MODE = 384;
|
|
1326
1575
|
function writeEnvIntegrationsForAgent(codeName, args) {
|
|
1327
1576
|
const agentDir = getAgentDir(codeName);
|
|
1328
|
-
const envPath =
|
|
1577
|
+
const envPath = join3(agentDir, ".env.integrations");
|
|
1329
1578
|
let existing = null;
|
|
1330
1579
|
try {
|
|
1331
|
-
existing =
|
|
1580
|
+
existing = readFileSync4(envPath, "utf-8");
|
|
1332
1581
|
} catch {
|
|
1333
1582
|
}
|
|
1334
1583
|
if (existing === null && Object.keys(args.updates).length === 0)
|
|
1335
1584
|
return;
|
|
1336
1585
|
const content = mergeEnvIntegrationsContent(existing, args);
|
|
1337
|
-
|
|
1586
|
+
writeFileSync4(envPath, content, { mode: SECRET_FILE_MODE });
|
|
1338
1587
|
try {
|
|
1339
|
-
|
|
1588
|
+
chmodSync4(envPath, SECRET_FILE_MODE);
|
|
1340
1589
|
} catch {
|
|
1341
1590
|
}
|
|
1342
1591
|
try {
|
|
1343
1592
|
const projectDir = getProjectDir(codeName);
|
|
1344
|
-
|
|
1345
|
-
const dest =
|
|
1346
|
-
|
|
1593
|
+
mkdirSync3(projectDir, { recursive: true });
|
|
1594
|
+
const dest = join3(projectDir, ".env.integrations");
|
|
1595
|
+
writeFileSync4(dest, content, { mode: SECRET_FILE_MODE });
|
|
1347
1596
|
try {
|
|
1348
|
-
|
|
1597
|
+
chmodSync4(dest, SECRET_FILE_MODE);
|
|
1349
1598
|
} catch {
|
|
1350
1599
|
}
|
|
1351
1600
|
} catch (err) {
|
|
@@ -1363,16 +1612,16 @@ var MIGRATABLE_FIELD_TO_ENV_VAR = {
|
|
|
1363
1612
|
AGT_API_KEY: "AGT_API_KEY"
|
|
1364
1613
|
};
|
|
1365
1614
|
function migrateExistingLiteralSecrets(codeName) {
|
|
1366
|
-
const mcpJsonPath =
|
|
1615
|
+
const mcpJsonPath = join3(getAgentDir(codeName), "provision", ".mcp.json");
|
|
1367
1616
|
let config;
|
|
1368
1617
|
try {
|
|
1369
|
-
config = JSON.parse(
|
|
1618
|
+
config = JSON.parse(readFileSync4(mcpJsonPath, "utf-8"));
|
|
1370
1619
|
} catch {
|
|
1371
1620
|
return;
|
|
1372
1621
|
}
|
|
1373
1622
|
let existingEnvKeys = /* @__PURE__ */ new Set();
|
|
1374
1623
|
try {
|
|
1375
|
-
existingEnvKeys = new Set(parseEnvFileEntries(
|
|
1624
|
+
existingEnvKeys = new Set(parseEnvFileEntries(readFileSync4(join3(getAgentDir(codeName), ".env.integrations"), "utf-8")).keys());
|
|
1376
1625
|
} catch {
|
|
1377
1626
|
}
|
|
1378
1627
|
const updates = {};
|
|
@@ -1449,7 +1698,7 @@ function assertSafeRelativePath(relativePath) {
|
|
|
1449
1698
|
}
|
|
1450
1699
|
}
|
|
1451
1700
|
function getHomeDir() {
|
|
1452
|
-
return process.env["HOME"] ?? process.env["USERPROFILE"] ??
|
|
1701
|
+
return process.env["HOME"] ?? process.env["USERPROFILE"] ?? homedir3();
|
|
1453
1702
|
}
|
|
1454
1703
|
var ID_KEYED_LAYOUT_ENABLED = false;
|
|
1455
1704
|
var VALID_AGENT_ID = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;
|
|
@@ -1471,8 +1720,8 @@ function ensureIdKeyedLayout(codeName, agentId) {
|
|
|
1471
1720
|
assertValidCodeName(codeName);
|
|
1472
1721
|
assertValidAgentId(agentId);
|
|
1473
1722
|
const home = getHomeDir();
|
|
1474
|
-
const codeNamePath =
|
|
1475
|
-
const idPath =
|
|
1723
|
+
const codeNamePath = join3(home, ".augmented", codeName);
|
|
1724
|
+
const idPath = join3(home, ".augmented", agentId);
|
|
1476
1725
|
let state;
|
|
1477
1726
|
try {
|
|
1478
1727
|
state = lstatSync(codeNamePath).isSymbolicLink() ? "symlink" : "realdir";
|
|
@@ -1487,20 +1736,20 @@ function ensureIdKeyedLayout(codeName, agentId) {
|
|
|
1487
1736
|
if (target !== agentId) {
|
|
1488
1737
|
throw new Error(`Codename symlink ${codeNamePath} points at "${target}", expected "${agentId}"; refusing to provision over a mismatched id-keyed layout.`);
|
|
1489
1738
|
}
|
|
1490
|
-
|
|
1739
|
+
mkdirSync3(idPath, { recursive: true });
|
|
1491
1740
|
return idPath;
|
|
1492
1741
|
}
|
|
1493
|
-
|
|
1742
|
+
mkdirSync3(idPath, { recursive: true });
|
|
1494
1743
|
symlinkSync(agentId, codeNamePath);
|
|
1495
1744
|
return idPath;
|
|
1496
1745
|
}
|
|
1497
1746
|
function stagedMigrationLinkPath(home, codeName) {
|
|
1498
|
-
return
|
|
1747
|
+
return join3(home, ".augmented", `.${codeName}.migrating`);
|
|
1499
1748
|
}
|
|
1500
1749
|
function cleanupStaleStagedLink(staged) {
|
|
1501
1750
|
try {
|
|
1502
1751
|
if (lstatSync(staged).isSymbolicLink())
|
|
1503
|
-
|
|
1752
|
+
rmSync2(staged, { force: true });
|
|
1504
1753
|
} catch {
|
|
1505
1754
|
}
|
|
1506
1755
|
}
|
|
@@ -1515,8 +1764,8 @@ function migrateAgentDirToIdKeyed(codeName, agentId, opts = {}) {
|
|
|
1515
1764
|
assertValidCodeName(codeName);
|
|
1516
1765
|
assertValidAgentId(agentId);
|
|
1517
1766
|
const home = opts.home ?? getHomeDir();
|
|
1518
|
-
const codeNamePath =
|
|
1519
|
-
const idPath =
|
|
1767
|
+
const codeNamePath = join3(home, ".augmented", codeName);
|
|
1768
|
+
const idPath = join3(home, ".augmented", agentId);
|
|
1520
1769
|
const staged = stagedMigrationLinkPath(home, codeName);
|
|
1521
1770
|
let codeNameKind;
|
|
1522
1771
|
try {
|
|
@@ -1524,7 +1773,7 @@ function migrateAgentDirToIdKeyed(codeName, agentId, opts = {}) {
|
|
|
1524
1773
|
} catch {
|
|
1525
1774
|
codeNameKind = "absent";
|
|
1526
1775
|
}
|
|
1527
|
-
const idExists =
|
|
1776
|
+
const idExists = existsSync4(idPath);
|
|
1528
1777
|
if (codeNameKind === "symlink") {
|
|
1529
1778
|
const target = readlinkSync(codeNamePath);
|
|
1530
1779
|
if (target !== agentId) {
|
|
@@ -1534,7 +1783,7 @@ function migrateAgentDirToIdKeyed(codeName, agentId, opts = {}) {
|
|
|
1534
1783
|
}
|
|
1535
1784
|
if (codeNameKind === "absent" && idExists) {
|
|
1536
1785
|
if (isSymlinkTo(staged, agentId)) {
|
|
1537
|
-
|
|
1786
|
+
renameSync4(staged, codeNamePath);
|
|
1538
1787
|
} else {
|
|
1539
1788
|
cleanupStaleStagedLink(staged);
|
|
1540
1789
|
symlinkSync(agentId, codeNamePath);
|
|
@@ -1548,21 +1797,21 @@ function migrateAgentDirToIdKeyed(codeName, agentId, opts = {}) {
|
|
|
1548
1797
|
}
|
|
1549
1798
|
cleanupStaleStagedLink(staged);
|
|
1550
1799
|
symlinkSync(agentId, staged);
|
|
1551
|
-
|
|
1552
|
-
|
|
1800
|
+
renameSync4(codeNamePath, idPath);
|
|
1801
|
+
renameSync4(staged, codeNamePath);
|
|
1553
1802
|
return "migrated";
|
|
1554
1803
|
}
|
|
1555
1804
|
function getAgentDir(codeName) {
|
|
1556
1805
|
assertValidCodeName(codeName);
|
|
1557
|
-
return resolveRealAgentPath(
|
|
1806
|
+
return resolveRealAgentPath(join3(getHomeDir(), ".augmented", codeName));
|
|
1558
1807
|
}
|
|
1559
1808
|
var migratedCodeNames = /* @__PURE__ */ new Set();
|
|
1560
1809
|
function migrateLegacyClaudecodeDir(codeName, log2) {
|
|
1561
1810
|
assertValidCodeName(codeName);
|
|
1562
1811
|
if (migratedCodeNames.has(codeName))
|
|
1563
1812
|
return;
|
|
1564
|
-
const legacyRoot =
|
|
1565
|
-
if (!
|
|
1813
|
+
const legacyRoot = join3(getHomeDir(), ".augmented", codeName, "claudecode");
|
|
1814
|
+
if (!existsSync4(legacyRoot)) {
|
|
1566
1815
|
migratedCodeNames.add(codeName);
|
|
1567
1816
|
return;
|
|
1568
1817
|
}
|
|
@@ -1572,33 +1821,33 @@ function migrateLegacyClaudecodeDir(codeName, log2) {
|
|
|
1572
1821
|
};
|
|
1573
1822
|
try {
|
|
1574
1823
|
const walkAndMigrate = (srcDir, destDir) => {
|
|
1575
|
-
|
|
1824
|
+
mkdirSync3(destDir, { recursive: true });
|
|
1576
1825
|
for (const entry of readdirSync(srcDir, { withFileTypes: true })) {
|
|
1577
|
-
const src =
|
|
1578
|
-
const dest =
|
|
1826
|
+
const src = join3(srcDir, entry.name);
|
|
1827
|
+
const dest = join3(destDir, entry.name);
|
|
1579
1828
|
if (entry.isDirectory()) {
|
|
1580
1829
|
walkAndMigrate(src, dest);
|
|
1581
1830
|
continue;
|
|
1582
1831
|
}
|
|
1583
|
-
if (entry.name === ".mcp.json" &&
|
|
1832
|
+
if (entry.name === ".mcp.json" && existsSync4(dest)) {
|
|
1584
1833
|
try {
|
|
1585
|
-
const oldCfg = JSON.parse(
|
|
1586
|
-
const newCfg = JSON.parse(
|
|
1834
|
+
const oldCfg = JSON.parse(readFileSync4(src, "utf-8"));
|
|
1835
|
+
const newCfg = JSON.parse(readFileSync4(dest, "utf-8"));
|
|
1587
1836
|
const merged = { mcpServers: { ...oldCfg.mcpServers ?? {}, ...newCfg.mcpServers ?? {} } };
|
|
1588
|
-
|
|
1837
|
+
writeFileSync4(dest, JSON.stringify(merged, null, 2));
|
|
1589
1838
|
emit(`[migrate] '${codeName}' merged .mcp.json (${Object.keys(merged.mcpServers).length} servers)`);
|
|
1590
1839
|
} catch (err) {
|
|
1591
1840
|
throw new Error(`Failed merging .mcp.json (${src} \u2192 ${dest}): ${err.message}`);
|
|
1592
1841
|
}
|
|
1593
1842
|
continue;
|
|
1594
1843
|
}
|
|
1595
|
-
if (!
|
|
1844
|
+
if (!existsSync4(dest)) {
|
|
1596
1845
|
copyFileSync(src, dest);
|
|
1597
1846
|
continue;
|
|
1598
1847
|
}
|
|
1599
1848
|
try {
|
|
1600
|
-
const srcStat =
|
|
1601
|
-
const destStat =
|
|
1849
|
+
const srcStat = readFileSync4(src);
|
|
1850
|
+
const destStat = readFileSync4(dest);
|
|
1602
1851
|
if (!srcStat.equals(destStat)) {
|
|
1603
1852
|
}
|
|
1604
1853
|
} catch (err) {
|
|
@@ -1607,7 +1856,7 @@ function migrateLegacyClaudecodeDir(codeName, log2) {
|
|
|
1607
1856
|
}
|
|
1608
1857
|
};
|
|
1609
1858
|
walkAndMigrate(legacyRoot, newRoot);
|
|
1610
|
-
|
|
1859
|
+
rmSync2(legacyRoot, { recursive: true, force: true });
|
|
1611
1860
|
emit(`[migrate] '${codeName}': collapsed ~/.augmented/${codeName}/claudecode/ into ~/.augmented/${codeName}/`);
|
|
1612
1861
|
migratedCodeNames.add(codeName);
|
|
1613
1862
|
} catch (err) {
|
|
@@ -1615,25 +1864,25 @@ function migrateLegacyClaudecodeDir(codeName, log2) {
|
|
|
1615
1864
|
}
|
|
1616
1865
|
}
|
|
1617
1866
|
function syncGitHubBrokerCredentialTooling(projectDir, enabled) {
|
|
1618
|
-
const binDir =
|
|
1867
|
+
const binDir = join3(projectDir, GITHUB_BROKER_BIN_DIR);
|
|
1619
1868
|
if (!enabled) {
|
|
1620
|
-
|
|
1869
|
+
rmSync2(binDir, { recursive: true, force: true });
|
|
1621
1870
|
return {};
|
|
1622
1871
|
}
|
|
1623
|
-
const helperPath =
|
|
1624
|
-
const shimPath =
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1872
|
+
const helperPath = join3(binDir, GIT_CREDENTIAL_HELPER_BASENAME);
|
|
1873
|
+
const shimPath = join3(binDir, GH_SHIM_BASENAME);
|
|
1874
|
+
mkdirSync3(binDir, { recursive: true });
|
|
1875
|
+
writeFileSync4(helperPath, renderGitCredentialHelper(), { mode: BROKER_SCRIPT_MODE });
|
|
1876
|
+
chmodSync4(helperPath, BROKER_SCRIPT_MODE);
|
|
1877
|
+
writeFileSync4(shimPath, renderGhShim(), { mode: BROKER_SCRIPT_MODE });
|
|
1878
|
+
chmodSync4(shimPath, BROKER_SCRIPT_MODE);
|
|
1630
1879
|
return buildGitCredentialEnv(helperPath);
|
|
1631
1880
|
}
|
|
1632
1881
|
function getProjectDir(codeName) {
|
|
1633
|
-
return
|
|
1882
|
+
return join3(getAgentDir(codeName), "project");
|
|
1634
1883
|
}
|
|
1635
1884
|
function getScratchDir(codeName) {
|
|
1636
|
-
return
|
|
1885
|
+
return join3(getAgentDir(codeName), "scratch");
|
|
1637
1886
|
}
|
|
1638
1887
|
function sweepScratchDir(codeName, now = Date.now()) {
|
|
1639
1888
|
const scratchDir = getScratchDir(codeName);
|
|
@@ -1646,11 +1895,11 @@ function sweepScratchDir(codeName, now = Date.now()) {
|
|
|
1646
1895
|
}
|
|
1647
1896
|
const cutoff = now - SCRATCH_RETENTION_DAYS * 24 * 60 * 60 * 1e3;
|
|
1648
1897
|
for (const entry of entries) {
|
|
1649
|
-
const full =
|
|
1898
|
+
const full = join3(scratchDir, entry);
|
|
1650
1899
|
try {
|
|
1651
1900
|
if (isFreshWithin(full, cutoff))
|
|
1652
1901
|
continue;
|
|
1653
|
-
|
|
1902
|
+
rmSync2(full, { recursive: true, force: true });
|
|
1654
1903
|
removed += 1;
|
|
1655
1904
|
} catch {
|
|
1656
1905
|
}
|
|
@@ -1686,7 +1935,7 @@ function isFreshWithin(path, cutoff) {
|
|
|
1686
1935
|
const child = dir.readSync();
|
|
1687
1936
|
if (child === null)
|
|
1688
1937
|
break;
|
|
1689
|
-
queue.push(
|
|
1938
|
+
queue.push(join3(current, child.name));
|
|
1690
1939
|
budget -= 1;
|
|
1691
1940
|
}
|
|
1692
1941
|
} catch {
|
|
@@ -1703,18 +1952,18 @@ function isFreshWithin(path, cutoff) {
|
|
|
1703
1952
|
function syncMcpToProject(codeName) {
|
|
1704
1953
|
const agentDir = getAgentDir(codeName);
|
|
1705
1954
|
const projectDir = getProjectDir(codeName);
|
|
1706
|
-
const provisionMcpPath =
|
|
1707
|
-
const projectMcpPath =
|
|
1955
|
+
const provisionMcpPath = join3(agentDir, "provision", ".mcp.json");
|
|
1956
|
+
const projectMcpPath = join3(projectDir, ".mcp.json");
|
|
1708
1957
|
try {
|
|
1709
|
-
const content =
|
|
1710
|
-
|
|
1711
|
-
|
|
1958
|
+
const content = readFileSync4(provisionMcpPath, "utf-8");
|
|
1959
|
+
mkdirSync3(projectDir, { recursive: true });
|
|
1960
|
+
writeFileSync4(projectMcpPath, content, { mode: MCP_FILE_MODE });
|
|
1712
1961
|
try {
|
|
1713
|
-
|
|
1962
|
+
chmodSync4(projectMcpPath, MCP_FILE_MODE);
|
|
1714
1963
|
} catch {
|
|
1715
1964
|
}
|
|
1716
1965
|
try {
|
|
1717
|
-
const mismatches = mcpMirrorParityErrors(JSON.parse(content), JSON.parse(
|
|
1966
|
+
const mismatches = mcpMirrorParityErrors(JSON.parse(content), JSON.parse(readFileSync4(projectMcpPath, "utf-8")));
|
|
1718
1967
|
for (const m of mismatches) {
|
|
1719
1968
|
process.stderr.write(`${formatMirrorMismatch(m)} agent=${codeName}
|
|
1720
1969
|
`);
|
|
@@ -1728,19 +1977,19 @@ function syncMcpToProject(codeName) {
|
|
|
1728
1977
|
}
|
|
1729
1978
|
var INTEGRATIONS_SUMMARY_FILE = "integrations-summary.json";
|
|
1730
1979
|
function integrationsSummaryPath(codeName) {
|
|
1731
|
-
return
|
|
1980
|
+
return join3(getAgentDir(codeName), "provision", INTEGRATIONS_SUMMARY_FILE);
|
|
1732
1981
|
}
|
|
1733
1982
|
function writeIntegrationsSummaryForAgent(codeName, summaries) {
|
|
1734
1983
|
const target = integrationsSummaryPath(codeName);
|
|
1735
1984
|
try {
|
|
1736
|
-
|
|
1737
|
-
|
|
1985
|
+
mkdirSync3(dirname3(target), { recursive: true });
|
|
1986
|
+
writeFileSync4(target, JSON.stringify(summaries, null, 2));
|
|
1738
1987
|
} catch {
|
|
1739
1988
|
}
|
|
1740
1989
|
}
|
|
1741
1990
|
function readIntegrationsSummaryForAgent(codeName) {
|
|
1742
1991
|
try {
|
|
1743
|
-
const raw =
|
|
1992
|
+
const raw = readFileSync4(integrationsSummaryPath(codeName), "utf-8");
|
|
1744
1993
|
const parsed = JSON.parse(raw);
|
|
1745
1994
|
return Array.isArray(parsed) ? parsed : [];
|
|
1746
1995
|
} catch {
|
|
@@ -1750,10 +1999,10 @@ function readIntegrationsSummaryForAgent(codeName) {
|
|
|
1750
1999
|
function renderChannelMessageHandlerForAgent(codeName) {
|
|
1751
2000
|
const agentDir = getAgentDir(codeName);
|
|
1752
2001
|
const projectDir = getProjectDir(codeName);
|
|
1753
|
-
const provisionMcpPath =
|
|
2002
|
+
const provisionMcpPath = join3(agentDir, "provision", ".mcp.json");
|
|
1754
2003
|
let mcpServerKeys;
|
|
1755
2004
|
try {
|
|
1756
|
-
const config = JSON.parse(
|
|
2005
|
+
const config = JSON.parse(readFileSync4(provisionMcpPath, "utf-8"));
|
|
1757
2006
|
mcpServerKeys = Object.keys(config.mcpServers ?? {});
|
|
1758
2007
|
} catch {
|
|
1759
2008
|
return;
|
|
@@ -1761,10 +2010,10 @@ function renderChannelMessageHandlerForAgent(codeName) {
|
|
|
1761
2010
|
const integrations = readIntegrationsSummaryForAgent(codeName);
|
|
1762
2011
|
const content = buildChannelMessageHandlerAgent({ mcpServerKeys, integrations });
|
|
1763
2012
|
for (const baseDir of [agentDir, projectDir]) {
|
|
1764
|
-
const target =
|
|
2013
|
+
const target = join3(baseDir, ".claude", "agents", "channel-message-handler.md");
|
|
1765
2014
|
try {
|
|
1766
|
-
|
|
1767
|
-
|
|
2015
|
+
mkdirSync3(dirname3(target), { recursive: true });
|
|
2016
|
+
writeFileSync4(target, content);
|
|
1768
2017
|
} catch {
|
|
1769
2018
|
}
|
|
1770
2019
|
}
|
|
@@ -1779,9 +2028,9 @@ function writeMcpJsonGuarded(codeName, path, config) {
|
|
|
1779
2028
|
return true;
|
|
1780
2029
|
}
|
|
1781
2030
|
function readExistingMcpEnvVar(codeName, serverId, envKey) {
|
|
1782
|
-
const mcpJsonPath =
|
|
2031
|
+
const mcpJsonPath = join3(getAgentDir(codeName), "provision", ".mcp.json");
|
|
1783
2032
|
try {
|
|
1784
|
-
const raw =
|
|
2033
|
+
const raw = readFileSync4(mcpJsonPath, "utf-8");
|
|
1785
2034
|
const config = JSON.parse(raw);
|
|
1786
2035
|
const server = config.mcpServers?.[serverId];
|
|
1787
2036
|
if (!server || typeof server !== "object")
|
|
@@ -1810,9 +2059,9 @@ function resolveBrokerAgentId(codeName, fallback) {
|
|
|
1810
2059
|
}
|
|
1811
2060
|
function deployArtifactsToProject(codeName, provisionDir) {
|
|
1812
2061
|
const projectDir = getProjectDir(codeName);
|
|
1813
|
-
|
|
2062
|
+
mkdirSync3(projectDir, { recursive: true });
|
|
1814
2063
|
try {
|
|
1815
|
-
|
|
2064
|
+
mkdirSync3(getScratchDir(codeName), { recursive: true });
|
|
1816
2065
|
sweepScratchDir(codeName);
|
|
1817
2066
|
} catch (err) {
|
|
1818
2067
|
process.stderr.write(`[scratch] [ensure-or-sweep-failed] agent=${codeName} error=${err.message}
|
|
@@ -1822,135 +2071,135 @@ function deployArtifactsToProject(codeName, provisionDir) {
|
|
|
1822
2071
|
const SKILLS_START = "<!-- AGT:SKILLS_INDEX_START -->";
|
|
1823
2072
|
const SKILLS_END = "<!-- AGT:SKILLS_INDEX_END -->";
|
|
1824
2073
|
for (const file of artifactFiles) {
|
|
1825
|
-
const src =
|
|
1826
|
-
const dest =
|
|
2074
|
+
const src = join3(provisionDir, file);
|
|
2075
|
+
const dest = join3(projectDir, file);
|
|
1827
2076
|
try {
|
|
1828
|
-
const srcContent =
|
|
1829
|
-
if (file === "CLAUDE.md" &&
|
|
1830
|
-
const destContent =
|
|
2077
|
+
const srcContent = readFileSync4(src, "utf-8");
|
|
2078
|
+
if (file === "CLAUDE.md" && existsSync4(dest)) {
|
|
2079
|
+
const destContent = readFileSync4(dest, "utf-8");
|
|
1831
2080
|
const stripIndex = (s) => s.replace(new RegExp(`${SKILLS_START}[\\s\\S]*?${SKILLS_END}`), "").trimEnd();
|
|
1832
2081
|
if (stripIndex(srcContent) === stripIndex(destContent))
|
|
1833
2082
|
continue;
|
|
1834
2083
|
const indexMatch = destContent.match(new RegExp(`${SKILLS_START}[\\s\\S]*?${SKILLS_END}`));
|
|
1835
2084
|
if (indexMatch) {
|
|
1836
|
-
|
|
2085
|
+
writeFileSync4(dest, srcContent.trimEnd() + "\n\n" + indexMatch[0] + "\n");
|
|
1837
2086
|
continue;
|
|
1838
2087
|
}
|
|
1839
2088
|
}
|
|
1840
2089
|
if (file === ".mcp.json") {
|
|
1841
|
-
|
|
2090
|
+
writeFileSync4(dest, srcContent, { mode: MCP_FILE_MODE });
|
|
1842
2091
|
try {
|
|
1843
|
-
|
|
2092
|
+
chmodSync4(dest, MCP_FILE_MODE);
|
|
1844
2093
|
} catch {
|
|
1845
2094
|
}
|
|
1846
2095
|
} else {
|
|
1847
|
-
|
|
2096
|
+
writeFileSync4(dest, srcContent);
|
|
1848
2097
|
}
|
|
1849
2098
|
} catch {
|
|
1850
2099
|
}
|
|
1851
2100
|
}
|
|
1852
|
-
const skillsDir =
|
|
1853
|
-
const destSkillsDir =
|
|
2101
|
+
const skillsDir = join3(provisionDir, ".claude", "skills");
|
|
2102
|
+
const destSkillsDir = join3(projectDir, ".claude", "skills");
|
|
1854
2103
|
try {
|
|
1855
|
-
if (
|
|
1856
|
-
const srcFolders =
|
|
2104
|
+
if (existsSync4(destSkillsDir)) {
|
|
2105
|
+
const srcFolders = existsSync4(skillsDir) ? new Set(readdirSync(skillsDir)) : /* @__PURE__ */ new Set();
|
|
1857
2106
|
for (const folder of readdirSync(destSkillsDir)) {
|
|
1858
2107
|
if (folder.startsWith("knowledge-") || folder === "core-knowledge" && !srcFolders.has(folder)) {
|
|
1859
2108
|
try {
|
|
1860
|
-
|
|
2109
|
+
rmSync2(join3(destSkillsDir, folder), { recursive: true });
|
|
1861
2110
|
} catch {
|
|
1862
2111
|
}
|
|
1863
2112
|
}
|
|
1864
2113
|
}
|
|
1865
2114
|
}
|
|
1866
|
-
if (
|
|
2115
|
+
if (existsSync4(skillsDir)) {
|
|
1867
2116
|
for (const skillFolder of readdirSync(skillsDir)) {
|
|
1868
|
-
const srcSkillFile =
|
|
1869
|
-
if (!
|
|
2117
|
+
const srcSkillFile = join3(skillsDir, skillFolder, "SKILL.md");
|
|
2118
|
+
if (!existsSync4(srcSkillFile))
|
|
1870
2119
|
continue;
|
|
1871
|
-
const destFolder =
|
|
1872
|
-
const destFile =
|
|
1873
|
-
const srcContent =
|
|
2120
|
+
const destFolder = join3(destSkillsDir, skillFolder);
|
|
2121
|
+
const destFile = join3(destFolder, "SKILL.md");
|
|
2122
|
+
const srcContent = readFileSync4(srcSkillFile, "utf-8");
|
|
1874
2123
|
try {
|
|
1875
|
-
if (
|
|
2124
|
+
if (existsSync4(destFile) && readFileSync4(destFile, "utf-8") === srcContent)
|
|
1876
2125
|
continue;
|
|
1877
2126
|
} catch {
|
|
1878
2127
|
}
|
|
1879
|
-
|
|
1880
|
-
|
|
2128
|
+
mkdirSync3(destFolder, { recursive: true });
|
|
2129
|
+
writeFileSync4(destFile, srcContent);
|
|
1881
2130
|
}
|
|
1882
2131
|
}
|
|
1883
2132
|
} catch {
|
|
1884
2133
|
}
|
|
1885
|
-
const agentsDir =
|
|
1886
|
-
const destAgentsDir =
|
|
2134
|
+
const agentsDir = join3(provisionDir, ".claude", "agents");
|
|
2135
|
+
const destAgentsDir = join3(projectDir, ".claude", "agents");
|
|
1887
2136
|
try {
|
|
1888
|
-
if (
|
|
2137
|
+
if (existsSync4(agentsDir)) {
|
|
1889
2138
|
const sourceAgentFiles = new Set(readdirSync(agentsDir).filter((f) => f.endsWith(".md")));
|
|
1890
|
-
if (
|
|
2139
|
+
if (existsSync4(destAgentsDir)) {
|
|
1891
2140
|
for (const destFile of readdirSync(destAgentsDir)) {
|
|
1892
2141
|
if (!destFile.endsWith(".md"))
|
|
1893
2142
|
continue;
|
|
1894
2143
|
if (sourceAgentFiles.has(destFile))
|
|
1895
2144
|
continue;
|
|
1896
2145
|
try {
|
|
1897
|
-
|
|
2146
|
+
rmSync2(join3(destAgentsDir, destFile));
|
|
1898
2147
|
} catch {
|
|
1899
2148
|
}
|
|
1900
2149
|
}
|
|
1901
2150
|
}
|
|
1902
2151
|
for (const agentFile of sourceAgentFiles) {
|
|
1903
|
-
const srcPath =
|
|
1904
|
-
const destPath =
|
|
1905
|
-
const srcContent =
|
|
2152
|
+
const srcPath = join3(agentsDir, agentFile);
|
|
2153
|
+
const destPath = join3(destAgentsDir, agentFile);
|
|
2154
|
+
const srcContent = readFileSync4(srcPath, "utf-8");
|
|
1906
2155
|
try {
|
|
1907
|
-
if (
|
|
2156
|
+
if (existsSync4(destPath) && readFileSync4(destPath, "utf-8") === srcContent)
|
|
1908
2157
|
continue;
|
|
1909
2158
|
} catch {
|
|
1910
2159
|
}
|
|
1911
|
-
|
|
1912
|
-
|
|
2160
|
+
mkdirSync3(destAgentsDir, { recursive: true });
|
|
2161
|
+
writeFileSync4(destPath, srcContent);
|
|
1913
2162
|
}
|
|
1914
2163
|
}
|
|
1915
2164
|
} catch {
|
|
1916
2165
|
}
|
|
1917
|
-
const workflowsDir =
|
|
1918
|
-
const destWorkflowsDir =
|
|
2166
|
+
const workflowsDir = join3(provisionDir, ".claude", "workflows");
|
|
2167
|
+
const destWorkflowsDir = join3(projectDir, ".claude", "workflows");
|
|
1919
2168
|
try {
|
|
1920
|
-
const sourceWorkflowFiles =
|
|
1921
|
-
if (
|
|
2169
|
+
const sourceWorkflowFiles = existsSync4(workflowsDir) ? new Set(readdirSync(workflowsDir).filter((f) => f.endsWith(".js"))) : /* @__PURE__ */ new Set();
|
|
2170
|
+
if (existsSync4(destWorkflowsDir)) {
|
|
1922
2171
|
for (const destFile of readdirSync(destWorkflowsDir)) {
|
|
1923
2172
|
if (!destFile.endsWith(".js"))
|
|
1924
2173
|
continue;
|
|
1925
2174
|
if (sourceWorkflowFiles.has(destFile))
|
|
1926
2175
|
continue;
|
|
1927
2176
|
try {
|
|
1928
|
-
|
|
2177
|
+
rmSync2(join3(destWorkflowsDir, destFile));
|
|
1929
2178
|
} catch {
|
|
1930
2179
|
}
|
|
1931
2180
|
}
|
|
1932
2181
|
}
|
|
1933
2182
|
for (const workflowFile of sourceWorkflowFiles) {
|
|
1934
|
-
const srcPath =
|
|
1935
|
-
const destPath =
|
|
1936
|
-
const srcContent =
|
|
2183
|
+
const srcPath = join3(workflowsDir, workflowFile);
|
|
2184
|
+
const destPath = join3(destWorkflowsDir, workflowFile);
|
|
2185
|
+
const srcContent = readFileSync4(srcPath, "utf-8");
|
|
1937
2186
|
try {
|
|
1938
|
-
if (
|
|
2187
|
+
if (existsSync4(destPath) && readFileSync4(destPath, "utf-8") === srcContent)
|
|
1939
2188
|
continue;
|
|
1940
2189
|
} catch {
|
|
1941
2190
|
}
|
|
1942
|
-
|
|
1943
|
-
|
|
2191
|
+
mkdirSync3(destWorkflowsDir, { recursive: true });
|
|
2192
|
+
writeFileSync4(destPath, srcContent);
|
|
1944
2193
|
}
|
|
1945
2194
|
} catch {
|
|
1946
2195
|
}
|
|
1947
|
-
const agentMcpPath =
|
|
1948
|
-
const projectMcpPath =
|
|
2196
|
+
const agentMcpPath = join3(getAgentDir(codeName), "provision", ".mcp.json");
|
|
2197
|
+
const projectMcpPath = join3(projectDir, ".mcp.json");
|
|
1949
2198
|
try {
|
|
1950
|
-
const agentMcp = JSON.parse(
|
|
2199
|
+
const agentMcp = JSON.parse(readFileSync4(agentMcpPath, "utf-8"));
|
|
1951
2200
|
let projectMcp;
|
|
1952
2201
|
try {
|
|
1953
|
-
projectMcp = JSON.parse(
|
|
2202
|
+
projectMcp = JSON.parse(readFileSync4(projectMcpPath, "utf-8"));
|
|
1954
2203
|
} catch {
|
|
1955
2204
|
projectMcp = { mcpServers: {} };
|
|
1956
2205
|
}
|
|
@@ -1961,9 +2210,9 @@ function deployArtifactsToProject(codeName, provisionDir) {
|
|
|
1961
2210
|
return !(entry && typeof entry["url"] === "string" && entry["url"].startsWith("/"));
|
|
1962
2211
|
}));
|
|
1963
2212
|
projectMcp["mcpServers"] = { ...stripRelativeUrls(projectServers), ...stripRelativeUrls(agentServers) };
|
|
1964
|
-
|
|
2213
|
+
writeFileSync4(projectMcpPath, JSON.stringify(projectMcp, null, 2), { mode: MCP_FILE_MODE });
|
|
1965
2214
|
try {
|
|
1966
|
-
|
|
2215
|
+
chmodSync4(projectMcpPath, MCP_FILE_MODE);
|
|
1967
2216
|
} catch {
|
|
1968
2217
|
}
|
|
1969
2218
|
} catch {
|
|
@@ -1971,37 +2220,37 @@ function deployArtifactsToProject(codeName, provisionDir) {
|
|
|
1971
2220
|
const agentDir = getAgentDir(codeName);
|
|
1972
2221
|
for (const envFile of [".env", ".env.integrations"]) {
|
|
1973
2222
|
try {
|
|
1974
|
-
const content =
|
|
1975
|
-
const envDest =
|
|
1976
|
-
|
|
2223
|
+
const content = readFileSync4(join3(agentDir, envFile), "utf-8");
|
|
2224
|
+
const envDest = join3(projectDir, envFile);
|
|
2225
|
+
writeFileSync4(envDest, content, { mode: SECRET_FILE_MODE });
|
|
1977
2226
|
try {
|
|
1978
|
-
|
|
2227
|
+
chmodSync4(envDest, SECRET_FILE_MODE);
|
|
1979
2228
|
} catch {
|
|
1980
2229
|
}
|
|
1981
2230
|
} catch {
|
|
1982
2231
|
}
|
|
1983
2232
|
}
|
|
1984
2233
|
try {
|
|
1985
|
-
const gitDir =
|
|
1986
|
-
const hookSrc =
|
|
1987
|
-
if (
|
|
1988
|
-
const hooksDir =
|
|
1989
|
-
|
|
1990
|
-
const hookDest =
|
|
1991
|
-
const srcContent =
|
|
1992
|
-
const upToDate =
|
|
2234
|
+
const gitDir = join3(projectDir, ".git");
|
|
2235
|
+
const hookSrc = join3(provisionDir, ".git-hooks", "pre-commit");
|
|
2236
|
+
if (existsSync4(gitDir) && existsSync4(hookSrc)) {
|
|
2237
|
+
const hooksDir = join3(gitDir, "hooks");
|
|
2238
|
+
mkdirSync3(hooksDir, { recursive: true });
|
|
2239
|
+
const hookDest = join3(hooksDir, "pre-commit");
|
|
2240
|
+
const srcContent = readFileSync4(hookSrc, "utf-8");
|
|
2241
|
+
const upToDate = existsSync4(hookDest) && readFileSync4(hookDest, "utf-8") === srcContent;
|
|
1993
2242
|
if (!upToDate)
|
|
1994
|
-
|
|
1995
|
-
|
|
2243
|
+
writeFileSync4(hookDest, srcContent);
|
|
2244
|
+
chmodSync4(hookDest, 493);
|
|
1996
2245
|
}
|
|
1997
2246
|
} catch {
|
|
1998
2247
|
}
|
|
1999
2248
|
}
|
|
2000
2249
|
function provisionStopHook(codeName) {
|
|
2001
2250
|
const projectDir = getProjectDir(codeName);
|
|
2002
|
-
const claudeDir =
|
|
2003
|
-
|
|
2004
|
-
const hookScriptPath =
|
|
2251
|
+
const claudeDir = join3(projectDir, ".claude");
|
|
2252
|
+
mkdirSync3(claudeDir, { recursive: true });
|
|
2253
|
+
const hookScriptPath = join3(claudeDir, "agt-stop-hook.sh");
|
|
2005
2254
|
const hookScript = [
|
|
2006
2255
|
"#!/bin/bash",
|
|
2007
2256
|
"# Auto-generated by Augmented \u2014 captures persistent session task results.",
|
|
@@ -2032,8 +2281,8 @@ function provisionStopHook(codeName) {
|
|
|
2032
2281
|
"esac",
|
|
2033
2282
|
"exit 0"
|
|
2034
2283
|
].join("\n") + "\n";
|
|
2035
|
-
|
|
2036
|
-
const ghostHookPath =
|
|
2284
|
+
writeFileSync4(hookScriptPath, hookScript, { mode: 493 });
|
|
2285
|
+
const ghostHookPath = join3(claudeDir, "agt-ghost-reply-hook.sh");
|
|
2037
2286
|
const jqNormalizeContent = '(.message.content // .content // []) | if type == "string" then [{type: "text", text: .}] elif type == "array" then . else [] end';
|
|
2038
2287
|
const ghostHookScript = [
|
|
2039
2288
|
"#!/bin/bash",
|
|
@@ -2905,12 +3154,12 @@ function provisionStopHook(codeName) {
|
|
|
2905
3154
|
"fi",
|
|
2906
3155
|
"exit 0"
|
|
2907
3156
|
].join("\n") + "\n";
|
|
2908
|
-
|
|
3157
|
+
writeFileSync4(ghostHookPath, ghostHookScript, { mode: 493 });
|
|
2909
3158
|
const backlogHookPath = provisionBacklogPullHook(codeName);
|
|
2910
|
-
const settingsPath =
|
|
3159
|
+
const settingsPath = join3(claudeDir, "settings.local.json");
|
|
2911
3160
|
let settings = {};
|
|
2912
3161
|
try {
|
|
2913
|
-
settings = JSON.parse(
|
|
3162
|
+
settings = JSON.parse(readFileSync4(settingsPath, "utf-8"));
|
|
2914
3163
|
} catch {
|
|
2915
3164
|
}
|
|
2916
3165
|
const hooks = settings["hooks"] ?? {};
|
|
@@ -2924,21 +3173,21 @@ function provisionStopHook(codeName) {
|
|
|
2924
3173
|
}
|
|
2925
3174
|
];
|
|
2926
3175
|
settings["hooks"] = hooks;
|
|
2927
|
-
|
|
3176
|
+
writeFileSync4(settingsPath, JSON.stringify(settings, null, 2));
|
|
2928
3177
|
}
|
|
2929
3178
|
function provisionIsolationHook(codeName, agentId) {
|
|
2930
3179
|
const projectDir = getProjectDir(codeName);
|
|
2931
|
-
const claudeDir =
|
|
2932
|
-
|
|
3180
|
+
const claudeDir = join3(projectDir, ".claude");
|
|
3181
|
+
mkdirSync3(claudeDir, { recursive: true });
|
|
2933
3182
|
const hasAgentId = agentId !== void 0;
|
|
2934
3183
|
if (hasAgentId)
|
|
2935
3184
|
assertValidAgentId(agentId);
|
|
2936
3185
|
const homeDir = getHomeDir();
|
|
2937
|
-
const augmentedBase =
|
|
3186
|
+
const augmentedBase = join3(homeDir, ".augmented");
|
|
2938
3187
|
const ownAgentDir = getAgentDir(codeName);
|
|
2939
|
-
const logFile =
|
|
3188
|
+
const logFile = join3(ownAgentDir, "isolation.log");
|
|
2940
3189
|
const idAllowClause = hasAgentId ? ` && [ "$AGENT_DIR" != "${agentId}" ]` : "";
|
|
2941
|
-
const hookScriptPath =
|
|
3190
|
+
const hookScriptPath = join3(claudeDir, "agt-isolation-hook.sh");
|
|
2942
3191
|
const hookScript = [
|
|
2943
3192
|
"#!/bin/bash",
|
|
2944
3193
|
"# Auto-generated by Augmented \u2014 prevents cross-agent file access.",
|
|
@@ -2991,11 +3240,11 @@ function provisionIsolationHook(codeName, agentId) {
|
|
|
2991
3240
|
"",
|
|
2992
3241
|
"exit 0"
|
|
2993
3242
|
].join("\n") + "\n";
|
|
2994
|
-
|
|
2995
|
-
const settingsPath =
|
|
3243
|
+
writeFileSync4(hookScriptPath, hookScript, { mode: 493 });
|
|
3244
|
+
const settingsPath = join3(claudeDir, "settings.local.json");
|
|
2996
3245
|
let settings = {};
|
|
2997
3246
|
try {
|
|
2998
|
-
settings = JSON.parse(
|
|
3247
|
+
settings = JSON.parse(readFileSync4(settingsPath, "utf-8"));
|
|
2999
3248
|
} catch {
|
|
3000
3249
|
}
|
|
3001
3250
|
const hooks = settings["hooks"] ?? {};
|
|
@@ -3010,13 +3259,13 @@ function provisionIsolationHook(codeName, agentId) {
|
|
|
3010
3259
|
}
|
|
3011
3260
|
];
|
|
3012
3261
|
settings["hooks"] = hooks;
|
|
3013
|
-
|
|
3262
|
+
writeFileSync4(settingsPath, JSON.stringify(settings, null, 2));
|
|
3014
3263
|
}
|
|
3015
3264
|
function provisionBacklogPullHook(codeName) {
|
|
3016
3265
|
const projectDir = getProjectDir(codeName);
|
|
3017
|
-
const claudeDir =
|
|
3018
|
-
|
|
3019
|
-
const hookScriptPath =
|
|
3266
|
+
const claudeDir = join3(projectDir, ".claude");
|
|
3267
|
+
mkdirSync3(claudeDir, { recursive: true });
|
|
3268
|
+
const hookScriptPath = join3(claudeDir, "agt-backlog-pull-hook.sh");
|
|
3020
3269
|
const hookScript = `#!/usr/bin/env bash
|
|
3021
3270
|
# Auto-generated by Augmented (CS-1549) \u2014 Stop hook: don't end a turn idle
|
|
3022
3271
|
# beside a non-empty backlog. Fail-open on every path; blocks at most once per
|
|
@@ -3141,14 +3390,14 @@ If you genuinely should not pull it, say so in one line and why (it is deliberat
|
|
|
3141
3390
|
jq -cn --arg r "$REASON" '{decision:"block", reason:$r}'
|
|
3142
3391
|
exit 0
|
|
3143
3392
|
`;
|
|
3144
|
-
|
|
3393
|
+
writeFileSync4(hookScriptPath, hookScript, { mode: 493 });
|
|
3145
3394
|
return hookScriptPath;
|
|
3146
3395
|
}
|
|
3147
3396
|
function provisionAutoKanbanProgressHook(codeName) {
|
|
3148
3397
|
const projectDir = getProjectDir(codeName);
|
|
3149
|
-
const claudeDir =
|
|
3150
|
-
|
|
3151
|
-
const hookScriptPath =
|
|
3398
|
+
const claudeDir = join3(projectDir, ".claude");
|
|
3399
|
+
mkdirSync3(claudeDir, { recursive: true });
|
|
3400
|
+
const hookScriptPath = join3(claudeDir, "agt-auto-kanban-progress-hook.sh");
|
|
3152
3401
|
const hookScript = `#!/usr/bin/env bash
|
|
3153
3402
|
# Auto-generated by Augmented (ENG-6179 / ENG-6241) \u2014 PostToolUse auto-progress.
|
|
3154
3403
|
# Maps the agent's latest tool action onto its active in-thread kanban progress
|
|
@@ -3256,11 +3505,11 @@ BODY="$(jq -nc --arg a "$AGENT_ID" --arg s "$STEP" '{agent_id:$a, step:$s}' 2>/d
|
|
|
3256
3505
|
|
|
3257
3506
|
exit 0
|
|
3258
3507
|
`;
|
|
3259
|
-
|
|
3260
|
-
const settingsPath =
|
|
3508
|
+
writeFileSync4(hookScriptPath, hookScript, { mode: 493 });
|
|
3509
|
+
const settingsPath = join3(claudeDir, "settings.local.json");
|
|
3261
3510
|
let settings = {};
|
|
3262
3511
|
try {
|
|
3263
|
-
settings = JSON.parse(
|
|
3512
|
+
settings = JSON.parse(readFileSync4(settingsPath, "utf-8"));
|
|
3264
3513
|
} catch {
|
|
3265
3514
|
}
|
|
3266
3515
|
const hooks = settings["hooks"] ?? {};
|
|
@@ -3272,13 +3521,13 @@ exit 0
|
|
|
3272
3521
|
}
|
|
3273
3522
|
];
|
|
3274
3523
|
settings["hooks"] = hooks;
|
|
3275
|
-
|
|
3524
|
+
writeFileSync4(settingsPath, JSON.stringify(settings, null, 2));
|
|
3276
3525
|
}
|
|
3277
3526
|
function provisionChannelProgressHook(codeName) {
|
|
3278
3527
|
const projectDir = getProjectDir(codeName);
|
|
3279
|
-
const claudeDir =
|
|
3280
|
-
|
|
3281
|
-
const hookScriptPath =
|
|
3528
|
+
const claudeDir = join3(projectDir, ".claude");
|
|
3529
|
+
mkdirSync3(claudeDir, { recursive: true });
|
|
3530
|
+
const hookScriptPath = join3(claudeDir, "agt-channel-progress-hook.sh");
|
|
3282
3531
|
const hookScript = `#!/usr/bin/env bash
|
|
3283
3532
|
# Auto-generated by Augmented (ENG-6567 Phase 2) \u2014 PostToolUse channel-progress
|
|
3284
3533
|
# heartbeat. Writes a throttled local {step, updated_at_ms} the channel MCP reads
|
|
@@ -3345,11 +3594,11 @@ else
|
|
|
3345
3594
|
fi
|
|
3346
3595
|
exit 0
|
|
3347
3596
|
`;
|
|
3348
|
-
|
|
3349
|
-
const settingsPath =
|
|
3597
|
+
writeFileSync4(hookScriptPath, hookScript, { mode: 493 });
|
|
3598
|
+
const settingsPath = join3(claudeDir, "settings.local.json");
|
|
3350
3599
|
let settings = {};
|
|
3351
3600
|
try {
|
|
3352
|
-
settings = JSON.parse(
|
|
3601
|
+
settings = JSON.parse(readFileSync4(settingsPath, "utf-8"));
|
|
3353
3602
|
} catch {
|
|
3354
3603
|
}
|
|
3355
3604
|
const hooks = settings["hooks"] ?? {};
|
|
@@ -3365,14 +3614,14 @@ exit 0
|
|
|
3365
3614
|
}
|
|
3366
3615
|
hooks["PostToolUse"] = groups;
|
|
3367
3616
|
settings["hooks"] = hooks;
|
|
3368
|
-
|
|
3617
|
+
writeFileSync4(settingsPath, JSON.stringify(settings, null, 2));
|
|
3369
3618
|
}
|
|
3370
3619
|
function provisionOrientHook(codeName) {
|
|
3371
3620
|
const projectDir = getProjectDir(codeName);
|
|
3372
|
-
const claudeDir =
|
|
3373
|
-
|
|
3621
|
+
const claudeDir = join3(projectDir, ".claude");
|
|
3622
|
+
mkdirSync3(claudeDir, { recursive: true });
|
|
3374
3623
|
const agentDir = getAgentDir(codeName);
|
|
3375
|
-
const hookScriptPath =
|
|
3624
|
+
const hookScriptPath = join3(claudeDir, "agt-orient-hook.sh");
|
|
3376
3625
|
const hookScript = [
|
|
3377
3626
|
"#!/bin/bash",
|
|
3378
3627
|
"# Auto-generated by Augmented (ENG-5397) \u2014 SessionStart orientation hook.",
|
|
@@ -3522,11 +3771,11 @@ function provisionOrientHook(codeName) {
|
|
|
3522
3771
|
"fi",
|
|
3523
3772
|
"exit 0"
|
|
3524
3773
|
].join("\n") + "\n";
|
|
3525
|
-
|
|
3526
|
-
const settingsPath =
|
|
3774
|
+
writeFileSync4(hookScriptPath, hookScript, { mode: 493 });
|
|
3775
|
+
const settingsPath = join3(claudeDir, "settings.local.json");
|
|
3527
3776
|
let settings = {};
|
|
3528
3777
|
try {
|
|
3529
|
-
settings = JSON.parse(
|
|
3778
|
+
settings = JSON.parse(readFileSync4(settingsPath, "utf-8"));
|
|
3530
3779
|
} catch {
|
|
3531
3780
|
}
|
|
3532
3781
|
const hooks = settings["hooks"] ?? {};
|
|
@@ -3546,15 +3795,15 @@ function provisionOrientHook(codeName) {
|
|
|
3546
3795
|
}
|
|
3547
3796
|
hooks["SessionStart"] = existingSessionStart;
|
|
3548
3797
|
settings["hooks"] = hooks;
|
|
3549
|
-
|
|
3798
|
+
writeFileSync4(settingsPath, JSON.stringify(settings, null, 2));
|
|
3550
3799
|
}
|
|
3551
3800
|
function provisionPreCompactHook(codeName) {
|
|
3552
3801
|
const projectDir = getProjectDir(codeName);
|
|
3553
|
-
const claudeDir =
|
|
3554
|
-
|
|
3802
|
+
const claudeDir = join3(projectDir, ".claude");
|
|
3803
|
+
mkdirSync3(claudeDir, { recursive: true });
|
|
3555
3804
|
const agentDir = getAgentDir(codeName);
|
|
3556
3805
|
const jqNormalizeContent = '(.message.content // .content // []) | if type == "string" then [{type: "text", text: .}] elif type == "array" then . else [] end';
|
|
3557
|
-
const hookScriptPath =
|
|
3806
|
+
const hookScriptPath = join3(claudeDir, "agt-pre-compact-hook.sh");
|
|
3558
3807
|
const hookScript = [
|
|
3559
3808
|
"#!/bin/bash",
|
|
3560
3809
|
"# Auto-generated by Augmented (ENG-7339) - PreCompact courtesy notice.",
|
|
@@ -3658,12 +3907,12 @@ function provisionPreCompactHook(codeName) {
|
|
|
3658
3907
|
'if [ "$WROTE" = "1" ]; then date +%s > "$NOTICE_MARKER" 2>/dev/null || true; fi',
|
|
3659
3908
|
"exit 0"
|
|
3660
3909
|
].join("\n") + "\n";
|
|
3661
|
-
|
|
3662
|
-
|
|
3663
|
-
const settingsPath =
|
|
3910
|
+
writeFileSync4(hookScriptPath, hookScript, { mode: 493 });
|
|
3911
|
+
chmodSync4(hookScriptPath, 493);
|
|
3912
|
+
const settingsPath = join3(claudeDir, "settings.local.json");
|
|
3664
3913
|
let settings = {};
|
|
3665
3914
|
try {
|
|
3666
|
-
settings = JSON.parse(
|
|
3915
|
+
settings = JSON.parse(readFileSync4(settingsPath, "utf-8"));
|
|
3667
3916
|
} catch {
|
|
3668
3917
|
}
|
|
3669
3918
|
const hooks = settings["hooks"] ?? {};
|
|
@@ -3683,14 +3932,14 @@ function provisionPreCompactHook(codeName) {
|
|
|
3683
3932
|
}
|
|
3684
3933
|
hooks["PreCompact"] = existingPreCompact;
|
|
3685
3934
|
settings["hooks"] = hooks;
|
|
3686
|
-
|
|
3935
|
+
writeFileSync4(settingsPath, JSON.stringify(settings, null, 2));
|
|
3687
3936
|
}
|
|
3688
3937
|
function provisionSessionStateHook(codeName) {
|
|
3689
3938
|
const projectDir = getProjectDir(codeName);
|
|
3690
|
-
const claudeDir =
|
|
3691
|
-
|
|
3939
|
+
const claudeDir = join3(projectDir, ".claude");
|
|
3940
|
+
mkdirSync3(claudeDir, { recursive: true });
|
|
3692
3941
|
const agentDir = getAgentDir(codeName);
|
|
3693
|
-
const hookScriptPath =
|
|
3942
|
+
const hookScriptPath = join3(claudeDir, "agt-session-state-hook.sh");
|
|
3694
3943
|
const hookScript = `#!/usr/bin/env bash
|
|
3695
3944
|
# Auto-generated by Augmented (ENG-6233 / ENG-6268) \u2014 SessionStart session-state
|
|
3696
3945
|
# recorder. Writes the model + session origin (which only the agent's own
|
|
@@ -3767,11 +4016,11 @@ fi
|
|
|
3767
4016
|
|
|
3768
4017
|
exit 0
|
|
3769
4018
|
`;
|
|
3770
|
-
|
|
3771
|
-
const settingsPath =
|
|
4019
|
+
writeFileSync4(hookScriptPath, hookScript, { mode: 493 });
|
|
4020
|
+
const settingsPath = join3(claudeDir, "settings.local.json");
|
|
3772
4021
|
let settings = {};
|
|
3773
4022
|
try {
|
|
3774
|
-
settings = JSON.parse(
|
|
4023
|
+
settings = JSON.parse(readFileSync4(settingsPath, "utf-8"));
|
|
3775
4024
|
} catch {
|
|
3776
4025
|
}
|
|
3777
4026
|
const hooks = settings["hooks"] ?? {};
|
|
@@ -3787,13 +4036,13 @@ exit 0
|
|
|
3787
4036
|
}
|
|
3788
4037
|
hooks["SessionStart"] = existingSessionStart;
|
|
3789
4038
|
settings["hooks"] = hooks;
|
|
3790
|
-
|
|
4039
|
+
writeFileSync4(settingsPath, JSON.stringify(settings, null, 2));
|
|
3791
4040
|
}
|
|
3792
4041
|
function modifyJsonConfig(filePath, fn) {
|
|
3793
4042
|
let originalContent;
|
|
3794
4043
|
let config;
|
|
3795
4044
|
try {
|
|
3796
|
-
originalContent =
|
|
4045
|
+
originalContent = readFileSync4(filePath, "utf-8");
|
|
3797
4046
|
config = JSON.parse(originalContent);
|
|
3798
4047
|
} catch {
|
|
3799
4048
|
return;
|
|
@@ -3804,7 +4053,7 @@ function modifyJsonConfig(filePath, fn) {
|
|
|
3804
4053
|
const newContent = JSON.stringify(config, null, 2);
|
|
3805
4054
|
if (newContent === originalContent)
|
|
3806
4055
|
return;
|
|
3807
|
-
|
|
4056
|
+
writeFileSync4(filePath, newContent);
|
|
3808
4057
|
}
|
|
3809
4058
|
var SECRETS_DENY_PERMISSIONS = [
|
|
3810
4059
|
// Read blocks
|
|
@@ -3902,7 +4151,7 @@ function buildSettingsJson(input) {
|
|
|
3902
4151
|
const projectDir = getProjectDir(agent.code_name);
|
|
3903
4152
|
const agentDir = getAgentDir(agent.code_name);
|
|
3904
4153
|
const homeDir = getHomeDir();
|
|
3905
|
-
const codenameAliasDir =
|
|
4154
|
+
const codenameAliasDir = join3(homeDir, ".augmented", agent.code_name);
|
|
3906
4155
|
settings["allowedDirectories"] = [
|
|
3907
4156
|
.../* @__PURE__ */ new Set([
|
|
3908
4157
|
projectDir,
|
|
@@ -3911,7 +4160,7 @@ function buildSettingsJson(input) {
|
|
|
3911
4160
|
// Agent's config dir (.env, schedules, registration)
|
|
3912
4161
|
codenameAliasDir,
|
|
3913
4162
|
// Codename symlink alias (== agentDir for legacy agents)
|
|
3914
|
-
|
|
4163
|
+
join3(homeDir, ".augmented", "_mcp"),
|
|
3915
4164
|
// Shared MCP binaries
|
|
3916
4165
|
"/tmp"
|
|
3917
4166
|
// Temp files
|
|
@@ -4029,10 +4278,10 @@ ${integrationsBlock}`;
|
|
|
4029
4278
|
function renderAugmentedWorkerForAgent(codeName) {
|
|
4030
4279
|
const agentDir = getAgentDir(codeName);
|
|
4031
4280
|
const projectDir = getProjectDir(codeName);
|
|
4032
|
-
const provisionMcpPath =
|
|
4281
|
+
const provisionMcpPath = join3(agentDir, "provision", ".mcp.json");
|
|
4033
4282
|
let mcpServerKeys;
|
|
4034
4283
|
try {
|
|
4035
|
-
const config = JSON.parse(
|
|
4284
|
+
const config = JSON.parse(readFileSync4(provisionMcpPath, "utf-8"));
|
|
4036
4285
|
mcpServerKeys = Object.keys(config.mcpServers ?? {});
|
|
4037
4286
|
} catch {
|
|
4038
4287
|
return;
|
|
@@ -4040,10 +4289,10 @@ function renderAugmentedWorkerForAgent(codeName) {
|
|
|
4040
4289
|
const integrations = readIntegrationsSummaryForAgent(codeName);
|
|
4041
4290
|
const content = buildAugmentedWorkerAgent({ mcpServerKeys, integrations });
|
|
4042
4291
|
for (const baseDir of [agentDir, projectDir]) {
|
|
4043
|
-
const target =
|
|
4292
|
+
const target = join3(baseDir, ".claude", "agents", "augmented-worker.md");
|
|
4044
4293
|
try {
|
|
4045
|
-
|
|
4046
|
-
|
|
4294
|
+
mkdirSync3(dirname3(target), { recursive: true });
|
|
4295
|
+
writeFileSync4(target, content);
|
|
4047
4296
|
} catch {
|
|
4048
4297
|
}
|
|
4049
4298
|
}
|
|
@@ -4069,8 +4318,8 @@ function buildPostizMcpEntry(integration) {
|
|
|
4069
4318
|
}
|
|
4070
4319
|
function buildMcpJson(input) {
|
|
4071
4320
|
const mcpServers = {};
|
|
4072
|
-
const turnInitiatorFile =
|
|
4073
|
-
const localMcpPath =
|
|
4321
|
+
const turnInitiatorFile = join3(getAgentDir(input.agent.code_name), ".current-turn-initiator.json");
|
|
4322
|
+
const localMcpPath = join3(getHomeDir(), ".augmented", "_mcp", "index.js");
|
|
4074
4323
|
mcpServers["augmented"] = {
|
|
4075
4324
|
command: "node",
|
|
4076
4325
|
args: [localMcpPath],
|
|
@@ -4122,7 +4371,7 @@ function buildMcpJson(input) {
|
|
|
4122
4371
|
const xeroIntegration = input.integrations?.find((i) => i.definition_id === "xero");
|
|
4123
4372
|
if (xeroIntegration) {
|
|
4124
4373
|
const brokerMode = Boolean(xeroIntegration.id);
|
|
4125
|
-
const localXeroMcpPath =
|
|
4374
|
+
const localXeroMcpPath = join3(getHomeDir(), ".augmented", "_mcp", "xero.js");
|
|
4126
4375
|
mcpServers["xero"] = {
|
|
4127
4376
|
command: "node",
|
|
4128
4377
|
args: [localXeroMcpPath],
|
|
@@ -4162,7 +4411,7 @@ function buildMcpJson(input) {
|
|
|
4162
4411
|
// getProjectDir (the ADR-0049 seam), not the MCP child's inherited
|
|
4163
4412
|
// cwd, so the path stays correct if Claude Code ever spawns the
|
|
4164
4413
|
// server from somewhere else.
|
|
4165
|
-
XERO_EXPORT_DIR:
|
|
4414
|
+
XERO_EXPORT_DIR: join3(getProjectDir(input.agent.code_name), "xero-exports"),
|
|
4166
4415
|
PATH: process.env["PATH"] ?? "",
|
|
4167
4416
|
HOME: process.env["HOME"] ?? ""
|
|
4168
4417
|
}
|
|
@@ -4173,8 +4422,8 @@ function buildMcpJson(input) {
|
|
|
4173
4422
|
mcpServers["postiz"] = buildPostizMcpEntry(postizIntegration);
|
|
4174
4423
|
}
|
|
4175
4424
|
const remoteOAuthProxyPaths = {
|
|
4176
|
-
proxyPath:
|
|
4177
|
-
tokenFile:
|
|
4425
|
+
proxyPath: join3(getHomeDir(), ".augmented", "_mcp", "remote-oauth-proxy.js"),
|
|
4426
|
+
tokenFile: join3(getProjectDir(input.agent.code_name), ".env.integrations")
|
|
4178
4427
|
};
|
|
4179
4428
|
for (const integration of input.integrations ?? []) {
|
|
4180
4429
|
const connectionKey = integration.connection_key;
|
|
@@ -4240,7 +4489,7 @@ function buildMcpJson(input) {
|
|
|
4240
4489
|
}
|
|
4241
4490
|
const hasAdminDebug = input.integrations?.some((i) => i.definition_id === "augmented-admin") ?? false;
|
|
4242
4491
|
if (hasAdminDebug) {
|
|
4243
|
-
const localAdminMcpPath =
|
|
4492
|
+
const localAdminMcpPath = join3(getHomeDir(), ".augmented", "_mcp", "augmented-admin.js");
|
|
4244
4493
|
mcpServers["augmented-admin"] = {
|
|
4245
4494
|
command: "node",
|
|
4246
4495
|
args: [localAdminMcpPath],
|
|
@@ -4254,7 +4503,7 @@ function buildMcpJson(input) {
|
|
|
4254
4503
|
}
|
|
4255
4504
|
const hasSupport = input.integrations?.some((i) => i.definition_id === "augmented-support") ?? false;
|
|
4256
4505
|
if (hasSupport) {
|
|
4257
|
-
const localSupportMcpPath =
|
|
4506
|
+
const localSupportMcpPath = join3(getHomeDir(), ".augmented", "_mcp", "augmented-support.js");
|
|
4258
4507
|
mcpServers["augmented-support"] = {
|
|
4259
4508
|
command: "node",
|
|
4260
4509
|
args: [localSupportMcpPath],
|
|
@@ -4268,7 +4517,7 @@ function buildMcpJson(input) {
|
|
|
4268
4517
|
}
|
|
4269
4518
|
const hasHelpKb = input.integrations?.some((i) => i.definition_id === "augmented-help-kb") ?? false;
|
|
4270
4519
|
if (hasHelpKb) {
|
|
4271
|
-
const localHelpKbMcpPath =
|
|
4520
|
+
const localHelpKbMcpPath = join3(getHomeDir(), ".augmented", "_mcp", "augmented-help-kb.js");
|
|
4272
4521
|
mcpServers["augmented-help-kb"] = {
|
|
4273
4522
|
command: "node",
|
|
4274
4523
|
args: [localHelpKbMcpPath],
|
|
@@ -4282,7 +4531,7 @@ function buildMcpJson(input) {
|
|
|
4282
4531
|
}
|
|
4283
4532
|
const origamiIntegration = input.integrations?.find((i) => i.definition_id === "origami");
|
|
4284
4533
|
if (origamiIntegration?.stdioMcp === true && origamiIntegration.id) {
|
|
4285
|
-
const localOrigamiMcpPath =
|
|
4534
|
+
const localOrigamiMcpPath = join3(getHomeDir(), ".augmented", "_mcp", "origami.js");
|
|
4286
4535
|
mcpServers["origami"] = {
|
|
4287
4536
|
command: "node",
|
|
4288
4537
|
args: [localOrigamiMcpPath],
|
|
@@ -4526,14 +4775,14 @@ ${sections}`
|
|
|
4526
4775
|
},
|
|
4527
4776
|
async getRegisteredAgents(_profile) {
|
|
4528
4777
|
const homeDir = getHomeDir();
|
|
4529
|
-
const augDir =
|
|
4778
|
+
const augDir = join3(homeDir, ".augmented");
|
|
4530
4779
|
const agents = /* @__PURE__ */ new Set();
|
|
4531
4780
|
try {
|
|
4532
4781
|
const entries = readdirSync(augDir);
|
|
4533
4782
|
for (const entry of entries) {
|
|
4534
4783
|
if (entry.startsWith("_") || entry.startsWith("."))
|
|
4535
4784
|
continue;
|
|
4536
|
-
const agentRoot =
|
|
4785
|
+
const agentRoot = join3(augDir, entry);
|
|
4537
4786
|
let st;
|
|
4538
4787
|
try {
|
|
4539
4788
|
st = lstatSync(agentRoot);
|
|
@@ -4542,11 +4791,11 @@ ${sections}`
|
|
|
4542
4791
|
}
|
|
4543
4792
|
if (st.isSymbolicLink() || !st.isDirectory())
|
|
4544
4793
|
continue;
|
|
4545
|
-
if (!
|
|
4794
|
+
if (!existsSync4(join3(agentRoot, "registration.json")))
|
|
4546
4795
|
continue;
|
|
4547
4796
|
let codeName = entry;
|
|
4548
4797
|
try {
|
|
4549
|
-
const reg = JSON.parse(
|
|
4798
|
+
const reg = JSON.parse(readFileSync4(join3(agentRoot, "registration.json"), "utf8"));
|
|
4550
4799
|
if (reg && typeof reg.code_name === "string" && reg.code_name) {
|
|
4551
4800
|
codeName = reg.code_name;
|
|
4552
4801
|
}
|
|
@@ -4565,9 +4814,9 @@ ${sections}`
|
|
|
4565
4814
|
}
|
|
4566
4815
|
const agentDir = getAgentDir(codeName);
|
|
4567
4816
|
const projectDir = getProjectDir(codeName);
|
|
4568
|
-
|
|
4569
|
-
|
|
4570
|
-
|
|
4817
|
+
mkdirSync3(agentDir, { recursive: true });
|
|
4818
|
+
mkdirSync3(projectDir, { recursive: true });
|
|
4819
|
+
writeFileSync4(join3(agentDir, "registration.json"), JSON.stringify({
|
|
4571
4820
|
code_name: codeName,
|
|
4572
4821
|
agent_id: agentId ?? null,
|
|
4573
4822
|
team_dir: teamDir,
|
|
@@ -4575,7 +4824,7 @@ ${sections}`
|
|
|
4575
4824
|
framework: "claude-code",
|
|
4576
4825
|
registered_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
4577
4826
|
}, null, 2));
|
|
4578
|
-
if (
|
|
4827
|
+
if (existsSync4(teamDir)) {
|
|
4579
4828
|
deployArtifactsToProject(codeName, teamDir);
|
|
4580
4829
|
}
|
|
4581
4830
|
return true;
|
|
@@ -4586,10 +4835,10 @@ ${sections}`
|
|
|
4586
4835
|
async deregisterAgent(codeName) {
|
|
4587
4836
|
try {
|
|
4588
4837
|
const agentDir = getAgentDir(codeName);
|
|
4589
|
-
const regFile =
|
|
4590
|
-
if (
|
|
4591
|
-
const { unlinkSync:
|
|
4592
|
-
|
|
4838
|
+
const regFile = join3(agentDir, "registration.json");
|
|
4839
|
+
if (existsSync4(regFile)) {
|
|
4840
|
+
const { unlinkSync: unlinkSync5 } = await import("fs");
|
|
4841
|
+
unlinkSync5(regFile);
|
|
4593
4842
|
}
|
|
4594
4843
|
return true;
|
|
4595
4844
|
} catch {
|
|
@@ -4598,7 +4847,7 @@ ${sections}`
|
|
|
4598
4847
|
},
|
|
4599
4848
|
writeAuthProfiles(codeName, profiles) {
|
|
4600
4849
|
const agentDir = getAgentDir(codeName);
|
|
4601
|
-
|
|
4850
|
+
mkdirSync3(agentDir, { recursive: true });
|
|
4602
4851
|
const envLines = ["# Augmented auth profiles \u2014 auto-generated, do not edit"];
|
|
4603
4852
|
for (const p of profiles) {
|
|
4604
4853
|
if (!p.api_key)
|
|
@@ -4612,9 +4861,9 @@ ${sections}`
|
|
|
4612
4861
|
}
|
|
4613
4862
|
}
|
|
4614
4863
|
if (envLines.length > 1) {
|
|
4615
|
-
const envPath =
|
|
4616
|
-
|
|
4617
|
-
|
|
4864
|
+
const envPath = join3(agentDir, ".env");
|
|
4865
|
+
writeFileSync4(envPath, envLines.join("\n") + "\n");
|
|
4866
|
+
chmodSync4(envPath, SECRET_FILE_MODE);
|
|
4618
4867
|
}
|
|
4619
4868
|
},
|
|
4620
4869
|
// Claude Code has no gateway process — methods intentionally omitted
|
|
@@ -4647,7 +4896,7 @@ ${sections}`
|
|
|
4647
4896
|
const senderPolicyInternalOnly = options?.senderPolicy?.internal_only === true;
|
|
4648
4897
|
const senderPolicyEnv = senderPolicyTeamId ? { AGT_TEAM_ID: senderPolicyTeamId } : {};
|
|
4649
4898
|
const agentDir = getAgentDir(codeName);
|
|
4650
|
-
|
|
4899
|
+
mkdirSync3(agentDir, { recursive: true });
|
|
4651
4900
|
const isPersistent = options?.sessionMode === "persistent";
|
|
4652
4901
|
const peerDisabledMode = options?.peerDisabled ?? (options?.telegramPeerDisabled === true ? "all" : "off");
|
|
4653
4902
|
if (channelId === "telegram") {
|
|
@@ -4655,7 +4904,7 @@ ${sections}`
|
|
|
4655
4904
|
if (!botToken)
|
|
4656
4905
|
return;
|
|
4657
4906
|
const allowedChats = config["allowed_chats"];
|
|
4658
|
-
const localTelegramChannel =
|
|
4907
|
+
const localTelegramChannel = join3(getHomeDir(), ".augmented", "_mcp", "telegram-channel.js");
|
|
4659
4908
|
const resolvedAgtHostForTelegram = process.env["AGT_HOST"]?.trim() || "https://api.augmented.team";
|
|
4660
4909
|
const resolvedAgtApiKeyForTelegram = process.env["AGT_API_KEY"]?.trim();
|
|
4661
4910
|
writeEnvIntegrationsForAgent(codeName, {
|
|
@@ -4670,7 +4919,7 @@ ${sections}`
|
|
|
4670
4919
|
...options?.agentId ? { AGT_AGENT_ID: options.agentId } : {},
|
|
4671
4920
|
...tzEnv,
|
|
4672
4921
|
// ENG-6582 (D16): stamp the verified turn initiator for broker MCPs.
|
|
4673
|
-
AGT_TURN_INITIATOR_FILE:
|
|
4922
|
+
AGT_TURN_INITIATOR_FILE: join3(getAgentDir(codeName), ".current-turn-initiator.json")
|
|
4674
4923
|
};
|
|
4675
4924
|
if (allowedChats && allowedChats.length > 0) {
|
|
4676
4925
|
telegramEnv.TELEGRAM_ALLOWED_CHATS = allowedChats.join(",");
|
|
@@ -4730,11 +4979,11 @@ ${sections}`
|
|
|
4730
4979
|
args: [localTelegramChannel],
|
|
4731
4980
|
env: telegramEnv
|
|
4732
4981
|
};
|
|
4733
|
-
const provisionMcpPath =
|
|
4734
|
-
|
|
4982
|
+
const provisionMcpPath = join3(agentDir, "provision", ".mcp.json");
|
|
4983
|
+
mkdirSync3(dirname3(provisionMcpPath), { recursive: true });
|
|
4735
4984
|
let mcpConfig2 = { mcpServers: {} };
|
|
4736
4985
|
try {
|
|
4737
|
-
mcpConfig2 = JSON.parse(
|
|
4986
|
+
mcpConfig2 = JSON.parse(readFileSync4(provisionMcpPath, "utf-8"));
|
|
4738
4987
|
if (!mcpConfig2.mcpServers)
|
|
4739
4988
|
mcpConfig2.mcpServers = {};
|
|
4740
4989
|
} catch {
|
|
@@ -4747,13 +4996,13 @@ ${sections}`
|
|
|
4747
4996
|
return;
|
|
4748
4997
|
}
|
|
4749
4998
|
if (isPersistent && (channelId === "discord" || channelId === "slack")) {
|
|
4750
|
-
const channelDir =
|
|
4999
|
+
const channelDir = join3(getHomeDir(), ".claude", "channels", channelId);
|
|
4751
5000
|
if (channelId === "discord")
|
|
4752
|
-
|
|
5001
|
+
mkdirSync3(channelDir, { recursive: true });
|
|
4753
5002
|
if (channelId === "discord") {
|
|
4754
5003
|
const botToken = config["bot_token"];
|
|
4755
5004
|
if (botToken) {
|
|
4756
|
-
|
|
5005
|
+
writeFileSync4(join3(channelDir, ".env"), `DISCORD_BOT_TOKEN=${botToken}
|
|
4757
5006
|
`);
|
|
4758
5007
|
}
|
|
4759
5008
|
} else if (channelId === "slack") {
|
|
@@ -4819,11 +5068,11 @@ ${sections}`
|
|
|
4819
5068
|
...appToken ? { SLACK_APP_TOKEN: appToken } : {}
|
|
4820
5069
|
}
|
|
4821
5070
|
});
|
|
4822
|
-
const localSlackChannel =
|
|
5071
|
+
const localSlackChannel = join3(getHomeDir(), ".augmented", "_mcp", "slack-channel.js");
|
|
4823
5072
|
const slackAvatarEnvUrl = resolveAvatarEnvUrl(options?.agentAvatarUrl).url;
|
|
4824
5073
|
const slackEntry = {
|
|
4825
|
-
command:
|
|
4826
|
-
args:
|
|
5074
|
+
command: existsSync4(localSlackChannel) ? "node" : "npx",
|
|
5075
|
+
args: existsSync4(localSlackChannel) ? [localSlackChannel] : ["-y", "@augmented/claude-code-channel-slack"],
|
|
4827
5076
|
env: {
|
|
4828
5077
|
SLACK_BOT_TOKEN: "${SLACK_BOT_TOKEN}",
|
|
4829
5078
|
...appToken ? { SLACK_APP_TOKEN: "${SLACK_APP_TOKEN}" } : {},
|
|
@@ -4905,14 +5154,14 @@ ${sections}`
|
|
|
4905
5154
|
...pingAllowedUsers.length > 0 ? { SLACK_PING_ALLOWED_USERS: pingAllowedUsers.join(",") } : {},
|
|
4906
5155
|
// ENG-6563 (D16): stamp the verified turn initiator so broker MCPs
|
|
4907
5156
|
// can forward it when the agent files an approval mid-turn.
|
|
4908
|
-
AGT_TURN_INITIATOR_FILE:
|
|
5157
|
+
AGT_TURN_INITIATOR_FILE: join3(agentDir, ".current-turn-initiator.json")
|
|
4909
5158
|
}
|
|
4910
5159
|
};
|
|
4911
|
-
const provisionMcpPath =
|
|
4912
|
-
|
|
5160
|
+
const provisionMcpPath = join3(agentDir, "provision", ".mcp.json");
|
|
5161
|
+
mkdirSync3(dirname3(provisionMcpPath), { recursive: true });
|
|
4913
5162
|
let mcpConfig2 = { mcpServers: {} };
|
|
4914
5163
|
try {
|
|
4915
|
-
mcpConfig2 = JSON.parse(
|
|
5164
|
+
mcpConfig2 = JSON.parse(readFileSync4(provisionMcpPath, "utf-8"));
|
|
4916
5165
|
if (!mcpConfig2.mcpServers)
|
|
4917
5166
|
mcpConfig2.mcpServers = {};
|
|
4918
5167
|
} catch {
|
|
@@ -4922,10 +5171,10 @@ ${sections}`
|
|
|
4922
5171
|
return;
|
|
4923
5172
|
}
|
|
4924
5173
|
syncMcpToProject(codeName);
|
|
4925
|
-
const staleChannelsPath =
|
|
4926
|
-
if (
|
|
5174
|
+
const staleChannelsPath = join3(getProjectDir(codeName), ".mcp-channels.json");
|
|
5175
|
+
if (existsSync4(staleChannelsPath)) {
|
|
4927
5176
|
try {
|
|
4928
|
-
|
|
5177
|
+
rmSync2(staleChannelsPath, { force: true });
|
|
4929
5178
|
} catch {
|
|
4930
5179
|
}
|
|
4931
5180
|
}
|
|
@@ -4933,11 +5182,11 @@ ${sections}`
|
|
|
4933
5182
|
}
|
|
4934
5183
|
return;
|
|
4935
5184
|
}
|
|
4936
|
-
const mcpJsonPath =
|
|
4937
|
-
|
|
5185
|
+
const mcpJsonPath = join3(agentDir, "provision", ".mcp.json");
|
|
5186
|
+
mkdirSync3(dirname3(mcpJsonPath), { recursive: true });
|
|
4938
5187
|
let mcpConfig;
|
|
4939
5188
|
try {
|
|
4940
|
-
mcpConfig = JSON.parse(
|
|
5189
|
+
mcpConfig = JSON.parse(readFileSync4(mcpJsonPath, "utf-8"));
|
|
4941
5190
|
} catch {
|
|
4942
5191
|
mcpConfig = { mcpServers: {} };
|
|
4943
5192
|
}
|
|
@@ -4956,7 +5205,7 @@ ${sections}`
|
|
|
4956
5205
|
const appToken = config["app_token"];
|
|
4957
5206
|
if (!botToken)
|
|
4958
5207
|
return;
|
|
4959
|
-
const localSlackChannel =
|
|
5208
|
+
const localSlackChannel = join3(getHomeDir(), ".augmented", "_mcp", "slack-channel.js");
|
|
4960
5209
|
const slackThreadAutoFollow = config["thread_auto_follow"];
|
|
4961
5210
|
const slackAutoFollowEnv = slackThreadAutoFollow && slackThreadAutoFollow !== "off" ? { SLACK_THREAD_AUTO_FOLLOW: slackThreadAutoFollow } : {};
|
|
4962
5211
|
const slackChannelResponseMode = config["channel_response_mode"];
|
|
@@ -5031,7 +5280,7 @@ ${sections}`
|
|
|
5031
5280
|
}
|
|
5032
5281
|
});
|
|
5033
5282
|
const slackAvatarEnvUrl = resolveAvatarEnvUrl(options?.agentAvatarUrl).url;
|
|
5034
|
-
if (isPersistent &&
|
|
5283
|
+
if (isPersistent && existsSync4(localSlackChannel)) {
|
|
5035
5284
|
mcpServers["slack"] = {
|
|
5036
5285
|
command: "node",
|
|
5037
5286
|
args: [localSlackChannel],
|
|
@@ -5049,7 +5298,7 @@ ${sections}`
|
|
|
5049
5298
|
...slackAgtAuthEnv,
|
|
5050
5299
|
...tzEnv,
|
|
5051
5300
|
// ENG-6563 (D16): stamp the verified turn initiator for broker MCPs.
|
|
5052
|
-
AGT_TURN_INITIATOR_FILE:
|
|
5301
|
+
AGT_TURN_INITIATOR_FILE: join3(getAgentDir(codeName), ".current-turn-initiator.json"),
|
|
5053
5302
|
// ENG-6155: avatar URL → bot Slack profile photo (see persistent
|
|
5054
5303
|
// branch above). Mirrored here so oneshot-mode agents get it too.
|
|
5055
5304
|
// ENG-6245: slackAvatarEnvUrl is null for data-URI / oversized values.
|
|
@@ -5074,7 +5323,7 @@ ${sections}`
|
|
|
5074
5323
|
...slackAgtAuthEnv,
|
|
5075
5324
|
...tzEnv,
|
|
5076
5325
|
// ENG-6563 (D16): stamp the verified turn initiator for broker MCPs.
|
|
5077
|
-
AGT_TURN_INITIATOR_FILE:
|
|
5326
|
+
AGT_TURN_INITIATOR_FILE: join3(getAgentDir(codeName), ".current-turn-initiator.json"),
|
|
5078
5327
|
// ENG-6155: avatar URL → bot Slack profile photo (see persistent
|
|
5079
5328
|
// branch above). Mirrored here so oneshot-mode agents get it too.
|
|
5080
5329
|
// ENG-6245: slackAvatarEnvUrl is null for data-URI / oversized values.
|
|
@@ -5087,12 +5336,12 @@ ${sections}`
|
|
|
5087
5336
|
const clientSecret = config["client_secret"];
|
|
5088
5337
|
if (!appId || !clientSecret)
|
|
5089
5338
|
return;
|
|
5090
|
-
const localTeamsChannel =
|
|
5339
|
+
const localTeamsChannel = join3(getHomeDir(), ".augmented", "_mcp", "teams-channel.js");
|
|
5091
5340
|
const agentDirMs = getAgentDir(codeName);
|
|
5092
5341
|
try {
|
|
5093
|
-
|
|
5094
|
-
|
|
5095
|
-
|
|
5342
|
+
mkdirSync3(join3(agentDirMs, "msteams-pending-inbound", ".markers"), { recursive: true });
|
|
5343
|
+
mkdirSync3(join3(agentDirMs, "msteams-pending-interactions"), { recursive: true });
|
|
5344
|
+
mkdirSync3(join3(agentDirMs, "msteams-recovery-outbox"), { recursive: true });
|
|
5096
5345
|
} catch {
|
|
5097
5346
|
}
|
|
5098
5347
|
const tenantId = config["tenant_id"] ?? "common";
|
|
@@ -5154,7 +5403,7 @@ ${sections}`
|
|
|
5154
5403
|
...senderPolicyInternalOnly ? { MSTEAMS_INTERNAL_ONLY: "true" } : {},
|
|
5155
5404
|
...senderPolicyInternalOnly && tenantId !== "common" ? { MSTEAMS_HOME_TENANT_ID: tenantId } : {}
|
|
5156
5405
|
};
|
|
5157
|
-
if (isPersistent &&
|
|
5406
|
+
if (isPersistent && existsSync4(localTeamsChannel)) {
|
|
5158
5407
|
mcpServers["msteams"] = {
|
|
5159
5408
|
command: "node",
|
|
5160
5409
|
args: [localTeamsChannel],
|
|
@@ -5170,7 +5419,7 @@ ${sections}`
|
|
|
5170
5419
|
}
|
|
5171
5420
|
if (channelId === "whatsapp") {
|
|
5172
5421
|
const provider = config["provider"] ?? "kapso";
|
|
5173
|
-
const localWhatsappChannel =
|
|
5422
|
+
const localWhatsappChannel = join3(getHomeDir(), ".augmented", "_mcp", "whatsapp-channel.js");
|
|
5174
5423
|
if (provider === "baileys") {
|
|
5175
5424
|
mcpServers["whatsapp"] = {
|
|
5176
5425
|
command: "node",
|
|
@@ -5189,7 +5438,7 @@ ${sections}`
|
|
|
5189
5438
|
const phoneNumberId = config["phone_number_id"];
|
|
5190
5439
|
if (projectApiKey && phoneNumberId) {
|
|
5191
5440
|
try {
|
|
5192
|
-
|
|
5441
|
+
mkdirSync3(join3(getAgentDir(codeName), "whatsapp-pending-inbound"), { recursive: true });
|
|
5193
5442
|
} catch {
|
|
5194
5443
|
}
|
|
5195
5444
|
writeEnvIntegrationsForAgent(codeName, {
|
|
@@ -5217,11 +5466,11 @@ ${sections}`
|
|
|
5217
5466
|
}
|
|
5218
5467
|
},
|
|
5219
5468
|
hasChannelCredentials(codeName, channelId) {
|
|
5220
|
-
const provisionMcpPath =
|
|
5221
|
-
if (!
|
|
5469
|
+
const provisionMcpPath = join3(getAgentDir(codeName), "provision", ".mcp.json");
|
|
5470
|
+
if (!existsSync4(provisionMcpPath))
|
|
5222
5471
|
return false;
|
|
5223
5472
|
try {
|
|
5224
|
-
const parsed = JSON.parse(
|
|
5473
|
+
const parsed = JSON.parse(readFileSync4(provisionMcpPath, "utf-8"));
|
|
5225
5474
|
return Boolean(parsed.mcpServers?.[channelId]);
|
|
5226
5475
|
} catch {
|
|
5227
5476
|
return false;
|
|
@@ -5229,7 +5478,7 @@ ${sections}`
|
|
|
5229
5478
|
},
|
|
5230
5479
|
removeChannelCredentials(codeName, channelId) {
|
|
5231
5480
|
const agentDir = getAgentDir(codeName);
|
|
5232
|
-
const mcpJsonPath =
|
|
5481
|
+
const mcpJsonPath = join3(agentDir, "provision", ".mcp.json");
|
|
5233
5482
|
modifyJsonConfig(mcpJsonPath, (config) => {
|
|
5234
5483
|
const mcpServers = config["mcpServers"];
|
|
5235
5484
|
if (!mcpServers || !(channelId in mcpServers))
|
|
@@ -5241,7 +5490,7 @@ ${sections}`
|
|
|
5241
5490
|
},
|
|
5242
5491
|
async updateAgentModel(codeName, model) {
|
|
5243
5492
|
const agentDir = getAgentDir(codeName);
|
|
5244
|
-
const settingsPath =
|
|
5493
|
+
const settingsPath = join3(agentDir, "provision", "settings.json");
|
|
5245
5494
|
let changed = false;
|
|
5246
5495
|
modifyJsonConfig(settingsPath, (config) => {
|
|
5247
5496
|
config["model"] = model;
|
|
@@ -5259,20 +5508,20 @@ ${sections}`
|
|
|
5259
5508
|
seedProfileConfig(codeName) {
|
|
5260
5509
|
const agentDir = getAgentDir(codeName);
|
|
5261
5510
|
const projectDir = getProjectDir(codeName);
|
|
5262
|
-
|
|
5263
|
-
|
|
5511
|
+
mkdirSync3(join3(agentDir, "provision"), { recursive: true });
|
|
5512
|
+
mkdirSync3(projectDir, { recursive: true });
|
|
5264
5513
|
},
|
|
5265
5514
|
syncScheduledTasks(codeName, tasks) {
|
|
5266
5515
|
const agentDir = getAgentDir(codeName);
|
|
5267
|
-
const schedulesPath =
|
|
5516
|
+
const schedulesPath = join3(agentDir, "schedules.json");
|
|
5268
5517
|
const mapped = mapScheduledTasks(tasks);
|
|
5269
|
-
|
|
5270
|
-
|
|
5518
|
+
mkdirSync3(agentDir, { recursive: true });
|
|
5519
|
+
writeFileSync4(schedulesPath, JSON.stringify({ schedules: mapped }, null, 2));
|
|
5271
5520
|
return Promise.resolve();
|
|
5272
5521
|
},
|
|
5273
5522
|
writeIntegrations(codeName, integrations, agentId, options) {
|
|
5274
5523
|
const agentDir = getAgentDir(codeName);
|
|
5275
|
-
|
|
5524
|
+
mkdirSync3(agentDir, { recursive: true });
|
|
5276
5525
|
const summariesForSidecar = integrations.map((i) => {
|
|
5277
5526
|
const def = INTEGRATION_REGISTRY.find((d) => d.id === i.definition_id);
|
|
5278
5527
|
return {
|
|
@@ -5351,6 +5600,7 @@ ${sections}`
|
|
|
5351
5600
|
updates: envUpdates
|
|
5352
5601
|
});
|
|
5353
5602
|
writeXurlStoreForIntegrations(decryptedIntegrations);
|
|
5603
|
+
writeFramerStoreForIntegrations(decryptedIntegrations);
|
|
5354
5604
|
for (const integration of decryptedIntegrations) {
|
|
5355
5605
|
const def = INTEGRATION_REGISTRY.find((d) => d.id === integration.definition_id);
|
|
5356
5606
|
if (!def?.nativeMcp)
|
|
@@ -5388,7 +5638,7 @@ ${sections}`
|
|
|
5388
5638
|
xeroEnv.AGT_AGENT_ID = agentId;
|
|
5389
5639
|
xeroEnv.AGT_INTEGRATION_ID = xeroIntegration.id;
|
|
5390
5640
|
}
|
|
5391
|
-
const localXeroMcpPath =
|
|
5641
|
+
const localXeroMcpPath = join3(getHomeDir(), ".augmented", "_mcp", "xero.js");
|
|
5392
5642
|
this.writeMcpServer(codeName, "xero", {
|
|
5393
5643
|
command: "node",
|
|
5394
5644
|
args: [localXeroMcpPath],
|
|
@@ -5400,8 +5650,8 @@ ${sections}`
|
|
|
5400
5650
|
this.writeMcpServer(codeName, "postiz", buildPostizMcpEntry(postizIntegration));
|
|
5401
5651
|
}
|
|
5402
5652
|
const remoteOAuthProxyPaths = {
|
|
5403
|
-
proxyPath:
|
|
5404
|
-
tokenFile:
|
|
5653
|
+
proxyPath: join3(getHomeDir(), ".augmented", "_mcp", "remote-oauth-proxy.js"),
|
|
5654
|
+
tokenFile: join3(getProjectDir(codeName), ".env.integrations")
|
|
5405
5655
|
};
|
|
5406
5656
|
for (const integration of integrations) {
|
|
5407
5657
|
const connectionKey = integration.connection_key;
|
|
@@ -5442,7 +5692,7 @@ ${sections}`
|
|
|
5442
5692
|
// ENG-6586 (D16): keep incremental cloud-broker wiring in sync with
|
|
5443
5693
|
// buildMcpJson so agents that add cloud-broker post-provision still
|
|
5444
5694
|
// forward the per-turn initiator.
|
|
5445
|
-
AGT_TURN_INITIATOR_FILE:
|
|
5695
|
+
AGT_TURN_INITIATOR_FILE: join3(getAgentDir(codeName), ".current-turn-initiator.json"),
|
|
5446
5696
|
PATH: process.env["PATH"] ?? "",
|
|
5447
5697
|
HOME: process.env["HOME"] ?? ""
|
|
5448
5698
|
}
|
|
@@ -5466,7 +5716,7 @@ ${sections}`
|
|
|
5466
5716
|
// ENG-6563 (D16): keep incremental xero-broker wiring in sync with
|
|
5467
5717
|
// buildMcpJson so agents that add xero-broker post-provision still
|
|
5468
5718
|
// forward the per-turn initiator.
|
|
5469
|
-
AGT_TURN_INITIATOR_FILE:
|
|
5719
|
+
AGT_TURN_INITIATOR_FILE: join3(getAgentDir(codeName), ".current-turn-initiator.json"),
|
|
5470
5720
|
PATH: process.env["PATH"] ?? "",
|
|
5471
5721
|
HOME: process.env["HOME"] ?? ""
|
|
5472
5722
|
}
|
|
@@ -5475,7 +5725,7 @@ ${sections}`
|
|
|
5475
5725
|
}
|
|
5476
5726
|
const hasAdminDebug = integrations.some((i) => i.definition_id === "augmented-admin");
|
|
5477
5727
|
if (hasAdminDebug) {
|
|
5478
|
-
const localAdminMcpPath =
|
|
5728
|
+
const localAdminMcpPath = join3(getHomeDir(), ".augmented", "_mcp", "augmented-admin.js");
|
|
5479
5729
|
this.writeMcpServer(codeName, "augmented-admin", {
|
|
5480
5730
|
command: "node",
|
|
5481
5731
|
args: [localAdminMcpPath],
|
|
@@ -5489,7 +5739,7 @@ ${sections}`
|
|
|
5489
5739
|
}
|
|
5490
5740
|
const hasSupport = integrations.some((i) => i.definition_id === "augmented-support");
|
|
5491
5741
|
if (hasSupport) {
|
|
5492
|
-
const localSupportMcpPath =
|
|
5742
|
+
const localSupportMcpPath = join3(getHomeDir(), ".augmented", "_mcp", "augmented-support.js");
|
|
5493
5743
|
this.writeMcpServer(codeName, "augmented-support", {
|
|
5494
5744
|
command: "node",
|
|
5495
5745
|
args: [localSupportMcpPath],
|
|
@@ -5503,7 +5753,7 @@ ${sections}`
|
|
|
5503
5753
|
}
|
|
5504
5754
|
const hasHelpKb = integrations.some((i) => i.definition_id === "augmented-help-kb");
|
|
5505
5755
|
if (hasHelpKb) {
|
|
5506
|
-
const localHelpKbMcpPath =
|
|
5756
|
+
const localHelpKbMcpPath = join3(getHomeDir(), ".augmented", "_mcp", "augmented-help-kb.js");
|
|
5507
5757
|
this.writeMcpServer(codeName, "augmented-help-kb", {
|
|
5508
5758
|
command: "node",
|
|
5509
5759
|
args: [localHelpKbMcpPath],
|
|
@@ -5519,7 +5769,7 @@ ${sections}`
|
|
|
5519
5769
|
const origamiStdioAgentId = resolveBrokerAgentId(codeName) ?? agentId;
|
|
5520
5770
|
const origamiStdioExpected = Boolean(origamiStdio?.stdioMcp === true && origamiStdio.id);
|
|
5521
5771
|
if (origamiStdioExpected && origamiStdioAgentId) {
|
|
5522
|
-
const localOrigamiMcpPath =
|
|
5772
|
+
const localOrigamiMcpPath = join3(getHomeDir(), ".augmented", "_mcp", "origami.js");
|
|
5523
5773
|
this.writeMcpServer(codeName, "origami", {
|
|
5524
5774
|
command: "node",
|
|
5525
5775
|
args: [localOrigamiMcpPath],
|
|
@@ -5636,9 +5886,9 @@ ${sections}`
|
|
|
5636
5886
|
}
|
|
5637
5887
|
}
|
|
5638
5888
|
const projectDir = getProjectDir(codeName);
|
|
5639
|
-
const claudeMdPath =
|
|
5889
|
+
const claudeMdPath = join3(projectDir, "CLAUDE.md");
|
|
5640
5890
|
try {
|
|
5641
|
-
const existing =
|
|
5891
|
+
const existing = readFileSync4(claudeMdPath, "utf-8");
|
|
5642
5892
|
const renderSection = options?.renderClaudeMdSection === true;
|
|
5643
5893
|
const newSection = renderSection ? buildIntegrationsSection(summariesForSidecar) : "";
|
|
5644
5894
|
const sentinelStart = INTEGRATIONS_SECTION_START.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -5655,15 +5905,15 @@ ${sections}`
|
|
|
5655
5905
|
updated = existing;
|
|
5656
5906
|
}
|
|
5657
5907
|
if (updated !== existing)
|
|
5658
|
-
|
|
5908
|
+
writeFileSync4(claudeMdPath, updated);
|
|
5659
5909
|
const agentDir2 = getAgentDir(codeName);
|
|
5660
|
-
const envSrc =
|
|
5910
|
+
const envSrc = join3(agentDir2, ".env.integrations");
|
|
5661
5911
|
try {
|
|
5662
|
-
const envContent =
|
|
5663
|
-
const envDest =
|
|
5664
|
-
|
|
5912
|
+
const envContent = readFileSync4(envSrc, "utf-8");
|
|
5913
|
+
const envDest = join3(projectDir, ".env.integrations");
|
|
5914
|
+
writeFileSync4(envDest, envContent, { mode: SECRET_FILE_MODE });
|
|
5665
5915
|
try {
|
|
5666
|
-
|
|
5916
|
+
chmodSync4(envDest, SECRET_FILE_MODE);
|
|
5667
5917
|
} catch {
|
|
5668
5918
|
}
|
|
5669
5919
|
} catch {
|
|
@@ -5675,11 +5925,11 @@ ${sections}`
|
|
|
5675
5925
|
},
|
|
5676
5926
|
writeMcpServer(codeName, serverId, config) {
|
|
5677
5927
|
const agentDir = getAgentDir(codeName);
|
|
5678
|
-
const mcpJsonPath =
|
|
5679
|
-
|
|
5928
|
+
const mcpJsonPath = join3(agentDir, "provision", ".mcp.json");
|
|
5929
|
+
mkdirSync3(join3(agentDir, "provision"), { recursive: true });
|
|
5680
5930
|
let mcpConfig;
|
|
5681
5931
|
try {
|
|
5682
|
-
mcpConfig = JSON.parse(
|
|
5932
|
+
mcpConfig = JSON.parse(readFileSync4(mcpJsonPath, "utf-8"));
|
|
5683
5933
|
} catch {
|
|
5684
5934
|
mcpConfig = { mcpServers: {} };
|
|
5685
5935
|
}
|
|
@@ -5723,7 +5973,7 @@ ${sections}`
|
|
|
5723
5973
|
}
|
|
5724
5974
|
},
|
|
5725
5975
|
getMcpPath(codeName) {
|
|
5726
|
-
return
|
|
5976
|
+
return join3(getAgentDir(codeName), "provision", ".mcp.json");
|
|
5727
5977
|
},
|
|
5728
5978
|
/**
|
|
5729
5979
|
* ENG-7994: the declared servers from `provision/.mcp.json`. Mirrors what the
|
|
@@ -5734,7 +5984,7 @@ ${sections}`
|
|
|
5734
5984
|
readMcpServers(codeName) {
|
|
5735
5985
|
let parsed;
|
|
5736
5986
|
try {
|
|
5737
|
-
parsed = JSON.parse(
|
|
5987
|
+
parsed = JSON.parse(readFileSync4(join3(getAgentDir(codeName), "provision", ".mcp.json"), "utf-8"));
|
|
5738
5988
|
} catch {
|
|
5739
5989
|
return {};
|
|
5740
5990
|
}
|
|
@@ -5747,10 +5997,10 @@ ${sections}`
|
|
|
5747
5997
|
},
|
|
5748
5998
|
removeMcpServer(codeName, serverId) {
|
|
5749
5999
|
const agentDir = getAgentDir(codeName);
|
|
5750
|
-
const mcpJsonPath =
|
|
6000
|
+
const mcpJsonPath = join3(agentDir, "provision", ".mcp.json");
|
|
5751
6001
|
let mcpConfig;
|
|
5752
6002
|
try {
|
|
5753
|
-
mcpConfig = JSON.parse(
|
|
6003
|
+
mcpConfig = JSON.parse(readFileSync4(mcpJsonPath, "utf-8"));
|
|
5754
6004
|
} catch {
|
|
5755
6005
|
return;
|
|
5756
6006
|
}
|
|
@@ -5769,27 +6019,27 @@ ${sections}`
|
|
|
5769
6019
|
const READ_WRITE_MODE = 420;
|
|
5770
6020
|
const agentDir = getAgentDir(codeName);
|
|
5771
6021
|
const projectDir = getProjectDir(codeName);
|
|
5772
|
-
for (const baseDir of [
|
|
5773
|
-
const skillDir =
|
|
5774
|
-
|
|
6022
|
+
for (const baseDir of [join3(agentDir, "skills"), join3(projectDir, ".claude", "skills")]) {
|
|
6023
|
+
const skillDir = join3(baseDir, skillId);
|
|
6024
|
+
mkdirSync3(skillDir, { recursive: true });
|
|
5775
6025
|
for (const file of files) {
|
|
5776
6026
|
assertSafeRelativePath(file.relativePath);
|
|
5777
|
-
const filePath =
|
|
6027
|
+
const filePath = join3(skillDir, file.relativePath);
|
|
5778
6028
|
const rel = relative(skillDir, filePath);
|
|
5779
6029
|
if (rel.startsWith("..") || rel === "") {
|
|
5780
6030
|
throw new Error(`Path traversal detected: ${file.relativePath} resolves outside ${skillDir}`);
|
|
5781
6031
|
}
|
|
5782
|
-
|
|
5783
|
-
if (isPluginManaged &&
|
|
6032
|
+
mkdirSync3(join3(filePath, ".."), { recursive: true });
|
|
6033
|
+
if (isPluginManaged && existsSync4(filePath)) {
|
|
5784
6034
|
try {
|
|
5785
|
-
|
|
6035
|
+
chmodSync4(filePath, READ_WRITE_MODE);
|
|
5786
6036
|
} catch {
|
|
5787
6037
|
}
|
|
5788
6038
|
}
|
|
5789
|
-
|
|
6039
|
+
writeFileSync4(filePath, file.content);
|
|
5790
6040
|
if (isPluginManaged) {
|
|
5791
6041
|
try {
|
|
5792
|
-
|
|
6042
|
+
chmodSync4(filePath, READ_ONLY_MODE);
|
|
5793
6043
|
} catch {
|
|
5794
6044
|
}
|
|
5795
6045
|
}
|
|
@@ -5798,11 +6048,11 @@ ${sections}`
|
|
|
5798
6048
|
},
|
|
5799
6049
|
installPlugin(codeName, pluginId, pluginPath, pluginConfig) {
|
|
5800
6050
|
const agentDir = getAgentDir(codeName);
|
|
5801
|
-
const pluginsJsonPath =
|
|
5802
|
-
|
|
6051
|
+
const pluginsJsonPath = join3(agentDir, "plugins.json");
|
|
6052
|
+
mkdirSync3(agentDir, { recursive: true });
|
|
5803
6053
|
let pluginsConfig;
|
|
5804
6054
|
try {
|
|
5805
|
-
pluginsConfig = JSON.parse(
|
|
6055
|
+
pluginsConfig = JSON.parse(readFileSync4(pluginsJsonPath, "utf-8"));
|
|
5806
6056
|
} catch {
|
|
5807
6057
|
pluginsConfig = { plugins: {} };
|
|
5808
6058
|
}
|
|
@@ -5815,7 +6065,7 @@ ${sections}`
|
|
|
5815
6065
|
installed_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
5816
6066
|
...pluginConfig ? { config: pluginConfig } : {}
|
|
5817
6067
|
};
|
|
5818
|
-
|
|
6068
|
+
writeFileSync4(pluginsJsonPath, JSON.stringify(pluginsConfig, null, 2));
|
|
5819
6069
|
},
|
|
5820
6070
|
/**
|
|
5821
6071
|
* Full plugin provisioning: install scripts, register hooks, apply permissions,
|
|
@@ -5831,11 +6081,11 @@ ${sections}`
|
|
|
5831
6081
|
assertValidCodeName(codeName);
|
|
5832
6082
|
assertValidCodeName(plugin.slug);
|
|
5833
6083
|
const projectDir = getProjectDir(codeName);
|
|
5834
|
-
const claudeDir =
|
|
5835
|
-
|
|
6084
|
+
const claudeDir = join3(projectDir, ".claude");
|
|
6085
|
+
mkdirSync3(claudeDir, { recursive: true });
|
|
5836
6086
|
const sourceSpec = options?.scriptSource ?? `augmented-plugin:${plugin.slug}`;
|
|
5837
6087
|
this.installPlugin(codeName, plugin.slug, sourceSpec, contextValues);
|
|
5838
|
-
const installedDir =
|
|
6088
|
+
const installedDir = join3(projectDir, ".claude", "plugins", plugin.slug);
|
|
5839
6089
|
for (const skill of plugin.skills) {
|
|
5840
6090
|
const skillId = skill.id;
|
|
5841
6091
|
assertValidCodeName(skillId);
|
|
@@ -5847,10 +6097,10 @@ ${sections}`
|
|
|
5847
6097
|
}
|
|
5848
6098
|
const scriptsConfig = plugin.scripts;
|
|
5849
6099
|
if (scriptsConfig?.hooks) {
|
|
5850
|
-
const settingsPath =
|
|
6100
|
+
const settingsPath = join3(claudeDir, "settings.local.json");
|
|
5851
6101
|
let settings = {};
|
|
5852
6102
|
try {
|
|
5853
|
-
settings = JSON.parse(
|
|
6103
|
+
settings = JSON.parse(readFileSync4(settingsPath, "utf-8"));
|
|
5854
6104
|
} catch {
|
|
5855
6105
|
}
|
|
5856
6106
|
const existingHooks = settings["hooks"] ?? {};
|
|
@@ -5884,13 +6134,13 @@ ${sections}`
|
|
|
5884
6134
|
}
|
|
5885
6135
|
}
|
|
5886
6136
|
settings["hooks"] = existingHooks;
|
|
5887
|
-
|
|
6137
|
+
writeFileSync4(settingsPath, JSON.stringify(settings, null, 2));
|
|
5888
6138
|
}
|
|
5889
6139
|
if (plugin.allowed_tools.length > 0) {
|
|
5890
|
-
const settingsPath =
|
|
6140
|
+
const settingsPath = join3(claudeDir, "settings.local.json");
|
|
5891
6141
|
let settings = {};
|
|
5892
6142
|
try {
|
|
5893
|
-
settings = JSON.parse(
|
|
6143
|
+
settings = JSON.parse(readFileSync4(settingsPath, "utf-8"));
|
|
5894
6144
|
} catch {
|
|
5895
6145
|
}
|
|
5896
6146
|
const existingPerms = settings["permissions"] ?? {};
|
|
@@ -5902,20 +6152,20 @@ ${sections}`
|
|
|
5902
6152
|
}
|
|
5903
6153
|
existingPerms["allow"] = allowList;
|
|
5904
6154
|
settings["permissions"] = existingPerms;
|
|
5905
|
-
|
|
6155
|
+
writeFileSync4(settingsPath, JSON.stringify(settings, null, 2));
|
|
5906
6156
|
}
|
|
5907
6157
|
if (contextValues && Object.keys(contextValues).length > 0) {
|
|
5908
|
-
const configDir =
|
|
5909
|
-
|
|
5910
|
-
|
|
6158
|
+
const configDir = join3(projectDir, `.${plugin.slug}`);
|
|
6159
|
+
mkdirSync3(configDir, { recursive: true });
|
|
6160
|
+
writeFileSync4(join3(configDir, "config.json"), JSON.stringify(contextValues, null, 2));
|
|
5911
6161
|
}
|
|
5912
6162
|
},
|
|
5913
6163
|
executePluginHook(ctx) {
|
|
5914
6164
|
assertValidCodeName(ctx.codeName);
|
|
5915
|
-
const agentRootDir =
|
|
6165
|
+
const agentRootDir = join3(getHomeDir(), ".augmented", ctx.codeName);
|
|
5916
6166
|
const projectDir = getProjectDir(ctx.codeName);
|
|
5917
|
-
|
|
5918
|
-
|
|
6167
|
+
mkdirSync3(agentRootDir, { recursive: true });
|
|
6168
|
+
mkdirSync3(projectDir, { recursive: true });
|
|
5919
6169
|
const startedAt = Date.now();
|
|
5920
6170
|
return new Promise((resolve) => {
|
|
5921
6171
|
const child = execFile("bash", ["-c", ctx.script], {
|
|
@@ -5951,7 +6201,7 @@ ${sections}`
|
|
|
5951
6201
|
},
|
|
5952
6202
|
writeTokenFile(codeName, integrations) {
|
|
5953
6203
|
const agentDir = getAgentDir(codeName);
|
|
5954
|
-
|
|
6204
|
+
mkdirSync3(agentDir, { recursive: true });
|
|
5955
6205
|
const tokens = {};
|
|
5956
6206
|
for (const integration of integrations) {
|
|
5957
6207
|
if (integration.auth_type !== "oauth2" && integration.auth_type !== "github_app")
|
|
@@ -5968,9 +6218,9 @@ ${sections}`
|
|
|
5968
6218
|
}
|
|
5969
6219
|
if (Object.keys(tokens).length === 0)
|
|
5970
6220
|
return;
|
|
5971
|
-
const tokenPath =
|
|
5972
|
-
|
|
5973
|
-
|
|
6221
|
+
const tokenPath = join3(agentDir, ".tokens.json");
|
|
6222
|
+
writeFileSync4(tokenPath, JSON.stringify(tokens, null, 2));
|
|
6223
|
+
chmodSync4(tokenPath, SECRET_FILE_MODE);
|
|
5974
6224
|
}
|
|
5975
6225
|
};
|
|
5976
6226
|
registerFramework(claudeCodeAdapter);
|
|
@@ -5992,14 +6242,14 @@ function jsonOutput(data) {
|
|
|
5992
6242
|
}
|
|
5993
6243
|
|
|
5994
6244
|
// src/lib/config.ts
|
|
5995
|
-
import { readFileSync as
|
|
5996
|
-
import { join as
|
|
5997
|
-
import { homedir as
|
|
5998
|
-
var AUGMENTED_DIR =
|
|
5999
|
-
var CONFIG_PATH =
|
|
6245
|
+
import { readFileSync as readFileSync5, writeFileSync as writeFileSync5, mkdirSync as mkdirSync4, existsSync as existsSync5 } from "fs";
|
|
6246
|
+
import { join as join4 } from "path";
|
|
6247
|
+
import { homedir as homedir4 } from "os";
|
|
6248
|
+
var AUGMENTED_DIR = join4(homedir4(), ".augmented");
|
|
6249
|
+
var CONFIG_PATH = join4(AUGMENTED_DIR, "config.json");
|
|
6000
6250
|
function ensureAugmentedDir() {
|
|
6001
|
-
if (!
|
|
6002
|
-
|
|
6251
|
+
if (!existsSync5(AUGMENTED_DIR)) {
|
|
6252
|
+
mkdirSync4(AUGMENTED_DIR, { recursive: true });
|
|
6003
6253
|
}
|
|
6004
6254
|
}
|
|
6005
6255
|
function reloadFromShellProfile() {
|
|
@@ -6008,11 +6258,11 @@ function reloadFromShellProfile() {
|
|
|
6008
6258
|
function loadFromShellProfile(force = false) {
|
|
6009
6259
|
if (!force && process.env["AGT_HOST"] && process.env["AGT_API_KEY"]) return;
|
|
6010
6260
|
const shell = process.env["SHELL"] ?? "";
|
|
6011
|
-
const home =
|
|
6012
|
-
const candidates = shell.includes("zsh") ? [
|
|
6261
|
+
const home = homedir4();
|
|
6262
|
+
const candidates = shell.includes("zsh") ? [join4(home, ".zshrc"), join4(home, ".zprofile")] : shell.includes("fish") ? [join4(home, ".config", "fish", "config.fish")] : [join4(home, ".bashrc"), join4(home, ".bash_profile")];
|
|
6013
6263
|
for (const profile of candidates) {
|
|
6014
6264
|
try {
|
|
6015
|
-
const content =
|
|
6265
|
+
const content = readFileSync5(profile, "utf-8");
|
|
6016
6266
|
for (const key of ["AGT_HOST", "AGT_API_KEY", "AGT_TEAM"]) {
|
|
6017
6267
|
if (!force && process.env[key]) continue;
|
|
6018
6268
|
const match = content.split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#")).map(
|
|
@@ -6037,7 +6287,7 @@ function getApiKey() {
|
|
|
6037
6287
|
}
|
|
6038
6288
|
function getConfig() {
|
|
6039
6289
|
try {
|
|
6040
|
-
const raw =
|
|
6290
|
+
const raw = readFileSync5(CONFIG_PATH, "utf-8");
|
|
6041
6291
|
return JSON.parse(raw);
|
|
6042
6292
|
} catch {
|
|
6043
6293
|
return {};
|
|
@@ -6045,7 +6295,7 @@ function getConfig() {
|
|
|
6045
6295
|
}
|
|
6046
6296
|
function saveConfig(config) {
|
|
6047
6297
|
ensureAugmentedDir();
|
|
6048
|
-
|
|
6298
|
+
writeFileSync5(CONFIG_PATH, JSON.stringify(config, null, 2));
|
|
6049
6299
|
}
|
|
6050
6300
|
function getActiveTeam() {
|
|
6051
6301
|
const envTeam = process.env["AGT_TEAM"];
|
|
@@ -6092,7 +6342,7 @@ function exchangeFailureKind(err) {
|
|
|
6092
6342
|
}
|
|
6093
6343
|
|
|
6094
6344
|
// src/lib/api-client.ts
|
|
6095
|
-
var agtCliVersion = true ? "0.28.
|
|
6345
|
+
var agtCliVersion = true ? "0.28.660" : "dev";
|
|
6096
6346
|
var lastConfigHash = null;
|
|
6097
6347
|
function setConfigHash(hash) {
|
|
6098
6348
|
lastConfigHash = hash && hash.length > 0 ? hash : null;
|
|
@@ -6342,13 +6592,13 @@ async function getHostId() {
|
|
|
6342
6592
|
}
|
|
6343
6593
|
|
|
6344
6594
|
// src/lib/atomic-write.ts
|
|
6345
|
-
import { closeSync, fsyncSync, openSync, writeSync, renameSync as
|
|
6346
|
-
import { dirname as
|
|
6595
|
+
import { closeSync, fsyncSync, openSync, writeSync, renameSync as renameSync5, mkdirSync as mkdirSync5 } from "fs";
|
|
6596
|
+
import { dirname as dirname4 } from "path";
|
|
6347
6597
|
function atomicWriteFileSync(path, data) {
|
|
6348
|
-
const dirPath =
|
|
6598
|
+
const dirPath = dirname4(path);
|
|
6349
6599
|
const tmpPath = `${path}.tmp.${process.pid}.${Math.random().toString(36).slice(2, 8)}`;
|
|
6350
6600
|
try {
|
|
6351
|
-
|
|
6601
|
+
mkdirSync5(dirPath, { recursive: true });
|
|
6352
6602
|
} catch {
|
|
6353
6603
|
}
|
|
6354
6604
|
const fd = openSync(tmpPath, "w", 420);
|
|
@@ -6361,7 +6611,7 @@ function atomicWriteFileSync(path, data) {
|
|
|
6361
6611
|
} finally {
|
|
6362
6612
|
closeSync(fd);
|
|
6363
6613
|
}
|
|
6364
|
-
|
|
6614
|
+
renameSync5(tmpPath, path);
|
|
6365
6615
|
try {
|
|
6366
6616
|
const dirFd = openSync(dirPath, "r");
|
|
6367
6617
|
try {
|
|
@@ -6374,15 +6624,15 @@ function atomicWriteFileSync(path, data) {
|
|
|
6374
6624
|
}
|
|
6375
6625
|
|
|
6376
6626
|
// src/lib/feature-flags-host.ts
|
|
6377
|
-
import { existsSync as
|
|
6378
|
-
import { join as
|
|
6627
|
+
import { existsSync as existsSync6, readFileSync as readFileSync6, statSync as statSync2 } from "fs";
|
|
6628
|
+
import { join as join5 } from "path";
|
|
6379
6629
|
function defaultFlagsCachePath(configDir) {
|
|
6380
|
-
return
|
|
6630
|
+
return join5(configDir, "flags-cache.json");
|
|
6381
6631
|
}
|
|
6382
6632
|
function readFlagsCache(path) {
|
|
6383
6633
|
try {
|
|
6384
|
-
if (!
|
|
6385
|
-
const parsed = JSON.parse(
|
|
6634
|
+
if (!existsSync6(path)) return null;
|
|
6635
|
+
const parsed = JSON.parse(readFileSync6(path, "utf8"));
|
|
6386
6636
|
if (!parsed || typeof parsed !== "object") return null;
|
|
6387
6637
|
const obj = parsed;
|
|
6388
6638
|
const flags = obj["flags"];
|
|
@@ -6408,7 +6658,7 @@ function flagsCacheAgeSeconds(cache, path, now = /* @__PURE__ */ new Date()) {
|
|
|
6408
6658
|
return Math.max(0, (now.getTime() - fromRecorded) / 1e3);
|
|
6409
6659
|
}
|
|
6410
6660
|
try {
|
|
6411
|
-
return Math.max(0, (now.getTime() -
|
|
6661
|
+
return Math.max(0, (now.getTime() - statSync2(path).mtimeMs) / 1e3);
|
|
6412
6662
|
} catch {
|
|
6413
6663
|
return null;
|
|
6414
6664
|
}
|
|
@@ -8008,8 +8258,8 @@ function verdictForUnavailableMcpConfig(cause, ctx) {
|
|
|
8008
8258
|
}
|
|
8009
8259
|
|
|
8010
8260
|
// src/lib/connectivity-probe-context.ts
|
|
8011
|
-
import { delimiter as pathDelimiter, join as
|
|
8012
|
-
import { existsSync as
|
|
8261
|
+
import { delimiter as pathDelimiter, join as join6 } from "path";
|
|
8262
|
+
import { existsSync as existsSync7, readFileSync as readFileSync7 } from "fs";
|
|
8013
8263
|
|
|
8014
8264
|
// src/lib/mcp-stdio-probe.ts
|
|
8015
8265
|
import { spawn } from "child_process";
|
|
@@ -8520,7 +8770,7 @@ function resolveHttpServerEntry(entry, env) {
|
|
|
8520
8770
|
function readMcpHttpServerConfig(projectDir, serverKey, env) {
|
|
8521
8771
|
let servers;
|
|
8522
8772
|
try {
|
|
8523
|
-
const raw =
|
|
8773
|
+
const raw = readFileSync7(join6(projectDir, ".mcp.json"), "utf-8");
|
|
8524
8774
|
servers = JSON.parse(raw).mcpServers ?? {};
|
|
8525
8775
|
} catch {
|
|
8526
8776
|
return { ok: false, cause: "file-unreadable" };
|
|
@@ -8532,7 +8782,7 @@ function readMcpHttpServerConfig(projectDir, serverKey, env) {
|
|
|
8532
8782
|
}
|
|
8533
8783
|
function resolveDeclaredServerKey(projectDir, definitionId, derivedKey) {
|
|
8534
8784
|
try {
|
|
8535
|
-
const raw =
|
|
8785
|
+
const raw = readFileSync7(join6(projectDir, ".mcp.json"), "utf-8");
|
|
8536
8786
|
const servers = JSON.parse(raw).mcpServers ?? {};
|
|
8537
8787
|
const declared = Object.keys(servers);
|
|
8538
8788
|
if (derivedKey !== definitionId && derivedKey !== sanitizeServerKey(definitionId)) {
|
|
@@ -8574,7 +8824,7 @@ function resolveStdioServerEntry(entry, env) {
|
|
|
8574
8824
|
function readMcpStdioServerConfig(projectDir, serverKey, env) {
|
|
8575
8825
|
let servers;
|
|
8576
8826
|
try {
|
|
8577
|
-
const raw =
|
|
8827
|
+
const raw = readFileSync7(join6(projectDir, ".mcp.json"), "utf-8");
|
|
8578
8828
|
servers = JSON.parse(raw).mcpServers ?? {};
|
|
8579
8829
|
} catch {
|
|
8580
8830
|
return { ok: false, cause: "file-unreadable" };
|
|
@@ -8600,9 +8850,9 @@ function deriveMcpServerKey(input) {
|
|
|
8600
8850
|
function buildProbeEnv(projectDir, agentId) {
|
|
8601
8851
|
const probeEnv = { ...process.env };
|
|
8602
8852
|
try {
|
|
8603
|
-
const envIntPath =
|
|
8604
|
-
if (
|
|
8605
|
-
Object.assign(probeEnv, parseEnvIntegrations(
|
|
8853
|
+
const envIntPath = join6(projectDir, ".env.integrations");
|
|
8854
|
+
if (existsSync7(envIntPath)) {
|
|
8855
|
+
Object.assign(probeEnv, parseEnvIntegrations(readFileSync7(envIntPath, "utf-8")));
|
|
8606
8856
|
}
|
|
8607
8857
|
} catch {
|
|
8608
8858
|
}
|
|
@@ -8610,8 +8860,8 @@ function buildProbeEnv(projectDir, agentId) {
|
|
|
8610
8860
|
probeEnv.AGT_AGENT_ID = agentId.trim();
|
|
8611
8861
|
}
|
|
8612
8862
|
try {
|
|
8613
|
-
const agentBinDir =
|
|
8614
|
-
if (
|
|
8863
|
+
const agentBinDir = join6(projectDir, ".claude", "agt-bin");
|
|
8864
|
+
if (existsSync7(agentBinDir)) {
|
|
8615
8865
|
probeEnv.PATH = probeEnv.PATH ? `${agentBinDir}${pathDelimiter}${probeEnv.PATH}` : agentBinDir;
|
|
8616
8866
|
}
|
|
8617
8867
|
} catch {
|
|
@@ -8747,9 +8997,9 @@ function buildConnectivityProbeDeps(projectDir, probeEnv) {
|
|
|
8747
8997
|
|
|
8748
8998
|
// src/lib/session-tool-bind-probe-host.ts
|
|
8749
8999
|
import { execFileSync as syncExecFile } from "child_process";
|
|
8750
|
-
import { readFileSync as
|
|
8751
|
-
import { join as
|
|
8752
|
-
import { dirname as
|
|
9000
|
+
import { readFileSync as readFileSync8 } from "fs";
|
|
9001
|
+
import { join as join7 } from "path";
|
|
9002
|
+
import { dirname as dirname5 } from "path";
|
|
8753
9003
|
function deliveryFields(i) {
|
|
8754
9004
|
const keys = ["source_type", "provider", "mcp_command", "mcp_url", "cli_binary", "cli_package"];
|
|
8755
9005
|
const out = {};
|
|
@@ -8762,7 +9012,7 @@ async function gatherSessionToolBindProbe(agent, integrations, projectDir, opts)
|
|
|
8762
9012
|
if (integrations.length === 0) return null;
|
|
8763
9013
|
let mcpRaw = null;
|
|
8764
9014
|
try {
|
|
8765
|
-
mcpRaw =
|
|
9015
|
+
mcpRaw = readFileSync8(join7(projectDir, ".mcp.json"), "utf-8");
|
|
8766
9016
|
} catch {
|
|
8767
9017
|
mcpRaw = null;
|
|
8768
9018
|
}
|
|
@@ -8855,7 +9105,7 @@ var SLACK_MCP_SERVER_KEY = "slack";
|
|
|
8855
9105
|
function readSlackTransportDownKeys(projectDir) {
|
|
8856
9106
|
const none = /* @__PURE__ */ new Set();
|
|
8857
9107
|
try {
|
|
8858
|
-
const raw =
|
|
9108
|
+
const raw = readFileSync8(join7(dirname5(projectDir), SLACK_SOCKET_STATE_FILENAME), "utf-8");
|
|
8859
9109
|
const state = parseSlackSocketState(raw, Date.now());
|
|
8860
9110
|
return isSlackInboundTransportDown(state, SLACK_TRANSPORT_DOWN_AFTER_MS) ? /* @__PURE__ */ new Set([SLACK_MCP_SERVER_KEY]) : none;
|
|
8861
9111
|
} catch {
|
|
@@ -8971,35 +9221,35 @@ function decidePin(opts) {
|
|
|
8971
9221
|
|
|
8972
9222
|
// src/commands/manager.ts
|
|
8973
9223
|
import chalk3 from "chalk";
|
|
8974
|
-
import { existsSync as
|
|
8975
|
-
import { join as
|
|
8976
|
-
import { homedir as
|
|
9224
|
+
import { existsSync as existsSync9, realpathSync as realpathSync2 } from "fs";
|
|
9225
|
+
import { join as join9 } from "path";
|
|
9226
|
+
import { homedir as homedir5, userInfo } from "os";
|
|
8977
9227
|
import { spawn as spawn3 } from "child_process";
|
|
8978
9228
|
|
|
8979
9229
|
// src/lib/watchdog.ts
|
|
8980
|
-
import { readFileSync as
|
|
8981
|
-
import { join as
|
|
9230
|
+
import { readFileSync as readFileSync9, writeFileSync as writeFileSync6, unlinkSync as unlinkSync4, existsSync as existsSync8, mkdirSync as mkdirSync6, openSync as openSync2, closeSync as closeSync2, chmodSync as chmodSync5 } from "fs";
|
|
9231
|
+
import { join as join8 } from "path";
|
|
8982
9232
|
import { spawn as spawn2, execFileSync as execFileSync3 } from "child_process";
|
|
8983
|
-
var DEFAULT_CONFIG_DIR =
|
|
9233
|
+
var DEFAULT_CONFIG_DIR = join8(process.env["HOME"] ?? "/tmp", ".augmented");
|
|
8984
9234
|
function getManagerPaths(configDir) {
|
|
8985
9235
|
return {
|
|
8986
|
-
pidFile:
|
|
8987
|
-
stateFile:
|
|
8988
|
-
logFile:
|
|
9236
|
+
pidFile: join8(configDir, "manager.pid"),
|
|
9237
|
+
stateFile: join8(configDir, "manager-state.json"),
|
|
9238
|
+
logFile: join8(configDir, "manager.log")
|
|
8989
9239
|
};
|
|
8990
9240
|
}
|
|
8991
9241
|
function ensureDir(configDir) {
|
|
8992
|
-
if (!
|
|
8993
|
-
|
|
9242
|
+
if (!existsSync8(configDir)) {
|
|
9243
|
+
mkdirSync6(configDir, { recursive: true });
|
|
8994
9244
|
}
|
|
8995
9245
|
}
|
|
8996
9246
|
function writePidFile(configDir, pid) {
|
|
8997
9247
|
ensureDir(configDir);
|
|
8998
|
-
|
|
9248
|
+
writeFileSync6(getManagerPaths(configDir).pidFile, String(pid), { mode: 384 });
|
|
8999
9249
|
}
|
|
9000
9250
|
function readPidFile(configDir) {
|
|
9001
9251
|
try {
|
|
9002
|
-
const raw =
|
|
9252
|
+
const raw = readFileSync9(getManagerPaths(configDir).pidFile, "utf-8").trim();
|
|
9003
9253
|
const pid = parseInt(raw, 10);
|
|
9004
9254
|
return isNaN(pid) ? null : pid;
|
|
9005
9255
|
} catch {
|
|
@@ -9008,7 +9258,7 @@ function readPidFile(configDir) {
|
|
|
9008
9258
|
}
|
|
9009
9259
|
function removePidFile(configDir) {
|
|
9010
9260
|
try {
|
|
9011
|
-
|
|
9261
|
+
unlinkSync4(getManagerPaths(configDir).pidFile);
|
|
9012
9262
|
} catch {
|
|
9013
9263
|
}
|
|
9014
9264
|
}
|
|
@@ -9045,7 +9295,7 @@ function defaultPgrep() {
|
|
|
9045
9295
|
}
|
|
9046
9296
|
function readStateFile(configDir) {
|
|
9047
9297
|
try {
|
|
9048
|
-
const raw =
|
|
9298
|
+
const raw = readFileSync9(getManagerPaths(configDir).stateFile, "utf-8");
|
|
9049
9299
|
return JSON.parse(raw);
|
|
9050
9300
|
} catch {
|
|
9051
9301
|
return null;
|
|
@@ -9053,7 +9303,7 @@ function readStateFile(configDir) {
|
|
|
9053
9303
|
}
|
|
9054
9304
|
function removeStateFile(configDir) {
|
|
9055
9305
|
try {
|
|
9056
|
-
|
|
9306
|
+
unlinkSync4(getManagerPaths(configDir).stateFile);
|
|
9057
9307
|
} catch {
|
|
9058
9308
|
}
|
|
9059
9309
|
}
|
|
@@ -9079,7 +9329,7 @@ function startWatchdog(opts) {
|
|
|
9079
9329
|
const { logFile } = getManagerPaths(configDir);
|
|
9080
9330
|
const logFd = openSync2(logFile, "a", 384);
|
|
9081
9331
|
try {
|
|
9082
|
-
|
|
9332
|
+
chmodSync5(logFile, 384);
|
|
9083
9333
|
} catch {
|
|
9084
9334
|
}
|
|
9085
9335
|
const intervalSec = String(Math.max(Math.floor(opts.intervalMs / 1e3), 5));
|
|
@@ -9101,7 +9351,7 @@ function startWatchdog(opts) {
|
|
|
9101
9351
|
const deadline = Date.now() + 5e3;
|
|
9102
9352
|
const sleepBuf = new Int32Array(new SharedArrayBuffer(4));
|
|
9103
9353
|
while (Date.now() < deadline) {
|
|
9104
|
-
if (
|
|
9354
|
+
if (existsSync8(pidFile)) {
|
|
9105
9355
|
return { pid: child.pid };
|
|
9106
9356
|
}
|
|
9107
9357
|
if (child.exitCode !== null) {
|
|
@@ -9207,7 +9457,7 @@ function normalizePinInEnv(env) {
|
|
|
9207
9457
|
function managerStartCommand(opts) {
|
|
9208
9458
|
const json = isJsonMode();
|
|
9209
9459
|
if (!process.env.HOME || !process.env.HOME.trim()) {
|
|
9210
|
-
const fallback =
|
|
9460
|
+
const fallback = homedir5();
|
|
9211
9461
|
process.env.HOME = fallback;
|
|
9212
9462
|
if (!json) {
|
|
9213
9463
|
info(`HOME was not set in the manager env \u2014 defaulting to ${fallback}.`);
|
|
@@ -9241,7 +9491,7 @@ function managerStartCommand(opts) {
|
|
|
9241
9491
|
process.exitCode = 1;
|
|
9242
9492
|
return;
|
|
9243
9493
|
}
|
|
9244
|
-
const configDir = opts.configDir ??
|
|
9494
|
+
const configDir = opts.configDir ?? join9(homedir5(), ".augmented");
|
|
9245
9495
|
if (opts.supervise) {
|
|
9246
9496
|
if (json) {
|
|
9247
9497
|
jsonOutput({ ok: false, error: "--supervise is not supported with --json" });
|
|
@@ -9337,7 +9587,7 @@ function runSupervisorLoop(intervalSec, configDir) {
|
|
|
9337
9587
|
}
|
|
9338
9588
|
async function managerStopCommand(opts = {}) {
|
|
9339
9589
|
const json = isJsonMode();
|
|
9340
|
-
const configDir = opts.configDir ??
|
|
9590
|
+
const configDir = opts.configDir ?? join9(homedir5(), ".augmented");
|
|
9341
9591
|
try {
|
|
9342
9592
|
const result = await stopWatchdog(configDir);
|
|
9343
9593
|
if (!result.stopped && !result.pid) {
|
|
@@ -9365,7 +9615,7 @@ async function managerStopCommand(opts = {}) {
|
|
|
9365
9615
|
}
|
|
9366
9616
|
function managerStatusCommand(opts = {}) {
|
|
9367
9617
|
const json = isJsonMode();
|
|
9368
|
-
const configDir = opts.configDir ??
|
|
9618
|
+
const configDir = opts.configDir ?? join9(homedir5(), ".augmented");
|
|
9369
9619
|
const status = getManagerStatus(configDir);
|
|
9370
9620
|
if (!status) {
|
|
9371
9621
|
if (json) {
|
|
@@ -9437,7 +9687,7 @@ function resolveStableAgtBin(rawPath) {
|
|
|
9437
9687
|
if (!prefix || !formula) return rawPath;
|
|
9438
9688
|
const candidates = [`${prefix}/bin/${formula}`, `${prefix}/bin/agt`];
|
|
9439
9689
|
for (const candidate of candidates) {
|
|
9440
|
-
if (!
|
|
9690
|
+
if (!existsSync9(candidate)) continue;
|
|
9441
9691
|
try {
|
|
9442
9692
|
realpathSync2(candidate);
|
|
9443
9693
|
return candidate;
|
|
@@ -9457,7 +9707,7 @@ async function managerInstallCommand(opts = {}) {
|
|
|
9457
9707
|
process.exitCode = 1;
|
|
9458
9708
|
return;
|
|
9459
9709
|
}
|
|
9460
|
-
const configDir = opts.configDir ??
|
|
9710
|
+
const configDir = opts.configDir ?? join9(homedir5(), ".augmented");
|
|
9461
9711
|
const rawAgtBin = process.argv[1];
|
|
9462
9712
|
if (!rawAgtBin) {
|
|
9463
9713
|
const msg = "Could not resolve the agt binary path from argv. Re-run via the installed `agt` command.";
|
|
@@ -9468,9 +9718,9 @@ async function managerInstallCommand(opts = {}) {
|
|
|
9468
9718
|
}
|
|
9469
9719
|
const agtBin = resolveStableAgtBin(rawAgtBin);
|
|
9470
9720
|
if (process.platform === "darwin") {
|
|
9471
|
-
const home =
|
|
9721
|
+
const home = homedir5();
|
|
9472
9722
|
const protectedRoots = ["Documents", "Downloads", "Desktop", "Movies", "Music", "Pictures"];
|
|
9473
|
-
const offending = protectedRoots.map((r) =>
|
|
9723
|
+
const offending = protectedRoots.map((r) => join9(home, r)).find((p) => agtBin === p || agtBin.startsWith(`${p}/`));
|
|
9474
9724
|
if (offending) {
|
|
9475
9725
|
const msg = `agt binary at ${agtBin} sits inside a macOS TCC-protected folder (${offending}). launchd-spawned processes cannot read files there and the manager would EPERM on startup. Either install agt globally (\`npm install -g @integrity-labs/agt-cli\`) or copy the dist outside protected folders before running this command.`;
|
|
9476
9726
|
if (json) jsonOutput({ ok: false, error: msg });
|
|
@@ -9483,7 +9733,7 @@ async function managerInstallCommand(opts = {}) {
|
|
|
9483
9733
|
AGT_HOST: getHost(),
|
|
9484
9734
|
// ?? alone wouldn't catch `HOME=""` from a stripped systemd env.
|
|
9485
9735
|
// Treat empty / whitespace-only as missing.
|
|
9486
|
-
HOME: process.env.HOME?.trim() ||
|
|
9736
|
+
HOME: process.env.HOME?.trim() || homedir5(),
|
|
9487
9737
|
USER: process.env.USER?.trim() || userInfo().username
|
|
9488
9738
|
};
|
|
9489
9739
|
const apiKey = getApiKey();
|
|
@@ -9539,7 +9789,7 @@ async function managerInstallSystemUnitCommand(opts = {}) {
|
|
|
9539
9789
|
return;
|
|
9540
9790
|
}
|
|
9541
9791
|
const user = opts.user ?? "root";
|
|
9542
|
-
const configDir = opts.configDir ?? (user === "root" ? "/root/.augmented" :
|
|
9792
|
+
const configDir = opts.configDir ?? (user === "root" ? "/root/.augmented" : join9("/home", user, ".augmented"));
|
|
9543
9793
|
const rawAgtBin = process.argv[1];
|
|
9544
9794
|
if (!rawAgtBin) {
|
|
9545
9795
|
const msg = "Could not resolve the agt binary path from argv. Re-run via the installed `agt` command.";
|
|
@@ -9834,4 +10084,4 @@ export {
|
|
|
9834
10084
|
managerInstallSystemUnitCommand,
|
|
9835
10085
|
managerUninstallSystemUnitCommand
|
|
9836
10086
|
};
|
|
9837
|
-
//# sourceMappingURL=chunk-
|
|
10087
|
+
//# sourceMappingURL=chunk-ESEOTR5J.js.map
|