@legioncodeinc/hive 0.2.0 → 0.3.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 +2 -2
- package/dist/daemon/dashboard/app.js +26 -25
- package/dist/daemon/dashboard/host.d.ts +7 -0
- package/dist/daemon/dashboard/host.js +16 -0
- package/dist/daemon/dashboard/host.js.map +1 -1
- package/dist/daemon/dashboard/web-assets.d.ts +2 -0
- package/dist/daemon/dashboard/web-assets.js +19 -0
- package/dist/daemon/dashboard/web-assets.js.map +1 -1
- package/dist/daemon/gate.d.ts +2 -2
- package/dist/daemon/gate.js +15 -4
- package/dist/daemon/gate.js.map +1 -1
- package/dist/daemon/installer/bin-resolver.d.ts +34 -0
- package/dist/daemon/installer/bin-resolver.js +86 -0
- package/dist/daemon/installer/bin-resolver.js.map +1 -0
- package/dist/daemon/installer/config.d.ts +63 -0
- package/dist/daemon/installer/config.js +74 -0
- package/dist/daemon/installer/config.js.map +1 -0
- package/dist/daemon/installer/detection.d.ts +20 -0
- package/dist/daemon/installer/detection.js +73 -0
- package/dist/daemon/installer/detection.js.map +1 -0
- package/dist/daemon/installer/funnel-telemetry.d.ts +54 -0
- package/dist/daemon/installer/funnel-telemetry.js +134 -0
- package/dist/daemon/installer/funnel-telemetry.js.map +1 -0
- package/dist/daemon/installer/index.d.ts +12 -0
- package/dist/daemon/installer/index.js +10 -0
- package/dist/daemon/installer/index.js.map +1 -0
- package/dist/daemon/installer/install-state.d.ts +50 -0
- package/dist/daemon/installer/install-state.js +142 -0
- package/dist/daemon/installer/install-state.js.map +1 -0
- package/dist/daemon/installer/manifest-snapshot.json +25 -0
- package/dist/daemon/installer/manifest.d.ts +47 -0
- package/dist/daemon/installer/manifest.js +103 -0
- package/dist/daemon/installer/manifest.js.map +1 -0
- package/dist/daemon/installer/products.d.ts +33 -0
- package/dist/daemon/installer/products.js +42 -0
- package/dist/daemon/installer/products.js.map +1 -0
- package/dist/daemon/installer/routes.d.ts +43 -0
- package/dist/daemon/installer/routes.js +201 -0
- package/dist/daemon/installer/routes.js.map +1 -0
- package/dist/daemon/installer/security.d.ts +33 -0
- package/dist/daemon/installer/security.js +80 -0
- package/dist/daemon/installer/security.js.map +1 -0
- package/dist/daemon/installer/spawn.d.ts +48 -0
- package/dist/daemon/installer/spawn.js +51 -0
- package/dist/daemon/installer/spawn.js.map +1 -0
- package/dist/daemon/installer/token.d.ts +23 -0
- package/dist/daemon/installer/token.js +56 -0
- package/dist/daemon/installer/token.js.map +1 -0
- package/dist/daemon/server.d.ts +6 -0
- package/dist/daemon/server.js +7 -0
- package/dist/daemon/server.js.map +1 -1
- package/dist/dashboard/web/app.js +42 -20
- package/dist/dashboard/web/app.js.map +1 -1
- package/dist/dashboard/web/boot-route.d.ts +11 -7
- package/dist/dashboard/web/boot-route.js +12 -6
- package/dist/dashboard/web/boot-route.js.map +1 -1
- package/dist/dashboard/web/main.js +2 -1
- package/dist/dashboard/web/main.js.map +1 -1
- package/dist/dashboard/web/onboarding/advanced-picker.d.ts +16 -0
- package/dist/dashboard/web/onboarding/advanced-picker.js +59 -0
- package/dist/dashboard/web/onboarding/advanced-picker.js.map +1 -0
- package/dist/dashboard/web/onboarding/contracts.d.ts +188 -0
- package/dist/dashboard/web/onboarding/contracts.js +161 -0
- package/dist/dashboard/web/onboarding/contracts.js.map +1 -0
- package/dist/dashboard/web/onboarding/health-view.d.ts +17 -0
- package/dist/dashboard/web/onboarding/health-view.js +79 -0
- package/dist/dashboard/web/onboarding/health-view.js.map +1 -0
- package/dist/dashboard/web/onboarding/install-card.d.ts +27 -0
- package/dist/dashboard/web/onboarding/install-card.js +170 -0
- package/dist/dashboard/web/onboarding/install-card.js.map +1 -0
- package/dist/dashboard/web/onboarding/login-step.d.ts +29 -0
- package/dist/dashboard/web/onboarding/login-step.js +104 -0
- package/dist/dashboard/web/onboarding/login-step.js.map +1 -0
- package/dist/dashboard/web/onboarding/onboarding-client.d.ts +52 -0
- package/dist/dashboard/web/onboarding/onboarding-client.js +133 -0
- package/dist/dashboard/web/onboarding/onboarding-client.js.map +1 -0
- package/dist/dashboard/web/onboarding/onboarding-hero.d.ts +24 -0
- package/dist/dashboard/web/onboarding/onboarding-hero.js +70 -0
- package/dist/dashboard/web/onboarding/onboarding-hero.js.map +1 -0
- package/dist/dashboard/web/onboarding/onboarding-screen.d.ts +43 -0
- package/dist/dashboard/web/onboarding/onboarding-screen.js +161 -0
- package/dist/dashboard/web/onboarding/onboarding-screen.js.map +1 -0
- package/dist/dashboard/web/onboarding/onboarding-selection-store.d.ts +20 -0
- package/dist/dashboard/web/onboarding/onboarding-selection-store.js +76 -0
- package/dist/dashboard/web/onboarding/onboarding-selection-store.js.map +1 -0
- package/dist/dashboard/web/onboarding/product-copy.d.ts +40 -0
- package/dist/dashboard/web/onboarding/product-copy.js +70 -0
- package/dist/dashboard/web/onboarding/product-copy.js.map +1 -0
- package/dist/dashboard/web/onboarding/use-install-dwell.d.ts +22 -0
- package/dist/dashboard/web/onboarding/use-install-dwell.js +37 -0
- package/dist/dashboard/web/onboarding/use-install-dwell.js.map +1 -0
- package/dist/dashboard/web/onboarding/use-onboarding-token.d.ts +9 -0
- package/dist/dashboard/web/onboarding/use-onboarding-token.js +34 -0
- package/dist/dashboard/web/onboarding/use-onboarding-token.js.map +1 -0
- package/dist/dashboard/web/route-daemon-owner.d.ts +7 -0
- package/dist/dashboard/web/route-daemon-owner.js +15 -0
- package/dist/dashboard/web/route-daemon-owner.js.map +1 -0
- package/dist/dashboard/web/wire.d.ts +1 -1
- package/dist/shared/onboarding-types.d.ts +79 -0
- package/dist/shared/onboarding-types.js +12 -0
- package/dist/shared/onboarding-types.js.map +1 -0
- package/dist/telemetry/emit.d.ts +30 -3
- package/dist/telemetry/emit.js +25 -2
- package/dist/telemetry/emit.js.map +1 -1
- package/dist/telemetry/onboarding-session-ledger.d.ts +31 -0
- package/dist/telemetry/onboarding-session-ledger.js +78 -0
- package/dist/telemetry/onboarding-session-ledger.js.map +1 -0
- package/package.json +1 -1
|
@@ -38,9 +38,15 @@ import { usePathRoute } from "./router.js";
|
|
|
38
38
|
import { PAGE_MAX_WIDTH, usePoll } from "./page-frame.js";
|
|
39
39
|
import { FirstRunBindCTA } from "./needs-project.js";
|
|
40
40
|
import { ScopeProvider, useScopeSwitcher } from "./scope-context.js";
|
|
41
|
+
import { DEFAULT_DAEMON_BASES } from "../../shared/daemon-routing.js";
|
|
41
42
|
import { createWireClient, EMPTY_SETTINGS } from "./wire.js";
|
|
42
|
-
|
|
43
|
+
import { resolveRouteDaemonOwner } from "./route-daemon-owner.js";
|
|
44
|
+
/** How often the shell probes per-owner liveness (ms). */
|
|
43
45
|
const HEALTH_POLL_MS = 5000;
|
|
46
|
+
const INITIAL_DAEMON_UP = Object.freeze({
|
|
47
|
+
honeycomb: true,
|
|
48
|
+
nectar: true,
|
|
49
|
+
});
|
|
44
50
|
/** The narrow-viewport breakpoint that auto-collapses the sidebar (mirrors host.ts's media rule). */
|
|
45
51
|
const NARROW_BREAKPOINT = 900;
|
|
46
52
|
/**
|
|
@@ -78,7 +84,7 @@ export function Shell({ client, assetBase = "assets" } = {}) {
|
|
|
78
84
|
const wire = React.useMemo(() => client ?? createWireClient(), [client]);
|
|
79
85
|
const { route, navigate } = usePathRoute();
|
|
80
86
|
// ── shell-owned state ──
|
|
81
|
-
const [
|
|
87
|
+
const [daemonUpByOwner, setDaemonUpByOwner] = React.useState(INITIAL_DAEMON_UP);
|
|
82
88
|
// The shell owns the SINGLE `/health` poll; `reasons` flow DOWN to the home's subsystem strip via
|
|
83
89
|
// PageProps so the page never polls `/health` a second time (the former double-poll, now deduped).
|
|
84
90
|
const [healthReasons, setHealthReasons] = React.useState(null);
|
|
@@ -87,7 +93,14 @@ export function Shell({ client, assetBase = "assets" } = {}) {
|
|
|
87
93
|
// Collapsed: a manual toggle OR an auto-collapse under the narrow breakpoint (037a AC-6). We track
|
|
88
94
|
// both an explicit user choice and the viewport, preferring the user's choice once they toggle.
|
|
89
95
|
const [collapsed, setCollapsed] = React.useState(false);
|
|
90
|
-
const
|
|
96
|
+
const routeOwner = resolveRouteDaemonOwner(route);
|
|
97
|
+
const pageDaemonUp = daemonUpByOwner[routeOwner];
|
|
98
|
+
const honeycombUp = daemonUpByOwner.honeycomb;
|
|
99
|
+
const daemonUrl = routeOwner === "nectar"
|
|
100
|
+
? DEFAULT_DAEMON_BASES.nectar
|
|
101
|
+
: settings.settings.port
|
|
102
|
+
? `http://127.0.0.1:${settings.settings.port}`
|
|
103
|
+
: DEFAULT_DAEMON_BASES.honeycomb;
|
|
91
104
|
/** Hydrate the org/workspace identity for the sidebar sub-line (the shell's slice of settings). */
|
|
92
105
|
const hydrateIdentity = React.useCallback(async () => {
|
|
93
106
|
setSettings(await wire.settings());
|
|
@@ -99,17 +112,18 @@ export function Shell({ client, assetBase = "assets" } = {}) {
|
|
|
99
112
|
// Track the previous liveness so identity re-hydration fires ONLY on a down→up recovery (the mount
|
|
100
113
|
// effect already hydrates once) — not on every healthy 5s tick. Null = no probe resolved yet.
|
|
101
114
|
const prevDaemonUpRef = React.useRef(null);
|
|
102
|
-
// D-5: the shell owns
|
|
103
|
-
//
|
|
104
|
-
//
|
|
105
|
-
// here and passed DOWN — the page's former duplicate /health poll is gone.
|
|
115
|
+
// D-5 / c-AC-3: the shell owns per-OWNER liveness polls and gates ONLY the active route's owner.
|
|
116
|
+
// Honeycomb uses `/health`; nectar uses a lightweight hive-graph status probe (nectar-routed).
|
|
117
|
+
// On honeycomb RECOVERY (down→up) re-hydrate the identity. Via `usePoll` for background-tab pause.
|
|
106
118
|
usePoll(async () => {
|
|
107
|
-
const
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
119
|
+
const [honeycombProbe, nectarStatus] = await Promise.all([wire.health(), wire.hiveGraphStatus()]);
|
|
120
|
+
const nextHoneycombUp = honeycombProbe.up;
|
|
121
|
+
const nextNectarUp = !nectarStatus.unreachable;
|
|
122
|
+
setDaemonUpByOwner({ honeycomb: nextHoneycombUp, nectar: nextNectarUp });
|
|
123
|
+
setHealthReasons(honeycombProbe.reasons);
|
|
124
|
+
if (nextHoneycombUp && prevDaemonUpRef.current === false)
|
|
111
125
|
void hydrateIdentity();
|
|
112
|
-
prevDaemonUpRef.current =
|
|
126
|
+
prevDaemonUpRef.current = nextHoneycombUp;
|
|
113
127
|
}, HEALTH_POLL_MS);
|
|
114
128
|
// 037a AC-6: auto-collapse under the narrow breakpoint. Tracks the viewport via matchMedia; the
|
|
115
129
|
// listener is cleaned up on unmount. A manual toggle still works (it sets `collapsed` directly).
|
|
@@ -161,19 +175,27 @@ export function Shell({ client, assetBase = "assets" } = {}) {
|
|
|
161
175
|
const identity = `${settings.orgName || settings.orgId || "local"} · ${settings.workspace || "default"}`;
|
|
162
176
|
// The PageProps every routed page receives (D-7). One shared wire, the liveness flag, the asset
|
|
163
177
|
// base, and the shell-owned pollinating pulse.
|
|
164
|
-
const pageProps = { wire, daemonUp, assetBase, pollinating, healthReasons };
|
|
165
|
-
return (_jsx(ScopeProvider, { wire: wire, children: _jsxs("div", { style: { display: "flex", minHeight: "100vh", background: "var(--bg-canvas)" }, children: [_jsx(Sidebar, { entries: ROUTES, activeRoute: route, onNavigate: navigate, daemonUp:
|
|
178
|
+
const pageProps = { wire, daemonUp: pageDaemonUp, assetBase, pollinating, healthReasons };
|
|
179
|
+
return (_jsx(ScopeProvider, { wire: wire, children: _jsxs("div", { style: { display: "flex", minHeight: "100vh", background: "var(--bg-canvas)" }, children: [_jsx(Sidebar, { entries: ROUTES, activeRoute: route, onNavigate: navigate, daemonUp: honeycombUp, identity: identity, assetBase: assetBase, collapsed: collapsed, onToggleCollapsed: () => setCollapsed((c) => !c) }), _jsxs("div", { style: { flex: 1, minWidth: 0, display: "flex", flexDirection: "column" }, children: [_jsx(HealthRail, { onOpenHealth: () => navigate(HEALTH_ROUTE) }), _jsxs("div", { style: {
|
|
166
180
|
display: "flex",
|
|
167
181
|
alignItems: "center",
|
|
168
182
|
gap: 12,
|
|
169
183
|
padding: "16px 28px",
|
|
170
184
|
borderBottom: "1px solid var(--border-subtle)",
|
|
171
|
-
}, children: [_jsx("span", { style: { flex: 1 } }), _jsx(Button, { variant: "pollinate", onClick: () => void pollinate(), disabled: pollinating, children: pollinating ? "pollinating…" : "Pollinate now" })] }),
|
|
172
|
-
void
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
185
|
+
}, children: [_jsx("span", { style: { flex: 1 } }), _jsx(Button, { variant: "pollinate", onClick: () => void pollinate(), disabled: pollinating, children: pollinating ? "pollinating…" : "Pollinate now" })] }), pageDaemonUp ? (_jsx(Outlet, { route: route, pageProps: pageProps, navigate: navigate })) : (_jsx("div", { style: { flex: 1, minWidth: 0, padding: "28px 28px 48px" }, children: _jsx("div", { style: { maxWidth: PAGE_MAX_WIDTH, margin: "0 auto" }, children: _jsx(ConnectivityBanner, { url: daemonUrl, onRetry: () => {
|
|
186
|
+
void (async () => {
|
|
187
|
+
if (routeOwner === "nectar") {
|
|
188
|
+
const status = await wire.hiveGraphStatus();
|
|
189
|
+
const up = !status.unreachable;
|
|
190
|
+
setDaemonUpByOwner((prev) => ({ ...prev, nectar: up }));
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
const { up } = await wire.health();
|
|
194
|
+
setDaemonUpByOwner((prev) => ({ ...prev, honeycomb: up }));
|
|
195
|
+
if (up)
|
|
196
|
+
void hydrateIdentity();
|
|
197
|
+
}
|
|
198
|
+
})();
|
|
177
199
|
} }) }) }))] })] }) }));
|
|
178
200
|
}
|
|
179
201
|
//# sourceMappingURL=app.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app.js","sourceRoot":"","sources":["../../../src/dashboard/web/app.tsx"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,EAAmB,MAAM,eAAe,CAAC;AACpE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,OAAO,EAAkB,MAAM,iBAAiB,CAAC;AAC1E,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAA8D,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"app.js","sourceRoot":"","sources":["../../../src/dashboard/web/app.tsx"],"names":[],"mappings":"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"}
|
|
@@ -4,20 +4,24 @@
|
|
|
4
4
|
* By the time this bundle runs, hive's SERVER gate (`hive/src/daemon/gate.ts`, PRD-003a)
|
|
5
5
|
* has already evaluated health-then-auth and served the shell ONLY for a path it authorized:
|
|
6
6
|
* `/buzzing` (fleet not healthy, or landed there directly — always exempt), `/login` (logged out,
|
|
7
|
-
* or landed there directly — always exempt),
|
|
8
|
-
*
|
|
7
|
+
* or landed there directly — always exempt), `/onboarding` (PRD-009b, also gate-exempt — see
|
|
8
|
+
* `gate.ts`'s `GATE_EXEMPT_ROUTES`), or any other path (healthy + authenticated). This pure
|
|
9
|
+
* function is the whole boot decision `main.tsx` needs: a plain lookup from `location.pathname`
|
|
9
10
|
* to which top-level screen to mount. It never re-derives health or auth itself — doing so would
|
|
10
11
|
* resurrect the retired `ReadinessSplash`→`SetupGate` nested client gate (ADR-0004, m-AC-6).
|
|
11
12
|
*/
|
|
12
|
-
export type BootScreen = "buzzing" | "login" | "shell";
|
|
13
|
+
export type BootScreen = "buzzing" | "login" | "onboarding" | "shell";
|
|
13
14
|
/** The `/buzzing` route (PRD-002's readiness splash, now the gate-exempt readiness screen). */
|
|
14
15
|
export declare const BUZZING_PATH: "/buzzing";
|
|
15
16
|
/** The `/login` route (PRD-003b's device-flow guided setup, now the gate-exempt login screen). */
|
|
16
17
|
export declare const LOGIN_PATH: "/login";
|
|
18
|
+
/** The `/onboarding` route (PRD-009b's guided fleet installer, also gate-exempt — ob-AC-1). */
|
|
19
|
+
export declare const ONBOARDING_PATH: "/onboarding";
|
|
17
20
|
/**
|
|
18
|
-
* Resolve which top-level screen `main.tsx` should mount for the current path. `/buzzing
|
|
19
|
-
* `/login` are the
|
|
20
|
-
* every registry route (`/projects`, `/harnesses`, ...) — mounts the
|
|
21
|
-
* whose own path router (`router.tsx`) then resolves the specific page via
|
|
21
|
+
* Resolve which top-level screen `main.tsx` should mount for the current path. `/buzzing`,
|
|
22
|
+
* `/login`, and `/onboarding` are the gate-exempt screens (m-AC-7 / m-AC-8 / ob-AC-1); every other
|
|
23
|
+
* path — including `/` and every registry route (`/projects`, `/harnesses`, ...) — mounts the
|
|
24
|
+
* authenticated `<Shell>`, whose own path router (`router.tsx`) then resolves the specific page via
|
|
25
|
+
* `registry.tsx`.
|
|
22
26
|
*/
|
|
23
27
|
export declare function resolveBootScreen(pathname: string): BootScreen;
|
|
@@ -4,8 +4,9 @@
|
|
|
4
4
|
* By the time this bundle runs, hive's SERVER gate (`hive/src/daemon/gate.ts`, PRD-003a)
|
|
5
5
|
* has already evaluated health-then-auth and served the shell ONLY for a path it authorized:
|
|
6
6
|
* `/buzzing` (fleet not healthy, or landed there directly — always exempt), `/login` (logged out,
|
|
7
|
-
* or landed there directly — always exempt),
|
|
8
|
-
*
|
|
7
|
+
* or landed there directly — always exempt), `/onboarding` (PRD-009b, also gate-exempt — see
|
|
8
|
+
* `gate.ts`'s `GATE_EXEMPT_ROUTES`), or any other path (healthy + authenticated). This pure
|
|
9
|
+
* function is the whole boot decision `main.tsx` needs: a plain lookup from `location.pathname`
|
|
9
10
|
* to which top-level screen to mount. It never re-derives health or auth itself — doing so would
|
|
10
11
|
* resurrect the retired `ReadinessSplash`→`SetupGate` nested client gate (ADR-0004, m-AC-6).
|
|
11
12
|
*/
|
|
@@ -13,17 +14,22 @@
|
|
|
13
14
|
export const BUZZING_PATH = "/buzzing";
|
|
14
15
|
/** The `/login` route (PRD-003b's device-flow guided setup, now the gate-exempt login screen). */
|
|
15
16
|
export const LOGIN_PATH = "/login";
|
|
17
|
+
/** The `/onboarding` route (PRD-009b's guided fleet installer, also gate-exempt — ob-AC-1). */
|
|
18
|
+
export const ONBOARDING_PATH = "/onboarding";
|
|
16
19
|
/**
|
|
17
|
-
* Resolve which top-level screen `main.tsx` should mount for the current path. `/buzzing
|
|
18
|
-
* `/login` are the
|
|
19
|
-
* every registry route (`/projects`, `/harnesses`, ...) — mounts the
|
|
20
|
-
* whose own path router (`router.tsx`) then resolves the specific page via
|
|
20
|
+
* Resolve which top-level screen `main.tsx` should mount for the current path. `/buzzing`,
|
|
21
|
+
* `/login`, and `/onboarding` are the gate-exempt screens (m-AC-7 / m-AC-8 / ob-AC-1); every other
|
|
22
|
+
* path — including `/` and every registry route (`/projects`, `/harnesses`, ...) — mounts the
|
|
23
|
+
* authenticated `<Shell>`, whose own path router (`router.tsx`) then resolves the specific page via
|
|
24
|
+
* `registry.tsx`.
|
|
21
25
|
*/
|
|
22
26
|
export function resolveBootScreen(pathname) {
|
|
23
27
|
if (pathname === BUZZING_PATH)
|
|
24
28
|
return "buzzing";
|
|
25
29
|
if (pathname === LOGIN_PATH)
|
|
26
30
|
return "login";
|
|
31
|
+
if (pathname === ONBOARDING_PATH)
|
|
32
|
+
return "onboarding";
|
|
27
33
|
return "shell";
|
|
28
34
|
}
|
|
29
35
|
//# sourceMappingURL=boot-route.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"boot-route.js","sourceRoot":"","sources":["../../../src/dashboard/web/boot-route.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"boot-route.js","sourceRoot":"","sources":["../../../src/dashboard/web/boot-route.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,+FAA+F;AAC/F,MAAM,CAAC,MAAM,YAAY,GAAG,UAAmB,CAAC;AAEhD,kGAAkG;AAClG,MAAM,CAAC,MAAM,UAAU,GAAG,QAAiB,CAAC;AAE5C,+FAA+F;AAC/F,MAAM,CAAC,MAAM,eAAe,GAAG,aAAsB,CAAC;AAEtD;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,QAAgB;IACjD,IAAI,QAAQ,KAAK,YAAY;QAAE,OAAO,SAAS,CAAC;IAChD,IAAI,QAAQ,KAAK,UAAU;QAAE,OAAO,OAAO,CAAC;IAC5C,IAAI,QAAQ,KAAK,eAAe;QAAE,OAAO,YAAY,CAAC;IACtD,OAAO,OAAO,CAAC;AAChB,CAAC"}
|
|
@@ -25,6 +25,7 @@ import { createRoot } from "react-dom/client";
|
|
|
25
25
|
import { Shell } from "./app.js";
|
|
26
26
|
import { resolveBootScreen } from "./boot-route.js";
|
|
27
27
|
import { BuzzingScreen } from "./buzzing-screen.js";
|
|
28
|
+
import { OnboardingScreen } from "./onboarding/onboarding-screen.js";
|
|
28
29
|
import { LoginScreen } from "./setup-gate.js";
|
|
29
30
|
/** Mount the screen the server already authorized for `location.pathname`. Idempotent-safe per load. */
|
|
30
31
|
function mount() {
|
|
@@ -44,7 +45,7 @@ function mount() {
|
|
|
44
45
|
// the specific registry page — PRD-003c m-AC-1 through m-AC-5).
|
|
45
46
|
const pathname = typeof window === "undefined" ? "/" : window.location.pathname;
|
|
46
47
|
const screen = resolveBootScreen(pathname);
|
|
47
|
-
const element = screen === "buzzing" ? (_jsx(BuzzingScreen, { assetBase: assetBase })) : screen === "login" ? (_jsx(LoginScreen, { assetBase: assetBase })) : (_jsx(Shell, { assetBase: assetBase }));
|
|
48
|
+
const element = screen === "buzzing" ? (_jsx(BuzzingScreen, { assetBase: assetBase })) : screen === "login" ? (_jsx(LoginScreen, { assetBase: assetBase })) : screen === "onboarding" ? (_jsx(OnboardingScreen, { assetBase: assetBase })) : (_jsx(Shell, { assetBase: assetBase }));
|
|
48
49
|
createRoot(root).render(_jsx(React.StrictMode, { children: element }));
|
|
49
50
|
}
|
|
50
51
|
mount();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.js","sourceRoot":"","sources":["../../../src/dashboard/web/main.tsx"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACjC,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE9C,wGAAwG;AACxG,SAAS,KAAK;IACb,MAAM,IAAI,GAAG,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;IAC7C,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO;IAC1B,yFAAyF;IACzF,8FAA8F;IAC9F,+FAA+F;IAC/F,iGAAiG;IACjG,wFAAwF;IACxF,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC,iBAAiB,CAAC,IAAI,QAAQ,CAAC;IACtE,MAAM,SAAS,GAAG,oBAAoB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC;IAEpF,+FAA+F;IAC/F,4FAA4F;IAC5F,8FAA8F;IAC9F,gEAAgE;IAChE,MAAM,QAAQ,GAAG,OAAO,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC;IAChF,MAAM,MAAM,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IAE3C,MAAM,OAAO,GACZ,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,CACtB,KAAC,aAAa,IAAC,SAAS,EAAE,SAAS,GAAI,CACvC,CAAC,CAAC,CAAC,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,CACxB,KAAC,WAAW,IAAC,SAAS,EAAE,SAAS,GAAI,CACrC,CAAC,CAAC,CAAC,CACH,KAAC,KAAK,IAAC,SAAS,EAAE,SAAS,GAAI,CAC/B,CAAC;IAEH,UAAU,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAC,KAAK,CAAC,UAAU,cAAE,OAAO,GAAoB,CAAC,CAAC;AACzE,CAAC;AAED,KAAK,EAAE,CAAC"}
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../../../src/dashboard/web/main.tsx"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACjC,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AACrE,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE9C,wGAAwG;AACxG,SAAS,KAAK;IACb,MAAM,IAAI,GAAG,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;IAC7C,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO;IAC1B,yFAAyF;IACzF,8FAA8F;IAC9F,+FAA+F;IAC/F,iGAAiG;IACjG,wFAAwF;IACxF,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC,iBAAiB,CAAC,IAAI,QAAQ,CAAC;IACtE,MAAM,SAAS,GAAG,oBAAoB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC;IAEpF,+FAA+F;IAC/F,4FAA4F;IAC5F,8FAA8F;IAC9F,gEAAgE;IAChE,MAAM,QAAQ,GAAG,OAAO,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC;IAChF,MAAM,MAAM,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IAE3C,MAAM,OAAO,GACZ,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,CACtB,KAAC,aAAa,IAAC,SAAS,EAAE,SAAS,GAAI,CACvC,CAAC,CAAC,CAAC,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,CACxB,KAAC,WAAW,IAAC,SAAS,EAAE,SAAS,GAAI,CACrC,CAAC,CAAC,CAAC,MAAM,KAAK,YAAY,CAAC,CAAC,CAAC,CAC7B,KAAC,gBAAgB,IAAC,SAAS,EAAE,SAAS,GAAI,CAC1C,CAAC,CAAC,CAAC,CACH,KAAC,KAAK,IAAC,SAAS,EAAE,SAAS,GAAI,CAC/B,CAAC;IAEH,UAAU,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAC,KAAK,CAAC,UAAU,cAAE,OAAO,GAAoB,CAAC,CAAC;AACzE,CAAC;AAED,KAAK,EAAE,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The ADVANCED product picker, PRD-009b ob-AC-7. Product CARDS with checkboxes, each carrying the
|
|
3
|
+
* product logo and a one-line purpose, a `Recommended` badge on Doctor, and a visible warning when
|
|
4
|
+
* Doctor is deselected. Confirming enters the same guided flow for exactly the chosen products.
|
|
5
|
+
*/
|
|
6
|
+
import React from "react";
|
|
7
|
+
import type { InstallableProduct } from "./contracts.js";
|
|
8
|
+
export interface AdvancedPickerProps {
|
|
9
|
+
/** The remaining (not-yet-installed) installable products, in the fixed order (ob-AC-2: never assumed). */
|
|
10
|
+
readonly products: readonly InstallableProduct[];
|
|
11
|
+
readonly assetBase: string;
|
|
12
|
+
/** Called with EXACTLY the checked products, in the fixed order, when the operator confirms. */
|
|
13
|
+
readonly onConfirm: (selected: readonly InstallableProduct[]) => void;
|
|
14
|
+
}
|
|
15
|
+
/** ob-AC-7, the Advanced picker. Doctor is pre-checked (recommended) same as every other product. */
|
|
16
|
+
export declare function AdvancedPicker({ products, assetBase, onConfirm }: AdvancedPickerProps): React.JSX.Element;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* The ADVANCED product picker, PRD-009b ob-AC-7. Product CARDS with checkboxes, each carrying the
|
|
4
|
+
* product logo and a one-line purpose, a `Recommended` badge on Doctor, and a visible warning when
|
|
5
|
+
* Doctor is deselected. Confirming enters the same guided flow for exactly the chosen products.
|
|
6
|
+
*/
|
|
7
|
+
import React from "react";
|
|
8
|
+
import { Badge, Button } from "../primitives.js";
|
|
9
|
+
import { DOCTOR_DESELECT_WARNING, PRODUCT_COPY, productLogoUrl } from "./product-copy.js";
|
|
10
|
+
/** One product picker card: logo, one-line purpose, `Recommended` badge (Doctor only), a checkbox. */
|
|
11
|
+
function PickerCard({ product, checked, onToggle, assetBase, }) {
|
|
12
|
+
const copy = PRODUCT_COPY[product];
|
|
13
|
+
return (_jsxs("label", { "data-testid": `onboarding-picker-item-${product}`, "data-checked": checked, style: {
|
|
14
|
+
display: "flex",
|
|
15
|
+
alignItems: "center",
|
|
16
|
+
gap: 14,
|
|
17
|
+
padding: "14px 16px",
|
|
18
|
+
borderRadius: "var(--radius-lg)",
|
|
19
|
+
border: `1px solid ${checked ? "var(--honey-border)" : "var(--border-default)"}`,
|
|
20
|
+
background: checked ? "var(--honey-subtle)" : "var(--bg-elevated)",
|
|
21
|
+
cursor: "pointer",
|
|
22
|
+
textAlign: "left",
|
|
23
|
+
}, children: [_jsx("input", { type: "checkbox", checked: checked, onChange: onToggle, "data-testid": `onboarding-picker-checkbox-${product}`, style: { width: 18, height: 18, flex: "none", accentColor: "var(--honey)" } }), _jsx("img", { src: productLogoUrl(product, assetBase), width: 32, height: 32, alt: "", style: { flex: "none" } }), _jsxs("div", { style: { flex: 1, minWidth: 0, display: "flex", flexDirection: "column", gap: 2 }, children: [_jsxs("div", { style: { display: "flex", alignItems: "center", gap: 8 }, children: [_jsx("span", { style: { fontFamily: "var(--font-sans)", fontSize: "var(--text-sm)", fontWeight: 700, color: "var(--text-primary)" }, children: copy.title }), copy.recommended && _jsx(Badge, { tone: "honey", children: "Recommended" })] }), _jsx("span", { style: { fontFamily: "var(--font-sans)", fontSize: "var(--text-xs)", color: "var(--text-secondary)" }, children: copy.headline })] })] }));
|
|
24
|
+
}
|
|
25
|
+
/** ob-AC-7, the Advanced picker. Doctor is pre-checked (recommended) same as every other product. */
|
|
26
|
+
export function AdvancedPicker({ products, assetBase, onConfirm }) {
|
|
27
|
+
const [selected, setSelected] = React.useState(() => new Set(products));
|
|
28
|
+
const toggle = React.useCallback((product) => {
|
|
29
|
+
setSelected((current) => {
|
|
30
|
+
const next = new Set(current);
|
|
31
|
+
if (next.has(product))
|
|
32
|
+
next.delete(product);
|
|
33
|
+
else
|
|
34
|
+
next.add(product);
|
|
35
|
+
return next;
|
|
36
|
+
});
|
|
37
|
+
}, []);
|
|
38
|
+
const doctorDeselected = products.includes("doctor") && !selected.has("doctor");
|
|
39
|
+
return (_jsx("div", { "data-testid": "onboarding-picker", style: {
|
|
40
|
+
display: "flex",
|
|
41
|
+
alignItems: "center",
|
|
42
|
+
justifyContent: "center",
|
|
43
|
+
minHeight: "100vh",
|
|
44
|
+
padding: 32,
|
|
45
|
+
background: "var(--bg-canvas)",
|
|
46
|
+
textAlign: "center",
|
|
47
|
+
}, children: _jsxs("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", gap: 22, width: "100%", maxWidth: 520 }, children: [_jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 8 }, children: [_jsx("h1", { style: { fontSize: "var(--text-2xl)", fontWeight: 700, color: "var(--text-primary)", margin: 0, letterSpacing: "-0.02em" }, children: "Pick what you want to install" }), _jsx("p", { style: { fontFamily: "var(--font-sans)", fontSize: "var(--text-sm)", color: "var(--text-secondary)", margin: 0 }, children: "Everything you skip stays skipped until you come back and choose it." })] }), _jsx("div", { style: { display: "flex", flexDirection: "column", gap: 10, width: "100%", textAlign: "left" }, children: products.map((product) => (_jsx(PickerCard, { product: product, checked: selected.has(product), onToggle: () => toggle(product), assetBase: assetBase }, product))) }), doctorDeselected && (_jsx("p", { "data-testid": "onboarding-picker-doctor-warning", style: {
|
|
48
|
+
fontFamily: "var(--font-sans)",
|
|
49
|
+
fontSize: "var(--text-xs)",
|
|
50
|
+
color: "var(--severity-warning)",
|
|
51
|
+
background: "var(--severity-warning-bg)",
|
|
52
|
+
border: "1px solid var(--severity-warning)",
|
|
53
|
+
borderRadius: "var(--radius-md)",
|
|
54
|
+
padding: "10px 14px",
|
|
55
|
+
margin: 0,
|
|
56
|
+
width: "100%",
|
|
57
|
+
}, children: DOCTOR_DESELECT_WARNING })), _jsx(Button, { variant: "primary", size: "lg", "data-testid": "onboarding-picker-confirm", onClick: () => onConfirm(products.filter((p) => selected.has(p))), children: "Continue" })] }) }));
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=advanced-picker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"advanced-picker.js","sourceRoot":"","sources":["../../../../src/dashboard/web/onboarding/advanced-picker.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `/onboarding` route's WIRE CONTRACT, PRD-009b, mirroring the daemon-side installer service
|
|
3
|
+
* from PRD-009a (`src/daemon/installer/`). `src/shared/onboarding-types.ts` is being authored in
|
|
4
|
+
* parallel by the daemon-side agent; these are LOCAL types matching that contract's field names
|
|
5
|
+
* exactly (per the implementation brief), so a later integration pass can point imports at the
|
|
6
|
+
* shared module without changing a single field name.
|
|
7
|
+
*
|
|
8
|
+
* Every schema mirrors the `wire.ts` convention: zod at the boundary, every field `.catch()`-
|
|
9
|
+
* defaulted so a partial/malformed body degrades to a safe empty state rather than throwing into
|
|
10
|
+
* React (the onboarding screen is the FIRST thing a new operator sees: it must never white-screen).
|
|
11
|
+
*/
|
|
12
|
+
import { z } from "zod";
|
|
13
|
+
import type { FleetHealth, FleetStatusResponse } from "../../../shared/fleet-readiness.js";
|
|
14
|
+
/** Every product the daemon reports detection for (hive is always present; it is the caller). */
|
|
15
|
+
export declare const ONBOARDING_PRODUCTS: readonly ["honeycomb", "doctor", "hive", "nectar"];
|
|
16
|
+
export type OnboardingProduct = (typeof ONBOARDING_PRODUCTS)[number];
|
|
17
|
+
/** The three INSTALLABLE products, in the fixed order the guided flow walks them (ob-AC-6). */
|
|
18
|
+
export declare const FIXED_PRODUCT_ORDER: readonly ["doctor", "honeycomb", "nectar"];
|
|
19
|
+
export type InstallableProduct = (typeof FIXED_PRODUCT_ORDER)[number];
|
|
20
|
+
export declare function isInstallableProduct(value: string): value is InstallableProduct;
|
|
21
|
+
export declare const PRODUCT_INSTALL_STATES: readonly ["not_installed", "installed", "install_in_progress", "install_failed"];
|
|
22
|
+
export type ProductInstallState = (typeof PRODUCT_INSTALL_STATES)[number];
|
|
23
|
+
declare const ProductErrorSchema: z.ZodObject<{
|
|
24
|
+
stage: z.ZodCatch<z.ZodString>;
|
|
25
|
+
summary: z.ZodCatch<z.ZodString>;
|
|
26
|
+
}, z.core.$strip>;
|
|
27
|
+
export type ProductInstallError = z.infer<typeof ProductErrorSchema>;
|
|
28
|
+
declare const ProductDetectionSchema: z.ZodObject<{
|
|
29
|
+
state: z.ZodCatch<z.ZodEnum<{
|
|
30
|
+
not_installed: "not_installed";
|
|
31
|
+
installed: "installed";
|
|
32
|
+
install_in_progress: "install_in_progress";
|
|
33
|
+
install_failed: "install_failed";
|
|
34
|
+
}>>;
|
|
35
|
+
version: z.ZodOptional<z.ZodString>;
|
|
36
|
+
error: z.ZodOptional<z.ZodObject<{
|
|
37
|
+
stage: z.ZodCatch<z.ZodString>;
|
|
38
|
+
summary: z.ZodCatch<z.ZodString>;
|
|
39
|
+
}, z.core.$strip>>;
|
|
40
|
+
}, z.core.$strip>;
|
|
41
|
+
export type ProductDetection = z.infer<typeof ProductDetectionSchema>;
|
|
42
|
+
/** The safe default for a product the response omitted (never assume installed). */
|
|
43
|
+
export declare const DEFAULT_PRODUCT_DETECTION: ProductDetection;
|
|
44
|
+
export declare const DetectResponseSchema: z.ZodObject<{
|
|
45
|
+
products: z.ZodCatch<z.ZodObject<{
|
|
46
|
+
honeycomb: z.ZodOptional<z.ZodObject<{
|
|
47
|
+
state: z.ZodCatch<z.ZodEnum<{
|
|
48
|
+
not_installed: "not_installed";
|
|
49
|
+
installed: "installed";
|
|
50
|
+
install_in_progress: "install_in_progress";
|
|
51
|
+
install_failed: "install_failed";
|
|
52
|
+
}>>;
|
|
53
|
+
version: z.ZodOptional<z.ZodString>;
|
|
54
|
+
error: z.ZodOptional<z.ZodObject<{
|
|
55
|
+
stage: z.ZodCatch<z.ZodString>;
|
|
56
|
+
summary: z.ZodCatch<z.ZodString>;
|
|
57
|
+
}, z.core.$strip>>;
|
|
58
|
+
}, z.core.$strip>>;
|
|
59
|
+
doctor: z.ZodOptional<z.ZodObject<{
|
|
60
|
+
state: z.ZodCatch<z.ZodEnum<{
|
|
61
|
+
not_installed: "not_installed";
|
|
62
|
+
installed: "installed";
|
|
63
|
+
install_in_progress: "install_in_progress";
|
|
64
|
+
install_failed: "install_failed";
|
|
65
|
+
}>>;
|
|
66
|
+
version: z.ZodOptional<z.ZodString>;
|
|
67
|
+
error: z.ZodOptional<z.ZodObject<{
|
|
68
|
+
stage: z.ZodCatch<z.ZodString>;
|
|
69
|
+
summary: z.ZodCatch<z.ZodString>;
|
|
70
|
+
}, z.core.$strip>>;
|
|
71
|
+
}, z.core.$strip>>;
|
|
72
|
+
hive: z.ZodOptional<z.ZodObject<{
|
|
73
|
+
state: z.ZodCatch<z.ZodEnum<{
|
|
74
|
+
not_installed: "not_installed";
|
|
75
|
+
installed: "installed";
|
|
76
|
+
install_in_progress: "install_in_progress";
|
|
77
|
+
install_failed: "install_failed";
|
|
78
|
+
}>>;
|
|
79
|
+
version: z.ZodOptional<z.ZodString>;
|
|
80
|
+
error: z.ZodOptional<z.ZodObject<{
|
|
81
|
+
stage: z.ZodCatch<z.ZodString>;
|
|
82
|
+
summary: z.ZodCatch<z.ZodString>;
|
|
83
|
+
}, z.core.$strip>>;
|
|
84
|
+
}, z.core.$strip>>;
|
|
85
|
+
nectar: z.ZodOptional<z.ZodObject<{
|
|
86
|
+
state: z.ZodCatch<z.ZodEnum<{
|
|
87
|
+
not_installed: "not_installed";
|
|
88
|
+
installed: "installed";
|
|
89
|
+
install_in_progress: "install_in_progress";
|
|
90
|
+
install_failed: "install_failed";
|
|
91
|
+
}>>;
|
|
92
|
+
version: z.ZodOptional<z.ZodString>;
|
|
93
|
+
error: z.ZodOptional<z.ZodObject<{
|
|
94
|
+
stage: z.ZodCatch<z.ZodString>;
|
|
95
|
+
summary: z.ZodCatch<z.ZodString>;
|
|
96
|
+
}, z.core.$strip>>;
|
|
97
|
+
}, z.core.$strip>>;
|
|
98
|
+
}, z.core.$strip>>;
|
|
99
|
+
}, z.core.$strip>;
|
|
100
|
+
export type DetectResponse = z.infer<typeof DetectResponseSchema>;
|
|
101
|
+
/** The honest "nothing detected yet" default (a fetch failure never fabricates an installed product). */
|
|
102
|
+
export declare const EMPTY_DETECTION: DetectResponse;
|
|
103
|
+
/** Read one product's detection, defaulting to {@link DEFAULT_PRODUCT_DETECTION} when omitted. */
|
|
104
|
+
export declare function detectionFor(detection: DetectResponse, product: OnboardingProduct): ProductDetection;
|
|
105
|
+
/** ob-AC-3, every one of the four products reports `installed`. */
|
|
106
|
+
export declare function isFleetFullyInstalled(detection: DetectResponse): boolean;
|
|
107
|
+
/**
|
|
108
|
+
* The remaining (not-yet-installed) installable products, in the FIXED order, the set both the
|
|
109
|
+
* Standard flow (ob-AC-6, unfiltered) and the Advanced picker (ob-AC-7, pre-checked) start from.
|
|
110
|
+
*/
|
|
111
|
+
export declare function remainingProducts(detection: DetectResponse): readonly InstallableProduct[];
|
|
112
|
+
/**
|
|
113
|
+
* ob-AC-16/ob-AC-17, true when detection shows an install already under way or failed for one of
|
|
114
|
+
* the remaining products, meaning a choice (Standard or Advanced) was already made in a prior
|
|
115
|
+
* visit. The resumed queue is simply {@link remainingProducts} walked from the top: any product
|
|
116
|
+
* already `installed` is filtered out, and the first remaining entry is exactly the one that was
|
|
117
|
+
* mid-flight or failed (re-attached, never re-offered the hero/picker).
|
|
118
|
+
*/
|
|
119
|
+
export declare function hasResumableInstall(detection: DetectResponse): boolean;
|
|
120
|
+
/**
|
|
121
|
+
* The queue to resume with (ob-AC-16), honoring the operator's original subset when it is known.
|
|
122
|
+
* `remainingProducts` alone would reinstall a product the operator explicitly DESELECTED in the
|
|
123
|
+
* Advanced picker, because the daemon has no server-side memory of that subset. When a persisted
|
|
124
|
+
* selection exists (see onboarding-selection-store), the resume queue is the remaining products
|
|
125
|
+
* intersected with it, so a deselected product is never silently reinstalled. When no selection is
|
|
126
|
+
* persisted (a fresh browser, cleared storage), any product that is genuinely mid-flight or failed
|
|
127
|
+
* is still resumed (an in-flight fact, not an assumption); a merely `not_installed` product with no
|
|
128
|
+
* persisted intent is left out, so the flow never installs something the operator did not choose.
|
|
129
|
+
*/
|
|
130
|
+
export declare function buildResumeQueue(detection: DetectResponse, persistedSelection: readonly InstallableProduct[] | null): readonly InstallableProduct[];
|
|
131
|
+
export declare const InstallStartResponseSchema: z.ZodObject<{
|
|
132
|
+
product: z.ZodCatch<z.ZodEnum<{
|
|
133
|
+
honeycomb: "honeycomb";
|
|
134
|
+
nectar: "nectar";
|
|
135
|
+
doctor: "doctor";
|
|
136
|
+
}>>;
|
|
137
|
+
state: z.ZodCatch<z.ZodEnum<{
|
|
138
|
+
installed: "installed";
|
|
139
|
+
install_in_progress: "install_in_progress";
|
|
140
|
+
}>>;
|
|
141
|
+
}, z.core.$strip>;
|
|
142
|
+
export type InstallStartResponse = z.infer<typeof InstallStartResponseSchema>;
|
|
143
|
+
/** `POST /api/onboarding/install` -> 409 refusal (is-AC-5). */
|
|
144
|
+
export declare const InstallRefusalResponseSchema: z.ZodObject<{
|
|
145
|
+
error: z.ZodEnum<{
|
|
146
|
+
unpublished: "unpublished";
|
|
147
|
+
manifest_unresolved: "manifest_unresolved";
|
|
148
|
+
}>;
|
|
149
|
+
}, z.core.$strip>;
|
|
150
|
+
export type InstallRefusalResponse = z.infer<typeof InstallRefusalResponseSchema>;
|
|
151
|
+
export type InstallStartResult = InstallStartResponse | InstallRefusalResponse;
|
|
152
|
+
/** Honest operator copy for installer refusals (409), with the same retry affordance as other failures. */
|
|
153
|
+
export declare function installRefusalMessage(error: InstallRefusalResponse["error"]): string;
|
|
154
|
+
/** The four REAL, observable install stages plus the two terminal outcomes (ob-AC-9: never a percent). */
|
|
155
|
+
export declare const INSTALL_STAGES: readonly ["resolving", "downloading", "linking", "registering_service", "completed", "failed"];
|
|
156
|
+
export type InstallStage = (typeof INSTALL_STAGES)[number];
|
|
157
|
+
/** The four IN-FLIGHT stages, in display order (excludes the two terminal outcomes). */
|
|
158
|
+
export declare const IN_FLIGHT_STAGES: readonly ["resolving", "downloading", "linking", "registering_service"];
|
|
159
|
+
export declare const InstallProgressEventSchema: z.ZodObject<{
|
|
160
|
+
stage: z.ZodCatch<z.ZodEnum<{
|
|
161
|
+
resolving: "resolving";
|
|
162
|
+
downloading: "downloading";
|
|
163
|
+
linking: "linking";
|
|
164
|
+
registering_service: "registering_service";
|
|
165
|
+
completed: "completed";
|
|
166
|
+
failed: "failed";
|
|
167
|
+
}>>;
|
|
168
|
+
detail: z.ZodOptional<z.ZodString>;
|
|
169
|
+
}, z.core.$strip>;
|
|
170
|
+
export type InstallProgressEvent = z.infer<typeof InstallProgressEventSchema>;
|
|
171
|
+
export interface HealthResponse {
|
|
172
|
+
readonly ready: boolean;
|
|
173
|
+
readonly status: FleetStatusResponse;
|
|
174
|
+
}
|
|
175
|
+
/** The honest "daemon unreachable" default a failed/malformed health read degrades to. */
|
|
176
|
+
export declare const UNREACHABLE_HEALTH: HealthResponse;
|
|
177
|
+
/**
|
|
178
|
+
* Parse a `GET /api/onboarding/health` body leniently (mirrors `buzzing-screen.tsx`'s established
|
|
179
|
+
* `as FleetStatusResponse` cast for this exact daemon-owned union, {@link FleetStatusResponse} is
|
|
180
|
+
* a discriminated union keyed on `supervisor`, not a flat shape zod's object schemas model cleanly,
|
|
181
|
+
* and the existing precedent already trusts the daemon's own `isFleetReady`-validated projection).
|
|
182
|
+
*/
|
|
183
|
+
export declare function parseHealthResponse(body: unknown): HealthResponse;
|
|
184
|
+
/** Re-exported so onboarding modules read the daemon health vocabulary from one place. */
|
|
185
|
+
export type { FleetHealth, FleetStatusResponse };
|
|
186
|
+
/** The exact UI-fired event names (product install + health events are daemon-side, never sent here). */
|
|
187
|
+
export declare const ONBOARDING_UI_EVENTS: readonly ["onboarding_started", "mode_selected", "login_shown", "dashboard_reached"];
|
|
188
|
+
export type OnboardingUiEvent = (typeof ONBOARDING_UI_EVENTS)[number];
|