@kevinrabun/judges 3.69.0 → 3.70.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.
Files changed (38) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +56 -0
  4. package/dist/cli.js.map +1 -1
  5. package/dist/commands/finding-impact.d.ts +5 -0
  6. package/dist/commands/finding-impact.d.ts.map +1 -0
  7. package/dist/commands/finding-impact.js +136 -0
  8. package/dist/commands/finding-impact.js.map +1 -0
  9. package/dist/commands/review-archive.d.ts +5 -0
  10. package/dist/commands/review-archive.d.ts.map +1 -0
  11. package/dist/commands/review-archive.js +136 -0
  12. package/dist/commands/review-archive.js.map +1 -0
  13. package/dist/commands/review-ci-status.d.ts +5 -0
  14. package/dist/commands/review-ci-status.d.ts.map +1 -0
  15. package/dist/commands/review-ci-status.js +201 -0
  16. package/dist/commands/review-ci-status.js.map +1 -0
  17. package/dist/commands/review-custom-prompt.d.ts +5 -0
  18. package/dist/commands/review-custom-prompt.d.ts.map +1 -0
  19. package/dist/commands/review-custom-prompt.js +171 -0
  20. package/dist/commands/review-custom-prompt.js.map +1 -0
  21. package/dist/commands/review-diff-context.d.ts +5 -0
  22. package/dist/commands/review-diff-context.d.ts.map +1 -0
  23. package/dist/commands/review-diff-context.js +159 -0
  24. package/dist/commands/review-diff-context.js.map +1 -0
  25. package/dist/commands/review-tag.d.ts +5 -0
  26. package/dist/commands/review-tag.d.ts.map +1 -0
  27. package/dist/commands/review-tag.js +137 -0
  28. package/dist/commands/review-tag.js.map +1 -0
  29. package/dist/commands/review-team-summary.d.ts +5 -0
  30. package/dist/commands/review-team-summary.d.ts.map +1 -0
  31. package/dist/commands/review-team-summary.js +156 -0
  32. package/dist/commands/review-team-summary.js.map +1 -0
  33. package/dist/commands/review-whitelist.d.ts +5 -0
  34. package/dist/commands/review-whitelist.d.ts.map +1 -0
  35. package/dist/commands/review-whitelist.js +159 -0
  36. package/dist/commands/review-whitelist.js.map +1 -0
  37. package/package.json +1 -1
  38. package/server.json +2 -2
