@triedotdev/mcp 1.0.37 → 1.0.39
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/README.md +592 -34
- package/dist/{chunk-QFTSX2BX.js → chunk-B3MBKB2U.js} +2016 -172
- package/dist/chunk-B3MBKB2U.js.map +1 -0
- package/dist/{chunk-VSCPOIWS.js → chunk-HG5AWUH7.js} +536 -61
- package/dist/chunk-HG5AWUH7.js.map +1 -0
- package/dist/cli/main.js +5 -0
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/yolo-daemon.js +9 -2
- package/dist/cli/yolo-daemon.js.map +1 -1
- package/dist/index.js +62 -6
- package/dist/index.js.map +1 -1
- package/dist/workers/agent-worker.js +1 -1
- package/package.json +2 -3
- package/QUICK_START.md +0 -228
- package/dist/chunk-QFTSX2BX.js.map +0 -1
- package/dist/chunk-VSCPOIWS.js.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
CustomAgent,
|
|
3
3
|
getAgentRegistry
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-B3MBKB2U.js";
|
|
5
5
|
import {
|
|
6
6
|
ProgressReporter
|
|
7
7
|
} from "./chunk-OB45V2QC.js";
|
|
@@ -21,9 +21,9 @@ import {
|
|
|
21
21
|
} from "./chunk-DGUM43GV.js";
|
|
22
22
|
|
|
23
23
|
// src/tools/scan.ts
|
|
24
|
-
import { readFile as
|
|
25
|
-
import { existsSync as
|
|
26
|
-
import { basename as basename6, isAbsolute, resolve as resolve2, join as
|
|
24
|
+
import { readFile as readFile9, readdir as readdir2, writeFile as writeFile4 } from "fs/promises";
|
|
25
|
+
import { existsSync as existsSync6 } from "fs";
|
|
26
|
+
import { basename as basename6, isAbsolute, resolve as resolve2, join as join7, extname as extname3 } from "path";
|
|
27
27
|
|
|
28
28
|
// src/orchestrator/context-analyzer.ts
|
|
29
29
|
import { readFile } from "fs/promises";
|
|
@@ -650,11 +650,366 @@ var RiskAssessor = class {
|
|
|
650
650
|
}
|
|
651
651
|
};
|
|
652
652
|
|
|
653
|
+
// src/utils/context-state.ts
|
|
654
|
+
import { readFile as readFile2, writeFile, mkdir } from "fs/promises";
|
|
655
|
+
import { existsSync as existsSync2 } from "fs";
|
|
656
|
+
import { join } from "path";
|
|
657
|
+
var AGENTS_MD_PATH = ".trie/AGENTS.md";
|
|
658
|
+
var STATE_JSON_PATH = ".trie/state.json";
|
|
659
|
+
async function loadContextState() {
|
|
660
|
+
const workDir = getWorkingDirectory(void 0, true);
|
|
661
|
+
const statePath = join(workDir, STATE_JSON_PATH);
|
|
662
|
+
try {
|
|
663
|
+
if (existsSync2(statePath)) {
|
|
664
|
+
const content = await readFile2(statePath, "utf-8");
|
|
665
|
+
return JSON.parse(content);
|
|
666
|
+
}
|
|
667
|
+
} catch {
|
|
668
|
+
}
|
|
669
|
+
return getDefaultState();
|
|
670
|
+
}
|
|
671
|
+
async function saveContextState(state) {
|
|
672
|
+
const workDir = getWorkingDirectory(void 0, true);
|
|
673
|
+
const trieDir = join(workDir, ".trie");
|
|
674
|
+
const statePath = join(workDir, STATE_JSON_PATH);
|
|
675
|
+
await mkdir(trieDir, { recursive: true });
|
|
676
|
+
await writeFile(statePath, JSON.stringify(state, null, 2));
|
|
677
|
+
}
|
|
678
|
+
async function updateContextAfterScan(results, filesScanned, contextSignals, duration) {
|
|
679
|
+
const state = await loadContextState();
|
|
680
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
681
|
+
const allIssues = results.flatMap((r) => r.issues);
|
|
682
|
+
const issueCounts = {
|
|
683
|
+
critical: allIssues.filter((i) => i.severity === "critical").length,
|
|
684
|
+
serious: allIssues.filter((i) => i.severity === "serious").length,
|
|
685
|
+
moderate: allIssues.filter((i) => i.severity === "moderate").length,
|
|
686
|
+
low: allIssues.filter((i) => i.severity === "low").length,
|
|
687
|
+
total: allIssues.length
|
|
688
|
+
};
|
|
689
|
+
const fileIssueMap = /* @__PURE__ */ new Map();
|
|
690
|
+
for (const issue of allIssues) {
|
|
691
|
+
const count = fileIssueMap.get(issue.file) || 0;
|
|
692
|
+
fileIssueMap.set(issue.file, count + 1);
|
|
693
|
+
}
|
|
694
|
+
const hotFiles = Array.from(fileIssueMap.entries()).sort((a, b) => b[1] - a[1]).slice(0, 10).map(([file, issueCount]) => ({ file, issueCount }));
|
|
695
|
+
const scanSummary = {
|
|
696
|
+
timestamp: now,
|
|
697
|
+
agents: results.map((r) => r.agent),
|
|
698
|
+
filesScanned,
|
|
699
|
+
issues: issueCounts,
|
|
700
|
+
duration,
|
|
701
|
+
hotFiles
|
|
702
|
+
};
|
|
703
|
+
for (const result of results) {
|
|
704
|
+
state.agentStatus[result.agent] = {
|
|
705
|
+
lastRun: now,
|
|
706
|
+
issuesFound: result.issues.length
|
|
707
|
+
};
|
|
708
|
+
}
|
|
709
|
+
const criticalPenalty = issueCounts.critical * 25;
|
|
710
|
+
const seriousPenalty = issueCounts.serious * 10;
|
|
711
|
+
const moderatePenalty = issueCounts.moderate * 3;
|
|
712
|
+
const lowPenalty = issueCounts.low * 1;
|
|
713
|
+
const totalPenalty = Math.min(100, criticalPenalty + seriousPenalty + moderatePenalty + lowPenalty);
|
|
714
|
+
state.healthScore = Math.max(0, 100 - totalPenalty);
|
|
715
|
+
state.activePriorities = generatePriorities(issueCounts, contextSignals);
|
|
716
|
+
state.contextSignals = { ...state.contextSignals, ...contextSignals };
|
|
717
|
+
state.scanHistory = [scanSummary, ...state.scanHistory.slice(0, 19)];
|
|
718
|
+
state.lastScan = scanSummary;
|
|
719
|
+
await saveContextState(state);
|
|
720
|
+
await updateAgentsMd(state);
|
|
721
|
+
}
|
|
722
|
+
async function updateAgentsMd(state) {
|
|
723
|
+
const workDir = getWorkingDirectory(void 0, true);
|
|
724
|
+
const mdPath = join(workDir, AGENTS_MD_PATH);
|
|
725
|
+
let content;
|
|
726
|
+
try {
|
|
727
|
+
content = await readFile2(mdPath, "utf-8");
|
|
728
|
+
} catch {
|
|
729
|
+
content = getAgentsMdTemplate();
|
|
730
|
+
}
|
|
731
|
+
content = updateSection(content, "Project State", generateProjectStateTable(state));
|
|
732
|
+
content = updateSection(content, "Active Priorities", generatePrioritiesList(state));
|
|
733
|
+
content = updateSection(content, "Agent Status", generateAgentStatusTable(state));
|
|
734
|
+
content = updateSection(content, "Recent Scan History", generateScanHistoryTable(state));
|
|
735
|
+
content = updateSection(content, "Context Signals Detected", generateContextSignals(state));
|
|
736
|
+
content = updateSection(content, "Risk Assessment", generateRiskAssessment(state));
|
|
737
|
+
content = updateSection(content, "Hot Files", generateHotFilesSection(state));
|
|
738
|
+
content = content.replace(
|
|
739
|
+
/Last updated:.*$/m,
|
|
740
|
+
`Last updated: ${(/* @__PURE__ */ new Date()).toISOString()}`
|
|
741
|
+
);
|
|
742
|
+
await writeFile(mdPath, content);
|
|
743
|
+
}
|
|
744
|
+
function updateSection(content, sectionName, newContent) {
|
|
745
|
+
const sectionRegex = new RegExp(
|
|
746
|
+
`(### ${sectionName}[\\s\\S]*?)(?=###|---|
|
|
747
|
+
## |$)`,
|
|
748
|
+
"g"
|
|
749
|
+
);
|
|
750
|
+
const replacement = `### ${sectionName}
|
|
751
|
+
${newContent}
|
|
752
|
+
|
|
753
|
+
`;
|
|
754
|
+
if (content.match(sectionRegex)) {
|
|
755
|
+
return content.replace(sectionRegex, replacement);
|
|
756
|
+
}
|
|
757
|
+
return content;
|
|
758
|
+
}
|
|
759
|
+
function generateProjectStateTable(state) {
|
|
760
|
+
const lastScan = state.lastScan;
|
|
761
|
+
const lastScanDate = lastScan ? new Date(lastScan.timestamp).toLocaleString() : "Never";
|
|
762
|
+
const criticalCount = lastScan?.issues.critical ?? 0;
|
|
763
|
+
const totalTasks = lastScan?.issues.total ?? 0;
|
|
764
|
+
return `| Metric | Value | Updated |
|
|
765
|
+
|--------|-------|---------|
|
|
766
|
+
| Last Scan | ${lastScanDate} | ${lastScan ? "Auto" : "-"} |
|
|
767
|
+
| Critical Issues | ${criticalCount} | ${lastScan ? "Auto" : "-"} |
|
|
768
|
+
| Open Tasks | ${totalTasks} | ${lastScan ? "Auto" : "-"} |
|
|
769
|
+
| Health Score | ${state.healthScore}% | ${lastScan ? "Auto" : "-"} |`;
|
|
770
|
+
}
|
|
771
|
+
function generatePrioritiesList(state) {
|
|
772
|
+
if (state.activePriorities.length === 0) {
|
|
773
|
+
return "_No active priorities. Run a scan to identify issues._";
|
|
774
|
+
}
|
|
775
|
+
return state.activePriorities.map((p, i) => `${i + 1}. ${p}`).join("\n");
|
|
776
|
+
}
|
|
777
|
+
function generatePriorities(issues, contextSignals) {
|
|
778
|
+
const priorities = [];
|
|
779
|
+
if (issues.critical > 0) {
|
|
780
|
+
priorities.push(`\u{1F6A8} Fix ${issues.critical} critical security issue${issues.critical > 1 ? "s" : ""} immediately`);
|
|
781
|
+
}
|
|
782
|
+
if (issues.serious > 0) {
|
|
783
|
+
priorities.push(`\u26A0\uFE0F Address ${issues.serious} serious issue${issues.serious > 1 ? "s" : ""} before deployment`);
|
|
784
|
+
}
|
|
785
|
+
if (contextSignals.touchesAuth && issues.critical === 0) {
|
|
786
|
+
priorities.push("\u2705 Auth code reviewed - continue monitoring");
|
|
787
|
+
}
|
|
788
|
+
if (contextSignals.touchesPayments) {
|
|
789
|
+
priorities.push("\u{1F4B3} Payment code detected - ensure PCI compliance");
|
|
790
|
+
}
|
|
791
|
+
if (contextSignals.touchesUserData) {
|
|
792
|
+
priorities.push("\u{1F510} User data handling detected - verify privacy compliance");
|
|
793
|
+
}
|
|
794
|
+
if (issues.moderate > 5) {
|
|
795
|
+
priorities.push(`\u{1F4CB} Schedule time to address ${issues.moderate} moderate issues`);
|
|
796
|
+
}
|
|
797
|
+
if (priorities.length === 0) {
|
|
798
|
+
priorities.push("\u2728 No critical issues - focus on feature development");
|
|
799
|
+
}
|
|
800
|
+
return priorities.slice(0, 5);
|
|
801
|
+
}
|
|
802
|
+
function generateAgentStatusTable(state) {
|
|
803
|
+
const builtInAgents = [
|
|
804
|
+
"security",
|
|
805
|
+
"privacy",
|
|
806
|
+
"legal",
|
|
807
|
+
"accessibility",
|
|
808
|
+
"bugs",
|
|
809
|
+
"design",
|
|
810
|
+
"architecture",
|
|
811
|
+
"performance",
|
|
812
|
+
"devops",
|
|
813
|
+
"soc2",
|
|
814
|
+
"e2e",
|
|
815
|
+
"typecheck",
|
|
816
|
+
"visual-qa",
|
|
817
|
+
"data-flow"
|
|
818
|
+
];
|
|
819
|
+
let table = `| Agent | Status | Last Run | Issues Found |
|
|
820
|
+
|-------|--------|----------|--------------|`;
|
|
821
|
+
for (const agent of builtInAgents) {
|
|
822
|
+
const status = state.agentStatus[agent];
|
|
823
|
+
const lastRun = status?.lastRun ? new Date(status.lastRun).toLocaleDateString() : "Never";
|
|
824
|
+
const issues = status?.issuesFound ?? "-";
|
|
825
|
+
const statusEmoji = status ? "\u2705" : "\u23F8\uFE0F";
|
|
826
|
+
table += `
|
|
827
|
+
| ${agent} | ${statusEmoji} Ready | ${lastRun} | ${issues} |`;
|
|
828
|
+
}
|
|
829
|
+
return table;
|
|
830
|
+
}
|
|
831
|
+
function generateScanHistoryTable(state) {
|
|
832
|
+
if (state.scanHistory.length === 0) {
|
|
833
|
+
return `| Date | Agents | Files | Issues | Duration |
|
|
834
|
+
|------|--------|-------|--------|----------|
|
|
835
|
+
| - | - | - | - | - |`;
|
|
836
|
+
}
|
|
837
|
+
let table = `| Date | Agents | Files | Issues | Duration |
|
|
838
|
+
|------|--------|-------|--------|----------|`;
|
|
839
|
+
for (const scan of state.scanHistory.slice(0, 10)) {
|
|
840
|
+
const date = new Date(scan.timestamp).toLocaleDateString();
|
|
841
|
+
const agents = scan.agents.slice(0, 3).join(", ") + (scan.agents.length > 3 ? "..." : "");
|
|
842
|
+
const duration = `${(scan.duration / 1e3).toFixed(1)}s`;
|
|
843
|
+
table += `
|
|
844
|
+
| ${date} | ${agents} | ${scan.filesScanned} | ${scan.issues.total} | ${duration} |`;
|
|
845
|
+
}
|
|
846
|
+
return table;
|
|
847
|
+
}
|
|
848
|
+
function generateContextSignals(state) {
|
|
849
|
+
const signals = [
|
|
850
|
+
"touchesAuth",
|
|
851
|
+
"touchesPayments",
|
|
852
|
+
"touchesUserData",
|
|
853
|
+
"touchesAPI",
|
|
854
|
+
"touchesDatabase",
|
|
855
|
+
"touchesCrypto"
|
|
856
|
+
];
|
|
857
|
+
return signals.map((s) => {
|
|
858
|
+
const value = state.contextSignals[s];
|
|
859
|
+
const emoji = value === true ? "\u2705" : value === false ? "\u274C" : "\u2753";
|
|
860
|
+
return `- \`${s}\`: ${emoji} ${value === void 0 ? "Unknown" : value ? "Yes" : "No"}`;
|
|
861
|
+
}).join("\n");
|
|
862
|
+
}
|
|
863
|
+
function generateRiskAssessment(state) {
|
|
864
|
+
const score = state.healthScore;
|
|
865
|
+
let riskLevel;
|
|
866
|
+
let confidence;
|
|
867
|
+
if (state.lastScan === null) {
|
|
868
|
+
return `- Overall Risk: Unknown
|
|
869
|
+
- Confidence: 0%`;
|
|
870
|
+
}
|
|
871
|
+
if (score >= 90) {
|
|
872
|
+
riskLevel = "\u{1F7E2} Low";
|
|
873
|
+
confidence = 95;
|
|
874
|
+
} else if (score >= 70) {
|
|
875
|
+
riskLevel = "\u{1F7E1} Medium";
|
|
876
|
+
confidence = 85;
|
|
877
|
+
} else if (score >= 50) {
|
|
878
|
+
riskLevel = "\u{1F7E0} High";
|
|
879
|
+
confidence = 80;
|
|
880
|
+
} else {
|
|
881
|
+
riskLevel = "\u{1F534} Critical";
|
|
882
|
+
confidence = 90;
|
|
883
|
+
}
|
|
884
|
+
return `- Overall Risk: ${riskLevel}
|
|
885
|
+
- Health Score: ${score}%
|
|
886
|
+
- Confidence: ${confidence}%`;
|
|
887
|
+
}
|
|
888
|
+
function generateHotFilesSection(state) {
|
|
889
|
+
if (!state.lastScan || state.lastScan.hotFiles.length === 0) {
|
|
890
|
+
return "_Run a scan to identify hot files._";
|
|
891
|
+
}
|
|
892
|
+
return state.lastScan.hotFiles.map((f) => `- \`${f.file}\` - ${f.issueCount} issue${f.issueCount > 1 ? "s" : ""}`).join("\n");
|
|
893
|
+
}
|
|
894
|
+
function getDefaultState() {
|
|
895
|
+
return {
|
|
896
|
+
lastScan: null,
|
|
897
|
+
healthScore: 0,
|
|
898
|
+
activePriorities: [
|
|
899
|
+
"Initial setup required - run first scan with `trie scan`",
|
|
900
|
+
"Configure agents in `.trie/config.json`",
|
|
901
|
+
"Set up CI/CD integration"
|
|
902
|
+
],
|
|
903
|
+
contextSignals: {},
|
|
904
|
+
agentStatus: {},
|
|
905
|
+
scanHistory: [],
|
|
906
|
+
customAgents: []
|
|
907
|
+
};
|
|
908
|
+
}
|
|
909
|
+
function getAgentsMdTemplate() {
|
|
910
|
+
return `# Trie Agent Context
|
|
911
|
+
|
|
912
|
+
> **Auto-generated file** - Updated automatically when agents run.
|
|
913
|
+
> Last updated: Never (initial state)
|
|
914
|
+
|
|
915
|
+
This file provides prioritized context for all AI coding assistants working with this codebase.
|
|
916
|
+
Agents should read this file first and update it after completing scans.
|
|
917
|
+
|
|
918
|
+
---
|
|
919
|
+
|
|
920
|
+
## Quick Context (Read First)
|
|
921
|
+
|
|
922
|
+
### Project State
|
|
923
|
+
| Metric | Value | Updated |
|
|
924
|
+
|--------|-------|---------|
|
|
925
|
+
| Last Scan | Never | - |
|
|
926
|
+
| Critical Issues | 0 | - |
|
|
927
|
+
| Open Tasks | 0 | - |
|
|
928
|
+
| Health Score | Unknown | - |
|
|
929
|
+
|
|
930
|
+
### Active Priorities
|
|
931
|
+
1. Initial setup required - run first scan with \`trie scan\`
|
|
932
|
+
2. Configure agents in \`.trie/config.json\`
|
|
933
|
+
3. Set up CI/CD integration
|
|
934
|
+
|
|
935
|
+
### Hot Files
|
|
936
|
+
_Run a scan to identify hot files._
|
|
937
|
+
|
|
938
|
+
---
|
|
939
|
+
|
|
940
|
+
## Agent Status
|
|
941
|
+
|
|
942
|
+
### Agent Status
|
|
943
|
+
| Agent | Status | Last Run | Issues Found |
|
|
944
|
+
|-------|--------|----------|--------------|
|
|
945
|
+
| security | Ready | Never | - |
|
|
946
|
+
| privacy | Ready | Never | - |
|
|
947
|
+
| bugs | Ready | Never | - |
|
|
948
|
+
|
|
949
|
+
### Recent Scan History
|
|
950
|
+
| Date | Agents | Files | Issues | Duration |
|
|
951
|
+
|------|--------|-------|--------|----------|
|
|
952
|
+
| - | - | - | - | - |
|
|
953
|
+
|
|
954
|
+
---
|
|
955
|
+
|
|
956
|
+
## Context Analysis
|
|
957
|
+
|
|
958
|
+
### Context Signals Detected
|
|
959
|
+
- \`touchesAuth\`: Unknown
|
|
960
|
+
- \`touchesPayments\`: Unknown
|
|
961
|
+
- \`touchesUserData\`: Unknown
|
|
962
|
+
- \`touchesAPI\`: Unknown
|
|
963
|
+
- \`touchesDatabase\`: Unknown
|
|
964
|
+
- \`touchesCrypto\`: Unknown
|
|
965
|
+
|
|
966
|
+
### Risk Assessment
|
|
967
|
+
- Overall Risk: Unknown
|
|
968
|
+
- Confidence: 0%
|
|
969
|
+
|
|
970
|
+
---
|
|
971
|
+
|
|
972
|
+
*This file is maintained by Trie agents. Manual edits will be preserved in non-auto sections.*
|
|
973
|
+
`;
|
|
974
|
+
}
|
|
975
|
+
async function getContextForAI() {
|
|
976
|
+
const state = await loadContextState();
|
|
977
|
+
const lines = [
|
|
978
|
+
"## Trie Context Summary",
|
|
979
|
+
"",
|
|
980
|
+
`**Health Score:** ${state.healthScore}%`,
|
|
981
|
+
`**Last Scan:** ${state.lastScan ? new Date(state.lastScan.timestamp).toLocaleString() : "Never"}`,
|
|
982
|
+
"",
|
|
983
|
+
"**Active Priorities:**",
|
|
984
|
+
...state.activePriorities.map((p) => `- ${p}`),
|
|
985
|
+
""
|
|
986
|
+
];
|
|
987
|
+
if (state.lastScan) {
|
|
988
|
+
lines.push(
|
|
989
|
+
"**Recent Issues:**",
|
|
990
|
+
`- Critical: ${state.lastScan.issues.critical}`,
|
|
991
|
+
`- Serious: ${state.lastScan.issues.serious}`,
|
|
992
|
+
`- Moderate: ${state.lastScan.issues.moderate}`,
|
|
993
|
+
`- Low: ${state.lastScan.issues.low}`,
|
|
994
|
+
""
|
|
995
|
+
);
|
|
996
|
+
if (state.lastScan.hotFiles.length > 0) {
|
|
997
|
+
lines.push(
|
|
998
|
+
"**Hot Files (most issues):**",
|
|
999
|
+
...state.lastScan.hotFiles.slice(0, 5).map((f) => `- ${f.file}: ${f.issueCount} issues`),
|
|
1000
|
+
""
|
|
1001
|
+
);
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
return lines.join("\n");
|
|
1005
|
+
}
|
|
1006
|
+
|
|
653
1007
|
// src/orchestrator/triager.ts
|
|
654
1008
|
var Triager = class {
|
|
655
1009
|
agentRegistry = getAgentRegistry();
|
|
656
1010
|
config;
|
|
657
1011
|
customAgentsLoaded = false;
|
|
1012
|
+
contextState = null;
|
|
658
1013
|
constructor(config) {
|
|
659
1014
|
this.config = {
|
|
660
1015
|
minConfidence: 0.15,
|
|
@@ -665,6 +1020,18 @@ var Triager = class {
|
|
|
665
1020
|
...config
|
|
666
1021
|
};
|
|
667
1022
|
}
|
|
1023
|
+
/**
|
|
1024
|
+
* Load previous context state for smart triaging
|
|
1025
|
+
*/
|
|
1026
|
+
async loadPreviousContext() {
|
|
1027
|
+
if (this.contextState === null) {
|
|
1028
|
+
try {
|
|
1029
|
+
this.contextState = await loadContextState();
|
|
1030
|
+
} catch {
|
|
1031
|
+
this.contextState = null;
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
668
1035
|
/**
|
|
669
1036
|
* Ensure custom agents are loaded before triaging
|
|
670
1037
|
*/
|
|
@@ -676,11 +1043,20 @@ var Triager = class {
|
|
|
676
1043
|
}
|
|
677
1044
|
async selectAgents(context, riskLevel) {
|
|
678
1045
|
await this.ensureCustomAgentsLoaded();
|
|
679
|
-
|
|
680
|
-
|
|
1046
|
+
await this.loadPreviousContext();
|
|
1047
|
+
let effectiveRiskLevel = riskLevel;
|
|
1048
|
+
if (this.contextState?.healthScore !== void 0 && this.contextState.healthScore < 50) {
|
|
1049
|
+
if (riskLevel === "low" || riskLevel === "medium") {
|
|
1050
|
+
effectiveRiskLevel = "high";
|
|
1051
|
+
console.error(` \u{1F4CA} Health score ${this.contextState.healthScore}% - escalating to ${effectiveRiskLevel.toUpperCase()} risk`);
|
|
1052
|
+
}
|
|
1053
|
+
}
|
|
1054
|
+
if (effectiveRiskLevel === "critical" || effectiveRiskLevel === "high") {
|
|
1055
|
+
console.error(` \u26A0\uFE0F ${effectiveRiskLevel.toUpperCase()} risk - activating all agents for comprehensive review`);
|
|
681
1056
|
return this.getAllAgents();
|
|
682
1057
|
}
|
|
683
|
-
const scores = this.scoreAgents(context,
|
|
1058
|
+
const scores = this.scoreAgents(context, effectiveRiskLevel);
|
|
1059
|
+
this.boostAgentsWithHistory(scores);
|
|
684
1060
|
this.logAgentScoring(scores);
|
|
685
1061
|
const qualified = scores.filter((s) => s.confidence >= this.config.minConfidence);
|
|
686
1062
|
qualified.sort((a, b) => {
|
|
@@ -692,6 +1068,20 @@ var Triager = class {
|
|
|
692
1068
|
}
|
|
693
1069
|
return qualified.map((s) => s.agent);
|
|
694
1070
|
}
|
|
1071
|
+
/**
|
|
1072
|
+
* Boost confidence for agents that found issues in previous scans
|
|
1073
|
+
*/
|
|
1074
|
+
boostAgentsWithHistory(scores) {
|
|
1075
|
+
if (!this.contextState?.agentStatus) return;
|
|
1076
|
+
for (const score of scores) {
|
|
1077
|
+
const previousRun = this.contextState.agentStatus[score.agent.name];
|
|
1078
|
+
if (previousRun?.issuesFound && previousRun.issuesFound > 0) {
|
|
1079
|
+
const boost = Math.min(0.3, previousRun.issuesFound * 0.05);
|
|
1080
|
+
score.confidence = Math.min(1, score.confidence + boost);
|
|
1081
|
+
score.reasons.push(`found ${previousRun.issuesFound} issues in last scan`);
|
|
1082
|
+
}
|
|
1083
|
+
}
|
|
1084
|
+
}
|
|
695
1085
|
scoreAgents(context, riskLevel) {
|
|
696
1086
|
const allAgents = this.getAllAgents();
|
|
697
1087
|
const scores = [];
|
|
@@ -998,6 +1388,64 @@ var Triager = class {
|
|
|
998
1388
|
reasons.push("data access");
|
|
999
1389
|
}
|
|
1000
1390
|
}
|
|
1391
|
+
if (agent.name === "moneybags") {
|
|
1392
|
+
tier = 3;
|
|
1393
|
+
if (context.touchesPayments) {
|
|
1394
|
+
confidence += 0.6;
|
|
1395
|
+
reasons.push("payment code = high cost risk");
|
|
1396
|
+
}
|
|
1397
|
+
if (context.touchesAuth) {
|
|
1398
|
+
confidence += 0.4;
|
|
1399
|
+
reasons.push("auth bugs are expensive");
|
|
1400
|
+
}
|
|
1401
|
+
if (context.touchesHealthData) {
|
|
1402
|
+
confidence += 0.5;
|
|
1403
|
+
reasons.push("HIPAA violations");
|
|
1404
|
+
}
|
|
1405
|
+
if (context.touchesUserData) {
|
|
1406
|
+
confidence += 0.3;
|
|
1407
|
+
reasons.push("PII exposure costs");
|
|
1408
|
+
}
|
|
1409
|
+
if (context.touchesDatabase) {
|
|
1410
|
+
confidence += 0.25;
|
|
1411
|
+
reasons.push("data loss risk");
|
|
1412
|
+
}
|
|
1413
|
+
if (context.isNewFeature) {
|
|
1414
|
+
confidence += 0.2;
|
|
1415
|
+
reasons.push("new code risk");
|
|
1416
|
+
}
|
|
1417
|
+
if (riskLevel === "high" || riskLevel === "critical") {
|
|
1418
|
+
confidence *= 1.3;
|
|
1419
|
+
reasons.push("high-stakes context");
|
|
1420
|
+
}
|
|
1421
|
+
}
|
|
1422
|
+
if (agent.name === "production-ready") {
|
|
1423
|
+
tier = 3;
|
|
1424
|
+
if (context.touchesAPI) {
|
|
1425
|
+
confidence += 0.4;
|
|
1426
|
+
reasons.push("API deployment");
|
|
1427
|
+
}
|
|
1428
|
+
if (context.touchesDatabase) {
|
|
1429
|
+
confidence += 0.35;
|
|
1430
|
+
reasons.push("database operations");
|
|
1431
|
+
}
|
|
1432
|
+
if (context.touchesAuth) {
|
|
1433
|
+
confidence += 0.35;
|
|
1434
|
+
reasons.push("auth system");
|
|
1435
|
+
}
|
|
1436
|
+
if (context.touchesPayments) {
|
|
1437
|
+
confidence += 0.5;
|
|
1438
|
+
reasons.push("payment processing");
|
|
1439
|
+
}
|
|
1440
|
+
if (context.linesChanged > 200) {
|
|
1441
|
+
confidence += 0.3;
|
|
1442
|
+
reasons.push("significant changes");
|
|
1443
|
+
}
|
|
1444
|
+
if (riskLevel === "high" || riskLevel === "critical") {
|
|
1445
|
+
confidence += 0.4;
|
|
1446
|
+
reasons.push("production gate check");
|
|
1447
|
+
}
|
|
1448
|
+
}
|
|
1001
1449
|
confidence = Math.min(1, confidence);
|
|
1002
1450
|
return { agent, confidence, reasons, tier, isCustom: false };
|
|
1003
1451
|
}
|
|
@@ -1373,8 +1821,8 @@ function calculateOptimalConcurrency() {
|
|
|
1373
1821
|
}
|
|
1374
1822
|
|
|
1375
1823
|
// src/utils/cache-manager.ts
|
|
1376
|
-
import { readFile as
|
|
1377
|
-
import { join } from "path";
|
|
1824
|
+
import { readFile as readFile3, writeFile as writeFile2, mkdir as mkdir2, stat } from "fs/promises";
|
|
1825
|
+
import { join as join2 } from "path";
|
|
1378
1826
|
import { createHash } from "crypto";
|
|
1379
1827
|
var CacheManager = class {
|
|
1380
1828
|
cacheDir;
|
|
@@ -1384,8 +1832,8 @@ var CacheManager = class {
|
|
|
1384
1832
|
// 24 hours
|
|
1385
1833
|
MAX_ENTRIES = 1e3;
|
|
1386
1834
|
constructor(baseDir) {
|
|
1387
|
-
this.cacheDir =
|
|
1388
|
-
this.indexPath =
|
|
1835
|
+
this.cacheDir = join2(baseDir, ".trie", "cache");
|
|
1836
|
+
this.indexPath = join2(this.cacheDir, "index.json");
|
|
1389
1837
|
}
|
|
1390
1838
|
/**
|
|
1391
1839
|
* Generate cache key for a file and agent combination
|
|
@@ -1399,7 +1847,7 @@ var CacheManager = class {
|
|
|
1399
1847
|
*/
|
|
1400
1848
|
async getFileHash(filePath) {
|
|
1401
1849
|
try {
|
|
1402
|
-
const content = await
|
|
1850
|
+
const content = await readFile3(filePath, "utf-8");
|
|
1403
1851
|
const stats = await stat(filePath);
|
|
1404
1852
|
const hash = createHash("sha256").update(content).digest("hex").slice(0, 16);
|
|
1405
1853
|
return {
|
|
@@ -1416,7 +1864,7 @@ var CacheManager = class {
|
|
|
1416
1864
|
*/
|
|
1417
1865
|
async loadIndex() {
|
|
1418
1866
|
try {
|
|
1419
|
-
const content = await
|
|
1867
|
+
const content = await readFile3(this.indexPath, "utf-8");
|
|
1420
1868
|
return JSON.parse(content);
|
|
1421
1869
|
} catch {
|
|
1422
1870
|
return {
|
|
@@ -1431,8 +1879,8 @@ var CacheManager = class {
|
|
|
1431
1879
|
*/
|
|
1432
1880
|
async saveIndex(index) {
|
|
1433
1881
|
try {
|
|
1434
|
-
await
|
|
1435
|
-
await
|
|
1882
|
+
await mkdir2(this.cacheDir, { recursive: true });
|
|
1883
|
+
await writeFile2(this.indexPath, JSON.stringify(index, null, 2));
|
|
1436
1884
|
} catch (error) {
|
|
1437
1885
|
console.warn("Failed to save cache index:", error);
|
|
1438
1886
|
}
|
|
@@ -1639,8 +2087,8 @@ var Executor = class {
|
|
|
1639
2087
|
};
|
|
1640
2088
|
|
|
1641
2089
|
// src/analysis/cross-file.ts
|
|
1642
|
-
import { readFile as
|
|
1643
|
-
import { join as
|
|
2090
|
+
import { readFile as readFile4, readdir } from "fs/promises";
|
|
2091
|
+
import { join as join3, extname as extname2, relative, dirname, basename as basename2 } from "path";
|
|
1644
2092
|
async function buildDependencyGraph(rootDir, maxFiles = 200) {
|
|
1645
2093
|
const files = /* @__PURE__ */ new Map();
|
|
1646
2094
|
const issues = [];
|
|
@@ -1670,7 +2118,7 @@ async function buildDependencyGraph(rootDir, maxFiles = 200) {
|
|
|
1670
2118
|
}
|
|
1671
2119
|
async function parseFile(filePath, rootDir) {
|
|
1672
2120
|
try {
|
|
1673
|
-
const content = await
|
|
2121
|
+
const content = await readFile4(filePath, "utf-8");
|
|
1674
2122
|
const relativePath = relative(rootDir, filePath);
|
|
1675
2123
|
const lines = content.split("\n");
|
|
1676
2124
|
const imports = [];
|
|
@@ -1759,7 +2207,7 @@ function resolveImport(source, fromPath, files) {
|
|
|
1759
2207
|
return null;
|
|
1760
2208
|
}
|
|
1761
2209
|
const fromDir = dirname(fromPath);
|
|
1762
|
-
let resolvedPath =
|
|
2210
|
+
let resolvedPath = join3(fromDir, source);
|
|
1763
2211
|
const extensions = ["", ".ts", ".tsx", ".js", ".jsx", "/index.ts", "/index.tsx", "/index.js"];
|
|
1764
2212
|
for (const ext of extensions) {
|
|
1765
2213
|
const tryPath = resolvedPath + ext;
|
|
@@ -1873,7 +2321,7 @@ async function discoverFiles(dir, maxFiles) {
|
|
|
1873
2321
|
const entries = await readdir(currentDir, { withFileTypes: true });
|
|
1874
2322
|
for (const entry of entries) {
|
|
1875
2323
|
if (files.length >= maxFiles) break;
|
|
1876
|
-
const fullPath =
|
|
2324
|
+
const fullPath = join3(currentDir, entry.name);
|
|
1877
2325
|
if (entry.isDirectory()) {
|
|
1878
2326
|
if (!skipDirs.has(entry.name) && !entry.name.startsWith(".")) {
|
|
1879
2327
|
await walk(fullPath);
|
|
@@ -1980,7 +2428,7 @@ ${"\u2501".repeat(60)}
|
|
|
1980
2428
|
}
|
|
1981
2429
|
|
|
1982
2430
|
// src/analysis/semantic-analyzer.ts
|
|
1983
|
-
import { readFile as
|
|
2431
|
+
import { readFile as readFile5 } from "fs/promises";
|
|
1984
2432
|
import { basename as basename3, relative as relative2 } from "path";
|
|
1985
2433
|
var SemanticAnalyzer = class {
|
|
1986
2434
|
functions = [];
|
|
@@ -1993,7 +2441,7 @@ var SemanticAnalyzer = class {
|
|
|
1993
2441
|
async analyze(files, rootDir) {
|
|
1994
2442
|
for (const file of files) {
|
|
1995
2443
|
try {
|
|
1996
|
-
const content = await
|
|
2444
|
+
const content = await readFile5(file, "utf-8");
|
|
1997
2445
|
const relPath = relative2(rootDir, file);
|
|
1998
2446
|
this.detectFramework(content);
|
|
1999
2447
|
this.parseFunctions(content, relPath);
|
|
@@ -2554,7 +3002,7 @@ function formatPrioritizedResults(result) {
|
|
|
2554
3002
|
}
|
|
2555
3003
|
|
|
2556
3004
|
// src/analysis/attack-surface.ts
|
|
2557
|
-
import { readFile as
|
|
3005
|
+
import { readFile as readFile6 } from "fs/promises";
|
|
2558
3006
|
import { basename as basename5, relative as relative3 } from "path";
|
|
2559
3007
|
var AttackSurfaceAnalyzer = class {
|
|
2560
3008
|
endpoints = [];
|
|
@@ -2564,7 +3012,7 @@ var AttackSurfaceAnalyzer = class {
|
|
|
2564
3012
|
async analyze(files, rootDir) {
|
|
2565
3013
|
for (const file of files) {
|
|
2566
3014
|
try {
|
|
2567
|
-
const content = await
|
|
3015
|
+
const content = await readFile6(file, "utf-8");
|
|
2568
3016
|
const relPath = relative3(rootDir, file);
|
|
2569
3017
|
this.findEndpoints(content, relPath);
|
|
2570
3018
|
this.findDataFlows(content, relPath);
|
|
@@ -3309,9 +3757,9 @@ function getSymbolIndex() {
|
|
|
3309
3757
|
|
|
3310
3758
|
// src/trie/incremental-scanner.ts
|
|
3311
3759
|
import { createHash as createHash2 } from "crypto";
|
|
3312
|
-
import { readFile as
|
|
3313
|
-
import { existsSync as
|
|
3314
|
-
import { join as
|
|
3760
|
+
import { readFile as readFile7, writeFile as writeFile3, mkdir as mkdir3 } from "fs/promises";
|
|
3761
|
+
import { existsSync as existsSync3 } from "fs";
|
|
3762
|
+
import { join as join4 } from "path";
|
|
3315
3763
|
var CACHE_VERSION = "1.0.0";
|
|
3316
3764
|
var CACHE_FILE = ".trie-cache.json";
|
|
3317
3765
|
var IncrementalScanner = class {
|
|
@@ -3320,7 +3768,7 @@ var IncrementalScanner = class {
|
|
|
3320
3768
|
cacheDir;
|
|
3321
3769
|
dirty = false;
|
|
3322
3770
|
constructor(projectRoot) {
|
|
3323
|
-
this.cacheDir =
|
|
3771
|
+
this.cacheDir = join4(projectRoot, ".trie");
|
|
3324
3772
|
this.symbolIndex = getSymbolIndex();
|
|
3325
3773
|
this.cache = {
|
|
3326
3774
|
version: CACHE_VERSION,
|
|
@@ -3333,12 +3781,12 @@ var IncrementalScanner = class {
|
|
|
3333
3781
|
* Load cache from disk
|
|
3334
3782
|
*/
|
|
3335
3783
|
async loadCache() {
|
|
3336
|
-
const cachePath =
|
|
3337
|
-
if (!
|
|
3784
|
+
const cachePath = join4(this.cacheDir, CACHE_FILE);
|
|
3785
|
+
if (!existsSync3(cachePath)) {
|
|
3338
3786
|
return false;
|
|
3339
3787
|
}
|
|
3340
3788
|
try {
|
|
3341
|
-
const data = await
|
|
3789
|
+
const data = await readFile7(cachePath, "utf-8");
|
|
3342
3790
|
const parsed = JSON.parse(data);
|
|
3343
3791
|
if (parsed.version !== CACHE_VERSION) {
|
|
3344
3792
|
console.error(" \u26A0\uFE0F Cache version mismatch, rebuilding...");
|
|
@@ -3358,10 +3806,10 @@ var IncrementalScanner = class {
|
|
|
3358
3806
|
async saveCache() {
|
|
3359
3807
|
if (!this.dirty) return;
|
|
3360
3808
|
try {
|
|
3361
|
-
await
|
|
3362
|
-
const cachePath =
|
|
3809
|
+
await mkdir3(this.cacheDir, { recursive: true });
|
|
3810
|
+
const cachePath = join4(this.cacheDir, CACHE_FILE);
|
|
3363
3811
|
this.cache.lastUpdated = Date.now();
|
|
3364
|
-
await
|
|
3812
|
+
await writeFile3(cachePath, JSON.stringify(this.cache, null, 2));
|
|
3365
3813
|
this.dirty = false;
|
|
3366
3814
|
} catch (error) {
|
|
3367
3815
|
console.error(" \u26A0\uFE0F Failed to save cache");
|
|
@@ -3383,7 +3831,7 @@ var IncrementalScanner = class {
|
|
|
3383
3831
|
if (!cached) return true;
|
|
3384
3832
|
if (!content) {
|
|
3385
3833
|
try {
|
|
3386
|
-
content = await
|
|
3834
|
+
content = await readFile7(filePath, "utf-8");
|
|
3387
3835
|
} catch {
|
|
3388
3836
|
return true;
|
|
3389
3837
|
}
|
|
@@ -3398,7 +3846,7 @@ var IncrementalScanner = class {
|
|
|
3398
3846
|
async scanFile(filePath, forceRescan = false) {
|
|
3399
3847
|
let content;
|
|
3400
3848
|
try {
|
|
3401
|
-
content = await
|
|
3849
|
+
content = await readFile7(filePath, "utf-8");
|
|
3402
3850
|
} catch {
|
|
3403
3851
|
return { vulnerabilities: [], fromCache: false, symbolCount: 0 };
|
|
3404
3852
|
}
|
|
@@ -4581,14 +5029,14 @@ var InteractiveDashboard = class {
|
|
|
4581
5029
|
};
|
|
4582
5030
|
|
|
4583
5031
|
// src/config/loader.ts
|
|
4584
|
-
import { readFile as
|
|
4585
|
-
import { existsSync as
|
|
4586
|
-
import { join as
|
|
5032
|
+
import { readFile as readFile8 } from "fs/promises";
|
|
5033
|
+
import { existsSync as existsSync5 } from "fs";
|
|
5034
|
+
import { join as join6 } from "path";
|
|
4587
5035
|
|
|
4588
5036
|
// src/config/validation.ts
|
|
4589
5037
|
import { z } from "zod";
|
|
4590
|
-
import { existsSync as
|
|
4591
|
-
import { resolve, join as
|
|
5038
|
+
import { existsSync as existsSync4, readFileSync } from "fs";
|
|
5039
|
+
import { resolve, join as join5 } from "path";
|
|
4592
5040
|
var API_KEY_PATTERNS = {
|
|
4593
5041
|
anthropic: /^sk-ant-api\d{2}-[\w-]{95}$/,
|
|
4594
5042
|
openai: /^sk-[\w]{48}$/,
|
|
@@ -4701,8 +5149,8 @@ var ConfigValidator = class {
|
|
|
4701
5149
|
let anthropicKey = process.env.ANTHROPIC_API_KEY;
|
|
4702
5150
|
if (!anthropicKey) {
|
|
4703
5151
|
try {
|
|
4704
|
-
const configPath =
|
|
4705
|
-
if (
|
|
5152
|
+
const configPath = join5(getWorkingDirectory(void 0, true), ".trie", "config.json");
|
|
5153
|
+
if (existsSync4(configPath)) {
|
|
4706
5154
|
const config = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
4707
5155
|
anthropicKey = config.apiKeys?.anthropic;
|
|
4708
5156
|
}
|
|
@@ -4732,14 +5180,14 @@ var ConfigValidator = class {
|
|
|
4732
5180
|
if (paths?.include) {
|
|
4733
5181
|
for (const path of paths.include) {
|
|
4734
5182
|
const resolvedPath = resolve(path);
|
|
4735
|
-
if (!
|
|
5183
|
+
if (!existsSync4(resolvedPath)) {
|
|
4736
5184
|
errors.push(`Include path does not exist: ${path}`);
|
|
4737
5185
|
}
|
|
4738
5186
|
}
|
|
4739
5187
|
}
|
|
4740
5188
|
if (paths?.configDir) {
|
|
4741
5189
|
const configPath = resolve(paths.configDir);
|
|
4742
|
-
if (!
|
|
5190
|
+
if (!existsSync4(configPath)) {
|
|
4743
5191
|
try {
|
|
4744
5192
|
__require("fs").mkdirSync(configPath, { recursive: true });
|
|
4745
5193
|
} catch {
|
|
@@ -4859,8 +5307,8 @@ var ConfigValidator = class {
|
|
|
4859
5307
|
const workDir = getWorkingDirectory(void 0, true);
|
|
4860
5308
|
const envFiles = [".env", ".env.local", ".env.production"];
|
|
4861
5309
|
for (const envFile of envFiles) {
|
|
4862
|
-
const envPath =
|
|
4863
|
-
if (
|
|
5310
|
+
const envPath = join5(workDir, envFile);
|
|
5311
|
+
if (existsSync4(envPath)) {
|
|
4864
5312
|
const envContent = readFileSync(envPath, "utf-8");
|
|
4865
5313
|
if (envContent.includes("ANTHROPIC_API_KEY=")) {
|
|
4866
5314
|
hasApiKey = true;
|
|
@@ -4937,12 +5385,12 @@ var DEFAULT_CONFIG = {
|
|
|
4937
5385
|
// src/config/loader.ts
|
|
4938
5386
|
async function loadConfig() {
|
|
4939
5387
|
const validator = new ConfigValidator();
|
|
4940
|
-
const configPath =
|
|
5388
|
+
const configPath = join6(getWorkingDirectory(void 0, true), ".trie", "config.json");
|
|
4941
5389
|
try {
|
|
4942
|
-
if (!
|
|
5390
|
+
if (!existsSync5(configPath)) {
|
|
4943
5391
|
return DEFAULT_CONFIG;
|
|
4944
5392
|
}
|
|
4945
|
-
const configFile = await
|
|
5393
|
+
const configFile = await readFile8(configPath, "utf-8");
|
|
4946
5394
|
const userConfig = JSON.parse(configFile);
|
|
4947
5395
|
const merged = mergeConfig(DEFAULT_CONFIG, userConfig);
|
|
4948
5396
|
const result = validator.validateConfig(merged);
|
|
@@ -5801,7 +6249,7 @@ var TrieScanTool = class {
|
|
|
5801
6249
|
return resolve2(workDir, f);
|
|
5802
6250
|
});
|
|
5803
6251
|
const validFiles = resolvedFiles.filter((f) => {
|
|
5804
|
-
if (!
|
|
6252
|
+
if (!existsSync6(f)) {
|
|
5805
6253
|
this.progress.warn("File not found", f);
|
|
5806
6254
|
return false;
|
|
5807
6255
|
}
|
|
@@ -5863,6 +6311,14 @@ var TrieScanTool = class {
|
|
|
5863
6311
|
const allAgentNames = this.agentRegistry.getAgentNames();
|
|
5864
6312
|
this.logTriaging(selectedAgents.map((a) => a.name), allAgentNames, context, riskLevel);
|
|
5865
6313
|
this.progress.update(`${selectedAgents.length} agents selected for ${riskLevel} risk code`);
|
|
6314
|
+
const userCount = args?.userCount;
|
|
6315
|
+
if (userCount) {
|
|
6316
|
+
const moneybags = selectedAgents.find((a) => a.name === "moneybags");
|
|
6317
|
+
if (moneybags && "configure" in moneybags && typeof moneybags.configure === "function") {
|
|
6318
|
+
moneybags.configure({ userCount });
|
|
6319
|
+
console.error(` \u{1F4B0} Cost estimates scaled for ${userCount.toLocaleString()} users`);
|
|
6320
|
+
}
|
|
6321
|
+
}
|
|
5866
6322
|
this.progress.startPhase("ai-review", "Running AI analysis...");
|
|
5867
6323
|
this.progress.ai("Starting agent analysis", `${selectedAgents.length} agents`);
|
|
5868
6324
|
const agentResults = await this.executor.executeAgents(
|
|
@@ -6021,7 +6477,24 @@ var TrieScanTool = class {
|
|
|
6021
6477
|
prioritization: prioritized,
|
|
6022
6478
|
grouping: priorityReport
|
|
6023
6479
|
};
|
|
6024
|
-
await
|
|
6480
|
+
await writeFile4(args.output, JSON.stringify(report, null, 2));
|
|
6481
|
+
}
|
|
6482
|
+
try {
|
|
6483
|
+
const contextSignals = {
|
|
6484
|
+
touchesAuth: context.touchesAuth ?? false,
|
|
6485
|
+
touchesPayments: context.touchesPayments ?? false,
|
|
6486
|
+
touchesUserData: context.touchesUserData ?? false,
|
|
6487
|
+
touchesAPI: context.touchesAPI ?? false,
|
|
6488
|
+
touchesDatabase: context.touchesDatabase ?? false,
|
|
6489
|
+
touchesCrypto: context.touchesCrypto ?? false
|
|
6490
|
+
};
|
|
6491
|
+
await updateContextAfterScan(
|
|
6492
|
+
agentResults,
|
|
6493
|
+
validFiles.length,
|
|
6494
|
+
contextSignals,
|
|
6495
|
+
Date.now() - startTime
|
|
6496
|
+
);
|
|
6497
|
+
} catch {
|
|
6025
6498
|
}
|
|
6026
6499
|
return {
|
|
6027
6500
|
content: [
|
|
@@ -6120,8 +6593,8 @@ var TrieScanTool = class {
|
|
|
6120
6593
|
const enriched = [];
|
|
6121
6594
|
for (const issue of issues) {
|
|
6122
6595
|
try {
|
|
6123
|
-
if (issue.line &&
|
|
6124
|
-
const content = await
|
|
6596
|
+
if (issue.line && existsSync6(issue.file)) {
|
|
6597
|
+
const content = await readFile9(issue.file, "utf-8");
|
|
6125
6598
|
const lines = content.split("\n");
|
|
6126
6599
|
const startLine = Math.max(0, issue.line - 3);
|
|
6127
6600
|
const endLine = Math.min(lines.length, issue.line + 2);
|
|
@@ -6360,9 +6833,9 @@ ${issue.fix}
|
|
|
6360
6833
|
* Get a code snippet around a specific line
|
|
6361
6834
|
*/
|
|
6362
6835
|
async getCodeSnippet(filePath, line) {
|
|
6363
|
-
if (!line || !
|
|
6836
|
+
if (!line || !existsSync6(filePath)) return null;
|
|
6364
6837
|
try {
|
|
6365
|
-
const content = await
|
|
6838
|
+
const content = await readFile9(filePath, "utf-8");
|
|
6366
6839
|
const lines = content.split("\n");
|
|
6367
6840
|
const start = Math.max(0, line - 3);
|
|
6368
6841
|
const end = Math.min(lines.length, line + 2);
|
|
@@ -6386,7 +6859,7 @@ ${issue.fix}
|
|
|
6386
6859
|
const entries = await readdir2(currentDir, { withFileTypes: true });
|
|
6387
6860
|
for (const entry of entries) {
|
|
6388
6861
|
if (files.length >= maxFiles) break;
|
|
6389
|
-
const fullPath =
|
|
6862
|
+
const fullPath = join7(currentDir, entry.name);
|
|
6390
6863
|
if (entry.isDirectory()) {
|
|
6391
6864
|
if (!SKIP_DIRS.has(entry.name) && !entry.name.startsWith(".")) {
|
|
6392
6865
|
await walk(fullPath);
|
|
@@ -6411,12 +6884,12 @@ ${issue.fix}
|
|
|
6411
6884
|
return files;
|
|
6412
6885
|
}
|
|
6413
6886
|
async loadTeamMembers(workDir) {
|
|
6414
|
-
const teamConfigPath =
|
|
6415
|
-
if (!
|
|
6887
|
+
const teamConfigPath = join7(workDir, ".trie", "team.json");
|
|
6888
|
+
if (!existsSync6(teamConfigPath)) {
|
|
6416
6889
|
return [];
|
|
6417
6890
|
}
|
|
6418
6891
|
try {
|
|
6419
|
-
const content = await
|
|
6892
|
+
const content = await readFile9(teamConfigPath, "utf-8");
|
|
6420
6893
|
const data = JSON.parse(content);
|
|
6421
6894
|
return Array.isArray(data.members) ? data.members : [];
|
|
6422
6895
|
} catch {
|
|
@@ -6435,6 +6908,8 @@ ${issue.fix}
|
|
|
6435
6908
|
|
|
6436
6909
|
export {
|
|
6437
6910
|
loadConfig,
|
|
6911
|
+
loadContextState,
|
|
6912
|
+
getContextForAI,
|
|
6438
6913
|
TrieScanTool
|
|
6439
6914
|
};
|
|
6440
|
-
//# sourceMappingURL=chunk-
|
|
6915
|
+
//# sourceMappingURL=chunk-HG5AWUH7.js.map
|