@integrity-labs/agt-cli 0.28.691 → 0.28.692
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-2GNXBVWJ.js → chunk-7K2I4LJZ.js} +12 -25
- package/dist/chunk-7K2I4LJZ.js.map +1 -0
- package/dist/{chunk-ZY57BJYH.js → chunk-ITB6NEXM.js} +430 -628
- package/dist/chunk-ITB6NEXM.js.map +1 -0
- package/dist/{chunk-XF2B7JHC.js → chunk-WHW747J3.js} +2 -2
- package/dist/{claude-pair-runtime-PDOGREOQ.js → claude-pair-runtime-ENI5O3JA.js} +2 -2
- package/dist/lib/manager-worker.js +13 -15
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/mcp/direct-chat-channel.js +11 -24
- package/dist/mcp/index.js +11 -24
- package/dist/mcp/origami.js +11 -24
- package/dist/mcp/slack-channel.js +11 -24
- package/dist/mcp/telegram-channel.js +11 -24
- package/dist/{persistent-session-LVBNKFMF.js → persistent-session-42FL5BEW.js} +3 -3
- package/dist/{responsiveness-probe-T52RFYK3.js → responsiveness-probe-RG2SD7HX.js} +3 -3
- package/dist/{session-auth-dead-MV6C7TBH.js → session-auth-dead-SHLP7FRQ.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-2GNXBVWJ.js.map +0 -1
- package/dist/chunk-ZY57BJYH.js.map +0 -1
- /package/dist/{chunk-XF2B7JHC.js.map → chunk-WHW747J3.js.map} +0 -0
- /package/dist/{claude-pair-runtime-PDOGREOQ.js.map → claude-pair-runtime-ENI5O3JA.js.map} +0 -0
- /package/dist/{persistent-session-LVBNKFMF.js.map → persistent-session-42FL5BEW.js.map} +0 -0
- /package/dist/{responsiveness-probe-T52RFYK3.js.map → responsiveness-probe-RG2SD7HX.js.map} +0 -0
- /package/dist/{session-auth-dead-MV6C7TBH.js.map → session-auth-dead-SHLP7FRQ.js.map} +0 -0
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
parseEnvFileEntries,
|
|
13
13
|
parseEnvIntegrations,
|
|
14
14
|
shellQuote
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-WHW747J3.js";
|
|
16
16
|
import {
|
|
17
17
|
BIND_FAILURE_QUARANTINE_THRESHOLD,
|
|
18
18
|
INTEGRATIONS_SECTION_END,
|
|
@@ -59,7 +59,7 @@ import {
|
|
|
59
59
|
resolveConnectivityProbe,
|
|
60
60
|
worseConnectivityOutcome,
|
|
61
61
|
wrapScheduledTaskPrompt
|
|
62
|
-
} from "./chunk-
|
|
62
|
+
} from "./chunk-7K2I4LJZ.js";
|
|
63
63
|
import {
|
|
64
64
|
parsePsRows
|
|
65
65
|
} from "./chunk-XWVM4KPK.js";
|
|
@@ -369,182 +369,6 @@ function formatMirrorMismatch(m) {
|
|
|
369
369
|
return `[mcp-mirror] [parity-violation] server=${m.server} field=${m.field} location=${m.location} reason=${m.reason}`;
|
|
370
370
|
}
|
|
371
371
|
|
|
372
|
-
// ../../packages/core/dist/provisioning/secret-file-tmpfs.js
|
|
373
|
-
import { statfsSync, accessSync, constants as fsConstants, lstatSync, readlinkSync, readFileSync as readFileSync2, writeFileSync as writeFileSync2, mkdirSync, chmodSync as chmodSync2, rmSync, symlinkSync, existsSync as existsSync2 } from "fs";
|
|
374
|
-
import { dirname, join } from "path";
|
|
375
|
-
var SECRET_FILE_MODE = 384;
|
|
376
|
-
var TMPFS_MAGIC = 16914836;
|
|
377
|
-
var DEFAULT_TMPFS_CANDIDATES = ["/dev/shm", "/run"];
|
|
378
|
-
var TMPFS_SECRETS_SUBDIR = "augmented-secrets";
|
|
379
|
-
var backingEnabled = false;
|
|
380
|
-
var cachedBase;
|
|
381
|
-
var baseOverride;
|
|
382
|
-
function setSecretFileTmpfsBacking(enabled) {
|
|
383
|
-
backingEnabled = enabled;
|
|
384
|
-
}
|
|
385
|
-
function isSecretFileTmpfsBackingEnabled() {
|
|
386
|
-
return backingEnabled;
|
|
387
|
-
}
|
|
388
|
-
function resolveTmpfsBase(candidates = DEFAULT_TMPFS_CANDIDATES) {
|
|
389
|
-
if (baseOverride !== void 0)
|
|
390
|
-
return baseOverride;
|
|
391
|
-
if (cachedBase !== void 0)
|
|
392
|
-
return cachedBase;
|
|
393
|
-
cachedBase = null;
|
|
394
|
-
for (const cand of candidates) {
|
|
395
|
-
try {
|
|
396
|
-
if (Number(statfsSync(cand).type) !== TMPFS_MAGIC)
|
|
397
|
-
continue;
|
|
398
|
-
accessSync(cand, fsConstants.W_OK);
|
|
399
|
-
cachedBase = cand;
|
|
400
|
-
break;
|
|
401
|
-
} catch {
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
return cachedBase;
|
|
405
|
-
}
|
|
406
|
-
function ensureSafeSecretsRoot(base) {
|
|
407
|
-
const root = join(base, TMPFS_SECRETS_SUBDIR);
|
|
408
|
-
try {
|
|
409
|
-
mkdirSync(root, { recursive: true, mode: 448 });
|
|
410
|
-
} catch {
|
|
411
|
-
return null;
|
|
412
|
-
}
|
|
413
|
-
let st;
|
|
414
|
-
try {
|
|
415
|
-
st = lstatSync(root);
|
|
416
|
-
} catch {
|
|
417
|
-
return null;
|
|
418
|
-
}
|
|
419
|
-
if (st.isSymbolicLink() || !st.isDirectory())
|
|
420
|
-
return null;
|
|
421
|
-
const uid = typeof process.getuid === "function" ? process.getuid() : void 0;
|
|
422
|
-
if (uid !== void 0 && st.uid !== uid)
|
|
423
|
-
return null;
|
|
424
|
-
if ((st.mode & 63) !== 0) {
|
|
425
|
-
try {
|
|
426
|
-
chmodSync2(root, 448);
|
|
427
|
-
if ((lstatSync(root).mode & 63) !== 0)
|
|
428
|
-
return null;
|
|
429
|
-
} catch {
|
|
430
|
-
return null;
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
|
-
return root;
|
|
434
|
-
}
|
|
435
|
-
function ensureTmpfsTargetSeeded(tmpfsTarget, migratedContent, mode) {
|
|
436
|
-
let exists = true;
|
|
437
|
-
let empty = false;
|
|
438
|
-
try {
|
|
439
|
-
empty = readFileSync2(tmpfsTarget, "utf-8").length === 0;
|
|
440
|
-
} catch {
|
|
441
|
-
exists = false;
|
|
442
|
-
}
|
|
443
|
-
if (!exists) {
|
|
444
|
-
writeFileSync2(tmpfsTarget, migratedContent ?? "", { mode });
|
|
445
|
-
} else if (empty && migratedContent !== null) {
|
|
446
|
-
writeFileSync2(tmpfsTarget, migratedContent, { mode });
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
|
-
function ensureSecretFileTmpfsBacked(persistentPath, tmpfsTarget, mode = SECRET_FILE_MODE) {
|
|
450
|
-
mkdirSync(dirname(tmpfsTarget), { recursive: true, mode: 448 });
|
|
451
|
-
let migratedContent = null;
|
|
452
|
-
let alreadyLinked = false;
|
|
453
|
-
try {
|
|
454
|
-
const st = lstatSync(persistentPath);
|
|
455
|
-
if (st.isSymbolicLink()) {
|
|
456
|
-
if (readlinkSync(persistentPath) === tmpfsTarget) {
|
|
457
|
-
alreadyLinked = true;
|
|
458
|
-
} else {
|
|
459
|
-
rmSync(persistentPath, { force: true });
|
|
460
|
-
}
|
|
461
|
-
} else {
|
|
462
|
-
try {
|
|
463
|
-
migratedContent = readFileSync2(persistentPath, "utf-8");
|
|
464
|
-
} catch {
|
|
465
|
-
migratedContent = null;
|
|
466
|
-
}
|
|
467
|
-
rmSync(persistentPath, { force: true });
|
|
468
|
-
}
|
|
469
|
-
} catch {
|
|
470
|
-
}
|
|
471
|
-
ensureTmpfsTargetSeeded(tmpfsTarget, migratedContent, mode);
|
|
472
|
-
if (alreadyLinked)
|
|
473
|
-
return { backed: true, migrated: false };
|
|
474
|
-
mkdirSync(dirname(persistentPath), { recursive: true });
|
|
475
|
-
symlinkSync(tmpfsTarget, persistentPath);
|
|
476
|
-
return { backed: true, migrated: migratedContent !== null };
|
|
477
|
-
}
|
|
478
|
-
function healTmpfsSecretSymlink(persistentPath, expectedTarget) {
|
|
479
|
-
let target;
|
|
480
|
-
try {
|
|
481
|
-
if (!lstatSync(persistentPath).isSymbolicLink())
|
|
482
|
-
return false;
|
|
483
|
-
target = readlinkSync(persistentPath);
|
|
484
|
-
} catch {
|
|
485
|
-
return false;
|
|
486
|
-
}
|
|
487
|
-
if (target !== expectedTarget)
|
|
488
|
-
return false;
|
|
489
|
-
if (existsSync2(target))
|
|
490
|
-
return false;
|
|
491
|
-
try {
|
|
492
|
-
mkdirSync(dirname(target), { recursive: true, mode: 448 });
|
|
493
|
-
writeFileSync2(target, "", { mode: SECRET_FILE_MODE });
|
|
494
|
-
return true;
|
|
495
|
-
} catch {
|
|
496
|
-
return false;
|
|
497
|
-
}
|
|
498
|
-
}
|
|
499
|
-
function healAgentTmpfsSecretSymlinks(agentDir, projectDir, agentKey) {
|
|
500
|
-
const base = resolveTmpfsBase();
|
|
501
|
-
if (base === null)
|
|
502
|
-
return;
|
|
503
|
-
const agentRamDir = join(base, TMPFS_SECRETS_SUBDIR, agentKey);
|
|
504
|
-
healTmpfsSecretSymlink(join(agentDir, ".env.integrations"), join(agentRamDir, "env.integrations"));
|
|
505
|
-
healTmpfsSecretSymlink(join(projectDir, ".env.integrations"), join(agentRamDir, "project.env.integrations"));
|
|
506
|
-
}
|
|
507
|
-
function ensureSecretFileNotTmpfsBacked(persistentPath) {
|
|
508
|
-
let st;
|
|
509
|
-
try {
|
|
510
|
-
st = lstatSync(persistentPath);
|
|
511
|
-
} catch {
|
|
512
|
-
return false;
|
|
513
|
-
}
|
|
514
|
-
if (!st.isSymbolicLink())
|
|
515
|
-
return false;
|
|
516
|
-
let ramTarget = null;
|
|
517
|
-
try {
|
|
518
|
-
ramTarget = readlinkSync(persistentPath);
|
|
519
|
-
} catch {
|
|
520
|
-
ramTarget = null;
|
|
521
|
-
}
|
|
522
|
-
rmSync(persistentPath, { force: true });
|
|
523
|
-
if (ramTarget !== null) {
|
|
524
|
-
try {
|
|
525
|
-
rmSync(ramTarget, { force: true });
|
|
526
|
-
} catch {
|
|
527
|
-
}
|
|
528
|
-
}
|
|
529
|
-
return true;
|
|
530
|
-
}
|
|
531
|
-
function ensureAgentSecretFilesTmpfsBacked(agentDir, projectDir, agentKey) {
|
|
532
|
-
const base = resolveTmpfsBase();
|
|
533
|
-
if (base === null)
|
|
534
|
-
return false;
|
|
535
|
-
const root = ensureSafeSecretsRoot(base);
|
|
536
|
-
if (root === null)
|
|
537
|
-
return false;
|
|
538
|
-
const agentRamDir = join(root, agentKey);
|
|
539
|
-
ensureSecretFileTmpfsBacked(join(agentDir, ".env.integrations"), join(agentRamDir, "env.integrations"));
|
|
540
|
-
ensureSecretFileTmpfsBacked(join(projectDir, ".env.integrations"), join(agentRamDir, "project.env.integrations"));
|
|
541
|
-
return true;
|
|
542
|
-
}
|
|
543
|
-
function ensureAgentSecretFilesNotTmpfsBacked(agentDir, projectDir) {
|
|
544
|
-
ensureSecretFileNotTmpfsBacked(join(agentDir, ".env.integrations"));
|
|
545
|
-
ensureSecretFileNotTmpfsBacked(join(projectDir, ".env.integrations"));
|
|
546
|
-
}
|
|
547
|
-
|
|
548
372
|
// ../../packages/core/dist/provisioning/hook-env.js
|
|
549
373
|
function augmentedHookPath(currentPath) {
|
|
550
374
|
const extras = [
|
|
@@ -585,15 +409,15 @@ function extractCommandNotFound(stderr) {
|
|
|
585
409
|
}
|
|
586
410
|
|
|
587
411
|
// ../../packages/core/dist/provisioning/frameworks/claudecode/index.js
|
|
588
|
-
import { readFileSync as
|
|
589
|
-
import { join as
|
|
412
|
+
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";
|
|
413
|
+
import { join as join3, relative, dirname as dirname3 } from "path";
|
|
590
414
|
import { homedir as homedir3 } from "os";
|
|
591
415
|
import { execFile } from "child_process";
|
|
592
416
|
|
|
593
417
|
// ../../packages/core/dist/integrations/xurl-config.js
|
|
594
|
-
import { chmodSync as
|
|
418
|
+
import { chmodSync as chmodSync2, existsSync as existsSync2, mkdirSync, readFileSync as readFileSync2, renameSync as renameSync2, unlinkSync as unlinkSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
595
419
|
import { homedir } from "os";
|
|
596
|
-
import { dirname
|
|
420
|
+
import { dirname, join } from "path";
|
|
597
421
|
import { parse as parseYaml, stringify as stringifyYaml } from "yaml";
|
|
598
422
|
var XURL_FILE_MODE = 384;
|
|
599
423
|
var XURL_AGT_APP_PREFIX = "agt-";
|
|
@@ -712,17 +536,17 @@ function buildAgtXurlApps(integrations) {
|
|
|
712
536
|
}
|
|
713
537
|
function getXurlStorePath() {
|
|
714
538
|
const home = process.env["HOME"] ?? process.env["USERPROFILE"] ?? homedir();
|
|
715
|
-
return
|
|
539
|
+
return join(home, ".xurl");
|
|
716
540
|
}
|
|
717
541
|
function writeXurlStoreForIntegrations(integrations, filePath = getXurlStorePath()) {
|
|
718
542
|
const agtApps = buildAgtXurlApps(integrations);
|
|
719
543
|
if (Object.keys(agtApps).length === 0)
|
|
720
544
|
return null;
|
|
721
545
|
let existing = null;
|
|
722
|
-
if (
|
|
546
|
+
if (existsSync2(filePath)) {
|
|
723
547
|
let raw;
|
|
724
548
|
try {
|
|
725
|
-
raw =
|
|
549
|
+
raw = readFileSync2(filePath, "utf-8");
|
|
726
550
|
} catch {
|
|
727
551
|
return null;
|
|
728
552
|
}
|
|
@@ -733,9 +557,9 @@ function writeXurlStoreForIntegrations(integrations, filePath = getXurlStorePath
|
|
|
733
557
|
existing = parsed;
|
|
734
558
|
}
|
|
735
559
|
const merged = mergeXurlStore(existing, agtApps);
|
|
736
|
-
|
|
560
|
+
mkdirSync(dirname(filePath), { recursive: true });
|
|
737
561
|
const tmpPath = `${filePath}.tmp-${process.pid}-${Date.now()}`;
|
|
738
|
-
|
|
562
|
+
writeFileSync2(tmpPath, serializeXurlStore(merged), { mode: XURL_FILE_MODE });
|
|
739
563
|
try {
|
|
740
564
|
renameSync2(tmpPath, filePath);
|
|
741
565
|
} catch (err) {
|
|
@@ -746,16 +570,16 @@ function writeXurlStoreForIntegrations(integrations, filePath = getXurlStorePath
|
|
|
746
570
|
throw err;
|
|
747
571
|
}
|
|
748
572
|
try {
|
|
749
|
-
|
|
573
|
+
chmodSync2(filePath, XURL_FILE_MODE);
|
|
750
574
|
} catch {
|
|
751
575
|
}
|
|
752
576
|
return filePath;
|
|
753
577
|
}
|
|
754
578
|
|
|
755
579
|
// ../../packages/core/dist/integrations/framer-credentials.js
|
|
756
|
-
import { chmodSync as
|
|
580
|
+
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";
|
|
757
581
|
import { homedir as homedir2 } from "os";
|
|
758
|
-
import { dirname as
|
|
582
|
+
import { dirname as dirname2, join as join2 } from "path";
|
|
759
583
|
var FRAMER_PROJECTS_CONFIG_VERSION = 2;
|
|
760
584
|
var BARE_PROJECT_ID = /^[A-Za-z0-9]{20}$/u;
|
|
761
585
|
var SLUGGED_PROJECT_ID = /^.+--([A-Za-z0-9]+)/u;
|
|
@@ -854,11 +678,11 @@ function mergeFramerProjectsConfig(existing, inputs, options = {}) {
|
|
|
854
678
|
var FRAMER_FILE_MODE = 384;
|
|
855
679
|
var MANAGED_SIDECAR_NAME = ".augmented-managed-projects.json";
|
|
856
680
|
function sidecarPathFor(projectsPath) {
|
|
857
|
-
return
|
|
681
|
+
return join2(dirname2(projectsPath), MANAGED_SIDECAR_NAME);
|
|
858
682
|
}
|
|
859
683
|
function readManagedIds(projectsPath) {
|
|
860
684
|
try {
|
|
861
|
-
const raw =
|
|
685
|
+
const raw = readFileSync3(sidecarPathFor(projectsPath), "utf-8");
|
|
862
686
|
const parsed = JSON.parse(raw);
|
|
863
687
|
if (!Array.isArray(parsed))
|
|
864
688
|
return [];
|
|
@@ -877,7 +701,7 @@ function writeManagedIds(projectsPath, ids) {
|
|
|
877
701
|
}
|
|
878
702
|
return;
|
|
879
703
|
}
|
|
880
|
-
|
|
704
|
+
writeFileSync3(target, `${JSON.stringify([...ids].sort(), null, " ")}
|
|
881
705
|
`, {
|
|
882
706
|
mode: FRAMER_FILE_MODE
|
|
883
707
|
});
|
|
@@ -890,18 +714,18 @@ var LOCK_MAX_ATTEMPTS = 50;
|
|
|
890
714
|
function withStoreLock(projectsPath, fn) {
|
|
891
715
|
const lockDir = `${projectsPath}.lock`;
|
|
892
716
|
try {
|
|
893
|
-
|
|
717
|
+
mkdirSync2(dirname2(projectsPath), { recursive: true, mode: 448 });
|
|
894
718
|
} catch {
|
|
895
719
|
}
|
|
896
720
|
let held = false;
|
|
897
721
|
for (let attempt = 0; attempt < LOCK_MAX_ATTEMPTS && !held; attempt++) {
|
|
898
722
|
try {
|
|
899
|
-
|
|
723
|
+
mkdirSync2(lockDir);
|
|
900
724
|
held = true;
|
|
901
725
|
} catch {
|
|
902
726
|
try {
|
|
903
727
|
if (Date.now() - statSync(lockDir).mtimeMs > LOCK_STALE_MS) {
|
|
904
|
-
|
|
728
|
+
rmSync(lockDir, { recursive: true, force: true });
|
|
905
729
|
continue;
|
|
906
730
|
}
|
|
907
731
|
} catch {
|
|
@@ -919,7 +743,7 @@ function withStoreLock(projectsPath, fn) {
|
|
|
919
743
|
return { acquired: true, value: fn() };
|
|
920
744
|
} finally {
|
|
921
745
|
try {
|
|
922
|
-
|
|
746
|
+
rmSync(lockDir, { recursive: true, force: true });
|
|
923
747
|
} catch {
|
|
924
748
|
}
|
|
925
749
|
}
|
|
@@ -930,9 +754,9 @@ function asString2(value) {
|
|
|
930
754
|
function getFramerProjectsPath() {
|
|
931
755
|
const xdg = process.env["XDG_CONFIG_HOME"];
|
|
932
756
|
if (xdg)
|
|
933
|
-
return
|
|
757
|
+
return join2(xdg, "framer", "projects.json");
|
|
934
758
|
const home = process.env["HOME"] ?? process.env["USERPROFILE"] ?? homedir2();
|
|
935
|
-
return
|
|
759
|
+
return join2(home, ".config", "framer", "projects.json");
|
|
936
760
|
}
|
|
937
761
|
function buildFramerCredentialInputs(integrations) {
|
|
938
762
|
const inputs = [];
|
|
@@ -961,9 +785,9 @@ function writeFramerStoreForIntegrations(integrations, filePath = getFramerProje
|
|
|
961
785
|
if (inputs.length === 0 && previouslyManagedIds.length === 0)
|
|
962
786
|
return null;
|
|
963
787
|
let existing = null;
|
|
964
|
-
if (
|
|
788
|
+
if (existsSync3(filePath)) {
|
|
965
789
|
try {
|
|
966
|
-
existing =
|
|
790
|
+
existing = readFileSync3(filePath, "utf-8");
|
|
967
791
|
} catch {
|
|
968
792
|
return null;
|
|
969
793
|
}
|
|
@@ -975,9 +799,9 @@ function writeFramerStoreForIntegrations(integrations, filePath = getFramerProje
|
|
|
975
799
|
}
|
|
976
800
|
if (!content)
|
|
977
801
|
return null;
|
|
978
|
-
|
|
802
|
+
mkdirSync2(dirname2(filePath), { recursive: true, mode: 448 });
|
|
979
803
|
const tmpPath = `${filePath}.tmp-${process.pid}-${Date.now()}`;
|
|
980
|
-
|
|
804
|
+
writeFileSync3(tmpPath, content, { mode: FRAMER_FILE_MODE });
|
|
981
805
|
try {
|
|
982
806
|
renameSync3(tmpPath, filePath);
|
|
983
807
|
} catch (err) {
|
|
@@ -988,7 +812,7 @@ function writeFramerStoreForIntegrations(integrations, filePath = getFramerProje
|
|
|
988
812
|
throw err;
|
|
989
813
|
}
|
|
990
814
|
try {
|
|
991
|
-
|
|
815
|
+
chmodSync3(filePath, FRAMER_FILE_MODE);
|
|
992
816
|
} catch {
|
|
993
817
|
}
|
|
994
818
|
writeManagedIds(filePath, written);
|
|
@@ -1687,51 +1511,30 @@ main().catch((err) => fail(err && err.message ? err.message : String(err)));
|
|
|
1687
1511
|
|
|
1688
1512
|
// ../../packages/core/dist/provisioning/frameworks/claudecode/index.js
|
|
1689
1513
|
var VALID_CODE_NAME = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
1690
|
-
var
|
|
1514
|
+
var SECRET_FILE_MODE = 384;
|
|
1691
1515
|
function writeEnvIntegrationsForAgent(codeName, args) {
|
|
1692
1516
|
const agentDir = getAgentDir(codeName);
|
|
1693
|
-
const envPath =
|
|
1517
|
+
const envPath = join3(agentDir, ".env.integrations");
|
|
1694
1518
|
let existing = null;
|
|
1695
1519
|
try {
|
|
1696
|
-
existing =
|
|
1520
|
+
existing = readFileSync4(envPath, "utf-8");
|
|
1697
1521
|
} catch {
|
|
1698
1522
|
}
|
|
1699
|
-
if (isSecretFileTmpfsBackingEnabled()) {
|
|
1700
|
-
try {
|
|
1701
|
-
healAgentTmpfsSecretSymlinks(agentDir, join4(agentDir, "project"), basename(agentDir));
|
|
1702
|
-
} catch {
|
|
1703
|
-
}
|
|
1704
|
-
}
|
|
1705
1523
|
if (existing === null && Object.keys(args.updates).length === 0)
|
|
1706
1524
|
return;
|
|
1707
|
-
if (isSecretFileTmpfsBackingEnabled()) {
|
|
1708
|
-
try {
|
|
1709
|
-
ensureAgentSecretFilesTmpfsBacked(agentDir, join4(agentDir, "project"), basename(agentDir));
|
|
1710
|
-
} catch (err) {
|
|
1711
|
-
process.stderr.write(`[env-integrations] [tmpfs-backing-failed] agent=${codeName} error=${err.message}
|
|
1712
|
-
`);
|
|
1713
|
-
}
|
|
1714
|
-
} else {
|
|
1715
|
-
try {
|
|
1716
|
-
ensureAgentSecretFilesNotTmpfsBacked(agentDir, join4(agentDir, "project"));
|
|
1717
|
-
} catch (err) {
|
|
1718
|
-
process.stderr.write(`[env-integrations] [tmpfs-revert-failed] agent=${codeName} error=${err.message}
|
|
1719
|
-
`);
|
|
1720
|
-
}
|
|
1721
|
-
}
|
|
1722
1525
|
const content = mergeEnvIntegrationsContent(existing, args);
|
|
1723
|
-
|
|
1526
|
+
writeFileSync4(envPath, content, { mode: SECRET_FILE_MODE });
|
|
1724
1527
|
try {
|
|
1725
|
-
|
|
1528
|
+
chmodSync4(envPath, SECRET_FILE_MODE);
|
|
1726
1529
|
} catch {
|
|
1727
1530
|
}
|
|
1728
1531
|
try {
|
|
1729
1532
|
const projectDir = getProjectDir(codeName);
|
|
1730
|
-
|
|
1731
|
-
const dest =
|
|
1732
|
-
|
|
1533
|
+
mkdirSync3(projectDir, { recursive: true });
|
|
1534
|
+
const dest = join3(projectDir, ".env.integrations");
|
|
1535
|
+
writeFileSync4(dest, content, { mode: SECRET_FILE_MODE });
|
|
1733
1536
|
try {
|
|
1734
|
-
|
|
1537
|
+
chmodSync4(dest, SECRET_FILE_MODE);
|
|
1735
1538
|
} catch {
|
|
1736
1539
|
}
|
|
1737
1540
|
} catch (err) {
|
|
@@ -1749,16 +1552,16 @@ var MIGRATABLE_FIELD_TO_ENV_VAR = {
|
|
|
1749
1552
|
AGT_API_KEY: "AGT_API_KEY"
|
|
1750
1553
|
};
|
|
1751
1554
|
function migrateExistingLiteralSecrets(codeName) {
|
|
1752
|
-
const mcpJsonPath =
|
|
1555
|
+
const mcpJsonPath = join3(getAgentDir(codeName), "provision", ".mcp.json");
|
|
1753
1556
|
let config;
|
|
1754
1557
|
try {
|
|
1755
|
-
config = JSON.parse(
|
|
1558
|
+
config = JSON.parse(readFileSync4(mcpJsonPath, "utf-8"));
|
|
1756
1559
|
} catch {
|
|
1757
1560
|
return;
|
|
1758
1561
|
}
|
|
1759
1562
|
let existingEnvKeys = /* @__PURE__ */ new Set();
|
|
1760
1563
|
try {
|
|
1761
|
-
existingEnvKeys = new Set(parseEnvFileEntries(
|
|
1564
|
+
existingEnvKeys = new Set(parseEnvFileEntries(readFileSync4(join3(getAgentDir(codeName), ".env.integrations"), "utf-8")).keys());
|
|
1762
1565
|
} catch {
|
|
1763
1566
|
}
|
|
1764
1567
|
const updates = {};
|
|
@@ -1846,7 +1649,7 @@ function assertValidAgentId(agentId) {
|
|
|
1846
1649
|
}
|
|
1847
1650
|
function resolveRealAgentPath(codeNamePath) {
|
|
1848
1651
|
try {
|
|
1849
|
-
if (
|
|
1652
|
+
if (lstatSync(codeNamePath).isSymbolicLink()) {
|
|
1850
1653
|
return realpathSync(codeNamePath);
|
|
1851
1654
|
}
|
|
1852
1655
|
} catch {
|
|
@@ -1857,11 +1660,11 @@ function ensureIdKeyedLayout(codeName, agentId) {
|
|
|
1857
1660
|
assertValidCodeName(codeName);
|
|
1858
1661
|
assertValidAgentId(agentId);
|
|
1859
1662
|
const home = getHomeDir();
|
|
1860
|
-
const codeNamePath =
|
|
1861
|
-
const idPath =
|
|
1663
|
+
const codeNamePath = join3(home, ".augmented", codeName);
|
|
1664
|
+
const idPath = join3(home, ".augmented", agentId);
|
|
1862
1665
|
let state;
|
|
1863
1666
|
try {
|
|
1864
|
-
state =
|
|
1667
|
+
state = lstatSync(codeNamePath).isSymbolicLink() ? "symlink" : "realdir";
|
|
1865
1668
|
} catch {
|
|
1866
1669
|
state = "absent";
|
|
1867
1670
|
}
|
|
@@ -1869,30 +1672,30 @@ function ensureIdKeyedLayout(codeName, agentId) {
|
|
|
1869
1672
|
return codeNamePath;
|
|
1870
1673
|
}
|
|
1871
1674
|
if (state === "symlink") {
|
|
1872
|
-
const target =
|
|
1675
|
+
const target = readlinkSync(codeNamePath);
|
|
1873
1676
|
if (target !== agentId) {
|
|
1874
1677
|
throw new Error(`Codename symlink ${codeNamePath} points at "${target}", expected "${agentId}"; refusing to provision over a mismatched id-keyed layout.`);
|
|
1875
1678
|
}
|
|
1876
|
-
|
|
1679
|
+
mkdirSync3(idPath, { recursive: true });
|
|
1877
1680
|
return idPath;
|
|
1878
1681
|
}
|
|
1879
|
-
|
|
1880
|
-
|
|
1682
|
+
mkdirSync3(idPath, { recursive: true });
|
|
1683
|
+
symlinkSync(agentId, codeNamePath);
|
|
1881
1684
|
return idPath;
|
|
1882
1685
|
}
|
|
1883
1686
|
function stagedMigrationLinkPath(home, codeName) {
|
|
1884
|
-
return
|
|
1687
|
+
return join3(home, ".augmented", `.${codeName}.migrating`);
|
|
1885
1688
|
}
|
|
1886
1689
|
function cleanupStaleStagedLink(staged) {
|
|
1887
1690
|
try {
|
|
1888
|
-
if (
|
|
1889
|
-
|
|
1691
|
+
if (lstatSync(staged).isSymbolicLink())
|
|
1692
|
+
rmSync2(staged, { force: true });
|
|
1890
1693
|
} catch {
|
|
1891
1694
|
}
|
|
1892
1695
|
}
|
|
1893
1696
|
function isSymlinkTo(path, target) {
|
|
1894
1697
|
try {
|
|
1895
|
-
return
|
|
1698
|
+
return lstatSync(path).isSymbolicLink() && readlinkSync(path) === target;
|
|
1896
1699
|
} catch {
|
|
1897
1700
|
return false;
|
|
1898
1701
|
}
|
|
@@ -1901,18 +1704,18 @@ function migrateAgentDirToIdKeyed(codeName, agentId, opts = {}) {
|
|
|
1901
1704
|
assertValidCodeName(codeName);
|
|
1902
1705
|
assertValidAgentId(agentId);
|
|
1903
1706
|
const home = opts.home ?? getHomeDir();
|
|
1904
|
-
const codeNamePath =
|
|
1905
|
-
const idPath =
|
|
1707
|
+
const codeNamePath = join3(home, ".augmented", codeName);
|
|
1708
|
+
const idPath = join3(home, ".augmented", agentId);
|
|
1906
1709
|
const staged = stagedMigrationLinkPath(home, codeName);
|
|
1907
1710
|
let codeNameKind;
|
|
1908
1711
|
try {
|
|
1909
|
-
codeNameKind =
|
|
1712
|
+
codeNameKind = lstatSync(codeNamePath).isSymbolicLink() ? "symlink" : "realdir";
|
|
1910
1713
|
} catch {
|
|
1911
1714
|
codeNameKind = "absent";
|
|
1912
1715
|
}
|
|
1913
|
-
const idExists =
|
|
1716
|
+
const idExists = existsSync4(idPath);
|
|
1914
1717
|
if (codeNameKind === "symlink") {
|
|
1915
|
-
const target =
|
|
1718
|
+
const target = readlinkSync(codeNamePath);
|
|
1916
1719
|
if (target !== agentId) {
|
|
1917
1720
|
throw new Error(`Codename symlink ${codeNamePath} points at "${target}", expected "${agentId}"; refusing to migrate.`);
|
|
1918
1721
|
}
|
|
@@ -1923,7 +1726,7 @@ function migrateAgentDirToIdKeyed(codeName, agentId, opts = {}) {
|
|
|
1923
1726
|
renameSync4(staged, codeNamePath);
|
|
1924
1727
|
} else {
|
|
1925
1728
|
cleanupStaleStagedLink(staged);
|
|
1926
|
-
|
|
1729
|
+
symlinkSync(agentId, codeNamePath);
|
|
1927
1730
|
}
|
|
1928
1731
|
return "recovered";
|
|
1929
1732
|
}
|
|
@@ -1933,22 +1736,22 @@ function migrateAgentDirToIdKeyed(codeName, agentId, opts = {}) {
|
|
|
1933
1736
|
return "conflict";
|
|
1934
1737
|
}
|
|
1935
1738
|
cleanupStaleStagedLink(staged);
|
|
1936
|
-
|
|
1739
|
+
symlinkSync(agentId, staged);
|
|
1937
1740
|
renameSync4(codeNamePath, idPath);
|
|
1938
1741
|
renameSync4(staged, codeNamePath);
|
|
1939
1742
|
return "migrated";
|
|
1940
1743
|
}
|
|
1941
1744
|
function getAgentDir(codeName) {
|
|
1942
1745
|
assertValidCodeName(codeName);
|
|
1943
|
-
return resolveRealAgentPath(
|
|
1746
|
+
return resolveRealAgentPath(join3(getHomeDir(), ".augmented", codeName));
|
|
1944
1747
|
}
|
|
1945
1748
|
var migratedCodeNames = /* @__PURE__ */ new Set();
|
|
1946
1749
|
function migrateLegacyClaudecodeDir(codeName, log2) {
|
|
1947
1750
|
assertValidCodeName(codeName);
|
|
1948
1751
|
if (migratedCodeNames.has(codeName))
|
|
1949
1752
|
return;
|
|
1950
|
-
const legacyRoot =
|
|
1951
|
-
if (!
|
|
1753
|
+
const legacyRoot = join3(getHomeDir(), ".augmented", codeName, "claudecode");
|
|
1754
|
+
if (!existsSync4(legacyRoot)) {
|
|
1952
1755
|
migratedCodeNames.add(codeName);
|
|
1953
1756
|
return;
|
|
1954
1757
|
}
|
|
@@ -1958,33 +1761,33 @@ function migrateLegacyClaudecodeDir(codeName, log2) {
|
|
|
1958
1761
|
};
|
|
1959
1762
|
try {
|
|
1960
1763
|
const walkAndMigrate = (srcDir, destDir) => {
|
|
1961
|
-
|
|
1764
|
+
mkdirSync3(destDir, { recursive: true });
|
|
1962
1765
|
for (const entry of readdirSync(srcDir, { withFileTypes: true })) {
|
|
1963
|
-
const src =
|
|
1964
|
-
const dest =
|
|
1766
|
+
const src = join3(srcDir, entry.name);
|
|
1767
|
+
const dest = join3(destDir, entry.name);
|
|
1965
1768
|
if (entry.isDirectory()) {
|
|
1966
1769
|
walkAndMigrate(src, dest);
|
|
1967
1770
|
continue;
|
|
1968
1771
|
}
|
|
1969
|
-
if (entry.name === ".mcp.json" &&
|
|
1772
|
+
if (entry.name === ".mcp.json" && existsSync4(dest)) {
|
|
1970
1773
|
try {
|
|
1971
|
-
const oldCfg = JSON.parse(
|
|
1972
|
-
const newCfg = JSON.parse(
|
|
1774
|
+
const oldCfg = JSON.parse(readFileSync4(src, "utf-8"));
|
|
1775
|
+
const newCfg = JSON.parse(readFileSync4(dest, "utf-8"));
|
|
1973
1776
|
const merged = { mcpServers: { ...oldCfg.mcpServers ?? {}, ...newCfg.mcpServers ?? {} } };
|
|
1974
|
-
|
|
1777
|
+
writeFileSync4(dest, JSON.stringify(merged, null, 2));
|
|
1975
1778
|
emit(`[migrate] '${codeName}' merged .mcp.json (${Object.keys(merged.mcpServers).length} servers)`);
|
|
1976
1779
|
} catch (err) {
|
|
1977
1780
|
throw new Error(`Failed merging .mcp.json (${src} \u2192 ${dest}): ${err.message}`);
|
|
1978
1781
|
}
|
|
1979
1782
|
continue;
|
|
1980
1783
|
}
|
|
1981
|
-
if (!
|
|
1784
|
+
if (!existsSync4(dest)) {
|
|
1982
1785
|
copyFileSync(src, dest);
|
|
1983
1786
|
continue;
|
|
1984
1787
|
}
|
|
1985
1788
|
try {
|
|
1986
|
-
const srcStat =
|
|
1987
|
-
const destStat =
|
|
1789
|
+
const srcStat = readFileSync4(src);
|
|
1790
|
+
const destStat = readFileSync4(dest);
|
|
1988
1791
|
if (!srcStat.equals(destStat)) {
|
|
1989
1792
|
}
|
|
1990
1793
|
} catch (err) {
|
|
@@ -1993,7 +1796,7 @@ function migrateLegacyClaudecodeDir(codeName, log2) {
|
|
|
1993
1796
|
}
|
|
1994
1797
|
};
|
|
1995
1798
|
walkAndMigrate(legacyRoot, newRoot);
|
|
1996
|
-
|
|
1799
|
+
rmSync2(legacyRoot, { recursive: true, force: true });
|
|
1997
1800
|
emit(`[migrate] '${codeName}': collapsed ~/.augmented/${codeName}/claudecode/ into ~/.augmented/${codeName}/`);
|
|
1998
1801
|
migratedCodeNames.add(codeName);
|
|
1999
1802
|
} catch (err) {
|
|
@@ -2001,25 +1804,25 @@ function migrateLegacyClaudecodeDir(codeName, log2) {
|
|
|
2001
1804
|
}
|
|
2002
1805
|
}
|
|
2003
1806
|
function syncGitHubBrokerCredentialTooling(projectDir, enabled) {
|
|
2004
|
-
const binDir =
|
|
1807
|
+
const binDir = join3(projectDir, GITHUB_BROKER_BIN_DIR);
|
|
2005
1808
|
if (!enabled) {
|
|
2006
|
-
|
|
1809
|
+
rmSync2(binDir, { recursive: true, force: true });
|
|
2007
1810
|
return {};
|
|
2008
1811
|
}
|
|
2009
|
-
const helperPath =
|
|
2010
|
-
const shimPath =
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
1812
|
+
const helperPath = join3(binDir, GIT_CREDENTIAL_HELPER_BASENAME);
|
|
1813
|
+
const shimPath = join3(binDir, GH_SHIM_BASENAME);
|
|
1814
|
+
mkdirSync3(binDir, { recursive: true });
|
|
1815
|
+
writeFileSync4(helperPath, renderGitCredentialHelper(), { mode: BROKER_SCRIPT_MODE });
|
|
1816
|
+
chmodSync4(helperPath, BROKER_SCRIPT_MODE);
|
|
1817
|
+
writeFileSync4(shimPath, renderGhShim(), { mode: BROKER_SCRIPT_MODE });
|
|
1818
|
+
chmodSync4(shimPath, BROKER_SCRIPT_MODE);
|
|
2016
1819
|
return buildGitCredentialEnv(helperPath);
|
|
2017
1820
|
}
|
|
2018
1821
|
function getProjectDir(codeName) {
|
|
2019
|
-
return
|
|
1822
|
+
return join3(getAgentDir(codeName), "project");
|
|
2020
1823
|
}
|
|
2021
1824
|
function getScratchDir(codeName) {
|
|
2022
|
-
return
|
|
1825
|
+
return join3(getAgentDir(codeName), "scratch");
|
|
2023
1826
|
}
|
|
2024
1827
|
function getAgentTmpDir(codeName) {
|
|
2025
1828
|
return agentTmpDirFor(getAgentDir(codeName));
|
|
@@ -2035,11 +1838,11 @@ function sweepScratchDir(codeName, now = Date.now()) {
|
|
|
2035
1838
|
}
|
|
2036
1839
|
const cutoff = now - SCRATCH_RETENTION_DAYS * 24 * 60 * 60 * 1e3;
|
|
2037
1840
|
for (const entry of entries) {
|
|
2038
|
-
const full =
|
|
1841
|
+
const full = join3(scratchDir, entry);
|
|
2039
1842
|
try {
|
|
2040
1843
|
if (isFreshWithin(full, cutoff))
|
|
2041
1844
|
continue;
|
|
2042
|
-
|
|
1845
|
+
rmSync2(full, { recursive: true, force: true });
|
|
2043
1846
|
removed += 1;
|
|
2044
1847
|
} catch {
|
|
2045
1848
|
}
|
|
@@ -2056,7 +1859,7 @@ function isFreshWithin(path, cutoff) {
|
|
|
2056
1859
|
const current = queue.pop();
|
|
2057
1860
|
let stat;
|
|
2058
1861
|
try {
|
|
2059
|
-
stat =
|
|
1862
|
+
stat = lstatSync(current);
|
|
2060
1863
|
} catch {
|
|
2061
1864
|
return true;
|
|
2062
1865
|
}
|
|
@@ -2075,7 +1878,7 @@ function isFreshWithin(path, cutoff) {
|
|
|
2075
1878
|
const child = dir.readSync();
|
|
2076
1879
|
if (child === null)
|
|
2077
1880
|
break;
|
|
2078
|
-
queue.push(
|
|
1881
|
+
queue.push(join3(current, child.name));
|
|
2079
1882
|
budget -= 1;
|
|
2080
1883
|
}
|
|
2081
1884
|
} catch {
|
|
@@ -2092,18 +1895,18 @@ function isFreshWithin(path, cutoff) {
|
|
|
2092
1895
|
function syncMcpToProject(codeName) {
|
|
2093
1896
|
const agentDir = getAgentDir(codeName);
|
|
2094
1897
|
const projectDir = getProjectDir(codeName);
|
|
2095
|
-
const provisionMcpPath =
|
|
2096
|
-
const projectMcpPath =
|
|
1898
|
+
const provisionMcpPath = join3(agentDir, "provision", ".mcp.json");
|
|
1899
|
+
const projectMcpPath = join3(projectDir, ".mcp.json");
|
|
2097
1900
|
try {
|
|
2098
|
-
const content =
|
|
2099
|
-
|
|
2100
|
-
|
|
1901
|
+
const content = readFileSync4(provisionMcpPath, "utf-8");
|
|
1902
|
+
mkdirSync3(projectDir, { recursive: true });
|
|
1903
|
+
writeFileSync4(projectMcpPath, content, { mode: MCP_FILE_MODE });
|
|
2101
1904
|
try {
|
|
2102
|
-
|
|
1905
|
+
chmodSync4(projectMcpPath, MCP_FILE_MODE);
|
|
2103
1906
|
} catch {
|
|
2104
1907
|
}
|
|
2105
1908
|
try {
|
|
2106
|
-
const mismatches = mcpMirrorParityErrors(JSON.parse(content), JSON.parse(
|
|
1909
|
+
const mismatches = mcpMirrorParityErrors(JSON.parse(content), JSON.parse(readFileSync4(projectMcpPath, "utf-8")));
|
|
2107
1910
|
for (const m of mismatches) {
|
|
2108
1911
|
process.stderr.write(`${formatMirrorMismatch(m)} agent=${codeName}
|
|
2109
1912
|
`);
|
|
@@ -2117,19 +1920,19 @@ function syncMcpToProject(codeName) {
|
|
|
2117
1920
|
}
|
|
2118
1921
|
var INTEGRATIONS_SUMMARY_FILE = "integrations-summary.json";
|
|
2119
1922
|
function integrationsSummaryPath(codeName) {
|
|
2120
|
-
return
|
|
1923
|
+
return join3(getAgentDir(codeName), "provision", INTEGRATIONS_SUMMARY_FILE);
|
|
2121
1924
|
}
|
|
2122
1925
|
function writeIntegrationsSummaryForAgent(codeName, summaries) {
|
|
2123
1926
|
const target = integrationsSummaryPath(codeName);
|
|
2124
1927
|
try {
|
|
2125
|
-
|
|
2126
|
-
|
|
1928
|
+
mkdirSync3(dirname3(target), { recursive: true });
|
|
1929
|
+
writeFileSync4(target, JSON.stringify(summaries, null, 2));
|
|
2127
1930
|
} catch {
|
|
2128
1931
|
}
|
|
2129
1932
|
}
|
|
2130
1933
|
function readIntegrationsSummaryForAgent(codeName) {
|
|
2131
1934
|
try {
|
|
2132
|
-
const raw =
|
|
1935
|
+
const raw = readFileSync4(integrationsSummaryPath(codeName), "utf-8");
|
|
2133
1936
|
const parsed = JSON.parse(raw);
|
|
2134
1937
|
return Array.isArray(parsed) ? parsed : [];
|
|
2135
1938
|
} catch {
|
|
@@ -2139,10 +1942,10 @@ function readIntegrationsSummaryForAgent(codeName) {
|
|
|
2139
1942
|
function renderChannelMessageHandlerForAgent(codeName) {
|
|
2140
1943
|
const agentDir = getAgentDir(codeName);
|
|
2141
1944
|
const projectDir = getProjectDir(codeName);
|
|
2142
|
-
const provisionMcpPath =
|
|
1945
|
+
const provisionMcpPath = join3(agentDir, "provision", ".mcp.json");
|
|
2143
1946
|
let mcpServerKeys;
|
|
2144
1947
|
try {
|
|
2145
|
-
const config = JSON.parse(
|
|
1948
|
+
const config = JSON.parse(readFileSync4(provisionMcpPath, "utf-8"));
|
|
2146
1949
|
mcpServerKeys = Object.keys(config.mcpServers ?? {});
|
|
2147
1950
|
} catch {
|
|
2148
1951
|
return;
|
|
@@ -2150,10 +1953,10 @@ function renderChannelMessageHandlerForAgent(codeName) {
|
|
|
2150
1953
|
const integrations = readIntegrationsSummaryForAgent(codeName);
|
|
2151
1954
|
const content = buildChannelMessageHandlerAgent({ mcpServerKeys, integrations });
|
|
2152
1955
|
for (const baseDir of [agentDir, projectDir]) {
|
|
2153
|
-
const target =
|
|
1956
|
+
const target = join3(baseDir, ".claude", "agents", "channel-message-handler.md");
|
|
2154
1957
|
try {
|
|
2155
|
-
|
|
2156
|
-
|
|
1958
|
+
mkdirSync3(dirname3(target), { recursive: true });
|
|
1959
|
+
writeFileSync4(target, content);
|
|
2157
1960
|
} catch {
|
|
2158
1961
|
}
|
|
2159
1962
|
}
|
|
@@ -2168,9 +1971,9 @@ function writeMcpJsonGuarded(codeName, path, config) {
|
|
|
2168
1971
|
return true;
|
|
2169
1972
|
}
|
|
2170
1973
|
function readExistingMcpEnvVar(codeName, serverId, envKey) {
|
|
2171
|
-
const mcpJsonPath =
|
|
1974
|
+
const mcpJsonPath = join3(getAgentDir(codeName), "provision", ".mcp.json");
|
|
2172
1975
|
try {
|
|
2173
|
-
const raw =
|
|
1976
|
+
const raw = readFileSync4(mcpJsonPath, "utf-8");
|
|
2174
1977
|
const config = JSON.parse(raw);
|
|
2175
1978
|
const server = config.mcpServers?.[serverId];
|
|
2176
1979
|
if (!server || typeof server !== "object")
|
|
@@ -2199,10 +2002,10 @@ function resolveBrokerAgentId(codeName, fallback) {
|
|
|
2199
2002
|
}
|
|
2200
2003
|
function deployArtifactsToProject(codeName, provisionDir) {
|
|
2201
2004
|
const projectDir = getProjectDir(codeName);
|
|
2202
|
-
|
|
2005
|
+
mkdirSync3(projectDir, { recursive: true });
|
|
2203
2006
|
try {
|
|
2204
|
-
|
|
2205
|
-
|
|
2007
|
+
mkdirSync3(getScratchDir(codeName), { recursive: true });
|
|
2008
|
+
mkdirSync3(getAgentTmpDir(codeName), { recursive: true });
|
|
2206
2009
|
sweepScratchDir(codeName);
|
|
2207
2010
|
} catch (err) {
|
|
2208
2011
|
process.stderr.write(`[scratch] [ensure-or-sweep-failed] agent=${codeName} error=${err.message}
|
|
@@ -2212,135 +2015,135 @@ function deployArtifactsToProject(codeName, provisionDir) {
|
|
|
2212
2015
|
const SKILLS_START = "<!-- AGT:SKILLS_INDEX_START -->";
|
|
2213
2016
|
const SKILLS_END = "<!-- AGT:SKILLS_INDEX_END -->";
|
|
2214
2017
|
for (const file of artifactFiles) {
|
|
2215
|
-
const src =
|
|
2216
|
-
const dest =
|
|
2018
|
+
const src = join3(provisionDir, file);
|
|
2019
|
+
const dest = join3(projectDir, file);
|
|
2217
2020
|
try {
|
|
2218
|
-
const srcContent =
|
|
2219
|
-
if (file === "CLAUDE.md" &&
|
|
2220
|
-
const destContent =
|
|
2021
|
+
const srcContent = readFileSync4(src, "utf-8");
|
|
2022
|
+
if (file === "CLAUDE.md" && existsSync4(dest)) {
|
|
2023
|
+
const destContent = readFileSync4(dest, "utf-8");
|
|
2221
2024
|
const stripIndex = (s) => s.replace(new RegExp(`${SKILLS_START}[\\s\\S]*?${SKILLS_END}`), "").trimEnd();
|
|
2222
2025
|
if (stripIndex(srcContent) === stripIndex(destContent))
|
|
2223
2026
|
continue;
|
|
2224
2027
|
const indexMatch = destContent.match(new RegExp(`${SKILLS_START}[\\s\\S]*?${SKILLS_END}`));
|
|
2225
2028
|
if (indexMatch) {
|
|
2226
|
-
|
|
2029
|
+
writeFileSync4(dest, srcContent.trimEnd() + "\n\n" + indexMatch[0] + "\n");
|
|
2227
2030
|
continue;
|
|
2228
2031
|
}
|
|
2229
2032
|
}
|
|
2230
2033
|
if (file === ".mcp.json") {
|
|
2231
|
-
|
|
2034
|
+
writeFileSync4(dest, srcContent, { mode: MCP_FILE_MODE });
|
|
2232
2035
|
try {
|
|
2233
|
-
|
|
2036
|
+
chmodSync4(dest, MCP_FILE_MODE);
|
|
2234
2037
|
} catch {
|
|
2235
2038
|
}
|
|
2236
2039
|
} else {
|
|
2237
|
-
|
|
2040
|
+
writeFileSync4(dest, srcContent);
|
|
2238
2041
|
}
|
|
2239
2042
|
} catch {
|
|
2240
2043
|
}
|
|
2241
2044
|
}
|
|
2242
|
-
const skillsDir =
|
|
2243
|
-
const destSkillsDir =
|
|
2045
|
+
const skillsDir = join3(provisionDir, ".claude", "skills");
|
|
2046
|
+
const destSkillsDir = join3(projectDir, ".claude", "skills");
|
|
2244
2047
|
try {
|
|
2245
|
-
if (
|
|
2246
|
-
const srcFolders =
|
|
2048
|
+
if (existsSync4(destSkillsDir)) {
|
|
2049
|
+
const srcFolders = existsSync4(skillsDir) ? new Set(readdirSync(skillsDir)) : /* @__PURE__ */ new Set();
|
|
2247
2050
|
for (const folder of readdirSync(destSkillsDir)) {
|
|
2248
2051
|
if (folder.startsWith("knowledge-") || folder === "core-knowledge" && !srcFolders.has(folder)) {
|
|
2249
2052
|
try {
|
|
2250
|
-
|
|
2053
|
+
rmSync2(join3(destSkillsDir, folder), { recursive: true });
|
|
2251
2054
|
} catch {
|
|
2252
2055
|
}
|
|
2253
2056
|
}
|
|
2254
2057
|
}
|
|
2255
2058
|
}
|
|
2256
|
-
if (
|
|
2059
|
+
if (existsSync4(skillsDir)) {
|
|
2257
2060
|
for (const skillFolder of readdirSync(skillsDir)) {
|
|
2258
|
-
const srcSkillFile =
|
|
2259
|
-
if (!
|
|
2061
|
+
const srcSkillFile = join3(skillsDir, skillFolder, "SKILL.md");
|
|
2062
|
+
if (!existsSync4(srcSkillFile))
|
|
2260
2063
|
continue;
|
|
2261
|
-
const destFolder =
|
|
2262
|
-
const destFile =
|
|
2263
|
-
const srcContent =
|
|
2064
|
+
const destFolder = join3(destSkillsDir, skillFolder);
|
|
2065
|
+
const destFile = join3(destFolder, "SKILL.md");
|
|
2066
|
+
const srcContent = readFileSync4(srcSkillFile, "utf-8");
|
|
2264
2067
|
try {
|
|
2265
|
-
if (
|
|
2068
|
+
if (existsSync4(destFile) && readFileSync4(destFile, "utf-8") === srcContent)
|
|
2266
2069
|
continue;
|
|
2267
2070
|
} catch {
|
|
2268
2071
|
}
|
|
2269
|
-
|
|
2270
|
-
|
|
2072
|
+
mkdirSync3(destFolder, { recursive: true });
|
|
2073
|
+
writeFileSync4(destFile, srcContent);
|
|
2271
2074
|
}
|
|
2272
2075
|
}
|
|
2273
2076
|
} catch {
|
|
2274
2077
|
}
|
|
2275
|
-
const agentsDir =
|
|
2276
|
-
const destAgentsDir =
|
|
2078
|
+
const agentsDir = join3(provisionDir, ".claude", "agents");
|
|
2079
|
+
const destAgentsDir = join3(projectDir, ".claude", "agents");
|
|
2277
2080
|
try {
|
|
2278
|
-
if (
|
|
2081
|
+
if (existsSync4(agentsDir)) {
|
|
2279
2082
|
const sourceAgentFiles = new Set(readdirSync(agentsDir).filter((f) => f.endsWith(".md")));
|
|
2280
|
-
if (
|
|
2083
|
+
if (existsSync4(destAgentsDir)) {
|
|
2281
2084
|
for (const destFile of readdirSync(destAgentsDir)) {
|
|
2282
2085
|
if (!destFile.endsWith(".md"))
|
|
2283
2086
|
continue;
|
|
2284
2087
|
if (sourceAgentFiles.has(destFile))
|
|
2285
2088
|
continue;
|
|
2286
2089
|
try {
|
|
2287
|
-
|
|
2090
|
+
rmSync2(join3(destAgentsDir, destFile));
|
|
2288
2091
|
} catch {
|
|
2289
2092
|
}
|
|
2290
2093
|
}
|
|
2291
2094
|
}
|
|
2292
2095
|
for (const agentFile of sourceAgentFiles) {
|
|
2293
|
-
const srcPath =
|
|
2294
|
-
const destPath =
|
|
2295
|
-
const srcContent =
|
|
2096
|
+
const srcPath = join3(agentsDir, agentFile);
|
|
2097
|
+
const destPath = join3(destAgentsDir, agentFile);
|
|
2098
|
+
const srcContent = readFileSync4(srcPath, "utf-8");
|
|
2296
2099
|
try {
|
|
2297
|
-
if (
|
|
2100
|
+
if (existsSync4(destPath) && readFileSync4(destPath, "utf-8") === srcContent)
|
|
2298
2101
|
continue;
|
|
2299
2102
|
} catch {
|
|
2300
2103
|
}
|
|
2301
|
-
|
|
2302
|
-
|
|
2104
|
+
mkdirSync3(destAgentsDir, { recursive: true });
|
|
2105
|
+
writeFileSync4(destPath, srcContent);
|
|
2303
2106
|
}
|
|
2304
2107
|
}
|
|
2305
2108
|
} catch {
|
|
2306
2109
|
}
|
|
2307
|
-
const workflowsDir =
|
|
2308
|
-
const destWorkflowsDir =
|
|
2110
|
+
const workflowsDir = join3(provisionDir, ".claude", "workflows");
|
|
2111
|
+
const destWorkflowsDir = join3(projectDir, ".claude", "workflows");
|
|
2309
2112
|
try {
|
|
2310
|
-
const sourceWorkflowFiles =
|
|
2311
|
-
if (
|
|
2113
|
+
const sourceWorkflowFiles = existsSync4(workflowsDir) ? new Set(readdirSync(workflowsDir).filter((f) => f.endsWith(".js"))) : /* @__PURE__ */ new Set();
|
|
2114
|
+
if (existsSync4(destWorkflowsDir)) {
|
|
2312
2115
|
for (const destFile of readdirSync(destWorkflowsDir)) {
|
|
2313
2116
|
if (!destFile.endsWith(".js"))
|
|
2314
2117
|
continue;
|
|
2315
2118
|
if (sourceWorkflowFiles.has(destFile))
|
|
2316
2119
|
continue;
|
|
2317
2120
|
try {
|
|
2318
|
-
|
|
2121
|
+
rmSync2(join3(destWorkflowsDir, destFile));
|
|
2319
2122
|
} catch {
|
|
2320
2123
|
}
|
|
2321
2124
|
}
|
|
2322
2125
|
}
|
|
2323
2126
|
for (const workflowFile of sourceWorkflowFiles) {
|
|
2324
|
-
const srcPath =
|
|
2325
|
-
const destPath =
|
|
2326
|
-
const srcContent =
|
|
2127
|
+
const srcPath = join3(workflowsDir, workflowFile);
|
|
2128
|
+
const destPath = join3(destWorkflowsDir, workflowFile);
|
|
2129
|
+
const srcContent = readFileSync4(srcPath, "utf-8");
|
|
2327
2130
|
try {
|
|
2328
|
-
if (
|
|
2131
|
+
if (existsSync4(destPath) && readFileSync4(destPath, "utf-8") === srcContent)
|
|
2329
2132
|
continue;
|
|
2330
2133
|
} catch {
|
|
2331
2134
|
}
|
|
2332
|
-
|
|
2333
|
-
|
|
2135
|
+
mkdirSync3(destWorkflowsDir, { recursive: true });
|
|
2136
|
+
writeFileSync4(destPath, srcContent);
|
|
2334
2137
|
}
|
|
2335
2138
|
} catch {
|
|
2336
2139
|
}
|
|
2337
|
-
const agentMcpPath =
|
|
2338
|
-
const projectMcpPath =
|
|
2140
|
+
const agentMcpPath = join3(getAgentDir(codeName), "provision", ".mcp.json");
|
|
2141
|
+
const projectMcpPath = join3(projectDir, ".mcp.json");
|
|
2339
2142
|
try {
|
|
2340
|
-
const agentMcp = JSON.parse(
|
|
2143
|
+
const agentMcp = JSON.parse(readFileSync4(agentMcpPath, "utf-8"));
|
|
2341
2144
|
let projectMcp;
|
|
2342
2145
|
try {
|
|
2343
|
-
projectMcp = JSON.parse(
|
|
2146
|
+
projectMcp = JSON.parse(readFileSync4(projectMcpPath, "utf-8"));
|
|
2344
2147
|
} catch {
|
|
2345
2148
|
projectMcp = { mcpServers: {} };
|
|
2346
2149
|
}
|
|
@@ -2351,9 +2154,9 @@ function deployArtifactsToProject(codeName, provisionDir) {
|
|
|
2351
2154
|
return !(entry && typeof entry["url"] === "string" && entry["url"].startsWith("/"));
|
|
2352
2155
|
}));
|
|
2353
2156
|
projectMcp["mcpServers"] = { ...stripRelativeUrls(projectServers), ...stripRelativeUrls(agentServers) };
|
|
2354
|
-
|
|
2157
|
+
writeFileSync4(projectMcpPath, JSON.stringify(projectMcp, null, 2), { mode: MCP_FILE_MODE });
|
|
2355
2158
|
try {
|
|
2356
|
-
|
|
2159
|
+
chmodSync4(projectMcpPath, MCP_FILE_MODE);
|
|
2357
2160
|
} catch {
|
|
2358
2161
|
}
|
|
2359
2162
|
} catch {
|
|
@@ -2361,37 +2164,37 @@ function deployArtifactsToProject(codeName, provisionDir) {
|
|
|
2361
2164
|
const agentDir = getAgentDir(codeName);
|
|
2362
2165
|
for (const envFile of [".env", ".env.integrations"]) {
|
|
2363
2166
|
try {
|
|
2364
|
-
const content =
|
|
2365
|
-
const envDest =
|
|
2366
|
-
|
|
2167
|
+
const content = readFileSync4(join3(agentDir, envFile), "utf-8");
|
|
2168
|
+
const envDest = join3(projectDir, envFile);
|
|
2169
|
+
writeFileSync4(envDest, content, { mode: SECRET_FILE_MODE });
|
|
2367
2170
|
try {
|
|
2368
|
-
|
|
2171
|
+
chmodSync4(envDest, SECRET_FILE_MODE);
|
|
2369
2172
|
} catch {
|
|
2370
2173
|
}
|
|
2371
2174
|
} catch {
|
|
2372
2175
|
}
|
|
2373
2176
|
}
|
|
2374
2177
|
try {
|
|
2375
|
-
const gitDir =
|
|
2376
|
-
const hookSrc =
|
|
2377
|
-
if (
|
|
2378
|
-
const hooksDir =
|
|
2379
|
-
|
|
2380
|
-
const hookDest =
|
|
2381
|
-
const srcContent =
|
|
2382
|
-
const upToDate =
|
|
2178
|
+
const gitDir = join3(projectDir, ".git");
|
|
2179
|
+
const hookSrc = join3(provisionDir, ".git-hooks", "pre-commit");
|
|
2180
|
+
if (existsSync4(gitDir) && existsSync4(hookSrc)) {
|
|
2181
|
+
const hooksDir = join3(gitDir, "hooks");
|
|
2182
|
+
mkdirSync3(hooksDir, { recursive: true });
|
|
2183
|
+
const hookDest = join3(hooksDir, "pre-commit");
|
|
2184
|
+
const srcContent = readFileSync4(hookSrc, "utf-8");
|
|
2185
|
+
const upToDate = existsSync4(hookDest) && readFileSync4(hookDest, "utf-8") === srcContent;
|
|
2383
2186
|
if (!upToDate)
|
|
2384
|
-
|
|
2385
|
-
|
|
2187
|
+
writeFileSync4(hookDest, srcContent);
|
|
2188
|
+
chmodSync4(hookDest, 493);
|
|
2386
2189
|
}
|
|
2387
2190
|
} catch {
|
|
2388
2191
|
}
|
|
2389
2192
|
}
|
|
2390
2193
|
function provisionStopHook(codeName) {
|
|
2391
2194
|
const projectDir = getProjectDir(codeName);
|
|
2392
|
-
const claudeDir =
|
|
2393
|
-
|
|
2394
|
-
const hookScriptPath =
|
|
2195
|
+
const claudeDir = join3(projectDir, ".claude");
|
|
2196
|
+
mkdirSync3(claudeDir, { recursive: true });
|
|
2197
|
+
const hookScriptPath = join3(claudeDir, "agt-stop-hook.sh");
|
|
2395
2198
|
const hookScript = [
|
|
2396
2199
|
"#!/bin/bash",
|
|
2397
2200
|
"# Auto-generated by Augmented \u2014 captures persistent session task results.",
|
|
@@ -2422,8 +2225,8 @@ function provisionStopHook(codeName) {
|
|
|
2422
2225
|
"esac",
|
|
2423
2226
|
"exit 0"
|
|
2424
2227
|
].join("\n") + "\n";
|
|
2425
|
-
|
|
2426
|
-
const ghostHookPath =
|
|
2228
|
+
writeFileSync4(hookScriptPath, hookScript, { mode: 493 });
|
|
2229
|
+
const ghostHookPath = join3(claudeDir, "agt-ghost-reply-hook.sh");
|
|
2427
2230
|
const jqNormalizeContent = '(.message.content // .content // []) | if type == "string" then [{type: "text", text: .}] elif type == "array" then . else [] end';
|
|
2428
2231
|
const ghostHookScript = [
|
|
2429
2232
|
"#!/bin/bash",
|
|
@@ -3295,12 +3098,12 @@ function provisionStopHook(codeName) {
|
|
|
3295
3098
|
"fi",
|
|
3296
3099
|
"exit 0"
|
|
3297
3100
|
].join("\n") + "\n";
|
|
3298
|
-
|
|
3101
|
+
writeFileSync4(ghostHookPath, ghostHookScript, { mode: 493 });
|
|
3299
3102
|
const backlogHookPath = provisionBacklogPullHook(codeName);
|
|
3300
|
-
const settingsPath =
|
|
3103
|
+
const settingsPath = join3(claudeDir, "settings.local.json");
|
|
3301
3104
|
let settings = {};
|
|
3302
3105
|
try {
|
|
3303
|
-
settings = JSON.parse(
|
|
3106
|
+
settings = JSON.parse(readFileSync4(settingsPath, "utf-8"));
|
|
3304
3107
|
} catch {
|
|
3305
3108
|
}
|
|
3306
3109
|
const hooks = settings["hooks"] ?? {};
|
|
@@ -3314,21 +3117,21 @@ function provisionStopHook(codeName) {
|
|
|
3314
3117
|
}
|
|
3315
3118
|
];
|
|
3316
3119
|
settings["hooks"] = hooks;
|
|
3317
|
-
|
|
3120
|
+
writeFileSync4(settingsPath, JSON.stringify(settings, null, 2));
|
|
3318
3121
|
}
|
|
3319
3122
|
function provisionIsolationHook(codeName, agentId) {
|
|
3320
3123
|
const projectDir = getProjectDir(codeName);
|
|
3321
|
-
const claudeDir =
|
|
3322
|
-
|
|
3124
|
+
const claudeDir = join3(projectDir, ".claude");
|
|
3125
|
+
mkdirSync3(claudeDir, { recursive: true });
|
|
3323
3126
|
const hasAgentId = agentId !== void 0;
|
|
3324
3127
|
if (hasAgentId)
|
|
3325
3128
|
assertValidAgentId(agentId);
|
|
3326
3129
|
const homeDir = getHomeDir();
|
|
3327
|
-
const augmentedBase =
|
|
3130
|
+
const augmentedBase = join3(homeDir, ".augmented");
|
|
3328
3131
|
const ownAgentDir = getAgentDir(codeName);
|
|
3329
|
-
const logFile =
|
|
3132
|
+
const logFile = join3(ownAgentDir, "isolation.log");
|
|
3330
3133
|
const idAllowClause = hasAgentId ? ` && [ "$AGENT_DIR" != "${agentId}" ]` : "";
|
|
3331
|
-
const hookScriptPath =
|
|
3134
|
+
const hookScriptPath = join3(claudeDir, "agt-isolation-hook.sh");
|
|
3332
3135
|
const hookScript = [
|
|
3333
3136
|
"#!/bin/bash",
|
|
3334
3137
|
"# Auto-generated by Augmented \u2014 prevents cross-agent file access.",
|
|
@@ -3381,11 +3184,11 @@ function provisionIsolationHook(codeName, agentId) {
|
|
|
3381
3184
|
"",
|
|
3382
3185
|
"exit 0"
|
|
3383
3186
|
].join("\n") + "\n";
|
|
3384
|
-
|
|
3385
|
-
const settingsPath =
|
|
3187
|
+
writeFileSync4(hookScriptPath, hookScript, { mode: 493 });
|
|
3188
|
+
const settingsPath = join3(claudeDir, "settings.local.json");
|
|
3386
3189
|
let settings = {};
|
|
3387
3190
|
try {
|
|
3388
|
-
settings = JSON.parse(
|
|
3191
|
+
settings = JSON.parse(readFileSync4(settingsPath, "utf-8"));
|
|
3389
3192
|
} catch {
|
|
3390
3193
|
}
|
|
3391
3194
|
const hooks = settings["hooks"] ?? {};
|
|
@@ -3400,13 +3203,13 @@ function provisionIsolationHook(codeName, agentId) {
|
|
|
3400
3203
|
}
|
|
3401
3204
|
];
|
|
3402
3205
|
settings["hooks"] = hooks;
|
|
3403
|
-
|
|
3206
|
+
writeFileSync4(settingsPath, JSON.stringify(settings, null, 2));
|
|
3404
3207
|
}
|
|
3405
3208
|
function provisionBacklogPullHook(codeName) {
|
|
3406
3209
|
const projectDir = getProjectDir(codeName);
|
|
3407
|
-
const claudeDir =
|
|
3408
|
-
|
|
3409
|
-
const hookScriptPath =
|
|
3210
|
+
const claudeDir = join3(projectDir, ".claude");
|
|
3211
|
+
mkdirSync3(claudeDir, { recursive: true });
|
|
3212
|
+
const hookScriptPath = join3(claudeDir, "agt-backlog-pull-hook.sh");
|
|
3410
3213
|
const hookScript = `#!/usr/bin/env bash
|
|
3411
3214
|
# Auto-generated by Augmented (CS-1549) \u2014 Stop hook: don't end a turn idle
|
|
3412
3215
|
# beside a non-empty backlog. Fail-open on every path; blocks at most once per
|
|
@@ -3568,14 +3371,14 @@ If you genuinely should not pull it, say so in one line and why (it is deliberat
|
|
|
3568
3371
|
jq -cn --arg r "$REASON" '{decision:"block", reason:$r}'
|
|
3569
3372
|
exit 0
|
|
3570
3373
|
`;
|
|
3571
|
-
|
|
3374
|
+
writeFileSync4(hookScriptPath, hookScript, { mode: 493 });
|
|
3572
3375
|
return hookScriptPath;
|
|
3573
3376
|
}
|
|
3574
3377
|
function provisionAutoKanbanProgressHook(codeName) {
|
|
3575
3378
|
const projectDir = getProjectDir(codeName);
|
|
3576
|
-
const claudeDir =
|
|
3577
|
-
|
|
3578
|
-
const hookScriptPath =
|
|
3379
|
+
const claudeDir = join3(projectDir, ".claude");
|
|
3380
|
+
mkdirSync3(claudeDir, { recursive: true });
|
|
3381
|
+
const hookScriptPath = join3(claudeDir, "agt-auto-kanban-progress-hook.sh");
|
|
3579
3382
|
const hookScript = `#!/usr/bin/env bash
|
|
3580
3383
|
# Auto-generated by Augmented (ENG-6179 / ENG-6241) \u2014 PostToolUse auto-progress.
|
|
3581
3384
|
# Maps the agent's latest tool action onto its active in-thread kanban progress
|
|
@@ -3683,11 +3486,11 @@ BODY="$(jq -nc --arg a "$AGENT_ID" --arg s "$STEP" '{agent_id:$a, step:$s}' 2>/d
|
|
|
3683
3486
|
|
|
3684
3487
|
exit 0
|
|
3685
3488
|
`;
|
|
3686
|
-
|
|
3687
|
-
const settingsPath =
|
|
3489
|
+
writeFileSync4(hookScriptPath, hookScript, { mode: 493 });
|
|
3490
|
+
const settingsPath = join3(claudeDir, "settings.local.json");
|
|
3688
3491
|
let settings = {};
|
|
3689
3492
|
try {
|
|
3690
|
-
settings = JSON.parse(
|
|
3493
|
+
settings = JSON.parse(readFileSync4(settingsPath, "utf-8"));
|
|
3691
3494
|
} catch {
|
|
3692
3495
|
}
|
|
3693
3496
|
const hooks = settings["hooks"] ?? {};
|
|
@@ -3699,13 +3502,13 @@ exit 0
|
|
|
3699
3502
|
}
|
|
3700
3503
|
];
|
|
3701
3504
|
settings["hooks"] = hooks;
|
|
3702
|
-
|
|
3505
|
+
writeFileSync4(settingsPath, JSON.stringify(settings, null, 2));
|
|
3703
3506
|
}
|
|
3704
3507
|
function provisionChannelProgressHook(codeName) {
|
|
3705
3508
|
const projectDir = getProjectDir(codeName);
|
|
3706
|
-
const claudeDir =
|
|
3707
|
-
|
|
3708
|
-
const hookScriptPath =
|
|
3509
|
+
const claudeDir = join3(projectDir, ".claude");
|
|
3510
|
+
mkdirSync3(claudeDir, { recursive: true });
|
|
3511
|
+
const hookScriptPath = join3(claudeDir, "agt-channel-progress-hook.sh");
|
|
3709
3512
|
const hookScript = `#!/usr/bin/env bash
|
|
3710
3513
|
# Auto-generated by Augmented (ENG-6567 Phase 2) \u2014 PostToolUse channel-progress
|
|
3711
3514
|
# heartbeat. Writes a throttled local {step, updated_at_ms} the channel MCP reads
|
|
@@ -3772,11 +3575,11 @@ else
|
|
|
3772
3575
|
fi
|
|
3773
3576
|
exit 0
|
|
3774
3577
|
`;
|
|
3775
|
-
|
|
3776
|
-
const settingsPath =
|
|
3578
|
+
writeFileSync4(hookScriptPath, hookScript, { mode: 493 });
|
|
3579
|
+
const settingsPath = join3(claudeDir, "settings.local.json");
|
|
3777
3580
|
let settings = {};
|
|
3778
3581
|
try {
|
|
3779
|
-
settings = JSON.parse(
|
|
3582
|
+
settings = JSON.parse(readFileSync4(settingsPath, "utf-8"));
|
|
3780
3583
|
} catch {
|
|
3781
3584
|
}
|
|
3782
3585
|
const hooks = settings["hooks"] ?? {};
|
|
@@ -3792,14 +3595,14 @@ exit 0
|
|
|
3792
3595
|
}
|
|
3793
3596
|
hooks["PostToolUse"] = groups;
|
|
3794
3597
|
settings["hooks"] = hooks;
|
|
3795
|
-
|
|
3598
|
+
writeFileSync4(settingsPath, JSON.stringify(settings, null, 2));
|
|
3796
3599
|
}
|
|
3797
3600
|
function provisionOrientHook(codeName) {
|
|
3798
3601
|
const projectDir = getProjectDir(codeName);
|
|
3799
|
-
const claudeDir =
|
|
3800
|
-
|
|
3602
|
+
const claudeDir = join3(projectDir, ".claude");
|
|
3603
|
+
mkdirSync3(claudeDir, { recursive: true });
|
|
3801
3604
|
const agentDir = getAgentDir(codeName);
|
|
3802
|
-
const hookScriptPath =
|
|
3605
|
+
const hookScriptPath = join3(claudeDir, "agt-orient-hook.sh");
|
|
3803
3606
|
const hookScript = [
|
|
3804
3607
|
"#!/bin/bash",
|
|
3805
3608
|
"# Auto-generated by Augmented (ENG-5397) \u2014 SessionStart orientation hook.",
|
|
@@ -3949,11 +3752,11 @@ function provisionOrientHook(codeName) {
|
|
|
3949
3752
|
"fi",
|
|
3950
3753
|
"exit 0"
|
|
3951
3754
|
].join("\n") + "\n";
|
|
3952
|
-
|
|
3953
|
-
const settingsPath =
|
|
3755
|
+
writeFileSync4(hookScriptPath, hookScript, { mode: 493 });
|
|
3756
|
+
const settingsPath = join3(claudeDir, "settings.local.json");
|
|
3954
3757
|
let settings = {};
|
|
3955
3758
|
try {
|
|
3956
|
-
settings = JSON.parse(
|
|
3759
|
+
settings = JSON.parse(readFileSync4(settingsPath, "utf-8"));
|
|
3957
3760
|
} catch {
|
|
3958
3761
|
}
|
|
3959
3762
|
const hooks = settings["hooks"] ?? {};
|
|
@@ -3973,15 +3776,15 @@ function provisionOrientHook(codeName) {
|
|
|
3973
3776
|
}
|
|
3974
3777
|
hooks["SessionStart"] = existingSessionStart;
|
|
3975
3778
|
settings["hooks"] = hooks;
|
|
3976
|
-
|
|
3779
|
+
writeFileSync4(settingsPath, JSON.stringify(settings, null, 2));
|
|
3977
3780
|
}
|
|
3978
3781
|
function provisionPreCompactHook(codeName) {
|
|
3979
3782
|
const projectDir = getProjectDir(codeName);
|
|
3980
|
-
const claudeDir =
|
|
3981
|
-
|
|
3783
|
+
const claudeDir = join3(projectDir, ".claude");
|
|
3784
|
+
mkdirSync3(claudeDir, { recursive: true });
|
|
3982
3785
|
const agentDir = getAgentDir(codeName);
|
|
3983
3786
|
const jqNormalizeContent = '(.message.content // .content // []) | if type == "string" then [{type: "text", text: .}] elif type == "array" then . else [] end';
|
|
3984
|
-
const hookScriptPath =
|
|
3787
|
+
const hookScriptPath = join3(claudeDir, "agt-pre-compact-hook.sh");
|
|
3985
3788
|
const hookScript = [
|
|
3986
3789
|
"#!/bin/bash",
|
|
3987
3790
|
"# Auto-generated by Augmented (ENG-7339) - PreCompact courtesy notice.",
|
|
@@ -4085,12 +3888,12 @@ function provisionPreCompactHook(codeName) {
|
|
|
4085
3888
|
'if [ "$WROTE" = "1" ]; then date +%s > "$NOTICE_MARKER" 2>/dev/null || true; fi',
|
|
4086
3889
|
"exit 0"
|
|
4087
3890
|
].join("\n") + "\n";
|
|
4088
|
-
|
|
4089
|
-
|
|
4090
|
-
const settingsPath =
|
|
3891
|
+
writeFileSync4(hookScriptPath, hookScript, { mode: 493 });
|
|
3892
|
+
chmodSync4(hookScriptPath, 493);
|
|
3893
|
+
const settingsPath = join3(claudeDir, "settings.local.json");
|
|
4091
3894
|
let settings = {};
|
|
4092
3895
|
try {
|
|
4093
|
-
settings = JSON.parse(
|
|
3896
|
+
settings = JSON.parse(readFileSync4(settingsPath, "utf-8"));
|
|
4094
3897
|
} catch {
|
|
4095
3898
|
}
|
|
4096
3899
|
const hooks = settings["hooks"] ?? {};
|
|
@@ -4110,14 +3913,14 @@ function provisionPreCompactHook(codeName) {
|
|
|
4110
3913
|
}
|
|
4111
3914
|
hooks["PreCompact"] = existingPreCompact;
|
|
4112
3915
|
settings["hooks"] = hooks;
|
|
4113
|
-
|
|
3916
|
+
writeFileSync4(settingsPath, JSON.stringify(settings, null, 2));
|
|
4114
3917
|
}
|
|
4115
3918
|
function provisionSessionStateHook(codeName) {
|
|
4116
3919
|
const projectDir = getProjectDir(codeName);
|
|
4117
|
-
const claudeDir =
|
|
4118
|
-
|
|
3920
|
+
const claudeDir = join3(projectDir, ".claude");
|
|
3921
|
+
mkdirSync3(claudeDir, { recursive: true });
|
|
4119
3922
|
const agentDir = getAgentDir(codeName);
|
|
4120
|
-
const hookScriptPath =
|
|
3923
|
+
const hookScriptPath = join3(claudeDir, "agt-session-state-hook.sh");
|
|
4121
3924
|
const hookScript = `#!/usr/bin/env bash
|
|
4122
3925
|
# Auto-generated by Augmented (ENG-6233 / ENG-6268) \u2014 SessionStart session-state
|
|
4123
3926
|
# recorder. Writes the model + session origin (which only the agent's own
|
|
@@ -4194,11 +3997,11 @@ fi
|
|
|
4194
3997
|
|
|
4195
3998
|
exit 0
|
|
4196
3999
|
`;
|
|
4197
|
-
|
|
4198
|
-
const settingsPath =
|
|
4000
|
+
writeFileSync4(hookScriptPath, hookScript, { mode: 493 });
|
|
4001
|
+
const settingsPath = join3(claudeDir, "settings.local.json");
|
|
4199
4002
|
let settings = {};
|
|
4200
4003
|
try {
|
|
4201
|
-
settings = JSON.parse(
|
|
4004
|
+
settings = JSON.parse(readFileSync4(settingsPath, "utf-8"));
|
|
4202
4005
|
} catch {
|
|
4203
4006
|
}
|
|
4204
4007
|
const hooks = settings["hooks"] ?? {};
|
|
@@ -4214,13 +4017,13 @@ exit 0
|
|
|
4214
4017
|
}
|
|
4215
4018
|
hooks["SessionStart"] = existingSessionStart;
|
|
4216
4019
|
settings["hooks"] = hooks;
|
|
4217
|
-
|
|
4020
|
+
writeFileSync4(settingsPath, JSON.stringify(settings, null, 2));
|
|
4218
4021
|
}
|
|
4219
4022
|
function modifyJsonConfig(filePath, fn) {
|
|
4220
4023
|
let originalContent;
|
|
4221
4024
|
let config;
|
|
4222
4025
|
try {
|
|
4223
|
-
originalContent =
|
|
4026
|
+
originalContent = readFileSync4(filePath, "utf-8");
|
|
4224
4027
|
config = JSON.parse(originalContent);
|
|
4225
4028
|
} catch {
|
|
4226
4029
|
return;
|
|
@@ -4231,7 +4034,7 @@ function modifyJsonConfig(filePath, fn) {
|
|
|
4231
4034
|
const newContent = JSON.stringify(config, null, 2);
|
|
4232
4035
|
if (newContent === originalContent)
|
|
4233
4036
|
return;
|
|
4234
|
-
|
|
4037
|
+
writeFileSync4(filePath, newContent);
|
|
4235
4038
|
}
|
|
4236
4039
|
var SECRETS_DENY_PERMISSIONS = [
|
|
4237
4040
|
// Read blocks
|
|
@@ -4329,7 +4132,7 @@ function buildSettingsJson(input) {
|
|
|
4329
4132
|
const projectDir = getProjectDir(agent.code_name);
|
|
4330
4133
|
const agentDir = getAgentDir(agent.code_name);
|
|
4331
4134
|
const homeDir = getHomeDir();
|
|
4332
|
-
const codenameAliasDir =
|
|
4135
|
+
const codenameAliasDir = join3(homeDir, ".augmented", agent.code_name);
|
|
4333
4136
|
settings["allowedDirectories"] = [
|
|
4334
4137
|
.../* @__PURE__ */ new Set([
|
|
4335
4138
|
projectDir,
|
|
@@ -4338,7 +4141,7 @@ function buildSettingsJson(input) {
|
|
|
4338
4141
|
// Agent's config dir (.env, schedules, registration)
|
|
4339
4142
|
codenameAliasDir,
|
|
4340
4143
|
// Codename symlink alias (== agentDir for legacy agents)
|
|
4341
|
-
|
|
4144
|
+
join3(homeDir, ".augmented", "_mcp"),
|
|
4342
4145
|
// Shared MCP binaries
|
|
4343
4146
|
"/tmp"
|
|
4344
4147
|
// Temp files
|
|
@@ -4456,10 +4259,10 @@ ${integrationsBlock}`;
|
|
|
4456
4259
|
function renderAugmentedWorkerForAgent(codeName) {
|
|
4457
4260
|
const agentDir = getAgentDir(codeName);
|
|
4458
4261
|
const projectDir = getProjectDir(codeName);
|
|
4459
|
-
const provisionMcpPath =
|
|
4262
|
+
const provisionMcpPath = join3(agentDir, "provision", ".mcp.json");
|
|
4460
4263
|
let mcpServerKeys;
|
|
4461
4264
|
try {
|
|
4462
|
-
const config = JSON.parse(
|
|
4265
|
+
const config = JSON.parse(readFileSync4(provisionMcpPath, "utf-8"));
|
|
4463
4266
|
mcpServerKeys = Object.keys(config.mcpServers ?? {});
|
|
4464
4267
|
} catch {
|
|
4465
4268
|
return;
|
|
@@ -4467,10 +4270,10 @@ function renderAugmentedWorkerForAgent(codeName) {
|
|
|
4467
4270
|
const integrations = readIntegrationsSummaryForAgent(codeName);
|
|
4468
4271
|
const content = buildAugmentedWorkerAgent({ mcpServerKeys, integrations });
|
|
4469
4272
|
for (const baseDir of [agentDir, projectDir]) {
|
|
4470
|
-
const target =
|
|
4273
|
+
const target = join3(baseDir, ".claude", "agents", "augmented-worker.md");
|
|
4471
4274
|
try {
|
|
4472
|
-
|
|
4473
|
-
|
|
4275
|
+
mkdirSync3(dirname3(target), { recursive: true });
|
|
4276
|
+
writeFileSync4(target, content);
|
|
4474
4277
|
} catch {
|
|
4475
4278
|
}
|
|
4476
4279
|
}
|
|
@@ -4496,8 +4299,8 @@ function buildPostizMcpEntry(integration) {
|
|
|
4496
4299
|
}
|
|
4497
4300
|
function buildMcpJson(input) {
|
|
4498
4301
|
const mcpServers = {};
|
|
4499
|
-
const turnInitiatorFile =
|
|
4500
|
-
const localMcpPath =
|
|
4302
|
+
const turnInitiatorFile = join3(getAgentDir(input.agent.code_name), ".current-turn-initiator.json");
|
|
4303
|
+
const localMcpPath = join3(getHomeDir(), ".augmented", "_mcp", "index.js");
|
|
4501
4304
|
mcpServers["augmented"] = {
|
|
4502
4305
|
command: "node",
|
|
4503
4306
|
args: [localMcpPath],
|
|
@@ -4549,7 +4352,7 @@ function buildMcpJson(input) {
|
|
|
4549
4352
|
const xeroIntegration = input.integrations?.find((i) => i.definition_id === "xero");
|
|
4550
4353
|
if (xeroIntegration) {
|
|
4551
4354
|
const brokerMode = Boolean(xeroIntegration.id);
|
|
4552
|
-
const localXeroMcpPath =
|
|
4355
|
+
const localXeroMcpPath = join3(getHomeDir(), ".augmented", "_mcp", "xero.js");
|
|
4553
4356
|
mcpServers["xero"] = {
|
|
4554
4357
|
command: "node",
|
|
4555
4358
|
args: [localXeroMcpPath],
|
|
@@ -4589,7 +4392,7 @@ function buildMcpJson(input) {
|
|
|
4589
4392
|
// getProjectDir (the ADR-0049 seam), not the MCP child's inherited
|
|
4590
4393
|
// cwd, so the path stays correct if Claude Code ever spawns the
|
|
4591
4394
|
// server from somewhere else.
|
|
4592
|
-
XERO_EXPORT_DIR:
|
|
4395
|
+
XERO_EXPORT_DIR: join3(getProjectDir(input.agent.code_name), "xero-exports"),
|
|
4593
4396
|
PATH: process.env["PATH"] ?? "",
|
|
4594
4397
|
HOME: process.env["HOME"] ?? ""
|
|
4595
4398
|
}
|
|
@@ -4600,8 +4403,8 @@ function buildMcpJson(input) {
|
|
|
4600
4403
|
mcpServers["postiz"] = buildPostizMcpEntry(postizIntegration);
|
|
4601
4404
|
}
|
|
4602
4405
|
const remoteOAuthProxyPaths = {
|
|
4603
|
-
proxyPath:
|
|
4604
|
-
tokenFile:
|
|
4406
|
+
proxyPath: join3(getHomeDir(), ".augmented", "_mcp", "remote-oauth-proxy.js"),
|
|
4407
|
+
tokenFile: join3(getProjectDir(input.agent.code_name), ".env.integrations")
|
|
4605
4408
|
};
|
|
4606
4409
|
for (const integration of input.integrations ?? []) {
|
|
4607
4410
|
const connectionKey = integration.connection_key;
|
|
@@ -4667,7 +4470,7 @@ function buildMcpJson(input) {
|
|
|
4667
4470
|
}
|
|
4668
4471
|
const hasAdminDebug = input.integrations?.some((i) => i.definition_id === "augmented-admin") ?? false;
|
|
4669
4472
|
if (hasAdminDebug) {
|
|
4670
|
-
const localAdminMcpPath =
|
|
4473
|
+
const localAdminMcpPath = join3(getHomeDir(), ".augmented", "_mcp", "augmented-admin.js");
|
|
4671
4474
|
mcpServers["augmented-admin"] = {
|
|
4672
4475
|
command: "node",
|
|
4673
4476
|
args: [localAdminMcpPath],
|
|
@@ -4681,7 +4484,7 @@ function buildMcpJson(input) {
|
|
|
4681
4484
|
}
|
|
4682
4485
|
const hasSupport = input.integrations?.some((i) => i.definition_id === "augmented-support") ?? false;
|
|
4683
4486
|
if (hasSupport) {
|
|
4684
|
-
const localSupportMcpPath =
|
|
4487
|
+
const localSupportMcpPath = join3(getHomeDir(), ".augmented", "_mcp", "augmented-support.js");
|
|
4685
4488
|
mcpServers["augmented-support"] = {
|
|
4686
4489
|
command: "node",
|
|
4687
4490
|
args: [localSupportMcpPath],
|
|
@@ -4695,7 +4498,7 @@ function buildMcpJson(input) {
|
|
|
4695
4498
|
}
|
|
4696
4499
|
const hasHelpKb = input.integrations?.some((i) => i.definition_id === "augmented-help-kb") ?? false;
|
|
4697
4500
|
if (hasHelpKb) {
|
|
4698
|
-
const localHelpKbMcpPath =
|
|
4501
|
+
const localHelpKbMcpPath = join3(getHomeDir(), ".augmented", "_mcp", "augmented-help-kb.js");
|
|
4699
4502
|
mcpServers["augmented-help-kb"] = {
|
|
4700
4503
|
command: "node",
|
|
4701
4504
|
args: [localHelpKbMcpPath],
|
|
@@ -4709,7 +4512,7 @@ function buildMcpJson(input) {
|
|
|
4709
4512
|
}
|
|
4710
4513
|
const origamiIntegration = input.integrations?.find((i) => i.definition_id === "origami");
|
|
4711
4514
|
if (origamiIntegration?.stdioMcp === true && origamiIntegration.id) {
|
|
4712
|
-
const localOrigamiMcpPath =
|
|
4515
|
+
const localOrigamiMcpPath = join3(getHomeDir(), ".augmented", "_mcp", "origami.js");
|
|
4713
4516
|
mcpServers["origami"] = {
|
|
4714
4517
|
command: "node",
|
|
4715
4518
|
args: [localOrigamiMcpPath],
|
|
@@ -4953,27 +4756,27 @@ ${sections}`
|
|
|
4953
4756
|
},
|
|
4954
4757
|
async getRegisteredAgents(_profile) {
|
|
4955
4758
|
const homeDir = getHomeDir();
|
|
4956
|
-
const augDir =
|
|
4759
|
+
const augDir = join3(homeDir, ".augmented");
|
|
4957
4760
|
const agents = /* @__PURE__ */ new Set();
|
|
4958
4761
|
try {
|
|
4959
4762
|
const entries = readdirSync(augDir);
|
|
4960
4763
|
for (const entry of entries) {
|
|
4961
4764
|
if (entry.startsWith("_") || entry.startsWith("."))
|
|
4962
4765
|
continue;
|
|
4963
|
-
const agentRoot =
|
|
4766
|
+
const agentRoot = join3(augDir, entry);
|
|
4964
4767
|
let st;
|
|
4965
4768
|
try {
|
|
4966
|
-
st =
|
|
4769
|
+
st = lstatSync(agentRoot);
|
|
4967
4770
|
} catch {
|
|
4968
4771
|
continue;
|
|
4969
4772
|
}
|
|
4970
4773
|
if (st.isSymbolicLink() || !st.isDirectory())
|
|
4971
4774
|
continue;
|
|
4972
|
-
if (!
|
|
4775
|
+
if (!existsSync4(join3(agentRoot, "registration.json")))
|
|
4973
4776
|
continue;
|
|
4974
4777
|
let codeName = entry;
|
|
4975
4778
|
try {
|
|
4976
|
-
const reg = JSON.parse(
|
|
4779
|
+
const reg = JSON.parse(readFileSync4(join3(agentRoot, "registration.json"), "utf8"));
|
|
4977
4780
|
if (reg && typeof reg.code_name === "string" && reg.code_name) {
|
|
4978
4781
|
codeName = reg.code_name;
|
|
4979
4782
|
}
|
|
@@ -4992,9 +4795,9 @@ ${sections}`
|
|
|
4992
4795
|
}
|
|
4993
4796
|
const agentDir = getAgentDir(codeName);
|
|
4994
4797
|
const projectDir = getProjectDir(codeName);
|
|
4995
|
-
|
|
4996
|
-
|
|
4997
|
-
|
|
4798
|
+
mkdirSync3(agentDir, { recursive: true });
|
|
4799
|
+
mkdirSync3(projectDir, { recursive: true });
|
|
4800
|
+
writeFileSync4(join3(agentDir, "registration.json"), JSON.stringify({
|
|
4998
4801
|
code_name: codeName,
|
|
4999
4802
|
agent_id: agentId ?? null,
|
|
5000
4803
|
team_dir: teamDir,
|
|
@@ -5002,7 +4805,7 @@ ${sections}`
|
|
|
5002
4805
|
framework: "claude-code",
|
|
5003
4806
|
registered_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
5004
4807
|
}, null, 2));
|
|
5005
|
-
if (
|
|
4808
|
+
if (existsSync4(teamDir)) {
|
|
5006
4809
|
deployArtifactsToProject(codeName, teamDir);
|
|
5007
4810
|
}
|
|
5008
4811
|
return true;
|
|
@@ -5013,8 +4816,8 @@ ${sections}`
|
|
|
5013
4816
|
async deregisterAgent(codeName) {
|
|
5014
4817
|
try {
|
|
5015
4818
|
const agentDir = getAgentDir(codeName);
|
|
5016
|
-
const regFile =
|
|
5017
|
-
if (
|
|
4819
|
+
const regFile = join3(agentDir, "registration.json");
|
|
4820
|
+
if (existsSync4(regFile)) {
|
|
5018
4821
|
const { unlinkSync: unlinkSync5 } = await import("fs");
|
|
5019
4822
|
unlinkSync5(regFile);
|
|
5020
4823
|
}
|
|
@@ -5025,7 +4828,7 @@ ${sections}`
|
|
|
5025
4828
|
},
|
|
5026
4829
|
writeAuthProfiles(codeName, profiles) {
|
|
5027
4830
|
const agentDir = getAgentDir(codeName);
|
|
5028
|
-
|
|
4831
|
+
mkdirSync3(agentDir, { recursive: true });
|
|
5029
4832
|
const envLines = ["# Augmented auth profiles \u2014 auto-generated, do not edit"];
|
|
5030
4833
|
for (const p of profiles) {
|
|
5031
4834
|
if (!p.api_key)
|
|
@@ -5039,9 +4842,9 @@ ${sections}`
|
|
|
5039
4842
|
}
|
|
5040
4843
|
}
|
|
5041
4844
|
if (envLines.length > 1) {
|
|
5042
|
-
const envPath =
|
|
5043
|
-
|
|
5044
|
-
|
|
4845
|
+
const envPath = join3(agentDir, ".env");
|
|
4846
|
+
writeFileSync4(envPath, envLines.join("\n") + "\n");
|
|
4847
|
+
chmodSync4(envPath, SECRET_FILE_MODE);
|
|
5045
4848
|
}
|
|
5046
4849
|
},
|
|
5047
4850
|
// Claude Code has no gateway process — methods intentionally omitted
|
|
@@ -5074,7 +4877,7 @@ ${sections}`
|
|
|
5074
4877
|
const senderPolicyInternalOnly = options?.senderPolicy?.internal_only === true;
|
|
5075
4878
|
const senderPolicyEnv = senderPolicyTeamId ? { AGT_TEAM_ID: senderPolicyTeamId } : {};
|
|
5076
4879
|
const agentDir = getAgentDir(codeName);
|
|
5077
|
-
|
|
4880
|
+
mkdirSync3(agentDir, { recursive: true });
|
|
5078
4881
|
const persistChannelSecrets = options?.channelSecretDelivery !== "spawn-env";
|
|
5079
4882
|
const channelSecretUpdates = (updates, fullKeySet) => {
|
|
5080
4883
|
if (persistChannelSecrets)
|
|
@@ -5088,7 +4891,7 @@ ${sections}`
|
|
|
5088
4891
|
if (!botToken)
|
|
5089
4892
|
return;
|
|
5090
4893
|
const allowedChats = config["allowed_chats"];
|
|
5091
|
-
const localTelegramChannel =
|
|
4894
|
+
const localTelegramChannel = join3(getHomeDir(), ".augmented", "_mcp", "telegram-channel.js");
|
|
5092
4895
|
const resolvedAgtHostForTelegram = process.env["AGT_HOST"]?.trim() || "https://api.augmented.team";
|
|
5093
4896
|
const resolvedAgtApiKeyForTelegram = process.env["AGT_API_KEY"]?.trim();
|
|
5094
4897
|
writeEnvIntegrationsForAgent(codeName, {
|
|
@@ -5103,7 +4906,7 @@ ${sections}`
|
|
|
5103
4906
|
...options?.agentId ? { AGT_AGENT_ID: options.agentId } : {},
|
|
5104
4907
|
...tzEnv,
|
|
5105
4908
|
// ENG-6582 (D16): stamp the verified turn initiator for broker MCPs.
|
|
5106
|
-
AGT_TURN_INITIATOR_FILE:
|
|
4909
|
+
AGT_TURN_INITIATOR_FILE: join3(getAgentDir(codeName), ".current-turn-initiator.json")
|
|
5107
4910
|
};
|
|
5108
4911
|
if (allowedChats && allowedChats.length > 0) {
|
|
5109
4912
|
telegramEnv.TELEGRAM_ALLOWED_CHATS = allowedChats.join(",");
|
|
@@ -5163,11 +4966,11 @@ ${sections}`
|
|
|
5163
4966
|
args: [localTelegramChannel],
|
|
5164
4967
|
env: telegramEnv
|
|
5165
4968
|
};
|
|
5166
|
-
const provisionMcpPath =
|
|
5167
|
-
|
|
4969
|
+
const provisionMcpPath = join3(agentDir, "provision", ".mcp.json");
|
|
4970
|
+
mkdirSync3(dirname3(provisionMcpPath), { recursive: true });
|
|
5168
4971
|
let mcpConfig2 = { mcpServers: {} };
|
|
5169
4972
|
try {
|
|
5170
|
-
mcpConfig2 = JSON.parse(
|
|
4973
|
+
mcpConfig2 = JSON.parse(readFileSync4(provisionMcpPath, "utf-8"));
|
|
5171
4974
|
if (!mcpConfig2.mcpServers)
|
|
5172
4975
|
mcpConfig2.mcpServers = {};
|
|
5173
4976
|
} catch {
|
|
@@ -5180,13 +4983,13 @@ ${sections}`
|
|
|
5180
4983
|
return;
|
|
5181
4984
|
}
|
|
5182
4985
|
if (isPersistent && (channelId === "discord" || channelId === "slack")) {
|
|
5183
|
-
const channelDir =
|
|
4986
|
+
const channelDir = join3(getHomeDir(), ".claude", "channels", channelId);
|
|
5184
4987
|
if (channelId === "discord")
|
|
5185
|
-
|
|
4988
|
+
mkdirSync3(channelDir, { recursive: true });
|
|
5186
4989
|
if (channelId === "discord") {
|
|
5187
4990
|
const botToken = config["bot_token"];
|
|
5188
4991
|
if (botToken) {
|
|
5189
|
-
|
|
4992
|
+
writeFileSync4(join3(channelDir, ".env"), `DISCORD_BOT_TOKEN=${botToken}
|
|
5190
4993
|
`);
|
|
5191
4994
|
}
|
|
5192
4995
|
} else if (channelId === "slack") {
|
|
@@ -5252,11 +5055,11 @@ ${sections}`
|
|
|
5252
5055
|
...appToken ? { SLACK_APP_TOKEN: appToken } : {}
|
|
5253
5056
|
}, ["SLACK_BOT_TOKEN", "SLACK_APP_TOKEN"])
|
|
5254
5057
|
});
|
|
5255
|
-
const localSlackChannel =
|
|
5058
|
+
const localSlackChannel = join3(getHomeDir(), ".augmented", "_mcp", "slack-channel.js");
|
|
5256
5059
|
const slackAvatarEnvUrl = resolveAvatarEnvUrl(options?.agentAvatarUrl).url;
|
|
5257
5060
|
const slackEntry = {
|
|
5258
|
-
command:
|
|
5259
|
-
args:
|
|
5061
|
+
command: existsSync4(localSlackChannel) ? "node" : "npx",
|
|
5062
|
+
args: existsSync4(localSlackChannel) ? [localSlackChannel] : ["-y", "@augmented/claude-code-channel-slack"],
|
|
5260
5063
|
env: {
|
|
5261
5064
|
SLACK_BOT_TOKEN: "${SLACK_BOT_TOKEN}",
|
|
5262
5065
|
...appToken ? { SLACK_APP_TOKEN: "${SLACK_APP_TOKEN}" } : {},
|
|
@@ -5338,14 +5141,14 @@ ${sections}`
|
|
|
5338
5141
|
...pingAllowedUsers.length > 0 ? { SLACK_PING_ALLOWED_USERS: pingAllowedUsers.join(",") } : {},
|
|
5339
5142
|
// ENG-6563 (D16): stamp the verified turn initiator so broker MCPs
|
|
5340
5143
|
// can forward it when the agent files an approval mid-turn.
|
|
5341
|
-
AGT_TURN_INITIATOR_FILE:
|
|
5144
|
+
AGT_TURN_INITIATOR_FILE: join3(agentDir, ".current-turn-initiator.json")
|
|
5342
5145
|
}
|
|
5343
5146
|
};
|
|
5344
|
-
const provisionMcpPath =
|
|
5345
|
-
|
|
5147
|
+
const provisionMcpPath = join3(agentDir, "provision", ".mcp.json");
|
|
5148
|
+
mkdirSync3(dirname3(provisionMcpPath), { recursive: true });
|
|
5346
5149
|
let mcpConfig2 = { mcpServers: {} };
|
|
5347
5150
|
try {
|
|
5348
|
-
mcpConfig2 = JSON.parse(
|
|
5151
|
+
mcpConfig2 = JSON.parse(readFileSync4(provisionMcpPath, "utf-8"));
|
|
5349
5152
|
if (!mcpConfig2.mcpServers)
|
|
5350
5153
|
mcpConfig2.mcpServers = {};
|
|
5351
5154
|
} catch {
|
|
@@ -5355,10 +5158,10 @@ ${sections}`
|
|
|
5355
5158
|
return;
|
|
5356
5159
|
}
|
|
5357
5160
|
syncMcpToProject(codeName);
|
|
5358
|
-
const staleChannelsPath =
|
|
5359
|
-
if (
|
|
5161
|
+
const staleChannelsPath = join3(getProjectDir(codeName), ".mcp-channels.json");
|
|
5162
|
+
if (existsSync4(staleChannelsPath)) {
|
|
5360
5163
|
try {
|
|
5361
|
-
|
|
5164
|
+
rmSync2(staleChannelsPath, { force: true });
|
|
5362
5165
|
} catch {
|
|
5363
5166
|
}
|
|
5364
5167
|
}
|
|
@@ -5366,11 +5169,11 @@ ${sections}`
|
|
|
5366
5169
|
}
|
|
5367
5170
|
return;
|
|
5368
5171
|
}
|
|
5369
|
-
const mcpJsonPath =
|
|
5370
|
-
|
|
5172
|
+
const mcpJsonPath = join3(agentDir, "provision", ".mcp.json");
|
|
5173
|
+
mkdirSync3(dirname3(mcpJsonPath), { recursive: true });
|
|
5371
5174
|
let mcpConfig;
|
|
5372
5175
|
try {
|
|
5373
|
-
mcpConfig = JSON.parse(
|
|
5176
|
+
mcpConfig = JSON.parse(readFileSync4(mcpJsonPath, "utf-8"));
|
|
5374
5177
|
} catch {
|
|
5375
5178
|
mcpConfig = { mcpServers: {} };
|
|
5376
5179
|
}
|
|
@@ -5389,7 +5192,7 @@ ${sections}`
|
|
|
5389
5192
|
const appToken = config["app_token"];
|
|
5390
5193
|
if (!botToken)
|
|
5391
5194
|
return;
|
|
5392
|
-
const localSlackChannel =
|
|
5195
|
+
const localSlackChannel = join3(getHomeDir(), ".augmented", "_mcp", "slack-channel.js");
|
|
5393
5196
|
const slackThreadAutoFollow = config["thread_auto_follow"];
|
|
5394
5197
|
const slackAutoFollowEnv = slackThreadAutoFollow && slackThreadAutoFollow !== "off" ? { SLACK_THREAD_AUTO_FOLLOW: slackThreadAutoFollow } : {};
|
|
5395
5198
|
const slackChannelResponseMode = config["channel_response_mode"];
|
|
@@ -5464,7 +5267,7 @@ ${sections}`
|
|
|
5464
5267
|
}, ["SLACK_BOT_TOKEN", "SLACK_APP_TOKEN"])
|
|
5465
5268
|
});
|
|
5466
5269
|
const slackAvatarEnvUrl = resolveAvatarEnvUrl(options?.agentAvatarUrl).url;
|
|
5467
|
-
if (isPersistent &&
|
|
5270
|
+
if (isPersistent && existsSync4(localSlackChannel)) {
|
|
5468
5271
|
mcpServers["slack"] = {
|
|
5469
5272
|
command: "node",
|
|
5470
5273
|
args: [localSlackChannel],
|
|
@@ -5482,7 +5285,7 @@ ${sections}`
|
|
|
5482
5285
|
...slackAgtAuthEnv,
|
|
5483
5286
|
...tzEnv,
|
|
5484
5287
|
// ENG-6563 (D16): stamp the verified turn initiator for broker MCPs.
|
|
5485
|
-
AGT_TURN_INITIATOR_FILE:
|
|
5288
|
+
AGT_TURN_INITIATOR_FILE: join3(getAgentDir(codeName), ".current-turn-initiator.json"),
|
|
5486
5289
|
// ENG-6155: avatar URL → bot Slack profile photo (see persistent
|
|
5487
5290
|
// branch above). Mirrored here so oneshot-mode agents get it too.
|
|
5488
5291
|
// ENG-6245: slackAvatarEnvUrl is null for data-URI / oversized values.
|
|
@@ -5507,7 +5310,7 @@ ${sections}`
|
|
|
5507
5310
|
...slackAgtAuthEnv,
|
|
5508
5311
|
...tzEnv,
|
|
5509
5312
|
// ENG-6563 (D16): stamp the verified turn initiator for broker MCPs.
|
|
5510
|
-
AGT_TURN_INITIATOR_FILE:
|
|
5313
|
+
AGT_TURN_INITIATOR_FILE: join3(getAgentDir(codeName), ".current-turn-initiator.json"),
|
|
5511
5314
|
// ENG-6155: avatar URL → bot Slack profile photo (see persistent
|
|
5512
5315
|
// branch above). Mirrored here so oneshot-mode agents get it too.
|
|
5513
5316
|
// ENG-6245: slackAvatarEnvUrl is null for data-URI / oversized values.
|
|
@@ -5520,12 +5323,12 @@ ${sections}`
|
|
|
5520
5323
|
const clientSecret = config["client_secret"];
|
|
5521
5324
|
if (!appId || !clientSecret)
|
|
5522
5325
|
return;
|
|
5523
|
-
const localTeamsChannel =
|
|
5326
|
+
const localTeamsChannel = join3(getHomeDir(), ".augmented", "_mcp", "teams-channel.js");
|
|
5524
5327
|
const agentDirMs = getAgentDir(codeName);
|
|
5525
5328
|
try {
|
|
5526
|
-
|
|
5527
|
-
|
|
5528
|
-
|
|
5329
|
+
mkdirSync3(join3(agentDirMs, "msteams-pending-inbound", ".markers"), { recursive: true });
|
|
5330
|
+
mkdirSync3(join3(agentDirMs, "msteams-pending-interactions"), { recursive: true });
|
|
5331
|
+
mkdirSync3(join3(agentDirMs, "msteams-recovery-outbox"), { recursive: true });
|
|
5529
5332
|
} catch {
|
|
5530
5333
|
}
|
|
5531
5334
|
const tenantId = config["tenant_id"] ?? "common";
|
|
@@ -5587,7 +5390,7 @@ ${sections}`
|
|
|
5587
5390
|
...senderPolicyInternalOnly ? { MSTEAMS_INTERNAL_ONLY: "true" } : {},
|
|
5588
5391
|
...senderPolicyInternalOnly && tenantId !== "common" ? { MSTEAMS_HOME_TENANT_ID: tenantId } : {}
|
|
5589
5392
|
};
|
|
5590
|
-
if (isPersistent &&
|
|
5393
|
+
if (isPersistent && existsSync4(localTeamsChannel)) {
|
|
5591
5394
|
mcpServers["msteams"] = {
|
|
5592
5395
|
command: "node",
|
|
5593
5396
|
args: [localTeamsChannel],
|
|
@@ -5603,7 +5406,7 @@ ${sections}`
|
|
|
5603
5406
|
}
|
|
5604
5407
|
if (channelId === "whatsapp") {
|
|
5605
5408
|
const provider = config["provider"] ?? "kapso";
|
|
5606
|
-
const localWhatsappChannel =
|
|
5409
|
+
const localWhatsappChannel = join3(getHomeDir(), ".augmented", "_mcp", "whatsapp-channel.js");
|
|
5607
5410
|
if (provider === "baileys") {
|
|
5608
5411
|
mcpServers["whatsapp"] = {
|
|
5609
5412
|
command: "node",
|
|
@@ -5622,7 +5425,7 @@ ${sections}`
|
|
|
5622
5425
|
const phoneNumberId = config["phone_number_id"];
|
|
5623
5426
|
if (projectApiKey && phoneNumberId) {
|
|
5624
5427
|
try {
|
|
5625
|
-
|
|
5428
|
+
mkdirSync3(join3(getAgentDir(codeName), "whatsapp-pending-inbound"), { recursive: true });
|
|
5626
5429
|
} catch {
|
|
5627
5430
|
}
|
|
5628
5431
|
writeEnvIntegrationsForAgent(codeName, {
|
|
@@ -5650,11 +5453,11 @@ ${sections}`
|
|
|
5650
5453
|
}
|
|
5651
5454
|
},
|
|
5652
5455
|
hasChannelCredentials(codeName, channelId) {
|
|
5653
|
-
const provisionMcpPath =
|
|
5654
|
-
if (!
|
|
5456
|
+
const provisionMcpPath = join3(getAgentDir(codeName), "provision", ".mcp.json");
|
|
5457
|
+
if (!existsSync4(provisionMcpPath))
|
|
5655
5458
|
return false;
|
|
5656
5459
|
try {
|
|
5657
|
-
const parsed = JSON.parse(
|
|
5460
|
+
const parsed = JSON.parse(readFileSync4(provisionMcpPath, "utf-8"));
|
|
5658
5461
|
return Boolean(parsed.mcpServers?.[channelId]);
|
|
5659
5462
|
} catch {
|
|
5660
5463
|
return false;
|
|
@@ -5662,7 +5465,7 @@ ${sections}`
|
|
|
5662
5465
|
},
|
|
5663
5466
|
removeChannelCredentials(codeName, channelId) {
|
|
5664
5467
|
const agentDir = getAgentDir(codeName);
|
|
5665
|
-
const mcpJsonPath =
|
|
5468
|
+
const mcpJsonPath = join3(agentDir, "provision", ".mcp.json");
|
|
5666
5469
|
modifyJsonConfig(mcpJsonPath, (config) => {
|
|
5667
5470
|
const mcpServers = config["mcpServers"];
|
|
5668
5471
|
if (!mcpServers || !(channelId in mcpServers))
|
|
@@ -5674,7 +5477,7 @@ ${sections}`
|
|
|
5674
5477
|
},
|
|
5675
5478
|
async updateAgentModel(codeName, model) {
|
|
5676
5479
|
const agentDir = getAgentDir(codeName);
|
|
5677
|
-
const settingsPath =
|
|
5480
|
+
const settingsPath = join3(agentDir, "provision", "settings.json");
|
|
5678
5481
|
let changed = false;
|
|
5679
5482
|
modifyJsonConfig(settingsPath, (config) => {
|
|
5680
5483
|
config["model"] = model;
|
|
@@ -5692,20 +5495,20 @@ ${sections}`
|
|
|
5692
5495
|
seedProfileConfig(codeName) {
|
|
5693
5496
|
const agentDir = getAgentDir(codeName);
|
|
5694
5497
|
const projectDir = getProjectDir(codeName);
|
|
5695
|
-
|
|
5696
|
-
|
|
5498
|
+
mkdirSync3(join3(agentDir, "provision"), { recursive: true });
|
|
5499
|
+
mkdirSync3(projectDir, { recursive: true });
|
|
5697
5500
|
},
|
|
5698
5501
|
syncScheduledTasks(codeName, tasks) {
|
|
5699
5502
|
const agentDir = getAgentDir(codeName);
|
|
5700
|
-
const schedulesPath =
|
|
5503
|
+
const schedulesPath = join3(agentDir, "schedules.json");
|
|
5701
5504
|
const mapped = mapScheduledTasks(tasks);
|
|
5702
|
-
|
|
5703
|
-
|
|
5505
|
+
mkdirSync3(agentDir, { recursive: true });
|
|
5506
|
+
writeFileSync4(schedulesPath, JSON.stringify({ schedules: mapped }, null, 2));
|
|
5704
5507
|
return Promise.resolve();
|
|
5705
5508
|
},
|
|
5706
5509
|
writeIntegrations(codeName, integrations, agentId, options) {
|
|
5707
5510
|
const agentDir = getAgentDir(codeName);
|
|
5708
|
-
|
|
5511
|
+
mkdirSync3(agentDir, { recursive: true });
|
|
5709
5512
|
const summariesForSidecar = integrations.map((i) => {
|
|
5710
5513
|
const def = INTEGRATION_REGISTRY.find((d) => d.id === i.definition_id);
|
|
5711
5514
|
return {
|
|
@@ -5822,7 +5625,7 @@ ${sections}`
|
|
|
5822
5625
|
xeroEnv.AGT_AGENT_ID = agentId;
|
|
5823
5626
|
xeroEnv.AGT_INTEGRATION_ID = xeroIntegration.id;
|
|
5824
5627
|
}
|
|
5825
|
-
const localXeroMcpPath =
|
|
5628
|
+
const localXeroMcpPath = join3(getHomeDir(), ".augmented", "_mcp", "xero.js");
|
|
5826
5629
|
this.writeMcpServer(codeName, "xero", {
|
|
5827
5630
|
command: "node",
|
|
5828
5631
|
args: [localXeroMcpPath],
|
|
@@ -5834,8 +5637,8 @@ ${sections}`
|
|
|
5834
5637
|
this.writeMcpServer(codeName, "postiz", buildPostizMcpEntry(postizIntegration));
|
|
5835
5638
|
}
|
|
5836
5639
|
const remoteOAuthProxyPaths = {
|
|
5837
|
-
proxyPath:
|
|
5838
|
-
tokenFile:
|
|
5640
|
+
proxyPath: join3(getHomeDir(), ".augmented", "_mcp", "remote-oauth-proxy.js"),
|
|
5641
|
+
tokenFile: join3(getProjectDir(codeName), ".env.integrations")
|
|
5839
5642
|
};
|
|
5840
5643
|
for (const integration of integrations) {
|
|
5841
5644
|
const connectionKey = integration.connection_key;
|
|
@@ -5876,7 +5679,7 @@ ${sections}`
|
|
|
5876
5679
|
// ENG-6586 (D16): keep incremental cloud-broker wiring in sync with
|
|
5877
5680
|
// buildMcpJson so agents that add cloud-broker post-provision still
|
|
5878
5681
|
// forward the per-turn initiator.
|
|
5879
|
-
AGT_TURN_INITIATOR_FILE:
|
|
5682
|
+
AGT_TURN_INITIATOR_FILE: join3(getAgentDir(codeName), ".current-turn-initiator.json"),
|
|
5880
5683
|
PATH: process.env["PATH"] ?? "",
|
|
5881
5684
|
HOME: process.env["HOME"] ?? ""
|
|
5882
5685
|
}
|
|
@@ -5900,7 +5703,7 @@ ${sections}`
|
|
|
5900
5703
|
// ENG-6563 (D16): keep incremental xero-broker wiring in sync with
|
|
5901
5704
|
// buildMcpJson so agents that add xero-broker post-provision still
|
|
5902
5705
|
// forward the per-turn initiator.
|
|
5903
|
-
AGT_TURN_INITIATOR_FILE:
|
|
5706
|
+
AGT_TURN_INITIATOR_FILE: join3(getAgentDir(codeName), ".current-turn-initiator.json"),
|
|
5904
5707
|
PATH: process.env["PATH"] ?? "",
|
|
5905
5708
|
HOME: process.env["HOME"] ?? ""
|
|
5906
5709
|
}
|
|
@@ -5909,7 +5712,7 @@ ${sections}`
|
|
|
5909
5712
|
}
|
|
5910
5713
|
const hasAdminDebug = integrations.some((i) => i.definition_id === "augmented-admin");
|
|
5911
5714
|
if (hasAdminDebug) {
|
|
5912
|
-
const localAdminMcpPath =
|
|
5715
|
+
const localAdminMcpPath = join3(getHomeDir(), ".augmented", "_mcp", "augmented-admin.js");
|
|
5913
5716
|
this.writeMcpServer(codeName, "augmented-admin", {
|
|
5914
5717
|
command: "node",
|
|
5915
5718
|
args: [localAdminMcpPath],
|
|
@@ -5923,7 +5726,7 @@ ${sections}`
|
|
|
5923
5726
|
}
|
|
5924
5727
|
const hasSupport = integrations.some((i) => i.definition_id === "augmented-support");
|
|
5925
5728
|
if (hasSupport) {
|
|
5926
|
-
const localSupportMcpPath =
|
|
5729
|
+
const localSupportMcpPath = join3(getHomeDir(), ".augmented", "_mcp", "augmented-support.js");
|
|
5927
5730
|
this.writeMcpServer(codeName, "augmented-support", {
|
|
5928
5731
|
command: "node",
|
|
5929
5732
|
args: [localSupportMcpPath],
|
|
@@ -5937,7 +5740,7 @@ ${sections}`
|
|
|
5937
5740
|
}
|
|
5938
5741
|
const hasHelpKb = integrations.some((i) => i.definition_id === "augmented-help-kb");
|
|
5939
5742
|
if (hasHelpKb) {
|
|
5940
|
-
const localHelpKbMcpPath =
|
|
5743
|
+
const localHelpKbMcpPath = join3(getHomeDir(), ".augmented", "_mcp", "augmented-help-kb.js");
|
|
5941
5744
|
this.writeMcpServer(codeName, "augmented-help-kb", {
|
|
5942
5745
|
command: "node",
|
|
5943
5746
|
args: [localHelpKbMcpPath],
|
|
@@ -5953,7 +5756,7 @@ ${sections}`
|
|
|
5953
5756
|
const origamiStdioAgentId = resolveBrokerAgentId(codeName) ?? agentId;
|
|
5954
5757
|
const origamiStdioExpected = Boolean(origamiStdio?.stdioMcp === true && origamiStdio.id);
|
|
5955
5758
|
if (origamiStdioExpected && origamiStdioAgentId) {
|
|
5956
|
-
const localOrigamiMcpPath =
|
|
5759
|
+
const localOrigamiMcpPath = join3(getHomeDir(), ".augmented", "_mcp", "origami.js");
|
|
5957
5760
|
this.writeMcpServer(codeName, "origami", {
|
|
5958
5761
|
command: "node",
|
|
5959
5762
|
args: [localOrigamiMcpPath],
|
|
@@ -6070,9 +5873,9 @@ ${sections}`
|
|
|
6070
5873
|
}
|
|
6071
5874
|
}
|
|
6072
5875
|
const projectDir = getProjectDir(codeName);
|
|
6073
|
-
const claudeMdPath =
|
|
5876
|
+
const claudeMdPath = join3(projectDir, "CLAUDE.md");
|
|
6074
5877
|
try {
|
|
6075
|
-
const existing =
|
|
5878
|
+
const existing = readFileSync4(claudeMdPath, "utf-8");
|
|
6076
5879
|
const renderSection = options?.renderClaudeMdSection === true;
|
|
6077
5880
|
const newSection = renderSection ? buildIntegrationsSection(summariesForSidecar) : "";
|
|
6078
5881
|
const sentinelStart = INTEGRATIONS_SECTION_START.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -6089,15 +5892,15 @@ ${sections}`
|
|
|
6089
5892
|
updated = existing;
|
|
6090
5893
|
}
|
|
6091
5894
|
if (updated !== existing)
|
|
6092
|
-
|
|
5895
|
+
writeFileSync4(claudeMdPath, updated);
|
|
6093
5896
|
const agentDir2 = getAgentDir(codeName);
|
|
6094
|
-
const envSrc =
|
|
5897
|
+
const envSrc = join3(agentDir2, ".env.integrations");
|
|
6095
5898
|
try {
|
|
6096
|
-
const envContent =
|
|
6097
|
-
const envDest =
|
|
6098
|
-
|
|
5899
|
+
const envContent = readFileSync4(envSrc, "utf-8");
|
|
5900
|
+
const envDest = join3(projectDir, ".env.integrations");
|
|
5901
|
+
writeFileSync4(envDest, envContent, { mode: SECRET_FILE_MODE });
|
|
6099
5902
|
try {
|
|
6100
|
-
|
|
5903
|
+
chmodSync4(envDest, SECRET_FILE_MODE);
|
|
6101
5904
|
} catch {
|
|
6102
5905
|
}
|
|
6103
5906
|
} catch {
|
|
@@ -6109,11 +5912,11 @@ ${sections}`
|
|
|
6109
5912
|
},
|
|
6110
5913
|
writeMcpServer(codeName, serverId, config) {
|
|
6111
5914
|
const agentDir = getAgentDir(codeName);
|
|
6112
|
-
const mcpJsonPath =
|
|
6113
|
-
|
|
5915
|
+
const mcpJsonPath = join3(agentDir, "provision", ".mcp.json");
|
|
5916
|
+
mkdirSync3(join3(agentDir, "provision"), { recursive: true });
|
|
6114
5917
|
let mcpConfig;
|
|
6115
5918
|
try {
|
|
6116
|
-
mcpConfig = JSON.parse(
|
|
5919
|
+
mcpConfig = JSON.parse(readFileSync4(mcpJsonPath, "utf-8"));
|
|
6117
5920
|
} catch {
|
|
6118
5921
|
mcpConfig = { mcpServers: {} };
|
|
6119
5922
|
}
|
|
@@ -6157,7 +5960,7 @@ ${sections}`
|
|
|
6157
5960
|
}
|
|
6158
5961
|
},
|
|
6159
5962
|
getMcpPath(codeName) {
|
|
6160
|
-
return
|
|
5963
|
+
return join3(getAgentDir(codeName), "provision", ".mcp.json");
|
|
6161
5964
|
},
|
|
6162
5965
|
/**
|
|
6163
5966
|
* ENG-7994: the declared servers from `provision/.mcp.json`. Mirrors what the
|
|
@@ -6168,7 +5971,7 @@ ${sections}`
|
|
|
6168
5971
|
readMcpServers(codeName) {
|
|
6169
5972
|
let parsed;
|
|
6170
5973
|
try {
|
|
6171
|
-
parsed = JSON.parse(
|
|
5974
|
+
parsed = JSON.parse(readFileSync4(join3(getAgentDir(codeName), "provision", ".mcp.json"), "utf-8"));
|
|
6172
5975
|
} catch {
|
|
6173
5976
|
return {};
|
|
6174
5977
|
}
|
|
@@ -6181,10 +5984,10 @@ ${sections}`
|
|
|
6181
5984
|
},
|
|
6182
5985
|
removeMcpServer(codeName, serverId) {
|
|
6183
5986
|
const agentDir = getAgentDir(codeName);
|
|
6184
|
-
const mcpJsonPath =
|
|
5987
|
+
const mcpJsonPath = join3(agentDir, "provision", ".mcp.json");
|
|
6185
5988
|
let mcpConfig;
|
|
6186
5989
|
try {
|
|
6187
|
-
mcpConfig = JSON.parse(
|
|
5990
|
+
mcpConfig = JSON.parse(readFileSync4(mcpJsonPath, "utf-8"));
|
|
6188
5991
|
} catch {
|
|
6189
5992
|
return;
|
|
6190
5993
|
}
|
|
@@ -6203,27 +6006,27 @@ ${sections}`
|
|
|
6203
6006
|
const READ_WRITE_MODE = 420;
|
|
6204
6007
|
const agentDir = getAgentDir(codeName);
|
|
6205
6008
|
const projectDir = getProjectDir(codeName);
|
|
6206
|
-
for (const baseDir of [
|
|
6207
|
-
const skillDir =
|
|
6208
|
-
|
|
6009
|
+
for (const baseDir of [join3(agentDir, "skills"), join3(projectDir, ".claude", "skills")]) {
|
|
6010
|
+
const skillDir = join3(baseDir, skillId);
|
|
6011
|
+
mkdirSync3(skillDir, { recursive: true });
|
|
6209
6012
|
for (const file of files) {
|
|
6210
6013
|
assertSafeRelativePath(file.relativePath);
|
|
6211
|
-
const filePath =
|
|
6014
|
+
const filePath = join3(skillDir, file.relativePath);
|
|
6212
6015
|
const rel = relative(skillDir, filePath);
|
|
6213
6016
|
if (rel.startsWith("..") || rel === "") {
|
|
6214
6017
|
throw new Error(`Path traversal detected: ${file.relativePath} resolves outside ${skillDir}`);
|
|
6215
6018
|
}
|
|
6216
|
-
|
|
6217
|
-
if (isPluginManaged &&
|
|
6019
|
+
mkdirSync3(join3(filePath, ".."), { recursive: true });
|
|
6020
|
+
if (isPluginManaged && existsSync4(filePath)) {
|
|
6218
6021
|
try {
|
|
6219
|
-
|
|
6022
|
+
chmodSync4(filePath, READ_WRITE_MODE);
|
|
6220
6023
|
} catch {
|
|
6221
6024
|
}
|
|
6222
6025
|
}
|
|
6223
|
-
|
|
6026
|
+
writeFileSync4(filePath, file.content);
|
|
6224
6027
|
if (isPluginManaged) {
|
|
6225
6028
|
try {
|
|
6226
|
-
|
|
6029
|
+
chmodSync4(filePath, READ_ONLY_MODE);
|
|
6227
6030
|
} catch {
|
|
6228
6031
|
}
|
|
6229
6032
|
}
|
|
@@ -6232,11 +6035,11 @@ ${sections}`
|
|
|
6232
6035
|
},
|
|
6233
6036
|
installPlugin(codeName, pluginId, pluginPath, pluginConfig) {
|
|
6234
6037
|
const agentDir = getAgentDir(codeName);
|
|
6235
|
-
const pluginsJsonPath =
|
|
6236
|
-
|
|
6038
|
+
const pluginsJsonPath = join3(agentDir, "plugins.json");
|
|
6039
|
+
mkdirSync3(agentDir, { recursive: true });
|
|
6237
6040
|
let pluginsConfig;
|
|
6238
6041
|
try {
|
|
6239
|
-
pluginsConfig = JSON.parse(
|
|
6042
|
+
pluginsConfig = JSON.parse(readFileSync4(pluginsJsonPath, "utf-8"));
|
|
6240
6043
|
} catch {
|
|
6241
6044
|
pluginsConfig = { plugins: {} };
|
|
6242
6045
|
}
|
|
@@ -6249,7 +6052,7 @@ ${sections}`
|
|
|
6249
6052
|
installed_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6250
6053
|
...pluginConfig ? { config: pluginConfig } : {}
|
|
6251
6054
|
};
|
|
6252
|
-
|
|
6055
|
+
writeFileSync4(pluginsJsonPath, JSON.stringify(pluginsConfig, null, 2));
|
|
6253
6056
|
},
|
|
6254
6057
|
/**
|
|
6255
6058
|
* Full plugin provisioning: install scripts, register hooks, apply permissions,
|
|
@@ -6265,11 +6068,11 @@ ${sections}`
|
|
|
6265
6068
|
assertValidCodeName(codeName);
|
|
6266
6069
|
assertValidCodeName(plugin.slug);
|
|
6267
6070
|
const projectDir = getProjectDir(codeName);
|
|
6268
|
-
const claudeDir =
|
|
6269
|
-
|
|
6071
|
+
const claudeDir = join3(projectDir, ".claude");
|
|
6072
|
+
mkdirSync3(claudeDir, { recursive: true });
|
|
6270
6073
|
const sourceSpec = options?.scriptSource ?? `augmented-plugin:${plugin.slug}`;
|
|
6271
6074
|
this.installPlugin(codeName, plugin.slug, sourceSpec, contextValues);
|
|
6272
|
-
const installedDir =
|
|
6075
|
+
const installedDir = join3(projectDir, ".claude", "plugins", plugin.slug);
|
|
6273
6076
|
for (const skill of plugin.skills) {
|
|
6274
6077
|
const skillId = skill.id;
|
|
6275
6078
|
assertValidCodeName(skillId);
|
|
@@ -6281,10 +6084,10 @@ ${sections}`
|
|
|
6281
6084
|
}
|
|
6282
6085
|
const scriptsConfig = plugin.scripts;
|
|
6283
6086
|
if (scriptsConfig?.hooks) {
|
|
6284
|
-
const settingsPath =
|
|
6087
|
+
const settingsPath = join3(claudeDir, "settings.local.json");
|
|
6285
6088
|
let settings = {};
|
|
6286
6089
|
try {
|
|
6287
|
-
settings = JSON.parse(
|
|
6090
|
+
settings = JSON.parse(readFileSync4(settingsPath, "utf-8"));
|
|
6288
6091
|
} catch {
|
|
6289
6092
|
}
|
|
6290
6093
|
const existingHooks = settings["hooks"] ?? {};
|
|
@@ -6318,13 +6121,13 @@ ${sections}`
|
|
|
6318
6121
|
}
|
|
6319
6122
|
}
|
|
6320
6123
|
settings["hooks"] = existingHooks;
|
|
6321
|
-
|
|
6124
|
+
writeFileSync4(settingsPath, JSON.stringify(settings, null, 2));
|
|
6322
6125
|
}
|
|
6323
6126
|
if (plugin.allowed_tools.length > 0) {
|
|
6324
|
-
const settingsPath =
|
|
6127
|
+
const settingsPath = join3(claudeDir, "settings.local.json");
|
|
6325
6128
|
let settings = {};
|
|
6326
6129
|
try {
|
|
6327
|
-
settings = JSON.parse(
|
|
6130
|
+
settings = JSON.parse(readFileSync4(settingsPath, "utf-8"));
|
|
6328
6131
|
} catch {
|
|
6329
6132
|
}
|
|
6330
6133
|
const existingPerms = settings["permissions"] ?? {};
|
|
@@ -6336,20 +6139,20 @@ ${sections}`
|
|
|
6336
6139
|
}
|
|
6337
6140
|
existingPerms["allow"] = allowList;
|
|
6338
6141
|
settings["permissions"] = existingPerms;
|
|
6339
|
-
|
|
6142
|
+
writeFileSync4(settingsPath, JSON.stringify(settings, null, 2));
|
|
6340
6143
|
}
|
|
6341
6144
|
if (contextValues && Object.keys(contextValues).length > 0) {
|
|
6342
|
-
const configDir =
|
|
6343
|
-
|
|
6344
|
-
|
|
6145
|
+
const configDir = join3(projectDir, `.${plugin.slug}`);
|
|
6146
|
+
mkdirSync3(configDir, { recursive: true });
|
|
6147
|
+
writeFileSync4(join3(configDir, "config.json"), JSON.stringify(contextValues, null, 2));
|
|
6345
6148
|
}
|
|
6346
6149
|
},
|
|
6347
6150
|
executePluginHook(ctx) {
|
|
6348
6151
|
assertValidCodeName(ctx.codeName);
|
|
6349
|
-
const agentRootDir =
|
|
6152
|
+
const agentRootDir = join3(getHomeDir(), ".augmented", ctx.codeName);
|
|
6350
6153
|
const projectDir = getProjectDir(ctx.codeName);
|
|
6351
|
-
|
|
6352
|
-
|
|
6154
|
+
mkdirSync3(agentRootDir, { recursive: true });
|
|
6155
|
+
mkdirSync3(projectDir, { recursive: true });
|
|
6353
6156
|
const startedAt = Date.now();
|
|
6354
6157
|
return new Promise((resolve) => {
|
|
6355
6158
|
const child = execFile("bash", ["-c", ctx.script], {
|
|
@@ -6385,7 +6188,7 @@ ${sections}`
|
|
|
6385
6188
|
},
|
|
6386
6189
|
writeTokenFile(codeName, integrations) {
|
|
6387
6190
|
const agentDir = getAgentDir(codeName);
|
|
6388
|
-
|
|
6191
|
+
mkdirSync3(agentDir, { recursive: true });
|
|
6389
6192
|
const tokens = {};
|
|
6390
6193
|
for (const integration of integrations) {
|
|
6391
6194
|
if (integration.auth_type !== "oauth2" && integration.auth_type !== "github_app")
|
|
@@ -6402,9 +6205,9 @@ ${sections}`
|
|
|
6402
6205
|
}
|
|
6403
6206
|
if (Object.keys(tokens).length === 0)
|
|
6404
6207
|
return;
|
|
6405
|
-
const tokenPath =
|
|
6406
|
-
|
|
6407
|
-
|
|
6208
|
+
const tokenPath = join3(agentDir, ".tokens.json");
|
|
6209
|
+
writeFileSync4(tokenPath, JSON.stringify(tokens, null, 2));
|
|
6210
|
+
chmodSync4(tokenPath, SECRET_FILE_MODE);
|
|
6408
6211
|
}
|
|
6409
6212
|
};
|
|
6410
6213
|
registerFramework(claudeCodeAdapter);
|
|
@@ -6426,14 +6229,14 @@ function jsonOutput(data) {
|
|
|
6426
6229
|
}
|
|
6427
6230
|
|
|
6428
6231
|
// src/lib/config.ts
|
|
6429
|
-
import { readFileSync as
|
|
6430
|
-
import { join as
|
|
6232
|
+
import { readFileSync as readFileSync5, writeFileSync as writeFileSync5, mkdirSync as mkdirSync4, existsSync as existsSync5 } from "fs";
|
|
6233
|
+
import { join as join4 } from "path";
|
|
6431
6234
|
import { homedir as homedir4 } from "os";
|
|
6432
|
-
var AUGMENTED_DIR =
|
|
6433
|
-
var CONFIG_PATH =
|
|
6235
|
+
var AUGMENTED_DIR = join4(homedir4(), ".augmented");
|
|
6236
|
+
var CONFIG_PATH = join4(AUGMENTED_DIR, "config.json");
|
|
6434
6237
|
function ensureAugmentedDir() {
|
|
6435
|
-
if (!
|
|
6436
|
-
|
|
6238
|
+
if (!existsSync5(AUGMENTED_DIR)) {
|
|
6239
|
+
mkdirSync4(AUGMENTED_DIR, { recursive: true });
|
|
6437
6240
|
}
|
|
6438
6241
|
}
|
|
6439
6242
|
function reloadFromShellProfile() {
|
|
@@ -6443,10 +6246,10 @@ function loadFromShellProfile(force = false) {
|
|
|
6443
6246
|
if (!force && process.env["AGT_HOST"] && process.env["AGT_API_KEY"]) return;
|
|
6444
6247
|
const shell = process.env["SHELL"] ?? "";
|
|
6445
6248
|
const home = homedir4();
|
|
6446
|
-
const candidates = shell.includes("zsh") ? [
|
|
6249
|
+
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")];
|
|
6447
6250
|
for (const profile of candidates) {
|
|
6448
6251
|
try {
|
|
6449
|
-
const content =
|
|
6252
|
+
const content = readFileSync5(profile, "utf-8");
|
|
6450
6253
|
for (const key of ["AGT_HOST", "AGT_API_KEY", "AGT_TEAM"]) {
|
|
6451
6254
|
if (!force && process.env[key]) continue;
|
|
6452
6255
|
const match = content.split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#")).map(
|
|
@@ -6471,7 +6274,7 @@ function getApiKey() {
|
|
|
6471
6274
|
}
|
|
6472
6275
|
function getConfig() {
|
|
6473
6276
|
try {
|
|
6474
|
-
const raw =
|
|
6277
|
+
const raw = readFileSync5(CONFIG_PATH, "utf-8");
|
|
6475
6278
|
return JSON.parse(raw);
|
|
6476
6279
|
} catch {
|
|
6477
6280
|
return {};
|
|
@@ -6479,7 +6282,7 @@ function getConfig() {
|
|
|
6479
6282
|
}
|
|
6480
6283
|
function saveConfig(config) {
|
|
6481
6284
|
ensureAugmentedDir();
|
|
6482
|
-
|
|
6285
|
+
writeFileSync5(CONFIG_PATH, JSON.stringify(config, null, 2));
|
|
6483
6286
|
}
|
|
6484
6287
|
function getActiveTeam() {
|
|
6485
6288
|
const envTeam = process.env["AGT_TEAM"];
|
|
@@ -6526,7 +6329,7 @@ function exchangeFailureKind(err) {
|
|
|
6526
6329
|
}
|
|
6527
6330
|
|
|
6528
6331
|
// src/lib/api-client.ts
|
|
6529
|
-
var agtCliVersion = true ? "0.28.
|
|
6332
|
+
var agtCliVersion = true ? "0.28.692" : "dev";
|
|
6530
6333
|
var lastConfigHash = null;
|
|
6531
6334
|
function setConfigHash(hash) {
|
|
6532
6335
|
lastConfigHash = hash && hash.length > 0 ? hash : null;
|
|
@@ -6776,13 +6579,13 @@ async function getHostId() {
|
|
|
6776
6579
|
}
|
|
6777
6580
|
|
|
6778
6581
|
// src/lib/atomic-write.ts
|
|
6779
|
-
import { closeSync, fsyncSync, openSync, writeSync, renameSync as renameSync5, mkdirSync as
|
|
6780
|
-
import { dirname as
|
|
6582
|
+
import { closeSync, fsyncSync, openSync, writeSync, renameSync as renameSync5, mkdirSync as mkdirSync5 } from "fs";
|
|
6583
|
+
import { dirname as dirname4 } from "path";
|
|
6781
6584
|
function atomicWriteFileSync(path, data) {
|
|
6782
|
-
const dirPath =
|
|
6585
|
+
const dirPath = dirname4(path);
|
|
6783
6586
|
const tmpPath = `${path}.tmp.${process.pid}.${Math.random().toString(36).slice(2, 8)}`;
|
|
6784
6587
|
try {
|
|
6785
|
-
|
|
6588
|
+
mkdirSync5(dirPath, { recursive: true });
|
|
6786
6589
|
} catch {
|
|
6787
6590
|
}
|
|
6788
6591
|
const fd = openSync(tmpPath, "w", 420);
|
|
@@ -6808,15 +6611,15 @@ function atomicWriteFileSync(path, data) {
|
|
|
6808
6611
|
}
|
|
6809
6612
|
|
|
6810
6613
|
// src/lib/feature-flags-host.ts
|
|
6811
|
-
import { existsSync as
|
|
6812
|
-
import { join as
|
|
6614
|
+
import { existsSync as existsSync6, readFileSync as readFileSync6, statSync as statSync2 } from "fs";
|
|
6615
|
+
import { join as join5 } from "path";
|
|
6813
6616
|
function defaultFlagsCachePath(configDir) {
|
|
6814
|
-
return
|
|
6617
|
+
return join5(configDir, "flags-cache.json");
|
|
6815
6618
|
}
|
|
6816
6619
|
function readFlagsCache(path) {
|
|
6817
6620
|
try {
|
|
6818
|
-
if (!
|
|
6819
|
-
const parsed = JSON.parse(
|
|
6621
|
+
if (!existsSync6(path)) return null;
|
|
6622
|
+
const parsed = JSON.parse(readFileSync6(path, "utf8"));
|
|
6820
6623
|
if (!parsed || typeof parsed !== "object") return null;
|
|
6821
6624
|
const obj = parsed;
|
|
6822
6625
|
const flags = obj["flags"];
|
|
@@ -7281,16 +7084,16 @@ function buildArgvMatchersForEntry(key, entry) {
|
|
|
7281
7084
|
const tail = "(?![A-Za-z0-9_-])";
|
|
7282
7085
|
if (/^@?[a-z0-9]([a-z0-9._-]*\/)?[a-z0-9._-]+$/i.test(stripped)) {
|
|
7283
7086
|
patterns.push(new RegExp(`${escapeRe(stripped)}${tail}`));
|
|
7284
|
-
const
|
|
7285
|
-
if (
|
|
7286
|
-
patterns.push(new RegExp(`${escapeRe(
|
|
7087
|
+
const basename = stripped.split("/").pop();
|
|
7088
|
+
if (basename && basename !== stripped) {
|
|
7089
|
+
patterns.push(new RegExp(`${escapeRe(basename)}${tail}`));
|
|
7287
7090
|
}
|
|
7288
7091
|
break;
|
|
7289
7092
|
}
|
|
7290
7093
|
if (stripped.includes("/")) {
|
|
7291
|
-
const
|
|
7292
|
-
if (
|
|
7293
|
-
patterns.push(new RegExp(`${escapeRe(
|
|
7094
|
+
const basename = stripped.split("/").pop();
|
|
7095
|
+
if (basename) {
|
|
7096
|
+
patterns.push(new RegExp(`${escapeRe(basename)}${tail}`));
|
|
7294
7097
|
break;
|
|
7295
7098
|
}
|
|
7296
7099
|
}
|
|
@@ -8442,8 +8245,8 @@ function verdictForUnavailableMcpConfig(cause, ctx) {
|
|
|
8442
8245
|
}
|
|
8443
8246
|
|
|
8444
8247
|
// src/lib/connectivity-probe-context.ts
|
|
8445
|
-
import { delimiter as pathDelimiter, join as
|
|
8446
|
-
import { existsSync as
|
|
8248
|
+
import { delimiter as pathDelimiter, join as join6 } from "path";
|
|
8249
|
+
import { existsSync as existsSync7, readFileSync as readFileSync7 } from "fs";
|
|
8447
8250
|
|
|
8448
8251
|
// src/lib/mcp-stdio-probe.ts
|
|
8449
8252
|
import { spawn } from "child_process";
|
|
@@ -8954,7 +8757,7 @@ function resolveHttpServerEntry(entry, env) {
|
|
|
8954
8757
|
function readMcpHttpServerConfig(projectDir, serverKey, env) {
|
|
8955
8758
|
let servers;
|
|
8956
8759
|
try {
|
|
8957
|
-
const raw =
|
|
8760
|
+
const raw = readFileSync7(join6(projectDir, ".mcp.json"), "utf-8");
|
|
8958
8761
|
servers = JSON.parse(raw).mcpServers ?? {};
|
|
8959
8762
|
} catch {
|
|
8960
8763
|
return { ok: false, cause: "file-unreadable" };
|
|
@@ -8966,7 +8769,7 @@ function readMcpHttpServerConfig(projectDir, serverKey, env) {
|
|
|
8966
8769
|
}
|
|
8967
8770
|
function resolveDeclaredServerKey(projectDir, definitionId, derivedKey) {
|
|
8968
8771
|
try {
|
|
8969
|
-
const raw =
|
|
8772
|
+
const raw = readFileSync7(join6(projectDir, ".mcp.json"), "utf-8");
|
|
8970
8773
|
const servers = JSON.parse(raw).mcpServers ?? {};
|
|
8971
8774
|
const declared = Object.keys(servers);
|
|
8972
8775
|
if (derivedKey !== definitionId && derivedKey !== sanitizeServerKey(definitionId)) {
|
|
@@ -9008,7 +8811,7 @@ function resolveStdioServerEntry(entry, env) {
|
|
|
9008
8811
|
function readMcpStdioServerConfig(projectDir, serverKey, env) {
|
|
9009
8812
|
let servers;
|
|
9010
8813
|
try {
|
|
9011
|
-
const raw =
|
|
8814
|
+
const raw = readFileSync7(join6(projectDir, ".mcp.json"), "utf-8");
|
|
9012
8815
|
servers = JSON.parse(raw).mcpServers ?? {};
|
|
9013
8816
|
} catch {
|
|
9014
8817
|
return { ok: false, cause: "file-unreadable" };
|
|
@@ -9034,9 +8837,9 @@ function deriveMcpServerKey(input) {
|
|
|
9034
8837
|
function buildProbeEnv(projectDir, agentId) {
|
|
9035
8838
|
const probeEnv = { ...process.env };
|
|
9036
8839
|
try {
|
|
9037
|
-
const envIntPath =
|
|
9038
|
-
if (
|
|
9039
|
-
Object.assign(probeEnv, parseEnvIntegrations(
|
|
8840
|
+
const envIntPath = join6(projectDir, ".env.integrations");
|
|
8841
|
+
if (existsSync7(envIntPath)) {
|
|
8842
|
+
Object.assign(probeEnv, parseEnvIntegrations(readFileSync7(envIntPath, "utf-8")));
|
|
9040
8843
|
}
|
|
9041
8844
|
} catch {
|
|
9042
8845
|
}
|
|
@@ -9044,8 +8847,8 @@ function buildProbeEnv(projectDir, agentId) {
|
|
|
9044
8847
|
probeEnv.AGT_AGENT_ID = agentId.trim();
|
|
9045
8848
|
}
|
|
9046
8849
|
try {
|
|
9047
|
-
const agentBinDir =
|
|
9048
|
-
if (
|
|
8850
|
+
const agentBinDir = join6(projectDir, ".claude", "agt-bin");
|
|
8851
|
+
if (existsSync7(agentBinDir)) {
|
|
9049
8852
|
probeEnv.PATH = probeEnv.PATH ? `${agentBinDir}${pathDelimiter}${probeEnv.PATH}` : agentBinDir;
|
|
9050
8853
|
}
|
|
9051
8854
|
} catch {
|
|
@@ -9181,9 +8984,9 @@ function buildConnectivityProbeDeps(projectDir, probeEnv) {
|
|
|
9181
8984
|
|
|
9182
8985
|
// src/lib/session-tool-bind-probe-host.ts
|
|
9183
8986
|
import { execFileSync as syncExecFile } from "child_process";
|
|
9184
|
-
import { readFileSync as
|
|
9185
|
-
import { join as
|
|
9186
|
-
import { dirname as
|
|
8987
|
+
import { readFileSync as readFileSync8 } from "fs";
|
|
8988
|
+
import { join as join7 } from "path";
|
|
8989
|
+
import { dirname as dirname5 } from "path";
|
|
9187
8990
|
function deliveryFields(i) {
|
|
9188
8991
|
const keys = ["source_type", "provider", "mcp_command", "mcp_url", "cli_binary", "cli_package"];
|
|
9189
8992
|
const out = {};
|
|
@@ -9196,7 +8999,7 @@ async function gatherSessionToolBindProbe(agent, integrations, projectDir, opts)
|
|
|
9196
8999
|
if (integrations.length === 0) return null;
|
|
9197
9000
|
let mcpRaw = null;
|
|
9198
9001
|
try {
|
|
9199
|
-
mcpRaw =
|
|
9002
|
+
mcpRaw = readFileSync8(join7(projectDir, ".mcp.json"), "utf-8");
|
|
9200
9003
|
} catch {
|
|
9201
9004
|
mcpRaw = null;
|
|
9202
9005
|
}
|
|
@@ -9289,7 +9092,7 @@ var SLACK_MCP_SERVER_KEY = "slack";
|
|
|
9289
9092
|
function readSlackTransportDownKeys(projectDir) {
|
|
9290
9093
|
const none = /* @__PURE__ */ new Set();
|
|
9291
9094
|
try {
|
|
9292
|
-
const raw =
|
|
9095
|
+
const raw = readFileSync8(join7(dirname5(projectDir), SLACK_SOCKET_STATE_FILENAME), "utf-8");
|
|
9293
9096
|
const state = parseSlackSocketState(raw, Date.now());
|
|
9294
9097
|
return isSlackInboundTransportDown(state, SLACK_TRANSPORT_DOWN_AFTER_MS) ? /* @__PURE__ */ new Set([SLACK_MCP_SERVER_KEY]) : none;
|
|
9295
9098
|
} catch {
|
|
@@ -9405,35 +9208,35 @@ function decidePin(opts) {
|
|
|
9405
9208
|
|
|
9406
9209
|
// src/commands/manager.ts
|
|
9407
9210
|
import chalk3 from "chalk";
|
|
9408
|
-
import { existsSync as
|
|
9409
|
-
import { join as
|
|
9211
|
+
import { existsSync as existsSync9, realpathSync as realpathSync2 } from "fs";
|
|
9212
|
+
import { join as join9 } from "path";
|
|
9410
9213
|
import { homedir as homedir5, userInfo } from "os";
|
|
9411
9214
|
import { spawn as spawn3 } from "child_process";
|
|
9412
9215
|
|
|
9413
9216
|
// src/lib/watchdog.ts
|
|
9414
|
-
import { readFileSync as
|
|
9415
|
-
import { join as
|
|
9217
|
+
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";
|
|
9218
|
+
import { join as join8 } from "path";
|
|
9416
9219
|
import { spawn as spawn2, execFileSync as execFileSync3 } from "child_process";
|
|
9417
|
-
var DEFAULT_CONFIG_DIR =
|
|
9220
|
+
var DEFAULT_CONFIG_DIR = join8(process.env["HOME"] ?? "/tmp", ".augmented");
|
|
9418
9221
|
function getManagerPaths(configDir) {
|
|
9419
9222
|
return {
|
|
9420
|
-
pidFile:
|
|
9421
|
-
stateFile:
|
|
9422
|
-
logFile:
|
|
9223
|
+
pidFile: join8(configDir, "manager.pid"),
|
|
9224
|
+
stateFile: join8(configDir, "manager-state.json"),
|
|
9225
|
+
logFile: join8(configDir, "manager.log")
|
|
9423
9226
|
};
|
|
9424
9227
|
}
|
|
9425
9228
|
function ensureDir(configDir) {
|
|
9426
|
-
if (!
|
|
9427
|
-
|
|
9229
|
+
if (!existsSync8(configDir)) {
|
|
9230
|
+
mkdirSync6(configDir, { recursive: true });
|
|
9428
9231
|
}
|
|
9429
9232
|
}
|
|
9430
9233
|
function writePidFile(configDir, pid) {
|
|
9431
9234
|
ensureDir(configDir);
|
|
9432
|
-
|
|
9235
|
+
writeFileSync6(getManagerPaths(configDir).pidFile, String(pid), { mode: 384 });
|
|
9433
9236
|
}
|
|
9434
9237
|
function readPidFile(configDir) {
|
|
9435
9238
|
try {
|
|
9436
|
-
const raw =
|
|
9239
|
+
const raw = readFileSync9(getManagerPaths(configDir).pidFile, "utf-8").trim();
|
|
9437
9240
|
const pid = parseInt(raw, 10);
|
|
9438
9241
|
return isNaN(pid) ? null : pid;
|
|
9439
9242
|
} catch {
|
|
@@ -9479,7 +9282,7 @@ function defaultPgrep() {
|
|
|
9479
9282
|
}
|
|
9480
9283
|
function readStateFile(configDir) {
|
|
9481
9284
|
try {
|
|
9482
|
-
const raw =
|
|
9285
|
+
const raw = readFileSync9(getManagerPaths(configDir).stateFile, "utf-8");
|
|
9483
9286
|
return JSON.parse(raw);
|
|
9484
9287
|
} catch {
|
|
9485
9288
|
return null;
|
|
@@ -9513,7 +9316,7 @@ function startWatchdog(opts) {
|
|
|
9513
9316
|
const { logFile } = getManagerPaths(configDir);
|
|
9514
9317
|
const logFd = openSync2(logFile, "a", 384);
|
|
9515
9318
|
try {
|
|
9516
|
-
|
|
9319
|
+
chmodSync5(logFile, 384);
|
|
9517
9320
|
} catch {
|
|
9518
9321
|
}
|
|
9519
9322
|
const intervalSec = String(Math.max(Math.floor(opts.intervalMs / 1e3), 5));
|
|
@@ -9535,7 +9338,7 @@ function startWatchdog(opts) {
|
|
|
9535
9338
|
const deadline = Date.now() + 5e3;
|
|
9536
9339
|
const sleepBuf = new Int32Array(new SharedArrayBuffer(4));
|
|
9537
9340
|
while (Date.now() < deadline) {
|
|
9538
|
-
if (
|
|
9341
|
+
if (existsSync8(pidFile)) {
|
|
9539
9342
|
return { pid: child.pid };
|
|
9540
9343
|
}
|
|
9541
9344
|
if (child.exitCode !== null) {
|
|
@@ -9675,7 +9478,7 @@ function managerStartCommand(opts) {
|
|
|
9675
9478
|
process.exitCode = 1;
|
|
9676
9479
|
return;
|
|
9677
9480
|
}
|
|
9678
|
-
const configDir = opts.configDir ??
|
|
9481
|
+
const configDir = opts.configDir ?? join9(homedir5(), ".augmented");
|
|
9679
9482
|
if (opts.supervise) {
|
|
9680
9483
|
if (json) {
|
|
9681
9484
|
jsonOutput({ ok: false, error: "--supervise is not supported with --json" });
|
|
@@ -9771,7 +9574,7 @@ function runSupervisorLoop(intervalSec, configDir) {
|
|
|
9771
9574
|
}
|
|
9772
9575
|
async function managerStopCommand(opts = {}) {
|
|
9773
9576
|
const json = isJsonMode();
|
|
9774
|
-
const configDir = opts.configDir ??
|
|
9577
|
+
const configDir = opts.configDir ?? join9(homedir5(), ".augmented");
|
|
9775
9578
|
try {
|
|
9776
9579
|
const result = await stopWatchdog(configDir);
|
|
9777
9580
|
if (!result.stopped && !result.pid) {
|
|
@@ -9799,7 +9602,7 @@ async function managerStopCommand(opts = {}) {
|
|
|
9799
9602
|
}
|
|
9800
9603
|
function managerStatusCommand(opts = {}) {
|
|
9801
9604
|
const json = isJsonMode();
|
|
9802
|
-
const configDir = opts.configDir ??
|
|
9605
|
+
const configDir = opts.configDir ?? join9(homedir5(), ".augmented");
|
|
9803
9606
|
const status = getManagerStatus(configDir);
|
|
9804
9607
|
if (!status) {
|
|
9805
9608
|
if (json) {
|
|
@@ -9871,7 +9674,7 @@ function resolveStableAgtBin(rawPath) {
|
|
|
9871
9674
|
if (!prefix || !formula) return rawPath;
|
|
9872
9675
|
const candidates = [`${prefix}/bin/${formula}`, `${prefix}/bin/agt`];
|
|
9873
9676
|
for (const candidate of candidates) {
|
|
9874
|
-
if (!
|
|
9677
|
+
if (!existsSync9(candidate)) continue;
|
|
9875
9678
|
try {
|
|
9876
9679
|
realpathSync2(candidate);
|
|
9877
9680
|
return candidate;
|
|
@@ -9891,7 +9694,7 @@ async function managerInstallCommand(opts = {}) {
|
|
|
9891
9694
|
process.exitCode = 1;
|
|
9892
9695
|
return;
|
|
9893
9696
|
}
|
|
9894
|
-
const configDir = opts.configDir ??
|
|
9697
|
+
const configDir = opts.configDir ?? join9(homedir5(), ".augmented");
|
|
9895
9698
|
const rawAgtBin = process.argv[1];
|
|
9896
9699
|
if (!rawAgtBin) {
|
|
9897
9700
|
const msg = "Could not resolve the agt binary path from argv. Re-run via the installed `agt` command.";
|
|
@@ -9904,7 +9707,7 @@ async function managerInstallCommand(opts = {}) {
|
|
|
9904
9707
|
if (process.platform === "darwin") {
|
|
9905
9708
|
const home = homedir5();
|
|
9906
9709
|
const protectedRoots = ["Documents", "Downloads", "Desktop", "Movies", "Music", "Pictures"];
|
|
9907
|
-
const offending = protectedRoots.map((r) =>
|
|
9710
|
+
const offending = protectedRoots.map((r) => join9(home, r)).find((p) => agtBin === p || agtBin.startsWith(`${p}/`));
|
|
9908
9711
|
if (offending) {
|
|
9909
9712
|
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.`;
|
|
9910
9713
|
if (json) jsonOutput({ ok: false, error: msg });
|
|
@@ -9973,7 +9776,7 @@ async function managerInstallSystemUnitCommand(opts = {}) {
|
|
|
9973
9776
|
return;
|
|
9974
9777
|
}
|
|
9975
9778
|
const user = opts.user ?? "root";
|
|
9976
|
-
const configDir = opts.configDir ?? (user === "root" ? "/root/.augmented" :
|
|
9779
|
+
const configDir = opts.configDir ?? (user === "root" ? "/root/.augmented" : join9("/home", user, ".augmented"));
|
|
9977
9780
|
const rawAgtBin = process.argv[1];
|
|
9978
9781
|
if (!rawAgtBin) {
|
|
9979
9782
|
const msg = "Could not resolve the agt binary path from argv. Re-run via the installed `agt` command.";
|
|
@@ -10185,7 +9988,6 @@ function withEvidence(outcome, evidence) {
|
|
|
10185
9988
|
export {
|
|
10186
9989
|
LITERAL_SECRET_PATTERNS,
|
|
10187
9990
|
safeWriteJsonAtomic,
|
|
10188
|
-
setSecretFileTmpfsBacking,
|
|
10189
9991
|
extractCommandNotFound,
|
|
10190
9992
|
migrateAgentDirToIdKeyed,
|
|
10191
9993
|
provisionStopHook,
|
|
@@ -10268,4 +10070,4 @@ export {
|
|
|
10268
10070
|
managerInstallSystemUnitCommand,
|
|
10269
10071
|
managerUninstallSystemUnitCommand
|
|
10270
10072
|
};
|
|
10271
|
-
//# sourceMappingURL=chunk-
|
|
10073
|
+
//# sourceMappingURL=chunk-ITB6NEXM.js.map
|