@viren/claude-code-dashboard 0.0.5 → 0.0.7
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/README.md +12 -0
- package/generate-dashboard.mjs +248 -625
- package/package.json +1 -1
- package/src/analysis.mjs +19 -12
- package/src/assembler.mjs +8 -4
- package/src/constants.mjs +1 -1
- package/src/demo.mjs +191 -248
- package/src/helpers.mjs +21 -0
- package/src/pipeline.mjs +500 -0
- package/src/sections.mjs +7 -3
- package/template/dashboard.css +73 -4
- package/template/dashboard.js +46 -0
package/package.json
CHANGED
package/src/analysis.mjs
CHANGED
|
@@ -90,22 +90,29 @@ export function detectTechStack(repoDir) {
|
|
|
90
90
|
return { stacks: [...stacks] };
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
export function
|
|
94
|
-
if (
|
|
93
|
+
export function classifyDrift(commitCount) {
|
|
94
|
+
if (commitCount === null || commitCount === undefined || commitCount < 0) {
|
|
95
|
+
return { level: "unknown", commitsSince: 0 };
|
|
96
|
+
}
|
|
97
|
+
const n = Math.max(0, Number(commitCount) || 0);
|
|
98
|
+
if (n === 0) return { level: "synced", commitsSince: 0 };
|
|
99
|
+
if (n <= 5) return { level: "low", commitsSince: n };
|
|
100
|
+
if (n <= 20) return { level: "medium", commitsSince: n };
|
|
101
|
+
return { level: "high", commitsSince: n };
|
|
102
|
+
}
|
|
95
103
|
|
|
96
|
-
|
|
104
|
+
/** Count commits since config was last updated. Returns null if unknown. */
|
|
105
|
+
export function getGitRevCount(repoDir, configTimestamp) {
|
|
106
|
+
if (!configTimestamp) return null;
|
|
97
107
|
const countStr = gitCmd(repoDir, "rev-list", "--count", `--since=${configTimestamp}`, "HEAD");
|
|
98
|
-
if (!countStr) return
|
|
99
|
-
|
|
108
|
+
if (!countStr) return null;
|
|
100
109
|
const parsed = Number(countStr);
|
|
101
|
-
if (!Number.isFinite(parsed)) return
|
|
102
|
-
|
|
103
|
-
|
|
110
|
+
if (!Number.isFinite(parsed)) return null;
|
|
111
|
+
return Math.max(0, parsed - 1); // -1 to exclude the config commit itself
|
|
112
|
+
}
|
|
104
113
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
if (commitsSince <= 20) return { level: "medium", commitsSince };
|
|
108
|
-
return { level: "high", commitsSince };
|
|
114
|
+
export function computeDrift(repoDir, configTimestamp) {
|
|
115
|
+
return classifyDrift(getGitRevCount(repoDir, configTimestamp));
|
|
109
116
|
}
|
|
110
117
|
|
|
111
118
|
export function findExemplar(stack, configuredRepos) {
|
package/src/assembler.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import { readFileSync } from "fs";
|
|
|
2
2
|
import { fileURLToPath } from "url";
|
|
3
3
|
import { dirname, join } from "path";
|
|
4
4
|
|
|
5
|
-
import { esc } from "./helpers.mjs";
|
|
5
|
+
import { esc, insightsToMarkdown } from "./helpers.mjs";
|
|
6
6
|
import { VERSION, REPO_URL } from "./constants.mjs";
|
|
7
7
|
import { renderCmd, renderRule, renderRepoCard } from "./render.mjs";
|
|
8
8
|
import {
|
|
@@ -64,8 +64,11 @@ export function generateDashboardHtml(data) {
|
|
|
64
64
|
// ── Build section HTML fragments ──────────────────────────────────────────
|
|
65
65
|
|
|
66
66
|
const header = `<h1>claude code dashboard</h1>
|
|
67
|
-
<
|
|
68
|
-
<
|
|
67
|
+
<div class="header-actions">
|
|
68
|
+
<button id="refresh-btn" class="header-btn" title="Copy refresh command to clipboard" aria-label="Copy refresh command">↻ refresh</button>
|
|
69
|
+
<button id="theme-toggle" class="theme-toggle" title="Toggle light/dark mode" aria-label="Toggle theme"><span class="theme-icon"></span></button>
|
|
70
|
+
</div>
|
|
71
|
+
<p class="sub">generated ${timestamp} · <a href="${esc(REPO_URL)}" target="_blank" rel="noopener" style="color:var(--accent);text-decoration:none">v${esc(VERSION)}</a></p>`;
|
|
69
72
|
|
|
70
73
|
const statsBar = renderStatsBar(data);
|
|
71
74
|
|
|
@@ -80,7 +83,8 @@ export function generateDashboardHtml(data) {
|
|
|
80
83
|
${globalRules.map((r) => renderRule(r)).join("\n ")}
|
|
81
84
|
</div>
|
|
82
85
|
</div>`;
|
|
83
|
-
const
|
|
86
|
+
const insightsMarkdown = insightsToMarkdown(insights);
|
|
87
|
+
const insightsHtml = renderInsightsCard(insights, insightsMarkdown);
|
|
84
88
|
const chainsHtml = renderChainsCard(chains);
|
|
85
89
|
const consolidationHtml = renderConsolidationCard(consolidationGroups);
|
|
86
90
|
const tabOverview = `${overviewCommands}\n ${insightsHtml}\n ${chainsHtml}\n ${consolidationHtml}`;
|
package/src/constants.mjs
CHANGED