kaafil-react-uikit 0.4.1 → 0.4.2
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/CHANGELOG.md +28 -5
- package/dist/admin/index.cjs +355 -353
- package/dist/admin/index.cjs.map +1 -1
- package/dist/admin/index.js +16 -14
- package/dist/admin/index.js.map +1 -1
- package/dist/{chunk-EP4VCID7.js → chunk-3E2FN5JJ.js} +3 -3
- package/dist/{chunk-EP4VCID7.js.map → chunk-3E2FN5JJ.js.map} +1 -1
- package/dist/{chunk-TPBKRXEB.cjs → chunk-3RZDHDEY.cjs} +17 -17
- package/dist/{chunk-TPBKRXEB.cjs.map → chunk-3RZDHDEY.cjs.map} +1 -1
- package/dist/chunk-62HCQWZL.cjs +12 -0
- package/dist/chunk-62HCQWZL.cjs.map +1 -0
- package/dist/{chunk-ABWNV4N4.js → chunk-6FUVFVYY.js} +97 -4
- package/dist/chunk-6FUVFVYY.js.map +1 -0
- package/dist/{chunk-BUE2GJDN.js → chunk-762SWUEG.js} +3 -3
- package/dist/{chunk-BUE2GJDN.js.map → chunk-762SWUEG.js.map} +1 -1
- package/dist/{chunk-CCJ5XNWY.cjs → chunk-CK3L6Y43.cjs} +98 -2
- package/dist/chunk-CK3L6Y43.cjs.map +1 -0
- package/dist/{chunk-XBYLSJOS.cjs → chunk-DI77H7ED.cjs} +83 -83
- package/dist/{chunk-XBYLSJOS.cjs.map → chunk-DI77H7ED.cjs.map} +1 -1
- package/dist/{chunk-5DVTAEQC.js → chunk-EDLIJSMR.js} +5 -5
- package/dist/{chunk-5DVTAEQC.js.map → chunk-EDLIJSMR.js.map} +1 -1
- package/dist/{chunk-DABF4PUI.js → chunk-ITGVRN2S.js} +3 -3
- package/dist/{chunk-DABF4PUI.js.map → chunk-ITGVRN2S.js.map} +1 -1
- package/dist/{chunk-DUZG6A22.cjs → chunk-LO3GQFQ6.cjs} +4 -4
- package/dist/{chunk-DUZG6A22.cjs.map → chunk-LO3GQFQ6.cjs.map} +1 -1
- package/dist/{chunk-4LZXDRAD.cjs → chunk-QD4Z5DRT.cjs} +12 -12
- package/dist/{chunk-4LZXDRAD.cjs.map → chunk-QD4Z5DRT.cjs.map} +1 -1
- package/dist/{chunk-VAJ4D7EF.js → chunk-QMUIZHJO.js} +510 -16
- package/dist/chunk-QMUIZHJO.js.map +1 -0
- package/dist/{chunk-TV5QTT44.js → chunk-RW6TJMRK.js} +3 -3
- package/dist/{chunk-TV5QTT44.js.map → chunk-RW6TJMRK.js.map} +1 -1
- package/dist/{chunk-2D4Y4LOT.cjs → chunk-V6UQ6GIM.cjs} +551 -48
- package/dist/chunk-V6UQ6GIM.cjs.map +1 -0
- package/dist/chunk-XU7GP53M.js +10 -0
- package/dist/chunk-XU7GP53M.js.map +1 -0
- package/dist/{chunk-DDSNXKFN.cjs → chunk-XYIOM75D.cjs} +9 -9
- package/dist/{chunk-DDSNXKFN.cjs.map → chunk-XYIOM75D.cjs.map} +1 -1
- package/dist/core/index.cjs +153 -613
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +36 -1
- package/dist/core/index.d.ts +36 -1
- package/dist/core/index.js +21 -511
- package/dist/core/index.js.map +1 -1
- package/dist/index.css +1 -1
- package/dist/manager/index.cjs +239 -239
- package/dist/manager/index.js +6 -6
- package/dist/traveller/index.cjs +35 -35
- package/dist/traveller/index.js +5 -5
- package/package.json +1 -1
- package/dist/chunk-2D4Y4LOT.cjs.map +0 -1
- package/dist/chunk-2JABR4FF.js +0 -105
- package/dist/chunk-2JABR4FF.js.map +0 -1
- package/dist/chunk-ABWNV4N4.js.map +0 -1
- package/dist/chunk-CCJ5XNWY.cjs.map +0 -1
- package/dist/chunk-KDGBJPPZ.cjs +0 -110
- package/dist/chunk-KDGBJPPZ.cjs.map +0 -1
- package/dist/chunk-VAJ4D7EF.js.map +0 -1
package/dist/core/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/errors/errors.ts","../../src/core/hooks/useBlobStatus.ts","../../src/core/hooks/useFeedbackNps.ts","../../src/core/hooks/useJourney.ts","../../src/core/hooks/useSnapshotEntity.ts","../../src/core/hooks/useStaleness.ts","../../src/core/hooks/useTreks.ts","../../src/core/shells/internal/themeAttributes.ts","../../src/core/shells/AppShell.tsx","../../src/core/shells/ConfigShell.tsx","../../src/core/shells/ErrorShell.tsx","../../src/core/shells/internal/sessionExpiryBridge.ts","../../src/core/shells/OfflineShell.tsx","../../src/core/shells/internal/jwtKind.ts","../../src/core/shells/SessionShell.tsx","../../src/core/shells/TelemetryShell.tsx","../../src/core/shells/ThemeShell.tsx","../../src/core/provider/KaafilUIKitProvider.tsx","../../src/core/shells/HostCssCompatibilityProbe.tsx","../../src/core/shells/KaafilSessionProbe.tsx"],"names":["useState","useEffect","useCallback","useContext","SyncOpMethod","useRef","Fragment","jsx","jsxs","createContext","kind","useMemo"],"mappings":"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","file":"index.js","sourcesContent":["// Named error classes a /core hook throws (as opposed to `classifyError()`'s\n// classification of an error a hook CAUGHT). `08-core-hooks.md §1.4`'s\n// persona-restriction note is the concrete callsite for `UnsatisfiableSchemeError`\n// re-exported below; every §3 domain hook's still-`NotImplementedError` stub\n// is the callsite for the second.\n\n// Re-exported, not re-implemented: `kaafil-js`'s own `CredentialResolver`\n// already throws this for exactly the case `08-core-hooks.md §1.4` and every\n// §3 domain hook's \"Persona restriction\" paragraph describes (a manager\n// session calling `useVendors().upsert`, a share session calling\n// `useCapability()`, …). Re-exporting it from `/core` — rather than leaving\n// every family to `import { UnsatisfiableSchemeError } from 'kaafil-js/client'`\n// itself — is what lets a composite's `catch` block do\n// `instanceof UnsatisfiableSchemeError` without importing `kaafil-js` outside\n// `src/core/` (hard rule #1).\nexport { UnsatisfiableSchemeError } from 'kaafil-js/client';\n\n/**\n * Thrown by a §3 domain hook that has no implementation yet in this build.\n *\n * Deliberately NOT the same class as `kaafil-js`'s own `KaafilNotImplementedError`\n * (re-exported by `./classify.ts`'s callers via `kaafil-js/client` where\n * needed) — that one models the wire's `501 NOT_IMPLEMENTED` catalog code (a\n * reserved server route, `architecture/10-conventions.md §7`), a fact about\n * the API. This one is a fact about THIS PACKAGE's own build: the hook\n * exists, type-checks, and is importable, but its body has not been\n * authored yet. Naming it differently keeps a composite's `catch` block from\n * ever conflating \"the server hasn't shipped this route\" with \"the UIKit\n * hasn't shipped this hook\" — the two need different user-facing copy and\n * the two need different fixes.\n */\nexport class NotImplementedError extends Error {\n readonly hookName: string;\n readonly specSection: string;\n\n constructor(hookName: string, specSection: string) {\n super(\n `${hookName}() has no implementation in this build yet — see ` +\n `08-core-hooks.md ${specSection} for its full signature and SDK binding.`,\n );\n this.name = 'NotImplementedError';\n // `kaafil-js/src/http/errors.ts`'s classes all do this for the same\n // reason: a downlevel build target can rebuild the prototype chain\n // incorrectly through `super()`, breaking `instanceof` for the one class\n // whose whole purpose is to be caught by name.\n Object.setPrototypeOf(this, NotImplementedError.prototype);\n this.hookName = hookName;\n this.specSection = specSection;\n }\n}\n","'use client';\n\n// `08-core-hooks.md §2.8`. The independent lifecycle of one blob on the blob\n// lane — deliberately never blocking the parent money/form record.\n//\n// SDK MISMATCH (flagged, not papered over — `kaafil-js/src/offline/blob.ts`,\n// verified this session): the catalog's signature promises a five-state\n// union — `'pending' | 'uploading' | 'ready' | 'orphaned' | 'purged'` — plus\n// a `progress: number | undefined` (0..1). The real `BlobLane` exposes a\n// THREE-state `BlobRecord.status` (`'pending' | 'confirmed' | 'parked'`) and\n// no progress field of any kind — there is no partial-byte OR whole-file\n// upload-progress signal anywhere in `BlobRecord`. This hook maps what the\n// SDK actually reports onto the catalog's vocabulary as faithfully as it\n// can (`pending → pending`, `confirmed → ready`, `parked → orphaned`) and\n// hardcodes `progress: undefined` always, rather than inventing a byte\n// counter the SDK does not track. It cannot report `'purged'` at all — that\n// is a server-side FILE retention state (`files.meta()`'s `retentionClass`),\n// never a `BlobRecord.status` value, and polling `files.meta()` from inside\n// a \"thin subscription over the SDK's own OfflineEngine\" hook would be the\n// second-cache anti-pattern `07-offline-and-sync.md §9` forbids. See this\n// worker's final report for the `blocked` entry.\n\nimport { useContext, useState } from 'react';\nimport { OfflineEngineContext } from '../internal/contexts';\nimport { useOfflineEvent } from './useOfflineEvent';\n\nexport interface BlobStatusResult {\n readonly status: 'pending' | 'uploading' | 'ready' | 'orphaned' | 'purged';\n readonly progress: number | undefined;\n}\n\nexport function useBlobStatus(blobId: string): BlobStatusResult {\n // NOT `useOfflineEngine()` (its throwing form) — called from inside a\n // domain hook's unconditional `build()` (`createDomainHook.ts`), including\n // the render(s) before `OfflineShell` has opened an engine. No engine yet\n // reads the same as \"never seen\" below.\n const engine = useContext(OfflineEngineContext);\n const [, forceRefresh] = useState(0);\n\n useOfflineEvent('sync.drained', () => forceRefresh((tick) => tick + 1));\n useOfflineEvent('sync.error', () => forceRefresh((tick) => tick + 1));\n\n const record = engine?.blobs?.all().find((candidate) => candidate.id === blobId);\n\n if (record === undefined) {\n // Never seen (or already pruned after confirming) — the honest read is\n // \"pending\", the same posture `useSnapshotEntity()` takes for a row that\n // has not synced: absence is not evidence of failure.\n return { status: 'pending', progress: undefined };\n }\n\n const status: BlobStatusResult['status'] =\n record.status === 'confirmed'\n ? 'ready'\n : record.status === 'parked'\n ? 'orphaned'\n : record.attemptCount > 0\n ? 'uploading'\n : 'pending';\n\n return { status, progress: undefined };\n}\n","'use client';\n\n// `08-core-hooks.md §3` table, row `useFeedbackNps(scope)`. Primary SDK\n// surface (verified, `kaafil-js/src/resources/feedback-nps.ts`):\n// `feedbackNps.trip` (`managerAuth`, `agencyAdminAuth`, `apiKeyAuth`),\n// `feedbackNps.agency` (`agencyAdminAuth`, `apiKeyAuth` — never a manager\n// alone; agencyRef auto-bound on `KaafilClient`). Read-only by design: the\n// \"designate this form as the feedback survey\" write lives in `forms`, not\n// here. Below `feedback.summary.minResponses` the payload reports\n// `npsScore: null` — \"not enough responses yet\", never a zero.\n//\n// DECISION: no `createDomainHook()` gate — the two scope members\n// (`trip`/`agency`) have DIFFERENT credential sets and neither is a trip\n// capability module in `06-capability-and-personas.md §3`'s sense; a\n// `manager`-session caller of `agency` fails at the credential check\n// (`UnsatisfiableSchemeError`), which is a persona restriction, not a\n// capability darkness treatment. `manager/06-feedback-nps.md`'s own\n// `FeedbackNpsFlow` does its OWN `feedback-nps` capability gate at the\n// composite layer instead (`CapabilityGate` + `useCapability('feedback-nps')`\n// — the same shape every other capability-gated-but-not-domain-hook-gated\n// composite in this tree already uses).\n//\n// READ MODEL — LIVE, NOT CACHE-FIRST, same reasoning as `useCloseout.ts`'s\n// own header: both `feedbackNps.trip`/`feedbackNps.agency` are fully\n// DERIVED rollups recomputed on every read (window state, funnel counts,\n// the NPS bucket split) — there is no per-row `id`/`version` for\n// `extractSectionRows()` to key a delta feed on, and `'feedbackNps'` does\n// not appear in `SYNC_PULL_SECTIONS`. This hook refreshes explicitly rather\n// than subscribing to `snapshot.updated`.\n//\n// WRITE MODEL — the one write this module owns is the dispatch/chase\n// action, and it is NOT `feedbackNps`'s own: `FeedbackNpsResource` is\n// read-only by the SDK's own header comment. The real write is\n// `forms.trip.dispatch` (`kaafil-js/src/resources/forms.ts`,\n// `POST /api/v1/trips/{ref}/forms/{formId}/dispatch`), targeted at the\n// `formId` this same read already resolved — mirrors `useRooming.ts`'s own\n// `engine.enqueue()` recipe (hard-coded `operationId` literal, since\n// `OperationId` is not part of `kaafil-js/client`'s public surface) so the\n// tap is outbox-backed and idempotent exactly like every other manager\n// write in this package, per `manager/06-feedback-nps.md`'s own \"Offline\"\n// note (\"dispatch/chase is an outbox op with a `clientToken`-derived\n// idempotency key — a re-tick or retried tap cannot double-send\").\n//\n// DOUBLE `data.data` NESTING: `feedback-nps.ts`'s own header flags that\n// BOTH response schemas nest a second `data` inside the envelope's own\n// `data` — this hook reads `response.data.configured`/\n// `response.data.definitions`, not `response.configured`/\n// `response.definitions`, and re-exports the inner `data` shape directly so\n// no caller above this hook has to know about the double nesting either.\n\nimport type { DispatchFormOptions, FeedbackNpsResource, OutboxOp } from 'kaafil-js/client';\nimport { SyncOpMethod } from 'kaafil-js/client';\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport { useKaafilClient } from './useKaafilClient';\nimport type { OfflineMutationStatus } from './useOfflineMutation';\nimport { useOfflineMutation } from './useOfflineMutation';\n\nexport type FeedbackNpsScope =\n | { readonly kind: 'trip'; readonly tripRef: string }\n | { readonly kind: 'agency'; readonly agencyRef: string };\n\ntype TripFeedbackSummaryData = Awaited<ReturnType<FeedbackNpsResource['trip']>>['data'];\ntype AgencyFeedbackSummaryData = Awaited<ReturnType<FeedbackNpsResource['agency']>>['data'];\n\n/** The `trip` read's `configured: true` branch, narrowed — every\n * window/funnel/`nps` field a summary panel renders lives only here; the\n * `configured: false` branch carries only `reason`. */\nexport type FeedbackNpsTripSummary = Extract<TripFeedbackSummaryData, { configured: true }>;\n\n/** One row of the `agency` read's `definitions[]` — the agency-wide rollup\n * `manager/06-feedback-nps.md` explicitly leaves to the admin family; kept\n * here only so this one shared hook serves both scopes uniformly. */\nexport type FeedbackNpsAgencyDefinitionRow = AgencyFeedbackSummaryData['definitions'][number];\n\nexport type DispatchFeedbackChaseInput = Omit<\n DispatchFormOptions,\n 'tripRef' | 'formId' | 'idempotencyKey' | 'signal'\n>;\n\nexport interface FeedbackNpsReady {\n readonly kind: FeedbackNpsScope['kind'];\n /** `trip` scope only — the discriminated union verbatim off the wire.\n * `undefined` on `agency` scope, or before the first `trip` fetch has\n * settled (`loaded` distinguishes the two). */\n readonly summary: TripFeedbackSummaryData | undefined;\n /** `agency` scope only — always `[]` on `trip` scope. */\n readonly definitions: readonly FeedbackNpsAgencyDefinitionRow[];\n /** `true` once the first read has settled (success or failure) —\n * distinguishes \"never fetched yet\" from \"fetched, and this trip\n * genuinely has no feedback form configured\" (`CloseoutReady.loaded`'s\n * own contract, reused). */\n readonly loaded: boolean;\n /** `true` when the MOST RECENT fetch threw. `loaded`/`summary`/\n * `definitions` stay whatever they already were. */\n readonly lastFetchFailed: boolean;\n readonly syncedAt: string | undefined;\n readonly refresh: () => Promise<void>;\n /** `trip` scope only. Throws if called before a `configured: true`\n * summary has resolved a `formId` to target — a caller gates the\n * dispatch control on `summary?.configured === true` first exactly as\n * `manager/06-feedback-nps.md`'s own `FeedbackDispatchControls` does. */\n readonly dispatch: (input?: DispatchFeedbackChaseInput) => Promise<OutboxOp>;\n /** The dispatch op's OWN outbox lifecycle (`useOfflineMutation`'s own\n * `status`) — `'parked'`/`'conflicted'` is how a `423`\n * (\"this trip has been closed out\") or a `402` plan-lock surfaces, via\n * `dispatchOp?.parkReason?.userMessage` (`06-feedback-nps.md`'s own\n * `locked (423)`/`parked (402)` States rows). */\n readonly dispatchStatus: OfflineMutationStatus;\n readonly dispatchOp: OutboxOp | undefined;\n}\n\n/**\n * Two scope members, different credential sets, one shared read/refresh\n * shape — see this file's header for why there is no `createDomainHook()`\n * gate. `manager`'s own `FeedbackNpsFlow` only ever calls this with\n * `{ kind: 'trip', tripRef }`; the `agency` branch exists for the admin\n * family's own agency-wide rollup, reusing this same hook rather than a\n * second `useAgencyFeedbackNps()` (hard rule #2).\n */\nexport function useFeedbackNps(scope: FeedbackNpsScope): FeedbackNpsReady {\n const client = useKaafilClient();\n\n const [summary, setSummary] = useState<TripFeedbackSummaryData | undefined>(undefined);\n const [definitions, setDefinitions] = useState<readonly FeedbackNpsAgencyDefinitionRow[]>([]);\n const [loaded, setLoaded] = useState(false);\n const [lastFetchFailed, setLastFetchFailed] = useState(false);\n const [syncedAt, setSyncedAt] = useState<string | undefined>(undefined);\n\n // The dispatch write targets whichever `formId` the most recent `trip`\n // read resolved — a ref rather than a `useOfflineMutation` closure\n // variable so `dispatch` always reads the CURRENT summary even though\n // `useOfflineMutation`'s own `enqueue` is bound once per hook instance.\n const formIdRef = useRef<string | undefined>(undefined);\n\n // `scope` is a fresh object per render on most call sites; the deps array\n // below narrows to its own primitive members instead so this effect\n // doesn't re-fire every render — biome cannot see that `scope.tripRef`/\n // `scope.agencyRef` are each only read inside their own matching\n // `scope.kind` branch, so it flags the ternary as both missing a\n // dependency and carrying an unnecessary one; both reports are spurious.\n // biome-ignore lint/correctness/useExhaustiveDependencies: see comment above.\n const refresh = useCallback(async (): Promise<void> => {\n try {\n if (scope.kind === 'trip') {\n const response = await client.feedbackNps.trip({ tripRef: scope.tripRef });\n setSummary(response.data);\n formIdRef.current = response.data.configured ? response.data.formId : undefined;\n setLoaded(true);\n setLastFetchFailed(false);\n setSyncedAt(response.meta.serverTime);\n } else {\n // `client.feedbackNps` is the BOUND resource (`useKaafilClient()`\n // returns `KaafilClient`, never the raw `kaafil-js` resource) —\n // `agencyRef` is auto-bound on the client per this file's own\n // header, so `BoundReadAgencyFeedbackSummaryOptions` omits it\n // entirely; passing it here would be a type error, not a no-op.\n const response = await client.feedbackNps.agency({});\n setDefinitions(response.data.definitions);\n setLoaded(true);\n setLastFetchFailed(false);\n setSyncedAt(response.meta.serverTime);\n }\n } catch {\n // Honest failure, not a fabricated empty/dark summary — `loaded`\n // stays whatever it already was; only `lastFetchFailed` flips\n // (`CloseoutReady`'s own catch block, reused).\n setLastFetchFailed(true);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps -- `scope.tripRef`/`scope.agencyRef` are each only read inside their own matching `scope.kind` branch above; eslint's static check can't see through the discriminated union, so it flags this ternary as both a missing and a too-complex dependency. `biome check` (this file's other linter) reports the identical false positive for the same reason.\n }, [client, scope.kind, scope.kind === 'trip' ? scope.tripRef : scope.agencyRef]);\n\n useEffect(() => {\n void refresh();\n }, [refresh]);\n\n const dispatchMutation = useOfflineMutation<DispatchFeedbackChaseInput>({\n tripRef: scope.kind === 'trip' ? scope.tripRef : '',\n enqueue: (engine, input) => {\n const formId = formIdRef.current;\n if (formId === undefined || scope.kind !== 'trip') {\n // No configured form to dispatch against yet — the composite gates\n // its dispatch control on `summary?.configured === true` before\n // ever calling this, so reaching here is a caller bug, not a\n // reachable user path; throwing here rather than silently queuing\n // a request with no `formId` keeps that bug loud in dev.\n throw new Error('useFeedbackNps: cannot dispatch before a feedback form is resolved');\n }\n return engine.enqueue({\n tripRef: scope.tripRef,\n method: SyncOpMethod.Post,\n path: `/api/v1/trips/${scope.tripRef}/forms/${formId}/dispatch`,\n // Hardcoded literal, not imported: `OperationId` is not exported\n // from `kaafil-js/client`'s public surface — same convention as\n // `useRooming.ts`'s own `'assignRoomingBed' as never`. Verified\n // against `kaafil-js/src/generated/security.ts`\n // (`OPERATION_SECURITY.dispatchForm`) this session.\n operationId: 'dispatchForm' as never,\n body: input ?? {},\n });\n },\n });\n\n const dispatchMutate = dispatchMutation.mutate;\n const dispatch = useCallback(\n async (input?: DispatchFeedbackChaseInput): Promise<OutboxOp> => {\n const op = await dispatchMutate(input ?? {});\n // A dispatch changes `dispatched`/`completionRate` — re-request the\n // live summary rather than leaving it stale until an unrelated\n // remount (`RoomingReady.assign`'s own `refreshUnassignedPool` call,\n // same reasoning).\n void refresh();\n return op;\n },\n [dispatchMutate, refresh],\n );\n\n return {\n kind: scope.kind,\n summary,\n definitions,\n loaded,\n lastFetchFailed,\n syncedAt,\n refresh,\n dispatch,\n dispatchStatus: dispatchMutation.status,\n dispatchOp: dispatchMutation.op,\n };\n}\n","'use client';\n\n// `08-core-hooks.md §3.2`. Named separately from `useCapability` because it\n// also exposes the journey config surface, not only the resolved\n// capability triple. Wraps `journey.get` (`readJourneyOptions`),\n// `journey.capabilities` (`readJourneyCapabilities`),\n// `journey.capabilities({ live: true })` for `refreshCapabilities()`,\n// `journey.triggers.list`/`.patch` (agencyRef auto-bound on `KaafilClient`).\n// `refreshCapabilities` is a SYNCHRONOUS recompute against live state, never\n// persisted — it does NOT call `journey.rebuild` (`apiKeyAuth`-only, a full\n// async rebuild that persists new stage rows). Persona restriction:\n// `manager`/`agencyAdmin` only.\n//\n// DECISION: the catalog's literal `capabilities: ReturnType<typeof\n// useCapabilities>` cannot mean \"call `useCapabilities()` from inside this\n// hook\" — that hook resolves its trip from the AMBIENT `TripContext`\n// (`08-core-hooks.md §1.4`'s no-`tripRef` signature), which may differ from\n// the EXPLICIT `tripRef` this hook was called with. This hook instead reads\n// `../internal/useCapabilityRows.ts` directly, scoped to its own `tripRef`,\n// and derives the identical `ReadonlyMap<string, CapabilityTriple>` shape —\n// same implementation `useCapabilities()` itself calls, correctly scoped.\n\nimport type { BoundJourneyResource, JourneyResource } from 'kaafil-js/client';\nimport { useCallback, useEffect, useState } from 'react';\nimport { deriveCapabilityTriple } from '../internal/deriveCapabilityTriple';\nimport { isDevelopment } from '../internal/isDevelopment';\nimport { useCapabilityRows } from '../internal/useCapabilityRows';\nimport type { CapabilityTriple } from '../types/capability.types';\nimport { useKaafilClient } from './useKaafilClient';\nimport { usePersona } from './usePersona';\n\n// `JourneyReadResponse` is a LOCAL, non-exported type alias inside\n// `kaafil-js/src/resources/journey.ts` (verified this session) — never\n// re-exported from `kaafil-js/client`. Derived structurally off the one\n// exported resource type instead of restated by hand, so it can never drift\n// from what `journey.get()` actually returns.\ntype JourneyReadResponse = Awaited<ReturnType<JourneyResource['get']>>;\n\nexport interface JourneyResult {\n readonly read: JourneyReadResponse | undefined;\n readonly capabilities: ReadonlyMap<string, CapabilityTriple>;\n readonly refreshCapabilities: () => Promise<void>;\n readonly triggers: {\n list: BoundJourneyResource['triggers']['list'];\n patch: BoundJourneyResource['triggers']['patch'];\n };\n}\n\nexport function useJourney(tripRef: string): JourneyResult {\n const client = useKaafilClient();\n const persona = usePersona();\n const { rows } = useCapabilityRows(tripRef);\n const [read, setRead] = useState<JourneyReadResponse | undefined>(undefined);\n const [liveRows, setLiveRows] = useState<typeof rows | undefined>(undefined);\n\n useEffect(() => {\n if (persona === 'share') {\n if (isDevelopment()) {\n throw new Error(\n 'useJourney() was called from a share session — it is manager/agencyAdmin ' +\n 'only (08-core-hooks.md §3.2).',\n );\n }\n return;\n }\n let cancelled = false;\n void client.journey.get({ tripRef }).then((response) => {\n if (!cancelled) {\n setRead(response);\n }\n });\n return () => {\n cancelled = true;\n };\n }, [client, persona, tripRef]);\n\n const refreshCapabilities = useCallback(async (): Promise<void> => {\n const response = await client.journey.capabilities({ tripRef, live: true });\n setLiveRows(response);\n }, [client, tripRef]);\n\n const effectiveRows = liveRows ?? rows;\n const capabilities = new Map<string, CapabilityTriple>();\n for (const row of effectiveRows) {\n capabilities.set(row.capability, deriveCapabilityTriple(row));\n }\n\n return {\n read,\n capabilities,\n refreshCapabilities,\n triggers: {\n list: (options) => client.journey.triggers.list(options),\n patch: (options) => client.journey.triggers.patch(options),\n },\n };\n}\n","'use client';\n\n// `08-core-hooks.md §2.3`. A single row looked up out of the same snapshot\n// list `useSnapshotList` reads, by id — there is no per-id read in\n// `SnapshotStore` itself, so this is the narrowing convenience the catalog\n// says it is, built on the same list read rather than a second store call.\n\nimport { useContext } from 'react';\nimport { OfflineEngineContext } from '../internal/contexts';\nimport { useSnapshotList } from './useSnapshotList';\n\nexport interface SnapshotEntityResult<TRow> {\n readonly row: TRow | undefined;\n readonly syncedAt: string | undefined;\n}\n\n/**\n * `row` is `undefined` both when the id genuinely doesn't exist and when\n * the list hasn't synced yet — a caller distinguishes those with\n * `syncedAt`: absent entirely means \"never pulled\"; present with `row:\n * undefined` means \"pulled, and this id isn't in it\" (`08-core-hooks.md\n * §2.3`).\n */\nexport function useSnapshotEntity<TRow extends Record<string, unknown>>(\n tripRef: string,\n listName: string,\n id: string,\n): SnapshotEntityResult<TRow> {\n // NOT `useOfflineEngine()` (its throwing form) — same \"runs before\n // OfflineShell opens an engine\" window `useSnapshotList` already tolerates.\n const engine = useContext(OfflineEngineContext);\n const { rows } = useSnapshotList<TRow & { id: string }>(tripRef, listName);\n const row = rows.find((candidate) => candidate.id === id);\n\n // The list-level `syncedAt` `useSnapshotList` derives is the max across\n // every cached row; the narrower \"never pulled\" vs. \"pulled, id absent\"\n // distinction this hook promises needs the ENTITY's own stamp, read\n // straight off the engine both hooks already share one instance of. No\n // engine yet reads the same as \"never pulled\" — `undefined`.\n const syncedAt = engine === null ? undefined : engine.snapshot.syncedAt(tripRef, listName, id);\n\n return { row, syncedAt };\n}\n","'use client';\n\n// `08-core-hooks.md §2.4`. `ageSeconds` from `useServerTime()` minus the\n// list's `syncedAt`; `isStale` past a threshold `ConfigShell` supplies —\n// never a hardcoded UIKit constant (thresholds are a presentation decision\n// left to the composite/theme layer).\n\nimport type { StalenessState } from '../types/offline.types';\nimport { useResolvedSetting } from './useResolvedSetting';\nimport { useServerTime } from './useServerTime';\nimport { useSnapshotList } from './useSnapshotList';\n\n/**\n * DECISION: the catalog names \"a threshold `ConfigShell` supplies\" without\n * naming the resolved-setting key. `stale.thresholdSeconds` is this hook's\n * own choice of key, under the `stale` module namespace — the closest fit to\n * `useResolvedSetting`'s `module.group.key` shape (`08-core-hooks.md §1.5`)\n * for a value that isn't owned by any one of the eighteen domain modules.\n * `isStale` is conservatively `false` (never a guessed threshold) when\n * nothing resolved one — the honest reading of \"no threshold configured\"\n * given `useResolvedSetting()` may never supply its own default (hard rule\n * #5).\n */\nexport function useStaleness(tripRef: string, listName: string): StalenessState {\n const { syncedAt } = useSnapshotList(tripRef, listName);\n const { now } = useServerTime();\n const thresholdSeconds = useResolvedSetting<number>('stale.thresholdSeconds.default');\n\n if (syncedAt === undefined) {\n return { syncedAt: undefined, ageSeconds: undefined, isStale: false };\n }\n\n let ageSeconds: number | undefined;\n try {\n // `useServerTime().now()` throws until a `snapshot.updated` event has\n // landed at least once (see that file's header) — an entity CAN carry a\n // `syncedAt` earlier than that (a drain success rebases from\n // `sync.drained`'s outcome, which does not itself carry `serverTime`\n // on the event `useServerTime` listens to). Falling back to \"unknown\n // age\" here is the honest answer for that narrow window, not a second\n // local-clock guess.\n ageSeconds = (Date.parse(now()) - Date.parse(syncedAt)) / 1000;\n } catch {\n ageSeconds = undefined;\n }\n const isStale =\n ageSeconds !== undefined && thresholdSeconds !== undefined && ageSeconds > thresholdSeconds;\n\n return { syncedAt, ageSeconds, isStale };\n}\n","'use client';\n\n// `08-core-hooks.md §3` table, row `useTreks(tripRef)`. Primary SDK surface\n// (verified, `kaafil-js/src/resources/treks.ts`): `treks.board`,\n// `treks.postpone`, `treks.walkIns.meta`, `treks.walkIns.create`,\n// `treks.walkIns.{list,listPage}`, `treks.walkIns.reconcile`. All six accept\n// `managerAuth`/`apiKeyAuth`/`agencyAdminAuth`; the `trekRef: 'active'`\n// sentinel is refused `422 ACTIVE_REQUIRES_MANAGER` for `apiKey`/\n// `agencyAdmin` on all six. PERSONALIZED mode-dark.\n//\n// NONE OF THIS IS A SNAPSHOT-LIST READ. `08-treks.md`'s own `Offline` rows\n// cite \"cache-first from the snapshot\" for both the board and the walk-in\n// roster, but `SYNC_PULL_SECTIONS` (`kaafil-js/src/offline/pull.ts`,\n// verified) lists exactly `rooming, stayWindows, pickups, seating, bookings,\n// expenses, checklist, float, collections, itinerary, closeout` — no\n// `treks` and no `walkIns` entry. There is no `SnapshotStore` list this hook\n// could subscribe `useSnapshotList` to for either read. Both `board` and\n// `walkIns` below are therefore LIVE, explicitly-refreshed reads — the same\n// shape `useFloat.ts` documents for `summary` (its own derived, uncacheable\n// balance) — refreshed on mount and again after any write that could have\n// changed them, never claimed as offline-cached. This is a genuine gap\n// between the spec's FRD §5 and this build's real SDK plumbing, not an\n// oversight; see this worker's final report.\n//\n// `board`'s `emptyState` (`{ reason: 'no_trek_assigned', message }`) is a\n// normal `200`, not a thrown error (`treks.ts`'s own header) — modelled\n// below as `board.data.emptyState` staying non-null, never surfaced via\n// `lastFetchFailed`.\n//\n// WRITES. `createWalkIn`/`postpone` enqueue via `useOfflineMutation` — the\n// walk-in's minted `travellerId` is stable across the offline→online\n// transition per the SDK's own doc comment, and postpone's ripple/stamps\n// are computed server-side only, matching `08-treks.md`'s own `Offline`\n// rows. `reconcileWalkIn` is exposed too (verified real SDK method, cited\n// by this worker's own task brief: \"walk-ins now support manual\n// reconcile\") even though it is outside `08-treks.md`'s own prop tables —\n// `TrekWalkInRoster` needs a real action for its `needsReconciliation`\n// badge, and inventing a client-side reconciliation would violate\n// `treks.ts`'s own \"matching happens entirely server-side\" framing. It\n// enqueues through the same offline lane as the other two writes for the\n// identical at-least-once/idempotency guarantees.\n\nimport type {\n CreateTrekWalkInOptions,\n OutboxOp,\n PostponeTrekOptions,\n TreksResource,\n} from 'kaafil-js/client';\nimport { SyncOpMethod } from 'kaafil-js/client';\nimport { useCallback, useEffect, useState } from 'react';\nimport { createDomainHook } from '../internal/createDomainHook';\nimport type { DomainHookResult } from '../types/domain.types';\nimport { useKaafilClient } from './useKaafilClient';\nimport { useOfflineMutation } from './useOfflineMutation';\n\n/** `TrekBoardResponse` — verified against `kaafil-js/src/generated/\n * schema.d.ts`. `TreksResource['board']` resolves to `KaafilResponse<\n * TrekBoardResponse>` = `TrekBoardResponse & { meta }` (`kaafil-js/src/\n * types/meta.ts`'s own intersection, not a nested `data` field — unlike\n * `FloatSummaryResponse`/`FloatLedgerResponse`, `TrekBoardResponse` carries\n * `phase`/`stops`/`runningHeadCount`/`emptyState` at its own top level).\n * `phase`/`externalTripId` are `null` only when `emptyState` is set; every\n * other field still comes back with its empty/zero identity rather than\n * being omitted (the schema's own doc comment). */\nexport type TrekBoardData = Awaited<ReturnType<TreksResource['board']>>;\nexport type TrekBoardStop = TrekBoardData['stops'][number];\n\n/** One row of `treks.walkIns.listPage()`'s page — `KaafilPagedResponse<\n * readonly WalkInListItemResponse[]>` = the array itself, `meta` attached\n * (`kaafil-js/src/types/meta.ts`), never a nested `.data`. */\nexport type TrekWalkInRow = Awaited<ReturnType<TreksResource['walkIns']['listPage']>>[number];\n\n/** `WalkInMetaResponse` — the pickup options + field-requirement hints a\n * walk-in intake form reads, verified against the generated schema; same\n * flat (non-`data`-nested) shape as `TrekBoardData`. */\nexport type TrekWalkInMetaData = Awaited<ReturnType<TreksResource['walkIns']['meta']>>;\n\nexport type CreateTrekWalkInInput = Omit<\n CreateTrekWalkInOptions,\n 'trekRef' | 'idempotencyKey' | 'signal'\n>;\nexport type PostponeTrekInput = Omit<PostponeTrekOptions, 'trekRef' | 'idempotencyKey' | 'signal'>;\n/** `ReconcileTrekWalkInOptions` — verified real (`treks.ts`'s own\n * `walkIns.reconcile`) but NOT re-exported from `kaafil-js/client`'s public\n * surface (verified: `client-entry.ts`'s `export type { ... } from\n * './resources/treks'` list omits it, unlike its five siblings). Derived\n * structurally off `TreksResource['walkIns']['reconcile']`'s own parameter\n * rather than importing a name that does not exist on the package's public\n * barrel — see this worker's final report for the exact export gap. */\nexport type ReconcileTrekWalkInInput = Omit<\n Parameters<TreksResource['walkIns']['reconcile']>[0],\n 'trekRef' | 'walkInId' | 'idempotencyKey' | 'signal'\n>;\n\n/**\n * The phase-aware boarding board — a live-fetched, explicitly-refreshed\n * state, never a snapshot subscription. See this file's header for why.\n */\nexport interface TrekBoardState {\n readonly data: TrekBoardData | undefined;\n /** `true` once at least one `client.treks.board()` call has settled\n * (success or failure) — same `loaded` contract `RoomingUnassignedPool`/\n * `useFloat().summary` document. */\n readonly loaded: boolean;\n /** `true` when the MOST RECENT fetch threw — a genuine transport/server\n * failure, distinct from the honest `emptyState` \"no trek assigned\"\n * `200`. */\n readonly lastFetchFailed: boolean;\n readonly fetchedAt: string | undefined;\n readonly refresh: () => Promise<void>;\n}\n\n/** The walk-in roster — live-fetched via `listPage`, one page at a time\n * (`08-treks.md §TrekWalkInRoster`'s own prop table cites `.list`/\n * `.listPage`, never a delta feed). `loadMore` advances the cursor; calling\n * `refresh` resets back to the first page. */\nexport interface TrekWalkInsState {\n readonly rows: readonly TrekWalkInRow[];\n readonly loaded: boolean;\n readonly lastFetchFailed: boolean;\n readonly fetchedAt: string | undefined;\n readonly hasMore: boolean;\n readonly refresh: () => Promise<void>;\n readonly loadMore: () => Promise<void>;\n}\n\nexport interface TrekWalkInMetaState {\n readonly data: TrekWalkInMetaData | undefined;\n readonly loaded: boolean;\n readonly lastFetchFailed: boolean;\n readonly refresh: () => Promise<void>;\n}\n\nexport interface TreksReady {\n readonly board: TrekBoardState;\n readonly walkIns: TrekWalkInsState;\n readonly walkInMeta: TrekWalkInMetaState;\n /** `POST .../walk-ins` — lands `BOARDED` directly for a manager submitter\n * (`D-211`). */\n readonly createWalkIn: (input: CreateTrekWalkInInput) => Promise<OutboxOp>;\n /** `POST .../postpone` — shifts itinerary/stay-window dates server-side;\n * never shifts pickup `scheduledTime`s (`08-treks.md`'s own \"Does NOT\"). */\n readonly postpone: (input: PostponeTrekInput) => Promise<OutboxOp>;\n /** `POST .../walk-ins/{walkInId}/reconcile` — the human fallback for a\n * name-only walk-in the automatic CRM-phone match can't clear on its\n * own. See this file's header for why this is exposed beyond\n * `08-treks.md`'s own prop tables. */\n readonly reconcileWalkIn: (\n walkInId: string,\n input: ReconcileTrekWalkInInput,\n ) => Promise<OutboxOp>;\n}\n\nconst WALK_INS_PAGE_SIZE = 25;\n\nconst useTreksInternal = createDomainHook<TreksReady>('treks', (tripRef) => {\n const client = useKaafilClient();\n\n // ---- board (live) --------------------------------------------------\n const [boardData, setBoardData] = useState<TrekBoardData | undefined>(undefined);\n const [boardLoaded, setBoardLoaded] = useState(false);\n const [boardFetchFailed, setBoardFetchFailed] = useState(false);\n const [boardFetchedAt, setBoardFetchedAt] = useState<string | undefined>(undefined);\n\n const refreshBoard = useCallback(async (): Promise<void> => {\n try {\n const response = await client.treks.board({ trekRef: tripRef });\n setBoardData(response);\n setBoardLoaded(true);\n setBoardFetchFailed(false);\n setBoardFetchedAt(response.meta.serverTime);\n } catch {\n // Honest failure, not a fabricated board — `loaded` stays whatever it\n // already was; only `lastFetchFailed` flips. Same reasoning as\n // `useFloat.ts`'s `refreshSummary`.\n setBoardFetchFailed(true);\n }\n }, [client, tripRef]);\n\n useEffect(() => {\n void refreshBoard();\n }, [refreshBoard]);\n\n // ---- walkIns (live, paginated) --------------------------------------\n const [walkInRows, setWalkInRows] = useState<readonly TrekWalkInRow[]>([]);\n const [walkInsLoaded, setWalkInsLoaded] = useState(false);\n const [walkInsFetchFailed, setWalkInsFetchFailed] = useState(false);\n const [walkInsFetchedAt, setWalkInsFetchedAt] = useState<string | undefined>(undefined);\n const [walkInsCursor, setWalkInsCursor] = useState<string | undefined>(undefined);\n const [walkInsHasNext, setWalkInsHasNext] = useState(false);\n\n const refreshWalkIns = useCallback(async (): Promise<void> => {\n try {\n const page = await client.treks.walkIns.listPage({\n trekRef: tripRef,\n limit: WALK_INS_PAGE_SIZE,\n });\n setWalkInRows(page);\n setWalkInsLoaded(true);\n setWalkInsFetchFailed(false);\n setWalkInsFetchedAt(page.meta.serverTime);\n setWalkInsCursor(page.meta.page.cursor ?? undefined);\n setWalkInsHasNext(page.meta.page.hasNext);\n } catch {\n setWalkInsFetchFailed(true);\n }\n }, [client, tripRef]);\n\n const loadMoreWalkIns = useCallback(async (): Promise<void> => {\n if (walkInsCursor === undefined || !walkInsHasNext) {\n return;\n }\n try {\n const page = await client.treks.walkIns.listPage({\n trekRef: tripRef,\n cursor: walkInsCursor,\n limit: WALK_INS_PAGE_SIZE,\n });\n setWalkInRows((existing) => [...existing, ...page]);\n setWalkInsFetchedAt(page.meta.serverTime);\n setWalkInsCursor(page.meta.page.cursor ?? undefined);\n setWalkInsHasNext(page.meta.page.hasNext);\n } catch {\n setWalkInsFetchFailed(true);\n }\n }, [client, tripRef, walkInsCursor, walkInsHasNext]);\n\n useEffect(() => {\n void refreshWalkIns();\n }, [refreshWalkIns]);\n\n // ---- walkInMeta (live) ------------------------------------------------\n const [metaData, setMetaData] = useState<TrekWalkInMetaData | undefined>(undefined);\n const [metaLoaded, setMetaLoaded] = useState(false);\n const [metaFetchFailed, setMetaFetchFailed] = useState(false);\n\n const refreshMeta = useCallback(async (): Promise<void> => {\n try {\n const response = await client.treks.walkIns.meta({ trekRef: tripRef });\n setMetaData(response);\n setMetaLoaded(true);\n setMetaFetchFailed(false);\n } catch {\n setMetaFetchFailed(true);\n }\n }, [client, tripRef]);\n\n useEffect(() => {\n void refreshMeta();\n }, [refreshMeta]);\n\n // ---- writes -------------------------------------------------------\n const createWalkInMutation = useOfflineMutation<CreateTrekWalkInInput>({\n tripRef,\n enqueue: (engine, input) =>\n engine.enqueue({\n tripRef,\n method: SyncOpMethod.Post,\n path: `/api/v1/treks/${tripRef}/walk-ins`,\n // `OperationId` is not exported from `kaafil-js/client`'s public\n // surface — same documented gap `useFloat.ts`/`useRooming.ts` cast\n // around for their own literal `operationId`s.\n operationId: 'createTrekWalkIn' as never,\n body: input,\n }),\n });\n\n const postponeMutation = useOfflineMutation<PostponeTrekInput>({\n tripRef,\n enqueue: (engine, input) =>\n engine.enqueue({\n tripRef,\n method: SyncOpMethod.Post,\n path: `/api/v1/treks/${tripRef}/postpone`,\n operationId: 'postponeTrek' as never,\n body: input,\n }),\n });\n\n const reconcileMutation = useOfflineMutation<{\n readonly walkInId: string;\n readonly input: ReconcileTrekWalkInInput;\n }>({\n tripRef,\n enqueue: (engine, { walkInId, input }) =>\n engine.enqueue({\n tripRef,\n method: SyncOpMethod.Post,\n path: `/api/v1/treks/${tripRef}/walk-ins/${walkInId}/reconcile`,\n operationId: 'reconcileTrekWalkIn' as never,\n body: input,\n }),\n });\n\n const createWalkInMutate = createWalkInMutation.mutate;\n const createWalkIn = useCallback(\n async (input: CreateTrekWalkInInput): Promise<OutboxOp> => {\n const op = await createWalkInMutate(input);\n // A new walk-in changes both the board's head-count and the roster —\n // re-request both live reads rather than leaving them stale, the\n // same \"re-fetch what a write could have changed\" precedent\n // `useFloat.ts`'s `issue`/`return`/`adjust` document.\n void refreshBoard();\n void refreshWalkIns();\n return op;\n },\n [createWalkInMutate, refreshBoard, refreshWalkIns],\n );\n\n const postponeMutate = postponeMutation.mutate;\n const postpone = useCallback(\n async (input: PostponeTrekInput): Promise<OutboxOp> => {\n const op = await postponeMutate(input);\n void refreshBoard();\n return op;\n },\n [postponeMutate, refreshBoard],\n );\n\n const reconcileMutate = reconcileMutation.mutate;\n const reconcileWalkIn = useCallback(\n async (walkInId: string, input: ReconcileTrekWalkInInput): Promise<OutboxOp> => {\n const op = await reconcileMutate({ walkInId, input });\n void refreshWalkIns();\n return op;\n },\n [reconcileMutate, refreshWalkIns],\n );\n\n return {\n board: {\n data: boardData,\n loaded: boardLoaded,\n lastFetchFailed: boardFetchFailed,\n fetchedAt: boardFetchedAt,\n refresh: refreshBoard,\n },\n walkIns: {\n rows: walkInRows,\n loaded: walkInsLoaded,\n lastFetchFailed: walkInsFetchFailed,\n fetchedAt: walkInsFetchedAt,\n hasMore: walkInsHasNext,\n refresh: refreshWalkIns,\n loadMore: loadMoreWalkIns,\n },\n walkInMeta: {\n data: metaData,\n loaded: metaLoaded,\n lastFetchFailed: metaFetchFailed,\n refresh: refreshMeta,\n },\n createWalkIn,\n postpone,\n reconcileWalkIn,\n };\n});\n\n/**\n * PERSONALIZED mode-dark. Returns `{ status: 'dark', reason }` before any\n * fetch when the `'treks'` capability triple isn't `lit`\n * (`06-capability-and-personas.md §3`).\n */\nexport function useTreks(tripRef: string): DomainHookResult<TreksReady> {\n return useTreksInternal(tripRef);\n}\n","'use client';\n\n// The seam between `ThemeShell` and `AppShell` ONLY — this is NOT part of the\n// hooks-phase contract in `../../internal/contexts.ts` and is never exported\n// outside this directory. `shells/05-theme-shell.md` fixes theme as a\n// CSS-only mechanism (\"no mutable JS theme object, no recompute on render\")\n// — this context carries a resolved STRING pair, produced once per prop/\n// media-query change, never an object graph a consumer could inspect or that\n// could drift from the CSS it selects.\n//\n// `AppShell` is the one shell holding a real DOM root (`.kf-root`,\n// `shells/01-app-shell.md`'s \"physical boundary\") — `ThemeShell` itself\n// renders no DOM node of its own (`shells/README.md §1`: a shell has no\n// visual output, and a bare wrapper div \"for its own sake\" fails that test).\n// So `ThemeShell` resolves the values and `AppShell` is the one that actually\n// stamps `data-kf-theme`/`data-kf-density` onto the root it already owns.\n\nimport { createContext } from 'react';\n\nexport interface ThemeAttributes {\n readonly theme: 'light' | 'dark';\n readonly density: 'compact' | 'default' | 'comfortable' | undefined;\n}\n\n/**\n * `null` when `ThemeShell` is not mounted — the tier-6-adjacent \"advanced\n * path\" of mounting a subset of shells (`shells/README.md §5`) may skip\n * `ThemeShell` entirely. `AppShell` treats a `null` read as \"no attribute to\n * stamp,\" never as a required context — `ThemeShell` is presentational, not\n * load-bearing the way `SessionShell` is (`useRequiredContext` is for the\n * latter only).\n */\nexport const ThemeAttributesContext = createContext<ThemeAttributes | null>(null);\n","'use client';\n\n// `shells/01-app-shell.md`. Fourth in the locked mount order\n// (`shells/README.md §2` row 4) — the physical/CSS boundary: `.kf-root`, the\n// CSS-isolation rung, the container-query root, the z-index/stacking root,\n// and (per `./internal/themeAttributes.ts`'s seam) the node `ThemeShell`'s\n// resolved theme/density actually land on. Owns SHAPE, never CONTENT — it\n// reserves nav/action-bar/connectivity regions and fills nothing itself.\n// Imports nothing from `kaafil-js`/`kaafil-js/client` (`shells/README.md §3`).\n//\n// FLAGGED DECISION (see this phase's report): `01-app-shell.md`'s own props\n// table has no `family` prop — family is described as fixed at *import*\n// time, by whichever family's own Surface component (out of this phase's\n// scope) composes this shell. That component needs SOMETHING to tell this\n// generic shell which of the three frame defaults applies and to stamp\n// `data-kf-family` (the task brief's explicit ask for this shell), so an\n// optional `family` prop is added here — undocumented by the spec doc, never\n// exposed by `KaafilUIKitProvider` (which deliberately has no view onto\n// family, `shells/00-kaafil-uikit-provider.md`'s \"Does NOT\" list), and read\n// only by this shell to resolve its own default `frame` and to stamp the\n// data attribute when a caller (a future family Surface component, or an\n// integrator on the advanced path, `shells/README.md §5`) supplies it.\n\nimport type { ReactNode, RefObject } from 'react';\nimport { useContext, useEffect, useRef, useState } from 'react';\nimport { createPortal } from 'react-dom';\nimport type { KaafilTokenOverrides } from '../../primitives/internal/tokenStyle';\n// `src/core/shells/**` importing from `src/primitives/internal/**` is a new\n// cross-layer direction (U-019 §\"the shells matter most\" build note) — no\n// ESLint boundary rule in `eslint.config.mjs` forbids it: the only\n// import-restriction rules there gate `kaafil-js`/`kaafil-js/client` and\n// internal barrel imports, neither of which this touches.\nimport { tokenStyle } from '../../primitives/internal/tokenStyle';\nimport { isDevelopment } from '../internal/isDevelopment';\nimport { ThemeAttributesContext } from './internal/themeAttributes';\n\nexport type AppShellFamily = 'admin' | 'manager' | 'traveller';\nexport type AppShellFrame = 'desk' | 'field' | 'document';\n\nconst FAMILY_DEFAULT_FRAME: Readonly<Record<AppShellFamily, AppShellFrame>> = {\n admin: 'desk',\n manager: 'field',\n traveller: 'document',\n};\n\n// Build-time value per `05-theming-and-branding.md §4.4` (\"the exact figure\n// is a build-time value, not fixed here\") — this is a placeholder threshold\n// until that value is fixed; only the dev-only warning below depends on it,\n// never a layout decision.\nconst DESK_MINIMUM_CONTAINER_WIDTH_PX = 640;\n\nexport interface AppShellProps {\n readonly frame?: AppShellFrame;\n readonly family?: AppShellFamily;\n readonly isolation?: 'scoped' | 'shadow';\n readonly navSlot?: ReactNode;\n readonly actionBarSlot?: ReactNode;\n readonly connectivitySlot?: ReactNode;\n readonly children?: ReactNode;\n /**\n * Per-instance `--kf-*` token overrides (`00-decisions.md` U-019). Layer-3\n * tokens are per component TYPE; this is how one INSTANCE differs from\n * another without restyling every sibling. On a shell this is also the\n * per-SUBTREE scope: custom properties inherit, so tokens set here reach\n * every descendant — including across the shadow-DOM boundary in\n * `isolation=\"shadow\"` mode, since custom-property inheritance follows\n * the flat tree from a shadow host into its shadow root (unlike ordinary\n * selector-based CSS, which does not cross that boundary). `.kf-root`\n * here is either the shadow host itself, or a light-DOM ancestor of it —\n * both cases inherit normally, so `style` lands once, on this outermost\n * node, never needing to be re-applied inside `ShadowIsolationBoundary`.\n */\n readonly style?: KaafilTokenOverrides;\n}\n\n/** Rung 2 of the CSS-isolation ladder (`05-theming-and-branding.md §7`): a\n * real Shadow DOM boundary, with `{children}` portaled into it. Getting the\n * `/styles` stylesheet itself INTO the shadow root (host CSS does not cross\n * a shadow boundary) is a `/styles`-phase concern this shell cannot resolve\n * — flagged in this phase's report, not silently assumed solved here. */\nfunction ShadowIsolationBoundary({\n className,\n children,\n}: {\n readonly className: string;\n readonly children: ReactNode;\n}): ReactNode {\n const hostRef = useRef<HTMLDivElement | null>(null);\n const [shadowContainer, setShadowContainer] = useState<HTMLElement | null>(null);\n\n useEffect(() => {\n const host = hostRef.current;\n if (host === null) {\n return;\n }\n const shadow = host.shadowRoot ?? host.attachShadow({ mode: 'open' });\n let container = shadow.querySelector<HTMLDivElement>('div[data-kf-shadow-content]');\n if (container === null) {\n container = document.createElement('div');\n container.setAttribute('data-kf-shadow-content', '');\n shadow.appendChild(container);\n }\n setShadowContainer(container);\n }, []);\n\n return (\n <div ref={hostRef} className={className} data-kf-isolation=\"shadow\">\n {shadowContainer !== null ? createPortal(children, shadowContainer) : null}\n </div>\n );\n}\n\n/**\n * Warns, once per mount, when a `'desk'` frame's own `.kf-root` is squeezed\n * below the stated minimum (`05-theming-and-branding.md §4.4`) — never\n * auto-swaps the frame; the host chooses `frame=\"field\"` explicitly instead.\n */\nfunction useDeskMinimumWidthWarning(\n rootRef: RefObject<HTMLElement | null>,\n frame: AppShellFrame,\n): void {\n useEffect(() => {\n if (frame !== 'desk' || !isDevelopment() || typeof ResizeObserver === 'undefined') {\n return;\n }\n const node = rootRef.current;\n if (node === null) {\n return;\n }\n let warned = false;\n const observer = new ResizeObserver((entries) => {\n const entry = entries[0];\n if (entry === undefined || warned) {\n return;\n }\n if (entry.contentRect.width < DESK_MINIMUM_CONTAINER_WIDTH_PX) {\n warned = true;\n // biome-ignore lint/suspicious/noConsole: dev-only, gated above by isDevelopment()\n console.warn(\n `kaafil-react-uikit: the 'desk' frame's .kf-root is narrower than the stated minimum ` +\n `container width (05-theming-and-branding.md §4.4). AppShell never auto-swaps frames — ` +\n 'mount the manager family, or pass frame=\"field\" explicitly, for this container.',\n );\n }\n });\n observer.observe(node);\n return () => observer.disconnect();\n }, [rootRef, frame]);\n}\n\n/** A dev-only reminder that the 'field' frame's connectivity region — the\n * single, permanently-visible sync indicator briefing §27.2 requires — was\n * left unfilled. Never a fallback UI; only a named warning. */\nfunction useUnfilledConnectivitySlotWarning(\n frame: AppShellFrame,\n connectivitySlot: ReactNode,\n): void {\n useEffect(() => {\n if (frame === 'field' && connectivitySlot === undefined && isDevelopment()) {\n // biome-ignore lint/suspicious/noConsole: dev-only, gated above by isDevelopment()\n console.warn(\n 'kaafil-react-uikit: AppShell\\'s \"field\" frame has no connectivitySlot filled — the ' +\n 'permanently-visible connectivity/sync region this frame reserves is empty ' +\n '(01-app-shell.md, briefing §27.2).',\n );\n }\n }, [frame, connectivitySlot]);\n}\n\n/**\n * Establishes `.kf-root`, the resolved `frame` shape, the CSS-isolation\n * rung, and the container-query root. Renders unconditionally — never\n * withholds `{children}` behind a loading gate (`shells/README.md §1`).\n */\nexport function AppShell({\n frame,\n family,\n isolation = 'scoped',\n navSlot,\n actionBarSlot,\n connectivitySlot,\n children,\n style,\n}: AppShellProps): ReactNode {\n const themeAttributes = useContext(ThemeAttributesContext);\n const rootRef = useRef<HTMLDivElement | null>(null);\n const resolvedFrame: AppShellFrame =\n frame ?? (family !== undefined ? FAMILY_DEFAULT_FRAME[family] : 'document');\n\n useDeskMinimumWidthWarning(rootRef, resolvedFrame);\n useUnfilledConnectivitySlotWarning(resolvedFrame, connectivitySlot);\n\n const dataAttributes: Record<string, string> = {\n 'data-kf-frame': resolvedFrame,\n };\n if (family !== undefined) {\n dataAttributes['data-kf-family'] = family;\n }\n if (themeAttributes !== null) {\n dataAttributes['data-kf-theme'] = themeAttributes.theme;\n if (themeAttributes.density !== undefined) {\n dataAttributes['data-kf-density'] = themeAttributes.density;\n }\n }\n\n const content = (\n <>\n {resolvedFrame === 'desk' && navSlot !== undefined ? (\n <div className=\"kf-app-shell__nav\">{navSlot}</div>\n ) : null}\n <div className=\"kf-app-shell__content\">{children}</div>\n {resolvedFrame === 'field' && actionBarSlot !== undefined ? (\n <div className=\"kf-app-shell__action-bar\">{actionBarSlot}</div>\n ) : null}\n {resolvedFrame === 'field' && connectivitySlot !== undefined ? (\n <div className=\"kf-app-shell__connectivity\">{connectivitySlot}</div>\n ) : null}\n {/* The single page-level live region `12-accessibility.md §8` places\n \"near AppShell\" — structural, not visual output (`shells/README.md\n §1`'s narrow exception, the same class AppShell's own root gets). */}\n <div className=\"kf-app-shell__live-region\" role=\"status\" aria-live=\"polite\" />\n </>\n );\n\n // NOT `containerType: 'inline-size'` here. `.kf-root` must never declare\n // inline-size containment: `src/styles/base/reset.css`'s \"CONTAINMENT\n // DELIBERATELY NOT DECLARED HERE\" comment measured that containment on\n // `.kf-root` computes its width WITHOUT regard to contents, which\n // collapses to ~0px the instant a host mounts this shell in any\n // shrink-to-fit context (flex item, grid auto track, inline-block,\n // `float`). This was already fixed once by removing it from reset.css;\n // reintroducing it here on `AppShell`'s own root would be the exact same\n // bug a second time. It also stays dead weight here for the same reason\n // reset.css's comment gives: a grep of this tree still finds ZERO\n // `@container` queries, so there is nothing to keep containment for. If\n // that changes, follow reset.css's own instruction — put\n // `container-type: inline-size` on an inner content wrapper whose size is\n // imposed from OUTSIDE by `.kf-root` (e.g. `.kf-app-shell__content`),\n // never back on `.kf-root` itself.\n if (isolation === 'shadow') {\n return (\n <div\n ref={rootRef}\n className=\"kf-root\"\n data-kf-isolation=\"shadow\"\n {...dataAttributes}\n style={tokenStyle(style)}\n >\n <ShadowIsolationBoundary className=\"kf-app-shell__shadow-host\">\n {content}\n </ShadowIsolationBoundary>\n </div>\n );\n }\n\n return (\n <div\n ref={rootRef}\n className=\"kf-root\"\n data-kf-isolation=\"scoped\"\n {...dataAttributes}\n style={tokenStyle(style)}\n >\n {content}\n </div>\n );\n}\n","'use client';\n\n// `shells/04-config-shell.md`. Seventh in the locked mount order\n// (`shells/README.md §2` row 7) — resolves module flags/settings and\n// exposes them through `ConfigContext`'s `resolveSetting` closure\n// (`../internal/contexts.ts`, hooks-phase-owned; `useResolvedSetting()`\n// reads through it, `08-core-hooks.md §1.5`). Never supplies a default for\n// an unresolvable knob — every key absent from `seedConfig` resolves\n// `undefined`, forever, until the host's seed carries it or `⛔ GAP-002`\n// closes (`shells/04-config-shell.md`'s \"Agency settings are unreachable\"\n// section) — this is the ONE thing this shell must never paper over.\n//\n// DISCOVERY (see this phase's report): the capability triple\n// (`useCapability`/`useCapabilities`, `08-core-hooks.md §1.4`) is read by\n// the hooks phase directly off `useKaafilClient()`/`usePersona()`\n// (`../internal/useCapabilityRows.ts`) — it never reads through\n// `ConfigContext` at all. This shell's ONLY concrete wiring responsibility\n// in this build is therefore `resolveSetting`; `refreshOn` is accepted for\n// API completeness against `shells/04-config-shell.md`'s prop table but has\n// no runtime effect here, since capability re-derivation already happens\n// independently inside the hooks phase's own `snapshot.updated` listener.\n\nimport type { ReactNode } from 'react';\nimport { useMemo } from 'react';\nimport { ConfigContext } from '../internal/contexts';\n\n/** A `module.group.key`-keyed document — the shape `seedConfig.tenant`/\n * `seedConfig.agency` each carry (`shells/04-config-shell.md`'s `seedConfig`\n * prop). Not exported from `../types` — this is `ConfigShell`'s own prop\n * shape, not a `08-core-hooks.md`-catalogued type. */\nexport type ConfigDocument = Readonly<Record<string, unknown>>;\n\nexport interface ConfigShellProps {\n readonly seedConfig?: {\n readonly tenant?: ConfigDocument;\n readonly agency?: ConfigDocument;\n };\n /** Accepted, not yet load-bearing — see this file's header DISCOVERY note. */\n readonly refreshOn?: ReadonlyArray<'trip-load' | 'refocus' | 'snapshot-update'>;\n readonly children?: ReactNode;\n}\n\n/**\n * Builds `resolveSetting` over the two rungs of the precedence ladder this\n * package can actually reach today (`shells/04-config-shell.md §\"Agency\n * settings are unreachable\"`) — Agency narrows Tenant, Tenant is the seed's\n * outer rung; neither Kaafil-default nor Partner has a browser-reachable\n * read at all (`⛔ GAP-002`), so this shell does not fabricate either.\n */\nexport function ConfigShell({ seedConfig = {}, children }: ConfigShellProps): ReactNode {\n const value = useMemo(\n () => ({\n resolveSetting<T>(key: `${string}.${string}.${string}`): T | undefined {\n const agencyValue = seedConfig.agency?.[key];\n if (agencyValue !== undefined) {\n return agencyValue as T;\n }\n const tenantValue = seedConfig.tenant?.[key];\n return tenantValue === undefined ? undefined : (tenantValue as T);\n },\n }),\n [seedConfig.agency, seedConfig.tenant],\n );\n\n return <ConfigContext.Provider value={value}>{children}</ConfigContext.Provider>;\n}\n","'use client';\n\n// `shells/08-error-shell.md`. Outermost in the locked mount order\n// (`shells/README.md §2` row 1) — the one shell that must survive any of the\n// other eight failing to initialize, so it depends on none of them. Catches\n// a THROWN render error (never the ordinary hook-state a mutation's own\n// error branch already carries, `07-offline-and-sync.md §6, §10`) and\n// classifies it into exactly three fallback shapes: retryable, parked,\n// isolation (404-shaped, never 403 — briefing anti-pattern #10). Its own\n// fallback renders with hardcoded, minimal styling and copy — it must\n// survive without `ThemeShell`/`I18nShell` context, since either may be the\n// very thing that failed (`shells/README.md §2` row 2's dependency note).\n\nimport type { ReactNode } from 'react';\nimport { Component, Fragment } from 'react';\nimport { classifyError } from '../errors/classify';\n\nexport type ErrorShellClassification = 'retryable' | 'parked' | 'isolation';\n\nexport interface ErrorShellFallbackContext {\n readonly classification: ErrorShellClassification;\n readonly code: string | undefined;\n}\n\nexport interface ErrorShellProps {\n readonly fallbackSlot?: (ctx: ErrorShellFallbackContext) => ReactNode;\n readonly children?: ReactNode;\n}\n\ninterface ErrorShellState {\n readonly caught: { readonly error: unknown } | null;\n readonly retryKey: number;\n}\n\n/**\n * Maps a caught error to one of this shell's three fallback shapes.\n * `classifyError()`'s four `ErrorHandlingPath`s are the master catalog's own\n * axis (`errors/catalog.ts`) — this shell folds them down to its own three,\n * per `shells/08-error-shell.md`'s \"States\" field: `parked`/\n * `UnsatisfiableSchemeError` map straight across; a `RESOURCE_NOT_FOUND`\n * code is always rendered `isolation`-shaped, since isolation is\n * deliberately indistinguishable from genuine absence at this layer\n * (`06-capability-and-personas.md §9`, briefing anti-pattern #10); every\n * other path — including `re-auth`/`surface-to-user`, which ordinarily\n * never reach here as a THROWN error at all — falls to `retryable`, the\n * least assumptive shape for a failure that reached this shell only because\n * it was thrown rather than surfaced through the normal hook path.\n */\nfunction classifyForFallback(error: unknown): ErrorShellFallbackContext {\n const classification = classifyError(error);\n if (classification.code === 'RESOURCE_NOT_FOUND') {\n return { classification: 'isolation', code: classification.code };\n }\n if (classification.path === 'parked' || classification.unsatisfiableScheme) {\n return { classification: 'parked', code: classification.code };\n }\n return { classification: 'retryable', code: classification.code };\n}\n\nconst FALLBACK_STYLE: Record<string, string | number> = {\n fontFamily: 'system-ui, sans-serif',\n padding: '1.5rem',\n border: '1px solid #999',\n borderRadius: '4px',\n color: '#1a1a1a',\n background: '#fff',\n};\n\nfunction DefaultFallback({\n ctx,\n onRetry,\n}: {\n readonly ctx: ErrorShellFallbackContext;\n readonly onRetry: () => void;\n}): ReactNode {\n const role = ctx.classification === 'retryable' ? 'status' : 'alert';\n const ariaLive = ctx.classification === 'retryable' ? 'polite' : 'assertive';\n const message =\n ctx.classification === 'isolation'\n ? 'Not found.'\n : ctx.classification === 'parked'\n ? \"This action can't be completed right now.\"\n : 'Something went wrong.';\n\n return (\n <div style={FALLBACK_STYLE} role={role} aria-live={ariaLive}>\n <p style={{ margin: 0 }}>{message}</p>\n {ctx.classification === 'retryable' ? (\n <button type=\"button\" onClick={onRetry} style={{ marginTop: '0.75rem' }}>\n Try again\n </button>\n ) : null}\n </div>\n );\n}\n\n/**\n * Catches a thrown render error from anything beneath it. Never consumes\n * `ThemeShell`/`I18nShell` context in its own fallback, never retries a\n * `parked`/`isolation` classification, and never offers an admin override\n * for a classified `423`/`402`/`422`.\n */\nexport class ErrorShell extends Component<ErrorShellProps, ErrorShellState> {\n override state: ErrorShellState = { caught: null, retryKey: 0 };\n\n static getDerivedStateFromError(error: unknown): Partial<ErrorShellState> {\n return { caught: { error } };\n }\n\n private handleRetry = (): void => {\n // Only reachable for the `retryable` classification — remounts the\n // subtree via the `retryKey` below, never retries a `parked`/`isolation`\n // classification (briefing anti-pattern #9).\n this.setState((current) => ({ caught: null, retryKey: current.retryKey + 1 }));\n };\n\n override render(): ReactNode {\n if (this.state.caught !== null) {\n const ctx = classifyForFallback(this.state.caught.error);\n if (this.props.fallbackSlot !== undefined) {\n return this.props.fallbackSlot(ctx);\n }\n return <DefaultFallback ctx={ctx} onRetry={this.handleRetry} />;\n }\n // A `Fragment`, not a wrapper `<div>` — this shell renders NO DOM node\n // of its own on the happy path (`shells/README.md §1`); the `key` is\n // what actually remounts the subtree on retry, forwarding `{children}`\n // straight to `ThemeShell` otherwise.\n return <Fragment key={this.state.retryKey}>{this.props.children}</Fragment>;\n }\n}\n","// The seam between `SessionShell` and `OfflineShell` ONLY — never exported\n// outside this directory, and not part of the hooks-phase contract in\n// `../../internal/contexts.ts`.\n//\n// `session.expired`/`share.expired`/`share.revoked` are `OfflineEventMap`\n// entries (`kaafil-js/src/offline/events.ts`, verified) — they exist only\n// once an `OfflineEngine` is open, and `OfflineShell` (row 6 of the locked\n// mount order) is the shell that opens it, nested strictly INSIDE\n// `SessionShell` (row 5). `SessionShell` is nonetheless the shell whose\n// documented job is to fire `onSessionExpired` exactly once for the whole\n// tree (`00-decisions.md` U-014, `shells/02-session-shell.md`) — it owns the\n// once-then-inert LATCH, but has no direct access to the engine that emits\n// the event. This context is the bridge: `SessionShell` provides a single\n// `reportExpired` callback (already de-duplicated), and `OfflineShell` is\n// the one that actually wires `engine.events.on(...)` and calls it, since\n// only `OfflineShell` can see the engine.\n\nimport { createContext } from 'react';\n\n/** `undefined` when `SessionShell` was mounted standalone (the advanced\n * path, `shells/README.md §5`) with no interest in the expiry latch —\n * `OfflineShell` simply skips wiring the bridge in that case, it never\n * throws for a missing bridge the way `useRequiredContext` would for a\n * load-bearing session read. */\nexport const SessionExpiryBridgeContext = createContext<\n ((reason: 'session' | 'share') => void) | undefined\n>(undefined);\n","'use client';\n\n// `shells/03-offline-shell.md`. Sixth in the locked mount order\n// (`shells/README.md §2` row 6) — constructs and owns the single\n// `OfflineEngine` via `client.openOffline(options)`\n// (`kaafil-js/src/client-entry.ts`, verified), so every `/core` hook in\n// `08-core-hooks.md §2`+ has exactly one live engine to read from. Mints no\n// idempotency key itself (that is `engine.enqueue()`'s own job, once,\n// inside `kaafil-js`) and builds no second cache — this shell is wiring,\n// not a mechanism (`07-offline-and-sync.md` owns every offline mechanic;\n// this file only says when the engine that implements them opens/closes).\n//\n// This shell is ALSO where `SessionShell`'s expiry latch\n// (`./internal/sessionExpiryBridge.ts`) gets its real subscription — see\n// `SessionShell.tsx`'s header for why the bridge exists at all.\n\nimport type {\n BlobSource,\n BlobUploader,\n ConflictResolver,\n EntityReader,\n KaafilStorageAdapter,\n OfflineEngine,\n} from 'kaafil-js/client';\nimport type { ReactNode } from 'react';\nimport { useContext, useEffect, useRef, useState } from 'react';\nimport { usePersona } from '../hooks/usePersona';\nimport { useSession } from '../hooks/useSession';\nimport { KaafilClientContext, OfflineEngineContext } from '../internal/contexts';\nimport { SessionExpiryBridgeContext } from './internal/sessionExpiryBridge';\n\nexport interface OfflineShellProps {\n readonly storage: KaafilStorageAdapter;\n readonly blob?: { readonly uploader: BlobUploader; readonly source: BlobSource };\n readonly conflictResolver?: ConflictResolver;\n readonly readEntity?: EntityReader;\n /** Escalation-tier override — see `shells/03-offline-shell.md`'s own\n * warning about two concurrently-open credentials sharing one browser's\n * storage. Defaults to a scope derived from persona + agencyRef, never\n * the credential secret itself. */\n readonly scope?: string;\n readonly children?: ReactNode;\n}\n\n/**\n * Opens the one `OfflineEngine` for the open session's credential, once\n * `SessionShell`'s credential exists — `OpenOfflineOptions` cannot be shaped\n * before that (`shells/README.md §2` row 6's rationale). Closes the previous\n * engine and opens a fresh one on a genuine credential change (a different\n * agency, a re-minted share token); an ordinary silent token rotation never\n * reaches this effect at all (`shells/03-offline-shell.md`'s \"Credential\n * binding and credential change\" section).\n */\nexport function OfflineShell({\n storage,\n blob,\n conflictResolver,\n readEntity,\n scope,\n children,\n}: OfflineShellProps): ReactNode {\n // NOT `useKaafilClient()` (its throwing form) — `SessionShell` renders\n // `{children}` through one initial \"opening\" frame with no\n // `KaafilClientContext.Provider` at all (`SessionShell.tsx`'s own \"this\n // shell renders `{children}` unconditionally throughout\" comment), before\n // its credential-open effect ever runs. This shell is mounted directly\n // inside that render tree (locked mount order, `shells/README.md §2` row\n // 6), so it must tolerate a momentarily-absent client at RENDER time —\n // the effect below already independently gates on `session.status`,\n // which is equally not `'authenticated'` during that same window.\n const client = useContext(KaafilClientContext);\n const persona = usePersona();\n const session = useSession();\n const reportExpired = useContext(SessionExpiryBridgeContext);\n const [engine, setEngine] = useState<OfflineEngine | null>(null);\n const engineRef = useRef<OfflineEngine | null>(null);\n\n const derivedScope = scope ?? `${persona}:${session.agencyRef ?? 'share'}`;\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: storage/conflictResolver/readEntity/blob omitted deliberately — a new engine opens only on a genuine credential change (derivedScope/session.status/persona), never on every re-render of a host passing a fresh-identity callback/adapter each time (shells/03-offline-shell.md's own warning against tearing down an in-flight pull for no reason).\n useEffect(() => {\n // `client === null` and `session.status !== 'authenticated'` are the\n // same \"SessionShell hasn't opened a client yet\" window in practice\n // (its credential-open effect sets both together), but checking both\n // keeps this effect correct even if that ever changes — never a\n // `client!` assertion papering over the render-time optional read above.\n if (session.status !== 'authenticated' || client === null) {\n return;\n }\n const newEngine = client.openOffline({\n storage,\n scope: derivedScope,\n ...(readEntity !== undefined ? { readEntity } : {}),\n ...(conflictResolver !== undefined ? { conflictResolver } : {}),\n ...(blob !== undefined ? { blob } : {}),\n // GAP flagged in this phase's report: a share session's local\n // `expiresAt` enforcement (`OpenOfflineOptions.share`,\n // `07-offline-and-sync.md §8`) needs an `expiresAt` this shell has no\n // source for yet — it is not on `useSession()`'s derived shape and no\n // prop carries it. Omitted here rather than guessed; a share engine\n // opens without the local expiry/grace/purge enforcement until that\n // value has a wire source.\n });\n engineRef.current = newEngine;\n\n // OPEN IT. `openOffline()` only constructs the engine; `open()` is what\n // hydrates every store from the durable adapter and binds the\n // `online`/foreground triggers, and its own docblock says to call it once\n // before first paint. Without it the whole offline lane is inert in a way\n // that looks like it is working:\n //\n // · nothing hydrates, so the outbox's `inflight -> pending` recovery\n // never runs and a write interrupted by a reload stays stuck;\n // · nothing binds `online`, so reconnecting never kicks the drainer and\n // a queued write is never attempted — `attemptCount` stays 0 forever,\n // with no error anywhere, and the write simply never reaches Kaafil.\n //\n // The engine is set into context only AFTER it is open, so no consumer\n // can read a half-initialised one and conclude the outbox is empty.\n // ── WHY THERE ARE TWO FLAGS AND NOT ONE ───────────────────────────────\n //\n // `open()` is ASYNC, and React can tear this effect down before it\n // settles. The previous version closed the engine only `if (opened)`,\n // which is never true at that point — so the engine was simply leaked,\n // still holding its `online`/`visibilitychange` listeners and still\n // bound to the same IndexedDB scope as its replacement.\n //\n // Under `<StrictMode>` — which every React and Next scaffold turns on in\n // development, and which every QA therefore runs — the effect is\n // deliberately double-invoked, so this happened on EVERY mount. Two live\n // engines then shared one outbox key and overwrote each other's persists:\n // one marked an op `inflight`, the other reloaded, re-sent and rescheduled\n // it, and whichever wrote last won. The queue wedged at `status:\n // 'inflight', attemptCount: 0`, which no kick can rescue because a\n // drain pass will not select an op another attempt appears to own.\n //\n // The symptom was a tour leader adding an itinerary block out of signal,\n // getting no error, and finding hours later that it had never reached the\n // server — while the outbox row sat there looking perfectly healthy.\n //\n // So: `disposed` says the effect is gone, `opened` says the engine is\n // real. Between them every engine is closed exactly once, whether `open()`\n // resolves before teardown or long after it.\n let opened = false;\n let disposed = false;\n void newEngine\n .open()\n .then(() => {\n opened = true;\n if (disposed) {\n // Teardown won the race. Close it HERE — this is the only remaining\n // moment anything holds a reference to this engine.\n newEngine.close();\n return;\n }\n if (engineRef.current === newEngine) setEngine(newEngine);\n })\n .catch(() => {\n // A durable store that will not open (private browsing, a locked-down\n // profile) is the storage adapter's own documented failure, and it\n // fails at open precisely so it can be surfaced rather than silently\n // losing work later. Publishing the engine anyway would be the worse\n // outcome: the surfaces would render and quietly drop writes.\n //\n // Nothing to close: `open()` rejected, so no listener was ever bound.\n if (!disposed && engineRef.current === newEngine) setEngine(null);\n });\n\n const unsubscribeSessionExpired =\n persona !== 'share'\n ? newEngine.events.on('session.expired', () => reportExpired?.('session'))\n : undefined;\n const unsubscribeShareExpired =\n persona === 'share'\n ? newEngine.events.on('share.expired', () => reportExpired?.('share'))\n : undefined;\n const unsubscribeShareRevoked =\n persona === 'share'\n ? newEngine.events.on('share.revoked', () => reportExpired?.('share'))\n : undefined;\n\n return () => {\n unsubscribeSessionExpired?.();\n unsubscribeShareExpired?.();\n unsubscribeShareRevoked?.();\n // Set FIRST, so that if `open()` is still in flight the `.then` above\n // sees it and closes the engine itself. Closing here instead would tear\n // down stores mid-hydration; leaving it to nobody — which is what this\n // used to do — leaks a second live engine onto the same outbox.\n disposed = true;\n if (opened) newEngine.close();\n if (engineRef.current === newEngine) {\n engineRef.current = null;\n }\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps -- storage/conflictResolver/readEntity/blob omitted deliberately, same rationale as the biome-ignore above this effect.\n }, [client, derivedScope, session.status, persona, reportExpired]);\n\n return <OfflineEngineContext.Provider value={engine}>{children}</OfflineEngineContext.Provider>;\n}\n","// `shells/02-session-shell.md`'s \"One auth adapter per credential kind, never\n// a shared dispatch\" note: which of `client.session.open()` /\n// `client.admin.open()` `SessionShell` calls is decided by the credential's\n// own signed `kind` claim (`shells/00-kaafil-uikit-provider.md` §Composes,\n// `00-decisions.md` U-003) — never by a `persona`/`kind` prop, since that\n// would be exactly the second source of truth U-003 forbids. This file reads\n// the claim WITHOUT verifying the signature: verification is the engine's job\n// on every subsequent request; this is a client-side DISPATCH decision only,\n// never a trust boundary.\n//\n// ASSUMPTION flagged in this phase's report: the exact literal value of the\n// JWT's `kind` claim for a manager-session token is read from\n// `kaafil-js/src/auth/credentials.ts`'s `CredentialKind.ManagerSession =\n// 'managerSession'` naming convention note (\"agencyAdmin is named after the\n// engine's own JWT kind claim... unlike managerSession, which predates this\n// convention\") — this file accepts both `'managerSession'` and the shorter\n// `'manager'` as aliases for the manager case since the engine (a sibling,\n// out-of-scope repo) was not read to confirm which literal it actually signs.\n\nexport type ManagerOrAgencyAdminKind = 'managerSession' | 'agencyAdmin';\n\nfunction base64UrlDecode(segment: string): string {\n const padded = segment.replace(/-/g, '+').replace(/_/g, '/');\n const withPadding = padded + '='.repeat((4 - (padded.length % 4)) % 4);\n // `atob` is universally available in every browser this package targets\n // (`00-decisions.md` U-006's \"guest in a host page\" — no Node `Buffer`\n // dependency belongs here).\n return atob(withPadding);\n}\n\n/**\n * Reads the unverified `kind` claim off an `accessToken` JWT to decide\n * whether `SessionShell` opens a manager or an agencyAdmin session — the only\n * signal available for this decision, since the provider deliberately\n * exposes no `persona`/`kind` prop (`00-decisions.md` U-003). Throws a named,\n * actionable error for a token this cannot parse or whose claim is not\n * recognised, rather than guessing — this is exactly the \"tokens invalid or\n * already expired at mount\" failure mode `<KaafilSessionProbe/>`\n * (`shells/00-kaafil-uikit-provider.md`) exists to name.\n */\nexport function decodeManagerOrAgencyAdminKind(accessToken: string): ManagerOrAgencyAdminKind {\n const segments = accessToken.split('.');\n const payloadSegment = segments[1];\n if (segments.length !== 3 || payloadSegment === undefined) {\n throw new Error(\n 'SessionShell could not parse \"accessToken\" as a JWT — it does not have the three ' +\n 'dot-separated segments every manager/agencyAdmin session token has.',\n );\n }\n\n let claim: unknown;\n try {\n claim = JSON.parse(base64UrlDecode(payloadSegment));\n } catch {\n throw new Error(\n 'SessionShell could not decode \"accessToken\"\\'s payload segment as JSON — the value ' +\n 'handed to <KaafilUIKitProvider accessToken> is not a well-formed JWT.',\n );\n }\n\n const kind = (claim as { kind?: unknown }).kind;\n if (kind === 'agencyAdmin') {\n return 'agencyAdmin';\n }\n if (kind === 'managerSession' || kind === 'manager') {\n return 'managerSession';\n }\n throw new Error(\n `SessionShell read an unrecognised \"kind\" claim (\"${String(kind)}\") off \"accessToken\" — ` +\n 'expected the manager or agencyAdmin session JWT shape (00-decisions.md U-003).',\n );\n}\n","'use client';\n\n// `shells/02-session-shell.md`. Fifth in the locked mount order\n// (`shells/README.md §2` row 5) — the ONLY place in this package that opens\n// a Kaafil credential. Constructs and opens the one `KaafilClient`\n// (`08-core-hooks.md §1.1`'s \"root, not a consumer\" framing), resolves\n// `persona`, and collapses every terminal expiry into exactly one\n// `onSessionExpired` call for the whole mounted tree (`00-decisions.md`\n// U-014). Never exposes a JWT, a raw token, or which credential kind is\n// structurally active beyond the derived `persona` label (`00-decisions.md`\n// U-003) — never retries a rejected/rotated-out credential.\n//\n// The expiry EVENT itself (`session.expired`/`share.expired`/\n// `share.revoked`) only exists once an `OfflineEngine` is open\n// (`kaafil-js/src/offline/events.ts`) — that engine is `OfflineShell`'s,\n// nested INSIDE this shell. This shell owns the once-then-inert LATCH and\n// the `onSessionExpired` prop; `./internal/sessionExpiryBridge.ts` is how it\n// hands that latch to `OfflineShell`, which is the one that can actually see\n// the engine and wire the real subscription.\n\nimport type { Environment } from 'kaafil-js/client';\nimport { KaafilClient } from 'kaafil-js/client';\nimport type { ReactNode } from 'react';\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport { KaafilClientContext, SessionContext } from '../internal/contexts';\nimport type { Persona, SessionState } from '../types/session.types';\nimport { decodeManagerOrAgencyAdminKind } from './internal/jwtKind';\nimport { SessionExpiryBridgeContext } from './internal/sessionExpiryBridge';\n\n/** Discriminated per `00-decisions.md` U-014/U-003 — passing a `shareToken`\n * alongside `agencyRef` is a compile error, never a shape this shell has to\n * defensively validate at runtime. */\nexport type SessionShellCredential =\n | {\n readonly accessToken: string;\n readonly refreshToken: string;\n readonly agencyRef: string;\n readonly shareToken?: undefined;\n readonly credentialResolver?: undefined;\n }\n | {\n readonly shareToken: string;\n readonly accessToken?: undefined;\n readonly refreshToken?: undefined;\n readonly agencyRef?: undefined;\n readonly credentialResolver?: undefined;\n }\n | {\n readonly credentialResolver: () => Promise<\n { accessToken: string; refreshToken: string; agencyRef: string } | { shareToken: string }\n >;\n readonly accessToken?: undefined;\n readonly refreshToken?: undefined;\n readonly agencyRef?: undefined;\n readonly shareToken?: undefined;\n };\n\nexport type SessionShellProps = SessionShellCredential & {\n readonly environment?: Environment;\n /** Forwarded into `session.open`'s/`admin.open`'s own `onRefresh` field —\n * no-ops silently for a `share` credential, which has no refresh shape\n * (`shells/02-session-shell.md`). */\n readonly onRefresh?: (result: unknown) => void | Promise<void>;\n readonly onSessionExpired?: (credentialKind: Persona) => void;\n readonly children?: ReactNode;\n};\n\ninterface ResolvedCredential {\n readonly kind: Persona;\n readonly accessToken?: string;\n readonly refreshToken?: string;\n readonly agencyRef?: string;\n readonly shareToken?: string;\n}\n\nasync function resolveCredential(props: SessionShellProps): Promise<ResolvedCredential> {\n if (props.credentialResolver !== undefined) {\n const resolved = await props.credentialResolver();\n if ('shareToken' in resolved) {\n return { kind: 'share', shareToken: resolved.shareToken };\n }\n const kind =\n decodeManagerOrAgencyAdminKind(resolved.accessToken) === 'agencyAdmin'\n ? 'agencyAdmin'\n : 'manager';\n return { kind, ...resolved };\n }\n if (props.shareToken !== undefined) {\n return { kind: 'share', shareToken: props.shareToken };\n }\n const kind =\n decodeManagerOrAgencyAdminKind(props.accessToken) === 'agencyAdmin' ? 'agencyAdmin' : 'manager';\n return {\n kind,\n accessToken: props.accessToken,\n refreshToken: props.refreshToken,\n agencyRef: props.agencyRef,\n };\n}\n\n/**\n * Opens the credential the resolved value props imply, exposes\n * `KaafilClientContext`/`SessionContext`, and latches `onSessionExpired` to\n * fire exactly once per terminal expiry — see this file's header for why the\n * actual event subscription happens one shell further in\n * (`./internal/sessionExpiryBridge.ts`). `client.close()` runs on unmount and\n * before any re-open — `KaafilClient` throws `KaafilClientAlreadyOpenError`\n * on a second `open()` without an intervening `close()` (verified,\n * `client-entry.ts`).\n */\nexport function SessionShell(props: SessionShellProps): ReactNode {\n const { environment = 'live', onRefresh, onSessionExpired, children } = props;\n const [state, setState] = useState<{ client: KaafilClient; session: SessionState } | null>(null);\n const expiredCallbackFiredRef = useRef(false);\n const currentPersonaRef = useRef<Persona>('manager');\n\n const reportExpired = useCallback(() => {\n if (expiredCallbackFiredRef.current) {\n return;\n }\n expiredCallbackFiredRef.current = true;\n onSessionExpired?.(currentPersonaRef.current);\n setState((current) =>\n current === null\n ? current\n : { ...current, session: { ...current.session, status: 'expired' } },\n );\n }, [onSessionExpired]);\n\n // The four raw values below (never `credentialResolver`/`onRefresh`, both\n // deliberately excluded) are what this effect re-opens on — a genuine\n // change of the resolved credential's own identity, never on every render\n // of a host passing a fresh-identity closure each time\n // (`shells/02-session-shell.md`'s \"two layers of rotation\" note: silent\n // rotation happens entirely inside `kaafil-js`, never here).\n const accessTokenDep = 'accessToken' in props ? props.accessToken : undefined;\n const refreshTokenDep = 'refreshToken' in props ? props.refreshToken : undefined;\n const agencyRefDep = 'agencyRef' in props ? props.agencyRef : undefined;\n const shareTokenDep = 'shareToken' in props ? props.shareToken : undefined;\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: props/onRefresh omitted deliberately — see the comment above this effect's four dependency variables for why.\n useEffect(() => {\n let cancelled = false;\n const client = new KaafilClient({ environment });\n expiredCallbackFiredRef.current = false;\n\n async function open(): Promise<void> {\n const credential = await resolveCredential(props);\n if (cancelled) {\n return;\n }\n currentPersonaRef.current = credential.kind;\n\n if (credential.kind === 'share') {\n client.share.open({ token: credential.shareToken as string });\n } else if (credential.kind === 'agencyAdmin') {\n client.admin.open({\n accessToken: credential.accessToken as string,\n refreshToken: credential.refreshToken as string,\n agencyRef: credential.agencyRef as string,\n ...(onRefresh !== undefined ? { onRefresh } : {}),\n });\n } else {\n client.session.open({\n accessToken: credential.accessToken as string,\n refreshToken: credential.refreshToken as string,\n agencyRef: credential.agencyRef as string,\n ...(onRefresh !== undefined ? { onRefresh } : {}),\n });\n }\n\n setState({\n client,\n session: {\n status: 'authenticated',\n persona: credential.kind,\n agencyRef: credential.agencyRef,\n environment,\n },\n });\n }\n\n void open();\n\n return () => {\n cancelled = true;\n client.close();\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps -- props/onRefresh omitted deliberately, same rationale as the biome-ignore above this effect.\n }, [environment, accessTokenDep, refreshTokenDep, agencyRefDep, shareTokenDep]);\n\n if (state === null) {\n // `useSession().status === 'opening'` — this shell renders `{children}`\n // unconditionally throughout (`shells/README.md §1`); it is the SESSION\n // context that is briefly absent, not the render tree.\n return (\n <SessionExpiryBridgeContext.Provider value={reportExpired}>\n <SessionContext.Provider\n value={{ status: 'opening', persona: 'manager', agencyRef: undefined, environment }}\n >\n {children}\n </SessionContext.Provider>\n </SessionExpiryBridgeContext.Provider>\n );\n }\n\n return (\n <SessionExpiryBridgeContext.Provider value={reportExpired}>\n <KaafilClientContext.Provider value={state.client}>\n <SessionContext.Provider value={state.session}>{children}</SessionContext.Provider>\n </KaafilClientContext.Provider>\n </SessionExpiryBridgeContext.Provider>\n );\n}\n","'use client';\n\n// `shells/09-telemetry-shell.md`. Innermost in the locked mount order\n// (`shells/README.md §2` row 9) — the single, optional, fire-and-forget\n// `onEvent` sink. Never gates a rendering/mutation decision on the\n// callback's presence or return value; never awaits it; never ships an\n// analytics dependency of its own. Renders `{children}` unconditionally —\n// no wrapper, no visual output of any kind (`shells/README.md §1`).\n\nimport type { ReactNode } from 'react';\nimport { useEffect, useRef } from 'react';\nimport { useServerTime } from '../hooks/useServerTime';\nimport { useSession } from '../hooks/useSession';\n\n/**\n * The discriminated union `09-telemetry-shell.md §\"Event taxonomy\"` owns —\n * every field is an opaque id, an enum, or a count, never PII, never a money\n * amount. This is the type's one home; a new event type is added to this\n * union and to the table in that doc, nowhere else.\n */\nexport type TelemetryEvent =\n | { readonly type: 'session.opened'; readonly timestamp: string; readonly persona: string }\n | { readonly type: 'session.expired'; readonly timestamp: string; readonly persona: string }\n | {\n readonly type: 'capability.darkened';\n readonly timestamp: string;\n readonly capability: string;\n readonly reason: 'mode' | 'data' | 'flag';\n }\n | {\n readonly type: 'sync.drained';\n readonly timestamp: string;\n readonly tripRef: string;\n readonly pending: number;\n }\n | {\n readonly type: 'sync.error';\n readonly timestamp: string;\n readonly tripRef: string;\n readonly pending: number;\n }\n | {\n readonly type: 'outbox.parked';\n readonly timestamp: string;\n readonly opId: string;\n readonly code: string;\n }\n | {\n readonly type: 'conflict.surfaced';\n readonly timestamp: string;\n readonly opId: string;\n }\n | {\n readonly type: 'conflict.resolved';\n readonly timestamp: string;\n readonly opId: string;\n readonly choice?: 'keep-queued' | 'keep-current';\n }\n | {\n readonly type: 'error.caught';\n readonly timestamp: string;\n readonly classification: 'retryable' | 'parked' | 'isolation';\n readonly code: string | undefined;\n }\n | {\n readonly type: 'brand.headStrategyRejected';\n readonly timestamp: string;\n readonly persona: string;\n }\n | {\n readonly type: 'frame.resolved';\n readonly timestamp: string;\n readonly frame: string;\n readonly overridden: boolean;\n };\n\nexport interface TelemetryShellProps {\n readonly onEvent?: (event: TelemetryEvent) => void;\n readonly children?: ReactNode;\n}\n\n/** Never rethrown into `ErrorShell` — a host's own broken analytics code\n * must not be able to break the product observing it. */\nfunction emit(onEvent: ((event: TelemetryEvent) => void) | undefined, event: TelemetryEvent): void {\n if (onEvent === undefined) {\n return;\n }\n try {\n onEvent(event);\n } catch {\n // Swallowed at the call site — see this function's own doc comment.\n }\n}\n\n/**\n * Wires the taxonomy's `session.opened`/`session.expired` rows off\n * `useSession()`'s own status transitions — `useSession()` (hooks phase)\n * already folds the underlying `session.expired`/`share.expired`/\n * `share.revoked` offline events into its returned `status`\n * (`../hooks/useSession.ts`), so watching `status` here is the one signal\n * this shell needs, without a second, competing subscription to the same\n * underlying event. The remaining taxonomy rows\n * (`capability.darkened`/`sync.*`/`outbox.parked`/`conflict.*`/\n * `error.caught`/`brand.headStrategyRejected`/`frame.resolved`) are defined\n * in the `TelemetryEvent` union above (their one home) for the\n * component-authoring phase's composites to emit into this same sink —\n * this shell does not synthesize them itself before the events they\n * describe exist to observe.\n */\nexport function TelemetryShell({ onEvent, children }: TelemetryShellProps): ReactNode {\n const session = useSession();\n const serverTime = useServerTime();\n const previousStatusRef = useRef<string | undefined>(undefined);\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: onEvent/serverTime.now/session.persona omitted deliberately — they are fresh identities every render, and listing them would fire this effect every render instead of only on a status transition, defeating the previousStatusRef guard below.\n useEffect(() => {\n const previousStatus = previousStatusRef.current;\n // `serverTime.sinceLastSync` is `undefined` until the first response\n // carrying `meta.serverTime` has landed — this shell never fabricates a\n // local-clock stand-in (hard rule #6); an event this early is simply\n // not emitted with a timestamp it cannot honestly vouch for.\n if (serverTime.sinceLastSync !== undefined) {\n if (session.status === 'authenticated' && previousStatus !== 'authenticated') {\n emit(onEvent, {\n type: 'session.opened',\n timestamp: serverTime.now(),\n persona: session.persona,\n });\n }\n if (session.status === 'expired' && previousStatus !== 'expired') {\n emit(onEvent, {\n type: 'session.expired',\n timestamp: serverTime.now(),\n persona: session.persona,\n });\n }\n }\n previousStatusRef.current = session.status;\n // eslint-disable-next-line react-hooks/exhaustive-deps -- onEvent/serverTime.now/session.persona omitted deliberately, same rationale as the biome-ignore above this effect.\n }, [session.status, serverTime.sinceLastSync]);\n\n return <>{children}</>;\n}\n","'use client';\n\n// `shells/05-theme-shell.md`. Second-outermost shell — resolves the theme\n// axis (and, per this phase's brief, the density override) into a plain\n// string pair, exposed via `./internal/themeAttributes.ts`'s context for\n// `AppShell` to stamp onto its own root. Never a JS theme object, never a\n// re-render triggered by anything beyond CSS itself; never reads the session\n// or a capability triple (`shells/README.md §3`'s `ThemeShell` forbidden\n// row).\n//\n// FLAGGED DECISION (see this phase's report): `05-theme-shell.md`'s own props\n// table carries only `theme` — density stamping is assigned to this shell by\n// the task brief that commissioned this file, not by that spec doc. Density\n// is exposed through the identical CSS-only mechanism, so it travels with\n// theme through the same context rather than inventing a tenth shell for one\n// attribute.\n\nimport type { ReactNode } from 'react';\nimport { useEffect, useMemo, useState } from 'react';\nimport { ThemeAttributesContext } from './internal/themeAttributes';\n\nexport interface ThemeShellProps {\n readonly theme?: 'light' | 'dark' | 'system';\n readonly density?: 'compact' | 'default' | 'comfortable';\n readonly children?: ReactNode;\n}\n\nfunction resolveSystemTheme(): 'light' | 'dark' {\n if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') {\n // No `matchMedia` (SSR, a non-browser test harness) — 'light' is the\n // base :root token set `data-kf-theme=\"dark\"` re-points FROM\n // (`05-theming-and-branding.md §5`).\n return 'light';\n }\n return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';\n}\n\n/**\n * Resolves theme/density synchronously, during render — not behind a\n * `useEffect`, so there is no theme-loading flash for a descendant to\n * observe (`05-theme-shell.md`'s \"no theme-loading state\" contract). Only\n * `theme=\"system\"` needs a live subscription, to follow the OS preference\n * across a change while mounted; an explicit `\"light\"`/`\"dark\"` is used\n * immediately and never touches `matchMedia` at all.\n */\nexport function ThemeShell({ theme = 'system', density, children }: ThemeShellProps): ReactNode {\n const [systemTheme, setSystemTheme] = useState<'light' | 'dark'>(() =>\n theme === 'system' ? resolveSystemTheme() : theme,\n );\n\n useEffect(() => {\n if (\n theme !== 'system' ||\n typeof window === 'undefined' ||\n typeof window.matchMedia !== 'function'\n ) {\n return;\n }\n const query = window.matchMedia('(prefers-color-scheme: dark)');\n const listener = (event: MediaQueryListEvent): void => {\n setSystemTheme(event.matches ? 'dark' : 'light');\n };\n query.addEventListener('change', listener);\n return () => query.removeEventListener('change', listener);\n }, [theme]);\n\n const resolvedTheme = theme === 'system' ? systemTheme : theme;\n const value = useMemo(() => ({ theme: resolvedTheme, density }), [resolvedTheme, density]);\n\n return (\n <ThemeAttributesContext.Provider value={value}>{children}</ThemeAttributesContext.Provider>\n );\n}\n","'use client';\n\n// `shells/00-kaafil-uikit-provider.md`. The composed root — the nine shells\n// of `shells/README.md §2`, pre-nested in their locked mount order, exposed\n// as one component. An integrator mounting this never needs to know a\n// shell name (`shells/README.md §4`).\n//\n// FLAGGED GAP (see this phase's report): `OfflineShell`'s `storage` prop is\n// REQUIRED with no default — \"the SDK deliberately refuses to choose a\n// storage adapter on the host's behalf\" (`shells/03-offline-shell.md`) — yet\n// `shells/00-kaafil-uikit-provider.md`'s own prop table names NO offline\n// prop at all. Since the locked mount order composes `OfflineShell`\n// unconditionally (row 6) but this provider cannot construct its required\n// prop out of nothing, `storage` (and `blob`/`conflictResolver`/\n// `readEntity`/`scope`) are added here as optional pass-throughs, absent\n// from the spec's own provider prop table. When `storage` is omitted,\n// `OfflineShell` is not mounted at all — never a guessed adapter — and every\n// `/core` hook that needs an engine throws its ordinary \"outside the\n// provider tree\" error, which is the honest state when no engine exists.\n// The same treatment applies to `ConfigShell`'s `seedConfig`/`refreshOn`,\n// undocumented at this level for the same reason.\n\nimport type {\n BlobSource,\n BlobUploader,\n ConflictResolver,\n EntityReader,\n Environment,\n KaafilStorageAdapter,\n} from 'kaafil-js/client';\nimport type { ReactNode } from 'react';\nimport { createContext, useContext } from 'react';\nimport { AppShell } from '../shells/AppShell';\nimport type { KaafilBrandAssets } from '../shells/BrandShell';\nimport { BrandShell } from '../shells/BrandShell';\nimport type { ConfigDocument } from '../shells/ConfigShell';\nimport { ConfigShell } from '../shells/ConfigShell';\nimport { ErrorShell } from '../shells/ErrorShell';\nimport { I18nShell } from '../shells/I18nShell';\nimport { OfflineShell } from '../shells/OfflineShell';\nimport type { SessionShellCredential } from '../shells/SessionShell';\nimport { SessionShell } from '../shells/SessionShell';\nimport type { TelemetryEvent } from '../shells/TelemetryShell';\nimport { TelemetryShell } from '../shells/TelemetryShell';\nimport { ThemeShell } from '../shells/ThemeShell';\nimport type { Persona } from '../types/session.types';\n\nexport type KaafilUIKitProviderCredential = SessionShellCredential;\n\n/** `defaultCapabilityViews` (`shells/00-kaafil-uikit-provider.md`'s props\n * table) — a tree-wide DEFAULT for the three capability-dark view overrides\n * `04-customization-ladder.md §5.1` defines. No composite exists yet to\n * consume this (component authoring is out of scope for this phase), so\n * this context is the provider's own seam for one to read later; it never\n * changes which of the three treatments applies, only what a composite\n * falls back to rendering when it hasn't set its own same-named prop. */\nexport interface DefaultCapabilityViews {\n readonly modeDarkView?: ReactNode | ((ctx: unknown) => ReactNode);\n readonly dataDarkView?: ReactNode | ((ctx: unknown) => ReactNode);\n readonly flagDarkView?: ReactNode | ((ctx: unknown) => ReactNode);\n}\n\nconst DefaultCapabilityViewsContext = createContext<DefaultCapabilityViews>({});\n\n/** Reads the tree-wide default set by `<KaafilUIKitProvider\n * defaultCapabilityViews>` — `{}` when the provider didn't set one, never a\n * required context (a missing default simply means every composite falls\n * back to its own built-in dark treatment). */\nexport function useDefaultCapabilityViews(): DefaultCapabilityViews {\n return useContext(DefaultCapabilityViewsContext);\n}\n\nexport interface KaafilUIKitProviderProps {\n readonly environment?: Environment;\n readonly onSessionExpired?: (credentialKind: Persona) => void;\n readonly density?: 'compact' | 'default' | 'comfortable';\n readonly theme?: 'light' | 'dark' | 'system';\n readonly brand?: KaafilBrandAssets & { readonly headStrategy?: 'none' | 'own-page' };\n readonly locale?: string;\n readonly isolation?: 'scoped' | 'shadow';\n readonly onEvent?: (event: TelemetryEvent) => void;\n // See this file's header FLAGGED GAP note — undocumented at the spec's\n // provider-prop-table level, necessary for OfflineShell/ConfigShell to\n // function at all.\n readonly storage?: KaafilStorageAdapter;\n readonly blob?: { readonly uploader: BlobUploader; readonly source: BlobSource };\n readonly conflictResolver?: ConflictResolver;\n readonly readEntity?: EntityReader;\n readonly offlineScope?: string;\n readonly seedConfig?: { readonly tenant?: ConfigDocument; readonly agency?: ConfigDocument };\n readonly defaultCapabilityViews?: DefaultCapabilityViews;\n readonly children?: ReactNode;\n}\n\nexport type KaafilUIKitProviderCredentialProps = KaafilUIKitProviderCredential &\n KaafilUIKitProviderProps;\n\n/**\n * Composes `ErrorShell → ThemeShell → I18nShell → AppShell → SessionShell →\n * OfflineShell → ConfigShell → BrandShell → TelemetryShell → {children}`,\n * the locked order (`shells/README.md §2`). No `persona` prop, no `mode`\n * prop, no `sessionEndpoint` — the credential union above is the only way\n * in, as VALUES (`00-decisions.md` U-003, U-014).\n */\nexport function KaafilUIKitProvider(props: KaafilUIKitProviderCredentialProps): ReactNode {\n const {\n environment,\n onSessionExpired,\n density,\n theme,\n brand,\n locale,\n isolation,\n onEvent,\n storage,\n blob,\n conflictResolver,\n readEntity,\n offlineScope,\n seedConfig,\n defaultCapabilityViews,\n children,\n ...credential\n } = props;\n\n const inner = (\n <DefaultCapabilityViewsContext.Provider value={defaultCapabilityViews ?? {}}>\n <ConfigShell seedConfig={seedConfig}>\n <BrandShell\n appName={brand?.appName}\n logo={brand?.logo}\n logoMark={brand?.logoMark}\n favicon={brand?.favicon}\n headStrategy={brand?.headStrategy}\n >\n <TelemetryShell onEvent={onEvent}>{children}</TelemetryShell>\n </BrandShell>\n </ConfigShell>\n </DefaultCapabilityViewsContext.Provider>\n );\n\n return (\n <ErrorShell>\n <ThemeShell theme={theme} density={density}>\n <I18nShell locale={locale}>\n <AppShell isolation={isolation}>\n <SessionShell\n {...(credential as SessionShellCredential)}\n environment={environment}\n onSessionExpired={onSessionExpired}\n >\n {storage !== undefined ? (\n <OfflineShell\n storage={storage}\n blob={blob}\n conflictResolver={conflictResolver}\n readEntity={readEntity}\n scope={offlineScope}\n >\n {inner}\n </OfflineShell>\n ) : (\n inner\n )}\n </SessionShell>\n </AppShell>\n </I18nShell>\n </ThemeShell>\n </ErrorShell>\n );\n}\n","'use client';\n\n// `05-theming-and-branding.md §7`'s \"Host-CSS Compatibility Probe\" — a\n// dev-only component that checks for the eight named host-CSS hazards and\n// reports which are detected, recommending an isolation rung. An\n// integrator drops this into their page during Stage 0/1 instead of\n// debugging a rendering artefact by inspection.\n\nimport type { ReactNode } from 'react';\nimport { useEffect, useState } from 'react';\nimport type { KaafilTokenOverrides } from '../../primitives/internal/tokenStyle';\n// `src/core/shells/**` importing from `src/primitives/internal/**` — see\n// `AppShell.tsx`'s own header note; no ESLint boundary rule forbids it.\nimport { tokenStyle } from '../../primitives/internal/tokenStyle';\nimport { isDevelopment } from '../internal/isDevelopment';\nimport { useKaafilChrome } from './I18nShell';\n\nexport type HostCssHazard =\n | 'global-box-sizing-reset'\n | 'global-button-input-unset'\n | 'tailwind-preflight-after-ours'\n | 'global-margin-padding-reset'\n | 'conflicting-layer-order'\n | 'global-img-max-width'\n | 'host-css-reset-library'\n | 'global-focus-outline-removed';\n\nconst HAZARD_LABELS: Readonly<Record<HostCssHazard, string>> = {\n 'global-box-sizing-reset': \"A global box-sizing reset escapes this widget's scope.\",\n 'global-button-input-unset': 'A global button/input unset rule is active.',\n 'tailwind-preflight-after-ours': \"A Tailwind preflight is loaded after this widget's CSS.\",\n 'global-margin-padding-reset': 'A global margin/padding reset is active.',\n 'conflicting-layer-order': 'A conflicting @layer declaration order was detected.',\n 'global-img-max-width': \"A global img max-width rule fights this widget's media components.\",\n 'host-css-reset-library':\n \"A host-level CSS reset library (e.g. normalize.css) loads after this widget's CSS.\",\n 'global-focus-outline-removed':\n \"A global :focus outline removal defeats this widget's focus-visible ring.\",\n};\n\n/** Synchronous, DOM-measurement-based detection against a throwaway probe\n * element — never a network call, never a heuristic that escalates\n * isolation automatically (`05-theming-and-branding.md §7`: escalation is\n * always the host's own explicit `isolation` choice). */\nfunction detectHazards(): readonly HostCssHazard[] {\n if (typeof document === 'undefined') {\n return [];\n }\n const probe = document.createElement('div');\n probe.setAttribute('data-kf-host-css-probe', '');\n probe.style.position = 'absolute';\n probe.style.visibility = 'hidden';\n probe.style.pointerEvents = 'none';\n document.body.appendChild(probe);\n\n const button = document.createElement('button');\n probe.appendChild(button);\n const img = document.createElement('img');\n probe.appendChild(img);\n const buttonStyle = getComputedStyle(button);\n const imgStyle = getComputedStyle(img);\n const probeStyle = getComputedStyle(probe);\n\n const hazards: HostCssHazard[] = [];\n if (probeStyle.boxSizing !== 'border-box' && probeStyle.boxSizing !== 'content-box') {\n hazards.push('global-box-sizing-reset');\n }\n if (buttonStyle.appearance === 'none' && buttonStyle.border === '0px none') {\n hazards.push('global-button-input-unset');\n }\n if (probeStyle.margin !== '' && probeStyle.margin === '0px' && probeStyle.padding === '0px') {\n hazards.push('global-margin-padding-reset');\n }\n if (imgStyle.maxWidth === '100%') {\n hazards.push('global-img-max-width');\n }\n if (buttonStyle.outlineStyle === 'none') {\n hazards.push('global-focus-outline-removed');\n }\n // `tailwind-preflight-after-ours`, `conflicting-layer-order`, and\n // `host-css-reset-library` need to inspect the host's own stylesheet\n // ORDER relative to this package's `/styles` import, which a DOM\n // measurement inside one probe element cannot observe — flagged as\n // undetected-by-this-build hazards in the report, not silently skipped.\n\n document.body.removeChild(probe);\n return hazards;\n}\n\nexport interface HostCssCompatibilityProbeProps {\n /**\n * Per-instance `--kf-*` token overrides (`00-decisions.md` U-019). Layer-3\n * tokens are per component TYPE; this is how one INSTANCE differs from\n * another without restyling every sibling.\n */\n readonly style?: KaafilTokenOverrides;\n}\n\n/** Dev-only per `05-theming-and-branding.md §7` — a no-op in production,\n * with a dev-only warning at the ONE other place `isDevelopment()` reads\n * false-negatively (a production build accidentally shipping this probe). */\nexport function HostCssCompatibilityProbe({\n style,\n}: HostCssCompatibilityProbeProps = {}): ReactNode {\n const chrome = useKaafilChrome();\n const [hazards, setHazards] = useState<readonly HostCssHazard[] | null>(null);\n\n useEffect(() => {\n if (isDevelopment()) {\n setHazards(detectHazards());\n }\n }, []);\n\n if (!isDevelopment() || hazards === null) {\n return null;\n }\n\n return (\n <div\n style={tokenStyle(style, {\n border: '1px solid #999',\n padding: '0.75rem',\n borderRadius: '4px',\n })}\n >\n <p style={{ margin: 0, fontWeight: 600 }}>{chrome.t('probe.hostCss.title')}</p>\n {hazards.length === 0 ? (\n <p style={{ margin: '0.5rem 0 0' }}>{chrome.t('probe.hostCss.clean')}</p>\n ) : (\n <ul style={{ margin: '0.5rem 0 0' }}>\n {hazards.map((hazard) => (\n <li key={hazard}>{HAZARD_LABELS[hazard]}</li>\n ))}\n </ul>\n )}\n {hazards.length > 0 ? (\n <p style={{ margin: '0.5rem 0 0' }}>\n Recommended: pass <code>isolation="shadow"</code> to <KaafilUIKitProvider>\n (05-theming-and-branding.md §7, rung 2).\n </p>\n ) : null}\n </div>\n );\n}\n","'use client';\n\n// `shells/00-kaafil-uikit-provider.md`'s \"Dev-only diagnostics\" section. NOT\n// part of `KaafilUIKitProvider` itself — an ordinary diagnostic component an\n// integrator mounts as a CHILD, anywhere under the provider, during Stage\n// 0/1 (`01-integration-story.md §8`). Reports one of five named failure\n// modes when red, never a generic \"something failed\" (`shared/\n// 01-system-screens.md`'s `BootError` family).\n\nimport type { ReactNode } from 'react';\nimport type { KaafilTokenOverrides } from '../../primitives/internal/tokenStyle';\n// `src/core/shells/**` importing from `src/primitives/internal/**` — see\n// `AppShell.tsx`'s own header note; no ESLint boundary rule forbids it.\nimport { tokenStyle } from '../../primitives/internal/tokenStyle';\nimport { useSession } from '../hooks/useSession';\nimport { useKaafilChrome } from './I18nShell';\n\nexport interface KaafilSessionProbeProps {\n /** The host's own intended environment — cross-checked against the\n * opened credential's actual `environment` to catch \"wrong environment\"/\n * \"test key on live\" (`shells/00-kaafil-uikit-provider.md`). */\n readonly expectedEnvironment?: 'live' | 'test';\n /**\n * Per-instance `--kf-*` token overrides (`00-decisions.md` U-019). Layer-3\n * tokens are per component TYPE; this is how one INSTANCE differs from\n * another without restyling every sibling.\n */\n readonly style?: KaafilTokenOverrides;\n}\n\n/**\n * When green: a card naming credential kind, environment, and status. When\n * red: names exactly ONE of the five documented failure modes this probe\n * exists to distinguish — this build can only detect the two that are\n * directly readable off `useSession()`'s derived shape (an expired/rejected\n * credential, and an environment mismatch); \"clock skew\" and \"CORS\" need a\n * live network probe this component does not attempt on its own, so they\n * are named here as documented, undetected-by-this-build failure modes\n * rather than silently omitted from the contract.\n */\nexport function KaafilSessionProbe({\n expectedEnvironment,\n style,\n}: KaafilSessionProbeProps): ReactNode {\n const session = useSession();\n const chrome = useKaafilChrome();\n\n if (session.status === 'expired') {\n return (\n <div\n role=\"status\"\n style={tokenStyle(style, {\n border: '1px solid #c00',\n padding: '0.75rem',\n borderRadius: '4px',\n })}\n >\n Tokens invalid or already expired at mount — the values handed to\n <KaafilUIKitProvider> were rejected before a successful open (00-decisions.md U-014).\n </div>\n );\n }\n\n if (\n expectedEnvironment !== undefined &&\n session.status === 'authenticated' &&\n session.environment !== expectedEnvironment\n ) {\n return (\n <div\n role=\"status\"\n style={tokenStyle(style, {\n border: '1px solid #c00',\n padding: '0.75rem',\n borderRadius: '4px',\n })}\n >\n Wrong environment — expected "{expectedEnvironment}" but the opened credential is\n "{session.environment}"\n {session.environment === 'test' && expectedEnvironment === 'live'\n ? ' (test key on live).'\n : '.'}\n </div>\n );\n }\n\n if (session.status === 'opening') {\n return (\n <div role=\"status\" style={tokenStyle(style)}>\n {chrome.t('chrome.loading')}\n </div>\n );\n }\n\n return (\n <div\n style={tokenStyle(style, {\n border: '1px solid #0a0',\n padding: '0.75rem',\n borderRadius: '4px',\n })}\n >\n <p style={{ margin: 0 }}>{chrome.t('probe.session.ok')}</p>\n <dl style={{ margin: '0.5rem 0 0' }}>\n <dt>{chrome.t('probe.session.credentialKind')}</dt>\n <dd>{session.persona}</dd>\n <dt>{chrome.t('probe.session.environment')}</dt>\n <dd>{session.environment}</dd>\n {session.agencyRef !== undefined ? (\n <>\n <dt>{chrome.t('probe.session.agency')}</dt>\n <dd>{session.agencyRef}</dd>\n </>\n ) : null}\n </dl>\n </div>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/core/errors/errors.ts","../../src/core/hooks/useBlobStatus.ts","../../src/core/hooks/useFeedbackNps.ts","../../src/core/hooks/useJourney.ts","../../src/core/hooks/useResolvedSetting.ts","../../src/core/hooks/useSnapshotEntity.ts","../../src/core/hooks/useStaleness.ts","../../src/core/hooks/useTreks.ts","../../src/core/shells/HostCssCompatibilityProbe.tsx","../../src/core/shells/KaafilSessionProbe.tsx"],"names":["useState","useEffect","useCallback","useContext","SyncOpMethod","jsx","jsxs"],"mappings":"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","file":"index.js","sourcesContent":["// Named error classes a /core hook throws (as opposed to `classifyError()`'s\n// classification of an error a hook CAUGHT). `08-core-hooks.md §1.4`'s\n// persona-restriction note is the concrete callsite for `UnsatisfiableSchemeError`\n// re-exported below; every §3 domain hook's still-`NotImplementedError` stub\n// is the callsite for the second.\n\n// Re-exported, not re-implemented: `kaafil-js`'s own `CredentialResolver`\n// already throws this for exactly the case `08-core-hooks.md §1.4` and every\n// §3 domain hook's \"Persona restriction\" paragraph describes (a manager\n// session calling `useVendors().upsert`, a share session calling\n// `useCapability()`, …). Re-exporting it from `/core` — rather than leaving\n// every family to `import { UnsatisfiableSchemeError } from 'kaafil-js/client'`\n// itself — is what lets a composite's `catch` block do\n// `instanceof UnsatisfiableSchemeError` without importing `kaafil-js` outside\n// `src/core/` (hard rule #1).\nexport { UnsatisfiableSchemeError } from 'kaafil-js/client';\n\n/**\n * Thrown by a §3 domain hook that has no implementation yet in this build.\n *\n * Deliberately NOT the same class as `kaafil-js`'s own `KaafilNotImplementedError`\n * (re-exported by `./classify.ts`'s callers via `kaafil-js/client` where\n * needed) — that one models the wire's `501 NOT_IMPLEMENTED` catalog code (a\n * reserved server route, `architecture/10-conventions.md §7`), a fact about\n * the API. This one is a fact about THIS PACKAGE's own build: the hook\n * exists, type-checks, and is importable, but its body has not been\n * authored yet. Naming it differently keeps a composite's `catch` block from\n * ever conflating \"the server hasn't shipped this route\" with \"the UIKit\n * hasn't shipped this hook\" — the two need different user-facing copy and\n * the two need different fixes.\n */\nexport class NotImplementedError extends Error {\n readonly hookName: string;\n readonly specSection: string;\n\n constructor(hookName: string, specSection: string) {\n super(\n `${hookName}() has no implementation in this build yet — see ` +\n `08-core-hooks.md ${specSection} for its full signature and SDK binding.`,\n );\n this.name = 'NotImplementedError';\n // `kaafil-js/src/http/errors.ts`'s classes all do this for the same\n // reason: a downlevel build target can rebuild the prototype chain\n // incorrectly through `super()`, breaking `instanceof` for the one class\n // whose whole purpose is to be caught by name.\n Object.setPrototypeOf(this, NotImplementedError.prototype);\n this.hookName = hookName;\n this.specSection = specSection;\n }\n}\n","'use client';\n\n// `08-core-hooks.md §2.8`. The independent lifecycle of one blob on the blob\n// lane — deliberately never blocking the parent money/form record.\n//\n// SDK MISMATCH (flagged, not papered over — `kaafil-js/src/offline/blob.ts`,\n// verified this session): the catalog's signature promises a five-state\n// union — `'pending' | 'uploading' | 'ready' | 'orphaned' | 'purged'` — plus\n// a `progress: number | undefined` (0..1). The real `BlobLane` exposes a\n// THREE-state `BlobRecord.status` (`'pending' | 'confirmed' | 'parked'`) and\n// no progress field of any kind — there is no partial-byte OR whole-file\n// upload-progress signal anywhere in `BlobRecord`. This hook maps what the\n// SDK actually reports onto the catalog's vocabulary as faithfully as it\n// can (`pending → pending`, `confirmed → ready`, `parked → orphaned`) and\n// hardcodes `progress: undefined` always, rather than inventing a byte\n// counter the SDK does not track. It cannot report `'purged'` at all — that\n// is a server-side FILE retention state (`files.meta()`'s `retentionClass`),\n// never a `BlobRecord.status` value, and polling `files.meta()` from inside\n// a \"thin subscription over the SDK's own OfflineEngine\" hook would be the\n// second-cache anti-pattern `07-offline-and-sync.md §9` forbids. See this\n// worker's final report for the `blocked` entry.\n\nimport { useContext, useState } from 'react';\nimport { OfflineEngineContext } from '../internal/contexts';\nimport { useOfflineEvent } from './useOfflineEvent';\n\nexport interface BlobStatusResult {\n readonly status: 'pending' | 'uploading' | 'ready' | 'orphaned' | 'purged';\n readonly progress: number | undefined;\n}\n\nexport function useBlobStatus(blobId: string): BlobStatusResult {\n // NOT `useOfflineEngine()` (its throwing form) — called from inside a\n // domain hook's unconditional `build()` (`createDomainHook.ts`), including\n // the render(s) before `OfflineShell` has opened an engine. No engine yet\n // reads the same as \"never seen\" below.\n const engine = useContext(OfflineEngineContext);\n const [, forceRefresh] = useState(0);\n\n useOfflineEvent('sync.drained', () => forceRefresh((tick) => tick + 1));\n useOfflineEvent('sync.error', () => forceRefresh((tick) => tick + 1));\n\n const record = engine?.blobs?.all().find((candidate) => candidate.id === blobId);\n\n if (record === undefined) {\n // Never seen (or already pruned after confirming) — the honest read is\n // \"pending\", the same posture `useSnapshotEntity()` takes for a row that\n // has not synced: absence is not evidence of failure.\n return { status: 'pending', progress: undefined };\n }\n\n const status: BlobStatusResult['status'] =\n record.status === 'confirmed'\n ? 'ready'\n : record.status === 'parked'\n ? 'orphaned'\n : record.attemptCount > 0\n ? 'uploading'\n : 'pending';\n\n return { status, progress: undefined };\n}\n","'use client';\n\n// `08-core-hooks.md §3` table, row `useFeedbackNps(scope)`. Primary SDK\n// surface (verified, `kaafil-js/src/resources/feedback-nps.ts`):\n// `feedbackNps.trip` (`managerAuth`, `agencyAdminAuth`, `apiKeyAuth`),\n// `feedbackNps.agency` (`agencyAdminAuth`, `apiKeyAuth` — never a manager\n// alone; agencyRef auto-bound on `KaafilClient`). Read-only by design: the\n// \"designate this form as the feedback survey\" write lives in `forms`, not\n// here. Below `feedback.summary.minResponses` the payload reports\n// `npsScore: null` — \"not enough responses yet\", never a zero.\n//\n// DECISION: no `createDomainHook()` gate — the two scope members\n// (`trip`/`agency`) have DIFFERENT credential sets and neither is a trip\n// capability module in `06-capability-and-personas.md §3`'s sense; a\n// `manager`-session caller of `agency` fails at the credential check\n// (`UnsatisfiableSchemeError`), which is a persona restriction, not a\n// capability darkness treatment. `manager/06-feedback-nps.md`'s own\n// `FeedbackNpsFlow` does its OWN `feedback-nps` capability gate at the\n// composite layer instead (`CapabilityGate` + `useCapability('feedback-nps')`\n// — the same shape every other capability-gated-but-not-domain-hook-gated\n// composite in this tree already uses).\n//\n// READ MODEL — LIVE, NOT CACHE-FIRST, same reasoning as `useCloseout.ts`'s\n// own header: both `feedbackNps.trip`/`feedbackNps.agency` are fully\n// DERIVED rollups recomputed on every read (window state, funnel counts,\n// the NPS bucket split) — there is no per-row `id`/`version` for\n// `extractSectionRows()` to key a delta feed on, and `'feedbackNps'` does\n// not appear in `SYNC_PULL_SECTIONS`. This hook refreshes explicitly rather\n// than subscribing to `snapshot.updated`.\n//\n// WRITE MODEL — the one write this module owns is the dispatch/chase\n// action, and it is NOT `feedbackNps`'s own: `FeedbackNpsResource` is\n// read-only by the SDK's own header comment. The real write is\n// `forms.trip.dispatch` (`kaafil-js/src/resources/forms.ts`,\n// `POST /api/v1/trips/{ref}/forms/{formId}/dispatch`), targeted at the\n// `formId` this same read already resolved — mirrors `useRooming.ts`'s own\n// `engine.enqueue()` recipe (hard-coded `operationId` literal, since\n// `OperationId` is not part of `kaafil-js/client`'s public surface) so the\n// tap is outbox-backed and idempotent exactly like every other manager\n// write in this package, per `manager/06-feedback-nps.md`'s own \"Offline\"\n// note (\"dispatch/chase is an outbox op with a `clientToken`-derived\n// idempotency key — a re-tick or retried tap cannot double-send\").\n//\n// DOUBLE `data.data` NESTING: `feedback-nps.ts`'s own header flags that\n// BOTH response schemas nest a second `data` inside the envelope's own\n// `data` — this hook reads `response.data.configured`/\n// `response.data.definitions`, not `response.configured`/\n// `response.definitions`, and re-exports the inner `data` shape directly so\n// no caller above this hook has to know about the double nesting either.\n\nimport type { DispatchFormOptions, FeedbackNpsResource, OutboxOp } from 'kaafil-js/client';\nimport { SyncOpMethod } from 'kaafil-js/client';\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport { useKaafilClient } from './useKaafilClient';\nimport type { OfflineMutationStatus } from './useOfflineMutation';\nimport { useOfflineMutation } from './useOfflineMutation';\n\nexport type FeedbackNpsScope =\n | { readonly kind: 'trip'; readonly tripRef: string }\n | { readonly kind: 'agency'; readonly agencyRef: string };\n\ntype TripFeedbackSummaryData = Awaited<ReturnType<FeedbackNpsResource['trip']>>['data'];\ntype AgencyFeedbackSummaryData = Awaited<ReturnType<FeedbackNpsResource['agency']>>['data'];\n\n/** The `trip` read's `configured: true` branch, narrowed — every\n * window/funnel/`nps` field a summary panel renders lives only here; the\n * `configured: false` branch carries only `reason`. */\nexport type FeedbackNpsTripSummary = Extract<TripFeedbackSummaryData, { configured: true }>;\n\n/** One row of the `agency` read's `definitions[]` — the agency-wide rollup\n * `manager/06-feedback-nps.md` explicitly leaves to the admin family; kept\n * here only so this one shared hook serves both scopes uniformly. */\nexport type FeedbackNpsAgencyDefinitionRow = AgencyFeedbackSummaryData['definitions'][number];\n\nexport type DispatchFeedbackChaseInput = Omit<\n DispatchFormOptions,\n 'tripRef' | 'formId' | 'idempotencyKey' | 'signal'\n>;\n\nexport interface FeedbackNpsReady {\n readonly kind: FeedbackNpsScope['kind'];\n /** `trip` scope only — the discriminated union verbatim off the wire.\n * `undefined` on `agency` scope, or before the first `trip` fetch has\n * settled (`loaded` distinguishes the two). */\n readonly summary: TripFeedbackSummaryData | undefined;\n /** `agency` scope only — always `[]` on `trip` scope. */\n readonly definitions: readonly FeedbackNpsAgencyDefinitionRow[];\n /** `true` once the first read has settled (success or failure) —\n * distinguishes \"never fetched yet\" from \"fetched, and this trip\n * genuinely has no feedback form configured\" (`CloseoutReady.loaded`'s\n * own contract, reused). */\n readonly loaded: boolean;\n /** `true` when the MOST RECENT fetch threw. `loaded`/`summary`/\n * `definitions` stay whatever they already were. */\n readonly lastFetchFailed: boolean;\n readonly syncedAt: string | undefined;\n readonly refresh: () => Promise<void>;\n /** `trip` scope only. Throws if called before a `configured: true`\n * summary has resolved a `formId` to target — a caller gates the\n * dispatch control on `summary?.configured === true` first exactly as\n * `manager/06-feedback-nps.md`'s own `FeedbackDispatchControls` does. */\n readonly dispatch: (input?: DispatchFeedbackChaseInput) => Promise<OutboxOp>;\n /** The dispatch op's OWN outbox lifecycle (`useOfflineMutation`'s own\n * `status`) — `'parked'`/`'conflicted'` is how a `423`\n * (\"this trip has been closed out\") or a `402` plan-lock surfaces, via\n * `dispatchOp?.parkReason?.userMessage` (`06-feedback-nps.md`'s own\n * `locked (423)`/`parked (402)` States rows). */\n readonly dispatchStatus: OfflineMutationStatus;\n readonly dispatchOp: OutboxOp | undefined;\n}\n\n/**\n * Two scope members, different credential sets, one shared read/refresh\n * shape — see this file's header for why there is no `createDomainHook()`\n * gate. `manager`'s own `FeedbackNpsFlow` only ever calls this with\n * `{ kind: 'trip', tripRef }`; the `agency` branch exists for the admin\n * family's own agency-wide rollup, reusing this same hook rather than a\n * second `useAgencyFeedbackNps()` (hard rule #2).\n */\nexport function useFeedbackNps(scope: FeedbackNpsScope): FeedbackNpsReady {\n const client = useKaafilClient();\n\n const [summary, setSummary] = useState<TripFeedbackSummaryData | undefined>(undefined);\n const [definitions, setDefinitions] = useState<readonly FeedbackNpsAgencyDefinitionRow[]>([]);\n const [loaded, setLoaded] = useState(false);\n const [lastFetchFailed, setLastFetchFailed] = useState(false);\n const [syncedAt, setSyncedAt] = useState<string | undefined>(undefined);\n\n // The dispatch write targets whichever `formId` the most recent `trip`\n // read resolved — a ref rather than a `useOfflineMutation` closure\n // variable so `dispatch` always reads the CURRENT summary even though\n // `useOfflineMutation`'s own `enqueue` is bound once per hook instance.\n const formIdRef = useRef<string | undefined>(undefined);\n\n // `scope` is a fresh object per render on most call sites; the deps array\n // below narrows to its own primitive members instead so this effect\n // doesn't re-fire every render — biome cannot see that `scope.tripRef`/\n // `scope.agencyRef` are each only read inside their own matching\n // `scope.kind` branch, so it flags the ternary as both missing a\n // dependency and carrying an unnecessary one; both reports are spurious.\n // biome-ignore lint/correctness/useExhaustiveDependencies: see comment above.\n const refresh = useCallback(async (): Promise<void> => {\n try {\n if (scope.kind === 'trip') {\n const response = await client.feedbackNps.trip({ tripRef: scope.tripRef });\n setSummary(response.data);\n formIdRef.current = response.data.configured ? response.data.formId : undefined;\n setLoaded(true);\n setLastFetchFailed(false);\n setSyncedAt(response.meta.serverTime);\n } else {\n // `client.feedbackNps` is the BOUND resource (`useKaafilClient()`\n // returns `KaafilClient`, never the raw `kaafil-js` resource) —\n // `agencyRef` is auto-bound on the client per this file's own\n // header, so `BoundReadAgencyFeedbackSummaryOptions` omits it\n // entirely; passing it here would be a type error, not a no-op.\n const response = await client.feedbackNps.agency({});\n setDefinitions(response.data.definitions);\n setLoaded(true);\n setLastFetchFailed(false);\n setSyncedAt(response.meta.serverTime);\n }\n } catch {\n // Honest failure, not a fabricated empty/dark summary — `loaded`\n // stays whatever it already was; only `lastFetchFailed` flips\n // (`CloseoutReady`'s own catch block, reused).\n setLastFetchFailed(true);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps -- `scope.tripRef`/`scope.agencyRef` are each only read inside their own matching `scope.kind` branch above; eslint's static check can't see through the discriminated union, so it flags this ternary as both a missing and a too-complex dependency. `biome check` (this file's other linter) reports the identical false positive for the same reason.\n }, [client, scope.kind, scope.kind === 'trip' ? scope.tripRef : scope.agencyRef]);\n\n useEffect(() => {\n void refresh();\n }, [refresh]);\n\n const dispatchMutation = useOfflineMutation<DispatchFeedbackChaseInput>({\n tripRef: scope.kind === 'trip' ? scope.tripRef : '',\n enqueue: (engine, input) => {\n const formId = formIdRef.current;\n if (formId === undefined || scope.kind !== 'trip') {\n // No configured form to dispatch against yet — the composite gates\n // its dispatch control on `summary?.configured === true` before\n // ever calling this, so reaching here is a caller bug, not a\n // reachable user path; throwing here rather than silently queuing\n // a request with no `formId` keeps that bug loud in dev.\n throw new Error('useFeedbackNps: cannot dispatch before a feedback form is resolved');\n }\n return engine.enqueue({\n tripRef: scope.tripRef,\n method: SyncOpMethod.Post,\n path: `/api/v1/trips/${scope.tripRef}/forms/${formId}/dispatch`,\n // Hardcoded literal, not imported: `OperationId` is not exported\n // from `kaafil-js/client`'s public surface — same convention as\n // `useRooming.ts`'s own `'assignRoomingBed' as never`. Verified\n // against `kaafil-js/src/generated/security.ts`\n // (`OPERATION_SECURITY.dispatchForm`) this session.\n operationId: 'dispatchForm' as never,\n body: input ?? {},\n });\n },\n });\n\n const dispatchMutate = dispatchMutation.mutate;\n const dispatch = useCallback(\n async (input?: DispatchFeedbackChaseInput): Promise<OutboxOp> => {\n const op = await dispatchMutate(input ?? {});\n // A dispatch changes `dispatched`/`completionRate` — re-request the\n // live summary rather than leaving it stale until an unrelated\n // remount (`RoomingReady.assign`'s own `refreshUnassignedPool` call,\n // same reasoning).\n void refresh();\n return op;\n },\n [dispatchMutate, refresh],\n );\n\n return {\n kind: scope.kind,\n summary,\n definitions,\n loaded,\n lastFetchFailed,\n syncedAt,\n refresh,\n dispatch,\n dispatchStatus: dispatchMutation.status,\n dispatchOp: dispatchMutation.op,\n };\n}\n","'use client';\n\n// `08-core-hooks.md §3.2`. Named separately from `useCapability` because it\n// also exposes the journey config surface, not only the resolved\n// capability triple. Wraps `journey.get` (`readJourneyOptions`),\n// `journey.capabilities` (`readJourneyCapabilities`),\n// `journey.capabilities({ live: true })` for `refreshCapabilities()`,\n// `journey.triggers.list`/`.patch` (agencyRef auto-bound on `KaafilClient`).\n// `refreshCapabilities` is a SYNCHRONOUS recompute against live state, never\n// persisted — it does NOT call `journey.rebuild` (`apiKeyAuth`-only, a full\n// async rebuild that persists new stage rows). Persona restriction:\n// `manager`/`agencyAdmin` only.\n//\n// DECISION: the catalog's literal `capabilities: ReturnType<typeof\n// useCapabilities>` cannot mean \"call `useCapabilities()` from inside this\n// hook\" — that hook resolves its trip from the AMBIENT `TripContext`\n// (`08-core-hooks.md §1.4`'s no-`tripRef` signature), which may differ from\n// the EXPLICIT `tripRef` this hook was called with. This hook instead reads\n// `../internal/useCapabilityRows.ts` directly, scoped to its own `tripRef`,\n// and derives the identical `ReadonlyMap<string, CapabilityTriple>` shape —\n// same implementation `useCapabilities()` itself calls, correctly scoped.\n\nimport type { BoundJourneyResource, JourneyResource } from 'kaafil-js/client';\nimport { useCallback, useEffect, useState } from 'react';\nimport { deriveCapabilityTriple } from '../internal/deriveCapabilityTriple';\nimport { isDevelopment } from '../internal/isDevelopment';\nimport { useCapabilityRows } from '../internal/useCapabilityRows';\nimport type { CapabilityTriple } from '../types/capability.types';\nimport { useKaafilClient } from './useKaafilClient';\nimport { usePersona } from './usePersona';\n\n// `JourneyReadResponse` is a LOCAL, non-exported type alias inside\n// `kaafil-js/src/resources/journey.ts` (verified this session) — never\n// re-exported from `kaafil-js/client`. Derived structurally off the one\n// exported resource type instead of restated by hand, so it can never drift\n// from what `journey.get()` actually returns.\ntype JourneyReadResponse = Awaited<ReturnType<JourneyResource['get']>>;\n\nexport interface JourneyResult {\n readonly read: JourneyReadResponse | undefined;\n readonly capabilities: ReadonlyMap<string, CapabilityTriple>;\n readonly refreshCapabilities: () => Promise<void>;\n readonly triggers: {\n list: BoundJourneyResource['triggers']['list'];\n patch: BoundJourneyResource['triggers']['patch'];\n };\n}\n\nexport function useJourney(tripRef: string): JourneyResult {\n const client = useKaafilClient();\n const persona = usePersona();\n const { rows } = useCapabilityRows(tripRef);\n const [read, setRead] = useState<JourneyReadResponse | undefined>(undefined);\n const [liveRows, setLiveRows] = useState<typeof rows | undefined>(undefined);\n\n useEffect(() => {\n if (persona === 'share') {\n if (isDevelopment()) {\n throw new Error(\n 'useJourney() was called from a share session — it is manager/agencyAdmin ' +\n 'only (08-core-hooks.md §3.2).',\n );\n }\n return;\n }\n let cancelled = false;\n void client.journey.get({ tripRef }).then((response) => {\n if (!cancelled) {\n setRead(response);\n }\n });\n return () => {\n cancelled = true;\n };\n }, [client, persona, tripRef]);\n\n const refreshCapabilities = useCallback(async (): Promise<void> => {\n const response = await client.journey.capabilities({ tripRef, live: true });\n setLiveRows(response);\n }, [client, tripRef]);\n\n const effectiveRows = liveRows ?? rows;\n const capabilities = new Map<string, CapabilityTriple>();\n for (const row of effectiveRows) {\n capabilities.set(row.capability, deriveCapabilityTriple(row));\n }\n\n return {\n read,\n capabilities,\n refreshCapabilities,\n triggers: {\n list: (options) => client.journey.triggers.list(options),\n patch: (options) => client.journey.triggers.patch(options),\n },\n };\n}\n","'use client';\n\n// `08-core-hooks.md §1.5`. NO default parameter — enforced in the signature\n// itself, not by convention: there is no second parameter position for a\n// caller to put one in. `06-capability-and-personas.md`'s 5-rung precedence\n// chain is `ConfigShell`'s job (`../internal/contexts.ts`'s `ConfigContext`);\n// this hook is a pure derived read over it, per the catalog's own \"Cleanup:\n// None\" note.\n\nimport { ConfigContext } from '../internal/contexts';\nimport { useRequiredContext } from '../internal/useRequiredContext';\n\n/**\n * Returns the resolved value of `key` (`module.group.key`), or `undefined`\n * when no rung supplied one and there is no frozen default to fall back to.\n * There is no default parameter and none may ever be added (hard rule #5) —\n * a component that needs to render something while this is `undefined`\n * renders a loading/unknown state, never a guessed value.\n */\nexport function useResolvedSetting<T>(key: `${string}.${string}.${string}`): T | undefined {\n const config = useRequiredContext(ConfigContext, 'useResolvedSetting', 'ConfigShell');\n return config.resolveSetting<T>(key);\n}\n","'use client';\n\n// `08-core-hooks.md §2.3`. A single row looked up out of the same snapshot\n// list `useSnapshotList` reads, by id — there is no per-id read in\n// `SnapshotStore` itself, so this is the narrowing convenience the catalog\n// says it is, built on the same list read rather than a second store call.\n\nimport { useContext } from 'react';\nimport { OfflineEngineContext } from '../internal/contexts';\nimport { useSnapshotList } from './useSnapshotList';\n\nexport interface SnapshotEntityResult<TRow> {\n readonly row: TRow | undefined;\n readonly syncedAt: string | undefined;\n}\n\n/**\n * `row` is `undefined` both when the id genuinely doesn't exist and when\n * the list hasn't synced yet — a caller distinguishes those with\n * `syncedAt`: absent entirely means \"never pulled\"; present with `row:\n * undefined` means \"pulled, and this id isn't in it\" (`08-core-hooks.md\n * §2.3`).\n */\nexport function useSnapshotEntity<TRow extends Record<string, unknown>>(\n tripRef: string,\n listName: string,\n id: string,\n): SnapshotEntityResult<TRow> {\n // NOT `useOfflineEngine()` (its throwing form) — same \"runs before\n // OfflineShell opens an engine\" window `useSnapshotList` already tolerates.\n const engine = useContext(OfflineEngineContext);\n const { rows } = useSnapshotList<TRow & { id: string }>(tripRef, listName);\n const row = rows.find((candidate) => candidate.id === id);\n\n // The list-level `syncedAt` `useSnapshotList` derives is the max across\n // every cached row; the narrower \"never pulled\" vs. \"pulled, id absent\"\n // distinction this hook promises needs the ENTITY's own stamp, read\n // straight off the engine both hooks already share one instance of. No\n // engine yet reads the same as \"never pulled\" — `undefined`.\n const syncedAt = engine === null ? undefined : engine.snapshot.syncedAt(tripRef, listName, id);\n\n return { row, syncedAt };\n}\n","'use client';\n\n// `08-core-hooks.md §2.4`. `ageSeconds` from `useServerTime()` minus the\n// list's `syncedAt`; `isStale` past a threshold `ConfigShell` supplies —\n// never a hardcoded UIKit constant (thresholds are a presentation decision\n// left to the composite/theme layer).\n\nimport type { StalenessState } from '../types/offline.types';\nimport { useResolvedSetting } from './useResolvedSetting';\nimport { useServerTime } from './useServerTime';\nimport { useSnapshotList } from './useSnapshotList';\n\n/**\n * DECISION: the catalog names \"a threshold `ConfigShell` supplies\" without\n * naming the resolved-setting key. `stale.thresholdSeconds` is this hook's\n * own choice of key, under the `stale` module namespace — the closest fit to\n * `useResolvedSetting`'s `module.group.key` shape (`08-core-hooks.md §1.5`)\n * for a value that isn't owned by any one of the eighteen domain modules.\n * `isStale` is conservatively `false` (never a guessed threshold) when\n * nothing resolved one — the honest reading of \"no threshold configured\"\n * given `useResolvedSetting()` may never supply its own default (hard rule\n * #5).\n */\nexport function useStaleness(tripRef: string, listName: string): StalenessState {\n const { syncedAt } = useSnapshotList(tripRef, listName);\n const { now } = useServerTime();\n const thresholdSeconds = useResolvedSetting<number>('stale.thresholdSeconds.default');\n\n if (syncedAt === undefined) {\n return { syncedAt: undefined, ageSeconds: undefined, isStale: false };\n }\n\n let ageSeconds: number | undefined;\n try {\n // `useServerTime().now()` throws until a `snapshot.updated` event has\n // landed at least once (see that file's header) — an entity CAN carry a\n // `syncedAt` earlier than that (a drain success rebases from\n // `sync.drained`'s outcome, which does not itself carry `serverTime`\n // on the event `useServerTime` listens to). Falling back to \"unknown\n // age\" here is the honest answer for that narrow window, not a second\n // local-clock guess.\n ageSeconds = (Date.parse(now()) - Date.parse(syncedAt)) / 1000;\n } catch {\n ageSeconds = undefined;\n }\n const isStale =\n ageSeconds !== undefined && thresholdSeconds !== undefined && ageSeconds > thresholdSeconds;\n\n return { syncedAt, ageSeconds, isStale };\n}\n","'use client';\n\n// `08-core-hooks.md §3` table, row `useTreks(tripRef)`. Primary SDK surface\n// (verified, `kaafil-js/src/resources/treks.ts`): `treks.board`,\n// `treks.postpone`, `treks.walkIns.meta`, `treks.walkIns.create`,\n// `treks.walkIns.{list,listPage}`, `treks.walkIns.reconcile`. All six accept\n// `managerAuth`/`apiKeyAuth`/`agencyAdminAuth`; the `trekRef: 'active'`\n// sentinel is refused `422 ACTIVE_REQUIRES_MANAGER` for `apiKey`/\n// `agencyAdmin` on all six. PERSONALIZED mode-dark.\n//\n// NONE OF THIS IS A SNAPSHOT-LIST READ. `08-treks.md`'s own `Offline` rows\n// cite \"cache-first from the snapshot\" for both the board and the walk-in\n// roster, but `SYNC_PULL_SECTIONS` (`kaafil-js/src/offline/pull.ts`,\n// verified) lists exactly `rooming, stayWindows, pickups, seating, bookings,\n// expenses, checklist, float, collections, itinerary, closeout` — no\n// `treks` and no `walkIns` entry. There is no `SnapshotStore` list this hook\n// could subscribe `useSnapshotList` to for either read. Both `board` and\n// `walkIns` below are therefore LIVE, explicitly-refreshed reads — the same\n// shape `useFloat.ts` documents for `summary` (its own derived, uncacheable\n// balance) — refreshed on mount and again after any write that could have\n// changed them, never claimed as offline-cached. This is a genuine gap\n// between the spec's FRD §5 and this build's real SDK plumbing, not an\n// oversight; see this worker's final report.\n//\n// `board`'s `emptyState` (`{ reason: 'no_trek_assigned', message }`) is a\n// normal `200`, not a thrown error (`treks.ts`'s own header) — modelled\n// below as `board.data.emptyState` staying non-null, never surfaced via\n// `lastFetchFailed`.\n//\n// WRITES. `createWalkIn`/`postpone` enqueue via `useOfflineMutation` — the\n// walk-in's minted `travellerId` is stable across the offline→online\n// transition per the SDK's own doc comment, and postpone's ripple/stamps\n// are computed server-side only, matching `08-treks.md`'s own `Offline`\n// rows. `reconcileWalkIn` is exposed too (verified real SDK method, cited\n// by this worker's own task brief: \"walk-ins now support manual\n// reconcile\") even though it is outside `08-treks.md`'s own prop tables —\n// `TrekWalkInRoster` needs a real action for its `needsReconciliation`\n// badge, and inventing a client-side reconciliation would violate\n// `treks.ts`'s own \"matching happens entirely server-side\" framing. It\n// enqueues through the same offline lane as the other two writes for the\n// identical at-least-once/idempotency guarantees.\n\nimport type {\n CreateTrekWalkInOptions,\n OutboxOp,\n PostponeTrekOptions,\n TreksResource,\n} from 'kaafil-js/client';\nimport { SyncOpMethod } from 'kaafil-js/client';\nimport { useCallback, useEffect, useState } from 'react';\nimport { createDomainHook } from '../internal/createDomainHook';\nimport type { DomainHookResult } from '../types/domain.types';\nimport { useKaafilClient } from './useKaafilClient';\nimport { useOfflineMutation } from './useOfflineMutation';\n\n/** `TrekBoardResponse` — verified against `kaafil-js/src/generated/\n * schema.d.ts`. `TreksResource['board']` resolves to `KaafilResponse<\n * TrekBoardResponse>` = `TrekBoardResponse & { meta }` (`kaafil-js/src/\n * types/meta.ts`'s own intersection, not a nested `data` field — unlike\n * `FloatSummaryResponse`/`FloatLedgerResponse`, `TrekBoardResponse` carries\n * `phase`/`stops`/`runningHeadCount`/`emptyState` at its own top level).\n * `phase`/`externalTripId` are `null` only when `emptyState` is set; every\n * other field still comes back with its empty/zero identity rather than\n * being omitted (the schema's own doc comment). */\nexport type TrekBoardData = Awaited<ReturnType<TreksResource['board']>>;\nexport type TrekBoardStop = TrekBoardData['stops'][number];\n\n/** One row of `treks.walkIns.listPage()`'s page — `KaafilPagedResponse<\n * readonly WalkInListItemResponse[]>` = the array itself, `meta` attached\n * (`kaafil-js/src/types/meta.ts`), never a nested `.data`. */\nexport type TrekWalkInRow = Awaited<ReturnType<TreksResource['walkIns']['listPage']>>[number];\n\n/** `WalkInMetaResponse` — the pickup options + field-requirement hints a\n * walk-in intake form reads, verified against the generated schema; same\n * flat (non-`data`-nested) shape as `TrekBoardData`. */\nexport type TrekWalkInMetaData = Awaited<ReturnType<TreksResource['walkIns']['meta']>>;\n\nexport type CreateTrekWalkInInput = Omit<\n CreateTrekWalkInOptions,\n 'trekRef' | 'idempotencyKey' | 'signal'\n>;\nexport type PostponeTrekInput = Omit<PostponeTrekOptions, 'trekRef' | 'idempotencyKey' | 'signal'>;\n/** `ReconcileTrekWalkInOptions` — verified real (`treks.ts`'s own\n * `walkIns.reconcile`) but NOT re-exported from `kaafil-js/client`'s public\n * surface (verified: `client-entry.ts`'s `export type { ... } from\n * './resources/treks'` list omits it, unlike its five siblings). Derived\n * structurally off `TreksResource['walkIns']['reconcile']`'s own parameter\n * rather than importing a name that does not exist on the package's public\n * barrel — see this worker's final report for the exact export gap. */\nexport type ReconcileTrekWalkInInput = Omit<\n Parameters<TreksResource['walkIns']['reconcile']>[0],\n 'trekRef' | 'walkInId' | 'idempotencyKey' | 'signal'\n>;\n\n/**\n * The phase-aware boarding board — a live-fetched, explicitly-refreshed\n * state, never a snapshot subscription. See this file's header for why.\n */\nexport interface TrekBoardState {\n readonly data: TrekBoardData | undefined;\n /** `true` once at least one `client.treks.board()` call has settled\n * (success or failure) — same `loaded` contract `RoomingUnassignedPool`/\n * `useFloat().summary` document. */\n readonly loaded: boolean;\n /** `true` when the MOST RECENT fetch threw — a genuine transport/server\n * failure, distinct from the honest `emptyState` \"no trek assigned\"\n * `200`. */\n readonly lastFetchFailed: boolean;\n readonly fetchedAt: string | undefined;\n readonly refresh: () => Promise<void>;\n}\n\n/** The walk-in roster — live-fetched via `listPage`, one page at a time\n * (`08-treks.md §TrekWalkInRoster`'s own prop table cites `.list`/\n * `.listPage`, never a delta feed). `loadMore` advances the cursor; calling\n * `refresh` resets back to the first page. */\nexport interface TrekWalkInsState {\n readonly rows: readonly TrekWalkInRow[];\n readonly loaded: boolean;\n readonly lastFetchFailed: boolean;\n readonly fetchedAt: string | undefined;\n readonly hasMore: boolean;\n readonly refresh: () => Promise<void>;\n readonly loadMore: () => Promise<void>;\n}\n\nexport interface TrekWalkInMetaState {\n readonly data: TrekWalkInMetaData | undefined;\n readonly loaded: boolean;\n readonly lastFetchFailed: boolean;\n readonly refresh: () => Promise<void>;\n}\n\nexport interface TreksReady {\n readonly board: TrekBoardState;\n readonly walkIns: TrekWalkInsState;\n readonly walkInMeta: TrekWalkInMetaState;\n /** `POST .../walk-ins` — lands `BOARDED` directly for a manager submitter\n * (`D-211`). */\n readonly createWalkIn: (input: CreateTrekWalkInInput) => Promise<OutboxOp>;\n /** `POST .../postpone` — shifts itinerary/stay-window dates server-side;\n * never shifts pickup `scheduledTime`s (`08-treks.md`'s own \"Does NOT\"). */\n readonly postpone: (input: PostponeTrekInput) => Promise<OutboxOp>;\n /** `POST .../walk-ins/{walkInId}/reconcile` — the human fallback for a\n * name-only walk-in the automatic CRM-phone match can't clear on its\n * own. See this file's header for why this is exposed beyond\n * `08-treks.md`'s own prop tables. */\n readonly reconcileWalkIn: (\n walkInId: string,\n input: ReconcileTrekWalkInInput,\n ) => Promise<OutboxOp>;\n}\n\nconst WALK_INS_PAGE_SIZE = 25;\n\nconst useTreksInternal = createDomainHook<TreksReady>('treks', (tripRef) => {\n const client = useKaafilClient();\n\n // ---- board (live) --------------------------------------------------\n const [boardData, setBoardData] = useState<TrekBoardData | undefined>(undefined);\n const [boardLoaded, setBoardLoaded] = useState(false);\n const [boardFetchFailed, setBoardFetchFailed] = useState(false);\n const [boardFetchedAt, setBoardFetchedAt] = useState<string | undefined>(undefined);\n\n const refreshBoard = useCallback(async (): Promise<void> => {\n try {\n const response = await client.treks.board({ trekRef: tripRef });\n setBoardData(response);\n setBoardLoaded(true);\n setBoardFetchFailed(false);\n setBoardFetchedAt(response.meta.serverTime);\n } catch {\n // Honest failure, not a fabricated board — `loaded` stays whatever it\n // already was; only `lastFetchFailed` flips. Same reasoning as\n // `useFloat.ts`'s `refreshSummary`.\n setBoardFetchFailed(true);\n }\n }, [client, tripRef]);\n\n useEffect(() => {\n void refreshBoard();\n }, [refreshBoard]);\n\n // ---- walkIns (live, paginated) --------------------------------------\n const [walkInRows, setWalkInRows] = useState<readonly TrekWalkInRow[]>([]);\n const [walkInsLoaded, setWalkInsLoaded] = useState(false);\n const [walkInsFetchFailed, setWalkInsFetchFailed] = useState(false);\n const [walkInsFetchedAt, setWalkInsFetchedAt] = useState<string | undefined>(undefined);\n const [walkInsCursor, setWalkInsCursor] = useState<string | undefined>(undefined);\n const [walkInsHasNext, setWalkInsHasNext] = useState(false);\n\n const refreshWalkIns = useCallback(async (): Promise<void> => {\n try {\n const page = await client.treks.walkIns.listPage({\n trekRef: tripRef,\n limit: WALK_INS_PAGE_SIZE,\n });\n setWalkInRows(page);\n setWalkInsLoaded(true);\n setWalkInsFetchFailed(false);\n setWalkInsFetchedAt(page.meta.serverTime);\n setWalkInsCursor(page.meta.page.cursor ?? undefined);\n setWalkInsHasNext(page.meta.page.hasNext);\n } catch {\n setWalkInsFetchFailed(true);\n }\n }, [client, tripRef]);\n\n const loadMoreWalkIns = useCallback(async (): Promise<void> => {\n if (walkInsCursor === undefined || !walkInsHasNext) {\n return;\n }\n try {\n const page = await client.treks.walkIns.listPage({\n trekRef: tripRef,\n cursor: walkInsCursor,\n limit: WALK_INS_PAGE_SIZE,\n });\n setWalkInRows((existing) => [...existing, ...page]);\n setWalkInsFetchedAt(page.meta.serverTime);\n setWalkInsCursor(page.meta.page.cursor ?? undefined);\n setWalkInsHasNext(page.meta.page.hasNext);\n } catch {\n setWalkInsFetchFailed(true);\n }\n }, [client, tripRef, walkInsCursor, walkInsHasNext]);\n\n useEffect(() => {\n void refreshWalkIns();\n }, [refreshWalkIns]);\n\n // ---- walkInMeta (live) ------------------------------------------------\n const [metaData, setMetaData] = useState<TrekWalkInMetaData | undefined>(undefined);\n const [metaLoaded, setMetaLoaded] = useState(false);\n const [metaFetchFailed, setMetaFetchFailed] = useState(false);\n\n const refreshMeta = useCallback(async (): Promise<void> => {\n try {\n const response = await client.treks.walkIns.meta({ trekRef: tripRef });\n setMetaData(response);\n setMetaLoaded(true);\n setMetaFetchFailed(false);\n } catch {\n setMetaFetchFailed(true);\n }\n }, [client, tripRef]);\n\n useEffect(() => {\n void refreshMeta();\n }, [refreshMeta]);\n\n // ---- writes -------------------------------------------------------\n const createWalkInMutation = useOfflineMutation<CreateTrekWalkInInput>({\n tripRef,\n enqueue: (engine, input) =>\n engine.enqueue({\n tripRef,\n method: SyncOpMethod.Post,\n path: `/api/v1/treks/${tripRef}/walk-ins`,\n // `OperationId` is not exported from `kaafil-js/client`'s public\n // surface — same documented gap `useFloat.ts`/`useRooming.ts` cast\n // around for their own literal `operationId`s.\n operationId: 'createTrekWalkIn' as never,\n body: input,\n }),\n });\n\n const postponeMutation = useOfflineMutation<PostponeTrekInput>({\n tripRef,\n enqueue: (engine, input) =>\n engine.enqueue({\n tripRef,\n method: SyncOpMethod.Post,\n path: `/api/v1/treks/${tripRef}/postpone`,\n operationId: 'postponeTrek' as never,\n body: input,\n }),\n });\n\n const reconcileMutation = useOfflineMutation<{\n readonly walkInId: string;\n readonly input: ReconcileTrekWalkInInput;\n }>({\n tripRef,\n enqueue: (engine, { walkInId, input }) =>\n engine.enqueue({\n tripRef,\n method: SyncOpMethod.Post,\n path: `/api/v1/treks/${tripRef}/walk-ins/${walkInId}/reconcile`,\n operationId: 'reconcileTrekWalkIn' as never,\n body: input,\n }),\n });\n\n const createWalkInMutate = createWalkInMutation.mutate;\n const createWalkIn = useCallback(\n async (input: CreateTrekWalkInInput): Promise<OutboxOp> => {\n const op = await createWalkInMutate(input);\n // A new walk-in changes both the board's head-count and the roster —\n // re-request both live reads rather than leaving them stale, the\n // same \"re-fetch what a write could have changed\" precedent\n // `useFloat.ts`'s `issue`/`return`/`adjust` document.\n void refreshBoard();\n void refreshWalkIns();\n return op;\n },\n [createWalkInMutate, refreshBoard, refreshWalkIns],\n );\n\n const postponeMutate = postponeMutation.mutate;\n const postpone = useCallback(\n async (input: PostponeTrekInput): Promise<OutboxOp> => {\n const op = await postponeMutate(input);\n void refreshBoard();\n return op;\n },\n [postponeMutate, refreshBoard],\n );\n\n const reconcileMutate = reconcileMutation.mutate;\n const reconcileWalkIn = useCallback(\n async (walkInId: string, input: ReconcileTrekWalkInInput): Promise<OutboxOp> => {\n const op = await reconcileMutate({ walkInId, input });\n void refreshWalkIns();\n return op;\n },\n [reconcileMutate, refreshWalkIns],\n );\n\n return {\n board: {\n data: boardData,\n loaded: boardLoaded,\n lastFetchFailed: boardFetchFailed,\n fetchedAt: boardFetchedAt,\n refresh: refreshBoard,\n },\n walkIns: {\n rows: walkInRows,\n loaded: walkInsLoaded,\n lastFetchFailed: walkInsFetchFailed,\n fetchedAt: walkInsFetchedAt,\n hasMore: walkInsHasNext,\n refresh: refreshWalkIns,\n loadMore: loadMoreWalkIns,\n },\n walkInMeta: {\n data: metaData,\n loaded: metaLoaded,\n lastFetchFailed: metaFetchFailed,\n refresh: refreshMeta,\n },\n createWalkIn,\n postpone,\n reconcileWalkIn,\n };\n});\n\n/**\n * PERSONALIZED mode-dark. Returns `{ status: 'dark', reason }` before any\n * fetch when the `'treks'` capability triple isn't `lit`\n * (`06-capability-and-personas.md §3`).\n */\nexport function useTreks(tripRef: string): DomainHookResult<TreksReady> {\n return useTreksInternal(tripRef);\n}\n","'use client';\n\n// `05-theming-and-branding.md §7`'s \"Host-CSS Compatibility Probe\" — a\n// dev-only component that checks for the eight named host-CSS hazards and\n// reports which are detected, recommending an isolation rung. An\n// integrator drops this into their page during Stage 0/1 instead of\n// debugging a rendering artefact by inspection.\n\nimport type { ReactNode } from 'react';\nimport { useEffect, useState } from 'react';\nimport type { KaafilTokenOverrides } from '../../primitives/internal/tokenStyle';\n// `src/core/shells/**` importing from `src/primitives/internal/**` — see\n// `AppShell.tsx`'s own header note; no ESLint boundary rule forbids it.\nimport { tokenStyle } from '../../primitives/internal/tokenStyle';\nimport { isDevelopment } from '../internal/isDevelopment';\nimport { useKaafilChrome } from './I18nShell';\n\nexport type HostCssHazard =\n | 'global-box-sizing-reset'\n | 'global-button-input-unset'\n | 'tailwind-preflight-after-ours'\n | 'global-margin-padding-reset'\n | 'conflicting-layer-order'\n | 'global-img-max-width'\n | 'host-css-reset-library'\n | 'global-focus-outline-removed';\n\nconst HAZARD_LABELS: Readonly<Record<HostCssHazard, string>> = {\n 'global-box-sizing-reset': \"A global box-sizing reset escapes this widget's scope.\",\n 'global-button-input-unset': 'A global button/input unset rule is active.',\n 'tailwind-preflight-after-ours': \"A Tailwind preflight is loaded after this widget's CSS.\",\n 'global-margin-padding-reset': 'A global margin/padding reset is active.',\n 'conflicting-layer-order': 'A conflicting @layer declaration order was detected.',\n 'global-img-max-width': \"A global img max-width rule fights this widget's media components.\",\n 'host-css-reset-library':\n \"A host-level CSS reset library (e.g. normalize.css) loads after this widget's CSS.\",\n 'global-focus-outline-removed':\n \"A global :focus outline removal defeats this widget's focus-visible ring.\",\n};\n\n/** Synchronous, DOM-measurement-based detection against a throwaway probe\n * element — never a network call, never a heuristic that escalates\n * isolation automatically (`05-theming-and-branding.md §7`: escalation is\n * always the host's own explicit `isolation` choice). */\nfunction detectHazards(): readonly HostCssHazard[] {\n if (typeof document === 'undefined') {\n return [];\n }\n const probe = document.createElement('div');\n probe.setAttribute('data-kf-host-css-probe', '');\n probe.style.position = 'absolute';\n probe.style.visibility = 'hidden';\n probe.style.pointerEvents = 'none';\n document.body.appendChild(probe);\n\n const button = document.createElement('button');\n probe.appendChild(button);\n const img = document.createElement('img');\n probe.appendChild(img);\n const buttonStyle = getComputedStyle(button);\n const imgStyle = getComputedStyle(img);\n const probeStyle = getComputedStyle(probe);\n\n const hazards: HostCssHazard[] = [];\n if (probeStyle.boxSizing !== 'border-box' && probeStyle.boxSizing !== 'content-box') {\n hazards.push('global-box-sizing-reset');\n }\n if (buttonStyle.appearance === 'none' && buttonStyle.border === '0px none') {\n hazards.push('global-button-input-unset');\n }\n if (probeStyle.margin !== '' && probeStyle.margin === '0px' && probeStyle.padding === '0px') {\n hazards.push('global-margin-padding-reset');\n }\n if (imgStyle.maxWidth === '100%') {\n hazards.push('global-img-max-width');\n }\n if (buttonStyle.outlineStyle === 'none') {\n hazards.push('global-focus-outline-removed');\n }\n // `tailwind-preflight-after-ours`, `conflicting-layer-order`, and\n // `host-css-reset-library` need to inspect the host's own stylesheet\n // ORDER relative to this package's `/styles` import, which a DOM\n // measurement inside one probe element cannot observe — flagged as\n // undetected-by-this-build hazards in the report, not silently skipped.\n\n document.body.removeChild(probe);\n return hazards;\n}\n\nexport interface HostCssCompatibilityProbeProps {\n /**\n * Per-instance `--kf-*` token overrides (`00-decisions.md` U-019). Layer-3\n * tokens are per component TYPE; this is how one INSTANCE differs from\n * another without restyling every sibling.\n */\n readonly style?: KaafilTokenOverrides;\n}\n\n/** Dev-only per `05-theming-and-branding.md §7` — a no-op in production,\n * with a dev-only warning at the ONE other place `isDevelopment()` reads\n * false-negatively (a production build accidentally shipping this probe). */\nexport function HostCssCompatibilityProbe({\n style,\n}: HostCssCompatibilityProbeProps = {}): ReactNode {\n const chrome = useKaafilChrome();\n const [hazards, setHazards] = useState<readonly HostCssHazard[] | null>(null);\n\n useEffect(() => {\n if (isDevelopment()) {\n setHazards(detectHazards());\n }\n }, []);\n\n if (!isDevelopment() || hazards === null) {\n return null;\n }\n\n return (\n <div\n style={tokenStyle(style, {\n border: '1px solid #999',\n padding: '0.75rem',\n borderRadius: '4px',\n })}\n >\n <p style={{ margin: 0, fontWeight: 600 }}>{chrome.t('probe.hostCss.title')}</p>\n {hazards.length === 0 ? (\n <p style={{ margin: '0.5rem 0 0' }}>{chrome.t('probe.hostCss.clean')}</p>\n ) : (\n <ul style={{ margin: '0.5rem 0 0' }}>\n {hazards.map((hazard) => (\n <li key={hazard}>{HAZARD_LABELS[hazard]}</li>\n ))}\n </ul>\n )}\n {hazards.length > 0 ? (\n <p style={{ margin: '0.5rem 0 0' }}>\n Recommended: pass <code>isolation="shadow"</code> to <KaafilUIKitProvider>\n (05-theming-and-branding.md §7, rung 2).\n </p>\n ) : null}\n </div>\n );\n}\n","'use client';\n\n// `shells/00-kaafil-uikit-provider.md`'s \"Dev-only diagnostics\" section. NOT\n// part of `KaafilUIKitProvider` itself — an ordinary diagnostic component an\n// integrator mounts as a CHILD, anywhere under the provider, during Stage\n// 0/1 (`01-integration-story.md §8`). Reports one of five named failure\n// modes when red, never a generic \"something failed\" (`shared/\n// 01-system-screens.md`'s `BootError` family).\n\nimport type { ReactNode } from 'react';\nimport type { KaafilTokenOverrides } from '../../primitives/internal/tokenStyle';\n// `src/core/shells/**` importing from `src/primitives/internal/**` — see\n// `AppShell.tsx`'s own header note; no ESLint boundary rule forbids it.\nimport { tokenStyle } from '../../primitives/internal/tokenStyle';\nimport { useSession } from '../hooks/useSession';\nimport { useKaafilChrome } from './I18nShell';\n\nexport interface KaafilSessionProbeProps {\n /** The host's own intended environment — cross-checked against the\n * opened credential's actual `environment` to catch \"wrong environment\"/\n * \"test key on live\" (`shells/00-kaafil-uikit-provider.md`). */\n readonly expectedEnvironment?: 'live' | 'test';\n /**\n * Per-instance `--kf-*` token overrides (`00-decisions.md` U-019). Layer-3\n * tokens are per component TYPE; this is how one INSTANCE differs from\n * another without restyling every sibling.\n */\n readonly style?: KaafilTokenOverrides;\n}\n\n/**\n * When green: a card naming credential kind, environment, and status. When\n * red: names exactly ONE of the five documented failure modes this probe\n * exists to distinguish — this build can only detect the two that are\n * directly readable off `useSession()`'s derived shape (an expired/rejected\n * credential, and an environment mismatch); \"clock skew\" and \"CORS\" need a\n * live network probe this component does not attempt on its own, so they\n * are named here as documented, undetected-by-this-build failure modes\n * rather than silently omitted from the contract.\n */\nexport function KaafilSessionProbe({\n expectedEnvironment,\n style,\n}: KaafilSessionProbeProps): ReactNode {\n const session = useSession();\n const chrome = useKaafilChrome();\n\n if (session.status === 'expired') {\n return (\n <div\n role=\"status\"\n style={tokenStyle(style, {\n border: '1px solid #c00',\n padding: '0.75rem',\n borderRadius: '4px',\n })}\n >\n Tokens invalid or already expired at mount — the values handed to\n <KaafilUIKitProvider> were rejected before a successful open (00-decisions.md U-014).\n </div>\n );\n }\n\n if (\n expectedEnvironment !== undefined &&\n session.status === 'authenticated' &&\n session.environment !== expectedEnvironment\n ) {\n return (\n <div\n role=\"status\"\n style={tokenStyle(style, {\n border: '1px solid #c00',\n padding: '0.75rem',\n borderRadius: '4px',\n })}\n >\n Wrong environment — expected "{expectedEnvironment}" but the opened credential is\n "{session.environment}"\n {session.environment === 'test' && expectedEnvironment === 'live'\n ? ' (test key on live).'\n : '.'}\n </div>\n );\n }\n\n if (session.status === 'opening') {\n return (\n <div role=\"status\" style={tokenStyle(style)}>\n {chrome.t('chrome.loading')}\n </div>\n );\n }\n\n return (\n <div\n style={tokenStyle(style, {\n border: '1px solid #0a0',\n padding: '0.75rem',\n borderRadius: '4px',\n })}\n >\n <p style={{ margin: 0 }}>{chrome.t('probe.session.ok')}</p>\n <dl style={{ margin: '0.5rem 0 0' }}>\n <dt>{chrome.t('probe.session.credentialKind')}</dt>\n <dd>{session.persona}</dd>\n <dt>{chrome.t('probe.session.environment')}</dt>\n <dd>{session.environment}</dd>\n {session.agencyRef !== undefined ? (\n <>\n <dt>{chrome.t('probe.session.agency')}</dt>\n <dd>{session.agencyRef}</dd>\n </>\n ) : null}\n </dl>\n </div>\n );\n}\n"]}
|