@triedotdev/mcp 1.0.68 → 1.0.70
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 +14 -0
- package/dist/{chunk-HWJJIAR7.js → chunk-BHIKY5PW.js} +13 -2
- package/dist/chunk-BHIKY5PW.js.map +1 -0
- package/dist/{chunk-O7WFJC2P.js → chunk-COXK23KW.js} +11 -6
- package/dist/chunk-COXK23KW.js.map +1 -0
- package/dist/{chunk-CMZTFDNC.js → chunk-LWT7XFDD.js} +6 -6
- package/dist/chunk-LWT7XFDD.js.map +1 -0
- package/dist/{chunk-IF2KTITI.js → chunk-OAICCSDL.js} +334 -42
- package/dist/chunk-OAICCSDL.js.map +1 -0
- package/dist/cli/main.js +14 -3
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/yolo-daemon.js +4 -4
- package/dist/{goal-manager-B673YUZF.js → goal-manager-5FLR7IS2.js} +3 -3
- package/dist/{guardian-agent-FYZ5F3DA.js → guardian-agent-QFREM3AR.js} +4 -4
- package/dist/index.js +5 -5
- package/package.json +1 -1
- package/dist/chunk-CMZTFDNC.js.map +0 -1
- package/dist/chunk-HWJJIAR7.js.map +0 -1
- package/dist/chunk-IF2KTITI.js.map +0 -1
- package/dist/chunk-O7WFJC2P.js.map +0 -1
- /package/dist/{goal-manager-B673YUZF.js.map → goal-manager-5FLR7IS2.js.map} +0 -0
- /package/dist/{guardian-agent-FYZ5F3DA.js.map → guardian-agent-QFREM3AR.js.map} +0 -0
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
import {
|
|
7
7
|
SlackIntegration,
|
|
8
8
|
getGuardian
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-LWT7XFDD.js";
|
|
10
10
|
import {
|
|
11
11
|
Executor,
|
|
12
12
|
Triager,
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
} from "./chunk-3AKE4M4Z.js";
|
|
20
20
|
import {
|
|
21
21
|
getGuardianState
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-COXK23KW.js";
|
|
23
23
|
import {
|
|
24
24
|
createSkillFromFile,
|
|
25
25
|
getSkillRegistry,
|
|
@@ -30,6 +30,9 @@ import {
|
|
|
30
30
|
removeGlobalSkill,
|
|
31
31
|
updateContextAfterScan
|
|
32
32
|
} from "./chunk-E2ASFZMF.js";
|
|
33
|
+
import {
|
|
34
|
+
findCrossProjectPatterns
|
|
35
|
+
} from "./chunk-6TSYRIQS.js";
|
|
33
36
|
import {
|
|
34
37
|
Trie
|
|
35
38
|
} from "./chunk-6NLHFIYA.js";
|
|
@@ -41,6 +44,8 @@ import {
|
|
|
41
44
|
} from "./chunk-Z7N7KDK3.js";
|
|
42
45
|
import {
|
|
43
46
|
atomicWriteJSON,
|
|
47
|
+
getMemoryStats,
|
|
48
|
+
getRecentIssues,
|
|
44
49
|
searchIssues
|
|
45
50
|
} from "./chunk-2KLYR5GW.js";
|
|
46
51
|
import {
|
|
@@ -587,7 +592,8 @@ var InteractiveDashboard = class {
|
|
|
587
592
|
skills: 0,
|
|
588
593
|
guardian: 0,
|
|
589
594
|
goals: 0,
|
|
590
|
-
hypotheses: 0
|
|
595
|
+
hypotheses: 0,
|
|
596
|
+
memory: 0
|
|
591
597
|
},
|
|
592
598
|
notification: null,
|
|
593
599
|
notificationHistory: [],
|
|
@@ -674,6 +680,18 @@ var InteractiveDashboard = class {
|
|
|
674
680
|
inputMode: "browse",
|
|
675
681
|
inputBuffer: "",
|
|
676
682
|
lastRefresh: 0
|
|
683
|
+
},
|
|
684
|
+
// Memory tree state
|
|
685
|
+
memoryTree: {
|
|
686
|
+
loaded: false,
|
|
687
|
+
issues: [],
|
|
688
|
+
stats: null,
|
|
689
|
+
globalPatterns: [],
|
|
690
|
+
expandedNodes: /* @__PURE__ */ new Set(["severity", "files"]),
|
|
691
|
+
// Default expanded
|
|
692
|
+
selectedNode: "severity",
|
|
693
|
+
scrollPosition: 0,
|
|
694
|
+
lastRefresh: 0
|
|
677
695
|
}
|
|
678
696
|
};
|
|
679
697
|
}
|
|
@@ -993,39 +1011,6 @@ var InteractiveDashboard = class {
|
|
|
993
1011
|
this.addActivity(`Guardian error: ${error instanceof Error ? error.message : "unknown"}`);
|
|
994
1012
|
}
|
|
995
1013
|
}
|
|
996
|
-
/**
|
|
997
|
-
* Dismiss the top insight/notification in the strip
|
|
998
|
-
*/
|
|
999
|
-
dismissTopNotification() {
|
|
1000
|
-
if (this.state.view === "guardian") {
|
|
1001
|
-
const sortedInsights = this.state.guardianInsights.sort((a, b) => {
|
|
1002
|
-
if (a.dismissed !== b.dismissed) return a.dismissed ? 1 : -1;
|
|
1003
|
-
if (a.priority !== b.priority) return b.priority - a.priority;
|
|
1004
|
-
return b.timestamp - a.timestamp;
|
|
1005
|
-
});
|
|
1006
|
-
const insight2 = sortedInsights[this.state.scrollPositions.guardian];
|
|
1007
|
-
if (insight2 && !insight2.dismissed) {
|
|
1008
|
-
insight2.dismissed = true;
|
|
1009
|
-
this.persistInsightDismissal(insight2.id);
|
|
1010
|
-
this.addActivity(`\u2713 Dismissed: ${insight2.message.slice(0, 40)}...`);
|
|
1011
|
-
this.render();
|
|
1012
|
-
return;
|
|
1013
|
-
}
|
|
1014
|
-
}
|
|
1015
|
-
const insight = this.state.guardianInsights.filter((i) => !i.dismissed).sort((a, b) => b.priority - a.priority)[0];
|
|
1016
|
-
if (insight) {
|
|
1017
|
-
insight.dismissed = true;
|
|
1018
|
-
this.persistInsightDismissal(insight.id);
|
|
1019
|
-
this.addActivity(`\u2713 Acknowledged: ${insight.message.slice(0, 40)}...`);
|
|
1020
|
-
this.render();
|
|
1021
|
-
return;
|
|
1022
|
-
}
|
|
1023
|
-
const unread = this.state.notificationHistory.find((n) => !n.dismissed);
|
|
1024
|
-
if (unread) {
|
|
1025
|
-
unread.dismissed = true;
|
|
1026
|
-
this.render();
|
|
1027
|
-
}
|
|
1028
|
-
}
|
|
1029
1014
|
/**
|
|
1030
1015
|
* Dismiss the currently selected insight in Guardian view
|
|
1031
1016
|
*/
|
|
@@ -1555,6 +1540,10 @@ var InteractiveDashboard = class {
|
|
|
1555
1540
|
this.goToView("hypotheses");
|
|
1556
1541
|
this.refreshHypothesesData();
|
|
1557
1542
|
break;
|
|
1543
|
+
case "t":
|
|
1544
|
+
this.goToView("memory");
|
|
1545
|
+
this.loadMemoryTreeData();
|
|
1546
|
+
break;
|
|
1558
1547
|
}
|
|
1559
1548
|
if (this.isActive) {
|
|
1560
1549
|
this.render();
|
|
@@ -1776,6 +1765,9 @@ var InteractiveDashboard = class {
|
|
|
1776
1765
|
case "hypotheses":
|
|
1777
1766
|
this.renderHypothesesView(width, height);
|
|
1778
1767
|
break;
|
|
1768
|
+
case "memory":
|
|
1769
|
+
this.renderMemoryTreeView(width, height);
|
|
1770
|
+
break;
|
|
1779
1771
|
}
|
|
1780
1772
|
}
|
|
1781
1773
|
this.renderFooter(width);
|
|
@@ -2706,7 +2698,7 @@ var InteractiveDashboard = class {
|
|
|
2706
2698
|
this.renderLine(" " + colors.critical("[ERROR] Missing resolvedCount in goal achievement details"), width);
|
|
2707
2699
|
linesUsed++;
|
|
2708
2700
|
} else if (insight.details.resolvedCount === 0) {
|
|
2709
|
-
this.renderLine(" " + colors.
|
|
2701
|
+
this.renderLine(" " + colors.yellow("[WARNING] resolvedCount is 0 - no issues were found matching this goal"), width);
|
|
2710
2702
|
linesUsed++;
|
|
2711
2703
|
} else if (!insight.details.resolvedIssues) {
|
|
2712
2704
|
this.renderLine(" " + colors.critical(`[ERROR] Missing resolvedIssues array (expected ${insight.details.resolvedCount} issues)`), width);
|
|
@@ -2836,7 +2828,7 @@ var InteractiveDashboard = class {
|
|
|
2836
2828
|
this.renderLine(" " + colors.highlight("Active:"), width);
|
|
2837
2829
|
activeGoals.forEach((goal, idx) => {
|
|
2838
2830
|
const isSelected = goalsPanel.selectedIndex === idx;
|
|
2839
|
-
const progress =
|
|
2831
|
+
const progress = this.calculateGoalProgress(goal);
|
|
2840
2832
|
const bar = this.renderProgressBar(progress, 10);
|
|
2841
2833
|
const source = goal.autoGenerated ? colors.dim("[auto]") : colors.dim("[manual]");
|
|
2842
2834
|
const prefix = isSelected ? colors.highlight("\u25B6 ") : " ";
|
|
@@ -2937,14 +2929,265 @@ var InteractiveDashboard = class {
|
|
|
2937
2929
|
this.renderLine(" " + key("j/k") + colors.dim(" navigate ") + key("a") + colors.dim(" add ") + key("b") + colors.dim(" back"), width);
|
|
2938
2930
|
}
|
|
2939
2931
|
}
|
|
2932
|
+
/**
|
|
2933
|
+
* Calculate goal progress correctly for both increase and reduction goals.
|
|
2934
|
+
* For reduction goals (startValue > target): progress = (startValue - currentValue) / (startValue - target)
|
|
2935
|
+
* For increase goals (startValue <= target): progress = currentValue / target
|
|
2936
|
+
*/
|
|
2937
|
+
calculateGoalProgress(goal) {
|
|
2938
|
+
if (goal.target <= 0) return 0;
|
|
2939
|
+
const startValue = goal.startValue ?? goal.currentValue;
|
|
2940
|
+
if (startValue > goal.target) {
|
|
2941
|
+
const totalReduction = startValue - goal.target;
|
|
2942
|
+
const actualReduction = startValue - goal.currentValue;
|
|
2943
|
+
return Math.round(actualReduction / totalReduction * 100);
|
|
2944
|
+
}
|
|
2945
|
+
return Math.round(goal.currentValue / goal.target * 100);
|
|
2946
|
+
}
|
|
2940
2947
|
/**
|
|
2941
2948
|
* Render a simple progress bar
|
|
2942
2949
|
*/
|
|
2943
2950
|
renderProgressBar(percent, width) {
|
|
2944
|
-
const
|
|
2951
|
+
const clamped = Math.max(0, Math.min(100, percent));
|
|
2952
|
+
const filled = Math.round(clamped / 100 * width);
|
|
2945
2953
|
const empty = width - filled;
|
|
2946
2954
|
return colors.border("[") + colors.success("\u2588".repeat(filled)) + colors.dim("\u2591".repeat(empty)) + colors.border("]");
|
|
2947
2955
|
}
|
|
2956
|
+
/**
|
|
2957
|
+
* Render memory tree view - visual hierarchy of issues
|
|
2958
|
+
*/
|
|
2959
|
+
renderMemoryTreeView(width, _height) {
|
|
2960
|
+
const { memoryTree } = this.state;
|
|
2961
|
+
const stats = memoryTree.stats;
|
|
2962
|
+
const issues = memoryTree.issues;
|
|
2963
|
+
const patterns = memoryTree.globalPatterns;
|
|
2964
|
+
const totalIssues = stats?.totalIssues || issues.length;
|
|
2965
|
+
this.renderLine(" " + colors.header("MEMORY TREE") + " " + colors.dim(`[${totalIssues} issues]`) + " " + colors.border("[") + colors.highlight("t") + colors.border("]"), width);
|
|
2966
|
+
this.renderSectionBorder(width);
|
|
2967
|
+
if (!memoryTree.loaded) {
|
|
2968
|
+
this.renderLine(" " + colors.dim("Loading memory data..."), width);
|
|
2969
|
+
return;
|
|
2970
|
+
}
|
|
2971
|
+
if (issues.length === 0 && patterns.length === 0) {
|
|
2972
|
+
this.renderLine(" " + colors.dim("No issues in memory yet."), width);
|
|
2973
|
+
this.renderLine(" " + colors.dim("Run a scan to populate the memory tree."), width);
|
|
2974
|
+
return;
|
|
2975
|
+
}
|
|
2976
|
+
const tree = box;
|
|
2977
|
+
const selected = memoryTree.selectedNode;
|
|
2978
|
+
const expanded = memoryTree.expandedNodes;
|
|
2979
|
+
const bySeverity = { critical: [], serious: [], moderate: [], low: [] };
|
|
2980
|
+
for (const issue of issues) {
|
|
2981
|
+
const sev = issue.severity;
|
|
2982
|
+
if (sev === "critical") bySeverity.critical.push(issue);
|
|
2983
|
+
else if (sev === "serious") bySeverity.serious.push(issue);
|
|
2984
|
+
else if (sev === "moderate") bySeverity.moderate.push(issue);
|
|
2985
|
+
else if (sev === "low") bySeverity.low.push(issue);
|
|
2986
|
+
}
|
|
2987
|
+
const byFile = /* @__PURE__ */ new Map();
|
|
2988
|
+
for (const issue of issues) {
|
|
2989
|
+
if (!byFile.has(issue.file)) {
|
|
2990
|
+
byFile.set(issue.file, []);
|
|
2991
|
+
}
|
|
2992
|
+
byFile.get(issue.file).push(issue);
|
|
2993
|
+
}
|
|
2994
|
+
const sortedFiles = Array.from(byFile.entries()).sort((a, b) => b[1].length - a[1].length).slice(0, 10);
|
|
2995
|
+
const byAgent = /* @__PURE__ */ new Map();
|
|
2996
|
+
for (const issue of issues) {
|
|
2997
|
+
if (!byAgent.has(issue.agent)) {
|
|
2998
|
+
byAgent.set(issue.agent, []);
|
|
2999
|
+
}
|
|
3000
|
+
byAgent.get(issue.agent).push(issue);
|
|
3001
|
+
}
|
|
3002
|
+
const sortedAgents = Array.from(byAgent.entries()).sort((a, b) => b[1].length - a[1].length);
|
|
3003
|
+
const severityBar = (count, max, barWidth = 16) => {
|
|
3004
|
+
const filled = max > 0 ? Math.round(count / max * barWidth) : 0;
|
|
3005
|
+
return "\u2588".repeat(filled) + "\u2591".repeat(barWidth - filled);
|
|
3006
|
+
};
|
|
3007
|
+
const maxCount = Math.max(
|
|
3008
|
+
bySeverity.critical.length,
|
|
3009
|
+
bySeverity.serious.length,
|
|
3010
|
+
bySeverity.moderate.length,
|
|
3011
|
+
bySeverity.low.length,
|
|
3012
|
+
1
|
|
3013
|
+
);
|
|
3014
|
+
const sevExpanded = expanded.has("severity");
|
|
3015
|
+
const sevIcon = sevExpanded ? "\u25BC" : "\u25B6";
|
|
3016
|
+
const sevSelected = selected === "severity";
|
|
3017
|
+
const sevPrefix = sevSelected ? colors.selected("\u2192") : " ";
|
|
3018
|
+
this.renderLine(` ${sevPrefix} ${sevIcon} ` + (sevSelected ? colors.selected("By Severity") : colors.header("By Severity")), width);
|
|
3019
|
+
if (sevExpanded) {
|
|
3020
|
+
const critSelected = selected === "severity-critical";
|
|
3021
|
+
const critPrefix = critSelected ? colors.selected("\u2192") : " ";
|
|
3022
|
+
const critCount = bySeverity.critical.length;
|
|
3023
|
+
const critBar = colors.critical(severityBar(critCount, maxCount));
|
|
3024
|
+
this.renderLine(` ${critPrefix} ${tree.vertical} ${critSelected ? colors.selected("critical") : colors.critical("critical")} (${critCount}) ${critBar}`, width);
|
|
3025
|
+
if (expanded.has("severity-critical") && bySeverity.critical.length > 0) {
|
|
3026
|
+
const critIssues = bySeverity.critical.slice(0, 5);
|
|
3027
|
+
critIssues.forEach((issue, idx) => {
|
|
3028
|
+
const isLast = idx === critIssues.length - 1;
|
|
3029
|
+
const connector = isLast ? tree.bottomLeft : tree.leftT;
|
|
3030
|
+
const issueId = `severity-critical-${issue.id}`;
|
|
3031
|
+
const issueSelected = selected === issueId;
|
|
3032
|
+
const prefix = issueSelected ? colors.selected("\u2192") : " ";
|
|
3033
|
+
const filename = issue.file.split("/").pop() || issue.file;
|
|
3034
|
+
const line = issue.line ? `:${issue.line}` : "";
|
|
3035
|
+
const desc = issue.issue.slice(0, 35) + (issue.issue.length > 35 ? "..." : "");
|
|
3036
|
+
this.renderLine(` ${prefix} ${tree.vertical} ${connector}${tree.horizontal} ${issueSelected ? colors.selected(`${filename}${line}`) : colors.dim(`${filename}${line}`)} - ${colors.critical(desc)}`, width);
|
|
3037
|
+
});
|
|
3038
|
+
if (bySeverity.critical.length > 5) {
|
|
3039
|
+
this.renderLine(` ${tree.vertical} ${colors.dim(`... ${bySeverity.critical.length - 5} more`)}`, width);
|
|
3040
|
+
}
|
|
3041
|
+
}
|
|
3042
|
+
const serSelected = selected === "severity-serious";
|
|
3043
|
+
const serPrefix = serSelected ? colors.selected("\u2192") : " ";
|
|
3044
|
+
const serCount = bySeverity.serious.length;
|
|
3045
|
+
const serBar = colors.serious(severityBar(serCount, maxCount));
|
|
3046
|
+
this.renderLine(` ${serPrefix} ${tree.vertical} ${serSelected ? colors.selected("serious") : colors.serious("serious")} (${serCount}) ${serBar}`, width);
|
|
3047
|
+
const modSelected = selected === "severity-moderate";
|
|
3048
|
+
const modPrefix = modSelected ? colors.selected("\u2192") : " ";
|
|
3049
|
+
const modCount = bySeverity.moderate.length;
|
|
3050
|
+
const modBar = colors.moderate(severityBar(modCount, maxCount));
|
|
3051
|
+
this.renderLine(` ${modPrefix} ${tree.vertical} ${modSelected ? colors.selected("moderate") : colors.moderate("moderate")} (${modCount}) ${modBar}`, width);
|
|
3052
|
+
const lowSelected = selected === "severity-low";
|
|
3053
|
+
const lowPrefix = lowSelected ? colors.selected("\u2192") : " ";
|
|
3054
|
+
const lowCount = bySeverity.low.length;
|
|
3055
|
+
const lowBar = colors.low(severityBar(lowCount, maxCount));
|
|
3056
|
+
this.renderLine(` ${lowPrefix} ${tree.bottomLeft} ${lowSelected ? colors.selected("low") : colors.low("low")} (${lowCount}) ${lowBar}`, width);
|
|
3057
|
+
}
|
|
3058
|
+
const filesExpanded = expanded.has("files");
|
|
3059
|
+
const filesIcon = filesExpanded ? "\u25BC" : "\u25B6";
|
|
3060
|
+
const filesSelected = selected === "files";
|
|
3061
|
+
const filesPrefix = filesSelected ? colors.selected("\u2192") : " ";
|
|
3062
|
+
this.renderLine(` ${filesPrefix} ${filesIcon} ` + (filesSelected ? colors.selected("By File (Hot Spots)") : colors.header("By File (Hot Spots)")), width);
|
|
3063
|
+
if (filesExpanded && sortedFiles.length > 0) {
|
|
3064
|
+
const maxFileCount = sortedFiles[0]?.[1].length || 1;
|
|
3065
|
+
sortedFiles.forEach(([file, fileIssues], idx) => {
|
|
3066
|
+
const isLast = idx === sortedFiles.length - 1;
|
|
3067
|
+
const connector = isLast ? tree.bottomLeft : tree.leftT;
|
|
3068
|
+
const fileId = `file-${file}`;
|
|
3069
|
+
const fileNodeSelected = selected === fileId;
|
|
3070
|
+
const prefix = fileNodeSelected ? colors.selected("\u2192") : " ";
|
|
3071
|
+
const filename = file.split("/").pop() || file;
|
|
3072
|
+
const count = fileIssues.length;
|
|
3073
|
+
const fileBar = severityBar(count, maxFileCount);
|
|
3074
|
+
const hasCritical = fileIssues.some((i) => i.severity === "critical");
|
|
3075
|
+
const barColor = hasCritical ? colors.critical(fileBar) : colors.moderate(fileBar);
|
|
3076
|
+
this.renderLine(` ${prefix} ${connector}${tree.horizontal} ${fileNodeSelected ? colors.selected(filename) : filename} (${count}) ${barColor}`, width);
|
|
3077
|
+
});
|
|
3078
|
+
}
|
|
3079
|
+
const agentsExpanded = expanded.has("agents");
|
|
3080
|
+
const agentsIcon = agentsExpanded ? "\u25BC" : "\u25B6";
|
|
3081
|
+
const agentsSelected = selected === "agents";
|
|
3082
|
+
const agentsPrefix = agentsSelected ? colors.selected("\u2192") : " ";
|
|
3083
|
+
this.renderLine(` ${agentsPrefix} ${agentsIcon} ` + (agentsSelected ? colors.selected("By Agent") : colors.header("By Agent")), width);
|
|
3084
|
+
if (agentsExpanded && sortedAgents.length > 0) {
|
|
3085
|
+
sortedAgents.forEach(([agent, agentIssues], idx) => {
|
|
3086
|
+
const isLast = idx === sortedAgents.length - 1;
|
|
3087
|
+
const connector = isLast ? tree.bottomLeft : tree.leftT;
|
|
3088
|
+
const agentId = `agent-${agent}`;
|
|
3089
|
+
const agentSelected = selected === agentId;
|
|
3090
|
+
const prefix = agentSelected ? colors.selected("\u2192") : " ";
|
|
3091
|
+
this.renderLine(` ${prefix} ${connector}${tree.horizontal} ${agentSelected ? colors.selected(agent) : agent} (${agentIssues.length})`, width);
|
|
3092
|
+
});
|
|
3093
|
+
}
|
|
3094
|
+
const patternsExpanded = expanded.has("patterns");
|
|
3095
|
+
const patternsIcon = patternsExpanded ? "\u25BC" : "\u25B6";
|
|
3096
|
+
const patternsSelected = selected === "patterns";
|
|
3097
|
+
const patternsPrefix = patternsSelected ? colors.selected("\u2192") : " ";
|
|
3098
|
+
const patternCount = patterns.length;
|
|
3099
|
+
this.renderLine(` ${patternsPrefix} ${patternsIcon} ` + (patternsSelected ? colors.selected(`Cross-Project Patterns (${patternCount} recurring)`) : colors.header(`Cross-Project Patterns (${patternCount} recurring)`)), width);
|
|
3100
|
+
if (patternsExpanded && patterns.length > 0) {
|
|
3101
|
+
patterns.slice(0, 5).forEach((pattern, idx) => {
|
|
3102
|
+
const isLast = idx === Math.min(4, patterns.length - 1);
|
|
3103
|
+
const connector = isLast ? tree.bottomLeft : tree.leftT;
|
|
3104
|
+
const patternId = `pattern-${pattern.id}`;
|
|
3105
|
+
const patternNodeSelected = selected === patternId;
|
|
3106
|
+
const prefix = patternNodeSelected ? colors.selected("\u2192") : " ";
|
|
3107
|
+
const desc = pattern.pattern.slice(0, 40) + (pattern.pattern.length > 40 ? "..." : "");
|
|
3108
|
+
const projectsText = `seen in ${pattern.projects.length} projects`;
|
|
3109
|
+
this.renderLine(` ${prefix} ${connector}${tree.horizontal} ${patternNodeSelected ? colors.selected(`"${desc}"`) : colors.dim(`"${desc}"`)} - ${colors.dim(projectsText)}`, width);
|
|
3110
|
+
});
|
|
3111
|
+
if (patterns.length > 5) {
|
|
3112
|
+
this.renderLine(` ${colors.dim(`... ${patterns.length - 5} more patterns`)}`, width);
|
|
3113
|
+
}
|
|
3114
|
+
}
|
|
3115
|
+
this.renderLine("", width);
|
|
3116
|
+
this.renderSectionBorder(width);
|
|
3117
|
+
const trend = stats?.improvementTrend || "unknown";
|
|
3118
|
+
const trendIcon = trend === "improving" ? colors.success("\u2191") : trend === "declining" ? colors.critical("\u2193") : colors.dim("\u2192");
|
|
3119
|
+
const trendText = trend === "improving" ? colors.success("Improving") : trend === "declining" ? colors.critical("Declining") : colors.dim("Stable");
|
|
3120
|
+
const resolvedCount = stats?.resolvedCount || 0;
|
|
3121
|
+
this.renderLine(` ${colors.dim("Trend:")} ${trendIcon} ${trendText} ${colors.dim("| Resolved:")} ${colors.success(resolvedCount.toString())} ${colors.dim("| Historical:")} ${colors.dim((stats?.historicalIssues || 0).toString())}`, width);
|
|
3122
|
+
}
|
|
3123
|
+
/**
|
|
3124
|
+
* Get all visible memory tree nodes for navigation
|
|
3125
|
+
*/
|
|
3126
|
+
getMemoryTreeNodes() {
|
|
3127
|
+
const nodes = [];
|
|
3128
|
+
const expanded = this.state.memoryTree.expandedNodes;
|
|
3129
|
+
const issues = this.state.memoryTree.issues;
|
|
3130
|
+
const patterns = this.state.memoryTree.globalPatterns;
|
|
3131
|
+
nodes.push({ id: "severity", level: 0 });
|
|
3132
|
+
if (expanded.has("severity")) {
|
|
3133
|
+
nodes.push({ id: "severity-critical", level: 1 });
|
|
3134
|
+
if (expanded.has("severity-critical")) {
|
|
3135
|
+
const criticalIssues = issues.filter((i) => i.severity === "critical").slice(0, 5);
|
|
3136
|
+
criticalIssues.forEach((issue) => {
|
|
3137
|
+
nodes.push({ id: `severity-critical-${issue.id}`, level: 2 });
|
|
3138
|
+
});
|
|
3139
|
+
}
|
|
3140
|
+
nodes.push({ id: "severity-serious", level: 1 });
|
|
3141
|
+
nodes.push({ id: "severity-moderate", level: 1 });
|
|
3142
|
+
nodes.push({ id: "severity-low", level: 1 });
|
|
3143
|
+
}
|
|
3144
|
+
nodes.push({ id: "files", level: 0 });
|
|
3145
|
+
if (expanded.has("files")) {
|
|
3146
|
+
const byFile = /* @__PURE__ */ new Map();
|
|
3147
|
+
for (const issue of issues) {
|
|
3148
|
+
if (!byFile.has(issue.file)) byFile.set(issue.file, []);
|
|
3149
|
+
byFile.get(issue.file).push(issue);
|
|
3150
|
+
}
|
|
3151
|
+
const sortedFiles = Array.from(byFile.keys()).sort((a, b) => (byFile.get(b)?.length || 0) - (byFile.get(a)?.length || 0)).slice(0, 10);
|
|
3152
|
+
sortedFiles.forEach((file) => {
|
|
3153
|
+
nodes.push({ id: `file-${file}`, level: 1 });
|
|
3154
|
+
});
|
|
3155
|
+
}
|
|
3156
|
+
nodes.push({ id: "agents", level: 0 });
|
|
3157
|
+
if (expanded.has("agents")) {
|
|
3158
|
+
const byAgent = /* @__PURE__ */ new Map();
|
|
3159
|
+
for (const issue of issues) {
|
|
3160
|
+
if (!byAgent.has(issue.agent)) byAgent.set(issue.agent, []);
|
|
3161
|
+
byAgent.get(issue.agent).push(issue);
|
|
3162
|
+
}
|
|
3163
|
+
const sortedAgents = Array.from(byAgent.keys()).sort((a, b) => (byAgent.get(b)?.length || 0) - (byAgent.get(a)?.length || 0));
|
|
3164
|
+
sortedAgents.forEach((agent) => {
|
|
3165
|
+
nodes.push({ id: `agent-${agent}`, level: 1 });
|
|
3166
|
+
});
|
|
3167
|
+
}
|
|
3168
|
+
nodes.push({ id: "patterns", level: 0 });
|
|
3169
|
+
if (expanded.has("patterns")) {
|
|
3170
|
+
patterns.slice(0, 5).forEach((pattern) => {
|
|
3171
|
+
nodes.push({ id: `pattern-${pattern.id}`, level: 1 });
|
|
3172
|
+
});
|
|
3173
|
+
}
|
|
3174
|
+
return nodes;
|
|
3175
|
+
}
|
|
3176
|
+
/**
|
|
3177
|
+
* Toggle expand/collapse on selected memory tree node
|
|
3178
|
+
*/
|
|
3179
|
+
toggleMemoryTreeNode() {
|
|
3180
|
+
const selected = this.state.memoryTree.selectedNode;
|
|
3181
|
+
const expanded = this.state.memoryTree.expandedNodes;
|
|
3182
|
+
const expandableNodes = ["severity", "files", "agents", "patterns", "severity-critical", "severity-serious", "severity-moderate", "severity-low"];
|
|
3183
|
+
if (expandableNodes.includes(selected)) {
|
|
3184
|
+
if (expanded.has(selected)) {
|
|
3185
|
+
expanded.delete(selected);
|
|
3186
|
+
} else {
|
|
3187
|
+
expanded.add(selected);
|
|
3188
|
+
}
|
|
3189
|
+
}
|
|
3190
|
+
}
|
|
2948
3191
|
/**
|
|
2949
3192
|
* Refresh skills data from the system
|
|
2950
3193
|
*/
|
|
@@ -3051,6 +3294,34 @@ var InteractiveDashboard = class {
|
|
|
3051
3294
|
this.addActivity(`Hypotheses refresh error: ${error instanceof Error ? error.message : String(error)}`);
|
|
3052
3295
|
}
|
|
3053
3296
|
}
|
|
3297
|
+
/**
|
|
3298
|
+
* Load memory tree data from issue store and global patterns
|
|
3299
|
+
*/
|
|
3300
|
+
async loadMemoryTreeData() {
|
|
3301
|
+
const now = Date.now();
|
|
3302
|
+
if (now - this.state.memoryTree.lastRefresh < 500) {
|
|
3303
|
+
return;
|
|
3304
|
+
}
|
|
3305
|
+
this.state.memoryTree.lastRefresh = now;
|
|
3306
|
+
try {
|
|
3307
|
+
const workDir = getWorkingDirectory(void 0, true);
|
|
3308
|
+
const [issues, stats, patterns] = await Promise.all([
|
|
3309
|
+
getRecentIssues({ workDir, limit: 200, daysBack: 30 }),
|
|
3310
|
+
getMemoryStats(workDir),
|
|
3311
|
+
findCrossProjectPatterns(2)
|
|
3312
|
+
]);
|
|
3313
|
+
this.state.memoryTree.issues = issues;
|
|
3314
|
+
this.state.memoryTree.stats = stats;
|
|
3315
|
+
this.state.memoryTree.globalPatterns = patterns;
|
|
3316
|
+
this.state.memoryTree.loaded = true;
|
|
3317
|
+
if (!this.state.memoryTree.loaded) {
|
|
3318
|
+
this.addActivity(`Memory loaded: ${issues.length} issues, ${patterns.length} patterns`);
|
|
3319
|
+
}
|
|
3320
|
+
this.render();
|
|
3321
|
+
} catch (error) {
|
|
3322
|
+
this.addActivity(`Memory load error: ${error instanceof Error ? error.message : String(error)}`);
|
|
3323
|
+
}
|
|
3324
|
+
}
|
|
3054
3325
|
/**
|
|
3055
3326
|
* Add a new goal from the UI
|
|
3056
3327
|
*
|
|
@@ -3723,6 +3994,7 @@ var InteractiveDashboard = class {
|
|
|
3723
3994
|
}
|
|
3724
3995
|
if (this.state.readiness) paneHints.push(hint("r", "Ready"));
|
|
3725
3996
|
if (this.state.semanticAnalysis || this.state.attackSurface) paneHints.push(hint("a", "Analysis"));
|
|
3997
|
+
paneHints.push(hint("t", "Memory"));
|
|
3726
3998
|
paneHints.push(hint("i", "Toolkit"));
|
|
3727
3999
|
paneHints.push(hint("l", "Log"));
|
|
3728
4000
|
const paneStr = paneHints.length > 0 ? " " + paneHints.join(" ") : "";
|
|
@@ -3758,6 +4030,8 @@ var InteractiveDashboard = class {
|
|
|
3758
4030
|
} else {
|
|
3759
4031
|
this.renderLine(" " + hint("j/k", "Nav") + " " + hint("a", "Add") + " " + hint("v", "Validate") + " " + hint("x", "Invalidate") + " " + hint("d", "Delete") + " " + hint("b", "Back") + " " + hint("q", "Quit"), width);
|
|
3760
4032
|
}
|
|
4033
|
+
} else if (this.state.view === "memory") {
|
|
4034
|
+
this.renderLine(" " + hint("j/k", "Nav") + " " + hint("Enter", "Expand") + " " + hint("b", "Back") + " " + hint("h", "Help") + " " + hint("q", "Quit"), width);
|
|
3761
4035
|
} else if (this.state.view === "details" || this.state.view === "costs" || this.state.view === "readiness" || this.state.view === "analysis" || this.state.view === "rawlog") {
|
|
3762
4036
|
this.renderLine(" " + hint("b", "Back") + " " + hint("n/p", "Pages") + " " + hint("Tab", "Main") + " " + hint("h", "Help") + " " + hint("q", "Quit"), width);
|
|
3763
4037
|
} else if (this.state.view === "agents") {
|
|
@@ -3775,11 +4049,15 @@ var InteractiveDashboard = class {
|
|
|
3775
4049
|
return;
|
|
3776
4050
|
}
|
|
3777
4051
|
if (!this.state.scanComplete) return;
|
|
3778
|
-
const mainViews = ["overview", "issues", "agents", "files"];
|
|
4052
|
+
const mainViews = ["overview", "issues", "agents", "files", "memory"];
|
|
3779
4053
|
const currentIndex = mainViews.indexOf(this.state.view);
|
|
3780
4054
|
if (currentIndex >= 0) {
|
|
3781
4055
|
const nextIndex = (currentIndex + 1) % mainViews.length;
|
|
3782
|
-
|
|
4056
|
+
const nextView = mainViews[nextIndex] ?? "overview";
|
|
4057
|
+
this.state.view = nextView;
|
|
4058
|
+
if (nextView === "memory") {
|
|
4059
|
+
this.loadMemoryTreeData();
|
|
4060
|
+
}
|
|
3783
4061
|
} else {
|
|
3784
4062
|
this.state.view = "overview";
|
|
3785
4063
|
}
|
|
@@ -3818,6 +4096,12 @@ var InteractiveDashboard = class {
|
|
|
3818
4096
|
if (this.state.selectedGuardianInsight < this.state.scrollPositions.guardian) {
|
|
3819
4097
|
this.state.scrollPositions.guardian = this.state.selectedGuardianInsight;
|
|
3820
4098
|
}
|
|
4099
|
+
} else if (this.state.view === "memory") {
|
|
4100
|
+
const nodes = this.getMemoryTreeNodes();
|
|
4101
|
+
const currentIdx = nodes.findIndex((n) => n.id === this.state.memoryTree.selectedNode);
|
|
4102
|
+
if (currentIdx > 0) {
|
|
4103
|
+
this.state.memoryTree.selectedNode = nodes[currentIdx - 1]?.id || nodes[0]?.id || "severity";
|
|
4104
|
+
}
|
|
3821
4105
|
}
|
|
3822
4106
|
}
|
|
3823
4107
|
navigateDown() {
|
|
@@ -3852,6 +4136,12 @@ var InteractiveDashboard = class {
|
|
|
3852
4136
|
if (this.state.selectedGuardianInsight >= this.state.scrollPositions.guardian + visibleItems) {
|
|
3853
4137
|
this.state.scrollPositions.guardian = this.state.selectedGuardianInsight - visibleItems + 1;
|
|
3854
4138
|
}
|
|
4139
|
+
} else if (this.state.view === "memory") {
|
|
4140
|
+
const nodes = this.getMemoryTreeNodes();
|
|
4141
|
+
const currentIdx = nodes.findIndex((n) => n.id === this.state.memoryTree.selectedNode);
|
|
4142
|
+
if (currentIdx < nodes.length - 1) {
|
|
4143
|
+
this.state.memoryTree.selectedNode = nodes[currentIdx + 1]?.id || "severity";
|
|
4144
|
+
}
|
|
3855
4145
|
}
|
|
3856
4146
|
}
|
|
3857
4147
|
getSortedAgents() {
|
|
@@ -3963,6 +4253,8 @@ var InteractiveDashboard = class {
|
|
|
3963
4253
|
} else {
|
|
3964
4254
|
this.state.expandedGuardianInsight = this.state.selectedGuardianInsight;
|
|
3965
4255
|
}
|
|
4256
|
+
} else if (this.state.view === "memory") {
|
|
4257
|
+
this.toggleMemoryTreeNode();
|
|
3966
4258
|
}
|
|
3967
4259
|
}
|
|
3968
4260
|
/**
|
|
@@ -10113,4 +10405,4 @@ export {
|
|
|
10113
10405
|
InteractiveDashboard,
|
|
10114
10406
|
TrieScanTool
|
|
10115
10407
|
};
|
|
10116
|
-
//# sourceMappingURL=chunk-
|
|
10408
|
+
//# sourceMappingURL=chunk-OAICCSDL.js.map
|