@magicvr/schema-ui-shell 0.1.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.
Files changed (53) hide show
  1. package/app/App.d.ts +23 -0
  2. package/app/AuthGate.d.ts +20 -0
  3. package/app/HostFailureScreen.d.ts +18 -0
  4. package/app/LoginPage.d.ts +11 -0
  5. package/app/ManifestFailure.d.ts +3 -0
  6. package/app/branding.d.ts +33 -0
  7. package/app/config-events.d.ts +18 -0
  8. package/app/index.d.ts +15 -0
  9. package/app/navigation.d.ts +27 -0
  10. package/app/notification-bell.d.ts +10 -0
  11. package/components/data-table.d.ts +43 -0
  12. package/components/force-password-change.d.ts +1 -0
  13. package/components/invite-accept.d.ts +6 -0
  14. package/components/locale-switcher.d.ts +23 -0
  15. package/components/theme-toggle.d.ts +10 -0
  16. package/components/timezone-switcher.d.ts +16 -0
  17. package/components/ui/async-state.d.ts +27 -0
  18. package/components/ui/breadcrumbs.d.ts +78 -0
  19. package/components/ui/button.d.ts +11 -0
  20. package/components/ui/card.d.ts +8 -0
  21. package/components/ui/input.d.ts +5 -0
  22. package/components/ui/label.d.ts +3 -0
  23. package/components/ui/skeleton.d.ts +2 -0
  24. package/components/ui/textarea.d.ts +5 -0
  25. package/host/boot.d.ts +64 -0
  26. package/host/bootstrap.d.ts +105 -0
  27. package/host/claim.d.ts +75 -0
  28. package/host/failure.d.ts +97 -0
  29. package/host/return-intent.d.ts +55 -0
  30. package/i18n/catalog.d.ts +51 -0
  31. package/i18n/format.d.ts +17 -0
  32. package/i18n/locale.d.ts +51 -0
  33. package/i18n/runtime.d.ts +90 -0
  34. package/i18n/timezone.d.ts +57 -0
  35. package/index.js +23764 -0
  36. package/lib/datetime.d.ts +14 -0
  37. package/lib/fetch-timeout.d.ts +13 -0
  38. package/lib/utils.d.ts +2 -0
  39. package/package.json +30 -0
  40. package/renderer/confirm.d.ts +17 -0
  41. package/renderer/custom-components.d.ts +14 -0
  42. package/renderer/form-controls.d.ts +45 -0
  43. package/renderer/form-controls.types.d.ts +135 -0
  44. package/renderer/modal.d.ts +6 -0
  45. package/renderer/permissions.d.ts +53 -0
  46. package/renderer/reaction-engine.d.ts +92 -0
  47. package/renderer/reaction-expression.d.ts +74 -0
  48. package/renderer/reactions.d.ts +64 -0
  49. package/renderer/render.d.ts +194 -0
  50. package/renderer/render.types.d.ts +289 -0
  51. package/renderer/resource.d.ts +114 -0
  52. package/renderer/schema-table.d.ts +90 -0
  53. package/theme/theme.d.ts +64 -0
