react-anti-pattern-sniffer 0.1.0
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/.snifferrc.json +29 -0
- package/LICENSE +21 -0
- package/README.md +289 -0
- package/bin/react-sniff.js +3 -0
- package/dist/src/cli/arg-parser.d.ts +10 -0
- package/dist/src/cli/arg-parser.d.ts.map +1 -0
- package/dist/src/cli/arg-parser.js +81 -0
- package/dist/src/cli/arg-parser.js.map +1 -0
- package/dist/src/cli/config-loader.d.ts +11 -0
- package/dist/src/cli/config-loader.d.ts.map +1 -0
- package/dist/src/cli/config-loader.js +140 -0
- package/dist/src/cli/config-loader.js.map +1 -0
- package/dist/src/cli/help.d.ts +3 -0
- package/dist/src/cli/help.d.ts.map +1 -0
- package/dist/src/cli/help.js +59 -0
- package/dist/src/cli/help.js.map +1 -0
- package/dist/src/cli/index.d.ts +2 -0
- package/dist/src/cli/index.d.ts.map +1 -0
- package/dist/src/cli/index.js +107 -0
- package/dist/src/cli/index.js.map +1 -0
- package/dist/src/core/file-discoverer.d.ts +8 -0
- package/dist/src/core/file-discoverer.d.ts.map +1 -0
- package/dist/src/core/file-discoverer.js +151 -0
- package/dist/src/core/file-discoverer.js.map +1 -0
- package/dist/src/core/orchestrator.d.ts +13 -0
- package/dist/src/core/orchestrator.d.ts.map +1 -0
- package/dist/src/core/orchestrator.js +176 -0
- package/dist/src/core/orchestrator.js.map +1 -0
- package/dist/src/core/sniffer-ignore.d.ts +25 -0
- package/dist/src/core/sniffer-ignore.d.ts.map +1 -0
- package/dist/src/core/sniffer-ignore.js +91 -0
- package/dist/src/core/sniffer-ignore.js.map +1 -0
- package/dist/src/core/sniffer-registry.d.ts +8 -0
- package/dist/src/core/sniffer-registry.d.ts.map +1 -0
- package/dist/src/core/sniffer-registry.js +64 -0
- package/dist/src/core/sniffer-registry.js.map +1 -0
- package/dist/src/core/worker-pool.d.ts +27 -0
- package/dist/src/core/worker-pool.d.ts.map +1 -0
- package/dist/src/core/worker-pool.js +176 -0
- package/dist/src/core/worker-pool.js.map +1 -0
- package/dist/src/core/worker-runner.d.ts +2 -0
- package/dist/src/core/worker-runner.d.ts.map +1 -0
- package/dist/src/core/worker-runner.js +52 -0
- package/dist/src/core/worker-runner.js.map +1 -0
- package/dist/src/output/formatter.d.ts +3 -0
- package/dist/src/output/formatter.d.ts.map +1 -0
- package/dist/src/output/formatter.js +13 -0
- package/dist/src/output/formatter.js.map +1 -0
- package/dist/src/output/json-renderer.d.ts +3 -0
- package/dist/src/output/json-renderer.d.ts.map +1 -0
- package/dist/src/output/json-renderer.js +49 -0
- package/dist/src/output/json-renderer.js.map +1 -0
- package/dist/src/output/markdown-renderer.d.ts +3 -0
- package/dist/src/output/markdown-renderer.d.ts.map +1 -0
- package/dist/src/output/markdown-renderer.js +70 -0
- package/dist/src/output/markdown-renderer.js.map +1 -0
- package/dist/src/plugins/plugin-loader.d.ts +7 -0
- package/dist/src/plugins/plugin-loader.d.ts.map +1 -0
- package/dist/src/plugins/plugin-loader.js +47 -0
- package/dist/src/plugins/plugin-loader.js.map +1 -0
- package/dist/src/plugins/plugin-sandbox.d.ts +3 -0
- package/dist/src/plugins/plugin-sandbox.d.ts.map +1 -0
- package/dist/src/plugins/plugin-sandbox.js +105 -0
- package/dist/src/plugins/plugin-sandbox.js.map +1 -0
- package/dist/src/plugins/plugin-validator.d.ts +14 -0
- package/dist/src/plugins/plugin-validator.d.ts.map +1 -0
- package/dist/src/plugins/plugin-validator.js +92 -0
- package/dist/src/plugins/plugin-validator.js.map +1 -0
- package/dist/src/sniffers/god-hook-sniffer.d.ts +12 -0
- package/dist/src/sniffers/god-hook-sniffer.d.ts.map +1 -0
- package/dist/src/sniffers/god-hook-sniffer.js +109 -0
- package/dist/src/sniffers/god-hook-sniffer.js.map +1 -0
- package/dist/src/sniffers/prop-drilling-sniffer.d.ts +5 -0
- package/dist/src/sniffers/prop-drilling-sniffer.d.ts.map +1 -0
- package/dist/src/sniffers/prop-drilling-sniffer.js +145 -0
- package/dist/src/sniffers/prop-drilling-sniffer.js.map +1 -0
- package/dist/src/sniffers/prop-explosion-sniffer.d.ts +4 -0
- package/dist/src/sniffers/prop-explosion-sniffer.d.ts.map +1 -0
- package/dist/src/sniffers/prop-explosion-sniffer.js +134 -0
- package/dist/src/sniffers/prop-explosion-sniffer.js.map +1 -0
- package/dist/src/sniffers/sniffer-interface.d.ts +88 -0
- package/dist/src/sniffers/sniffer-interface.d.ts.map +1 -0
- package/dist/src/sniffers/sniffer-interface.js +18 -0
- package/dist/src/sniffers/sniffer-interface.js.map +1 -0
- package/dist/src/tui/interactive-viewer.d.ts +7 -0
- package/dist/src/tui/interactive-viewer.d.ts.map +1 -0
- package/dist/src/tui/interactive-viewer.js +453 -0
- package/dist/src/tui/interactive-viewer.js.map +1 -0
- package/dist/src/utils/logger.d.ts +11 -0
- package/dist/src/utils/logger.d.ts.map +1 -0
- package/dist/src/utils/logger.js +90 -0
- package/dist/src/utils/logger.js.map +1 -0
- package/dist/src/utils/regex-helpers.d.ts +53 -0
- package/dist/src/utils/regex-helpers.d.ts.map +1 -0
- package/dist/src/utils/regex-helpers.js +275 -0
- package/dist/src/utils/regex-helpers.js.map +1 -0
- package/package.json +40 -0
|
@@ -0,0 +1,453 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.interactiveViewer = interactiveViewer;
|
|
4
|
+
const node_fs_1 = require("node:fs");
|
|
5
|
+
const node_path_1 = require("node:path");
|
|
6
|
+
// ANSI codes
|
|
7
|
+
const RESET = '\x1b[0m';
|
|
8
|
+
const BOLD = '\x1b[1m';
|
|
9
|
+
const DIM = '\x1b[2m';
|
|
10
|
+
const UNDERLINE = '\x1b[4m';
|
|
11
|
+
const CYAN = '\x1b[36m';
|
|
12
|
+
const YELLOW = '\x1b[33m';
|
|
13
|
+
const RED = '\x1b[31m';
|
|
14
|
+
const GREEN = '\x1b[32m';
|
|
15
|
+
const MAGENTA = '\x1b[35m';
|
|
16
|
+
const WHITE = '\x1b[37m';
|
|
17
|
+
const BG_CYAN = '\x1b[46m';
|
|
18
|
+
const BG_MAGENTA = '\x1b[45m';
|
|
19
|
+
const CLEAR_SCREEN = '\x1b[2J\x1b[H';
|
|
20
|
+
const HIDE_CURSOR = '\x1b[?25l';
|
|
21
|
+
const SHOW_CURSOR = '\x1b[?25h';
|
|
22
|
+
function formatSmellName(name) {
|
|
23
|
+
return name.split('-').map(w => w.charAt(0).toUpperCase() + w.slice(1)).join(' ');
|
|
24
|
+
}
|
|
25
|
+
function severityIcon(severity) {
|
|
26
|
+
switch (severity) {
|
|
27
|
+
case 'error': return `${RED}●${RESET}`;
|
|
28
|
+
case 'warning': return `${YELLOW}●${RESET}`;
|
|
29
|
+
case 'info': return `${CYAN}●${RESET}`;
|
|
30
|
+
default: return `${DIM}●${RESET}`;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function groupDetections(results, batchSize) {
|
|
34
|
+
// Collect all detections grouped by sniffer name
|
|
35
|
+
const bySmell = new Map();
|
|
36
|
+
for (const [, snifferResults] of results) {
|
|
37
|
+
for (const result of snifferResults) {
|
|
38
|
+
for (const detection of result.detections) {
|
|
39
|
+
const existing = bySmell.get(detection.snifferName) || [];
|
|
40
|
+
existing.push(detection);
|
|
41
|
+
bySmell.set(detection.snifferName, existing);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
const groups = [];
|
|
46
|
+
let remaining = batchSize;
|
|
47
|
+
for (const [name, detections] of bySmell) {
|
|
48
|
+
if (remaining <= 0)
|
|
49
|
+
break;
|
|
50
|
+
const batch = detections.slice(0, remaining);
|
|
51
|
+
remaining -= batch.length;
|
|
52
|
+
groups.push({
|
|
53
|
+
name,
|
|
54
|
+
label: formatSmellName(name),
|
|
55
|
+
detections: batch,
|
|
56
|
+
collapsed: false,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
return groups;
|
|
60
|
+
}
|
|
61
|
+
function getVisibleItems(state) {
|
|
62
|
+
const items = [];
|
|
63
|
+
for (let gi = 0; gi < state.groups.length; gi++) {
|
|
64
|
+
const group = state.groups[gi];
|
|
65
|
+
if (state.filterSmell && group.name !== state.filterSmell)
|
|
66
|
+
continue;
|
|
67
|
+
items.push({ type: 'group', groupIdx: gi });
|
|
68
|
+
if (!group.collapsed) {
|
|
69
|
+
for (let ii = 0; ii < group.detections.length; ii++) {
|
|
70
|
+
items.push({ type: 'item', groupIdx: gi, itemIdx: ii });
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return items;
|
|
75
|
+
}
|
|
76
|
+
function render(state) {
|
|
77
|
+
const lines = [];
|
|
78
|
+
const w = process.stdout.columns || 80;
|
|
79
|
+
const hr = DIM + '─'.repeat(w) + RESET;
|
|
80
|
+
// Header
|
|
81
|
+
const shownIssues = state.groups.reduce((s, g) => s + g.detections.length, 0);
|
|
82
|
+
lines.push('');
|
|
83
|
+
lines.push(` ${BOLD}${MAGENTA}React Anti-Pattern Sniffer${RESET} ${DIM}│${RESET} ${BOLD}${shownIssues}${RESET}${DIM}/${state.totalIssues} issues shown • ${state.fileCount} files scanned${RESET}`);
|
|
84
|
+
if (state.batchSize < state.totalIssues) {
|
|
85
|
+
lines.push(` ${DIM}Batch size: ${state.batchSize} (use -b to change)${RESET}`);
|
|
86
|
+
}
|
|
87
|
+
lines.push(hr);
|
|
88
|
+
// Flash message
|
|
89
|
+
if (state.copied) {
|
|
90
|
+
lines.push(` ${GREEN}${BOLD}✔ ${state.copied}${RESET}`);
|
|
91
|
+
lines.push('');
|
|
92
|
+
}
|
|
93
|
+
// Groups and items
|
|
94
|
+
const visible = getVisibleItems(state);
|
|
95
|
+
for (let vi = 0; vi < visible.length; vi++) {
|
|
96
|
+
const entry = visible[vi];
|
|
97
|
+
const isCurrent = vi === state.cursor;
|
|
98
|
+
const pointer = isCurrent ? `${CYAN}${BOLD}▸${RESET}` : ' ';
|
|
99
|
+
if (entry.type === 'group') {
|
|
100
|
+
const group = state.groups[entry.groupIdx];
|
|
101
|
+
const arrow = group.collapsed ? '▶' : '▼';
|
|
102
|
+
const count = group.detections.length;
|
|
103
|
+
const highlight = isCurrent ? `${BOLD}${WHITE}` : '';
|
|
104
|
+
lines.push(` ${pointer} ${highlight}${arrow} ${group.label}${RESET} ${DIM}(${count} issue${count !== 1 ? 's' : ''})${RESET}`);
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
const group = state.groups[entry.groupIdx];
|
|
108
|
+
const det = group.detections[entry.itemIdx];
|
|
109
|
+
const relPath = (0, node_path_1.relative)(state.targetDir, det.filePath);
|
|
110
|
+
const highlight = isCurrent ? `${BOLD}` : `${DIM}`;
|
|
111
|
+
const bg = isCurrent ? `${UNDERLINE}` : '';
|
|
112
|
+
const icon = severityIcon(det.severity);
|
|
113
|
+
// Extract component name from details if available
|
|
114
|
+
const compName = det.details?.componentName
|
|
115
|
+
|| det.details?.hookName
|
|
116
|
+
|| '';
|
|
117
|
+
const nameStr = compName ? `${CYAN}${compName}${RESET} ` : '';
|
|
118
|
+
lines.push(` ${pointer} ${icon} ${bg}${highlight}${relPath}${RESET}${DIM}:${det.line}${RESET} ${nameStr}${DIM}— ${truncate(det.message, w - relPath.length - 20)}${RESET}`);
|
|
119
|
+
// Show details for selected item
|
|
120
|
+
if (isCurrent && state.showDetails) {
|
|
121
|
+
lines.push('');
|
|
122
|
+
lines.push(` ${BOLD}Message:${RESET} ${det.message}`);
|
|
123
|
+
lines.push(` ${BOLD}Suggestion:${RESET}`);
|
|
124
|
+
for (const suggLine of det.suggestion.split('\n')) {
|
|
125
|
+
lines.push(` ${DIM}${suggLine}${RESET}`);
|
|
126
|
+
}
|
|
127
|
+
if (det.details) {
|
|
128
|
+
lines.push(` ${BOLD}Details:${RESET} ${DIM}${JSON.stringify(det.details, null, 0)}${RESET}`);
|
|
129
|
+
}
|
|
130
|
+
lines.push('');
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
if (visible.length === 0) {
|
|
135
|
+
lines.push(` ${DIM}No issues to display${state.filterSmell ? ' (filter active)' : ''}${RESET}`);
|
|
136
|
+
}
|
|
137
|
+
lines.push('');
|
|
138
|
+
lines.push(hr);
|
|
139
|
+
// Action bar
|
|
140
|
+
const filterLabel = state.filterSmell ? `${YELLOW}[f]ilter: ${state.filterSmell}${RESET}` : `${DIM}[f]ilter${RESET}`;
|
|
141
|
+
const detailLabel = state.showDetails ? `${CYAN}[d]etails: on${RESET}` : `${DIM}[d]etails${RESET}`;
|
|
142
|
+
lines.push(` ${GREEN}[c]${RESET}opy as prompt ${GREEN}[a]${RESET}ll as md ${RED}[x]${RESET} ignore ${filterLabel} ${detailLabel} ${DIM}[q]uit${RESET}`);
|
|
143
|
+
lines.push(` ${DIM}↑/↓ navigate ←/→ or enter collapse/expand tab next group${RESET}`);
|
|
144
|
+
return lines.join('\n');
|
|
145
|
+
}
|
|
146
|
+
function truncate(str, max) {
|
|
147
|
+
if (max < 10)
|
|
148
|
+
max = 10;
|
|
149
|
+
if (str.length <= max)
|
|
150
|
+
return str;
|
|
151
|
+
return str.substring(0, max - 1) + '…';
|
|
152
|
+
}
|
|
153
|
+
function detectionToPromptMarkdown(det, targetDir) {
|
|
154
|
+
const relPath = (0, node_path_1.relative)(targetDir, det.filePath);
|
|
155
|
+
const lines = [];
|
|
156
|
+
lines.push(`## ${formatSmellName(det.snifferName)} — \`${relPath}:${det.line}\``);
|
|
157
|
+
lines.push('');
|
|
158
|
+
lines.push(det.message);
|
|
159
|
+
lines.push('');
|
|
160
|
+
lines.push('### Suggestion');
|
|
161
|
+
lines.push(det.suggestion);
|
|
162
|
+
if (det.details) {
|
|
163
|
+
lines.push('');
|
|
164
|
+
lines.push('### Details');
|
|
165
|
+
lines.push('```json');
|
|
166
|
+
lines.push(JSON.stringify(det.details, null, 2));
|
|
167
|
+
lines.push('```');
|
|
168
|
+
}
|
|
169
|
+
return lines.join('\n');
|
|
170
|
+
}
|
|
171
|
+
function allToMarkdown(state) {
|
|
172
|
+
const lines = [];
|
|
173
|
+
lines.push('# React Anti-Pattern Report');
|
|
174
|
+
lines.push('');
|
|
175
|
+
for (const group of state.groups) {
|
|
176
|
+
if (state.filterSmell && group.name !== state.filterSmell)
|
|
177
|
+
continue;
|
|
178
|
+
lines.push(`## ${group.label} (${group.detections.length} issues)`);
|
|
179
|
+
lines.push('');
|
|
180
|
+
for (const det of group.detections) {
|
|
181
|
+
const relPath = (0, node_path_1.relative)(state.targetDir, det.filePath);
|
|
182
|
+
lines.push(`### \`${relPath}:${det.line}\``);
|
|
183
|
+
lines.push(det.message);
|
|
184
|
+
lines.push('');
|
|
185
|
+
lines.push('**Suggestion:**');
|
|
186
|
+
lines.push(det.suggestion);
|
|
187
|
+
lines.push('');
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return lines.join('\n');
|
|
191
|
+
}
|
|
192
|
+
function copyToClipboard(text) {
|
|
193
|
+
try {
|
|
194
|
+
const { execSync } = require('node:child_process');
|
|
195
|
+
// Try different clipboard tools
|
|
196
|
+
const cmds = ['xclip -selection clipboard', 'xsel --clipboard --input', 'pbcopy', 'clip.exe'];
|
|
197
|
+
for (const cmd of cmds) {
|
|
198
|
+
try {
|
|
199
|
+
execSync(cmd, { input: text, stdio: ['pipe', 'pipe', 'pipe'] });
|
|
200
|
+
return true;
|
|
201
|
+
}
|
|
202
|
+
catch {
|
|
203
|
+
continue;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
catch {
|
|
208
|
+
// Clipboard not available
|
|
209
|
+
}
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
212
|
+
function addToSnifferIgnore(det, targetDir) {
|
|
213
|
+
const ignorePath = (0, node_path_1.join)(targetDir, '.snifferignore');
|
|
214
|
+
const relPath = (0, node_path_1.relative)(targetDir, det.filePath);
|
|
215
|
+
const compName = det.details?.componentName
|
|
216
|
+
|| det.details?.hookName
|
|
217
|
+
|| '';
|
|
218
|
+
const entry = compName
|
|
219
|
+
? `${relPath}:${compName} # ${det.snifferName}`
|
|
220
|
+
: `${relPath} # ${det.snifferName}`;
|
|
221
|
+
// Check if already ignored
|
|
222
|
+
if ((0, node_fs_1.existsSync)(ignorePath)) {
|
|
223
|
+
const existing = (0, node_fs_1.readFileSync)(ignorePath, 'utf8');
|
|
224
|
+
if (existing.includes(entry.split(' #')[0]))
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
(0, node_fs_1.appendFileSync)(ignorePath, entry + '\n', 'utf8');
|
|
228
|
+
}
|
|
229
|
+
function flash(state, msg) {
|
|
230
|
+
state.copied = msg;
|
|
231
|
+
if (state.flashTimeout)
|
|
232
|
+
clearTimeout(state.flashTimeout);
|
|
233
|
+
state.flashTimeout = setTimeout(() => {
|
|
234
|
+
state.copied = null;
|
|
235
|
+
process.stdout.write(CLEAR_SCREEN + render(state));
|
|
236
|
+
}, 2000);
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Launch the interactive TUI viewer.
|
|
240
|
+
* Returns a promise that resolves when the user quits.
|
|
241
|
+
*/
|
|
242
|
+
async function interactiveViewer(results, totalIssues, fileCount, targetDir, batchSize) {
|
|
243
|
+
const groups = groupDetections(results, batchSize);
|
|
244
|
+
if (groups.length === 0) {
|
|
245
|
+
console.log(`\n ${GREEN}${BOLD}✔ No anti-patterns detected!${RESET}\n`);
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
const state = {
|
|
249
|
+
groups,
|
|
250
|
+
cursor: 0,
|
|
251
|
+
selectedGroup: 0,
|
|
252
|
+
selectedItem: -1,
|
|
253
|
+
showDetails: false,
|
|
254
|
+
filterSmell: null,
|
|
255
|
+
batchSize,
|
|
256
|
+
totalIssues,
|
|
257
|
+
fileCount,
|
|
258
|
+
targetDir,
|
|
259
|
+
copied: null,
|
|
260
|
+
flashTimeout: null,
|
|
261
|
+
};
|
|
262
|
+
// Enter raw mode
|
|
263
|
+
if (!process.stdin.isTTY) {
|
|
264
|
+
// Non-interactive fallback: just print markdown
|
|
265
|
+
console.log(allToMarkdown(state));
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
process.stdin.setRawMode(true);
|
|
269
|
+
process.stdin.resume();
|
|
270
|
+
process.stdin.setEncoding('utf8');
|
|
271
|
+
process.stdout.write(HIDE_CURSOR);
|
|
272
|
+
process.stdout.write(CLEAR_SCREEN + render(state));
|
|
273
|
+
return new Promise((resolve) => {
|
|
274
|
+
const cleanup = () => {
|
|
275
|
+
process.stdout.write(SHOW_CURSOR);
|
|
276
|
+
process.stdout.write('\n');
|
|
277
|
+
if (state.flashTimeout)
|
|
278
|
+
clearTimeout(state.flashTimeout);
|
|
279
|
+
process.stdin.setRawMode(false);
|
|
280
|
+
process.stdin.pause();
|
|
281
|
+
process.stdin.removeListener('data', onKey);
|
|
282
|
+
resolve();
|
|
283
|
+
};
|
|
284
|
+
const redraw = () => {
|
|
285
|
+
process.stdout.write(CLEAR_SCREEN + render(state));
|
|
286
|
+
};
|
|
287
|
+
const visible = () => getVisibleItems(state);
|
|
288
|
+
const onKey = (key) => {
|
|
289
|
+
const items = visible();
|
|
290
|
+
const maxIdx = items.length - 1;
|
|
291
|
+
// Ctrl+C or q = quit
|
|
292
|
+
if (key === '\x03' || key === 'q' || key === 'Q') {
|
|
293
|
+
cleanup();
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
// Arrow up or k
|
|
297
|
+
if (key === '\x1b[A' || key === 'k') {
|
|
298
|
+
state.cursor = Math.max(0, state.cursor - 1);
|
|
299
|
+
redraw();
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
// Arrow down or j
|
|
303
|
+
if (key === '\x1b[B' || key === 'j') {
|
|
304
|
+
state.cursor = Math.min(maxIdx, state.cursor + 1);
|
|
305
|
+
redraw();
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
// Tab = next group
|
|
309
|
+
if (key === '\t') {
|
|
310
|
+
// Find next group entry after cursor
|
|
311
|
+
for (let i = state.cursor + 1; i < items.length; i++) {
|
|
312
|
+
if (items[i].type === 'group') {
|
|
313
|
+
state.cursor = i;
|
|
314
|
+
redraw();
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
// Wrap to first group
|
|
319
|
+
for (let i = 0; i < items.length; i++) {
|
|
320
|
+
if (items[i].type === 'group') {
|
|
321
|
+
state.cursor = i;
|
|
322
|
+
redraw();
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
// Enter, right arrow, or l = toggle collapse / expand
|
|
329
|
+
if (key === '\r' || key === '\x1b[C' || key === 'l') {
|
|
330
|
+
const current = items[state.cursor];
|
|
331
|
+
if (current && current.type === 'group') {
|
|
332
|
+
state.groups[current.groupIdx].collapsed = !state.groups[current.groupIdx].collapsed;
|
|
333
|
+
redraw();
|
|
334
|
+
}
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
// Left arrow or h = collapse
|
|
338
|
+
if (key === '\x1b[D' || key === 'h') {
|
|
339
|
+
const current = items[state.cursor];
|
|
340
|
+
if (current) {
|
|
341
|
+
const gi = current.type === 'group' ? current.groupIdx : current.groupIdx;
|
|
342
|
+
state.groups[gi].collapsed = true;
|
|
343
|
+
// Move cursor to the group header
|
|
344
|
+
for (let i = 0; i < items.length; i++) {
|
|
345
|
+
if (items[i].type === 'group' && items[i].groupIdx === gi) {
|
|
346
|
+
state.cursor = i;
|
|
347
|
+
break;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
redraw();
|
|
351
|
+
}
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
// d = toggle details
|
|
355
|
+
if (key === 'd' || key === 'D') {
|
|
356
|
+
state.showDetails = !state.showDetails;
|
|
357
|
+
redraw();
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
// c = copy current as AI prompt
|
|
361
|
+
if (key === 'c' || key === 'C') {
|
|
362
|
+
const current = items[state.cursor];
|
|
363
|
+
if (current && current.type === 'item') {
|
|
364
|
+
const det = state.groups[current.groupIdx].detections[current.itemIdx];
|
|
365
|
+
const md = detectionToPromptMarkdown(det, state.targetDir);
|
|
366
|
+
if (copyToClipboard(md)) {
|
|
367
|
+
flash(state, 'Copied to clipboard as AI prompt!');
|
|
368
|
+
}
|
|
369
|
+
else {
|
|
370
|
+
// Fallback: print to stdout after exiting
|
|
371
|
+
flash(state, 'Clipboard unavailable — press [p] to print instead');
|
|
372
|
+
}
|
|
373
|
+
redraw();
|
|
374
|
+
}
|
|
375
|
+
return;
|
|
376
|
+
}
|
|
377
|
+
// p = print current detection markdown to stdout (fallback for no clipboard)
|
|
378
|
+
if (key === 'p' || key === 'P') {
|
|
379
|
+
const current = items[state.cursor];
|
|
380
|
+
if (current && current.type === 'item') {
|
|
381
|
+
const det = state.groups[current.groupIdx].detections[current.itemIdx];
|
|
382
|
+
const md = detectionToPromptMarkdown(det, state.targetDir);
|
|
383
|
+
process.stdout.write(SHOW_CURSOR);
|
|
384
|
+
process.stdout.write(CLEAR_SCREEN);
|
|
385
|
+
console.log(md);
|
|
386
|
+
console.log(`\n${DIM}Press any key to return...${RESET}`);
|
|
387
|
+
// Wait for a key then redraw
|
|
388
|
+
const onceKey = () => {
|
|
389
|
+
process.stdout.write(HIDE_CURSOR);
|
|
390
|
+
redraw();
|
|
391
|
+
};
|
|
392
|
+
process.stdin.once('data', onceKey);
|
|
393
|
+
}
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
396
|
+
// a = copy all as markdown
|
|
397
|
+
if (key === 'a' || key === 'A') {
|
|
398
|
+
const md = allToMarkdown(state);
|
|
399
|
+
if (copyToClipboard(md)) {
|
|
400
|
+
flash(state, 'All issues copied as markdown!');
|
|
401
|
+
}
|
|
402
|
+
else {
|
|
403
|
+
flash(state, 'Clipboard unavailable — use --format markdown instead');
|
|
404
|
+
}
|
|
405
|
+
redraw();
|
|
406
|
+
return;
|
|
407
|
+
}
|
|
408
|
+
// x = ignore current component
|
|
409
|
+
if (key === 'x' || key === 'X') {
|
|
410
|
+
const current = items[state.cursor];
|
|
411
|
+
if (current && current.type === 'item') {
|
|
412
|
+
const group = state.groups[current.groupIdx];
|
|
413
|
+
const det = group.detections[current.itemIdx];
|
|
414
|
+
addToSnifferIgnore(det, state.targetDir);
|
|
415
|
+
// Remove from view
|
|
416
|
+
group.detections.splice(current.itemIdx, 1);
|
|
417
|
+
if (group.detections.length === 0) {
|
|
418
|
+
state.groups.splice(current.groupIdx, 1);
|
|
419
|
+
}
|
|
420
|
+
// Adjust cursor
|
|
421
|
+
const newItems = visible();
|
|
422
|
+
if (state.cursor >= newItems.length) {
|
|
423
|
+
state.cursor = Math.max(0, newItems.length - 1);
|
|
424
|
+
}
|
|
425
|
+
flash(state, `Ignored — added to .snifferignore`);
|
|
426
|
+
redraw();
|
|
427
|
+
}
|
|
428
|
+
return;
|
|
429
|
+
}
|
|
430
|
+
// f = cycle filter
|
|
431
|
+
if (key === 'f' || key === 'F') {
|
|
432
|
+
const smellNames = [...new Set(state.groups.map(g => g.name))];
|
|
433
|
+
if (state.filterSmell === null) {
|
|
434
|
+
state.filterSmell = smellNames[0] || null;
|
|
435
|
+
}
|
|
436
|
+
else {
|
|
437
|
+
const idx = smellNames.indexOf(state.filterSmell);
|
|
438
|
+
if (idx === smellNames.length - 1) {
|
|
439
|
+
state.filterSmell = null; // show all
|
|
440
|
+
}
|
|
441
|
+
else {
|
|
442
|
+
state.filterSmell = smellNames[idx + 1];
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
state.cursor = 0;
|
|
446
|
+
redraw();
|
|
447
|
+
return;
|
|
448
|
+
}
|
|
449
|
+
};
|
|
450
|
+
process.stdin.on('data', onKey);
|
|
451
|
+
});
|
|
452
|
+
}
|
|
453
|
+
//# sourceMappingURL=interactive-viewer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interactive-viewer.js","sourceRoot":"","sources":["../../../src/tui/interactive-viewer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'silent';
|
|
2
|
+
export declare function setLogLevel(level: LogLevel): void;
|
|
3
|
+
export declare function getLogLevel(): LogLevel;
|
|
4
|
+
export declare function debug(...args: unknown[]): void;
|
|
5
|
+
export declare function info(...args: unknown[]): void;
|
|
6
|
+
export declare function warn(...args: unknown[]): void;
|
|
7
|
+
export declare function error(...args: unknown[]): void;
|
|
8
|
+
export declare function step(label: string): void;
|
|
9
|
+
export declare function success(label: string): void;
|
|
10
|
+
export declare function fileProgress(current: number, total: number, filePath: string): void;
|
|
11
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../../src/utils/logger.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;AAsBtE,wBAAgB,WAAW,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI,CAEjD;AAED,wBAAgB,WAAW,IAAI,QAAQ,CAEtC;AAeD,wBAAgB,KAAK,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAI9C;AAED,wBAAgB,IAAI,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAI7C;AAED,wBAAgB,IAAI,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAI7C;AAED,wBAAgB,KAAK,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAI9C;AAID,wBAAgB,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAIxC;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAI3C;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAMnF"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.setLogLevel = setLogLevel;
|
|
4
|
+
exports.getLogLevel = getLogLevel;
|
|
5
|
+
exports.debug = debug;
|
|
6
|
+
exports.info = info;
|
|
7
|
+
exports.warn = warn;
|
|
8
|
+
exports.error = error;
|
|
9
|
+
exports.step = step;
|
|
10
|
+
exports.success = success;
|
|
11
|
+
exports.fileProgress = fileProgress;
|
|
12
|
+
const LOG_LEVELS = {
|
|
13
|
+
debug: 0,
|
|
14
|
+
info: 1,
|
|
15
|
+
warn: 2,
|
|
16
|
+
error: 3,
|
|
17
|
+
silent: 4,
|
|
18
|
+
};
|
|
19
|
+
let currentLevel = 'info';
|
|
20
|
+
// ANSI color codes
|
|
21
|
+
const RESET = '\x1b[0m';
|
|
22
|
+
const DIM = '\x1b[2m';
|
|
23
|
+
const BOLD = '\x1b[1m';
|
|
24
|
+
const CYAN = '\x1b[36m';
|
|
25
|
+
const YELLOW = '\x1b[33m';
|
|
26
|
+
const RED = '\x1b[31m';
|
|
27
|
+
const GREEN = '\x1b[32m';
|
|
28
|
+
const MAGENTA = '\x1b[35m';
|
|
29
|
+
function setLogLevel(level) {
|
|
30
|
+
currentLevel = level;
|
|
31
|
+
}
|
|
32
|
+
function getLogLevel() {
|
|
33
|
+
return currentLevel;
|
|
34
|
+
}
|
|
35
|
+
function shouldLog(level) {
|
|
36
|
+
return LOG_LEVELS[level] >= LOG_LEVELS[currentLevel];
|
|
37
|
+
}
|
|
38
|
+
function timestamp() {
|
|
39
|
+
const now = new Date();
|
|
40
|
+
const ms = String(now.getMilliseconds()).padStart(3, '0');
|
|
41
|
+
const s = String(now.getSeconds()).padStart(2, '0');
|
|
42
|
+
const m = String(now.getMinutes()).padStart(2, '0');
|
|
43
|
+
const h = String(now.getHours()).padStart(2, '0');
|
|
44
|
+
return `${DIM}${h}:${m}:${s}.${ms}${RESET}`;
|
|
45
|
+
}
|
|
46
|
+
function debug(...args) {
|
|
47
|
+
if (shouldLog('debug')) {
|
|
48
|
+
console.error(`${timestamp()} ${DIM}DBG${RESET}`, ...args);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function info(...args) {
|
|
52
|
+
if (shouldLog('info')) {
|
|
53
|
+
console.error(`${timestamp()} ${CYAN}${BOLD}INF${RESET}`, ...args);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
function warn(...args) {
|
|
57
|
+
if (shouldLog('warn')) {
|
|
58
|
+
console.error(`${timestamp()} ${YELLOW}${BOLD}WRN${RESET}`, ...args);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
function error(...args) {
|
|
62
|
+
if (shouldLog('error')) {
|
|
63
|
+
console.error(`${timestamp()} ${RED}${BOLD}ERR${RESET}`, ...args);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
// TUI-specific helpers for progress display
|
|
67
|
+
function step(label) {
|
|
68
|
+
if (shouldLog('info')) {
|
|
69
|
+
console.error(`${timestamp()} ${MAGENTA}${BOLD}>>>${RESET} ${label}`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
function success(label) {
|
|
73
|
+
if (shouldLog('info')) {
|
|
74
|
+
console.error(`${timestamp()} ${GREEN}${BOLD} ✔ ${RESET} ${label}`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
function fileProgress(current, total, filePath) {
|
|
78
|
+
if (shouldLog('debug')) {
|
|
79
|
+
const pct = Math.round((current / total) * 100);
|
|
80
|
+
const bar = progressBar(pct);
|
|
81
|
+
console.error(`${timestamp()} ${DIM}${bar} [${current}/${total}]${RESET} ${DIM}${filePath}${RESET}`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
function progressBar(pct) {
|
|
85
|
+
const width = 20;
|
|
86
|
+
const filled = Math.round((pct / 100) * width);
|
|
87
|
+
const empty = width - filled;
|
|
88
|
+
return `${GREEN}${'█'.repeat(filled)}${DIM}${'░'.repeat(empty)}${RESET}`;
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../../src/utils/logger.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared regex patterns and utility functions for React code parsing.
|
|
3
|
+
* All sniffers depend on these for consistent detection.
|
|
4
|
+
*/
|
|
5
|
+
export declare const FUNCTIONAL_COMPONENT_DECL: RegExp;
|
|
6
|
+
export declare const DESTRUCTURED_PROPS: RegExp;
|
|
7
|
+
export declare const JSX_OPENING_TAG: RegExp;
|
|
8
|
+
export declare const JSX_ATTRIBUTE: RegExp;
|
|
9
|
+
export declare const JSX_SPREAD: RegExp;
|
|
10
|
+
export declare const CUSTOM_HOOK_DECL: RegExp;
|
|
11
|
+
export declare const USE_STATE: RegExp;
|
|
12
|
+
export declare const USE_EFFECT: RegExp;
|
|
13
|
+
export declare const USE_CALLBACK: RegExp;
|
|
14
|
+
export declare const USE_MEMO: RegExp;
|
|
15
|
+
export declare const USE_REF: RegExp;
|
|
16
|
+
export declare const USE_CONTEXT: RegExp;
|
|
17
|
+
export declare const USE_REDUCER: RegExp;
|
|
18
|
+
export declare const USE_LAYOUT_EFFECT: RegExp;
|
|
19
|
+
/**
|
|
20
|
+
* Extract a brace-balanced block starting from a given index.
|
|
21
|
+
* The character at `startIndex` should be '{'.
|
|
22
|
+
* Returns the substring including the braces, or null if unbalanced.
|
|
23
|
+
*/
|
|
24
|
+
export declare function extractBracedBlock(source: string, startIndex: number): string | null;
|
|
25
|
+
/**
|
|
26
|
+
* Get the 1-indexed line number for a character offset.
|
|
27
|
+
*/
|
|
28
|
+
export declare function getLineNumber(source: string, charIndex: number): number;
|
|
29
|
+
/**
|
|
30
|
+
* Get the 1-indexed column number for a character offset.
|
|
31
|
+
*/
|
|
32
|
+
export declare function getColumnNumber(source: string, charIndex: number): number;
|
|
33
|
+
/**
|
|
34
|
+
* Count regex matches in a string.
|
|
35
|
+
*/
|
|
36
|
+
export declare function countMatches(source: string, regex: RegExp): number;
|
|
37
|
+
/**
|
|
38
|
+
* Strip comments and string literals from source code.
|
|
39
|
+
* Useful for avoiding false positives from commented-out code.
|
|
40
|
+
*/
|
|
41
|
+
export declare function stripCommentsAndStrings(source: string): string;
|
|
42
|
+
/**
|
|
43
|
+
* Parse destructured prop names from a destructuring pattern string.
|
|
44
|
+
* Input: " a, b = 'default', c, ...rest "
|
|
45
|
+
* Output: ["a", "b", "c"] (excludes rest params)
|
|
46
|
+
*/
|
|
47
|
+
export declare function parseDestructuredProps(propsString: string): string[];
|
|
48
|
+
/**
|
|
49
|
+
* Find the opening brace index after a given position.
|
|
50
|
+
* Skips parentheses, arrow functions, type annotations, etc.
|
|
51
|
+
*/
|
|
52
|
+
export declare function findOpeningBrace(source: string, startIndex: number): number;
|
|
53
|
+
//# sourceMappingURL=regex-helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"regex-helpers.d.ts","sourceRoot":"","sources":["../../../src/utils/regex-helpers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,eAAO,MAAM,yBAAyB,QAC2N,CAAC;AAIlQ,eAAO,MAAM,kBAAkB,QAAqB,CAAC;AAKrD,eAAO,MAAM,eAAe,QAAkD,CAAC;AAI/E,eAAO,MAAM,aAAa,QAA6F,CAAC;AAGxH,eAAO,MAAM,UAAU,QAA2B,CAAC;AAInD,eAAO,MAAM,gBAAgB,QAC+C,CAAC;AAG7E,eAAO,MAAM,SAAS,QAAoC,CAAC;AAC3D,eAAO,MAAM,UAAU,QAAsB,CAAC;AAC9C,eAAO,MAAM,YAAY,QAAwB,CAAC;AAClD,eAAO,MAAM,QAAQ,QAAoB,CAAC;AAC1C,eAAO,MAAM,OAAO,QAAkC,CAAC;AACvD,eAAO,MAAM,WAAW,QAAuB,CAAC;AAChD,eAAO,MAAM,WAAW,QAAuB,CAAC;AAChD,eAAO,MAAM,iBAAiB,QAA4B,CAAC;AAE3D;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAsFpF;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAMvE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAOzE;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAIlE;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAmD9D;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CAuCpE;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAO3E"}
|