@hansenexus/hud 0.1.0 → 0.2.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/README.md +42 -23
- package/dist/index.d.ts +39 -0
- package/dist/index.js +399 -0
- package/package.json +45 -136
- package/chunk-0cj8dkk7.js +0 -127
- package/chunk-1atxwdhw.js +0 -48
- package/chunk-24vrg16w.js +0 -39
- package/chunk-3j9sm249.js +0 -26
- package/chunk-50pq4sg6.js +0 -41
- package/chunk-5gtx3pza.js +0 -9
- package/chunk-6gw4x08j.js +0 -264
- package/chunk-6jt8yg4m.js +0 -117
- package/chunk-71se605m.js +0 -85
- package/chunk-82nm9wcg.js +0 -316
- package/chunk-8tam7r3h.js +0 -68
- package/chunk-babjpqkb.js +0 -52
- package/chunk-c5y856ad.js +0 -98
- package/chunk-ghxh8926.js +0 -172
- package/chunk-hc2g0n35.js +0 -24
- package/chunk-k0vr8dsy.js +0 -179
- package/chunk-k50yfp5d.js +0 -166
- package/chunk-kyeb6qeq.js +0 -95
- package/chunk-msqkkqw7.js +0 -140
- package/chunk-nm82wr8r.js +0 -58
- package/chunk-r06bpmy6.js +0 -79
- package/chunk-t9eh4t0b.js +0 -89
- package/chunk-tf774c4w.js +0 -115
- package/chunk-v086j53b.js +0 -19
- package/chunk-wspz08q7.js +0 -67
- package/chunk-xezxydm3.js +0 -47
- package/chunk-xjn0896g.js +0 -574
- package/chunk-xztw0xyt.js +0 -113
- package/chunk-zzrpd92r.js +0 -172
- package/core/access.d.mts +0 -53
- package/core/access.js +0 -27
- package/core/api-types.d.mts +0 -146
- package/core/api-types.js +0 -9
- package/core/capabilities.d.mts +0 -27
- package/core/capabilities.js +0 -14
- package/core/capture-buffer.d.mts +0 -37
- package/core/capture-buffer.js +0 -9
- package/core/force-state.d.mts +0 -68
- package/core/force-state.js +0 -21
- package/core/mock-cookie.d.mts +0 -30
- package/core/mock-cookie.js +0 -15
- package/core/types.d.mts +0 -59
- package/core/types.js +0 -9
- package/hud-provider.d.mts +0 -38
- package/hud-provider.js +0 -15
- package/hud.d.mts +0 -15
- package/hud.js +0 -18
- package/index.d.mts +0 -94
- package/index.js +0 -170
- package/lazy-panel.d.mts +0 -28
- package/lazy-panel.js +0 -11
- package/panels/cicd-panel.d.mts +0 -9
- package/panels/cicd-panel.js +0 -13
- package/panels/debug-info-panel.d.mts +0 -21
- package/panels/debug-info-panel.js +0 -9
- package/panels/dispatch-panel.d.mts +0 -10
- package/panels/dispatch-panel.js +0 -14
- package/panels/env-info-panel.d.mts +0 -9
- package/panels/env-info-panel.js +0 -12
- package/panels/feature-flags-panel.d.mts +0 -26
- package/panels/feature-flags-panel.js +0 -9
- package/panels/force-state-panel.d.mts +0 -11
- package/panels/force-state-panel.js +0 -113
- package/panels/info-row.d.mts +0 -21
- package/panels/info-row.js +0 -14
- package/panels/mock-seed-panel.d.mts +0 -15
- package/panels/mock-seed-panel.js +0 -14
- package/panels/network-console-panel.d.mts +0 -6
- package/panels/network-console-panel.js +0 -9
- package/panels/role-switcher-panel.d.mts +0 -28
- package/panels/role-switcher-panel.js +0 -9
- package/panels/sessions-panel.d.mts +0 -6
- package/panels/sessions-panel.js +0 -13
- package/panels/tokens-panel.d.mts +0 -38
- package/panels/tokens-panel.js +0 -9
- package/panels/unlock-panel.d.mts +0 -33
- package/panels/unlock-panel.js +0 -14
- package/panels/variants-panel.d.mts +0 -51
- package/panels/variants-panel.js +0 -12
- package/panels/vitals-panel.d.mts +0 -11
- package/panels/vitals-panel.js +0 -15
- package/server/guard.d.mts +0 -42
- package/server/guard.js +0 -12
- package/server/unlock.d.mts +0 -28
- package/server/unlock.js +0 -108
- package/state-boundary.d.mts +0 -25
- package/state-boundary.js +0 -54
package/chunk-ghxh8926.js
DELETED
|
@@ -1,172 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
usePoll
|
|
3
|
-
} from "./chunk-xezxydm3.js";
|
|
4
|
-
import {
|
|
5
|
-
useHud
|
|
6
|
-
} from "./chunk-wspz08q7.js";
|
|
7
|
-
import {
|
|
8
|
-
LoadingSpinner,
|
|
9
|
-
PanelSection
|
|
10
|
-
} from "./chunk-kyeb6qeq.js";
|
|
11
|
-
import {
|
|
12
|
-
Badge
|
|
13
|
-
} from "./chunk-xztw0xyt.js";
|
|
14
|
-
import {
|
|
15
|
-
__require
|
|
16
|
-
} from "./chunk-5gtx3pza.js";
|
|
17
|
-
|
|
18
|
-
// panels/vitals-panel.tsx
|
|
19
|
-
import { Activity, ServerCrash } from "lucide-react";
|
|
20
|
-
import { useEffect, useSyncExternalStore } from "react";
|
|
21
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
22
|
-
"use client";
|
|
23
|
-
var VITAL_ORDER = ["LCP", "INP", "CLS", "TTFB", "FCP"];
|
|
24
|
-
var vitals = new Map;
|
|
25
|
-
var vitalsSnapshot = new Map;
|
|
26
|
-
var vitalListeners = new Set;
|
|
27
|
-
var vitalsStarted = false;
|
|
28
|
-
function recordVital(name, value, rating) {
|
|
29
|
-
vitals.set(name, { value, rating });
|
|
30
|
-
vitalsSnapshot = new Map(vitals);
|
|
31
|
-
for (const listener of vitalListeners)
|
|
32
|
-
listener();
|
|
33
|
-
}
|
|
34
|
-
function startVitals() {
|
|
35
|
-
if (vitalsStarted || typeof window === "undefined")
|
|
36
|
-
return;
|
|
37
|
-
vitalsStarted = true;
|
|
38
|
-
import("web-vitals").then(({ onCLS, onFCP, onLCP, onTTFB, onINP }) => {
|
|
39
|
-
const report = (metric) => recordVital(metric.name, metric.value, metric.rating);
|
|
40
|
-
onCLS(report, { reportAllChanges: true });
|
|
41
|
-
onINP(report, { reportAllChanges: true });
|
|
42
|
-
onLCP(report);
|
|
43
|
-
onFCP(report);
|
|
44
|
-
onTTFB(report);
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
function subscribeVitals(listener) {
|
|
48
|
-
vitalListeners.add(listener);
|
|
49
|
-
return () => vitalListeners.delete(listener);
|
|
50
|
-
}
|
|
51
|
-
function getVitalsSnapshot() {
|
|
52
|
-
const out = {};
|
|
53
|
-
for (const [name, sample] of vitals)
|
|
54
|
-
out[name] = Number(sample.value.toFixed(2));
|
|
55
|
-
return out;
|
|
56
|
-
}
|
|
57
|
-
function formatVital(name, value) {
|
|
58
|
-
if (name === "CLS")
|
|
59
|
-
return value.toFixed(3);
|
|
60
|
-
if (value >= 1000)
|
|
61
|
-
return `${(value / 1000).toFixed(2)} s`;
|
|
62
|
-
return `${Math.round(value)} ms`;
|
|
63
|
-
}
|
|
64
|
-
var RATING_CLASS = {
|
|
65
|
-
good: "text-emerald-500",
|
|
66
|
-
"needs-improvement": "text-amber-500",
|
|
67
|
-
poor: "text-red-500"
|
|
68
|
-
};
|
|
69
|
-
function VitalsPanel() {
|
|
70
|
-
const { config } = useHud();
|
|
71
|
-
const samples = useSyncExternalStore(subscribeVitals, () => vitalsSnapshot, () => vitalsSnapshot);
|
|
72
|
-
useEffect(() => {
|
|
73
|
-
startVitals();
|
|
74
|
-
}, []);
|
|
75
|
-
const apiBase = config.apiBase ?? "/api/hud";
|
|
76
|
-
const signoz = usePoll(`${apiBase}/signoz?service=${encodeURIComponent(config.appSlug)}`, 60000);
|
|
77
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
78
|
-
className: "space-y-4",
|
|
79
|
-
children: [
|
|
80
|
-
/* @__PURE__ */ jsxs(PanelSection, {
|
|
81
|
-
icon: Activity,
|
|
82
|
-
title: "Web Vitals · this page load",
|
|
83
|
-
children: [
|
|
84
|
-
/* @__PURE__ */ jsx("div", {
|
|
85
|
-
className: "flex flex-wrap gap-2 px-2",
|
|
86
|
-
children: VITAL_ORDER.map((name) => {
|
|
87
|
-
const sample = samples.get(name);
|
|
88
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
89
|
-
className: "min-w-[92px] rounded-md border bg-muted/20 px-3 py-2",
|
|
90
|
-
children: [
|
|
91
|
-
/* @__PURE__ */ jsx("div", {
|
|
92
|
-
className: "text-[10px] uppercase tracking-wider text-muted-foreground",
|
|
93
|
-
children: name
|
|
94
|
-
}),
|
|
95
|
-
/* @__PURE__ */ jsx("div", {
|
|
96
|
-
className: `font-mono text-sm font-semibold ${sample ? RATING_CLASS[sample.rating] : "text-muted-foreground/50"}`,
|
|
97
|
-
children: sample ? formatVital(name, sample.value) : "—"
|
|
98
|
-
})
|
|
99
|
-
]
|
|
100
|
-
}, name);
|
|
101
|
-
})
|
|
102
|
-
}),
|
|
103
|
-
/* @__PURE__ */ jsx("p", {
|
|
104
|
-
className: "px-2 text-[10px] text-muted-foreground/60",
|
|
105
|
-
children: "CLS/INP update live; LCP/FCP/TTFB are per page load. History lands in SigNoz via /api/otel/vitals."
|
|
106
|
-
})
|
|
107
|
-
]
|
|
108
|
-
}),
|
|
109
|
-
/* @__PURE__ */ jsxs(PanelSection, {
|
|
110
|
-
icon: ServerCrash,
|
|
111
|
-
title: `Server · ${config.appSlug} (1h)`,
|
|
112
|
-
children: [
|
|
113
|
-
signoz.loading && /* @__PURE__ */ jsx(LoadingSpinner, {}),
|
|
114
|
-
signoz.error && /* @__PURE__ */ jsxs("p", {
|
|
115
|
-
className: "px-2 text-[10px] text-amber-500",
|
|
116
|
-
children: [
|
|
117
|
-
"hub unreachable — ",
|
|
118
|
-
signoz.error
|
|
119
|
-
]
|
|
120
|
-
}),
|
|
121
|
-
signoz.data && /* @__PURE__ */ jsxs("div", {
|
|
122
|
-
className: "space-y-1 px-2",
|
|
123
|
-
children: [
|
|
124
|
-
/* @__PURE__ */ jsxs("div", {
|
|
125
|
-
className: "flex items-center gap-2",
|
|
126
|
-
children: [
|
|
127
|
-
/* @__PURE__ */ jsx(ServerStat, {
|
|
128
|
-
label: "error rate",
|
|
129
|
-
value: signoz.data.errorRate,
|
|
130
|
-
unit: "/s"
|
|
131
|
-
}),
|
|
132
|
-
/* @__PURE__ */ jsx(ServerStat, {
|
|
133
|
-
label: "p95",
|
|
134
|
-
value: signoz.data.p95Latency,
|
|
135
|
-
unit: " ms"
|
|
136
|
-
}),
|
|
137
|
-
/* @__PURE__ */ jsx(ServerStat, {
|
|
138
|
-
label: "req rate",
|
|
139
|
-
value: signoz.data.requestCount,
|
|
140
|
-
unit: "/s"
|
|
141
|
-
})
|
|
142
|
-
]
|
|
143
|
-
}),
|
|
144
|
-
signoz.data.source === "mock" && /* @__PURE__ */ jsx(Badge, {
|
|
145
|
-
variant: "outline",
|
|
146
|
-
className: "h-4 px-1.5 text-[9px] text-muted-foreground",
|
|
147
|
-
children: "mock data — SIGNOZ_QUERY_URL unset"
|
|
148
|
-
})
|
|
149
|
-
]
|
|
150
|
-
})
|
|
151
|
-
]
|
|
152
|
-
})
|
|
153
|
-
]
|
|
154
|
-
});
|
|
155
|
-
}
|
|
156
|
-
function ServerStat({ label, value, unit }) {
|
|
157
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
158
|
-
className: "min-w-[92px] rounded-md border bg-muted/20 px-3 py-2",
|
|
159
|
-
children: [
|
|
160
|
-
/* @__PURE__ */ jsx("div", {
|
|
161
|
-
className: "text-[10px] uppercase tracking-wider text-muted-foreground",
|
|
162
|
-
children: label
|
|
163
|
-
}),
|
|
164
|
-
/* @__PURE__ */ jsx("div", {
|
|
165
|
-
className: "font-mono text-sm font-semibold",
|
|
166
|
-
children: value === null ? "—" : `${value.toFixed(value < 10 ? 2 : 0)}${unit}`
|
|
167
|
-
})
|
|
168
|
-
]
|
|
169
|
-
});
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
export { getVitalsSnapshot, VitalsPanel };
|
package/chunk-hc2g0n35.js
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
// core/mock-cookie.ts
|
|
2
|
-
var HUD_MOCK_COOKIE = "hud-mock";
|
|
3
|
-
function isHudMockEnabled(cookieValue, env) {
|
|
4
|
-
const hudAllowed = env.nodeEnv === "development" || env.hudEnabled === "true";
|
|
5
|
-
return hudAllowed && cookieValue === "1";
|
|
6
|
-
}
|
|
7
|
-
function hudMockCookieString(enabled) {
|
|
8
|
-
if (!enabled)
|
|
9
|
-
return `${HUD_MOCK_COOKIE}=; path=/; max-age=0; samesite=lax`;
|
|
10
|
-
return `${HUD_MOCK_COOKIE}=1; path=/; max-age=${60 * 60 * 24 * 30}; samesite=lax`;
|
|
11
|
-
}
|
|
12
|
-
function readHudMockCookie() {
|
|
13
|
-
if (typeof document === "undefined")
|
|
14
|
-
return;
|
|
15
|
-
const match = document.cookie.split("; ").find((part) => part.startsWith(`${HUD_MOCK_COOKIE}=`));
|
|
16
|
-
return match?.slice(HUD_MOCK_COOKIE.length + 1);
|
|
17
|
-
}
|
|
18
|
-
function setHudMockCookie(enabled) {
|
|
19
|
-
if (typeof document === "undefined")
|
|
20
|
-
return;
|
|
21
|
-
document.cookie = hudMockCookieString(enabled);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export { HUD_MOCK_COOKIE, isHudMockEnabled, hudMockCookieString, readHudMockCookie, setHudMockCookie };
|
package/chunk-k0vr8dsy.js
DELETED
|
@@ -1,179 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
bridgeFetch,
|
|
3
|
-
getBridgeInfo
|
|
4
|
-
} from "./chunk-50pq4sg6.js";
|
|
5
|
-
import {
|
|
6
|
-
useHud
|
|
7
|
-
} from "./chunk-wspz08q7.js";
|
|
8
|
-
import {
|
|
9
|
-
LoadingSpinner,
|
|
10
|
-
PanelSection
|
|
11
|
-
} from "./chunk-kyeb6qeq.js";
|
|
12
|
-
import {
|
|
13
|
-
Badge,
|
|
14
|
-
Button,
|
|
15
|
-
Switch
|
|
16
|
-
} from "./chunk-xztw0xyt.js";
|
|
17
|
-
import {
|
|
18
|
-
readHudMockCookie,
|
|
19
|
-
setHudMockCookie
|
|
20
|
-
} from "./chunk-hc2g0n35.js";
|
|
21
|
-
|
|
22
|
-
// panels/mock-seed-panel.tsx
|
|
23
|
-
import { Database, FlaskConical, RefreshCw } from "lucide-react";
|
|
24
|
-
import { useEffect, useState } from "react";
|
|
25
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
26
|
-
"use client";
|
|
27
|
-
function MockSeedPanel({ seeds = [] }) {
|
|
28
|
-
const { config, can } = useHud();
|
|
29
|
-
const [mockCookie, setMockCookie] = useState(undefined);
|
|
30
|
-
const [bridge, setBridge] = useState(undefined);
|
|
31
|
-
const [runs, setRuns] = useState([]);
|
|
32
|
-
const apiBase = config.apiBase ?? "/api/hud";
|
|
33
|
-
const canSeed = can("inject.seed") && seeds.length > 0;
|
|
34
|
-
useEffect(() => {
|
|
35
|
-
setMockCookie(readHudMockCookie());
|
|
36
|
-
}, []);
|
|
37
|
-
useEffect(() => {
|
|
38
|
-
if (!canSeed)
|
|
39
|
-
return;
|
|
40
|
-
let cancelled = false;
|
|
41
|
-
getBridgeInfo(apiBase).then((info) => {
|
|
42
|
-
if (!cancelled)
|
|
43
|
-
setBridge(info);
|
|
44
|
-
});
|
|
45
|
-
return () => {
|
|
46
|
-
cancelled = true;
|
|
47
|
-
};
|
|
48
|
-
}, [apiBase, canSeed]);
|
|
49
|
-
const mockOn = mockCookie === "1";
|
|
50
|
-
function toggleMock(next) {
|
|
51
|
-
setHudMockCookie(next);
|
|
52
|
-
setMockCookie(next ? "1" : undefined);
|
|
53
|
-
window.location.reload();
|
|
54
|
-
}
|
|
55
|
-
async function runSeed(seed) {
|
|
56
|
-
if (!bridge)
|
|
57
|
-
return;
|
|
58
|
-
const runId = `${seed.id}-${Date.now()}`;
|
|
59
|
-
setRuns((prev) => [{ id: runId, label: seed.label, status: "running" }, ...prev]);
|
|
60
|
-
try {
|
|
61
|
-
const res = await bridgeFetch(bridge, "/seed", {
|
|
62
|
-
method: "POST",
|
|
63
|
-
body: JSON.stringify({
|
|
64
|
-
app: config.appSlug,
|
|
65
|
-
fn: seed.fn,
|
|
66
|
-
args: seed.args,
|
|
67
|
-
local: seed.local
|
|
68
|
-
})
|
|
69
|
-
});
|
|
70
|
-
const body = await res.json();
|
|
71
|
-
setRuns((prev) => prev.map((run) => run.id === runId ? { ...run, status: body.ok ? "done" : "failed", detail: body.output ?? body.error } : run));
|
|
72
|
-
} catch (error) {
|
|
73
|
-
setRuns((prev) => prev.map((run) => run.id === runId ? {
|
|
74
|
-
...run,
|
|
75
|
-
status: "failed",
|
|
76
|
-
detail: error instanceof Error ? error.message : "seed failed"
|
|
77
|
-
} : run));
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
81
|
-
className: "space-y-4",
|
|
82
|
-
children: [
|
|
83
|
-
can("mock.toggle") && /* @__PURE__ */ jsx(PanelSection, {
|
|
84
|
-
icon: FlaskConical,
|
|
85
|
-
title: "Mock Convex",
|
|
86
|
-
children: /* @__PURE__ */ jsxs("div", {
|
|
87
|
-
className: "flex items-center justify-between px-2",
|
|
88
|
-
children: [
|
|
89
|
-
/* @__PURE__ */ jsxs("div", {
|
|
90
|
-
children: [
|
|
91
|
-
/* @__PURE__ */ jsx("div", {
|
|
92
|
-
className: "text-xs font-medium",
|
|
93
|
-
children: "Mock backend"
|
|
94
|
-
}),
|
|
95
|
-
/* @__PURE__ */ jsx("p", {
|
|
96
|
-
className: "text-[10px] text-muted-foreground/60",
|
|
97
|
-
children: "Swaps the Convex client for a dummy — reload applies (server re-reads the cookie)."
|
|
98
|
-
})
|
|
99
|
-
]
|
|
100
|
-
}),
|
|
101
|
-
/* @__PURE__ */ jsxs("div", {
|
|
102
|
-
className: "flex items-center gap-2",
|
|
103
|
-
children: [
|
|
104
|
-
mockOn && /* @__PURE__ */ jsx(Badge, {
|
|
105
|
-
variant: "outline",
|
|
106
|
-
className: "h-4 px-1.5 text-[9px] text-amber-500",
|
|
107
|
-
children: "mock"
|
|
108
|
-
}),
|
|
109
|
-
/* @__PURE__ */ jsx(Switch, {
|
|
110
|
-
checked: mockOn,
|
|
111
|
-
onCheckedChange: toggleMock
|
|
112
|
-
})
|
|
113
|
-
]
|
|
114
|
-
})
|
|
115
|
-
]
|
|
116
|
-
})
|
|
117
|
-
}),
|
|
118
|
-
canSeed && /* @__PURE__ */ jsxs(PanelSection, {
|
|
119
|
-
icon: Database,
|
|
120
|
-
title: "Seed data",
|
|
121
|
-
children: [
|
|
122
|
-
bridge === undefined && /* @__PURE__ */ jsx(LoadingSpinner, {}),
|
|
123
|
-
bridge === null && /* @__PURE__ */ jsx("p", {
|
|
124
|
-
className: "px-2 text-[10px] text-amber-500",
|
|
125
|
-
children: "bridge not reachable — run `bun hud:bridge` in the repo to seed from here."
|
|
126
|
-
}),
|
|
127
|
-
bridge != null && /* @__PURE__ */ jsx("div", {
|
|
128
|
-
className: "space-y-1 px-2",
|
|
129
|
-
children: seeds.map((seed) => /* @__PURE__ */ jsxs("div", {
|
|
130
|
-
className: "flex items-center gap-2",
|
|
131
|
-
children: [
|
|
132
|
-
/* @__PURE__ */ jsxs(Button, {
|
|
133
|
-
size: "sm",
|
|
134
|
-
variant: "outline",
|
|
135
|
-
className: "h-6 text-[11px]",
|
|
136
|
-
onClick: () => runSeed(seed),
|
|
137
|
-
children: [
|
|
138
|
-
/* @__PURE__ */ jsx(RefreshCw, {
|
|
139
|
-
className: "mr-1.5 h-3 w-3"
|
|
140
|
-
}),
|
|
141
|
-
seed.label
|
|
142
|
-
]
|
|
143
|
-
}),
|
|
144
|
-
seed.description && /* @__PURE__ */ jsx("span", {
|
|
145
|
-
className: "min-w-0 flex-1 truncate text-[10px] text-muted-foreground/60",
|
|
146
|
-
children: seed.description
|
|
147
|
-
})
|
|
148
|
-
]
|
|
149
|
-
}, seed.id))
|
|
150
|
-
})
|
|
151
|
-
]
|
|
152
|
-
}),
|
|
153
|
-
runs.length > 0 && /* @__PURE__ */ jsx(PanelSection, {
|
|
154
|
-
title: "Seed runs",
|
|
155
|
-
children: runs.map((run) => /* @__PURE__ */ jsxs("div", {
|
|
156
|
-
className: "flex items-center gap-2 px-2 py-1 font-mono text-[10.5px]",
|
|
157
|
-
children: [
|
|
158
|
-
/* @__PURE__ */ jsx(Badge, {
|
|
159
|
-
variant: "outline",
|
|
160
|
-
className: `h-4 px-1.5 text-[9px] ${run.status === "done" ? "text-emerald-500" : run.status === "failed" ? "text-red-500" : "text-amber-500"}`,
|
|
161
|
-
children: run.status
|
|
162
|
-
}),
|
|
163
|
-
/* @__PURE__ */ jsx("span", {
|
|
164
|
-
className: "min-w-0 flex-1 truncate",
|
|
165
|
-
children: run.label
|
|
166
|
-
}),
|
|
167
|
-
run.detail && /* @__PURE__ */ jsx("span", {
|
|
168
|
-
className: "max-w-[220px] truncate text-muted-foreground/60",
|
|
169
|
-
title: run.detail,
|
|
170
|
-
children: run.detail
|
|
171
|
-
})
|
|
172
|
-
]
|
|
173
|
-
}, run.id))
|
|
174
|
-
})
|
|
175
|
-
]
|
|
176
|
-
});
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
export { MockSeedPanel };
|
package/chunk-k50yfp5d.js
DELETED
|
@@ -1,166 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
useHud
|
|
3
|
-
} from "./chunk-wspz08q7.js";
|
|
4
|
-
import {
|
|
5
|
-
PanelSection
|
|
6
|
-
} from "./chunk-kyeb6qeq.js";
|
|
7
|
-
import {
|
|
8
|
-
Badge,
|
|
9
|
-
Button
|
|
10
|
-
} from "./chunk-xztw0xyt.js";
|
|
11
|
-
|
|
12
|
-
// panels/variants-panel.tsx
|
|
13
|
-
import { ArrowUpRight, Beaker, Wand2 } from "lucide-react";
|
|
14
|
-
import { useState } from "react";
|
|
15
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
16
|
-
"use client";
|
|
17
|
-
var STATUS_CLASS = {
|
|
18
|
-
active: "text-emerald-500",
|
|
19
|
-
decided: "text-muted-foreground"
|
|
20
|
-
};
|
|
21
|
-
function VariantsPanel({ adapter }) {
|
|
22
|
-
const { can } = useHud();
|
|
23
|
-
const { categories, reviewHref, categoryHref, openPreview, generate } = adapter;
|
|
24
|
-
const [path, setPath] = useState("");
|
|
25
|
-
const [brief, setBrief] = useState("");
|
|
26
|
-
const [result, setResult] = useState(null);
|
|
27
|
-
const [sending, setSending] = useState(false);
|
|
28
|
-
const grouped = new Map;
|
|
29
|
-
for (const category of categories) {
|
|
30
|
-
const key = category.domain ?? "shared";
|
|
31
|
-
grouped.set(key, [...grouped.get(key) ?? [], category]);
|
|
32
|
-
}
|
|
33
|
-
async function submitGenerate() {
|
|
34
|
-
if (!generate || !path.trim())
|
|
35
|
-
return;
|
|
36
|
-
setSending(true);
|
|
37
|
-
setResult(null);
|
|
38
|
-
try {
|
|
39
|
-
setResult(await generate({ path: path.trim(), brief: brief.trim(), count: 3 }));
|
|
40
|
-
} catch (error) {
|
|
41
|
-
setResult({ ok: false, error: error instanceof Error ? error.message : "generate failed" });
|
|
42
|
-
} finally {
|
|
43
|
-
setSending(false);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
47
|
-
className: "space-y-4",
|
|
48
|
-
children: [
|
|
49
|
-
/* @__PURE__ */ jsxs(PanelSection, {
|
|
50
|
-
icon: Beaker,
|
|
51
|
-
title: `Categories (${categories.length})`,
|
|
52
|
-
children: [
|
|
53
|
-
categories.length === 0 && /* @__PURE__ */ jsx("p", {
|
|
54
|
-
className: "px-2 text-[10px] text-muted-foreground/60",
|
|
55
|
-
children: "No preview categories registered for this app."
|
|
56
|
-
}),
|
|
57
|
-
/* @__PURE__ */ jsx("div", {
|
|
58
|
-
className: "space-y-2 px-2",
|
|
59
|
-
children: Array.from(grouped.entries()).map(([domain, list]) => /* @__PURE__ */ jsxs("div", {
|
|
60
|
-
children: [
|
|
61
|
-
/* @__PURE__ */ jsx("div", {
|
|
62
|
-
className: "text-[9px] uppercase tracking-wider text-muted-foreground/50",
|
|
63
|
-
children: domain
|
|
64
|
-
}),
|
|
65
|
-
list.map((category) => /* @__PURE__ */ jsxs("div", {
|
|
66
|
-
className: "flex items-center gap-2 py-1 text-[11px]",
|
|
67
|
-
children: [
|
|
68
|
-
/* @__PURE__ */ jsx(Badge, {
|
|
69
|
-
variant: "outline",
|
|
70
|
-
className: `h-4 px-1.5 text-[9px] ${STATUS_CLASS[category.status] ?? "text-amber-500"}`,
|
|
71
|
-
children: category.status
|
|
72
|
-
}),
|
|
73
|
-
/* @__PURE__ */ jsx("span", {
|
|
74
|
-
className: "min-w-0 flex-1 truncate",
|
|
75
|
-
children: category.name
|
|
76
|
-
}),
|
|
77
|
-
/* @__PURE__ */ jsxs("span", {
|
|
78
|
-
className: "text-muted-foreground/60",
|
|
79
|
-
children: [
|
|
80
|
-
category.alternativeCount,
|
|
81
|
-
" alt",
|
|
82
|
-
category.alternativeCount === 1 ? "" : "s"
|
|
83
|
-
]
|
|
84
|
-
}),
|
|
85
|
-
openPreview ? /* @__PURE__ */ jsx(Button, {
|
|
86
|
-
variant: "ghost",
|
|
87
|
-
size: "sm",
|
|
88
|
-
className: "h-5 px-1.5 text-[10px]",
|
|
89
|
-
onClick: () => openPreview(category.id),
|
|
90
|
-
children: "open"
|
|
91
|
-
}) : categoryHref ? /* @__PURE__ */ jsxs("a", {
|
|
92
|
-
href: categoryHref(category.id),
|
|
93
|
-
className: "inline-flex items-center gap-0.5 text-[10px] text-primary hover:underline",
|
|
94
|
-
children: [
|
|
95
|
-
"open",
|
|
96
|
-
/* @__PURE__ */ jsx(ArrowUpRight, {
|
|
97
|
-
className: "h-2.5 w-2.5"
|
|
98
|
-
})
|
|
99
|
-
]
|
|
100
|
-
}) : null
|
|
101
|
-
]
|
|
102
|
-
}, category.id))
|
|
103
|
-
]
|
|
104
|
-
}, domain))
|
|
105
|
-
}),
|
|
106
|
-
/* @__PURE__ */ jsx("div", {
|
|
107
|
-
className: "px-2 pt-1",
|
|
108
|
-
children: /* @__PURE__ */ jsxs("a", {
|
|
109
|
-
href: reviewHref,
|
|
110
|
-
className: "inline-flex items-center gap-1 text-[10px] text-primary hover:underline",
|
|
111
|
-
children: [
|
|
112
|
-
"Full review dashboard (vote, showcase, decisions)",
|
|
113
|
-
/* @__PURE__ */ jsx(ArrowUpRight, {
|
|
114
|
-
className: "h-3 w-3"
|
|
115
|
-
})
|
|
116
|
-
]
|
|
117
|
-
})
|
|
118
|
-
})
|
|
119
|
-
]
|
|
120
|
-
}),
|
|
121
|
-
generate && can("variants.generate") && /* @__PURE__ */ jsx(PanelSection, {
|
|
122
|
-
icon: Wand2,
|
|
123
|
-
title: "Generate variants",
|
|
124
|
-
children: /* @__PURE__ */ jsxs("div", {
|
|
125
|
-
className: "space-y-2 px-2",
|
|
126
|
-
children: [
|
|
127
|
-
/* @__PURE__ */ jsx("input", {
|
|
128
|
-
value: path,
|
|
129
|
-
onChange: (e) => setPath(e.target.value),
|
|
130
|
-
placeholder: "apps/console/src/components/… (repo-relative)",
|
|
131
|
-
className: "w-full rounded-md border bg-muted/20 p-2 font-mono text-[11px] outline-none focus:ring-1 focus:ring-ring"
|
|
132
|
-
}),
|
|
133
|
-
/* @__PURE__ */ jsx("textarea", {
|
|
134
|
-
value: brief,
|
|
135
|
-
onChange: (e) => setBrief(e.target.value),
|
|
136
|
-
placeholder: "Brief, e.g.: three denser table treatments, keep the glass language",
|
|
137
|
-
className: "min-h-[44px] w-full rounded-md border bg-muted/20 p-2 font-mono text-[11px] outline-none focus:ring-1 focus:ring-ring"
|
|
138
|
-
}),
|
|
139
|
-
/* @__PURE__ */ jsxs("div", {
|
|
140
|
-
className: "flex items-center gap-2",
|
|
141
|
-
children: [
|
|
142
|
-
/* @__PURE__ */ jsx(Button, {
|
|
143
|
-
size: "sm",
|
|
144
|
-
className: "h-6 text-[11px]",
|
|
145
|
-
disabled: sending || !path.trim(),
|
|
146
|
-
onClick: submitGenerate,
|
|
147
|
-
children: "Queue 3 variants"
|
|
148
|
-
}),
|
|
149
|
-
/* @__PURE__ */ jsx("span", {
|
|
150
|
-
className: "text-[10px] text-muted-foreground/60",
|
|
151
|
-
children: "Writes a .claude/queue marker — the next session runs /generate-variants."
|
|
152
|
-
})
|
|
153
|
-
]
|
|
154
|
-
}),
|
|
155
|
-
result && /* @__PURE__ */ jsx("p", {
|
|
156
|
-
className: `font-mono text-[10px] ${result.ok ? "text-emerald-500" : "text-red-500"}`,
|
|
157
|
-
children: result.ok ? `queued → ${result.markerPath}` : result.error
|
|
158
|
-
})
|
|
159
|
-
]
|
|
160
|
-
})
|
|
161
|
-
})
|
|
162
|
-
]
|
|
163
|
-
});
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
export { VariantsPanel };
|
package/chunk-kyeb6qeq.js
DELETED
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Button
|
|
3
|
-
} from "./chunk-xztw0xyt.js";
|
|
4
|
-
|
|
5
|
-
// panels/info-row.tsx
|
|
6
|
-
import { Copy } from "lucide-react";
|
|
7
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
-
"use client";
|
|
9
|
-
function PanelSection({
|
|
10
|
-
icon: Icon,
|
|
11
|
-
title,
|
|
12
|
-
children
|
|
13
|
-
}) {
|
|
14
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
15
|
-
children: [
|
|
16
|
-
/* @__PURE__ */ jsxs("h4", {
|
|
17
|
-
className: "mb-2 flex items-center gap-1.5 text-[11px] font-semibold uppercase tracking-wider text-muted-foreground",
|
|
18
|
-
children: [
|
|
19
|
-
Icon && /* @__PURE__ */ jsx(Icon, {
|
|
20
|
-
className: "h-3 w-3"
|
|
21
|
-
}),
|
|
22
|
-
title
|
|
23
|
-
]
|
|
24
|
-
}),
|
|
25
|
-
/* @__PURE__ */ jsx("div", {
|
|
26
|
-
className: "space-y-1.5",
|
|
27
|
-
children
|
|
28
|
-
})
|
|
29
|
-
]
|
|
30
|
-
});
|
|
31
|
-
}
|
|
32
|
-
function InfoRow({
|
|
33
|
-
label,
|
|
34
|
-
value,
|
|
35
|
-
copyable = false
|
|
36
|
-
}) {
|
|
37
|
-
function handleCopy() {
|
|
38
|
-
navigator.clipboard.writeText(value);
|
|
39
|
-
}
|
|
40
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
41
|
-
className: "flex items-center justify-between px-2 py-1 hover:bg-muted/50",
|
|
42
|
-
children: [
|
|
43
|
-
/* @__PURE__ */ jsx("span", {
|
|
44
|
-
className: "text-[10px] text-muted-foreground",
|
|
45
|
-
children: label
|
|
46
|
-
}),
|
|
47
|
-
/* @__PURE__ */ jsxs("div", {
|
|
48
|
-
className: "flex items-center gap-1",
|
|
49
|
-
children: [
|
|
50
|
-
/* @__PURE__ */ jsx("span", {
|
|
51
|
-
className: "max-w-[220px] truncate font-mono text-[10px]",
|
|
52
|
-
children: value
|
|
53
|
-
}),
|
|
54
|
-
copyable && /* @__PURE__ */ jsx(Button, {
|
|
55
|
-
variant: "ghost",
|
|
56
|
-
size: "icon",
|
|
57
|
-
className: "h-4 w-4 shrink-0",
|
|
58
|
-
onClick: handleCopy,
|
|
59
|
-
children: /* @__PURE__ */ jsx(Copy, {
|
|
60
|
-
className: "h-2.5 w-2.5"
|
|
61
|
-
})
|
|
62
|
-
})
|
|
63
|
-
]
|
|
64
|
-
})
|
|
65
|
-
]
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
function ShortcutRow({ keys, label }) {
|
|
69
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
70
|
-
className: "flex items-center justify-between px-2 py-1",
|
|
71
|
-
children: [
|
|
72
|
-
/* @__PURE__ */ jsx("span", {
|
|
73
|
-
className: "text-[10px] text-muted-foreground",
|
|
74
|
-
children: label
|
|
75
|
-
}),
|
|
76
|
-
/* @__PURE__ */ jsx("div", {
|
|
77
|
-
className: "flex gap-0.5",
|
|
78
|
-
children: keys.map((key) => /* @__PURE__ */ jsx("kbd", {
|
|
79
|
-
className: "flex h-5 min-w-[20px] items-center justify-center rounded border bg-muted/50 px-1 font-mono text-[10px]",
|
|
80
|
-
children: key
|
|
81
|
-
}, key))
|
|
82
|
-
})
|
|
83
|
-
]
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
function LoadingSpinner() {
|
|
87
|
-
return /* @__PURE__ */ jsx("div", {
|
|
88
|
-
className: "flex items-center justify-center py-8",
|
|
89
|
-
children: /* @__PURE__ */ jsx("div", {
|
|
90
|
-
className: "h-5 w-5 animate-spin rounded-full border-2 border-muted-foreground border-t-transparent"
|
|
91
|
-
})
|
|
92
|
-
});
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
export { PanelSection, InfoRow, ShortcutRow, LoadingSpinner };
|