@chemx/starter-kit 26.9.12-118 → 26.9.12-93
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/cli/audit/prompts.js +62 -116
- package/cli/audit/reporter-grouping.d.ts +0 -6
- package/cli/audit/reporter-grouping.js +5 -48
- package/cli/audit/reporter-sections.js +8 -14
- package/cli/audit/reporter.js +2 -3
- package/cli/audit/types.d.ts +4 -9
- package/cli/audit.js +2 -31
- package/docs/CHANGELOG.md +0 -4
- package/package.json +1 -1
package/cli/audit/prompts.js
CHANGED
|
@@ -1,92 +1,35 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
RESET
|
|
10
|
-
} from './reporter-utils.js';
|
|
11
|
-
|
|
12
|
-
const SEVERITY_COLORS = {
|
|
13
|
-
CRITICAL: RED,
|
|
14
|
-
HIGH: ORANGE,
|
|
15
|
-
MEDIUM: YELLOW,
|
|
16
|
-
LOW: DIM
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
const renderTreeLines = (node, depth = 0) => {
|
|
20
|
-
const lines = [];
|
|
21
|
-
const indent = ' ' + ' '.repeat(depth);
|
|
22
|
-
|
|
23
|
-
const sortedDirs = Array.from(node.dirs.entries()).sort((a, b) => a[0].localeCompare(b[0]));
|
|
24
|
-
for (const [dirName, childNode] of sortedDirs) {
|
|
25
|
-
lines.push(`${indent}📁 ${BOLD}${dirName}${RESET}`);
|
|
26
|
-
const childLines = renderTreeLines(childNode, depth + 1);
|
|
27
|
-
lines.push(...childLines);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const sortedFiles = Array.from(node.files.entries()).sort((a, b) => a[0].localeCompare(b[0]));
|
|
31
|
-
for (const [fileName, locs] of sortedFiles) {
|
|
32
|
-
const uniqueLocs = Array.from(new Set(locs)).join(', ');
|
|
33
|
-
lines.push(`${indent}- \`${YELLOW}${fileName}:${uniqueLocs}${RESET}\``);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
return lines;
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
export const formatGroupedPromptViolations = (violations = []) => {
|
|
40
|
-
const hasNoViolations = violations.length === 0;
|
|
41
|
-
if (hasNoViolations) return [];
|
|
42
|
-
|
|
43
|
-
const ruleGroups = groupViolationsByRule(violations);
|
|
44
|
-
const lines = [];
|
|
45
|
-
|
|
46
|
-
ruleGroups.forEach((rg, idx) => {
|
|
47
|
-
const sevColor = SEVERITY_COLORS[rg.severity] || YELLOW;
|
|
48
|
-
const countLabel = rg.total === 1 ? '1 item' : `${rg.total} items`;
|
|
49
|
-
lines.push(`${idx + 1}. ${sevColor}[${rg.rule}]${RESET} ${BOLD}(${countLabel})${RESET}`);
|
|
50
|
-
lines.push(` Hazard: ${rg.hazard}`);
|
|
51
|
-
lines.push(` Directive: ${CYAN}${rg.directive}${RESET}`);
|
|
52
|
-
lines.push(' Locations:');
|
|
53
|
-
|
|
54
|
-
const tree = buildPathTree(rg.violations);
|
|
55
|
-
const treeLines = renderTreeLines(tree, 0);
|
|
56
|
-
lines.push(...treeLines);
|
|
57
|
-
lines.push('');
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
return lines;
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
export const buildGradeFPrompt = (report, options = {}) => {
|
|
64
|
-
const { excludeAiSlop = false } = options;
|
|
65
|
-
const { violations = [], hotspots = [] } = report;
|
|
66
|
-
const critical = violations
|
|
67
|
-
.filter((v) => v.severity === 'CRITICAL')
|
|
68
|
-
.filter((v) => (excludeAiSlop ? !v.isAiSlop : true));
|
|
1
|
+
const CYAN = '\x1b[38;2;98;201;255m';
|
|
2
|
+
const BOLD = '\x1b[1m';
|
|
3
|
+
const DIM = '\x1b[2m';
|
|
4
|
+
const RESET = '\x1b[0m';
|
|
5
|
+
|
|
6
|
+
export const buildGradeFPrompt = (report) => {
|
|
7
|
+
const { violations, hotspots } = report;
|
|
8
|
+
const critical = violations.filter((v) => v.severity === 'CRITICAL');
|
|
69
9
|
const extremeMonoliths = hotspots.filter((h) => h.lineCount >= 2000);
|
|
70
10
|
|
|
71
|
-
|
|
72
|
-
const hasNoMonoliths = extremeMonoliths.length === 0;
|
|
73
|
-
if (hasNoCritical && hasNoMonoliths) return '';
|
|
11
|
+
if (critical.length === 0 && extremeMonoliths.length === 0) return '';
|
|
74
12
|
|
|
75
13
|
const lines = [];
|
|
76
14
|
lines.push('Act as a Principal Systems Architect. Surgically refactor the following Grade F Critical Context Hazards in our codebase according to Chemical X Molecular Architecture Standards:\n');
|
|
77
15
|
|
|
78
16
|
if (extremeMonoliths.length > 0) {
|
|
79
17
|
lines.push('### EXTREME MONOLITHS (>= 2,000 lines of code) : MONOLITH DECOMPOSITION');
|
|
80
|
-
lines.push('Action: Decompose into crystalline single-responsibility capsules (< 100 lines per molecule). Convert top-level view into a declarative Table-of-Contents view.\n');
|
|
81
18
|
extremeMonoliths.forEach((h, i) => {
|
|
82
19
|
lines.push(`${i + 1}. File: \`${h.filePath}\` (${h.lineCount} lines)`);
|
|
20
|
+
lines.push(' Action: Decompose this monolith into crystalline single-responsibility capsules (< 100 lines per molecule). Convert top-level view into a declarative Table-of-Contents view.');
|
|
83
21
|
});
|
|
84
22
|
lines.push('');
|
|
85
23
|
}
|
|
86
24
|
|
|
87
25
|
if (critical.length > 0) {
|
|
88
26
|
lines.push('### CRITICAL AST VIOLATIONS');
|
|
89
|
-
|
|
27
|
+
critical.forEach((v, i) => {
|
|
28
|
+
lines.push(`${i + 1}. \`${v.filePath}:${v.line}:${v.column}\` [${v.rule}]`);
|
|
29
|
+
lines.push(` Hazard: ${v.hazard}`);
|
|
30
|
+
lines.push(` Directive: ${v.directive}`);
|
|
31
|
+
});
|
|
32
|
+
lines.push('');
|
|
90
33
|
}
|
|
91
34
|
|
|
92
35
|
lines.push('### STRICT EXECUTION RULES:');
|
|
@@ -99,33 +42,33 @@ export const buildGradeFPrompt = (report, options = {}) => {
|
|
|
99
42
|
return lines.join('\n');
|
|
100
43
|
};
|
|
101
44
|
|
|
102
|
-
export const buildGradeDPrompt = (report
|
|
103
|
-
const {
|
|
104
|
-
const
|
|
105
|
-
const high = violations
|
|
106
|
-
.filter((v) => v.severity === 'HIGH')
|
|
107
|
-
.filter((v) => (excludeAiSlop ? !v.isAiSlop : true));
|
|
45
|
+
export const buildGradeDPrompt = (report) => {
|
|
46
|
+
const { violations, hotspots } = report;
|
|
47
|
+
const high = violations.filter((v) => v.severity === 'HIGH');
|
|
108
48
|
const severeMonoliths = hotspots.filter((h) => h.lineCount >= 1000 && h.lineCount < 2000);
|
|
109
49
|
|
|
110
|
-
|
|
111
|
-
const hasNoMonoliths = severeMonoliths.length === 0;
|
|
112
|
-
if (hasNoHigh && hasNoMonoliths) return '';
|
|
50
|
+
if (high.length === 0 && severeMonoliths.length === 0) return '';
|
|
113
51
|
|
|
114
52
|
const lines = [];
|
|
115
53
|
lines.push('Act as a Principal Systems Architect. Refactor the following Grade D High-Severity Architectural Debts according to Chemical X Molecular Architecture Standards:\n');
|
|
116
54
|
|
|
117
55
|
if (severeMonoliths.length > 0) {
|
|
118
56
|
lines.push('### SEVERE MONOLITHS (1,000 - 1,999 lines of code)');
|
|
119
|
-
lines.push('Action: Extract sub-features into isolated molecule capsules (< 100 lines of code) and domain composables.\n');
|
|
120
57
|
severeMonoliths.forEach((h, i) => {
|
|
121
58
|
lines.push(`${i + 1}. File: \`${h.filePath}\` (${h.lineCount} lines)`);
|
|
59
|
+
lines.push(' Action: Extract sub-features into isolated molecule capsules (< 100 lines of code) and domain composables.');
|
|
122
60
|
});
|
|
123
61
|
lines.push('');
|
|
124
62
|
}
|
|
125
63
|
|
|
126
64
|
if (high.length > 0) {
|
|
127
65
|
lines.push('### HIGH SEVERITY VIOLATIONS');
|
|
128
|
-
|
|
66
|
+
high.forEach((v, i) => {
|
|
67
|
+
lines.push(`${i + 1}. \`${v.filePath}:${v.line}:${v.column}\` [${v.rule}]`);
|
|
68
|
+
lines.push(` Hazard: ${v.hazard}`);
|
|
69
|
+
lines.push(` Directive: ${v.directive}`);
|
|
70
|
+
});
|
|
71
|
+
lines.push('');
|
|
129
72
|
}
|
|
130
73
|
|
|
131
74
|
lines.push('### STRICT EXECUTION RULES:');
|
|
@@ -136,33 +79,33 @@ export const buildGradeDPrompt = (report, options = {}) => {
|
|
|
136
79
|
return lines.join('\n');
|
|
137
80
|
};
|
|
138
81
|
|
|
139
|
-
export const buildGradeCPrompt = (report
|
|
140
|
-
const {
|
|
141
|
-
const
|
|
142
|
-
const medium = violations
|
|
143
|
-
.filter((v) => v.severity === 'MEDIUM')
|
|
144
|
-
.filter((v) => (excludeAiSlop ? !v.isAiSlop : true));
|
|
82
|
+
export const buildGradeCPrompt = (report) => {
|
|
83
|
+
const { violations, hotspots } = report;
|
|
84
|
+
const medium = violations.filter((v) => v.severity === 'MEDIUM');
|
|
145
85
|
const warningMonoliths = hotspots.filter((h) => h.lineCount >= 500 && h.lineCount < 1000);
|
|
146
86
|
|
|
147
|
-
|
|
148
|
-
const hasNoMonoliths = warningMonoliths.length === 0;
|
|
149
|
-
if (hasNoMedium && hasNoMonoliths) return '';
|
|
87
|
+
if (medium.length === 0 && warningMonoliths.length === 0) return '';
|
|
150
88
|
|
|
151
89
|
const lines = [];
|
|
152
90
|
lines.push('Act as a Senior Frontend Engineer. Refactor the following Grade C Medium-Severity Technical Debts according to Chemical X Molecular Architecture Standards:\n');
|
|
153
91
|
|
|
154
92
|
if (warningMonoliths.length > 0) {
|
|
155
93
|
lines.push('### WARNING MONOLITHS (500 - 999 lines of code)');
|
|
156
|
-
lines.push('Action: Bring file under 500 line budget by extracting helper functions, types, and child molecules.\n');
|
|
157
94
|
warningMonoliths.forEach((h, i) => {
|
|
158
95
|
lines.push(`${i + 1}. File: \`${h.filePath}\` (${h.lineCount} lines)`);
|
|
96
|
+
lines.push(' Action: Bring file under 500 line budget by extracting helper functions, types, and child molecules.');
|
|
159
97
|
});
|
|
160
98
|
lines.push('');
|
|
161
99
|
}
|
|
162
100
|
|
|
163
101
|
if (medium.length > 0) {
|
|
164
102
|
lines.push('### MEDIUM SEVERITY VIOLATIONS');
|
|
165
|
-
|
|
103
|
+
medium.forEach((v, i) => {
|
|
104
|
+
lines.push(`${i + 1}. \`${v.filePath}:${v.line}:${v.column}\` [${v.rule}]`);
|
|
105
|
+
lines.push(` Hazard: ${v.hazard}`);
|
|
106
|
+
lines.push(` Directive: ${v.directive}`);
|
|
107
|
+
});
|
|
108
|
+
lines.push('');
|
|
166
109
|
}
|
|
167
110
|
|
|
168
111
|
lines.push('### STRICT EXECUTION RULES:');
|
|
@@ -173,21 +116,22 @@ export const buildGradeCPrompt = (report, options = {}) => {
|
|
|
173
116
|
return lines.join('\n');
|
|
174
117
|
};
|
|
175
118
|
|
|
176
|
-
export const buildGradeBPrompt = (report
|
|
177
|
-
const {
|
|
178
|
-
const
|
|
179
|
-
const low = violations
|
|
180
|
-
.filter((v) => v.severity === 'LOW')
|
|
181
|
-
.filter((v) => (excludeAiSlop ? !v.isAiSlop : true));
|
|
119
|
+
export const buildGradeBPrompt = (report) => {
|
|
120
|
+
const { violations } = report;
|
|
121
|
+
const low = violations.filter((v) => v.severity === 'LOW');
|
|
182
122
|
|
|
183
|
-
|
|
184
|
-
if (hasNoLow) return '';
|
|
123
|
+
if (low.length === 0) return '';
|
|
185
124
|
|
|
186
125
|
const lines = [];
|
|
187
126
|
lines.push('Act as a Clean Code Specialist. Clean up the following Grade B Low-Severity Hygiene Issues according to Chemical X standards:\n');
|
|
188
127
|
|
|
189
128
|
lines.push('### LOW HYGIENE VIOLATIONS');
|
|
190
|
-
|
|
129
|
+
low.forEach((v, i) => {
|
|
130
|
+
lines.push(`${i + 1}. \`${v.filePath}:${v.line}:${v.column}\` [${v.rule}]`);
|
|
131
|
+
lines.push(` Hazard: ${v.hazard}`);
|
|
132
|
+
lines.push(` Directive: ${v.directive}`);
|
|
133
|
+
});
|
|
134
|
+
lines.push('');
|
|
191
135
|
|
|
192
136
|
lines.push('### STRICT EXECUTION RULES:');
|
|
193
137
|
lines.push('1. Typography Hygiene: Replace all em dashes with standard hyphens (-) or colons (:).');
|
|
@@ -201,14 +145,18 @@ export const buildAiSlopPrompt = (report) => {
|
|
|
201
145
|
const { violations = [] } = report;
|
|
202
146
|
const slopViolations = violations.filter((v) => Boolean(v.isAiSlop));
|
|
203
147
|
|
|
204
|
-
|
|
205
|
-
if (hasNoSlop) return '';
|
|
148
|
+
if (slopViolations.length === 0) return '';
|
|
206
149
|
|
|
207
150
|
const lines = [];
|
|
208
151
|
lines.push('Act as a Clean Code Specialist and Code Authenticity Guardian. Eliminate the following AI Slop and conversational artifacts from our codebase according to Chemical X standards:\n');
|
|
209
152
|
|
|
210
153
|
lines.push('### AI SLOP & CODE AUTHENTICITY VIOLATIONS');
|
|
211
|
-
|
|
154
|
+
slopViolations.forEach((v, i) => {
|
|
155
|
+
lines.push(`${i + 1}. \`${v.filePath}:${v.line}:${v.column}\` [${v.rule}]`);
|
|
156
|
+
lines.push(` Hazard: ${v.hazard}`);
|
|
157
|
+
lines.push(` Directive: ${v.directive}`);
|
|
158
|
+
});
|
|
159
|
+
lines.push('');
|
|
212
160
|
|
|
213
161
|
lines.push('### STRICT EXECUTION RULES:');
|
|
214
162
|
lines.push('1. Conversational Residue: Completely remove leaked AI conversational preambles, assistant markdown code fences, and pleasantry comments.');
|
|
@@ -225,17 +173,16 @@ export const buildHotspotsPrompt = (report) => {
|
|
|
225
173
|
const { hotspots = [] } = report;
|
|
226
174
|
const monolithHotspots = hotspots.filter((h) => h.isMonolith || h.lineCount > 500);
|
|
227
175
|
|
|
228
|
-
|
|
229
|
-
if (hasNoMonoliths) return '';
|
|
176
|
+
if (monolithHotspots.length === 0) return '';
|
|
230
177
|
|
|
231
178
|
const lines = [];
|
|
232
179
|
lines.push('Act as a Principal Systems Architect. Surgically decompose the following monolithic hotspot files according to Chemical X Molecular Architecture Standards:\n');
|
|
233
180
|
|
|
234
181
|
lines.push('### MONOLITHIC REFACTORING HOTSPOTS');
|
|
235
|
-
lines.push('Action: Decompose into single-responsibility crystalline molecule capsules (< 100 lines) and dedicated domain composables.\n');
|
|
236
182
|
monolithHotspots.forEach((h, i) => {
|
|
237
183
|
const tier = h.monolithTier ? `[${h.monolithTier} MONOLITH]` : '[MONOLITH]';
|
|
238
184
|
lines.push(`${i + 1}. File: \`${h.filePath}\` (${h.lineCount} lines, ${h.violationCount} hazards) ${tier}`);
|
|
185
|
+
lines.push(' Action: Decompose into single-responsibility crystalline molecule capsules (< 100 lines) and dedicated domain composables.');
|
|
239
186
|
});
|
|
240
187
|
lines.push('');
|
|
241
188
|
|
|
@@ -251,16 +198,15 @@ export const buildHotspotsPrompt = (report) => {
|
|
|
251
198
|
|
|
252
199
|
export const buildMasterPrompt = (report) => {
|
|
253
200
|
const sections = [
|
|
254
|
-
buildGradeFPrompt(report
|
|
255
|
-
buildGradeDPrompt(report
|
|
256
|
-
buildGradeCPrompt(report
|
|
257
|
-
buildGradeBPrompt(report
|
|
201
|
+
buildGradeFPrompt(report),
|
|
202
|
+
buildGradeDPrompt(report),
|
|
203
|
+
buildGradeCPrompt(report),
|
|
204
|
+
buildGradeBPrompt(report),
|
|
258
205
|
buildAiSlopPrompt(report),
|
|
259
206
|
buildHotspotsPrompt(report)
|
|
260
207
|
].filter(Boolean);
|
|
261
208
|
|
|
262
|
-
|
|
263
|
-
if (hasNoSections) return '';
|
|
209
|
+
if (sections.length === 0) return '';
|
|
264
210
|
|
|
265
211
|
const header = `Act as a Principal Systems Architect. Execute a phased architectural refactoring of our codebase according to Chemical X Molecular Architecture Standards.\n\n`;
|
|
266
212
|
return header + sections.join('\n\n---\n\n');
|
|
@@ -29,15 +29,9 @@ export interface RuleHazardSummary {
|
|
|
29
29
|
readonly directories: readonly RuleDirectoryOccurrence[];
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
export interface PathTreeNode {
|
|
33
|
-
readonly dirs: Map<string, PathTreeNode>;
|
|
34
|
-
readonly files: Map<string, string[]>;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
32
|
export declare function resolveDirectory(filePath?: string): string;
|
|
38
33
|
export declare function groupViolationsByDirectory(violations?: readonly HazardViolation[]): readonly DirectoryHazardSummary[];
|
|
39
34
|
export declare function groupViolationsByRule(violations?: readonly HazardViolation[]): readonly RuleHazardSummary[];
|
|
40
|
-
export declare function buildPathTree(violations?: readonly HazardViolation[]): PathTreeNode;
|
|
41
35
|
export declare function formatCompactLocations(violations: readonly HazardViolation[], maxShown?: number): string;
|
|
42
36
|
export declare function renderGroupedViolationsTerminal(violations: readonly HazardViolation[]): string;
|
|
43
37
|
export declare function formatDirectoryDistributionSection(report: AuditReport, themeColor?: string | null): string;
|
|
@@ -157,34 +157,6 @@ const resolveSeverityColor = (severity) => {
|
|
|
157
157
|
return DIM;
|
|
158
158
|
};
|
|
159
159
|
|
|
160
|
-
export const buildPathTree = (violations = []) => {
|
|
161
|
-
const root = { dirs: new Map(), files: new Map() };
|
|
162
|
-
|
|
163
|
-
for (const v of violations) {
|
|
164
|
-
const rawPath = v.filePath || '';
|
|
165
|
-
const normalized = rawPath.replace(/\\/g, '/').replace(/^\.\//, '');
|
|
166
|
-
const segments = normalized.split('/');
|
|
167
|
-
const fileName = segments.pop();
|
|
168
|
-
|
|
169
|
-
let current = root;
|
|
170
|
-
for (const seg of segments) {
|
|
171
|
-
const segName = seg.endsWith('/') ? seg : `${seg}/`;
|
|
172
|
-
if (!current.dirs.has(segName)) {
|
|
173
|
-
current.dirs.set(segName, { dirs: new Map(), files: new Map() });
|
|
174
|
-
}
|
|
175
|
-
current = current.dirs.get(segName);
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
if (!current.files.has(fileName)) {
|
|
179
|
-
current.files.set(fileName, []);
|
|
180
|
-
}
|
|
181
|
-
const loc = v.column ? `${v.line}:${v.column}` : `${v.line}`;
|
|
182
|
-
current.files.get(fileName).push(loc);
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
return root;
|
|
186
|
-
};
|
|
187
|
-
|
|
188
160
|
export const formatCompactLocations = (violations, maxShown = 4) => {
|
|
189
161
|
const formatLocationItem = (v) => {
|
|
190
162
|
const base = path.basename(v.filePath);
|
|
@@ -214,8 +186,7 @@ export const renderGroupedViolationsTerminal = (violations) => {
|
|
|
214
186
|
|
|
215
187
|
if (isSingleOccurrence) {
|
|
216
188
|
const v = rg.violations[0];
|
|
217
|
-
|
|
218
|
-
lines.push(` ${sevColor}[#${idx + 1} ${rg.severity}]${RESET} [${rg.rule}] ${YELLOW}${v.filePath}:${v.line}${colStr}${RESET}`);
|
|
189
|
+
lines.push(` ${sevColor}[#${idx + 1} ${rg.severity}]${RESET} [${rg.rule}] ${YELLOW}${v.filePath}:${v.line}:${v.column}${RESET}`);
|
|
219
190
|
lines.push(` Hazard: ${rg.hazard}`);
|
|
220
191
|
lines.push(` Directive: ${CYAN}${rg.directive}${RESET}\n`);
|
|
221
192
|
return;
|
|
@@ -228,24 +199,10 @@ export const renderGroupedViolationsTerminal = (violations) => {
|
|
|
228
199
|
lines.push(` Directive: ${CYAN}${rg.directive}${RESET}`);
|
|
229
200
|
lines.push(` Locations:`);
|
|
230
201
|
|
|
231
|
-
const
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
const sortedDirs = Array.from(node.dirs.entries()).sort((a, b) => a[0].localeCompare(b[0]));
|
|
236
|
-
for (const [dirName, childNode] of sortedDirs) {
|
|
237
|
-
lines.push(`${indent}📁 ${BOLD}${dirName}${RESET}`);
|
|
238
|
-
renderTerminalTree(childNode, depth + 1);
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
const sortedFiles = Array.from(node.files.entries()).sort((a, b) => a[0].localeCompare(b[0]));
|
|
242
|
-
for (const [fileName, locs] of sortedFiles) {
|
|
243
|
-
const uniqueLocs = Array.from(new Set(locs)).join(', ');
|
|
244
|
-
lines.push(`${indent}- ${YELLOW}${fileName}:${uniqueLocs}${RESET}`);
|
|
245
|
-
}
|
|
246
|
-
};
|
|
247
|
-
|
|
248
|
-
renderTerminalTree(tree, 0);
|
|
202
|
+
for (const d of rg.directories) {
|
|
203
|
+
const locs = formatCompactLocations(d.violations, 4);
|
|
204
|
+
lines.push(` 📁 ${d.directory} (${d.count}): ${locs}`);
|
|
205
|
+
}
|
|
249
206
|
lines.push('');
|
|
250
207
|
});
|
|
251
208
|
|
|
@@ -166,8 +166,7 @@ export const formatPillarsSection = (report, themeColor = null) => {
|
|
|
166
166
|
return lines.join('\n');
|
|
167
167
|
};
|
|
168
168
|
|
|
169
|
-
export const formatHotspotsSection = (report, themeColor = null
|
|
170
|
-
const { includePrompt = true } = typeof options === 'boolean' ? { includePrompt: options } : options;
|
|
169
|
+
export const formatHotspotsSection = (report, themeColor = null) => {
|
|
171
170
|
const { hotspots } = report;
|
|
172
171
|
const sectionColor = themeColor || resolveTopSectionColor(report);
|
|
173
172
|
const lines = [];
|
|
@@ -185,11 +184,9 @@ export const formatHotspotsSection = (report, themeColor = null, options = {}) =
|
|
|
185
184
|
}
|
|
186
185
|
}
|
|
187
186
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
lines.push(formatPromptBox('🤖 AI AGENT REFACTORING PROMPT (MONOLITH DECOMPOSITION)', promptHotspots));
|
|
192
|
-
}
|
|
187
|
+
const promptHotspots = buildHotspotsPrompt(report);
|
|
188
|
+
if (promptHotspots) {
|
|
189
|
+
lines.push(formatPromptBox('🤖 AI AGENT REFACTORING PROMPT (MONOLITH DECOMPOSITION)', promptHotspots));
|
|
193
190
|
}
|
|
194
191
|
|
|
195
192
|
lines.push(`${sectionColor}======================================================================${RESET}\n`);
|
|
@@ -224,8 +221,7 @@ export const formatContextAnalysisSection = (report, themeColor = null) => {
|
|
|
224
221
|
return lines.join('\n');
|
|
225
222
|
};
|
|
226
223
|
|
|
227
|
-
export const formatAiSlopSection = (report, themeColor = null
|
|
228
|
-
const { includePrompt = true } = typeof options === 'boolean' ? { includePrompt: options } : options;
|
|
224
|
+
export const formatAiSlopSection = (report, themeColor = null) => {
|
|
229
225
|
const { aiSlop, violations = [] } = report;
|
|
230
226
|
const slopViolations = violations.filter(isSlopViolation);
|
|
231
227
|
const sectionColor = themeColor || resolveTopSectionColor(report);
|
|
@@ -247,11 +243,9 @@ export const formatAiSlopSection = (report, themeColor = null, options = {}) =>
|
|
|
247
243
|
lines.push(renderGroupedViolationsTerminal(slopViolations));
|
|
248
244
|
}
|
|
249
245
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
lines.push(formatPromptBox('🤖 AI AGENT REFACTORING PROMPT (AI SLOP & AUTHENTICITY)', promptSlop));
|
|
254
|
-
}
|
|
246
|
+
const promptSlop = buildAiSlopPrompt(report);
|
|
247
|
+
if (promptSlop) {
|
|
248
|
+
lines.push(formatPromptBox('🤖 AI AGENT REFACTORING PROMPT (AI SLOP & AUTHENTICITY)', promptSlop));
|
|
255
249
|
}
|
|
256
250
|
|
|
257
251
|
lines.push(`${sectionColor}======================================================================${RESET}\n`);
|
package/cli/audit/reporter.js
CHANGED
|
@@ -49,7 +49,6 @@ export {
|
|
|
49
49
|
resolveDirectory,
|
|
50
50
|
groupViolationsByDirectory,
|
|
51
51
|
groupViolationsByRule,
|
|
52
|
-
buildPathTree,
|
|
53
52
|
formatCompactLocations,
|
|
54
53
|
renderGroupedViolationsTerminal,
|
|
55
54
|
formatDirectoryDistributionSection
|
|
@@ -109,9 +108,9 @@ export const formatTerminalReport = (report) => {
|
|
|
109
108
|
lines.push(formatScorecardSection(report, topColor));
|
|
110
109
|
lines.push(formatContextAnalysisSection(report, topColor));
|
|
111
110
|
lines.push(formatPillarsSection(report, topColor));
|
|
112
|
-
lines.push(formatHotspotsSection(report, topColor
|
|
111
|
+
lines.push(formatHotspotsSection(report, topColor));
|
|
113
112
|
lines.push(formatDirectoryDistributionSection(report, topColor));
|
|
114
|
-
lines.push(formatAiSlopSection(report, topColor
|
|
113
|
+
lines.push(formatAiSlopSection(report, topColor));
|
|
115
114
|
lines.push(formatCriticalSection(report));
|
|
116
115
|
lines.push(formatHighMediumSection(report));
|
|
117
116
|
lines.push(formatLowSection(report));
|
package/cli/audit/types.d.ts
CHANGED
|
@@ -123,15 +123,10 @@ export declare function calculateAiSlopScore(violations: readonly HazardViolatio
|
|
|
123
123
|
export * from './reporter';
|
|
124
124
|
export * from './social';
|
|
125
125
|
|
|
126
|
-
export
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
export declare function formatGroupedPromptViolations(violations?: readonly HazardViolation[]): string[];
|
|
131
|
-
export declare function buildGradeFPrompt(report: AuditReport, options?: PromptOptions): string;
|
|
132
|
-
export declare function buildGradeDPrompt(report: AuditReport, options?: PromptOptions): string;
|
|
133
|
-
export declare function buildGradeCPrompt(report: AuditReport, options?: PromptOptions): string;
|
|
134
|
-
export declare function buildGradeBPrompt(report: AuditReport, options?: PromptOptions): string;
|
|
126
|
+
export declare function buildGradeFPrompt(report: AuditReport): string;
|
|
127
|
+
export declare function buildGradeDPrompt(report: AuditReport): string;
|
|
128
|
+
export declare function buildGradeCPrompt(report: AuditReport): string;
|
|
129
|
+
export declare function buildGradeBPrompt(report: AuditReport): string;
|
|
135
130
|
export declare function buildAiSlopPrompt(report: AuditReport): string;
|
|
136
131
|
export declare function buildHotspotsPrompt(report: AuditReport): string;
|
|
137
132
|
export declare function buildMasterPrompt(report: AuditReport): string;
|
package/cli/audit.js
CHANGED
|
@@ -40,17 +40,6 @@ import {
|
|
|
40
40
|
getReportCardAsciiLines,
|
|
41
41
|
REPORT_CARD_ASCII
|
|
42
42
|
} from './audit/reporter.js';
|
|
43
|
-
import {
|
|
44
|
-
buildGradeFPrompt,
|
|
45
|
-
buildGradeDPrompt,
|
|
46
|
-
buildGradeCPrompt,
|
|
47
|
-
buildGradeBPrompt,
|
|
48
|
-
buildAiSlopPrompt,
|
|
49
|
-
buildHotspotsPrompt,
|
|
50
|
-
buildMasterPrompt,
|
|
51
|
-
formatPromptBox,
|
|
52
|
-
formatGroupedPromptViolations
|
|
53
|
-
} from './audit/prompts.js';
|
|
54
43
|
|
|
55
44
|
const IGNORED_DIRS = new Set([
|
|
56
45
|
'node_modules',
|
|
@@ -244,16 +233,7 @@ export {
|
|
|
244
233
|
getAsciiGradeLines,
|
|
245
234
|
formatAsciiGrade,
|
|
246
235
|
getReportCardAsciiLines,
|
|
247
|
-
REPORT_CARD_ASCII
|
|
248
|
-
buildGradeFPrompt,
|
|
249
|
-
buildGradeDPrompt,
|
|
250
|
-
buildGradeCPrompt,
|
|
251
|
-
buildGradeBPrompt,
|
|
252
|
-
buildAiSlopPrompt,
|
|
253
|
-
buildHotspotsPrompt,
|
|
254
|
-
buildMasterPrompt,
|
|
255
|
-
formatPromptBox,
|
|
256
|
-
formatGroupedPromptViolations
|
|
236
|
+
REPORT_CARD_ASCII
|
|
257
237
|
};
|
|
258
238
|
|
|
259
239
|
export default {
|
|
@@ -290,14 +270,5 @@ export default {
|
|
|
290
270
|
getReportCardAsciiLines,
|
|
291
271
|
REPORT_CARD_ASCII,
|
|
292
272
|
PILLARS,
|
|
293
|
-
RULE_REGISTRY
|
|
294
|
-
buildGradeFPrompt,
|
|
295
|
-
buildGradeDPrompt,
|
|
296
|
-
buildGradeCPrompt,
|
|
297
|
-
buildGradeBPrompt,
|
|
298
|
-
buildAiSlopPrompt,
|
|
299
|
-
buildHotspotsPrompt,
|
|
300
|
-
buildMasterPrompt,
|
|
301
|
-
formatPromptBox,
|
|
302
|
-
formatGroupedPromptViolations
|
|
273
|
+
RULE_REGISTRY
|
|
303
274
|
};
|
package/docs/CHANGELOG.md
CHANGED
|
@@ -20,10 +20,6 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|
|
20
20
|
|
|
21
21
|
### Added
|
|
22
22
|
- Expanded AST static analysis engine with Pillars 8 to 11 (`cli/audit/extended-visitors.js`): added automated rules and visitors for Accessibility & Semantic Integrity (`A11Y_CLICKABLE_NON_SEMANTIC`, `A11Y_IMAGE_MISSING_ALT`), Security & Content Safety (`SECURITY_RAW_HTML_INJECTION`, `SECURITY_HARDCODED_SECRET`), Testing Discipline (`TEST_FAKE_GREEN`, `TEST_MISSING_COLOCATED`), and Naming Conventions (`NAMING_BARE_BOOLEAN`, `NAMING_HANDLER_PREFIX`).
|
|
23
|
-
- Implemented nested bullet tree path-chain formatter (`formatGroupedPromptViolations` in `cli/audit/prompts.js` and `renderGroupedViolationsTerminal` in `cli/audit/reporter-grouping.js`), clustering violations by rule and rendering folder hierarchy steps as indented bullet chains with `📁` folder emojis and ANSI severity colors (`📁 app/` -> `📁 components/` -> `📁 molecules/` -> leaf files with line hits) to eliminate boilerplate repetitions and slash AI prompt token consumption by up to 85%.
|
|
24
|
-
- Consolidated monolith refactoring action directives across `buildHotspotsPrompt`, `buildGradeFPrompt`, `buildGradeDPrompt`, and `buildGradeCPrompt`, stating action requirements once per section.
|
|
25
|
-
- Added `{ excludeAiSlop }` filter options to grade prompt builders to prevent duplicate slop violation listings in `buildMasterPrompt`.
|
|
26
|
-
- Added `{ includePrompt: false }` flag to `formatHotspotsSection` and `formatAiSlopSection` when rendered within full terminal report (`cli/audit/reporter.js`), preventing mid-report prompt box duplication before the master prompt.
|
|
27
23
|
- Added AI Agent refactoring prompt generator for AI Slop & Authenticity (`buildAiSlopPrompt` in `cli/audit/prompts.js`), generating surgical instructions to eliminate conversational residue, lazy placeholders, echo comments, shallow catch blocks, and reinvented utilities.
|
|
28
24
|
- Added AI Agent refactoring prompt generator for Top Refactoring Hotspots (`buildHotspotsPrompt` in `cli/audit/prompts.js`), providing phased decomposition plans for files exceeding line budgets.
|
|
29
25
|
- Integrated AI Slop and Hotspots prompt boxes into report sections (`formatAiSlopSection`, `formatHotspotsSection` in `cli/audit/reporter-sections.js`), composite master prompt (`buildMasterPrompt`), and interactive navigator inspection views (`cli/navigator-actions.js`, `cli/navigator.js`, `cli/navigator-menu.js`).
|