@integrity-labs/agt-cli 0.28.1126 → 0.28.1128
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 +6 -6
- package/dist/{chunk-OCMJ5E6J.js → chunk-B6UYVEMD.js} +2 -1
- package/dist/chunk-B6UYVEMD.js.map +1 -0
- package/dist/{chunk-C5YNHEST.js → chunk-BUCSF5DF.js} +3 -3
- package/dist/{chunk-JI2D2TA2.js → chunk-EVYDMDOY.js} +55 -26
- package/dist/chunk-EVYDMDOY.js.map +1 -0
- package/dist/{chunk-DIOP5LSU.js → chunk-Q272XYOI.js} +941 -378
- package/dist/chunk-Q272XYOI.js.map +1 -0
- package/dist/{claude-pair-runtime-5OBFRZWS.js → claude-pair-runtime-AFNXHDMT.js} +3 -3
- package/dist/lib/manager-worker.js +336 -28
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/mcp/direct-chat-channel.js +2 -0
- package/dist/mcp/index.js +2 -0
- package/dist/mcp/origami.js +2 -0
- package/dist/mcp/slack-channel.js +2 -0
- package/dist/mcp/telegram-channel.js +2 -0
- package/dist/{persistent-session-E5IR3RBF.js → persistent-session-ICG7OHZM.js} +4 -4
- package/dist/{responsiveness-probe-KCICZE6E.js → responsiveness-probe-HRMY4TOT.js} +4 -4
- package/dist/{session-auth-dead-VYP4VCMX.js → session-auth-dead-DCS7IE2F.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-DIOP5LSU.js.map +0 -1
- package/dist/chunk-JI2D2TA2.js.map +0 -1
- package/dist/chunk-OCMJ5E6J.js.map +0 -1
- /package/dist/{chunk-C5YNHEST.js.map → chunk-BUCSF5DF.js.map} +0 -0
- /package/dist/{claude-pair-runtime-5OBFRZWS.js.map → claude-pair-runtime-AFNXHDMT.js.map} +0 -0
- /package/dist/{persistent-session-E5IR3RBF.js.map → persistent-session-ICG7OHZM.js.map} +0 -0
- /package/dist/{responsiveness-probe-KCICZE6E.js.map → responsiveness-probe-HRMY4TOT.js.map} +0 -0
- /package/dist/{session-auth-dead-VYP4VCMX.js.map → session-auth-dead-DCS7IE2F.js.map} +0 -0
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
parseEnvFileEntries,
|
|
17
17
|
parseEnvIntegrations,
|
|
18
18
|
shellQuote
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-BUCSF5DF.js";
|
|
20
20
|
import {
|
|
21
21
|
BIND_FAILURE_QUARANTINE_THRESHOLD,
|
|
22
22
|
INTEGRATIONS_SECTION_END,
|
|
@@ -79,13 +79,13 @@ import {
|
|
|
79
79
|
sessionTranscriptDir,
|
|
80
80
|
worseConnectivityOutcome,
|
|
81
81
|
wrapScheduledTaskPrompt
|
|
82
|
-
} from "./chunk-
|
|
82
|
+
} from "./chunk-EVYDMDOY.js";
|
|
83
83
|
import {
|
|
84
84
|
classifyUnanswerablePane,
|
|
85
85
|
isConsumerTermsDialogVisible,
|
|
86
86
|
paneRemedy,
|
|
87
87
|
summarizeUnanswerablePane
|
|
88
|
-
} from "./chunk-
|
|
88
|
+
} from "./chunk-B6UYVEMD.js";
|
|
89
89
|
import {
|
|
90
90
|
parsePsRows
|
|
91
91
|
} from "./chunk-XWVM4KPK.js";
|
|
@@ -521,6 +521,559 @@ function describeChannelWriteFailure(outcome, channelId, trigger) {
|
|
|
521
521
|
}
|
|
522
522
|
}
|
|
523
523
|
|
|
524
|
+
// ../../packages/core/dist/provisioning/frameworks/claudecode/root-rm-guard.js
|
|
525
|
+
import { mkdirSync, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
526
|
+
import { join as join2 } from "path";
|
|
527
|
+
function createShellGuard() {
|
|
528
|
+
const REFUSAL = "Refused: don't create or delete files at /. Use your scratch dir (../scratch/).";
|
|
529
|
+
const SHELLS = ["bash", "sh", "zsh", "dash", "ksh"];
|
|
530
|
+
const PREFIX_CMDS = ["sudo", "doas", "nice", "nohup", "command", "exec", "time", "stdbuf", "ionice", "env", "builtin"];
|
|
531
|
+
const KEYWORDS = ["if", "then", "else", "elif", "fi", "do", "done", "while", "until", "for", "in", "!", "{", "}", "case", "esac"];
|
|
532
|
+
const MAX_DEPTH = 3;
|
|
533
|
+
function newWord() {
|
|
534
|
+
return { text: "", expansion: false, glob: false, tilde: false };
|
|
535
|
+
}
|
|
536
|
+
function skipParens(src, start) {
|
|
537
|
+
let depth = 1;
|
|
538
|
+
let i = start;
|
|
539
|
+
while (i < src.length) {
|
|
540
|
+
const c = src[i];
|
|
541
|
+
if (c === "\\") {
|
|
542
|
+
i += 2;
|
|
543
|
+
continue;
|
|
544
|
+
}
|
|
545
|
+
if (c === "'") {
|
|
546
|
+
const j = src.indexOf("'", i + 1);
|
|
547
|
+
if (j < 0)
|
|
548
|
+
return -1;
|
|
549
|
+
i = j + 1;
|
|
550
|
+
continue;
|
|
551
|
+
}
|
|
552
|
+
if (c === '"') {
|
|
553
|
+
i++;
|
|
554
|
+
while (i < src.length && src[i] !== '"') {
|
|
555
|
+
if (src[i] === "\\")
|
|
556
|
+
i++;
|
|
557
|
+
i++;
|
|
558
|
+
}
|
|
559
|
+
if (i >= src.length)
|
|
560
|
+
return -1;
|
|
561
|
+
i++;
|
|
562
|
+
continue;
|
|
563
|
+
}
|
|
564
|
+
if (c === "(")
|
|
565
|
+
depth++;
|
|
566
|
+
if (c === ")") {
|
|
567
|
+
depth--;
|
|
568
|
+
if (depth === 0)
|
|
569
|
+
return i;
|
|
570
|
+
}
|
|
571
|
+
i++;
|
|
572
|
+
}
|
|
573
|
+
return -1;
|
|
574
|
+
}
|
|
575
|
+
function lex(src) {
|
|
576
|
+
const out = { ok: true, heredoc: false, substitution: false, segments: [] };
|
|
577
|
+
let seg = { words: [], redirOut: [] };
|
|
578
|
+
let w = null;
|
|
579
|
+
let pendingRedir = "";
|
|
580
|
+
const heredocs = [];
|
|
581
|
+
function endWord() {
|
|
582
|
+
if (!w)
|
|
583
|
+
return;
|
|
584
|
+
if (pendingRedir === "out")
|
|
585
|
+
seg.redirOut.push(w);
|
|
586
|
+
else if (pendingRedir === "")
|
|
587
|
+
seg.words.push(w);
|
|
588
|
+
pendingRedir = "";
|
|
589
|
+
w = null;
|
|
590
|
+
}
|
|
591
|
+
function endSeg() {
|
|
592
|
+
endWord();
|
|
593
|
+
if (seg.words.length || seg.redirOut.length)
|
|
594
|
+
out.segments.push(seg);
|
|
595
|
+
seg = { words: [], redirOut: [] };
|
|
596
|
+
}
|
|
597
|
+
function word() {
|
|
598
|
+
if (!w)
|
|
599
|
+
w = newWord();
|
|
600
|
+
return w;
|
|
601
|
+
}
|
|
602
|
+
let i = 0;
|
|
603
|
+
while (i < src.length) {
|
|
604
|
+
const c = src[i];
|
|
605
|
+
if (c === "\n") {
|
|
606
|
+
endSeg();
|
|
607
|
+
i++;
|
|
608
|
+
while (heredocs.length) {
|
|
609
|
+
const h = heredocs.shift();
|
|
610
|
+
let found = false;
|
|
611
|
+
while (i < src.length) {
|
|
612
|
+
let end = src.indexOf("\n", i);
|
|
613
|
+
if (end < 0)
|
|
614
|
+
end = src.length;
|
|
615
|
+
let line = src.slice(i, end);
|
|
616
|
+
i = end + 1;
|
|
617
|
+
if (h.strip)
|
|
618
|
+
line = line.replace(/^\t+/, "");
|
|
619
|
+
if (line === h.delim) {
|
|
620
|
+
found = true;
|
|
621
|
+
break;
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
if (!found) {
|
|
625
|
+
out.ok = false;
|
|
626
|
+
i = src.length;
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
continue;
|
|
630
|
+
}
|
|
631
|
+
if (c === " " || c === " ") {
|
|
632
|
+
endWord();
|
|
633
|
+
i++;
|
|
634
|
+
continue;
|
|
635
|
+
}
|
|
636
|
+
if (c === "#" && !w) {
|
|
637
|
+
const j = src.indexOf("\n", i);
|
|
638
|
+
i = j < 0 ? src.length : j;
|
|
639
|
+
continue;
|
|
640
|
+
}
|
|
641
|
+
if (c === "\\") {
|
|
642
|
+
if (src[i + 1] === "\n") {
|
|
643
|
+
i += 2;
|
|
644
|
+
continue;
|
|
645
|
+
}
|
|
646
|
+
if (i + 1 >= src.length) {
|
|
647
|
+
out.ok = false;
|
|
648
|
+
i++;
|
|
649
|
+
continue;
|
|
650
|
+
}
|
|
651
|
+
word().text += src[i + 1];
|
|
652
|
+
i += 2;
|
|
653
|
+
continue;
|
|
654
|
+
}
|
|
655
|
+
if (c === "'") {
|
|
656
|
+
const j = src.indexOf("'", i + 1);
|
|
657
|
+
if (j < 0) {
|
|
658
|
+
out.ok = false;
|
|
659
|
+
break;
|
|
660
|
+
}
|
|
661
|
+
word().text += src.slice(i + 1, j);
|
|
662
|
+
i = j + 1;
|
|
663
|
+
continue;
|
|
664
|
+
}
|
|
665
|
+
if (c === '"') {
|
|
666
|
+
const cur2 = word();
|
|
667
|
+
i++;
|
|
668
|
+
let closed = false;
|
|
669
|
+
while (i < src.length) {
|
|
670
|
+
const d = src[i];
|
|
671
|
+
if (d === '"') {
|
|
672
|
+
closed = true;
|
|
673
|
+
i++;
|
|
674
|
+
break;
|
|
675
|
+
}
|
|
676
|
+
if (d === "\\" && i + 1 < src.length) {
|
|
677
|
+
cur2.text += src[i + 1];
|
|
678
|
+
i += 2;
|
|
679
|
+
continue;
|
|
680
|
+
}
|
|
681
|
+
if (d === "`") {
|
|
682
|
+
out.substitution = true;
|
|
683
|
+
cur2.expansion = true;
|
|
684
|
+
const j = src.indexOf("`", i + 1);
|
|
685
|
+
if (j < 0) {
|
|
686
|
+
out.ok = false;
|
|
687
|
+
i = src.length;
|
|
688
|
+
break;
|
|
689
|
+
}
|
|
690
|
+
cur2.text += src.slice(i, j + 1);
|
|
691
|
+
i = j + 1;
|
|
692
|
+
continue;
|
|
693
|
+
}
|
|
694
|
+
if (d === "$") {
|
|
695
|
+
cur2.expansion = true;
|
|
696
|
+
if (src[i + 1] === "(") {
|
|
697
|
+
out.substitution = true;
|
|
698
|
+
const j = skipParens(src, i + 2);
|
|
699
|
+
if (j < 0) {
|
|
700
|
+
out.ok = false;
|
|
701
|
+
i = src.length;
|
|
702
|
+
break;
|
|
703
|
+
}
|
|
704
|
+
cur2.text += src.slice(i, j + 1);
|
|
705
|
+
i = j + 1;
|
|
706
|
+
continue;
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
cur2.text += d;
|
|
710
|
+
i++;
|
|
711
|
+
}
|
|
712
|
+
if (!closed) {
|
|
713
|
+
out.ok = false;
|
|
714
|
+
break;
|
|
715
|
+
}
|
|
716
|
+
continue;
|
|
717
|
+
}
|
|
718
|
+
if (c === "`") {
|
|
719
|
+
out.substitution = true;
|
|
720
|
+
const cur2 = word();
|
|
721
|
+
cur2.expansion = true;
|
|
722
|
+
const j = src.indexOf("`", i + 1);
|
|
723
|
+
if (j < 0) {
|
|
724
|
+
out.ok = false;
|
|
725
|
+
break;
|
|
726
|
+
}
|
|
727
|
+
cur2.text += src.slice(i, j + 1);
|
|
728
|
+
i = j + 1;
|
|
729
|
+
continue;
|
|
730
|
+
}
|
|
731
|
+
if (c === "$") {
|
|
732
|
+
const cur2 = word();
|
|
733
|
+
cur2.expansion = true;
|
|
734
|
+
if (src[i + 1] === "(") {
|
|
735
|
+
out.substitution = true;
|
|
736
|
+
const j = skipParens(src, i + 2);
|
|
737
|
+
if (j < 0) {
|
|
738
|
+
out.ok = false;
|
|
739
|
+
break;
|
|
740
|
+
}
|
|
741
|
+
cur2.text += src.slice(i, j + 1);
|
|
742
|
+
i = j + 1;
|
|
743
|
+
continue;
|
|
744
|
+
}
|
|
745
|
+
if (src[i + 1] === "{") {
|
|
746
|
+
const j = src.indexOf("}", i + 2);
|
|
747
|
+
if (j < 0) {
|
|
748
|
+
out.ok = false;
|
|
749
|
+
break;
|
|
750
|
+
}
|
|
751
|
+
cur2.text += src.slice(i, j + 1);
|
|
752
|
+
i = j + 1;
|
|
753
|
+
continue;
|
|
754
|
+
}
|
|
755
|
+
cur2.text += c;
|
|
756
|
+
i++;
|
|
757
|
+
continue;
|
|
758
|
+
}
|
|
759
|
+
if (c === ">" || c === "<" && src[i + 1] !== "<" || c === "&" && src[i + 1] === ">") {
|
|
760
|
+
if (w && /^\d+$/.test(w.text) && !w.expansion)
|
|
761
|
+
w = null;
|
|
762
|
+
else
|
|
763
|
+
endWord();
|
|
764
|
+
const isOut = c !== "<";
|
|
765
|
+
i += c === "&" ? 2 : 1;
|
|
766
|
+
if (isOut && (src[i] === ">" || src[i] === "|"))
|
|
767
|
+
i++;
|
|
768
|
+
if (src[i] === "&") {
|
|
769
|
+
i++;
|
|
770
|
+
pendingRedir = "in";
|
|
771
|
+
} else {
|
|
772
|
+
pendingRedir = isOut ? "out" : "in";
|
|
773
|
+
}
|
|
774
|
+
continue;
|
|
775
|
+
}
|
|
776
|
+
if (c === "<" && src[i + 1] === "<") {
|
|
777
|
+
endWord();
|
|
778
|
+
if (src[i + 2] === "<") {
|
|
779
|
+
i += 3;
|
|
780
|
+
pendingRedir = "in";
|
|
781
|
+
continue;
|
|
782
|
+
}
|
|
783
|
+
i += 2;
|
|
784
|
+
let strip = false;
|
|
785
|
+
if (src[i] === "-") {
|
|
786
|
+
strip = true;
|
|
787
|
+
i++;
|
|
788
|
+
}
|
|
789
|
+
while (src[i] === " " || src[i] === " ")
|
|
790
|
+
i++;
|
|
791
|
+
let delim = "";
|
|
792
|
+
while (i < src.length && !/[\s;&|<>()]/.test(src[i])) {
|
|
793
|
+
const d = src[i];
|
|
794
|
+
if (d === "'" || d === '"') {
|
|
795
|
+
const j = src.indexOf(d, i + 1);
|
|
796
|
+
if (j < 0) {
|
|
797
|
+
out.ok = false;
|
|
798
|
+
break;
|
|
799
|
+
}
|
|
800
|
+
delim += src.slice(i + 1, j);
|
|
801
|
+
i = j + 1;
|
|
802
|
+
continue;
|
|
803
|
+
}
|
|
804
|
+
if (d === "\\") {
|
|
805
|
+
delim += src[i + 1] ?? "";
|
|
806
|
+
i += 2;
|
|
807
|
+
continue;
|
|
808
|
+
}
|
|
809
|
+
delim += d;
|
|
810
|
+
i++;
|
|
811
|
+
}
|
|
812
|
+
if (!delim) {
|
|
813
|
+
out.ok = false;
|
|
814
|
+
break;
|
|
815
|
+
}
|
|
816
|
+
out.heredoc = true;
|
|
817
|
+
heredocs.push({ delim, strip });
|
|
818
|
+
continue;
|
|
819
|
+
}
|
|
820
|
+
if (c === ";" || c === "&" || c === "|" || c === "(" || c === ")") {
|
|
821
|
+
endSeg();
|
|
822
|
+
i++;
|
|
823
|
+
continue;
|
|
824
|
+
}
|
|
825
|
+
const cur = word();
|
|
826
|
+
if (c === "*" || c === "?" || c === "[" || c === "{")
|
|
827
|
+
cur.glob = true;
|
|
828
|
+
if (c === "~" && cur.text === "")
|
|
829
|
+
cur.tilde = true;
|
|
830
|
+
cur.text += c;
|
|
831
|
+
i++;
|
|
832
|
+
}
|
|
833
|
+
endSeg();
|
|
834
|
+
if (heredocs.length)
|
|
835
|
+
out.ok = false;
|
|
836
|
+
return out;
|
|
837
|
+
}
|
|
838
|
+
function basename(p) {
|
|
839
|
+
const k = p.lastIndexOf("/");
|
|
840
|
+
return k < 0 ? p : p.slice(k + 1);
|
|
841
|
+
}
|
|
842
|
+
function analyzeInto(src, res, depth) {
|
|
843
|
+
const lexed = lex(src);
|
|
844
|
+
if (!lexed.ok)
|
|
845
|
+
res.ok = false;
|
|
846
|
+
if (lexed.heredoc)
|
|
847
|
+
res.heredoc = true;
|
|
848
|
+
if (lexed.substitution)
|
|
849
|
+
res.substitution = true;
|
|
850
|
+
for (const seg of lexed.segments) {
|
|
851
|
+
for (const r of seg.redirOut)
|
|
852
|
+
res.writes.push(r);
|
|
853
|
+
const words = seg.words.slice();
|
|
854
|
+
while (words.length) {
|
|
855
|
+
const t = words[0].text;
|
|
856
|
+
if (/^[A-Za-z_][A-Za-z0-9_]*=/.test(t)) {
|
|
857
|
+
words.shift();
|
|
858
|
+
continue;
|
|
859
|
+
}
|
|
860
|
+
if (KEYWORDS.indexOf(t) >= 0) {
|
|
861
|
+
words.shift();
|
|
862
|
+
continue;
|
|
863
|
+
}
|
|
864
|
+
if (PREFIX_CMDS.indexOf(basename(t)) >= 0) {
|
|
865
|
+
words.shift();
|
|
866
|
+
while (words.length && /^-/.test(words[0].text))
|
|
867
|
+
words.shift();
|
|
868
|
+
continue;
|
|
869
|
+
}
|
|
870
|
+
if (basename(t) === "timeout") {
|
|
871
|
+
words.shift();
|
|
872
|
+
while (words.length && /^-/.test(words[0].text))
|
|
873
|
+
words.shift();
|
|
874
|
+
words.shift();
|
|
875
|
+
continue;
|
|
876
|
+
}
|
|
877
|
+
break;
|
|
878
|
+
}
|
|
879
|
+
if (!words.length)
|
|
880
|
+
continue;
|
|
881
|
+
const cmd = basename(words[0].text);
|
|
882
|
+
const args = words.slice(1);
|
|
883
|
+
if (cmd === "rm") {
|
|
884
|
+
const inv = { targets: [], recursive: false, targetsUnknown: false };
|
|
885
|
+
let opts = true;
|
|
886
|
+
for (const a of args) {
|
|
887
|
+
if (opts && a.text === "--") {
|
|
888
|
+
opts = false;
|
|
889
|
+
continue;
|
|
890
|
+
}
|
|
891
|
+
if (opts && a.text.length > 1 && a.text[0] === "-" && !a.expansion) {
|
|
892
|
+
if (a.text === "--recursive" || a.text[1] !== "-" && /[rR]/.test(a.text))
|
|
893
|
+
inv.recursive = true;
|
|
894
|
+
continue;
|
|
895
|
+
}
|
|
896
|
+
inv.targets.push(a);
|
|
897
|
+
}
|
|
898
|
+
res.rm.push(inv);
|
|
899
|
+
} else if (cmd === "tee") {
|
|
900
|
+
for (const a of args)
|
|
901
|
+
if (!/^-/.test(a.text))
|
|
902
|
+
res.writes.push(a);
|
|
903
|
+
} else if (cmd === "xargs") {
|
|
904
|
+
if (args.some((a) => basename(a.text) === "rm")) {
|
|
905
|
+
res.rm.push({ targets: [], recursive: false, targetsUnknown: true });
|
|
906
|
+
}
|
|
907
|
+
} else if (cmd === "find") {
|
|
908
|
+
if (args.some((a) => a.text === "-delete" || a.text === "-exec" || a.text === "-execdir"))
|
|
909
|
+
res.findDelete = true;
|
|
910
|
+
} else if (SHELLS.indexOf(cmd) >= 0 || cmd === "eval") {
|
|
911
|
+
if (depth >= MAX_DEPTH) {
|
|
912
|
+
res.ok = false;
|
|
913
|
+
continue;
|
|
914
|
+
}
|
|
915
|
+
if (cmd === "eval") {
|
|
916
|
+
analyzeInto(args.map((a) => a.text).join(" "), res, depth + 1);
|
|
917
|
+
} else {
|
|
918
|
+
const k = args.findIndex((a) => /^-[A-Za-z]*c[A-Za-z]*$/.test(a.text));
|
|
919
|
+
if (k >= 0 && args[k + 1])
|
|
920
|
+
analyzeInto(args[k + 1].text, res, depth + 1);
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
function analyze(command) {
|
|
926
|
+
const res = {
|
|
927
|
+
ok: true,
|
|
928
|
+
heredoc: false,
|
|
929
|
+
substitution: false,
|
|
930
|
+
findDelete: false,
|
|
931
|
+
rm: [],
|
|
932
|
+
writes: []
|
|
933
|
+
};
|
|
934
|
+
if (typeof command !== "string") {
|
|
935
|
+
res.ok = false;
|
|
936
|
+
return res;
|
|
937
|
+
}
|
|
938
|
+
analyzeInto(command, res, 0);
|
|
939
|
+
return res;
|
|
940
|
+
}
|
|
941
|
+
function isRootLevelPath(word) {
|
|
942
|
+
if (!word || word.expansion || word.tilde)
|
|
943
|
+
return false;
|
|
944
|
+
const t = word.text;
|
|
945
|
+
if (t[0] !== "/")
|
|
946
|
+
return false;
|
|
947
|
+
const parts = [];
|
|
948
|
+
for (const p of t.split("/")) {
|
|
949
|
+
if (p === "" || p === ".")
|
|
950
|
+
continue;
|
|
951
|
+
if (p === "..") {
|
|
952
|
+
parts.pop();
|
|
953
|
+
continue;
|
|
954
|
+
}
|
|
955
|
+
parts.push(p);
|
|
956
|
+
}
|
|
957
|
+
return parts.length <= 1;
|
|
958
|
+
}
|
|
959
|
+
function hookVerdict(toolName, toolInput) {
|
|
960
|
+
const ti = toolInput && typeof toolInput === "object" ? toolInput : {};
|
|
961
|
+
if (toolName === "Write") {
|
|
962
|
+
const fp = ti["file_path"];
|
|
963
|
+
if (typeof fp !== "string")
|
|
964
|
+
return null;
|
|
965
|
+
return isRootLevelPath({ text: fp, expansion: false, glob: false, tilde: false }) ? REFUSAL : null;
|
|
966
|
+
}
|
|
967
|
+
if (toolName !== "Bash")
|
|
968
|
+
return null;
|
|
969
|
+
const cmd = ti["command"];
|
|
970
|
+
if (typeof cmd !== "string" || !cmd)
|
|
971
|
+
return null;
|
|
972
|
+
const a = analyze(cmd);
|
|
973
|
+
for (const inv of a.rm)
|
|
974
|
+
for (const t of inv.targets)
|
|
975
|
+
if (isRootLevelPath(t))
|
|
976
|
+
return REFUSAL;
|
|
977
|
+
for (const t of a.writes)
|
|
978
|
+
if (isRootLevelPath(t))
|
|
979
|
+
return REFUSAL;
|
|
980
|
+
return null;
|
|
981
|
+
}
|
|
982
|
+
return { analyze, isRootLevelPath, hookVerdict, refusal: REFUSAL };
|
|
983
|
+
}
|
|
984
|
+
var shellGuard = createShellGuard();
|
|
985
|
+
var ROOT_RM_HOOK_FILENAME = "agt-root-rm-hook.sh";
|
|
986
|
+
var ROOT_RM_HOOK_JS_FILENAME = "agt-root-rm-hook.mjs";
|
|
987
|
+
var ROOT_RM_HOOK_MATCHER = "Bash|Write";
|
|
988
|
+
function buildRootRmHookJs() {
|
|
989
|
+
return [
|
|
990
|
+
"'use strict';",
|
|
991
|
+
"// ENG-11513 root-level rm/write guard. Generated by provisionRootRmHook; see root-rm-guard.ts.",
|
|
992
|
+
`const createShellGuard = ${createShellGuard.toString()};`,
|
|
993
|
+
"let raw = '';",
|
|
994
|
+
"process.stdin.setEncoding('utf8');",
|
|
995
|
+
"process.stdin.on('data', (d) => { raw += d; });",
|
|
996
|
+
"process.stdin.on('end', () => {",
|
|
997
|
+
" let code = 0;",
|
|
998
|
+
" try {",
|
|
999
|
+
" const input = JSON.parse(raw);",
|
|
1000
|
+
" const reason = createShellGuard().hookVerdict(input && input.tool_name, input && input.tool_input);",
|
|
1001
|
+
" if (reason) { process.stderr.write(reason + '\\n'); code = 2; }",
|
|
1002
|
+
" } catch (e) { code = 0; }",
|
|
1003
|
+
" process.exit(code);",
|
|
1004
|
+
"});",
|
|
1005
|
+
""
|
|
1006
|
+
].join("\n");
|
|
1007
|
+
}
|
|
1008
|
+
function provisionRootRmHookAt(claudeDir) {
|
|
1009
|
+
mkdirSync(claudeDir, { recursive: true });
|
|
1010
|
+
const jsPath = join2(claudeDir, ROOT_RM_HOOK_JS_FILENAME);
|
|
1011
|
+
writeFileSync2(jsPath, buildRootRmHookJs(), { mode: 420 });
|
|
1012
|
+
const hookScriptPath = join2(claudeDir, ROOT_RM_HOOK_FILENAME);
|
|
1013
|
+
writeFileSync2(hookScriptPath, [
|
|
1014
|
+
"#!/usr/bin/env bash",
|
|
1015
|
+
"# ENG-11513: refuse rm of, or writes creating, files directly under /; see root-rm-guard.ts.",
|
|
1016
|
+
"# Fail open: no node, or any error in the matcher, allows the call.",
|
|
1017
|
+
"command -v node >/dev/null 2>&1 || exit 0",
|
|
1018
|
+
`exec node '${jsPath.replace(/'/g, `'\\''`)}'`
|
|
1019
|
+
].join("\n") + "\n", { mode: 493 });
|
|
1020
|
+
const settingsPath = join2(claudeDir, "settings.local.json");
|
|
1021
|
+
let settings = {};
|
|
1022
|
+
try {
|
|
1023
|
+
settings = JSON.parse(readFileSync2(settingsPath, "utf-8"));
|
|
1024
|
+
} catch {
|
|
1025
|
+
}
|
|
1026
|
+
const hooks = settings["hooks"] ?? {};
|
|
1027
|
+
const groups = Array.isArray(hooks["PreToolUse"]) ? hooks["PreToolUse"] : [];
|
|
1028
|
+
if (!groups.some((g) => (g.hooks ?? []).some((h) => h.command === hookScriptPath))) {
|
|
1029
|
+
groups.push({ matcher: ROOT_RM_HOOK_MATCHER, hooks: [{ type: "command", command: hookScriptPath }] });
|
|
1030
|
+
}
|
|
1031
|
+
hooks["PreToolUse"] = groups;
|
|
1032
|
+
settings["hooks"] = hooks;
|
|
1033
|
+
writeFileSync2(settingsPath, JSON.stringify(settings, null, 2));
|
|
1034
|
+
}
|
|
1035
|
+
var RM_POLICY_ARTIFACT = "rm-policy.json";
|
|
1036
|
+
var RM_POLICY_RELATIVE_PATH = `provision/${RM_POLICY_ARTIFACT}`;
|
|
1037
|
+
function stringList(v) {
|
|
1038
|
+
return Array.isArray(v) ? v.filter((x) => typeof x === "string") : [];
|
|
1039
|
+
}
|
|
1040
|
+
function rmPolicyFromGuardrails(guardrails) {
|
|
1041
|
+
if (guardrails === void 0)
|
|
1042
|
+
return null;
|
|
1043
|
+
const sources = [];
|
|
1044
|
+
for (const g of guardrails) {
|
|
1045
|
+
if (g.enforcement === "disabled")
|
|
1046
|
+
continue;
|
|
1047
|
+
if (g.definitionId === "tool.block_list") {
|
|
1048
|
+
const entries = [...stringList(g.config["blocked_tools"]), ...stringList(g.config["blocked_patterns"])];
|
|
1049
|
+
if (entries.some((e) => /(?:^|[^a-z])(?:rm|delete)(?:[^a-z]|$)/.test(e.toLowerCase()))) {
|
|
1050
|
+
sources.push(g.definitionId);
|
|
1051
|
+
}
|
|
1052
|
+
} else if (g.definitionId === "require-approval-for-actions") {
|
|
1053
|
+
const actions = stringList(g.config["actions"]).map((t) => t.trim().toLowerCase());
|
|
1054
|
+
if (actions.includes("delete"))
|
|
1055
|
+
sources.push(g.definitionId);
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
1058
|
+
return { no_delete: sources.length > 0, sources };
|
|
1059
|
+
}
|
|
1060
|
+
function guardrailsForProvision(guardrails, resolved) {
|
|
1061
|
+
return resolved === false ? void 0 : guardrails;
|
|
1062
|
+
}
|
|
1063
|
+
var RM_POLICY_UNKNOWN = { no_delete: null, sources: [] };
|
|
1064
|
+
function parseRmPolicy(text) {
|
|
1065
|
+
if (text === null)
|
|
1066
|
+
return null;
|
|
1067
|
+
try {
|
|
1068
|
+
const v = JSON.parse(text);
|
|
1069
|
+
if (typeof v["no_delete"] !== "boolean")
|
|
1070
|
+
return null;
|
|
1071
|
+
return { no_delete: v["no_delete"], sources: stringList(v["sources"]) };
|
|
1072
|
+
} catch {
|
|
1073
|
+
return null;
|
|
1074
|
+
}
|
|
1075
|
+
}
|
|
1076
|
+
|
|
524
1077
|
// ../../packages/core/dist/provisioning/frameworks/claudecode/core-knowledge-description.js
|
|
525
1078
|
var CORE_KNOWLEDGE_DESCRIPTION_MAX_CHARS = 1024;
|
|
526
1079
|
var CORE_KNOWLEDGE_TITLE_MAX_CHARS = 80;
|
|
@@ -582,15 +1135,15 @@ function orderTitlesForDescription(entries) {
|
|
|
582
1135
|
}
|
|
583
1136
|
|
|
584
1137
|
// ../../packages/core/dist/provisioning/frameworks/claudecode/index.js
|
|
585
|
-
import { readFileSync as
|
|
586
|
-
import { join as
|
|
1138
|
+
import { readFileSync as readFileSync5, writeFileSync as writeFileSync5, mkdirSync as mkdirSync4, existsSync as existsSync4, chmodSync as chmodSync4, readdirSync, rmSync as rmSync2, copyFileSync, lstatSync, realpathSync, symlinkSync, readlinkSync, renameSync as renameSync4, opendirSync } from "fs";
|
|
1139
|
+
import { join as join5, relative, dirname as dirname3 } from "path";
|
|
587
1140
|
import { homedir as homedir3, tmpdir } from "os";
|
|
588
1141
|
import { execFile } from "child_process";
|
|
589
1142
|
|
|
590
1143
|
// ../../packages/core/dist/integrations/xurl-config.js
|
|
591
|
-
import { chmodSync as chmodSync2, existsSync as existsSync2, mkdirSync, readFileSync as
|
|
1144
|
+
import { chmodSync as chmodSync2, existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync3, renameSync as renameSync2, unlinkSync as unlinkSync2, writeFileSync as writeFileSync3 } from "fs";
|
|
592
1145
|
import { homedir } from "os";
|
|
593
|
-
import { dirname, join as
|
|
1146
|
+
import { dirname, join as join3 } from "path";
|
|
594
1147
|
import { parse as parseYaml, stringify as stringifyYaml } from "yaml";
|
|
595
1148
|
var XURL_FILE_MODE = 384;
|
|
596
1149
|
var XURL_AGT_APP_PREFIX = "agt-";
|
|
@@ -709,7 +1262,7 @@ function buildAgtXurlApps(integrations) {
|
|
|
709
1262
|
}
|
|
710
1263
|
function getXurlStorePath() {
|
|
711
1264
|
const home = process.env["HOME"] ?? process.env["USERPROFILE"] ?? homedir();
|
|
712
|
-
return
|
|
1265
|
+
return join3(home, ".xurl");
|
|
713
1266
|
}
|
|
714
1267
|
function writeXurlStoreForIntegrations(integrations, filePath = getXurlStorePath()) {
|
|
715
1268
|
const agtApps = buildAgtXurlApps(integrations);
|
|
@@ -719,7 +1272,7 @@ function writeXurlStoreForIntegrations(integrations, filePath = getXurlStorePath
|
|
|
719
1272
|
if (existsSync2(filePath)) {
|
|
720
1273
|
let raw;
|
|
721
1274
|
try {
|
|
722
|
-
raw =
|
|
1275
|
+
raw = readFileSync3(filePath, "utf-8");
|
|
723
1276
|
} catch {
|
|
724
1277
|
return null;
|
|
725
1278
|
}
|
|
@@ -730,9 +1283,9 @@ function writeXurlStoreForIntegrations(integrations, filePath = getXurlStorePath
|
|
|
730
1283
|
existing = parsed;
|
|
731
1284
|
}
|
|
732
1285
|
const merged = mergeXurlStore(existing, agtApps);
|
|
733
|
-
|
|
1286
|
+
mkdirSync2(dirname(filePath), { recursive: true });
|
|
734
1287
|
const tmpPath = `${filePath}.tmp-${process.pid}-${Date.now()}`;
|
|
735
|
-
|
|
1288
|
+
writeFileSync3(tmpPath, serializeXurlStore(merged), { mode: XURL_FILE_MODE });
|
|
736
1289
|
try {
|
|
737
1290
|
renameSync2(tmpPath, filePath);
|
|
738
1291
|
} catch (err) {
|
|
@@ -750,9 +1303,9 @@ function writeXurlStoreForIntegrations(integrations, filePath = getXurlStorePath
|
|
|
750
1303
|
}
|
|
751
1304
|
|
|
752
1305
|
// ../../packages/core/dist/integrations/framer-credentials.js
|
|
753
|
-
import { chmodSync as chmodSync3, existsSync as existsSync3, mkdirSync as
|
|
1306
|
+
import { chmodSync as chmodSync3, existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync4, renameSync as renameSync3, rmSync, statSync, unlinkSync as unlinkSync3, writeFileSync as writeFileSync4 } from "fs";
|
|
754
1307
|
import { homedir as homedir2 } from "os";
|
|
755
|
-
import { dirname as dirname2, join as
|
|
1308
|
+
import { dirname as dirname2, join as join4 } from "path";
|
|
756
1309
|
var FRAMER_PROJECTS_CONFIG_VERSION = 2;
|
|
757
1310
|
var BARE_PROJECT_ID = /^[A-Za-z0-9]{20}$/u;
|
|
758
1311
|
var SLUGGED_PROJECT_ID = /^.+--([A-Za-z0-9]+)/u;
|
|
@@ -851,11 +1404,11 @@ function mergeFramerProjectsConfig(existing, inputs, options = {}) {
|
|
|
851
1404
|
var FRAMER_FILE_MODE = 384;
|
|
852
1405
|
var MANAGED_SIDECAR_NAME = ".augmented-managed-projects.json";
|
|
853
1406
|
function sidecarPathFor(projectsPath) {
|
|
854
|
-
return
|
|
1407
|
+
return join4(dirname2(projectsPath), MANAGED_SIDECAR_NAME);
|
|
855
1408
|
}
|
|
856
1409
|
function readManagedIds(projectsPath) {
|
|
857
1410
|
try {
|
|
858
|
-
const raw =
|
|
1411
|
+
const raw = readFileSync4(sidecarPathFor(projectsPath), "utf-8");
|
|
859
1412
|
const parsed = JSON.parse(raw);
|
|
860
1413
|
if (!Array.isArray(parsed))
|
|
861
1414
|
return [];
|
|
@@ -874,7 +1427,7 @@ function writeManagedIds(projectsPath, ids) {
|
|
|
874
1427
|
}
|
|
875
1428
|
return;
|
|
876
1429
|
}
|
|
877
|
-
|
|
1430
|
+
writeFileSync4(target, `${JSON.stringify([...ids].sort(), null, " ")}
|
|
878
1431
|
`, {
|
|
879
1432
|
mode: FRAMER_FILE_MODE
|
|
880
1433
|
});
|
|
@@ -887,13 +1440,13 @@ var LOCK_MAX_ATTEMPTS = 50;
|
|
|
887
1440
|
function withStoreLock(projectsPath, fn) {
|
|
888
1441
|
const lockDir = `${projectsPath}.lock`;
|
|
889
1442
|
try {
|
|
890
|
-
|
|
1443
|
+
mkdirSync3(dirname2(projectsPath), { recursive: true, mode: 448 });
|
|
891
1444
|
} catch {
|
|
892
1445
|
}
|
|
893
1446
|
let held = false;
|
|
894
1447
|
for (let attempt = 0; attempt < LOCK_MAX_ATTEMPTS && !held; attempt++) {
|
|
895
1448
|
try {
|
|
896
|
-
|
|
1449
|
+
mkdirSync3(lockDir);
|
|
897
1450
|
held = true;
|
|
898
1451
|
} catch {
|
|
899
1452
|
try {
|
|
@@ -927,9 +1480,9 @@ function asString2(value) {
|
|
|
927
1480
|
function getFramerProjectsPath() {
|
|
928
1481
|
const xdg = process.env["XDG_CONFIG_HOME"];
|
|
929
1482
|
if (xdg)
|
|
930
|
-
return
|
|
1483
|
+
return join4(xdg, "framer", "projects.json");
|
|
931
1484
|
const home = process.env["HOME"] ?? process.env["USERPROFILE"] ?? homedir2();
|
|
932
|
-
return
|
|
1485
|
+
return join4(home, ".config", "framer", "projects.json");
|
|
933
1486
|
}
|
|
934
1487
|
function buildFramerCredentialInputs(integrations) {
|
|
935
1488
|
const inputs = [];
|
|
@@ -960,7 +1513,7 @@ function writeFramerStoreForIntegrations(integrations, filePath = getFramerProje
|
|
|
960
1513
|
let existing = null;
|
|
961
1514
|
if (existsSync3(filePath)) {
|
|
962
1515
|
try {
|
|
963
|
-
existing =
|
|
1516
|
+
existing = readFileSync4(filePath, "utf-8");
|
|
964
1517
|
} catch {
|
|
965
1518
|
return null;
|
|
966
1519
|
}
|
|
@@ -972,9 +1525,9 @@ function writeFramerStoreForIntegrations(integrations, filePath = getFramerProje
|
|
|
972
1525
|
}
|
|
973
1526
|
if (!content)
|
|
974
1527
|
return null;
|
|
975
|
-
|
|
1528
|
+
mkdirSync3(dirname2(filePath), { recursive: true, mode: 448 });
|
|
976
1529
|
const tmpPath = `${filePath}.tmp-${process.pid}-${Date.now()}`;
|
|
977
|
-
|
|
1530
|
+
writeFileSync4(tmpPath, content, { mode: FRAMER_FILE_MODE });
|
|
978
1531
|
try {
|
|
979
1532
|
renameSync3(tmpPath, filePath);
|
|
980
1533
|
} catch (err) {
|
|
@@ -1788,25 +2341,25 @@ var VALID_CODE_NAME = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
|
1788
2341
|
var SECRET_FILE_MODE = 384;
|
|
1789
2342
|
function writeEnvIntegrationsForAgent(codeName, args) {
|
|
1790
2343
|
const agentDir = getAgentDir(codeName);
|
|
1791
|
-
const envPath =
|
|
2344
|
+
const envPath = join5(agentDir, ".env.integrations");
|
|
1792
2345
|
let existing = null;
|
|
1793
2346
|
try {
|
|
1794
|
-
existing =
|
|
2347
|
+
existing = readFileSync5(envPath, "utf-8");
|
|
1795
2348
|
} catch {
|
|
1796
2349
|
}
|
|
1797
2350
|
if (existing === null && Object.keys(args.updates).length === 0)
|
|
1798
2351
|
return;
|
|
1799
2352
|
const content = mergeEnvIntegrationsContent(existing, args);
|
|
1800
|
-
|
|
2353
|
+
writeFileSync5(envPath, content, { mode: SECRET_FILE_MODE });
|
|
1801
2354
|
try {
|
|
1802
2355
|
chmodSync4(envPath, SECRET_FILE_MODE);
|
|
1803
2356
|
} catch {
|
|
1804
2357
|
}
|
|
1805
2358
|
try {
|
|
1806
2359
|
const projectDir = getProjectDir2(codeName);
|
|
1807
|
-
|
|
1808
|
-
const dest =
|
|
1809
|
-
|
|
2360
|
+
mkdirSync4(projectDir, { recursive: true });
|
|
2361
|
+
const dest = join5(projectDir, ".env.integrations");
|
|
2362
|
+
writeFileSync5(dest, content, { mode: SECRET_FILE_MODE });
|
|
1810
2363
|
try {
|
|
1811
2364
|
chmodSync4(dest, SECRET_FILE_MODE);
|
|
1812
2365
|
} catch {
|
|
@@ -1826,16 +2379,16 @@ var MIGRATABLE_FIELD_TO_ENV_VAR = {
|
|
|
1826
2379
|
AGT_API_KEY: "AGT_API_KEY"
|
|
1827
2380
|
};
|
|
1828
2381
|
function migrateExistingLiteralSecrets(codeName) {
|
|
1829
|
-
const mcpJsonPath =
|
|
2382
|
+
const mcpJsonPath = join5(getAgentDir(codeName), "provision", ".mcp.json");
|
|
1830
2383
|
let config;
|
|
1831
2384
|
try {
|
|
1832
|
-
config = JSON.parse(
|
|
2385
|
+
config = JSON.parse(readFileSync5(mcpJsonPath, "utf-8"));
|
|
1833
2386
|
} catch {
|
|
1834
2387
|
return;
|
|
1835
2388
|
}
|
|
1836
2389
|
let existingEnvKeys = /* @__PURE__ */ new Set();
|
|
1837
2390
|
try {
|
|
1838
|
-
existingEnvKeys = new Set(parseEnvFileEntries(
|
|
2391
|
+
existingEnvKeys = new Set(parseEnvFileEntries(readFileSync5(join5(getAgentDir(codeName), ".env.integrations"), "utf-8")).keys());
|
|
1839
2392
|
} catch {
|
|
1840
2393
|
}
|
|
1841
2394
|
const updates = {};
|
|
@@ -1909,8 +2462,8 @@ function ensureIdKeyedLayout(codeName, agentId) {
|
|
|
1909
2462
|
assertValidCodeName(codeName);
|
|
1910
2463
|
assertValidAgentId(agentId);
|
|
1911
2464
|
const home = getHomeDir();
|
|
1912
|
-
const codeNamePath =
|
|
1913
|
-
const idPath =
|
|
2465
|
+
const codeNamePath = join5(home, ".augmented", codeName);
|
|
2466
|
+
const idPath = join5(home, ".augmented", agentId);
|
|
1914
2467
|
let state;
|
|
1915
2468
|
try {
|
|
1916
2469
|
state = lstatSync(codeNamePath).isSymbolicLink() ? "symlink" : "realdir";
|
|
@@ -1925,15 +2478,15 @@ function ensureIdKeyedLayout(codeName, agentId) {
|
|
|
1925
2478
|
if (target !== agentId) {
|
|
1926
2479
|
throw new Error(`Codename symlink ${codeNamePath} points at "${target}", expected "${agentId}"; refusing to provision over a mismatched id-keyed layout.`);
|
|
1927
2480
|
}
|
|
1928
|
-
|
|
2481
|
+
mkdirSync4(idPath, { recursive: true });
|
|
1929
2482
|
return idPath;
|
|
1930
2483
|
}
|
|
1931
|
-
|
|
2484
|
+
mkdirSync4(idPath, { recursive: true });
|
|
1932
2485
|
symlinkSync(agentId, codeNamePath);
|
|
1933
2486
|
return idPath;
|
|
1934
2487
|
}
|
|
1935
2488
|
function stagedMigrationLinkPath(home, codeName) {
|
|
1936
|
-
return
|
|
2489
|
+
return join5(home, ".augmented", `.${codeName}.migrating`);
|
|
1937
2490
|
}
|
|
1938
2491
|
function cleanupStaleStagedLink(staged) {
|
|
1939
2492
|
try {
|
|
@@ -1953,8 +2506,8 @@ function migrateAgentDirToIdKeyed(codeName, agentId, opts = {}) {
|
|
|
1953
2506
|
assertValidCodeName(codeName);
|
|
1954
2507
|
assertValidAgentId(agentId);
|
|
1955
2508
|
const home = opts.home ?? getHomeDir();
|
|
1956
|
-
const codeNamePath =
|
|
1957
|
-
const idPath =
|
|
2509
|
+
const codeNamePath = join5(home, ".augmented", codeName);
|
|
2510
|
+
const idPath = join5(home, ".augmented", agentId);
|
|
1958
2511
|
const staged = stagedMigrationLinkPath(home, codeName);
|
|
1959
2512
|
let codeNameKind;
|
|
1960
2513
|
try {
|
|
@@ -1992,14 +2545,14 @@ function migrateAgentDirToIdKeyed(codeName, agentId, opts = {}) {
|
|
|
1992
2545
|
}
|
|
1993
2546
|
function getAgentDir(codeName) {
|
|
1994
2547
|
assertValidCodeName(codeName);
|
|
1995
|
-
return resolveRealAgentPath(
|
|
2548
|
+
return resolveRealAgentPath(join5(getHomeDir(), ".augmented", codeName));
|
|
1996
2549
|
}
|
|
1997
2550
|
var migratedCodeNames = /* @__PURE__ */ new Set();
|
|
1998
2551
|
function migrateLegacyClaudecodeDir(codeName, log2) {
|
|
1999
2552
|
assertValidCodeName(codeName);
|
|
2000
2553
|
if (migratedCodeNames.has(codeName))
|
|
2001
2554
|
return;
|
|
2002
|
-
const legacyRoot =
|
|
2555
|
+
const legacyRoot = join5(getHomeDir(), ".augmented", codeName, "claudecode");
|
|
2003
2556
|
if (!existsSync4(legacyRoot)) {
|
|
2004
2557
|
migratedCodeNames.add(codeName);
|
|
2005
2558
|
return;
|
|
@@ -2010,20 +2563,20 @@ function migrateLegacyClaudecodeDir(codeName, log2) {
|
|
|
2010
2563
|
};
|
|
2011
2564
|
try {
|
|
2012
2565
|
const walkAndMigrate = (srcDir, destDir) => {
|
|
2013
|
-
|
|
2566
|
+
mkdirSync4(destDir, { recursive: true });
|
|
2014
2567
|
for (const entry of readdirSync(srcDir, { withFileTypes: true })) {
|
|
2015
|
-
const src =
|
|
2016
|
-
const dest =
|
|
2568
|
+
const src = join5(srcDir, entry.name);
|
|
2569
|
+
const dest = join5(destDir, entry.name);
|
|
2017
2570
|
if (entry.isDirectory()) {
|
|
2018
2571
|
walkAndMigrate(src, dest);
|
|
2019
2572
|
continue;
|
|
2020
2573
|
}
|
|
2021
2574
|
if (entry.name === ".mcp.json" && existsSync4(dest)) {
|
|
2022
2575
|
try {
|
|
2023
|
-
const oldCfg = JSON.parse(
|
|
2024
|
-
const newCfg = JSON.parse(
|
|
2576
|
+
const oldCfg = JSON.parse(readFileSync5(src, "utf-8"));
|
|
2577
|
+
const newCfg = JSON.parse(readFileSync5(dest, "utf-8"));
|
|
2025
2578
|
const merged = { mcpServers: { ...oldCfg.mcpServers ?? {}, ...newCfg.mcpServers ?? {} } };
|
|
2026
|
-
|
|
2579
|
+
writeFileSync5(dest, JSON.stringify(merged, null, 2));
|
|
2027
2580
|
emit(`[migrate] '${codeName}' merged .mcp.json (${Object.keys(merged.mcpServers).length} servers)`);
|
|
2028
2581
|
} catch (err) {
|
|
2029
2582
|
throw new Error(`Failed merging .mcp.json (${src} \u2192 ${dest}): ${err.message}`);
|
|
@@ -2035,8 +2588,8 @@ function migrateLegacyClaudecodeDir(codeName, log2) {
|
|
|
2035
2588
|
continue;
|
|
2036
2589
|
}
|
|
2037
2590
|
try {
|
|
2038
|
-
const srcStat =
|
|
2039
|
-
const destStat =
|
|
2591
|
+
const srcStat = readFileSync5(src);
|
|
2592
|
+
const destStat = readFileSync5(dest);
|
|
2040
2593
|
if (!srcStat.equals(destStat)) {
|
|
2041
2594
|
}
|
|
2042
2595
|
} catch (err) {
|
|
@@ -2053,25 +2606,25 @@ function migrateLegacyClaudecodeDir(codeName, log2) {
|
|
|
2053
2606
|
}
|
|
2054
2607
|
}
|
|
2055
2608
|
function syncGitHubBrokerCredentialTooling(projectDir, enabled) {
|
|
2056
|
-
const binDir =
|
|
2609
|
+
const binDir = join5(projectDir, GITHUB_BROKER_BIN_DIR);
|
|
2057
2610
|
if (!enabled) {
|
|
2058
2611
|
rmSync2(binDir, { recursive: true, force: true });
|
|
2059
2612
|
return {};
|
|
2060
2613
|
}
|
|
2061
|
-
const helperPath =
|
|
2062
|
-
const shimPath =
|
|
2063
|
-
|
|
2064
|
-
|
|
2614
|
+
const helperPath = join5(binDir, GIT_CREDENTIAL_HELPER_BASENAME);
|
|
2615
|
+
const shimPath = join5(binDir, GH_SHIM_BASENAME);
|
|
2616
|
+
mkdirSync4(binDir, { recursive: true });
|
|
2617
|
+
writeFileSync5(helperPath, renderGitCredentialHelper(), { mode: BROKER_SCRIPT_MODE });
|
|
2065
2618
|
chmodSync4(helperPath, BROKER_SCRIPT_MODE);
|
|
2066
|
-
|
|
2619
|
+
writeFileSync5(shimPath, renderGhShim(), { mode: BROKER_SCRIPT_MODE });
|
|
2067
2620
|
chmodSync4(shimPath, BROKER_SCRIPT_MODE);
|
|
2068
2621
|
return buildGitCredentialEnv(helperPath);
|
|
2069
2622
|
}
|
|
2070
2623
|
function getProjectDir2(codeName) {
|
|
2071
|
-
return
|
|
2624
|
+
return join5(getAgentDir(codeName), "project");
|
|
2072
2625
|
}
|
|
2073
2626
|
function reapLegacyTokenFile(codeName, onWarn = void 0) {
|
|
2074
|
-
const tokenFilePath =
|
|
2627
|
+
const tokenFilePath = join5(getAgentDir(codeName), ".tokens.json");
|
|
2075
2628
|
try {
|
|
2076
2629
|
rmSync2(tokenFilePath, { force: true });
|
|
2077
2630
|
return true;
|
|
@@ -2081,7 +2634,7 @@ function reapLegacyTokenFile(codeName, onWarn = void 0) {
|
|
|
2081
2634
|
}
|
|
2082
2635
|
}
|
|
2083
2636
|
function getScratchDir(codeName) {
|
|
2084
|
-
return
|
|
2637
|
+
return join5(getAgentDir(codeName), "scratch");
|
|
2085
2638
|
}
|
|
2086
2639
|
function getAgentTmpDir(codeName) {
|
|
2087
2640
|
return agentTmpDirFor(getAgentDir(codeName));
|
|
@@ -2097,7 +2650,7 @@ function sweepScratchDir(codeName, now = Date.now()) {
|
|
|
2097
2650
|
}
|
|
2098
2651
|
const cutoff = now - SCRATCH_RETENTION_DAYS * 24 * 60 * 60 * 1e3;
|
|
2099
2652
|
for (const entry of entries) {
|
|
2100
|
-
const full =
|
|
2653
|
+
const full = join5(scratchDir, entry);
|
|
2101
2654
|
try {
|
|
2102
2655
|
if (isFreshWithin(full, cutoff))
|
|
2103
2656
|
continue;
|
|
@@ -2125,7 +2678,7 @@ function sweepStrandedArtefactTmpDirs(now = Date.now()) {
|
|
|
2125
2678
|
for (const entry of entries) {
|
|
2126
2679
|
if (!STRANDED_ARTEFACT_TMP_PREFIXES.some((prefix) => entry.startsWith(prefix)))
|
|
2127
2680
|
continue;
|
|
2128
|
-
const full =
|
|
2681
|
+
const full = join5(root, entry);
|
|
2129
2682
|
try {
|
|
2130
2683
|
if (isFreshWithin(full, cutoff))
|
|
2131
2684
|
continue;
|
|
@@ -2165,7 +2718,7 @@ function isFreshWithin(path, cutoff) {
|
|
|
2165
2718
|
const child = dir.readSync();
|
|
2166
2719
|
if (child === null)
|
|
2167
2720
|
break;
|
|
2168
|
-
queue.push(
|
|
2721
|
+
queue.push(join5(current, child.name));
|
|
2169
2722
|
budget -= 1;
|
|
2170
2723
|
}
|
|
2171
2724
|
} catch {
|
|
@@ -2182,18 +2735,18 @@ function isFreshWithin(path, cutoff) {
|
|
|
2182
2735
|
function syncMcpToProject(codeName) {
|
|
2183
2736
|
const agentDir = getAgentDir(codeName);
|
|
2184
2737
|
const projectDir = getProjectDir2(codeName);
|
|
2185
|
-
const provisionMcpPath =
|
|
2186
|
-
const projectMcpPath =
|
|
2738
|
+
const provisionMcpPath = join5(agentDir, "provision", ".mcp.json");
|
|
2739
|
+
const projectMcpPath = join5(projectDir, ".mcp.json");
|
|
2187
2740
|
try {
|
|
2188
|
-
const content =
|
|
2189
|
-
|
|
2190
|
-
|
|
2741
|
+
const content = readFileSync5(provisionMcpPath, "utf-8");
|
|
2742
|
+
mkdirSync4(projectDir, { recursive: true });
|
|
2743
|
+
writeFileSync5(projectMcpPath, content, { mode: MCP_FILE_MODE });
|
|
2191
2744
|
try {
|
|
2192
2745
|
chmodSync4(projectMcpPath, MCP_FILE_MODE);
|
|
2193
2746
|
} catch {
|
|
2194
2747
|
}
|
|
2195
2748
|
try {
|
|
2196
|
-
const mismatches = mcpMirrorParityErrors(JSON.parse(content), JSON.parse(
|
|
2749
|
+
const mismatches = mcpMirrorParityErrors(JSON.parse(content), JSON.parse(readFileSync5(projectMcpPath, "utf-8")));
|
|
2197
2750
|
for (const m of mismatches) {
|
|
2198
2751
|
process.stderr.write(`${formatMirrorMismatch(m)} agent=${codeName}
|
|
2199
2752
|
`);
|
|
@@ -2207,19 +2760,19 @@ function syncMcpToProject(codeName) {
|
|
|
2207
2760
|
}
|
|
2208
2761
|
var INTEGRATIONS_SUMMARY_FILE = "integrations-summary.json";
|
|
2209
2762
|
function integrationsSummaryPath(codeName) {
|
|
2210
|
-
return
|
|
2763
|
+
return join5(getAgentDir(codeName), "provision", INTEGRATIONS_SUMMARY_FILE);
|
|
2211
2764
|
}
|
|
2212
2765
|
function writeIntegrationsSummaryForAgent(codeName, summaries) {
|
|
2213
2766
|
const target = integrationsSummaryPath(codeName);
|
|
2214
2767
|
try {
|
|
2215
|
-
|
|
2216
|
-
|
|
2768
|
+
mkdirSync4(dirname3(target), { recursive: true });
|
|
2769
|
+
writeFileSync5(target, JSON.stringify(summaries, null, 2));
|
|
2217
2770
|
} catch {
|
|
2218
2771
|
}
|
|
2219
2772
|
}
|
|
2220
2773
|
function readIntegrationsSummaryForAgent(codeName) {
|
|
2221
2774
|
try {
|
|
2222
|
-
const raw =
|
|
2775
|
+
const raw = readFileSync5(integrationsSummaryPath(codeName), "utf-8");
|
|
2223
2776
|
const parsed = JSON.parse(raw);
|
|
2224
2777
|
return Array.isArray(parsed) ? parsed : [];
|
|
2225
2778
|
} catch {
|
|
@@ -2229,10 +2782,10 @@ function readIntegrationsSummaryForAgent(codeName) {
|
|
|
2229
2782
|
function renderChannelMessageHandlerForAgent(codeName) {
|
|
2230
2783
|
const agentDir = getAgentDir(codeName);
|
|
2231
2784
|
const projectDir = getProjectDir2(codeName);
|
|
2232
|
-
const provisionMcpPath =
|
|
2785
|
+
const provisionMcpPath = join5(agentDir, "provision", ".mcp.json");
|
|
2233
2786
|
let mcpServerKeys;
|
|
2234
2787
|
try {
|
|
2235
|
-
const config = JSON.parse(
|
|
2788
|
+
const config = JSON.parse(readFileSync5(provisionMcpPath, "utf-8"));
|
|
2236
2789
|
mcpServerKeys = Object.keys(config.mcpServers ?? {});
|
|
2237
2790
|
} catch {
|
|
2238
2791
|
return;
|
|
@@ -2240,10 +2793,10 @@ function renderChannelMessageHandlerForAgent(codeName) {
|
|
|
2240
2793
|
const integrations = readIntegrationsSummaryForAgent(codeName);
|
|
2241
2794
|
const content = buildChannelMessageHandlerAgent({ mcpServerKeys, integrations });
|
|
2242
2795
|
for (const baseDir of [agentDir, projectDir]) {
|
|
2243
|
-
const target =
|
|
2796
|
+
const target = join5(baseDir, ".claude", "agents", "channel-message-handler.md");
|
|
2244
2797
|
try {
|
|
2245
|
-
|
|
2246
|
-
|
|
2798
|
+
mkdirSync4(dirname3(target), { recursive: true });
|
|
2799
|
+
writeFileSync5(target, content);
|
|
2247
2800
|
} catch {
|
|
2248
2801
|
}
|
|
2249
2802
|
}
|
|
@@ -2258,9 +2811,9 @@ function writeMcpJsonGuarded(codeName, path, config) {
|
|
|
2258
2811
|
return true;
|
|
2259
2812
|
}
|
|
2260
2813
|
function readExistingMcpEnvVar(codeName, serverId, envKey) {
|
|
2261
|
-
const mcpJsonPath =
|
|
2814
|
+
const mcpJsonPath = join5(getAgentDir(codeName), "provision", ".mcp.json");
|
|
2262
2815
|
try {
|
|
2263
|
-
const raw =
|
|
2816
|
+
const raw = readFileSync5(mcpJsonPath, "utf-8");
|
|
2264
2817
|
const config = JSON.parse(raw);
|
|
2265
2818
|
const server = config.mcpServers?.[serverId];
|
|
2266
2819
|
if (!server || typeof server !== "object")
|
|
@@ -2306,7 +2859,7 @@ function ensureWorkspaceTrusted(projectDir) {
|
|
|
2306
2859
|
return;
|
|
2307
2860
|
}
|
|
2308
2861
|
if (state !== "missing") {
|
|
2309
|
-
const raw =
|
|
2862
|
+
const raw = readFileSync5(configPath, "utf-8");
|
|
2310
2863
|
if (raw.trim()) {
|
|
2311
2864
|
config = JSON.parse(raw);
|
|
2312
2865
|
}
|
|
@@ -2318,10 +2871,10 @@ function ensureWorkspaceTrusted(projectDir) {
|
|
|
2318
2871
|
entry["hasTrustDialogAccepted"] = true;
|
|
2319
2872
|
projects[projectDir] = entry;
|
|
2320
2873
|
config["projects"] = projects;
|
|
2321
|
-
|
|
2874
|
+
mkdirSync4(dirname3(configPath), { recursive: true });
|
|
2322
2875
|
const tmpPath = `${configPath}.agt-${process.pid}.tmp`;
|
|
2323
2876
|
try {
|
|
2324
|
-
|
|
2877
|
+
writeFileSync5(tmpPath, `${JSON.stringify(config, null, 2)}
|
|
2325
2878
|
`, {
|
|
2326
2879
|
mode: 384,
|
|
2327
2880
|
flag: "wx"
|
|
@@ -2344,11 +2897,11 @@ function ensureWorkspaceTrusted(projectDir) {
|
|
|
2344
2897
|
}
|
|
2345
2898
|
function deployArtifactsToProject(codeName, provisionDir) {
|
|
2346
2899
|
const projectDir = getProjectDir2(codeName);
|
|
2347
|
-
|
|
2900
|
+
mkdirSync4(projectDir, { recursive: true });
|
|
2348
2901
|
ensureWorkspaceTrusted(projectDir);
|
|
2349
2902
|
try {
|
|
2350
|
-
|
|
2351
|
-
|
|
2903
|
+
mkdirSync4(getScratchDir(codeName), { recursive: true });
|
|
2904
|
+
mkdirSync4(getAgentTmpDir(codeName), { recursive: true });
|
|
2352
2905
|
sweepScratchDir(codeName);
|
|
2353
2906
|
sweepStrandedArtefactTmpDirs();
|
|
2354
2907
|
} catch (err) {
|
|
@@ -2359,42 +2912,42 @@ function deployArtifactsToProject(codeName, provisionDir) {
|
|
|
2359
2912
|
const SKILLS_START = SKILLS_INDEX_SECTION_START;
|
|
2360
2913
|
const SKILLS_END = SKILLS_INDEX_SECTION_END;
|
|
2361
2914
|
for (const file of artifactFiles) {
|
|
2362
|
-
const src =
|
|
2363
|
-
const dest =
|
|
2915
|
+
const src = join5(provisionDir, file);
|
|
2916
|
+
const dest = join5(projectDir, file);
|
|
2364
2917
|
try {
|
|
2365
|
-
const srcContent =
|
|
2918
|
+
const srcContent = readFileSync5(src, "utf-8");
|
|
2366
2919
|
if (file === "CLAUDE.md" && existsSync4(dest)) {
|
|
2367
|
-
const destContent =
|
|
2920
|
+
const destContent = readFileSync5(dest, "utf-8");
|
|
2368
2921
|
const stripIndex = (s) => s.replace(new RegExp(`${SKILLS_START}[\\s\\S]*?${SKILLS_END}`), "").trimEnd();
|
|
2369
2922
|
if (stripIndex(srcContent) === stripIndex(destContent))
|
|
2370
2923
|
continue;
|
|
2371
2924
|
const indexMatch = destContent.match(new RegExp(`${SKILLS_START}[\\s\\S]*?${SKILLS_END}`));
|
|
2372
2925
|
if (indexMatch) {
|
|
2373
|
-
|
|
2926
|
+
writeFileSync5(dest, srcContent.trimEnd() + "\n\n" + indexMatch[0] + "\n");
|
|
2374
2927
|
continue;
|
|
2375
2928
|
}
|
|
2376
2929
|
}
|
|
2377
2930
|
if (file === ".mcp.json") {
|
|
2378
|
-
|
|
2931
|
+
writeFileSync5(dest, srcContent, { mode: MCP_FILE_MODE });
|
|
2379
2932
|
try {
|
|
2380
2933
|
chmodSync4(dest, MCP_FILE_MODE);
|
|
2381
2934
|
} catch {
|
|
2382
2935
|
}
|
|
2383
2936
|
} else {
|
|
2384
|
-
|
|
2937
|
+
writeFileSync5(dest, srcContent);
|
|
2385
2938
|
}
|
|
2386
2939
|
} catch {
|
|
2387
2940
|
}
|
|
2388
2941
|
}
|
|
2389
|
-
const skillsDir =
|
|
2390
|
-
const destSkillsDir =
|
|
2942
|
+
const skillsDir = join5(provisionDir, ".claude", "skills");
|
|
2943
|
+
const destSkillsDir = join5(projectDir, ".claude", "skills");
|
|
2391
2944
|
try {
|
|
2392
2945
|
if (existsSync4(destSkillsDir)) {
|
|
2393
2946
|
const srcFolders = existsSync4(skillsDir) ? new Set(readdirSync(skillsDir)) : /* @__PURE__ */ new Set();
|
|
2394
2947
|
for (const folder of readdirSync(destSkillsDir)) {
|
|
2395
2948
|
if (folder.startsWith("knowledge-") || folder === "core-knowledge" && !srcFolders.has(folder)) {
|
|
2396
2949
|
try {
|
|
2397
|
-
rmSync2(
|
|
2950
|
+
rmSync2(join5(destSkillsDir, folder), { recursive: true });
|
|
2398
2951
|
} catch {
|
|
2399
2952
|
}
|
|
2400
2953
|
}
|
|
@@ -2402,25 +2955,25 @@ function deployArtifactsToProject(codeName, provisionDir) {
|
|
|
2402
2955
|
}
|
|
2403
2956
|
if (existsSync4(skillsDir)) {
|
|
2404
2957
|
for (const skillFolder of readdirSync(skillsDir)) {
|
|
2405
|
-
const srcSkillFile =
|
|
2958
|
+
const srcSkillFile = join5(skillsDir, skillFolder, "SKILL.md");
|
|
2406
2959
|
if (!existsSync4(srcSkillFile))
|
|
2407
2960
|
continue;
|
|
2408
|
-
const destFolder =
|
|
2409
|
-
const destFile =
|
|
2410
|
-
const srcContent =
|
|
2961
|
+
const destFolder = join5(destSkillsDir, skillFolder);
|
|
2962
|
+
const destFile = join5(destFolder, "SKILL.md");
|
|
2963
|
+
const srcContent = readFileSync5(srcSkillFile, "utf-8");
|
|
2411
2964
|
try {
|
|
2412
|
-
if (existsSync4(destFile) &&
|
|
2965
|
+
if (existsSync4(destFile) && readFileSync5(destFile, "utf-8") === srcContent)
|
|
2413
2966
|
continue;
|
|
2414
2967
|
} catch {
|
|
2415
2968
|
}
|
|
2416
|
-
|
|
2417
|
-
|
|
2969
|
+
mkdirSync4(destFolder, { recursive: true });
|
|
2970
|
+
writeFileSync5(destFile, srcContent);
|
|
2418
2971
|
}
|
|
2419
2972
|
}
|
|
2420
2973
|
} catch {
|
|
2421
2974
|
}
|
|
2422
|
-
const agentsDir =
|
|
2423
|
-
const destAgentsDir =
|
|
2975
|
+
const agentsDir = join5(provisionDir, ".claude", "agents");
|
|
2976
|
+
const destAgentsDir = join5(projectDir, ".claude", "agents");
|
|
2424
2977
|
try {
|
|
2425
2978
|
if (existsSync4(agentsDir)) {
|
|
2426
2979
|
const sourceAgentFiles = new Set(readdirSync(agentsDir).filter((f) => f.endsWith(".md")));
|
|
@@ -2431,28 +2984,28 @@ function deployArtifactsToProject(codeName, provisionDir) {
|
|
|
2431
2984
|
if (sourceAgentFiles.has(destFile))
|
|
2432
2985
|
continue;
|
|
2433
2986
|
try {
|
|
2434
|
-
rmSync2(
|
|
2987
|
+
rmSync2(join5(destAgentsDir, destFile));
|
|
2435
2988
|
} catch {
|
|
2436
2989
|
}
|
|
2437
2990
|
}
|
|
2438
2991
|
}
|
|
2439
2992
|
for (const agentFile of sourceAgentFiles) {
|
|
2440
|
-
const srcPath =
|
|
2441
|
-
const destPath =
|
|
2442
|
-
const srcContent =
|
|
2993
|
+
const srcPath = join5(agentsDir, agentFile);
|
|
2994
|
+
const destPath = join5(destAgentsDir, agentFile);
|
|
2995
|
+
const srcContent = readFileSync5(srcPath, "utf-8");
|
|
2443
2996
|
try {
|
|
2444
|
-
if (existsSync4(destPath) &&
|
|
2997
|
+
if (existsSync4(destPath) && readFileSync5(destPath, "utf-8") === srcContent)
|
|
2445
2998
|
continue;
|
|
2446
2999
|
} catch {
|
|
2447
3000
|
}
|
|
2448
|
-
|
|
2449
|
-
|
|
3001
|
+
mkdirSync4(destAgentsDir, { recursive: true });
|
|
3002
|
+
writeFileSync5(destPath, srcContent);
|
|
2450
3003
|
}
|
|
2451
3004
|
}
|
|
2452
3005
|
} catch {
|
|
2453
3006
|
}
|
|
2454
|
-
const workflowsDir =
|
|
2455
|
-
const destWorkflowsDir =
|
|
3007
|
+
const workflowsDir = join5(provisionDir, ".claude", "workflows");
|
|
3008
|
+
const destWorkflowsDir = join5(projectDir, ".claude", "workflows");
|
|
2456
3009
|
try {
|
|
2457
3010
|
const sourceWorkflowFiles = existsSync4(workflowsDir) ? new Set(readdirSync(workflowsDir).filter((f) => f.endsWith(".js"))) : /* @__PURE__ */ new Set();
|
|
2458
3011
|
if (existsSync4(destWorkflowsDir)) {
|
|
@@ -2462,32 +3015,32 @@ function deployArtifactsToProject(codeName, provisionDir) {
|
|
|
2462
3015
|
if (sourceWorkflowFiles.has(destFile))
|
|
2463
3016
|
continue;
|
|
2464
3017
|
try {
|
|
2465
|
-
rmSync2(
|
|
3018
|
+
rmSync2(join5(destWorkflowsDir, destFile));
|
|
2466
3019
|
} catch {
|
|
2467
3020
|
}
|
|
2468
3021
|
}
|
|
2469
3022
|
}
|
|
2470
3023
|
for (const workflowFile of sourceWorkflowFiles) {
|
|
2471
|
-
const srcPath =
|
|
2472
|
-
const destPath =
|
|
2473
|
-
const srcContent =
|
|
3024
|
+
const srcPath = join5(workflowsDir, workflowFile);
|
|
3025
|
+
const destPath = join5(destWorkflowsDir, workflowFile);
|
|
3026
|
+
const srcContent = readFileSync5(srcPath, "utf-8");
|
|
2474
3027
|
try {
|
|
2475
|
-
if (existsSync4(destPath) &&
|
|
3028
|
+
if (existsSync4(destPath) && readFileSync5(destPath, "utf-8") === srcContent)
|
|
2476
3029
|
continue;
|
|
2477
3030
|
} catch {
|
|
2478
3031
|
}
|
|
2479
|
-
|
|
2480
|
-
|
|
3032
|
+
mkdirSync4(destWorkflowsDir, { recursive: true });
|
|
3033
|
+
writeFileSync5(destPath, srcContent);
|
|
2481
3034
|
}
|
|
2482
3035
|
} catch {
|
|
2483
3036
|
}
|
|
2484
|
-
const agentMcpPath =
|
|
2485
|
-
const projectMcpPath =
|
|
3037
|
+
const agentMcpPath = join5(getAgentDir(codeName), "provision", ".mcp.json");
|
|
3038
|
+
const projectMcpPath = join5(projectDir, ".mcp.json");
|
|
2486
3039
|
try {
|
|
2487
|
-
const agentMcp = JSON.parse(
|
|
3040
|
+
const agentMcp = JSON.parse(readFileSync5(agentMcpPath, "utf-8"));
|
|
2488
3041
|
let projectMcp;
|
|
2489
3042
|
try {
|
|
2490
|
-
projectMcp = JSON.parse(
|
|
3043
|
+
projectMcp = JSON.parse(readFileSync5(projectMcpPath, "utf-8"));
|
|
2491
3044
|
} catch {
|
|
2492
3045
|
projectMcp = { mcpServers: {} };
|
|
2493
3046
|
}
|
|
@@ -2498,7 +3051,7 @@ function deployArtifactsToProject(codeName, provisionDir) {
|
|
|
2498
3051
|
return !(entry && typeof entry["url"] === "string" && entry["url"].startsWith("/"));
|
|
2499
3052
|
}));
|
|
2500
3053
|
projectMcp["mcpServers"] = { ...stripRelativeUrls(projectServers), ...stripRelativeUrls(agentServers) };
|
|
2501
|
-
|
|
3054
|
+
writeFileSync5(projectMcpPath, JSON.stringify(projectMcp, null, 2), { mode: MCP_FILE_MODE });
|
|
2502
3055
|
try {
|
|
2503
3056
|
chmodSync4(projectMcpPath, MCP_FILE_MODE);
|
|
2504
3057
|
} catch {
|
|
@@ -2508,9 +3061,9 @@ function deployArtifactsToProject(codeName, provisionDir) {
|
|
|
2508
3061
|
const agentDir = getAgentDir(codeName);
|
|
2509
3062
|
for (const envFile of [".env", ".env.integrations"]) {
|
|
2510
3063
|
try {
|
|
2511
|
-
const content =
|
|
2512
|
-
const envDest =
|
|
2513
|
-
|
|
3064
|
+
const content = readFileSync5(join5(agentDir, envFile), "utf-8");
|
|
3065
|
+
const envDest = join5(projectDir, envFile);
|
|
3066
|
+
writeFileSync5(envDest, content, { mode: SECRET_FILE_MODE });
|
|
2514
3067
|
try {
|
|
2515
3068
|
chmodSync4(envDest, SECRET_FILE_MODE);
|
|
2516
3069
|
} catch {
|
|
@@ -2519,16 +3072,16 @@ function deployArtifactsToProject(codeName, provisionDir) {
|
|
|
2519
3072
|
}
|
|
2520
3073
|
}
|
|
2521
3074
|
try {
|
|
2522
|
-
const gitDir =
|
|
2523
|
-
const hookSrc =
|
|
3075
|
+
const gitDir = join5(projectDir, ".git");
|
|
3076
|
+
const hookSrc = join5(provisionDir, ".git-hooks", "pre-commit");
|
|
2524
3077
|
if (existsSync4(gitDir) && existsSync4(hookSrc)) {
|
|
2525
|
-
const hooksDir =
|
|
2526
|
-
|
|
2527
|
-
const hookDest =
|
|
2528
|
-
const srcContent =
|
|
2529
|
-
const upToDate = existsSync4(hookDest) &&
|
|
3078
|
+
const hooksDir = join5(gitDir, "hooks");
|
|
3079
|
+
mkdirSync4(hooksDir, { recursive: true });
|
|
3080
|
+
const hookDest = join5(hooksDir, "pre-commit");
|
|
3081
|
+
const srcContent = readFileSync5(hookSrc, "utf-8");
|
|
3082
|
+
const upToDate = existsSync4(hookDest) && readFileSync5(hookDest, "utf-8") === srcContent;
|
|
2530
3083
|
if (!upToDate)
|
|
2531
|
-
|
|
3084
|
+
writeFileSync5(hookDest, srcContent);
|
|
2532
3085
|
chmodSync4(hookDest, 493);
|
|
2533
3086
|
}
|
|
2534
3087
|
} catch {
|
|
@@ -2536,9 +3089,9 @@ function deployArtifactsToProject(codeName, provisionDir) {
|
|
|
2536
3089
|
}
|
|
2537
3090
|
function provisionStopHook(codeName) {
|
|
2538
3091
|
const projectDir = getProjectDir2(codeName);
|
|
2539
|
-
const claudeDir =
|
|
2540
|
-
|
|
2541
|
-
const hookScriptPath =
|
|
3092
|
+
const claudeDir = join5(projectDir, ".claude");
|
|
3093
|
+
mkdirSync4(claudeDir, { recursive: true });
|
|
3094
|
+
const hookScriptPath = join5(claudeDir, "agt-stop-hook.sh");
|
|
2542
3095
|
const hookScript = [
|
|
2543
3096
|
"#!/bin/bash",
|
|
2544
3097
|
"# Auto-generated by Augmented \u2014 captures persistent session task results.",
|
|
@@ -2582,8 +3135,8 @@ function provisionStopHook(codeName) {
|
|
|
2582
3135
|
"esac",
|
|
2583
3136
|
"exit 0"
|
|
2584
3137
|
].join("\n") + "\n";
|
|
2585
|
-
|
|
2586
|
-
const ghostHookPath =
|
|
3138
|
+
writeFileSync5(hookScriptPath, hookScript, { mode: 493 });
|
|
3139
|
+
const ghostHookPath = join5(claudeDir, "agt-ghost-reply-hook.sh");
|
|
2587
3140
|
const jqNormalizeContent = '(.message.content // .content // []) | if type == "string" then [{type: "text", text: .}] elif type == "array" then . else [] end';
|
|
2588
3141
|
const ghostHookScript = [
|
|
2589
3142
|
"#!/bin/bash",
|
|
@@ -3470,12 +4023,12 @@ function provisionStopHook(codeName) {
|
|
|
3470
4023
|
"fi",
|
|
3471
4024
|
"exit 0"
|
|
3472
4025
|
].join("\n") + "\n";
|
|
3473
|
-
|
|
4026
|
+
writeFileSync5(ghostHookPath, ghostHookScript, { mode: 493 });
|
|
3474
4027
|
const backlogHookPath = provisionBacklogPullHook(codeName);
|
|
3475
|
-
const settingsPath =
|
|
4028
|
+
const settingsPath = join5(claudeDir, "settings.local.json");
|
|
3476
4029
|
let settings = {};
|
|
3477
4030
|
try {
|
|
3478
|
-
settings = JSON.parse(
|
|
4031
|
+
settings = JSON.parse(readFileSync5(settingsPath, "utf-8"));
|
|
3479
4032
|
} catch {
|
|
3480
4033
|
}
|
|
3481
4034
|
const hooks = settings["hooks"] ?? {};
|
|
@@ -3489,29 +4042,29 @@ function provisionStopHook(codeName) {
|
|
|
3489
4042
|
}
|
|
3490
4043
|
];
|
|
3491
4044
|
settings["hooks"] = hooks;
|
|
3492
|
-
|
|
4045
|
+
writeFileSync5(settingsPath, JSON.stringify(settings, null, 2));
|
|
3493
4046
|
}
|
|
3494
4047
|
function provisionIsolationHook(codeName, agentId) {
|
|
3495
4048
|
const homeDir = getHomeDir();
|
|
3496
|
-
const augmentedBase =
|
|
4049
|
+
const augmentedBase = join5(homeDir, ".augmented");
|
|
3497
4050
|
if (/["'$`\\\n]/.test(augmentedBase)) {
|
|
3498
4051
|
throw new Error(`provisionIsolationHook: home directory contains shell metacharacters: ${JSON.stringify(augmentedBase)}`);
|
|
3499
4052
|
}
|
|
3500
4053
|
const projectDir = getProjectDir2(codeName);
|
|
3501
|
-
const claudeDir =
|
|
3502
|
-
|
|
4054
|
+
const claudeDir = join5(projectDir, ".claude");
|
|
4055
|
+
mkdirSync4(claudeDir, { recursive: true });
|
|
3503
4056
|
const hasAgentId = agentId !== void 0;
|
|
3504
4057
|
if (hasAgentId)
|
|
3505
4058
|
assertValidAgentId(agentId);
|
|
3506
4059
|
const augmentedBaseRe = augmentedBase.replace(/[.[\]()*+?{}|^$]/g, "\\$&");
|
|
3507
|
-
const claudeProjectsBase =
|
|
4060
|
+
const claudeProjectsBase = join5(homeDir, ".claude", "projects");
|
|
3508
4061
|
const claudeProjectsBaseRe = claudeProjectsBase.replace(/[.[\]()*+?{}|^$]/g, "\\$&");
|
|
3509
4062
|
const mangledBase = augmentedBase.replace(/[^a-zA-Z0-9]/g, "-");
|
|
3510
4063
|
const ownAgentDir = getAgentDir(codeName);
|
|
3511
|
-
const logFile =
|
|
4064
|
+
const logFile = join5(ownAgentDir, "isolation.log");
|
|
3512
4065
|
const idAllowClause = hasAgentId ? ` && [ "$AGENT_DIR" != "${agentId}" ]` : "";
|
|
3513
4066
|
const idAllowClause2 = hasAgentId ? ` || [ "$OWNER" = "${agentId}" ]` : "";
|
|
3514
|
-
const hookScriptPath =
|
|
4067
|
+
const hookScriptPath = join5(claudeDir, "agt-isolation-hook.sh");
|
|
3515
4068
|
const hookScript = [
|
|
3516
4069
|
"#!/bin/bash",
|
|
3517
4070
|
"# Auto-generated by Augmented.",
|
|
@@ -3786,11 +4339,11 @@ function provisionIsolationHook(codeName, agentId) {
|
|
|
3786
4339
|
"",
|
|
3787
4340
|
"exit 0"
|
|
3788
4341
|
].join("\n") + "\n";
|
|
3789
|
-
|
|
3790
|
-
const settingsPath =
|
|
4342
|
+
writeFileSync5(hookScriptPath, hookScript, { mode: 493 });
|
|
4343
|
+
const settingsPath = join5(claudeDir, "settings.local.json");
|
|
3791
4344
|
let settings = {};
|
|
3792
4345
|
try {
|
|
3793
|
-
settings = JSON.parse(
|
|
4346
|
+
settings = JSON.parse(readFileSync5(settingsPath, "utf-8"));
|
|
3794
4347
|
} catch {
|
|
3795
4348
|
}
|
|
3796
4349
|
const hooks = settings["hooks"] ?? {};
|
|
@@ -3805,13 +4358,13 @@ function provisionIsolationHook(codeName, agentId) {
|
|
|
3805
4358
|
}
|
|
3806
4359
|
];
|
|
3807
4360
|
settings["hooks"] = hooks;
|
|
3808
|
-
|
|
4361
|
+
writeFileSync5(settingsPath, JSON.stringify(settings, null, 2));
|
|
3809
4362
|
}
|
|
3810
4363
|
function provisionBacklogPullHook(codeName) {
|
|
3811
4364
|
const projectDir = getProjectDir2(codeName);
|
|
3812
|
-
const claudeDir =
|
|
3813
|
-
|
|
3814
|
-
const hookScriptPath =
|
|
4365
|
+
const claudeDir = join5(projectDir, ".claude");
|
|
4366
|
+
mkdirSync4(claudeDir, { recursive: true });
|
|
4367
|
+
const hookScriptPath = join5(claudeDir, "agt-backlog-pull-hook.sh");
|
|
3815
4368
|
const hookScript = `#!/usr/bin/env bash
|
|
3816
4369
|
# Auto-generated by Augmented (CS-1549) \u2014 Stop hook: don't end a turn idle
|
|
3817
4370
|
# beside a non-empty backlog. Fail-open on every path; blocks at most once per
|
|
@@ -3982,14 +4535,14 @@ If you genuinely should not pull it, say so in one line and why (it is deliberat
|
|
|
3982
4535
|
jq -cn --arg r "$REASON" '{decision:"block", reason:$r}'
|
|
3983
4536
|
exit 0
|
|
3984
4537
|
`;
|
|
3985
|
-
|
|
4538
|
+
writeFileSync5(hookScriptPath, hookScript, { mode: 493 });
|
|
3986
4539
|
return hookScriptPath;
|
|
3987
4540
|
}
|
|
3988
4541
|
function provisionAutoKanbanProgressHook(codeName) {
|
|
3989
4542
|
const projectDir = getProjectDir2(codeName);
|
|
3990
|
-
const claudeDir =
|
|
3991
|
-
|
|
3992
|
-
const hookScriptPath =
|
|
4543
|
+
const claudeDir = join5(projectDir, ".claude");
|
|
4544
|
+
mkdirSync4(claudeDir, { recursive: true });
|
|
4545
|
+
const hookScriptPath = join5(claudeDir, "agt-auto-kanban-progress-hook.sh");
|
|
3993
4546
|
const hookScript = `#!/usr/bin/env bash
|
|
3994
4547
|
# Auto-generated by Augmented (ENG-6179 / ENG-6241) \u2014 PostToolUse auto-progress.
|
|
3995
4548
|
# Maps the agent's latest tool action onto its active in-thread kanban progress
|
|
@@ -4104,11 +4657,11 @@ BODY="$(jq -nc --arg a "$AGENT_ID" --arg s "$STEP" '{agent_id:$a, step:$s}' 2>/d
|
|
|
4104
4657
|
|
|
4105
4658
|
exit 0
|
|
4106
4659
|
`;
|
|
4107
|
-
|
|
4108
|
-
const settingsPath =
|
|
4660
|
+
writeFileSync5(hookScriptPath, hookScript, { mode: 493 });
|
|
4661
|
+
const settingsPath = join5(claudeDir, "settings.local.json");
|
|
4109
4662
|
let settings = {};
|
|
4110
4663
|
try {
|
|
4111
|
-
settings = JSON.parse(
|
|
4664
|
+
settings = JSON.parse(readFileSync5(settingsPath, "utf-8"));
|
|
4112
4665
|
} catch {
|
|
4113
4666
|
}
|
|
4114
4667
|
const hooks = settings["hooks"] ?? {};
|
|
@@ -4120,13 +4673,13 @@ exit 0
|
|
|
4120
4673
|
}
|
|
4121
4674
|
];
|
|
4122
4675
|
settings["hooks"] = hooks;
|
|
4123
|
-
|
|
4676
|
+
writeFileSync5(settingsPath, JSON.stringify(settings, null, 2));
|
|
4124
4677
|
}
|
|
4125
4678
|
function provisionChannelProgressHook(codeName) {
|
|
4126
4679
|
const projectDir = getProjectDir2(codeName);
|
|
4127
|
-
const claudeDir =
|
|
4128
|
-
|
|
4129
|
-
const hookScriptPath =
|
|
4680
|
+
const claudeDir = join5(projectDir, ".claude");
|
|
4681
|
+
mkdirSync4(claudeDir, { recursive: true });
|
|
4682
|
+
const hookScriptPath = join5(claudeDir, "agt-channel-progress-hook.sh");
|
|
4130
4683
|
const hookScript = `#!/usr/bin/env bash
|
|
4131
4684
|
# Auto-generated by Augmented (ENG-6567 Phase 2) \u2014 PostToolUse channel-progress
|
|
4132
4685
|
# heartbeat. Writes a throttled local {step, updated_at_ms} the channel MCP reads
|
|
@@ -4192,11 +4745,11 @@ else
|
|
|
4192
4745
|
fi
|
|
4193
4746
|
exit 0
|
|
4194
4747
|
`;
|
|
4195
|
-
|
|
4196
|
-
const settingsPath =
|
|
4748
|
+
writeFileSync5(hookScriptPath, hookScript, { mode: 493 });
|
|
4749
|
+
const settingsPath = join5(claudeDir, "settings.local.json");
|
|
4197
4750
|
let settings = {};
|
|
4198
4751
|
try {
|
|
4199
|
-
settings = JSON.parse(
|
|
4752
|
+
settings = JSON.parse(readFileSync5(settingsPath, "utf-8"));
|
|
4200
4753
|
} catch {
|
|
4201
4754
|
}
|
|
4202
4755
|
const hooks = settings["hooks"] ?? {};
|
|
@@ -4212,7 +4765,7 @@ exit 0
|
|
|
4212
4765
|
}
|
|
4213
4766
|
hooks["PostToolUse"] = groups;
|
|
4214
4767
|
settings["hooks"] = hooks;
|
|
4215
|
-
|
|
4768
|
+
writeFileSync5(settingsPath, JSON.stringify(settings, null, 2));
|
|
4216
4769
|
}
|
|
4217
4770
|
var LONG_COMMAND_BOUNDED_TIMEOUT_MS = 12e4;
|
|
4218
4771
|
var LONG_COMMAND_HOOK_FILENAME = "agt-long-command-hook.sh";
|
|
@@ -4576,13 +5129,16 @@ function classifyCommand(words0, loop, depth) {
|
|
|
4576
5129
|
}
|
|
4577
5130
|
`;
|
|
4578
5131
|
var LONG_COMMAND_MAX_FOREGROUND_TIMEOUT_MS = 18e4;
|
|
5132
|
+
function provisionRootRmHook(codeName) {
|
|
5133
|
+
provisionRootRmHookAt(join5(getProjectDir2(codeName), ".claude"));
|
|
5134
|
+
}
|
|
4579
5135
|
function provisionLongCommandHook(codeName) {
|
|
4580
5136
|
const projectDir = getProjectDir2(codeName);
|
|
4581
|
-
const claudeDir =
|
|
4582
|
-
|
|
4583
|
-
const hookScriptPath =
|
|
4584
|
-
const jsPath =
|
|
4585
|
-
|
|
5137
|
+
const claudeDir = join5(projectDir, ".claude");
|
|
5138
|
+
mkdirSync4(claudeDir, { recursive: true });
|
|
5139
|
+
const hookScriptPath = join5(claudeDir, LONG_COMMAND_HOOK_FILENAME);
|
|
5140
|
+
const jsPath = join5(claudeDir, LONG_COMMAND_HOOK_JS_FILENAME);
|
|
5141
|
+
writeFileSync5(jsPath, LONG_COMMAND_HOOK_JS.replace("__BOUND__", String(LONG_COMMAND_BOUNDED_TIMEOUT_MS)), { mode: 420 });
|
|
4586
5142
|
const hookScript = [
|
|
4587
5143
|
"#!/usr/bin/env bash",
|
|
4588
5144
|
"# ENG-11393: refuse known-slow foreground shell commands; see index.ts.",
|
|
@@ -4590,11 +5146,11 @@ function provisionLongCommandHook(codeName) {
|
|
|
4590
5146
|
"command -v node >/dev/null 2>&1 || exit 0",
|
|
4591
5147
|
`exec node '${jsPath.replace(/'/g, `'\\''`)}'`
|
|
4592
5148
|
].join("\n") + "\n";
|
|
4593
|
-
|
|
4594
|
-
const settingsPath =
|
|
5149
|
+
writeFileSync5(hookScriptPath, hookScript, { mode: 493 });
|
|
5150
|
+
const settingsPath = join5(claudeDir, "settings.local.json");
|
|
4595
5151
|
let settings = {};
|
|
4596
5152
|
try {
|
|
4597
|
-
settings = JSON.parse(
|
|
5153
|
+
settings = JSON.parse(readFileSync5(settingsPath, "utf-8"));
|
|
4598
5154
|
} catch {
|
|
4599
5155
|
}
|
|
4600
5156
|
const hooks = settings["hooks"] ?? {};
|
|
@@ -4608,15 +5164,15 @@ function provisionLongCommandHook(codeName) {
|
|
|
4608
5164
|
const env = settings["env"] ?? {};
|
|
4609
5165
|
env["BASH_MAX_TIMEOUT_MS"] = String(LONG_COMMAND_MAX_FOREGROUND_TIMEOUT_MS);
|
|
4610
5166
|
settings["env"] = env;
|
|
4611
|
-
|
|
5167
|
+
writeFileSync5(settingsPath, JSON.stringify(settings, null, 2));
|
|
4612
5168
|
}
|
|
4613
5169
|
function provisionOrientHook(codeName) {
|
|
4614
5170
|
const projectDir = getProjectDir2(codeName);
|
|
4615
|
-
const claudeDir =
|
|
4616
|
-
|
|
5171
|
+
const claudeDir = join5(projectDir, ".claude");
|
|
5172
|
+
mkdirSync4(claudeDir, { recursive: true });
|
|
4617
5173
|
const agentDir = getAgentDir(codeName);
|
|
4618
|
-
const codeRoots = [
|
|
4619
|
-
const hookScriptPath =
|
|
5174
|
+
const codeRoots = [join5(getHomeDir(), "code"), join5(agentDir, "code")];
|
|
5175
|
+
const hookScriptPath = join5(claudeDir, "agt-orient-hook.sh");
|
|
4620
5176
|
const hookScript = [
|
|
4621
5177
|
"#!/bin/bash",
|
|
4622
5178
|
"# Auto-generated by Augmented (ENG-5397) \u2014 SessionStart orientation hook.",
|
|
@@ -4888,11 +5444,11 @@ function provisionOrientHook(codeName) {
|
|
|
4888
5444
|
"fi",
|
|
4889
5445
|
"exit 0"
|
|
4890
5446
|
].join("\n") + "\n";
|
|
4891
|
-
|
|
4892
|
-
const settingsPath =
|
|
5447
|
+
writeFileSync5(hookScriptPath, hookScript, { mode: 493 });
|
|
5448
|
+
const settingsPath = join5(claudeDir, "settings.local.json");
|
|
4893
5449
|
let settings = {};
|
|
4894
5450
|
try {
|
|
4895
|
-
settings = JSON.parse(
|
|
5451
|
+
settings = JSON.parse(readFileSync5(settingsPath, "utf-8"));
|
|
4896
5452
|
} catch {
|
|
4897
5453
|
}
|
|
4898
5454
|
const hooks = settings["hooks"] ?? {};
|
|
@@ -4912,15 +5468,15 @@ function provisionOrientHook(codeName) {
|
|
|
4912
5468
|
}
|
|
4913
5469
|
hooks["SessionStart"] = existingSessionStart;
|
|
4914
5470
|
settings["hooks"] = hooks;
|
|
4915
|
-
|
|
5471
|
+
writeFileSync5(settingsPath, JSON.stringify(settings, null, 2));
|
|
4916
5472
|
}
|
|
4917
5473
|
function provisionPreCompactHook(codeName) {
|
|
4918
5474
|
const projectDir = getProjectDir2(codeName);
|
|
4919
|
-
const claudeDir =
|
|
4920
|
-
|
|
5475
|
+
const claudeDir = join5(projectDir, ".claude");
|
|
5476
|
+
mkdirSync4(claudeDir, { recursive: true });
|
|
4921
5477
|
const agentDir = getAgentDir(codeName);
|
|
4922
5478
|
const jqNormalizeContent = '(.message.content // .content // []) | if type == "string" then [{type: "text", text: .}] elif type == "array" then . else [] end';
|
|
4923
|
-
const hookScriptPath =
|
|
5479
|
+
const hookScriptPath = join5(claudeDir, "agt-pre-compact-hook.sh");
|
|
4924
5480
|
const hookScript = [
|
|
4925
5481
|
"#!/bin/bash",
|
|
4926
5482
|
"# Auto-generated by Augmented (ENG-7339) - PreCompact courtesy notice.",
|
|
@@ -5024,12 +5580,12 @@ function provisionPreCompactHook(codeName) {
|
|
|
5024
5580
|
'if [ "$WROTE" = "1" ]; then date +%s > "$NOTICE_MARKER" 2>/dev/null || true; fi',
|
|
5025
5581
|
"exit 0"
|
|
5026
5582
|
].join("\n") + "\n";
|
|
5027
|
-
|
|
5583
|
+
writeFileSync5(hookScriptPath, hookScript, { mode: 493 });
|
|
5028
5584
|
chmodSync4(hookScriptPath, 493);
|
|
5029
|
-
const settingsPath =
|
|
5585
|
+
const settingsPath = join5(claudeDir, "settings.local.json");
|
|
5030
5586
|
let settings = {};
|
|
5031
5587
|
try {
|
|
5032
|
-
settings = JSON.parse(
|
|
5588
|
+
settings = JSON.parse(readFileSync5(settingsPath, "utf-8"));
|
|
5033
5589
|
} catch {
|
|
5034
5590
|
}
|
|
5035
5591
|
const hooks = settings["hooks"] ?? {};
|
|
@@ -5049,14 +5605,14 @@ function provisionPreCompactHook(codeName) {
|
|
|
5049
5605
|
}
|
|
5050
5606
|
hooks["PreCompact"] = existingPreCompact;
|
|
5051
5607
|
settings["hooks"] = hooks;
|
|
5052
|
-
|
|
5608
|
+
writeFileSync5(settingsPath, JSON.stringify(settings, null, 2));
|
|
5053
5609
|
}
|
|
5054
5610
|
function provisionSessionStateHook(codeName) {
|
|
5055
5611
|
const projectDir = getProjectDir2(codeName);
|
|
5056
|
-
const claudeDir =
|
|
5057
|
-
|
|
5612
|
+
const claudeDir = join5(projectDir, ".claude");
|
|
5613
|
+
mkdirSync4(claudeDir, { recursive: true });
|
|
5058
5614
|
const agentDir = getAgentDir(codeName);
|
|
5059
|
-
const hookScriptPath =
|
|
5615
|
+
const hookScriptPath = join5(claudeDir, "agt-session-state-hook.sh");
|
|
5060
5616
|
const hookScript = `#!/usr/bin/env bash
|
|
5061
5617
|
# Auto-generated by Augmented (ENG-6233 / ENG-6268) \u2014 SessionStart session-state
|
|
5062
5618
|
# recorder. Writes the model + session origin (which only the agent's own
|
|
@@ -5133,11 +5689,11 @@ fi
|
|
|
5133
5689
|
|
|
5134
5690
|
exit 0
|
|
5135
5691
|
`;
|
|
5136
|
-
|
|
5137
|
-
const settingsPath =
|
|
5692
|
+
writeFileSync5(hookScriptPath, hookScript, { mode: 493 });
|
|
5693
|
+
const settingsPath = join5(claudeDir, "settings.local.json");
|
|
5138
5694
|
let settings = {};
|
|
5139
5695
|
try {
|
|
5140
|
-
settings = JSON.parse(
|
|
5696
|
+
settings = JSON.parse(readFileSync5(settingsPath, "utf-8"));
|
|
5141
5697
|
} catch {
|
|
5142
5698
|
}
|
|
5143
5699
|
const hooks = settings["hooks"] ?? {};
|
|
@@ -5153,13 +5709,13 @@ exit 0
|
|
|
5153
5709
|
}
|
|
5154
5710
|
hooks["SessionStart"] = existingSessionStart;
|
|
5155
5711
|
settings["hooks"] = hooks;
|
|
5156
|
-
|
|
5712
|
+
writeFileSync5(settingsPath, JSON.stringify(settings, null, 2));
|
|
5157
5713
|
}
|
|
5158
5714
|
function modifyJsonConfig(filePath, fn) {
|
|
5159
5715
|
let originalContent;
|
|
5160
5716
|
let config;
|
|
5161
5717
|
try {
|
|
5162
|
-
originalContent =
|
|
5718
|
+
originalContent = readFileSync5(filePath, "utf-8");
|
|
5163
5719
|
config = JSON.parse(originalContent);
|
|
5164
5720
|
} catch {
|
|
5165
5721
|
return;
|
|
@@ -5170,7 +5726,7 @@ function modifyJsonConfig(filePath, fn) {
|
|
|
5170
5726
|
const newContent = JSON.stringify(config, null, 2);
|
|
5171
5727
|
if (newContent === originalContent)
|
|
5172
5728
|
return;
|
|
5173
|
-
|
|
5729
|
+
writeFileSync5(filePath, newContent);
|
|
5174
5730
|
}
|
|
5175
5731
|
var SUBAGENT_BUILTIN_TOOLS = [
|
|
5176
5732
|
"Bash",
|
|
@@ -5256,7 +5812,7 @@ function buildSettingsJson(input) {
|
|
|
5256
5812
|
const projectDir = getProjectDir2(agent.code_name);
|
|
5257
5813
|
const agentDir = getAgentDir(agent.code_name);
|
|
5258
5814
|
const homeDir = getHomeDir();
|
|
5259
|
-
const codenameAliasDir =
|
|
5815
|
+
const codenameAliasDir = join5(homeDir, ".augmented", agent.code_name);
|
|
5260
5816
|
settings["allowedDirectories"] = [
|
|
5261
5817
|
.../* @__PURE__ */ new Set([
|
|
5262
5818
|
projectDir,
|
|
@@ -5265,7 +5821,7 @@ function buildSettingsJson(input) {
|
|
|
5265
5821
|
// Agent's config dir (.env, schedules, registration)
|
|
5266
5822
|
codenameAliasDir,
|
|
5267
5823
|
// Codename symlink alias (== agentDir for legacy agents)
|
|
5268
|
-
|
|
5824
|
+
join5(homeDir, ".augmented", "_mcp"),
|
|
5269
5825
|
// Shared MCP binaries
|
|
5270
5826
|
"/tmp"
|
|
5271
5827
|
// Temp files
|
|
@@ -5365,10 +5921,10 @@ ${integrationsBlock}`;
|
|
|
5365
5921
|
function renderAugmentedWorkerForAgent(codeName) {
|
|
5366
5922
|
const agentDir = getAgentDir(codeName);
|
|
5367
5923
|
const projectDir = getProjectDir2(codeName);
|
|
5368
|
-
const provisionMcpPath =
|
|
5924
|
+
const provisionMcpPath = join5(agentDir, "provision", ".mcp.json");
|
|
5369
5925
|
let mcpServerKeys;
|
|
5370
5926
|
try {
|
|
5371
|
-
const config = JSON.parse(
|
|
5927
|
+
const config = JSON.parse(readFileSync5(provisionMcpPath, "utf-8"));
|
|
5372
5928
|
mcpServerKeys = Object.keys(config.mcpServers ?? {});
|
|
5373
5929
|
} catch {
|
|
5374
5930
|
return;
|
|
@@ -5376,10 +5932,10 @@ function renderAugmentedWorkerForAgent(codeName) {
|
|
|
5376
5932
|
const integrations = readIntegrationsSummaryForAgent(codeName);
|
|
5377
5933
|
const content = buildAugmentedWorkerAgent({ mcpServerKeys, integrations });
|
|
5378
5934
|
for (const baseDir of [agentDir, projectDir]) {
|
|
5379
|
-
const target =
|
|
5935
|
+
const target = join5(baseDir, ".claude", "agents", "augmented-worker.md");
|
|
5380
5936
|
try {
|
|
5381
|
-
|
|
5382
|
-
|
|
5937
|
+
mkdirSync4(dirname3(target), { recursive: true });
|
|
5938
|
+
writeFileSync5(target, content);
|
|
5383
5939
|
} catch {
|
|
5384
5940
|
}
|
|
5385
5941
|
}
|
|
@@ -5405,8 +5961,8 @@ function buildPostizMcpEntry(integration) {
|
|
|
5405
5961
|
}
|
|
5406
5962
|
function buildMcpJson(input) {
|
|
5407
5963
|
const mcpServers = {};
|
|
5408
|
-
const turnInitiatorFile =
|
|
5409
|
-
const localMcpPath =
|
|
5964
|
+
const turnInitiatorFile = join5(getAgentDir(input.agent.code_name), ".current-turn-initiator.json");
|
|
5965
|
+
const localMcpPath = join5(getHomeDir(), ".augmented", "_mcp", "index.js");
|
|
5410
5966
|
mcpServers["augmented"] = {
|
|
5411
5967
|
command: "node",
|
|
5412
5968
|
args: [localMcpPath],
|
|
@@ -5459,7 +6015,7 @@ function buildMcpJson(input) {
|
|
|
5459
6015
|
const xeroIntegration = input.integrations?.find((i) => i.definition_id === "xero");
|
|
5460
6016
|
if (xeroIntegration) {
|
|
5461
6017
|
const brokerMode = Boolean(xeroIntegration.id);
|
|
5462
|
-
const localXeroMcpPath =
|
|
6018
|
+
const localXeroMcpPath = join5(getHomeDir(), ".augmented", "_mcp", "xero.js");
|
|
5463
6019
|
mcpServers["xero"] = {
|
|
5464
6020
|
command: "node",
|
|
5465
6021
|
args: [localXeroMcpPath],
|
|
@@ -5499,7 +6055,7 @@ function buildMcpJson(input) {
|
|
|
5499
6055
|
// getProjectDir (the ADR-0049 seam), not the MCP child's inherited
|
|
5500
6056
|
// cwd, so the path stays correct if Claude Code ever spawns the
|
|
5501
6057
|
// server from somewhere else.
|
|
5502
|
-
XERO_EXPORT_DIR:
|
|
6058
|
+
XERO_EXPORT_DIR: join5(getProjectDir2(input.agent.code_name), "xero-exports"),
|
|
5503
6059
|
PATH: process.env["PATH"] ?? "",
|
|
5504
6060
|
HOME: process.env["HOME"] ?? ""
|
|
5505
6061
|
}
|
|
@@ -5510,8 +6066,8 @@ function buildMcpJson(input) {
|
|
|
5510
6066
|
mcpServers["postiz"] = buildPostizMcpEntry(postizIntegration);
|
|
5511
6067
|
}
|
|
5512
6068
|
const remoteOAuthProxyPaths = {
|
|
5513
|
-
proxyPath:
|
|
5514
|
-
tokenFile:
|
|
6069
|
+
proxyPath: join5(getHomeDir(), ".augmented", "_mcp", "remote-oauth-proxy.js"),
|
|
6070
|
+
tokenFile: join5(getProjectDir2(input.agent.code_name), ".env.integrations")
|
|
5515
6071
|
};
|
|
5516
6072
|
for (const integration of input.integrations ?? []) {
|
|
5517
6073
|
const connectionKey = integration.connection_key;
|
|
@@ -5582,7 +6138,7 @@ function buildMcpJson(input) {
|
|
|
5582
6138
|
}
|
|
5583
6139
|
const hasAdminDebug = input.integrations?.some((i) => i.definition_id === "augmented-admin") ?? false;
|
|
5584
6140
|
if (hasAdminDebug) {
|
|
5585
|
-
const localAdminMcpPath =
|
|
6141
|
+
const localAdminMcpPath = join5(getHomeDir(), ".augmented", "_mcp", "augmented-admin.js");
|
|
5586
6142
|
mcpServers["augmented-admin"] = {
|
|
5587
6143
|
command: "node",
|
|
5588
6144
|
args: [localAdminMcpPath],
|
|
@@ -5596,7 +6152,7 @@ function buildMcpJson(input) {
|
|
|
5596
6152
|
}
|
|
5597
6153
|
const hasSupport = input.integrations?.some((i) => i.definition_id === "augmented-support") ?? false;
|
|
5598
6154
|
if (hasSupport) {
|
|
5599
|
-
const localSupportMcpPath =
|
|
6155
|
+
const localSupportMcpPath = join5(getHomeDir(), ".augmented", "_mcp", "augmented-support.js");
|
|
5600
6156
|
mcpServers["augmented-support"] = {
|
|
5601
6157
|
command: "node",
|
|
5602
6158
|
args: [localSupportMcpPath],
|
|
@@ -5610,7 +6166,7 @@ function buildMcpJson(input) {
|
|
|
5610
6166
|
}
|
|
5611
6167
|
const hasHelpKb = input.integrations?.some((i) => i.definition_id === "augmented-help-kb") ?? false;
|
|
5612
6168
|
if (hasHelpKb) {
|
|
5613
|
-
const localHelpKbMcpPath =
|
|
6169
|
+
const localHelpKbMcpPath = join5(getHomeDir(), ".augmented", "_mcp", "augmented-help-kb.js");
|
|
5614
6170
|
mcpServers["augmented-help-kb"] = {
|
|
5615
6171
|
command: "node",
|
|
5616
6172
|
args: [localHelpKbMcpPath],
|
|
@@ -5624,7 +6180,7 @@ function buildMcpJson(input) {
|
|
|
5624
6180
|
}
|
|
5625
6181
|
const origamiIntegration = input.integrations?.find((i) => i.definition_id === "origami");
|
|
5626
6182
|
if (origamiIntegration?.stdioMcp === true && origamiIntegration.id) {
|
|
5627
|
-
const localOrigamiMcpPath =
|
|
6183
|
+
const localOrigamiMcpPath = join5(getHomeDir(), ".augmented", "_mcp", "origami.js");
|
|
5628
6184
|
mcpServers["origami"] = {
|
|
5629
6185
|
command: "node",
|
|
5630
6186
|
args: [localOrigamiMcpPath],
|
|
@@ -5643,7 +6199,7 @@ function buildMcpJson(input) {
|
|
|
5643
6199
|
agentId: input.agent.agent_id,
|
|
5644
6200
|
agentCodeName: input.agent.code_name,
|
|
5645
6201
|
config: computerUseIntegration.config,
|
|
5646
|
-
proxyPath:
|
|
6202
|
+
proxyPath: join5(getHomeDir(), ".augmented", "_mcp", "computer-use-proxy.js"),
|
|
5647
6203
|
agentDir: getAgentDir(input.agent.code_name)
|
|
5648
6204
|
});
|
|
5649
6205
|
if (rendered.entry) {
|
|
@@ -5844,6 +6400,8 @@ var claudeCodeAdapter = {
|
|
|
5844
6400
|
content: JSON.stringify(integrationSummaries, null, 2)
|
|
5845
6401
|
}
|
|
5846
6402
|
];
|
|
6403
|
+
const rmPolicy = rmPolicyFromGuardrails(input.guardrails) ?? RM_POLICY_UNKNOWN;
|
|
6404
|
+
artifacts.push({ relativePath: RM_POLICY_ARTIFACT, content: JSON.stringify(rmPolicy, null, 2) });
|
|
5847
6405
|
const knowledgeEntries = input.knowledge ?? [];
|
|
5848
6406
|
const delivery = input.knowledgeDelivery ?? "both";
|
|
5849
6407
|
const includeFiles = delivery === "files" || delivery === "both";
|
|
@@ -5889,14 +6447,14 @@ ${sections}`
|
|
|
5889
6447
|
},
|
|
5890
6448
|
async getRegisteredAgents(_profile) {
|
|
5891
6449
|
const homeDir = getHomeDir();
|
|
5892
|
-
const augDir =
|
|
6450
|
+
const augDir = join5(homeDir, ".augmented");
|
|
5893
6451
|
const agents = /* @__PURE__ */ new Set();
|
|
5894
6452
|
try {
|
|
5895
6453
|
const entries = readdirSync(augDir);
|
|
5896
6454
|
for (const entry of entries) {
|
|
5897
6455
|
if (entry.startsWith("_") || entry.startsWith("."))
|
|
5898
6456
|
continue;
|
|
5899
|
-
const agentRoot =
|
|
6457
|
+
const agentRoot = join5(augDir, entry);
|
|
5900
6458
|
let st;
|
|
5901
6459
|
try {
|
|
5902
6460
|
st = lstatSync(agentRoot);
|
|
@@ -5905,11 +6463,11 @@ ${sections}`
|
|
|
5905
6463
|
}
|
|
5906
6464
|
if (st.isSymbolicLink() || !st.isDirectory())
|
|
5907
6465
|
continue;
|
|
5908
|
-
if (!existsSync4(
|
|
6466
|
+
if (!existsSync4(join5(agentRoot, "registration.json")))
|
|
5909
6467
|
continue;
|
|
5910
6468
|
let codeName = entry;
|
|
5911
6469
|
try {
|
|
5912
|
-
const reg = JSON.parse(
|
|
6470
|
+
const reg = JSON.parse(readFileSync5(join5(agentRoot, "registration.json"), "utf8"));
|
|
5913
6471
|
if (reg && typeof reg.code_name === "string" && reg.code_name) {
|
|
5914
6472
|
codeName = reg.code_name;
|
|
5915
6473
|
}
|
|
@@ -5928,9 +6486,9 @@ ${sections}`
|
|
|
5928
6486
|
}
|
|
5929
6487
|
const agentDir = getAgentDir(codeName);
|
|
5930
6488
|
const projectDir = getProjectDir2(codeName);
|
|
5931
|
-
|
|
5932
|
-
|
|
5933
|
-
|
|
6489
|
+
mkdirSync4(agentDir, { recursive: true });
|
|
6490
|
+
mkdirSync4(projectDir, { recursive: true });
|
|
6491
|
+
writeFileSync5(join5(agentDir, "registration.json"), JSON.stringify({
|
|
5934
6492
|
code_name: codeName,
|
|
5935
6493
|
agent_id: agentId ?? null,
|
|
5936
6494
|
team_dir: teamDir,
|
|
@@ -5949,7 +6507,7 @@ ${sections}`
|
|
|
5949
6507
|
async deregisterAgent(codeName) {
|
|
5950
6508
|
try {
|
|
5951
6509
|
const agentDir = getAgentDir(codeName);
|
|
5952
|
-
const regFile =
|
|
6510
|
+
const regFile = join5(agentDir, "registration.json");
|
|
5953
6511
|
if (existsSync4(regFile)) {
|
|
5954
6512
|
const { unlinkSync: unlinkSync5 } = await import("fs");
|
|
5955
6513
|
unlinkSync5(regFile);
|
|
@@ -5961,7 +6519,7 @@ ${sections}`
|
|
|
5961
6519
|
},
|
|
5962
6520
|
writeAuthProfiles(codeName, profiles) {
|
|
5963
6521
|
const agentDir = getAgentDir(codeName);
|
|
5964
|
-
|
|
6522
|
+
mkdirSync4(agentDir, { recursive: true });
|
|
5965
6523
|
const envLines = ["# Augmented auth profiles \u2014 auto-generated, do not edit"];
|
|
5966
6524
|
for (const p of profiles) {
|
|
5967
6525
|
if (!p.api_key)
|
|
@@ -5975,8 +6533,8 @@ ${sections}`
|
|
|
5975
6533
|
}
|
|
5976
6534
|
}
|
|
5977
6535
|
if (envLines.length > 1) {
|
|
5978
|
-
const envPath =
|
|
5979
|
-
|
|
6536
|
+
const envPath = join5(agentDir, ".env");
|
|
6537
|
+
writeFileSync5(envPath, envLines.join("\n") + "\n");
|
|
5980
6538
|
chmodSync4(envPath, SECRET_FILE_MODE);
|
|
5981
6539
|
}
|
|
5982
6540
|
},
|
|
@@ -6025,7 +6583,7 @@ ${sections}`
|
|
|
6025
6583
|
const senderPolicyInternalOnly = options?.senderPolicy?.internal_only === true;
|
|
6026
6584
|
const senderPolicyEnv = senderPolicyTeamId ? { AGT_TEAM_ID: senderPolicyTeamId } : {};
|
|
6027
6585
|
const agentDir = getAgentDir(codeName);
|
|
6028
|
-
|
|
6586
|
+
mkdirSync4(agentDir, { recursive: true });
|
|
6029
6587
|
const persistChannelSecrets = options?.channelSecretDelivery !== "spawn-env";
|
|
6030
6588
|
const channelSecretUpdates = (updates, fullKeySet) => {
|
|
6031
6589
|
if (persistChannelSecrets)
|
|
@@ -6039,7 +6597,7 @@ ${sections}`
|
|
|
6039
6597
|
if (!botToken)
|
|
6040
6598
|
return missingCredentialField("bot_token");
|
|
6041
6599
|
const allowedChats = config["allowed_chats"];
|
|
6042
|
-
const localTelegramChannel =
|
|
6600
|
+
const localTelegramChannel = join5(getHomeDir(), ".augmented", "_mcp", "telegram-channel.js");
|
|
6043
6601
|
const resolvedAgtHostForTelegram = process.env["AGT_HOST"]?.trim() || "https://api.augmented.team";
|
|
6044
6602
|
const resolvedAgtApiKeyForTelegram = process.env["AGT_API_KEY"]?.trim();
|
|
6045
6603
|
writeEnvIntegrationsForAgent(codeName, {
|
|
@@ -6054,7 +6612,7 @@ ${sections}`
|
|
|
6054
6612
|
...options?.agentId ? { AGT_AGENT_ID: options.agentId } : {},
|
|
6055
6613
|
...tzEnv,
|
|
6056
6614
|
// ENG-6582 (D16): stamp the verified turn initiator for broker MCPs.
|
|
6057
|
-
AGT_TURN_INITIATOR_FILE:
|
|
6615
|
+
AGT_TURN_INITIATOR_FILE: join5(getAgentDir(codeName), ".current-turn-initiator.json")
|
|
6058
6616
|
};
|
|
6059
6617
|
if (allowedChats && allowedChats.length > 0) {
|
|
6060
6618
|
telegramEnv.TELEGRAM_ALLOWED_CHATS = allowedChats.join(",");
|
|
@@ -6129,11 +6687,11 @@ ${sections}`
|
|
|
6129
6687
|
args: [localTelegramChannel],
|
|
6130
6688
|
env: telegramEnv
|
|
6131
6689
|
};
|
|
6132
|
-
const provisionMcpPath =
|
|
6133
|
-
|
|
6690
|
+
const provisionMcpPath = join5(agentDir, "provision", ".mcp.json");
|
|
6691
|
+
mkdirSync4(dirname3(provisionMcpPath), { recursive: true });
|
|
6134
6692
|
let mcpConfig2 = { mcpServers: {} };
|
|
6135
6693
|
try {
|
|
6136
|
-
mcpConfig2 = JSON.parse(
|
|
6694
|
+
mcpConfig2 = JSON.parse(readFileSync5(provisionMcpPath, "utf-8"));
|
|
6137
6695
|
if (!mcpConfig2.mcpServers)
|
|
6138
6696
|
mcpConfig2.mcpServers = {};
|
|
6139
6697
|
} catch {
|
|
@@ -6147,13 +6705,13 @@ ${sections}`
|
|
|
6147
6705
|
}
|
|
6148
6706
|
if (isPersistent && (channelId === "discord" || channelId === "slack")) {
|
|
6149
6707
|
let wrotePersistentCredential = false;
|
|
6150
|
-
const channelDir =
|
|
6708
|
+
const channelDir = join5(getHomeDir(), ".claude", "channels", channelId);
|
|
6151
6709
|
if (channelId === "discord")
|
|
6152
|
-
|
|
6710
|
+
mkdirSync4(channelDir, { recursive: true });
|
|
6153
6711
|
if (channelId === "discord") {
|
|
6154
6712
|
const botToken = config["bot_token"];
|
|
6155
6713
|
if (botToken) {
|
|
6156
|
-
|
|
6714
|
+
writeFileSync5(join5(channelDir, ".env"), `DISCORD_BOT_TOKEN=${botToken}
|
|
6157
6715
|
`);
|
|
6158
6716
|
wrotePersistentCredential = true;
|
|
6159
6717
|
}
|
|
@@ -6217,7 +6775,7 @@ ${sections}`
|
|
|
6217
6775
|
...appToken ? { SLACK_APP_TOKEN: appToken } : {}
|
|
6218
6776
|
}, ["SLACK_BOT_TOKEN", "SLACK_APP_TOKEN"])
|
|
6219
6777
|
});
|
|
6220
|
-
const localSlackChannel =
|
|
6778
|
+
const localSlackChannel = join5(getHomeDir(), ".augmented", "_mcp", "slack-channel.js");
|
|
6221
6779
|
const slackAvatarEnvUrl = resolveAvatarEnvUrl(options?.agentAvatarUrl).url;
|
|
6222
6780
|
const slackEntry = {
|
|
6223
6781
|
command: existsSync4(localSlackChannel) ? "node" : "npx",
|
|
@@ -6312,14 +6870,14 @@ ${sections}`
|
|
|
6312
6870
|
...pingAllowedUsers.length > 0 ? { SLACK_PING_ALLOWED_USERS: pingAllowedUsers.join(",") } : {},
|
|
6313
6871
|
// ENG-6563 (D16): stamp the verified turn initiator so broker MCPs
|
|
6314
6872
|
// can forward it when the agent files an approval mid-turn.
|
|
6315
|
-
AGT_TURN_INITIATOR_FILE:
|
|
6873
|
+
AGT_TURN_INITIATOR_FILE: join5(agentDir, ".current-turn-initiator.json")
|
|
6316
6874
|
}
|
|
6317
6875
|
};
|
|
6318
|
-
const provisionMcpPath =
|
|
6319
|
-
|
|
6876
|
+
const provisionMcpPath = join5(agentDir, "provision", ".mcp.json");
|
|
6877
|
+
mkdirSync4(dirname3(provisionMcpPath), { recursive: true });
|
|
6320
6878
|
let mcpConfig2 = { mcpServers: {} };
|
|
6321
6879
|
try {
|
|
6322
|
-
mcpConfig2 = JSON.parse(
|
|
6880
|
+
mcpConfig2 = JSON.parse(readFileSync5(provisionMcpPath, "utf-8"));
|
|
6323
6881
|
if (!mcpConfig2.mcpServers)
|
|
6324
6882
|
mcpConfig2.mcpServers = {};
|
|
6325
6883
|
} catch {
|
|
@@ -6330,7 +6888,7 @@ ${sections}`
|
|
|
6330
6888
|
}
|
|
6331
6889
|
syncMcpToProject(codeName);
|
|
6332
6890
|
wrotePersistentCredential = true;
|
|
6333
|
-
const staleChannelsPath =
|
|
6891
|
+
const staleChannelsPath = join5(getProjectDir2(codeName), ".mcp-channels.json");
|
|
6334
6892
|
if (existsSync4(staleChannelsPath)) {
|
|
6335
6893
|
try {
|
|
6336
6894
|
rmSync2(staleChannelsPath, { force: true });
|
|
@@ -6344,11 +6902,11 @@ ${sections}`
|
|
|
6344
6902
|
}
|
|
6345
6903
|
return CHANNEL_WRITE_OK;
|
|
6346
6904
|
}
|
|
6347
|
-
const mcpJsonPath =
|
|
6348
|
-
|
|
6905
|
+
const mcpJsonPath = join5(agentDir, "provision", ".mcp.json");
|
|
6906
|
+
mkdirSync4(dirname3(mcpJsonPath), { recursive: true });
|
|
6349
6907
|
let mcpConfig;
|
|
6350
6908
|
try {
|
|
6351
|
-
mcpConfig = JSON.parse(
|
|
6909
|
+
mcpConfig = JSON.parse(readFileSync5(mcpJsonPath, "utf-8"));
|
|
6352
6910
|
} catch {
|
|
6353
6911
|
mcpConfig = { mcpServers: {} };
|
|
6354
6912
|
}
|
|
@@ -6367,7 +6925,7 @@ ${sections}`
|
|
|
6367
6925
|
const appToken = config["app_token"];
|
|
6368
6926
|
if (!botToken)
|
|
6369
6927
|
return missingCredentialField("bot_token");
|
|
6370
|
-
const localSlackChannel =
|
|
6928
|
+
const localSlackChannel = join5(getHomeDir(), ".augmented", "_mcp", "slack-channel.js");
|
|
6371
6929
|
const slackThreadAutoFollow = config["thread_auto_follow"];
|
|
6372
6930
|
const slackAutoFollowEnv = slackThreadAutoFollow && slackThreadAutoFollow !== "off" ? { SLACK_THREAD_AUTO_FOLLOW: slackThreadAutoFollow } : {};
|
|
6373
6931
|
const slackChannelResponseMode = config["channel_response_mode"];
|
|
@@ -6456,7 +7014,7 @@ ${sections}`
|
|
|
6456
7014
|
...slackAgtAuthEnv,
|
|
6457
7015
|
...tzEnv,
|
|
6458
7016
|
// ENG-6563 (D16): stamp the verified turn initiator for broker MCPs.
|
|
6459
|
-
AGT_TURN_INITIATOR_FILE:
|
|
7017
|
+
AGT_TURN_INITIATOR_FILE: join5(getAgentDir(codeName), ".current-turn-initiator.json"),
|
|
6460
7018
|
// ENG-6155: avatar URL → bot Slack profile photo (see persistent
|
|
6461
7019
|
// branch above). Mirrored here so oneshot-mode agents get it too.
|
|
6462
7020
|
// ENG-6245: slackAvatarEnvUrl is null for data-URI / oversized values.
|
|
@@ -6481,7 +7039,7 @@ ${sections}`
|
|
|
6481
7039
|
...slackAgtAuthEnv,
|
|
6482
7040
|
...tzEnv,
|
|
6483
7041
|
// ENG-6563 (D16): stamp the verified turn initiator for broker MCPs.
|
|
6484
|
-
AGT_TURN_INITIATOR_FILE:
|
|
7042
|
+
AGT_TURN_INITIATOR_FILE: join5(getAgentDir(codeName), ".current-turn-initiator.json"),
|
|
6485
7043
|
// ENG-6155: avatar URL → bot Slack profile photo (see persistent
|
|
6486
7044
|
// branch above). Mirrored here so oneshot-mode agents get it too.
|
|
6487
7045
|
// ENG-6245: slackAvatarEnvUrl is null for data-URI / oversized values.
|
|
@@ -6495,12 +7053,12 @@ ${sections}`
|
|
|
6495
7053
|
if (!appId || !clientSecret) {
|
|
6496
7054
|
return missingCredentialField(!appId ? "app_id" : "client_secret");
|
|
6497
7055
|
}
|
|
6498
|
-
const localTeamsChannel =
|
|
7056
|
+
const localTeamsChannel = join5(getHomeDir(), ".augmented", "_mcp", "teams-channel.js");
|
|
6499
7057
|
const agentDirMs = getAgentDir(codeName);
|
|
6500
7058
|
try {
|
|
6501
|
-
|
|
6502
|
-
|
|
6503
|
-
|
|
7059
|
+
mkdirSync4(join5(agentDirMs, "msteams-pending-inbound", ".markers"), { recursive: true });
|
|
7060
|
+
mkdirSync4(join5(agentDirMs, "msteams-pending-interactions"), { recursive: true });
|
|
7061
|
+
mkdirSync4(join5(agentDirMs, "msteams-recovery-outbox"), { recursive: true });
|
|
6504
7062
|
} catch {
|
|
6505
7063
|
}
|
|
6506
7064
|
const tenantId = config["tenant_id"] ?? "common";
|
|
@@ -6582,7 +7140,7 @@ ${sections}`
|
|
|
6582
7140
|
}
|
|
6583
7141
|
if (channelId === "whatsapp") {
|
|
6584
7142
|
const provider = config["provider"] ?? "kapso";
|
|
6585
|
-
const localWhatsappChannel =
|
|
7143
|
+
const localWhatsappChannel = join5(getHomeDir(), ".augmented", "_mcp", "whatsapp-channel.js");
|
|
6586
7144
|
if (provider === "baileys") {
|
|
6587
7145
|
mcpServers["whatsapp"] = {
|
|
6588
7146
|
command: "node",
|
|
@@ -6602,7 +7160,7 @@ ${sections}`
|
|
|
6602
7160
|
const phoneNumberId = config["phone_number_id"];
|
|
6603
7161
|
if (projectApiKey && phoneNumberId) {
|
|
6604
7162
|
try {
|
|
6605
|
-
|
|
7163
|
+
mkdirSync4(join5(getAgentDir(codeName), "whatsapp-pending-inbound"), { recursive: true });
|
|
6606
7164
|
} catch {
|
|
6607
7165
|
}
|
|
6608
7166
|
writeEnvIntegrationsForAgent(codeName, {
|
|
@@ -6634,11 +7192,11 @@ ${sections}`
|
|
|
6634
7192
|
return CHANNEL_WRITE_OK;
|
|
6635
7193
|
},
|
|
6636
7194
|
hasChannelCredentials(codeName, channelId) {
|
|
6637
|
-
const provisionMcpPath =
|
|
7195
|
+
const provisionMcpPath = join5(getAgentDir(codeName), "provision", ".mcp.json");
|
|
6638
7196
|
if (!existsSync4(provisionMcpPath))
|
|
6639
7197
|
return false;
|
|
6640
7198
|
try {
|
|
6641
|
-
const parsed = JSON.parse(
|
|
7199
|
+
const parsed = JSON.parse(readFileSync5(provisionMcpPath, "utf-8"));
|
|
6642
7200
|
return Boolean(parsed.mcpServers?.[channelId]);
|
|
6643
7201
|
} catch {
|
|
6644
7202
|
return false;
|
|
@@ -6646,7 +7204,7 @@ ${sections}`
|
|
|
6646
7204
|
},
|
|
6647
7205
|
removeChannelCredentials(codeName, channelId) {
|
|
6648
7206
|
const agentDir = getAgentDir(codeName);
|
|
6649
|
-
const mcpJsonPath =
|
|
7207
|
+
const mcpJsonPath = join5(agentDir, "provision", ".mcp.json");
|
|
6650
7208
|
modifyJsonConfig(mcpJsonPath, (config) => {
|
|
6651
7209
|
const mcpServers = config["mcpServers"];
|
|
6652
7210
|
if (!mcpServers || !(channelId in mcpServers))
|
|
@@ -6658,7 +7216,7 @@ ${sections}`
|
|
|
6658
7216
|
},
|
|
6659
7217
|
async updateAgentModel(codeName, model) {
|
|
6660
7218
|
const agentDir = getAgentDir(codeName);
|
|
6661
|
-
const settingsPath =
|
|
7219
|
+
const settingsPath = join5(agentDir, "provision", "settings.json");
|
|
6662
7220
|
let changed = false;
|
|
6663
7221
|
modifyJsonConfig(settingsPath, (config) => {
|
|
6664
7222
|
config["model"] = model;
|
|
@@ -6676,20 +7234,20 @@ ${sections}`
|
|
|
6676
7234
|
seedProfileConfig(codeName) {
|
|
6677
7235
|
const agentDir = getAgentDir(codeName);
|
|
6678
7236
|
const projectDir = getProjectDir2(codeName);
|
|
6679
|
-
|
|
6680
|
-
|
|
7237
|
+
mkdirSync4(join5(agentDir, "provision"), { recursive: true });
|
|
7238
|
+
mkdirSync4(projectDir, { recursive: true });
|
|
6681
7239
|
},
|
|
6682
7240
|
syncScheduledTasks(codeName, tasks) {
|
|
6683
7241
|
const agentDir = getAgentDir(codeName);
|
|
6684
|
-
const schedulesPath =
|
|
7242
|
+
const schedulesPath = join5(agentDir, "schedules.json");
|
|
6685
7243
|
const mapped = mapScheduledTasks(tasks);
|
|
6686
|
-
|
|
6687
|
-
|
|
7244
|
+
mkdirSync4(agentDir, { recursive: true });
|
|
7245
|
+
writeFileSync5(schedulesPath, JSON.stringify({ schedules: mapped }, null, 2));
|
|
6688
7246
|
return Promise.resolve();
|
|
6689
7247
|
},
|
|
6690
7248
|
writeIntegrations(codeName, integrations, agentId, options) {
|
|
6691
7249
|
const agentDir = getAgentDir(codeName);
|
|
6692
|
-
|
|
7250
|
+
mkdirSync4(agentDir, { recursive: true });
|
|
6693
7251
|
const summariesForSidecar = integrations.map((i) => {
|
|
6694
7252
|
const def = INTEGRATION_REGISTRY.find((d) => d.id === i.definition_id);
|
|
6695
7253
|
return {
|
|
@@ -6804,7 +7362,7 @@ ${sections}`
|
|
|
6804
7362
|
xeroEnv.AGT_AGENT_ID = agentId;
|
|
6805
7363
|
xeroEnv.AGT_INTEGRATION_ID = xeroIntegration.id;
|
|
6806
7364
|
}
|
|
6807
|
-
const localXeroMcpPath =
|
|
7365
|
+
const localXeroMcpPath = join5(getHomeDir(), ".augmented", "_mcp", "xero.js");
|
|
6808
7366
|
this.writeMcpServer(codeName, "xero", {
|
|
6809
7367
|
command: "node",
|
|
6810
7368
|
args: [localXeroMcpPath],
|
|
@@ -6816,8 +7374,8 @@ ${sections}`
|
|
|
6816
7374
|
this.writeMcpServer(codeName, "postiz", buildPostizMcpEntry(postizIntegration));
|
|
6817
7375
|
}
|
|
6818
7376
|
const remoteOAuthProxyPaths = {
|
|
6819
|
-
proxyPath:
|
|
6820
|
-
tokenFile:
|
|
7377
|
+
proxyPath: join5(getHomeDir(), ".augmented", "_mcp", "remote-oauth-proxy.js"),
|
|
7378
|
+
tokenFile: join5(getProjectDir2(codeName), ".env.integrations")
|
|
6821
7379
|
};
|
|
6822
7380
|
for (const integration of integrations) {
|
|
6823
7381
|
const connectionKey = integration.connection_key;
|
|
@@ -6863,7 +7421,7 @@ ${sections}`
|
|
|
6863
7421
|
// ENG-6586 (D16): keep incremental cloud-broker wiring in sync with
|
|
6864
7422
|
// buildMcpJson so agents that add cloud-broker post-provision still
|
|
6865
7423
|
// forward the per-turn initiator.
|
|
6866
|
-
AGT_TURN_INITIATOR_FILE:
|
|
7424
|
+
AGT_TURN_INITIATOR_FILE: join5(getAgentDir(codeName), ".current-turn-initiator.json"),
|
|
6867
7425
|
PATH: process.env["PATH"] ?? "",
|
|
6868
7426
|
HOME: process.env["HOME"] ?? ""
|
|
6869
7427
|
}
|
|
@@ -6887,7 +7445,7 @@ ${sections}`
|
|
|
6887
7445
|
// ENG-6563 (D16): keep incremental xero-broker wiring in sync with
|
|
6888
7446
|
// buildMcpJson so agents that add xero-broker post-provision still
|
|
6889
7447
|
// forward the per-turn initiator.
|
|
6890
|
-
AGT_TURN_INITIATOR_FILE:
|
|
7448
|
+
AGT_TURN_INITIATOR_FILE: join5(getAgentDir(codeName), ".current-turn-initiator.json"),
|
|
6891
7449
|
PATH: process.env["PATH"] ?? "",
|
|
6892
7450
|
HOME: process.env["HOME"] ?? ""
|
|
6893
7451
|
}
|
|
@@ -6896,7 +7454,7 @@ ${sections}`
|
|
|
6896
7454
|
}
|
|
6897
7455
|
const hasAdminDebug = integrations.some((i) => i.definition_id === "augmented-admin");
|
|
6898
7456
|
if (hasAdminDebug) {
|
|
6899
|
-
const localAdminMcpPath =
|
|
7457
|
+
const localAdminMcpPath = join5(getHomeDir(), ".augmented", "_mcp", "augmented-admin.js");
|
|
6900
7458
|
this.writeMcpServer(codeName, "augmented-admin", {
|
|
6901
7459
|
command: "node",
|
|
6902
7460
|
args: [localAdminMcpPath],
|
|
@@ -6910,7 +7468,7 @@ ${sections}`
|
|
|
6910
7468
|
}
|
|
6911
7469
|
const hasSupport = integrations.some((i) => i.definition_id === "augmented-support");
|
|
6912
7470
|
if (hasSupport) {
|
|
6913
|
-
const localSupportMcpPath =
|
|
7471
|
+
const localSupportMcpPath = join5(getHomeDir(), ".augmented", "_mcp", "augmented-support.js");
|
|
6914
7472
|
this.writeMcpServer(codeName, "augmented-support", {
|
|
6915
7473
|
command: "node",
|
|
6916
7474
|
args: [localSupportMcpPath],
|
|
@@ -6924,7 +7482,7 @@ ${sections}`
|
|
|
6924
7482
|
}
|
|
6925
7483
|
const hasHelpKb = integrations.some((i) => i.definition_id === "augmented-help-kb");
|
|
6926
7484
|
if (hasHelpKb) {
|
|
6927
|
-
const localHelpKbMcpPath =
|
|
7485
|
+
const localHelpKbMcpPath = join5(getHomeDir(), ".augmented", "_mcp", "augmented-help-kb.js");
|
|
6928
7486
|
this.writeMcpServer(codeName, "augmented-help-kb", {
|
|
6929
7487
|
command: "node",
|
|
6930
7488
|
args: [localHelpKbMcpPath],
|
|
@@ -6940,7 +7498,7 @@ ${sections}`
|
|
|
6940
7498
|
const origamiStdioAgentId = resolveBrokerAgentId(codeName) ?? agentId;
|
|
6941
7499
|
const origamiStdioExpected = Boolean(origamiStdio?.stdioMcp === true && origamiStdio.id);
|
|
6942
7500
|
if (origamiStdioExpected && origamiStdioAgentId) {
|
|
6943
|
-
const localOrigamiMcpPath =
|
|
7501
|
+
const localOrigamiMcpPath = join5(getHomeDir(), ".augmented", "_mcp", "origami.js");
|
|
6944
7502
|
this.writeMcpServer(codeName, "origami", {
|
|
6945
7503
|
command: "node",
|
|
6946
7504
|
args: [localOrigamiMcpPath],
|
|
@@ -6961,7 +7519,7 @@ ${sections}`
|
|
|
6961
7519
|
agentId: computerUseAgentId,
|
|
6962
7520
|
agentCodeName: codeName,
|
|
6963
7521
|
config: computerUseRow.config,
|
|
6964
|
-
proxyPath:
|
|
7522
|
+
proxyPath: join5(getHomeDir(), ".augmented", "_mcp", "computer-use-proxy.js"),
|
|
6965
7523
|
agentDir: getAgentDir(codeName)
|
|
6966
7524
|
});
|
|
6967
7525
|
if (rendered.entry) {
|
|
@@ -7085,9 +7643,9 @@ ${sections}`
|
|
|
7085
7643
|
}
|
|
7086
7644
|
}
|
|
7087
7645
|
const projectDir = getProjectDir2(codeName);
|
|
7088
|
-
const claudeMdPath =
|
|
7646
|
+
const claudeMdPath = join5(projectDir, "CLAUDE.md");
|
|
7089
7647
|
try {
|
|
7090
|
-
const existing =
|
|
7648
|
+
const existing = readFileSync5(claudeMdPath, "utf-8");
|
|
7091
7649
|
const renderSection = options?.renderClaudeMdSection === true;
|
|
7092
7650
|
const newSection = renderSection ? buildIntegrationsSection(summariesForSidecar) : "";
|
|
7093
7651
|
const sentinelStart = INTEGRATIONS_SECTION_START.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -7104,13 +7662,13 @@ ${sections}`
|
|
|
7104
7662
|
updated = existing;
|
|
7105
7663
|
}
|
|
7106
7664
|
if (updated !== existing)
|
|
7107
|
-
|
|
7665
|
+
writeFileSync5(claudeMdPath, updated);
|
|
7108
7666
|
const agentDir2 = getAgentDir(codeName);
|
|
7109
|
-
const envSrc =
|
|
7667
|
+
const envSrc = join5(agentDir2, ".env.integrations");
|
|
7110
7668
|
try {
|
|
7111
|
-
const envContent =
|
|
7112
|
-
const envDest =
|
|
7113
|
-
|
|
7669
|
+
const envContent = readFileSync5(envSrc, "utf-8");
|
|
7670
|
+
const envDest = join5(projectDir, ".env.integrations");
|
|
7671
|
+
writeFileSync5(envDest, envContent, { mode: SECRET_FILE_MODE });
|
|
7114
7672
|
try {
|
|
7115
7673
|
chmodSync4(envDest, SECRET_FILE_MODE);
|
|
7116
7674
|
} catch {
|
|
@@ -7124,11 +7682,11 @@ ${sections}`
|
|
|
7124
7682
|
},
|
|
7125
7683
|
writeMcpServer(codeName, serverId, config) {
|
|
7126
7684
|
const agentDir = getAgentDir(codeName);
|
|
7127
|
-
const mcpJsonPath =
|
|
7128
|
-
|
|
7685
|
+
const mcpJsonPath = join5(agentDir, "provision", ".mcp.json");
|
|
7686
|
+
mkdirSync4(join5(agentDir, "provision"), { recursive: true });
|
|
7129
7687
|
let mcpConfig;
|
|
7130
7688
|
try {
|
|
7131
|
-
mcpConfig = JSON.parse(
|
|
7689
|
+
mcpConfig = JSON.parse(readFileSync5(mcpJsonPath, "utf-8"));
|
|
7132
7690
|
} catch {
|
|
7133
7691
|
mcpConfig = { mcpServers: {} };
|
|
7134
7692
|
}
|
|
@@ -7172,7 +7730,7 @@ ${sections}`
|
|
|
7172
7730
|
}
|
|
7173
7731
|
},
|
|
7174
7732
|
getMcpPath(codeName) {
|
|
7175
|
-
return
|
|
7733
|
+
return join5(getAgentDir(codeName), "provision", ".mcp.json");
|
|
7176
7734
|
},
|
|
7177
7735
|
/**
|
|
7178
7736
|
* ENG-7994: the declared servers from `provision/.mcp.json`. Mirrors what the
|
|
@@ -7183,7 +7741,7 @@ ${sections}`
|
|
|
7183
7741
|
readMcpServers(codeName) {
|
|
7184
7742
|
let parsed;
|
|
7185
7743
|
try {
|
|
7186
|
-
parsed = JSON.parse(
|
|
7744
|
+
parsed = JSON.parse(readFileSync5(join5(getAgentDir(codeName), "provision", ".mcp.json"), "utf-8"));
|
|
7187
7745
|
} catch {
|
|
7188
7746
|
return {};
|
|
7189
7747
|
}
|
|
@@ -7196,10 +7754,10 @@ ${sections}`
|
|
|
7196
7754
|
},
|
|
7197
7755
|
removeMcpServer(codeName, serverId) {
|
|
7198
7756
|
const agentDir = getAgentDir(codeName);
|
|
7199
|
-
const mcpJsonPath =
|
|
7757
|
+
const mcpJsonPath = join5(agentDir, "provision", ".mcp.json");
|
|
7200
7758
|
let mcpConfig;
|
|
7201
7759
|
try {
|
|
7202
|
-
mcpConfig = JSON.parse(
|
|
7760
|
+
mcpConfig = JSON.parse(readFileSync5(mcpJsonPath, "utf-8"));
|
|
7203
7761
|
} catch {
|
|
7204
7762
|
return;
|
|
7205
7763
|
}
|
|
@@ -7218,24 +7776,24 @@ ${sections}`
|
|
|
7218
7776
|
const READ_WRITE_MODE = 420;
|
|
7219
7777
|
const agentDir = getAgentDir(codeName);
|
|
7220
7778
|
const projectDir = getProjectDir2(codeName);
|
|
7221
|
-
for (const baseDir of [
|
|
7222
|
-
const skillDir =
|
|
7223
|
-
|
|
7779
|
+
for (const baseDir of [join5(agentDir, "skills"), join5(projectDir, ".claude", "skills")]) {
|
|
7780
|
+
const skillDir = join5(baseDir, skillId);
|
|
7781
|
+
mkdirSync4(skillDir, { recursive: true });
|
|
7224
7782
|
for (const file of files) {
|
|
7225
7783
|
assertSafeRelativePath(file.relativePath);
|
|
7226
|
-
const filePath =
|
|
7784
|
+
const filePath = join5(skillDir, file.relativePath);
|
|
7227
7785
|
const rel = relative(skillDir, filePath);
|
|
7228
7786
|
if (rel.startsWith("..") || rel === "") {
|
|
7229
7787
|
throw new Error(`Path traversal detected: ${file.relativePath} resolves outside ${skillDir}`);
|
|
7230
7788
|
}
|
|
7231
|
-
|
|
7789
|
+
mkdirSync4(join5(filePath, ".."), { recursive: true });
|
|
7232
7790
|
if (isPluginManaged && existsSync4(filePath)) {
|
|
7233
7791
|
try {
|
|
7234
7792
|
chmodSync4(filePath, READ_WRITE_MODE);
|
|
7235
7793
|
} catch {
|
|
7236
7794
|
}
|
|
7237
7795
|
}
|
|
7238
|
-
|
|
7796
|
+
writeFileSync5(filePath, file.content);
|
|
7239
7797
|
if (isPluginManaged) {
|
|
7240
7798
|
try {
|
|
7241
7799
|
chmodSync4(filePath, READ_ONLY_MODE);
|
|
@@ -7247,11 +7805,11 @@ ${sections}`
|
|
|
7247
7805
|
},
|
|
7248
7806
|
installPlugin(codeName, pluginId, pluginPath, pluginConfig) {
|
|
7249
7807
|
const agentDir = getAgentDir(codeName);
|
|
7250
|
-
const pluginsJsonPath =
|
|
7251
|
-
|
|
7808
|
+
const pluginsJsonPath = join5(agentDir, "plugins.json");
|
|
7809
|
+
mkdirSync4(agentDir, { recursive: true });
|
|
7252
7810
|
let pluginsConfig;
|
|
7253
7811
|
try {
|
|
7254
|
-
pluginsConfig = JSON.parse(
|
|
7812
|
+
pluginsConfig = JSON.parse(readFileSync5(pluginsJsonPath, "utf-8"));
|
|
7255
7813
|
} catch {
|
|
7256
7814
|
pluginsConfig = { plugins: {} };
|
|
7257
7815
|
}
|
|
@@ -7264,7 +7822,7 @@ ${sections}`
|
|
|
7264
7822
|
installed_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
7265
7823
|
...pluginConfig ? { config: pluginConfig } : {}
|
|
7266
7824
|
};
|
|
7267
|
-
|
|
7825
|
+
writeFileSync5(pluginsJsonPath, JSON.stringify(pluginsConfig, null, 2));
|
|
7268
7826
|
},
|
|
7269
7827
|
/**
|
|
7270
7828
|
* Full plugin provisioning: install scripts, register hooks, apply permissions,
|
|
@@ -7280,11 +7838,11 @@ ${sections}`
|
|
|
7280
7838
|
assertValidCodeName(codeName);
|
|
7281
7839
|
assertValidCodeName(plugin.slug);
|
|
7282
7840
|
const projectDir = getProjectDir2(codeName);
|
|
7283
|
-
const claudeDir =
|
|
7284
|
-
|
|
7841
|
+
const claudeDir = join5(projectDir, ".claude");
|
|
7842
|
+
mkdirSync4(claudeDir, { recursive: true });
|
|
7285
7843
|
const sourceSpec = options?.scriptSource ?? `augmented-plugin:${plugin.slug}`;
|
|
7286
7844
|
this.installPlugin(codeName, plugin.slug, sourceSpec, contextValues);
|
|
7287
|
-
const installedDir =
|
|
7845
|
+
const installedDir = join5(projectDir, ".claude", "plugins", plugin.slug);
|
|
7288
7846
|
for (const skill of plugin.skills) {
|
|
7289
7847
|
const skillId = skill.id;
|
|
7290
7848
|
assertValidCodeName(skillId);
|
|
@@ -7296,10 +7854,10 @@ ${sections}`
|
|
|
7296
7854
|
}
|
|
7297
7855
|
const scriptsConfig = plugin.scripts;
|
|
7298
7856
|
if (scriptsConfig?.hooks) {
|
|
7299
|
-
const settingsPath =
|
|
7857
|
+
const settingsPath = join5(claudeDir, "settings.local.json");
|
|
7300
7858
|
let settings = {};
|
|
7301
7859
|
try {
|
|
7302
|
-
settings = JSON.parse(
|
|
7860
|
+
settings = JSON.parse(readFileSync5(settingsPath, "utf-8"));
|
|
7303
7861
|
} catch {
|
|
7304
7862
|
}
|
|
7305
7863
|
const existingHooks = settings["hooks"] ?? {};
|
|
@@ -7333,13 +7891,13 @@ ${sections}`
|
|
|
7333
7891
|
}
|
|
7334
7892
|
}
|
|
7335
7893
|
settings["hooks"] = existingHooks;
|
|
7336
|
-
|
|
7894
|
+
writeFileSync5(settingsPath, JSON.stringify(settings, null, 2));
|
|
7337
7895
|
}
|
|
7338
7896
|
if (plugin.allowed_tools.length > 0) {
|
|
7339
|
-
const settingsPath =
|
|
7897
|
+
const settingsPath = join5(claudeDir, "settings.local.json");
|
|
7340
7898
|
let settings = {};
|
|
7341
7899
|
try {
|
|
7342
|
-
settings = JSON.parse(
|
|
7900
|
+
settings = JSON.parse(readFileSync5(settingsPath, "utf-8"));
|
|
7343
7901
|
} catch {
|
|
7344
7902
|
}
|
|
7345
7903
|
const existingPerms = settings["permissions"] ?? {};
|
|
@@ -7351,20 +7909,20 @@ ${sections}`
|
|
|
7351
7909
|
}
|
|
7352
7910
|
existingPerms["allow"] = allowList;
|
|
7353
7911
|
settings["permissions"] = existingPerms;
|
|
7354
|
-
|
|
7912
|
+
writeFileSync5(settingsPath, JSON.stringify(settings, null, 2));
|
|
7355
7913
|
}
|
|
7356
7914
|
if (contextValues && Object.keys(contextValues).length > 0) {
|
|
7357
|
-
const configDir =
|
|
7358
|
-
|
|
7359
|
-
|
|
7915
|
+
const configDir = join5(projectDir, `.${plugin.slug}`);
|
|
7916
|
+
mkdirSync4(configDir, { recursive: true });
|
|
7917
|
+
writeFileSync5(join5(configDir, "config.json"), JSON.stringify(contextValues, null, 2));
|
|
7360
7918
|
}
|
|
7361
7919
|
},
|
|
7362
7920
|
executePluginHook(ctx) {
|
|
7363
7921
|
assertValidCodeName(ctx.codeName);
|
|
7364
|
-
const agentRootDir =
|
|
7922
|
+
const agentRootDir = join5(getHomeDir(), ".augmented", ctx.codeName);
|
|
7365
7923
|
const projectDir = getProjectDir2(ctx.codeName);
|
|
7366
|
-
|
|
7367
|
-
|
|
7924
|
+
mkdirSync4(agentRootDir, { recursive: true });
|
|
7925
|
+
mkdirSync4(projectDir, { recursive: true });
|
|
7368
7926
|
const startedAt = Date.now();
|
|
7369
7927
|
return new Promise((resolve) => {
|
|
7370
7928
|
const child = execFile("bash", ["-c", ctx.script], {
|
|
@@ -7418,14 +7976,14 @@ function jsonOutput(data) {
|
|
|
7418
7976
|
}
|
|
7419
7977
|
|
|
7420
7978
|
// src/lib/config.ts
|
|
7421
|
-
import { readFileSync as
|
|
7422
|
-
import { join as
|
|
7979
|
+
import { readFileSync as readFileSync6, writeFileSync as writeFileSync6, mkdirSync as mkdirSync5, existsSync as existsSync5 } from "fs";
|
|
7980
|
+
import { join as join6 } from "path";
|
|
7423
7981
|
import { homedir as homedir4 } from "os";
|
|
7424
|
-
var AUGMENTED_DIR =
|
|
7425
|
-
var CONFIG_PATH =
|
|
7982
|
+
var AUGMENTED_DIR = join6(homedir4(), ".augmented");
|
|
7983
|
+
var CONFIG_PATH = join6(AUGMENTED_DIR, "config.json");
|
|
7426
7984
|
function ensureAugmentedDir() {
|
|
7427
7985
|
if (!existsSync5(AUGMENTED_DIR)) {
|
|
7428
|
-
|
|
7986
|
+
mkdirSync5(AUGMENTED_DIR, { recursive: true });
|
|
7429
7987
|
}
|
|
7430
7988
|
}
|
|
7431
7989
|
function reloadFromShellProfile() {
|
|
@@ -7435,10 +7993,10 @@ function loadFromShellProfile(force = false) {
|
|
|
7435
7993
|
if (!force && process.env["AGT_HOST"] && process.env["AGT_API_KEY"]) return;
|
|
7436
7994
|
const shell = process.env["SHELL"] ?? "";
|
|
7437
7995
|
const home = homedir4();
|
|
7438
|
-
const candidates = shell.includes("zsh") ? [
|
|
7996
|
+
const candidates = shell.includes("zsh") ? [join6(home, ".zshrc"), join6(home, ".zprofile")] : shell.includes("fish") ? [join6(home, ".config", "fish", "config.fish")] : [join6(home, ".bashrc"), join6(home, ".bash_profile")];
|
|
7439
7997
|
for (const profile of candidates) {
|
|
7440
7998
|
try {
|
|
7441
|
-
const content =
|
|
7999
|
+
const content = readFileSync6(profile, "utf-8");
|
|
7442
8000
|
for (const key of ["AGT_HOST", "AGT_API_KEY", "AGT_TEAM"]) {
|
|
7443
8001
|
if (!force && process.env[key]) continue;
|
|
7444
8002
|
const match = content.split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#")).map(
|
|
@@ -7463,7 +8021,7 @@ function getApiKey() {
|
|
|
7463
8021
|
}
|
|
7464
8022
|
function getConfig() {
|
|
7465
8023
|
try {
|
|
7466
|
-
const raw =
|
|
8024
|
+
const raw = readFileSync6(CONFIG_PATH, "utf-8");
|
|
7467
8025
|
return JSON.parse(raw);
|
|
7468
8026
|
} catch {
|
|
7469
8027
|
return {};
|
|
@@ -7471,7 +8029,7 @@ function getConfig() {
|
|
|
7471
8029
|
}
|
|
7472
8030
|
function saveConfig(config) {
|
|
7473
8031
|
ensureAugmentedDir();
|
|
7474
|
-
|
|
8032
|
+
writeFileSync6(CONFIG_PATH, JSON.stringify(config, null, 2));
|
|
7475
8033
|
}
|
|
7476
8034
|
function getActiveTeam() {
|
|
7477
8035
|
const envTeam = process.env["AGT_TEAM"];
|
|
@@ -7518,7 +8076,7 @@ function exchangeFailureKind(err) {
|
|
|
7518
8076
|
}
|
|
7519
8077
|
|
|
7520
8078
|
// src/lib/api-client.ts
|
|
7521
|
-
var agtCliVersion = true ? "0.28.
|
|
8079
|
+
var agtCliVersion = true ? "0.28.1128" : "dev";
|
|
7522
8080
|
var lastConfigHash = null;
|
|
7523
8081
|
function setConfigHash(hash) {
|
|
7524
8082
|
lastConfigHash = hash && hash.length > 0 ? hash : null;
|
|
@@ -7786,13 +8344,13 @@ async function getHostId() {
|
|
|
7786
8344
|
}
|
|
7787
8345
|
|
|
7788
8346
|
// src/lib/atomic-write.ts
|
|
7789
|
-
import { closeSync, fsyncSync, openSync, writeSync, renameSync as renameSync5, mkdirSync as
|
|
8347
|
+
import { closeSync, fsyncSync, openSync, writeSync, renameSync as renameSync5, mkdirSync as mkdirSync6 } from "fs";
|
|
7790
8348
|
import { dirname as dirname4 } from "path";
|
|
7791
8349
|
function atomicWriteFileSync(path, data) {
|
|
7792
8350
|
const dirPath = dirname4(path);
|
|
7793
8351
|
const tmpPath = `${path}.tmp.${process.pid}.${Math.random().toString(36).slice(2, 8)}`;
|
|
7794
8352
|
try {
|
|
7795
|
-
|
|
8353
|
+
mkdirSync6(dirPath, { recursive: true });
|
|
7796
8354
|
} catch {
|
|
7797
8355
|
}
|
|
7798
8356
|
const fd = openSync(tmpPath, "w", 420);
|
|
@@ -7818,16 +8376,16 @@ function atomicWriteFileSync(path, data) {
|
|
|
7818
8376
|
}
|
|
7819
8377
|
|
|
7820
8378
|
// src/lib/feature-flags-host.ts
|
|
7821
|
-
import { existsSync as existsSync6, readFileSync as
|
|
8379
|
+
import { existsSync as existsSync6, readFileSync as readFileSync7, rmSync as rmSync3, statSync as statSync2 } from "fs";
|
|
7822
8380
|
import { homedir as homedir5 } from "os";
|
|
7823
|
-
import { join as
|
|
8381
|
+
import { join as join7 } from "path";
|
|
7824
8382
|
function defaultFlagsCachePath(configDir) {
|
|
7825
|
-
return
|
|
8383
|
+
return join7(configDir, "flags-cache.json");
|
|
7826
8384
|
}
|
|
7827
8385
|
function readFlagsCache(path) {
|
|
7828
8386
|
try {
|
|
7829
8387
|
if (!existsSync6(path)) return null;
|
|
7830
|
-
const parsed = JSON.parse(
|
|
8388
|
+
const parsed = JSON.parse(readFileSync7(path, "utf8"));
|
|
7831
8389
|
if (!parsed || typeof parsed !== "object") return null;
|
|
7832
8390
|
const obj = parsed;
|
|
7833
8391
|
const flags = obj["flags"];
|
|
@@ -8097,12 +8655,12 @@ var HostFlagStore = class {
|
|
|
8097
8655
|
* The in-memory state stays authoritative and the next heartbeat retries.
|
|
8098
8656
|
*/
|
|
8099
8657
|
persistPerAgentCaches(updatedAt) {
|
|
8100
|
-
const root =
|
|
8658
|
+
const root = join7(homedir5(), ".augmented");
|
|
8101
8659
|
for (const agentId of this.mirrorAgentIds) {
|
|
8102
8660
|
try {
|
|
8103
|
-
const dir =
|
|
8661
|
+
const dir = join7(root, agentId);
|
|
8104
8662
|
if (!existsSync6(dir)) continue;
|
|
8105
|
-
writeFlagsCache(
|
|
8663
|
+
writeFlagsCache(join7(dir, "flags-cache.json"), {
|
|
8106
8664
|
schema_version: this.lastSchemaVersion,
|
|
8107
8665
|
updated_at: updatedAt,
|
|
8108
8666
|
flags: this.flagsForAgent(agentId),
|
|
@@ -8116,7 +8674,7 @@ var HostFlagStore = class {
|
|
|
8116
8674
|
} catch (err) {
|
|
8117
8675
|
let removed = "left in place";
|
|
8118
8676
|
try {
|
|
8119
|
-
rmSync3(
|
|
8677
|
+
rmSync3(join7(root, agentId, "flags-cache.json"), { force: true, recursive: true });
|
|
8120
8678
|
removed = "stale mirror removed";
|
|
8121
8679
|
} catch (rmErr) {
|
|
8122
8680
|
removed = `stale mirror could NOT be removed: ${rmErr.message}`;
|
|
@@ -10012,8 +10570,8 @@ function verdictForUnavailableMcpConfig(cause, ctx) {
|
|
|
10012
10570
|
}
|
|
10013
10571
|
|
|
10014
10572
|
// src/lib/connectivity-probe-context.ts
|
|
10015
|
-
import { delimiter as pathDelimiter, join as
|
|
10016
|
-
import { existsSync as existsSync7, readFileSync as
|
|
10573
|
+
import { delimiter as pathDelimiter, join as join8 } from "path";
|
|
10574
|
+
import { existsSync as existsSync7, readFileSync as readFileSync8 } from "fs";
|
|
10017
10575
|
import { homedir as homedir6 } from "os";
|
|
10018
10576
|
|
|
10019
10577
|
// src/lib/mcp-stdio-probe.ts
|
|
@@ -10757,7 +11315,7 @@ function resolveHttpServerEntry(entry, env) {
|
|
|
10757
11315
|
function readMcpHttpServerConfig(projectDir, serverKey, env) {
|
|
10758
11316
|
let servers;
|
|
10759
11317
|
try {
|
|
10760
|
-
const raw =
|
|
11318
|
+
const raw = readFileSync8(join8(projectDir, ".mcp.json"), "utf-8");
|
|
10761
11319
|
servers = JSON.parse(raw).mcpServers ?? {};
|
|
10762
11320
|
} catch {
|
|
10763
11321
|
return { ok: false, cause: "file-unreadable" };
|
|
@@ -10769,7 +11327,7 @@ function readMcpHttpServerConfig(projectDir, serverKey, env) {
|
|
|
10769
11327
|
}
|
|
10770
11328
|
function resolveDeclaredServerKey(projectDir, definitionId, derivedKey) {
|
|
10771
11329
|
try {
|
|
10772
|
-
const raw =
|
|
11330
|
+
const raw = readFileSync8(join8(projectDir, ".mcp.json"), "utf-8");
|
|
10773
11331
|
const servers = JSON.parse(raw).mcpServers ?? {};
|
|
10774
11332
|
const declared = Object.keys(servers);
|
|
10775
11333
|
if (derivedKey !== definitionId && derivedKey !== sanitizeServerKey(definitionId)) {
|
|
@@ -10811,7 +11369,7 @@ function resolveStdioServerEntry(entry, env) {
|
|
|
10811
11369
|
function readMcpStdioServerConfig(projectDir, serverKey, env) {
|
|
10812
11370
|
let servers;
|
|
10813
11371
|
try {
|
|
10814
|
-
const raw =
|
|
11372
|
+
const raw = readFileSync8(join8(projectDir, ".mcp.json"), "utf-8");
|
|
10815
11373
|
servers = JSON.parse(raw).mcpServers ?? {};
|
|
10816
11374
|
} catch {
|
|
10817
11375
|
return { ok: false, cause: "file-unreadable" };
|
|
@@ -10839,15 +11397,15 @@ function toolkitPathDirs() {
|
|
|
10839
11397
|
const home = process.env.HOME?.trim() || homedir6();
|
|
10840
11398
|
return [
|
|
10841
11399
|
...PROBE_TOOLKIT_PATH_DIRS,
|
|
10842
|
-
...PROBE_HOME_RELATIVE_PATH_SEGMENTS.map((seg) =>
|
|
11400
|
+
...PROBE_HOME_RELATIVE_PATH_SEGMENTS.map((seg) => join8(home, seg))
|
|
10843
11401
|
];
|
|
10844
11402
|
}
|
|
10845
11403
|
function buildProbeEnv(projectDir, agentId) {
|
|
10846
11404
|
const probeEnv = { ...process.env };
|
|
10847
11405
|
try {
|
|
10848
|
-
const envIntPath =
|
|
11406
|
+
const envIntPath = join8(projectDir, ".env.integrations");
|
|
10849
11407
|
if (existsSync7(envIntPath)) {
|
|
10850
|
-
Object.assign(probeEnv, parseEnvIntegrations(
|
|
11408
|
+
Object.assign(probeEnv, parseEnvIntegrations(readFileSync8(envIntPath, "utf-8")));
|
|
10851
11409
|
}
|
|
10852
11410
|
} catch {
|
|
10853
11411
|
}
|
|
@@ -10855,7 +11413,7 @@ function buildProbeEnv(projectDir, agentId) {
|
|
|
10855
11413
|
probeEnv.AGT_AGENT_ID = agentId.trim();
|
|
10856
11414
|
}
|
|
10857
11415
|
try {
|
|
10858
|
-
const agentBinDir =
|
|
11416
|
+
const agentBinDir = join8(projectDir, ".claude", "agt-bin");
|
|
10859
11417
|
if (existsSync7(agentBinDir)) {
|
|
10860
11418
|
const parts = probeEnv.PATH ? probeEnv.PATH.split(pathDelimiter) : [];
|
|
10861
11419
|
parts.unshift(agentBinDir);
|
|
@@ -11249,8 +11807,8 @@ var TunnelWatcher = class {
|
|
|
11249
11807
|
|
|
11250
11808
|
// src/lib/session-tool-bind-probe-host.ts
|
|
11251
11809
|
import { execFileSync as syncExecFile } from "child_process";
|
|
11252
|
-
import { readFileSync as
|
|
11253
|
-
import { join as
|
|
11810
|
+
import { readFileSync as readFileSync9 } from "fs";
|
|
11811
|
+
import { join as join9 } from "path";
|
|
11254
11812
|
import { dirname as dirname5 } from "path";
|
|
11255
11813
|
function deliveryFields(i) {
|
|
11256
11814
|
const keys = ["source_type", "provider", "mcp_command", "mcp_url", "cli_binary", "cli_package"];
|
|
@@ -11264,7 +11822,7 @@ async function gatherSessionToolBindProbe(agent, integrations, projectDir, opts)
|
|
|
11264
11822
|
if (integrations.length === 0) return null;
|
|
11265
11823
|
let mcpRaw = null;
|
|
11266
11824
|
try {
|
|
11267
|
-
mcpRaw =
|
|
11825
|
+
mcpRaw = readFileSync9(join9(projectDir, ".mcp.json"), "utf-8");
|
|
11268
11826
|
} catch {
|
|
11269
11827
|
mcpRaw = null;
|
|
11270
11828
|
}
|
|
@@ -11368,7 +11926,7 @@ var SLACK_MCP_SERVER_KEY = "slack";
|
|
|
11368
11926
|
function readSlackTransportDownKeys(projectDir) {
|
|
11369
11927
|
const none = /* @__PURE__ */ new Set();
|
|
11370
11928
|
try {
|
|
11371
|
-
const raw =
|
|
11929
|
+
const raw = readFileSync9(join9(dirname5(projectDir), SLACK_SOCKET_STATE_FILENAME), "utf-8");
|
|
11372
11930
|
const state = parseSlackSocketState(raw, Date.now());
|
|
11373
11931
|
return isSlackInboundTransportDown(state, SLACK_TRANSPORT_DOWN_AFTER_MS) ? /* @__PURE__ */ new Set([SLACK_MCP_SERVER_KEY]) : none;
|
|
11374
11932
|
} catch {
|
|
@@ -11455,11 +12013,11 @@ function describeWorkerModuleFailure(err) {
|
|
|
11455
12013
|
// src/lib/drain-transcript-flush.ts
|
|
11456
12014
|
import { existsSync as existsSync8, readdirSync as readdirSync2 } from "fs";
|
|
11457
12015
|
import { homedir as homedir7 } from "os";
|
|
11458
|
-
import { dirname as dirname6, join as
|
|
12016
|
+
import { dirname as dirname6, join as join10, relative as relative2, sep } from "path";
|
|
11459
12017
|
import { spawn as spawn2 } from "child_process";
|
|
11460
12018
|
|
|
11461
12019
|
// src/lib/host-archive-address.ts
|
|
11462
|
-
import { readFileSync as
|
|
12020
|
+
import { readFileSync as readFileSync10 } from "fs";
|
|
11463
12021
|
var DEFAULT_ARCHIVE_ADDRESS_PATH = "/var/lib/augmented/session-archive-address.json";
|
|
11464
12022
|
var CACHE_TTL_MS = 5 * 60 * 1e3;
|
|
11465
12023
|
var cache2 = /* @__PURE__ */ new Map();
|
|
@@ -11475,7 +12033,7 @@ function readHostArchiveAddress(path) {
|
|
|
11475
12033
|
if (hit && now - hit.at < CACHE_TTL_MS) return hit.value;
|
|
11476
12034
|
let value = null;
|
|
11477
12035
|
try {
|
|
11478
|
-
const raw =
|
|
12036
|
+
const raw = readFileSync10(file, "utf-8");
|
|
11479
12037
|
const parsed = JSON.parse(raw);
|
|
11480
12038
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
11481
12039
|
const obj = parsed;
|
|
@@ -11499,7 +12057,7 @@ function readHostArchiveAddress(path) {
|
|
|
11499
12057
|
|
|
11500
12058
|
// src/lib/drain-transcript-flush.ts
|
|
11501
12059
|
function sessionsBaseDir() {
|
|
11502
|
-
return
|
|
12060
|
+
return join10(homedir7(), ".claude", "projects");
|
|
11503
12061
|
}
|
|
11504
12062
|
var PER_FILE_UPLOAD_TIMEOUT_MS = 3e4;
|
|
11505
12063
|
var UPLOAD_CONCURRENCY = 4;
|
|
@@ -11510,7 +12068,7 @@ function listJsonlFiles(dir) {
|
|
|
11510
12068
|
const out = [];
|
|
11511
12069
|
const walk = (d) => {
|
|
11512
12070
|
for (const entry of readdirSync2(d, { withFileTypes: true })) {
|
|
11513
|
-
const full =
|
|
12071
|
+
const full = join10(d, entry.name);
|
|
11514
12072
|
if (entry.isDirectory()) walk(full);
|
|
11515
12073
|
else if (entry.isFile() && entry.name.endsWith(".jsonl")) out.push(full);
|
|
11516
12074
|
}
|
|
@@ -11527,7 +12085,7 @@ function transcriptObjectKey(keyPrefix, baseDir, file) {
|
|
|
11527
12085
|
return `${keyPrefix.replace(/\/+$/, "")}/${rel}`;
|
|
11528
12086
|
}
|
|
11529
12087
|
function drainManifestObjectKey(keyPrefix, baseDir, transcriptDir) {
|
|
11530
|
-
return transcriptObjectKey(keyPrefix, baseDir,
|
|
12088
|
+
return transcriptObjectKey(keyPrefix, baseDir, join10(transcriptDir, DRAIN_MANIFEST_FILENAME));
|
|
11531
12089
|
}
|
|
11532
12090
|
async function flushAgentTranscriptsOnDrain(codeName, deps) {
|
|
11533
12091
|
const dir = deps.resolveTranscriptDir(codeName);
|
|
@@ -11679,7 +12237,7 @@ function drainTranscriptFlushDeps(log2) {
|
|
|
11679
12237
|
// tree — the thing host-archive-address.ts's header warns about.
|
|
11680
12238
|
readSourceLayout: (codeName) => {
|
|
11681
12239
|
const agentDir = dirname6(getProjectDir(codeName));
|
|
11682
|
-
const codeNameDir =
|
|
12240
|
+
const codeNameDir = join10(homedir7(), ".augmented", codeName);
|
|
11683
12241
|
return { layout: agentDir === codeNameDir ? "codename-keyed" : "id-keyed", agentDir };
|
|
11684
12242
|
},
|
|
11685
12243
|
readSessionPin: (codeName) => readDailySessionPin(codeName),
|
|
@@ -11767,34 +12325,34 @@ function decidePin(opts) {
|
|
|
11767
12325
|
// src/commands/manager.ts
|
|
11768
12326
|
import chalk3 from "chalk";
|
|
11769
12327
|
import { existsSync as existsSync10, realpathSync as realpathSync2 } from "fs";
|
|
11770
|
-
import { join as
|
|
12328
|
+
import { join as join12 } from "path";
|
|
11771
12329
|
import { homedir as homedir8, userInfo } from "os";
|
|
11772
12330
|
import { spawn as spawn4 } from "child_process";
|
|
11773
12331
|
|
|
11774
12332
|
// src/lib/watchdog.ts
|
|
11775
|
-
import { readFileSync as
|
|
11776
|
-
import { join as
|
|
12333
|
+
import { readFileSync as readFileSync11, writeFileSync as writeFileSync7, unlinkSync as unlinkSync4, existsSync as existsSync9, mkdirSync as mkdirSync7, openSync as openSync2, closeSync as closeSync2, chmodSync as chmodSync5 } from "fs";
|
|
12334
|
+
import { join as join11 } from "path";
|
|
11777
12335
|
import { spawn as spawn3, execFileSync as execFileSync3 } from "child_process";
|
|
11778
|
-
var DEFAULT_CONFIG_DIR =
|
|
12336
|
+
var DEFAULT_CONFIG_DIR = join11(process.env["HOME"] ?? "/tmp", ".augmented");
|
|
11779
12337
|
function getManagerPaths(configDir) {
|
|
11780
12338
|
return {
|
|
11781
|
-
pidFile:
|
|
11782
|
-
stateFile:
|
|
11783
|
-
logFile:
|
|
12339
|
+
pidFile: join11(configDir, "manager.pid"),
|
|
12340
|
+
stateFile: join11(configDir, "manager-state.json"),
|
|
12341
|
+
logFile: join11(configDir, "manager.log")
|
|
11784
12342
|
};
|
|
11785
12343
|
}
|
|
11786
12344
|
function ensureDir(configDir) {
|
|
11787
12345
|
if (!existsSync9(configDir)) {
|
|
11788
|
-
|
|
12346
|
+
mkdirSync7(configDir, { recursive: true });
|
|
11789
12347
|
}
|
|
11790
12348
|
}
|
|
11791
12349
|
function writePidFile(configDir, pid) {
|
|
11792
12350
|
ensureDir(configDir);
|
|
11793
|
-
|
|
12351
|
+
writeFileSync7(getManagerPaths(configDir).pidFile, String(pid), { mode: 384 });
|
|
11794
12352
|
}
|
|
11795
12353
|
function readPidFile(configDir) {
|
|
11796
12354
|
try {
|
|
11797
|
-
const raw =
|
|
12355
|
+
const raw = readFileSync11(getManagerPaths(configDir).pidFile, "utf-8").trim();
|
|
11798
12356
|
const pid = parseInt(raw, 10);
|
|
11799
12357
|
return isNaN(pid) ? null : pid;
|
|
11800
12358
|
} catch {
|
|
@@ -11840,7 +12398,7 @@ function defaultPgrep() {
|
|
|
11840
12398
|
}
|
|
11841
12399
|
function readStateFile(configDir) {
|
|
11842
12400
|
try {
|
|
11843
|
-
const raw =
|
|
12401
|
+
const raw = readFileSync11(getManagerPaths(configDir).stateFile, "utf-8");
|
|
11844
12402
|
return JSON.parse(raw);
|
|
11845
12403
|
} catch {
|
|
11846
12404
|
return null;
|
|
@@ -12036,7 +12594,7 @@ function managerStartCommand(opts) {
|
|
|
12036
12594
|
process.exitCode = 1;
|
|
12037
12595
|
return;
|
|
12038
12596
|
}
|
|
12039
|
-
const configDir = opts.configDir ??
|
|
12597
|
+
const configDir = opts.configDir ?? join12(homedir8(), ".augmented");
|
|
12040
12598
|
if (opts.supervise) {
|
|
12041
12599
|
if (json) {
|
|
12042
12600
|
jsonOutput({ ok: false, error: "--supervise is not supported with --json" });
|
|
@@ -12132,7 +12690,7 @@ function runSupervisorLoop(intervalSec, configDir) {
|
|
|
12132
12690
|
}
|
|
12133
12691
|
async function managerStopCommand(opts = {}) {
|
|
12134
12692
|
const json = isJsonMode();
|
|
12135
|
-
const configDir = opts.configDir ??
|
|
12693
|
+
const configDir = opts.configDir ?? join12(homedir8(), ".augmented");
|
|
12136
12694
|
try {
|
|
12137
12695
|
const result = await stopWatchdog(configDir);
|
|
12138
12696
|
if (!result.stopped && !result.pid) {
|
|
@@ -12160,7 +12718,7 @@ async function managerStopCommand(opts = {}) {
|
|
|
12160
12718
|
}
|
|
12161
12719
|
function managerStatusCommand(opts = {}) {
|
|
12162
12720
|
const json = isJsonMode();
|
|
12163
|
-
const configDir = opts.configDir ??
|
|
12721
|
+
const configDir = opts.configDir ?? join12(homedir8(), ".augmented");
|
|
12164
12722
|
const status = getManagerStatus(configDir);
|
|
12165
12723
|
if (!status) {
|
|
12166
12724
|
if (json) {
|
|
@@ -12270,7 +12828,7 @@ async function managerInstallCommand(opts = {}) {
|
|
|
12270
12828
|
process.exitCode = 1;
|
|
12271
12829
|
return;
|
|
12272
12830
|
}
|
|
12273
|
-
const configDir = opts.configDir ??
|
|
12831
|
+
const configDir = opts.configDir ?? join12(homedir8(), ".augmented");
|
|
12274
12832
|
const rawAgtBin = process.argv[1];
|
|
12275
12833
|
if (!rawAgtBin) {
|
|
12276
12834
|
const msg = "Could not resolve the agt binary path from argv. Re-run via the installed `agt` command.";
|
|
@@ -12283,7 +12841,7 @@ async function managerInstallCommand(opts = {}) {
|
|
|
12283
12841
|
if (process.platform === "darwin") {
|
|
12284
12842
|
const home = homedir8();
|
|
12285
12843
|
const protectedRoots = ["Documents", "Downloads", "Desktop", "Movies", "Music", "Pictures"];
|
|
12286
|
-
const offending = protectedRoots.map((r) =>
|
|
12844
|
+
const offending = protectedRoots.map((r) => join12(home, r)).find((p) => agtBin === p || agtBin.startsWith(`${p}/`));
|
|
12287
12845
|
if (offending) {
|
|
12288
12846
|
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.`;
|
|
12289
12847
|
if (json) jsonOutput({ ok: false, error: msg });
|
|
@@ -12349,7 +12907,7 @@ async function managerInstallSystemUnitCommand(opts = {}) {
|
|
|
12349
12907
|
return;
|
|
12350
12908
|
}
|
|
12351
12909
|
const user = opts.user ?? "root";
|
|
12352
|
-
const configDir = opts.configDir ?? (user === "root" ? "/root/.augmented" :
|
|
12910
|
+
const configDir = opts.configDir ?? (user === "root" ? "/root/.augmented" : join12("/home", user, ".augmented"));
|
|
12353
12911
|
const rawAgtBin = process.argv[1];
|
|
12354
12912
|
if (!rawAgtBin) {
|
|
12355
12913
|
const msg = "Could not resolve the agt binary path from argv. Re-run via the installed `agt` command.";
|
|
@@ -12570,12 +13128,17 @@ export {
|
|
|
12570
13128
|
COMPUTER_USE_MCP_KEY,
|
|
12571
13129
|
extractCommandNotFound,
|
|
12572
13130
|
describeChannelWriteFailure,
|
|
13131
|
+
shellGuard,
|
|
13132
|
+
RM_POLICY_RELATIVE_PATH,
|
|
13133
|
+
guardrailsForProvision,
|
|
13134
|
+
parseRmPolicy,
|
|
12573
13135
|
migrateAgentDirToIdKeyed,
|
|
12574
13136
|
reapLegacyTokenFile,
|
|
12575
13137
|
provisionStopHook,
|
|
12576
13138
|
provisionIsolationHook,
|
|
12577
13139
|
provisionAutoKanbanProgressHook,
|
|
12578
13140
|
provisionChannelProgressHook,
|
|
13141
|
+
provisionRootRmHook,
|
|
12579
13142
|
provisionLongCommandHook,
|
|
12580
13143
|
provisionOrientHook,
|
|
12581
13144
|
provisionPreCompactHook,
|
|
@@ -12664,4 +13227,4 @@ export {
|
|
|
12664
13227
|
managerInstallSystemUnitCommand,
|
|
12665
13228
|
managerUninstallSystemUnitCommand
|
|
12666
13229
|
};
|
|
12667
|
-
//# sourceMappingURL=chunk-
|
|
13230
|
+
//# sourceMappingURL=chunk-Q272XYOI.js.map
|