@triedotdev/mcp 1.0.113 → 1.0.114
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/dist/auto-fix-apply-PCAHWLXF.js +10 -0
- package/dist/autonomy-config-O4H3Z7YV.js +30 -0
- package/dist/chunk-2GIAROBF.js +173 -0
- package/dist/chunk-2GIAROBF.js.map +1 -0
- package/dist/{chunk-33WL3D7A.js → chunk-2SIFK7OW.js} +7 -419
- package/dist/chunk-2SIFK7OW.js.map +1 -0
- package/dist/chunk-43X6JBEM.js +36 -0
- package/dist/chunk-43X6JBEM.js.map +1 -0
- package/dist/{chunk-2764KZZQ.js → chunk-4SBZXIMG.js} +133 -595
- package/dist/chunk-4SBZXIMG.js.map +1 -0
- package/dist/chunk-55DOQNHJ.js +772 -0
- package/dist/chunk-55DOQNHJ.js.map +1 -0
- package/dist/chunk-6LXSA2OZ.js +425 -0
- package/dist/chunk-6LXSA2OZ.js.map +1 -0
- package/dist/{chunk-SDS3UVFY.js → chunk-AOFYU6T3.js} +113 -559
- package/dist/chunk-AOFYU6T3.js.map +1 -0
- package/dist/{chunk-6QR6QZIX.js → chunk-D3EXBJE2.js} +25 -658
- package/dist/chunk-D3EXBJE2.js.map +1 -0
- package/dist/chunk-DJ2YAGHK.js +50 -0
- package/dist/chunk-DJ2YAGHK.js.map +1 -0
- package/dist/chunk-DRDEEF6G.js +328 -0
- package/dist/chunk-DRDEEF6G.js.map +1 -0
- package/dist/chunk-DZREHOGW.js +706 -0
- package/dist/chunk-DZREHOGW.js.map +1 -0
- package/dist/chunk-KRH642MT.js +947 -0
- package/dist/chunk-KRH642MT.js.map +1 -0
- package/dist/{chunk-QYOACM2C.js → chunk-MVNJPJBK.js} +22 -252
- package/dist/chunk-MVNJPJBK.js.map +1 -0
- package/dist/chunk-NS2MSZMB.js +394 -0
- package/dist/chunk-NS2MSZMB.js.map +1 -0
- package/dist/chunk-SWSK7ANT.js +340 -0
- package/dist/chunk-SWSK7ANT.js.map +1 -0
- package/dist/chunk-VRLMTOB6.js +566 -0
- package/dist/chunk-VRLMTOB6.js.map +1 -0
- package/dist/chunk-YR4BMGYO.js +130 -0
- package/dist/chunk-YR4BMGYO.js.map +1 -0
- package/dist/chunk-ZV2K6M7T.js +74 -0
- package/dist/chunk-ZV2K6M7T.js.map +1 -0
- package/dist/cli/main.js +107 -375
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/yolo-daemon.js +18 -8
- package/dist/cli/yolo-daemon.js.map +1 -1
- package/dist/client-7XZHCMD3.js +28 -0
- package/dist/client-7XZHCMD3.js.map +1 -0
- package/dist/{goal-manager-AP4LTE6U.js → goal-manager-LMS6ZJB7.js} +7 -3
- package/dist/goal-manager-LMS6ZJB7.js.map +1 -0
- package/dist/goal-validator-7UPLOVAZ.js +184 -0
- package/dist/goal-validator-7UPLOVAZ.js.map +1 -0
- package/dist/graph-U5JWSAB5.js +10 -0
- package/dist/graph-U5JWSAB5.js.map +1 -0
- package/dist/guardian-agent-EXP7APLC.js +25 -0
- package/dist/guardian-agent-EXP7APLC.js.map +1 -0
- package/dist/hypothesis-KGC3P54C.js +19 -0
- package/dist/hypothesis-KGC3P54C.js.map +1 -0
- package/dist/incident-index-PNIVT47T.js +11 -0
- package/dist/incident-index-PNIVT47T.js.map +1 -0
- package/dist/index.js +285 -16
- package/dist/index.js.map +1 -1
- package/dist/ledger-SR6OEBLO.js +15 -0
- package/dist/ledger-SR6OEBLO.js.map +1 -0
- package/dist/output-manager-BOTMXSND.js +13 -0
- package/dist/output-manager-BOTMXSND.js.map +1 -0
- package/dist/pattern-discovery-F7LU5K6E.js +8 -0
- package/dist/pattern-discovery-F7LU5K6E.js.map +1 -0
- package/package.json +1 -1
- package/dist/chunk-2764KZZQ.js.map +0 -1
- package/dist/chunk-33WL3D7A.js.map +0 -1
- package/dist/chunk-6JPPYG7F.js +0 -1813
- package/dist/chunk-6JPPYG7F.js.map +0 -1
- package/dist/chunk-6QR6QZIX.js.map +0 -1
- package/dist/chunk-QYOACM2C.js.map +0 -1
- package/dist/chunk-SDS3UVFY.js.map +0 -1
- package/dist/guardian-agent-XEYNG7RH.js +0 -18
- /package/dist/{goal-manager-AP4LTE6U.js.map → auto-fix-apply-PCAHWLXF.js.map} +0 -0
- /package/dist/{guardian-agent-XEYNG7RH.js.map → autonomy-config-O4H3Z7YV.js.map} +0 -0
|
@@ -0,0 +1,566 @@
|
|
|
1
|
+
import {
|
|
2
|
+
isInteractiveMode
|
|
3
|
+
} from "./chunk-APMV77PU.js";
|
|
4
|
+
|
|
5
|
+
// src/utils/output-manager.ts
|
|
6
|
+
import pc from "picocolors";
|
|
7
|
+
var OutputManagerImpl = class {
|
|
8
|
+
mode = "console";
|
|
9
|
+
streamingManager;
|
|
10
|
+
markdownBuffer = [];
|
|
11
|
+
jsonBuffer = [];
|
|
12
|
+
rawLogBuffer = [];
|
|
13
|
+
// Callbacks for TUI integration (explicitly allow undefined for exactOptionalPropertyTypes)
|
|
14
|
+
onBanner = void 0;
|
|
15
|
+
onSnippet = void 0;
|
|
16
|
+
onCost = void 0;
|
|
17
|
+
onReadiness = void 0;
|
|
18
|
+
onSemantic = void 0;
|
|
19
|
+
onAttack = void 0;
|
|
20
|
+
onActivity = void 0;
|
|
21
|
+
onLog = void 0;
|
|
22
|
+
onNudge = void 0;
|
|
23
|
+
/**
|
|
24
|
+
* Set the output mode
|
|
25
|
+
*/
|
|
26
|
+
setMode(mode) {
|
|
27
|
+
this.mode = mode;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Get current output mode
|
|
31
|
+
*/
|
|
32
|
+
getMode() {
|
|
33
|
+
return this.mode;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Set streaming manager for TUI updates
|
|
37
|
+
*/
|
|
38
|
+
setStreamingManager(manager) {
|
|
39
|
+
this.streamingManager = manager;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Register TUI callbacks for rich content
|
|
43
|
+
*/
|
|
44
|
+
registerTUICallbacks(callbacks) {
|
|
45
|
+
this.onBanner = callbacks.onBanner;
|
|
46
|
+
this.onSnippet = callbacks.onSnippet;
|
|
47
|
+
this.onCost = callbacks.onCost;
|
|
48
|
+
this.onReadiness = callbacks.onReadiness;
|
|
49
|
+
this.onSemantic = callbacks.onSemantic;
|
|
50
|
+
this.onAttack = callbacks.onAttack;
|
|
51
|
+
this.onActivity = callbacks.onActivity;
|
|
52
|
+
this.onLog = callbacks.onLog;
|
|
53
|
+
this.onNudge = callbacks.onNudge;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Clear TUI callbacks (when dashboard stops)
|
|
57
|
+
*/
|
|
58
|
+
clearTUICallbacks() {
|
|
59
|
+
this.onBanner = void 0;
|
|
60
|
+
this.onSnippet = void 0;
|
|
61
|
+
this.onCost = void 0;
|
|
62
|
+
this.onReadiness = void 0;
|
|
63
|
+
this.onSemantic = void 0;
|
|
64
|
+
this.onAttack = void 0;
|
|
65
|
+
this.onActivity = void 0;
|
|
66
|
+
this.onLog = void 0;
|
|
67
|
+
this.onNudge = void 0;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Emit content - routes to appropriate handler based on mode
|
|
71
|
+
*/
|
|
72
|
+
emit(content) {
|
|
73
|
+
content.timestamp = content.timestamp ?? Date.now();
|
|
74
|
+
switch (this.mode) {
|
|
75
|
+
case "tui":
|
|
76
|
+
this.routeToTUI(content);
|
|
77
|
+
break;
|
|
78
|
+
case "console":
|
|
79
|
+
this.routeToConsole(content);
|
|
80
|
+
break;
|
|
81
|
+
case "mcp":
|
|
82
|
+
this.routeToMarkdown(content);
|
|
83
|
+
break;
|
|
84
|
+
case "json":
|
|
85
|
+
this.routeToJson(content);
|
|
86
|
+
break;
|
|
87
|
+
case "silent":
|
|
88
|
+
break;
|
|
89
|
+
}
|
|
90
|
+
this.captureRawLog(content);
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Route content to TUI (dashboard callbacks)
|
|
94
|
+
*/
|
|
95
|
+
routeToTUI(content) {
|
|
96
|
+
switch (content.type) {
|
|
97
|
+
case "banner":
|
|
98
|
+
this.onBanner?.(content.content);
|
|
99
|
+
break;
|
|
100
|
+
case "snippet":
|
|
101
|
+
this.onSnippet?.(content.content);
|
|
102
|
+
break;
|
|
103
|
+
case "cost":
|
|
104
|
+
this.onCost?.(content.content);
|
|
105
|
+
break;
|
|
106
|
+
case "readiness":
|
|
107
|
+
this.onReadiness?.(content.content);
|
|
108
|
+
break;
|
|
109
|
+
case "semantic":
|
|
110
|
+
this.onSemantic?.(content.content);
|
|
111
|
+
break;
|
|
112
|
+
case "attack":
|
|
113
|
+
this.onAttack?.(content.content);
|
|
114
|
+
break;
|
|
115
|
+
case "activity":
|
|
116
|
+
this.onActivity?.(content.content);
|
|
117
|
+
break;
|
|
118
|
+
case "log":
|
|
119
|
+
const level = content.metadata?.severity ?? "info";
|
|
120
|
+
this.onLog?.(level, content.content);
|
|
121
|
+
break;
|
|
122
|
+
case "issue":
|
|
123
|
+
this.streamingManager?.reportIssue(content.content);
|
|
124
|
+
break;
|
|
125
|
+
case "progress":
|
|
126
|
+
break;
|
|
127
|
+
case "report":
|
|
128
|
+
break;
|
|
129
|
+
case "nudge":
|
|
130
|
+
this.onNudge?.(content.content);
|
|
131
|
+
break;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Route content to console (ANSI formatted)
|
|
136
|
+
*/
|
|
137
|
+
routeToConsole(content) {
|
|
138
|
+
switch (content.type) {
|
|
139
|
+
case "banner":
|
|
140
|
+
const banner = content.content;
|
|
141
|
+
console.error("\n" + "=".repeat(60));
|
|
142
|
+
console.error(banner.art);
|
|
143
|
+
if (banner.version) {
|
|
144
|
+
console.error(` ${banner.skill} v${banner.version}`);
|
|
145
|
+
}
|
|
146
|
+
console.error("");
|
|
147
|
+
if (banner.quote) {
|
|
148
|
+
console.error(` "${banner.quote}"`);
|
|
149
|
+
}
|
|
150
|
+
console.error("=".repeat(60) + "\n");
|
|
151
|
+
break;
|
|
152
|
+
case "snippet":
|
|
153
|
+
const snippet = content.content;
|
|
154
|
+
console.error(`
|
|
155
|
+
${pc.dim("File:")} ${snippet.file}`);
|
|
156
|
+
for (let i = 0; i < snippet.lines.length; i++) {
|
|
157
|
+
const lineNum = snippet.startLine + i;
|
|
158
|
+
const isHighlight = lineNum === snippet.highlightLine;
|
|
159
|
+
const prefix = isHighlight ? pc.red("\u2192") : " ";
|
|
160
|
+
const lineNumStr = pc.dim(lineNum.toString().padStart(4));
|
|
161
|
+
const line = isHighlight ? pc.yellow(snippet.lines[i]) : snippet.lines[i];
|
|
162
|
+
console.error(`${prefix} ${lineNumStr} | ${line}`);
|
|
163
|
+
}
|
|
164
|
+
console.error("");
|
|
165
|
+
break;
|
|
166
|
+
case "cost":
|
|
167
|
+
const cost = content.content;
|
|
168
|
+
console.error("\n" + pc.cyan("[$] Cost Estimate:"));
|
|
169
|
+
console.error(` Fix now: ${pc.green(this.formatCurrency(cost.fixNowCost))}`);
|
|
170
|
+
console.error(` If production: ${pc.red(this.formatCurrency(cost.productionCost))}`);
|
|
171
|
+
console.error(` Savings: ${pc.yellow(this.formatCurrency(cost.savings))}`);
|
|
172
|
+
console.error("");
|
|
173
|
+
break;
|
|
174
|
+
case "readiness":
|
|
175
|
+
const readiness = content.content;
|
|
176
|
+
const statusColor = readiness.status === "ready" ? pc.green : readiness.status === "caution" ? pc.yellow : pc.red;
|
|
177
|
+
console.error("\n" + pc.cyan("[%] Production Readiness:"));
|
|
178
|
+
console.error(` Score: ${statusColor(readiness.score + "/100")}`);
|
|
179
|
+
console.error(` Requirements: ${readiness.requirementsMet}/${readiness.total}`);
|
|
180
|
+
console.error(` Status: ${statusColor(readiness.status.toUpperCase())}`);
|
|
181
|
+
console.error("");
|
|
182
|
+
break;
|
|
183
|
+
case "semantic":
|
|
184
|
+
const semantic = content.content;
|
|
185
|
+
console.error("\n" + pc.cyan("[?] Semantic Analysis:"));
|
|
186
|
+
if (semantic.dataFlowIssues > 0) {
|
|
187
|
+
console.error(` ${pc.red("[!]")} ${semantic.dataFlowIssues} data flow vulnerabilities`);
|
|
188
|
+
}
|
|
189
|
+
if (semantic.raceConditions > 0) {
|
|
190
|
+
console.error(` ${pc.yellow("[~]")} ${semantic.raceConditions} race conditions`);
|
|
191
|
+
}
|
|
192
|
+
if (semantic.authIssues > 0) {
|
|
193
|
+
console.error(` ${pc.red("[!]")} ${semantic.authIssues} authentication issues`);
|
|
194
|
+
}
|
|
195
|
+
console.error("");
|
|
196
|
+
break;
|
|
197
|
+
case "attack":
|
|
198
|
+
const attack = content.content;
|
|
199
|
+
console.error("\n" + pc.cyan("[>] Attack Surface:"));
|
|
200
|
+
console.error(` Endpoints: ${attack.totalEndpoints}`);
|
|
201
|
+
if (attack.unprotected > 0) {
|
|
202
|
+
console.error(` ${pc.red("Unprotected:")} ${attack.unprotected}`);
|
|
203
|
+
}
|
|
204
|
+
console.error(` Risk Score: ${attack.riskScore}/100`);
|
|
205
|
+
console.error("");
|
|
206
|
+
break;
|
|
207
|
+
case "activity":
|
|
208
|
+
console.error(pc.dim(`[${this.formatTime()}]`) + ` ${content.content}`);
|
|
209
|
+
break;
|
|
210
|
+
case "log":
|
|
211
|
+
const logLevel = String(content.metadata?.severity ?? "info");
|
|
212
|
+
const levelColor = logLevel === "error" || logLevel === "critical" ? pc.red : logLevel === "warn" || logLevel === "serious" ? pc.yellow : logLevel === "info" || logLevel === "moderate" ? pc.blue : pc.dim;
|
|
213
|
+
console.error(levelColor(`[${logLevel.toUpperCase()}]`) + ` ${content.content}`);
|
|
214
|
+
break;
|
|
215
|
+
case "issue":
|
|
216
|
+
const issue = content.content;
|
|
217
|
+
const sevColor = issue.severity === "critical" ? pc.red : issue.severity === "serious" ? pc.yellow : issue.severity === "moderate" ? pc.blue : pc.dim;
|
|
218
|
+
console.error(`${sevColor(`[${issue.severity.toUpperCase()}]`)} ${issue.issue}`);
|
|
219
|
+
console.error(` ${pc.dim("File:")} ${issue.file}:${issue.line ?? "?"}`);
|
|
220
|
+
break;
|
|
221
|
+
case "report":
|
|
222
|
+
console.error(content.content);
|
|
223
|
+
break;
|
|
224
|
+
case "nudge":
|
|
225
|
+
const nudge = content.content;
|
|
226
|
+
const nudgeColor = nudge.severity === "critical" ? pc.red : nudge.severity === "warning" ? pc.yellow : pc.cyan;
|
|
227
|
+
const nudgeIcon = nudge.severity === "critical" ? "[!!!]" : nudge.severity === "warning" ? "[!]" : "[>]";
|
|
228
|
+
console.error("");
|
|
229
|
+
console.error(nudgeColor("\u2501".repeat(60)));
|
|
230
|
+
console.error(nudgeColor(`${nudgeIcon} TRIE AGENT SAYS:`));
|
|
231
|
+
console.error(nudgeColor("\u2501".repeat(60)));
|
|
232
|
+
console.error("");
|
|
233
|
+
console.error(` ${pc.bold(nudge.message)}`);
|
|
234
|
+
if (nudge.file) {
|
|
235
|
+
console.error(` ${pc.dim("File:")} ${nudge.file}`);
|
|
236
|
+
}
|
|
237
|
+
console.error("");
|
|
238
|
+
console.error(nudgeColor("\u2501".repeat(60)));
|
|
239
|
+
console.error("");
|
|
240
|
+
break;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Route content to markdown buffer
|
|
245
|
+
*/
|
|
246
|
+
routeToMarkdown(content) {
|
|
247
|
+
switch (content.type) {
|
|
248
|
+
case "banner":
|
|
249
|
+
const banner = content.content;
|
|
250
|
+
this.markdownBuffer.push(`## ${banner.skill}
|
|
251
|
+
`);
|
|
252
|
+
if (banner.quote) {
|
|
253
|
+
this.markdownBuffer.push(`> ${banner.quote}
|
|
254
|
+
`);
|
|
255
|
+
}
|
|
256
|
+
break;
|
|
257
|
+
case "snippet":
|
|
258
|
+
const snippet = content.content;
|
|
259
|
+
this.markdownBuffer.push(`
|
|
260
|
+
**File:** \`${snippet.file}\`
|
|
261
|
+
`);
|
|
262
|
+
this.markdownBuffer.push("```\n");
|
|
263
|
+
for (let i = 0; i < snippet.lines.length; i++) {
|
|
264
|
+
const lineNum = snippet.startLine + i;
|
|
265
|
+
const prefix = lineNum === snippet.highlightLine ? "\u2192" : " ";
|
|
266
|
+
this.markdownBuffer.push(`${prefix} ${lineNum.toString().padStart(4)} | ${snippet.lines[i]}
|
|
267
|
+
`);
|
|
268
|
+
}
|
|
269
|
+
this.markdownBuffer.push("```\n");
|
|
270
|
+
break;
|
|
271
|
+
case "cost":
|
|
272
|
+
const cost = content.content;
|
|
273
|
+
this.markdownBuffer.push(`
|
|
274
|
+
### Cost Estimate
|
|
275
|
+
`);
|
|
276
|
+
this.markdownBuffer.push(`- Fix now: ${this.formatCurrency(cost.fixNowCost)}
|
|
277
|
+
`);
|
|
278
|
+
this.markdownBuffer.push(`- If production: ${this.formatCurrency(cost.productionCost)}
|
|
279
|
+
`);
|
|
280
|
+
this.markdownBuffer.push(`- Savings: ${this.formatCurrency(cost.savings)}
|
|
281
|
+
`);
|
|
282
|
+
break;
|
|
283
|
+
case "readiness":
|
|
284
|
+
const readiness = content.content;
|
|
285
|
+
this.markdownBuffer.push(`
|
|
286
|
+
### Production Readiness
|
|
287
|
+
`);
|
|
288
|
+
this.markdownBuffer.push(`- Score: ${readiness.score}/100
|
|
289
|
+
`);
|
|
290
|
+
this.markdownBuffer.push(`- Requirements: ${readiness.requirementsMet}/${readiness.total}
|
|
291
|
+
`);
|
|
292
|
+
this.markdownBuffer.push(`- Status: **${readiness.status.toUpperCase()}**
|
|
293
|
+
`);
|
|
294
|
+
break;
|
|
295
|
+
case "semantic":
|
|
296
|
+
const semantic = content.content;
|
|
297
|
+
this.markdownBuffer.push(`
|
|
298
|
+
### Semantic Analysis
|
|
299
|
+
`);
|
|
300
|
+
if (semantic.dataFlowIssues > 0) {
|
|
301
|
+
this.markdownBuffer.push(`- [CRITICAL] ${semantic.dataFlowIssues} data flow vulnerabilities
|
|
302
|
+
`);
|
|
303
|
+
}
|
|
304
|
+
if (semantic.raceConditions > 0) {
|
|
305
|
+
this.markdownBuffer.push(`- [WARN] ${semantic.raceConditions} race conditions
|
|
306
|
+
`);
|
|
307
|
+
}
|
|
308
|
+
if (semantic.authIssues > 0) {
|
|
309
|
+
this.markdownBuffer.push(`- [CRITICAL] ${semantic.authIssues} authentication issues
|
|
310
|
+
`);
|
|
311
|
+
}
|
|
312
|
+
break;
|
|
313
|
+
case "attack":
|
|
314
|
+
const attack = content.content;
|
|
315
|
+
this.markdownBuffer.push(`
|
|
316
|
+
### Attack Surface
|
|
317
|
+
`);
|
|
318
|
+
this.markdownBuffer.push(`- Endpoints: ${attack.totalEndpoints}
|
|
319
|
+
`);
|
|
320
|
+
this.markdownBuffer.push(`- Unprotected: ${attack.unprotected}
|
|
321
|
+
`);
|
|
322
|
+
this.markdownBuffer.push(`- Risk Score: ${attack.riskScore}/100
|
|
323
|
+
`);
|
|
324
|
+
break;
|
|
325
|
+
case "report":
|
|
326
|
+
this.markdownBuffer.push(content.content);
|
|
327
|
+
break;
|
|
328
|
+
default:
|
|
329
|
+
this.jsonBuffer.push(content);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Route content to JSON buffer
|
|
334
|
+
*/
|
|
335
|
+
routeToJson(content) {
|
|
336
|
+
this.jsonBuffer.push(content);
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Capture content in raw log buffer
|
|
340
|
+
*/
|
|
341
|
+
captureRawLog(content) {
|
|
342
|
+
const time = this.formatTime(content.timestamp);
|
|
343
|
+
const level = content.metadata?.severity ?? content.type;
|
|
344
|
+
let message = "";
|
|
345
|
+
switch (content.type) {
|
|
346
|
+
case "banner":
|
|
347
|
+
message = `[BANNER] ${content.content.skill}`;
|
|
348
|
+
break;
|
|
349
|
+
case "activity":
|
|
350
|
+
case "log":
|
|
351
|
+
message = content.content;
|
|
352
|
+
break;
|
|
353
|
+
case "issue":
|
|
354
|
+
const issue = content.content;
|
|
355
|
+
message = `[${issue.severity.toUpperCase()}] ${issue.issue}`;
|
|
356
|
+
break;
|
|
357
|
+
default:
|
|
358
|
+
message = `[${content.type.toUpperCase()}] Content received`;
|
|
359
|
+
}
|
|
360
|
+
this.rawLogBuffer.push({ time, level, message });
|
|
361
|
+
if (this.rawLogBuffer.length > 500) {
|
|
362
|
+
this.rawLogBuffer = this.rawLogBuffer.slice(-500);
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* Get raw log buffer for display
|
|
367
|
+
*/
|
|
368
|
+
getRawLog() {
|
|
369
|
+
return [...this.rawLogBuffer];
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* Get accumulated markdown output
|
|
373
|
+
*/
|
|
374
|
+
getMarkdown() {
|
|
375
|
+
return this.markdownBuffer.join("\n");
|
|
376
|
+
}
|
|
377
|
+
/**
|
|
378
|
+
* Get accumulated JSON output
|
|
379
|
+
*/
|
|
380
|
+
getJson() {
|
|
381
|
+
return [...this.jsonBuffer];
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* Clear buffers
|
|
385
|
+
*/
|
|
386
|
+
clearBuffers() {
|
|
387
|
+
this.markdownBuffer = [];
|
|
388
|
+
this.jsonBuffer = [];
|
|
389
|
+
}
|
|
390
|
+
// ============================================
|
|
391
|
+
// Convenience methods for common output types
|
|
392
|
+
// ============================================
|
|
393
|
+
/**
|
|
394
|
+
* Display a skill banner
|
|
395
|
+
*/
|
|
396
|
+
banner(skill, art, options) {
|
|
397
|
+
this.emit({
|
|
398
|
+
type: "banner",
|
|
399
|
+
content: { skill, art, quote: options?.quote, version: options?.version },
|
|
400
|
+
metadata: { agent: skill }
|
|
401
|
+
});
|
|
402
|
+
}
|
|
403
|
+
/**
|
|
404
|
+
* Display a code snippet
|
|
405
|
+
*/
|
|
406
|
+
snippet(file, lines, startLine, highlightLine) {
|
|
407
|
+
this.emit({
|
|
408
|
+
type: "snippet",
|
|
409
|
+
content: { file, lines, startLine, highlightLine },
|
|
410
|
+
metadata: { file }
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
/**
|
|
414
|
+
* Display cost estimate
|
|
415
|
+
*/
|
|
416
|
+
cost(fixNowCost, productionCost, savings, perIssue) {
|
|
417
|
+
this.emit({
|
|
418
|
+
type: "cost",
|
|
419
|
+
content: { fixNowCost, productionCost, savings, perIssue }
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
/**
|
|
423
|
+
* Display production readiness
|
|
424
|
+
*/
|
|
425
|
+
readiness(score, requirementsMet, total, status, requirements) {
|
|
426
|
+
const content = { score, requirementsMet, total, status };
|
|
427
|
+
if (requirements) {
|
|
428
|
+
content.requirements = requirements;
|
|
429
|
+
}
|
|
430
|
+
this.emit({
|
|
431
|
+
type: "readiness",
|
|
432
|
+
content
|
|
433
|
+
});
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
436
|
+
* Display semantic analysis results
|
|
437
|
+
*/
|
|
438
|
+
semantic(dataFlowIssues, raceConditions, authIssues) {
|
|
439
|
+
this.emit({
|
|
440
|
+
type: "semantic",
|
|
441
|
+
content: { dataFlowIssues, raceConditions, authIssues }
|
|
442
|
+
});
|
|
443
|
+
}
|
|
444
|
+
/**
|
|
445
|
+
* Display attack surface analysis
|
|
446
|
+
*/
|
|
447
|
+
attack(totalEndpoints, unprotected, riskScore) {
|
|
448
|
+
this.emit({
|
|
449
|
+
type: "attack",
|
|
450
|
+
content: { totalEndpoints, unprotected, riskScore }
|
|
451
|
+
});
|
|
452
|
+
}
|
|
453
|
+
/**
|
|
454
|
+
* Log an activity message
|
|
455
|
+
*/
|
|
456
|
+
activity(message) {
|
|
457
|
+
this.emit({
|
|
458
|
+
type: "activity",
|
|
459
|
+
content: message
|
|
460
|
+
});
|
|
461
|
+
}
|
|
462
|
+
/**
|
|
463
|
+
* Log a message at specified level
|
|
464
|
+
*/
|
|
465
|
+
log(level, message) {
|
|
466
|
+
this.emit({
|
|
467
|
+
type: "log",
|
|
468
|
+
content: message,
|
|
469
|
+
metadata: { severity: level }
|
|
470
|
+
});
|
|
471
|
+
}
|
|
472
|
+
/**
|
|
473
|
+
* Log info message
|
|
474
|
+
*/
|
|
475
|
+
info(message) {
|
|
476
|
+
this.log("info", message);
|
|
477
|
+
}
|
|
478
|
+
/**
|
|
479
|
+
* Log warning message
|
|
480
|
+
*/
|
|
481
|
+
warn(message) {
|
|
482
|
+
this.log("warn", message);
|
|
483
|
+
}
|
|
484
|
+
/**
|
|
485
|
+
* Log error message
|
|
486
|
+
*/
|
|
487
|
+
error(message) {
|
|
488
|
+
this.log("error", message);
|
|
489
|
+
}
|
|
490
|
+
/**
|
|
491
|
+
* Log debug message
|
|
492
|
+
*/
|
|
493
|
+
debug(message) {
|
|
494
|
+
this.log("debug", message);
|
|
495
|
+
}
|
|
496
|
+
/**
|
|
497
|
+
* Report an issue
|
|
498
|
+
*/
|
|
499
|
+
issue(issue) {
|
|
500
|
+
this.emit({
|
|
501
|
+
type: "issue",
|
|
502
|
+
content: issue,
|
|
503
|
+
metadata: { severity: issue.severity, agent: issue.agent, file: issue.file }
|
|
504
|
+
});
|
|
505
|
+
}
|
|
506
|
+
/**
|
|
507
|
+
* Add a report section
|
|
508
|
+
*/
|
|
509
|
+
report(content) {
|
|
510
|
+
this.emit({
|
|
511
|
+
type: "report",
|
|
512
|
+
content
|
|
513
|
+
});
|
|
514
|
+
}
|
|
515
|
+
/**
|
|
516
|
+
* Send a proactive notification/nudge to the user
|
|
517
|
+
* This creates a prominent popup in TUI mode or a boxed message in console mode
|
|
518
|
+
*/
|
|
519
|
+
nudge(message, severity = "warning", file, autoHideMs) {
|
|
520
|
+
const metadata = {};
|
|
521
|
+
if (severity === "critical") metadata.severity = "critical";
|
|
522
|
+
else if (severity === "warning") metadata.severity = "moderate";
|
|
523
|
+
else metadata.severity = "low";
|
|
524
|
+
if (file !== void 0) metadata.file = file;
|
|
525
|
+
this.emit({
|
|
526
|
+
type: "nudge",
|
|
527
|
+
content: { message, severity, file, autoHideMs },
|
|
528
|
+
metadata
|
|
529
|
+
});
|
|
530
|
+
}
|
|
531
|
+
// ============================================
|
|
532
|
+
// Helpers
|
|
533
|
+
// ============================================
|
|
534
|
+
formatCurrency(amount) {
|
|
535
|
+
if (amount >= 1e6) return `$${(amount / 1e6).toFixed(2)}M`;
|
|
536
|
+
if (amount >= 1e3) return `$${(amount / 1e3).toFixed(1)}k`;
|
|
537
|
+
return `$${amount}`;
|
|
538
|
+
}
|
|
539
|
+
formatTime(timestamp) {
|
|
540
|
+
const date = timestamp ? new Date(timestamp) : /* @__PURE__ */ new Date();
|
|
541
|
+
return date.toLocaleTimeString("en-US", { hour12: false, hour: "2-digit", minute: "2-digit", second: "2-digit" });
|
|
542
|
+
}
|
|
543
|
+
};
|
|
544
|
+
var instance = null;
|
|
545
|
+
function getOutputManager() {
|
|
546
|
+
if (!instance) {
|
|
547
|
+
instance = new OutputManagerImpl();
|
|
548
|
+
if (isInteractiveMode()) {
|
|
549
|
+
instance.setMode("tui");
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
return instance;
|
|
553
|
+
}
|
|
554
|
+
function output() {
|
|
555
|
+
return getOutputManager();
|
|
556
|
+
}
|
|
557
|
+
function resetOutputManager() {
|
|
558
|
+
instance = null;
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
export {
|
|
562
|
+
getOutputManager,
|
|
563
|
+
output,
|
|
564
|
+
resetOutputManager
|
|
565
|
+
};
|
|
566
|
+
//# sourceMappingURL=chunk-VRLMTOB6.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/output-manager.ts"],"sourcesContent":["/**\n * OutputManager - Unified output abstraction for all UI modes\n * \n * Routes content to the appropriate renderer based on current mode:\n * - TUI: Routes to InteractiveDashboard\n * - Console: Routes to console.error with ANSI colors\n * - MCP: Accumulates for markdown response\n * - JSON: Accumulates for JSON response\n * - Silent: Discards output\n * \n * This solves the problem of skills suppressing content in interactive mode\n * by redirecting it to the dashboard instead.\n */\n\nimport type { Issue } from '../types/index.js';\nimport type { StreamingManager } from './streaming.js';\nimport { isInteractiveMode } from './progress.js';\nimport pc from 'picocolors';\n\n// Output content types\nexport type OutputContentType = \n | 'banner' // ASCII art banner from skills\n | 'progress' // Progress update\n | 'issue' // Issue found\n | 'snippet' // Code snippet with context\n | 'cost' // Cost estimate from Moneybags\n | 'readiness' // Production readiness score\n | 'semantic' // Semantic analysis (data flow, race conditions)\n | 'attack' // Attack surface analysis\n | 'activity' // Activity log message\n | 'report' // Full markdown report section\n | 'log' // Raw log message\n | 'nudge'; // Proactive guardian notification\n\n// Nudge content for proactive notifications\nexport interface NudgeContent {\n message: string;\n severity: 'critical' | 'warning' | 'info';\n file?: string;\n autoHideMs?: number; // Auto-dismiss after this many milliseconds\n}\n\nexport interface BannerContent {\n skill: string;\n art: string;\n quote?: string;\n version?: string;\n}\n\nexport interface SnippetContent {\n file: string;\n lines: string[];\n highlightLine?: number;\n startLine: number;\n}\n\nexport interface CostContent {\n fixNowCost: number;\n productionCost: number;\n savings: number;\n perIssue?: Array<{ issue: string; cost: number }>;\n}\n\nexport interface ReadinessContent {\n score: number;\n requirementsMet: number;\n total: number;\n status: 'ready' | 'caution' | 'not-ready';\n requirements?: Array<{ name: string; met: boolean }>;\n}\n\nexport interface SemanticContent {\n dataFlowIssues: number;\n raceConditions: number;\n authIssues: number;\n details?: Array<{ type: string; description: string; file: string; line?: number }>;\n}\n\nexport interface AttackSurfaceContent {\n totalEndpoints: number;\n unprotected: number;\n riskScore: number;\n endpoints?: Array<{ path: string; method: string; auth: boolean; sensitive: boolean }>;\n}\n\nexport interface OutputContent {\n type: OutputContentType;\n content: any;\n timestamp?: number;\n metadata?: {\n severity?: 'critical' | 'serious' | 'moderate' | 'low';\n agent?: string;\n file?: string;\n };\n}\n\nexport type OutputMode = 'tui' | 'console' | 'mcp' | 'json' | 'silent';\n\n/**\n * Central output manager - singleton\n */\nclass OutputManagerImpl {\n private mode: OutputMode = 'console';\n private streamingManager?: StreamingManager;\n private markdownBuffer: string[] = [];\n private jsonBuffer: OutputContent[] = [];\n private rawLogBuffer: Array<{ time: string; level: string; message: string }> = [];\n \n // Callbacks for TUI integration (explicitly allow undefined for exactOptionalPropertyTypes)\n private onBanner: ((content: BannerContent) => void) | undefined = undefined;\n private onSnippet: ((content: SnippetContent) => void) | undefined = undefined;\n private onCost: ((content: CostContent) => void) | undefined = undefined;\n private onReadiness: ((content: ReadinessContent) => void) | undefined = undefined;\n private onSemantic: ((content: SemanticContent) => void) | undefined = undefined;\n private onAttack: ((content: AttackSurfaceContent) => void) | undefined = undefined;\n private onActivity: ((message: string) => void) | undefined = undefined;\n private onLog: ((level: string, message: string) => void) | undefined = undefined;\n private onNudge: ((content: NudgeContent) => void) | undefined = undefined;\n\n /**\n * Set the output mode\n */\n setMode(mode: OutputMode): void {\n this.mode = mode;\n }\n\n /**\n * Get current output mode\n */\n getMode(): OutputMode {\n return this.mode;\n }\n\n /**\n * Set streaming manager for TUI updates\n */\n setStreamingManager(manager: StreamingManager): void {\n this.streamingManager = manager;\n }\n\n /**\n * Register TUI callbacks for rich content\n */\n registerTUICallbacks(callbacks: {\n onBanner?: (content: BannerContent) => void;\n onSnippet?: (content: SnippetContent) => void;\n onCost?: (content: CostContent) => void;\n onReadiness?: (content: ReadinessContent) => void;\n onSemantic?: (content: SemanticContent) => void;\n onAttack?: (content: AttackSurfaceContent) => void;\n onActivity?: (message: string) => void;\n onLog?: (level: string, message: string) => void;\n onNudge?: (content: NudgeContent) => void;\n }): void {\n this.onBanner = callbacks.onBanner;\n this.onSnippet = callbacks.onSnippet;\n this.onCost = callbacks.onCost;\n this.onReadiness = callbacks.onReadiness;\n this.onSemantic = callbacks.onSemantic;\n this.onAttack = callbacks.onAttack;\n this.onActivity = callbacks.onActivity;\n this.onLog = callbacks.onLog;\n this.onNudge = callbacks.onNudge;\n }\n\n /**\n * Clear TUI callbacks (when dashboard stops)\n */\n clearTUICallbacks(): void {\n this.onBanner = undefined;\n this.onSnippet = undefined;\n this.onCost = undefined;\n this.onReadiness = undefined;\n this.onSemantic = undefined;\n this.onAttack = undefined;\n this.onActivity = undefined;\n this.onLog = undefined;\n this.onNudge = undefined;\n }\n\n /**\n * Emit content - routes to appropriate handler based on mode\n */\n emit(content: OutputContent): void {\n content.timestamp = content.timestamp ?? Date.now();\n \n switch (this.mode) {\n case 'tui':\n this.routeToTUI(content);\n break;\n case 'console':\n this.routeToConsole(content);\n break;\n case 'mcp':\n this.routeToMarkdown(content);\n break;\n case 'json':\n this.routeToJson(content);\n break;\n case 'silent':\n // Discard\n break;\n }\n \n // Always capture in raw log buffer\n this.captureRawLog(content);\n }\n\n /**\n * Route content to TUI (dashboard callbacks)\n */\n private routeToTUI(content: OutputContent): void {\n switch (content.type) {\n case 'banner':\n this.onBanner?.(content.content as BannerContent);\n break;\n case 'snippet':\n this.onSnippet?.(content.content as SnippetContent);\n break;\n case 'cost':\n this.onCost?.(content.content as CostContent);\n break;\n case 'readiness':\n this.onReadiness?.(content.content as ReadinessContent);\n break;\n case 'semantic':\n this.onSemantic?.(content.content as SemanticContent);\n break;\n case 'attack':\n this.onAttack?.(content.content as AttackSurfaceContent);\n break;\n case 'activity':\n this.onActivity?.(content.content as string);\n break;\n case 'log':\n const level = content.metadata?.severity ?? 'info';\n this.onLog?.(level, content.content as string);\n break;\n case 'issue':\n // Issues go through streaming manager\n this.streamingManager?.reportIssue(content.content as Issue);\n break;\n case 'progress':\n // Progress goes through streaming manager\n break;\n case 'report':\n // Reports are captured but not directly displayed\n break;\n case 'nudge':\n // Proactive notifications go to dashboard\n this.onNudge?.(content.content as NudgeContent);\n break;\n }\n }\n\n /**\n * Route content to console (ANSI formatted)\n */\n private routeToConsole(content: OutputContent): void {\n switch (content.type) {\n case 'banner':\n const banner = content.content as BannerContent;\n console.error('\\n' + '='.repeat(60));\n console.error(banner.art);\n if (banner.version) {\n console.error(` ${banner.skill} v${banner.version}`);\n }\n console.error('');\n if (banner.quote) {\n console.error(` \"${banner.quote}\"`);\n }\n console.error('='.repeat(60) + '\\n');\n break;\n \n case 'snippet':\n const snippet = content.content as SnippetContent;\n console.error(`\\n${pc.dim('File:')} ${snippet.file}`);\n for (let i = 0; i < snippet.lines.length; i++) {\n const lineNum = snippet.startLine + i;\n const isHighlight = lineNum === snippet.highlightLine;\n const prefix = isHighlight ? pc.red('→') : ' ';\n const lineNumStr = pc.dim(lineNum.toString().padStart(4));\n const line = isHighlight ? pc.yellow(snippet.lines[i]) : snippet.lines[i];\n console.error(`${prefix} ${lineNumStr} | ${line}`);\n }\n console.error('');\n break;\n \n case 'cost':\n const cost = content.content as CostContent;\n console.error('\\n' + pc.cyan('[$] Cost Estimate:'));\n console.error(` Fix now: ${pc.green(this.formatCurrency(cost.fixNowCost))}`);\n console.error(` If production: ${pc.red(this.formatCurrency(cost.productionCost))}`);\n console.error(` Savings: ${pc.yellow(this.formatCurrency(cost.savings))}`);\n console.error('');\n break;\n \n case 'readiness':\n const readiness = content.content as ReadinessContent;\n const statusColor = readiness.status === 'ready' ? pc.green : \n readiness.status === 'caution' ? pc.yellow : pc.red;\n console.error('\\n' + pc.cyan('[%] Production Readiness:'));\n console.error(` Score: ${statusColor(readiness.score + '/100')}`);\n console.error(` Requirements: ${readiness.requirementsMet}/${readiness.total}`);\n console.error(` Status: ${statusColor(readiness.status.toUpperCase())}`);\n console.error('');\n break;\n \n case 'semantic':\n const semantic = content.content as SemanticContent;\n console.error('\\n' + pc.cyan('[?] Semantic Analysis:'));\n if (semantic.dataFlowIssues > 0) {\n console.error(` ${pc.red('[!]')} ${semantic.dataFlowIssues} data flow vulnerabilities`);\n }\n if (semantic.raceConditions > 0) {\n console.error(` ${pc.yellow('[~]')} ${semantic.raceConditions} race conditions`);\n }\n if (semantic.authIssues > 0) {\n console.error(` ${pc.red('[!]')} ${semantic.authIssues} authentication issues`);\n }\n console.error('');\n break;\n \n case 'attack':\n const attack = content.content as AttackSurfaceContent;\n console.error('\\n' + pc.cyan('[>] Attack Surface:'));\n console.error(` Endpoints: ${attack.totalEndpoints}`);\n if (attack.unprotected > 0) {\n console.error(` ${pc.red('Unprotected:')} ${attack.unprotected}`);\n }\n console.error(` Risk Score: ${attack.riskScore}/100`);\n console.error('');\n break;\n \n case 'activity':\n console.error(pc.dim(`[${this.formatTime()}]`) + ` ${content.content}`);\n break;\n \n case 'log':\n // For log content, severity can be any string (info, warn, error, debug)\n const logLevel = String(content.metadata?.severity ?? 'info');\n const levelColor = logLevel === 'error' || logLevel === 'critical' ? pc.red :\n logLevel === 'warn' || logLevel === 'serious' ? pc.yellow :\n logLevel === 'info' || logLevel === 'moderate' ? pc.blue : pc.dim;\n console.error(levelColor(`[${logLevel.toUpperCase()}]`) + ` ${content.content}`);\n break;\n \n case 'issue':\n const issue = content.content as Issue;\n const sevColor = issue.severity === 'critical' ? pc.red :\n issue.severity === 'serious' ? pc.yellow :\n issue.severity === 'moderate' ? pc.blue : pc.dim;\n console.error(`${sevColor(`[${issue.severity.toUpperCase()}]`)} ${issue.issue}`);\n console.error(` ${pc.dim('File:')} ${issue.file}:${issue.line ?? '?'}`);\n break;\n \n case 'report':\n // Reports are printed as-is (already formatted)\n console.error(content.content);\n break;\n \n case 'nudge':\n // Proactive notifications in console mode\n const nudge = content.content as NudgeContent;\n const nudgeColor = nudge.severity === 'critical' ? pc.red :\n nudge.severity === 'warning' ? pc.yellow : pc.cyan;\n const nudgeIcon = nudge.severity === 'critical' ? '[!!!]' :\n nudge.severity === 'warning' ? '[!]' : '[>]';\n console.error('');\n console.error(nudgeColor('━'.repeat(60)));\n console.error(nudgeColor(`${nudgeIcon} TRIE AGENT SAYS:`));\n console.error(nudgeColor('━'.repeat(60)));\n console.error('');\n console.error(` ${pc.bold(nudge.message)}`);\n if (nudge.file) {\n console.error(` ${pc.dim('File:')} ${nudge.file}`);\n }\n console.error('');\n console.error(nudgeColor('━'.repeat(60)));\n console.error('');\n break;\n }\n }\n\n /**\n * Route content to markdown buffer\n */\n private routeToMarkdown(content: OutputContent): void {\n switch (content.type) {\n case 'banner':\n const banner = content.content as BannerContent;\n this.markdownBuffer.push(`## ${banner.skill}\\n`);\n if (banner.quote) {\n this.markdownBuffer.push(`> ${banner.quote}\\n`);\n }\n break;\n \n case 'snippet':\n const snippet = content.content as SnippetContent;\n this.markdownBuffer.push(`\\n**File:** \\`${snippet.file}\\`\\n`);\n this.markdownBuffer.push('```\\n');\n for (let i = 0; i < snippet.lines.length; i++) {\n const lineNum = snippet.startLine + i;\n const prefix = lineNum === snippet.highlightLine ? '→' : ' ';\n this.markdownBuffer.push(`${prefix} ${lineNum.toString().padStart(4)} | ${snippet.lines[i]}\\n`);\n }\n this.markdownBuffer.push('```\\n');\n break;\n \n case 'cost':\n const cost = content.content as CostContent;\n this.markdownBuffer.push(`\\n### Cost Estimate\\n`);\n this.markdownBuffer.push(`- Fix now: ${this.formatCurrency(cost.fixNowCost)}\\n`);\n this.markdownBuffer.push(`- If production: ${this.formatCurrency(cost.productionCost)}\\n`);\n this.markdownBuffer.push(`- Savings: ${this.formatCurrency(cost.savings)}\\n`);\n break;\n \n case 'readiness':\n const readiness = content.content as ReadinessContent;\n this.markdownBuffer.push(`\\n### Production Readiness\\n`);\n this.markdownBuffer.push(`- Score: ${readiness.score}/100\\n`);\n this.markdownBuffer.push(`- Requirements: ${readiness.requirementsMet}/${readiness.total}\\n`);\n this.markdownBuffer.push(`- Status: **${readiness.status.toUpperCase()}**\\n`);\n break;\n \n case 'semantic':\n const semantic = content.content as SemanticContent;\n this.markdownBuffer.push(`\\n### Semantic Analysis\\n`);\n if (semantic.dataFlowIssues > 0) {\n this.markdownBuffer.push(`- [CRITICAL] ${semantic.dataFlowIssues} data flow vulnerabilities\\n`);\n }\n if (semantic.raceConditions > 0) {\n this.markdownBuffer.push(`- [WARN] ${semantic.raceConditions} race conditions\\n`);\n }\n if (semantic.authIssues > 0) {\n this.markdownBuffer.push(`- [CRITICAL] ${semantic.authIssues} authentication issues\\n`);\n }\n break;\n \n case 'attack':\n const attack = content.content as AttackSurfaceContent;\n this.markdownBuffer.push(`\\n### Attack Surface\\n`);\n this.markdownBuffer.push(`- Endpoints: ${attack.totalEndpoints}\\n`);\n this.markdownBuffer.push(`- Unprotected: ${attack.unprotected}\\n`);\n this.markdownBuffer.push(`- Risk Score: ${attack.riskScore}/100\\n`);\n break;\n \n case 'report':\n this.markdownBuffer.push(content.content);\n break;\n \n default:\n // Other types are captured in JSON buffer\n this.jsonBuffer.push(content);\n }\n }\n\n /**\n * Route content to JSON buffer\n */\n private routeToJson(content: OutputContent): void {\n this.jsonBuffer.push(content);\n }\n\n /**\n * Capture content in raw log buffer\n */\n private captureRawLog(content: OutputContent): void {\n const time = this.formatTime(content.timestamp);\n const level = content.metadata?.severity ?? content.type;\n let message = '';\n \n switch (content.type) {\n case 'banner':\n message = `[BANNER] ${(content.content as BannerContent).skill}`;\n break;\n case 'activity':\n case 'log':\n message = content.content as string;\n break;\n case 'issue':\n const issue = content.content as Issue;\n message = `[${issue.severity.toUpperCase()}] ${issue.issue}`;\n break;\n default:\n message = `[${content.type.toUpperCase()}] Content received`;\n }\n \n this.rawLogBuffer.push({ time, level, message });\n \n // Keep buffer size reasonable\n if (this.rawLogBuffer.length > 500) {\n this.rawLogBuffer = this.rawLogBuffer.slice(-500);\n }\n }\n\n /**\n * Get raw log buffer for display\n */\n getRawLog(): Array<{ time: string; level: string; message: string }> {\n return [...this.rawLogBuffer];\n }\n\n /**\n * Get accumulated markdown output\n */\n getMarkdown(): string {\n return this.markdownBuffer.join('\\n');\n }\n\n /**\n * Get accumulated JSON output\n */\n getJson(): OutputContent[] {\n return [...this.jsonBuffer];\n }\n\n /**\n * Clear buffers\n */\n clearBuffers(): void {\n this.markdownBuffer = [];\n this.jsonBuffer = [];\n }\n\n // ============================================\n // Convenience methods for common output types\n // ============================================\n\n /**\n * Display a skill banner\n */\n banner(skill: string, art: string, options?: { quote?: string; version?: string }): void {\n this.emit({\n type: 'banner',\n content: { skill, art, quote: options?.quote, version: options?.version } as BannerContent,\n metadata: { agent: skill }\n });\n }\n\n /**\n * Display a code snippet\n */\n snippet(file: string, lines: string[], startLine: number, highlightLine?: number): void {\n this.emit({\n type: 'snippet',\n content: { file, lines, startLine, highlightLine } as SnippetContent,\n metadata: { file }\n });\n }\n\n /**\n * Display cost estimate\n */\n cost(fixNowCost: number, productionCost: number, savings: number, perIssue?: Array<{ issue: string; cost: number }>): void {\n this.emit({\n type: 'cost',\n content: { fixNowCost, productionCost, savings, perIssue } as CostContent\n });\n }\n\n /**\n * Display production readiness\n */\n readiness(\n score: number, \n requirementsMet: number, \n total: number, \n status: 'ready' | 'caution' | 'not-ready',\n requirements?: Array<{ name: string; met: boolean }>\n ): void {\n const content: ReadinessContent = { score, requirementsMet, total, status };\n if (requirements) {\n content.requirements = requirements;\n }\n this.emit({\n type: 'readiness',\n content\n });\n }\n\n /**\n * Display semantic analysis results\n */\n semantic(dataFlowIssues: number, raceConditions: number, authIssues: number): void {\n this.emit({\n type: 'semantic',\n content: { dataFlowIssues, raceConditions, authIssues } as SemanticContent\n });\n }\n\n /**\n * Display attack surface analysis\n */\n attack(totalEndpoints: number, unprotected: number, riskScore: number): void {\n this.emit({\n type: 'attack',\n content: { totalEndpoints, unprotected, riskScore } as AttackSurfaceContent\n });\n }\n\n /**\n * Log an activity message\n */\n activity(message: string): void {\n this.emit({\n type: 'activity',\n content: message\n });\n }\n\n /**\n * Log a message at specified level\n */\n log(level: 'info' | 'warn' | 'error' | 'debug', message: string): void {\n this.emit({\n type: 'log',\n content: message,\n metadata: { severity: level as any }\n });\n }\n\n /**\n * Log info message\n */\n info(message: string): void {\n this.log('info', message);\n }\n\n /**\n * Log warning message\n */\n warn(message: string): void {\n this.log('warn', message);\n }\n\n /**\n * Log error message\n */\n error(message: string): void {\n this.log('error', message);\n }\n\n /**\n * Log debug message\n */\n debug(message: string): void {\n this.log('debug', message);\n }\n\n /**\n * Report an issue\n */\n issue(issue: Issue): void {\n this.emit({\n type: 'issue',\n content: issue,\n metadata: { severity: issue.severity, agent: issue.agent, file: issue.file }\n });\n }\n\n /**\n * Add a report section\n */\n report(content: string): void {\n this.emit({\n type: 'report',\n content\n });\n }\n\n /**\n * Send a proactive notification/nudge to the user\n * This creates a prominent popup in TUI mode or a boxed message in console mode\n */\n nudge(message: string, severity: 'critical' | 'warning' | 'info' = 'warning', file?: string, autoHideMs?: number): void {\n const metadata: { severity?: 'critical' | 'serious' | 'moderate' | 'low'; agent?: string; file?: string } = {};\n // Map nudge severity to issue severity\n if (severity === 'critical') metadata.severity = 'critical';\n else if (severity === 'warning') metadata.severity = 'moderate';\n else metadata.severity = 'low';\n if (file !== undefined) metadata.file = file;\n this.emit({\n type: 'nudge',\n content: { message, severity, file, autoHideMs } as NudgeContent,\n metadata,\n });\n }\n\n // ============================================\n // Helpers\n // ============================================\n\n private formatCurrency(amount: number): string {\n if (amount >= 1000000) return `$${(amount / 1000000).toFixed(2)}M`;\n if (amount >= 1000) return `$${(amount / 1000).toFixed(1)}k`;\n return `$${amount}`;\n }\n\n private formatTime(timestamp?: number): string {\n const date = timestamp ? new Date(timestamp) : new Date();\n return date.toLocaleTimeString('en-US', { hour12: false, hour: '2-digit', minute: '2-digit', second: '2-digit' });\n }\n}\n\n// Singleton instance\nlet instance: OutputManagerImpl | null = null;\n\n/**\n * Get the OutputManager instance\n */\nexport function getOutputManager(): OutputManagerImpl {\n if (!instance) {\n instance = new OutputManagerImpl();\n \n // Auto-detect mode based on interactive mode flag\n if (isInteractiveMode()) {\n instance.setMode('tui');\n }\n }\n return instance;\n}\n\n/**\n * Convenience function - shorthand for getOutputManager()\n */\nexport function output(): OutputManagerImpl {\n return getOutputManager();\n}\n\n/**\n * Reset the OutputManager (for testing)\n */\nexport function resetOutputManager(): void {\n instance = null;\n}\n"],"mappings":"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","names":[]}
|