package/app/App.d.ts ADDED
@@ -0,0 +1,23 @@
1
+ import { type Branding } from "@/app/branding";
2
+ import { type AppManifest, type NavigationContext } from "@/protocol/app-manifest";
3
+ export interface AppProps {
4
+ manifest: AppManifest;
5
+ navigationContext?: NavigationContext;
6
+ /** Set when the boot /me session failed; surfaces a non-blocking notice. */
7
+ accountError?: unknown;
8
+ /** Injectable fetch for page-schema documents (defaults to `globalThis.fetch`). */
9
+ schemaFetcher?: typeof fetch;
10
+ /** Injectable fetch for table data sources such as `/api/users` (GOAL-011). */
11
+ resourceFetcher?: typeof fetch;
12
+ /** Authenticated user rendered in the header; present → show a sign-out button. */
13
+ currentUser?: {
14
+ id: string;
15
+ name?: string;
16
+ avatarUrl?: string;
17
+ } | null;
18
+ /** Revokes the session (AuthProvider flips to the login page). */
19
+ onLogout?: () => void;
20
+ /** Optional branding override (tests); defaults to live GET /api/branding. */
21
+ branding?: Branding;
22
+ }
23
+ export declare function App({ manifest, navigationContext, accountError, schemaFetcher, resourceFetcher, currentUser, onLogout, branding: brandingProp, }: AppProps): import("react").JSX.Element;
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Production auth gate (ADR-0035 stage order): renders the anonymous surfaces
3
+ * (login / invite accept / forced password change / terminal failure screens)
4
+ * and mounts the schema-driven shell `<App>` for an authenticated session.
5
+ *
6
+ * W14 F-001: extracted verbatim from main.tsx so the PRODUCTION assembly of
7
+ * <App> is unit-testable. The entry point runs createRoot side effects on
8
+ * import, which made its wiring invisible to tests — the exact gap that let
9
+ * GOAL-013 F-010 (`/api/schema` 挂认证) ship without a matching schemaFetcher
10
+ * Bearer transport, so every page failed D-VAL loading with an anonymous 401
11
+ * ("无法显示此页面"). The production-wiring regression lock lives in
12
+ * auth-gate.wiring.test.tsx.
13
+ */
14
+ import type { AppManifest } from "@/protocol/app-manifest";
15
+ /** Boot placeholder while the session adapter resolves (ADR-0035 D4). */
16
+ export declare function BootScreen(): import("react").JSX.Element;
17
+ /** Renders the login page when unauthenticated, the shell when authenticated. */
18
+ export declare function AuthGate({ manifest }: {
19
+ manifest: AppManifest;
20
+ }): import("react").JSX.Element;
@@ -0,0 +1,18 @@
1
+ import type { HostFailure } from "@/host/failure";
2
+ export interface HostFailureScreenProps {
3
+ failure: HostFailure;
4
+ onAction: (action: {
5
+ type: string;
6
+ url?: string;
7
+ }) => void;
8
+ /** When true, render as a section (caller provides the landmark, e.g. the shell main). */
9
+ bare?: boolean;
10
+ }
11
+ /**
12
+ * Global failure surface (ADR-0036 D7 / spec 10 §3.8 behavioral conformance):
13
+ * unique error title inside the `main` landmark, focus moved to the title on
14
+ * first terminal entry, assertive/polite live-region announcement by kind,
15
+ * no re-announcement for the same failureId, keyboard-reachable recovery
16
+ * actions.
17
+ */
18
+ export declare function HostFailureScreen({ failure, onAction, bare }: HostFailureScreenProps): import("react").JSX.Element;
@@ -0,0 +1,11 @@
1
+ import { type LoginCaptcha } from "@/account/auth-client";
2
+ /**
3
+ * R2 login surface (GOAL-005) + S3 visual upgrade (workspace-006 / D-004 Sign in).
4
+ * Uses design-system Card / Input / Label / Button primitives (not one-off inputs).
5
+ */
6
+ export declare function LoginPage({ onLogin, }: {
7
+ onLogin: (username: string, password: string, captcha?: LoginCaptcha, resolveMFA?: (proof: string) => Promise<{
8
+ code: string;
9
+ recoveryCode?: string;
10
+ }>) => Promise<void>;
11
+ }): import("react").JSX.Element;
@@ -0,0 +1,3 @@
1
+ export declare function ManifestFailure({ error }: {
2
+ error: unknown;
3
+ }): import("react").JSX.Element;
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Site branding / startup configuration (GOAL-013 + VP-007 S3): loads the
3
+ * Settings contribution's public startup projection for shell title + logos,
4
+ * the browser favicon, and the site-wide defaults (locale / timezone / theme).
5
+ * Empty logoUrl means hide logo in UI; document title always uses siteTitle.
6
+ */
7
+ export declare const DEFAULT_SITE_TITLE = "Schema UI Core";
8
+ export interface Branding {
9
+ siteTitle: string;
10
+ logoUrl: string;
11
+ logoUrlLight: string;
12
+ logoUrlDark: string;
13
+ faviconUrl: string;
14
+ defaultLocale: string;
15
+ supportedLocales: string[];
16
+ siteTimezone: string;
17
+ /** Site-wide default currency (ISO 4217; ""/unset = per-locale map). */
18
+ defaultCurrency: string;
19
+ defaultTheme: string;
20
+ copyrightText: string;
21
+ icpNumber: string;
22
+ }
23
+ export declare function subscribeToBrandingChanges(listener: () => void): () => void;
24
+ /** Same-origin path or http(s) URL — mirrors the API normalizeLogoURL gate. */
25
+ export declare function isSafeBrandingUrl(url: string): boolean;
26
+ export declare function fetchBranding(fetcher?: typeof fetch): Promise<Branding>;
27
+ export declare function defaultBranding(): Branding;
28
+ /**
29
+ * Applies site title + favicon to the document; clears the favicon link when
30
+ * no favicon/logo URL is available. VP-007 S3: the favicon comes from
31
+ * `faviconUrl` (falling back to `logoUrl` for backward compatibility).
32
+ */
33
+ export declare function applyDocumentBranding(branding: Branding): void;
@@ -0,0 +1,18 @@
1
+ export declare const CONFIG_CHANGED_EVENT = "schema-ui:config-changed";
2
+ export declare const CONFIG_CHANGED_HEADER = "X-Schema-UI-Config-Changed";
3
+ export declare const SETTINGS_BRANDING_NAMESPACE = "settings.branding";
4
+ /** Account self-service profile saves (W13 T-05): the session refreshes /me. */
5
+ export declare const ACCOUNT_PROFILE_NAMESPACE = "account.profile";
6
+ /** Notification read/read-all (W13 T-06): the header badge refreshes at once. */
7
+ export declare const NOTIFICATIONS_READ_NAMESPACE = "notifications.read";
8
+ export interface ConfigChangedDetail {
9
+ namespace: string;
10
+ }
11
+ /** Wraps a resource fetcher with the host-level configuration change hook. */
12
+ export declare function createConfigAwareFetcher(authFetch: typeof fetch): typeof fetch;
13
+ /** Converts a successful module response into a namespaced host event. */
14
+ export declare function publishConfigChangeFromResponse(response: Response): void;
15
+ /** Publishes a host configuration change without naming a product endpoint. */
16
+ export declare function notifyConfigChanged(namespace: string): void;
17
+ /** Subscribes to one configuration namespace and returns its cleanup hook. */
18
+ export declare function subscribeToConfigChanges(namespace: string, listener: () => void): () => void;
package/app/index.d.ts ADDED
@@ -0,0 +1,15 @@
1
+ /**
2
+ * @schema-ui/shell 聚合导出:应用壳 + Host 互操作面(R3 六包化)。
3
+ */
4
+ export * from "./App";
5
+ export * from "./AuthGate";
6
+ export * from "./LoginPage";
7
+ export * from "./HostFailureScreen";
8
+ export * from "./ManifestFailure";
9
+ export * from "./branding";
10
+ export * from "./config-events";
11
+ export * from "./navigation";
12
+ export * from "./notification-bell";
13
+ export * from "../host/boot";
14
+ export * from "../host/bootstrap";
15
+ export * from "../host/claim";
@@ -0,0 +1,27 @@
1
+ import { type AppManifest, type NavigationContext } from "@/protocol/app-manifest";
2
+ import { type MessageParams } from "@/i18n/catalog";
3
+ export interface ProjectedLink {
4
+ type: "link";
5
+ href?: string;
6
+ label: string;
7
+ pageRef?: string;
8
+ url?: string;
9
+ icon?: string;
10
+ active: boolean;
11
+ }
12
+ export interface ProjectedGroup {
13
+ type: "group";
14
+ label: string;
15
+ icon?: string;
16
+ items: ProjectedLink[];
17
+ }
18
+ export type ProjectedItem = ProjectedLink | ProjectedGroup;
19
+ export interface NavigationProjection {
20
+ top: ProjectedItem[];
21
+ sidebar: ProjectedItem[];
22
+ user: ProjectedItem[];
23
+ }
24
+ /** Translator used for labelKey/titleKey resolution; defaults to identity. */
25
+ type Translator = (key: string, params?: MessageParams, literalFallback?: string) => string;
26
+ export declare function projectNavigation(manifest: AppManifest, currentPath: string, context?: NavigationContext, t?: Translator): NavigationProjection;
27
+ export {};
@@ -0,0 +1,10 @@
1
+ export interface NotificationBellProps {
2
+ /** Authed same-origin fetch (defaults to globalThis.fetch for bare tests). */
3
+ fetcher?: typeof fetch;
4
+ /** Navigation callback for the "view all" link (kept out of router). */
5
+ onViewAll: () => void;
6
+ /** W13 T-06: opens one notification — navigate to the list page with the
7
+ * detail target (/notifications?open=<id>); the page expands + marks read. */
8
+ onOpenItem: (id: string) => void;
9
+ }
10
+ export declare function NotificationBell({ fetcher, onViewAll, onOpenItem }: NotificationBellProps): import("react").JSX.Element;
@@ -0,0 +1,43 @@
1
+ import type { ReactNode } from "react";
2
+ export type SortOrder = "asc" | "desc";
3
+ export interface SortState {
4
+ field: string;
5
+ order: SortOrder;
6
+ }
7
+ export interface DataTableColumn<T> {
8
+ key: string;
9
+ /** Cell content or header node (checkboxes render in headers for selection). */
10
+ label: ReactNode;
11
+ sortable?: boolean;
12
+ /** W4 · GOAL-005: render the string fallback single-line truncated with a
13
+ * native title full-text affordance so long values do not crowd out
14
+ * sibling columns. Custom render cells are unaffected. Since the
15
+ * table-style refresh every string cell truncates by default; this flag
16
+ * is kept for schema declarations that opt into the 16rem cap. */
17
+ truncate?: boolean;
18
+ /** Column width hint (px number or CSS length). Content-driven auto layout
19
+ * otherwise; a column that declares a width skips the default max-width
20
+ * cap so it can exceed it (table-layout auto still grows on content). */
21
+ width?: number | string;
22
+ /** Minimum column width (px number or CSS length). */
23
+ minWidth?: number | string;
24
+ render?: (row: T) => ReactNode;
25
+ }
26
+ export interface DataTableProps<T> {
27
+ columns: DataTableColumn<T>[];
28
+ rows: T[];
29
+ rowKey: (row: T) => string;
30
+ sort?: SortState;
31
+ onSortChange?: (sort: SortState | null) => void;
32
+ loading?: boolean;
33
+ error?: string | null;
34
+ emptyMessage?: string;
35
+ caption?: string;
36
+ /** Invoked when a data row is clicked (row selection, S4 · GOAL-007). */
37
+ onRowClick?: (row: T) => void;
38
+ /** Row key of the currently selected row (highlight), S4 · GOAL-007. */
39
+ selectedKey?: string;
40
+ /** W15-F02: retry control shown in the error state. */
41
+ onRetry?: () => void;
42
+ }
43
+ export declare function DataTable<T>({ columns, rows, rowKey, sort, onSortChange, loading, error, emptyMessage, caption, onRowClick, selectedKey, onRetry, }: DataTableProps<T>): import("react").JSX.Element;
@@ -0,0 +1 @@
1
+ export declare function ForcePasswordChange(): import("react").JSX.Element;
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Public invitation acceptance surface (workspace-019 R3 · GOAL-004 C4):
3
+ * mounted at /invite/accept?token=… for unauthenticated visitors. Success
4
+ * returns WITHOUT tokens — the new user signs in with their chosen password.
5
+ */
6
+ export declare function InviteAcceptPage(): import("react").JSX.Element;
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Language switcher (S1 · C4) — refactored to a lightweight header
3
+ * dropdown (2026-08-14, user request):
4
+ *
5
+ * - Trigger: pure icon button (lucide Languages), same size/shape as the
6
+ * theme toggle and notification bell (size-9 rounded-md ghost).
7
+ * - Menu: absolutely positioned panel (NO portal — the app root carries
8
+ * the `dark` class, so the panel inherits the dark theme variables
9
+ * automatically; no Radix/Headless portal scope issue).
10
+ * - Dark-mode styling via design tokens (shadcn convention): bg-popover
11
+ * resolves to ~neutral-900 in dark, border-border to white/10
12
+ * (~neutral-800), accent hover to ~neutral-800, popover-foreground to
13
+ * ~neutral-200 — exactly the requested palette; light mode stays
14
+ * correct automatically.
15
+ * - Selected item shows a checkmark (lucide Check) on the right.
16
+ *
17
+ * Reachable from the Shell and the anonymous login page — no settings
18
+ * permission required (VP-007 requirement).
19
+ */
20
+ export interface LocaleSwitcherProps {
21
+ className?: string;
22
+ }
23
+ export declare function LocaleSwitcher({ className }: LocaleSwitcherProps): import("react").JSX.Element;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Theme toggle (S1 · C3) — W8 visual unification (GOAL-009):
3
+ *
4
+ * The trigger now matches the neighbouring header icon buttons (language
5
+ * switcher and notification bell): size-9 rounded-md ghost with
6
+ * text-muted-foreground + hover:bg-accent — instead of the form-styled
7
+ * outline Button. The tooltip / aria-label follow the active locale via
8
+ * the i18n catalog (shell.theme.toggle) — no hardcoded English.
9
+ */
10
+ export declare function ThemeToggle(): import("react").JSX.Element;
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Timezone switcher (workspace-020 · R2 · C2).
3
+ *
4
+ * User-level timezone override next to the language switcher in the header
5
+ * locale channel (contract GOAL-002 D-001 §4.2): persists via the single
6
+ * localStorage channel "schema-ui:timezone"; "auto" removes the key.
7
+ * The option list is the documented common set (contract §6 permits a
8
+ * verifiable, extendable list); the effective timezone always degrades
9
+ * safely through the L1–L4 resolver in i18n/timezone.
10
+ */
11
+ /** Common IANA set offered in the header menu (extendable per contract §6). */
12
+ export declare const TIMEZONE_OPTIONS: readonly string[];
13
+ export interface TimezoneSwitcherProps {
14
+ className?: string;
15
+ }
16
+ export declare function TimezoneSwitcher({ className }: TimezoneSwitcherProps): import("react").JSX.Element;
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Shared pure state determination for async display regions (S4 · GOAL-004).
3
+ *
4
+ * statCard / chart / list-table each fetch a resource independently and used
5
+ * to invent their own ad-hoc "Loading…" text placeholder. This module
6
+ * centralizes the loading / error / empty / ready decision into one pure,
7
+ * directly-testable function so every consumer renders the same sequence
8
+ * (Skeleton while loading, a `role="alert"` message on error, a muted empty
9
+ * message otherwise) instead of drifting independently.
10
+ */
11
+ export type AsyncDisplayState = "loading" | "error" | "empty" | "ready";
12
+ export interface AsyncDisplayInput {
13
+ /** True while the underlying fetch/request has not yet settled. */
14
+ loading: boolean;
15
+ /** Non-null when the fetch/request failed. */
16
+ error: string | null;
17
+ /** True when the fetch succeeded but produced no renderable rows/points. */
18
+ isEmpty?: boolean;
19
+ }
20
+ /**
21
+ * Resolves the single display state a region should show.
22
+ *
23
+ * Precedence: `error` wins over `loading` (a failed fetch is not "still
24
+ * loading" even if a stale loading flag lingers), and `loading` wins over
25
+ * `isEmpty` (emptiness is unknown until the fetch settles).
26
+ */
27
+ export declare function resolveAsyncDisplayState({ loading, error, isEmpty, }: AsyncDisplayInput): AsyncDisplayState;
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Breadcrumb navigation for nested admin pages (GOAL-015).
3
+ *
4
+ * Semantic hierarchy, not visit history (user ruling 2026-08-14):
5
+ * the trail is the page's place in the manifest navigation tree
6
+ * (slot → group labels → page) plus consumer-declared parents for
7
+ * inner pages reached by row navigation (e.g. dictionary-entries →
8
+ * data-dictionary, task-runs → scheduled-tasks). No protocol change:
9
+ * the parent map is a web-shell declaration (BREADCRUMB_PAGE_PARENTS).
10
+ *
11
+ * Trail shape: 首页 => 一级页 => ... => n级内页 — the home page
12
+ * (manifest homePageRef, the domain-root default) always leads, then nav
13
+ * group labels and declared parents, then the current page. Visual: compact
14
+ * 12px trail — muted clickable ancestors (hover brighten + underline), thin
15
+ * "/" separators, brighter non-clickable current item, and an optional
16
+ * small circular ghost back button (semantic parent) at the far left.
17
+ */
18
+ import { type MessageParams } from "@/i18n/catalog";
19
+ export interface BreadcrumbEntry {
20
+ /** Page id (manifest pageId); group labels use the label text as key. */
21
+ pageId: string;
22
+ label: string;
23
+ /** Application route of this ancestor; empty for group labels. */
24
+ route: string;
25
+ /** True for the current (deepest) page. */
26
+ current: boolean;
27
+ }
28
+ export interface BreadcrumbPage {
29
+ pageId: string;
30
+ title?: string;
31
+ titleKey?: string;
32
+ route: string;
33
+ }
34
+ interface BreadcrumbNavItem {
35
+ pageRef?: string;
36
+ label?: string;
37
+ labelKey?: string;
38
+ items?: BreadcrumbNavItem[];
39
+ }
40
+ export declare function Breadcrumbs({ entries, onNavigate, onBack, showBack, }: {
41
+ entries: BreadcrumbEntry[];
42
+ onNavigate: (route: string) => void;
43
+ onBack: () => void;
44
+ /** Compact circular ghost back button (semantic parent), far left. */
45
+ showBack?: boolean;
46
+ }): import("react").JSX.Element | null;
47
+ /**
48
+ * Resolves the SEMANTIC breadcrumb trail for a matched page.
49
+ *
50
+ * Sources, in order:
51
+ * 1. manifest navigation tree — a page rendered under a group shows the
52
+ * group labels as non-clickable ancestors (outermost first);
53
+ * 2. declared parents (options.parents) — inner pages reached by row
54
+ * navigation declare their parent pageId; the chain walks up until a
55
+ * page with no declared parent (its nav group chain, if any, is
56
+ * included). Unknown declared parents fail safe (skipped).
57
+ * 3. pages not in the tree and without a declared parent are
58
+ * single-level (no trail UI).
59
+ *
60
+ * This is NOT the visit history: the same page always shows the same
61
+ * trail regardless of how the user got there (user ruling 2026-08-14).
62
+ */
63
+ export declare function resolveBreadcrumbTrail(pages: BreadcrumbPage[], currentPage: BreadcrumbPage | undefined, t: (key: string, params?: MessageParams, literalFallback?: string) => string, options?: {
64
+ navigation?: {
65
+ top?: BreadcrumbNavItem[];
66
+ sidebar?: BreadcrumbNavItem[];
67
+ user?: BreadcrumbNavItem[];
68
+ };
69
+ /** Consumer-declared parent pageId per inner page (web-shell level). */
70
+ parents?: Record<string, string>;
71
+ /**
72
+ * Home pageId (manifest app.homePageRef — the domain-root default page,
73
+ * not necessarily the dashboard). The trail ALWAYS starts with it:
74
+ * 首页 => 一级页 => ... => n级内页 (user spec 2026-08-14).
75
+ */
76
+ homePageId?: string;
77
+ }): BreadcrumbEntry[];
78
+ export {};
@@ -0,0 +1,11 @@
1
+ import * as React from "react";
2
+ import { type VariantProps } from "class-variance-authority";
3
+ declare const buttonVariants: (props?: ({
4
+ variant?: "default" | "outline" | "secondary" | "ghost" | null | undefined;
5
+ size?: "default" | "sm" | "lg" | null | undefined;
6
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
7
+ export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
8
+ asChild?: boolean;
9
+ }
10
+ declare const Button: React.ForwardRefExoticComponent<ButtonProps & React.RefAttributes<HTMLButtonElement>>;
11
+ export { Button, buttonVariants };
@@ -0,0 +1,8 @@
1
+ import * as React from "react";
2
+ declare const Card: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & React.RefAttributes<HTMLDivElement>>;
3
+ declare const CardHeader: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & React.RefAttributes<HTMLDivElement>>;
4
+ declare const CardTitle: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLHeadingElement> & React.RefAttributes<HTMLParagraphElement>>;
5
+ declare const CardDescription: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLParagraphElement> & React.RefAttributes<HTMLParagraphElement>>;
6
+ declare const CardContent: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & React.RefAttributes<HTMLDivElement>>;
7
+ declare const CardFooter: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & React.RefAttributes<HTMLDivElement>>;
8
+ export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent };
@@ -0,0 +1,5 @@
1
+ import * as React from "react";
2
+ export interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
3
+ }
4
+ declare const Input: React.ForwardRefExoticComponent<InputProps & React.RefAttributes<HTMLInputElement>>;
5
+ export { Input };
@@ -0,0 +1,3 @@
1
+ import * as React from "react";
2
+ declare const Label: React.ForwardRefExoticComponent<React.LabelHTMLAttributes<HTMLLabelElement> & React.RefAttributes<HTMLLabelElement>>;
3
+ export { Label };
@@ -0,0 +1,2 @@
1
+ declare function Skeleton({ className, ...props }: React.HTMLAttributes<HTMLDivElement>): import("react").JSX.Element;
2
+ export { Skeleton };
@@ -0,0 +1,5 @@
1
+ import * as React from "react";
2
+ export interface TextareaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {
3
+ }
4
+ declare const Textarea: React.ForwardRefExoticComponent<TextareaProps & React.RefAttributes<HTMLTextAreaElement>>;
5
+ export { Textarea };
package/host/boot.d.ts ADDED
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Production host boot orchestration (ADR-0035 §2.3 stage order).
3
+ *
4
+ * Stage order is mandatory: availability-gate terminals must render WITHOUT
5
+ * fetching the manifest; auth-resolution terminals likewise. Each decision
6
+ * reuses the fixture-pinned `evaluateBootstrap`, so the vendored upstream
7
+ * host-bootstrap suite covers every stage this orchestrator executes.
8
+ */
9
+ import type { AppManifest } from "@/protocol/app-manifest";
10
+ import { discoverBootstrapDocument, type BootstrapAuth, type BootstrapEvaluation } from "@/host/bootstrap";
11
+ import { type HostFailure } from "@/host/failure";
12
+ /** Session adapter state (ADR-0035 D4): normalized by AuthContext. */
13
+ export type SessionAdapterState = "loading" | "authenticated" | "unauthenticated" | "reauth-required" | "locked";
14
+ /** Maps the session adapter state to the bootstrap normalized auth input (D4). */
15
+ export declare function adapterAuthFor(status: SessionAdapterState, user: {
16
+ id: string;
17
+ name?: string;
18
+ } | null): BootstrapAuth;
19
+ export interface HostBootState {
20
+ evaluation: BootstrapEvaluation;
21
+ failure: HostFailure | null;
22
+ manifest: AppManifest | null;
23
+ }
24
+ export interface HostBootInput {
25
+ documentResult: Awaited<ReturnType<typeof discoverBootstrapDocument>>;
26
+ auth: BootstrapAuth;
27
+ manifestLoader: () => Promise<{
28
+ manifest: AppManifest;
29
+ bytes: Uint8Array;
30
+ }>;
31
+ registry?: unknown;
32
+ }
33
+ /**
34
+ * Executes the deterministic bootstrap lifecycle in production stage order.
35
+ *
36
+ * 1. discovery result (already resolved by the caller);
37
+ * 2. bootstrap-validation + availability-gate + auth-resolution (no manifest
38
+ * fetch happens before terminals are decided);
39
+ * 3. manifest load + integrity check (declared sha256);
40
+ * 4. manifest capability narrowing (degraded);
41
+ * 5. READY / READY_DEGRADED.
42
+ */
43
+ export declare function bootHost(input: HostBootInput): Promise<HostBootState>;
44
+ /** Login/session gate: locked and reauth-required must never reach ready. */
45
+ export declare function isBootTerminal(state: HostBootState): boolean;
46
+ /**
47
+ * Reauth-required terminal for the post-boot session-loss path (ADR-0035 D7):
48
+ * the same closed failure result the boot orchestrator produces when the
49
+ * adapter reports reauth-required before manifest-load.
50
+ */
51
+ export declare function reauthFailure(): HostFailure;
52
+ /**
53
+ * Account-lock terminal (GOAL-004 S4-6, ADR-0035 D7 / ADR-0036 D6): the
54
+ * closed failure result for the locked adapter state. account-locked allows
55
+ * home/support only — no reauth, no retry loop.
56
+ */
57
+ export declare function lockedFailure(): HostFailure;
58
+ /** Executes a recovery action; bootstrap retry always rebuilds the instance. */
59
+ export declare function executeBootRecovery(action: {
60
+ type: string;
61
+ url?: string;
62
+ }): void;
63
+ /** W13 F-015: a support URL is only navigable when it resolves to http(s). */
64
+ export declare function isSafeSupportUrl(raw: string): boolean;
@@ -0,0 +1,105 @@
1
+ /**
2
+ * Host bootstrap runtime (ADR-0035 / spec 10 §2, `host.bootstrap`).
3
+ *
4
+ * Production entry: `discoverBootstrapDocument()` fetches the optional public
5
+ * bootstrap document from the real entry; `evaluateBootstrap()` implements
6
+ * the deterministic lifecycle stages. This module is consumed by the
7
+ * production boot path (`main.tsx`) — it is not a fixture adapter.
8
+ *
9
+ * Pinned upstream machine contracts: `src/protocol/upstream/provenance-v2.8.json`.
10
+ */
11
+ export declare const DEFAULT_BOOTSTRAP_PATH = "/.well-known/schema-ui/host-bootstrap.json";
12
+ export declare const BOOTSTRAP_VERSION: "1.0";
13
+ export type BootstrapAvailabilityMode = "normal" | "maintenance" | "upgrade-required" | "degraded";
14
+ export interface BootstrapAvailability {
15
+ mode: BootstrapAvailabilityMode;
16
+ messageKey?: string;
17
+ retryAfterSeconds?: number;
18
+ minimumHostVersion?: string;
19
+ disabledCapabilities?: string[];
20
+ }
21
+ export interface BootstrapDocument {
22
+ bootstrapVersion: string;
23
+ requiredCapabilities: string[];
24
+ manifest: {
25
+ url: string;
26
+ sha256?: string;
27
+ };
28
+ availability: BootstrapAvailability;
29
+ }
30
+ export type BootstrapAuthState = "anonymous" | "authenticated" | "reauth-required" | "locked";
31
+ export interface BootstrapAuth {
32
+ state: BootstrapAuthState;
33
+ principal?: {
34
+ id?: string;
35
+ name?: string;
36
+ roles?: string[];
37
+ };
38
+ expiresAt?: string;
39
+ provenance?: string;
40
+ }
41
+ export interface HostSupport {
42
+ supportedBootstrapVersions: string[];
43
+ supportedCapabilities: string[];
44
+ }
45
+ export type BootstrapResultCode = "OK" | "INVALID_HOST_SUPPORT" | "INVALID_REQUIRED_CAPABILITIES" | "UNSUPPORTED_BOOTSTRAP_VERSION" | "INVALID_BOOTSTRAP_DOCUMENT" | "MISSING_REQUIRED_CAPABILITY" | "BOOTSTRAP_DOCUMENT_FAILED" | "MANIFEST_CAPABILITY_REJECTED" | "MANIFEST_INTEGRITY_FAILED";
46
+ export type BootstrapResult = "READY" | "READY_DEGRADED" | "MAINTENANCE" | "UPGRADE_REQUIRED" | "REAUTH_REQUIRED" | "ACCOUNT_LOCKED" | "BOOTSTRAP_DOCUMENT_FAILED" | "BOOTSTRAP_NEGOTIATION_REJECTED" | "MANIFEST_CAPABILITY_REJECTED" | "MANIFEST_INTEGRITY_FAILED";
47
+ export type BootstrapFetchClassification = "rate-limited" | "timeout" | "offline" | "unavailable" | "protocol";
48
+ export interface BootstrapEvaluation {
49
+ code: BootstrapResultCode;
50
+ result: BootstrapResult;
51
+ phase: string;
52
+ fetchClassification: BootstrapFetchClassification | null;
53
+ missingCapabilities: string[];
54
+ effectiveCapabilities: string[] | null;
55
+ context: {
56
+ user: {
57
+ id: string;
58
+ name: string;
59
+ roles: string[];
60
+ };
61
+ } | null;
62
+ }
63
+ export interface BootstrapDiscovery {
64
+ status: "ok" | "not-provided" | "failed";
65
+ document: BootstrapDocument | null;
66
+ classification: BootstrapFetchClassification | null;
67
+ bytesSha256: string | null;
68
+ }
69
+ /**
70
+ * Discovery (stage 1): GET the default (or explicit) bootstrap URL with
71
+ * `credentials: omit`. Only 200 succeeds; 404/410 on the default entry means
72
+ * "not provided" (fallback to the ADR-0025 manifest entry); every other
73
+ * status, redirect, wrong content type or parse failure is fail-closed.
74
+ */
75
+ export declare function discoverBootstrapDocument(options?: {
76
+ url?: string;
77
+ fetcher?: typeof fetch;
78
+ }): Promise<BootstrapDiscovery>;
79
+ /**
80
+ * Deterministic lifecycle evaluation (stages 2–9). Mirrors the upstream B1
81
+ * reference (`host-bootstrap.js`) so the vendored conformance fixtures must
82
+ * pass against this production implementation without exclusions.
83
+ */
84
+ export declare function evaluateBootstrap(input: {
85
+ document: BootstrapDocument | null;
86
+ fetch: {
87
+ status: "ok" | "not-provided" | "failed";
88
+ classification?: string | null;
89
+ };
90
+ hostSupport: HostSupport;
91
+ auth: BootstrapAuth;
92
+ manifest: {
93
+ protocolVersion: string;
94
+ requiredCapabilities?: string[];
95
+ } | null;
96
+ integrity: {
97
+ declaredSha256: string;
98
+ computedSha256: string;
99
+ } | null;
100
+ capabilityRegistry: {
101
+ capabilities: Record<string, unknown>;
102
+ };
103
+ }): BootstrapEvaluation;
104
+ /** SHA-256 of raw bytes as lowercase hex (Web Crypto, browser + node). */
105
+ export declare function sha256Hex(bytes: Uint8Array): Promise<string>;