@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.
Files changed (41) hide show
  1. package/README.md +17 -13
  2. package/dist/{agent-smith-O7RG7WQ3.js → agent-smith-4IJZHSNQ.js} +3 -2
  3. package/dist/{agent-smith-runner-EW4C4PTF.js → agent-smith-runner-4PE3GOUX.js} +5 -3
  4. package/dist/{agent-smith-runner-EW4C4PTF.js.map → agent-smith-runner-4PE3GOUX.js.map} +1 -1
  5. package/dist/{chunk-HUQQSQOD.js → chunk-3XWSM2DU.js} +73 -44
  6. package/dist/chunk-3XWSM2DU.js.map +1 -0
  7. package/dist/{chunk-KLKY34RE.js → chunk-4EHBRED6.js} +139 -12
  8. package/dist/chunk-4EHBRED6.js.map +1 -0
  9. package/dist/{chunk-6ODT4U4O.js → chunk-C7LXN754.js} +539 -194
  10. package/dist/chunk-C7LXN754.js.map +1 -0
  11. package/dist/{chunk-AVOMCNBD.js → chunk-DV3JQTLQ.js} +23 -86
  12. package/dist/chunk-DV3JQTLQ.js.map +1 -0
  13. package/dist/{chunk-3CS6Z2SL.js → chunk-MVUCBUBR.js} +7 -2
  14. package/dist/chunk-MVUCBUBR.js.map +1 -0
  15. package/dist/{chunk-JAVEBJF4.js → chunk-NM7ZVUHO.js} +790 -62
  16. package/dist/chunk-NM7ZVUHO.js.map +1 -0
  17. package/dist/chunk-RAZUNSBI.js +171 -0
  18. package/dist/chunk-RAZUNSBI.js.map +1 -0
  19. package/dist/{chunk-MR755QGT.js → chunk-ULOW5HSH.js} +7 -2
  20. package/dist/chunk-ULOW5HSH.js.map +1 -0
  21. package/dist/cli/main.js +6 -5
  22. package/dist/cli/main.js.map +1 -1
  23. package/dist/cli/yolo-daemon.js +10 -9
  24. package/dist/cli/yolo-daemon.js.map +1 -1
  25. package/dist/index.js +37 -23
  26. package/dist/index.js.map +1 -1
  27. package/dist/{vibe-code-signatures-4CBHUSI7.js → vibe-code-signatures-TGMQXYGO.js} +3 -2
  28. package/dist/{vulnerability-signatures-J3CUQ7VR.js → vulnerability-signatures-GOVD4Q24.js} +3 -2
  29. package/dist/workers/agent-worker.js +4 -3
  30. package/dist/workers/agent-worker.js.map +1 -1
  31. package/package.json +1 -1
  32. package/dist/chunk-3CS6Z2SL.js.map +0 -1
  33. package/dist/chunk-6ODT4U4O.js.map +0 -1
  34. package/dist/chunk-AVOMCNBD.js.map +0 -1
  35. package/dist/chunk-HUQQSQOD.js.map +0 -1
  36. package/dist/chunk-JAVEBJF4.js.map +0 -1
  37. package/dist/chunk-KLKY34RE.js.map +0 -1
  38. package/dist/chunk-MR755QGT.js.map +0 -1
  39. /package/dist/{agent-smith-O7RG7WQ3.js.map → agent-smith-4IJZHSNQ.js.map} +0 -0
  40. /package/dist/{vibe-code-signatures-4CBHUSI7.js.map → vibe-code-signatures-TGMQXYGO.js.map} +0 -0
  41. /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
- // src/utils/progress.ts
6
- var _interactiveMode = false;
7
- function setInteractiveMode(enabled) {
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
- console.error(`
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
- if (this.swarmAnimationLog.length > 0) {
924
- console.error(this.swarmAnimationLog.join("\n"));
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
- console.error(`[SMITH] Analyzing file-level metrics...`);
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
- console.error(`[SMITH] Detecting cross-file patterns...`);
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
- console.error(`
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 instance of result.instances) {
1073
- byFile.set(instance.file, (byFile.get(instance.file) || 0) + 1);
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
- console.error(` Deploying ${subAgentTypes.length} specialized hunters across ${files.length} files...`);
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
- console.error(`
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 instance of result.instances) {
1261
- const existing = byFile.get(instance.file) || [];
1262
- existing.push(instance);
1263
- byFile.set(instance.file, existing);
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
- console.error("\n" + "=".repeat(60));
1675
- console.error(AGENT_SMITH_ASCII);
1676
- console.error(" Relentless Pattern Hunter v" + this.version);
1677
- console.error("");
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-6ODT4U4O.js.map
2238
+ //# sourceMappingURL=chunk-C7LXN754.js.map