@triedotdev/mcp 1.0.58 → 1.0.60
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 +17 -13
- package/dist/{agent-smith-O7RG7WQ3.js → agent-smith-4IJZHSNQ.js} +3 -2
- package/dist/{agent-smith-runner-EW4C4PTF.js → agent-smith-runner-4PE3GOUX.js} +5 -3
- package/dist/{agent-smith-runner-EW4C4PTF.js.map → agent-smith-runner-4PE3GOUX.js.map} +1 -1
- package/dist/{chunk-HUQQSQOD.js → chunk-3XWSM2DU.js} +73 -44
- package/dist/chunk-3XWSM2DU.js.map +1 -0
- package/dist/{chunk-KLKY34RE.js → chunk-4EHBRED6.js} +139 -12
- package/dist/chunk-4EHBRED6.js.map +1 -0
- package/dist/{chunk-6ODT4U4O.js → chunk-C7LXN754.js} +539 -194
- package/dist/chunk-C7LXN754.js.map +1 -0
- package/dist/{chunk-AVOMCNBD.js → chunk-DV3JQTLQ.js} +23 -86
- package/dist/chunk-DV3JQTLQ.js.map +1 -0
- package/dist/{chunk-3CS6Z2SL.js → chunk-MVUCBUBR.js} +7 -2
- package/dist/chunk-MVUCBUBR.js.map +1 -0
- package/dist/{chunk-JAVEBJF4.js → chunk-NM7ZVUHO.js} +790 -62
- package/dist/chunk-NM7ZVUHO.js.map +1 -0
- package/dist/chunk-RAZUNSBI.js +171 -0
- package/dist/chunk-RAZUNSBI.js.map +1 -0
- package/dist/{chunk-MR755QGT.js → chunk-ULOW5HSH.js} +7 -2
- package/dist/chunk-ULOW5HSH.js.map +1 -0
- package/dist/cli/main.js +6 -5
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/yolo-daemon.js +10 -9
- package/dist/cli/yolo-daemon.js.map +1 -1
- package/dist/index.js +37 -23
- package/dist/index.js.map +1 -1
- package/dist/{vibe-code-signatures-4CBHUSI7.js → vibe-code-signatures-TGMQXYGO.js} +3 -2
- package/dist/{vulnerability-signatures-J3CUQ7VR.js → vulnerability-signatures-GOVD4Q24.js} +3 -2
- package/dist/workers/agent-worker.js +4 -3
- package/dist/workers/agent-worker.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-3CS6Z2SL.js.map +0 -1
- package/dist/chunk-6ODT4U4O.js.map +0 -1
- package/dist/chunk-AVOMCNBD.js.map +0 -1
- package/dist/chunk-HUQQSQOD.js.map +0 -1
- package/dist/chunk-JAVEBJF4.js.map +0 -1
- package/dist/chunk-KLKY34RE.js.map +0 -1
- package/dist/chunk-MR755QGT.js.map +0 -1
- /package/dist/{agent-smith-O7RG7WQ3.js.map → agent-smith-4IJZHSNQ.js.map} +0 -0
- /package/dist/{vibe-code-signatures-4CBHUSI7.js.map → vibe-code-signatures-TGMQXYGO.js.map} +0 -0
- /package/dist/{vulnerability-signatures-J3CUQ7VR.js.map → vulnerability-signatures-GOVD4Q24.js.map} +0 -0
|
@@ -1,170 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getWorkingDirectory
|
|
3
3
|
} from "./chunk-ASGSTVVF.js";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
_interactiveMode = enabled;
|
|
9
|
-
}
|
|
10
|
-
function isInteractiveMode() {
|
|
11
|
-
return _interactiveMode;
|
|
12
|
-
}
|
|
13
|
-
var ProgressReporter = class {
|
|
14
|
-
currentPhase = "init";
|
|
15
|
-
startTime = Date.now();
|
|
16
|
-
phaseStartTime = Date.now();
|
|
17
|
-
verbose;
|
|
18
|
-
constructor(options = {}) {
|
|
19
|
-
this.verbose = options.verbose ?? true;
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Report a status update
|
|
23
|
-
*/
|
|
24
|
-
report(message, detail) {
|
|
25
|
-
if (!this.verbose || _interactiveMode) return;
|
|
26
|
-
const prefix = this.getPhaseIcon(this.currentPhase);
|
|
27
|
-
const fullMessage = detail ? `${message}: ${detail}` : message;
|
|
28
|
-
console.error(`${prefix} ${fullMessage}`);
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* Start a new phase
|
|
32
|
-
*/
|
|
33
|
-
startPhase(phase, message) {
|
|
34
|
-
this.currentPhase = phase;
|
|
35
|
-
this.phaseStartTime = Date.now();
|
|
36
|
-
this.report(message);
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* Update within current phase
|
|
40
|
-
*/
|
|
41
|
-
update(message, detail) {
|
|
42
|
-
this.report(message, detail);
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* Report progress on a file
|
|
46
|
-
*/
|
|
47
|
-
file(action, filePath) {
|
|
48
|
-
const fileName = filePath.split("/").pop() || filePath;
|
|
49
|
-
this.report(action, fileName);
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* Report an AI analysis step
|
|
53
|
-
*/
|
|
54
|
-
ai(action, context) {
|
|
55
|
-
if (_interactiveMode) return;
|
|
56
|
-
const prefix = "[AI]";
|
|
57
|
-
const message = context ? `${action}: ${context}` : action;
|
|
58
|
-
console.error(`${prefix} ${message}`);
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* Report a finding
|
|
62
|
-
*/
|
|
63
|
-
finding(severity, message) {
|
|
64
|
-
if (_interactiveMode) return;
|
|
65
|
-
const labels = {
|
|
66
|
-
critical: "[CRITICAL]",
|
|
67
|
-
serious: "[SERIOUS]",
|
|
68
|
-
moderate: "[MODERATE]",
|
|
69
|
-
low: "[LOW]"
|
|
70
|
-
};
|
|
71
|
-
console.error(` ${labels[severity]} ${message}`);
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* Complete current phase
|
|
75
|
-
*/
|
|
76
|
-
completePhase(summary) {
|
|
77
|
-
const elapsed = Date.now() - this.phaseStartTime;
|
|
78
|
-
this.report(`Done: ${summary}`, `(${elapsed}ms)`);
|
|
79
|
-
}
|
|
80
|
-
/**
|
|
81
|
-
* Complete the entire operation
|
|
82
|
-
*/
|
|
83
|
-
complete(summary) {
|
|
84
|
-
if (_interactiveMode) return;
|
|
85
|
-
const totalElapsed = Date.now() - this.startTime;
|
|
86
|
-
console.error("");
|
|
87
|
-
console.error(`----------------------------------------`);
|
|
88
|
-
console.error(`[COMPLETE] ${summary}`);
|
|
89
|
-
console.error(` Total time: ${(totalElapsed / 1e3).toFixed(2)}s`);
|
|
90
|
-
console.error(`----------------------------------------`);
|
|
91
|
-
console.error("");
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* Report an error
|
|
95
|
-
*/
|
|
96
|
-
error(message, detail) {
|
|
97
|
-
if (_interactiveMode) return;
|
|
98
|
-
const fullMessage = detail ? `${message}: ${detail}` : message;
|
|
99
|
-
console.error(`[ERROR] ${fullMessage}`);
|
|
100
|
-
}
|
|
101
|
-
/**
|
|
102
|
-
* Report a warning
|
|
103
|
-
*/
|
|
104
|
-
warn(message, detail) {
|
|
105
|
-
if (_interactiveMode) return;
|
|
106
|
-
const fullMessage = detail ? `${message}: ${detail}` : message;
|
|
107
|
-
console.error(`[WARN] ${fullMessage}`);
|
|
108
|
-
}
|
|
109
|
-
/**
|
|
110
|
-
* Get icon for current phase
|
|
111
|
-
*/
|
|
112
|
-
getPhaseIcon(phase) {
|
|
113
|
-
const icons = {
|
|
114
|
-
"init": ">>",
|
|
115
|
-
"discovery": ">>",
|
|
116
|
-
"reading": ">>",
|
|
117
|
-
"analyzing": ">>",
|
|
118
|
-
"ai-review": "[AI]",
|
|
119
|
-
"prioritizing": ">>",
|
|
120
|
-
"complete": "[OK]"
|
|
121
|
-
};
|
|
122
|
-
return icons[phase] || ">>";
|
|
123
|
-
}
|
|
124
|
-
/**
|
|
125
|
-
* Create a sub-reporter for a specific agent
|
|
126
|
-
*/
|
|
127
|
-
forAgent(agentName) {
|
|
128
|
-
return new AgentProgressReporter(agentName, this.verbose);
|
|
129
|
-
}
|
|
130
|
-
};
|
|
131
|
-
var AgentProgressReporter = class {
|
|
132
|
-
agentName;
|
|
133
|
-
verbose;
|
|
134
|
-
issueCount = 0;
|
|
135
|
-
constructor(agentName, verbose = true) {
|
|
136
|
-
this.agentName = agentName;
|
|
137
|
-
this.verbose = verbose;
|
|
138
|
-
}
|
|
139
|
-
start() {
|
|
140
|
-
if (!this.verbose || _interactiveMode) return;
|
|
141
|
-
console.error(`
|
|
142
|
-
[AGENT] ${this.agentName.toUpperCase()} starting...`);
|
|
143
|
-
}
|
|
144
|
-
analyzing(file) {
|
|
145
|
-
if (!this.verbose || _interactiveMode) return;
|
|
146
|
-
const fileName = file.split("/").pop() || file;
|
|
147
|
-
console.error(` Analyzing ${fileName}...`);
|
|
148
|
-
}
|
|
149
|
-
aiReview(context) {
|
|
150
|
-
if (!this.verbose || _interactiveMode) return;
|
|
151
|
-
console.error(` [AI] reviewing: ${context}`);
|
|
152
|
-
}
|
|
153
|
-
found(severity, issue) {
|
|
154
|
-
this.issueCount++;
|
|
155
|
-
if (!this.verbose || _interactiveMode) return;
|
|
156
|
-
const label = severity === "critical" ? "[CRITICAL]" : severity === "serious" ? "[SERIOUS]" : severity === "moderate" ? "[MODERATE]" : "[LOW]";
|
|
157
|
-
console.error(` ${label} Found: ${issue}`);
|
|
158
|
-
}
|
|
159
|
-
complete(summary) {
|
|
160
|
-
if (!this.verbose || _interactiveMode) return;
|
|
161
|
-
const msg = summary || `Found ${this.issueCount} issues`;
|
|
162
|
-
console.error(` Done: ${this.agentName}: ${msg}`);
|
|
163
|
-
}
|
|
164
|
-
getIssueCount() {
|
|
165
|
-
return this.issueCount;
|
|
166
|
-
}
|
|
167
|
-
};
|
|
4
|
+
import {
|
|
5
|
+
AgentProgressReporter,
|
|
6
|
+
isInteractiveMode
|
|
7
|
+
} from "./chunk-RAZUNSBI.js";
|
|
168
8
|
|
|
169
9
|
// src/skills/built-in/base-skill.ts
|
|
170
10
|
import { relative } from "path";
|
|
@@ -635,6 +475,518 @@ import { readFile, writeFile, mkdir, rm } from "fs/promises";
|
|
|
635
475
|
import { existsSync as existsSync2 } from "fs";
|
|
636
476
|
import { join as join2, dirname, basename } from "path";
|
|
637
477
|
import { createHash } from "crypto";
|
|
478
|
+
|
|
479
|
+
// src/utils/output-manager.ts
|
|
480
|
+
import pc from "picocolors";
|
|
481
|
+
var OutputManagerImpl = class {
|
|
482
|
+
mode = "console";
|
|
483
|
+
streamingManager;
|
|
484
|
+
markdownBuffer = [];
|
|
485
|
+
jsonBuffer = [];
|
|
486
|
+
rawLogBuffer = [];
|
|
487
|
+
// Callbacks for TUI integration (explicitly allow undefined for exactOptionalPropertyTypes)
|
|
488
|
+
onBanner = void 0;
|
|
489
|
+
onSnippet = void 0;
|
|
490
|
+
onCost = void 0;
|
|
491
|
+
onReadiness = void 0;
|
|
492
|
+
onSemantic = void 0;
|
|
493
|
+
onAttack = void 0;
|
|
494
|
+
onActivity = void 0;
|
|
495
|
+
onLog = void 0;
|
|
496
|
+
/**
|
|
497
|
+
* Set the output mode
|
|
498
|
+
*/
|
|
499
|
+
setMode(mode) {
|
|
500
|
+
this.mode = mode;
|
|
501
|
+
}
|
|
502
|
+
/**
|
|
503
|
+
* Get current output mode
|
|
504
|
+
*/
|
|
505
|
+
getMode() {
|
|
506
|
+
return this.mode;
|
|
507
|
+
}
|
|
508
|
+
/**
|
|
509
|
+
* Set streaming manager for TUI updates
|
|
510
|
+
*/
|
|
511
|
+
setStreamingManager(manager) {
|
|
512
|
+
this.streamingManager = manager;
|
|
513
|
+
}
|
|
514
|
+
/**
|
|
515
|
+
* Register TUI callbacks for rich content
|
|
516
|
+
*/
|
|
517
|
+
registerTUICallbacks(callbacks) {
|
|
518
|
+
this.onBanner = callbacks.onBanner;
|
|
519
|
+
this.onSnippet = callbacks.onSnippet;
|
|
520
|
+
this.onCost = callbacks.onCost;
|
|
521
|
+
this.onReadiness = callbacks.onReadiness;
|
|
522
|
+
this.onSemantic = callbacks.onSemantic;
|
|
523
|
+
this.onAttack = callbacks.onAttack;
|
|
524
|
+
this.onActivity = callbacks.onActivity;
|
|
525
|
+
this.onLog = callbacks.onLog;
|
|
526
|
+
}
|
|
527
|
+
/**
|
|
528
|
+
* Clear TUI callbacks (when dashboard stops)
|
|
529
|
+
*/
|
|
530
|
+
clearTUICallbacks() {
|
|
531
|
+
this.onBanner = void 0;
|
|
532
|
+
this.onSnippet = void 0;
|
|
533
|
+
this.onCost = void 0;
|
|
534
|
+
this.onReadiness = void 0;
|
|
535
|
+
this.onSemantic = void 0;
|
|
536
|
+
this.onAttack = void 0;
|
|
537
|
+
this.onActivity = void 0;
|
|
538
|
+
this.onLog = void 0;
|
|
539
|
+
}
|
|
540
|
+
/**
|
|
541
|
+
* Emit content - routes to appropriate handler based on mode
|
|
542
|
+
*/
|
|
543
|
+
emit(content) {
|
|
544
|
+
content.timestamp = content.timestamp ?? Date.now();
|
|
545
|
+
switch (this.mode) {
|
|
546
|
+
case "tui":
|
|
547
|
+
this.routeToTUI(content);
|
|
548
|
+
break;
|
|
549
|
+
case "console":
|
|
550
|
+
this.routeToConsole(content);
|
|
551
|
+
break;
|
|
552
|
+
case "mcp":
|
|
553
|
+
this.routeToMarkdown(content);
|
|
554
|
+
break;
|
|
555
|
+
case "json":
|
|
556
|
+
this.routeToJson(content);
|
|
557
|
+
break;
|
|
558
|
+
case "silent":
|
|
559
|
+
break;
|
|
560
|
+
}
|
|
561
|
+
this.captureRawLog(content);
|
|
562
|
+
}
|
|
563
|
+
/**
|
|
564
|
+
* Route content to TUI (dashboard callbacks)
|
|
565
|
+
*/
|
|
566
|
+
routeToTUI(content) {
|
|
567
|
+
switch (content.type) {
|
|
568
|
+
case "banner":
|
|
569
|
+
this.onBanner?.(content.content);
|
|
570
|
+
break;
|
|
571
|
+
case "snippet":
|
|
572
|
+
this.onSnippet?.(content.content);
|
|
573
|
+
break;
|
|
574
|
+
case "cost":
|
|
575
|
+
this.onCost?.(content.content);
|
|
576
|
+
break;
|
|
577
|
+
case "readiness":
|
|
578
|
+
this.onReadiness?.(content.content);
|
|
579
|
+
break;
|
|
580
|
+
case "semantic":
|
|
581
|
+
this.onSemantic?.(content.content);
|
|
582
|
+
break;
|
|
583
|
+
case "attack":
|
|
584
|
+
this.onAttack?.(content.content);
|
|
585
|
+
break;
|
|
586
|
+
case "activity":
|
|
587
|
+
this.onActivity?.(content.content);
|
|
588
|
+
break;
|
|
589
|
+
case "log":
|
|
590
|
+
const level = content.metadata?.severity ?? "info";
|
|
591
|
+
this.onLog?.(level, content.content);
|
|
592
|
+
break;
|
|
593
|
+
case "issue":
|
|
594
|
+
this.streamingManager?.reportIssue(content.content);
|
|
595
|
+
break;
|
|
596
|
+
case "progress":
|
|
597
|
+
break;
|
|
598
|
+
case "report":
|
|
599
|
+
break;
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
/**
|
|
603
|
+
* Route content to console (ANSI formatted)
|
|
604
|
+
*/
|
|
605
|
+
routeToConsole(content) {
|
|
606
|
+
switch (content.type) {
|
|
607
|
+
case "banner":
|
|
608
|
+
const banner = content.content;
|
|
609
|
+
console.error("\n" + "=".repeat(60));
|
|
610
|
+
console.error(banner.art);
|
|
611
|
+
if (banner.version) {
|
|
612
|
+
console.error(` ${banner.skill} v${banner.version}`);
|
|
613
|
+
}
|
|
614
|
+
console.error("");
|
|
615
|
+
if (banner.quote) {
|
|
616
|
+
console.error(` "${banner.quote}"`);
|
|
617
|
+
}
|
|
618
|
+
console.error("=".repeat(60) + "\n");
|
|
619
|
+
break;
|
|
620
|
+
case "snippet":
|
|
621
|
+
const snippet = content.content;
|
|
622
|
+
console.error(`
|
|
623
|
+
${pc.dim("File:")} ${snippet.file}`);
|
|
624
|
+
for (let i = 0; i < snippet.lines.length; i++) {
|
|
625
|
+
const lineNum = snippet.startLine + i;
|
|
626
|
+
const isHighlight = lineNum === snippet.highlightLine;
|
|
627
|
+
const prefix = isHighlight ? pc.red("\u2192") : " ";
|
|
628
|
+
const lineNumStr = pc.dim(lineNum.toString().padStart(4));
|
|
629
|
+
const line = isHighlight ? pc.yellow(snippet.lines[i]) : snippet.lines[i];
|
|
630
|
+
console.error(`${prefix} ${lineNumStr} | ${line}`);
|
|
631
|
+
}
|
|
632
|
+
console.error("");
|
|
633
|
+
break;
|
|
634
|
+
case "cost":
|
|
635
|
+
const cost = content.content;
|
|
636
|
+
console.error("\n" + pc.cyan("\u{1F4B0} Cost Estimate:"));
|
|
637
|
+
console.error(` Fix now: ${pc.green(this.formatCurrency(cost.fixNowCost))}`);
|
|
638
|
+
console.error(` If production: ${pc.red(this.formatCurrency(cost.productionCost))}`);
|
|
639
|
+
console.error(` Savings: ${pc.yellow(this.formatCurrency(cost.savings))}`);
|
|
640
|
+
console.error("");
|
|
641
|
+
break;
|
|
642
|
+
case "readiness":
|
|
643
|
+
const readiness = content.content;
|
|
644
|
+
const statusColor = readiness.status === "ready" ? pc.green : readiness.status === "caution" ? pc.yellow : pc.red;
|
|
645
|
+
console.error("\n" + pc.cyan("\u{1F4CA} Production Readiness:"));
|
|
646
|
+
console.error(` Score: ${statusColor(readiness.score + "/100")}`);
|
|
647
|
+
console.error(` Requirements: ${readiness.requirementsMet}/${readiness.total}`);
|
|
648
|
+
console.error(` Status: ${statusColor(readiness.status.toUpperCase())}`);
|
|
649
|
+
console.error("");
|
|
650
|
+
break;
|
|
651
|
+
case "semantic":
|
|
652
|
+
const semantic = content.content;
|
|
653
|
+
console.error("\n" + pc.cyan("\u{1F50D} Semantic Analysis:"));
|
|
654
|
+
if (semantic.dataFlowIssues > 0) {
|
|
655
|
+
console.error(` ${pc.red("[!]")} ${semantic.dataFlowIssues} data flow vulnerabilities`);
|
|
656
|
+
}
|
|
657
|
+
if (semantic.raceConditions > 0) {
|
|
658
|
+
console.error(` ${pc.yellow("[~]")} ${semantic.raceConditions} race conditions`);
|
|
659
|
+
}
|
|
660
|
+
if (semantic.authIssues > 0) {
|
|
661
|
+
console.error(` ${pc.red("[!]")} ${semantic.authIssues} authentication issues`);
|
|
662
|
+
}
|
|
663
|
+
console.error("");
|
|
664
|
+
break;
|
|
665
|
+
case "attack":
|
|
666
|
+
const attack = content.content;
|
|
667
|
+
console.error("\n" + pc.cyan("\u{1F3AF} Attack Surface:"));
|
|
668
|
+
console.error(` Endpoints: ${attack.totalEndpoints}`);
|
|
669
|
+
if (attack.unprotected > 0) {
|
|
670
|
+
console.error(` ${pc.red("Unprotected:")} ${attack.unprotected}`);
|
|
671
|
+
}
|
|
672
|
+
console.error(` Risk Score: ${attack.riskScore}/100`);
|
|
673
|
+
console.error("");
|
|
674
|
+
break;
|
|
675
|
+
case "activity":
|
|
676
|
+
console.error(pc.dim(`[${this.formatTime()}]`) + ` ${content.content}`);
|
|
677
|
+
break;
|
|
678
|
+
case "log":
|
|
679
|
+
const logLevel = String(content.metadata?.severity ?? "info");
|
|
680
|
+
const levelColor = logLevel === "error" || logLevel === "critical" ? pc.red : logLevel === "warn" || logLevel === "serious" ? pc.yellow : logLevel === "info" || logLevel === "moderate" ? pc.blue : pc.dim;
|
|
681
|
+
console.error(levelColor(`[${logLevel.toUpperCase()}]`) + ` ${content.content}`);
|
|
682
|
+
break;
|
|
683
|
+
case "issue":
|
|
684
|
+
const issue = content.content;
|
|
685
|
+
const sevColor = issue.severity === "critical" ? pc.red : issue.severity === "serious" ? pc.yellow : issue.severity === "moderate" ? pc.blue : pc.dim;
|
|
686
|
+
console.error(`${sevColor(`[${issue.severity.toUpperCase()}]`)} ${issue.issue}`);
|
|
687
|
+
console.error(` ${pc.dim("File:")} ${issue.file}:${issue.line ?? "?"}`);
|
|
688
|
+
break;
|
|
689
|
+
case "report":
|
|
690
|
+
console.error(content.content);
|
|
691
|
+
break;
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
/**
|
|
695
|
+
* Route content to markdown buffer
|
|
696
|
+
*/
|
|
697
|
+
routeToMarkdown(content) {
|
|
698
|
+
switch (content.type) {
|
|
699
|
+
case "banner":
|
|
700
|
+
const banner = content.content;
|
|
701
|
+
this.markdownBuffer.push(`## ${banner.skill}
|
|
702
|
+
`);
|
|
703
|
+
if (banner.quote) {
|
|
704
|
+
this.markdownBuffer.push(`> ${banner.quote}
|
|
705
|
+
`);
|
|
706
|
+
}
|
|
707
|
+
break;
|
|
708
|
+
case "snippet":
|
|
709
|
+
const snippet = content.content;
|
|
710
|
+
this.markdownBuffer.push(`
|
|
711
|
+
**File:** \`${snippet.file}\`
|
|
712
|
+
`);
|
|
713
|
+
this.markdownBuffer.push("```\n");
|
|
714
|
+
for (let i = 0; i < snippet.lines.length; i++) {
|
|
715
|
+
const lineNum = snippet.startLine + i;
|
|
716
|
+
const prefix = lineNum === snippet.highlightLine ? "\u2192" : " ";
|
|
717
|
+
this.markdownBuffer.push(`${prefix} ${lineNum.toString().padStart(4)} | ${snippet.lines[i]}
|
|
718
|
+
`);
|
|
719
|
+
}
|
|
720
|
+
this.markdownBuffer.push("```\n");
|
|
721
|
+
break;
|
|
722
|
+
case "cost":
|
|
723
|
+
const cost = content.content;
|
|
724
|
+
this.markdownBuffer.push(`
|
|
725
|
+
### Cost Estimate
|
|
726
|
+
`);
|
|
727
|
+
this.markdownBuffer.push(`- Fix now: ${this.formatCurrency(cost.fixNowCost)}
|
|
728
|
+
`);
|
|
729
|
+
this.markdownBuffer.push(`- If production: ${this.formatCurrency(cost.productionCost)}
|
|
730
|
+
`);
|
|
731
|
+
this.markdownBuffer.push(`- Savings: ${this.formatCurrency(cost.savings)}
|
|
732
|
+
`);
|
|
733
|
+
break;
|
|
734
|
+
case "readiness":
|
|
735
|
+
const readiness = content.content;
|
|
736
|
+
this.markdownBuffer.push(`
|
|
737
|
+
### Production Readiness
|
|
738
|
+
`);
|
|
739
|
+
this.markdownBuffer.push(`- Score: ${readiness.score}/100
|
|
740
|
+
`);
|
|
741
|
+
this.markdownBuffer.push(`- Requirements: ${readiness.requirementsMet}/${readiness.total}
|
|
742
|
+
`);
|
|
743
|
+
this.markdownBuffer.push(`- Status: **${readiness.status.toUpperCase()}**
|
|
744
|
+
`);
|
|
745
|
+
break;
|
|
746
|
+
case "semantic":
|
|
747
|
+
const semantic = content.content;
|
|
748
|
+
this.markdownBuffer.push(`
|
|
749
|
+
### Semantic Analysis
|
|
750
|
+
`);
|
|
751
|
+
if (semantic.dataFlowIssues > 0) {
|
|
752
|
+
this.markdownBuffer.push(`- [CRITICAL] ${semantic.dataFlowIssues} data flow vulnerabilities
|
|
753
|
+
`);
|
|
754
|
+
}
|
|
755
|
+
if (semantic.raceConditions > 0) {
|
|
756
|
+
this.markdownBuffer.push(`- [WARN] ${semantic.raceConditions} race conditions
|
|
757
|
+
`);
|
|
758
|
+
}
|
|
759
|
+
if (semantic.authIssues > 0) {
|
|
760
|
+
this.markdownBuffer.push(`- [CRITICAL] ${semantic.authIssues} authentication issues
|
|
761
|
+
`);
|
|
762
|
+
}
|
|
763
|
+
break;
|
|
764
|
+
case "attack":
|
|
765
|
+
const attack = content.content;
|
|
766
|
+
this.markdownBuffer.push(`
|
|
767
|
+
### Attack Surface
|
|
768
|
+
`);
|
|
769
|
+
this.markdownBuffer.push(`- Endpoints: ${attack.totalEndpoints}
|
|
770
|
+
`);
|
|
771
|
+
this.markdownBuffer.push(`- Unprotected: ${attack.unprotected}
|
|
772
|
+
`);
|
|
773
|
+
this.markdownBuffer.push(`- Risk Score: ${attack.riskScore}/100
|
|
774
|
+
`);
|
|
775
|
+
break;
|
|
776
|
+
case "report":
|
|
777
|
+
this.markdownBuffer.push(content.content);
|
|
778
|
+
break;
|
|
779
|
+
default:
|
|
780
|
+
this.jsonBuffer.push(content);
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
/**
|
|
784
|
+
* Route content to JSON buffer
|
|
785
|
+
*/
|
|
786
|
+
routeToJson(content) {
|
|
787
|
+
this.jsonBuffer.push(content);
|
|
788
|
+
}
|
|
789
|
+
/**
|
|
790
|
+
* Capture content in raw log buffer
|
|
791
|
+
*/
|
|
792
|
+
captureRawLog(content) {
|
|
793
|
+
const time = this.formatTime(content.timestamp);
|
|
794
|
+
const level = content.metadata?.severity ?? content.type;
|
|
795
|
+
let message = "";
|
|
796
|
+
switch (content.type) {
|
|
797
|
+
case "banner":
|
|
798
|
+
message = `[BANNER] ${content.content.skill}`;
|
|
799
|
+
break;
|
|
800
|
+
case "activity":
|
|
801
|
+
case "log":
|
|
802
|
+
message = content.content;
|
|
803
|
+
break;
|
|
804
|
+
case "issue":
|
|
805
|
+
const issue = content.content;
|
|
806
|
+
message = `[${issue.severity.toUpperCase()}] ${issue.issue}`;
|
|
807
|
+
break;
|
|
808
|
+
default:
|
|
809
|
+
message = `[${content.type.toUpperCase()}] Content received`;
|
|
810
|
+
}
|
|
811
|
+
this.rawLogBuffer.push({ time, level, message });
|
|
812
|
+
if (this.rawLogBuffer.length > 500) {
|
|
813
|
+
this.rawLogBuffer = this.rawLogBuffer.slice(-500);
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
/**
|
|
817
|
+
* Get raw log buffer for display
|
|
818
|
+
*/
|
|
819
|
+
getRawLog() {
|
|
820
|
+
return [...this.rawLogBuffer];
|
|
821
|
+
}
|
|
822
|
+
/**
|
|
823
|
+
* Get accumulated markdown output
|
|
824
|
+
*/
|
|
825
|
+
getMarkdown() {
|
|
826
|
+
return this.markdownBuffer.join("\n");
|
|
827
|
+
}
|
|
828
|
+
/**
|
|
829
|
+
* Get accumulated JSON output
|
|
830
|
+
*/
|
|
831
|
+
getJson() {
|
|
832
|
+
return [...this.jsonBuffer];
|
|
833
|
+
}
|
|
834
|
+
/**
|
|
835
|
+
* Clear buffers
|
|
836
|
+
*/
|
|
837
|
+
clearBuffers() {
|
|
838
|
+
this.markdownBuffer = [];
|
|
839
|
+
this.jsonBuffer = [];
|
|
840
|
+
}
|
|
841
|
+
// ============================================
|
|
842
|
+
// Convenience methods for common output types
|
|
843
|
+
// ============================================
|
|
844
|
+
/**
|
|
845
|
+
* Display a skill banner
|
|
846
|
+
*/
|
|
847
|
+
banner(skill, art, options) {
|
|
848
|
+
this.emit({
|
|
849
|
+
type: "banner",
|
|
850
|
+
content: { skill, art, quote: options?.quote, version: options?.version },
|
|
851
|
+
metadata: { agent: skill }
|
|
852
|
+
});
|
|
853
|
+
}
|
|
854
|
+
/**
|
|
855
|
+
* Display a code snippet
|
|
856
|
+
*/
|
|
857
|
+
snippet(file, lines, startLine, highlightLine) {
|
|
858
|
+
this.emit({
|
|
859
|
+
type: "snippet",
|
|
860
|
+
content: { file, lines, startLine, highlightLine },
|
|
861
|
+
metadata: { file }
|
|
862
|
+
});
|
|
863
|
+
}
|
|
864
|
+
/**
|
|
865
|
+
* Display cost estimate
|
|
866
|
+
*/
|
|
867
|
+
cost(fixNowCost, productionCost, savings, perIssue) {
|
|
868
|
+
this.emit({
|
|
869
|
+
type: "cost",
|
|
870
|
+
content: { fixNowCost, productionCost, savings, perIssue }
|
|
871
|
+
});
|
|
872
|
+
}
|
|
873
|
+
/**
|
|
874
|
+
* Display production readiness
|
|
875
|
+
*/
|
|
876
|
+
readiness(score, requirementsMet, total, status) {
|
|
877
|
+
this.emit({
|
|
878
|
+
type: "readiness",
|
|
879
|
+
content: { score, requirementsMet, total, status }
|
|
880
|
+
});
|
|
881
|
+
}
|
|
882
|
+
/**
|
|
883
|
+
* Display semantic analysis results
|
|
884
|
+
*/
|
|
885
|
+
semantic(dataFlowIssues, raceConditions, authIssues) {
|
|
886
|
+
this.emit({
|
|
887
|
+
type: "semantic",
|
|
888
|
+
content: { dataFlowIssues, raceConditions, authIssues }
|
|
889
|
+
});
|
|
890
|
+
}
|
|
891
|
+
/**
|
|
892
|
+
* Display attack surface analysis
|
|
893
|
+
*/
|
|
894
|
+
attack(totalEndpoints, unprotected, riskScore) {
|
|
895
|
+
this.emit({
|
|
896
|
+
type: "attack",
|
|
897
|
+
content: { totalEndpoints, unprotected, riskScore }
|
|
898
|
+
});
|
|
899
|
+
}
|
|
900
|
+
/**
|
|
901
|
+
* Log an activity message
|
|
902
|
+
*/
|
|
903
|
+
activity(message) {
|
|
904
|
+
this.emit({
|
|
905
|
+
type: "activity",
|
|
906
|
+
content: message
|
|
907
|
+
});
|
|
908
|
+
}
|
|
909
|
+
/**
|
|
910
|
+
* Log a message at specified level
|
|
911
|
+
*/
|
|
912
|
+
log(level, message) {
|
|
913
|
+
this.emit({
|
|
914
|
+
type: "log",
|
|
915
|
+
content: message,
|
|
916
|
+
metadata: { severity: level }
|
|
917
|
+
});
|
|
918
|
+
}
|
|
919
|
+
/**
|
|
920
|
+
* Log info message
|
|
921
|
+
*/
|
|
922
|
+
info(message) {
|
|
923
|
+
this.log("info", message);
|
|
924
|
+
}
|
|
925
|
+
/**
|
|
926
|
+
* Log warning message
|
|
927
|
+
*/
|
|
928
|
+
warn(message) {
|
|
929
|
+
this.log("warn", message);
|
|
930
|
+
}
|
|
931
|
+
/**
|
|
932
|
+
* Log error message
|
|
933
|
+
*/
|
|
934
|
+
error(message) {
|
|
935
|
+
this.log("error", message);
|
|
936
|
+
}
|
|
937
|
+
/**
|
|
938
|
+
* Log debug message
|
|
939
|
+
*/
|
|
940
|
+
debug(message) {
|
|
941
|
+
this.log("debug", message);
|
|
942
|
+
}
|
|
943
|
+
/**
|
|
944
|
+
* Report an issue
|
|
945
|
+
*/
|
|
946
|
+
issue(issue) {
|
|
947
|
+
this.emit({
|
|
948
|
+
type: "issue",
|
|
949
|
+
content: issue,
|
|
950
|
+
metadata: { severity: issue.severity, agent: issue.agent, file: issue.file }
|
|
951
|
+
});
|
|
952
|
+
}
|
|
953
|
+
/**
|
|
954
|
+
* Add a report section
|
|
955
|
+
*/
|
|
956
|
+
report(content) {
|
|
957
|
+
this.emit({
|
|
958
|
+
type: "report",
|
|
959
|
+
content
|
|
960
|
+
});
|
|
961
|
+
}
|
|
962
|
+
// ============================================
|
|
963
|
+
// Helpers
|
|
964
|
+
// ============================================
|
|
965
|
+
formatCurrency(amount) {
|
|
966
|
+
if (amount >= 1e6) return `$${(amount / 1e6).toFixed(2)}M`;
|
|
967
|
+
if (amount >= 1e3) return `$${(amount / 1e3).toFixed(1)}k`;
|
|
968
|
+
return `$${amount}`;
|
|
969
|
+
}
|
|
970
|
+
formatTime(timestamp) {
|
|
971
|
+
const date = timestamp ? new Date(timestamp) : /* @__PURE__ */ new Date();
|
|
972
|
+
return date.toLocaleTimeString("en-US", { hour12: false, hour: "2-digit", minute: "2-digit", second: "2-digit" });
|
|
973
|
+
}
|
|
974
|
+
};
|
|
975
|
+
var instance = null;
|
|
976
|
+
function getOutputManager() {
|
|
977
|
+
if (!instance) {
|
|
978
|
+
instance = new OutputManagerImpl();
|
|
979
|
+
if (isInteractiveMode()) {
|
|
980
|
+
instance.setMode("tui");
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
return instance;
|
|
984
|
+
}
|
|
985
|
+
function output() {
|
|
986
|
+
return getOutputManager();
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
// src/skills/built-in/agent-smith.ts
|
|
638
990
|
var MEMORY_LIMITS = {
|
|
639
991
|
MAX_LOCATIONS_PER_ISSUE: 5,
|
|
640
992
|
MAX_TRACKED_ISSUES: 500,
|
|
@@ -917,17 +1269,16 @@ var AgentSmithSkill = class extends BaseSkill {
|
|
|
917
1269
|
const loadedFiles = Array.from(fileContents.keys());
|
|
918
1270
|
this.displaySmithEntrance();
|
|
919
1271
|
await this.loadMemory(context.workingDir);
|
|
920
|
-
|
|
921
|
-
[SMITH] Deploying sub-agent swarm across ${loadedFiles.length} files...`);
|
|
1272
|
+
output().activity(`[SMITH] Deploying sub-agent swarm across ${loadedFiles.length} files...`);
|
|
922
1273
|
const subAgentResults = await this.deploySubAgents(loadedFiles, fileContents);
|
|
923
|
-
|
|
924
|
-
|
|
1274
|
+
for (const line of this.swarmAnimationLog) {
|
|
1275
|
+
output().activity(line);
|
|
925
1276
|
}
|
|
926
1277
|
for (const result of subAgentResults) {
|
|
927
1278
|
const subIssues = await this.processSubAgentResult(result, context);
|
|
928
1279
|
issues.push(...subIssues);
|
|
929
1280
|
}
|
|
930
|
-
|
|
1281
|
+
output().activity(`[SMITH] Analyzing file-level metrics...`);
|
|
931
1282
|
const fileLevelResults = await this.analyzeFileLevelIssues(fileContents);
|
|
932
1283
|
for (const result of fileLevelResults) {
|
|
933
1284
|
for (const fileIssue of result.issues) {
|
|
@@ -942,7 +1293,7 @@ var AgentSmithSkill = class extends BaseSkill {
|
|
|
942
1293
|
));
|
|
943
1294
|
}
|
|
944
1295
|
}
|
|
945
|
-
|
|
1296
|
+
output().activity(`[SMITH] Detecting cross-file patterns...`);
|
|
946
1297
|
const crossFileResults = this.analyzeCrossFilePatterns(subAgentResults);
|
|
947
1298
|
for (const result of crossFileResults) {
|
|
948
1299
|
issues.push(this.createSmithIssue(
|
|
@@ -962,9 +1313,7 @@ var AgentSmithSkill = class extends BaseSkill {
|
|
|
962
1313
|
const aiIssue = this.createAIAnalysisIssue(loadedFiles, subAgentResults);
|
|
963
1314
|
issues.push(aiIssue);
|
|
964
1315
|
}
|
|
965
|
-
|
|
966
|
-
[SMITH] Hunt complete. ${issues.length} violations found.
|
|
967
|
-
`);
|
|
1316
|
+
output().activity(`[SMITH] Hunt complete. ${issues.length} violations found.`);
|
|
968
1317
|
return issues;
|
|
969
1318
|
}
|
|
970
1319
|
/**
|
|
@@ -1069,8 +1418,8 @@ var AgentSmithSkill = class extends BaseSkill {
|
|
|
1069
1418
|
const crossFileResults = [];
|
|
1070
1419
|
for (const result of subAgentResults) {
|
|
1071
1420
|
const byFile = /* @__PURE__ */ new Map();
|
|
1072
|
-
for (const
|
|
1073
|
-
byFile.set(
|
|
1421
|
+
for (const instance2 of result.instances) {
|
|
1422
|
+
byFile.set(instance2.file, (byFile.get(instance2.file) || 0) + 1);
|
|
1074
1423
|
}
|
|
1075
1424
|
if (byFile.size >= 5) {
|
|
1076
1425
|
const occurrences = Array.from(byFile.entries()).map(([file, count]) => ({ file, count }));
|
|
@@ -1152,13 +1501,11 @@ var AgentSmithSkill = class extends BaseSkill {
|
|
|
1152
1501
|
"emoji-overflow-hunter",
|
|
1153
1502
|
"inter-font-hunter"
|
|
1154
1503
|
];
|
|
1155
|
-
|
|
1504
|
+
output().activity(` Deploying ${subAgentTypes.length} specialized hunters across ${files.length} files...`);
|
|
1156
1505
|
const { results, animationLog } = await this.runAgentSwarm(subAgentTypes, fileContents);
|
|
1157
1506
|
this.swarmAnimationLog = animationLog;
|
|
1158
1507
|
const activeHunters = results.filter((r) => r.instances.length > 0);
|
|
1159
|
-
|
|
1160
|
-
>> ${activeHunters.length} hunters found targets. Violations acquired.
|
|
1161
|
-
`);
|
|
1508
|
+
output().activity(` >> ${activeHunters.length} hunters found targets. Violations acquired.`);
|
|
1162
1509
|
return activeHunters;
|
|
1163
1510
|
}
|
|
1164
1511
|
/**
|
|
@@ -1257,10 +1604,10 @@ var AgentSmithSkill = class extends BaseSkill {
|
|
|
1257
1604
|
const issues = [];
|
|
1258
1605
|
const config = SUB_AGENT_PATTERNS[result.type];
|
|
1259
1606
|
const byFile = /* @__PURE__ */ new Map();
|
|
1260
|
-
for (const
|
|
1261
|
-
const existing = byFile.get(
|
|
1262
|
-
existing.push(
|
|
1263
|
-
byFile.set(
|
|
1607
|
+
for (const instance2 of result.instances) {
|
|
1608
|
+
const existing = byFile.get(instance2.file) || [];
|
|
1609
|
+
existing.push(instance2);
|
|
1610
|
+
byFile.set(instance2.file, existing);
|
|
1264
1611
|
}
|
|
1265
1612
|
for (const [file, instances] of byFile) {
|
|
1266
1613
|
const inevitabilityScore = this.calculateInevitabilityScore(result.type, instances.length);
|
|
@@ -1668,15 +2015,14 @@ ${config.fix}`;
|
|
|
1668
2015
|
}
|
|
1669
2016
|
/**
|
|
1670
2017
|
* Display Agent Smith ASCII art entrance
|
|
2018
|
+
* Uses OutputManager to route to TUI or console based on mode
|
|
1671
2019
|
*/
|
|
1672
2020
|
displaySmithEntrance() {
|
|
1673
|
-
const greeting = AGENT_SMITH_GREETING[Math.floor(Math.random() * AGENT_SMITH_GREETING.length)];
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
console.error(' "' + greeting + '"');
|
|
1679
|
-
console.error("=".repeat(60) + "\n");
|
|
2021
|
+
const greeting = AGENT_SMITH_GREETING[Math.floor(Math.random() * AGENT_SMITH_GREETING.length)] ?? "The code will be... assimilated.";
|
|
2022
|
+
output().banner("agent-smith", AGENT_SMITH_ASCII, {
|
|
2023
|
+
quote: greeting,
|
|
2024
|
+
version: this.version
|
|
2025
|
+
});
|
|
1680
2026
|
}
|
|
1681
2027
|
/**
|
|
1682
2028
|
* Save memory to disk (with optimization)
|
|
@@ -1880,14 +2226,13 @@ ${config.fix}`;
|
|
|
1880
2226
|
};
|
|
1881
2227
|
|
|
1882
2228
|
export {
|
|
1883
|
-
setInteractiveMode,
|
|
1884
|
-
isInteractiveMode,
|
|
1885
|
-
ProgressReporter,
|
|
1886
2229
|
isAIAvailable,
|
|
1887
2230
|
runAIAnalysis,
|
|
1888
2231
|
getAIStatusMessage,
|
|
1889
2232
|
BaseSkill,
|
|
2233
|
+
getOutputManager,
|
|
2234
|
+
output,
|
|
1890
2235
|
SUB_AGENT_PATTERNS,
|
|
1891
2236
|
AgentSmithSkill
|
|
1892
2237
|
};
|
|
1893
|
-
//# sourceMappingURL=chunk-
|
|
2238
|
+
//# sourceMappingURL=chunk-C7LXN754.js.map
|