kaafil-react-uikit 0.4.1 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/CHANGELOG.md +44 -5
  2. package/dist/admin/index.cjs +355 -353
  3. package/dist/admin/index.cjs.map +1 -1
  4. package/dist/admin/index.js +16 -14
  5. package/dist/admin/index.js.map +1 -1
  6. package/dist/{chunk-EP4VCID7.js → chunk-3E2FN5JJ.js} +3 -3
  7. package/dist/{chunk-EP4VCID7.js.map → chunk-3E2FN5JJ.js.map} +1 -1
  8. package/dist/{chunk-TPBKRXEB.cjs → chunk-3RZDHDEY.cjs} +17 -17
  9. package/dist/{chunk-TPBKRXEB.cjs.map → chunk-3RZDHDEY.cjs.map} +1 -1
  10. package/dist/chunk-62HCQWZL.cjs +12 -0
  11. package/dist/chunk-62HCQWZL.cjs.map +1 -0
  12. package/dist/{chunk-ABWNV4N4.js → chunk-6FUVFVYY.js} +97 -4
  13. package/dist/chunk-6FUVFVYY.js.map +1 -0
  14. package/dist/{chunk-BUE2GJDN.js → chunk-762SWUEG.js} +3 -3
  15. package/dist/{chunk-BUE2GJDN.js.map → chunk-762SWUEG.js.map} +1 -1
  16. package/dist/{chunk-CCJ5XNWY.cjs → chunk-CK3L6Y43.cjs} +98 -2
  17. package/dist/chunk-CK3L6Y43.cjs.map +1 -0
  18. package/dist/{chunk-XBYLSJOS.cjs → chunk-DI77H7ED.cjs} +83 -83
  19. package/dist/{chunk-XBYLSJOS.cjs.map → chunk-DI77H7ED.cjs.map} +1 -1
  20. package/dist/{chunk-5DVTAEQC.js → chunk-EDLIJSMR.js} +5 -5
  21. package/dist/{chunk-5DVTAEQC.js.map → chunk-EDLIJSMR.js.map} +1 -1
  22. package/dist/{chunk-VAJ4D7EF.js → chunk-FEJL6GKJ.js} +513 -20
  23. package/dist/chunk-FEJL6GKJ.js.map +1 -0
  24. package/dist/{chunk-2D4Y4LOT.cjs → chunk-IBVCH6GC.cjs} +553 -51
  25. package/dist/chunk-IBVCH6GC.cjs.map +1 -0
  26. package/dist/{chunk-DABF4PUI.js → chunk-ITGVRN2S.js} +3 -3
  27. package/dist/{chunk-DABF4PUI.js.map → chunk-ITGVRN2S.js.map} +1 -1
  28. package/dist/{chunk-DUZG6A22.cjs → chunk-LO3GQFQ6.cjs} +4 -4
  29. package/dist/{chunk-DUZG6A22.cjs.map → chunk-LO3GQFQ6.cjs.map} +1 -1
  30. package/dist/{chunk-4LZXDRAD.cjs → chunk-QD4Z5DRT.cjs} +12 -12
  31. package/dist/{chunk-4LZXDRAD.cjs.map → chunk-QD4Z5DRT.cjs.map} +1 -1
  32. package/dist/{chunk-TV5QTT44.js → chunk-RW6TJMRK.js} +3 -3
  33. package/dist/{chunk-TV5QTT44.js.map → chunk-RW6TJMRK.js.map} +1 -1
  34. package/dist/chunk-XU7GP53M.js +10 -0
  35. package/dist/chunk-XU7GP53M.js.map +1 -0
  36. package/dist/{chunk-DDSNXKFN.cjs → chunk-XYIOM75D.cjs} +9 -9
  37. package/dist/{chunk-DDSNXKFN.cjs.map → chunk-XYIOM75D.cjs.map} +1 -1
  38. package/dist/core/index.cjs +153 -613
  39. package/dist/core/index.cjs.map +1 -1
  40. package/dist/core/index.d.cts +36 -1
  41. package/dist/core/index.d.ts +36 -1
  42. package/dist/core/index.js +21 -511
  43. package/dist/core/index.js.map +1 -1
  44. package/dist/index.css +1 -1
  45. package/dist/manager/index.cjs +239 -239
  46. package/dist/manager/index.js +6 -6
  47. package/dist/traveller/index.cjs +35 -35
  48. package/dist/traveller/index.js +5 -5
  49. package/package.json +2 -2
  50. package/dist/chunk-2D4Y4LOT.cjs.map +0 -1
  51. package/dist/chunk-2JABR4FF.js +0 -105
  52. package/dist/chunk-2JABR4FF.js.map +0 -1
  53. package/dist/chunk-ABWNV4N4.js.map +0 -1
  54. package/dist/chunk-CCJ5XNWY.cjs.map +0 -1
  55. package/dist/chunk-KDGBJPPZ.cjs +0 -110
  56. package/dist/chunk-KDGBJPPZ.cjs.map +0 -1
  57. package/dist/chunk-VAJ4D7EF.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/hooks/useAgencyAdminMe.ts","../src/core/hooks/useAgencyChecklistTemplates.ts","../src/core/hooks/useAgencyForms.ts","../src/core/hooks/useAgencyJourneyTriggers.ts","../src/core/hooks/useAgencyManagerProfile.ts","../src/core/hooks/useAgencySettings.ts","../src/core/hooks/useAgencyTrip.ts","../src/core/hooks/useAgencyTripManifest.ts","../src/core/hooks/useAgencyTrips.ts","../src/core/hooks/useBookings.ts","../src/core/hooks/useCapabilityStatuses.ts","../src/core/hooks/useDirectories.ts","../src/core/hooks/usePaginatedList.ts","../src/core/hooks/useShareLinks.ts","../src/core/hooks/useTravellerFormResponses.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/routing/deepLinks.ts"],"names":["useKaafilClient","useState","useEffect","useCallback","document","useRef","DEFAULT_PAGE_LIMIT","createDomainHook","useSnapshotList","useOfflineMutation","SyncOpMethod","useCapabilityRows","useMemo","deriveCapabilityTriple","useServerTime","classifyError","createContext","jsx","createPortal","isDevelopment","useContext","jsxs","Fragment","tokenStyle","ConfigContext","Component","KaafilClientContext","usePersona","useSession","OfflineEngineContext","kind","client","KaafilClient","SessionContext","BrandShell","I18nShell"],"mappings":"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","file":"chunk-IBVCH6GC.cjs","sourcesContent":["'use client';\n\n// `useManagerMe.ts`'s exact shape, scoped to the `agencyAdmin` sibling read\n// — `client.agencyAdminMe.read()` (`GET /api/v1/agency-admin/me`, this\n// session's own new engine/SDK addition, mirroring `manager-me` module for\n// module). Unlike `useManagerMe()`, there is no trip list to carry —\n// `AgencyAdmin` has no per-trip assignment table at all, so this hook is\n// identity only: the header/avatar chrome for `KaafilAgencyWorkspace`.\n\nimport type { AgencyAdminMeResponse } from 'kaafil-js/client';\nimport { useEffect, useState } from 'react';\nimport { useKaafilClient } from './useKaafilClient';\n\nexport type { AgencyAdminMeResponse };\n\nexport interface AgencyAdminMeLoading {\n readonly status: 'loading';\n}\n\nexport interface AgencyAdminMeError {\n readonly status: 'error';\n}\n\nexport interface AgencyAdminMeReady {\n readonly status: 'ready';\n readonly agencyAdmin: AgencyAdminMeResponse['agencyAdmin'];\n}\n\nexport type AgencyAdminMeResult = AgencyAdminMeLoading | AgencyAdminMeError | AgencyAdminMeReady;\n\n/**\n * `client.agencyAdminMe.read()` behind a plain fetch-on-mount effect — this\n * read takes no parameter (it resolves entirely off the authenticated\n * principal, `agency-admin-me.routes.ts`'s own header, cited), so it never\n * re-fetches on a prop change. A caller wanting \"refresh now\" re-mounts this\n * hook's owning component.\n */\nexport function useAgencyAdminMe(): AgencyAdminMeResult {\n const client = useKaafilClient();\n const [result, setResult] = useState<AgencyAdminMeResult>({ status: 'loading' });\n\n useEffect(() => {\n let cancelled = false;\n setResult({ status: 'loading' });\n client.agencyAdminMe\n .read()\n .then((response) => {\n if (cancelled) {\n return;\n }\n setResult({ status: 'ready', agencyAdmin: response.agencyAdmin });\n })\n .catch(() => {\n if (!cancelled) {\n setResult({ status: 'error' });\n }\n });\n return () => {\n cancelled = true;\n };\n }, [client]);\n\n return result;\n}\n","'use client';\n\n// The agency-wide checklist template library — `client.checklists\n// .agencyTemplates.{list,create,patch,remove,publish}` (`kaafil-js/src\n// /resources/checklists.ts`, bound agency-ref-free in `client-entry.ts`\n// lines 407-452 — verified directly in source, superseding this SDK's own\n// `useChecklists.ts` header comment claiming `agencyRef` isn't auto-bound).\n// `useChecklists.ts` already types and forwards these five methods\n// (`listAgencyTemplates`/`createAgencyTemplate`/`patchAgencyTemplate`/\n// `removeAgencyTemplate`/`publishAgencyTemplate`) but that hook takes a\n// `tripRef` and is PERSONALIZED mode-dark on a trip-scoped capability —\n// wrong shape for an agency-wide, no-trip-in-context screen\n// (`admin/07-checklists.md`'s `ChecklistTemplateLibrary`/\n// `ChecklistTemplateEditor`/`TemplateAuthoringFlow`, none of which carry a\n// `tripRef` prop). This hook is the real, correctly-shaped entry point\n// those composites use instead — `useAgencyAdminMe()`'s own zero-param\n// shape, with `useVendors.ts`'s list+refresh+CRUD contract.\n//\n// NO CAPABILITY GATE — same reasoning `useAgencyTravellerProfile.ts`/\n// `useAgencyManagerProfile.ts` already document: this is agency\n// configuration data, not a plan-gated module feature, and there is no\n// `tripRef` here to derive a capability triple from in the first place.\n//\n// WRITES ARE PLAIN LIVE CALLS, NEVER OFFLINE-ENQUEUED — agency-scoped\n// authoring, not a trip write; no `tripRef` for an outbox op to key on, the\n// identical posture `useVendors.ts`'s own `upsert`/`remove` document. Every\n// write re-fetches `templates` afterward rather than hand-rolling an\n// optimistic merge — the same discipline `useVendors.ts`/`useChecklists.ts`\n// both already follow.\n\nimport type { KaafilClient } from 'kaafil-js/client';\nimport { useCallback, useEffect, useState } from 'react';\nimport type {\n CreateAgencyChecklistTemplateInput,\n PatchAgencyChecklistTemplateInput,\n PublishAgencyChecklistTemplateInput,\n RemoveAgencyChecklistTemplateInput,\n} from './useChecklists';\nimport { useKaafilClient } from './useKaafilClient';\n\nexport type {\n CreateAgencyChecklistTemplateInput,\n ListAgencyChecklistTemplatesInput,\n PatchAgencyChecklistTemplateInput,\n PublishAgencyChecklistTemplateInput,\n RemoveAgencyChecklistTemplateInput,\n} from './useChecklists';\n\n// `client.checklists.agencyTemplates` — `useChecklists.ts`'s own\n// `BoundAgencyChecklistTemplates` type alias, re-derived here rather than\n// imported (that alias is not exported from `useChecklists.ts`) off the one\n// exported anchor, `KaafilClient` itself.\ntype BoundAgencyChecklistTemplates = KaafilClient['checklists']['agencyTemplates'];\n\n/** `ChecklistTemplateSectionResponse` (`kaafil-js/src/generated\n * /schema.d.ts`) — never imported by name, the same \"derive off the one\n * exported anchor\" discipline `useChecklists.ts` itself documents for this\n * exact resource. */\nexport type ChecklistTemplateRow = Awaited<\n ReturnType<BoundAgencyChecklistTemplates['list']>\n>['templates'][number];\n\nexport type ChecklistTemplateItemRow = ChecklistTemplateRow['items'][number];\n\nexport interface AgencyChecklistTemplatesReady {\n readonly templates: readonly ChecklistTemplateRow[];\n /** `true` once at least one `list()` call has settled (success or\n * failure) — same `loaded` contract every other agency-wide list hook\n * this package ships already uses. */\n readonly loaded: boolean;\n /** `true` when the MOST RECENT fetch threw. */\n readonly lastFetchFailed: boolean;\n readonly refresh: () => Promise<void>;\n readonly createTemplate: (\n input: CreateAgencyChecklistTemplateInput,\n ) => Promise<ChecklistTemplateRow>;\n readonly patchTemplate: (\n input: PatchAgencyChecklistTemplateInput,\n ) => Promise<ChecklistTemplateRow>;\n readonly removeTemplate: (input: RemoveAgencyChecklistTemplateInput) => Promise<void>;\n readonly publishTemplate: (\n input: PublishAgencyChecklistTemplateInput,\n ) => Promise<ChecklistTemplateRow>;\n}\n\nexport function useAgencyChecklistTemplates(): AgencyChecklistTemplatesReady {\n const client = useKaafilClient();\n const [templates, setTemplates] = useState<readonly ChecklistTemplateRow[]>([]);\n const [loaded, setLoaded] = useState(false);\n const [lastFetchFailed, setLastFetchFailed] = useState(false);\n\n const refresh = useCallback(async (): Promise<void> => {\n try {\n const response = await client.checklists.agencyTemplates.list({});\n setTemplates(response.templates);\n setLoaded(true);\n setLastFetchFailed(false);\n } catch {\n setLastFetchFailed(true);\n }\n }, [client]);\n\n useEffect(() => {\n void refresh();\n }, [refresh]);\n\n const createTemplate = useCallback(\n async (input: CreateAgencyChecklistTemplateInput): Promise<ChecklistTemplateRow> => {\n const response = await client.checklists.agencyTemplates.create(input);\n void refresh();\n return response;\n },\n [client, refresh],\n );\n\n const patchTemplate = useCallback(\n async (input: PatchAgencyChecklistTemplateInput): Promise<ChecklistTemplateRow> => {\n const response = await client.checklists.agencyTemplates.patch(input);\n void refresh();\n return response;\n },\n [client, refresh],\n );\n\n const removeTemplate = useCallback(\n async (input: RemoveAgencyChecklistTemplateInput): Promise<void> => {\n await client.checklists.agencyTemplates.remove(input);\n void refresh();\n },\n [client, refresh],\n );\n\n const publishTemplate = useCallback(\n async (input: PublishAgencyChecklistTemplateInput): Promise<ChecklistTemplateRow> => {\n const response = await client.checklists.agencyTemplates.publish(input);\n void refresh();\n return response;\n },\n [client, refresh],\n );\n\n return {\n templates,\n loaded,\n lastFetchFailed,\n refresh,\n createTemplate,\n patchTemplate,\n removeTemplate,\n publishTemplate,\n };\n}\n","'use client';\n\n// The agency-wide form-authoring surface — `client.forms.{create,list,get,\n// patch,delete,archive,unarchive,publish,close,reopen,clone,reorder}` plus\n// `forms.sections.*`/`forms.fields.*`/`forms.bindings.list`\n// (`kaafil-js/src/resources/forms.ts`). `useForms.ts` already types and\n// forwards every one of these (its own \"authoring surface\" section) but\n// that hook takes a `tripRef` and is capability-gated on a trip's `'forms'`\n// row (`createDomainHook`, verified directly this wave) — wrong shape for\n// an agency-wide, no-trip-in-context screen (`admin/05-forms.md`'s\n// `FormsLibrary`/`FormBuilder`, neither of which carry a `tripRef` prop).\n// This hook is the correctly-shaped entry point those composites use\n// instead, the exact same correction `useAgencyChecklistTemplates.ts`\n// already made for its own sibling pair — see that file's own header for\n// the fuller precedent.\n//\n// NO CAPABILITY GATE — same reasoning `useAgencyChecklistTemplates.ts`/\n// `useAgencyTravellerProfile.ts` already document: this is agency\n// configuration data, not a plan-gated module feature, and there is no\n// `tripRef` here to derive a capability triple from in the first place.\n//\n// WRITES ARE PLAIN LIVE CALLS, NEVER OFFLINE-ENQUEUED — agency-scoped\n// authoring, not a trip write; no `tripRef` for an outbox op to key on,\n// `useForms.ts`'s own header gives the identical reasoning for this same\n// resource's writes. Every write re-fetches `forms` afterward rather than\n// hand-rolling an optimistic merge, same discipline as every other\n// agency-wide hook in this file.\n//\n// VERSIONED WRITES — `patch`/`delete` on the form itself, a section, or a\n// field all require the row's current `version` (`forms.ts`'s own header:\n// \"this SDK builds the `If-Match` header itself\"); every `Patch*Input`/\n// `Delete*Input` below carries it, non-optional, matching the wire.\n//\n// `forms.delete` IS REAL (verified directly against `kaafil-js/src/\n// resources/forms.ts` this wave, unlike checklist templates, which only\n// exposes `remove` via `agencyTemplates` — no bare \"delete a form\" analog\n// there) — `FormBuilder`'s own delete affordance should still gate this to\n// `DRAFT`-status forms in the UI as a safety convention (deleting a\n// published form with real responses is a real, sharp edge the wire itself\n// does not prevent), not because the endpoint refuses it.\n//\n// Types below are derived structurally off `KaafilClient['forms']` (the one\n// exported anchor), never by importing the generated schema's request/\n// response names directly — the same discipline `useAgencyChecklistTemplates\n// .ts`'s own header documents for its sibling resource.\n\nimport type { KaafilClient } from 'kaafil-js/client';\nimport { useCallback, useEffect, useState } from 'react';\nimport { useKaafilClient } from './useKaafilClient';\n\ntype BoundForms = KaafilClient['forms'];\n\n/** `FormListResponse.items[]` — the agency's whole catalog (metadata only,\n * no sections/fields). */\nexport type FormRow = Awaited<ReturnType<BoundForms['list']>>['items'][number];\n\n/** `FormDetailResponse` — one form's full definition: metadata + sections +\n * fields. `FormBuilder`'s own read. */\nexport type FormDetailRow = Awaited<ReturnType<BoundForms['get']>>;\n\n/** The patch-transition family's own return shape (`FormDefinitionResponse`\n * — metadata only, no `sections`/`fields`) — `patch`/`archive`/`unarchive`/\n * `publish`/`close`/`reopen`/`clone` all answer this, distinct from\n * `FormDetailRow`, which only `get`/`create` return. */\nexport type FormSummaryRow = Awaited<ReturnType<BoundForms['patch']>>;\n\nexport type FormSectionRow = FormDetailRow['sections'][number];\nexport type FormFieldRow = FormDetailRow['fields'][number];\n\n/** `GET /api/v1/forms/bindings` row — the closed profile/CRM-key catalog a\n * field's `binding` may target. */\nexport type BindingRow = Awaited<ReturnType<BoundForms['bindings']['list']>>['items'][number];\n\nexport type CreateFormInput = Omit<\n Parameters<BoundForms['create']>[0],\n 'idempotencyKey' | 'signal'\n>;\nexport type PatchFormInput = Omit<Parameters<BoundForms['patch']>[0], 'signal'>;\nexport type DeleteFormInput = Omit<Parameters<BoundForms['delete']>[0], 'signal'>;\nexport type CloneFormInput = Omit<Parameters<BoundForms['clone']>[0], 'idempotencyKey' | 'signal'>;\nexport type ReorderFormInput = Omit<Parameters<BoundForms['reorder']>[0], 'signal'>;\nexport type CreateFormSectionInput = Omit<\n Parameters<BoundForms['sections']['create']>[0],\n 'signal'\n>;\nexport type PatchFormSectionInput = Omit<Parameters<BoundForms['sections']['patch']>[0], 'signal'>;\nexport type DeleteFormSectionInput = Omit<\n Parameters<BoundForms['sections']['delete']>[0],\n 'signal'\n>;\nexport type CreateFormFieldInput = Omit<Parameters<BoundForms['fields']['create']>[0], 'signal'>;\nexport type PatchFormFieldInput = Omit<Parameters<BoundForms['fields']['patch']>[0], 'signal'>;\nexport type DeleteFormFieldInput = Omit<Parameters<BoundForms['fields']['delete']>[0], 'signal'>;\n\nexport interface AgencyFormsReady {\n readonly forms: readonly FormRow[];\n /** `true` once at least one `list()` call has settled (success or\n * failure). */\n readonly loaded: boolean;\n /** `true` when the MOST RECENT fetch threw. */\n readonly lastFetchFailed: boolean;\n readonly refresh: () => Promise<void>;\n readonly createForm: (input: CreateFormInput) => Promise<FormDetailRow>;\n /** Live read of one form's full definition — `FormBuilder`'s own load. */\n readonly getForm: (formId: string) => Promise<FormDetailRow>;\n readonly patchForm: (input: PatchFormInput) => Promise<FormSummaryRow>;\n /** See this file's header — real, but UI-gated to `DRAFT` as a safety\n * convention, not a wire restriction. */\n readonly deleteForm: (input: DeleteFormInput) => Promise<void>;\n readonly archiveForm: (formId: string) => Promise<FormSummaryRow>;\n readonly unarchiveForm: (formId: string) => Promise<FormSummaryRow>;\n readonly publishForm: (formId: string) => Promise<FormSummaryRow>;\n readonly closeForm: (formId: string) => Promise<FormSummaryRow>;\n readonly reopenForm: (formId: string) => Promise<FormSummaryRow>;\n readonly cloneForm: (input: CloneFormInput) => Promise<FormSummaryRow>;\n /** One idempotent transaction over every section's and field's\n * `sortOrder` — never one call per row. */\n readonly reorderForm: (input: ReorderFormInput) => Promise<void>;\n readonly createSection: (input: CreateFormSectionInput) => Promise<FormSectionRow>;\n readonly patchSection: (input: PatchFormSectionInput) => Promise<FormSectionRow>;\n readonly deleteSection: (input: DeleteFormSectionInput) => Promise<void>;\n readonly createField: (input: CreateFormFieldInput) => Promise<FormFieldRow>;\n readonly patchField: (input: PatchFormFieldInput) => Promise<FormFieldRow>;\n readonly deleteField: (input: DeleteFormFieldInput) => Promise<void>;\n readonly listBindings: () => Promise<readonly BindingRow[]>;\n}\n\nexport function useAgencyForms(): AgencyFormsReady {\n const client = useKaafilClient();\n const [forms, setForms] = useState<readonly FormRow[]>([]);\n const [loaded, setLoaded] = useState(false);\n const [lastFetchFailed, setLastFetchFailed] = useState(false);\n\n const refresh = useCallback(async (): Promise<void> => {\n try {\n const response = await client.forms.list({});\n setForms(response.items);\n setLoaded(true);\n setLastFetchFailed(false);\n } catch {\n setLastFetchFailed(true);\n }\n }, [client]);\n\n useEffect(() => {\n void refresh();\n }, [refresh]);\n\n const createForm = useCallback(\n async (input: CreateFormInput): Promise<FormDetailRow> => {\n const response = await client.forms.create(input);\n void refresh();\n return response;\n },\n [client, refresh],\n );\n\n const getForm = useCallback(\n async (formId: string): Promise<FormDetailRow> => client.forms.get({ formId }),\n [client],\n );\n\n const patchForm = useCallback(\n async (input: PatchFormInput): Promise<FormSummaryRow> => {\n const response = await client.forms.patch(input);\n void refresh();\n return response;\n },\n [client, refresh],\n );\n\n const deleteForm = useCallback(\n async (input: DeleteFormInput): Promise<void> => {\n await client.forms.delete(input);\n void refresh();\n },\n [client, refresh],\n );\n\n const archiveForm = useCallback(\n async (formId: string): Promise<FormSummaryRow> => {\n const response = await client.forms.archive({ formId });\n void refresh();\n return response;\n },\n [client, refresh],\n );\n\n const unarchiveForm = useCallback(\n async (formId: string): Promise<FormSummaryRow> => {\n const response = await client.forms.unarchive({ formId });\n void refresh();\n return response;\n },\n [client, refresh],\n );\n\n const publishForm = useCallback(\n async (formId: string): Promise<FormSummaryRow> => {\n const response = await client.forms.publish({ formId });\n void refresh();\n return response;\n },\n [client, refresh],\n );\n\n const closeForm = useCallback(\n async (formId: string): Promise<FormSummaryRow> => {\n const response = await client.forms.close({ formId });\n void refresh();\n return response;\n },\n [client, refresh],\n );\n\n const reopenForm = useCallback(\n async (formId: string): Promise<FormSummaryRow> => {\n const response = await client.forms.reopen({ formId });\n void refresh();\n return response;\n },\n [client, refresh],\n );\n\n const cloneForm = useCallback(\n async (input: CloneFormInput): Promise<FormSummaryRow> => {\n const response = await client.forms.clone(input);\n void refresh();\n return response;\n },\n [client, refresh],\n );\n\n const reorderForm = useCallback(\n async (input: ReorderFormInput): Promise<void> => {\n await client.forms.reorder(input);\n },\n [client],\n );\n\n const createSection = useCallback(\n async (input: CreateFormSectionInput): Promise<FormSectionRow> =>\n client.forms.sections.create(input),\n [client],\n );\n\n const patchSection = useCallback(\n async (input: PatchFormSectionInput): Promise<FormSectionRow> =>\n client.forms.sections.patch(input),\n [client],\n );\n\n const deleteSection = useCallback(\n async (input: DeleteFormSectionInput): Promise<void> => {\n await client.forms.sections.delete(input);\n },\n [client],\n );\n\n const createField = useCallback(\n async (input: CreateFormFieldInput): Promise<FormFieldRow> => client.forms.fields.create(input),\n [client],\n );\n\n const patchField = useCallback(\n async (input: PatchFormFieldInput): Promise<FormFieldRow> => client.forms.fields.patch(input),\n [client],\n );\n\n const deleteField = useCallback(\n async (input: DeleteFormFieldInput): Promise<void> => {\n await client.forms.fields.delete(input);\n },\n [client],\n );\n\n const listBindings = useCallback(async (): Promise<readonly BindingRow[]> => {\n const response = await client.forms.bindings.list();\n return response.items;\n }, [client]);\n\n return {\n forms,\n loaded,\n lastFetchFailed,\n refresh,\n createForm,\n getForm,\n patchForm,\n deleteForm,\n archiveForm,\n unarchiveForm,\n publishForm,\n closeForm,\n reopenForm,\n cloneForm,\n reorderForm,\n createSection,\n patchSection,\n deleteSection,\n createField,\n patchField,\n deleteField,\n listBindings,\n };\n}\n","'use client';\n\n// The agency-wide journey trigger catalog — `client.journey.triggers.{list,\n// patch}` (`kaafil-js/src/resources/journey.ts`). `useJourney.ts` already\n// types and forwards these two methods but that hook takes a `tripRef` and\n// is capability-gated on a trip's own capability rows (`createDomainHook`,\n// verified this wave) — wrong shape for an agency-wide, no-trip-in-context\n// screen (`admin/08-journey-orchestration.md`'s own `TriggerTemplateEditor`,\n// which carries no `tripRef` prop). This hook is the correctly-shaped entry\n// point that composite uses instead — the identical correction\n// `useAgencyChecklistTemplates.ts`/`useAgencyForms.ts` already made for their\n// own sibling pairs; see either file's own header for the fuller precedent.\n//\n// NO CAPABILITY GATE — same reasoning those two hooks already document: this\n// is agency configuration data (the trigger CATALOG, not a trip's own\n// journey), and there is no `tripRef` here to derive a capability triple\n// from in the first place.\n//\n// THE CATALOG IS FIXED — `GET`/`PATCH` only, no create/delete on the wire\n// (`journey.ts`'s own `JourneyTriggersResource`). A row's `key`/`module`/\n// `tripMode`/`phase` are identity, set once by the engine's own seed\n// (`journey.constants.ts#JOURNEY_DEFAULT_TRIGGERS`) — only `enabled`/\n// `anchor`/`offsetHours` are ever patchable (`PatchJourneyTriggerRequest`,\n// verified against `kaafil-js/src/generated/schema.d.ts`).\n\nimport type { KaafilClient } from 'kaafil-js/client';\nimport { useCallback, useEffect, useState } from 'react';\nimport { useKaafilClient } from './useKaafilClient';\n\ntype BoundJourneyTriggers = KaafilClient['journey']['triggers'];\n\n/** `JourneyTriggerResponse` — one row of `GET /agencies/{ref}/journey-triggers`. */\nexport type JourneyTriggerRow = Awaited<ReturnType<BoundJourneyTriggers['list']>>[number];\n\nexport type PatchJourneyTriggerInput = Omit<\n Parameters<BoundJourneyTriggers['patch']>[0],\n 'idempotencyKey' | 'signal'\n>;\n\nexport interface AgencyJourneyTriggersReady {\n readonly triggers: readonly JourneyTriggerRow[];\n /** `true` once at least one `list()` call has settled (success or failure). */\n readonly loaded: boolean;\n /** `true` when the MOST RECENT fetch threw. */\n readonly lastFetchFailed: boolean;\n readonly refresh: () => Promise<void>;\n readonly patchTrigger: (input: PatchJourneyTriggerInput) => Promise<JourneyTriggerRow>;\n}\n\nexport function useAgencyJourneyTriggers(): AgencyJourneyTriggersReady {\n const client = useKaafilClient();\n const [triggers, setTriggers] = useState<readonly JourneyTriggerRow[]>([]);\n const [loaded, setLoaded] = useState(false);\n const [lastFetchFailed, setLastFetchFailed] = useState(false);\n\n const refresh = useCallback(async (): Promise<void> => {\n try {\n // `journey.triggers.list` answers `KaafilResponse<readonly\n // JourneyTriggerResponse[]>` — `T & {meta}`, never a `{items: [...]}`\n // envelope the way `forms.list`/`checklists.agencyTemplates.list` do —\n // the response IS the array itself, verified against\n // `kaafil-js/src/resources/journey.ts`'s own return type.\n const response = await client.journey.triggers.list({});\n setTriggers(response);\n setLoaded(true);\n setLastFetchFailed(false);\n } catch {\n setLastFetchFailed(true);\n }\n }, [client]);\n\n useEffect(() => {\n void refresh();\n }, [refresh]);\n\n const patchTrigger = useCallback(\n async (input: PatchJourneyTriggerInput): Promise<JourneyTriggerRow> => {\n const response = await client.journey.triggers.patch(input);\n void refresh();\n return response;\n },\n [client, refresh],\n );\n\n return { triggers, loaded, lastFetchFailed, refresh, patchTrigger };\n}\n","'use client';\n\n// Agency-wide manager profile — `agencies.managers.get`\n// (`kaafil-js/src/resources/agencies.ts`, this session's own new engine+SDK\n// endpoint, mirroring `travellers.getAgencyProfile`/GAP-016 for managers).\n// Mirrors `useAgencyTravellerProfile.ts`'s exact read-side pattern (a single\n// explicit-ref-scoped live GET, not a cache-first list). Identity plus every\n// trip this manager has been assigned to — no lifetime-finance/notes\n// equivalent, since neither exists for a manager (no balance, no\n// `ManagerNote` model).\n//\n// NO CAPABILITY GATE — same reasoning `useAgencyTravellerProfile.ts`\n// documents: a manager profile is roster data, not a plan-gated module\n// feature. NO WRITE HERE — role/lead changes stay trip-scoped\n// (`trips.managers.patch`, `useDirectories().promoteManager`).\n\nimport type { ManagerAgencyProfileResponse } from 'kaafil-js/client';\nimport { useCallback, useEffect, useState } from 'react';\nimport { useKaafilClient } from './useKaafilClient';\n\nexport type { ManagerAgencyProfileResponse };\nexport type ManagerAgencyProfileRead = ManagerAgencyProfileResponse;\n\nexport interface AgencyManagerProfileResult {\n readonly read: ManagerAgencyProfileRead | undefined;\n readonly readFailed: boolean;\n readonly refresh: () => Promise<void>;\n}\n\nexport function useAgencyManagerProfile(managerRef: string): AgencyManagerProfileResult {\n const client = useKaafilClient();\n const [read, setRead] = useState<ManagerAgencyProfileRead | undefined>(undefined);\n const [readFailed, setReadFailed] = useState(false);\n\n const refresh = useCallback(async (): Promise<void> => {\n try {\n const response = await client.agencies.managers.get({ managerRef });\n setRead(response);\n setReadFailed(false);\n } catch {\n setReadFailed(true);\n }\n }, [client, managerRef]);\n\n useEffect(() => {\n void refresh();\n }, [refresh]);\n\n return { read, readFailed, refresh };\n}\n","'use client';\n\n// The agency's own operational settings document — `client.agencies.settings\n// .{get,patch}` (`kaafil-js/src/resources/agencies.ts`, GAP-002, closed via a\n// sibling route, never a widened `consoleAuth` array — see that file's own\n// header). Agency-wide, no `tripRef`, no capability gate — the same\n// reasoning `useAgencyJourneyTriggers.ts`/`useAgencyChecklistTemplates.ts`\n// already document for their own agency-wide screens: this is agency\n// configuration data, not a trip's own state.\n//\n// THE STORED DOCUMENT ONLY, NEVER MERGED WITH DEFAULTS — `AgencySettingsResponse\n// .settings` is `{[key: string]: unknown}` holding exactly the sections/knobs\n// this agency has explicitly set. An absent section or knob means it\n// inherits the Kaafil default — never \"off\"/\"zero\". This hook returns that\n// raw stored document unmodified; it is the caller's job (`AgencySettingsScreen`\n// and its `SectionCard`s) to render \"using the default\" for anything absent,\n// never to substitute a guessed value. Mirrors `useResolvedSetting()`'s own\n// \"no default parameter, ever\" contract from the read side.\n//\n// WHOLE-SECTION REPLACE ON WRITE — `PATCH` replaces each section object\n// wholesale, never merging field-by-field within one. A caller must always\n// send every field of a section it wants to keep, not a diff — this hook\n// does not attempt to hide that from callers by auto-merging, since a wrong\n// guess here would silently drop settings the agency already made.\n\nimport type { KaafilClient } from 'kaafil-js/client';\nimport { useCallback, useEffect, useState } from 'react';\nimport { useKaafilClient } from './useKaafilClient';\n\ntype BoundAgencySettings = KaafilClient['agencies']['settings'];\n\n/** `AgencySettingsResponse` — never imported by name, derived off the one\n * exported anchor (`useAgencyJourneyTriggers.ts`'s own convention). */\nexport type AgencySettingsDocument = Awaited<ReturnType<BoundAgencySettings['get']>>;\n\nexport type PatchAgencySettingsInput = Omit<Parameters<BoundAgencySettings['patch']>[0], 'signal'>;\n\nexport interface AgencySettingsReady {\n readonly document: AgencySettingsDocument | undefined;\n readonly loaded: boolean;\n readonly lastFetchFailed: boolean;\n readonly refresh: () => Promise<void>;\n readonly patchSettings: (input: PatchAgencySettingsInput) => Promise<AgencySettingsDocument>;\n}\n\nexport function useAgencySettings(): AgencySettingsReady {\n const client = useKaafilClient();\n const [document, setDocument] = useState<AgencySettingsDocument | undefined>(undefined);\n const [loaded, setLoaded] = useState(false);\n const [lastFetchFailed, setLastFetchFailed] = useState(false);\n\n const refresh = useCallback(async (): Promise<void> => {\n try {\n const response = await client.agencies.settings.get({});\n setDocument(response);\n setLoaded(true);\n setLastFetchFailed(false);\n } catch {\n setLastFetchFailed(true);\n }\n }, [client]);\n\n useEffect(() => {\n void refresh();\n }, [refresh]);\n\n const patchSettings = useCallback(\n async (input: PatchAgencySettingsInput): Promise<AgencySettingsDocument> => {\n const response = await client.agencies.settings.patch(input);\n void refresh();\n return response;\n },\n [client, refresh],\n );\n\n return { document, loaded, lastFetchFailed, refresh, patchSettings };\n}\n","'use client';\n\n// One trip's own console read — `agencies.trips.get`\n// (`kaafil-js/src/resources/agencies.ts`, over this pass's own new engine\n// module `trip-directory`). Identity plus the live manifest size, the full\n// manager roster and a money rollup over the trip's balance rows.\n//\n// NOT `trips.get`. That one (`GET /api/v1/trips/{ref}`) is `apiKeyAuth`-only\n// and returns the ingest ECHO — calling it from any browser persona throws\n// `UnsatisfiableSchemeError` before a request is sent. This hook reads the\n// agency-scoped sibling instead, which accepts `agencyAdminAuth`.\n// `useAgencyManagerProfile.ts`/`useAgencyTravellerProfile.ts` are the exact\n// read-side pattern followed here: a single explicit-ref-scoped live GET,\n// not a cache-first list.\n//\n// NO CAPABILITY GATE — a trip's own identity is navigation data, not a\n// plan-gated module feature (`useAgencyTravellerProfile.ts`'s own reasoning).\n//\n// NO WRITE HERE. Create/patch/cancel are `trip-ingest`'s `apiKeyAuth`-only\n// lane; the one trip-scoped write an admin CAN make to a trip's roster is\n// role/lead (`useDirectories().promoteManager`), which lives with the\n// directory hook that already owns it rather than being re-derived here.\n\nimport type { AgencyTripsResource } from 'kaafil-js/client';\nimport { useCallback, useEffect, useState } from 'react';\nimport { useKaafilClient } from './useKaafilClient';\n\n// Derived structurally off the SDK resource — `TripDirectoryRowResponse` is a\n// private alias inside `resources/agencies.ts`, so this cannot drift from\n// what the SDK actually returns (`useDirectories.ts`'s own convention).\nexport type AgencyTripRead = Awaited<ReturnType<AgencyTripsResource['get']>>;\n\nexport interface AgencyTripResult {\n readonly read: AgencyTripRead | undefined;\n readonly readFailed: boolean;\n readonly refresh: () => Promise<void>;\n}\n\nexport function useAgencyTrip(tripRef: string): AgencyTripResult {\n const client = useKaafilClient();\n const [read, setRead] = useState<AgencyTripRead | undefined>(undefined);\n const [readFailed, setReadFailed] = useState(false);\n\n const refresh = useCallback(async (): Promise<void> => {\n try {\n const response = await client.agencies.trips.get({ tripRef });\n setRead(response);\n setReadFailed(false);\n } catch {\n setReadFailed(true);\n }\n }, [client, tripRef]);\n\n useEffect(() => {\n void refresh();\n }, [refresh]);\n\n return { read, readFailed, refresh };\n}\n","'use client';\n\n// One trip's manifest for the OFFICE — `agencies.trips.manifest.listPage`\n// (`kaafil-js/src/resources/agencies.ts`, over this pass's own new\n// `trip-directory` route).\n//\n// ── WHY THIS AND NOT `useDirectories().listTripManifest` ──────────────────\n//\n// Both read \"the travellers on this trip\", and both are real. They are not\n// interchangeable, and neither is a duplicate of the other:\n//\n// `listTripManifest` (and `useParties().tripRoster`, which reads the same\n// endpoint) wrap `travellers.listForTrip` → `GET /trips/{ref}/travellers`.\n// That operation takes NO query parameters and returns the full roster in\n// one array — exactly what the FIELD app wants, because a manager's device\n// caches the whole manifest and filters it locally. `ManagerManifestSection`\n// is built on it.\n//\n// This hook wraps the office read, which is filterable and paginated, and\n// whose row additionally carries `gender`, `medicalFlag`, `dateOfBirth` and\n// the traveller's `party` DENORMALISED. A desk console filters server-side\n// over a set it never holds entirely.\n//\n// The engine deliberately kept them as two operations rather than paginating\n// the existing one: an operation is array-shaped or page-shaped for EVERY\n// caller, so flipping it would have changed the SDK method's return type and\n// broken the field app's manifest to serve a console list. That reasoning is\n// recorded in `trip-directory.constants.ts` and in the route's own\n// description; this comment exists so nobody deletes one hook thinking it\n// duplicates the other.\n//\n// SHAPE: `useAgencyTrips.ts`'s exact posture — a `PaginatedListFetch`-shaped\n// FACTORY, not a resolved array, so the consuming composite drives its own\n// `usePaginatedList()` instance.\n//\n// NO CAPABILITY GATE, for the reason `useDirectories.ts` states for itself: a\n// trip's roster is core trip data, not one of the eleven capability modules,\n// and there is no `capability` key to resolve a triple for without inventing\n// one the wire does not have.\n\nimport type { TripManifestFacets, TripManifestFilters } from 'kaafil-js/client';\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport { useKaafilClient } from './useKaafilClient';\nimport type { PaginatedListFetch } from './usePaginatedList';\n\nexport type { TripManifestFacets, TripManifestFilters };\n\n// Derived structurally off the client's own bound resource rather than\n// imported by name — `TripManifestRowResponse` is a private alias inside\n// `resources/agencies.ts`, the same situation `useAgencyTrips.ts` documents,\n// so this cannot drift from what the SDK actually returns.\ntype BoundManifestResource = ReturnType<typeof useKaafilClient>['agencies']['trips']['manifest'];\n\nexport type TripManifestRow = Awaited<ReturnType<BoundManifestResource['listPage']>>[number];\n\n/** The reference panel's own flat-mode page size. */\nconst DEFAULT_PAGE_LIMIT = 20;\n\n/**\n * What a grouped read asks for.\n *\n * Grouping by booking party has to see the WHOLE filtered set before it can\n * group — a family split across a page boundary would render as two groups of\n * two. A trip's manifest is bounded by its capacity (tens to low hundreds),\n * not by a catalogue, so asking for a large page and following `hasNext`\n * terminates in one or two requests in practice. The reference panel makes\n * the same split: it paginates only in flat mode.\n *\n * 100 IS THE ROUTE'S OWN CEILING, not a taste call: `limit` on\n * `GET /agencies/{ref}/trips/{tripRef}/manifest` is `maximum: 100`. This\n * constant was 200, so EVERY grouped read was rejected with a\n * `422 VALIDATION_ERROR` before it fetched a single row — which is why\n * switching to \"Group by\" rendered nothing at all. Raising it again requires\n * raising the route's maximum first; the two must move together.\n */\nconst GROUPED_PAGE_LIMIT = 100;\n\nexport interface AgencyTripManifestResult {\n /**\n * One `PaginatedListFetch` per filter set, for the caller's own\n * `usePaginatedList()`. Remount (or re-key) the consumer when `filters`\n * changes — `usePaginatedList`'s own contract fetches page 0 exactly once\n * per mount.\n *\n * `pageSize` lets the grouped and flat modes ask for different pages off\n * the same hook without a second door.\n */\n readonly makeManifestFetch: (\n filters: TripManifestFilters,\n pageSize?: number,\n ) => PaginatedListFetch<TripManifestRow>;\n /**\n * Whole-set aggregates for the tiles above the table — `undefined` until\n * the first page lands.\n *\n * These describe the CURRENT FILTERED SET (unlike `useAgencyTrips`'\n * `segmentCounts`, which spans the whole agency): a head-count above a\n * filtered table has to describe that table. They arrive on the envelope's\n * `facets` key for the same reason those do — `PaginatedListFetchResult` is\n * shared, domain-agnostic plumbing and must not grow a `facets` slot that\n * would mean nothing for the five other lists using it.\n */\n readonly facets: TripManifestFacets | undefined;\n /** The page size a grouped read should pass — see `GROUPED_PAGE_LIMIT`. */\n readonly groupedPageSize: number;\n}\n\nexport function useAgencyTripManifest(tripRef: string): AgencyTripManifestResult {\n const client = useKaafilClient();\n const [facets, setFacets] = useState<TripManifestFacets | undefined>(undefined);\n\n // Guards the one `setState` inside an awaited fetch whose lifetime the\n // CALLER owns — without it, a filter change that unmounts the list body\n // mid-request sets state on a dead consumer.\n const mountedRef = useRef(true);\n useEffect(() => {\n mountedRef.current = true;\n return () => {\n mountedRef.current = false;\n };\n }, []);\n\n const makeManifestFetch = useCallback(\n (filters: TripManifestFilters, pageSize?: number): PaginatedListFetch<TripManifestRow> =>\n async (cursor) => {\n const page = await client.agencies.trips.manifest.listPage({\n tripRef,\n ...filters,\n cursor,\n limit: pageSize ?? DEFAULT_PAGE_LIMIT,\n });\n if (mountedRef.current) {\n setFacets(page.facets);\n }\n return {\n rows: page,\n nextCursor: page.meta.page.hasNext ? (page.meta.page.cursor ?? undefined) : undefined,\n };\n },\n [client, tripRef],\n );\n\n return { makeManifestFetch, facets, groupedPageSize: GROUPED_PAGE_LIMIT };\n}\n","'use client';\n\n// The agency's own trip list — `agencies.trips.listPage`\n// (`kaafil-js/src/resources/agencies.ts`, over this pass's own new engine\n// module `trip-directory`).\n//\n// WHY THIS HOOK EXISTS AT ALL. Before the endpoint behind it, there was NO\n// browser-reachable \"list this agency's trips\" read on any plane:\n// `managerMe.listTrips` is a manager's OWN assignments and `managerAuth`-only,\n// and the `trips` resource itself (`upsert`/`get`/`cancel`) is\n// `apiKeyAuth`-only ingest. That absence is why\n// `KaafilAgencyWorkspace.types.ts` had to declare `trips` a REQUIRED prop and\n// call it \"the one documented departure from 0 required props\" — the host had\n// to supply the list from its own CRM data because the SDK could not. This\n// hook closes that.\n//\n// SHAPE: `useDirectories.ts`'s exact posture for its two agency-wide lists —\n// a `PaginatedListFetch`-shaped FACTORY rather than a resolved array, so the\n// consuming composite drives its own `usePaginatedList()` instance over it\n// (`08-core-hooks.md §4`'s domain-agnostic pagination plumbing, never\n// re-implemented here).\n//\n// NO CAPABILITY GATE, for the reason `useDirectories.ts` states for itself: a\n// trip directory is agency navigation data, not one of the eleven trip\n// capability modules, and there is no `capability` key this hook could\n// resolve a triple for without inventing one the wire does not have.\n//\n// READ-ONLY. There is deliberately no create/patch/cancel here: those stay\n// `trip-ingest`'s `apiKeyAuth`-only lane, structurally unreachable from any\n// browser session. A composite must not offer an affordance for them.\n\nimport type {\n AgencyTripFilters,\n AgencyTripSegmentCounts,\n AgencyTripsResource,\n} from 'kaafil-js/client';\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport { useKaafilClient } from './useKaafilClient';\nimport type { PaginatedListFetch } from './usePaginatedList';\n\nexport type { AgencyTripFilters, AgencyTripSegmentCounts };\n\n// Derived structurally off the SDK resource rather than imported by name —\n// `TripDirectoryRowResponse` is a private alias inside\n// `resources/agencies.ts`, the same situation `useDirectories.ts` documents\n// for its own four row shapes, so this can never drift from what the SDK\n// actually returns.\nexport type AgencyTripRow = Awaited<ReturnType<AgencyTripsResource['listPage']>>[number];\n\n/** Matches the engine's own default page size for this route. */\nconst DEFAULT_PAGE_LIMIT = 20;\n\nexport interface AgencyTripsResult {\n /**\n * One `PaginatedListFetch` per filter set, for the caller's own\n * `usePaginatedList()`. Remount (or re-key) the consumer when `filters`\n * changes — `usePaginatedList`'s own contract fetches page 0 exactly once\n * per mount.\n */\n readonly makeTripsFetch: (filters: AgencyTripFilters) => PaginatedListFetch<AgencyTripRow>;\n /**\n * Per-bucket counts over the WHOLE agency, for the list's filter chips —\n * `undefined` until the first page lands.\n *\n * These arrive on the envelope's `facets` key rather than in the page\n * body, because they are computed over the whole filtered set rather than\n * the page. `PaginatedListFetchResult` has no slot for them and must not\n * grow one: that type is shared, domain-agnostic plumbing (its own header\n * insists on it), and a `facets` field there would mean nothing for the\n * four other lists that use it. So this hook keeps them itself, written\n * as each page resolves.\n */\n readonly segmentCounts: AgencyTripSegmentCounts | undefined;\n}\n\nexport function useAgencyTrips(): AgencyTripsResult {\n const client = useKaafilClient();\n const [segmentCounts, setSegmentCounts] = useState<AgencyTripSegmentCounts | undefined>(\n undefined,\n );\n // Guards the one `setState` that happens inside an awaited fetch the\n // CALLER owns the lifetime of — without it, a filter change that unmounts\n // the list body mid-request sets state on a dead consumer.\n const mountedRef = useRef(true);\n useEffect(() => {\n mountedRef.current = true;\n return () => {\n mountedRef.current = false;\n };\n }, []);\n\n const makeTripsFetch = useCallback(\n (filters: AgencyTripFilters): PaginatedListFetch<AgencyTripRow> =>\n async (cursor) => {\n const page = await client.agencies.trips.listPage({\n ...filters,\n cursor,\n limit: DEFAULT_PAGE_LIMIT,\n });\n if (mountedRef.current) {\n setSegmentCounts(page.facets.segments);\n }\n return {\n rows: page,\n nextCursor: page.meta.page.hasNext ? (page.meta.page.cursor ?? undefined) : undefined,\n };\n },\n [client],\n );\n\n return { makeTripsFetch, segmentCounts };\n}\n","'use client';\n\n// `08-core-hooks.md §3` table, row `useBookings(tripRef)`.\n//\n// ── TWO THINGS IN THIS HEADER USED TO BE TRUE AND ARE NOT ─────────────────\n//\n// It said `bookings.list` \"excludes `agencyAdminAuth`; an admin-mode surface\n// renders this from the CRM's own data, not through us\", and it said \"this\n// hook exposes NO write path … read-only by design, not by omission. Do not\n// add a write method.\" Both were accurate when written and both moved, so\n// they are corrected here rather than left to mislead the next reader:\n//\n// `list` `['apiKey', 'manager', 'agencyAdmin']`\n// `vouchers.replace` `['apiKey', 'agencyAdmin']`\n// `bulkUpsert`/`delete` STILL `apiKey` ALONE — unreachable from a browser,\n// and that absence IS still structural. A booking is\n// the CRM's fact: the desk may point one at a\n// voucher file and may not create, change or remove\n// it. Do not add those two.\n//\n// The desk read exists because the voucher write names a `bookingRef` and\n// nothing else can discover one.\n//\n// ── CACHE-FIRST WITH A LIVE FALLBACK ──────────────────────────────────────\n//\n// `'bookings'` is a confirmed section of the consolidated pull\n// (`kaafil-js/src/offline/pull.ts`'s `SYNC_PULL_SECTIONS`), so a field device\n// reads its own snapshot. A DESK CONSOLE MOUNTS NO `OfflineShell` and so has\n// no snapshot at all — without the `live` lane below every desk surface\n// reading bookings would render an empty list rather than the trip's\n// bookings, which is the same hole `useExpenses` documents for its own read.\n//\n// `syncedAt`, NOT `status`, is the readability signal: a failed live read\n// still reports `status: 'ready'` with `[]`, and only `syncedAt === undefined`\n// distinguishes \"this trip has no bookings\" from \"we could not read them\".\n//\n// Rows may be a live booking OR the tombstone shape (`{ _tombstone: true, id,\n// version, deletedAt }`) for one deleted since the cursor — a consumer filters\n// those out itself (see `RoomingBoard.tsx`'s own `isLiveRoom` precedent),\n// never here, so a caller that genuinely wants to know \"what just got\n// tombstoned\" is not blocked by this hook throwing them away first.\n\nimport { type BookingListRow, SyncOpMethod } from 'kaafil-js/client';\n\n/** Re-exported so a family composite can type its own rows without\n * importing `kaafil-js` — hard rule #1 forbids that outside `src/core/`,\n * and dx-01 fails the build on it. */\nexport type { BookingListRow };\n\nimport { useCallback } from 'react';\nimport { createDomainHook } from '../internal/createDomainHook';\nimport type { DomainHookResult } from '../types/domain.types';\nimport { useOfflineMutation } from './useOfflineMutation';\nimport { useSnapshotList } from './useSnapshotList';\n\n/**\n * The FULL replacement set for one booking's vouchers.\n *\n * `voucherFileKeys` REPLACES the stored array wholesale (`bookings FRD` R6) —\n * there is no add-one call. A caller that sends only its new key detaches\n * every voucher the CRM already attached, so a UI must read the booking's\n * current list and send it back plus the addition. Named `…FileKeys` rather\n * than `…FileIds` because that is the wire field; the values are file ids.\n */\nexport interface ReplaceBookingVouchersInput {\n readonly bookingRef: string;\n readonly voucherFileKeys: readonly string[];\n}\n\nexport interface BookingsReady {\n readonly bookings: readonly BookingListRow[];\n readonly syncedAt: string | undefined;\n /** Re-read the live list — used after a voucher write so the booking's own\n * `voucherFileKeys` stops being stale. */\n readonly refreshLive: () => Promise<void>;\n /**\n * `PATCH /trips/{ref}/bookings/{bookingRef}/vouchers`. The ONE write this\n * hook has, and the only booking field a browser may change.\n *\n * `ReplaceBookingVouchersOptions` declares NO `idempotencyKey`, so nothing\n * here mints or accepts one (hard rule #4) and the desk lane is legal.\n */\n readonly replaceVouchers: (input: ReplaceBookingVouchersInput) => Promise<void>;\n}\n\nconst useBookingsInternal = createDomainHook<BookingsReady>('bookings', (tripRef) => {\n const {\n rows: bookings,\n syncedAt,\n refreshLive,\n } = useSnapshotList<BookingListRow>(tripRef, 'bookings', {\n live: async (liveClient, ref) => {\n // A BARE ARRAY, not an `{ items }` envelope — `bookings.list` is one of\n // the few reads in this SDK shaped that way, so `response` IS the rows\n // (plus `meta`, which `KaafilResponse<T> = T & { meta }` merges on).\n const response = await liveClient.bookings.list({ tripRef: ref });\n return { rows: [...response], syncedAt: response.meta.serverTime };\n },\n });\n\n const vouchersMutation = useOfflineMutation<ReplaceBookingVouchersInput>({\n tripRef,\n enqueue: (engine, input) =>\n engine.enqueue({\n tripRef,\n method: SyncOpMethod.Patch,\n path: `/api/v1/trips/${tripRef}/bookings/${input.bookingRef}/vouchers`,\n // Hardcoded literal, not imported: `OperationId` is not exported from\n // `kaafil-js/client`'s public surface (the reasoning `useRooming.ts`\n // documents). Verified against `kaafil-js/src/generated/security.ts`:\n // `OperationId.ReplaceBookingVouchers === 'replaceBookingVouchers'`.\n operationId: 'replaceBookingVouchers' as never,\n body: { voucherFileKeys: [...input.voucherFileKeys] },\n }),\n // THE DESK LANE, and the only lane that matters in practice: filing a\n // voucher is desk work and a desk console mounts no `OfflineShell`. The\n // outbox lane above exists because this hook cannot know which shell it\n // is under, not because a manager can call this route — they cannot.\n direct: (liveClient, input) =>\n liveClient.bookings.vouchers.replace({\n tripRef,\n bookingRef: input.bookingRef,\n voucherFileKeys: [...input.voucherFileKeys],\n }),\n });\n\n const mutate = vouchersMutation.mutate;\n const replaceVouchers = useCallback(\n async (input: ReplaceBookingVouchersInput): Promise<void> => {\n await mutate(input);\n // The booking's own `voucherFileKeys` just changed, and the next\n // replace has to send the CURRENT set — a stale read here is how a\n // second attachment silently detaches the first.\n await refreshLive();\n },\n [mutate, refreshLive],\n );\n\n return { bookings, syncedAt, refreshLive, replaceVouchers };\n});\n\nexport function useBookings(tripRef: string): DomainHookResult<BookingsReady> {\n return useBookingsInternal(tripRef);\n}\n","'use client';\n\n// Trip-scoped capability STATUSES plus the one thing `useCapabilities()`\n// cannot tell a caller: whether the read has landed yet.\n//\n// ── WHY THIS EXISTS ALONGSIDE `useCapabilities()` ─────────────────────────\n//\n// `useCapabilities()`'s signature is fixed by `08-core-hooks.md §1.4`: it\n// takes an optional key list and returns a `ReadonlyMap<string,\n// CapabilityTriple>`. There is nowhere in that return value to say \"the read\n// has not answered yet\", so a key that is merely UNRESOLVED is indistinguish-\n// able from one the last build genuinely never named — both come back as\n// `UNKNOWN_CAPABILITY_TRIPLE`, whose status is `mode-dark`\n// (`../internal/deriveCapabilityTriple.ts` explains why that is the right\n// default for a genuinely absent row).\n//\n// For a component that only lights or dims a control, that conflation is\n// harmless: it dims for one frame and then lights up. For a component whose\n// LAYOUT depends on the answer it is not, because `mode-dark` is the one\n// treatment that means \"render nothing at all\" (`06-capability-and-personas.md\n// §2`). `TripWorkspace`'s tab rail is exactly that case: read through\n// `useCapabilities()` it would drop all thirteen gated tabs on the first\n// render and then grow to full width when the read landed — a visible\n// structural jump, caused entirely by treating \"not yet known\" as \"does not\n// exist for this trip shape\".\n//\n// `../internal/useCapabilityRows.ts` already models this correctly and its own\n// doc comment says why the flag is there: \"callers use this to distinguish\n// 'still loading' from 'loaded, and this key genuinely wasn't in the\n// response'\". This hook is the public door onto that flag. It adds NO second\n// fetch, NO second cache and NO second derivation — it reads the same one\n// implementation both public shapes already read through, and derives status\n// with the same `deriveCapabilityTriple()`, so `06 §6` point 2 (\"this\n// derivation is the UIKit's value-add\", and it happens once) still holds and\n// no composite re-derives a status from raw booleans.\n//\n// EXPLICIT `tripRef`, unlike `useCapabilities()`. Same reason every `§3`\n// domain hook takes one: a screen that knows which trip it is scoped to\n// should say so rather than depend on an ambient context, and it means a\n// trip-scoped screen needs no `TripContext` provider at all.\n\nimport { useMemo } from 'react';\nimport { deriveCapabilityTriple } from '../internal/deriveCapabilityTriple';\nimport { useCapabilityRows } from '../internal/useCapabilityRows';\nimport type { CapabilityTriple } from '../types/capability.types';\n\nexport interface CapabilityStatusesResult {\n /** Capability key → the derived status, for every key the last read\n * carried. A key that is ABSENT from this map is absent from the read —\n * callers apply their own open-set fallback (`06 §6` point 5), which this\n * hook deliberately does not choose for them. */\n readonly statuses: ReadonlyMap<string, CapabilityTriple['status']>;\n /** `false` until the first `journey.capabilities()` response for this trip\n * has landed. A `share` session is immediately `true` with an empty map\n * (`06 §9` — no `share.*` operation exposes this read). */\n readonly loaded: boolean;\n}\n\nexport function useCapabilityStatuses(tripRef: string): CapabilityStatusesResult {\n const { rows, loaded } = useCapabilityRows(tripRef);\n\n const statuses = useMemo(() => {\n const map = new Map<string, CapabilityTriple['status']>();\n for (const row of rows) map.set(row.capability, deriveCapabilityTriple(row).status);\n return map;\n }, [rows]);\n\n return { statuses, loaded };\n}\n","'use client';\n\n// `08-core-hooks.md §3` table, row `useDirectories(agencyRef?)`. Primary SDK\n// surface (verified, `kaafil-js/src/resources/{agencies,travellers,trips}.ts`):\n// `agencies.managers.list`/`.listPage` (agencyRef auto-bound on\n// `KaafilClient`; `?forTripRef=` yields per-row `availability` — there is\n// NO date-range overlap search), `trips.managers.patch` (`isLead: true` =\n// promote; `422 BUSINESS_RULE_VIOLATION` for a manager bearer, never `403`),\n// `travellers.listForTrip`, `travellers.listForAgency`/`.listForAgencyPage`\n// (`q` is OPTIONAL — verified this wave against the real `kaafil-engine`/\n// `kaafil-js` source, a deliberate reversal of the previous \"search-only,\n// 2+ chars required, never browsable\" posture; omitting `q` now lists every\n// traveller in the agency, cursor-paginated), `trips.travellers.pushManifest`\n// (the bulk trip-manifest write —\n// still the only way to add a traveller to ONE TRIP's manifest from a\n// browser), and `travellers.create` (`GAP-008`, verified CLOSED this wave\n// against the real `kaafil-engine`/`kaafil-js` source, not just the docs:\n// `POST /api/v1/agencies/:ref/travellers`, `auth: ['apiKey', 'agencyAdmin']`\n// — a real, non-workaround, agency-directory create with no client-minted\n// id required; `externalTravellerId` omitted mints `externalId: null`\n// server-side). It is agency-directory-only with no trip attachment, so it\n// still cannot stand in for `pushManifest`'s \"add this traveller to THIS\n// trip's manifest\" — the two are different, both-real operations now,\n// not a real one and a workaround.\n//\n// DECISION: unlike every other §3 domain hook, this file does NOT wrap\n// itself in `createDomainHook()`/a `journey.capabilities()` gate. The\n// catalog's own row carries no \"PERSONALIZED mode-dark\" note (every gated\n// row does) and the three resource groups behind it are agency-scoped\n// directories, not one of the eleven trip-capability modules\n// (`06-capability-and-personas.md §3`) — there is no single `capability`\n// key this hook could resolve a triple for without inventing one the wire\n// does not have. Backs both `ManagerDirectoryFlow` and\n// `TravellerDirectoryFlow` (`families/admin/11-directories.md`, cited) —\n// listed once here because both read through the same agency-scoped\n// resource group; the flow layer is where the two directories split.\n//\n// SHAPE, IMPLEMENTED THIS PASS: the two agency-wide lists are cursor-paged\n// (`agencies.managers.listPage`/`travellers.listForAgencyPage`), so this\n// hook hands back `PaginatedListFetch`-shaped factories\n// (`usePaginatedList.ts`'s own contract) rather than a resolved array —\n// `ManagerDirectoryTable`/`TravellerSearchBox` each drive their own\n// `usePaginatedList()` instance over one, per `08-core-hooks.md §4`'s\n// domain-agnostic pagination plumbing, never re-implemented here.\n// `trips.managers.list` (`TripManagerRosterPanel`'s own read) already has a\n// dedicated, working, non-capability-gated hook — `useManagers.ts` — so\n// this file does not re-derive that fetch a second time (`02-architecture.md\n// §3a`'s \"duplicated logic is a bug\"); `TripManagerRosterPanel` calls both\n// hooks, `useManagers(tripRef)` for the read and this one for the\n// `promoteManager` write, exactly as `families/admin/11-directories.md`'s\n// own framing (\"share the `useDirectories()` hook and the `managers` module\n// boundary\") describes for the shared boundary, not a shared fetch.\n//\n// WRITES ARE DIRECT, NOT OUTBOX-ENQUEUED — A DOCUMENTED, BOUNDED DEVIATION.\n// `families/admin/11-directories.md §PromoteLeadControl`'s own Offline note\n// says the quiet part outright: \"This is an office/admin action, not a\n// field write a manager is expected to issue offline.\" `useOfflineMutation()`\n// binds to exactly one `tripRef` at the hook's own call site\n// (`OfflineMutationConfig.tripRef`), but `useDirectories(agencyRef?)`'s\n// signature carries no `tripRef` — it backs two agency-wide directories\n// that are not trip-scoped at all, and the trip-scoped exception panel\n// shares this SAME hook instance rather than opening a second one per\n// `tripRef`. Anchoring an outbox binding here would mean either minting a\n// throwaway `useOfflineMutation` per call (defeating its own tracked-`op`\n// contract) or forcing every non-trip-scoped consumer of this hook to\n// supply a `tripRef` it structurally does not have. Both writes below are\n// therefore awaited directly against `KaafilClient`, classified through the\n// shared `classifyError()` on failure (`409 CONFLICT_VERSION` /\n// `422 BUSINESS_RULE_VIOLATION` / `423 LOCKED` each surface distinctly, per\n// spec), and retried by the CALLER on demand — never silently queued.\n\nimport type {\n AgencyManagerFilters,\n AgencyManagersResource,\n PartyKind,\n TravellerDirectoryFilters,\n TravellersResource,\n TripManagersResource,\n TripPartiesResource,\n} from 'kaafil-js/client';\nimport { useCallback } from 'react';\nimport { classifyError, type ErrorClassification } from '../errors/classify';\nimport { useKaafilClient } from './useKaafilClient';\nimport type { PaginatedListFetch } from './usePaginatedList';\nimport { useServerTime } from './useServerTime';\n\nexport type { AgencyManagerFilters, TravellerDirectoryFilters };\n\n// None of these four row shapes are exported by name from `kaafil-js/client`\n// (`ManagerListRowResponse`/`TravellerDirectoryItemResponse`/\n// `TripManagerRowResponse`/`TripManifestItemResponse` are private aliases\n// inside their own `resources/*.ts` files) — derived structurally off the\n// exported RESOURCE interfaces instead, the same `Awaited<ReturnType<...>>`\n// precedent `useFloat.ts`'s `FloatSummaryRow`/`FloatMovementRow` and\n// `PickupStopAssignmentTable.types.ts`'s `PickupManifestTravellerRow` both\n// use, so none of these can ever drift from what the SDK actually returns.\nexport type ManagerListRowResponse = Awaited<\n ReturnType<AgencyManagersResource['listPage']>\n>[number];\nexport type TravellerDirectoryItemResponse = Awaited<\n ReturnType<TravellersResource['listForAgencyPage']>\n>[number];\nexport type TripManagerRowResponse = Awaited<ReturnType<TripManagersResource['patch']>>;\nexport type TripManifestItemResponse = Awaited<\n ReturnType<TravellersResource['listForTrip']>\n>[number];\n\nconst DEFAULT_PAGE_LIMIT = 20;\n\nexport interface PromoteManagerInput {\n readonly tripRef: string;\n readonly managerRef: string;\n /** The row's own `version` — `If-Match`, required (`trips.managers.patch`'s\n * own doc comment: a missing or stale one are the same `409`). */\n readonly version: number;\n readonly role?: 'MANAGER' | 'COORDINATOR';\n readonly isLead?: boolean;\n}\n\n/** Put an existing agency manager onto a trip.\n *\n * NO `sourceUpdatedAt`. The wire's `assignManager` takes one — it is a CRM's\n * own last-changed instant, used to order concurrent writes last-writer-wins\n * — and this pass made it OPTIONAL precisely so a desk need not send one. A\n * desk has no such instant, and minting `new Date()` here would be a local\n * clock deciding a conflict, which is the thing hard rule #6 keeps out of\n * `/core`. Omitted, the server stamps the write itself. */\nexport interface AssignManagerInput {\n readonly tripRef: string;\n /** Kaafil's id for the manager, or your own external ref — either\n * resolves. Comes from `agencyManagers`, which this hook already lists. */\n readonly managerRef: string;\n readonly role?: 'MANAGER' | 'COORDINATOR';\n /** `true` demotes whatever manager currently leads the trip, in the same\n * transaction — at most one lead per trip, the server's rule. */\n readonly isLead?: boolean;\n}\n\nexport interface UnassignManagerInput {\n readonly tripRef: string;\n readonly managerRef: string;\n}\n\nexport interface AddTravellerInput {\n readonly tripRef: string;\n /** Client-minted — this trip-manifest write (`pushManifest`) has no\n * \"omit to auto-mint\" behaviour of its own, unlike the agency-directory\n * `createAgencyTraveller` below. */\n readonly externalTravellerId: string;\n readonly fullName: string;\n readonly phone?: string;\n}\n\nexport interface CreateAgencyTravellerInput {\n readonly fullName: string;\n readonly phone?: string;\n readonly email?: string;\n readonly locale?: string;\n /** Omit to let the server mint `externalId: null` — real server-side\n * behaviour (`GAP-008`, confirmed against the live `kaafil-engine`\n * route), never a client-side id workaround. Supplying one that already\n * resolves within this agency returns the existing row rather than\n * erroring. */\n readonly externalTravellerId?: string;\n}\n\n// ── The manifest + party writes (this pass) ─────────────────────────────────\n//\n// All five are DIRECT, for the reason this file's own \"WRITES ARE DIRECT, NOT\n// OUTBOX-ENQUEUED\" section already gives for `promoteManager`: they are\n// office/admin acts, not field writes a manager issues offline. That is not\n// merely a preference here — `useParties()`' own `add`/`patch`/`remove`\n// enqueue through `useOfflineMutation`, which THROWS (\"this write has nowhere\n// to enqueue to yet\") when no `OfflineShell` is mounted, and a desk console\n// mounts none. So the outbox door is not available to an admin surface at\n// all, and these are the door that is.\n\nexport interface RemoveFromManifestInput {\n readonly tripRef: string;\n /** Kaafil's id for the traveller, or your own external id — either resolves. */\n readonly travellerRef: string;\n}\n\nexport type PartyWriteResponse = Awaited<ReturnType<TripPartiesResource['patch']>>;\n\nexport interface CreatePartyInput {\n readonly tripRef: string;\n readonly kind: PartyKind;\n /** OPTIONAL, and deliberately not nullable — unlike `PatchPartyInput.label`.\n * The wire lets a create omit a label but not send an explicit null, and it\n * lets a patch CLEAR one; those are different operations and this pair\n * mirrors the contract rather than flattening both to `string | null`. */\n readonly label?: string;\n /** Traveller refs — Kaafil ids or your own external ids. Creating a party\n * PINS it (FRD §4.10.5): it stops being re-derived from shared contact\n * details on the next manifest push. */\n readonly travellerRefs: readonly string[];\n}\n\nexport interface PatchPartyInput {\n readonly tripRef: string;\n readonly partyId: string;\n /** The PARTY row's version, from `trips.parties.list` or a manifest row's\n * denormalised party. A stale one answers `409 CONFLICT_VERSION`, which the\n * caller surfaces rather than retries blind. */\n readonly version: number;\n readonly kind?: PartyKind;\n /** `null` CLEARS the label; omitting the key leaves it alone. */\n readonly label?: string | null;\n readonly travellerRefs?: readonly string[];\n}\n\nexport interface DeletePartyInput {\n readonly tripRef: string;\n readonly partyId: string;\n}\n\n/**\n * ── WHY A SECOND NOTE WRITE EXISTS, AND WHY IT IS NOT A DUPLICATE ──────────\n *\n * `useTravellerProfile().addNote` already wraps `travellers.addNote`. It\n * enqueues through `useOfflineMutation`, which is right for the field — a\n * manager writes a note standing in a car park — and which THROWS (\"this\n * write has nowhere to enqueue to yet\") when no `OfflineShell` is mounted. A\n * desk console mounts none, so that door is closed to this family.\n *\n * This is the same operation through the office door: awaited directly,\n * classified on failure, retried by the caller. Exactly the split\n * `promoteManager` and the party writes above already make, and the reason\n * this file's \"WRITES ARE DIRECT\" section exists. The READ half is NOT\n * duplicated — an admin surface uses `useTravellerProfile`'s own live\n * `getDetail` read unchanged.\n *\n * Named `DirectNoteInput` rather than `AddTravellerNoteInput` so the two\n * doors are distinguishable at a glance in the barrel.\n */\nexport interface DirectNoteInput {\n readonly tripRef: string;\n readonly travellerRef: string;\n readonly body: string;\n}\n\n/** Thrown by every write in this hook on failure — the same\n * classification shape every other `/core` hook's error branch carries\n * (`classify.ts`), so a composite's `catch` narrows on `.code`/`.path`\n * exactly like `FloatMovementForm`/`ExpensesLedgerTable` already do. */\nexport class DirectoriesWriteError extends Error {\n readonly classification: ErrorClassification;\n constructor(classification: ErrorClassification) {\n super(\n classification.cause instanceof Error\n ? classification.cause.message\n : 'The directory write failed.',\n );\n this.name = 'DirectoriesWriteError';\n Object.setPrototypeOf(this, DirectoriesWriteError.prototype);\n this.classification = classification;\n }\n}\n\nexport interface DirectoriesReady {\n /** One page-fetcher factory per instance of `ManagerDirectoryTable` — a\n * fresh `usePaginatedList()` binding per distinct `filters` value (a\n * caller remounts on a filter change, the same \"reset paging on scope\n * change\" idiom `trip-manifest-panel.tsx`'s own `useEffect` documents). */\n readonly makeManagersFetch: (\n filters: AgencyManagerFilters,\n ) => PaginatedListFetch<ManagerListRowResponse>;\n /** Same shape, for `TravellerSearchBox` — `filters.q` is REQUIRED\n * upstream (`TravellerDirectoryFilters`'s own type), so a caller must\n * never invoke the returned fetch while `q` is under the 2-character\n * floor (`travellers.listForAgency`'s own doc comment: a guaranteed `422`\n * otherwise). */\n readonly makeTravellersFetch: (\n filters: TravellerDirectoryFilters,\n ) => PaginatedListFetch<TravellerDirectoryItemResponse>;\n /** `travellers.listForTrip` — the bounded, non-paginated manifest read\n * `TripTravellerManifestTable` would use if it were not, per its own\n * Offline note, a cache-first `useSnapshotList()` read instead; kept here\n * for a caller that genuinely wants a live one-shot manifest fetch. */\n readonly listTripManifest: (tripRef: string) => Promise<readonly TripManifestItemResponse[]>;\n /** `trips.managers.patch` — role change and/or lead promotion/demotion.\n * Throws `DirectoriesWriteError` on failure; see this file's header for\n * why this is a direct call, not an outbox enqueue. */\n readonly promoteManager: (input: PromoteManagerInput) => Promise<TripManagerRowResponse>;\n /** `trips.managers.assign` — puts an existing agency manager on the trip.\n * Both this and `unassignManager` were `apiKey`-only until this pass\n * widened them, which is why the roster card had a promote control and no\n * way to add anyone. Same direct-call posture as `promoteManager`. */\n readonly assignManager: (input: AssignManagerInput) => Promise<void>;\n /** `trips.managers.unassign` — a SOFT unlink, not a delete: the manager\n * stays in the agency directory and can be re-assigned, which is why this\n * needs no confirm-with-consequences dialog. */\n readonly unassignManager: (input: UnassignManagerInput) => Promise<void>;\n /** `trips.travellers.pushManifest`, single-traveller — resolves to the\n * echoed `externalTravellerId` on `verdict: 'applied'`, matching\n * `AddTravellerControl.onAdded`'s own contract. Throws\n * `DirectoriesWriteError` (including a synthesized one for\n * `verdict !== 'applied'`, which the wire never surfaces as an HTTP\n * failure) otherwise. */\n readonly addTraveller: (input: AddTravellerInput) => Promise<string>;\n /**\n * `trips.travellers.remove` — soft-removes a traveller's LINK to this trip.\n * The traveller stays in the agency directory; only their place on this\n * manifest goes.\n */\n readonly removeFromManifest: (input: RemoveFromManifestInput) => Promise<void>;\n /** `trips.parties.add` — a PINNED party (the manager override, FRD §4.10.5). */\n readonly createParty: (input: CreatePartyInput) => Promise<PartyWriteResponse>;\n /** `trips.parties.patch` — kind, label and/or membership. Also pins the party. */\n readonly patchParty: (input: PatchPartyInput) => Promise<PartyWriteResponse>;\n /** `trips.parties.remove` — retires a party. Its members become solo, which\n * is the ABSENCE of a party rather than a party of one. */\n readonly deleteParty: (input: DeletePartyInput) => Promise<void>;\n /** `travellers.addNote` — appends to this traveller's note thread on this trip. */\n readonly addTravellerNote: (input: DirectNoteInput) => Promise<void>;\n /** `travellers.create` — the real, non-workaround agency-directory create\n * (`GAP-008`, closed). Never trip-attached; a caller that needs \"add this\n * traveller to THIS trip's manifest\" still wants `addTraveller` above.\n * Throws `DirectoriesWriteError` on failure. */\n readonly createAgencyTraveller: (\n input: CreateAgencyTravellerInput,\n ) => Promise<TravellerDirectoryItemResponse>;\n}\n\nexport function useDirectories(agencyRef?: string): DirectoriesReady {\n // Structurally absent from every call site (`08-core-hooks.md §3`'s own\n // row) — `KaafilClient` auto-binds it from the open agencyAdmin session\n // (`client-entry.ts`'s \"agencyRef-bound option types\" section, verified);\n // accepted here only for signature parity with the catalog table.\n void agencyRef;\n const client = useKaafilClient();\n const serverTime = useServerTime();\n\n // NOTE: `serverTime` is still read for the other writes in this file; the\n // manifest push deliberately no longer uses it — see `addTraveller`.\n void serverTime;\n\n const makeManagersFetch = useCallback(\n (filters: AgencyManagerFilters): PaginatedListFetch<ManagerListRowResponse> =>\n async (cursor) => {\n const page = await client.agencies.managers.listPage({\n ...filters,\n cursor,\n limit: DEFAULT_PAGE_LIMIT,\n });\n return {\n rows: page,\n nextCursor: page.meta.page.hasNext ? (page.meta.page.cursor ?? undefined) : undefined,\n };\n },\n [client],\n );\n\n const makeTravellersFetch = useCallback(\n (filters: TravellerDirectoryFilters): PaginatedListFetch<TravellerDirectoryItemResponse> =>\n async (cursor) => {\n const page = await client.travellers.listForAgencyPage({\n ...filters,\n cursor,\n limit: DEFAULT_PAGE_LIMIT,\n });\n return {\n rows: page,\n nextCursor: page.meta.page.hasNext ? (page.meta.page.cursor ?? undefined) : undefined,\n };\n },\n [client],\n );\n\n const listTripManifest = useCallback(\n async (tripRef: string): Promise<readonly TripManifestItemResponse[]> => {\n const response = await client.travellers.listForTrip({ tripRef });\n return response;\n },\n [client],\n );\n\n const promoteManager = useCallback(\n async (input: PromoteManagerInput): Promise<TripManagerRowResponse> => {\n try {\n return await client.trips.managers.patch({\n tripRef: input.tripRef,\n managerRef: input.managerRef,\n version: input.version,\n role: input.role,\n isLead: input.isLead,\n });\n } catch (error) {\n throw new DirectoriesWriteError(classifyError(error));\n }\n },\n [client],\n );\n\n const assignManager = useCallback(\n async (input: AssignManagerInput): Promise<void> => {\n try {\n await client.trips.managers.assign({\n tripRef: input.tripRef,\n managerRef: input.managerRef,\n ...(input.role === undefined ? {} : { role: input.role }),\n ...(input.isLead === undefined ? {} : { isLead: input.isLead }),\n });\n } catch (error) {\n throw new DirectoriesWriteError(classifyError(error));\n }\n },\n [client],\n );\n\n const unassignManager = useCallback(\n async (input: UnassignManagerInput): Promise<void> => {\n try {\n await client.trips.managers.unassign({\n tripRef: input.tripRef,\n managerRef: input.managerRef,\n });\n } catch (error) {\n throw new DirectoriesWriteError(classifyError(error));\n }\n },\n [client],\n );\n\n const addTraveller = useCallback(\n async (input: AddTravellerInput): Promise<string> => {\n try {\n // NO `sourceUpdatedAt` — the same reasoning as `AssignManagerInput`'s,\n // and the same wire change: the field is now optional and the server\n // stamps the write itself.\n //\n // THIS IS THE ADD-TRAVELLER FAILURE QA REPORTED. It used to send\n // `serverTime.now()`, which THROWS until a `snapshot.updated` event\n // carrying `serverTime` has landed — and that event comes from the\n // OFFLINE lane, which the desk's direct reads never drive. So on the\n // desk the call threw before the request was even built: no HTTP\n // request was made, and the dialog said \"Couldn't add them. Nothing\n // changed — try again\", which was true and told nobody that a clock\n // was the problem. A desk has no source-system instant to send, and\n // minting one from the device clock is what hard rule #6 forbids.\n const response = await client.trips.travellers.pushManifest({\n tripRef: input.tripRef,\n travellers: [\n {\n externalTravellerId: input.externalTravellerId,\n fullName: input.fullName,\n phone: input.phone,\n },\n ],\n });\n const item = response.items.find(\n (entry) => entry.externalTravellerId === input.externalTravellerId,\n );\n if (item === undefined || item.verdict !== 'applied') {\n throw new DirectoriesWriteError({\n path: 'surface-to-user',\n code: item?.verdict === 'rejected' ? 'BUSINESS_RULE_VIOLATION' : undefined,\n status: undefined,\n unsatisfiableScheme: false,\n cause: undefined,\n });\n }\n return item.externalTravellerId;\n } catch (error) {\n if (error instanceof DirectoriesWriteError) {\n throw error;\n }\n throw new DirectoriesWriteError(classifyError(error));\n }\n },\n [client],\n );\n\n const createAgencyTraveller = useCallback(\n async (input: CreateAgencyTravellerInput): Promise<TravellerDirectoryItemResponse> => {\n try {\n return await client.travellers.create({\n fullName: input.fullName,\n phone: input.phone,\n email: input.email,\n locale: input.locale,\n externalTravellerId: input.externalTravellerId,\n });\n } catch (error) {\n throw new DirectoriesWriteError(classifyError(error));\n }\n },\n [client],\n );\n\n const removeFromManifest = useCallback(\n async (input: RemoveFromManifestInput): Promise<void> => {\n try {\n await client.trips.travellers.remove({\n tripRef: input.tripRef,\n travellerRef: input.travellerRef,\n });\n } catch (error) {\n throw new DirectoriesWriteError(classifyError(error));\n }\n },\n [client],\n );\n\n const createParty = useCallback(\n async (input: CreatePartyInput): Promise<PartyWriteResponse> => {\n try {\n return await client.trips.parties.add({\n tripRef: input.tripRef,\n kind: input.kind,\n ...(input.label !== undefined ? { label: input.label } : {}),\n travellerRefs: [...input.travellerRefs],\n });\n } catch (error) {\n throw new DirectoriesWriteError(classifyError(error));\n }\n },\n [client],\n );\n\n const patchParty = useCallback(\n async (input: PatchPartyInput): Promise<PartyWriteResponse> => {\n try {\n return await client.trips.parties.patch({\n tripRef: input.tripRef,\n partyId: input.partyId,\n version: input.version,\n ...(input.kind !== undefined ? { kind: input.kind } : {}),\n ...(input.label !== undefined ? { label: input.label } : {}),\n ...(input.travellerRefs !== undefined ? { travellerRefs: [...input.travellerRefs] } : {}),\n });\n } catch (error) {\n throw new DirectoriesWriteError(classifyError(error));\n }\n },\n [client],\n );\n\n const deleteParty = useCallback(\n async (input: DeletePartyInput): Promise<void> => {\n try {\n await client.trips.parties.remove({ tripRef: input.tripRef, partyId: input.partyId });\n } catch (error) {\n throw new DirectoriesWriteError(classifyError(error));\n }\n },\n [client],\n );\n\n const addTravellerNote = useCallback(\n async (input: DirectNoteInput): Promise<void> => {\n try {\n await client.travellers.addNote({\n tripRef: input.tripRef,\n travellerRef: input.travellerRef,\n body: input.body,\n });\n } catch (error) {\n throw new DirectoriesWriteError(classifyError(error));\n }\n },\n [client],\n );\n\n return {\n makeManagersFetch,\n makeTravellersFetch,\n listTripManifest,\n promoteManager,\n assignManager,\n unassignManager,\n addTraveller,\n createAgencyTraveller,\n removeFromManifest,\n createParty,\n patchParty,\n deleteParty,\n addTravellerNote,\n };\n}\n","'use client';\n\n// `08-core-hooks.md §4`. Cursor-pagination state matching the console's own\n// `CursorPagination` idiom — the caller never receives the cursor value\n// itself, only `hasPrev`/`hasNext`, so a component cannot construct or\n// persist a cursor by hand. Domain-agnostic pagination plumbing over\n// whatever `fetch` function the caller supplies (`agencies.managers\n// .listPage`, `travellers.listForAgencyPage`, any cursor-paginated\n// `forms`/`bookings` list).\n\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport { classifyError, type ErrorClassification } from '../errors/classify';\n\nexport interface PaginatedListFetchResult<TRow> {\n readonly rows: readonly TRow[];\n readonly nextCursor: string | undefined;\n}\n\nexport type PaginatedListFetch<TRow> = (\n cursor: string | undefined,\n) => Promise<PaginatedListFetchResult<TRow>>;\n\nexport interface PaginatedListOptions {\n readonly pageSize?: number;\n /**\n * APPEND each forward page to the rows already held, instead of replacing\n * them. Off by default, because an ordinary pager wants exactly one page\n * on screen at a time.\n *\n * Turn it on for a caller that must hold the WHOLE list before it can\n * render anything — grouping is the real case: a family split across a\n * page boundary would otherwise render as two groups of two. Such a caller\n * pages to exhaustion by calling `loadNext()` while `hasNext` holds, and\n * without this flag it ends up with only the LAST page (and renders an\n * empty state outright when that page lands empty on an exact page\n * boundary). That mismatch between this hook and `ManifestResults` is the\n * defect QA reported as \"the layout breaks completely when switching to\n * Group by\".\n *\n * Paging backwards makes no sense while accumulating, so `hasPrev` stays\n * false and `loadPrev()` is inert.\n */\n readonly accumulate?: boolean;\n}\n\nexport interface PaginatedListResult<TRow> {\n readonly rows: readonly TRow[];\n readonly hasNext: boolean;\n readonly hasPrev: boolean;\n /**\n * False until the first fetch has finished, whether it succeeded or\n * failed. `rows` is `[]` both before the first response and when the list\n * is genuinely empty, so a consumer that renders an empty state off\n * `rows.length` alone flashes \"nothing here\" on every mount — which is\n * what QA saw as the add-traveller dialog's \"weird loader\", once per\n * keystroke-debounce remount. Gate the empty state on this.\n */\n readonly settled: boolean;\n /**\n * The classified failure of the most recent page fetch, or `undefined`.\n * A failed page also clears `hasNext`, so a caller paging to exhaustion\n * stops rather than retrying the same broken cursor forever.\n */\n readonly error: ErrorClassification | undefined;\n readonly loadNext: () => Promise<void>;\n readonly loadPrev: () => Promise<void>;\n}\n\n/**\n * `pageSize` (`08-core-hooks.md §4`'s `options?.pageSize`) is accepted for\n * call-site parity with the documented signature; whether the SUPPLIED\n * `fetch` function actually honours it as a page-size hint is up to the\n * caller — this hook is domain-agnostic plumbing over `fetch`, never a\n * binding to one resource group, and has no wire-level knowledge of any one\n * endpoint's own page-size parameter name.\n */\nexport function usePaginatedList<TRow>(\n fetch: PaginatedListFetch<TRow>,\n options?: PaginatedListOptions,\n): PaginatedListResult<TRow> {\n const [rows, setRows] = useState<readonly TRow[]>([]);\n const [hasNext, setHasNext] = useState(false);\n const [pageIndex, setPageIndex] = useState(0);\n const [settled, setSettled] = useState(false);\n const [error, setError] = useState<ErrorClassification | undefined>(undefined);\n const fetchRef = useRef(fetch);\n fetchRef.current = fetch;\n // Read through a ref so `loadPage` keeps its empty dependency array — the\n // mount effect below depends on that stability to run exactly once.\n // `=== true` rather than `?? false`: hard rule #5 bans a `??` default on a\n // flag package-wide, and an explicit identity test says the same thing\n // without inventing a default at the read site.\n const accumulateRef = useRef(options?.accumulate === true);\n accumulateRef.current = options?.accumulate === true;\n // `cursors[i]` is the cursor that FETCHES page `i` (`cursors[0]` is always\n // `undefined` — a cold start). Never exposed to the caller — the returned\n // shape carries only `hasPrev`/`hasNext`, per this file's header.\n const cursorsRef = useRef<(string | undefined)[]>([undefined]);\n\n const loadPage = useCallback(async (index: number): Promise<void> => {\n const cursor = cursorsRef.current[index];\n try {\n const result = await fetchRef.current(cursor);\n // Landing on page `index` invalidates any cursor recorded for a\n // forward page beyond it from a PRIOR fetch at this same index (the\n // underlying list may have changed) — truncate before recording the\n // fresh `nextCursor`.\n cursorsRef.current = cursorsRef.current.slice(0, index + 1);\n if (result.nextCursor !== undefined) {\n cursorsRef.current[index + 1] = result.nextCursor;\n }\n // Page 0 always REPLACES, even while accumulating: it is the cold\n // start of a fresh list, not another page of the one already held.\n setRows((previous) =>\n accumulateRef.current && index > 0 ? [...previous, ...result.rows] : result.rows,\n );\n setHasNext(result.nextCursor !== undefined);\n setPageIndex(index);\n setError(undefined);\n } catch (caught: unknown) {\n // Clearing `hasNext` is what stops a caller that pages to exhaustion:\n // its loop is driven by `hasNext`, so leaving it set would re-fire the\n // same failing cursor forever. `rows` and `pageIndex` are left exactly\n // as they were — a failed page must not discard what already landed.\n setError(classifyError(caught));\n setHasNext(false);\n } finally {\n setSettled(true);\n }\n }, []);\n\n useEffect(() => {\n void loadPage(0);\n // `loadPage` is referentially stable (its own `useCallback` has an empty\n // dependency array), so including it here does not cause a second run —\n // this still executes exactly once on mount, with no \"identity\" input to\n // key a reset off beyond the caller choosing to remount the hook.\n }, [loadPage]);\n\n const loadNext = useCallback(async (): Promise<void> => {\n if (!hasNext) {\n return;\n }\n await loadPage(pageIndex + 1);\n }, [hasNext, pageIndex, loadPage]);\n\n const loadPrev = useCallback(async (): Promise<void> => {\n // Inert while accumulating — every page loaded is already on screen, so\n // there is nothing behind the caller to go back to.\n if (pageIndex === 0 || accumulateRef.current) {\n return;\n }\n await loadPage(pageIndex - 1);\n }, [pageIndex, loadPage]);\n\n return {\n rows,\n hasNext,\n hasPrev: !accumulateRef.current && pageIndex > 0,\n settled,\n error,\n loadNext,\n loadPrev,\n };\n}\n","'use client';\n\n// Traveller share links — `shareTokens.{create,list,read,revoke,patch,\n// regenerate}`.\n//\n// A share link is the traveller-facing view of one trip, scoped to a set of\n// SECTIONS the agency picks and expiring on a date it picks. Two shapes, and\n// the difference is load-bearing:\n//\n// PER-TRAVELLER minted with a `travellerRef`. May expose `money` — that\n// traveller's own balance due, never anyone else's.\n// FAMILY LINK minted WITHOUT one (`travellerRef` absent). Trip-level\n// sections only, and the engine REFUSES `money` at mint\n// rather than storing it and quietly ignoring it later\n// (R10 / FRD §4.6) — a subject-less token has no traveller\n// whose balance it could mean. `familySafeSections()` below\n// is the same rule stated client-side so a picker never\n// offers a checkbox the mint will reject.\n//\n// ── SHOWING A LINK AGAIN ──────────────────────────────────────────────────\n//\n// `create` and `regenerate` answer with `token`; `list`, `read`, `revoke` and\n// `patch` still never do.\n//\n// This used to be the whole story — only a SHA-256 was stored, so a reopened\n// dialog could list what existed and revoke or regenerate, but never recover\n// a link it had not kept. An operator asked \"can you resend that link?\" had\n// to REPLACE it, which revokes the copy the family is already using, so a\n// routine request quietly broke a working link.\n//\n// `reveal` closes that: the engine now also keeps the token sealed\n// (AES-256-GCM under `SECRET_WRAPPING_KEY`) and hands it back on demand.\n//\n// TWO NEGATIVE ANSWERS, and they are not the same. `reveal` resolves `null`\n// for a link minted BEFORE that column existed — those rows hold a digest and\n// nothing else, so the address is unrecoverable and the operator's only route\n// is `regenerate`. A rejection is an ordinary failure worth retrying. Do not\n// render them alike.\n//\n// ── WHY `list` MATTERS MORE THAN IT LOOKS ─────────────────────────────────\n//\n// `share-tokens.routes.ts` warns that \"a mint that runs twice leaves two live\n// links to the same traveller's data, only one of which the CRM knows about —\n// the second is unrevocable in practice because nobody holds its id.\" A\n// console that reloaded its page held no ids at all, so it would have gone on\n// minting exactly those orphans. `list` (added in the same pass that let an\n// agency admin mint at all) is what makes revoking possible for a caller that\n// did not mint.\n//\n// WRITES ARE DIRECT, not outbox-enqueued — `useDirectories.ts`'s own\n// \"office/admin action, not a field write a manager is expected to issue\n// offline\" reasoning, and here it is doubly true: `manager` is refused by\n// every one of these operations.\n\nimport type { ShareTokensResource } from 'kaafil-js/client';\nimport { useCallback, useEffect, useState } from 'react';\nimport type { ErrorClassification } from '../errors/classify';\nimport { classifyError } from '../errors/classify';\nimport { useKaafilClient } from './useKaafilClient';\n\n/** Metadata for one link. Never carries a plaintext token. */\nexport type ShareLinkRow = Awaited<ReturnType<ShareTokensResource['list']>>[number];\n/** A freshly minted link — the ONE shape that carries `token`. */\nexport type MintedShareLink = Awaited<ReturnType<ShareTokensResource['create']>>;\n\n/**\n * The 14 sections a link can expose, in the order the engine's own\n * `SHARE_SECTION_KEYS` declares them.\n *\n * Derived from the SDK's own request type rather than hand-listed, so a\n * section added engine-side becomes a compile error here instead of a\n * silently-missing checkbox.\n */\nexport type ShareSectionKey = keyof NonNullable<\n NonNullable<Parameters<ShareTokensResource['create']>[0]['config']>['sections']\n>;\n\nexport const SHARE_SECTION_KEYS: readonly ShareSectionKey[] = [\n 'itinerary',\n 'rooming',\n 'seating',\n 'checklists',\n 'pickup',\n 'accommodation',\n 'transport',\n 'activities',\n 'documents',\n 'money',\n 'managerContact',\n 'agencyContact',\n 'household',\n 'forms',\n];\n\n/**\n * The sections a link of this shape may carry.\n *\n * `money` is dropped for a family link because the engine refuses it at mint\n * — see this file's header. Stated here so a picker never renders a control\n * whose only outcome is a rejected write.\n */\nexport function familySafeSections(isFamilyLink: boolean): readonly ShareSectionKey[] {\n return isFamilyLink ? SHARE_SECTION_KEYS.filter((key) => key !== 'money') : SHARE_SECTION_KEYS;\n}\n\nexport type ShareSections = Readonly<Record<ShareSectionKey, boolean>>;\n\n/** Thrown by every write below — the same classified shape\n * `DirectoriesWriteError` carries, so a composite's `catch` narrows on\n * `.classification.code` identically. */\nexport class ShareLinkWriteError extends Error {\n readonly classification: ErrorClassification;\n constructor(classification: ErrorClassification) {\n super('Share-link write failed');\n this.name = 'ShareLinkWriteError';\n this.classification = classification;\n }\n}\n\nexport interface MintShareLinkInput {\n /** Omit for the whole-trip FAMILY link. */\n readonly travellerRef?: string;\n /**\n * Omit entirely for the agency's own mode-based default. Supplying it turns\n * every UNSET key OFF — a partial config does NOT inherit the defaults, so\n * a caller that supplies this must name every section it wants visible.\n * That is the wire's rule, not this hook's.\n */\n readonly sections?: ShareSections;\n readonly ttlDays?: number;\n readonly expiresAt?: string;\n}\n\nexport interface PatchShareLinkInput {\n readonly id: string;\n /** The token row's own version. A stale one answers `409 CONFLICT_VERSION`. */\n readonly version: number;\n readonly sections?: ShareSections;\n readonly expiresAt?: string;\n}\n\nexport interface ShareLinksResult {\n /** Live links on this trip — `undefined` until the first read lands. */\n readonly links: readonly ShareLinkRow[] | undefined;\n readonly readFailed: boolean;\n readonly refresh: () => Promise<void>;\n readonly mint: (input: MintShareLinkInput) => Promise<MintedShareLink>;\n readonly revoke: (id: string) => Promise<void>;\n readonly patch: (input: PatchShareLinkInput) => Promise<void>;\n readonly regenerate: (id: string) => Promise<MintedShareLink>;\n /**\n * The address of a link that already exists, so it can be re-sent instead\n * of replaced.\n *\n * `null` means this link predates recoverable storage and can NEVER be\n * shown — offer `regenerate`, not a retry. That is a successful call with a\n * negative answer, never an error.\n */\n readonly reveal: (id: string) => Promise<string | null>;\n}\n\n/**\n * `travellerRef` narrows the LIST to one subject; pass `null` for every link\n * on the trip, family link included. Minting takes its own `travellerRef`\n * independently, so one hook instance can list a traveller's links and mint\n * a family link.\n */\nexport function useShareLinks(tripRef: string, travellerRef: string | null): ShareLinksResult {\n const client = useKaafilClient();\n const [links, setLinks] = useState<readonly ShareLinkRow[] | undefined>(undefined);\n const [readFailed, setReadFailed] = useState(false);\n\n const refresh = useCallback(async (): Promise<void> => {\n try {\n const response = await client.shareTokens.list({\n tripRef,\n ...(travellerRef !== null ? { travellerRef } : {}),\n });\n setLinks(response);\n setReadFailed(false);\n } catch (error) {\n setReadFailed(true);\n // Swallowed deliberately — a failed LIST is a state this hook models\n // (`readFailed`), not an exception a caller has to catch. The WRITES\n // below throw, because a failed write needs a decision.\n void error;\n }\n }, [client, tripRef, travellerRef]);\n\n useEffect(() => {\n void refresh();\n }, [refresh]);\n\n const mint = useCallback(\n async (input: MintShareLinkInput): Promise<MintedShareLink> => {\n try {\n const minted = await client.shareTokens.create({\n tripRef,\n ...(input.travellerRef !== undefined ? { travellerRef: input.travellerRef } : {}),\n ...(input.sections !== undefined ? { config: { sections: input.sections } } : {}),\n ...(input.ttlDays !== undefined ? { ttlDays: input.ttlDays } : {}),\n ...(input.expiresAt !== undefined ? { expiresAt: input.expiresAt } : {}),\n });\n await refresh();\n return minted;\n } catch (error) {\n throw new ShareLinkWriteError(classifyError(error));\n }\n },\n [client, tripRef, refresh],\n );\n\n const revoke = useCallback(\n async (id: string): Promise<void> => {\n try {\n await client.shareTokens.revoke({ id });\n await refresh();\n } catch (error) {\n throw new ShareLinkWriteError(classifyError(error));\n }\n },\n [client, refresh],\n );\n\n const patch = useCallback(\n async (input: PatchShareLinkInput): Promise<void> => {\n try {\n await client.shareTokens.patch({\n id: input.id,\n version: input.version,\n ...(input.sections !== undefined ? { config: { sections: input.sections } } : {}),\n ...(input.expiresAt !== undefined ? { expiresAt: input.expiresAt } : {}),\n });\n await refresh();\n } catch (error) {\n throw new ShareLinkWriteError(classifyError(error));\n }\n },\n [client, refresh],\n );\n\n const regenerate = useCallback(\n async (id: string): Promise<MintedShareLink> => {\n try {\n const minted = await client.shareTokens.regenerate({ id });\n await refresh();\n return minted;\n } catch (error) {\n throw new ShareLinkWriteError(classifyError(error));\n }\n },\n [client, refresh],\n );\n\n const reveal = useCallback(\n async (id: string): Promise<string | null> => {\n try {\n const response = await client.shareTokens.reveal({ id });\n // `null` is the SERVER's answer for a link minted before the sealed\n // column existed, not a failure — it is returned as-is so the caller\n // can say \"this one can't be shown, replace it instead\" rather than\n // \"something went wrong, try again\". A genuine failure throws below.\n return response.token;\n } catch (error) {\n throw new ShareLinkWriteError(classifyError(error));\n }\n },\n [client],\n );\n\n return { links, readFailed, refresh, mint, revoke, patch, regenerate, reveal };\n}\n","'use client';\n\n// One traveller's form responses on one trip —\n// `forms.trip.travellerResponses.list`\n// (`GET /trips/{ref}/travellers/{travellerRef}/forms/responses`).\n//\n// ── WHY AN OFFICE SESSION CAN READ THIS ───────────────────────────────────\n//\n// The route accepted `manager` and `apiKey` only until this pass. It now\n// accepts `agencyAdmin` too, and the route's own description carries the\n// argument: this is ONE traveller's answers on ONE trip, the read a desk\n// console needs behind a traveller's detail panel, and the office is who\n// chases an unfilled consent form. It grants nothing new in kind — the same\n// session already reads that traveller's allergies, medical notes and\n// emergency contact through `getTravellerDetail`, which assembles them from\n// these very `TravellerAttribute` rows. Serving the derived fields while\n// refusing their source was an inconsistency, not a boundary.\n//\n// The TRIP-WIDE sibling (`listTripFormResponses` — every traveller's answers\n// to one form) stays manager-only, and `TripWorkspace`'s Forms tab still\n// reports itself blocked for exactly that reason. A per-traveller read and a\n// bulk response export are different questions.\n//\n// ── WHAT A ROW CARRIES, AND WHAT IT DOES NOT ──────────────────────────────\n//\n// `status`, `submittedAt`, `lastSavedAt`, `resubmitCount`, `submittedVia` and\n// `formId` — but NOT the form's title. Titles live on the form definition\n// (`forms.list`, itself admin-readable), so a consumer that wants to label a\n// row joins them itself. This hook does not make that read on its caller's\n// behalf: a detail panel showing three responses should not pull the agency's\n// whole form catalogue, and a caller that already has the catalogue should not\n// fetch it twice.\n//\n// NO CAPABILITY GATE HERE, but note the route ITSELF can answer\n// `422 CAPABILITY_UNAVAILABLE`/`402 PLAN_FEATURE_DISABLED` when `forms` is\n// dark for the agency — a server-side gate this hook surfaces as `readFailed`\n// rather than re-deriving client-side.\n\nimport type { FormsResource } from 'kaafil-js/client';\nimport { useCallback, useEffect, useState } from 'react';\nimport { useKaafilClient } from './useKaafilClient';\n\nexport type TravellerFormResponseRow = Awaited<\n ReturnType<FormsResource['trip']['travellerResponses']['list']>\n>['items'][number];\n\nexport interface TravellerFormResponsesResult {\n readonly responses: readonly TravellerFormResponseRow[] | undefined;\n readonly readFailed: boolean;\n readonly refresh: () => Promise<void>;\n}\n\n/**\n * `travellerRef` is nullable so a caller can mount this unconditionally while\n * its own panel is closed — Rules of Hooks forbid calling it conditionally,\n * and `null` reads as \"nothing open yet\" rather than firing a request for a\n * traveller nobody asked for.\n */\nexport function useTravellerFormResponses(\n tripRef: string,\n travellerRef: string | null,\n): TravellerFormResponsesResult {\n const client = useKaafilClient();\n const [responses, setResponses] = useState<readonly TravellerFormResponseRow[] | undefined>(\n undefined,\n );\n const [readFailed, setReadFailed] = useState(false);\n\n const refresh = useCallback(async (): Promise<void> => {\n if (travellerRef === null) {\n // Cleared rather than kept: a reopened panel showing the PREVIOUS\n // traveller's consent status for one frame is the kind of stale read\n // that matters on this screen.\n setResponses(undefined);\n setReadFailed(false);\n return;\n }\n try {\n const response = await client.forms.trip.travellerResponses.list({ tripRef, travellerRef });\n setResponses(response.items);\n setReadFailed(false);\n } catch {\n setReadFailed(true);\n }\n }, [client, tripRef, travellerRef]);\n\n useEffect(() => {\n void refresh();\n }, [refresh]);\n\n return { responses, readFailed, refresh };\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\n/**\n * Turns a share token into the link a host would actually send a family.\n *\n * A FUNCTION, not a base-URL string, because concatenation only covers one\n * of the shapes a real host needs. `https://crm.example/trip/<token>` is the\n * easy case; `?share=<token>`, a token in the middle of a path, a per-locale\n * prefix, or an encoded value are all just as ordinary, and a string forces\n * every one of them into the kit's guess about where the token goes. The\n * host already owns its URLs everywhere else in this package — hard rule #9,\n * \"the UIKit ships no router; navigation is `on*` callbacks\" — and this is\n * the same rule applied to the one URL the kit displays.\n */\nexport type BuildShareUrl = (token: string) => string;\n\nconst BuildShareUrlContext = createContext<BuildShareUrl | null>(null);\n\n/**\n * The host's share-link builder, or `null` when it did not supply one.\n *\n * `null` is a real answer, not a missing provider: the share dialog falls\n * back to showing the bare token, which is still the credential an operator\n * can paste behind their own URL. Guessing a host's URL shape would be worse\n * than showing the value.\n */\nexport function useBuildShareUrl(): BuildShareUrl | null {\n return useContext(BuildShareUrlContext);\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 /**\n * Turns a share token into the link you send a family, e.g.\n * ``(token) => `https://sharmatravels.example/trip/${token}` ``.\n *\n * SET THIS IF YOU USE SHARE LINKS. Kaafil returns a token, never a URL —\n * the traveller page is on YOUR domain and the engine has no idea what it\n * is. Without this the desk's share dialog can only show the raw token, a\n * UUID an operator cannot meaningfully send to anyone. It is optional\n * rather than required because a host that never mints a share link should\n * not have to supply one, and because guessing your URL shape would be\n * worse than showing the value you can paste behind it yourself.\n */\n readonly buildShareUrl?: BuildShareUrl;\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 buildShareUrl,\n children,\n ...credential\n } = props;\n\n const inner = (\n <BuildShareUrlContext.Provider value={buildShareUrl ?? null}>\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 </BuildShareUrlContext.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","// The deep-link contract — `shared/00-routing-and-deeplinks.md`.\n//\n// ── THE UIKIT STILL OWNS NO ROUTER ────────────────────────────────────────\n//\n// Nothing here declares a route, imports a router, or touches `window` /\n// `history` (hard rule #9; dx-06 fails the build on `window.*`). Every export\n// is a plain type or a pure function over plain values. The host's router\n// stays authoritative — this module exists so every integrator does not\n// hand-write the same query-string glue and the same blocker→destination\n// table against the spec.\n//\n// EVERYTHING IS OPT-IN. No screen's props changed to accommodate this; a host\n// that ignores this module entirely loses nothing it had.\n//\n// NOT A `.tsx` AND NOT A HOOK, deliberately: no `'use client'`. A host may\n// want to resolve a deep link on the server while rendering a link, and a\n// directive here would forbid that for no reason.\n\n// ── §2. Canonical param names ─────────────────────────────────────────────\n//\n// The spec's own point: this fixes PROP NAMES, never a URL shape. A host maps\n// `/agencies/:id/trips/:tripRef`, `/t/:token`, or a query-string-only SPA onto\n// these however its router already works.\n\n/** A desk/field screen scoped to one trip. `tripRef` is the host's own\n * external id OR a Kaafil id — every `:ref` route accepts either, and the\n * UIKit never asks a host to resolve one into the other first. */\nexport interface TripScopedParams {\n readonly tripRef: string;\n /** One of the trip workspace's own tab keys. Optional: absent means the\n * surface picks its own landing tab. */\n readonly initialTab?: KaafilTripTabKey;\n}\n\n/** An agency-wide desk screen. There is deliberately no `agencyRef`: scope\n * comes from the open credential, never a route param (`00-decisions.md`\n * U-003). */\nexport interface AgencyScopedParams {\n readonly initialPane?: string;\n}\n\n/** The public share surface. `token` is the opaque value from the share\n * link's own URL — never a traveller id, never a trip ref. */\nexport interface ShareParams {\n readonly token: string;\n}\n\n/** The two props introduced by the deep-link table itself. Both are bare\n * props on the receiving screen — they carry scope and behaviour, not\n * presentation, so neither is a `components`/`*Slot` key. */\nexport interface DeepLinkParams {\n /** The row the destination must scroll to and focus on arrival. */\n readonly highlightId?: string;\n /** A named filter preset the destination flow already exposes. The screen\n * passes it straight through; the UIKit has no filter language of its\n * own. */\n readonly presetFilter?: string;\n}\n\n// ── The shared tab vocabulary ─────────────────────────────────────────────\n//\n// Defined HERE rather than imported from `admin/`, for two reasons: `/core`\n// cannot import a family (the dependency runs the other way), and the spec\n// fixes \"one tab-composition table shared by both Surfaces\" — the manager and\n// admin trip surfaces use the identical key vocabulary so a deep link's\n// meaning does not change when an integrator graduates from a Surface to\n// mounting flows directly.\n//\n// This is deliberately the INTERSECTION — the tabs a closing-day blocker can\n// send someone to. A family's own tab union is a superset (admin adds\n// `overview`, `manifest`, `documents`, `bookings`, …) and every member here\n// is assignable to it.\nexport type KaafilTripTabKey =\n | 'itinerary'\n | 'pickups'\n | 'rooming'\n | 'vehicles'\n | 'vendors'\n | 'payments'\n | 'expenses'\n | 'float'\n | 'checklist'\n | 'forms';\n\n// ── §3. The closing-day blocker table ─────────────────────────────────────\n\n/**\n * The engine's own route hints (`closing-day.constants.ts#\n * CLOSEOUT_BLOCKER_ACTION_KEYS`), and the value a caller routes on.\n *\n * ROUTE ON `actionKey`, NEVER ON `key` OR THE COPY. The engine says so\n * outright — \"the route hint the FE navigates on, so it never parses copy\"\n * — and the titles are explicitly free to be reworded.\n */\nexport type CloseoutActionKey =\n | 'open_checklist'\n | 'open_collections'\n | 'open_expenses'\n | 'open_float'\n | 'open_forms'\n | 'open_itinerary'\n | 'open_mandatory_checklist'\n | 'open_past_itinerary'\n | 'open_pickups'\n | 'open_rooming'\n | 'open_seating'\n | 'open_vendors';\n\n/** The blocker keys the engine can emit (`CloseoutBlockerKey`). Accepted as\n * an optional refinement below — see `resolveBlockerDeepLink`. */\nexport type CloseoutBlockerKey =\n | 'balance_due'\n | 'missing_receipt'\n | 'float_not_returned'\n | 'open_mandatory_checklist'\n | 'required_form_gap'\n | 'unassigned_rooming'\n | 'unseated_travellers'\n | 'pickup_no_show'\n | 'reimbursements_pending'\n | 'unrated_vendors'\n | 'open_past_itinerary';\n\n/**\n * `actionKey` → the tab that clears the row.\n *\n * A type-keyed record (hard rule #8), total over the union so a new engine\n * action key is a compile error here rather than a row whose jump silently\n * does nothing.\n */\nexport const CLOSEOUT_ACTION_TAB: Readonly<Record<CloseoutActionKey, KaafilTripTabKey>> = {\n open_collections: 'payments',\n open_expenses: 'expenses',\n open_float: 'float',\n open_checklist: 'checklist',\n open_mandatory_checklist: 'checklist',\n open_forms: 'forms',\n open_rooming: 'rooming',\n open_seating: 'vehicles',\n open_pickups: 'pickups',\n open_itinerary: 'itinerary',\n open_past_itinerary: 'itinerary',\n open_vendors: 'vendors',\n};\n\n/**\n * `key` → the arrival filter, from the spec's §3 table.\n *\n * KEYED ON `key`, NOT `actionKey`, and that is not an inconsistency with the\n * rule above — it is forced. TWO KEYS SHARE ONE ACTION KEY:\n * `missing_receipt` and `reimbursements_pending` both carry\n * `actionKey: 'open_expenses'`, and they want opposite arrivals — one\n * pre-filters to spends with no receipt, the other must not filter at all.\n * A filter table keyed on `actionKey` could not tell them apart and would\n * silently apply the wrong one to whichever row arrived second.\n *\n * So: the TAB comes from `actionKey` (the engine's own hint, authoritative),\n * and the FILTER is refined by `key` when the caller has it. A caller with\n * only an `actionKey` still lands on the right tab, unfiltered — correct,\n * just less specific.\n */\nconst BLOCKER_PRESET_FILTER: Readonly<Partial<Record<CloseoutBlockerKey, string>>> = {\n balance_due: 'outstanding',\n missing_receipt: 'missing-receipt',\n open_mandatory_checklist: 'open-mandatory',\n required_form_gap: 'outstanding-respondents',\n unassigned_rooming: 'unassigned',\n // Mirrors `unassigned_rooming` — the spec gives seating the identical\n // arrival contract, pointed at the seating pool instead of the bed pool.\n unseated_travellers: 'unassigned',\n // DELIBERATELY ABSENT, each for its own reason:\n // `float_not_returned`, `pickup_no_show`, `open_past_itinerary` — these\n // arrive by `highlightId` on a single row, not by narrowing a list.\n // `reimbursements_pending` — see this map's header; filtering the\n // expense ledger to missing receipts would be actively wrong here.\n // `unrated_vendors` — see `resolveBlockerDeepLink`.\n};\n\n/** What a caller should do with a blocker row's action. */\nexport interface BlockerDeepLink extends DeepLinkParams {\n readonly tab: KaafilTripTabKey;\n}\n\nexport interface ResolveBlockerInput {\n /** The engine's route hint. The one required field. */\n readonly actionKey: string;\n /** The blocker's own key, when the caller has the whole row. Refines the\n * filter only; it never changes the tab. */\n readonly key?: string;\n /** Passed through untouched when the caller knows which row to focus —\n * typically only when the blocker's `count` is 1. */\n readonly highlightId?: string;\n}\n\n/**\n * Resolve one blocker row into a destination, or `null` for a row that has\n * nowhere to send anyone.\n *\n * `null` IS A REAL ANSWER AND MUST BE HANDLED — render the row's own\n * statement with no jump, never a control that goes nowhere. It happens for\n * an `actionKey` this build has no tab for (a later engine adding one), and\n * for a tab this trip does not have.\n *\n * ── TWO ROWS THE SPEC AND THE ENGINE DISAGREE ABOUT ──────────────────────\n *\n * `shared/00-routing-and-deeplinks.md §3` says `reimbursements_pending`\n * \"never navigates\" (resolved by CRM back-office, out of band) and that\n * `unrated_vendors` is unbuildable (`GAP-005`). The ENGINE assigns both an\n * `actionKey` anyway — `open_expenses` and `open_vendors` — on its own\n * stated principle that \"a row pointing at NO screen is a row a manager\n * cannot act on\".\n *\n * This follows the engine, because the engine is what actually ships the\n * row, and both destinations are defensible: the expenses tab shows claim\n * status read-only, which IS where you look to see where a reimbursement\n * got to, and the vendors tab is where a rating would live. In practice\n * neither costs anything — `unrated_vendors` is never emitted at all (the\n * engine has no vendor-rating source to probe), and `reimbursements_pending`\n * lands unfiltered by the note in `BLOCKER_PRESET_FILTER`.\n */\nexport function resolveBlockerDeepLink(input: ResolveBlockerInput): BlockerDeepLink | null {\n const tab = CLOSEOUT_ACTION_TAB[input.actionKey as CloseoutActionKey];\n if (tab === undefined) return null;\n\n const presetFilter =\n input.key === undefined ? undefined : BLOCKER_PRESET_FILTER[input.key as CloseoutBlockerKey];\n\n return {\n tab,\n ...(presetFilter !== undefined ? { presetFilter } : {}),\n ...(input.highlightId !== undefined ? { highlightId: input.highlightId } : {}),\n };\n}\n\n// ── Serializers ───────────────────────────────────────────────────────────\n//\n// Pure, over plain values. They read no global and touch no router: a host\n// takes the `URLSearchParams` and does whatever its own router does with it.\n// Round-tripping is the only contract — `fromSearchParams(toSearchParams(x))`\n// returns `x`'s deep-link fields.\n\n/** The wire names, fixed once so a link built by one integration is readable\n * by another. Deliberately short and prefixed to be recognisable in a URL a\n * support engineer is squinting at. */\nconst PARAM_TAB = 'kfTab';\nconst PARAM_HIGHLIGHT = 'kfHighlight';\nconst PARAM_FILTER = 'kfFilter';\n\n/**\n * A deep link → query params, for a host that wants to put one in a URL.\n *\n * Returns a FRESH `URLSearchParams` carrying only this link's own keys — it\n * never mutates an input, so a caller merges it into their own query string\n * on their own terms rather than having this decide what else survives.\n */\nexport function toSearchParams(link: Partial<BlockerDeepLink>): URLSearchParams {\n const params = new URLSearchParams();\n if (link.tab !== undefined) params.set(PARAM_TAB, link.tab);\n if (link.highlightId !== undefined) params.set(PARAM_HIGHLIGHT, link.highlightId);\n if (link.presetFilter !== undefined) params.set(PARAM_FILTER, link.presetFilter);\n return params;\n}\n\n/**\n * Query params → the props a surface takes, or `null` when the query carries\n * no Kaafil deep link at all.\n *\n * `null` rather than an empty object, so `if (link)` is enough to tell \"this\n * URL addresses a Kaafil surface\" from \"it does not\" — a host's own router\n * will hand this every query string it sees, most of which are none of our\n * business.\n *\n * AN UNKNOWN TAB IS DROPPED, not passed through. The value came from a URL,\n * which is user-editable; handing an arbitrary string to a surface as a tab\n * key would put unvalidated input into a registry lookup. `highlightId` and\n * `presetFilter` ARE passed through as-is — they are opaque by contract, and\n * the destination flow is what decides whether either matches anything.\n */\nexport function fromSearchParams(\n params: URLSearchParams,\n): (DeepLinkParams & { readonly initialTab?: KaafilTripTabKey }) | null {\n const rawTab = params.get(PARAM_TAB);\n const highlightId = params.get(PARAM_HIGHLIGHT);\n const presetFilter = params.get(PARAM_FILTER);\n if (rawTab === null && highlightId === null && presetFilter === null) return null;\n\n const initialTab = isTripTabKey(rawTab) ? rawTab : undefined;\n return {\n ...(initialTab !== undefined ? { initialTab } : {}),\n ...(highlightId !== null ? { highlightId } : {}),\n ...(presetFilter !== null ? { presetFilter } : {}),\n };\n}\n\n/** Narrows a string off a URL to the shared tab vocabulary. Exported because\n * a host validating its own route params wants the same check. */\nexport function isTripTabKey(value: string | null | undefined): value is KaafilTripTabKey {\n if (value === null || value === undefined) return false;\n return Object.hasOwn(TRIP_TAB_KEY_SET, value);\n}\n\n/** An object rather than a `Set` so the membership test needs no allocation\n * at module load and stays a plain own-property lookup. */\nconst TRIP_TAB_KEY_SET: Readonly<Record<KaafilTripTabKey, true>> = {\n itinerary: true,\n pickups: true,\n rooming: true,\n vehicles: true,\n vendors: true,\n payments: true,\n expenses: true,\n float: true,\n checklist: true,\n forms: true,\n};\n"]}
@@ -1,4 +1,4 @@
1
- import { OfflineEngineContext } from './chunk-ABWNV4N4.js';
1
+ import { OfflineEngineContext } from './chunk-6FUVFVYY.js';
2
2
  import { useContext, useState, useRef, useEffect } from 'react';
3
3
 
4
4
  var TICK_INTERVAL_MS = 1e3;
@@ -37,5 +37,5 @@ function useServerTime() {
37
37
  }
38
38
 
39
39
  export { useServerTime };
40
- //# sourceMappingURL=chunk-DABF4PUI.js.map
41
- //# sourceMappingURL=chunk-DABF4PUI.js.map
40
+ //# sourceMappingURL=chunk-ITGVRN2S.js.map
41
+ //# sourceMappingURL=chunk-ITGVRN2S.js.map