@@ -0,0 +1,171 @@
1
+ /**
2
+ * Review-custom-prompt — Customize review prompts for project-specific needs.
3
+ */
4
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
5
+ import { join, dirname } from "path";
6
+ // ─── Storage ────────────────────────────────────────────────────────────────
7
+ const PROMPT_FILE = join(".judges", "custom-prompts.json");
8
+ function loadPrompts() {
9
+ if (!existsSync(PROMPT_FILE))
10
+ return { version: "1.0.0", prompts: [] };
11
+ try {
12
+ return JSON.parse(readFileSync(PROMPT_FILE, "utf-8"));
13
+ }
14
+ catch {
15
+ return { version: "1.0.0", prompts: [] };
16
+ }
17
+ }
18
+ function savePrompts(store) {
19
+ mkdirSync(dirname(PROMPT_FILE), { recursive: true });
20
+ writeFileSync(PROMPT_FILE, JSON.stringify(store, null, 2), "utf-8");
21
+ }
22
+ function generateId() {
23
+ return `prompt-${Date.now().toString(36)}`;
24
+ }
25
+ // ─── Built-in Templates ─────────────────────────────────────────────────────
26
+ const BUILTIN_TEMPLATES = {
27
+ security: "Focus on security vulnerabilities: injection, XSS, CSRF, auth bypass, secrets exposure.",
28
+ performance: "Focus on performance issues: N+1 queries, memory leaks, unnecessary allocations, blocking I/O.",
29
+ "api-design": "Focus on API design: REST conventions, error handling, input validation, response formats.",
30
+ accessibility: "Focus on accessibility: ARIA labels, keyboard navigation, screen reader support.",
31
+ "error-handling": "Focus on error handling: try/catch usage, error propagation, user-facing messages.",
32
+ };
33
+ // ─── CLI ────────────────────────────────────────────────────────────────────
34
+ export function runReviewCustomPrompt(argv) {
35
+ if (argv.includes("--help") || argv.includes("-h")) {
36
+ console.log(`
37
+ judges review-custom-prompt — Customize review prompts for project needs
38
+
39
+ Usage:
40
+ judges review-custom-prompt add --name "API Review" --template "Focus on REST conventions" --lang typescript
41
+ judges review-custom-prompt list
42
+ judges review-custom-prompt show --name "API Review"
43
+ judges review-custom-prompt remove --id prompt-abc123
44
+ judges review-custom-prompt templates Show built-in templates
45
+ judges review-custom-prompt clear
46
+
47
+ Subcommands:
48
+ add Add a custom prompt
49
+ list List all custom prompts
50
+ show Show a specific prompt
51
+ remove Remove a custom prompt
52
+ templates Show built-in templates
53
+ clear Clear all custom prompts
54
+
55
+ Options:
56
+ --name <name> Prompt name
57
+ --template <text> Prompt template text
58
+ --desc <text> Description
59
+ --lang <language> Target language
60
+ --id <id> Prompt ID
61
+ --format json JSON output
62
+ --help, -h Show this help
63
+
64
+ Custom prompts stored in .judges/custom-prompts.json.
65
+ `);
66
+ return;
67
+ }
68
+ const subcommand = argv.find((a) => ["add", "list", "show", "remove", "templates", "clear"].includes(a)) || "list";
69
+ const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
70
+ const store = loadPrompts();
71
+ if (subcommand === "templates") {
72
+ if (format === "json") {
73
+ console.log(JSON.stringify(BUILTIN_TEMPLATES, null, 2));
74
+ return;
75
+ }
76
+ console.log("\nBuilt-in Prompt Templates:");
77
+ console.log("─".repeat(60));
78
+ for (const [name, template] of Object.entries(BUILTIN_TEMPLATES)) {
79
+ console.log(` ${name.padEnd(20)} ${template.slice(0, 60)}...`);
80
+ }
81
+ console.log("─".repeat(60));
82
+ return;
83
+ }
84
+ if (subcommand === "add") {
85
+ const name = argv.find((_a, i) => argv[i - 1] === "--name") || "";
86
+ const template = argv.find((_a, i) => argv[i - 1] === "--template") || "";
87
+ const desc = argv.find((_a, i) => argv[i - 1] === "--desc") || "";
88
+ const lang = argv.find((_a, i) => argv[i - 1] === "--lang") || "*";
89
+ if (!name || !template) {
90
+ console.error("Error: --name and --template are required.");
91
+ process.exitCode = 1;
92
+ return;
93
+ }
94
+ // Check for duplicate name
95
+ if (store.prompts.some((p) => p.name === name)) {
96
+ console.error(`Error: Prompt "${name}" already exists. Remove it first.`);
97
+ process.exitCode = 1;
98
+ return;
99
+ }
100
+ const id = generateId();
101
+ const now = new Date().toISOString();
102
+ store.prompts.push({ id, name, description: desc, template, language: lang, createdAt: now, updatedAt: now });
103
+ savePrompts(store);
104
+ console.log(`Added custom prompt "${name}" (${id}).`);
105
+ return;
106
+ }
107
+ if (subcommand === "show") {
108
+ const name = argv.find((_a, i) => argv[i - 1] === "--name") || "";
109
+ const prompt = store.prompts.find((p) => p.name === name);
110
+ if (!prompt) {
111
+ console.error(`Error: Prompt "${name}" not found.`);
112
+ process.exitCode = 1;
113
+ return;
114
+ }
115
+ if (format === "json") {
116
+ console.log(JSON.stringify(prompt, null, 2));
117
+ return;
118
+ }
119
+ console.log(`\nPrompt: ${prompt.name} (${prompt.id})`);
120
+ console.log("─".repeat(50));
121
+ console.log(` Language: ${prompt.language}`);
122
+ console.log(` Description: ${prompt.description || "(none)"}`);
123
+ console.log(` Created: ${prompt.createdAt.slice(0, 10)}`);
124
+ console.log(` Template:`);
125
+ console.log(` ${prompt.template}`);
126
+ console.log("─".repeat(50));
127
+ return;
128
+ }
129
+ if (subcommand === "remove") {
130
+ const id = argv.find((_a, i) => argv[i - 1] === "--id");
131
+ if (!id) {
132
+ console.error("Error: --id is required.");
133
+ process.exitCode = 1;
134
+ return;
135
+ }
136
+ const before = store.prompts.length;
137
+ store.prompts = store.prompts.filter((p) => p.id !== id);
138
+ if (store.prompts.length === before) {
139
+ console.error(`Error: Prompt "${id}" not found.`);
140
+ process.exitCode = 1;
141
+ return;
142
+ }
143
+ savePrompts(store);
144
+ console.log(`Removed prompt ${id}.`);
145
+ return;
146
+ }
147
+ if (subcommand === "clear") {
148
+ savePrompts({ version: "1.0.0", prompts: [] });
149
+ console.log("Custom prompts cleared.");
150
+ return;
151
+ }
152
+ // list
153
+ if (store.prompts.length === 0) {
154
+ console.log("No custom prompts. Use 'judges review-custom-prompt add' or 'templates' to get started.");
155
+ return;
156
+ }
157
+ if (format === "json") {
158
+ console.log(JSON.stringify(store.prompts, null, 2));
159
+ return;
160
+ }
161
+ console.log("\nCustom Prompts:");
162
+ console.log("─".repeat(70));
163
+ for (const p of store.prompts) {
164
+ console.log(` ${p.id} ${p.name.padEnd(25)} lang=${p.language} ${p.createdAt.slice(0, 10)}`);
165
+ if (p.description)
166
+ console.log(` ${p.description}`);
167
+ }
168
+ console.log("─".repeat(70));
169
+ console.log(` Total: ${store.prompts.length} prompt(s), ${Object.keys(BUILTIN_TEMPLATES).length} built-in template(s)`);
170
+ }
171
+ //# sourceMappingURL=review-custom-prompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-custom-prompt.js","sourceRoot":"","sources":["../../src/commands/review-custom-prompt.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Review-diff-context — Provide additional context around diff hunks for reviews.
3
+ */
4
+ export declare function runReviewDiffContext(argv: string[]): void;
5
+ //# sourceMappingURL=review-diff-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-diff-context.d.ts","sourceRoot":"","sources":["../../src/commands/review-diff-context.ts"],"names":[],"mappings":"AAAA;;GAEG;AAkGH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAwFzD"}
@@ -0,0 +1,159 @@
1
+ /**
2
+ * Review-diff-context — Provide additional context around diff hunks for reviews.
3
+ */
4
+ import { readFileSync, existsSync } from "fs";
5
+ import { execSync } from "child_process";
6
+ // ─── Diff Parsing ───────────────────────────────────────────────────────────
7
+ function parseDiffOutput(diffText, contextLines) {
8
+ const hunks = [];
9
+ const lines = diffText.split("\n");
10
+ let currentFile = "";
11
+ let hunkLines = [];
12
+ let hunkStart = 0;
13
+ for (const line of lines) {
14
+ if (line.startsWith("+++ b/")) {
15
+ currentFile = line.slice(6);
16
+ continue;
17
+ }
18
+ if (line.startsWith("--- "))
19
+ continue;
20
+ if (line.startsWith("@@ ")) {
21
+ // Flush previous hunk
22
+ if (hunkLines.length > 0 && currentFile) {
23
+ hunks.push(buildHunk(currentFile, hunkStart, hunkLines, contextLines));
24
+ hunkLines = [];
25
+ }
26
+ const match = line.match(/@@ -\d+(?:,\d+)? \+(\d+)/);
27
+ hunkStart = match ? parseInt(match[1], 10) : 1;
28
+ continue;
29
+ }
30
+ if (line.startsWith("diff --git")) {
31
+ // Flush previous hunk
32
+ if (hunkLines.length > 0 && currentFile) {
33
+ hunks.push(buildHunk(currentFile, hunkStart, hunkLines, contextLines));
34
+ hunkLines = [];
35
+ }
36
+ continue;
37
+ }
38
+ if (currentFile && (line.startsWith("+") || line.startsWith("-") || line.startsWith(" "))) {
39
+ hunkLines.push(line);
40
+ }
41
+ }
42
+ // Flush final hunk
43
+ if (hunkLines.length > 0 && currentFile) {
44
+ hunks.push(buildHunk(currentFile, hunkStart, hunkLines, contextLines));
45
+ }
46
+ return hunks;
47
+ }
48
+ function buildHunk(file, startLine, lines, contextLines) {
49
+ const content = lines.join("\n");
50
+ const endLine = startLine + lines.filter((l) => !l.startsWith("-")).length - 1;
51
+ const contextBefore = [];
52
+ const contextAfter = [];
53
+ // Try to read surrounding context from the file
54
+ if (existsSync(file)) {
55
+ try {
56
+ const fileLines = readFileSync(file, "utf-8").split("\n");
57
+ const bStart = Math.max(0, startLine - 1 - contextLines);
58
+ const bEnd = Math.max(0, startLine - 1);
59
+ for (let i = bStart; i < bEnd; i++) {
60
+ contextBefore.push(fileLines[i] || "");
61
+ }
62
+ const aStart = endLine;
63
+ const aEnd = Math.min(fileLines.length, endLine + contextLines);
64
+ for (let i = aStart; i < aEnd; i++) {
65
+ contextAfter.push(fileLines[i] || "");
66
+ }
67
+ }
68
+ catch {
69
+ // File unreadable, skip context
70
+ }
71
+ }
72
+ return { file, startLine, endLine, content, context: { before: contextBefore, after: contextAfter } };
73
+ }
74
+ // ─── CLI ────────────────────────────────────────────────────────────────────
75
+ export function runReviewDiffContext(argv) {
76
+ if (argv.includes("--help") || argv.includes("-h")) {
77
+ console.log(`
78
+ judges review-diff-context — Provide additional context for diff reviews
79
+
80
+ Usage:
81
+ judges review-diff-context Show diff with context
82
+ judges review-diff-context --context 10 Custom context lines
83
+ judges review-diff-context --ref HEAD~3 Compare against a ref
84
+ judges review-diff-context --file src/api.ts Focus on specific file
85
+
86
+ Options:
87
+ --context <n> Number of context lines (default: 5)
88
+ --ref <gitref> Git ref to compare against (default: HEAD~1)
89
+ --file <path> Focus on a specific file
90
+ --staged Show only staged changes
91
+ --format json JSON output
92
+ --help, -h Show this help
93
+
94
+ Shows diff hunks with surrounding file context to help reviewers
95
+ understand the broader code landscape around changes.
96
+ `);
97
+ return;
98
+ }
99
+ const contextLines = parseInt(argv.find((_a, i) => argv[i - 1] === "--context") || "5", 10);
100
+ const ref = argv.find((_a, i) => argv[i - 1] === "--ref") || "HEAD~1";
101
+ const fileFilter = argv.find((_a, i) => argv[i - 1] === "--file");
102
+ const staged = argv.includes("--staged");
103
+ const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
104
+ // Get diff
105
+ let diffText;
106
+ try {
107
+ const diffArgs = staged ? ["diff", "--staged"] : ["diff", ref];
108
+ if (fileFilter)
109
+ diffArgs.push("--", fileFilter);
110
+ diffText = execSync(`git ${diffArgs.join(" ")}`, { encoding: "utf-8", maxBuffer: 10 * 1024 * 1024 });
111
+ }
112
+ catch {
113
+ console.error("Error: Could not run git diff. Are you in a git repository?");
114
+ process.exitCode = 1;
115
+ return;
116
+ }
117
+ if (!diffText.trim()) {
118
+ console.log("No changes found.");
119
+ return;
120
+ }
121
+ const hunks = parseDiffOutput(diffText, contextLines);
122
+ const uniqueFiles = new Set(hunks.map((h) => h.file));
123
+ const report = {
124
+ timestamp: new Date().toISOString(),
125
+ contextLines,
126
+ hunks,
127
+ totalFiles: uniqueFiles.size,
128
+ };
129
+ if (format === "json") {
130
+ console.log(JSON.stringify(report, null, 2));
131
+ return;
132
+ }
133
+ console.log("\nDiff Context Report:");
134
+ console.log("═".repeat(70));
135
+ console.log(` Files changed: ${uniqueFiles.size} Hunks: ${hunks.length} Context: ±${contextLines} lines`);
136
+ console.log("═".repeat(70));
137
+ for (const hunk of hunks) {
138
+ console.log(`\n ── ${hunk.file} (lines ${hunk.startLine}–${hunk.endLine}) ──`);
139
+ if (hunk.context.before.length > 0) {
140
+ console.log(" [context before]");
141
+ for (const l of hunk.context.before) {
142
+ console.log(` │ ${l}`);
143
+ }
144
+ }
145
+ console.log(" [changes]");
146
+ for (const l of hunk.content.split("\n")) {
147
+ const prefix = l.startsWith("+") ? " + " : l.startsWith("-") ? " - " : " ";
148
+ console.log(`${prefix}${l.slice(1)}`);
149
+ }
150
+ if (hunk.context.after.length > 0) {
151
+ console.log(" [context after]");
152
+ for (const l of hunk.context.after) {
153
+ console.log(` │ ${l}`);
154
+ }
155
+ }
156
+ }
157
+ console.log("\n" + "═".repeat(70));
158
+ }
159
+ //# sourceMappingURL=review-diff-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-diff-context.js","sourceRoot":"","sources":["../../src/commands/review-diff-context.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Review-tag — Tag reviews with labels for organization and filtering.
3
+ */
4
+ export declare function runReviewTag(argv: string[]): void;
5
+ //# sourceMappingURL=review-tag.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-tag.d.ts","sourceRoot":"","sources":["../../src/commands/review-tag.ts"],"names":[],"mappings":"AAAA;;GAEG;AA6CH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAyHjD"}
@@ -0,0 +1,137 @@
1
+ /**
2
+ * Review-tag — Tag reviews with labels for organization and filtering.
3
+ */
4
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
5
+ import { join, dirname } from "path";
6
+ // ─── Storage ────────────────────────────────────────────────────────────────
7
+ const TAG_FILE = join(".judges", "review-tags.json");
8
+ function loadStore() {
9
+ if (!existsSync(TAG_FILE))
10
+ return { version: "1.0.0", reviews: [] };
11
+ try {
12
+ return JSON.parse(readFileSync(TAG_FILE, "utf-8"));
13
+ }
14
+ catch {
15
+ return { version: "1.0.0", reviews: [] };
16
+ }
17
+ }
18
+ function saveStore(store) {
19
+ mkdirSync(dirname(TAG_FILE), { recursive: true });
20
+ writeFileSync(TAG_FILE, JSON.stringify(store, null, 2), "utf-8");
21
+ }
22
+ function generateId() {
23
+ return `rev-${Date.now().toString(36)}`;
24
+ }
25
+ // ─── CLI ────────────────────────────────────────────────────────────────────
26
+ export function runReviewTag(argv) {
27
+ if (argv.includes("--help") || argv.includes("-h")) {
28
+ console.log(`
29
+ judges review-tag — Tag reviews for organization and filtering
30
+
31
+ Usage:
32
+ judges review-tag add --tags sprint-42,hotfix --score 8.5
33
+ judges review-tag list List all tags
34
+ judges review-tag list --tag sprint-42 List reviews with tag
35
+ judges review-tag remove --id rev-abc123 --tag hotfix
36
+ judges review-tag clear Clear all tags
37
+
38
+ Subcommands:
39
+ add Tag a review
40
+ list List tags or tagged reviews
41
+ remove Remove a tag from a review
42
+ clear Clear all tag data
43
+
44
+ Options:
45
+ --tags <t1,t2> Comma-separated tags
46
+ --tag <tag> Filter by single tag
47
+ --id <id> Review ID
48
+ --score <n> Review score
49
+ --source <text> Source description
50
+ --format json JSON output
51
+ --help, -h Show this help
52
+
53
+ Tag reviews for easy organization. Data in .judges/review-tags.json.
54
+ `);
55
+ return;
56
+ }
57
+ const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
58
+ const subcommand = argv.find((a) => ["add", "list", "remove", "clear"].includes(a)) || "list";
59
+ const store = loadStore();
60
+ if (subcommand === "add") {
61
+ const tagsArg = argv.find((_a, i) => argv[i - 1] === "--tags") || "";
62
+ const tags = tagsArg
63
+ .split(",")
64
+ .map((t) => t.trim())
65
+ .filter(Boolean);
66
+ if (tags.length === 0) {
67
+ console.error("Error: --tags is required.");
68
+ process.exitCode = 1;
69
+ return;
70
+ }
71
+ const score = parseFloat(argv.find((_a, i) => argv[i - 1] === "--score") || "0");
72
+ const source = argv.find((_a, i) => argv[i - 1] === "--source") || "";
73
+ const id = generateId();
74
+ store.reviews.push({ id, tags, createdAt: new Date().toISOString(), score, findingCount: 0, source });
75
+ saveStore(store);
76
+ console.log(`Tagged review ${id} with: ${tags.join(", ")}`);
77
+ return;
78
+ }
79
+ if (subcommand === "remove") {
80
+ const id = argv.find((_a, i) => argv[i - 1] === "--id");
81
+ const tag = argv.find((_a, i) => argv[i - 1] === "--tag");
82
+ if (!id || !tag) {
83
+ console.error("Error: --id and --tag are required.");
84
+ process.exitCode = 1;
85
+ return;
86
+ }
87
+ const review = store.reviews.find((r) => r.id === id);
88
+ if (!review) {
89
+ console.error(`Error: Review "${id}" not found.`);
90
+ process.exitCode = 1;
91
+ return;
92
+ }
93
+ review.tags = review.tags.filter((t) => t !== tag);
94
+ saveStore(store);
95
+ console.log(`Removed tag "${tag}" from ${id}.`);
96
+ return;
97
+ }
98
+ if (subcommand === "clear") {
99
+ saveStore({ version: "1.0.0", reviews: [] });
100
+ console.log("Tag data cleared.");
101
+ return;
102
+ }
103
+ // list
104
+ const filterTag = argv.find((_a, i) => argv[i - 1] === "--tag");
105
+ const filtered = filterTag ? store.reviews.filter((r) => r.tags.includes(filterTag)) : store.reviews;
106
+ if (format === "json") {
107
+ console.log(JSON.stringify(filtered, null, 2));
108
+ return;
109
+ }
110
+ if (filtered.length === 0) {
111
+ console.log(filterTag ? `No reviews tagged "${filterTag}".` : "No tagged reviews. Use 'judges review-tag add' to start.");
112
+ return;
113
+ }
114
+ // Show unique tags summary
115
+ if (!filterTag) {
116
+ const tagCounts = new Map();
117
+ for (const r of store.reviews) {
118
+ for (const t of r.tags) {
119
+ tagCounts.set(t, (tagCounts.get(t) || 0) + 1);
120
+ }
121
+ }
122
+ console.log("\nReview Tags:");
123
+ console.log("─".repeat(40));
124
+ for (const [tag, count] of [...tagCounts.entries()].sort((a, b) => b[1] - a[1])) {
125
+ console.log(` ${tag.padEnd(25)} ${count} review(s)`);
126
+ }
127
+ console.log("─".repeat(40));
128
+ return;
129
+ }
130
+ console.log(`\nReviews tagged "${filterTag}":`);
131
+ console.log("─".repeat(60));
132
+ for (const r of filtered) {
133
+ console.log(` ${r.id} score=${r.score.toFixed(1)} ${r.createdAt.slice(0, 10)} [${r.tags.join(", ")}]`);
134
+ }
135
+ console.log("─".repeat(60));
136
+ }
137
+ //# sourceMappingURL=review-tag.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-tag.js","sourceRoot":"","sources":["../../src/commands/review-tag.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Review-team-summary — Aggregate team review metrics.
3
+ */
4
+ export declare function runReviewTeamSummary(argv: string[]): void;
5
+ //# sourceMappingURL=review-team-summary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-team-summary.d.ts","sourceRoot":"","sources":["../../src/commands/review-team-summary.ts"],"names":[],"mappings":"AAAA;;GAEG;AA0DH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA0JzD"}