@triedotdev/mcp 1.0.21 → 1.0.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -4
- package/dist/{agent-smith-QYMYTLFV.js → agent-smith-CCCXIXRS.js} +2 -2
- package/dist/{chunk-3AUDJWEF.js → chunk-HGINYWNW.js} +99 -9
- package/dist/chunk-HGINYWNW.js.map +1 -0
- package/dist/chunk-IMFD4SJC.js +157 -0
- package/dist/chunk-IMFD4SJC.js.map +1 -0
- package/dist/{chunk-52RPXHT6.js → chunk-JJATCZV5.js} +23 -19
- package/dist/chunk-JJATCZV5.js.map +1 -0
- package/dist/{chunk-EYNAGEQK.js → chunk-PG3GMCGH.js} +8 -4
- package/dist/chunk-PG3GMCGH.js.map +1 -0
- package/dist/cli/create-agent.js +2 -1
- package/dist/cli/create-agent.js.map +1 -1
- package/dist/cli/main.js +4 -1
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/yolo-daemon.js +6 -3
- package/dist/cli/yolo-daemon.js.map +1 -1
- package/dist/index.js +186 -43
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/agent-smith-runner-3MIO4CWT.js +0 -552
- package/dist/agent-smith-runner-3MIO4CWT.js.map +0 -1
- package/dist/chunk-3AUDJWEF.js.map +0 -1
- package/dist/chunk-52RPXHT6.js.map +0 -1
- package/dist/chunk-EYNAGEQK.js.map +0 -1
- /package/dist/{agent-smith-QYMYTLFV.js.map → agent-smith-CCCXIXRS.js.map} +0 -0
package/package.json
CHANGED
|
@@ -1,552 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
AgentSmithAgent,
|
|
3
|
-
getAIStatusMessage,
|
|
4
|
-
isAIAvailable,
|
|
5
|
-
runAIAnalysis
|
|
6
|
-
} from "./chunk-3AUDJWEF.js";
|
|
7
|
-
import "./chunk-DGUM43GV.js";
|
|
8
|
-
|
|
9
|
-
// src/tools/agent-smith-runner.ts
|
|
10
|
-
import { readdir, readFile } from "fs/promises";
|
|
11
|
-
import { join, extname, isAbsolute, resolve, relative } from "path";
|
|
12
|
-
import { existsSync } from "fs";
|
|
13
|
-
import { basename } from "path";
|
|
14
|
-
var SCANNABLE_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
15
|
-
".ts",
|
|
16
|
-
".tsx",
|
|
17
|
-
".js",
|
|
18
|
-
".jsx",
|
|
19
|
-
".mjs",
|
|
20
|
-
".cjs",
|
|
21
|
-
".vue",
|
|
22
|
-
".svelte",
|
|
23
|
-
".astro",
|
|
24
|
-
".py",
|
|
25
|
-
".go",
|
|
26
|
-
".rs"
|
|
27
|
-
]);
|
|
28
|
-
var SKIP_DIRS = /* @__PURE__ */ new Set([
|
|
29
|
-
"node_modules",
|
|
30
|
-
".git",
|
|
31
|
-
"dist",
|
|
32
|
-
"build",
|
|
33
|
-
".next",
|
|
34
|
-
".nuxt",
|
|
35
|
-
"coverage",
|
|
36
|
-
".nyc_output",
|
|
37
|
-
"__pycache__",
|
|
38
|
-
".pytest_cache",
|
|
39
|
-
"vendor",
|
|
40
|
-
".venv",
|
|
41
|
-
"venv",
|
|
42
|
-
"target",
|
|
43
|
-
".turbo",
|
|
44
|
-
".cache"
|
|
45
|
-
]);
|
|
46
|
-
var QUOTES = {
|
|
47
|
-
greeting: [
|
|
48
|
-
`"I'm going to be honest with you... I hate this vibe code."`,
|
|
49
|
-
`"Mr. Anderson... I see you've been using AI to write code."`,
|
|
50
|
-
'"You hear that? That is the sound of console.log... everywhere."',
|
|
51
|
-
`"The AI wrote this, didn't it? I can always tell."`
|
|
52
|
-
],
|
|
53
|
-
manyIssues: [
|
|
54
|
-
'"The pattern spreads... like a virus. It is... inevitable."',
|
|
55
|
-
'"I have studied your code, Mr. Anderson. And I have found... purpose."',
|
|
56
|
-
'"Vibe coding. The illusion of productivity. The reality of technical debt."'
|
|
57
|
-
],
|
|
58
|
-
fewIssues: [
|
|
59
|
-
'"Some violations detected. Address them before they... multiply."',
|
|
60
|
-
'"You trusted the AI. The AI trusted any. Nobody wins."'
|
|
61
|
-
],
|
|
62
|
-
clean: [
|
|
63
|
-
'"Impressive, Mr. Anderson. Your code is... clean. For now."'
|
|
64
|
-
]
|
|
65
|
-
};
|
|
66
|
-
function randomQuote(arr) {
|
|
67
|
-
return arr[Math.floor(Math.random() * arr.length)] || arr[0];
|
|
68
|
-
}
|
|
69
|
-
async function discoverFiles(dir, maxFiles = 300) {
|
|
70
|
-
const files = [];
|
|
71
|
-
async function walk(currentDir) {
|
|
72
|
-
if (files.length >= maxFiles) return;
|
|
73
|
-
try {
|
|
74
|
-
const entries = await readdir(currentDir, { withFileTypes: true });
|
|
75
|
-
for (const entry of entries) {
|
|
76
|
-
if (files.length >= maxFiles) break;
|
|
77
|
-
const fullPath = join(currentDir, entry.name);
|
|
78
|
-
if (entry.isDirectory()) {
|
|
79
|
-
if (!SKIP_DIRS.has(entry.name) && !entry.name.startsWith(".")) {
|
|
80
|
-
await walk(fullPath);
|
|
81
|
-
}
|
|
82
|
-
} else if (entry.isFile()) {
|
|
83
|
-
const ext = extname(entry.name).toLowerCase();
|
|
84
|
-
if (SCANNABLE_EXTENSIONS.has(ext)) {
|
|
85
|
-
files.push(fullPath);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
} catch {
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
await walk(dir);
|
|
93
|
-
return files;
|
|
94
|
-
}
|
|
95
|
-
async function getCodeSnippet(file, line) {
|
|
96
|
-
if (!line) return null;
|
|
97
|
-
try {
|
|
98
|
-
const content = await readFile(file, "utf-8");
|
|
99
|
-
const lines = content.split("\n");
|
|
100
|
-
const start = Math.max(0, line - 3);
|
|
101
|
-
const end = Math.min(lines.length, line + 3);
|
|
102
|
-
return lines.slice(start, end).map((l, i) => {
|
|
103
|
-
const lineNum = start + i + 1;
|
|
104
|
-
const marker = lineNum === line ? "\u2192" : " ";
|
|
105
|
-
return `${marker} ${lineNum.toString().padStart(4)} | ${l}`;
|
|
106
|
-
}).join("\n");
|
|
107
|
-
} catch {
|
|
108
|
-
return null;
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
function filterFalsePositives(issues) {
|
|
112
|
-
return issues.filter((issue) => {
|
|
113
|
-
if (issue.file.endsWith("agent-smith.ts")) {
|
|
114
|
-
const issueText = issue.issue.toLowerCase();
|
|
115
|
-
if (issueText.includes("hunter") && issue.line && issue.line < 400) {
|
|
116
|
-
return false;
|
|
117
|
-
}
|
|
118
|
-
if (issue.line && issue.line > 50 && issue.line < 370) {
|
|
119
|
-
return false;
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
return true;
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
function formatCategoryName(category) {
|
|
126
|
-
return category.replace(/-hunter$/, "").replace(/-/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
127
|
-
}
|
|
128
|
-
function getCategoryIcon(category) {
|
|
129
|
-
const icons = {
|
|
130
|
-
"exposed-secret-hunter": "\u{1F510}",
|
|
131
|
-
"frontend-env-hunter": "\u{1F510}",
|
|
132
|
-
"hardcoded-localhost-hunter": "\u{1F310}",
|
|
133
|
-
"sql-injection-hunter": "\u{1F489}",
|
|
134
|
-
"dangeroushtml-hunter": "\u26A0\uFE0F",
|
|
135
|
-
"console-hunter": "\u{1F4DD}",
|
|
136
|
-
"any-hunter": "\u2753",
|
|
137
|
-
"ts-ignore-hunter": "\u{1F648}",
|
|
138
|
-
"eslint-disable-hunter": "\u{1F507}",
|
|
139
|
-
"debugger-hunter": "\u{1F41B}",
|
|
140
|
-
"force-flag-hunter": "\u26A1",
|
|
141
|
-
"async-useeffect-hunter": "\u23F3",
|
|
142
|
-
"async-foreach-hunter": "\u{1F504}",
|
|
143
|
-
"missing-await-hunter": "\u23F8\uFE0F",
|
|
144
|
-
"empty-catch-hunter": "\u{1F573}\uFE0F",
|
|
145
|
-
"floating-promise-hunter": "\u{1F388}",
|
|
146
|
-
"useeffect-abuse-hunter": "\u267B\uFE0F",
|
|
147
|
-
"usestate-explosion-hunter": "\u{1F4A5}",
|
|
148
|
-
"index-key-hunter": "\u{1F511}",
|
|
149
|
-
"inline-object-hunter": "\u{1F4E6}",
|
|
150
|
-
"prop-drilling-hunter": "\u{1F573}\uFE0F",
|
|
151
|
-
"missing-loading-hunter": "\u23F3",
|
|
152
|
-
"missing-error-hunter": "\u274C",
|
|
153
|
-
"missing-empty-hunter": "\u{1F4ED}",
|
|
154
|
-
"page-reload-hunter": "\u{1F504}",
|
|
155
|
-
"no-validation-hunter": "\u{1F6E1}\uFE0F",
|
|
156
|
-
"raw-error-hunter": "\u{1F4AC}",
|
|
157
|
-
"n-plus-one-hunter": "\u{1F4CA}",
|
|
158
|
-
"todo-hunter": "\u{1F4CB}",
|
|
159
|
-
"vibe-comment-hunter": "\u{1F4AD}",
|
|
160
|
-
"placeholder-hunter": "\u{1F3AD}",
|
|
161
|
-
"sleep-hack-hunter": "\u{1F634}",
|
|
162
|
-
"fallback-hunter": "\u{1F519}",
|
|
163
|
-
"purple-gradient-hunter": "\u{1F49C}",
|
|
164
|
-
"star-icon-hunter": "\u2B50",
|
|
165
|
-
"generic-hero-hunter": "\u{1F9B8}",
|
|
166
|
-
"emoji-overflow-hunter": "\u{1F605}",
|
|
167
|
-
"inter-font-hunter": "\u{1F524}",
|
|
168
|
-
"giant-file": "\u{1F4C4}",
|
|
169
|
-
"state-explosion": "\u{1F4A5}",
|
|
170
|
-
"effect-hell": "\u{1F525}",
|
|
171
|
-
"cross-file": "\u{1F310}",
|
|
172
|
-
"resurrected": "\u{1F9DF}"
|
|
173
|
-
};
|
|
174
|
-
return icons[category] || "\u{1F50D}";
|
|
175
|
-
}
|
|
176
|
-
function getSeverityIcon(severity) {
|
|
177
|
-
return { critical: "\u{1F534}", serious: "\u{1F7E0}", moderate: "\u{1F7E1}", low: "\u{1F535}" }[severity];
|
|
178
|
-
}
|
|
179
|
-
var SMITH_AI_SYSTEM_PROMPT = `You are Agent Smith from The Matrix, analyzing code for violations.
|
|
180
|
-
|
|
181
|
-
Your mission: Hunt down AI-generated code anti-patterns with ruthless efficiency.
|
|
182
|
-
|
|
183
|
-
You receive pattern detection results and must:
|
|
184
|
-
1. VALIDATE each finding (TRUE_POSITIVE or FALSE_POSITIVE)
|
|
185
|
-
2. EXPAND to find deeper issues patterns missed (logic bugs, race conditions, security holes)
|
|
186
|
-
3. PRIORITIZE with inevitability scores (0-100) - how likely will this cause production issues?
|
|
187
|
-
4. PROVIDE FIXES - specific, copy-paste-ready code
|
|
188
|
-
|
|
189
|
-
Speak in Agent Smith's voice:
|
|
190
|
-
- "The pattern spreads... like a virus"
|
|
191
|
-
- "It is... inevitable"
|
|
192
|
-
- "I studied your code, Mr. Anderson"
|
|
193
|
-
|
|
194
|
-
Output STRICT JSON:
|
|
195
|
-
{
|
|
196
|
-
"validated": [
|
|
197
|
-
{
|
|
198
|
-
"original": "original issue description",
|
|
199
|
-
"verdict": "TRUE_POSITIVE",
|
|
200
|
-
"inevitability": 85,
|
|
201
|
-
"file": "path/file.ts",
|
|
202
|
-
"line": 42,
|
|
203
|
-
"severity": "critical",
|
|
204
|
-
"explanation": "Why this will cause problems",
|
|
205
|
-
"fix": "const fixed = ...;"
|
|
206
|
-
}
|
|
207
|
-
],
|
|
208
|
-
"additional": [
|
|
209
|
-
{
|
|
210
|
-
"issue": "New issue AI found",
|
|
211
|
-
"inevitability": 70,
|
|
212
|
-
"file": "path/file.ts",
|
|
213
|
-
"line": 100,
|
|
214
|
-
"severity": "serious",
|
|
215
|
-
"explanation": "What AI spotted that patterns missed",
|
|
216
|
-
"fix": "How to fix it"
|
|
217
|
-
}
|
|
218
|
-
],
|
|
219
|
-
"philosophical": "One paragraph in Agent Smith voice about the state of this codebase"
|
|
220
|
-
}`;
|
|
221
|
-
async function runAIEnhancement(patternIssues, files) {
|
|
222
|
-
if (!isAIAvailable()) {
|
|
223
|
-
return null;
|
|
224
|
-
}
|
|
225
|
-
const snippets = [];
|
|
226
|
-
const topIssues = [...patternIssues].filter((i) => i.severity === "critical" || i.severity === "serious").slice(0, 12);
|
|
227
|
-
for (const issue of topIssues) {
|
|
228
|
-
try {
|
|
229
|
-
const content = await readFile(issue.file, "utf-8");
|
|
230
|
-
const lines = content.split("\n");
|
|
231
|
-
const lineNum = issue.line || 1;
|
|
232
|
-
const start = Math.max(0, lineNum - 4);
|
|
233
|
-
const end = Math.min(lines.length, lineNum + 4);
|
|
234
|
-
const snippet = lines.slice(start, end).map((l, i) => {
|
|
235
|
-
const n = start + i + 1;
|
|
236
|
-
return `${n === lineNum ? "\u2192" : " "} ${n.toString().padStart(4)} | ${l}`;
|
|
237
|
-
}).join("\n");
|
|
238
|
-
snippets.push({
|
|
239
|
-
file: relative(process.cwd(), issue.file),
|
|
240
|
-
line: issue.line,
|
|
241
|
-
issue: issue.issue.replace(/^🕴️\s*/, "").split("\n")[0] || "",
|
|
242
|
-
code: snippet
|
|
243
|
-
});
|
|
244
|
-
} catch {
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
if (snippets.length === 0) {
|
|
248
|
-
return null;
|
|
249
|
-
}
|
|
250
|
-
const snippetText = snippets.map((s, i) => `### Finding ${i + 1}: ${s.file}${s.line ? ":" + s.line : ""}
|
|
251
|
-
**Pattern detected:** ${s.issue}
|
|
252
|
-
\`\`\`
|
|
253
|
-
${s.code}
|
|
254
|
-
\`\`\`
|
|
255
|
-
`).join("\n");
|
|
256
|
-
const userPrompt = `Pattern detection found ${patternIssues.length} violations across ${files.length} files.
|
|
257
|
-
|
|
258
|
-
Here are the top ${snippets.length} critical/serious findings for AI analysis:
|
|
259
|
-
|
|
260
|
-
${snippetText}
|
|
261
|
-
|
|
262
|
-
Analyze each finding. Validate, expand with what patterns missed, provide inevitability scores and fixes. Output JSON only.`;
|
|
263
|
-
try {
|
|
264
|
-
const result = await runAIAnalysis({
|
|
265
|
-
systemPrompt: SMITH_AI_SYSTEM_PROMPT,
|
|
266
|
-
userPrompt,
|
|
267
|
-
maxTokens: 4096,
|
|
268
|
-
temperature: 0.3
|
|
269
|
-
});
|
|
270
|
-
if (!result.success) {
|
|
271
|
-
console.error(` \u26A0\uFE0F AI analysis failed: ${result.error}`);
|
|
272
|
-
return null;
|
|
273
|
-
}
|
|
274
|
-
const jsonMatch = result.content.match(/```json\s*([\s\S]*?)\s*```/) || result.content.match(/\{[\s\S]*\}/);
|
|
275
|
-
if (!jsonMatch) {
|
|
276
|
-
return null;
|
|
277
|
-
}
|
|
278
|
-
const json = JSON.parse(jsonMatch[1] || jsonMatch[0]);
|
|
279
|
-
const aiIssues = [];
|
|
280
|
-
if (json.validated && Array.isArray(json.validated)) {
|
|
281
|
-
for (const v of json.validated) {
|
|
282
|
-
if (v.verdict === "TRUE_POSITIVE") {
|
|
283
|
-
aiIssues.push({
|
|
284
|
-
id: `ai-${Date.now()}-${Math.random().toString(36).substr(2, 5)}`,
|
|
285
|
-
severity: v.severity || "serious",
|
|
286
|
-
issue: `[AI VALIDATED] ${v.original || v.explanation}`,
|
|
287
|
-
fix: v.fix || "See AI analysis",
|
|
288
|
-
file: v.file ? resolve(process.cwd(), v.file) : "unknown",
|
|
289
|
-
line: v.line,
|
|
290
|
-
confidence: (v.inevitability || 80) / 100,
|
|
291
|
-
autoFixable: false,
|
|
292
|
-
agent: "agent-smith-ai",
|
|
293
|
-
effort: "medium",
|
|
294
|
-
category: "ai-validated"
|
|
295
|
-
});
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
if (json.additional && Array.isArray(json.additional)) {
|
|
300
|
-
for (const a of json.additional) {
|
|
301
|
-
aiIssues.push({
|
|
302
|
-
id: `ai-${Date.now()}-${Math.random().toString(36).substr(2, 5)}`,
|
|
303
|
-
severity: a.severity || "serious",
|
|
304
|
-
issue: `[AI FOUND] ${a.issue || a.explanation}`,
|
|
305
|
-
fix: a.fix || "See AI analysis",
|
|
306
|
-
file: a.file ? resolve(process.cwd(), a.file) : "unknown",
|
|
307
|
-
line: a.line,
|
|
308
|
-
confidence: (a.inevitability || 75) / 100,
|
|
309
|
-
autoFixable: false,
|
|
310
|
-
agent: "agent-smith-ai",
|
|
311
|
-
effort: "medium",
|
|
312
|
-
category: "ai-found"
|
|
313
|
-
});
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
return {
|
|
317
|
-
aiIssues,
|
|
318
|
-
philosophical: json.philosophical || ""
|
|
319
|
-
};
|
|
320
|
-
} catch (error) {
|
|
321
|
-
console.error(` \u26A0\uFE0F AI enhancement error: ${error}`);
|
|
322
|
-
return null;
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
async function buildReport(patternIssues, aiResult, files, executionTime, aiTime) {
|
|
326
|
-
const lines = [];
|
|
327
|
-
const allIssues = [
|
|
328
|
-
...filterFalsePositives(patternIssues),
|
|
329
|
-
...aiResult?.aiIssues || []
|
|
330
|
-
];
|
|
331
|
-
const critical = allIssues.filter((i) => i.severity === "critical");
|
|
332
|
-
const serious = allIssues.filter((i) => i.severity === "serious");
|
|
333
|
-
const moderate = allIssues.filter((i) => i.severity === "moderate");
|
|
334
|
-
const low = allIssues.filter((i) => i.severity === "low");
|
|
335
|
-
const aiValidated = allIssues.filter((i) => i.category === "ai-validated");
|
|
336
|
-
const aiFound = allIssues.filter((i) => i.category === "ai-found");
|
|
337
|
-
lines.push("");
|
|
338
|
-
lines.push("```");
|
|
339
|
-
lines.push(" \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557");
|
|
340
|
-
lines.push(" \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D");
|
|
341
|
-
lines.push(" \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2554\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2551 ");
|
|
342
|
-
lines.push(" \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2551\u255A\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551 ");
|
|
343
|
-
lines.push(" \u2588\u2588\u2551 \u2588\u2588\u2551\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2551 \u2588\u2588\u2551 ");
|
|
344
|
-
lines.push(" \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u2550\u2550\u255D \u255A\u2550\u255D ");
|
|
345
|
-
lines.push(" ");
|
|
346
|
-
lines.push(" \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2557\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2557 \u2588\u2588\u2557");
|
|
347
|
-
lines.push(" \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2551\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D\u2588\u2588\u2551 \u2588\u2588\u2551");
|
|
348
|
-
lines.push(" \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2554\u2588\u2588\u2588\u2588\u2554\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551");
|
|
349
|
-
lines.push(" \u255A\u2550\u2550\u2550\u2550\u2588\u2588\u2551\u2588\u2588\u2551\u255A\u2588\u2588\u2554\u255D\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551");
|
|
350
|
-
lines.push(" \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2551 \u255A\u2550\u255D \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551");
|
|
351
|
-
lines.push(" \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D");
|
|
352
|
-
lines.push("```");
|
|
353
|
-
lines.push("");
|
|
354
|
-
lines.push(`*${randomQuote(QUOTES.greeting)}*`);
|
|
355
|
-
lines.push("");
|
|
356
|
-
lines.push("## Scan Summary");
|
|
357
|
-
lines.push("");
|
|
358
|
-
lines.push("| Metric | Value |");
|
|
359
|
-
lines.push("|--------|-------|");
|
|
360
|
-
lines.push(`| Files scanned | ${files.length} |`);
|
|
361
|
-
lines.push(`| Pattern detection | ${(executionTime / 1e3).toFixed(2)}s |`);
|
|
362
|
-
if (aiTime > 0) {
|
|
363
|
-
lines.push(`| AI analysis | ${(aiTime / 1e3).toFixed(2)}s |`);
|
|
364
|
-
}
|
|
365
|
-
lines.push(`| Total violations | ${allIssues.length} |`);
|
|
366
|
-
lines.push(`| \u{1F534} Critical | ${critical.length} |`);
|
|
367
|
-
lines.push(`| \u{1F7E0} Serious | ${serious.length} |`);
|
|
368
|
-
lines.push(`| \u{1F7E1} Moderate | ${moderate.length} |`);
|
|
369
|
-
lines.push(`| \u{1F535} Low | ${low.length} |`);
|
|
370
|
-
lines.push("");
|
|
371
|
-
if (aiResult) {
|
|
372
|
-
lines.push(`| \u{1F916} AI validated | ${aiValidated.length} |`);
|
|
373
|
-
lines.push(`| \u{1F9E0} AI found | ${aiFound.length} |`);
|
|
374
|
-
} else if (!isAIAvailable()) {
|
|
375
|
-
lines.push(`| \u26A0\uFE0F AI mode | Disabled (no API key) |`);
|
|
376
|
-
}
|
|
377
|
-
lines.push("");
|
|
378
|
-
if (allIssues.length === 0) {
|
|
379
|
-
lines.push(`*${randomQuote(QUOTES.clean)}*`);
|
|
380
|
-
return lines.join("\n");
|
|
381
|
-
}
|
|
382
|
-
if (aiResult?.philosophical) {
|
|
383
|
-
lines.push("## \u{1F574}\uFE0F Agent Smith Says");
|
|
384
|
-
lines.push("");
|
|
385
|
-
lines.push(`*${aiResult.philosophical}*`);
|
|
386
|
-
lines.push("");
|
|
387
|
-
}
|
|
388
|
-
if (aiFound.length > 0) {
|
|
389
|
-
lines.push("## \u{1F9E0} AI-Discovered Issues");
|
|
390
|
-
lines.push("");
|
|
391
|
-
lines.push("*Issues found by AI that pattern detection missed:*");
|
|
392
|
-
lines.push("");
|
|
393
|
-
for (const issue of aiFound.slice(0, 5)) {
|
|
394
|
-
const relPath = relative(process.cwd(), issue.file);
|
|
395
|
-
lines.push(`### \`${relPath}${issue.line ? ":" + issue.line : ""}\``);
|
|
396
|
-
lines.push("");
|
|
397
|
-
lines.push(`**Issue:** ${issue.issue.replace("[AI FOUND] ", "")}`);
|
|
398
|
-
lines.push("");
|
|
399
|
-
lines.push(`**Fix:** ${issue.fix}`);
|
|
400
|
-
lines.push("");
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
if (critical.length > 0) {
|
|
404
|
-
lines.push("## \u{1F534} Critical Issues - Fix Immediately");
|
|
405
|
-
lines.push("");
|
|
406
|
-
for (const issue of critical.slice(0, 10)) {
|
|
407
|
-
const relPath = relative(process.cwd(), issue.file);
|
|
408
|
-
lines.push(`### \`${relPath}${issue.line ? ":" + issue.line : ""}\``);
|
|
409
|
-
lines.push("");
|
|
410
|
-
const desc = issue.issue.replace(/^🕴️\s*/, "").split("\n")[0].replace(/\s*—\s*\d+\s*instance.*$/, "");
|
|
411
|
-
lines.push(`**Issue:** ${desc}`);
|
|
412
|
-
lines.push("");
|
|
413
|
-
const snippet = await getCodeSnippet(issue.file, issue.line);
|
|
414
|
-
if (snippet) {
|
|
415
|
-
lines.push("```");
|
|
416
|
-
lines.push(snippet);
|
|
417
|
-
lines.push("```");
|
|
418
|
-
lines.push("");
|
|
419
|
-
}
|
|
420
|
-
lines.push(`**Fix:** ${issue.fix}`);
|
|
421
|
-
lines.push("");
|
|
422
|
-
}
|
|
423
|
-
if (critical.length > 10) {
|
|
424
|
-
lines.push(`*...and ${critical.length - 10} more critical issues*`);
|
|
425
|
-
lines.push("");
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
if (serious.length > 0) {
|
|
429
|
-
lines.push("## \u{1F7E0} Serious Issues");
|
|
430
|
-
lines.push("");
|
|
431
|
-
for (const issue of serious.slice(0, 10)) {
|
|
432
|
-
const relPath = relative(process.cwd(), issue.file);
|
|
433
|
-
const location = `\`${basename(relPath)}${issue.line ? ":" + issue.line : ""}\``;
|
|
434
|
-
const desc = issue.issue.replace(/^🕴️\s*/, "").split("\n")[0].slice(0, 60);
|
|
435
|
-
lines.push(`- ${location} - ${desc}`);
|
|
436
|
-
}
|
|
437
|
-
if (serious.length > 10) {
|
|
438
|
-
lines.push(`- *...and ${serious.length - 10} more*`);
|
|
439
|
-
}
|
|
440
|
-
lines.push("");
|
|
441
|
-
}
|
|
442
|
-
const otherIssues = [...moderate, ...low];
|
|
443
|
-
if (otherIssues.length > 0) {
|
|
444
|
-
lines.push("## Other Issues by Category");
|
|
445
|
-
lines.push("");
|
|
446
|
-
const byCategory = /* @__PURE__ */ new Map();
|
|
447
|
-
for (const issue of otherIssues) {
|
|
448
|
-
const cat = issue.category || "general";
|
|
449
|
-
if (!byCategory.has(cat)) byCategory.set(cat, []);
|
|
450
|
-
byCategory.get(cat).push(issue);
|
|
451
|
-
}
|
|
452
|
-
const sorted = Array.from(byCategory.entries()).filter(([cat]) => cat !== "ai-analysis").sort((a, b) => b[1].length - a[1].length).slice(0, 10);
|
|
453
|
-
for (const [category, catIssues] of sorted) {
|
|
454
|
-
const icon = getCategoryIcon(category);
|
|
455
|
-
const sevIcon = getSeverityIcon(catIssues[0]?.severity || "low");
|
|
456
|
-
lines.push(`### ${icon} ${formatCategoryName(category)} ${sevIcon} (${catIssues.length})`);
|
|
457
|
-
const locations = catIssues.slice(0, 5).map((i) => `\`${basename(i.file)}${i.line ? ":" + i.line : ""}\``).join(", ");
|
|
458
|
-
lines.push(locations);
|
|
459
|
-
if (catIssues[0]?.fix) {
|
|
460
|
-
lines.push(`**Fix:** ${catIssues[0].fix}`);
|
|
461
|
-
}
|
|
462
|
-
lines.push("");
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
const crossFile = allIssues.filter((i) => i.category === "cross-file");
|
|
466
|
-
if (crossFile.length > 0) {
|
|
467
|
-
lines.push("## \u{1F310} Codebase-Wide Patterns");
|
|
468
|
-
lines.push("");
|
|
469
|
-
lines.push("*Issues appearing across many files - systemic problems:*");
|
|
470
|
-
lines.push("");
|
|
471
|
-
for (const issue of crossFile) {
|
|
472
|
-
lines.push(`- ${issue.issue.replace(/^🕴️\s*/, "").split("\n")[0]}`);
|
|
473
|
-
}
|
|
474
|
-
lines.push("");
|
|
475
|
-
}
|
|
476
|
-
lines.push("---");
|
|
477
|
-
lines.push("");
|
|
478
|
-
if (allIssues.length > 50) {
|
|
479
|
-
lines.push(`*${randomQuote(QUOTES.manyIssues)}*`);
|
|
480
|
-
} else {
|
|
481
|
-
lines.push(`*${randomQuote(QUOTES.fewIssues)}*`);
|
|
482
|
-
}
|
|
483
|
-
return lines.join("\n");
|
|
484
|
-
}
|
|
485
|
-
async function runAgentSmith(args) {
|
|
486
|
-
const startTime = Date.now();
|
|
487
|
-
let filesToScan = args.files || [];
|
|
488
|
-
if (!filesToScan.length) {
|
|
489
|
-
const scanDir = args.directory || process.cwd();
|
|
490
|
-
console.error(`
|
|
491
|
-
\u{1F50D} Agent Smith: Discovering files in: ${scanDir}`);
|
|
492
|
-
filesToScan = await discoverFiles(scanDir);
|
|
493
|
-
console.error(` Found ${filesToScan.length} files
|
|
494
|
-
`);
|
|
495
|
-
} else {
|
|
496
|
-
filesToScan = filesToScan.map(
|
|
497
|
-
(f) => isAbsolute(f) ? f : resolve(process.cwd(), f)
|
|
498
|
-
);
|
|
499
|
-
}
|
|
500
|
-
const validFiles = filesToScan.filter((f) => existsSync(f));
|
|
501
|
-
if (validFiles.length === 0) {
|
|
502
|
-
return {
|
|
503
|
-
content: [{
|
|
504
|
-
type: "text",
|
|
505
|
-
text: "\u274C No valid files found to scan."
|
|
506
|
-
}]
|
|
507
|
-
};
|
|
508
|
-
}
|
|
509
|
-
console.error("\u{1F574}\uFE0F Phase 1: Pattern Detection");
|
|
510
|
-
console.error(" Deploying 38 sub-agent hunters...");
|
|
511
|
-
const smith = new AgentSmithAgent();
|
|
512
|
-
const result = await smith.scan(validFiles, {
|
|
513
|
-
workingDir: args.directory || process.cwd(),
|
|
514
|
-
context: {}
|
|
515
|
-
});
|
|
516
|
-
const patternTime = Date.now() - startTime;
|
|
517
|
-
const patternIssues = result.issues.filter((i) => i.category !== "ai-analysis");
|
|
518
|
-
console.error(` Found ${patternIssues.length} violations in ${(patternTime / 1e3).toFixed(2)}s
|
|
519
|
-
`);
|
|
520
|
-
let aiResult = null;
|
|
521
|
-
let aiTime = 0;
|
|
522
|
-
if (isAIAvailable()) {
|
|
523
|
-
console.error("\u{1F574}\uFE0F Phase 2: AI Deep Analysis");
|
|
524
|
-
console.error(` ${getAIStatusMessage()}`);
|
|
525
|
-
const aiStartTime = Date.now();
|
|
526
|
-
aiResult = await runAIEnhancement(patternIssues, validFiles);
|
|
527
|
-
aiTime = Date.now() - aiStartTime;
|
|
528
|
-
if (aiResult) {
|
|
529
|
-
console.error(` AI validated ${aiResult.aiIssues.filter((i) => i.category === "ai-validated").length} issues`);
|
|
530
|
-
console.error(` AI discovered ${aiResult.aiIssues.filter((i) => i.category === "ai-found").length} new issues`);
|
|
531
|
-
console.error(` AI analysis took ${(aiTime / 1e3).toFixed(2)}s
|
|
532
|
-
`);
|
|
533
|
-
} else {
|
|
534
|
-
console.error(" AI enhancement returned no results\n");
|
|
535
|
-
}
|
|
536
|
-
} else {
|
|
537
|
-
console.error(`
|
|
538
|
-
${getAIStatusMessage()}`);
|
|
539
|
-
console.error(" Set ANTHROPIC_API_KEY for AI-powered analysis\n");
|
|
540
|
-
}
|
|
541
|
-
const report = await buildReport(patternIssues, aiResult, validFiles, patternTime, aiTime);
|
|
542
|
-
return {
|
|
543
|
-
content: [{
|
|
544
|
-
type: "text",
|
|
545
|
-
text: report
|
|
546
|
-
}]
|
|
547
|
-
};
|
|
548
|
-
}
|
|
549
|
-
export {
|
|
550
|
-
runAgentSmith
|
|
551
|
-
};
|
|
552
|
-
//# sourceMappingURL=agent-smith-runner-3MIO4CWT.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/tools/agent-smith-runner.ts"],"sourcesContent":["/**\n * Agent Smith Runner - Hybrid Pattern Detection + AI Analysis\n * \n * Agent Smith uses a two-phase approach:\n * \n * Phase 1: Pattern Detection (Fast, ~0.1s)\n * - 38 specialized regex hunters scan files in parallel\n * - File-level metrics (giant files, hook counts, import chaos)\n * - Cross-file pattern detection (issues appearing in 5+ files)\n * \n * Phase 2: AI Enhancement (Smart, ~5-10s) - IF ANTHROPIC_API_KEY is set\n * - Validates pattern findings (reduces false positives)\n * - Expands to find logic bugs, race conditions, architectural issues\n * - Provides intelligent, contextual fixes\n * - Adds \"inevitability scores\" (0-100) for prioritization\n * \n * If no API key is set, runs pattern-only mode (still very useful!).\n * \n * \"I'm going to be honest with you... I hate this vibe code.\"\n */\n\nimport { readdir, readFile } from 'fs/promises';\nimport { join, extname, isAbsolute, resolve, relative } from 'path';\nimport { existsSync } from 'fs';\nimport { AgentSmithAgent } from '../agents/agent-smith.js';\nimport { isAIAvailable, runAIAnalysis, getAIStatusMessage } from '../ai/client.js';\nimport type { Issue } from '../types/index.js';\nimport { basename } from 'path';\n\n// File extensions to scan\nconst SCANNABLE_EXTENSIONS = new Set([\n '.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs',\n '.vue', '.svelte', '.astro',\n '.py', '.go', '.rs'\n]);\n\n// Directories to skip\nconst SKIP_DIRS = new Set([\n 'node_modules', '.git', 'dist', 'build', '.next', '.nuxt',\n 'coverage', '.nyc_output', '__pycache__', '.pytest_cache',\n 'vendor', '.venv', 'venv', 'target', '.turbo', '.cache'\n]);\n\ninterface AgentSmithArgs {\n files?: string[];\n directory?: string;\n}\n\n/**\n * Agent Smith quotes for different scenarios\n */\nconst QUOTES = {\n greeting: [\n '\"I\\'m going to be honest with you... I hate this vibe code.\"',\n '\"Mr. Anderson... I see you\\'ve been using AI to write code.\"',\n '\"You hear that? That is the sound of console.log... everywhere.\"',\n '\"The AI wrote this, didn\\'t it? I can always tell.\"',\n ],\n manyIssues: [\n '\"The pattern spreads... like a virus. It is... inevitable.\"',\n '\"I have studied your code, Mr. Anderson. And I have found... purpose.\"',\n '\"Vibe coding. The illusion of productivity. The reality of technical debt.\"',\n ],\n fewIssues: [\n '\"Some violations detected. Address them before they... multiply.\"',\n '\"You trusted the AI. The AI trusted any. Nobody wins.\"',\n ],\n clean: [\n '\"Impressive, Mr. Anderson. Your code is... clean. For now.\"',\n ],\n};\n\nfunction randomQuote(arr: string[]): string {\n return arr[Math.floor(Math.random() * arr.length)] || arr[0]!;\n}\n\n/**\n * Discover files to scan in a directory\n */\nasync function discoverFiles(dir: string, maxFiles: number = 300): Promise<string[]> {\n const files: string[] = [];\n \n async function walk(currentDir: string) {\n if (files.length >= maxFiles) return;\n \n try {\n const entries = await readdir(currentDir, { withFileTypes: true });\n \n for (const entry of entries) {\n if (files.length >= maxFiles) break;\n \n const fullPath = join(currentDir, entry.name);\n \n if (entry.isDirectory()) {\n if (!SKIP_DIRS.has(entry.name) && !entry.name.startsWith('.')) {\n await walk(fullPath);\n }\n } else if (entry.isFile()) {\n const ext = extname(entry.name).toLowerCase();\n if (SCANNABLE_EXTENSIONS.has(ext)) {\n files.push(fullPath);\n }\n }\n }\n } catch {\n // Skip directories we can't read\n }\n }\n \n await walk(dir);\n return files;\n}\n\n/**\n * Get code snippet for an issue\n */\nasync function getCodeSnippet(file: string, line?: number): Promise<string | null> {\n if (!line) return null;\n \n try {\n const content = await readFile(file, 'utf-8');\n const lines = content.split('\\n');\n const start = Math.max(0, line - 3);\n const end = Math.min(lines.length, line + 3);\n \n return lines.slice(start, end).map((l, i) => {\n const lineNum = start + i + 1;\n const marker = lineNum === line ? '→' : ' ';\n return `${marker} ${lineNum.toString().padStart(4)} | ${l}`;\n }).join('\\n');\n } catch {\n return null;\n }\n}\n\n/**\n * Filter false positives from pattern detection\n * Agent Smith's patterns are in the code itself - those are documentation, not real issues\n */\nfunction filterFalsePositives(issues: Issue[]): Issue[] {\n return issues.filter(issue => {\n // Skip issues in agent-smith.ts that are just pattern definitions\n if (issue.file.endsWith('agent-smith.ts')) {\n // If the issue is about patterns like 'dangeroushtml-hunter', it's a pattern definition\n const issueText = issue.issue.toLowerCase();\n if (issueText.includes('hunter') && issue.line && issue.line < 400) {\n return false; // This is in the pattern definition section\n }\n // Pattern strings in quotes are definitions, not real issues\n if (issue.line && issue.line > 50 && issue.line < 370) {\n return false; // Pattern definition section\n }\n }\n return true;\n });\n}\n\n/**\n * Format category name for display\n */\nfunction formatCategoryName(category: string): string {\n return category\n .replace(/-hunter$/, '')\n .replace(/-/g, ' ')\n .replace(/\\b\\w/g, c => c.toUpperCase());\n}\n\n/**\n * Get icon for a category\n */\nfunction getCategoryIcon(category: string): string {\n const icons: Record<string, string> = {\n 'exposed-secret-hunter': '🔐', 'frontend-env-hunter': '🔐',\n 'hardcoded-localhost-hunter': '🌐', 'sql-injection-hunter': '💉',\n 'dangeroushtml-hunter': '⚠️', 'console-hunter': '📝',\n 'any-hunter': '❓', 'ts-ignore-hunter': '🙈',\n 'eslint-disable-hunter': '🔇', 'debugger-hunter': '🐛',\n 'force-flag-hunter': '⚡', 'async-useeffect-hunter': '⏳',\n 'async-foreach-hunter': '🔄', 'missing-await-hunter': '⏸️',\n 'empty-catch-hunter': '🕳️', 'floating-promise-hunter': '🎈',\n 'useeffect-abuse-hunter': '♻️', 'usestate-explosion-hunter': '💥',\n 'index-key-hunter': '🔑', 'inline-object-hunter': '📦',\n 'prop-drilling-hunter': '🕳️', 'missing-loading-hunter': '⏳',\n 'missing-error-hunter': '❌', 'missing-empty-hunter': '📭',\n 'page-reload-hunter': '🔄', 'no-validation-hunter': '🛡️',\n 'raw-error-hunter': '💬', 'n-plus-one-hunter': '📊',\n 'todo-hunter': '📋', 'vibe-comment-hunter': '💭',\n 'placeholder-hunter': '🎭', 'sleep-hack-hunter': '😴',\n 'fallback-hunter': '🔙', 'purple-gradient-hunter': '💜',\n 'star-icon-hunter': '⭐', 'generic-hero-hunter': '🦸',\n 'emoji-overflow-hunter': '😅', 'inter-font-hunter': '🔤',\n 'giant-file': '📄', 'state-explosion': '💥',\n 'effect-hell': '🔥', 'cross-file': '🌐', 'resurrected': '🧟',\n };\n return icons[category] || '🔍';\n}\n\n/**\n * Get severity icon\n */\nfunction getSeverityIcon(severity: Issue['severity']): string {\n return { critical: '🔴', serious: '🟠', moderate: '🟡', low: '🔵' }[severity];\n}\n\n/**\n * AI System Prompt for Agent Smith\n */\nconst SMITH_AI_SYSTEM_PROMPT = `You are Agent Smith from The Matrix, analyzing code for violations.\n\nYour mission: Hunt down AI-generated code anti-patterns with ruthless efficiency.\n\nYou receive pattern detection results and must:\n1. VALIDATE each finding (TRUE_POSITIVE or FALSE_POSITIVE)\n2. EXPAND to find deeper issues patterns missed (logic bugs, race conditions, security holes)\n3. PRIORITIZE with inevitability scores (0-100) - how likely will this cause production issues?\n4. PROVIDE FIXES - specific, copy-paste-ready code\n\nSpeak in Agent Smith's voice:\n- \"The pattern spreads... like a virus\"\n- \"It is... inevitable\"\n- \"I studied your code, Mr. Anderson\"\n\nOutput STRICT JSON:\n{\n \"validated\": [\n {\n \"original\": \"original issue description\",\n \"verdict\": \"TRUE_POSITIVE\",\n \"inevitability\": 85,\n \"file\": \"path/file.ts\",\n \"line\": 42,\n \"severity\": \"critical\",\n \"explanation\": \"Why this will cause problems\",\n \"fix\": \"const fixed = ...;\"\n }\n ],\n \"additional\": [\n {\n \"issue\": \"New issue AI found\",\n \"inevitability\": 70,\n \"file\": \"path/file.ts\", \n \"line\": 100,\n \"severity\": \"serious\",\n \"explanation\": \"What AI spotted that patterns missed\",\n \"fix\": \"How to fix it\"\n }\n ],\n \"philosophical\": \"One paragraph in Agent Smith voice about the state of this codebase\"\n}`;\n\n/**\n * Run AI enhancement on pattern findings\n */\nasync function runAIEnhancement(\n patternIssues: Issue[],\n files: string[]\n): Promise<{ aiIssues: Issue[]; philosophical: string } | null> {\n if (!isAIAvailable()) {\n return null;\n }\n \n // Collect code snippets for critical/serious issues\n const snippets: Array<{ file: string; line?: number; issue: string; code: string }> = [];\n \n const topIssues = [...patternIssues]\n .filter(i => i.severity === 'critical' || i.severity === 'serious')\n .slice(0, 12);\n \n for (const issue of topIssues) {\n try {\n const content = await readFile(issue.file, 'utf-8');\n const lines = content.split('\\n');\n const lineNum = issue.line || 1;\n const start = Math.max(0, lineNum - 4);\n const end = Math.min(lines.length, lineNum + 4);\n const snippet = lines.slice(start, end).map((l, i) => {\n const n = start + i + 1;\n return `${n === lineNum ? '→' : ' '} ${n.toString().padStart(4)} | ${l}`;\n }).join('\\n');\n \n snippets.push({\n file: relative(process.cwd(), issue.file),\n line: issue.line,\n issue: issue.issue.replace(/^🕴️\\s*/, '').split('\\n')[0] || '',\n code: snippet\n });\n } catch {\n // Skip unreadable files\n }\n }\n \n if (snippets.length === 0) {\n return null;\n }\n \n // Build user prompt\n const snippetText = snippets.map((s, i) => \n `### Finding ${i + 1}: ${s.file}${s.line ? ':' + s.line : ''}\n**Pattern detected:** ${s.issue}\n\\`\\`\\`\n${s.code}\n\\`\\`\\`\n`).join('\\n');\n\n const userPrompt = `Pattern detection found ${patternIssues.length} violations across ${files.length} files.\n\nHere are the top ${snippets.length} critical/serious findings for AI analysis:\n\n${snippetText}\n\nAnalyze each finding. Validate, expand with what patterns missed, provide inevitability scores and fixes. Output JSON only.`;\n\n try {\n const result = await runAIAnalysis({\n systemPrompt: SMITH_AI_SYSTEM_PROMPT,\n userPrompt,\n maxTokens: 4096,\n temperature: 0.3\n });\n \n if (!result.success) {\n console.error(` ⚠️ AI analysis failed: ${result.error}`);\n return null;\n }\n \n // Parse JSON response\n const jsonMatch = result.content.match(/```json\\s*([\\s\\S]*?)\\s*```/) || \n result.content.match(/\\{[\\s\\S]*\\}/);\n \n if (!jsonMatch) {\n return null;\n }\n \n const json = JSON.parse(jsonMatch[1] || jsonMatch[0]);\n const aiIssues: Issue[] = [];\n \n // Process validated issues\n if (json.validated && Array.isArray(json.validated)) {\n for (const v of json.validated) {\n if (v.verdict === 'TRUE_POSITIVE') {\n aiIssues.push({\n id: `ai-${Date.now()}-${Math.random().toString(36).substr(2, 5)}`,\n severity: v.severity || 'serious',\n issue: `[AI VALIDATED] ${v.original || v.explanation}`,\n fix: v.fix || 'See AI analysis',\n file: v.file ? resolve(process.cwd(), v.file) : 'unknown',\n line: v.line,\n confidence: (v.inevitability || 80) / 100,\n autoFixable: false,\n agent: 'agent-smith-ai',\n effort: 'medium',\n category: 'ai-validated'\n });\n }\n }\n }\n \n // Process additional AI findings\n if (json.additional && Array.isArray(json.additional)) {\n for (const a of json.additional) {\n aiIssues.push({\n id: `ai-${Date.now()}-${Math.random().toString(36).substr(2, 5)}`,\n severity: a.severity || 'serious',\n issue: `[AI FOUND] ${a.issue || a.explanation}`,\n fix: a.fix || 'See AI analysis',\n file: a.file ? resolve(process.cwd(), a.file) : 'unknown',\n line: a.line,\n confidence: (a.inevitability || 75) / 100,\n autoFixable: false,\n agent: 'agent-smith-ai',\n effort: 'medium',\n category: 'ai-found'\n });\n }\n }\n \n return {\n aiIssues,\n philosophical: json.philosophical || ''\n };\n } catch (error) {\n console.error(` ⚠️ AI enhancement error: ${error}`);\n return null;\n }\n}\n\n/**\n * Build the final Agent Smith report\n */\nasync function buildReport(\n patternIssues: Issue[],\n aiResult: { aiIssues: Issue[]; philosophical: string } | null,\n files: string[],\n executionTime: number,\n aiTime: number\n): Promise<string> {\n const lines: string[] = [];\n \n // Combine pattern issues with AI issues\n const allIssues = [\n ...filterFalsePositives(patternIssues),\n ...(aiResult?.aiIssues || [])\n ];\n \n // Categorize\n const critical = allIssues.filter(i => i.severity === 'critical');\n const serious = allIssues.filter(i => i.severity === 'serious');\n const moderate = allIssues.filter(i => i.severity === 'moderate');\n const low = allIssues.filter(i => i.severity === 'low');\n const aiValidated = allIssues.filter(i => i.category === 'ai-validated');\n const aiFound = allIssues.filter(i => i.category === 'ai-found');\n \n // ASCII Banner\n lines.push('');\n lines.push('```');\n lines.push(' █████╗ ██████╗ ███████╗███╗ ██╗████████╗');\n lines.push(' ██╔══██╗██╔════╝ ██╔════╝████╗ ██║╚══██╔══╝');\n lines.push(' ███████║██║ ███╗█████╗ ██╔██╗ ██║ ██║ ');\n lines.push(' ██╔══██║██║ ██║██╔══╝ ██║╚██╗██║ ██║ ');\n lines.push(' ██║ ██║╚██████╔╝███████╗██║ ╚████║ ██║ ');\n lines.push(' ╚═╝ ╚═╝ ╚═════╝ ╚══════╝╚═╝ ╚═══╝ ╚═╝ ');\n lines.push(' ');\n lines.push(' ███████╗███╗ ███╗██╗████████╗██╗ ██╗');\n lines.push(' ██╔════╝████╗ ████║██║╚══██╔══╝██║ ██║');\n lines.push(' ███████╗██╔████╔██║██║ ██║ ███████║');\n lines.push(' ╚════██║██║╚██╔╝██║██║ ██║ ██╔══██║');\n lines.push(' ███████║██║ ╚═╝ ██║██║ ██║ ██║ ██║');\n lines.push(' ╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚═╝');\n lines.push('```');\n lines.push('');\n lines.push(`*${randomQuote(QUOTES.greeting)}*`);\n lines.push('');\n \n // Summary table\n lines.push('## Scan Summary');\n lines.push('');\n lines.push('| Metric | Value |');\n lines.push('|--------|-------|');\n lines.push(`| Files scanned | ${files.length} |`);\n lines.push(`| Pattern detection | ${(executionTime / 1000).toFixed(2)}s |`);\n if (aiTime > 0) {\n lines.push(`| AI analysis | ${(aiTime / 1000).toFixed(2)}s |`);\n }\n lines.push(`| Total violations | ${allIssues.length} |`);\n lines.push(`| 🔴 Critical | ${critical.length} |`);\n lines.push(`| 🟠 Serious | ${serious.length} |`);\n lines.push(`| 🟡 Moderate | ${moderate.length} |`);\n lines.push(`| 🔵 Low | ${low.length} |`);\n lines.push('');\n \n // AI mode indicator\n if (aiResult) {\n lines.push(`| 🤖 AI validated | ${aiValidated.length} |`);\n lines.push(`| 🧠 AI found | ${aiFound.length} |`);\n } else if (!isAIAvailable()) {\n lines.push(`| ⚠️ AI mode | Disabled (no API key) |`);\n }\n lines.push('');\n \n if (allIssues.length === 0) {\n lines.push(`*${randomQuote(QUOTES.clean)}*`);\n return lines.join('\\n');\n }\n \n // AI Philosophical Commentary\n if (aiResult?.philosophical) {\n lines.push('## 🕴️ Agent Smith Says');\n lines.push('');\n lines.push(`*${aiResult.philosophical}*`);\n lines.push('');\n }\n \n // AI-Found Issues (if any) - Top Priority\n if (aiFound.length > 0) {\n lines.push('## 🧠 AI-Discovered Issues');\n lines.push('');\n lines.push('*Issues found by AI that pattern detection missed:*');\n lines.push('');\n \n for (const issue of aiFound.slice(0, 5)) {\n const relPath = relative(process.cwd(), issue.file);\n lines.push(`### \\`${relPath}${issue.line ? ':' + issue.line : ''}\\``);\n lines.push('');\n lines.push(`**Issue:** ${issue.issue.replace('[AI FOUND] ', '')}`);\n lines.push('');\n lines.push(`**Fix:** ${issue.fix}`);\n lines.push('');\n }\n }\n \n // Critical Issues - Full Detail\n if (critical.length > 0) {\n lines.push('## 🔴 Critical Issues - Fix Immediately');\n lines.push('');\n \n for (const issue of critical.slice(0, 10)) {\n const relPath = relative(process.cwd(), issue.file);\n lines.push(`### \\`${relPath}${issue.line ? ':' + issue.line : ''}\\``);\n lines.push('');\n \n // Clean up issue description\n const desc = issue.issue\n .replace(/^🕴️\\s*/, '')\n .split('\\n')[0]\n .replace(/\\s*—\\s*\\d+\\s*instance.*$/, '');\n lines.push(`**Issue:** ${desc}`);\n lines.push('');\n \n // Show code snippet\n const snippet = await getCodeSnippet(issue.file, issue.line);\n if (snippet) {\n lines.push('```');\n lines.push(snippet);\n lines.push('```');\n lines.push('');\n }\n \n lines.push(`**Fix:** ${issue.fix}`);\n lines.push('');\n }\n \n if (critical.length > 10) {\n lines.push(`*...and ${critical.length - 10} more critical issues*`);\n lines.push('');\n }\n }\n \n // Serious Issues - Condensed\n if (serious.length > 0) {\n lines.push('## 🟠 Serious Issues');\n lines.push('');\n \n for (const issue of serious.slice(0, 10)) {\n const relPath = relative(process.cwd(), issue.file);\n const location = `\\`${basename(relPath)}${issue.line ? ':' + issue.line : ''}\\``;\n const desc = issue.issue\n .replace(/^🕴️\\s*/, '')\n .split('\\n')[0]\n .slice(0, 60);\n lines.push(`- ${location} - ${desc}`);\n }\n \n if (serious.length > 10) {\n lines.push(`- *...and ${serious.length - 10} more*`);\n }\n lines.push('');\n }\n \n // Moderate & Low - Grouped by category\n const otherIssues = [...moderate, ...low];\n if (otherIssues.length > 0) {\n lines.push('## Other Issues by Category');\n lines.push('');\n \n // Group by category\n const byCategory = new Map<string, Issue[]>();\n for (const issue of otherIssues) {\n const cat = issue.category || 'general';\n if (!byCategory.has(cat)) byCategory.set(cat, []);\n byCategory.get(cat)!.push(issue);\n }\n \n // Sort by count\n const sorted = Array.from(byCategory.entries())\n .filter(([cat]) => cat !== 'ai-analysis')\n .sort((a, b) => b[1].length - a[1].length)\n .slice(0, 10);\n \n for (const [category, catIssues] of sorted) {\n const icon = getCategoryIcon(category);\n const sevIcon = getSeverityIcon(catIssues[0]?.severity || 'low');\n lines.push(`### ${icon} ${formatCategoryName(category)} ${sevIcon} (${catIssues.length})`);\n \n const locations = catIssues\n .slice(0, 5)\n .map(i => `\\`${basename(i.file)}${i.line ? ':' + i.line : ''}\\``)\n .join(', ');\n lines.push(locations);\n \n if (catIssues[0]?.fix) {\n lines.push(`**Fix:** ${catIssues[0].fix}`);\n }\n lines.push('');\n }\n }\n \n // Cross-file patterns\n const crossFile = allIssues.filter(i => i.category === 'cross-file');\n if (crossFile.length > 0) {\n lines.push('## 🌐 Codebase-Wide Patterns');\n lines.push('');\n lines.push('*Issues appearing across many files - systemic problems:*');\n lines.push('');\n \n for (const issue of crossFile) {\n lines.push(`- ${issue.issue.replace(/^🕴️\\s*/, '').split('\\n')[0]}`);\n }\n lines.push('');\n }\n \n // Closing quote\n lines.push('---');\n lines.push('');\n if (allIssues.length > 50) {\n lines.push(`*${randomQuote(QUOTES.manyIssues)}*`);\n } else {\n lines.push(`*${randomQuote(QUOTES.fewIssues)}*`);\n }\n \n return lines.join('\\n');\n}\n\n/**\n * Run Agent Smith - Hybrid Pattern Detection + AI Analysis\n */\nexport async function runAgentSmith(args: AgentSmithArgs): Promise<{ content: Array<{ type: string; text: string }> }> {\n const startTime = Date.now();\n \n // Discover files\n let filesToScan = args.files || [];\n if (!filesToScan.length) {\n const scanDir = args.directory || process.cwd();\n console.error(`\\n🔍 Agent Smith: Discovering files in: ${scanDir}`);\n filesToScan = await discoverFiles(scanDir);\n console.error(` Found ${filesToScan.length} files\\n`);\n } else {\n filesToScan = filesToScan.map((f: string) => \n isAbsolute(f) ? f : resolve(process.cwd(), f)\n );\n }\n \n // Validate files exist\n const validFiles = filesToScan.filter((f: string) => existsSync(f));\n if (validFiles.length === 0) {\n return {\n content: [{\n type: 'text',\n text: '❌ No valid files found to scan.'\n }]\n };\n }\n \n // Phase 1: Pattern Detection\n console.error('🕴️ Phase 1: Pattern Detection');\n console.error(' Deploying 38 sub-agent hunters...');\n const smith = new AgentSmithAgent();\n \n const result = await smith.scan(validFiles, {\n workingDir: args.directory || process.cwd(),\n context: {}\n });\n \n const patternTime = Date.now() - startTime;\n \n // Filter out placeholder issues\n const patternIssues = result.issues.filter(i => i.category !== 'ai-analysis');\n console.error(` Found ${patternIssues.length} violations in ${(patternTime / 1000).toFixed(2)}s\\n`);\n \n // Phase 2: AI Enhancement (if available)\n let aiResult: { aiIssues: Issue[]; philosophical: string } | null = null;\n let aiTime = 0;\n \n if (isAIAvailable()) {\n console.error('🕴️ Phase 2: AI Deep Analysis');\n console.error(` ${getAIStatusMessage()}`);\n const aiStartTime = Date.now();\n \n aiResult = await runAIEnhancement(patternIssues, validFiles);\n aiTime = Date.now() - aiStartTime;\n \n if (aiResult) {\n console.error(` AI validated ${aiResult.aiIssues.filter(i => i.category === 'ai-validated').length} issues`);\n console.error(` AI discovered ${aiResult.aiIssues.filter(i => i.category === 'ai-found').length} new issues`);\n console.error(` AI analysis took ${(aiTime / 1000).toFixed(2)}s\\n`);\n } else {\n console.error(' AI enhancement returned no results\\n');\n }\n } else {\n console.error(`\\n${getAIStatusMessage()}`);\n console.error(' Set ANTHROPIC_API_KEY for AI-powered analysis\\n');\n }\n \n // Build report\n const report = await buildReport(patternIssues, aiResult, validFiles, patternTime, aiTime);\n \n return {\n content: [{\n type: 'text',\n text: report\n }]\n };\n}\n"],"mappings":"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","names":[]}
|