@kevinrabun/judges 3.50.0 → 3.52.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/CHANGELOG.md +24 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +112 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/ai-gate.d.ts +8 -0
- package/dist/commands/ai-gate.d.ts.map +1 -0
- package/dist/commands/ai-gate.js +213 -0
- package/dist/commands/ai-gate.js.map +1 -0
- package/dist/commands/ai-output-compare.d.ts +9 -0
- package/dist/commands/ai-output-compare.d.ts.map +1 -0
- package/dist/commands/ai-output-compare.js +203 -0
- package/dist/commands/ai-output-compare.js.map +1 -0
- package/dist/commands/ai-pattern-trend.d.ts +9 -0
- package/dist/commands/ai-pattern-trend.d.ts.map +1 -0
- package/dist/commands/ai-pattern-trend.js +224 -0
- package/dist/commands/ai-pattern-trend.js.map +1 -0
- package/dist/commands/arch-audit.d.ts +9 -0
- package/dist/commands/arch-audit.d.ts.map +1 -0
- package/dist/commands/arch-audit.js +284 -0
- package/dist/commands/arch-audit.js.map +1 -0
- package/dist/commands/chat-notify.d.ts +9 -0
- package/dist/commands/chat-notify.d.ts.map +1 -0
- package/dist/commands/chat-notify.js +259 -0
- package/dist/commands/chat-notify.js.map +1 -0
- package/dist/commands/clarity-score.d.ts +9 -0
- package/dist/commands/clarity-score.d.ts.map +1 -0
- package/dist/commands/clarity-score.js +261 -0
- package/dist/commands/clarity-score.js.map +1 -0
- package/dist/commands/design-audit.d.ts +9 -0
- package/dist/commands/design-audit.d.ts.map +1 -0
- package/dist/commands/design-audit.js +302 -0
- package/dist/commands/design-audit.js.map +1 -0
- package/dist/commands/hallucination-score.d.ts +9 -0
- package/dist/commands/hallucination-score.d.ts.map +1 -0
- package/dist/commands/hallucination-score.js +317 -0
- package/dist/commands/hallucination-score.js.map +1 -0
- package/dist/commands/impact-scan.d.ts +9 -0
- package/dist/commands/impact-scan.d.ts.map +1 -0
- package/dist/commands/impact-scan.js +282 -0
- package/dist/commands/impact-scan.js.map +1 -0
- package/dist/commands/judge-learn.d.ts +9 -0
- package/dist/commands/judge-learn.d.ts.map +1 -0
- package/dist/commands/judge-learn.js +218 -0
- package/dist/commands/judge-learn.js.map +1 -0
- package/dist/commands/model-report.d.ts +9 -0
- package/dist/commands/model-report.d.ts.map +1 -0
- package/dist/commands/model-report.js +195 -0
- package/dist/commands/model-report.js.map +1 -0
- package/dist/commands/remediation-lib.d.ts +9 -0
- package/dist/commands/remediation-lib.d.ts.map +1 -0
- package/dist/commands/remediation-lib.js +266 -0
- package/dist/commands/remediation-lib.js.map +1 -0
- package/dist/commands/test-suggest.d.ts +9 -0
- package/dist/commands/test-suggest.d.ts.map +1 -0
- package/dist/commands/test-suggest.js +248 -0
- package/dist/commands/test-suggest.js.map +1 -0
- package/dist/commands/trust-adaptive.d.ts +9 -0
- package/dist/commands/trust-adaptive.d.ts.map +1 -0
- package/dist/commands/trust-adaptive.js +194 -0
- package/dist/commands/trust-adaptive.js.map +1 -0
- package/dist/commands/vendor-lock-detect.d.ts +8 -0
- package/dist/commands/vendor-lock-detect.d.ts.map +1 -0
- package/dist/commands/vendor-lock-detect.js +289 -0
- package/dist/commands/vendor-lock-detect.js.map +1 -0
- package/dist/commands/watch-judge.d.ts +8 -0
- package/dist/commands/watch-judge.d.ts.map +1 -0
- package/dist/commands/watch-judge.js +180 -0
- package/dist/commands/watch-judge.js.map +1 -0
- package/package.json +1 -1
- package/server.json +2 -2
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chat-notify — publish findings to Slack, Teams, Discord, or custom
|
|
3
|
+
* webhooks with rich formatting and team mention routing.
|
|
4
|
+
*
|
|
5
|
+
* DataAdapter-friendly: webhook URLs come from local config,
|
|
6
|
+
* no data stored server-side.
|
|
7
|
+
*/
|
|
8
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync } from "fs";
|
|
9
|
+
import { join } from "path";
|
|
10
|
+
// ─── Config ─────────────────────────────────────────────────────────────────
|
|
11
|
+
const CONFIG_DIR = ".judges-notify";
|
|
12
|
+
const CONFIG_FILE = join(CONFIG_DIR, "webhooks.json");
|
|
13
|
+
function ensureDir() {
|
|
14
|
+
if (!existsSync(CONFIG_DIR))
|
|
15
|
+
mkdirSync(CONFIG_DIR, { recursive: true });
|
|
16
|
+
}
|
|
17
|
+
function loadWebhooks() {
|
|
18
|
+
if (!existsSync(CONFIG_FILE))
|
|
19
|
+
return [];
|
|
20
|
+
try {
|
|
21
|
+
return JSON.parse(readFileSync(CONFIG_FILE, "utf-8"));
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return [];
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function saveWebhooks(webhooks) {
|
|
28
|
+
ensureDir();
|
|
29
|
+
writeFileSync(CONFIG_FILE, JSON.stringify(webhooks, null, 2));
|
|
30
|
+
}
|
|
31
|
+
// ─── Formatters ─────────────────────────────────────────────────────────────
|
|
32
|
+
function formatSlack(payload) {
|
|
33
|
+
const color = payload.criticalCount > 0 ? "#e74c3c" : payload.score < 60 ? "#f39c12" : "#2ecc71";
|
|
34
|
+
return {
|
|
35
|
+
attachments: [
|
|
36
|
+
{
|
|
37
|
+
color,
|
|
38
|
+
title: `🔍 Judges Panel: ${payload.subject}`,
|
|
39
|
+
text: payload.body,
|
|
40
|
+
fields: [
|
|
41
|
+
{ title: "Score", value: `${payload.score}/100`, short: true },
|
|
42
|
+
{ title: "Findings", value: String(payload.findings), short: true },
|
|
43
|
+
{ title: "Critical", value: String(payload.criticalCount), short: true },
|
|
44
|
+
],
|
|
45
|
+
footer: "Judges Panel",
|
|
46
|
+
ts: Math.floor(Date.now() / 1000),
|
|
47
|
+
},
|
|
48
|
+
],
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
function formatTeams(payload) {
|
|
52
|
+
const color = payload.criticalCount > 0 ? "FF0000" : payload.score < 60 ? "FFC107" : "28A745";
|
|
53
|
+
return {
|
|
54
|
+
"@type": "MessageCard",
|
|
55
|
+
"@context": "http://schema.org/extensions",
|
|
56
|
+
themeColor: color,
|
|
57
|
+
summary: `Judges Panel: ${payload.subject}`,
|
|
58
|
+
sections: [
|
|
59
|
+
{
|
|
60
|
+
activityTitle: `🔍 ${payload.subject}`,
|
|
61
|
+
facts: [
|
|
62
|
+
{ name: "Score", value: `${payload.score}/100` },
|
|
63
|
+
{ name: "Findings", value: String(payload.findings) },
|
|
64
|
+
{ name: "Critical", value: String(payload.criticalCount) },
|
|
65
|
+
],
|
|
66
|
+
text: payload.body,
|
|
67
|
+
},
|
|
68
|
+
],
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
function formatDiscord(payload) {
|
|
72
|
+
const color = payload.criticalCount > 0 ? 0xe74c3c : payload.score < 60 ? 0xf39c12 : 0x2ecc71;
|
|
73
|
+
return {
|
|
74
|
+
embeds: [
|
|
75
|
+
{
|
|
76
|
+
title: `🔍 Judges Panel: ${payload.subject}`,
|
|
77
|
+
description: payload.body,
|
|
78
|
+
color,
|
|
79
|
+
fields: [
|
|
80
|
+
{ name: "Score", value: `${payload.score}/100`, inline: true },
|
|
81
|
+
{ name: "Findings", value: String(payload.findings), inline: true },
|
|
82
|
+
{ name: "Critical", value: String(payload.criticalCount), inline: true },
|
|
83
|
+
],
|
|
84
|
+
timestamp: new Date().toISOString(),
|
|
85
|
+
},
|
|
86
|
+
],
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
function formatPayload(webhook, payload) {
|
|
90
|
+
switch (webhook.type) {
|
|
91
|
+
case "slack":
|
|
92
|
+
return JSON.stringify(formatSlack(payload));
|
|
93
|
+
case "teams":
|
|
94
|
+
return JSON.stringify(formatTeams(payload));
|
|
95
|
+
case "discord":
|
|
96
|
+
return JSON.stringify(formatDiscord(payload));
|
|
97
|
+
default:
|
|
98
|
+
return JSON.stringify(payload);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
// ─── CLI ────────────────────────────────────────────────────────────────────
|
|
102
|
+
export function runChatNotify(argv) {
|
|
103
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
104
|
+
console.log(`
|
|
105
|
+
judges chat-notify — Publish findings to chat platforms
|
|
106
|
+
|
|
107
|
+
Usage:
|
|
108
|
+
judges chat-notify --add --name "team-slack" --type slack --url <webhook-url>
|
|
109
|
+
judges chat-notify --send --subject "PR #42" --score 65 --findings 5 --critical 1
|
|
110
|
+
judges chat-notify --send --file eval-output.json
|
|
111
|
+
judges chat-notify --list
|
|
112
|
+
judges chat-notify --preview --name "team-slack" --subject "test"
|
|
113
|
+
judges chat-notify --remove --name "team-slack"
|
|
114
|
+
|
|
115
|
+
Options:
|
|
116
|
+
--add Add webhook configuration
|
|
117
|
+
--name <name> Webhook name
|
|
118
|
+
--type <platform> Platform: slack, teams, discord, custom
|
|
119
|
+
--url <webhook-url> Webhook URL (stored locally in .judges-notify/)
|
|
120
|
+
--channel <name> Channel name (for display)
|
|
121
|
+
--mention <user> Mention on critical findings
|
|
122
|
+
--min-severity <sev> Minimum severity to notify (default: medium)
|
|
123
|
+
--send Send notification
|
|
124
|
+
--subject <text> Notification subject
|
|
125
|
+
--score <n> Score (0-100)
|
|
126
|
+
--findings <n> Finding count
|
|
127
|
+
--critical <n> Critical finding count
|
|
128
|
+
--file <path> Import from evaluation output
|
|
129
|
+
--preview Preview formatted message (no send)
|
|
130
|
+
--list List configured webhooks
|
|
131
|
+
--remove Remove webhook
|
|
132
|
+
--format json JSON output
|
|
133
|
+
--help, -h Show this help
|
|
134
|
+
|
|
135
|
+
Platforms: Slack (attachments), Teams (MessageCard), Discord (embeds), Custom (raw JSON)
|
|
136
|
+
Webhook URLs are stored locally — no data sent to Judges servers.
|
|
137
|
+
`);
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
|
|
141
|
+
const isAdd = argv.includes("--add");
|
|
142
|
+
const isSend = argv.includes("--send");
|
|
143
|
+
const isList = argv.includes("--list");
|
|
144
|
+
const isPreview = argv.includes("--preview");
|
|
145
|
+
const isRemove = argv.includes("--remove");
|
|
146
|
+
const name = argv.find((_a, i) => argv[i - 1] === "--name") || "";
|
|
147
|
+
const webhookType = (argv.find((_a, i) => argv[i - 1] === "--type") ||
|
|
148
|
+
"custom");
|
|
149
|
+
const url = argv.find((_a, i) => argv[i - 1] === "--url") || "";
|
|
150
|
+
const channel = argv.find((_a, i) => argv[i - 1] === "--channel") || "";
|
|
151
|
+
const mention = argv.find((_a, i) => argv[i - 1] === "--mention") || "";
|
|
152
|
+
const subject = argv.find((_a, i) => argv[i - 1] === "--subject") || "Judges Panel Evaluation";
|
|
153
|
+
const score = parseInt(argv.find((_a, i) => argv[i - 1] === "--score") || "0");
|
|
154
|
+
const findings = parseInt(argv.find((_a, i) => argv[i - 1] === "--findings") || "0");
|
|
155
|
+
const critical = parseInt(argv.find((_a, i) => argv[i - 1] === "--critical") || "0");
|
|
156
|
+
const fileArg = argv.find((_a, i) => argv[i - 1] === "--file");
|
|
157
|
+
if (isAdd) {
|
|
158
|
+
if (!name || !url) {
|
|
159
|
+
console.error(" --name and --url are required for --add");
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
const webhooks = loadWebhooks();
|
|
163
|
+
if (webhooks.some((w) => w.name === name)) {
|
|
164
|
+
console.error(` Webhook "${name}" already exists. Remove first.`);
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
webhooks.push({ name, url, type: webhookType, channel, mentionOnCritical: mention || undefined });
|
|
168
|
+
saveWebhooks(webhooks);
|
|
169
|
+
console.log(` ✅ Added ${webhookType} webhook "${name}"`);
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
if (isRemove) {
|
|
173
|
+
if (!name) {
|
|
174
|
+
console.error(" --name is required");
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
const webhooks = loadWebhooks().filter((w) => w.name !== name);
|
|
178
|
+
saveWebhooks(webhooks);
|
|
179
|
+
console.log(` ✅ Removed webhook "${name}"`);
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
if (isList) {
|
|
183
|
+
const webhooks = loadWebhooks();
|
|
184
|
+
if (format === "json") {
|
|
185
|
+
console.log(JSON.stringify(webhooks, null, 2));
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
console.log(`\n Configured Webhooks — ${webhooks.length}\n ──────────────────────────`);
|
|
189
|
+
for (const w of webhooks) {
|
|
190
|
+
const masked = w.url.replace(/(.{20}).*(.{6})/, "$1***$2");
|
|
191
|
+
console.log(` 📡 ${w.name} (${w.type}) → ${masked}${w.channel ? ` #${w.channel}` : ""}`);
|
|
192
|
+
}
|
|
193
|
+
if (webhooks.length === 0)
|
|
194
|
+
console.log(" No webhooks configured. Use --add to add one.");
|
|
195
|
+
console.log("");
|
|
196
|
+
}
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
if (isSend || isPreview) {
|
|
200
|
+
const webhooks = loadWebhooks();
|
|
201
|
+
const targets = name ? webhooks.filter((w) => w.name === name) : webhooks;
|
|
202
|
+
if (targets.length === 0) {
|
|
203
|
+
console.error(" No webhooks configured. Use --add first.");
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
let payloadScore = score;
|
|
207
|
+
let payloadFindings = findings;
|
|
208
|
+
let payloadCritical = critical;
|
|
209
|
+
let body = `Score: ${score}/100 | ${findings} findings | ${critical} critical`;
|
|
210
|
+
if (fileArg && existsSync(fileArg)) {
|
|
211
|
+
try {
|
|
212
|
+
const data = JSON.parse(readFileSync(fileArg, "utf-8"));
|
|
213
|
+
payloadScore = data.overallScore || score;
|
|
214
|
+
payloadFindings = Array.isArray(data.findings) ? data.findings.length : findings;
|
|
215
|
+
payloadCritical = data.criticalCount || critical;
|
|
216
|
+
body = data.summary || body;
|
|
217
|
+
}
|
|
218
|
+
catch {
|
|
219
|
+
/* use manual values */
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
for (const webhook of targets) {
|
|
223
|
+
const payload = {
|
|
224
|
+
platform: webhook.type,
|
|
225
|
+
channel: webhook.channel || "",
|
|
226
|
+
subject,
|
|
227
|
+
body,
|
|
228
|
+
findings: payloadFindings,
|
|
229
|
+
criticalCount: payloadCritical,
|
|
230
|
+
score: payloadScore,
|
|
231
|
+
};
|
|
232
|
+
const formatted = formatPayload(webhook, payload);
|
|
233
|
+
if (isPreview) {
|
|
234
|
+
console.log(`\n Preview for ${webhook.name} (${webhook.type}):\n`);
|
|
235
|
+
console.log(JSON.stringify(JSON.parse(formatted), null, 2));
|
|
236
|
+
}
|
|
237
|
+
else {
|
|
238
|
+
// In a real implementation, this would use fetch/https to POST
|
|
239
|
+
// Since we can't store/process data server-side, we output the curl command
|
|
240
|
+
console.log(`\n 📡 ${webhook.name} (${webhook.type}):`);
|
|
241
|
+
console.log(` curl -X POST -H "Content-Type: application/json" -d '${formatted}' "${webhook.url}"`);
|
|
242
|
+
if (webhook.mentionOnCritical && payloadCritical > 0) {
|
|
243
|
+
console.log(` ⚠ Critical findings — mention ${webhook.mentionOnCritical}`);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
console.log("");
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
// Default: show status
|
|
251
|
+
const webhooks = loadWebhooks();
|
|
252
|
+
console.log(`\n Chat Notify — ${webhooks.length} webhook(s) configured`);
|
|
253
|
+
if (webhooks.length > 0) {
|
|
254
|
+
for (const w of webhooks)
|
|
255
|
+
console.log(` 📡 ${w.name} (${w.type})`);
|
|
256
|
+
}
|
|
257
|
+
console.log(" Use --help for usage.\n");
|
|
258
|
+
}
|
|
259
|
+
//# sourceMappingURL=chat-notify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chat-notify.js","sourceRoot":"","sources":["../../src/commands/chat-notify.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Clarity score — measure code readability and self-documentation
|
|
3
|
+
* specifically for AI-generated code. Flags "correct but cryptic"
|
|
4
|
+
* patterns that need documentation investment.
|
|
5
|
+
*
|
|
6
|
+
* All analysis local.
|
|
7
|
+
*/
|
|
8
|
+
export declare function runClarityScore(argv: string[]): void;
|
|
9
|
+
//# sourceMappingURL=clarity-score.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clarity-score.d.ts","sourceRoot":"","sources":["../../src/commands/clarity-score.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAoLH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAqGpD"}
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Clarity score — measure code readability and self-documentation
|
|
3
|
+
* specifically for AI-generated code. Flags "correct but cryptic"
|
|
4
|
+
* patterns that need documentation investment.
|
|
5
|
+
*
|
|
6
|
+
* All analysis local.
|
|
7
|
+
*/
|
|
8
|
+
import { existsSync, readFileSync, readdirSync } from "fs";
|
|
9
|
+
import { join, extname } from "path";
|
|
10
|
+
// ─── Analysers ──────────────────────────────────────────────────────────────
|
|
11
|
+
function analyzeClarity(content) {
|
|
12
|
+
const lines = content.split("\n");
|
|
13
|
+
const nonEmpty = lines.filter((l) => l.trim().length > 0);
|
|
14
|
+
const metrics = [];
|
|
15
|
+
const suggestions = [];
|
|
16
|
+
// 1. Naming quality
|
|
17
|
+
const identifiers = content.match(/(?:const|let|var|function)\s+(\w+)/g) || [];
|
|
18
|
+
const shortNames = identifiers.filter((id) => {
|
|
19
|
+
const name = id.replace(/^(?:const|let|var|function)\s+/, "");
|
|
20
|
+
return name.length <= 2 && !["i", "j", "k", "x", "y", "id"].includes(name);
|
|
21
|
+
});
|
|
22
|
+
const namingScore = identifiers.length > 0 ? Math.max(0, 100 - (shortNames.length / identifiers.length) * 200) : 100;
|
|
23
|
+
metrics.push({ id: "naming", label: "Naming Quality", score: Math.round(namingScore), weight: 25 });
|
|
24
|
+
if (namingScore < 60)
|
|
25
|
+
suggestions.push("Use descriptive variable names — single-letter names reduce readability");
|
|
26
|
+
// 2. Comment coverage
|
|
27
|
+
const commentLines = lines.filter((l) => /^\s*(?:\/\/|\/?\*|#)/.test(l)).length;
|
|
28
|
+
const commentRatio = nonEmpty.length > 0 ? commentLines / nonEmpty.length : 0;
|
|
29
|
+
const commentScore = commentRatio >= 0.15 ? 100 : commentRatio >= 0.08 ? 70 : commentRatio >= 0.03 ? 40 : 10;
|
|
30
|
+
metrics.push({
|
|
31
|
+
id: "comments",
|
|
32
|
+
label: "Comment Coverage",
|
|
33
|
+
score: commentScore,
|
|
34
|
+
weight: 20,
|
|
35
|
+
detail: `${Math.round(commentRatio * 100)}% of lines`,
|
|
36
|
+
});
|
|
37
|
+
if (commentScore < 50)
|
|
38
|
+
suggestions.push("Add comments explaining the 'why' — not the 'what'");
|
|
39
|
+
// 3. Function length
|
|
40
|
+
const fnBodies = [];
|
|
41
|
+
let braceDepth = 0;
|
|
42
|
+
let fnStart = -1;
|
|
43
|
+
for (let i = 0; i < lines.length; i++) {
|
|
44
|
+
if (/\bfunction\b|=>\s*{/.test(lines[i]) && fnStart === -1)
|
|
45
|
+
fnStart = i;
|
|
46
|
+
braceDepth += (lines[i].match(/{/g) || []).length;
|
|
47
|
+
braceDepth -= (lines[i].match(/}/g) || []).length;
|
|
48
|
+
if (fnStart >= 0 && braceDepth <= 0) {
|
|
49
|
+
fnBodies.push(i - fnStart + 1);
|
|
50
|
+
fnStart = -1;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
const avgFnLength = fnBodies.length > 0 ? fnBodies.reduce((a, b) => a + b, 0) / fnBodies.length : 0;
|
|
54
|
+
const fnLengthScore = avgFnLength <= 15 ? 100 : avgFnLength <= 30 ? 70 : avgFnLength <= 50 ? 40 : 10;
|
|
55
|
+
metrics.push({
|
|
56
|
+
id: "function-length",
|
|
57
|
+
label: "Function Length",
|
|
58
|
+
score: fnLengthScore,
|
|
59
|
+
weight: 15,
|
|
60
|
+
detail: `avg ${Math.round(avgFnLength)} lines`,
|
|
61
|
+
});
|
|
62
|
+
if (fnLengthScore < 50)
|
|
63
|
+
suggestions.push("Break long functions into smaller, focused functions");
|
|
64
|
+
// 4. Line complexity
|
|
65
|
+
const longLines = nonEmpty.filter((l) => l.length > 100).length;
|
|
66
|
+
const longLineRatio = nonEmpty.length > 0 ? longLines / nonEmpty.length : 0;
|
|
67
|
+
const lineComplexityScore = longLineRatio <= 0.05 ? 100 : longLineRatio <= 0.15 ? 70 : longLineRatio <= 0.3 ? 40 : 10;
|
|
68
|
+
metrics.push({
|
|
69
|
+
id: "line-length",
|
|
70
|
+
label: "Line Length",
|
|
71
|
+
score: lineComplexityScore,
|
|
72
|
+
weight: 10,
|
|
73
|
+
detail: `${longLines} lines > 100 chars`,
|
|
74
|
+
});
|
|
75
|
+
if (lineComplexityScore < 50)
|
|
76
|
+
suggestions.push("Break long lines for readability");
|
|
77
|
+
// 5. Nesting depth
|
|
78
|
+
let maxNesting = 0;
|
|
79
|
+
let currentNesting = 0;
|
|
80
|
+
for (const line of lines) {
|
|
81
|
+
currentNesting += (line.match(/{/g) || []).length;
|
|
82
|
+
maxNesting = Math.max(maxNesting, currentNesting);
|
|
83
|
+
currentNesting -= (line.match(/}/g) || []).length;
|
|
84
|
+
}
|
|
85
|
+
const nestingScore = maxNesting <= 3 ? 100 : maxNesting <= 5 ? 70 : maxNesting <= 7 ? 40 : 10;
|
|
86
|
+
metrics.push({
|
|
87
|
+
id: "nesting",
|
|
88
|
+
label: "Nesting Depth",
|
|
89
|
+
score: nestingScore,
|
|
90
|
+
weight: 15,
|
|
91
|
+
detail: `max ${maxNesting} levels`,
|
|
92
|
+
});
|
|
93
|
+
if (nestingScore < 50)
|
|
94
|
+
suggestions.push("Reduce nesting depth with early returns and guard clauses");
|
|
95
|
+
// 6. Magic numbers/strings
|
|
96
|
+
const magicNumbers = content.match(/(?<!\w)\d{3,}(?!\w)/g) || [];
|
|
97
|
+
const inlineStrings = content.match(/["'][^"']{20,}["']/g) || [];
|
|
98
|
+
const magicCount = magicNumbers.length + inlineStrings.length;
|
|
99
|
+
const magicScore = magicCount <= 2 ? 100 : magicCount <= 5 ? 70 : magicCount <= 10 ? 40 : 10;
|
|
100
|
+
metrics.push({
|
|
101
|
+
id: "magic-values",
|
|
102
|
+
label: "Named Constants",
|
|
103
|
+
score: magicScore,
|
|
104
|
+
weight: 10,
|
|
105
|
+
detail: `${magicCount} magic values`,
|
|
106
|
+
});
|
|
107
|
+
if (magicScore < 50)
|
|
108
|
+
suggestions.push("Extract magic numbers and long strings into named constants");
|
|
109
|
+
// 7. Consistent style
|
|
110
|
+
const semicolons = (content.match(/;\s*$/gm) || []).length;
|
|
111
|
+
const noSemicolons = nonEmpty.length - semicolons;
|
|
112
|
+
const semiRatio = nonEmpty.length > 0 ? Math.max(semicolons, noSemicolons) / nonEmpty.length : 1;
|
|
113
|
+
const styleScore = semiRatio >= 0.8 ? 100 : semiRatio >= 0.6 ? 60 : 30;
|
|
114
|
+
metrics.push({ id: "style-consistency", label: "Style Consistency", score: styleScore, weight: 5 });
|
|
115
|
+
if (styleScore < 60)
|
|
116
|
+
suggestions.push("Use consistent code style (semicolons, quotes, indentation)");
|
|
117
|
+
return { metrics, suggestions };
|
|
118
|
+
}
|
|
119
|
+
function computeOverallScore(metrics) {
|
|
120
|
+
const totalWeight = metrics.reduce((sum, m) => sum + m.weight, 0);
|
|
121
|
+
const weighted = metrics.reduce((sum, m) => sum + m.score * m.weight, 0);
|
|
122
|
+
return totalWeight > 0 ? Math.round(weighted / totalWeight) : 0;
|
|
123
|
+
}
|
|
124
|
+
function grade(score) {
|
|
125
|
+
if (score >= 90)
|
|
126
|
+
return "A";
|
|
127
|
+
if (score >= 80)
|
|
128
|
+
return "B";
|
|
129
|
+
if (score >= 70)
|
|
130
|
+
return "C";
|
|
131
|
+
if (score >= 60)
|
|
132
|
+
return "D";
|
|
133
|
+
return "F";
|
|
134
|
+
}
|
|
135
|
+
// ─── Scanner ────────────────────────────────────────────────────────────────
|
|
136
|
+
const SKIP = new Set(["node_modules", ".git", "dist", "build", "coverage"]);
|
|
137
|
+
const EXTS = new Set([".ts", ".js", ".py", ".java", ".cs", ".go", ".rb", ".php", ".rs"]);
|
|
138
|
+
function collectFiles(dir) {
|
|
139
|
+
const result = [];
|
|
140
|
+
function walk(d) {
|
|
141
|
+
let entries;
|
|
142
|
+
try {
|
|
143
|
+
entries = readdirSync(d);
|
|
144
|
+
}
|
|
145
|
+
catch {
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
for (const name of entries) {
|
|
149
|
+
if (SKIP.has(name) || name.startsWith("."))
|
|
150
|
+
continue;
|
|
151
|
+
const full = join(d, name);
|
|
152
|
+
try {
|
|
153
|
+
const sub = readdirSync(full);
|
|
154
|
+
void sub;
|
|
155
|
+
walk(full);
|
|
156
|
+
}
|
|
157
|
+
catch {
|
|
158
|
+
if (EXTS.has(extname(name).toLowerCase()))
|
|
159
|
+
result.push(full);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
walk(dir);
|
|
164
|
+
return result;
|
|
165
|
+
}
|
|
166
|
+
// ─── CLI ────────────────────────────────────────────────────────────────────
|
|
167
|
+
export function runClarityScore(argv) {
|
|
168
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
169
|
+
console.log(`
|
|
170
|
+
judges clarity-score — Measure code readability and self-documentation
|
|
171
|
+
|
|
172
|
+
Usage:
|
|
173
|
+
judges clarity-score <file-or-dir>
|
|
174
|
+
judges clarity-score src/ --min-grade C
|
|
175
|
+
|
|
176
|
+
Options:
|
|
177
|
+
--min-grade <A-F> Only show files at or below this grade
|
|
178
|
+
--format json JSON output
|
|
179
|
+
--help, -h Show this help
|
|
180
|
+
|
|
181
|
+
Metrics:
|
|
182
|
+
• Naming quality (descriptive vs. short names)
|
|
183
|
+
• Comment coverage (ratio of comment lines)
|
|
184
|
+
• Function length (average lines per function)
|
|
185
|
+
• Line length (lines exceeding 100 characters)
|
|
186
|
+
• Nesting depth (maximum brace depth)
|
|
187
|
+
• Named constants (magic numbers/strings)
|
|
188
|
+
• Style consistency (semicolon/formatting uniformity)
|
|
189
|
+
`);
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
|
|
193
|
+
const minGrade = argv.find((_a, i) => argv[i - 1] === "--min-grade");
|
|
194
|
+
const target = argv.find((a) => !a.startsWith("--") && !argv[argv.indexOf(a) - 1]?.startsWith("--")) || ".";
|
|
195
|
+
if (!existsSync(target)) {
|
|
196
|
+
console.error(` Path not found: ${target}`);
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
let files;
|
|
200
|
+
try {
|
|
201
|
+
readdirSync(target);
|
|
202
|
+
files = collectFiles(target);
|
|
203
|
+
}
|
|
204
|
+
catch {
|
|
205
|
+
files = [target];
|
|
206
|
+
}
|
|
207
|
+
const results = [];
|
|
208
|
+
for (const f of files) {
|
|
209
|
+
let content;
|
|
210
|
+
try {
|
|
211
|
+
content = readFileSync(f, "utf-8");
|
|
212
|
+
}
|
|
213
|
+
catch {
|
|
214
|
+
continue;
|
|
215
|
+
}
|
|
216
|
+
const { metrics, suggestions } = analyzeClarity(content);
|
|
217
|
+
const overall = computeOverallScore(metrics);
|
|
218
|
+
results.push({ file: f, overallScore: overall, grade: grade(overall), metrics, suggestions });
|
|
219
|
+
}
|
|
220
|
+
let filtered = results;
|
|
221
|
+
if (minGrade) {
|
|
222
|
+
const gradeOrder = ["A", "B", "C", "D", "F"];
|
|
223
|
+
const minIdx = gradeOrder.indexOf(minGrade.toUpperCase());
|
|
224
|
+
if (minIdx >= 0)
|
|
225
|
+
filtered = results.filter((r) => gradeOrder.indexOf(r.grade) >= minIdx);
|
|
226
|
+
}
|
|
227
|
+
filtered.sort((a, b) => a.overallScore - b.overallScore);
|
|
228
|
+
if (format === "json") {
|
|
229
|
+
console.log(JSON.stringify({ files: filtered, scannedFiles: files.length, timestamp: new Date().toISOString() }, null, 2));
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
232
|
+
const avgScore = results.length > 0 ? Math.round(results.reduce((s, r) => s + r.overallScore, 0) / results.length) : 0;
|
|
233
|
+
console.log(`\n Clarity Score — ${files.length} files`);
|
|
234
|
+
console.log(` Average: ${avgScore}/100 (${grade(avgScore)})\n ──────────────────────────`);
|
|
235
|
+
if (filtered.length === 0) {
|
|
236
|
+
console.log(` ✅ All files meet clarity threshold\n`);
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
for (const r of filtered.slice(0, 20)) {
|
|
240
|
+
const icon = r.grade === "A" ? "🟢" : r.grade === "B" ? "🟢" : r.grade === "C" ? "🟡" : r.grade === "D" ? "🟠" : "🔴";
|
|
241
|
+
console.log(`\n ${icon} ${r.file} — ${r.overallScore}/100 (${r.grade})`);
|
|
242
|
+
for (const m of r.metrics) {
|
|
243
|
+
const mIcon = m.score >= 70 ? "✓" : m.score >= 40 ? "~" : "✗";
|
|
244
|
+
console.log(` ${mIcon} ${m.label.padEnd(20)} ${String(m.score).padEnd(4)} ${m.detail || ""}`);
|
|
245
|
+
}
|
|
246
|
+
if (r.suggestions.length > 0) {
|
|
247
|
+
console.log(` Suggestions:`);
|
|
248
|
+
for (const s of r.suggestions)
|
|
249
|
+
console.log(` → ${s}`);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
if (filtered.length > 20)
|
|
253
|
+
console.log(` ... and ${filtered.length - 20} more files`);
|
|
254
|
+
// Grade distribution
|
|
255
|
+
const dist = { A: 0, B: 0, C: 0, D: 0, F: 0 };
|
|
256
|
+
for (const r of results)
|
|
257
|
+
dist[r.grade]++;
|
|
258
|
+
console.log(`\n Distribution: A:${dist.A} B:${dist.B} C:${dist.C} D:${dist.D} F:${dist.F}\n`);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
//# sourceMappingURL=clarity-score.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clarity-score.js","sourceRoot":"","sources":["../../src/commands/clarity-score.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Design audit — detect AI-generated code that breaks project
|
|
3
|
+
* conventions, introduces unnecessary abstractions, or creates
|
|
4
|
+
* architectural deviation from the baseline.
|
|
5
|
+
*
|
|
6
|
+
* All analysis local.
|
|
7
|
+
*/
|
|
8
|
+
export declare function runDesignAudit(argv: string[]): void;
|
|
9
|
+
//# sourceMappingURL=design-audit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"design-audit.d.ts","sourceRoot":"","sources":["../../src/commands/design-audit.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AA4PH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA6GnD"}
|