@legioncodeinc/hive 0.2.1 → 0.3.1
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/assets/brand/activeloop-full-mark-logo-on-dark.svg +209 -0
- package/assets/brand/activeloop-full-mark-logo.svg +208 -0
- package/assets/brand/divider-major.svg +1 -0
- package/assets/brand/divider-minor.svg +1 -0
- package/assets/brand/doctor-mark.svg +1 -0
- package/assets/brand/hive-mark.svg +1 -0
- package/assets/brand/hive-wordmark-black.svg +1 -0
- package/assets/brand/hive-wordmark-on-dark.svg +1 -0
- package/assets/brand/legion-logo-dark.svg +16 -0
- package/assets/brand/legion-logo-light.svg +16 -0
- package/assets/brand/nectar-mark.svg +1 -0
- package/assets/logos/fonts/Inter-Italic-VariableFont_opsz_wght.ttf +0 -0
- package/assets/logos/fonts/Inter-VariableFont_opsz_wght.ttf +0 -0
- package/assets/logos/fonts/JetBrainsMono-Bold.woff2 +0 -0
- package/assets/logos/fonts/JetBrainsMono-Medium.woff2 +0 -0
- package/assets/logos/fonts/JetBrainsMono-Regular.woff2 +0 -0
- package/assets/logos/fonts/JetBrainsMono-SemiBold.woff2 +0 -0
- package/assets/logos/honeycomb-memory-cluster.svg +17 -0
- package/assets/styles.css +11 -0
- package/assets/tokens/base.css +76 -0
- package/assets/tokens/colors.css +111 -0
- package/assets/tokens/fonts.css +32 -0
- package/assets/tokens/spacing.css +48 -0
- package/assets/tokens/typography.css +38 -0
- 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 +107 -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 +56 -0
- package/dist/daemon/installer/install-state.js +159 -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 +49 -0
- package/dist/daemon/installer/spawn.js +63 -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 +28 -0
- package/dist/dashboard/web/onboarding/install-card.js +171 -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 +193 -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 +27 -0
- package/dist/dashboard/web/onboarding/use-install-dwell.js +42 -0
- package/dist/dashboard/web/onboarding/use-install-dwell.js.map +1 -0
- package/dist/dashboard/web/onboarding/use-onboarding-token.d.ts +14 -0
- package/dist/dashboard/web/onboarding/use-onboarding-token.js +41 -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 +6 -2
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PRD-009a: the daemon side of the one-time onboarding token contract (is-AC-9/10).
|
|
3
|
+
*
|
|
4
|
+
* The bootstrap mints the token and writes it to `~/.honeycomb/hive/onboarding-token` at mode
|
|
5
|
+
* 0600 BEFORE the daemon starts (PRD-009d). The daemon reads it LAZILY at request time, not at
|
|
6
|
+
* startup, because on re-entry the daemon may already be running when a fresh bootstrap writes a
|
|
7
|
+
* new token. Comparison is constant time (`crypto.timingSafeEqual`). Completion invalidates the
|
|
8
|
+
* token: the file is deleted and an in-memory flag is set, so state-changing endpoints refuse all
|
|
9
|
+
* requests until a fresh bootstrap mints a new one (is-AC-10). The token is never logged, never
|
|
10
|
+
* returned, and never placed in an error body.
|
|
11
|
+
*/
|
|
12
|
+
import { timingSafeEqual } from "node:crypto";
|
|
13
|
+
/** Constant-time string comparison. Length is compared first (timingSafeEqual requires equal length). */
|
|
14
|
+
function constantTimeEquals(a, b) {
|
|
15
|
+
const bufA = Buffer.from(a, "utf8");
|
|
16
|
+
const bufB = Buffer.from(b, "utf8");
|
|
17
|
+
if (bufA.length !== bufB.length) {
|
|
18
|
+
// Still run a same-length comparison so a length mismatch is not a faster reject path.
|
|
19
|
+
timingSafeEqual(bufA, bufA);
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
return timingSafeEqual(bufA, bufB);
|
|
23
|
+
}
|
|
24
|
+
/** Build the token store over the injected config seams. */
|
|
25
|
+
export function createTokenStore(config) {
|
|
26
|
+
let invalidated = false;
|
|
27
|
+
const readToken = () => {
|
|
28
|
+
const raw = config.readTextFile(config.tokenPath);
|
|
29
|
+
if (raw === null)
|
|
30
|
+
return null;
|
|
31
|
+
const trimmed = raw.trim();
|
|
32
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
33
|
+
};
|
|
34
|
+
return {
|
|
35
|
+
isActive() {
|
|
36
|
+
if (invalidated)
|
|
37
|
+
return false;
|
|
38
|
+
return config.fileExists(config.tokenPath);
|
|
39
|
+
},
|
|
40
|
+
requireValid(provided) {
|
|
41
|
+
if (invalidated)
|
|
42
|
+
return false;
|
|
43
|
+
if (provided === null || provided === undefined || provided.length === 0)
|
|
44
|
+
return false;
|
|
45
|
+
const stored = readToken();
|
|
46
|
+
if (stored === null)
|
|
47
|
+
return false;
|
|
48
|
+
return constantTimeEquals(stored, provided);
|
|
49
|
+
},
|
|
50
|
+
invalidate() {
|
|
51
|
+
invalidated = true;
|
|
52
|
+
config.deleteFile(config.tokenPath);
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=token.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token.js","sourceRoot":"","sources":["../../../src/daemon/installer/token.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAI9C,yGAAyG;AACzG,SAAS,kBAAkB,CAAC,CAAS,EAAE,CAAS;IAC9C,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;IACpC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;IACpC,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,EAAE,CAAC;QAChC,uFAAuF;QACvF,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAC5B,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AACrC,CAAC;AAYD,4DAA4D;AAC5D,MAAM,UAAU,gBAAgB,CAAC,MAAuB;IACtD,IAAI,WAAW,GAAG,KAAK,CAAC;IAExB,MAAM,SAAS,GAAG,GAAkB,EAAE;QACpC,MAAM,GAAG,GAAG,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAClD,IAAI,GAAG,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC;QAC9B,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;QAC3B,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;IAC7C,CAAC,CAAC;IAEF,OAAO;QACL,QAAQ;YACN,IAAI,WAAW;gBAAE,OAAO,KAAK,CAAC;YAC9B,OAAO,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAC7C,CAAC;QACD,YAAY,CAAC,QAAQ;YACnB,IAAI,WAAW;gBAAE,OAAO,KAAK,CAAC;YAC9B,IAAI,QAAQ,KAAK,IAAI,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO,KAAK,CAAC;YACvF,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;YAC3B,IAAI,MAAM,KAAK,IAAI;gBAAE,OAAO,KAAK,CAAC;YAClC,OAAO,kBAAkB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QAC9C,CAAC;QACD,UAAU;YACR,WAAW,GAAG,IAAI,CAAC;YACnB,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QACtC,CAAC;KACF,CAAC;AACJ,CAAC"}
|
package/dist/daemon/server.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { type LockPaths } from "../lock.js";
|
|
|
4
4
|
import { type FetchImpl } from "./fleet-status.js";
|
|
5
5
|
import { type ProxyFetch } from "./proxy.js";
|
|
6
6
|
import { type TelemetryFetch } from "./telemetry-proxy.js";
|
|
7
|
+
import { type InstallerServiceOptions } from "./installer/index.js";
|
|
7
8
|
import type { SetupAuthFetchImpl } from "./setup-auth.js";
|
|
8
9
|
export interface CreateHiveOptions {
|
|
9
10
|
readonly host?: string;
|
|
@@ -20,6 +21,11 @@ export interface CreateHiveOptions {
|
|
|
20
21
|
readonly doctorEventsUrl?: string;
|
|
21
22
|
/** The fetch used by the telemetry relay to reach doctor's SSE stream (defaults to the global `fetch`). */
|
|
22
23
|
readonly telemetryStreamFetch?: TelemetryFetch;
|
|
24
|
+
/**
|
|
25
|
+
* PRD-009a: installer-service seams (manifest fetch, spawn, token/npm-prefix resolution, fs).
|
|
26
|
+
* A test injects fakes here so the onboarding endpoints never touch the network or real npm.
|
|
27
|
+
*/
|
|
28
|
+
readonly installer?: InstallerServiceOptions;
|
|
23
29
|
}
|
|
24
30
|
export interface StartHiveOptions extends CreateHiveOptions {
|
|
25
31
|
readonly lockPaths?: Partial<LockPaths>;
|
package/dist/daemon/server.js
CHANGED
|
@@ -8,6 +8,7 @@ import { createPortalGate } from "./gate.js";
|
|
|
8
8
|
import { createApiProxy } from "./proxy.js";
|
|
9
9
|
import { resolveRegisteredServiceNames } from "./registry.js";
|
|
10
10
|
import { createTelemetryStreamHandler } from "./telemetry-proxy.js";
|
|
11
|
+
import { createInstallerService } from "./installer/index.js";
|
|
11
12
|
function closeServer(server) {
|
|
12
13
|
return new Promise((resolve, reject) => {
|
|
13
14
|
server.close((error) => {
|
|
@@ -72,6 +73,12 @@ export function createHive(options = {}) {
|
|
|
72
73
|
doctorEventsUrl: options.doctorEventsUrl,
|
|
73
74
|
fetchImpl: options.telemetryStreamFetch
|
|
74
75
|
}));
|
|
76
|
+
// PRD-009a: the onboarding installer service (detection, install start, SSE progress, health,
|
|
77
|
+
// completion, funnel-event stub). Registered BEFORE the generic `/api/*` proxy so these specific
|
|
78
|
+
// `/api/onboarding/*` routes win (same registration-order discipline as `/api/fleet-status`). Its
|
|
79
|
+
// health check reuses the SAME fleet-status fetch + doctor URL the gate uses; a test can override
|
|
80
|
+
// any installer seam (manifest fetch, spawn, token/npm-prefix, fs) via `options.installer`.
|
|
81
|
+
createInstallerService({ fleetStatusFetch, doctorStatusUrl, ...options.installer }).register(app);
|
|
75
82
|
// Server-side federation (BFF): every other `/api/*` and `/setup/*` request is proxied over
|
|
76
83
|
// loopback to the workload daemon that owns it (honeycomb or nectar), resolved from
|
|
77
84
|
// doctor's registry. The browser only ever talks to hive's own origin.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/daemon/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EACL,yBAAyB,EACzB,yBAAyB,EAE1B,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,iBAAiB,EACjB,SAAS,EACT,SAAS,EACT,YAAY,EACb,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,oBAAoB,EAAE,2BAA2B,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACrG,OAAO,EAAE,gBAAgB,EAAkB,MAAM,mBAAmB,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAmB,MAAM,YAAY,CAAC;AAC7D,OAAO,EAAE,6BAA6B,EAAE,MAAM,eAAe,CAAC;AAC9D,OAAO,EAAE,4BAA4B,EAAuB,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/daemon/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EACL,yBAAyB,EACzB,yBAAyB,EAE1B,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,iBAAiB,EACjB,SAAS,EACT,SAAS,EACT,YAAY,EACb,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,oBAAoB,EAAE,2BAA2B,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACrG,OAAO,EAAE,gBAAgB,EAAkB,MAAM,mBAAmB,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAmB,MAAM,YAAY,CAAC;AAC7D,OAAO,EAAE,6BAA6B,EAAE,MAAM,eAAe,CAAC;AAC9D,OAAO,EAAE,4BAA4B,EAAuB,MAAM,sBAAsB,CAAC;AACzF,OAAO,EAAE,sBAAsB,EAAgC,MAAM,sBAAsB,CAAC;AA6C5F,SAAS,WAAW,CAAC,MAAuB;IAC1C,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAa,EAAE,EAAE;YAC7B,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;gBAC3B,MAAM,CAAC,KAAK,CAAC,CAAC;gBACd,OAAO;YACT,CAAC;YACD,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,UAA6B,EAAE;IACxD,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,SAAS,CAAC;IACvC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,SAAS,CAAC;IACvC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;IACpC,MAAM,SAAS,GAAG,GAAG,EAAE,CAAC;IAExB,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IAEvB,MAAM,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,IAAI,KAAK,CAAC;IAC3D,MAAM,eAAe,GAAG,OAAO,CAAC,eAAe,IAAI,iBAAiB,CAAC;IAErE,4FAA4F;IAC5F,yFAAyF;IACzF,4FAA4F;IAC5F,sEAAsE;IACtE,GAAG,CAAC,GAAG,CACL,GAAG,EACH,gBAAgB,CAAC;QACf,gBAAgB;QAChB,eAAe;QACf,cAAc,EAAE,OAAO,CAAC,cAAc;QACtC,YAAY,EAAE,OAAO,CAAC,YAAY;KACnC,CAAC,CACH,CAAC;IAEF,gGAAgG;IAChG,uBAAuB;IACvB,oBAAoB,CAAC,GAAG,CAAC,CAAC;IAE1B,4FAA4F;IAC5F,2FAA2F;IAC3F,4FAA4F;IAC5F,6FAA6F;IAC7F,kFAAkF;IAClF,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE;QACvB,MAAM,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QAC5C,IAAI,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;YACjC,CAAC,CAAC,MAAM,CAAC,eAAe,EAAE,UAAU,CAAC,CAAC;YACtC,OAAO,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;QAC/B,CAAC;QACD,OAAO,CAAC,CAAC,IAAI,CAAC;YACZ,MAAM,EAAE,IAAI;YACZ,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,SAAS,CAAC;YACxC,OAAO,EAAE,YAAY;SACtB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,sFAAsF;IACtF,kFAAkF;IAClF,GAAG,CAAC,GAAG,CAAC,mBAAmB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,CACvC,CAAC,CAAC,IAAI,CAAC,MAAM,gBAAgB,CAAC,gBAAgB,EAAE,eAAe,CAAC,CAAC,CAClE,CAAC;IAEF,uFAAuF;IACvF,sFAAsF;IACtF,2FAA2F;IAC3F,iGAAiG;IACjG,GAAG,CAAC,GAAG,CAAC,0BAA0B,EAAE,CAAC,CAAC,EAAE,EAAE,CACxC,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,6BAA6B,CAAC,EAAE,YAAY,EAAE,OAAO,CAAC,YAAY,EAAE,CAAC,EAAE,CAAC,CACzF,CAAC;IAEF,gFAAgF;IAChF,8FAA8F;IAC9F,8FAA8F;IAC9F,GAAG,CAAC,GAAG,CACL,uBAAuB,EACvB,4BAA4B,CAAC;QAC3B,eAAe,EAAE,OAAO,CAAC,eAAe;QACxC,SAAS,EAAE,OAAO,CAAC,oBAAoB;KACxC,CAAC,CACH,CAAC;IAEF,8FAA8F;IAC9F,iGAAiG;IACjG,kGAAkG;IAClG,kGAAkG;IAClG,4FAA4F;IAC5F,sBAAsB,CAAC,EAAE,gBAAgB,EAAE,eAAe,EAAE,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IAElG,4FAA4F;IAC5F,oFAAoF;IACpF,uEAAuE;IACvE,MAAM,QAAQ,GAAG,cAAc,CAAC,EAAE,YAAY,EAAE,OAAO,CAAC,YAAY,EAAE,SAAS,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;IACvG,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC5B,GAAG,CAAC,GAAG,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IAE9B,4FAA4F;IAC5F,6FAA6F;IAC7F,yFAAyF;IACzF,2BAA2B,CAAC,GAAG,CAAC,CAAC;IAEjC,OAAO;QACL,GAAG;QACH,IAAI;QACJ,IAAI;QACJ,SAAS;KACV,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,UAA4B,EAAE;IACtD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,KAAK,CAAC;IACzC,MAAM,IAAI,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;IACjC,MAAM,SAAS,GAAG,yBAAyB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAE/D,IAAI,MAAuB,CAAC;IAC5B,IAAI,CAAC;QACH,MAAM,GAAG,OAAO,CAAC;YACf,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK;YACrB,QAAQ,EAAE,IAAI,CAAC,IAAI;YACnB,IAAI,EAAE,IAAI,CAAC,IAAI;SAChB,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,yBAAyB,CAAC,SAAS,CAAC,CAAC;QACrC,MAAM,KAAK,CAAC;IACd,CAAC;IAED,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,MAAM,IAAI,GAAG,KAAK,IAAmB,EAAE;QACrC,IAAI,OAAO;YAAE,OAAO;QACpB,OAAO,GAAG,IAAI,CAAC;QACf,IAAI,CAAC;YACH,MAAM,WAAW,CAAC,MAAM,CAAC,CAAC;QAC5B,CAAC;gBAAS,CAAC;YACT,yBAAyB,CAAC,SAAS,CAAC,CAAC;QACvC,CAAC;IACH,CAAC,CAAC;IAEF,OAAO;QACL,GAAG,IAAI;QACP,SAAS;QACT,IAAI;KACL,CAAC;AACJ,CAAC"}
|
|
@@ -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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"}
|