selftune 0.2.26 → 0.2.27
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/apps/local-dashboard/dist/assets/{index-BIZDNtRp.js → index-bvHYAGBm.js} +8 -8
- package/apps/local-dashboard/dist/index.html +1 -1
- package/cli/selftune/dashboard-server.ts +46 -14
- package/package.json +1 -1
- package/packages/dashboard-core/src/screens/overview/OverviewCompositionSurface.test.tsx +1 -0
- package/packages/dashboard-core/src/screens/overview/OverviewCompositionSurface.tsx +1 -1
- package/packages/dashboard-core/src/screens/skill-report/SkillReportScaffold.tsx +5 -1
- package/skill/SKILL.md +1 -1
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<title>selftune — Dashboard</title>
|
|
7
7
|
<link rel="icon" type="image/png" href="/favicon.png" />
|
|
8
|
-
<script type="module" crossorigin src="/assets/index-
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-bvHYAGBm.js"></script>
|
|
9
9
|
<link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-Dw2cE7zH.js">
|
|
10
10
|
<link rel="modulepreload" crossorigin href="/assets/vendor-react-C5oyHiV1.js">
|
|
11
11
|
<link rel="modulepreload" crossorigin href="/assets/vendor-ui-B3BPIYy7.js">
|
|
@@ -185,6 +185,50 @@ const MIME_TYPES: Record<string, string> = {
|
|
|
185
185
|
".ico": "image/x-icon",
|
|
186
186
|
};
|
|
187
187
|
|
|
188
|
+
async function serveSpaShell(spaDir: string | null): Promise<Response> {
|
|
189
|
+
if (!spaDir) {
|
|
190
|
+
return new Response("Dashboard build not found. Run `bun run build:dashboard` first.", {
|
|
191
|
+
status: 503,
|
|
192
|
+
headers: { "Content-Type": "text/plain; charset=utf-8", ...corsHeaders() },
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const indexPath = join(spaDir, "index.html");
|
|
197
|
+
const indexFile = Bun.file(indexPath);
|
|
198
|
+
if (!(await indexFile.exists())) {
|
|
199
|
+
return new Response(
|
|
200
|
+
"Dashboard assets are updating. Retry in a moment or run `selftune dashboard --restart`.",
|
|
201
|
+
{
|
|
202
|
+
status: 503,
|
|
203
|
+
headers: {
|
|
204
|
+
"Content-Type": "text/plain; charset=utf-8",
|
|
205
|
+
"Retry-After": "1",
|
|
206
|
+
...corsHeaders(),
|
|
207
|
+
},
|
|
208
|
+
},
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
try {
|
|
213
|
+
const html = await indexFile.text();
|
|
214
|
+
return new Response(html, {
|
|
215
|
+
headers: { "Content-Type": "text/html; charset=utf-8", ...corsHeaders() },
|
|
216
|
+
});
|
|
217
|
+
} catch {
|
|
218
|
+
return new Response(
|
|
219
|
+
"Dashboard assets are updating. Retry in a moment or run `selftune dashboard --restart`.",
|
|
220
|
+
{
|
|
221
|
+
status: 503,
|
|
222
|
+
headers: {
|
|
223
|
+
"Content-Type": "text/plain; charset=utf-8",
|
|
224
|
+
"Retry-After": "1",
|
|
225
|
+
...corsHeaders(),
|
|
226
|
+
},
|
|
227
|
+
},
|
|
228
|
+
);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
188
232
|
async function computeStatusFromDb(): Promise<StatusResult> {
|
|
189
233
|
const db = getDb();
|
|
190
234
|
const telemetry = querySessionTelemetry(db);
|
|
@@ -519,16 +563,7 @@ export async function startDashboardServer(
|
|
|
519
563
|
|
|
520
564
|
// ---- GET / ---- Serve SPA shell
|
|
521
565
|
if (url.pathname === "/" && req.method === "GET") {
|
|
522
|
-
|
|
523
|
-
const html = await Bun.file(join(spaDir, "index.html")).text();
|
|
524
|
-
return new Response(html, {
|
|
525
|
-
headers: { "Content-Type": "text/html; charset=utf-8", ...corsHeaders() },
|
|
526
|
-
});
|
|
527
|
-
}
|
|
528
|
-
return new Response("Dashboard build not found. Run `bun run build:dashboard` first.", {
|
|
529
|
-
status: 503,
|
|
530
|
-
headers: { "Content-Type": "text/plain; charset=utf-8", ...corsHeaders() },
|
|
531
|
-
});
|
|
566
|
+
return serveSpaShell(spaDir);
|
|
532
567
|
}
|
|
533
568
|
|
|
534
569
|
// ---- POST /api/actions/{watch,evolve,rollback,watchlist} ----
|
|
@@ -672,10 +707,7 @@ export async function startDashboardServer(
|
|
|
672
707
|
|
|
673
708
|
// ---- SPA fallback ----
|
|
674
709
|
if (spaDir && req.method === "GET" && !url.pathname.startsWith("/api/")) {
|
|
675
|
-
|
|
676
|
-
return new Response(html, {
|
|
677
|
-
headers: { "Content-Type": "text/html; charset=utf-8", ...corsHeaders() },
|
|
678
|
-
});
|
|
710
|
+
return serveSpaShell(spaDir);
|
|
679
711
|
}
|
|
680
712
|
|
|
681
713
|
return new Response("Not Found", { status: 404, headers: corsHeaders() });
|
package/package.json
CHANGED
|
@@ -86,6 +86,7 @@ describe("OverviewCompositionSurface", () => {
|
|
|
86
86
|
expect(html).toContain("After Feed");
|
|
87
87
|
expect(html.indexOf("Comparison 1")).toBeLessThan(html.indexOf("Before Feed"));
|
|
88
88
|
expect(html.indexOf("Run Summary 4")).toBeLessThan(html.indexOf("After Feed"));
|
|
89
|
+
expect(html).toContain('<div class="col-span-12"><div>Before Feed</div></div>');
|
|
89
90
|
});
|
|
90
91
|
|
|
91
92
|
it("omits the comparison block when there are no rows", () => {
|
|
@@ -48,7 +48,7 @@ export function OverviewCompositionSurface({
|
|
|
48
48
|
<OverviewComparisonSurface {...comparison} renderSkillLink={renderSkillLink} />
|
|
49
49
|
</div>
|
|
50
50
|
) : null}
|
|
51
|
-
{sectionsBeforeFeed}
|
|
51
|
+
{sectionsBeforeFeed ? <div className="col-span-12">{sectionsBeforeFeed}</div> : null}
|
|
52
52
|
</>
|
|
53
53
|
) : null;
|
|
54
54
|
|
|
@@ -28,6 +28,7 @@ export interface SkillReportScaffoldProps {
|
|
|
28
28
|
summary?: ReactNode;
|
|
29
29
|
showOnboardingBanner?: boolean;
|
|
30
30
|
guideButtonLabel?: string;
|
|
31
|
+
prioritizeChildren?: boolean;
|
|
31
32
|
nextAction: SkillReportNextAction;
|
|
32
33
|
trustState: TrustState;
|
|
33
34
|
coverage?: TrustFields["coverage"];
|
|
@@ -52,6 +53,7 @@ export function SkillReportScaffold({
|
|
|
52
53
|
summary,
|
|
53
54
|
showOnboardingBanner = false,
|
|
54
55
|
guideButtonLabel = "How to read this page",
|
|
56
|
+
prioritizeChildren = false,
|
|
55
57
|
nextAction,
|
|
56
58
|
trustState,
|
|
57
59
|
coverage,
|
|
@@ -115,6 +117,8 @@ export function SkillReportScaffold({
|
|
|
115
117
|
}
|
|
116
118
|
/>
|
|
117
119
|
|
|
120
|
+
{prioritizeChildren && children ? <div className="space-y-4">{children}</div> : null}
|
|
121
|
+
|
|
118
122
|
<SkillTrustNarrativePanel
|
|
119
123
|
trustState={trustState}
|
|
120
124
|
coverage={coverage}
|
|
@@ -141,7 +145,7 @@ export function SkillReportScaffold({
|
|
|
141
145
|
/>
|
|
142
146
|
</div>
|
|
143
147
|
|
|
144
|
-
{children ? (
|
|
148
|
+
{children && !prioritizeChildren ? (
|
|
145
149
|
<div className="space-y-4 border-t border-border/10 pt-4">{children}</div>
|
|
146
150
|
) : null}
|
|
147
151
|
</div>
|