@triedotdev/mcp 1.0.41 → 1.0.42
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 +137 -3
- package/dist/{chunk-G2GNVUMP.js → chunk-2I6CFJTR.js} +62 -429
- package/dist/chunk-2I6CFJTR.js.map +1 -0
- package/dist/chunk-52SSNKXS.js +814 -0
- package/dist/chunk-52SSNKXS.js.map +1 -0
- package/dist/{chunk-B3MBKB2U.js → chunk-GBGONSOR.js} +201 -3
- package/dist/chunk-GBGONSOR.js.map +1 -0
- package/dist/cli/main.js +163 -11
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/yolo-daemon.js +3 -3
- package/dist/index.js +47 -10
- package/dist/index.js.map +1 -1
- package/dist/workers/agent-worker.js +2 -1
- package/dist/workers/agent-worker.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-B3MBKB2U.js.map +0 -1
- package/dist/chunk-G2GNVUMP.js.map +0 -1
- package/dist/chunk-Q4RVENDE.js +0 -229
- package/dist/chunk-Q4RVENDE.js.map +0 -1
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
loadProjectInfo,
|
|
3
|
-
projectInfoExists
|
|
4
|
-
} from "./chunk-Q4RVENDE.js";
|
|
5
1
|
import {
|
|
6
2
|
CustomAgent,
|
|
7
3
|
getAgentRegistry
|
|
8
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-GBGONSOR.js";
|
|
5
|
+
import {
|
|
6
|
+
loadContextState,
|
|
7
|
+
updateContextAfterScan
|
|
8
|
+
} from "./chunk-52SSNKXS.js";
|
|
9
9
|
import {
|
|
10
10
|
ProgressReporter
|
|
11
11
|
} from "./chunk-OB45V2QC.js";
|
|
@@ -25,9 +25,9 @@ import {
|
|
|
25
25
|
} from "./chunk-DGUM43GV.js";
|
|
26
26
|
|
|
27
27
|
// src/tools/scan.ts
|
|
28
|
-
import { readFile as
|
|
29
|
-
import { existsSync as
|
|
30
|
-
import { basename as basename6, isAbsolute, resolve as resolve2, join as
|
|
28
|
+
import { readFile as readFile8, readdir as readdir2, writeFile as writeFile3 } from "fs/promises";
|
|
29
|
+
import { existsSync as existsSync5 } from "fs";
|
|
30
|
+
import { basename as basename6, isAbsolute, resolve as resolve2, join as join6, extname as extname3 } from "path";
|
|
31
31
|
|
|
32
32
|
// src/orchestrator/context-analyzer.ts
|
|
33
33
|
import { readFile } from "fs/promises";
|
|
@@ -654,371 +654,6 @@ var RiskAssessor = class {
|
|
|
654
654
|
}
|
|
655
655
|
};
|
|
656
656
|
|
|
657
|
-
// src/utils/context-state.ts
|
|
658
|
-
import { readFile as readFile2, writeFile, mkdir } from "fs/promises";
|
|
659
|
-
import { existsSync as existsSync2 } from "fs";
|
|
660
|
-
import { join } from "path";
|
|
661
|
-
var AGENTS_MD_PATH = ".trie/AGENTS.md";
|
|
662
|
-
var STATE_JSON_PATH = ".trie/state.json";
|
|
663
|
-
async function loadContextState() {
|
|
664
|
-
const workDir = getWorkingDirectory(void 0, true);
|
|
665
|
-
const statePath = join(workDir, STATE_JSON_PATH);
|
|
666
|
-
try {
|
|
667
|
-
if (existsSync2(statePath)) {
|
|
668
|
-
const content = await readFile2(statePath, "utf-8");
|
|
669
|
-
return JSON.parse(content);
|
|
670
|
-
}
|
|
671
|
-
} catch {
|
|
672
|
-
}
|
|
673
|
-
return getDefaultState();
|
|
674
|
-
}
|
|
675
|
-
async function saveContextState(state) {
|
|
676
|
-
const workDir = getWorkingDirectory(void 0, true);
|
|
677
|
-
const trieDir = join(workDir, ".trie");
|
|
678
|
-
const statePath = join(workDir, STATE_JSON_PATH);
|
|
679
|
-
await mkdir(trieDir, { recursive: true });
|
|
680
|
-
await writeFile(statePath, JSON.stringify(state, null, 2));
|
|
681
|
-
}
|
|
682
|
-
async function updateContextAfterScan(results, filesScanned, contextSignals, duration) {
|
|
683
|
-
const state = await loadContextState();
|
|
684
|
-
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
685
|
-
const allIssues = results.flatMap((r) => r.issues);
|
|
686
|
-
const issueCounts = {
|
|
687
|
-
critical: allIssues.filter((i) => i.severity === "critical").length,
|
|
688
|
-
serious: allIssues.filter((i) => i.severity === "serious").length,
|
|
689
|
-
moderate: allIssues.filter((i) => i.severity === "moderate").length,
|
|
690
|
-
low: allIssues.filter((i) => i.severity === "low").length,
|
|
691
|
-
total: allIssues.length
|
|
692
|
-
};
|
|
693
|
-
const fileIssueMap = /* @__PURE__ */ new Map();
|
|
694
|
-
for (const issue of allIssues) {
|
|
695
|
-
const count = fileIssueMap.get(issue.file) || 0;
|
|
696
|
-
fileIssueMap.set(issue.file, count + 1);
|
|
697
|
-
}
|
|
698
|
-
const hotFiles = Array.from(fileIssueMap.entries()).sort((a, b) => b[1] - a[1]).slice(0, 10).map(([file, issueCount]) => ({ file, issueCount }));
|
|
699
|
-
const scanSummary = {
|
|
700
|
-
timestamp: now,
|
|
701
|
-
agents: results.map((r) => r.agent),
|
|
702
|
-
filesScanned,
|
|
703
|
-
issues: issueCounts,
|
|
704
|
-
duration,
|
|
705
|
-
hotFiles
|
|
706
|
-
};
|
|
707
|
-
for (const result of results) {
|
|
708
|
-
state.agentStatus[result.agent] = {
|
|
709
|
-
lastRun: now,
|
|
710
|
-
issuesFound: result.issues.length
|
|
711
|
-
};
|
|
712
|
-
}
|
|
713
|
-
const criticalPenalty = issueCounts.critical * 25;
|
|
714
|
-
const seriousPenalty = issueCounts.serious * 10;
|
|
715
|
-
const moderatePenalty = issueCounts.moderate * 3;
|
|
716
|
-
const lowPenalty = issueCounts.low * 1;
|
|
717
|
-
const totalPenalty = Math.min(100, criticalPenalty + seriousPenalty + moderatePenalty + lowPenalty);
|
|
718
|
-
state.healthScore = Math.max(0, 100 - totalPenalty);
|
|
719
|
-
state.activePriorities = generatePriorities(issueCounts, contextSignals);
|
|
720
|
-
state.contextSignals = { ...state.contextSignals, ...contextSignals };
|
|
721
|
-
state.scanHistory = [scanSummary, ...state.scanHistory.slice(0, 19)];
|
|
722
|
-
state.lastScan = scanSummary;
|
|
723
|
-
await saveContextState(state);
|
|
724
|
-
await updateAgentsMd(state);
|
|
725
|
-
}
|
|
726
|
-
async function updateAgentsMd(state) {
|
|
727
|
-
const workDir = getWorkingDirectory(void 0, true);
|
|
728
|
-
const mdPath = join(workDir, AGENTS_MD_PATH);
|
|
729
|
-
let content;
|
|
730
|
-
try {
|
|
731
|
-
content = await readFile2(mdPath, "utf-8");
|
|
732
|
-
} catch {
|
|
733
|
-
content = getAgentsMdTemplate();
|
|
734
|
-
}
|
|
735
|
-
content = updateSection(content, "Project State", generateProjectStateTable(state));
|
|
736
|
-
content = updateSection(content, "Active Priorities", generatePrioritiesList(state));
|
|
737
|
-
content = updateSection(content, "Agent Status", generateAgentStatusTable(state));
|
|
738
|
-
content = updateSection(content, "Recent Scan History", generateScanHistoryTable(state));
|
|
739
|
-
content = updateSection(content, "Context Signals Detected", generateContextSignals(state));
|
|
740
|
-
content = updateSection(content, "Risk Assessment", generateRiskAssessment(state));
|
|
741
|
-
content = updateSection(content, "Hot Files", generateHotFilesSection(state));
|
|
742
|
-
content = content.replace(
|
|
743
|
-
/Last updated:.*$/m,
|
|
744
|
-
`Last updated: ${(/* @__PURE__ */ new Date()).toISOString()}`
|
|
745
|
-
);
|
|
746
|
-
await writeFile(mdPath, content);
|
|
747
|
-
}
|
|
748
|
-
function updateSection(content, sectionName, newContent) {
|
|
749
|
-
const sectionRegex = new RegExp(
|
|
750
|
-
`(### ${sectionName}[\\s\\S]*?)(?=###|---|
|
|
751
|
-
## |$)`,
|
|
752
|
-
"g"
|
|
753
|
-
);
|
|
754
|
-
const replacement = `### ${sectionName}
|
|
755
|
-
${newContent}
|
|
756
|
-
|
|
757
|
-
`;
|
|
758
|
-
if (content.match(sectionRegex)) {
|
|
759
|
-
return content.replace(sectionRegex, replacement);
|
|
760
|
-
}
|
|
761
|
-
return content;
|
|
762
|
-
}
|
|
763
|
-
function generateProjectStateTable(state) {
|
|
764
|
-
const lastScan = state.lastScan;
|
|
765
|
-
const lastScanDate = lastScan ? new Date(lastScan.timestamp).toLocaleString() : "Never";
|
|
766
|
-
const criticalCount = lastScan?.issues.critical ?? 0;
|
|
767
|
-
const totalTasks = lastScan?.issues.total ?? 0;
|
|
768
|
-
return `| Metric | Value | Updated |
|
|
769
|
-
|--------|-------|---------|
|
|
770
|
-
| Last Scan | ${lastScanDate} | ${lastScan ? "Auto" : "-"} |
|
|
771
|
-
| Critical Issues | ${criticalCount} | ${lastScan ? "Auto" : "-"} |
|
|
772
|
-
| Open Tasks | ${totalTasks} | ${lastScan ? "Auto" : "-"} |
|
|
773
|
-
| Health Score | ${state.healthScore}% | ${lastScan ? "Auto" : "-"} |`;
|
|
774
|
-
}
|
|
775
|
-
function generatePrioritiesList(state) {
|
|
776
|
-
if (state.activePriorities.length === 0) {
|
|
777
|
-
return "_No active priorities. Run a scan to identify issues._";
|
|
778
|
-
}
|
|
779
|
-
return state.activePriorities.map((p, i) => `${i + 1}. ${p}`).join("\n");
|
|
780
|
-
}
|
|
781
|
-
function generatePriorities(issues, contextSignals) {
|
|
782
|
-
const priorities = [];
|
|
783
|
-
if (issues.critical > 0) {
|
|
784
|
-
priorities.push(`\u{1F6A8} Fix ${issues.critical} critical security issue${issues.critical > 1 ? "s" : ""} immediately`);
|
|
785
|
-
}
|
|
786
|
-
if (issues.serious > 0) {
|
|
787
|
-
priorities.push(`\u26A0\uFE0F Address ${issues.serious} serious issue${issues.serious > 1 ? "s" : ""} before deployment`);
|
|
788
|
-
}
|
|
789
|
-
if (contextSignals.touchesAuth && issues.critical === 0) {
|
|
790
|
-
priorities.push("\u2705 Auth code reviewed - continue monitoring");
|
|
791
|
-
}
|
|
792
|
-
if (contextSignals.touchesPayments) {
|
|
793
|
-
priorities.push("\u{1F4B3} Payment code detected - ensure PCI compliance");
|
|
794
|
-
}
|
|
795
|
-
if (contextSignals.touchesUserData) {
|
|
796
|
-
priorities.push("\u{1F510} User data handling detected - verify privacy compliance");
|
|
797
|
-
}
|
|
798
|
-
if (issues.moderate > 5) {
|
|
799
|
-
priorities.push(`\u{1F4CB} Schedule time to address ${issues.moderate} moderate issues`);
|
|
800
|
-
}
|
|
801
|
-
if (priorities.length === 0) {
|
|
802
|
-
priorities.push("\u2728 No critical issues - focus on feature development");
|
|
803
|
-
}
|
|
804
|
-
return priorities.slice(0, 5);
|
|
805
|
-
}
|
|
806
|
-
function generateAgentStatusTable(state) {
|
|
807
|
-
const builtInAgents = [
|
|
808
|
-
"security",
|
|
809
|
-
"privacy",
|
|
810
|
-
"legal",
|
|
811
|
-
"accessibility",
|
|
812
|
-
"bugs",
|
|
813
|
-
"design",
|
|
814
|
-
"architecture",
|
|
815
|
-
"performance",
|
|
816
|
-
"devops",
|
|
817
|
-
"soc2",
|
|
818
|
-
"e2e",
|
|
819
|
-
"typecheck",
|
|
820
|
-
"visual-qa",
|
|
821
|
-
"data-flow"
|
|
822
|
-
];
|
|
823
|
-
let table = `| Agent | Status | Last Run | Issues Found |
|
|
824
|
-
|-------|--------|----------|--------------|`;
|
|
825
|
-
for (const agent of builtInAgents) {
|
|
826
|
-
const status = state.agentStatus[agent];
|
|
827
|
-
const lastRun = status?.lastRun ? new Date(status.lastRun).toLocaleDateString() : "Never";
|
|
828
|
-
const issues = status?.issuesFound ?? "-";
|
|
829
|
-
const statusEmoji = status ? "\u2705" : "\u23F8\uFE0F";
|
|
830
|
-
table += `
|
|
831
|
-
| ${agent} | ${statusEmoji} Ready | ${lastRun} | ${issues} |`;
|
|
832
|
-
}
|
|
833
|
-
return table;
|
|
834
|
-
}
|
|
835
|
-
function generateScanHistoryTable(state) {
|
|
836
|
-
if (state.scanHistory.length === 0) {
|
|
837
|
-
return `| Date | Agents | Files | Issues | Duration |
|
|
838
|
-
|------|--------|-------|--------|----------|
|
|
839
|
-
| - | - | - | - | - |`;
|
|
840
|
-
}
|
|
841
|
-
let table = `| Date | Agents | Files | Issues | Duration |
|
|
842
|
-
|------|--------|-------|--------|----------|`;
|
|
843
|
-
for (const scan of state.scanHistory.slice(0, 10)) {
|
|
844
|
-
const date = new Date(scan.timestamp).toLocaleDateString();
|
|
845
|
-
const agents = scan.agents.slice(0, 3).join(", ") + (scan.agents.length > 3 ? "..." : "");
|
|
846
|
-
const duration = `${(scan.duration / 1e3).toFixed(1)}s`;
|
|
847
|
-
table += `
|
|
848
|
-
| ${date} | ${agents} | ${scan.filesScanned} | ${scan.issues.total} | ${duration} |`;
|
|
849
|
-
}
|
|
850
|
-
return table;
|
|
851
|
-
}
|
|
852
|
-
function generateContextSignals(state) {
|
|
853
|
-
const signals = [
|
|
854
|
-
"touchesAuth",
|
|
855
|
-
"touchesPayments",
|
|
856
|
-
"touchesUserData",
|
|
857
|
-
"touchesAPI",
|
|
858
|
-
"touchesDatabase",
|
|
859
|
-
"touchesCrypto"
|
|
860
|
-
];
|
|
861
|
-
return signals.map((s) => {
|
|
862
|
-
const value = state.contextSignals[s];
|
|
863
|
-
const emoji = value === true ? "\u2705" : value === false ? "\u274C" : "\u2753";
|
|
864
|
-
return `- \`${s}\`: ${emoji} ${value === void 0 ? "Unknown" : value ? "Yes" : "No"}`;
|
|
865
|
-
}).join("\n");
|
|
866
|
-
}
|
|
867
|
-
function generateRiskAssessment(state) {
|
|
868
|
-
const score = state.healthScore;
|
|
869
|
-
let riskLevel;
|
|
870
|
-
let confidence;
|
|
871
|
-
if (state.lastScan === null) {
|
|
872
|
-
return `- Overall Risk: Unknown
|
|
873
|
-
- Confidence: 0%`;
|
|
874
|
-
}
|
|
875
|
-
if (score >= 90) {
|
|
876
|
-
riskLevel = "\u{1F7E2} Low";
|
|
877
|
-
confidence = 95;
|
|
878
|
-
} else if (score >= 70) {
|
|
879
|
-
riskLevel = "\u{1F7E1} Medium";
|
|
880
|
-
confidence = 85;
|
|
881
|
-
} else if (score >= 50) {
|
|
882
|
-
riskLevel = "\u{1F7E0} High";
|
|
883
|
-
confidence = 80;
|
|
884
|
-
} else {
|
|
885
|
-
riskLevel = "\u{1F534} Critical";
|
|
886
|
-
confidence = 90;
|
|
887
|
-
}
|
|
888
|
-
return `- Overall Risk: ${riskLevel}
|
|
889
|
-
- Health Score: ${score}%
|
|
890
|
-
- Confidence: ${confidence}%`;
|
|
891
|
-
}
|
|
892
|
-
function generateHotFilesSection(state) {
|
|
893
|
-
if (!state.lastScan || state.lastScan.hotFiles.length === 0) {
|
|
894
|
-
return "_Run a scan to identify hot files._";
|
|
895
|
-
}
|
|
896
|
-
return state.lastScan.hotFiles.map((f) => `- \`${f.file}\` - ${f.issueCount} issue${f.issueCount > 1 ? "s" : ""}`).join("\n");
|
|
897
|
-
}
|
|
898
|
-
function getDefaultState() {
|
|
899
|
-
return {
|
|
900
|
-
lastScan: null,
|
|
901
|
-
healthScore: 0,
|
|
902
|
-
activePriorities: [
|
|
903
|
-
"Initial setup required - run first scan with `trie scan`",
|
|
904
|
-
"Configure agents in `.trie/config.json`",
|
|
905
|
-
"Set up CI/CD integration"
|
|
906
|
-
],
|
|
907
|
-
contextSignals: {},
|
|
908
|
-
agentStatus: {},
|
|
909
|
-
scanHistory: [],
|
|
910
|
-
customAgents: []
|
|
911
|
-
};
|
|
912
|
-
}
|
|
913
|
-
function getAgentsMdTemplate() {
|
|
914
|
-
return `# Trie Agent Context
|
|
915
|
-
|
|
916
|
-
> **Auto-generated file** - Updated automatically when agents run.
|
|
917
|
-
> Last updated: Never (initial state)
|
|
918
|
-
|
|
919
|
-
This file provides prioritized context for all AI coding assistants working with this codebase.
|
|
920
|
-
Agents should read this file first and update it after completing scans.
|
|
921
|
-
|
|
922
|
-
---
|
|
923
|
-
|
|
924
|
-
## Quick Context (Read First)
|
|
925
|
-
|
|
926
|
-
### Project State
|
|
927
|
-
| Metric | Value | Updated |
|
|
928
|
-
|--------|-------|---------|
|
|
929
|
-
| Last Scan | Never | - |
|
|
930
|
-
| Critical Issues | 0 | - |
|
|
931
|
-
| Open Tasks | 0 | - |
|
|
932
|
-
| Health Score | Unknown | - |
|
|
933
|
-
|
|
934
|
-
### Active Priorities
|
|
935
|
-
1. Initial setup required - run first scan with \`trie scan\`
|
|
936
|
-
2. Configure agents in \`.trie/config.json\`
|
|
937
|
-
3. Set up CI/CD integration
|
|
938
|
-
|
|
939
|
-
### Hot Files
|
|
940
|
-
_Run a scan to identify hot files._
|
|
941
|
-
|
|
942
|
-
---
|
|
943
|
-
|
|
944
|
-
## Agent Status
|
|
945
|
-
|
|
946
|
-
### Agent Status
|
|
947
|
-
| Agent | Status | Last Run | Issues Found |
|
|
948
|
-
|-------|--------|----------|--------------|
|
|
949
|
-
| security | Ready | Never | - |
|
|
950
|
-
| privacy | Ready | Never | - |
|
|
951
|
-
| bugs | Ready | Never | - |
|
|
952
|
-
|
|
953
|
-
### Recent Scan History
|
|
954
|
-
| Date | Agents | Files | Issues | Duration |
|
|
955
|
-
|------|--------|-------|--------|----------|
|
|
956
|
-
| - | - | - | - | - |
|
|
957
|
-
|
|
958
|
-
---
|
|
959
|
-
|
|
960
|
-
## Context Analysis
|
|
961
|
-
|
|
962
|
-
### Context Signals Detected
|
|
963
|
-
- \`touchesAuth\`: Unknown
|
|
964
|
-
- \`touchesPayments\`: Unknown
|
|
965
|
-
- \`touchesUserData\`: Unknown
|
|
966
|
-
- \`touchesAPI\`: Unknown
|
|
967
|
-
- \`touchesDatabase\`: Unknown
|
|
968
|
-
- \`touchesCrypto\`: Unknown
|
|
969
|
-
|
|
970
|
-
### Risk Assessment
|
|
971
|
-
- Overall Risk: Unknown
|
|
972
|
-
- Confidence: 0%
|
|
973
|
-
|
|
974
|
-
---
|
|
975
|
-
|
|
976
|
-
*This file is maintained by Trie agents. Manual edits will be preserved in non-auto sections.*
|
|
977
|
-
`;
|
|
978
|
-
}
|
|
979
|
-
async function getContextForAI() {
|
|
980
|
-
const state = await loadContextState();
|
|
981
|
-
const workDir = getWorkingDirectory(void 0, true);
|
|
982
|
-
const lines = [];
|
|
983
|
-
if (projectInfoExists(workDir)) {
|
|
984
|
-
const projectInfo = await loadProjectInfo(workDir);
|
|
985
|
-
if (projectInfo) {
|
|
986
|
-
lines.push(projectInfo);
|
|
987
|
-
lines.push("");
|
|
988
|
-
lines.push("---");
|
|
989
|
-
lines.push("");
|
|
990
|
-
}
|
|
991
|
-
}
|
|
992
|
-
lines.push(
|
|
993
|
-
"## Trie Scan Context",
|
|
994
|
-
"",
|
|
995
|
-
`**Health Score:** ${state.healthScore}%`,
|
|
996
|
-
`**Last Scan:** ${state.lastScan ? new Date(state.lastScan.timestamp).toLocaleString() : "Never"}`,
|
|
997
|
-
"",
|
|
998
|
-
"**Active Priorities:**",
|
|
999
|
-
...state.activePriorities.map((p) => `- ${p}`),
|
|
1000
|
-
""
|
|
1001
|
-
);
|
|
1002
|
-
if (state.lastScan) {
|
|
1003
|
-
lines.push(
|
|
1004
|
-
"**Recent Issues:**",
|
|
1005
|
-
`- Critical: ${state.lastScan.issues.critical}`,
|
|
1006
|
-
`- Serious: ${state.lastScan.issues.serious}`,
|
|
1007
|
-
`- Moderate: ${state.lastScan.issues.moderate}`,
|
|
1008
|
-
`- Low: ${state.lastScan.issues.low}`,
|
|
1009
|
-
""
|
|
1010
|
-
);
|
|
1011
|
-
if (state.lastScan.hotFiles.length > 0) {
|
|
1012
|
-
lines.push(
|
|
1013
|
-
"**Hot Files (most issues):**",
|
|
1014
|
-
...state.lastScan.hotFiles.slice(0, 5).map((f) => `- ${f.file}: ${f.issueCount} issues`),
|
|
1015
|
-
""
|
|
1016
|
-
);
|
|
1017
|
-
}
|
|
1018
|
-
}
|
|
1019
|
-
return lines.join("\n");
|
|
1020
|
-
}
|
|
1021
|
-
|
|
1022
657
|
// src/orchestrator/triager.ts
|
|
1023
658
|
var Triager = class {
|
|
1024
659
|
agentRegistry = getAgentRegistry();
|
|
@@ -1836,8 +1471,8 @@ function calculateOptimalConcurrency() {
|
|
|
1836
1471
|
}
|
|
1837
1472
|
|
|
1838
1473
|
// src/utils/cache-manager.ts
|
|
1839
|
-
import { readFile as
|
|
1840
|
-
import { join
|
|
1474
|
+
import { readFile as readFile2, writeFile, mkdir, stat } from "fs/promises";
|
|
1475
|
+
import { join } from "path";
|
|
1841
1476
|
import { createHash } from "crypto";
|
|
1842
1477
|
var CacheManager = class {
|
|
1843
1478
|
cacheDir;
|
|
@@ -1847,8 +1482,8 @@ var CacheManager = class {
|
|
|
1847
1482
|
// 24 hours
|
|
1848
1483
|
MAX_ENTRIES = 1e3;
|
|
1849
1484
|
constructor(baseDir) {
|
|
1850
|
-
this.cacheDir =
|
|
1851
|
-
this.indexPath =
|
|
1485
|
+
this.cacheDir = join(baseDir, ".trie", "cache");
|
|
1486
|
+
this.indexPath = join(this.cacheDir, "index.json");
|
|
1852
1487
|
}
|
|
1853
1488
|
/**
|
|
1854
1489
|
* Generate cache key for a file and agent combination
|
|
@@ -1862,7 +1497,7 @@ var CacheManager = class {
|
|
|
1862
1497
|
*/
|
|
1863
1498
|
async getFileHash(filePath) {
|
|
1864
1499
|
try {
|
|
1865
|
-
const content = await
|
|
1500
|
+
const content = await readFile2(filePath, "utf-8");
|
|
1866
1501
|
const stats = await stat(filePath);
|
|
1867
1502
|
const hash = createHash("sha256").update(content).digest("hex").slice(0, 16);
|
|
1868
1503
|
return {
|
|
@@ -1879,7 +1514,7 @@ var CacheManager = class {
|
|
|
1879
1514
|
*/
|
|
1880
1515
|
async loadIndex() {
|
|
1881
1516
|
try {
|
|
1882
|
-
const content = await
|
|
1517
|
+
const content = await readFile2(this.indexPath, "utf-8");
|
|
1883
1518
|
return JSON.parse(content);
|
|
1884
1519
|
} catch {
|
|
1885
1520
|
return {
|
|
@@ -1894,8 +1529,8 @@ var CacheManager = class {
|
|
|
1894
1529
|
*/
|
|
1895
1530
|
async saveIndex(index) {
|
|
1896
1531
|
try {
|
|
1897
|
-
await
|
|
1898
|
-
await
|
|
1532
|
+
await mkdir(this.cacheDir, { recursive: true });
|
|
1533
|
+
await writeFile(this.indexPath, JSON.stringify(index, null, 2));
|
|
1899
1534
|
} catch (error) {
|
|
1900
1535
|
console.warn("Failed to save cache index:", error);
|
|
1901
1536
|
}
|
|
@@ -2102,8 +1737,8 @@ var Executor = class {
|
|
|
2102
1737
|
};
|
|
2103
1738
|
|
|
2104
1739
|
// src/analysis/cross-file.ts
|
|
2105
|
-
import { readFile as
|
|
2106
|
-
import { join as
|
|
1740
|
+
import { readFile as readFile3, readdir } from "fs/promises";
|
|
1741
|
+
import { join as join2, extname as extname2, relative, dirname, basename as basename2 } from "path";
|
|
2107
1742
|
async function buildDependencyGraph(rootDir, maxFiles = 200) {
|
|
2108
1743
|
const files = /* @__PURE__ */ new Map();
|
|
2109
1744
|
const issues = [];
|
|
@@ -2133,7 +1768,7 @@ async function buildDependencyGraph(rootDir, maxFiles = 200) {
|
|
|
2133
1768
|
}
|
|
2134
1769
|
async function parseFile(filePath, rootDir) {
|
|
2135
1770
|
try {
|
|
2136
|
-
const content = await
|
|
1771
|
+
const content = await readFile3(filePath, "utf-8");
|
|
2137
1772
|
const relativePath = relative(rootDir, filePath);
|
|
2138
1773
|
const lines = content.split("\n");
|
|
2139
1774
|
const imports = [];
|
|
@@ -2222,7 +1857,7 @@ function resolveImport(source, fromPath, files) {
|
|
|
2222
1857
|
return null;
|
|
2223
1858
|
}
|
|
2224
1859
|
const fromDir = dirname(fromPath);
|
|
2225
|
-
let resolvedPath =
|
|
1860
|
+
let resolvedPath = join2(fromDir, source);
|
|
2226
1861
|
const extensions = ["", ".ts", ".tsx", ".js", ".jsx", "/index.ts", "/index.tsx", "/index.js"];
|
|
2227
1862
|
for (const ext of extensions) {
|
|
2228
1863
|
const tryPath = resolvedPath + ext;
|
|
@@ -2336,7 +1971,7 @@ async function discoverFiles(dir, maxFiles) {
|
|
|
2336
1971
|
const entries = await readdir(currentDir, { withFileTypes: true });
|
|
2337
1972
|
for (const entry of entries) {
|
|
2338
1973
|
if (files.length >= maxFiles) break;
|
|
2339
|
-
const fullPath =
|
|
1974
|
+
const fullPath = join2(currentDir, entry.name);
|
|
2340
1975
|
if (entry.isDirectory()) {
|
|
2341
1976
|
if (!skipDirs.has(entry.name) && !entry.name.startsWith(".")) {
|
|
2342
1977
|
await walk(fullPath);
|
|
@@ -2443,7 +2078,7 @@ ${"\u2501".repeat(60)}
|
|
|
2443
2078
|
}
|
|
2444
2079
|
|
|
2445
2080
|
// src/analysis/semantic-analyzer.ts
|
|
2446
|
-
import { readFile as
|
|
2081
|
+
import { readFile as readFile4 } from "fs/promises";
|
|
2447
2082
|
import { basename as basename3, relative as relative2 } from "path";
|
|
2448
2083
|
var SemanticAnalyzer = class {
|
|
2449
2084
|
functions = [];
|
|
@@ -2456,7 +2091,7 @@ var SemanticAnalyzer = class {
|
|
|
2456
2091
|
async analyze(files, rootDir) {
|
|
2457
2092
|
for (const file of files) {
|
|
2458
2093
|
try {
|
|
2459
|
-
const content = await
|
|
2094
|
+
const content = await readFile4(file, "utf-8");
|
|
2460
2095
|
const relPath = relative2(rootDir, file);
|
|
2461
2096
|
this.detectFramework(content);
|
|
2462
2097
|
this.parseFunctions(content, relPath);
|
|
@@ -3017,7 +2652,7 @@ function formatPrioritizedResults(result) {
|
|
|
3017
2652
|
}
|
|
3018
2653
|
|
|
3019
2654
|
// src/analysis/attack-surface.ts
|
|
3020
|
-
import { readFile as
|
|
2655
|
+
import { readFile as readFile5 } from "fs/promises";
|
|
3021
2656
|
import { basename as basename5, relative as relative3 } from "path";
|
|
3022
2657
|
var AttackSurfaceAnalyzer = class {
|
|
3023
2658
|
endpoints = [];
|
|
@@ -3027,7 +2662,7 @@ var AttackSurfaceAnalyzer = class {
|
|
|
3027
2662
|
async analyze(files, rootDir) {
|
|
3028
2663
|
for (const file of files) {
|
|
3029
2664
|
try {
|
|
3030
|
-
const content = await
|
|
2665
|
+
const content = await readFile5(file, "utf-8");
|
|
3031
2666
|
const relPath = relative3(rootDir, file);
|
|
3032
2667
|
this.findEndpoints(content, relPath);
|
|
3033
2668
|
this.findDataFlows(content, relPath);
|
|
@@ -3772,9 +3407,9 @@ function getSymbolIndex() {
|
|
|
3772
3407
|
|
|
3773
3408
|
// src/trie/incremental-scanner.ts
|
|
3774
3409
|
import { createHash as createHash2 } from "crypto";
|
|
3775
|
-
import { readFile as
|
|
3776
|
-
import { existsSync as
|
|
3777
|
-
import { join as
|
|
3410
|
+
import { readFile as readFile6, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
|
|
3411
|
+
import { existsSync as existsSync2 } from "fs";
|
|
3412
|
+
import { join as join3 } from "path";
|
|
3778
3413
|
var CACHE_VERSION = "1.0.0";
|
|
3779
3414
|
var CACHE_FILE = ".trie-cache.json";
|
|
3780
3415
|
var IncrementalScanner = class {
|
|
@@ -3783,7 +3418,7 @@ var IncrementalScanner = class {
|
|
|
3783
3418
|
cacheDir;
|
|
3784
3419
|
dirty = false;
|
|
3785
3420
|
constructor(projectRoot) {
|
|
3786
|
-
this.cacheDir =
|
|
3421
|
+
this.cacheDir = join3(projectRoot, ".trie");
|
|
3787
3422
|
this.symbolIndex = getSymbolIndex();
|
|
3788
3423
|
this.cache = {
|
|
3789
3424
|
version: CACHE_VERSION,
|
|
@@ -3796,12 +3431,12 @@ var IncrementalScanner = class {
|
|
|
3796
3431
|
* Load cache from disk
|
|
3797
3432
|
*/
|
|
3798
3433
|
async loadCache() {
|
|
3799
|
-
const cachePath =
|
|
3800
|
-
if (!
|
|
3434
|
+
const cachePath = join3(this.cacheDir, CACHE_FILE);
|
|
3435
|
+
if (!existsSync2(cachePath)) {
|
|
3801
3436
|
return false;
|
|
3802
3437
|
}
|
|
3803
3438
|
try {
|
|
3804
|
-
const data = await
|
|
3439
|
+
const data = await readFile6(cachePath, "utf-8");
|
|
3805
3440
|
const parsed = JSON.parse(data);
|
|
3806
3441
|
if (parsed.version !== CACHE_VERSION) {
|
|
3807
3442
|
console.error(" \u26A0\uFE0F Cache version mismatch, rebuilding...");
|
|
@@ -3821,10 +3456,10 @@ var IncrementalScanner = class {
|
|
|
3821
3456
|
async saveCache() {
|
|
3822
3457
|
if (!this.dirty) return;
|
|
3823
3458
|
try {
|
|
3824
|
-
await
|
|
3825
|
-
const cachePath =
|
|
3459
|
+
await mkdir2(this.cacheDir, { recursive: true });
|
|
3460
|
+
const cachePath = join3(this.cacheDir, CACHE_FILE);
|
|
3826
3461
|
this.cache.lastUpdated = Date.now();
|
|
3827
|
-
await
|
|
3462
|
+
await writeFile2(cachePath, JSON.stringify(this.cache, null, 2));
|
|
3828
3463
|
this.dirty = false;
|
|
3829
3464
|
} catch (error) {
|
|
3830
3465
|
console.error(" \u26A0\uFE0F Failed to save cache");
|
|
@@ -3846,7 +3481,7 @@ var IncrementalScanner = class {
|
|
|
3846
3481
|
if (!cached) return true;
|
|
3847
3482
|
if (!content) {
|
|
3848
3483
|
try {
|
|
3849
|
-
content = await
|
|
3484
|
+
content = await readFile6(filePath, "utf-8");
|
|
3850
3485
|
} catch {
|
|
3851
3486
|
return true;
|
|
3852
3487
|
}
|
|
@@ -3861,7 +3496,7 @@ var IncrementalScanner = class {
|
|
|
3861
3496
|
async scanFile(filePath, forceRescan = false) {
|
|
3862
3497
|
let content;
|
|
3863
3498
|
try {
|
|
3864
|
-
content = await
|
|
3499
|
+
content = await readFile6(filePath, "utf-8");
|
|
3865
3500
|
} catch {
|
|
3866
3501
|
return { vulnerabilities: [], fromCache: false, symbolCount: 0 };
|
|
3867
3502
|
}
|
|
@@ -5044,14 +4679,14 @@ var InteractiveDashboard = class {
|
|
|
5044
4679
|
};
|
|
5045
4680
|
|
|
5046
4681
|
// src/config/loader.ts
|
|
5047
|
-
import { readFile as
|
|
5048
|
-
import { existsSync as
|
|
5049
|
-
import { join as
|
|
4682
|
+
import { readFile as readFile7 } from "fs/promises";
|
|
4683
|
+
import { existsSync as existsSync4 } from "fs";
|
|
4684
|
+
import { join as join5 } from "path";
|
|
5050
4685
|
|
|
5051
4686
|
// src/config/validation.ts
|
|
5052
4687
|
import { z } from "zod";
|
|
5053
|
-
import { existsSync as
|
|
5054
|
-
import { resolve, join as
|
|
4688
|
+
import { existsSync as existsSync3, readFileSync } from "fs";
|
|
4689
|
+
import { resolve, join as join4 } from "path";
|
|
5055
4690
|
var API_KEY_PATTERNS = {
|
|
5056
4691
|
anthropic: /^sk-ant-api\d{2}-[\w-]{95}$/,
|
|
5057
4692
|
openai: /^sk-[\w]{48}$/,
|
|
@@ -5164,8 +4799,8 @@ var ConfigValidator = class {
|
|
|
5164
4799
|
let anthropicKey = process.env.ANTHROPIC_API_KEY;
|
|
5165
4800
|
if (!anthropicKey) {
|
|
5166
4801
|
try {
|
|
5167
|
-
const configPath =
|
|
5168
|
-
if (
|
|
4802
|
+
const configPath = join4(getWorkingDirectory(void 0, true), ".trie", "config.json");
|
|
4803
|
+
if (existsSync3(configPath)) {
|
|
5169
4804
|
const config = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
5170
4805
|
anthropicKey = config.apiKeys?.anthropic;
|
|
5171
4806
|
}
|
|
@@ -5195,14 +4830,14 @@ var ConfigValidator = class {
|
|
|
5195
4830
|
if (paths?.include) {
|
|
5196
4831
|
for (const path of paths.include) {
|
|
5197
4832
|
const resolvedPath = resolve(path);
|
|
5198
|
-
if (!
|
|
4833
|
+
if (!existsSync3(resolvedPath)) {
|
|
5199
4834
|
errors.push(`Include path does not exist: ${path}`);
|
|
5200
4835
|
}
|
|
5201
4836
|
}
|
|
5202
4837
|
}
|
|
5203
4838
|
if (paths?.configDir) {
|
|
5204
4839
|
const configPath = resolve(paths.configDir);
|
|
5205
|
-
if (!
|
|
4840
|
+
if (!existsSync3(configPath)) {
|
|
5206
4841
|
try {
|
|
5207
4842
|
__require("fs").mkdirSync(configPath, { recursive: true });
|
|
5208
4843
|
} catch {
|
|
@@ -5322,8 +4957,8 @@ var ConfigValidator = class {
|
|
|
5322
4957
|
const workDir = getWorkingDirectory(void 0, true);
|
|
5323
4958
|
const envFiles = [".env", ".env.local", ".env.production"];
|
|
5324
4959
|
for (const envFile of envFiles) {
|
|
5325
|
-
const envPath =
|
|
5326
|
-
if (
|
|
4960
|
+
const envPath = join4(workDir, envFile);
|
|
4961
|
+
if (existsSync3(envPath)) {
|
|
5327
4962
|
const envContent = readFileSync(envPath, "utf-8");
|
|
5328
4963
|
if (envContent.includes("ANTHROPIC_API_KEY=")) {
|
|
5329
4964
|
hasApiKey = true;
|
|
@@ -5400,12 +5035,12 @@ var DEFAULT_CONFIG = {
|
|
|
5400
5035
|
// src/config/loader.ts
|
|
5401
5036
|
async function loadConfig() {
|
|
5402
5037
|
const validator = new ConfigValidator();
|
|
5403
|
-
const configPath =
|
|
5038
|
+
const configPath = join5(getWorkingDirectory(void 0, true), ".trie", "config.json");
|
|
5404
5039
|
try {
|
|
5405
|
-
if (!
|
|
5040
|
+
if (!existsSync4(configPath)) {
|
|
5406
5041
|
return DEFAULT_CONFIG;
|
|
5407
5042
|
}
|
|
5408
|
-
const configFile = await
|
|
5043
|
+
const configFile = await readFile7(configPath, "utf-8");
|
|
5409
5044
|
const userConfig = JSON.parse(configFile);
|
|
5410
5045
|
const merged = mergeConfig(DEFAULT_CONFIG, userConfig);
|
|
5411
5046
|
const result = validator.validateConfig(merged);
|
|
@@ -6264,7 +5899,7 @@ var TrieScanTool = class {
|
|
|
6264
5899
|
return resolve2(workDir, f);
|
|
6265
5900
|
});
|
|
6266
5901
|
const validFiles = resolvedFiles.filter((f) => {
|
|
6267
|
-
if (!
|
|
5902
|
+
if (!existsSync5(f)) {
|
|
6268
5903
|
this.progress.warn("File not found", f);
|
|
6269
5904
|
return false;
|
|
6270
5905
|
}
|
|
@@ -6492,7 +6127,7 @@ var TrieScanTool = class {
|
|
|
6492
6127
|
prioritization: prioritized,
|
|
6493
6128
|
grouping: priorityReport
|
|
6494
6129
|
};
|
|
6495
|
-
await
|
|
6130
|
+
await writeFile3(args.output, JSON.stringify(report, null, 2));
|
|
6496
6131
|
}
|
|
6497
6132
|
try {
|
|
6498
6133
|
const contextSignals = {
|
|
@@ -6608,8 +6243,8 @@ var TrieScanTool = class {
|
|
|
6608
6243
|
const enriched = [];
|
|
6609
6244
|
for (const issue of issues) {
|
|
6610
6245
|
try {
|
|
6611
|
-
if (issue.line &&
|
|
6612
|
-
const content = await
|
|
6246
|
+
if (issue.line && existsSync5(issue.file)) {
|
|
6247
|
+
const content = await readFile8(issue.file, "utf-8");
|
|
6613
6248
|
const lines = content.split("\n");
|
|
6614
6249
|
const startLine = Math.max(0, issue.line - 3);
|
|
6615
6250
|
const endLine = Math.min(lines.length, issue.line + 2);
|
|
@@ -6848,9 +6483,9 @@ ${issue.fix}
|
|
|
6848
6483
|
* Get a code snippet around a specific line
|
|
6849
6484
|
*/
|
|
6850
6485
|
async getCodeSnippet(filePath, line) {
|
|
6851
|
-
if (!line || !
|
|
6486
|
+
if (!line || !existsSync5(filePath)) return null;
|
|
6852
6487
|
try {
|
|
6853
|
-
const content = await
|
|
6488
|
+
const content = await readFile8(filePath, "utf-8");
|
|
6854
6489
|
const lines = content.split("\n");
|
|
6855
6490
|
const start = Math.max(0, line - 3);
|
|
6856
6491
|
const end = Math.min(lines.length, line + 2);
|
|
@@ -6874,7 +6509,7 @@ ${issue.fix}
|
|
|
6874
6509
|
const entries = await readdir2(currentDir, { withFileTypes: true });
|
|
6875
6510
|
for (const entry of entries) {
|
|
6876
6511
|
if (files.length >= maxFiles) break;
|
|
6877
|
-
const fullPath =
|
|
6512
|
+
const fullPath = join6(currentDir, entry.name);
|
|
6878
6513
|
if (entry.isDirectory()) {
|
|
6879
6514
|
if (!SKIP_DIRS.has(entry.name) && !entry.name.startsWith(".")) {
|
|
6880
6515
|
await walk(fullPath);
|
|
@@ -6899,12 +6534,12 @@ ${issue.fix}
|
|
|
6899
6534
|
return files;
|
|
6900
6535
|
}
|
|
6901
6536
|
async loadTeamMembers(workDir) {
|
|
6902
|
-
const teamConfigPath =
|
|
6903
|
-
if (!
|
|
6537
|
+
const teamConfigPath = join6(workDir, ".trie", "team.json");
|
|
6538
|
+
if (!existsSync5(teamConfigPath)) {
|
|
6904
6539
|
return [];
|
|
6905
6540
|
}
|
|
6906
6541
|
try {
|
|
6907
|
-
const content = await
|
|
6542
|
+
const content = await readFile8(teamConfigPath, "utf-8");
|
|
6908
6543
|
const data = JSON.parse(content);
|
|
6909
6544
|
return Array.isArray(data.members) ? data.members : [];
|
|
6910
6545
|
} catch {
|
|
@@ -6923,8 +6558,6 @@ ${issue.fix}
|
|
|
6923
6558
|
|
|
6924
6559
|
export {
|
|
6925
6560
|
loadConfig,
|
|
6926
|
-
loadContextState,
|
|
6927
|
-
getContextForAI,
|
|
6928
6561
|
TrieScanTool
|
|
6929
6562
|
};
|
|
6930
|
-
//# sourceMappingURL=chunk-
|
|
6563
|
+
//# sourceMappingURL=chunk-2I6CFJTR.js.map
|