@judge-java/dashboard 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/dist/cli.d.ts ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * CLI for generating the code reviewe dashboard.
4
+ *
5
+ * Usage:
6
+ * npx judge-java-dashboard [--repo <path>] [--output <path>]
7
+ *
8
+ * By default, runs in the current directory and outputs to .codeagent/dashboard.html
9
+ */
10
+ export {};
11
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;GAOG"}
package/dist/cli.js ADDED
@@ -0,0 +1,60 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * CLI for generating the code reviewe dashboard.
4
+ *
5
+ * Usage:
6
+ * npx judge-java-dashboard [--repo <path>] [--output <path>]
7
+ *
8
+ * By default, runs in the current directory and outputs to .codeagent/dashboard.html
9
+ */
10
+ import * as path from "path";
11
+ import { generateDashboard } from "@judge-java/dashboard";
12
+ async function main() {
13
+ const args = process.argv.slice(2);
14
+ let repoRoot = process.cwd();
15
+ let outputOverride;
16
+ for (let i = 0; i < args.length; i++) {
17
+ if (args[i] === "--repo" && args[i + 1]) {
18
+ repoRoot = path.resolve(args[++i]);
19
+ }
20
+ else if (args[i] === "--output" && args[i + 1]) {
21
+ outputOverride = path.resolve(args[++i]);
22
+ }
23
+ else if (args[i] === "--help") {
24
+ console.log(`
25
+ judge-java-dashboard — generate the code health dashboard
26
+
27
+ Usage:
28
+ judge-java-dashboard [options]
29
+
30
+ Options:
31
+ --repo <path> Path to the repository root (default: current directory)
32
+ --output <path> Output path for dashboard.html (default: .codeagent/dashboard.html)
33
+ --help Show this help
34
+
35
+ The dashboard is a self-contained HTML file that visualises your .codeagent/ state:
36
+ - Open and resolved tracked issues
37
+ - Team decisions
38
+ - Domain conventions
39
+ - Audit log
40
+
41
+ Host it on GitHub Pages by pointing your Pages source to the .codeagent/ folder,
42
+ or simply open it locally in a browser.
43
+ `);
44
+ process.exit(0);
45
+ }
46
+ }
47
+ console.log(`\nā—ˆ judge-java dashboard\n`);
48
+ console.log(` Repository: ${repoRoot}`);
49
+ try {
50
+ const outputPath = await generateDashboard(repoRoot, outputOverride);
51
+ console.log(` Output: ${outputPath}`);
52
+ console.log(`\nāœ“ Dashboard generated.\n`);
53
+ }
54
+ catch (err) {
55
+ console.error(`\nāœ— Failed to generate dashboard: ${String(err)}\n`);
56
+ process.exit(1);
57
+ }
58
+ }
59
+ main();
60
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;GAOG;AAEH,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAC,iBAAiB,EAAC,MAAM,uBAAuB,CAAC;AAExD,KAAK,UAAU,IAAI;IACf,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACnC,IAAI,QAAQ,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAC7B,IAAI,cAAkC,CAAC;IAEvC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACnC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YACtC,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACvC,CAAC;aAAM,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,UAAU,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YAC/C,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAC7C,CAAC;aAAM,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE,CAAC;YAC9B,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;CAmBvB,CAAC,CAAC;YACS,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,CAAC;IACL,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;IAC1C,OAAO,CAAC,GAAG,CAAC,iBAAiB,QAAQ,EAAE,CAAC,CAAC;IAEzC,IAAI,CAAC;QACD,MAAM,UAAU,GAAG,MAAM,iBAAiB,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;QACrE,OAAO,CAAC,GAAG,CAAC,iBAAiB,UAAU,EAAE,CAAC,CAAC;QAC3C,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;IAC9C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACX,OAAO,CAAC,KAAK,CAAC,qCAAqC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACpE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;AACL,CAAC;AAED,IAAI,EAAE,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function generateDashboard(repoRoot: string, outputPath?: string): Promise<string>;
2
+ //# sourceMappingURL=generator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../src/generator.ts"],"names":[],"mappings":"AAKA,wBAAsB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAW9F"}
@@ -0,0 +1,436 @@
1
+ import * as fs from "fs/promises";
2
+ import * as path from "path";
3
+ import { loadMemory } from "@judge-java/core";
4
+ export async function generateDashboard(repoRoot, outputPath) {
5
+ const memory = await loadMemory(repoRoot);
6
+ const auditLog = await readAuditLog(repoRoot);
7
+ const repoName = path.basename(repoRoot);
8
+ const html = renderDashboard(repoName, memory, auditLog);
9
+ const resolvedOutputPath = outputPath ?? path.join(repoRoot, ".codeagent", "dashboard.html");
10
+ await fs.writeFile(resolvedOutputPath, html, "utf-8");
11
+ return resolvedOutputPath;
12
+ }
13
+ async function readAuditLog(repoRoot) {
14
+ try {
15
+ const content = await fs.readFile(path.join(repoRoot, ".codeagent", "audit.log"), "utf-8");
16
+ return content
17
+ .split("\n")
18
+ .filter(Boolean)
19
+ .reverse()
20
+ .slice(0, 50); // last 50 entries
21
+ }
22
+ catch {
23
+ return [];
24
+ }
25
+ }
26
+ function renderDashboard(repoName, memory, auditLog) {
27
+ const openIssues = memory.trackedIssues.filter((i) => i.status === "open");
28
+ const closedIssues = memory.trackedIssues.filter((i) => i.status === "closed");
29
+ const issuesByLevel = groupBy(openIssues, (i) => i.reviewLevel);
30
+ const generatedAt = new Date().toLocaleString();
31
+ return `<!DOCTYPE html>
32
+ <html lang="en">
33
+ <head>
34
+ <meta charset="UTF-8" />
35
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
36
+ <title>judge-java — ${escapeHtml(repoName)}</title>
37
+ <style>
38
+ *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
39
+
40
+ :root {
41
+ --bg: #0d1117;
42
+ --surface: #161b22;
43
+ --surface2: #21262d;
44
+ --border: #30363d;
45
+ --text: #e6edf3;
46
+ --muted: #8b949e;
47
+ --accent: #58a6ff;
48
+ --green: #3fb950;
49
+ --yellow: #d29922;
50
+ --red: #f85149;
51
+ --purple: #bc8cff;
52
+ --orange: #ffa657;
53
+ }
54
+
55
+ body {
56
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
57
+ background: var(--bg);
58
+ color: var(--text);
59
+ line-height: 1.6;
60
+ min-height: 100vh;
61
+ }
62
+
63
+ header {
64
+ background: var(--surface);
65
+ border-bottom: 1px solid var(--border);
66
+ padding: 1.25rem 2rem;
67
+ display: flex;
68
+ align-items: center;
69
+ gap: 1rem;
70
+ }
71
+
72
+ header .logo {
73
+ font-size: 1.1rem;
74
+ font-weight: 600;
75
+ color: var(--accent);
76
+ }
77
+
78
+ header .repo {
79
+ color: var(--muted);
80
+ font-size: 0.9rem;
81
+ }
82
+
83
+ header .generated {
84
+ margin-left: auto;
85
+ font-size: 0.8rem;
86
+ color: var(--muted);
87
+ }
88
+
89
+ main {
90
+ max-width: 1200px;
91
+ margin: 0 auto;
92
+ padding: 2rem;
93
+ }
94
+
95
+ .stats-grid {
96
+ display: grid;
97
+ grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
98
+ gap: 1rem;
99
+ margin-bottom: 2rem;
100
+ }
101
+
102
+ .stat-card {
103
+ background: var(--surface);
104
+ border: 1px solid var(--border);
105
+ border-radius: 8px;
106
+ padding: 1.25rem;
107
+ }
108
+
109
+ .stat-card .value {
110
+ font-size: 2rem;
111
+ font-weight: 700;
112
+ line-height: 1;
113
+ margin-bottom: 0.25rem;
114
+ }
115
+
116
+ .stat-card .label {
117
+ font-size: 0.8rem;
118
+ color: var(--muted);
119
+ text-transform: uppercase;
120
+ letter-spacing: 0.05em;
121
+ }
122
+
123
+ .value.green { color: var(--green); }
124
+ .value.yellow { color: var(--yellow); }
125
+ .value.red { color: var(--red); }
126
+ .value.purple { color: var(--purple); }
127
+ .value.blue { color: var(--accent); }
128
+
129
+ .section {
130
+ margin-bottom: 2.5rem;
131
+ }
132
+
133
+ .section-title {
134
+ font-size: 1rem;
135
+ font-weight: 600;
136
+ margin-bottom: 1rem;
137
+ padding-bottom: 0.5rem;
138
+ border-bottom: 1px solid var(--border);
139
+ display: flex;
140
+ align-items: center;
141
+ gap: 0.5rem;
142
+ }
143
+
144
+ .badge {
145
+ display: inline-flex;
146
+ align-items: center;
147
+ padding: 0.15rem 0.5rem;
148
+ border-radius: 20px;
149
+ font-size: 0.72rem;
150
+ font-weight: 600;
151
+ background: var(--surface2);
152
+ color: var(--muted);
153
+ }
154
+
155
+ .issue-list {
156
+ display: flex;
157
+ flex-direction: column;
158
+ gap: 0.5rem;
159
+ }
160
+
161
+ .issue-item {
162
+ background: var(--surface);
163
+ border: 1px solid var(--border);
164
+ border-radius: 6px;
165
+ padding: 0.875rem 1rem;
166
+ display: flex;
167
+ align-items: flex-start;
168
+ gap: 0.75rem;
169
+ }
170
+
171
+ .issue-item:hover {
172
+ border-color: var(--accent);
173
+ }
174
+
175
+ .issue-number {
176
+ color: var(--muted);
177
+ font-size: 0.8rem;
178
+ font-family: monospace;
179
+ min-width: 3rem;
180
+ padding-top: 0.1rem;
181
+ }
182
+
183
+ .issue-content { flex: 1; }
184
+
185
+ .issue-title {
186
+ font-size: 0.9rem;
187
+ font-weight: 500;
188
+ margin-bottom: 0.25rem;
189
+ }
190
+
191
+ .issue-meta {
192
+ font-size: 0.78rem;
193
+ color: var(--muted);
194
+ display: flex;
195
+ gap: 0.75rem;
196
+ flex-wrap: wrap;
197
+ }
198
+
199
+ .level-tag {
200
+ display: inline-flex;
201
+ padding: 0.1rem 0.4rem;
202
+ border-radius: 4px;
203
+ font-size: 0.72rem;
204
+ font-weight: 500;
205
+ background: var(--surface2);
206
+ }
207
+
208
+ .level-tag.refactoring_opportunities { color: var(--yellow); }
209
+ .level-tag.security { color: var(--red); }
210
+ .level-tag.performance { color: var(--orange); }
211
+ .level-tag.architecture { color: var(--purple); }
212
+ .level-tag.domain_language { color: var(--accent); }
213
+ .level-tag.test_quality { color: var(--green); }
214
+ .level-tag.scope_check { color: var(--muted); }
215
+ .level-tag.obvious_bugs { color: var(--red); }
216
+
217
+ .decision-item {
218
+ background: var(--surface);
219
+ border: 1px solid var(--border);
220
+ border-radius: 6px;
221
+ padding: 0.875rem 1rem;
222
+ }
223
+
224
+ .decision-title {
225
+ font-size: 0.9rem;
226
+ font-weight: 500;
227
+ margin-bottom: 0.25rem;
228
+ }
229
+
230
+ .decision-reason {
231
+ font-size: 0.82rem;
232
+ color: var(--muted);
233
+ }
234
+
235
+ .decision-meta {
236
+ font-size: 0.75rem;
237
+ color: var(--muted);
238
+ margin-top: 0.25rem;
239
+ }
240
+
241
+ .conventions-block {
242
+ background: var(--surface);
243
+ border: 1px solid var(--border);
244
+ border-radius: 6px;
245
+ padding: 1.25rem;
246
+ font-size: 0.85rem;
247
+ white-space: pre-wrap;
248
+ color: var(--muted);
249
+ max-height: 300px;
250
+ overflow-y: auto;
251
+ }
252
+
253
+ .audit-list {
254
+ background: var(--surface);
255
+ border: 1px solid var(--border);
256
+ border-radius: 6px;
257
+ overflow: hidden;
258
+ }
259
+
260
+ .audit-entry {
261
+ font-family: monospace;
262
+ font-size: 0.78rem;
263
+ padding: 0.5rem 1rem;
264
+ border-bottom: 1px solid var(--border);
265
+ color: var(--muted);
266
+ }
267
+
268
+ .audit-entry:last-child { border-bottom: none; }
269
+
270
+ .empty-state {
271
+ color: var(--muted);
272
+ font-size: 0.85rem;
273
+ text-align: center;
274
+ padding: 2rem;
275
+ background: var(--surface);
276
+ border: 1px dashed var(--border);
277
+ border-radius: 6px;
278
+ }
279
+
280
+ .level-breakdown {
281
+ display: grid;
282
+ grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
283
+ gap: 0.75rem;
284
+ margin-bottom: 1.5rem;
285
+ }
286
+
287
+ .level-card {
288
+ background: var(--surface);
289
+ border: 1px solid var(--border);
290
+ border-radius: 6px;
291
+ padding: 1rem;
292
+ display: flex;
293
+ justify-content: space-between;
294
+ align-items: center;
295
+ }
296
+
297
+ .level-card .count {
298
+ font-size: 1.4rem;
299
+ font-weight: 700;
300
+ color: var(--yellow);
301
+ }
302
+ </style>
303
+ </head>
304
+ <body>
305
+ <header>
306
+ <span class="logo">ā—ˆ judge-java</span>
307
+ <span class="repo">${escapeHtml(repoName)}</span>
308
+ <span class="generated">Generated ${escapeHtml(generatedAt)}</span>
309
+ </header>
310
+
311
+ <main>
312
+ <!-- Stats -->
313
+ <div class="stats-grid">
314
+ <div class="stat-card">
315
+ <div class="value yellow">${openIssues.length}</div>
316
+ <div class="label">Open Issues</div>
317
+ </div>
318
+ <div class="stat-card">
319
+ <div class="value green">${closedIssues.length}</div>
320
+ <div class="label">Resolved Issues</div>
321
+ </div>
322
+ <div class="stat-card">
323
+ <div class="value purple">${memory.decisions.length}</div>
324
+ <div class="label">Team Decisions</div>
325
+ </div>
326
+ <div class="stat-card">
327
+ <div class="value blue">${auditLog.length}</div>
328
+ <div class="label">Audit Events</div>
329
+ </div>
330
+ </div>
331
+
332
+ <!-- Open Issues by Level -->
333
+ ${openIssues.length > 0
334
+ ? `
335
+ <div class="section">
336
+ <div class="section-title">
337
+ Open Issues
338
+ <span class="badge">${openIssues.length}</span>
339
+ </div>
340
+ <div class="level-breakdown">
341
+ ${Object.entries(issuesByLevel)
342
+ .map(([level, issues]) => `
343
+ <div class="level-card">
344
+ <span class="level-tag ${escapeHtml(level)}">${formatLevel(level)}</span>
345
+ <span class="count">${issues.length}</span>
346
+ </div>`)
347
+ .join("")}
348
+ </div>
349
+ <div class="issue-list">
350
+ ${openIssues.map(renderIssue).join("")}
351
+ </div>
352
+ </div>`
353
+ : `
354
+ <div class="section">
355
+ <div class="section-title">Open Issues</div>
356
+ <div class="empty-state">No open issues. šŸŽ‰</div>
357
+ </div>`}
358
+
359
+ <!-- Team Decisions -->
360
+ <div class="section">
361
+ <div class="section-title">
362
+ Team Decisions
363
+ <span class="badge">${memory.decisions.length}</span>
364
+ </div>
365
+ ${memory.decisions.length > 0
366
+ ? `<div class="issue-list">${memory.decisions.map(renderDecision).join("")}</div>`
367
+ : `<div class="empty-state">No decisions recorded yet. Use <code>add_decision</code> to dismiss known patterns.</div>`}
368
+ </div>
369
+
370
+ <!-- Conventions -->
371
+ ${memory.narrative.trim()
372
+ ? `
373
+ <div class="section">
374
+ <div class="section-title">Domain Conventions & Context</div>
375
+ <div class="conventions-block">${escapeHtml(memory.narrative)}</div>
376
+ </div>`
377
+ : ""}
378
+
379
+ <!-- Audit Log -->
380
+ ${auditLog.length > 0
381
+ ? `
382
+ <div class="section">
383
+ <div class="section-title">
384
+ Audit Log
385
+ <span class="badge">last ${auditLog.length}</span>
386
+ </div>
387
+ <div class="audit-list">
388
+ ${auditLog.map((l) => `<div class="audit-entry">${escapeHtml(l)}</div>`).join("")}
389
+ </div>
390
+ </div>`
391
+ : ""}
392
+ </main>
393
+ </body>
394
+ </html>`;
395
+ }
396
+ function renderIssue(issue) {
397
+ return `
398
+ <div class="issue-item">
399
+ <span class="issue-number">#${issue.githubIssueNumber}</span>
400
+ <div class="issue-content">
401
+ <div class="issue-title">${escapeHtml(issue.title)}</div>
402
+ <div class="issue-meta">
403
+ <span class="level-tag ${escapeHtml(issue.reviewLevel)}">${formatLevel(issue.reviewLevel)}</span>
404
+ <span>${escapeHtml(issue.createdAt.split("T")[0])}</span>
405
+ ${issue.files.length > 0 ? `<span>${escapeHtml(issue.files[0])}</span>` : ""}
406
+ </div>
407
+ </div>
408
+ </div>`;
409
+ }
410
+ function renderDecision(decision) {
411
+ return `
412
+ <div class="decision-item">
413
+ <div class="decision-title">${escapeHtml(decision.title)}</div>
414
+ <div class="decision-reason">${escapeHtml(decision.reason)}</div>
415
+ <div class="decision-meta">${escapeHtml(decision.date)} Ā· ${escapeHtml(decision.author)}</div>
416
+ </div>`;
417
+ }
418
+ function formatLevel(level) {
419
+ return level.replace(/_/g, " ");
420
+ }
421
+ function groupBy(arr, key) {
422
+ return arr.reduce((acc, item) => {
423
+ const k = key(item);
424
+ (acc[k] ??= []).push(item);
425
+ return acc;
426
+ }, {});
427
+ }
428
+ function escapeHtml(str) {
429
+ return str
430
+ .replace(/&/g, "&amp;")
431
+ .replace(/</g, "&lt;")
432
+ .replace(/>/g, "&gt;")
433
+ .replace(/"/g, "&quot;")
434
+ .replace(/'/g, "&#039;");
435
+ }
436
+ //# sourceMappingURL=generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generator.js","sourceRoot":"","sources":["../src/generator.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "@judge-java/dashboard",
3
+ "version": "0.1.0",
4
+ "description": "Static HTML dashboard generator for judge-java",
5
+ "type": "module",
6
+ "main": "./dist/generator.js",
7
+ "types": "./dist/generator.d.ts",
8
+ "files": ["dist"],
9
+ "exports": {
10
+ ".": {
11
+ "import": "./dist/generator.js",
12
+ "types": "./dist/generator.d.ts"
13
+ }
14
+ },
15
+ "bin": {
16
+ "judge-java-dashboard": "./dist/cli.js"
17
+ },
18
+ "scripts": {
19
+ "build": "tsc -p tsconfig.json",
20
+ "test": "vitest run"
21
+ },
22
+ "dependencies": {
23
+ "@judge-java/core": "*"
24
+ }
25
+ }