@semiont/core 0.5.8 → 0.5.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/branded-types.ts","../src/identifiers.ts","../src/persisted-events.ts","../src/bus-protocol.ts","../src/event-utils.ts","../src/bus-log.ts","../src/event-bus.ts","../src/operators/burst-buffer.ts","../src/serialize-per-key.ts","../src/logger.ts","../src/annotation-utils.ts","../src/id-generation.ts","../src/annotation-assembly.ts","../src/web-annotation-utils.ts","../src/pdf-coordinates.ts","../src/resource-utils.ts","../src/bridged-channels.ts","../src/fuzzy-anchor.ts","../src/anchor-annotation.ts","../src/locales.ts","../src/svg-utils.ts","../src/text-context.ts","../src/text-encoding.ts","../src/validation.ts","../src/media-types.ts","../src/type-guards.ts","../src/errors.ts","../src/did-utils.ts","../src/config/toml-loader.ts","../src/config/environment-validator.ts","../src/config/configuration-error.ts","../src/config/platform-types.ts"],"names":["resourceUri","baseUrl","annotationUri","resourceId","ctx","start","end","email","parseToml"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Branded string types for compile-time type safety\n *\n * These types are zero-cost at runtime but prevent mixing\n * different string types at compile time.\n */\n\nimport type { components } from './types';\n\n// ============================================================================\n// OPENAPI-GENERATED TYPES (use directly from spec)\n// ============================================================================\n\nexport type Motivation = components['schemas']['Motivation'];\nexport type ContentFormat = components['schemas']['ContentFormat'];\n\n// ============================================================================\n// AUTHENTICATION & TOKENS\n// ============================================================================\n\nexport type Email = string & { readonly __brand: 'Email' };\nexport type AuthCode = string & { readonly __brand: 'AuthCode' };\nexport type GoogleCredential = string & { readonly __brand: 'GoogleCredential' };\nexport type AccessToken = string & { readonly __brand: 'AccessToken' };\nexport type RefreshToken = string & { readonly __brand: 'RefreshToken' };\nexport type MCPToken = string & { readonly __brand: 'MCPToken' };\nexport type CloneToken = string & { readonly __brand: 'CloneToken' };\n\n// ============================================================================\n// SYSTEM IDENTIFIERS\n// ============================================================================\n\nexport type JobId = string & { readonly __brand: 'JobId' };\nexport type UserDID = string & { readonly __brand: 'UserDID' };\nexport type EntityType = string & { readonly __brand: 'EntityType' };\nexport type SearchQuery = string & { readonly __brand: 'SearchQuery' };\nexport type BaseUrl = string & { readonly __brand: 'BaseUrl' };\n\n// ============================================================================\n// HELPER FUNCTIONS (minimal validation, just branding)\n// ============================================================================\n\nexport function email(value: string): Email { return value as Email; }\nexport function authCode(value: string): AuthCode { return value as AuthCode; }\nexport function googleCredential(value: string): GoogleCredential { return value as GoogleCredential; }\nexport function accessToken(value: string): AccessToken { return value as AccessToken; }\nexport function refreshToken(value: string): RefreshToken { return value as RefreshToken; }\nexport function mcpToken(value: string): MCPToken { return value as MCPToken; }\nexport function cloneToken(value: string): CloneToken { return value as CloneToken; }\nexport function jobId(value: string): JobId { return value as JobId; }\nexport function userDID(value: string): UserDID { return value as UserDID; }\nexport function entityType(value: string): EntityType { return value as EntityType; }\nexport function searchQuery(value: string): SearchQuery { return value as SearchQuery; }\nexport function baseUrl(value: string): BaseUrl { return value as BaseUrl; }\n\n// Motivation is an OpenAPI enum — use its values directly, no helper needed.\n// ContentFormat is a free-form MIME string whose base type must be a\n// SupportedMediaType; validation lives in media-types.ts, not in a brand.\n\n// ============================================================================\n// HTTP URI TYPES\n// ============================================================================\n\n// Branded type definitions for HTTP URIs returned by the API\nexport type ResourceUri = string & { readonly __brand: 'ResourceUri' };\n\n// W3C flat format for content negotiation: http://localhost:4000/annotations/{id}\nexport type AnnotationUri = string & { readonly __brand: 'AnnotationUri' };\n\n// Nested format for CRUD operations: http://localhost:4000/resources/{resourceId}/annotations/{annotationId}\nexport type ResourceAnnotationUri = string & { readonly __brand: 'ResourceAnnotationUri' };\n\n// Factory functions with runtime validation\nexport function resourceUri(uri: string): ResourceUri {\n if (!uri.startsWith('http://') && !uri.startsWith('https://')) {\n throw new TypeError(`Expected ResourceUri, got: ${uri}`);\n }\n return uri as ResourceUri;\n}\n\nexport function annotationUri(uri: string): AnnotationUri {\n if (!uri.startsWith('http://') && !uri.startsWith('https://')) {\n throw new TypeError(`Expected AnnotationUri, got: ${uri}`);\n }\n return uri as AnnotationUri;\n}\n\nexport function resourceAnnotationUri(uri: string): ResourceAnnotationUri {\n if (!uri.startsWith('http://') && !uri.startsWith('https://')) {\n throw new TypeError(`Expected ResourceAnnotationUri, got: ${uri}`);\n }\n // Additional validation: must contain /resources/ and /annotations/\n if (!uri.includes('/resources/') || !uri.includes('/annotations/')) {\n throw new TypeError(`Expected nested ResourceAnnotationUri format, got: ${uri}`);\n }\n return uri as ResourceAnnotationUri;\n}\n","/**\n * Branded identifier types for compile-time type safety.\n *\n * These types prevent mixing up resource IDs, annotation IDs, and user IDs\n * at compile time while having zero runtime overhead.\n *\n * URI types (ResourceUri, AnnotationUri) are in @semiont/http-transport\n * since they deal with HTTP URIs returned by the API.\n */\n\n// Branded type definitions for IDs only\nexport type ResourceId = string & { readonly __brand: 'ResourceId' };\nexport type AnnotationId = string & { readonly __brand: 'AnnotationId' };\nexport type UserId = string & { readonly __brand: 'UserId' };\n\n// Type guards with runtime validation\nexport function isResourceId(value: string): value is ResourceId {\n return !value.includes('/');\n}\n\nexport function isAnnotationId(value: string): value is AnnotationId {\n return !value.includes('/');\n}\n\n// Factory functions with runtime validation\nexport function resourceId(id: string): ResourceId {\n if (id.includes('/')) {\n throw new TypeError(`Expected ResourceId, got URI: ${id}`);\n }\n return id as ResourceId;\n}\n\nexport function annotationId(id: string): AnnotationId {\n if (id.includes('/')) {\n throw new TypeError(`Expected AnnotationId, got URI: ${id}`);\n }\n return id as AnnotationId;\n}\n\nexport function userId(id: string): UserId {\n return id as UserId;\n}\n","/**\n * Persisted Events\n *\n * The event types that get appended to the JSONL event log.\n * Each maps a type string to its OpenAPI payload schema.\n * The PersistedEvent union derives from this catalog.\n */\n\nimport type { components } from './types';\nimport type { AnnotationId, ResourceId } from './identifiers';\nimport type { Annotation } from './annotation-types';\nimport type { EventBase } from './event-base';\n\n// Branded payload overrides — the OpenAPI schemas reference the raw\n// `Annotation` type with `id: string`. At the TypeScript layer we narrow\n// to the branded `Annotation` so consumers read `payload.annotation.id`\n// as `AnnotationId` without an upcast at every seam.\ntype AnnotationAddedPayload =\n components['schemas']['AnnotationAddedPayload'] & { annotation: Annotation };\ntype AnnotationRemovedPayload =\n components['schemas']['AnnotationRemovedPayload'] & { annotationId: AnnotationId };\ntype AnnotationBodyUpdatedPayload =\n components['schemas']['AnnotationBodyUpdatedPayload'] & { annotationId: AnnotationId };\n\n// ── The Catalog ──────────────────────────────────────────────────────────────\n\n/**\n * Maps each persisted event type string to its OpenAPI payload schema.\n * Single source of truth for \"what events get written to the log.\"\n */\ntype PersistedEventCatalog = {\n 'yield:created': components['schemas']['ResourceCreatedPayload'];\n 'yield:cloned': components['schemas']['ResourceClonedPayload'];\n 'yield:updated': components['schemas']['ResourceUpdatedPayload'];\n 'yield:moved': components['schemas']['ResourceMovedPayload'];\n 'yield:representation-added': components['schemas']['RepresentationAddedPayload'];\n 'yield:representation-removed': components['schemas']['RepresentationRemovedPayload'];\n 'mark:added': AnnotationAddedPayload;\n 'mark:removed': AnnotationRemovedPayload;\n 'mark:body-updated': AnnotationBodyUpdatedPayload;\n 'mark:archived': components['schemas']['ResourceArchivedPayload'];\n 'mark:unarchived': components['schemas']['ResourceUnarchivedPayload'];\n 'mark:entity-tag-added': components['schemas']['EntityTagChangedPayload'];\n 'mark:entity-tag-removed': components['schemas']['EntityTagChangedPayload'];\n 'frame:entity-type-added': components['schemas']['EntityTypeAddedPayload'];\n 'frame:tag-schema-added': components['schemas']['TagSchemaAddedPayload'];\n 'job:started': components['schemas']['JobStartedPayload'];\n 'job:progress': components['schemas']['JobProgressPayload'];\n 'job:completed': components['schemas']['JobCompletedPayload'];\n 'job:failed': components['schemas']['JobFailedPayload'];\n};\n\n// ── Derived types ────────────────────────────────────────────────────────────\n\n/** System event types — persisted events that have no resourceId. */\ntype SystemEventType = 'frame:entity-type-added' | 'frame:tag-schema-added';\n\n/** Extract the concrete persisted event type for a given type string. */\nexport type EventOfType<K extends keyof PersistedEventCatalog> =\n K extends SystemEventType\n ? EventBase & { type: K; payload: PersistedEventCatalog[K] }\n : EventBase & { type: K; resourceId: ResourceId; payload: PersistedEventCatalog[K] };\n\n/** The union of all persisted event types. Discriminated on `type`. */\nexport type PersistedEvent = {\n [K in keyof PersistedEventCatalog]: EventOfType<K>\n}[keyof PersistedEventCatalog];\n\nexport type PersistedEventType = PersistedEvent['type'];\n\n/**\n * Runtime list of every persisted event type.\n *\n * Single source of truth for code that needs to enumerate event types at\n * runtime — most importantly the per-resource `events-stream` SSE route,\n * which subscribes to all of them. The exhaustiveness check below makes\n * it impossible to add a new member to `PersistedEventCatalog` without\n * also adding it here: forgetting fails to typecheck rather than silently\n * dropping the event from the events-stream.\n */\nexport const PERSISTED_EVENT_TYPES = [\n 'yield:created',\n 'yield:cloned',\n 'yield:updated',\n 'yield:moved',\n 'yield:representation-added',\n 'yield:representation-removed',\n 'mark:added',\n 'mark:removed',\n 'mark:body-updated',\n 'mark:archived',\n 'mark:unarchived',\n 'mark:entity-tag-added',\n 'mark:entity-tag-removed',\n 'frame:entity-type-added',\n 'frame:tag-schema-added',\n 'job:started',\n 'job:progress',\n 'job:completed',\n 'job:failed',\n] as const satisfies readonly PersistedEventType[];\n\n// Compile-time exhaustiveness: if PersistedEventType gains a member that\n// PERSISTED_EVENT_TYPES is missing, this assignment fails to typecheck.\n// The ERROR object names the missing-member case so the build error is\n// self-explanatory.\ntype _ExhaustivePersistedEventTypes =\n Exclude<PersistedEventType, typeof PERSISTED_EVENT_TYPES[number]> extends never\n ? true\n : { ERROR: 'PERSISTED_EVENT_TYPES is missing members of PersistedEventType' };\nconst _persistedEventTypesExhaustive: _ExhaustivePersistedEventTypes = true;\nvoid _persistedEventTypesExhaustive;\n\n/** Input type for appendEvent — PersistedEvent without id/timestamp (assigned at persistence time). */\nexport type EventInput = Omit<PersistedEvent, 'id' | 'timestamp'>;\n","/**\n * Bus Protocol\n *\n * The complete EventMap for the RxJS EventBus. Every channel name and\n * its payload type is defined here — domain events, commands, reads,\n * results, SSE stream payloads, and frontend UI events.\n *\n * Identifier discipline: where a payload carries an annotation or\n * resource id, the TypeScript layer narrows the OpenAPI `string` to the\n * branded type (`AnnotationId`, `ResourceId`, `UserId`). The runtime\n * wire shape is unchanged (brands have no runtime representation);\n * what this buys us is that command handlers don't have to re-brand\n * at every seam. Brand once at the entry boundary (HTTP route handler,\n * DOM attribute read, URL param parse), not at every bus hop in\n * between. See `.plans/BRAND-UPSTREAM.md` for the rationale.\n *\n * Organized by flow (verb), then by category within each flow.\n */\n\nimport type { components } from './types';\nimport type { AnnotationId, ResourceId } from './identifiers';\nimport type { StoredEvent } from './event-base';\nimport type { EventOfType } from './persisted-events';\n\n// Branded overrides for OpenAPI command payloads that carry identifier\n// fields. Narrows `string` → branded at the TypeScript layer.\n//\n// `_userId` is the gateway-injected authenticated DID (string at the\n// schema layer); handlers that need a `UserId` brand it locally.\ntype MarkDeleteCommand =\n components['schemas']['MarkDeleteCommand'] & {\n annotationId: AnnotationId;\n resourceId?: ResourceId;\n };\ntype MarkUpdateBodyCommand =\n components['schemas']['MarkUpdateBodyCommand'] & {\n annotationId: AnnotationId;\n resourceId: ResourceId;\n };\ntype BindInitiateCommand =\n components['schemas']['BindInitiateCommand'] & {\n annotationId: AnnotationId;\n resourceId: ResourceId;\n };\ntype BindUpdateBodyCommand =\n components['schemas']['BindUpdateBodyCommand'] & {\n annotationId: AnnotationId;\n resourceId: ResourceId;\n };\n\n/**\n * The unified EventMap — every channel on the EventBus.\n *\n * Convention:\n * - Domain events (past tense): StoredEvent<Interface> — branded types\n * - Commands/reads/results/UI: OpenAPI schema refs — plain strings\n * - void: UI-only signals with no payload\n */\nexport type EventMap = {\n\n // ========================================================================\n // YIELD FLOW — resource creation, update, move, clone\n // ========================================================================\n\n // Domain events (branded — system of record)\n 'yield:created': StoredEvent<EventOfType<'yield:created'>>;\n 'yield:cloned': StoredEvent<EventOfType<'yield:cloned'>>;\n 'yield:updated': StoredEvent<EventOfType<'yield:updated'>>;\n 'yield:moved': StoredEvent<EventOfType<'yield:moved'>>;\n 'yield:representation-added': StoredEvent<EventOfType<'yield:representation-added'>>;\n 'yield:representation-removed': StoredEvent<EventOfType<'yield:representation-removed'>>;\n\n // Generation lifecycle flows through the unified job:* family\n // (job:start, job:report-progress, job:complete, job:fail). The\n // pre-unification `yield:progress`/`yield:finished`/`yield:failed`\n // channels were removed on the lifecycle-unification.\n\n // Commands\n 'yield:create': components['schemas']['YieldCreateCommand'];\n 'yield:update': components['schemas']['YieldUpdateCommand'];\n 'yield:mv': components['schemas']['YieldMvCommand'];\n 'yield:clone': void;\n 'yield:clone-token-requested': components['schemas']['YieldCloneTokenRequest'];\n 'yield:clone-resource-requested': components['schemas']['YieldCloneResourceRequest'];\n 'yield:clone-create': components['schemas']['YieldCloneCreateCommand'];\n\n // Command results\n 'yield:create-ok': components['schemas']['YieldCreateOk'];\n 'yield:create-failed': components['schemas']['CommandError'];\n 'yield:update-ok': components['schemas']['YieldUpdateOk'];\n 'yield:update-failed': components['schemas']['YieldUpdateOk'] & components['schemas']['CommandError'];\n 'yield:move-ok': components['schemas']['YieldMoveOk'];\n 'yield:move-failed': { fromUri: string } & components['schemas']['CommandError'];\n 'yield:clone-token-generated': { correlationId: string; response: components['schemas']['CloneResourceWithTokenResponse'] };\n 'yield:clone-token-failed': { correlationId: string } & components['schemas']['CommandError'];\n 'yield:clone-resource-result': { correlationId: string; response: components['schemas']['GetResourceByTokenResponse'] };\n 'yield:clone-resource-failed': { correlationId: string } & components['schemas']['CommandError'];\n 'yield:clone-created': components['schemas']['YieldCloneCreated'];\n 'yield:clone-create-failed': { correlationId: string } & components['schemas']['CommandError'];\n\n // ========================================================================\n // MARK FLOW — annotation CRUD, AI assist, resource lifecycle\n // ========================================================================\n\n // Domain events (branded — system of record)\n 'mark:added': StoredEvent<EventOfType<'mark:added'>>;\n 'mark:removed': StoredEvent<EventOfType<'mark:removed'>>;\n 'mark:body-updated': StoredEvent<EventOfType<'mark:body-updated'>>;\n 'mark:entity-tag-added': StoredEvent<EventOfType<'mark:entity-tag-added'>>;\n 'mark:entity-tag-removed': StoredEvent<EventOfType<'mark:entity-tag-removed'>>;\n 'mark:archived': StoredEvent<EventOfType<'mark:archived'>>;\n 'mark:unarchived': StoredEvent<EventOfType<'mark:unarchived'>>;\n\n // Annotation-job lifecycle flows through the unified job:* family\n // (job:start, job:report-progress, job:complete, job:fail). UI\n // consumers filter by jobType. The pre-unification channels\n // `mark:progress`/`mark:assist-finished`/`mark:assist-failed` were\n // removed on the lifecycle-unification.\n\n // Commands\n 'mark:create-request': components['schemas']['MarkCreateRequest'];\n 'mark:create': components['schemas']['MarkCreateCommand'];\n 'mark:delete': MarkDeleteCommand;\n 'mark:update-body': MarkUpdateBodyCommand;\n 'mark:archive': components['schemas']['MarkArchiveCommand'];\n 'mark:unarchive': components['schemas']['MarkUnarchiveCommand'];\n 'mark:update-entity-types': components['schemas']['MarkUpdateEntityTypesCommand'];\n\n // Command results\n 'mark:create-ok': components['schemas']['MarkCreateOk'];\n 'mark:create-failed': components['schemas']['CommandError'];\n 'mark:delete-ok': components['schemas']['MarkDeleteOk'];\n 'mark:delete-failed': components['schemas']['CommandError'];\n 'mark:body-update-failed': components['schemas']['CommandError'];\n\n // UI events\n 'mark:select-comment': components['schemas']['SelectionData'];\n 'mark:select-tag': components['schemas']['SelectionData'];\n 'mark:select-assessment': components['schemas']['SelectionData'];\n 'mark:select-reference': components['schemas']['SelectionData'];\n 'mark:requested': components['schemas']['MarkRequestedEvent'];\n 'mark:cancel-pending': void;\n 'mark:submit': components['schemas']['MarkSubmitEvent'];\n 'mark:assist-request': components['schemas']['MarkAssistRequestEvent'];\n 'mark:assist-cancelled': void;\n 'mark:progress-dismiss': void;\n 'mark:mode-toggled': void;\n 'mark:selection-changed': components['schemas']['MarkSelectionChangedEvent'];\n 'mark:click-changed': components['schemas']['MarkClickChangedEvent'];\n 'mark:shape-changed': components['schemas']['MarkShapeChangedEvent'];\n\n // ========================================================================\n // FRAME FLOW — schema-layer vocabulary (entity types; future tag schemas,\n // relation/predicate types, ontology import). The eighth flow.\n // ========================================================================\n\n // Domain events (branded — system of record). System-level: no resourceId.\n 'frame:entity-type-added': StoredEvent<EventOfType<'frame:entity-type-added'>>;\n 'frame:tag-schema-added': StoredEvent<EventOfType<'frame:tag-schema-added'>>;\n\n // Commands\n 'frame:add-entity-type': components['schemas']['FrameAddEntityTypeCommand'];\n 'frame:add-tag-schema': components['schemas']['FrameAddTagSchemaCommand'];\n\n // Command results\n 'frame:entity-type-add-failed': components['schemas']['CommandError'];\n 'frame:tag-schema-add-failed': components['schemas']['CommandError'];\n\n // ========================================================================\n // BIND FLOW — reference linking\n // ========================================================================\n\n 'bind:initiate': BindInitiateCommand;\n 'bind:update-body': BindUpdateBodyCommand;\n 'bind:body-updated': components['schemas']['BindBodyUpdated'];\n 'bind:body-update-failed': components['schemas']['CommandError'];\n\n // ========================================================================\n // MATCH FLOW — search\n // ========================================================================\n\n 'match:search-requested': components['schemas']['MatchSearchRequest'];\n 'match:search-results': components['schemas']['MatchSearchResult'];\n 'match:search-failed': components['schemas']['MatchSearchFailed'];\n\n // ========================================================================\n // GATHER FLOW — context gathering\n // ========================================================================\n\n 'gather:requested': components['schemas']['GatherAnnotationRequest'];\n 'gather:complete': components['schemas']['GatherAnnotationComplete'];\n 'gather:failed': { correlationId: string; annotationId: string } & components['schemas']['CommandError'];\n 'gather:resource-requested': components['schemas']['GatherResourceRequest'];\n 'gather:resource-complete': components['schemas']['GatherResourceComplete'];\n 'gather:resource-failed': { correlationId: string; resourceId: string } & components['schemas']['CommandError'];\n\n 'gather:summary-requested': components['schemas']['GatherSummaryRequest'];\n 'gather:summary-result': { correlationId: string; response: Record<string, unknown> };\n 'gather:summary-failed': { correlationId: string } & components['schemas']['CommandError'];\n\n // SSE stream payloads\n 'gather:annotation-progress': components['schemas']['GatherProgress'];\n 'gather:annotation-finished': components['schemas']['GatherAnnotationFinished'];\n 'gather:progress': components['schemas']['GatherProgress'];\n 'gather:finished': components['schemas']['GatherFinished'];\n\n // ========================================================================\n // BROWSE FLOW — knowledge base reads + UI navigation\n // ========================================================================\n\n // Reads\n 'browse:resource-requested': components['schemas']['BrowseResourceRequest'];\n 'browse:resource-result': components['schemas']['BrowseResourceResult'];\n 'browse:resource-failed': { correlationId: string } & components['schemas']['CommandError'];\n\n 'browse:resources-requested': components['schemas']['BrowseResourcesRequest'];\n 'browse:resources-result': components['schemas']['BrowseResourcesResult'];\n 'browse:resources-failed': { correlationId: string } & components['schemas']['CommandError'];\n\n 'browse:annotations-requested': components['schemas']['BrowseAnnotationsRequest'];\n 'browse:annotations-result': components['schemas']['BrowseAnnotationsResult'];\n 'browse:annotations-failed': { correlationId: string } & components['schemas']['CommandError'];\n\n 'browse:annotation-requested': components['schemas']['BrowseAnnotationRequest'];\n 'browse:annotation-result': components['schemas']['BrowseAnnotationResult'];\n 'browse:annotation-failed': { correlationId: string } & components['schemas']['CommandError'];\n\n 'browse:events-requested': components['schemas']['BrowseEventsRequest'];\n 'browse:events-result': components['schemas']['BrowseEventsResult'];\n 'browse:events-failed': { correlationId: string } & components['schemas']['CommandError'];\n\n 'browse:annotation-history-requested': components['schemas']['BrowseAnnotationHistoryRequest'];\n 'browse:annotation-history-result': components['schemas']['BrowseAnnotationHistoryResult'];\n 'browse:annotation-history-failed': { correlationId: string } & components['schemas']['CommandError'];\n\n 'browse:annotation-context-requested': components['schemas']['BrowseAnnotationContextRequest'];\n 'browse:annotation-context-result': { correlationId: string; response: Record<string, unknown> };\n 'browse:annotation-context-failed': { correlationId: string } & components['schemas']['CommandError'];\n\n 'browse:referenced-by-requested': components['schemas']['BrowseReferencedByRequest'];\n 'browse:referenced-by-result': components['schemas']['BrowseReferencedByResult'];\n 'browse:referenced-by-failed': { correlationId: string } & components['schemas']['CommandError'];\n\n 'browse:entity-types-requested': components['schemas']['BrowseEntityTypesRequest'];\n 'browse:entity-types-result': components['schemas']['BrowseEntityTypesResult'];\n 'browse:entity-types-failed': { correlationId: string } & components['schemas']['CommandError'];\n\n 'browse:tag-schemas-requested': components['schemas']['BrowseTagSchemasRequest'];\n 'browse:tag-schemas-result': components['schemas']['BrowseTagSchemasResult'];\n 'browse:tag-schemas-failed': { correlationId: string } & components['schemas']['CommandError'];\n\n 'browse:directory-requested': components['schemas']['BrowseDirectoryRequest'];\n 'browse:directory-result': components['schemas']['BrowseDirectoryResult'];\n 'browse:directory-failed': { correlationId: string; path: string } & components['schemas']['CommandError'];\n\n // UI events (session-scoped — fire on the client bus, tied to a KB)\n 'browse:click': components['schemas']['BrowseClickEvent'];\n 'browse:reference-navigate': components['schemas']['BrowseReferenceNavigateEvent'];\n 'browse:entity-type-clicked': components['schemas']['BrowseEntityTypeClickedEvent'];\n\n // ========================================================================\n // SHELL — app-scoped UI events (fire on SemiontBrowser's bus, not the\n // per-session client bus). These must work regardless of whether a\n // KB session is active: panel toggles, sidebar, tab bar, routing.\n // ========================================================================\n\n 'panel:toggle': components['schemas']['BrowsePanelToggleEvent'];\n 'panel:open': components['schemas']['BrowsePanelOpenEvent'];\n 'panel:close': void;\n 'shell:sidebar-toggle': void;\n 'tabs:close': components['schemas']['BrowseResourceCloseEvent'];\n 'tabs:reorder': components['schemas']['BrowseResourceReorderEvent'];\n 'nav:link-clicked': components['schemas']['BrowseLinkClickedEvent'];\n 'nav:push': components['schemas']['BrowseRouterPushEvent'];\n 'nav:external': components['schemas']['BrowseExternalNavigateEvent'] & { cancelFallback: () => void };\n\n // ========================================================================\n // BECKON FLOW — annotation attention\n // ========================================================================\n\n 'beckon:hover': components['schemas']['BeckonHoverEvent'];\n 'beckon:focus': components['schemas']['BeckonFocusEvent'];\n 'beckon:sparkle': components['schemas']['BeckonSparkleEvent'];\n\n // ========================================================================\n // JOB FLOW — worker commands + domain events\n // ========================================================================\n\n // Domain events (branded — system of record)\n 'job:started': StoredEvent<EventOfType<'job:started'>>;\n 'job:progress': StoredEvent<EventOfType<'job:progress'>>;\n 'job:completed': StoredEvent<EventOfType<'job:completed'>>;\n 'job:failed': StoredEvent<EventOfType<'job:failed'>>;\n\n // Commands\n 'job:start': components['schemas']['JobStartCommand'];\n 'job:report-progress': components['schemas']['JobReportProgressCommand'];\n 'job:complete': components['schemas']['JobCompleteCommand'];\n 'job:fail': components['schemas']['JobFailCommand'];\n 'job:queued': components['schemas']['JobQueuedEvent'];\n 'job:cancel-requested': components['schemas']['JobCancelRequest'];\n 'job:status-requested': components['schemas']['JobStatusRequest'];\n 'job:create': components['schemas']['JobCreateCommand'];\n 'job:claim': components['schemas']['JobClaimCommand'];\n\n // Results\n 'job:status-result': components['schemas']['JobStatusResult'];\n 'job:status-failed': { correlationId: string } & components['schemas']['CommandError'];\n 'job:created': components['schemas']['JobCreatedResult'];\n 'job:create-failed': { correlationId: string } & components['schemas']['CommandError'];\n 'job:claimed': { correlationId: string; response: Record<string, unknown> };\n 'job:claim-failed': { correlationId: string } & components['schemas']['CommandError'];\n\n // ========================================================================\n // SETTINGS (frontend-only)\n // ========================================================================\n\n 'settings:theme-changed': components['schemas']['SettingsThemeChangedEvent'];\n 'settings:line-numbers-toggled': void;\n 'settings:locale-changed': components['schemas']['SettingsLocaleChangedEvent'];\n 'settings:hover-delay-changed': components['schemas']['SettingsHoverDelayChangedEvent'];\n\n // ========================================================================\n // SSE infrastructure\n // ========================================================================\n\n 'stream-connected': Record<string, never>;\n 'replay-window-exceeded': { resourceId?: string; lastEventId: number; missedCount: number; cap: number; message: string };\n /**\n * Emitted by the `/bus/subscribe` handler when a client reconnected\n * with `Last-Event-ID: p-<scope>-<seq>` but the server could not\n * replay all missed persisted events for that scope (retention\n * window exceeded, scope unknown, or request unparseable). The\n * client should treat this as a signal to fall back to the pre-\n * resumption contract: invalidate caches for the affected scope\n * and re-read from scratch. Analogous to `replay-window-exceeded`\n * but scoped to the bus gateway rather than the per-resource\n * events stream.\n *\n * `scope` is the scope string the client asked about (omitted for\n * global-persisted resumption gaps, if that path ever exists).\n * `reason` is human-readable, for logging.\n */\n 'bus:resume-gap': { scope?: string; lastSeenId?: string; reason: string };\n};\n\n/** Any valid channel name on the EventBus. */\nexport type EventName = keyof EventMap;\n\n/**\n * Genuine resource-bound broadcast event types.\n *\n * Publishers emit these on the scoped EventBus (`eventBus.scope(resourceId)`)\n * because every participant viewing the resource should receive them — not\n * just the caller who triggered the originating action. Examples: resource\n * generation progress, which multiple viewers of a generating resource all\n * want to see.\n *\n * Non-broadcast progress (AI-assist progress for one user, search results\n * for one caller) does NOT belong here. Those are per-caller correlation-ID\n * responses and publish globally — the caller filters by `correlationId`.\n *\n * The SDK's resource-scoped `browse.*` live queries wire these channels —\n * subscribing acquires the scope via the transport's `subscribeToResource`\n * (`scope=id&scoped=<channel>`) so the SSE route delivers them to that\n * participant (freshness follows observation; #847). WorkerStateUnit uses this\n * list to decide which emitted events to scope to their resource.\n */\nexport const RESOURCE_BROADCAST_TYPES = [\n // Currently empty. `job:complete` / `job:fail` were moved to GLOBAL,\n // `jobId`-keyed correlation delivery (#847): the dispatching caller\n // filters by `jobId`, and resource viewers filter the same global stream\n // by `resourceId` — no resource-scoped copy, so a client that is both\n // dispatcher and viewer no longer receives it twice. This set remains as\n // the extension point for *genuine* resource-bound broadcasts — events\n // every viewer of a resource should see and no single caller owns (e.g.\n // resource-generation progress for multiple viewers).\n] as const satisfies readonly EventName[];\n\nexport type ResourceBroadcastType = typeof RESOURCE_BROADCAST_TYPES[number];\n\n/**\n * Authoritative map from bus channel to OpenAPI schema name.\n *\n * Every {@link EventName} must appear. The `satisfies` clause below\n * enforces completeness at compile time — adding a channel to\n * {@link EventMap} without adding an entry here is a build error.\n *\n * Values:\n * - `<SchemaName>`: payload validates against `components['schemas'][SchemaName]`.\n * - `null`: no single-schema validation. Used for branded\n * `StoredEvent` wrappers, `void` UI signals, and compound inline\n * types (e.g. `{ correlationId } & CommandError`). These are not\n * validated by `/bus/emit`.\n *\n * The `/bus/emit` route reads this map to validate incoming payloads.\n * Consumers can also use it to do client-side pre-flight validation\n * before emitting.\n */\nexport const CHANNEL_SCHEMAS = {\n // ── YIELD FLOW ──────────────────────────────────────────────────\n 'yield:created': null, // StoredEvent\n 'yield:cloned': null,\n 'yield:updated': null,\n 'yield:moved': null,\n 'yield:representation-added': null,\n 'yield:representation-removed': null,\n 'yield:create': 'YieldCreateCommand',\n 'yield:update': 'YieldUpdateCommand',\n 'yield:mv': 'YieldMvCommand',\n 'yield:clone': null, // void\n 'yield:clone-token-requested': 'YieldCloneTokenRequest',\n 'yield:clone-resource-requested': 'YieldCloneResourceRequest',\n 'yield:clone-create': 'YieldCloneCreateCommand',\n 'yield:create-ok': 'YieldCreateOk',\n 'yield:create-failed': 'CommandError',\n 'yield:update-ok': 'YieldUpdateOk',\n 'yield:update-failed': null, // YieldUpdateOk & CommandError\n 'yield:move-ok': 'YieldMoveOk',\n 'yield:move-failed': null, // { fromUri } & CommandError\n 'yield:clone-token-generated': null, // { correlationId; response: CloneResourceWithTokenResponse }\n 'yield:clone-token-failed': null, // { correlationId } & CommandError\n 'yield:clone-resource-result': null, // { correlationId; response: GetResourceByTokenResponse }\n 'yield:clone-resource-failed': null, // { correlationId } & CommandError\n 'yield:clone-created': 'YieldCloneCreated',\n 'yield:clone-create-failed': null, // { correlationId } & CommandError\n\n // ── MARK FLOW ───────────────────────────────────────────────────\n 'mark:added': null, // StoredEvent\n 'mark:removed': null,\n 'mark:body-updated': null,\n 'mark:entity-tag-added': null,\n 'mark:entity-tag-removed': null,\n 'frame:entity-type-added': null,\n 'frame:tag-schema-added': null,\n 'mark:archived': null,\n 'mark:unarchived': null,\n 'mark:create-request': 'MarkCreateRequest',\n 'mark:create': 'MarkCreateCommand',\n 'mark:delete': 'MarkDeleteCommand',\n 'mark:update-body': 'MarkUpdateBodyCommand',\n 'mark:archive': 'MarkArchiveCommand',\n 'mark:unarchive': 'MarkUnarchiveCommand',\n 'mark:update-entity-types': 'MarkUpdateEntityTypesCommand',\n 'frame:add-entity-type': 'FrameAddEntityTypeCommand',\n 'frame:add-tag-schema': 'FrameAddTagSchemaCommand',\n 'mark:create-ok': 'MarkCreateOk',\n 'mark:create-failed': 'CommandError',\n 'mark:delete-ok': 'MarkDeleteOk',\n 'mark:delete-failed': 'CommandError',\n 'mark:body-update-failed': 'CommandError',\n 'frame:entity-type-add-failed': 'CommandError',\n 'frame:tag-schema-add-failed': 'CommandError',\n 'mark:select-comment': 'SelectionData',\n 'mark:select-tag': 'SelectionData',\n 'mark:select-assessment': 'SelectionData',\n 'mark:select-reference': 'SelectionData',\n 'mark:requested': 'MarkRequestedEvent',\n 'mark:cancel-pending': null, // void\n 'mark:submit': 'MarkSubmitEvent',\n 'mark:assist-request': 'MarkAssistRequestEvent',\n 'mark:assist-cancelled': null, // void\n 'mark:progress-dismiss': null, // void\n 'mark:mode-toggled': null, // void\n 'mark:selection-changed': 'MarkSelectionChangedEvent',\n 'mark:click-changed': 'MarkClickChangedEvent',\n 'mark:shape-changed': 'MarkShapeChangedEvent',\n\n // ── BIND FLOW ───────────────────────────────────────────────────\n 'bind:initiate': 'BindInitiateCommand',\n 'bind:update-body': 'BindUpdateBodyCommand',\n 'bind:body-updated': 'BindBodyUpdated',\n 'bind:body-update-failed': 'CommandError',\n\n // ── MATCH FLOW ──────────────────────────────────────────────────\n 'match:search-requested': 'MatchSearchRequest',\n 'match:search-results': 'MatchSearchResult',\n 'match:search-failed': 'MatchSearchFailed',\n\n // ── GATHER FLOW ─────────────────────────────────────────────────\n 'gather:requested': 'GatherAnnotationRequest',\n 'gather:complete': 'GatherAnnotationComplete',\n 'gather:failed': null, // { correlationId; annotationId } & CommandError\n 'gather:resource-requested': 'GatherResourceRequest',\n 'gather:resource-complete': 'GatherResourceComplete',\n 'gather:resource-failed': null, // { correlationId; resourceId } & CommandError\n 'gather:summary-requested': 'GatherSummaryRequest',\n 'gather:summary-result': null, // { correlationId; response: Record<string, unknown> }\n 'gather:summary-failed': null, // { correlationId } & CommandError\n 'gather:annotation-progress': 'GatherProgress',\n 'gather:annotation-finished': 'GatherAnnotationFinished',\n 'gather:progress': 'GatherProgress',\n 'gather:finished': 'GatherFinished',\n\n // ── BROWSE FLOW ─────────────────────────────────────────────────\n 'browse:resource-requested': 'BrowseResourceRequest',\n 'browse:resource-result': 'BrowseResourceResult',\n 'browse:resource-failed': null, // { correlationId } & CommandError\n 'browse:resources-requested': 'BrowseResourcesRequest',\n 'browse:resources-result': 'BrowseResourcesResult',\n 'browse:resources-failed': null,\n 'browse:annotations-requested': 'BrowseAnnotationsRequest',\n 'browse:annotations-result': 'BrowseAnnotationsResult',\n 'browse:annotations-failed': null,\n 'browse:annotation-requested': 'BrowseAnnotationRequest',\n 'browse:annotation-result': 'BrowseAnnotationResult',\n 'browse:annotation-failed': null,\n 'browse:events-requested': 'BrowseEventsRequest',\n 'browse:events-result': 'BrowseEventsResult',\n 'browse:events-failed': null,\n 'browse:annotation-history-requested': 'BrowseAnnotationHistoryRequest',\n 'browse:annotation-history-result': 'BrowseAnnotationHistoryResult',\n 'browse:annotation-history-failed': null,\n 'browse:annotation-context-requested': 'BrowseAnnotationContextRequest',\n 'browse:annotation-context-result': null, // { correlationId; response: Record<string, unknown> }\n 'browse:annotation-context-failed': null,\n 'browse:referenced-by-requested': 'BrowseReferencedByRequest',\n 'browse:referenced-by-result': 'BrowseReferencedByResult',\n 'browse:referenced-by-failed': null,\n 'browse:entity-types-requested': 'BrowseEntityTypesRequest',\n 'browse:entity-types-result': 'BrowseEntityTypesResult',\n 'browse:entity-types-failed': null,\n 'browse:tag-schemas-requested': 'BrowseTagSchemasRequest',\n 'browse:tag-schemas-result': 'BrowseTagSchemasResult',\n 'browse:tag-schemas-failed': null,\n 'browse:directory-requested': 'BrowseDirectoryRequest',\n 'browse:directory-result': 'BrowseDirectoryResult',\n 'browse:directory-failed': null, // { correlationId; path } & CommandError\n 'browse:click': 'BrowseClickEvent',\n 'browse:reference-navigate': 'BrowseReferenceNavigateEvent',\n 'browse:entity-type-clicked': 'BrowseEntityTypeClickedEvent',\n\n // ── SHELL (app-scoped UI events, fire on SemiontBrowser bus) ────\n 'panel:toggle': 'BrowsePanelToggleEvent',\n 'panel:open': 'BrowsePanelOpenEvent',\n 'panel:close': null, // void\n 'shell:sidebar-toggle': null, // void\n 'tabs:close': 'BrowseResourceCloseEvent',\n 'tabs:reorder': 'BrowseResourceReorderEvent',\n 'nav:link-clicked': 'BrowseLinkClickedEvent',\n 'nav:push': 'BrowseRouterPushEvent',\n 'nav:external': null, // includes runtime `cancelFallback: () => void`\n\n // ── BECKON FLOW ─────────────────────────────────────────────────\n 'beckon:hover': 'BeckonHoverEvent',\n 'beckon:focus': 'BeckonFocusEvent',\n 'beckon:sparkle': 'BeckonSparkleEvent',\n\n // ── JOB FLOW ────────────────────────────────────────────────────\n 'job:started': null, // StoredEvent\n 'job:progress': null,\n 'job:completed': null,\n 'job:failed': null,\n 'job:start': 'JobStartCommand',\n 'job:report-progress': 'JobReportProgressCommand',\n 'job:complete': 'JobCompleteCommand',\n 'job:fail': 'JobFailCommand',\n 'job:queued': 'JobQueuedEvent',\n 'job:cancel-requested': 'JobCancelRequest',\n 'job:status-requested': 'JobStatusRequest',\n 'job:create': 'JobCreateCommand',\n 'job:claim': 'JobClaimCommand',\n 'job:status-result': 'JobStatusResult',\n 'job:status-failed': null, // { correlationId } & CommandError\n 'job:created': 'JobCreatedResult',\n 'job:create-failed': null,\n 'job:claimed': null, // { correlationId; response: Record<string, unknown> }\n 'job:claim-failed': null,\n\n // ── SETTINGS (frontend-only) ────────────────────────────────────\n 'settings:theme-changed': 'SettingsThemeChangedEvent',\n 'settings:line-numbers-toggled': null, // void\n 'settings:locale-changed': 'SettingsLocaleChangedEvent',\n 'settings:hover-delay-changed': 'SettingsHoverDelayChangedEvent',\n\n // ── SSE infrastructure ──────────────────────────────────────────\n 'stream-connected': null, // Record<string, never>\n 'replay-window-exceeded': null, // inline payload\n 'bus:resume-gap': null, // inline payload\n} as const satisfies Record<EventName, keyof components['schemas'] | null>;\n\n/** Channels where `/bus/emit` validates the payload (non-null schema). */\nexport type EmittableChannel = {\n [K in EventName]: typeof CHANNEL_SCHEMAS[K] extends null ? never : K\n}[EventName];\n","/**\n * Event Type Guards and Extraction Utilities\n *\n * Domain logic for working with resource events.\n * No React dependencies - safe to use in any JavaScript environment.\n */\n\nimport type { StoredEvent } from './event-base';\nimport type { AnnotationUri } from './branded-types';\n\n/**\n * Minimal event shape accepted by event utility functions.\n * Compatible with both the internal `StoredEvent` type and the OpenAPI-derived\n * schema type (`GetEventsResponse['events'][number]`), which lacks `version`.\n *\n * Flat shape — event fields and metadata are peers (no `event` wrapper).\n */\nexport interface StoredEventLike {\n id: string;\n type: string; // Intentionally loose — accepts OpenAPI-derived types where type is string\n timestamp: string;\n userId: string;\n resourceId?: string;\n payload?: unknown;\n metadata: {\n sequenceNumber: number;\n };\n}\n\n// =============================================================================\n// EVENT TYPE GUARDS AND EXTRACTION\n// =============================================================================\n\n/**\n * Extract annotation ID from event payload\n * Returns null if event is not annotation-related\n *\n * For mark:added: extracts full URI from payload.annotation.id\n * For mark:removed/mark:body-updated: constructs full URI from payload.annotationId (UUID) + resourceId\n */\nexport function getAnnotationUriFromEvent(event: StoredEventLike): AnnotationUri | null {\n const payload = event.payload as Record<string, any> | undefined;\n\n if (event.type === 'mark:added') {\n return payload?.annotation?.id as AnnotationUri || null;\n }\n\n if (event.type === 'mark:removed' || event.type === 'mark:body-updated') {\n if (payload?.annotationId && event.resourceId) {\n try {\n const resourceUri = event.resourceId;\n const baseUrl = resourceUri.substring(0, resourceUri.lastIndexOf('/resources/'));\n return `${baseUrl}/annotations/${payload.annotationId}` as AnnotationUri;\n } catch (e) {\n return null;\n }\n }\n }\n\n return null;\n}\n\n/**\n * Check if an event is related to a specific annotation\n */\nexport function isEventRelatedToAnnotation(event: StoredEventLike, annotationUri: AnnotationUri): boolean {\n const eventAnnotationUri = getAnnotationUriFromEvent(event);\n return eventAnnotationUri === annotationUri;\n}\n\n/**\n * Type guard to check if an object is a StoredEvent (flat shape)\n */\nexport function isStoredEvent(event: any): event is StoredEvent {\n return event &&\n typeof event.id === 'string' &&\n typeof event.timestamp === 'string' &&\n typeof event.type === 'string' &&\n typeof event.metadata === 'object' &&\n typeof event.metadata.sequenceNumber === 'number';\n}\n\n","/**\n * Bus logging — runtime-toggleable cross-wire visibility.\n *\n * One line per event that crosses a process boundary, in a grep-able\n * format that's symmetric across frontend and backend:\n *\n * [bus EMIT] <channel> [scope=X] [cid=<first8>] <payload>\n * [bus RECV] <channel> [scope=X] [cid=<first8>] <payload>\n * [bus SSE] <channel> [scope=X] [cid=<first8>] <payload>\n *\n * Tier 1 of `.plans/OBSERVABILITY.md`. Forward-compatible with Tier 2:\n * the `cid` printed here is exactly the prefix of the W3C trace-id we\n * adopt later.\n *\n * Cost when disabled: one property read per call, zero allocations.\n *\n * Enable:\n * - Browser: `window.__SEMIONT_BUS_LOG__ = true` (DevTools or e2e init)\n * - Node: `SEMIONT_BUS_LOG=1` in the process env (read at module load)\n */\n\nconst NODE_BUS_LOG =\n typeof process !== 'undefined' && !!process.env?.SEMIONT_BUS_LOG;\n\nexport type BusOp = 'EMIT' | 'RECV' | 'SSE' | 'PUT' | 'GET';\n\nexport function busLogEnabled(): boolean {\n const g = globalThis as { __SEMIONT_BUS_LOG__?: boolean };\n if (g.__SEMIONT_BUS_LOG__) return true;\n return NODE_BUS_LOG;\n}\n\n/**\n * Optional active-span trace-id provider. When a Tier 2 OTel SDK is\n * initialized, `@semiont/observability` registers a provider here that\n * returns the active span's W3C `trace_id`. busLog appends it to each\n * emitted line so the grep-timeline correlates with the span tree in\n * an APM UI.\n *\n * Decoupling: `@semiont/core` does not depend on `@opentelemetry/api`.\n * If no provider is registered (Tier 1-only deployments, or before\n * `initObservabilityNode` runs), the field is omitted from the line —\n * same shape as before this hook existed.\n */\nlet traceIdProvider: (() => string | undefined) | undefined;\n\nexport function setBusLogTraceIdProvider(fn: (() => string | undefined) | undefined): void {\n traceIdProvider = fn;\n}\n\nexport function busLog(\n op: BusOp,\n channel: string,\n payload: unknown,\n scope?: string,\n): void {\n if (!busLogEnabled()) return;\n const cidRaw = (payload as { correlationId?: unknown } | null | undefined)?.correlationId;\n const cid = typeof cidRaw === 'string' ? cidRaw.slice(0, 8) : undefined;\n let traceId: string | undefined;\n if (traceIdProvider) {\n try { traceId = traceIdProvider(); } catch { /* noop */ }\n }\n const tag =\n `[bus ${op}] ${channel}` +\n (scope ? ` scope=${scope}` : '') +\n (cid ? ` cid=${cid}` : '') +\n (traceId ? ` trace=${traceId.slice(0, 8)}` : '');\n // eslint-disable-next-line no-console\n console.debug(tag, payload);\n}\n","/**\n * RxJS-based Event Bus\n *\n * Framework-agnostic event bus providing direct access to typed RxJS Subjects.\n *\n * Can be used in Node.js, browser, workers, CLI - anywhere RxJS runs.\n */\n\nimport { Subject } from 'rxjs';\nimport { busLog, busLogEnabled } from './bus-log';\nimport type { EventMap } from './bus-protocol';\nimport type { StoredEvent } from './event-base';\nimport type { PersistedEventType } from './persisted-events';\n\n/**\n * RxJS-based event bus\n *\n * Provides direct access to RxJS Subjects for each event type.\n * Use standard RxJS patterns for emitting and subscribing.\n *\n * @example\n * ```typescript\n * const eventBus = new EventBus();\n *\n * // Emit events\n * eventBus.get('beckon:hover').next({ annotationId: 'ann-1' });\n *\n * // Subscribe to events\n * const subscription = eventBus.get('beckon:hover').subscribe(({ annotationId }) => {\n * console.log('Hover:', annotationId);\n * });\n *\n * // Use RxJS operators\n * import { debounceTime } from 'rxjs/operators';\n * eventBus.get('beckon:hover')\n * .pipe(debounceTime(100))\n * .subscribe(handleHover);\n *\n * // Cleanup\n * subscription.unsubscribe();\n * eventBus.destroy();\n * ```\n */\nexport class EventBus {\n private subjects: Map<keyof EventMap, Subject<any>>;\n private isDestroyed: boolean;\n\n constructor() {\n this.subjects = new Map();\n this.isDestroyed = false;\n }\n\n /**\n * Get the RxJS Subject for an event\n *\n * Returns a typed Subject that can be used with all RxJS operators.\n * Subjects are created lazily on first access.\n *\n * @param eventName - The event name\n * @returns The RxJS Subject for this event\n *\n * @example\n * ```typescript\n * // Emit\n * eventBus.get('beckon:hover').next({ annotationId: 'ann-1' });\n *\n * // Subscribe\n * const sub = eventBus.get('beckon:hover').subscribe(handleHover);\n *\n * // With operators\n * eventBus.get('beckon:hover')\n * .pipe(debounceTime(100), distinctUntilChanged())\n * .subscribe(handleHover);\n * ```\n */\n get<K extends keyof EventMap>(eventName: K): Subject<EventMap[K]> {\n if (this.isDestroyed) {\n throw new Error(`Cannot access event '${String(eventName)}' on destroyed bus`);\n }\n\n if (!this.subjects.has(eventName)) {\n const subject = new Subject<EventMap[K]>();\n // When bus-log is enabled (`SEMIONT_BUS_LOG=1` or\n // `window.__SEMIONT_BUS_LOG__ = true`), wrap `.next()` so every\n // local emit on this channel produces a `[bus EMIT] <channel> ...`\n // line on `console.debug` — same shape as cross-wire emits from\n // HttpTransport. This is what makes local-only fan-out signals\n // (`beckon.hover`, `beckon.sparkle`, `mark.changeShape`, etc.)\n // visible to the e2e bus capture and to a developer's DevTools.\n // The `busLogEnabled()` check is at first-`get` time per channel;\n // setting the flag after channels are constructed won't\n // retroactively wrap them. The bus capture fixture uses\n // `addInitScript` so the flag is set before any namespace\n // construction, which is when `get()` is first called.\n if (busLogEnabled()) {\n const originalNext = subject.next.bind(subject);\n subject.next = (value: EventMap[K]): void => {\n busLog('EMIT', String(eventName), value as object);\n originalNext(value);\n };\n }\n this.subjects.set(eventName, subject);\n }\n return this.subjects.get(eventName)!;\n }\n\n /**\n * Get the RxJS Subject for a domain event type (PersistedEventType).\n *\n * Domain event channels carry `StoredEvent`. This method avoids the need\n * for `as keyof EventMap` casts when subscribing to domain event channels\n * using runtime `PersistedEventType` strings.\n */\n getDomainEvent(eventType: PersistedEventType): Subject<StoredEvent> {\n return this.get(eventType as keyof EventMap) as unknown as Subject<StoredEvent>;\n }\n\n /**\n * Destroy the event bus and complete all subjects\n *\n * After calling destroy(), no new events can be emitted or subscribed to.\n * All active subscriptions will be completed.\n */\n destroy(): void {\n if (this.isDestroyed) {\n return;\n }\n\n for (const subject of this.subjects.values()) {\n subject.complete();\n }\n\n this.subjects.clear();\n this.isDestroyed = true;\n }\n\n /**\n * Check if the event bus has been destroyed\n */\n get destroyed(): boolean {\n return this.isDestroyed;\n }\n\n /**\n * Create a resource-scoped event bus\n *\n * Events emitted or subscribed through the scoped bus are isolated to that resource.\n * Internally, events are namespaced but the API remains identical to the parent bus.\n *\n * @param resourceId - Resource identifier to scope events to\n * @returns A scoped event bus for this resource\n *\n * @example\n * ```typescript\n * const eventBus = new EventBus();\n * const resource1 = eventBus.scope('resource-1');\n * const resource2 = eventBus.scope('resource-2');\n *\n * // These are isolated - only resource1 subscribers will fire\n * resource1.get('detection:progress').next({ status: 'started' });\n * ```\n */\n scope(resourceId: string): ScopedEventBus {\n return new ScopedEventBus(this, resourceId);\n }\n}\n\n/**\n * Resource-scoped event bus\n *\n * Provides isolated event streams per resource while maintaining the same API\n * as the parent EventBus. Events are internally namespaced by resourceId.\n */\nexport class ScopedEventBus {\n constructor(\n private parent: EventBus,\n private scopePrefix: string\n ) {}\n\n /**\n * Get the RxJS Subject for a scoped event\n *\n * Returns the same type as the parent bus, but events are isolated to this scope.\n * Internally uses namespaced keys but preserves type safety.\n *\n * @param event - The event name\n * @returns The RxJS Subject for this scoped event\n */\n get<E extends keyof EventMap>(event: E): Subject<EventMap[E]> {\n // Internally namespace the event key, but preserve return type\n const scopedKey = `${this.scopePrefix}:${event as string}`;\n\n // Access parent's subjects map directly (needs cast for private access)\n const parentSubjects = (this.parent as any).subjects as Map<string, Subject<any>>;\n\n if (!parentSubjects.has(scopedKey)) {\n parentSubjects.set(scopedKey, new Subject<EventMap[E]>());\n }\n return parentSubjects.get(scopedKey)!;\n }\n\n /** Get the RxJS Subject for a domain event type on this scoped bus. */\n getDomainEvent(eventType: PersistedEventType): Subject<StoredEvent> {\n return this.get(eventType as keyof EventMap) as unknown as Subject<StoredEvent>;\n }\n\n /**\n * Create a nested scope\n *\n * Allows hierarchical scoping like `resource-1:subsystem-a`\n *\n * @param subScope - Additional scope level\n * @returns A nested scoped event bus\n */\n scope(subScope: string): ScopedEventBus {\n return new ScopedEventBus(this.parent, `${this.scopePrefix}:${subScope}`);\n }\n}\n","/**\n * Adaptive burst buffer RxJS operator.\n *\n * Passes the first event through immediately (zero latency for interactive use).\n * If more events arrive within the burst window, switches to accumulate mode\n * and flushes batches. Returns to passthrough mode after an idle period.\n *\n * Emits individual items (T) in passthrough mode and arrays (T[]) in batch mode.\n * Consumers distinguish via Array.isArray().\n *\n * Threshold tuning:\n * burstWindowMs — How long to wait for more events before flushing a batch.\n * 50ms is a good default: longer than event-loop jitter (~1-5ms)\n * but short enough to feel responsive.\n * maxBatchSize — Force-flush at this size to bound memory. 500 is safe for\n * Neo4j UNWIND queries. Increase if graph writes are cheap.\n * idleTimeoutMs — How long after the last flush before returning to passthrough.\n * 200ms is a good default. Must be >= burstWindowMs.\n *\n * See: BATCH-GRAPH-CONSUMER-RX.md for design rationale.\n * See: packages/graph/docs/ARCHITECTURE.md for graph consumer context.\n */\n\nimport { Observable, OperatorFunction } from 'rxjs';\n\nexport interface BurstBufferOptions {\n /**\n * Time window (ms) to detect burst activity after an event.\n * If another event arrives within this window, it is buffered.\n * The buffer flushes when no new event arrives for this duration (debounce).\n *\n * Recommended: 50ms.\n */\n burstWindowMs: number;\n\n /**\n * Maximum events to accumulate before forcing a flush.\n * Prevents unbounded memory growth during sustained bursts.\n *\n * Recommended: 500.\n */\n maxBatchSize: number;\n\n /**\n * Time (ms) of silence after the last flush before returning to passthrough mode.\n * The next event after this timeout emits immediately (leading edge).\n * Must be >= burstWindowMs.\n *\n * Recommended: 200ms.\n */\n idleTimeoutMs: number;\n}\n\n/**\n * Adaptive burst buffer operator.\n *\n * State machine:\n * PASSTHROUGH → event arrives → emit immediately, transition to ACCUMULATING\n * ACCUMULATING → event arrives → buffer it, reset burst timer\n * ACCUMULATING → burst timer fires (no new events for burstWindowMs) → flush buffer as T[]\n * ACCUMULATING → buffer reaches maxBatchSize → flush buffer as T[]\n * After flush → idle timer starts\n * Idle timer fires (no new events for idleTimeoutMs) → transition to PASSTHROUGH\n */\nexport function burstBuffer<T>(\n options: BurstBufferOptions\n): OperatorFunction<T, T | T[]> {\n const { burstWindowMs, maxBatchSize, idleTimeoutMs } = options;\n\n return (source: Observable<T>) =>\n new Observable<T | T[]>((subscriber) => {\n let mode: 'passthrough' | 'accumulating' = 'passthrough';\n let buffer: T[] = [];\n let burstTimer: ReturnType<typeof setTimeout> | null = null;\n let idleTimer: ReturnType<typeof setTimeout> | null = null;\n\n function clearBurstTimer() {\n if (burstTimer !== null) {\n clearTimeout(burstTimer);\n burstTimer = null;\n }\n }\n\n function clearIdleTimer() {\n if (idleTimer !== null) {\n clearTimeout(idleTimer);\n idleTimer = null;\n }\n }\n\n function flush() {\n if (buffer.length === 0) return;\n const batch = buffer;\n buffer = [];\n subscriber.next(batch);\n }\n\n function startIdleTimer() {\n clearIdleTimer();\n idleTimer = setTimeout(() => {\n idleTimer = null;\n mode = 'passthrough';\n }, idleTimeoutMs);\n }\n\n const subscription = source.subscribe({\n next(value: T) {\n clearIdleTimer();\n\n if (mode === 'passthrough') {\n // Leading edge: emit immediately\n subscriber.next(value);\n // Transition to accumulating — next event within burstWindowMs gets buffered\n mode = 'accumulating';\n // Start a burst timer: if nothing else arrives, start idle countdown\n burstTimer = setTimeout(() => {\n burstTimer = null;\n flush(); // flush anything accumulated (normally empty at this point)\n startIdleTimer();\n }, burstWindowMs);\n return;\n }\n\n // mode === 'accumulating'\n buffer.push(value);\n\n // Reset the burst window timer (debounce pattern)\n clearBurstTimer();\n\n if (buffer.length >= maxBatchSize) {\n // Force flush at max batch size\n flush();\n startIdleTimer();\n } else {\n // Debounce: flush after burstWindowMs of silence\n burstTimer = setTimeout(() => {\n burstTimer = null;\n flush();\n startIdleTimer();\n }, burstWindowMs);\n }\n },\n\n error(err) {\n clearBurstTimer();\n clearIdleTimer();\n flush();\n subscriber.error(err);\n },\n\n complete() {\n clearBurstTimer();\n clearIdleTimer();\n flush();\n subscriber.complete();\n },\n });\n\n // Teardown: clean up timers and unsubscribe from source\n return () => {\n clearBurstTimer();\n clearIdleTimer();\n subscription.unsubscribe();\n };\n });\n}\n","/**\n * serializePerKey — run async work serialized per key, parallel across keys.\n *\n * Invariant: two calls with the same `key` run strictly in sequence (the\n * second `work` does not start until the first has settled). Calls with\n * different keys overlap freely.\n *\n * Error isolation: a rejected work function does not poison subsequent\n * tasks for the same key. The next task starts fresh from whatever state\n * the failed task left behind. The rejection still propagates to *this*\n * caller.\n *\n * Registry cleanup: the entry for a key is removed as soon as its chain\n * empties, so the Map stays bounded by the number of keys with work\n * currently in flight, not by the total number of keys ever seen.\n *\n * ## Usage\n *\n * ```ts\n * const chains = new Map<string, Promise<void>>();\n *\n * async function write(resourceId: string, event: Event) {\n * return serializePerKey(resourceId, chains, async () => {\n * // Read-modify-write on a view file. Any two concurrent calls with\n * // the same resourceId will be serialized; different resourceIds\n * // will proceed in parallel.\n * const view = await viewStorage.get(resourceId);\n * applyEvent(view, event);\n * await viewStorage.save(resourceId, view);\n * });\n * }\n * ```\n *\n * ## When to use this vs RxJS `groupBy + concatMap`\n *\n * Use `serializePerKey` when the work arrives as **direct method calls**\n * that need to block the caller until completion. This is the RPC shape\n * — think `EventStore.appendEvent` calling `await views.materializeResource(...)`\n * and needing the view written before any subscriber sees the published\n * event.\n *\n * Use RxJS `groupBy(keyFn) + concatMap(...)` when the work arrives as an\n * **event stream** that a component subscribes to once at startup. This\n * is how `Smelter`, `GraphDBConsumer`, and `Gatherer` serialize their own\n * per-resource work — see their implementations in `packages/make-meaning`.\n *\n * Both patterns solve the same logical problem (\"serialize work per key\").\n * The choice is dictated by whether the caller is awaiting the result.\n */\nexport async function serializePerKey<K, T>(\n key: K,\n chains: Map<K, Promise<void>>,\n work: () => Promise<T>,\n): Promise<T> {\n const prev = chains.get(key) ?? Promise.resolve();\n\n // Chain onto prev, swallowing any error from the previous link so one\n // bad task doesn't poison subsequent ones for the same key. The new\n // link's own errors still propagate to our caller via `await next`.\n let result: T;\n const next = prev\n .catch(() => { /* prior failure doesn't block us */ })\n .then(async () => {\n result = await work();\n });\n\n chains.set(key, next);\n\n try {\n await next;\n return result!;\n } finally {\n // Only clear the entry if we're still the tail. If another caller\n // has already chained onto us, leave it so the chain stays intact.\n if (chains.get(key) === next) {\n chains.delete(key);\n }\n }\n}\n","/**\n * Logger interface for observability\n *\n * This interface is intentionally framework-agnostic to work with any logger\n * (winston, pino, bunyan, or simple console).\n *\n * Example usage:\n * ```typescript\n * import winston from 'winston';\n *\n * const logger = winston.createLogger({\n * level: 'debug',\n * transports: [new winston.transports.Console()]\n * });\n *\n * const service = new MyService(logger);\n * ```\n */\nexport interface Logger {\n debug(message: string, meta?: any): void;\n info(message: string, meta?: any): void;\n warn(message: string, meta?: any): void;\n error(message: string, meta?: any): void;\n child(meta: Record<string, any>): Logger;\n}\n\n/**\n * Serialize an error value into a form that JSON.stringify can handle\n * meaningfully.\n *\n * Winston's default JSON formatter serializes `Error` instances as `{}`\n * because `message`, `stack`, and `name` are non-enumerable properties on\n * the Error prototype. That means `logger.error('x', { error })` with a\n * raw Error argument produces useless log lines like\n * `{\"error\":{},\"message\":\"x\",...}`, throwing away the information you\n * actually need to diagnose the failure.\n *\n * This helper extracts the parts you want to see in a log — name,\n * message, stack, and cause — and leaves non-Error values alone (so\n * strings, numbers, and plain objects pass through unchanged).\n *\n * ## Usage\n *\n * ```ts\n * try {\n * await doSomething();\n * } catch (error) {\n * logger.error('Something failed', { error: errField(error) });\n * }\n * ```\n *\n * Use this at every `logger.error` call site that includes an `error`\n * field derived from a catch block. Raw `{ error }` without this helper\n * is almost always a bug.\n */\nexport function errField(error: unknown): unknown {\n if (error instanceof Error) {\n return {\n name: error.name,\n message: error.message,\n stack: error.stack,\n ...(error.cause !== undefined && { cause: errField(error.cause) }),\n };\n }\n return error;\n}\n","/**\n * Annotation body utilities\n *\n * These are the matcher primitives used by the `mark:body-updated` event\n * replay path (ViewMaterializer and GraphDBConsumer) to apply add/remove/\n * replace operations against an annotation body.\n */\n\nimport type { components } from './types';\nimport type { Annotation } from './annotation-types';\n\ntype BodyPurpose = components['schemas']['BodyPurpose'];\n\n/**\n * Identity of a body item for matching purposes.\n *\n * Identity is `type + source` for SpecificResource and `type + value` for\n * TextualBody. `purpose` is OPTIONAL: if the caller provides it, it's\n * included in the match (used to disambiguate same-source bodies under\n * different purposes, per the W3C Web Annotation model). If the caller\n * omits it, the matcher ignores purpose and matches on identity alone.\n *\n * Callers SHOULD provide `purpose` when they know it (e.g., the bind flow\n * always unlinks a `purpose: 'linking'` body) so that future multi-purpose\n * annotations continue to disambiguate correctly. Leaving `purpose`\n * unspecified matches whichever purpose comes first in the body — which is\n * fine today because Semiont annotations currently have at most one body\n * item per (type, source/value) pair.\n */\nexport type BodyItemIdentity =\n | { type: 'SpecificResource'; source: string; purpose?: BodyPurpose }\n | { type: 'TextualBody'; value: string; purpose?: BodyPurpose };\n\n/**\n * Find a body item by identity. Returns the index of the first match, or -1.\n *\n * See `BodyItemIdentity` for matching semantics.\n */\nexport function findBodyItem(\n body: Annotation['body'],\n identity: BodyItemIdentity,\n): number {\n if (!Array.isArray(body)) {\n return -1;\n }\n\n for (let i = 0; i < body.length; i++) {\n const item = body[i];\n\n if (typeof item !== 'object' || item === null || !('type' in item)) {\n continue;\n }\n\n const itemType = (item as { type: unknown }).type;\n if (itemType !== identity.type) {\n continue;\n }\n\n // Identity field match (source or value)\n if (identity.type === 'SpecificResource') {\n if (!('source' in item)) continue;\n const itemSource = (item as { source: unknown }).source;\n if (itemSource !== identity.source) continue;\n } else {\n if (!('value' in item)) continue;\n const itemValue = (item as { value: unknown }).value;\n if (itemValue !== identity.value) continue;\n }\n\n // Purpose match — ONLY if the caller specified one. Omitted purpose\n // means \"any purpose on this identity\", which is what the bind-flow\n // unlinker wants today.\n if (identity.purpose !== undefined) {\n const itemPurpose = (item as { purpose?: unknown }).purpose;\n if (itemPurpose !== identity.purpose) continue;\n }\n\n return i;\n }\n\n return -1;\n}\n","/**\n * ID generation utilities\n */\n\n// crypto.randomUUID() is available as a global in Node 14.17+ and all modern browsers.\n// Declared here because the core package tsconfig uses lib:ES2022 (no dom types).\ndeclare const crypto: { randomUUID(): string };\n\n/**\n * Generate a UUID v4 string (without dashes)\n */\nexport function generateUuid(): string {\n return crypto.randomUUID().replace(/-/g, '');\n}\n","/**\n * Annotation Assembly\n *\n * Pure functions for building W3C Annotations and applying body operations.\n * No EventBus, no persistence — just data transformation.\n */\n\nimport type { components } from './types';\nimport type { Selector } from './payload-types';\nimport type { Annotation } from './annotation-types';\nimport { annotationId } from './identifiers';\nimport { generateUuid } from './id-generation';\n\ntype Agent = components['schemas']['Agent'];\ntype AnnotationBody = components['schemas']['AnnotationBody'];\ntype CreateAnnotationRequest = components['schemas']['CreateAnnotationRequest'];\ntype UpdateAnnotationBodyRequest = components['schemas']['UpdateAnnotationBodyRequest'];\ntype TextPositionSelector = components['schemas']['TextPositionSelector'];\ntype SvgSelector = components['schemas']['SvgSelector'];\ntype FragmentSelector = components['schemas']['FragmentSelector'];\n\nexport interface AssembledAnnotation {\n annotation: Annotation;\n bodyArray: AnnotationBody[];\n}\n\n// =============================================================================\n// Selector utilities used by assembleAnnotation\n// =============================================================================\n\n/**\n * Get TextPositionSelector from a selector (single or array)\n */\nexport function getTextPositionSelector(selector: Selector | Selector[] | undefined): TextPositionSelector | null {\n if (!selector) return null;\n const selectors = Array.isArray(selector) ? selector : [selector];\n const found = selectors.find(s => s.type === 'TextPositionSelector');\n if (!found) return null;\n return found.type === 'TextPositionSelector' ? found : null;\n}\n\n/**\n * Get SvgSelector from a selector (single or array)\n */\nexport function getSvgSelector(selector: Selector | Selector[] | undefined): SvgSelector | null {\n if (!selector) return null;\n const selectors = Array.isArray(selector) ? selector : [selector];\n const found = selectors.find(s => s.type === 'SvgSelector');\n if (!found) return null;\n return found.type === 'SvgSelector' ? found : null;\n}\n\n/**\n * Get FragmentSelector from a selector (single or array)\n */\nexport function getFragmentSelector(selector: Selector | Selector[] | undefined): FragmentSelector | null {\n if (!selector) return null;\n const selectors = Array.isArray(selector) ? selector : [selector];\n const found = selectors.find(s => s.type === 'FragmentSelector');\n if (!found) return null;\n return found.type === 'FragmentSelector' ? found : null;\n}\n\n/**\n * Validate SVG markup for W3C compliance\n *\n * @returns null if valid, error message if invalid\n */\nexport function validateSvgMarkup(svg: string): string | null {\n if (!svg.includes('xmlns=\"http://www.w3.org/2000/svg\"')) {\n return 'SVG must include xmlns=\"http://www.w3.org/2000/svg\" attribute';\n }\n\n if (!svg.includes('<svg') || !svg.includes('</svg>')) {\n return 'SVG must have opening and closing tags';\n }\n\n const shapeElements = ['rect', 'circle', 'ellipse', 'polygon', 'polyline', 'path', 'line'];\n const hasShape = shapeElements.some(shape =>\n svg.includes(`<${shape}`) || svg.includes(`<${shape} `)\n );\n\n if (!hasShape) {\n return 'SVG must contain at least one shape element (rect, circle, ellipse, polygon, polyline, path, or line)';\n }\n\n return null;\n}\n\n// =============================================================================\n// Annotation assembly\n// =============================================================================\n\n/**\n * Build a complete W3C Annotation from a CreateAnnotationRequest.\n *\n * Generates a bare annotation ID (no URL prefix). URIs are constructed\n * at the API boundary when returning responses to clients.\n *\n * Throws on invalid input (missing selector, missing motivation, invalid SVG).\n */\nexport function assembleAnnotation(\n request: CreateAnnotationRequest,\n creator: Agent,\n): AssembledAnnotation {\n const newAnnotationId = annotationId(generateUuid());\n\n // Validate selector: must have TextPositionSelector, SvgSelector, or FragmentSelector\n const posSelector = getTextPositionSelector(request.target.selector);\n const svgSelector = getSvgSelector(request.target.selector);\n const fragmentSelector = getFragmentSelector(request.target.selector);\n\n if (!posSelector && !svgSelector && !fragmentSelector) {\n throw new Error('Either TextPositionSelector, SvgSelector, or FragmentSelector is required for creating annotations');\n }\n\n // Validate SVG markup if SvgSelector is provided\n if (svgSelector) {\n const svgError = validateSvgMarkup(svgSelector.value);\n if (svgError) {\n throw new Error(`Invalid SVG markup: ${svgError}`);\n }\n }\n\n if (!request.motivation) {\n throw new Error('motivation is required');\n }\n\n const now = new Date().toISOString();\n const annotation: Annotation = {\n '@context': 'http://www.w3.org/ns/anno.jsonld' as const,\n 'type': 'Annotation' as const,\n id: newAnnotationId,\n motivation: request.motivation,\n target: request.target,\n body: request.body as Annotation['body'],\n creator,\n created: now,\n modified: now,\n };\n\n const bodyArray = (Array.isArray(request.body) ? request.body : request.body ? [request.body] : []) as AnnotationBody[];\n\n return { annotation, bodyArray };\n}\n\n/**\n * Apply body operations (add/remove/replace) to an annotation's body array.\n * Returns a new array — does not mutate the input.\n */\nexport function applyBodyOperations(\n body: Annotation['body'],\n operations: UpdateAnnotationBodyRequest['operations'],\n): AnnotationBody[] {\n const bodyArray = Array.isArray(body) ? [...body] : [];\n\n for (const op of operations) {\n if (op.op === 'add') {\n const exists = bodyArray.some(item =>\n JSON.stringify(item) === JSON.stringify(op.item)\n );\n if (!exists) {\n bodyArray.push(op.item);\n }\n } else if (op.op === 'remove') {\n const index = bodyArray.findIndex(item =>\n JSON.stringify(item) === JSON.stringify(op.item)\n );\n if (index !== -1) {\n bodyArray.splice(index, 1);\n }\n } else if (op.op === 'replace') {\n const index = bodyArray.findIndex(item =>\n JSON.stringify(item) === JSON.stringify(op.oldItem)\n );\n if (index !== -1) {\n bodyArray[index] = op.newItem;\n }\n }\n }\n\n return bodyArray;\n}\n","/**\n * Annotation and Selector Utilities\n *\n * Pure TypeScript utilities for working with W3C Web Annotations.\n * No React dependencies - safe to use in any JavaScript environment.\n *\n * Body is either empty array (stub) or single SpecificResource (resolved)\n * Body can be array of TextualBody (tagging) + SpecificResource (linking)\n * Target can be simple string IRI or object with source and optional selector\n */\n\nimport type { components } from './types';\nimport type { Selector } from './payload-types';\nimport type { Annotation } from './annotation-types';\n\n// Re-export selector utilities (canonical location is annotation-assembly)\nexport {\n getTextPositionSelector,\n getSvgSelector,\n getFragmentSelector,\n validateSvgMarkup,\n} from './annotation-assembly';\ntype HighlightAnnotation = Annotation;\ntype ReferenceAnnotation = Annotation;\ntype TextPositionSelector = components['schemas']['TextPositionSelector'];\ntype TextQuoteSelector = components['schemas']['TextQuoteSelector'];\ntype SvgSelector = components['schemas']['SvgSelector'];\ntype FragmentSelector = components['schemas']['FragmentSelector'];\n\n// Re-export selector types for convenience\nexport type { TextPositionSelector, TextQuoteSelector, SvgSelector, FragmentSelector, Selector };\n\n/**\n * Get the source from an annotation body (null if stub)\n * Search for SpecificResource in body array\n */\nexport function getBodySource(body: Annotation['body']): string | null {\n if (Array.isArray(body)) {\n // Search for SpecificResource with source\n for (const item of body) {\n if (\n typeof item === 'object' &&\n item !== null &&\n 'type' in item &&\n 'source' in item\n ) {\n const itemType = (item as { type: unknown }).type;\n const itemSource = (item as { source: unknown }).source;\n\n if (itemType === 'SpecificResource' && typeof itemSource === 'string') {\n return itemSource;\n }\n }\n }\n return null; // No SpecificResource found = stub\n }\n\n // Single body object (SpecificResource)\n if (\n typeof body === 'object' &&\n body !== null &&\n 'type' in body &&\n 'source' in body\n ) {\n const bodyType = (body as { type: unknown }).type;\n const bodySource = (body as { source: unknown }).source;\n\n if (bodyType === 'SpecificResource' && typeof bodySource === 'string') {\n return bodySource;\n }\n }\n\n return null;\n}\n\n/**\n * Get the type from an annotation body (returns first body type in array)\n */\nexport function getBodyType(body: Annotation['body']): 'TextualBody' | 'SpecificResource' | null {\n if (Array.isArray(body)) {\n if (body.length === 0) {\n return null;\n }\n // Return type of first body item\n if (typeof body[0] === 'object' && body[0] !== null && 'type' in body[0]) {\n const firstType = (body[0] as { type: unknown }).type;\n if (firstType === 'TextualBody' || firstType === 'SpecificResource') {\n return firstType;\n }\n }\n return null;\n }\n\n // Single body object\n if (typeof body === 'object' && body !== null && 'type' in body) {\n const bodyType = (body as { type: unknown }).type;\n if (bodyType === 'TextualBody' || bodyType === 'SpecificResource') {\n return bodyType;\n }\n }\n\n return null;\n}\n\n/**\n * Check if body is resolved (has a source)\n * Check for SpecificResource in body array\n */\nexport function isBodyResolved(body: Annotation['body']): boolean {\n return getBodySource(body) !== null;\n}\n\n/**\n * Get the source IRI from target (handles both string and object forms)\n */\nexport function getTargetSource(target: Annotation['target']): string {\n if (typeof target === 'string') {\n return target;\n }\n return target.source;\n}\n\n/**\n * Get the selector from target (undefined if string or no selector)\n */\nexport function getTargetSelector(target: Annotation['target']) {\n if (typeof target === 'string') {\n return undefined;\n }\n return target.selector;\n}\n\n/**\n * Check if target has a selector\n */\nexport function hasTargetSelector(target: Annotation['target']): boolean {\n return typeof target !== 'string' && target.selector !== undefined;\n}\n\n/**\n * Type guard to check if an annotation is a highlight\n */\nexport function isHighlight(annotation: Annotation): annotation is HighlightAnnotation {\n return annotation.motivation === 'highlighting';\n}\n\n/**\n * Type guard to check if an annotation is a reference (linking)\n */\nexport function isReference(annotation: Annotation): annotation is ReferenceAnnotation {\n return annotation.motivation === 'linking';\n}\n\n/**\n * Type guard to check if an annotation is an assessment\n */\nexport function isAssessment(annotation: Annotation): annotation is Annotation {\n return annotation.motivation === 'assessing';\n}\n\n/**\n * Type guard to check if an annotation is a comment\n */\nexport function isComment(annotation: Annotation): annotation is Annotation {\n return annotation.motivation === 'commenting';\n}\n\n/**\n * Type guard to check if an annotation is a tag\n */\nexport function isTag(annotation: Annotation): annotation is Annotation {\n return annotation.motivation === 'tagging';\n}\n\n/**\n * Extract comment text from a comment annotation's body\n * @param annotation - The annotation to extract comment text from\n * @returns The comment text, or undefined if not a comment or no text found\n */\nexport function getCommentText(annotation: Annotation): string | undefined {\n if (!isComment(annotation)) return undefined;\n const body = Array.isArray(annotation.body) ? annotation.body[0] : annotation.body;\n if (body && 'value' in body) {\n return body.value;\n }\n return undefined;\n}\n\n/**\n * Type guard to check if a reference annotation is a stub (unresolved)\n * Stub if no SpecificResource in body array\n */\nexport function isStubReference(annotation: Annotation): boolean {\n return isReference(annotation) && !isBodyResolved(annotation.body);\n}\n\n/**\n * Type guard to check if a reference annotation is resolved\n * Resolved if SpecificResource exists in body array\n */\nexport function isResolvedReference(annotation: Annotation): annotation is ReferenceAnnotation {\n return isReference(annotation) && isBodyResolved(annotation.body);\n}\n\n// =============================================================================\n// SELECTOR UTILITIES\n// =============================================================================\n\n/**\n * Get the exact text from a selector (single or array)\n *\n * When selector is an array, tries to find a TextQuoteSelector (which has exact text).\n * TextPositionSelector does not have exact text, only character offsets.\n * Handles undefined selector (when target is a string IRI with no selector)\n */\nexport function getExactText(selector: Selector | Selector[] | undefined): string {\n if (!selector) {\n return ''; // No selector means entire resource\n }\n const selectors = Array.isArray(selector) ? selector : [selector];\n\n // Try to find TextQuoteSelector (has exact text)\n const quoteSelector = selectors.find(s => s.type === 'TextQuoteSelector') as TextQuoteSelector | undefined;\n if (quoteSelector) {\n return quoteSelector.exact;\n }\n\n // No TextQuoteSelector found\n return '';\n}\n\n/**\n * Get the exact text from an annotation's target selector\n * Uses getTargetSelector helper to safely get selector\n */\nexport function getAnnotationExactText(annotation: Annotation): string {\n const selector = getTargetSelector(annotation.target);\n return getExactText(selector as Selector | Selector[] | undefined);\n}\n\n/**\n * Get the primary selector from a selector (single or array)\n *\n * When selector is an array, returns the first selector.\n * When selector is a single object, returns it as-is.\n */\nexport function getPrimarySelector(selector: Selector | Selector[]): Selector {\n if (Array.isArray(selector)) {\n if (selector.length === 0) {\n throw new Error('Empty selector array');\n }\n const first = selector[0];\n if (!first) {\n throw new Error('Invalid selector array');\n }\n return first;\n }\n return selector;\n}\n\n/**\n * Get TextQuoteSelector from a selector (single or array)\n *\n * Returns the first TextQuoteSelector found, or null if none exists.\n */\nexport function getTextQuoteSelector(selector: Selector | Selector[]): TextQuoteSelector | null {\n const selectors = Array.isArray(selector) ? selector : [selector];\n const found = selectors.find(s => s.type === 'TextQuoteSelector');\n if (!found) return null;\n return found.type === 'TextQuoteSelector' ? found : null;\n}\n\n/**\n * Extract bounding box from SVG markup\n *\n * Attempts to extract x, y, width, height from the SVG viewBox or root element.\n * Returns null if bounding box cannot be determined.\n */\nexport function extractBoundingBox(svg: string): { x: number; y: number; width: number; height: number } | null {\n // Try to extract viewBox attribute from SVG element\n const viewBoxMatch = svg.match(/<svg[^>]*viewBox=\"([^\"]+)\"/);\n if (viewBoxMatch) {\n const values = viewBoxMatch[1].split(/\\s+/).map(parseFloat);\n if (values.length === 4 && values.every(v => !isNaN(v))) {\n return {\n x: values[0],\n y: values[1],\n width: values[2],\n height: values[3]\n };\n }\n }\n\n // Try to extract width/height attributes from SVG element (assume x=0, y=0)\n const svgTagMatch = svg.match(/<svg[^>]*>/);\n if (svgTagMatch) {\n const svgTag = svgTagMatch[0];\n const widthMatch = svgTag.match(/width=\"([^\"]+)\"/);\n const heightMatch = svgTag.match(/height=\"([^\"]+)\"/);\n\n if (widthMatch && heightMatch) {\n const width = parseFloat(widthMatch[1]);\n const height = parseFloat(heightMatch[1]);\n\n if (!isNaN(width) && !isNaN(height)) {\n return { x: 0, y: 0, width, height };\n }\n }\n }\n\n return null;\n}\n","/**\n * PDF viewrect FragmentSelector codec.\n *\n * `PdfCoordinate` is a bounding rectangle in PDF point space: origin at the\n * bottom-left of the page, Y increasing upward. The Y-flip to canvas pixels\n * lives in the browser (`react-ui`); the server has no canvas.\n *\n * These functions are the viewrect peer of the W3C `FragmentSelector` wrapper in\n * `web-annotation-utils`: they serialize/parse the RFC 3778\n * `page=N&viewrect=left,top,width,height` value. `@semiont/content` (geometry\n * from the text layer), `@semiont/jobs` (serialization at write time), and the\n * browser canvas all import them from here — no package reaches into the UI.\n *\n * RFC 3778 PDF Fragment Identifiers: https://tools.ietf.org/html/rfc3778\n */\n\n/**\n * A bounding rectangle in PDF point coordinates.\n * Origin at the bottom-left of the page; Y increases upward.\n */\nexport interface PdfCoordinate {\n page: number;\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\n/**\n * Serialize a PdfCoordinate to an RFC 3778 FragmentSelector value.\n * Format: `page=N&viewrect=left,top,width,height` (all in PDF points).\n */\nexport function createFragmentSelector(coord: PdfCoordinate): string {\n return `page=${coord.page}&viewrect=${coord.x},${coord.y},${coord.width},${coord.height}`;\n}\n\n/**\n * Parse an RFC 3778 FragmentSelector value into PDF coordinates.\n * Returns null when the value is not a well-formed page + viewrect fragment.\n */\nexport function parseFragmentSelector(fragment: string): PdfCoordinate | null {\n const pageMatch = fragment.match(/page=(\\d+)/);\n if (!pageMatch) return null;\n\n // Each coordinate: optional sign, integer part, optional fraction — tight enough\n // to round-trip negatives and reject malformed numbers (e.g. \"1.2.3\").\n const viewrectMatch = fragment.match(\n /viewrect=(-?\\d+(?:\\.\\d+)?),(-?\\d+(?:\\.\\d+)?),(-?\\d+(?:\\.\\d+)?),(-?\\d+(?:\\.\\d+)?)/\n );\n if (!viewrectMatch) return null;\n\n return {\n page: parseInt(pageMatch[1], 10),\n x: parseFloat(viewrectMatch[1]),\n y: parseFloat(viewrectMatch[2]),\n width: parseFloat(viewrectMatch[3]),\n height: parseFloat(viewrectMatch[4]),\n };\n}\n\n/** Extract the 1-indexed page number from a FragmentSelector value. */\nexport function getPageFromFragment(fragment: string): number | null {\n const match = fragment.match(/page=(\\d+)/);\n return match ? parseInt(match[1], 10) : null;\n}\n","/**\n * Helper functions for working with W3C ResourceDescriptor\n */\n\nimport type { components } from './types';\nimport type { ResourceDescriptor } from './graph';\n\ntype Representation = components['schemas']['Representation'];\n\n/**\n * Get the resource ID from @id property\n *\n * @id is always a bare ID (UUID), never a full URI.\n */\nexport function getResourceId(resource: ResourceDescriptor | undefined): string | undefined {\n if (!resource) return undefined;\n return resource['@id'] || undefined;\n}\n\n/**\n * Get the primary representation (first or only representation)\n */\nexport function getPrimaryRepresentation(resource: ResourceDescriptor | undefined): Representation | undefined {\n if (!resource?.representations) return undefined;\n const reps = Array.isArray(resource.representations)\n ? resource.representations\n : [resource.representations];\n return reps[0];\n}\n\n/**\n * Get the media type from the primary representation\n */\nexport function getPrimaryMediaType(resource: ResourceDescriptor | undefined): string | undefined {\n return getPrimaryRepresentation(resource)?.mediaType;\n}\n\n/**\n * Get the checksum from the primary representation\n */\nexport function getChecksum(resource: ResourceDescriptor | undefined): string | undefined {\n return getPrimaryRepresentation(resource)?.checksum;\n}\n\n/**\n * Get the language from the primary representation\n */\nexport function getLanguage(resource: ResourceDescriptor | undefined): string | undefined {\n return getPrimaryRepresentation(resource)?.language;\n}\n\n/**\n * Get storage URI from primary representation\n *\n * @param resource - ResourceDescriptor\n * @returns Storage URI or undefined\n */\nexport function getStorageUri(resource: ResourceDescriptor | undefined): string | undefined {\n return getPrimaryRepresentation(resource)?.storageUri;\n}\n\n/**\n * Get creator agent from wasAttributedTo\n * Handles both single agent and array of agents\n *\n * @param resource - ResourceDescriptor\n * @returns First agent or undefined\n */\nexport function getCreator(resource: ResourceDescriptor | undefined): components['schemas']['Agent'] | undefined {\n if (!resource?.wasAttributedTo) return undefined;\n\n return Array.isArray(resource.wasAttributedTo)\n ? resource.wasAttributedTo[0]\n : resource.wasAttributedTo;\n}\n\n/**\n * Get derived-from URI\n * Handles both single URI and array of URIs\n *\n * @param resource - ResourceDescriptor\n * @returns First derivation URI or undefined\n */\nexport function getDerivedFrom(resource: ResourceDescriptor | undefined): string | undefined {\n if (!resource?.wasDerivedFrom) return undefined;\n\n return Array.isArray(resource.wasDerivedFrom)\n ? resource.wasDerivedFrom[0]\n : resource.wasDerivedFrom;\n}\n\n/**\n * Check if resource is archived (application-specific field)\n *\n * @param resource - ResourceDescriptor\n * @returns True if archived, false otherwise\n */\nexport function isArchived(resource: ResourceDescriptor | undefined): boolean {\n return resource?.archived === true;\n}\n\n/**\n * Get entity types from resource (application-specific field)\n *\n * @param resource - ResourceDescriptor\n * @returns Array of entity types, empty if not set\n */\nexport function getResourceEntityTypes(resource: ResourceDescriptor | undefined): string[] {\n return resource?.entityTypes || [];\n}\n\n/**\n * Check if resource is a draft (application-specific field)\n *\n * @param resource - ResourceDescriptor\n * @returns True if draft, false otherwise\n */\nexport function isDraft(resource: ResourceDescriptor | undefined): boolean {\n return resource?.isDraft === true;\n}\n\n/**\n * Map charset names to Node.js Buffer encoding names\n * Node.js Buffer.toString() supports: 'utf8', 'utf16le', 'latin1', 'base64', 'hex', 'ascii', 'binary', 'ucs2'\n *\n * @param charset - Charset name (e.g., \"UTF-8\", \"ISO-8859-1\", \"Windows-1252\")\n * @returns Node.js BufferEncoding\n */\nexport function getNodeEncoding(charset: string): BufferEncoding {\n const normalized = charset.toLowerCase().replace(/[-_]/g, '');\n\n // Map common charset names to Node.js encodings\n const charsetMap: Record<string, BufferEncoding> = {\n 'utf8': 'utf8',\n 'iso88591': 'latin1',\n 'latin1': 'latin1',\n 'ascii': 'ascii',\n 'usascii': 'ascii',\n 'utf16le': 'utf16le',\n 'ucs2': 'ucs2',\n 'binary': 'binary',\n 'windows1252': 'latin1', // Windows-1252 is a superset of Latin-1\n 'cp1252': 'latin1',\n };\n\n return charsetMap[normalized] || 'utf8';\n}\n\n/**\n * Decode a representation buffer to string using the correct charset\n * Extracts charset from media type and uses appropriate encoding\n *\n * @param buffer - The raw representation data\n * @param mediaType - Media type with optional charset (e.g., \"text/plain; charset=iso-8859-1\")\n * @returns Decoded string\n *\n * @example\n * ```typescript\n * const content = decodeRepresentation(buffer, \"text/plain; charset=utf-8\");\n * const legacy = decodeRepresentation(buffer, \"text/plain; charset=windows-1252\");\n * ```\n */\nexport function decodeRepresentation(buffer: Buffer, mediaType: string): string {\n // Extract charset from mediaType (e.g., \"text/plain; charset=iso-8859-1\")\n const charsetMatch = mediaType.match(/charset=([^\\s;]+)/i);\n const charset = (charsetMatch?.[1] || 'utf-8').toLowerCase();\n\n // Map to Node.js encoding\n const encoding = getNodeEncoding(charset);\n\n return buffer.toString(encoding);\n}\n","/**\n * BRIDGED_CHANNELS\n *\n * The set of bus channels that any concrete transport bridges into the\n * caller-supplied bus via `bridgeInto`. Transport-neutral: every concrete\n * `ITransport` shares the same set; HTTP delivers them via SSE,\n * in-process transports forward them directly from the local actor bus.\n *\n * Note: this is the *fan-in* set — channels for events the transport\n * receives and pushes onto the client's bus. It is not the same as the\n * channels the client emits (which is open-ended).\n *\n * Resource-scoped channels (joined/left via `subscribeToResource`) are\n * tracked separately by transports that care about scope (HTTP).\n */\nexport const BRIDGED_CHANNELS = [\n 'browse:resources-result', 'browse:resources-failed',\n 'browse:resource-result', 'browse:resource-failed',\n 'browse:annotations-result', 'browse:annotations-failed',\n 'browse:annotation-result', 'browse:annotation-failed',\n 'browse:annotation-history-result', 'browse:annotation-history-failed',\n 'browse:events-result', 'browse:events-failed',\n 'browse:referenced-by-result', 'browse:referenced-by-failed',\n 'browse:entity-types-result', 'browse:entity-types-failed',\n 'browse:tag-schemas-result', 'browse:tag-schemas-failed',\n 'browse:directory-result', 'browse:directory-failed',\n 'browse:annotation-context-result', 'browse:annotation-context-failed',\n 'mark:delete-ok', 'mark:delete-failed',\n 'mark:create-ok', 'mark:create-failed',\n 'match:search-results', 'match:search-failed',\n 'gather:complete', 'gather:failed',\n 'gather:annotation-progress', 'gather:annotation-finished',\n 'gather:summary-result', 'gather:summary-failed',\n 'bind:body-updated', 'bind:body-update-failed',\n 'job:report-progress', 'job:complete', 'job:fail',\n 'job:status-result', 'job:status-failed',\n 'job:created', 'job:create-failed',\n 'job:claimed', 'job:claim-failed',\n 'yield:create-ok', 'yield:create-failed',\n 'yield:update-ok', 'yield:update-failed',\n 'yield:clone-token-generated', 'yield:clone-token-failed',\n 'yield:clone-resource-result', 'yield:clone-resource-failed',\n 'yield:clone-created', 'yield:clone-create-failed',\n 'frame:entity-type-added',\n 'frame:tag-schema-added',\n 'beckon:focus', 'beckon:sparkle',\n 'bus:resume-gap',\n] as const;\n\nexport type BridgedChannel = typeof BRIDGED_CHANNELS[number];\n","/**\n * Fuzzy Anchoring for W3C Web Annotation TextQuoteSelector\n *\n * Uses prefix/suffix context to disambiguate when the same text appears multiple times.\n * Implements fuzzy matching as specified in the W3C Web Annotation Data Model.\n *\n * @see https://www.w3.org/TR/annotation-model/#text-quote-selector\n */\n\nexport interface TextPosition {\n start: number;\n end: number;\n}\n\nexport type MatchQuality = 'exact' | 'normalized' | 'case-insensitive' | 'fuzzy';\n\n/**\n * Normalize text for comparison - handles common document editing changes\n *\n * Collapses whitespace, converts curly quotes to straight quotes,\n * and normalizes common punctuation variations.\n */\nexport function normalizeText(text: string): string {\n return text\n .replace(/\\s+/g, ' ') // collapse whitespace\n .replace(/[\\u2018\\u2019]/g, \"'\") // curly single quotes → straight\n .replace(/[\\u201C\\u201D]/g, '\"') // curly double quotes → straight\n .replace(/\\u2014/g, '--') // em-dash → double hyphen\n .replace(/\\u2013/g, '-') // en-dash → hyphen\n .trim();\n}\n\n/**\n * Calculate Levenshtein distance between two strings\n * Used for fuzzy matching when exact text doesn't match\n */\nfunction levenshteinDistance(str1: string, str2: string): number {\n const len1 = str1.length;\n const len2 = str2.length;\n const matrix: number[][] = [];\n\n // Initialize matrix\n for (let i = 0; i <= len1; i++) {\n matrix[i] = [i];\n }\n for (let j = 0; j <= len2; j++) {\n matrix[0]![j] = j;\n }\n\n // Fill matrix\n for (let i = 1; i <= len1; i++) {\n for (let j = 1; j <= len2; j++) {\n const cost = str1[i - 1] === str2[j - 1] ? 0 : 1;\n const deletion = matrix[i - 1]![j]! + 1;\n const insertion = matrix[i]![j - 1]! + 1;\n const substitution = matrix[i - 1]![j - 1]! + cost;\n matrix[i]![j] = Math.min(deletion, insertion, substitution);\n }\n }\n\n return matrix[len1]![len2]!;\n}\n\n/**\n * Pre-computed content strings for batch fuzzy matching.\n * Avoids recomputing normalizeText(content) and content.toLowerCase()\n * for every annotation when processing many annotations against the same content.\n *\n * `normalizedMap[i]` is the original-content index that normalized\n * character `i` came from. It has length `normalizedContent.length + 1`;\n * the final entry is `content.length` so a match that ends at the end of\n * the normalized string maps back to the end of the original. This map is\n * how `findBestTextMatch` recovers the *original* offset of a normalized\n * match — counting char-by-char with `normalizeText(singleChar)` is\n * wrong, because a lone whitespace char trims to `''` (contributing 0)\n * while in a full-string normalize it collapses to a single space\n * (contributing 1). That discrepancy shifted recovered offsets by the\n * number of whitespace runs before the match.\n */\nexport interface ContentCache {\n normalizedContent: string;\n normalizedMap: number[];\n lowerContent: string;\n}\n\n/**\n * Normalize text and, in the same pass, build a map from each normalized\n * character position back to the original-content index it came from.\n * The produced `normalized` string is identical to `normalizeText(input)`\n * — a test pins this equivalence so the two can't drift.\n */\nexport function normalizeTextWithMap(input: string): { normalized: string; map: number[] } {\n let normalized = '';\n const map: number[] = [];\n\n // First pass mirrors normalizeText exactly, char by char, recording the\n // origin index for every emitted normalized character.\n let pendingWhitespaceStart = -1; // origin index of an open whitespace run, or -1\n\n const flushWhitespace = () => {\n if (pendingWhitespaceStart !== -1) {\n // A whitespace run collapses to a single space, mapped to the run's\n // first char — but a *leading* run (nothing emitted yet) is dropped,\n // matching normalizeText's trailing `.trim()`.\n if (normalized.length > 0) {\n normalized += ' ';\n map.push(pendingWhitespaceStart);\n }\n pendingWhitespaceStart = -1;\n }\n };\n\n for (let i = 0; i < input.length; i++) {\n const ch = input[i]!;\n if (/\\s/.test(ch)) {\n if (pendingWhitespaceStart === -1) pendingWhitespaceStart = i;\n continue;\n }\n flushWhitespace();\n if (ch === '‘' || ch === '’') {\n normalized += \"'\"; map.push(i);\n } else if (ch === '“' || ch === '”') {\n normalized += '\"'; map.push(i);\n } else if (ch === '—') {\n normalized += '--'; map.push(i); map.push(i);\n } else if (ch === '–') {\n normalized += '-'; map.push(i);\n } else {\n normalized += ch; map.push(i);\n }\n }\n // A trailing whitespace run is dropped by trim — do not flush it.\n\n // `normalizeText` applies `.trim()` last. Our run logic already drops a\n // trailing whitespace run; a leading run is dropped because flushWhitespace\n // only runs before a non-space char, so a run at the very start is never\n // emitted. Both ends match trim().\n map.push(input.length); // sentinel: one past the last normalized char\n return { normalized, map };\n}\n\n/**\n * Build a ContentCache for a given content string.\n * Call once per content, pass to findBestTextMatch/anchorAnnotation for all annotations.\n */\nexport function buildContentCache(content: string): ContentCache {\n const { normalized, map } = normalizeTextWithMap(content);\n return {\n normalizedContent: normalized,\n normalizedMap: map,\n lowerContent: content.toLowerCase()\n };\n}\n\n/**\n * Find best match for text in content using multi-strategy search\n *\n * Shared core logic used by both anchorAnnotation (render-time) and\n * reconcileSelector (write-time).\n *\n * @param content - Full text content to search within\n * @param searchText - The text to find\n * @param positionHint - Hint for where to search (TextPositionSelector.start)\n * @param cache - Pre-computed normalized/lowered content (from buildContentCache)\n * @returns Match with position and quality, or null if not found\n */\nexport function findBestTextMatch(\n content: string,\n searchText: string,\n positionHint: number | undefined,\n cache: ContentCache\n): { start: number; end: number; matchQuality: MatchQuality } | null {\n const maxFuzzyDistance = Math.max(5, Math.floor(searchText.length * 0.05)); // 5% tolerance or min 5 chars\n\n // Strategy 1: Exact match (case-sensitive, exact whitespace)\n const exactIndex = content.indexOf(searchText);\n if (exactIndex !== -1) {\n return {\n start: exactIndex,\n end: exactIndex + searchText.length,\n matchQuality: 'exact'\n };\n }\n\n // Strategy 2: Normalized match (handles whitespace/quote variations).\n // Map the normalized match position back to the original via the\n // precomputed index map. The naive char-by-char re-normalize is wrong:\n // a lone whitespace char trims to '' (0-width) but collapses to a single\n // space (1-width) in a full normalize, so it under-counts by the number\n // of whitespace runs before the match, shifting the recovered offset.\n const normalizedSearch = normalizeText(searchText);\n const normalizedIndex = cache.normalizedContent.indexOf(normalizedSearch);\n if (normalizedIndex !== -1) {\n const start = cache.normalizedMap[normalizedIndex] ?? 0;\n const end = cache.normalizedMap[normalizedIndex + normalizedSearch.length] ?? content.length;\n return {\n start,\n end,\n matchQuality: 'normalized'\n };\n }\n\n // Strategy 3: Case-insensitive match\n const lowerSearch = searchText.toLowerCase();\n const caseInsensitiveIndex = cache.lowerContent.indexOf(lowerSearch);\n if (caseInsensitiveIndex !== -1) {\n return {\n start: caseInsensitiveIndex,\n end: caseInsensitiveIndex + searchText.length,\n matchQuality: 'case-insensitive'\n };\n }\n\n // Strategy 4: Fuzzy match using Levenshtein distance with sliding window\n // Search near position hint if provided, otherwise search full content\n const windowSize = searchText.length;\n const searchRadius = Math.min(500, content.length);\n const searchStart = positionHint !== undefined\n ? Math.max(0, positionHint - searchRadius)\n : 0;\n const searchEnd = positionHint !== undefined\n ? Math.min(content.length, positionHint + searchRadius)\n : content.length;\n\n let bestMatch: { start: number; distance: number } | null = null;\n\n // Scan through content with sliding window\n for (let i = searchStart; i <= searchEnd - windowSize; i++) {\n const candidate = content.substring(i, i + windowSize);\n const distance = levenshteinDistance(searchText, candidate);\n\n if (distance <= maxFuzzyDistance) {\n if (!bestMatch || distance < bestMatch.distance) {\n bestMatch = { start: i, distance };\n }\n }\n }\n\n if (bestMatch) {\n return {\n start: bestMatch.start,\n end: bestMatch.start + windowSize,\n matchQuality: 'fuzzy'\n };\n }\n\n return null;\n}\n\n/**\n * Verify that a position correctly points to the exact text\n * Useful for debugging and validation\n */\nexport function verifyPosition(\n content: string,\n position: TextPosition,\n expectedExact: string\n): boolean {\n const actualText = content.substring(position.start, position.end);\n return actualText === expectedExact;\n}\n","/**\n * Anchor a W3C Web Annotation to its rendered text.\n *\n * Render-time cleverness is deliberately limited to **verbatim** quote\n * matching. The annotation's two selectors are written to agree (the\n * write-side `reconcileSelector` + `buildTextAnnotation` invariant\n * guarantee `content.substring(start, end) === exact`). At render time the\n * only legitimate discrepancy is *positional drift*: the document grew or\n * shrank above the span after the annotation was written, so the offset is\n * stale but the exact text still exists, byte-identical, elsewhere. That is\n * the W3C-intended role of `TextQuoteSelector`, and it is safe because it\n * demands identical text — no normalization, no fuzzy matching, no\n * judgment call.\n *\n * Anything that would require *fuzzy* recovery (smart-quote folding,\n * whitespace collapse, Levenshtein) is out of scope here: a non-verbatim\n * mismatch means the content representation diverged or the stored record\n * is wrong, both of which are deterministic and belong upstream (canonical\n * content, or a corrected annotation event). The renderer does not guess —\n * it renders at the stored offset and flags the anchor low-confidence so\n * the discrepancy surfaces for an upstream fix.\n *\n * Returns `null` only when nothing usable is present; otherwise always\n * returns a position with a `strategy` and `confidence`.\n */\n\nexport type AnchorStrategy =\n /** Position hint pointed exactly at the exact text. Unambiguous. */\n | 'fast-path'\n /** Exact text appears once verbatim in the content. No tiebreak needed. */\n | 'unique-occurrence'\n /** Multiple verbatim occurrences; prefix+suffix uniquely identified one. */\n | 'context-disambiguated'\n /** Multiple verbatim candidates; position closest to hint chosen. */\n | 'position-tiebreaker'\n /** Exact text not found verbatim (or no quote); raw stored offset used,\n * flagged for upstream correction. */\n | 'position-fallback';\n\nexport type AnchorConfidence = 'high' | 'medium' | 'low';\n\nexport interface RenderedAnchor {\n start: number;\n end: number;\n strategy: AnchorStrategy;\n confidence: AnchorConfidence;\n}\n\nexport interface AnchorSelectors {\n position?: { start: number; end: number };\n quote?: { exact: string; prefix?: string; suffix?: string };\n}\n\n/**\n * Distance window for the position tiebreaker. Candidates closer than this\n * to the hint receive a non-zero position score; further candidates fall\n * back to zero. Tuned for typical document sizes; calibration tests pin\n * the boundary behaviour rather than the exact value.\n */\nexport const POSITION_WINDOW = 1024;\n\n/**\n * Score weights — kept as named constants so the calibration tests can\n * import them and pin the *relationships* rather than the magnitudes.\n *\n * Invariant: a full-context match always outranks any position score.\n * (`CONTEXT_FULL_WEIGHT * 2 > POSITION_WEIGHT_MAX`, accounting for\n * prefix+suffix each contributing the full weight.)\n */\nexport const CONTEXT_FULL_WEIGHT = 10;\nexport const CONTEXT_PARTIAL_WEIGHT = 5;\nexport const POSITION_WEIGHT_MAX = 5;\n\n/**\n * Locate the best-effort anchor for an annotation against the content the\n * renderer is about to display. Verbatim-only — see the module doc.\n */\nexport function anchorAnnotation(\n content: string,\n selectors: AnchorSelectors,\n): RenderedAnchor | null {\n const { position, quote } = selectors;\n\n // No quote selector. Position is the only signal; use it verbatim if\n // present and in-range, otherwise the annotation has no anchor.\n if (!quote || !quote.exact) {\n if (!position) return null;\n if (position.start < 0 || position.end > content.length || position.start >= position.end) {\n return null;\n }\n return {\n start: position.start,\n end: position.end,\n strategy: 'position-fallback',\n confidence: 'low',\n };\n }\n\n const { exact, prefix, suffix } = quote;\n\n // Fast path: position hint exactly matches the exact text.\n if (position) {\n const probeEnd = position.start + exact.length;\n if (\n position.start >= 0 &&\n probeEnd <= content.length &&\n content.substring(position.start, probeEnd) === exact\n ) {\n return {\n start: position.start,\n end: probeEnd,\n strategy: 'fast-path',\n confidence: 'high',\n };\n }\n }\n\n // Find all occurrences via exact indexOf. Cheap; bounded by content\n // size; sufficient for the common case where the renderer's content\n // matches the worker's content character-for-character.\n const occurrences = findAllOccurrences(content, exact);\n\n if (occurrences.length === 1) {\n const start = occurrences[0]!;\n return {\n start,\n end: start + exact.length,\n strategy: 'unique-occurrence',\n confidence: 'high',\n };\n }\n\n if (occurrences.length > 1) {\n const winner = pickByScore(content, occurrences, exact, prefix, suffix, position?.start);\n return winner;\n }\n\n // No verbatim occurrence. We do NOT fuzzy-match at render time — a\n // non-verbatim mismatch means the content diverged or the record is\n // wrong, which is an upstream concern. Render at the stored offset so the\n // highlight still appears, flagged low-confidence so the discrepancy is\n // visible and gets corrected at the source.\n if (position && position.start >= 0 && position.end <= content.length && position.start < position.end) {\n return {\n start: position.start,\n end: position.end,\n strategy: 'position-fallback',\n confidence: 'low',\n };\n }\n\n return null;\n}\n\nfunction findAllOccurrences(content: string, exact: string): number[] {\n const out: number[] = [];\n let i = content.indexOf(exact);\n while (i !== -1) {\n out.push(i);\n i = content.indexOf(exact, i + 1);\n }\n return out;\n}\n\n/**\n * Context match score at a candidate offset.\n * Returns full / partial / no-match per side (prefix and suffix), then\n * sums each side weighted by `CONTEXT_FULL_WEIGHT` / `CONTEXT_PARTIAL_WEIGHT`.\n *\n * \"Full\" means the stored context aligns exactly with the source text\n * adjacent to the candidate. \"Partial\" is the looser substring check —\n * the stored context appears somewhere in the candidate's surroundings\n * but isn't anchored to the edges. This is the same partial-match logic\n * the previous `findTextWithContext` used, captured here so the scorer\n * can use it as one signal among many instead of a hard filter.\n */\nfunction contextScoreAt(\n content: string,\n pos: number,\n exact: string,\n prefix: string | undefined,\n suffix: string | undefined,\n): { score: number; full: boolean } {\n let score = 0;\n let prefixFull = true;\n let suffixFull = true;\n\n if (prefix) {\n const adj = content.substring(Math.max(0, pos - prefix.length), pos);\n if (adj.endsWith(prefix)) {\n score += CONTEXT_FULL_WEIGHT;\n prefixFull = true;\n } else if (adj.includes(prefix.trim()) && prefix.trim().length > 0) {\n score += CONTEXT_PARTIAL_WEIGHT;\n prefixFull = false;\n } else {\n prefixFull = false;\n }\n }\n\n if (suffix) {\n const adj = content.substring(pos + exact.length, Math.min(content.length, pos + exact.length + suffix.length));\n if (adj.startsWith(suffix)) {\n score += CONTEXT_FULL_WEIGHT;\n suffixFull = true;\n } else if (adj.includes(suffix.trim()) && suffix.trim().length > 0) {\n score += CONTEXT_PARTIAL_WEIGHT;\n suffixFull = false;\n } else {\n suffixFull = false;\n }\n }\n\n // \"Full\" overall match means every provided context field aligned\n // exactly — no partial fallbacks. Used to bump confidence to high.\n const full =\n (prefix === undefined || prefixFull) &&\n (suffix === undefined || suffixFull) &&\n (prefix !== undefined || suffix !== undefined);\n\n return { score, full };\n}\n\nfunction positionScoreAt(pos: number, hint: number | undefined): number {\n if (hint === undefined) return 0;\n const distance = Math.abs(pos - hint);\n if (distance >= POSITION_WINDOW) return 0;\n return POSITION_WEIGHT_MAX * (1 - distance / POSITION_WINDOW);\n}\n\nfunction pickByScore(\n content: string,\n occurrences: number[],\n exact: string,\n prefix: string | undefined,\n suffix: string | undefined,\n hint: number | undefined,\n): RenderedAnchor {\n let bestPos = occurrences[0]!;\n let bestScore = -1;\n let bestContextFull = false;\n let bestHasAnyContextSignal = false;\n let bestHasAnyPositionSignal = false;\n\n for (const pos of occurrences) {\n const ctx = contextScoreAt(content, pos, exact, prefix, suffix);\n const positionScore = positionScoreAt(pos, hint);\n const total = ctx.score + positionScore;\n if (total > bestScore) {\n bestScore = total;\n bestPos = pos;\n bestContextFull = ctx.full;\n bestHasAnyContextSignal = ctx.score > 0;\n bestHasAnyPositionSignal = positionScore > 0;\n }\n }\n\n // Strategy + confidence classification:\n // - both context fields aligned exactly → high-confidence context-disambiguated\n // - some context aligned (full or partial), no position needed → context-disambiguated, medium\n // - position broke the tie (winning candidate has position signal but no context signal,\n // or context was equal across candidates) → position-tiebreaker\n // - no signal at all (all candidates scored zero) → position-tiebreaker, low confidence,\n // deterministic first-of-many fallback\n let strategy: AnchorStrategy;\n let confidence: AnchorConfidence;\n\n if (bestContextFull) {\n strategy = 'context-disambiguated';\n confidence = 'high';\n } else if (bestHasAnyContextSignal && !bestHasAnyPositionSignal) {\n strategy = 'context-disambiguated';\n confidence = 'medium';\n } else if (bestHasAnyContextSignal && bestHasAnyPositionSignal) {\n // Context partially matched and position helped break the tie.\n strategy = 'position-tiebreaker';\n confidence = 'medium';\n } else if (bestHasAnyPositionSignal) {\n strategy = 'position-tiebreaker';\n confidence = 'medium';\n } else {\n strategy = 'position-tiebreaker';\n confidence = 'low';\n }\n\n return {\n start: bestPos,\n end: bestPos + exact.length,\n strategy,\n confidence,\n };\n}\n","/**\n * Locale information\n * Copied from SDK for frontend use\n */\n\nexport interface LocaleInfo {\n code: string;\n nativeName: string;\n englishName: string;\n}\n\nexport const LOCALES: readonly LocaleInfo[] = [\n { code: 'ar', nativeName: 'العربية', englishName: 'Arabic' },\n { code: 'bn', nativeName: 'বাংলা', englishName: 'Bengali' },\n { code: 'cs', nativeName: 'Čeština', englishName: 'Czech' },\n { code: 'da', nativeName: 'Dansk', englishName: 'Danish' },\n { code: 'de', nativeName: 'Deutsch', englishName: 'German' },\n { code: 'el', nativeName: 'Ελληνικά', englishName: 'Greek' },\n { code: 'en', nativeName: 'English', englishName: 'English' },\n { code: 'es', nativeName: 'Español', englishName: 'Spanish' },\n { code: 'fa', nativeName: 'فارسی', englishName: 'Persian' },\n { code: 'fi', nativeName: 'Suomi', englishName: 'Finnish' },\n { code: 'fr', nativeName: 'Français', englishName: 'French' },\n { code: 'he', nativeName: 'עברית', englishName: 'Hebrew' },\n { code: 'hi', nativeName: 'हिन्दी', englishName: 'Hindi' },\n { code: 'id', nativeName: 'Bahasa Indonesia', englishName: 'Indonesian' },\n { code: 'it', nativeName: 'Italiano', englishName: 'Italian' },\n { code: 'ja', nativeName: '日本語', englishName: 'Japanese' },\n { code: 'ko', nativeName: '한국어', englishName: 'Korean' },\n { code: 'ms', nativeName: 'Bahasa Melayu', englishName: 'Malay' },\n { code: 'nl', nativeName: 'Nederlands', englishName: 'Dutch' },\n { code: 'no', nativeName: 'Norsk', englishName: 'Norwegian' },\n { code: 'pl', nativeName: 'Polski', englishName: 'Polish' },\n { code: 'pt', nativeName: 'Português', englishName: 'Portuguese' },\n { code: 'ro', nativeName: 'Română', englishName: 'Romanian' },\n { code: 'sv', nativeName: 'Svenska', englishName: 'Swedish' },\n { code: 'th', nativeName: 'ไทย', englishName: 'Thai' },\n { code: 'tr', nativeName: 'Türkçe', englishName: 'Turkish' },\n { code: 'uk', nativeName: 'Українська', englishName: 'Ukrainian' },\n { code: 'vi', nativeName: 'Tiếng Việt', englishName: 'Vietnamese' },\n { code: 'zh', nativeName: '中文', englishName: 'Chinese' },\n] as const;\n\n// Create lookup map for efficient access\nconst localeByCode = new Map<string, LocaleInfo>(\n LOCALES.map(locale => [locale.code.toLowerCase(), locale])\n);\n\n/**\n * Get locale information by code\n */\nexport function getLocaleInfo(code: string | undefined): LocaleInfo | undefined {\n if (!code) return undefined;\n return localeByCode.get(code.toLowerCase());\n}\n\n/**\n * Get the native name of a language by its locale code\n */\nexport function getLocaleNativeName(code: string | undefined): string | undefined {\n return getLocaleInfo(code)?.nativeName;\n}\n\n/**\n * Get the English name of a language by its locale code\n */\nexport function getLocaleEnglishName(code: string | undefined): string | undefined {\n return getLocaleInfo(code)?.englishName;\n}\n\n/**\n * Format locale code for display as \"Native Name (code)\"\n */\nexport function formatLocaleDisplay(code: string | undefined): string | undefined {\n if (!code) return undefined;\n\n const info = getLocaleInfo(code);\n if (!info) return code;\n\n return `${info.nativeName} (${code.toLowerCase()})`;\n}\n\n/**\n * Get all supported locale codes\n */\nexport function getAllLocaleCodes(): readonly string[] {\n return LOCALES.map(l => l.code);\n}\n","/**\n * SVG Utility Functions\n *\n * Utilities for creating, parsing, and manipulating W3C-compliant SVG selectors\n * for image annotation.\n */\n\nexport interface Point {\n x: number;\n y: number;\n}\n\nexport interface BoundingBox {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\n/**\n * Create W3C-compliant SVG rectangle selector\n */\nexport function createRectangleSvg(start: Point, end: Point): string {\n const x = Math.min(start.x, end.x);\n const y = Math.min(start.y, end.y);\n const width = Math.abs(end.x - start.x);\n const height = Math.abs(end.y - start.y);\n\n return `<svg xmlns=\"http://www.w3.org/2000/svg\"><rect x=\"${x}\" y=\"${y}\" width=\"${width}\" height=\"${height}\"/></svg>`;\n}\n\n/**\n * Create W3C-compliant SVG polygon selector\n */\nexport function createPolygonSvg(points: Point[]): string {\n if (points.length < 3) {\n throw new Error('Polygon requires at least 3 points');\n }\n\n const pointsStr = points.map(p => `${p.x},${p.y}`).join(' ');\n return `<svg xmlns=\"http://www.w3.org/2000/svg\"><polygon points=\"${pointsStr}\"/></svg>`;\n}\n\n/**\n * Create W3C-compliant SVG circle selector\n */\nexport function createCircleSvg(center: Point, radius: number): string {\n if (radius <= 0) {\n throw new Error('Circle radius must be positive');\n }\n\n return `<svg xmlns=\"http://www.w3.org/2000/svg\"><circle cx=\"${center.x}\" cy=\"${center.y}\" r=\"${radius}\"/></svg>`;\n}\n\n/**\n * Parse SVG selector to extract shape type and data\n */\nexport function parseSvgSelector(svg: string): {\n type: 'rect' | 'polygon' | 'circle' | 'path';\n data: any;\n} | null {\n // Extract rectangle\n const rectMatch = svg.match(/<rect\\s+([^>]+)\\/>/);\n if (rectMatch && rectMatch[1]) {\n const attrs = rectMatch[1];\n const x = parseFloat(attrs.match(/x=\"([^\"]+)\"/)?.[1] || '0');\n const y = parseFloat(attrs.match(/y=\"([^\"]+)\"/)?.[1] || '0');\n const width = parseFloat(attrs.match(/width=\"([^\"]+)\"/)?.[1] || '0');\n const height = parseFloat(attrs.match(/height=\"([^\"]+)\"/)?.[1] || '0');\n\n return {\n type: 'rect',\n data: { x, y, width, height }\n };\n }\n\n // Extract polygon\n const polygonMatch = svg.match(/<polygon\\s+points=\"([^\"]+)\"/);\n if (polygonMatch && polygonMatch[1]) {\n const pointsStr = polygonMatch[1];\n const points = pointsStr.split(/\\s+/).map(pair => {\n const [x, y] = pair.split(',').map(parseFloat);\n return { x, y };\n });\n\n return {\n type: 'polygon',\n data: { points }\n };\n }\n\n // Extract circle\n const circleMatch = svg.match(/<circle\\s+([^>]+)\\/>/);\n if (circleMatch && circleMatch[1]) {\n const attrs = circleMatch[1];\n const cx = parseFloat(attrs.match(/cx=\"([^\"]+)\"/)?.[1] || '0');\n const cy = parseFloat(attrs.match(/cy=\"([^\"]+)\"/)?.[1] || '0');\n const r = parseFloat(attrs.match(/r=\"([^\"]+)\"/)?.[1] || '0');\n\n return {\n type: 'circle',\n data: { cx, cy, r }\n };\n }\n\n return null;\n}\n\n/**\n * Normalize coordinates from display space to image native resolution\n */\nexport function normalizeCoordinates(\n point: Point,\n displayWidth: number,\n displayHeight: number,\n imageWidth: number,\n imageHeight: number\n): Point {\n return {\n x: (point.x / displayWidth) * imageWidth,\n y: (point.y / displayHeight) * imageHeight\n };\n}\n\n/**\n * Scale entire SVG selector from display space to image native resolution\n */\nexport function scaleSvgToNative(\n svg: string,\n displayWidth: number,\n displayHeight: number,\n imageWidth: number,\n imageHeight: number\n): string {\n const parsed = parseSvgSelector(svg);\n if (!parsed) return svg;\n\n const scaleX = imageWidth / displayWidth;\n const scaleY = imageHeight / displayHeight;\n\n switch (parsed.type) {\n case 'rect': {\n const { x, y, width, height } = parsed.data;\n return createRectangleSvg(\n { x: x * scaleX, y: y * scaleY },\n { x: (x + width) * scaleX, y: (y + height) * scaleY }\n );\n }\n\n case 'circle': {\n const { cx, cy, r } = parsed.data;\n return createCircleSvg(\n { x: cx * scaleX, y: cy * scaleY },\n r * Math.min(scaleX, scaleY)\n );\n }\n\n case 'polygon': {\n const points = parsed.data.points.map((p: Point) => ({\n x: p.x * scaleX,\n y: p.y * scaleY\n }));\n return createPolygonSvg(points);\n }\n }\n\n return svg;\n}\n","/**\n * Selector reconciliation for write-time annotation construction.\n *\n * LLM-produced text offsets are guides, not authoritative anchors.\n * `reconcileSelector` takes whatever the LLM emitted and produces a\n * `TextQuoteSelector`-equivalent `start`/`end`/`exact`/`prefix`/`suffix`\n * that is provably consistent with the source content:\n *\n * - `content.substring(start, end) === exact`\n * - `content.substring(start - prefix.length, start) === prefix`\n * - `content.substring(end, end + suffix.length) === suffix`\n *\n * No caller spreads LLM-emitted prefix/suffix into the stored selector.\n * The shared helper extracts both from source at the corrected position,\n * so the no-overlap invariant holds by construction.\n *\n * Returns `null` when the LLM emitted text that doesn't appear in the\n * source. Callers filter; the helper doesn't decide for them.\n *\n * @see https://www.w3.org/TR/annotation-model/#text-quote-selector\n */\n\nimport { findBestTextMatch, buildContentCache, type MatchQuality } from './fuzzy-anchor';\n\n/**\n * How the reconciliation arrived at the chosen offset. Carried into the\n * worker log so operators can audit ambiguous matches; the\n * `first-of-many` flag, in particular, is the signal that an annotation\n * *may* be anchored at the wrong occurrence and warrants review.\n */\nexport type AnchorMethod =\n /** Exact text appears once in the source — anchored unambiguously. */\n | 'unique-match'\n /** Multiple occurrences; LLM-emitted prefix/suffix picked one. */\n | 'context-recovered'\n /** Exact text not found verbatim; fuzzy match recovered it. */\n | 'fuzzy-match'\n /** Multiple occurrences, no context disambiguated — risky fallback. */\n | 'first-of-many';\n\nexport interface ReconciledSelector {\n start: number;\n end: number;\n /** Always a substring of the source content — never the LLM's emission. */\n exact: string;\n /** Extracted from source via extractContext — never the LLM's emission. */\n prefix?: string;\n /** Extracted from source via extractContext — never the LLM's emission. */\n suffix?: string;\n anchorMethod: AnchorMethod;\n /** Present when the fuzzy fallback recovered the match, naming how. */\n matchQuality?: MatchQuality;\n}\n\nexport interface LlmSelectorInput {\n exact: string;\n /** LLM-emitted context for disambiguation only — not for storage. */\n prefix?: string;\n /** LLM-emitted context for disambiguation only — not for storage. */\n suffix?: string;\n}\n\nconst CONTEXT_LENGTH = 64;\nconst MAX_EXTENSION = 32;\n// Minimum window of source text compared against an LLM-emitted prefix/suffix\n// when disambiguating multiple occurrences. The actual window grows to the\n// length of the LLM's prefix/suffix when that's longer — the prompts invite\n// up to 64 chars, and a fixed 32-char window can't `endsWith`/`includes` a\n// 64-char string, which would silently defeat disambiguation for exactly the\n// long, distinctive contexts that disambiguate best.\nconst DISAMBIGUATION_MIN_WINDOW = 32;\n\n/**\n * Extract prefix and suffix context for a `TextQuoteSelector` from\n * source content. Used internally by `reconcileSelector` after offsets\n * are reconciled, and exported for callers (e.g. UI-side selection\n * capture) that need the same extraction semantics.\n *\n * Extracts up to 64 characters before and after the selected text,\n * extending up to 32 additional chars to reach a word boundary so the\n * prefix/suffix is meaningful context rather than mid-word fragments.\n */\nexport function extractContext(\n content: string,\n start: number,\n end: number,\n): { prefix?: string; suffix?: string } {\n const result: { prefix?: string; suffix?: string } = {};\n\n if (start > 0) {\n let prefixStart = Math.max(0, start - CONTEXT_LENGTH);\n let extensionCount = 0;\n while (prefixStart > 0 && extensionCount < MAX_EXTENSION) {\n const char = content[prefixStart - 1];\n if (!char || /[\\s.,;:!?'\"()\\[\\]{}<>\\/\\\\]/.test(char)) break;\n prefixStart--;\n extensionCount++;\n }\n result.prefix = content.substring(prefixStart, start);\n }\n\n if (end < content.length) {\n let suffixEnd = Math.min(content.length, end + CONTEXT_LENGTH);\n let extensionCount = 0;\n while (suffixEnd < content.length && extensionCount < MAX_EXTENSION) {\n const char = content[suffixEnd];\n if (!char || /[\\s.,;:!?'\"()\\[\\]{}<>\\/\\\\]/.test(char)) break;\n suffixEnd++;\n extensionCount++;\n }\n result.suffix = content.substring(end, suffixEnd);\n }\n\n return result;\n}\n\n/**\n * Reconcile LLM-emitted offsets against the source. Returns a selector\n * whose `start`/`end` are verified to bracket `exact` in `content`, and\n * whose `prefix`/`suffix` are extracted from source — never carried\n * verbatim from the LLM.\n *\n * Returns `null` if `exact` cannot be found anywhere in the content,\n * even via fuzzy match. Callers filter null and log the drop.\n */\nexport function reconcileSelector(\n content: string,\n llm: LlmSelectorInput,\n): ReconciledSelector | null {\n const { exact, prefix: llmPrefix, suffix: llmSuffix } = llm;\n if (!exact) return null;\n\n // Find all verbatim occurrences.\n const occurrences: number[] = [];\n let i = content.indexOf(exact);\n while (i !== -1) {\n occurrences.push(i);\n i = content.indexOf(exact, i + 1);\n }\n\n if (occurrences.length === 1) {\n const start = occurrences[0]!;\n const end = start + exact.length;\n const ctx = extractContext(content, start, end);\n return {\n start,\n end,\n exact,\n ...(ctx.prefix !== undefined ? { prefix: ctx.prefix } : {}),\n ...(ctx.suffix !== undefined ? { suffix: ctx.suffix } : {}),\n anchorMethod: 'unique-match',\n };\n }\n\n if (occurrences.length > 1) {\n // Disambiguate via LLM-emitted prefix/suffix when present. Size the\n // comparison window to the LLM's prefix/suffix (with a floor), so a\n // 64-char prefix is matched against ≥64 chars of source — a fixed\n // smaller window can't `endsWith`/`includes` a longer LLM string.\n if (llmPrefix || llmSuffix) {\n const prefixWindow = Math.max(DISAMBIGUATION_MIN_WINDOW, llmPrefix?.length ?? 0);\n const suffixWindow = Math.max(DISAMBIGUATION_MIN_WINDOW, llmSuffix?.length ?? 0);\n for (const pos of occurrences) {\n const candPrefix = content.substring(Math.max(0, pos - prefixWindow), pos);\n const candSuffix = content.substring(\n pos + exact.length,\n Math.min(content.length, pos + exact.length + suffixWindow),\n );\n const prefixOk = !llmPrefix || candPrefix.endsWith(llmPrefix) || candPrefix.includes(llmPrefix.trim());\n const suffixOk = !llmSuffix || candSuffix.startsWith(llmSuffix) || candSuffix.includes(llmSuffix.trim());\n if (prefixOk && suffixOk) {\n const start = pos;\n const end = start + exact.length;\n const ctx = extractContext(content, start, end);\n return {\n start,\n end,\n exact,\n ...(ctx.prefix !== undefined ? { prefix: ctx.prefix } : {}),\n ...(ctx.suffix !== undefined ? { suffix: ctx.suffix } : {}),\n anchorMethod: 'context-recovered',\n };\n }\n }\n }\n\n // No context match. Fall back to the first occurrence and flag for\n // audit. Without an LLM-emitted locality hint there's no better\n // signal at this stage; `first-of-many` callers should log loudly so\n // operators can correct misanchored annotations.\n const start = occurrences[0]!;\n const end = start + exact.length;\n const ctx = extractContext(content, start, end);\n return {\n start,\n end,\n exact,\n ...(ctx.prefix !== undefined ? { prefix: ctx.prefix } : {}),\n ...(ctx.suffix !== undefined ? { suffix: ctx.suffix } : {}),\n anchorMethod: 'first-of-many',\n };\n }\n\n // No verbatim occurrences. Try fuzzy match (case-insensitive,\n // whitespace-normalized, Levenshtein with 5% tolerance). No position\n // hint to bias the search — fuzzy match scans content globally.\n const cache = buildContentCache(content);\n const fuzzy = findBestTextMatch(content, exact, undefined, cache);\n if (!fuzzy) return null;\n\n const actual = content.substring(fuzzy.start, fuzzy.end);\n const ctx = extractContext(content, fuzzy.start, fuzzy.end);\n return {\n start: fuzzy.start,\n end: fuzzy.end,\n // Use the actual source text, not the LLM's version — the LLM may\n // have emitted slightly different characters (smart vs straight\n // quotes, etc.) and we store what's verifiable.\n exact: actual,\n ...(ctx.prefix !== undefined ? { prefix: ctx.prefix } : {}),\n ...(ctx.suffix !== undefined ? { suffix: ctx.suffix } : {}),\n anchorMethod: 'fuzzy-match',\n matchQuality: fuzzy.matchQuality,\n };\n}\n","/**\n * Text encoding utilities for consistent charset handling\n *\n * Ensures frontend decoding matches backend decoding by respecting\n * charset parameters in mediaType (e.g., \"text/plain; charset=iso-8859-1\")\n */\n\n/**\n * Extract charset from mediaType parameter\n *\n * @param mediaType - Media type with optional charset (e.g., \"text/plain; charset=utf-8\")\n * @returns Charset name in lowercase (defaults to \"utf-8\")\n *\n * @example\n * extractCharset(\"text/plain; charset=iso-8859-1\") // \"iso-8859-1\"\n * extractCharset(\"text/plain\") // \"utf-8\"\n */\nexport function extractCharset(mediaType: string): string {\n const charsetMatch = mediaType.match(/charset=([^\\s;]+)/i);\n return (charsetMatch?.[1] || 'utf-8').toLowerCase();\n}\n\n/**\n * Decode ArrayBuffer to string using charset from mediaType\n *\n * Uses TextDecoder with the charset extracted from mediaType parameter.\n * This ensures the same character space is used for both annotation creation\n * (backend) and rendering (frontend).\n *\n * @param buffer - Binary data to decode\n * @param mediaType - Media type with optional charset parameter\n * @returns Decoded string in the original character space\n *\n * @example\n * const buffer = new Uint8Array([...]);\n * const text = decodeWithCharset(buffer, \"text/plain; charset=iso-8859-1\");\n */\nexport function decodeWithCharset(buffer: ArrayBuffer, mediaType: string): string {\n const charset = extractCharset(mediaType);\n\n // TextDecoder supports standard charset names\n // Common mappings that work in browsers:\n // - utf-8, utf-16, utf-16le, utf-16be\n // - iso-8859-1 through iso-8859-15\n // - windows-1252, windows-1251, etc.\n const decoder = new TextDecoder(charset);\n return decoder.decode(buffer);\n}\n","/**\n * Generic validation utilities for @semiont/http-transport\n *\n * Pure TypeScript validation with no external dependencies.\n * Safe to use in any JavaScript environment (Node.js, browser, Deno, etc.)\n */\n\n/**\n * Validation result types\n */\nexport type ValidationSuccess<T> = { success: true; data: T };\nexport type ValidationFailure = { success: false; error: string; details?: string[] };\nexport type ValidationResult<T> = ValidationSuccess<T> | ValidationFailure;\n\n/**\n * JWT Token validation\n *\n * Validates JWT token format (header.payload.signature).\n * Does not verify signature - use for format validation only.\n */\nexport const JWTTokenSchema = {\n parse(token: unknown): string {\n if (typeof token !== 'string') {\n throw new Error('Token must be a string');\n }\n if (!token || token.length === 0) {\n throw new Error('Token is required');\n }\n // JWT format: header.payload.signature\n const jwtRegex = /^[A-Za-z0-9\\-_]+\\.[A-Za-z0-9\\-_]+\\.[A-Za-z0-9\\-_]*$/;\n if (!jwtRegex.test(token)) {\n throw new Error('Invalid JWT token format');\n }\n return token;\n },\n\n safeParse(token: unknown): ValidationResult<string> {\n try {\n const validated = this.parse(token);\n return { success: true, data: validated };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Invalid JWT token',\n };\n }\n },\n};\n\n/**\n * Generic validation helper with error formatting\n *\n * Wraps any schema's parse method with try/catch and returns ValidationResult.\n *\n * @example\n * ```typescript\n * const result = validateData(JWTTokenSchema, 'eyJ...');\n * if (result.success) {\n * console.log('Valid token:', result.data);\n * } else {\n * console.error('Invalid:', result.error);\n * }\n * ```\n */\nexport function validateData<T>(\n schema: { parse(data: unknown): T },\n data: unknown\n): ValidationResult<T> {\n try {\n const validated = schema.parse(data);\n return { success: true, data: validated };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Validation failed',\n };\n }\n}\n\n/**\n * Email validation helper\n *\n * Validates email format using RFC 5322 simplified regex.\n *\n * @param email - Email address to validate\n * @returns true if valid email format\n */\nexport function isValidEmail(email: string): boolean {\n if (email.length < 1 || email.length > 255) {\n return false;\n }\n // RFC 5322 simplified email regex\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n return emailRegex.test(email);\n}\n","/**\n * Media-type registry for Semiont\n *\n * One supported-types list, capability-tiered, keyed by the spec's\n * SupportedMediaType enum. Admission (registry membership) is the\n * create/yield gate: every member is storable, nameable, and uploadable.\n * The curated capabilities say what more the system can do with a type:\n *\n * - `render` — which viewer the UI mounts ('none' → metadata + download)\n * - `anchoring` — which annotation model applies: character-offset text\n * selectors vs spatial geometry (PDFs are spatial)\n * - `extractText` — how the Smelter gets embeddable text ('none' → skip\n * embedding, never mojibake)\n * - `authorable` — offered in the compose editor's format dropdown\n * - `uploadable` — big tent: true for every registry member\n *\n * Capabilities are orthogonal strategies, not a ladder: images render but\n * yield no text; PDFs yield text but aren't authorable. A \"tier\" is a\n * derived reading, not a stored fact.\n *\n * Import-leniency invariant: restore/import preserves archive mediaTypes\n * verbatim, so \"every stored mediaType is registry-valid\" holds only for\n * content that entered through the validated create/yield gate. No code\n * reading a stored mediaType may assume `capabilitiesOf()` succeeds — the\n * `undefined` branch is mandatory wherever stored types are read.\n */\n\nimport type { components } from './types';\n\nexport type SupportedMediaType = components['schemas']['SupportedMediaType'];\n\nexport type RenderMode = 'text' | 'image' | 'pdf' | 'none';\nexport type AnchoringModel = 'text-selector' | 'spatial' | 'none';\nexport type TextExtraction = 'decode' | 'pdf-text-layer' | 'none';\n\nexport interface MediaTypeCapabilities {\n /** Canonical file extension, with leading dot. */\n extension: `.${string}`;\n /** UI display name. */\n label: string;\n render: RenderMode;\n anchoring: AnchoringModel;\n extractText: TextExtraction;\n authorable: boolean;\n uploadable: boolean;\n}\n\n/** Storage tier: catalogued — stored, named, uploadable — but not\n * displayed or annotated. */\nconst storedBinary = (extension: `.${string}`, label: string): MediaTypeCapabilities => ({\n extension,\n label,\n render: 'none',\n anchoring: 'none',\n extractText: 'none',\n authorable: false,\n uploadable: true,\n});\n\n/** Storage tier, text-flavored: embedded (charset-aware decode), not rendered. */\nconst storedText = (extension: `.${string}`, label: string): MediaTypeCapabilities => ({\n ...storedBinary(extension, label),\n extractText: 'decode',\n});\n\n/**\n * The registry. `satisfies Record<SupportedMediaType, …>` is the\n * drift-lock: adding a type to the spec enum without a capabilities row\n * (or vice versa) is a compile error.\n *\n * Row order matters for `mediaTypeForExtension`: extension collisions\n * (.xml, .yaml, .js, .ts, .webm) resolve to the first row declaring the\n * extension.\n */\nexport const MEDIA_TYPES = {\n // Full-capability tier\n 'text/markdown': { extension: '.md', label: 'Markdown', render: 'text', anchoring: 'text-selector', extractText: 'decode', authorable: true, uploadable: true },\n 'text/plain': { extension: '.txt', label: 'Plain Text', render: 'text', anchoring: 'text-selector', extractText: 'decode', authorable: true, uploadable: true },\n 'text/html': { extension: '.html', label: 'HTML', render: 'text', anchoring: 'text-selector', extractText: 'decode', authorable: true, uploadable: true },\n 'application/json': { extension: '.json', label: 'JSON', render: 'text', anchoring: 'text-selector', extractText: 'decode', authorable: false, uploadable: true },\n 'image/png': { extension: '.png', label: 'PNG image', render: 'image', anchoring: 'spatial', extractText: 'none', authorable: false, uploadable: true },\n 'image/jpeg': { extension: '.jpg', label: 'JPEG image', render: 'image', anchoring: 'spatial', extractText: 'none', authorable: false, uploadable: true },\n 'application/pdf': { extension: '.pdf', label: 'PDF', render: 'pdf', anchoring: 'spatial', extractText: 'pdf-text-layer', authorable: false, uploadable: true },\n\n // Storage tier — the big tent. Every row is a deliberate admission,\n // promotable by editing its row. Text-flavored rows embed (decode).\n\n // Text\n 'text/css': storedText('.css', 'CSS'),\n 'text/csv': storedText('.csv', 'CSV'),\n 'text/xml': storedText('.xml', 'XML'),\n\n // Structured-text application formats\n 'application/xml': storedText('.xml', 'XML'),\n 'application/yaml': storedText('.yaml', 'YAML'),\n 'application/x-yaml': storedText('.yaml', 'YAML'),\n\n // Programming languages\n 'text/javascript': storedText('.js', 'JavaScript'),\n 'application/javascript': storedText('.js', 'JavaScript'),\n 'text/x-typescript': storedText('.ts', 'TypeScript'),\n 'application/typescript': storedText('.ts', 'TypeScript'),\n 'text/x-python': storedText('.py', 'Python source'),\n 'text/x-java': storedText('.java', 'Java source'),\n 'text/x-c': storedText('.c', 'C source'),\n 'text/x-c++': storedText('.cpp', 'C++ source'),\n 'text/x-csharp': storedText('.cs', 'C# source'),\n 'text/x-go': storedText('.go', 'Go source'),\n 'text/x-rust': storedText('.rs', 'Rust source'),\n 'text/x-ruby': storedText('.rb', 'Ruby source'),\n 'text/x-php': storedText('.php', 'PHP source'),\n 'text/x-swift': storedText('.swift', 'Swift source'),\n 'text/x-kotlin': storedText('.kt', 'Kotlin source'),\n 'text/x-shell': storedText('.sh', 'Shell script'),\n\n // Documents\n 'application/msword': storedBinary('.doc', 'Word document (legacy)'),\n 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': storedBinary('.docx', 'Word document'),\n 'application/vnd.ms-excel': storedBinary('.xls', 'Excel spreadsheet (legacy)'),\n 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': storedBinary('.xlsx', 'Excel spreadsheet'),\n 'application/vnd.ms-powerpoint': storedBinary('.ppt', 'PowerPoint presentation (legacy)'),\n 'application/vnd.openxmlformats-officedocument.presentationml.presentation': storedBinary('.pptx', 'PowerPoint presentation'),\n\n // Archives\n 'application/zip': storedBinary('.zip', 'ZIP archive'),\n 'application/gzip': storedBinary('.gz', 'Gzip archive'),\n 'application/x-tar': storedBinary('.tar', 'TAR archive'),\n 'application/x-7z-compressed': storedBinary('.7z', '7z archive'),\n\n // Binaries\n 'application/octet-stream': storedBinary('.bin', 'Binary'),\n 'application/wasm': storedBinary('.wasm', 'WebAssembly module'),\n\n // Images beyond the rendered pair\n 'image/gif': storedBinary('.gif', 'GIF image'),\n 'image/webp': storedBinary('.webp', 'WebP image'),\n 'image/svg+xml': storedBinary('.svg', 'SVG image'),\n 'image/bmp': storedBinary('.bmp', 'BMP image'),\n 'image/tiff': storedBinary('.tiff', 'TIFF image'),\n 'image/x-icon': storedBinary('.ico', 'Icon'),\n\n // Video (before audio so .webm resolves to video)\n 'video/mp4': storedBinary('.mp4', 'MP4 video'),\n 'video/mpeg': storedBinary('.mpeg', 'MPEG video'),\n 'video/webm': storedBinary('.webm', 'WebM video'),\n 'video/ogg': storedBinary('.ogv', 'Ogg video'),\n 'video/quicktime': storedBinary('.mov', 'QuickTime video'),\n 'video/x-msvideo': storedBinary('.avi', 'AVI video'),\n\n // Audio\n 'audio/mpeg': storedBinary('.mp3', 'MP3 audio'),\n 'audio/wav': storedBinary('.wav', 'WAV audio'),\n 'audio/ogg': storedBinary('.ogg', 'Ogg audio'),\n 'audio/webm': storedBinary('.webm', 'WebM audio'),\n 'audio/aac': storedBinary('.aac', 'AAC audio'),\n 'audio/flac': storedBinary('.flac', 'FLAC audio'),\n\n // Fonts\n 'font/woff': storedBinary('.woff', 'WOFF font'),\n 'font/woff2': storedBinary('.woff2', 'WOFF2 font'),\n 'font/ttf': storedBinary('.ttf', 'TrueType font'),\n 'font/otf': storedBinary('.otf', 'OpenType font'),\n} satisfies Record<SupportedMediaType, MediaTypeCapabilities>;\n\n// String-indexable view for lookups with runtime strings.\nconst REGISTRY: Readonly<Record<string, MediaTypeCapabilities>> = MEDIA_TYPES;\n\n/**\n * Strip parameters (\"; charset=...\") and normalize case.\n * Replaces the inline `split(';')[0]` sites across the codebase.\n */\nexport function baseMediaType(format: string): string {\n return format.split(';')[0]!.trim().toLowerCase();\n}\n\n/**\n * Registry membership — the admission gate. Exact match: callers pass a\n * base type (see `baseMediaType`); strings carrying parameters are not\n * members.\n */\nexport function isSupportedMediaType(format: string): format is SupportedMediaType {\n return Object.hasOwn(MEDIA_TYPES, format);\n}\n\n/** Capabilities for a format (parameters tolerated), or undefined on registry miss. */\nexport function capabilitiesOf(format: string): MediaTypeCapabilities | undefined {\n return REGISTRY[baseMediaType(format)];\n}\n\n/**\n * Lenient extension lookup for naming foreign/imported content: '.dat' on\n * registry miss. Exporters use this — a vocabulary change must never\n * refuse to name restored data.\n */\nexport function extensionForMediaType(format: string): string {\n return capabilitiesOf(format)?.extension ?? '.dat';\n}\n\nconst EXTENSION_TO_MEDIA_TYPE: ReadonlyMap<string, SupportedMediaType> = (() => {\n const map = new Map<string, SupportedMediaType>();\n for (const type of Object.keys(MEDIA_TYPES) as SupportedMediaType[]) {\n const ext = MEDIA_TYPES[type].extension;\n if (!map.has(ext)) map.set(ext, type);\n }\n return map;\n})();\n\n/** Alternate spellings accepted by `mediaTypeForExtension`, mapped to\n * canonical registry extensions. */\nconst EXTENSION_ALIASES: Readonly<Record<string, string>> = {\n '.markdown': '.md',\n '.htm': '.html',\n '.jpeg': '.jpg',\n '.yml': '.yaml',\n};\n\n/**\n * Inverted registry: extension → media type, for the CLI and the upload\n * detection chain. Accepts 'md' or '.md', any case, and common alternate\n * spellings. Returns undefined for unknown extensions — detection chains\n * fall back to 'application/octet-stream' themselves.\n */\nexport function mediaTypeForExtension(ext: string): SupportedMediaType | undefined {\n const lower = ext.trim().toLowerCase();\n const dotted = lower.startsWith('.') ? lower : `.${lower}`;\n return EXTENSION_TO_MEDIA_TYPE.get(EXTENSION_ALIASES[dotted] ?? dotted);\n}\n\n/**\n * The Smelter's gate: how to get embeddable text from a format. Registry\n * rows answer directly; on a registry miss, base types under text/* decode\n * (RFC 2046 guarantees the text top-level type is textual — imported\n * unregistered text subtypes embed too), everything else is 'none'.\n */\nexport function textExtractionOf(format: string): TextExtraction {\n const caps = capabilitiesOf(format);\n if (caps) return caps.extractText;\n return baseMediaType(format).startsWith('text/') ? 'decode' : 'none';\n}\n\nconst REGISTRY_KEYS = Object.keys(MEDIA_TYPES) as SupportedMediaType[];\n\n/** Types offered in the compose editor's format dropdown. */\nexport const AUTHORABLE_MEDIA_TYPES: readonly SupportedMediaType[] = REGISTRY_KEYS.filter(\n (type) => MEDIA_TYPES[type].authorable,\n);\n\n/** Registry rows whose text the Smelter can extract. Rows only — the\n * text/* fallback in `textExtractionOf` isn't enumerable. */\nexport const EMBEDDABLE_MEDIA_TYPES: readonly SupportedMediaType[] = REGISTRY_KEYS.filter(\n (type) => MEDIA_TYPES[type].extractText !== 'none',\n);\n","/**\n * Common type guard utilities\n */\n\n/**\n * Check if value is a string\n */\nexport function isString(value: unknown): value is string {\n return typeof value === 'string';\n}\n\n/**\n * Check if value is a number (not NaN)\n */\nexport function isNumber(value: unknown): value is number {\n return typeof value === 'number' && !isNaN(value);\n}\n\n/**\n * Check if value is an object (not null, not array)\n */\nexport function isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/**\n * Check if value is an array\n */\nexport function isArray(value: unknown): value is unknown[] {\n return Array.isArray(value);\n}\n\n/**\n * Check if value is a boolean\n */\nexport function isBoolean(value: unknown): value is boolean {\n return typeof value === 'boolean';\n}\n\n/**\n * Check if value is a function\n */\nexport function isFunction(value: unknown): value is Function {\n return typeof value === 'function';\n}\n\n/**\n * Check if value is null\n */\nexport function isNull(value: unknown): value is null {\n return value === null;\n}\n\n/**\n * Check if value is undefined\n */\nexport function isUndefined(value: unknown): value is undefined {\n return value === undefined;\n}\n\n/**\n * Check if value is null or undefined\n */\nexport function isNullish(value: unknown): value is null | undefined {\n return value === null || value === undefined;\n}\n\n/**\n * Check if value is defined (not null or undefined)\n */\nexport function isDefined<T>(value: T | null | undefined): value is T {\n return value !== null && value !== undefined;\n}","/**\n * Common error classes — the unified Semiont error hierarchy.\n *\n * `SemiontError` is the base every other Semiont error class extends:\n * `APIError` (http-transport), `BusRequestError` and `SemiontSessionError` (sdk),\n * `ValidationError`, `ScriptError`, `NotFoundError`, `UnauthorizedError`,\n * `ConflictError` (here), and `AWSError` (cli). Subclasses tighten the\n * `code` field to a literal-union for discriminated handling.\n */\n\n/**\n * Transport-neutral error vocabulary. Every transport that surfaces\n * errors over `ITransport.errors$` maps its native failure modes to one\n * of these codes — HTTP `APIError` maps from status code, in-process\n * transports map from local failure shape, gRPC would map from status\n * code, etc. Routing layers (e.g. `SemiontBrowser`'s session-expired /\n * permission-denied modal routing) match on this vocabulary so they\n * stay transport-agnostic.\n *\n * - `unauthorized` — auth required / token missing or expired (HTTP 401)\n * - `forbidden` — auth ok but lacks permission (HTTP 403)\n * - `not-found` — resource missing (HTTP 404)\n * - `conflict` — concurrent modification, duplicate, etc. (HTTP 409)\n * - `bad-request` — request malformed (HTTP 400)\n * - `unavailable` — backend unreachable, network error, 5xx\n * - `error` — unclassified fallback\n */\nexport type TransportErrorCode =\n | 'unauthorized'\n | 'forbidden'\n | 'not-found'\n | 'conflict'\n | 'bad-request'\n | 'unavailable'\n | 'error';\n\nexport class SemiontError extends Error {\n constructor(\n message: string,\n public code: string,\n public details?: Record<string, unknown>,\n ) {\n super(message);\n this.name = 'SemiontError';\n Error.captureStackTrace(this, this.constructor);\n }\n}\n\nexport class ValidationError extends SemiontError {\n constructor(message: string, details?: Record<string, unknown>) {\n super(message, 'VALIDATION_ERROR', details);\n this.name = 'ValidationError';\n }\n}\n\nexport class ScriptError extends SemiontError {\n constructor(message: string, code: string = 'SCRIPT_ERROR', details?: Record<string, unknown>) {\n super(message, code, details);\n this.name = 'ScriptError';\n }\n}\n\nexport class NotFoundError extends SemiontError {\n constructor(resource: string, id?: string) {\n const message = id ? `${resource} with id '${id}' not found` : `${resource} not found`;\n super(message, 'NOT_FOUND', { resource, id });\n this.name = 'NotFoundError';\n }\n}\n\nexport class UnauthorizedError extends SemiontError {\n constructor(message: string = 'Unauthorized', details?: Record<string, unknown>) {\n super(message, 'UNAUTHORIZED', details);\n this.name = 'UnauthorizedError';\n }\n}\n\nexport class ConflictError extends SemiontError {\n constructor(message: string, details?: Record<string, unknown>) {\n super(message, 'CONFLICT', details);\n this.name = 'ConflictError';\n }\n}\n","/**\n * DID (Decentralized Identifier) and W3C Agent utilities\n *\n * DID:WEB shapes used in Semiont:\n *\n * Person: did:web:<host>:users:<email%40host>\n * Software: did:web:<host>:agents:<provider>:<model>\n *\n * `didToAgent` is the inverse: parse the DID, recognize whether the\n * subject is a person or a software peer, and return a typed Agent.\n *\n * Humans and software peers share the same identity *shape* (a DID\n * with a typed Agent on read). What differs is the path segment\n * (`:users:` vs `:agents:`) and the schema-typed fields each kind\n * carries on its Agent record.\n */\n\nimport type { components } from './types';\n\ntype Agent = components['schemas']['Agent'];\n\n/**\n * Convert a user object to a DID:WEB identifier.\n *\n * Format: did:web:<domain>:users:<email%40domain>\n */\nexport function userToDid(user: { email: string; domain: string }): string {\n return `did:web:${user.domain}:users:${encodeURIComponent(user.email)}`;\n}\n\n/**\n * Convert a software peer's (provider, model) configuration to a DID:WEB\n * identifier. Pool-vs-individual deployment is not part of identity —\n * one DID per (provider, model) on this host.\n *\n * Format: did:web:<domain>:agents:<provider>:<model%2F-encoded>\n *\n * Model strings often contain `:` and `/` (e.g. `gemma2:27b`,\n * `library/llama3`); both must be URI-encoded so DID parsing isn't\n * ambiguous.\n */\nexport function agentToDid(agent: { domain: string; provider: string; model: string }): string {\n return `did:web:${agent.domain}:agents:${encodeURIComponent(agent.provider)}:${encodeURIComponent(agent.model)}`;\n}\n\n/**\n * Convert a user object to a typed Person Agent with a DID:WEB identifier.\n */\nexport function userToAgent(user: {\n id: string;\n domain: string;\n name: string | null;\n email: string;\n}): Agent {\n return {\n '@type': 'Person',\n '@id': userToDid(user),\n name: user.name || user.email,\n };\n}\n\n/**\n * Convert a software peer's configuration to a typed Software Agent.\n * The `name` is a stable human-friendly label, not a parseable join —\n * UI composes display from `provider`/`model` at render time.\n */\nexport function softwareToAgent(software: {\n domain: string;\n provider: string;\n model: string;\n parameters?: Record<string, unknown>;\n}): Agent {\n return {\n '@type': 'Software',\n '@id': agentToDid(software),\n name: `${software.provider} ${software.model}`,\n provider: software.provider,\n model: software.model,\n ...(software.parameters && { parameters: software.parameters }),\n };\n}\n\n/**\n * Parse a DID:WEB string into a typed Agent.\n *\n * Recognizes:\n * did:web:<host>:users:<email> → Person (name = decoded email)\n * did:web:<host>:agents:<provider>:<model> → Software (provider + model)\n *\n * Anything else falls back to a Person with the trailing segment as\n * `name`. This is the read-side inverse of `userToDid`/`agentToDid`.\n */\nexport function didToAgent(did: string | undefined | null): Agent {\n if (!did) {\n return { '@type': 'Person', '@id': 'unknown', name: 'unknown' };\n }\n const parts = did.split(':');\n\n // Find the kind segment, scanning from the right so we are not fooled\n // by `host:port` colons earlier in the string.\n const agentsIdx = parts.lastIndexOf('agents');\n const usersIdx = parts.lastIndexOf('users');\n\n if (agentsIdx >= 0 && agentsIdx === parts.length - 3) {\n const provider = decodeURIComponent(parts[agentsIdx + 1] ?? '');\n const model = decodeURIComponent(parts[agentsIdx + 2] ?? '');\n return {\n '@type': 'Software',\n '@id': did,\n name: `${provider} ${model}`,\n provider,\n model,\n };\n }\n\n if (usersIdx >= 0 && usersIdx === parts.length - 2) {\n const name = decodeURIComponent(parts[usersIdx + 1] ?? '');\n return {\n '@type': 'Person',\n '@id': did,\n name,\n };\n }\n\n // Unknown shape — preserve the DID as @id, derive a best-effort name\n // from the trailing segment. Treat as Person (the safer default for\n // unknown actors).\n const encoded = parts[parts.length - 1] || 'unknown';\n return {\n '@type': 'Person',\n '@id': did,\n name: decodeURIComponent(encoded),\n };\n}\n","/**\n * TOML Config Loader\n *\n * Reads ~/.semiontconfig (TOML) and .semiont/config (TOML) and produces\n * an EnvironmentConfig for the requested environment.\n *\n * File format: see TOML-XDG-CONFIG.md\n *\n * Loading sequence:\n * 1. Read .semiont/config → projectName, site, environments.<env>.* (project base)\n * 2. Read ~/.semiontconfig → defaults, environments.<env>.* (user overrides)\n * 3. Deep-merge: project base ← user overrides (user wins on conflicts)\n * Any environment name is valid (local, staging, production, custom, ...)\n * 4. Resolve ${VAR} references from process.env\n * 5. Apply inheritance: workers.<name> → workers.default → error\n * 6. Map to EnvironmentConfig shape\n */\n\nimport { parse as parseToml } from 'smol-toml';\nimport type { EnvironmentConfig, OllamaProviderConfig, AnthropicProviderConfig } from './config.types';\nimport type { PlatformType } from './config.types';\n\n/**\n * Deep merge two plain objects. Arrays and primitives in `override` replace those in `base`.\n * Nested objects are merged recursively. `override` takes precedence on conflicts.\n */\nfunction deepMerge<T extends Record<string, unknown>>(base: T, override: Partial<T>): T {\n const result = { ...base } as Record<string, unknown>;\n for (const key of Object.keys(override)) {\n const b = base[key];\n const o = override[key];\n if (o !== undefined && o !== null && typeof o === 'object' && !Array.isArray(o) &&\n b !== undefined && b !== null && typeof b === 'object' && !Array.isArray(b)) {\n result[key] = deepMerge(b as Record<string, unknown>, o as Record<string, unknown>);\n } else if (o !== undefined) {\n result[key] = o;\n }\n }\n return result as T;\n}\n\nfunction resolveEnvVars(obj: unknown, env: Record<string, string | undefined>): unknown {\n if (typeof obj === 'string') {\n return obj.replace(/\\$\\{([^}]+)\\}/g, (match, expr: string) => {\n const sepIdx = expr.indexOf(':-');\n const varName = sepIdx >= 0 ? expr.slice(0, sepIdx) : expr;\n const defaultValue = sepIdx >= 0 ? expr.slice(sepIdx + 2) : undefined;\n const value = env[varName];\n if (value !== undefined) return value;\n if (defaultValue !== undefined) return defaultValue;\n throw new Error(`Environment variable ${varName} is not set (referenced in config as ${match})`);\n });\n }\n if (Array.isArray(obj)) {\n return obj.map(item => resolveEnvVars(item, env));\n }\n if (obj !== null && typeof obj === 'object') {\n const resolved: Record<string, unknown> = {};\n for (const key in obj as Record<string, unknown>) {\n resolved[key] = resolveEnvVars((obj as Record<string, unknown>)[key], env);\n }\n return resolved;\n }\n return obj;\n}\n\n// ── Inference config types (mirrored from packages/make-meaning/src/config.ts) ─\n// Kept here to avoid a circular dependency: core cannot import make-meaning.\n\nexport interface InferenceConfig {\n type: 'anthropic' | 'ollama';\n model: string;\n maxTokens?: number;\n apiKey?: string;\n endpoint?: string;\n baseURL?: string;\n}\n\nexport interface ActorInferenceConfig {\n gatherer?: InferenceConfig;\n matcher?: InferenceConfig;\n}\n\nexport interface WorkerInferenceConfig {\n default?: InferenceConfig;\n 'reference-annotation'?: InferenceConfig;\n 'highlight-annotation'?: InferenceConfig;\n 'assessment-annotation'?: InferenceConfig;\n 'comment-annotation'?: InferenceConfig;\n 'tag-annotation'?: InferenceConfig;\n 'generation'?: InferenceConfig;\n}\n\n// ── Types for ~/.semiontconfig ────────────────────────────────────────────────\n\ninterface SemiontConfigFile {\n user?: {\n name?: string;\n email?: string;\n };\n defaults?: {\n environment?: string;\n platform?: string;\n };\n environments?: Record<string, EnvironmentSection>;\n}\n\ninterface GraphSection {\n platform?: string;\n type?: string;\n name?: string;\n uri?: string;\n username?: string;\n password?: string;\n database?: string;\n [key: string]: unknown;\n}\n\ninterface InferenceFlatSection {\n // Flat (single-provider) format: type = \"anthropic\"|\"ollama\" at this level\n type?: 'anthropic' | 'ollama';\n platform?: string;\n model?: string;\n maxTokens?: number;\n apiKey?: string;\n endpoint?: string;\n baseURL?: string;\n // Keyed (multi-provider) format: [inference.anthropic] / [inference.ollama]\n anthropic?: { platform?: string; apiKey?: string; endpoint?: string };\n ollama?: { platform?: string; baseURL?: string; port?: number };\n}\n\ninterface EnvironmentSection {\n backend?: {\n platform?: string;\n port?: number;\n publicURL?: string;\n frontendURL?: string;\n corsOrigin?: string;\n };\n frontend?: {\n platform?: string;\n port?: number;\n publicURL?: string;\n };\n site?: {\n domain?: string;\n siteName?: string;\n adminEmail?: string;\n oauthAllowedDomains?: string[];\n enableLocalAuth?: boolean;\n };\n database?: {\n platform?: string;\n image?: string;\n host?: string;\n port?: number;\n name?: string;\n user?: string;\n password?: string;\n };\n graph?: GraphSection;\n vectors?: {\n type?: 'qdrant' | 'memory';\n host?: string;\n port?: number;\n // Legacy: embedding nested under vectors (migrated to top-level)\n embedding?: {\n type?: 'voyage' | 'ollama';\n model?: string;\n apiKey?: string;\n baseURL?: string;\n endpoint?: string;\n };\n chunking?: {\n chunkSize?: number;\n overlap?: number;\n };\n };\n embedding?: {\n type?: 'voyage' | 'ollama';\n model?: string;\n apiKey?: string;\n baseURL?: string;\n endpoint?: string;\n chunking?: {\n chunkSize?: number;\n overlap?: number;\n };\n };\n inference?: InferenceFlatSection;\n 'make-meaning'?: {\n graph?: Record<string, unknown>;\n actors?: {\n gatherer?: { inference?: InferenceConfig };\n matcher?: { inference?: InferenceConfig };\n };\n default?: { inference?: InferenceConfig };\n };\n workers?: Record<string, { inference?: InferenceConfig }>;\n actors?: Record<string, { inference?: InferenceConfig }>;\n logLevel?: 'error' | 'warn' | 'info' | 'http' | 'debug';\n}\n\n// ── File reader abstraction (same pattern as createConfigLoader) ──────────────\n\nexport type TomlFileReader = {\n readIfExists: (path: string) => string | null;\n};\n\nfunction requirePlatform(value: string | undefined, serviceName: string): PlatformType {\n if (!value) {\n throw new Error(`platform is required for service '${serviceName}' — add 'platform = \"posix\"|\"container\"|\"external\"' to its config section`);\n }\n return value as PlatformType;\n}\n\n// ── Main loader function ──────────────────────────────────────────────────────\n\n/**\n * Parse ~/.semiontconfig and .semiont/config and return EnvironmentConfig.\n *\n * @param projectRoot - Path to the project root (contains .semiont/config)\n * @param environment - Environment name (e.g. 'local', 'production')\n * @param globalConfigPath - Path to ~/.semiontconfig (caller resolves ~ expansion)\n * @param reader - File reader abstraction\n * @param env - Environment variables for ${VAR} resolution\n */\nexport function loadTomlConfig(\n projectRoot: string | null,\n environment: string,\n globalConfigPath: string,\n reader: TomlFileReader,\n env: Record<string, string | undefined>\n): EnvironmentConfig {\n // 1. Read project config from .semiont/config (skipped when no project root)\n const projectConfigContent = projectRoot ? reader.readIfExists(`${projectRoot}/.semiont/config`) : null;\n let projectName = 'semiont-project';\n let projectVersion: string | undefined;\n let projectSite: EnvironmentSection['site'] | undefined;\n let projectEnvSection: EnvironmentSection = {};\n if (projectConfigContent) {\n const projectConfig = parseToml(projectConfigContent) as {\n project?: { name?: string; version?: string };\n site?: EnvironmentSection['site'];\n environments?: Record<string, EnvironmentSection>;\n };\n projectName = projectConfig.project?.name ?? projectName;\n projectVersion = projectConfig.project?.version;\n projectSite = projectConfig.site;\n projectEnvSection = projectConfig.environments?.[environment] ?? {};\n }\n\n // 2. Read global config (optional — missing config yields empty environments)\n const globalContent = reader.readIfExists(globalConfigPath);\n const raw = globalContent ? (parseToml(globalContent) as SemiontConfigFile) : ({} as SemiontConfigFile);\n\n // 3. Deep-merge: project base + user overrides (user wins on conflicts)\n const userEnvSection: EnvironmentSection = raw.environments?.[environment] ?? {};\n const envSection: EnvironmentSection = deepMerge(\n projectEnvSection as Record<string, unknown>,\n userEnvSection as Record<string, unknown>\n ) as EnvironmentSection;\n\n // 4. Resolve ${VAR} references\n const resolved = resolveEnvVars(envSection, env) as EnvironmentSection;\n\n // 5. Build make-meaning actor/worker inference config with inheritance\n // The flat [inference] section provides defaults (apiKey, maxTokens, endpoint/baseURL).\n // Actor/worker sections only need to specify type and model; missing fields fall back\n // to the flat inference section.\n const flatInference = resolved.inference;\n const makeMeaningSection = resolved['make-meaning'];\n const workersSection = resolved.workers ?? {};\n const actorsSection = resolved.actors ?? {};\n const defaultWorkerInference = workersSection['default']?.inference;\n const defaultMakeMeaningInference = makeMeaningSection?.default?.inference;\n\n function mergeWithFlatInference(specific: InferenceConfig): InferenceConfig {\n if (!flatInference) return specific;\n // For keyed sub-sections, inherit credentials from the matching provider sub-section.\n // For flat (legacy) format, flatInference.type is required to know which fields apply.\n const providerDefaults: Partial<InferenceConfig> = {};\n if (specific.type === 'anthropic') {\n const a = flatInference.anthropic;\n if (a) {\n providerDefaults.apiKey = a.apiKey;\n providerDefaults.endpoint = a.endpoint;\n } else {\n if (!flatInference.type) {\n throw new Error(\n `[environments.${environment}.inference] is missing 'type'. ` +\n `Add type = \"anthropic\" or use [inference.anthropic] sub-section.`\n );\n }\n providerDefaults.apiKey = flatInference.apiKey;\n providerDefaults.endpoint = flatInference.endpoint;\n }\n } else if (specific.type === 'ollama') {\n const o = flatInference.ollama;\n if (o) {\n providerDefaults.baseURL = o.baseURL;\n } else {\n if (!flatInference.type) {\n throw new Error(\n `[environments.${environment}.inference] is missing 'type'. ` +\n `Add type = \"ollama\" or use [inference.ollama] sub-section.`\n );\n }\n providerDefaults.baseURL = flatInference.baseURL;\n }\n }\n return {\n maxTokens: flatInference.maxTokens,\n ...providerDefaults,\n ...specific,\n };\n }\n\n function resolveActorInference(fromMakeMeaning?: InferenceConfig, fromActors?: InferenceConfig): InferenceConfig | undefined {\n const base = fromMakeMeaning ?? fromActors ?? defaultMakeMeaningInference;\n if (!base) return undefined;\n return mergeWithFlatInference(base);\n }\n\n const actors: ActorInferenceConfig = {};\n const gathererInference = resolveActorInference(\n makeMeaningSection?.actors?.gatherer?.inference,\n actorsSection['gatherer']?.inference\n );\n if (gathererInference) actors.gatherer = gathererInference;\n\n const matcherInference = resolveActorInference(\n makeMeaningSection?.actors?.matcher?.inference,\n actorsSection['matcher']?.inference\n );\n if (matcherInference) actors.matcher = matcherInference;\n\n const workers: WorkerInferenceConfig = {};\n const workerTypes = ['reference-annotation', 'highlight-annotation', 'assessment-annotation', 'comment-annotation', 'tag-annotation', 'generation'] as const;\n if (defaultWorkerInference) {\n workers.default = mergeWithFlatInference(defaultWorkerInference);\n }\n for (const wt of workerTypes) {\n const specific = workersSection[wt]?.inference;\n if (specific) {\n (workers as Record<string, InferenceConfig>)[wt] = mergeWithFlatInference(specific);\n }\n }\n\n // 6. Map to EnvironmentConfig\n const backend = resolved.backend;\n const site = resolved.site ?? projectSite;\n const inferenceSection = resolved.inference;\n\n // Build inference providers config.\n // Supports two formats:\n // Flat: [environments.local.inference] type = \"anthropic\"|\"ollama\" (single provider)\n // Keyed: [environments.local.inference.anthropic] / [environments.local.inference.ollama] (multi-provider)\n let inferenceProviders: EnvironmentConfig['inference'] | undefined;\n if (inferenceSection) {\n inferenceProviders = {};\n // Keyed sub-sections take priority\n if (inferenceSection.anthropic) {\n const a = inferenceSection.anthropic;\n inferenceProviders.anthropic = {\n platform: requirePlatform(a.platform, 'inference.anthropic'),\n endpoint: a.endpoint ?? 'https://api.anthropic.com',\n apiKey: a.apiKey ?? '',\n } as AnthropicProviderConfig;\n } else if (inferenceSection.type === 'anthropic') {\n inferenceProviders.anthropic = {\n platform: requirePlatform(inferenceSection.platform, 'inference'),\n endpoint: inferenceSection.endpoint ?? 'https://api.anthropic.com',\n apiKey: inferenceSection.apiKey ?? '',\n } as AnthropicProviderConfig;\n }\n if (inferenceSection.ollama) {\n const o = inferenceSection.ollama;\n inferenceProviders.ollama = {\n platform: { type: requirePlatform(o.platform, 'inference.ollama') },\n baseURL: o.baseURL,\n port: o.baseURL ? undefined : (o.port ?? 11434),\n } as OllamaProviderConfig;\n } else if (inferenceSection.type === 'ollama') {\n inferenceProviders.ollama = {\n platform: { type: requirePlatform(inferenceSection.platform, 'inference') },\n baseURL: inferenceSection.baseURL,\n port: inferenceSection.baseURL ? undefined : 11434,\n } as OllamaProviderConfig;\n }\n }\n\n // Build top-level workers/actors maps for EnvironmentConfig\n const topLevelWorkers: EnvironmentConfig['workers'] = {};\n for (const [name, w] of Object.entries(workersSection)) {\n if (w.inference) {\n topLevelWorkers[name] = { inference: { type: w.inference.type, model: w.inference.model } };\n }\n }\n const topLevelActors: EnvironmentConfig['actors'] = {};\n for (const [name, a] of Object.entries(actorsSection)) {\n if (a.inference) {\n topLevelActors[name] = { inference: { type: a.inference.type, model: a.inference.model } };\n }\n }\n // Also include make-meaning actors\n if (makeMeaningSection?.actors?.gatherer?.inference) {\n topLevelActors['gatherer'] = { inference: { type: makeMeaningSection.actors.gatherer.inference.type, model: makeMeaningSection.actors.gatherer.inference.model } };\n }\n if (makeMeaningSection?.actors?.matcher?.inference) {\n topLevelActors['matcher'] = { inference: { type: makeMeaningSection.actors.matcher.inference.type, model: makeMeaningSection.actors.matcher.inference.model } };\n }\n\n const frontend = resolved.frontend;\n\n const services: EnvironmentConfig['services'] = {};\n\n if (backend) {\n services.backend = {\n platform: { type: requirePlatform(backend.platform, 'backend') },\n port: backend.port ?? 4000,\n publicURL: backend.publicURL ?? `http://localhost:${backend.port ?? 4000}`,\n corsOrigin: backend.corsOrigin ?? backend.frontendURL ?? 'http://localhost:3000',\n };\n }\n\n if (frontend) {\n services.frontend = {\n platform: { type: requirePlatform(frontend.platform, 'frontend') },\n port: frontend.port ?? 3000,\n siteName: site?.siteName ?? 'Semiont',\n publicURL: frontend.publicURL,\n };\n }\n\n if (resolved.graph) {\n services.graph = {\n ...resolved.graph,\n platform: { type: requirePlatform(resolved.graph.platform as string | undefined, 'graph') },\n type: (resolved.graph.type ?? 'neo4j') as import('./config.types').GraphDatabaseType,\n } as EnvironmentConfig['services']['graph'];\n } else if (makeMeaningSection?.graph) {\n services.graph = makeMeaningSection.graph as EnvironmentConfig['services']['graph'];\n }\n\n if (resolved.database) {\n services.database = {\n platform: { type: requirePlatform(resolved.database.platform, 'database') },\n type: 'postgres',\n image: resolved.database.image,\n host: resolved.database.host ?? 'localhost',\n port: resolved.database.port ?? 5432,\n name: resolved.database.name,\n user: resolved.database.user,\n password: resolved.database.password,\n } as EnvironmentConfig['services']['database'];\n }\n\n if (resolved.vectors) {\n services.vectors = {\n platform: { type: 'external' as PlatformType },\n type: (resolved.vectors.type ?? 'qdrant') as 'qdrant' | 'memory',\n host: resolved.vectors.host,\n port: resolved.vectors.port ?? 6333,\n } as EnvironmentConfig['services']['vectors'];\n }\n\n // Embedding: top-level takes precedence, fall back to legacy vectors.embedding\n const embeddingSource = resolved.embedding ?? resolved.vectors?.embedding;\n if (embeddingSource) {\n services.embedding = {\n platform: { type: 'external' as PlatformType },\n type: embeddingSource.type!,\n model: embeddingSource.model!,\n apiKey: embeddingSource.apiKey,\n baseURL: embeddingSource.baseURL,\n endpoint: embeddingSource.endpoint,\n chunking: (resolved.embedding?.chunking ?? resolved.vectors?.chunking) ? {\n chunkSize: (resolved.embedding?.chunking ?? resolved.vectors?.chunking)?.chunkSize ?? 512,\n overlap: (resolved.embedding?.chunking ?? resolved.vectors?.chunking)?.overlap ?? 64,\n } : undefined,\n } as EnvironmentConfig['services']['embedding'];\n }\n\n const config: EnvironmentConfig = {\n services,\n ...(inferenceProviders ? { inference: inferenceProviders } : {}),\n ...(Object.keys(topLevelWorkers).length > 0 ? { workers: topLevelWorkers } : {}),\n ...(Object.keys(topLevelActors).length > 0 ? { actors: topLevelActors } : {}),\n site: site ? {\n domain: site.domain ?? 'localhost',\n siteName: site.siteName,\n adminEmail: site.adminEmail,\n oauthAllowedDomains: site.oauthAllowedDomains as [string, ...string[]] | undefined,\n } : undefined,\n logLevel: resolved.logLevel,\n _metadata: {\n environment,\n projectRoot,\n projectName,\n projectVersion,\n ...(Object.keys(actors).length > 0 ? { actors } : {}),\n ...(Object.keys(workers).length > 0 ? { workers } : {}),\n },\n };\n\n return config;\n}\n\n/**\n * Create a TOML config loader backed by a file reader.\n * Drop-in replacement for createConfigLoader that reads TOML instead of JSON.\n * The caller must resolve globalConfigPath (e.g. expand '~' using process.env.HOME).\n */\nexport function createTomlConfigLoader(\n reader: TomlFileReader,\n globalConfigPath: string,\n env: Record<string, string | undefined>\n) {\n return (projectRoot: string | null, environment: string): EnvironmentConfig => {\n return loadTomlConfig(projectRoot, environment, globalConfigPath, reader, env);\n };\n}\n","/**\n * Environment validation utilities\n *\n * Pure functions - accept available environments as parameter instead of reading from filesystem\n */\n\nexport type Environment = string; // Allow any environment name\n\n/**\n * Type guard to check if a string is a valid Environment\n * @param value - The environment string to check\n * @param availableEnvironments - List of valid environment names\n */\nexport function isValidEnvironment(value: string | undefined, availableEnvironments: string[]): value is Environment {\n if (!value) return false;\n return availableEnvironments.includes(value);\n}\n\n/**\n * Parse environment string to Environment type\n * @param value - The environment string to parse\n * @param availableEnvironments - List of valid environment names\n * @returns Valid Environment type\n * @throws Error if environment is invalid or not provided\n */\nexport function parseEnvironment(value: string | undefined, availableEnvironments: string[]): Environment {\n if (!value) {\n throw new Error('Environment is required');\n }\n if (!isValidEnvironment(value, availableEnvironments)) {\n throw new Error(`Invalid environment: ${value}. Available environments: ${availableEnvironments.join(', ')}`);\n }\n return value;\n}\n\n/**\n * Validate and return environment or throw error\n * @param value - The environment string to validate\n * @param availableEnvironments - List of valid environment names\n * @throws Error if environment is invalid\n */\nexport function validateEnvironment(value: string | undefined, availableEnvironments: string[]): Environment {\n if (!value) {\n throw new Error('Environment is required');\n }\n if (!isValidEnvironment(value, availableEnvironments)) {\n throw new Error(`Invalid environment: ${value}. Available environments: ${availableEnvironments.join(', ')}`);\n }\n return value;\n}","/**\n * Configuration Error Class\n * \n * Custom error class for configuration validation and loading errors.\n * Provides structured error information with helpful suggestions.\n */\n\nexport class ConfigurationError extends Error {\n public override readonly cause?: Error;\n\n constructor(\n message: string,\n public environment?: string,\n public suggestion?: string,\n cause?: Error\n ) {\n super(message);\n this.name = 'ConfigurationError';\n this.cause = cause;\n }\n \n /**\n * Format the error nicely for CLI output\n */\n override toString(): string {\n let output = `❌ ${this.message}`;\n if (this.environment) {\n output += `\\n Environment: ${this.environment}`;\n }\n if (this.suggestion) {\n output += `\\n 💡 Suggestion: ${this.suggestion}`;\n }\n return output;\n }\n}","/**\n * Platform Types Module\n *\n * Re-exports PlatformType from schema-generated types.\n * Platforms represent WHERE services run (infrastructure targets).\n */\n\nimport { PlatformType as SchemaPlatformType } from './config.types';\n\n/**\n * Platform type literals from JSON Schema\n * These represent the infrastructure targets where services can be deployed\n */\nexport type PlatformType = SchemaPlatformType;\n\n/**\n * Type guard to check if a string is a valid platform type\n *\n * @param value - Value to check\n * @returns True if value is a valid PlatformType\n */\nexport function isValidPlatformType(value: string): value is PlatformType {\n return ['aws', 'container', 'posix', 'external'].includes(value);\n}\n\n/**\n * Get all valid platform types\n *\n * @returns Array of all platform types\n */\nexport function getAllPlatformTypes(): PlatformType[] {\n return ['aws', 'container', 'posix', 'external'];\n}"]}
|
|
1
|
+
{"version":3,"sources":["../src/branded-types.ts","../src/identifiers.ts","../src/persisted-events.ts","../src/bus-protocol.ts","../src/event-utils.ts","../src/bus-log.ts","../src/event-bus.ts","../src/operators/burst-buffer.ts","../src/serialize-per-key.ts","../src/logger.ts","../src/annotation-utils.ts","../src/id-generation.ts","../src/annotation-assembly.ts","../src/web-annotation-utils.ts","../src/pdf-coordinates.ts","../src/resource-utils.ts","../src/bridged-channels.ts","../src/fuzzy-anchor.ts","../src/anchor-annotation.ts","../src/locales.ts","../src/svg-utils.ts","../src/text-context.ts","../src/text-encoding.ts","../src/validation.ts","../src/media-types.ts","../src/type-guards.ts","../src/errors.ts","../src/did-utils.ts","../src/config/toml-loader.ts","../src/config/environment-validator.ts","../src/config/configuration-error.ts","../src/config/platform-types.ts"],"names":["resourceUri","baseUrl","annotationUri","resourceId","ctx","start","end","email","parseToml"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Branded string types for compile-time type safety\n *\n * These types are zero-cost at runtime but prevent mixing\n * different string types at compile time.\n */\n\nimport type { components } from './types';\n\n// ============================================================================\n// OPENAPI-GENERATED TYPES (use directly from spec)\n// ============================================================================\n\nexport type Motivation = components['schemas']['Motivation'];\nexport type ContentFormat = components['schemas']['ContentFormat'];\n\n// ============================================================================\n// AUTHENTICATION & TOKENS\n// ============================================================================\n\nexport type Email = string & { readonly __brand: 'Email' };\nexport type AuthCode = string & { readonly __brand: 'AuthCode' };\nexport type GoogleCredential = string & { readonly __brand: 'GoogleCredential' };\nexport type AccessToken = string & { readonly __brand: 'AccessToken' };\nexport type RefreshToken = string & { readonly __brand: 'RefreshToken' };\nexport type MCPToken = string & { readonly __brand: 'MCPToken' };\nexport type CloneToken = string & { readonly __brand: 'CloneToken' };\n\n// ============================================================================\n// SYSTEM IDENTIFIERS\n// ============================================================================\n\nexport type JobId = string & { readonly __brand: 'JobId' };\nexport type UserDID = string & { readonly __brand: 'UserDID' };\nexport type EntityType = string & { readonly __brand: 'EntityType' };\nexport type SearchQuery = string & { readonly __brand: 'SearchQuery' };\nexport type BaseUrl = string & { readonly __brand: 'BaseUrl' };\n\n// ============================================================================\n// HELPER FUNCTIONS (minimal validation, just branding)\n// ============================================================================\n\nexport function email(value: string): Email { return value as Email; }\nexport function authCode(value: string): AuthCode { return value as AuthCode; }\nexport function googleCredential(value: string): GoogleCredential { return value as GoogleCredential; }\nexport function accessToken(value: string): AccessToken { return value as AccessToken; }\nexport function refreshToken(value: string): RefreshToken { return value as RefreshToken; }\nexport function mcpToken(value: string): MCPToken { return value as MCPToken; }\nexport function cloneToken(value: string): CloneToken { return value as CloneToken; }\nexport function jobId(value: string): JobId { return value as JobId; }\nexport function userDID(value: string): UserDID { return value as UserDID; }\nexport function entityType(value: string): EntityType { return value as EntityType; }\nexport function searchQuery(value: string): SearchQuery { return value as SearchQuery; }\nexport function baseUrl(value: string): BaseUrl { return value as BaseUrl; }\n\n// Motivation is an OpenAPI enum — use its values directly, no helper needed.\n// ContentFormat is a free-form MIME string whose base type must be a\n// SupportedMediaType; validation lives in media-types.ts, not in a brand.\n\n// ============================================================================\n// HTTP URI TYPES\n// ============================================================================\n\n// Branded type definitions for HTTP URIs returned by the API\nexport type ResourceUri = string & { readonly __brand: 'ResourceUri' };\n\n// W3C flat format for content negotiation: http://localhost:4000/annotations/{id}\nexport type AnnotationUri = string & { readonly __brand: 'AnnotationUri' };\n\n// Nested format for CRUD operations: http://localhost:4000/resources/{resourceId}/annotations/{annotationId}\nexport type ResourceAnnotationUri = string & { readonly __brand: 'ResourceAnnotationUri' };\n\n// Factory functions with runtime validation\nexport function resourceUri(uri: string): ResourceUri {\n if (!uri.startsWith('http://') && !uri.startsWith('https://')) {\n throw new TypeError(`Expected ResourceUri, got: ${uri}`);\n }\n return uri as ResourceUri;\n}\n\nexport function annotationUri(uri: string): AnnotationUri {\n if (!uri.startsWith('http://') && !uri.startsWith('https://')) {\n throw new TypeError(`Expected AnnotationUri, got: ${uri}`);\n }\n return uri as AnnotationUri;\n}\n\nexport function resourceAnnotationUri(uri: string): ResourceAnnotationUri {\n if (!uri.startsWith('http://') && !uri.startsWith('https://')) {\n throw new TypeError(`Expected ResourceAnnotationUri, got: ${uri}`);\n }\n // Additional validation: must contain /resources/ and /annotations/\n if (!uri.includes('/resources/') || !uri.includes('/annotations/')) {\n throw new TypeError(`Expected nested ResourceAnnotationUri format, got: ${uri}`);\n }\n return uri as ResourceAnnotationUri;\n}\n","/**\n * Branded identifier types for compile-time type safety.\n *\n * These types prevent mixing up resource IDs, annotation IDs, and user IDs\n * at compile time while having zero runtime overhead.\n *\n * URI types (ResourceUri, AnnotationUri) are in @semiont/http-transport\n * since they deal with HTTP URIs returned by the API.\n */\n\n// Branded type definitions for IDs only\nexport type ResourceId = string & { readonly __brand: 'ResourceId' };\nexport type AnnotationId = string & { readonly __brand: 'AnnotationId' };\nexport type UserId = string & { readonly __brand: 'UserId' };\n\n// Type guards with runtime validation\nexport function isResourceId(value: string): value is ResourceId {\n return !value.includes('/');\n}\n\nexport function isAnnotationId(value: string): value is AnnotationId {\n return !value.includes('/');\n}\n\n// Factory functions with runtime validation\nexport function resourceId(id: string): ResourceId {\n if (id.includes('/')) {\n throw new TypeError(`Expected ResourceId, got URI: ${id}`);\n }\n return id as ResourceId;\n}\n\nexport function annotationId(id: string): AnnotationId {\n if (id.includes('/')) {\n throw new TypeError(`Expected AnnotationId, got URI: ${id}`);\n }\n return id as AnnotationId;\n}\n\nexport function userId(id: string): UserId {\n return id as UserId;\n}\n","/**\n * Persisted Events\n *\n * The event types that get appended to the JSONL event log.\n * Each maps a type string to its OpenAPI payload schema.\n * The PersistedEvent union derives from this catalog.\n */\n\nimport type { components } from './types';\nimport type { AnnotationId, ResourceId } from './identifiers';\nimport type { Annotation } from './annotation-types';\nimport type { EventBase } from './event-base';\n\n// Branded payload overrides — the OpenAPI schemas reference the raw\n// `Annotation` type with `id: string`. At the TypeScript layer we narrow\n// to the branded `Annotation` so consumers read `payload.annotation.id`\n// as `AnnotationId` without an upcast at every seam.\ntype AnnotationAddedPayload =\n components['schemas']['AnnotationAddedPayload'] & { annotation: Annotation };\ntype AnnotationRemovedPayload =\n components['schemas']['AnnotationRemovedPayload'] & { annotationId: AnnotationId };\ntype AnnotationBodyUpdatedPayload =\n components['schemas']['AnnotationBodyUpdatedPayload'] & { annotationId: AnnotationId };\n\n// ── The Catalog ──────────────────────────────────────────────────────────────\n\n/**\n * Maps each persisted event type string to its OpenAPI payload schema.\n * Single source of truth for \"what events get written to the log.\"\n */\ntype PersistedEventCatalog = {\n 'yield:created': components['schemas']['ResourceCreatedPayload'];\n 'yield:cloned': components['schemas']['ResourceClonedPayload'];\n 'yield:updated': components['schemas']['ResourceUpdatedPayload'];\n 'yield:moved': components['schemas']['ResourceMovedPayload'];\n 'yield:representation-added': components['schemas']['RepresentationAddedPayload'];\n 'yield:representation-removed': components['schemas']['RepresentationRemovedPayload'];\n 'mark:added': AnnotationAddedPayload;\n 'mark:removed': AnnotationRemovedPayload;\n 'mark:body-updated': AnnotationBodyUpdatedPayload;\n 'mark:archived': components['schemas']['ResourceArchivedPayload'];\n 'mark:unarchived': components['schemas']['ResourceUnarchivedPayload'];\n 'mark:entity-tag-added': components['schemas']['EntityTagChangedPayload'];\n 'mark:entity-tag-removed': components['schemas']['EntityTagChangedPayload'];\n 'frame:entity-type-added': components['schemas']['EntityTypeAddedPayload'];\n 'frame:tag-schema-added': components['schemas']['TagSchemaAddedPayload'];\n 'job:started': components['schemas']['JobStartedPayload'];\n 'job:progress': components['schemas']['JobProgressPayload'];\n 'job:completed': components['schemas']['JobCompletedPayload'];\n 'job:failed': components['schemas']['JobFailedPayload'];\n};\n\n// ── Derived types ────────────────────────────────────────────────────────────\n\n/** System event types — persisted events that have no resourceId. */\ntype SystemEventType = 'frame:entity-type-added' | 'frame:tag-schema-added';\n\n/** Extract the concrete persisted event type for a given type string. */\nexport type EventOfType<K extends keyof PersistedEventCatalog> =\n K extends SystemEventType\n ? EventBase & { type: K; payload: PersistedEventCatalog[K] }\n : EventBase & { type: K; resourceId: ResourceId; payload: PersistedEventCatalog[K] };\n\n/** The union of all persisted event types. Discriminated on `type`. */\nexport type PersistedEvent = {\n [K in keyof PersistedEventCatalog]: EventOfType<K>\n}[keyof PersistedEventCatalog];\n\nexport type PersistedEventType = PersistedEvent['type'];\n\n/**\n * Runtime list of every persisted event type.\n *\n * Single source of truth for code that needs to enumerate event types at\n * runtime — most importantly the per-resource `events-stream` SSE route,\n * which subscribes to all of them. The exhaustiveness check below makes\n * it impossible to add a new member to `PersistedEventCatalog` without\n * also adding it here: forgetting fails to typecheck rather than silently\n * dropping the event from the events-stream.\n */\nexport const PERSISTED_EVENT_TYPES = [\n 'yield:created',\n 'yield:cloned',\n 'yield:updated',\n 'yield:moved',\n 'yield:representation-added',\n 'yield:representation-removed',\n 'mark:added',\n 'mark:removed',\n 'mark:body-updated',\n 'mark:archived',\n 'mark:unarchived',\n 'mark:entity-tag-added',\n 'mark:entity-tag-removed',\n 'frame:entity-type-added',\n 'frame:tag-schema-added',\n 'job:started',\n 'job:progress',\n 'job:completed',\n 'job:failed',\n] as const satisfies readonly PersistedEventType[];\n\n// Compile-time exhaustiveness: if PersistedEventType gains a member that\n// PERSISTED_EVENT_TYPES is missing, this assignment fails to typecheck.\n// The ERROR object names the missing-member case so the build error is\n// self-explanatory.\ntype _ExhaustivePersistedEventTypes =\n Exclude<PersistedEventType, typeof PERSISTED_EVENT_TYPES[number]> extends never\n ? true\n : { ERROR: 'PERSISTED_EVENT_TYPES is missing members of PersistedEventType' };\nconst _persistedEventTypesExhaustive: _ExhaustivePersistedEventTypes = true;\nvoid _persistedEventTypesExhaustive;\n\n/** Input type for appendEvent — PersistedEvent without id/timestamp (assigned at persistence time). */\nexport type EventInput = Omit<PersistedEvent, 'id' | 'timestamp'>;\n","/**\n * Bus Protocol\n *\n * The complete EventMap for the RxJS EventBus. Every channel name and\n * its payload type is defined here — domain events, commands, reads,\n * results, SSE stream payloads, and frontend UI events.\n *\n * Identifier discipline: where a payload carries an annotation or\n * resource id, the TypeScript layer narrows the OpenAPI `string` to the\n * branded type (`AnnotationId`, `ResourceId`, `UserId`). The runtime\n * wire shape is unchanged (brands have no runtime representation);\n * what this buys us is that command handlers don't have to re-brand\n * at every seam. Brand once at the entry boundary (HTTP route handler,\n * DOM attribute read, URL param parse), not at every bus hop in\n * between. See `.plans/BRAND-UPSTREAM.md` for the rationale.\n *\n * Organized by flow (verb), then by category within each flow.\n */\n\nimport type { components } from './types';\nimport type { AnnotationId, ResourceId } from './identifiers';\nimport type { StoredEvent } from './event-base';\nimport type { EventOfType } from './persisted-events';\n\n// Branded overrides for OpenAPI command payloads that carry identifier\n// fields. Narrows `string` → branded at the TypeScript layer.\n//\n// `_userId` is the gateway-injected authenticated DID (string at the\n// schema layer); handlers that need a `UserId` brand it locally.\ntype MarkDeleteCommand =\n components['schemas']['MarkDeleteCommand'] & {\n annotationId: AnnotationId;\n resourceId?: ResourceId;\n };\ntype MarkUpdateBodyCommand =\n components['schemas']['MarkUpdateBodyCommand'] & {\n annotationId: AnnotationId;\n resourceId: ResourceId;\n };\ntype BindInitiateCommand =\n components['schemas']['BindInitiateCommand'] & {\n annotationId: AnnotationId;\n resourceId: ResourceId;\n };\ntype BindUpdateBodyCommand =\n components['schemas']['BindUpdateBodyCommand'] & {\n annotationId: AnnotationId;\n resourceId: ResourceId;\n };\n\n/**\n * The unified EventMap — every channel on the EventBus.\n *\n * Convention:\n * - Domain events (past tense): StoredEvent<Interface> — branded types\n * - Commands/reads/results/UI: OpenAPI schema refs — plain strings\n * - void: UI-only signals with no payload\n */\nexport type EventMap = {\n\n // ========================================================================\n // YIELD FLOW — resource creation, update, move, clone\n // ========================================================================\n\n // Domain events (branded — system of record)\n 'yield:created': StoredEvent<EventOfType<'yield:created'>>;\n 'yield:cloned': StoredEvent<EventOfType<'yield:cloned'>>;\n 'yield:updated': StoredEvent<EventOfType<'yield:updated'>>;\n 'yield:moved': StoredEvent<EventOfType<'yield:moved'>>;\n 'yield:representation-added': StoredEvent<EventOfType<'yield:representation-added'>>;\n 'yield:representation-removed': StoredEvent<EventOfType<'yield:representation-removed'>>;\n\n // Generation lifecycle flows through the unified job:* family\n // (job:start, job:report-progress, job:complete, job:fail). The\n // pre-unification `yield:progress`/`yield:finished`/`yield:failed`\n // channels were removed on the lifecycle-unification.\n\n // Commands\n 'yield:create': components['schemas']['YieldCreateCommand'];\n 'yield:update': components['schemas']['YieldUpdateCommand'];\n 'yield:mv': components['schemas']['YieldMvCommand'];\n 'yield:clone': void;\n 'yield:clone-token-requested': components['schemas']['YieldCloneTokenRequest'];\n 'yield:clone-resource-requested': components['schemas']['YieldCloneResourceRequest'];\n 'yield:clone-create': components['schemas']['YieldCloneCreateCommand'];\n\n // Command results\n 'yield:create-ok': components['schemas']['YieldCreateOk'];\n 'yield:create-failed': components['schemas']['CommandError'];\n 'yield:update-ok': components['schemas']['YieldUpdateOk'];\n 'yield:update-failed': components['schemas']['YieldUpdateOk'] & components['schemas']['CommandError'];\n 'yield:move-ok': components['schemas']['YieldMoveOk'];\n 'yield:move-failed': { fromUri: string } & components['schemas']['CommandError'];\n 'yield:clone-token-generated': { correlationId: string; response: components['schemas']['CloneResourceWithTokenResponse'] };\n 'yield:clone-token-failed': { correlationId: string } & components['schemas']['CommandError'];\n 'yield:clone-resource-result': { correlationId: string; response: components['schemas']['GetResourceByTokenResponse'] };\n 'yield:clone-resource-failed': { correlationId: string } & components['schemas']['CommandError'];\n 'yield:clone-created': components['schemas']['YieldCloneCreated'];\n 'yield:clone-create-failed': { correlationId: string } & components['schemas']['CommandError'];\n\n // ========================================================================\n // MARK FLOW — annotation CRUD, AI assist, resource lifecycle\n // ========================================================================\n\n // Domain events (branded — system of record)\n 'mark:added': StoredEvent<EventOfType<'mark:added'>>;\n 'mark:removed': StoredEvent<EventOfType<'mark:removed'>>;\n 'mark:body-updated': StoredEvent<EventOfType<'mark:body-updated'>>;\n 'mark:entity-tag-added': StoredEvent<EventOfType<'mark:entity-tag-added'>>;\n 'mark:entity-tag-removed': StoredEvent<EventOfType<'mark:entity-tag-removed'>>;\n 'mark:archived': StoredEvent<EventOfType<'mark:archived'>>;\n 'mark:unarchived': StoredEvent<EventOfType<'mark:unarchived'>>;\n\n // Annotation-job lifecycle flows through the unified job:* family\n // (job:start, job:report-progress, job:complete, job:fail). UI\n // consumers filter by jobType. The pre-unification channels\n // `mark:progress`/`mark:assist-finished`/`mark:assist-failed` were\n // removed on the lifecycle-unification.\n\n // Commands\n 'mark:create-request': components['schemas']['MarkCreateRequest'];\n 'mark:create': components['schemas']['MarkCreateCommand'];\n 'mark:delete': MarkDeleteCommand;\n 'mark:update-body': MarkUpdateBodyCommand;\n 'mark:archive': components['schemas']['MarkArchiveCommand'];\n 'mark:unarchive': components['schemas']['MarkUnarchiveCommand'];\n 'mark:update-entity-types': components['schemas']['MarkUpdateEntityTypesCommand'];\n\n // Command results\n 'mark:create-ok': components['schemas']['MarkCreateOk'];\n 'mark:create-failed': components['schemas']['CommandError'];\n 'mark:delete-ok': components['schemas']['MarkDeleteOk'];\n 'mark:delete-failed': components['schemas']['CommandError'];\n 'mark:body-update-failed': components['schemas']['CommandError'];\n\n // UI events\n 'mark:select-comment': components['schemas']['SelectionData'];\n 'mark:select-tag': components['schemas']['SelectionData'];\n 'mark:select-assessment': components['schemas']['SelectionData'];\n 'mark:select-reference': components['schemas']['SelectionData'];\n 'mark:requested': components['schemas']['MarkRequestedEvent'];\n 'mark:cancel-pending': void;\n 'mark:submit': components['schemas']['MarkSubmitEvent'];\n 'mark:assist-request': components['schemas']['MarkAssistRequestEvent'];\n 'mark:assist-cancelled': void;\n 'mark:progress-dismiss': void;\n 'mark:mode-toggled': void;\n 'mark:selection-changed': components['schemas']['MarkSelectionChangedEvent'];\n 'mark:click-changed': components['schemas']['MarkClickChangedEvent'];\n 'mark:shape-changed': components['schemas']['MarkShapeChangedEvent'];\n\n // ========================================================================\n // FRAME FLOW — schema-layer vocabulary (entity types; future tag schemas,\n // relation/predicate types, ontology import). The eighth flow.\n // ========================================================================\n\n // Domain events (branded — system of record). System-level: no resourceId.\n 'frame:entity-type-added': StoredEvent<EventOfType<'frame:entity-type-added'>>;\n 'frame:tag-schema-added': StoredEvent<EventOfType<'frame:tag-schema-added'>>;\n\n // Commands\n 'frame:add-entity-type': components['schemas']['FrameAddEntityTypeCommand'];\n 'frame:add-tag-schema': components['schemas']['FrameAddTagSchemaCommand'];\n\n // Command results\n 'frame:entity-type-add-failed': components['schemas']['CommandError'];\n 'frame:tag-schema-add-failed': components['schemas']['CommandError'];\n\n // ========================================================================\n // BIND FLOW — reference linking\n // ========================================================================\n\n 'bind:initiate': BindInitiateCommand;\n 'bind:update-body': BindUpdateBodyCommand;\n 'bind:body-updated': components['schemas']['BindBodyUpdated'];\n 'bind:body-update-failed': components['schemas']['CommandError'];\n\n // ========================================================================\n // MATCH FLOW — search\n // ========================================================================\n\n 'match:search-requested': components['schemas']['MatchSearchRequest'];\n 'match:search-results': components['schemas']['MatchSearchResult'];\n 'match:search-failed': components['schemas']['MatchSearchFailed'];\n\n // ========================================================================\n // GATHER FLOW — context gathering\n // ========================================================================\n\n 'gather:requested': components['schemas']['GatherAnnotationRequest'];\n 'gather:complete': components['schemas']['GatherAnnotationComplete'];\n 'gather:failed': { correlationId: string; annotationId: string } & components['schemas']['CommandError'];\n 'gather:resource-requested': components['schemas']['GatherResourceRequest'];\n 'gather:resource-complete': components['schemas']['GatherResourceComplete'];\n 'gather:resource-failed': { correlationId: string; resourceId: string } & components['schemas']['CommandError'];\n\n 'gather:summary-requested': components['schemas']['GatherSummaryRequest'];\n 'gather:summary-result': { correlationId: string; response: Record<string, unknown> };\n 'gather:summary-failed': { correlationId: string } & components['schemas']['CommandError'];\n\n // SSE stream payloads\n 'gather:annotation-progress': components['schemas']['GatherProgress'];\n 'gather:annotation-finished': components['schemas']['GatherAnnotationFinished'];\n 'gather:progress': components['schemas']['GatherProgress'];\n 'gather:finished': components['schemas']['GatherFinished'];\n\n // ========================================================================\n // BROWSE FLOW — knowledge base reads + UI navigation\n // ========================================================================\n\n // Reads\n 'browse:resource-requested': components['schemas']['BrowseResourceRequest'];\n 'browse:resource-result': components['schemas']['BrowseResourceResult'];\n 'browse:resource-failed': { correlationId: string } & components['schemas']['CommandError'];\n\n 'browse:resources-requested': components['schemas']['BrowseResourcesRequest'];\n 'browse:resources-result': components['schemas']['BrowseResourcesResult'];\n 'browse:resources-failed': { correlationId: string } & components['schemas']['CommandError'];\n\n 'browse:annotations-requested': components['schemas']['BrowseAnnotationsRequest'];\n 'browse:annotations-result': components['schemas']['BrowseAnnotationsResult'];\n 'browse:annotations-failed': { correlationId: string } & components['schemas']['CommandError'];\n\n 'browse:annotation-requested': components['schemas']['BrowseAnnotationRequest'];\n 'browse:annotation-result': components['schemas']['BrowseAnnotationResult'];\n 'browse:annotation-failed': { correlationId: string } & components['schemas']['CommandError'];\n\n 'browse:events-requested': components['schemas']['BrowseEventsRequest'];\n 'browse:events-result': components['schemas']['BrowseEventsResult'];\n 'browse:events-failed': { correlationId: string } & components['schemas']['CommandError'];\n\n 'browse:annotation-history-requested': components['schemas']['BrowseAnnotationHistoryRequest'];\n 'browse:annotation-history-result': components['schemas']['BrowseAnnotationHistoryResult'];\n 'browse:annotation-history-failed': { correlationId: string } & components['schemas']['CommandError'];\n\n 'browse:annotation-context-requested': components['schemas']['BrowseAnnotationContextRequest'];\n 'browse:annotation-context-result': { correlationId: string; response: Record<string, unknown> };\n 'browse:annotation-context-failed': { correlationId: string } & components['schemas']['CommandError'];\n\n 'browse:referenced-by-requested': components['schemas']['BrowseReferencedByRequest'];\n 'browse:referenced-by-result': components['schemas']['BrowseReferencedByResult'];\n 'browse:referenced-by-failed': { correlationId: string } & components['schemas']['CommandError'];\n\n 'browse:entity-types-requested': components['schemas']['BrowseEntityTypesRequest'];\n 'browse:entity-types-result': components['schemas']['BrowseEntityTypesResult'];\n 'browse:entity-types-failed': { correlationId: string } & components['schemas']['CommandError'];\n\n 'browse:tag-schemas-requested': components['schemas']['BrowseTagSchemasRequest'];\n 'browse:tag-schemas-result': components['schemas']['BrowseTagSchemasResult'];\n 'browse:tag-schemas-failed': { correlationId: string } & components['schemas']['CommandError'];\n\n 'browse:directory-requested': components['schemas']['BrowseDirectoryRequest'];\n 'browse:directory-result': components['schemas']['BrowseDirectoryResult'];\n 'browse:directory-failed': { correlationId: string; path: string } & components['schemas']['CommandError'];\n\n // UI events (session-scoped — fire on the client bus, tied to a KB)\n 'browse:click': components['schemas']['BrowseClickEvent'];\n 'browse:reference-navigate': components['schemas']['BrowseReferenceNavigateEvent'];\n 'browse:entity-type-clicked': components['schemas']['BrowseEntityTypeClickedEvent'];\n\n // ========================================================================\n // SHELL — app-scoped UI events (fire on SemiontBrowser's bus, not the\n // per-session client bus). These must work regardless of whether a\n // KB session is active: panel toggles, sidebar, tab bar, routing.\n // ========================================================================\n\n 'panel:toggle': components['schemas']['BrowsePanelToggleEvent'];\n 'panel:open': components['schemas']['BrowsePanelOpenEvent'];\n 'panel:close': void;\n 'shell:sidebar-toggle': void;\n 'tabs:close': components['schemas']['BrowseResourceCloseEvent'];\n 'tabs:reorder': components['schemas']['BrowseResourceReorderEvent'];\n 'nav:link-clicked': components['schemas']['BrowseLinkClickedEvent'];\n 'nav:push': components['schemas']['BrowseRouterPushEvent'];\n 'nav:external': components['schemas']['BrowseExternalNavigateEvent'] & { cancelFallback: () => void };\n\n // ========================================================================\n // BECKON FLOW — annotation attention\n // ========================================================================\n\n 'beckon:hover': components['schemas']['BeckonHoverEvent'];\n 'beckon:focus': components['schemas']['BeckonFocusEvent'];\n 'beckon:sparkle': components['schemas']['BeckonSparkleEvent'];\n\n // ========================================================================\n // JOB FLOW — worker commands + domain events\n // ========================================================================\n\n // Domain events (branded — system of record)\n 'job:started': StoredEvent<EventOfType<'job:started'>>;\n 'job:progress': StoredEvent<EventOfType<'job:progress'>>;\n 'job:completed': StoredEvent<EventOfType<'job:completed'>>;\n 'job:failed': StoredEvent<EventOfType<'job:failed'>>;\n\n // Commands\n 'job:start': components['schemas']['JobStartCommand'];\n 'job:report-progress': components['schemas']['JobReportProgressCommand'];\n 'job:complete': components['schemas']['JobCompleteCommand'];\n 'job:fail': components['schemas']['JobFailCommand'];\n 'job:queued': components['schemas']['JobQueuedEvent'];\n 'job:cancel-requested': components['schemas']['JobCancelRequest'];\n 'job:status-requested': components['schemas']['JobStatusRequest'];\n 'job:create': components['schemas']['JobCreateCommand'];\n 'job:claim': components['schemas']['JobClaimCommand'];\n\n // Results\n 'job:status-result': components['schemas']['JobStatusResult'];\n 'job:status-failed': { correlationId: string } & components['schemas']['CommandError'];\n 'job:created': components['schemas']['JobCreatedResult'];\n 'job:create-failed': { correlationId: string } & components['schemas']['CommandError'];\n 'job:claimed': { correlationId: string; response: Record<string, unknown> };\n 'job:claim-failed': { correlationId: string } & components['schemas']['CommandError'];\n\n // ========================================================================\n // SETTINGS (frontend-only)\n // ========================================================================\n\n 'settings:theme-changed': components['schemas']['SettingsThemeChangedEvent'];\n 'settings:line-numbers-toggled': void;\n 'settings:locale-changed': components['schemas']['SettingsLocaleChangedEvent'];\n 'settings:hover-delay-changed': components['schemas']['SettingsHoverDelayChangedEvent'];\n\n // ========================================================================\n // SSE infrastructure\n // ========================================================================\n\n 'stream-connected': Record<string, never>;\n 'replay-window-exceeded': { resourceId?: string; lastEventId: number; missedCount: number; cap: number; message: string };\n /**\n * Emitted by the `/bus/subscribe` handler when a client reconnected\n * with `Last-Event-ID: p-<scope>-<seq>` but the server could not\n * replay all missed persisted events for that scope (retention\n * window exceeded, scope unknown, or request unparseable). The\n * client should treat this as a signal to fall back to the pre-\n * resumption contract: invalidate caches for the affected scope\n * and re-read from scratch. Analogous to `replay-window-exceeded`\n * but scoped to the bus gateway rather than the per-resource\n * events stream.\n *\n * `scope` is the scope string the client asked about (omitted for\n * global-persisted resumption gaps, if that path ever exists).\n * `reason` is human-readable, for logging.\n */\n 'bus:resume-gap': { scope?: string; lastSeenId?: string; reason: string };\n};\n\n/** Any valid channel name on the EventBus. */\nexport type EventName = keyof EventMap;\n\n/**\n * Genuine resource-bound broadcast event types.\n *\n * Publishers emit these on the scoped EventBus (`eventBus.scope(resourceId)`)\n * because every participant viewing the resource should receive them — not\n * just the caller who triggered the originating action. Examples: resource\n * generation progress, which multiple viewers of a generating resource all\n * want to see.\n *\n * Non-broadcast progress (AI-assist progress for one user, search results\n * for one caller) does NOT belong here. Those are per-caller correlation-ID\n * responses and publish globally — the caller filters by `correlationId`.\n *\n * The SDK's resource-scoped `browse.*` live queries wire these channels —\n * subscribing acquires the scope via the transport's `subscribeToResource`\n * (`scope=id&scoped=<channel>`) so the SSE route delivers them to that\n * participant (freshness follows observation; #847). WorkerStateUnit uses this\n * list to decide which emitted events to scope to their resource.\n */\nexport const RESOURCE_BROADCAST_TYPES = [\n // Currently empty. `job:complete` / `job:fail` were moved to GLOBAL,\n // `jobId`-keyed correlation delivery (#847): the dispatching caller\n // filters by `jobId`, and resource viewers filter the same global stream\n // by `resourceId` — no resource-scoped copy, so a client that is both\n // dispatcher and viewer no longer receives it twice. This set remains as\n // the extension point for *genuine* resource-bound broadcasts — events\n // every viewer of a resource should see and no single caller owns (e.g.\n // resource-generation progress for multiple viewers).\n] as const satisfies readonly EventName[];\n\nexport type ResourceBroadcastType = typeof RESOURCE_BROADCAST_TYPES[number];\n\n/**\n * Authoritative map from bus channel to OpenAPI schema name.\n *\n * Every {@link EventName} must appear. The `satisfies` clause below\n * enforces completeness at compile time — adding a channel to\n * {@link EventMap} without adding an entry here is a build error.\n *\n * Values:\n * - `<SchemaName>`: payload validates against `components['schemas'][SchemaName]`.\n * - `null`: no single-schema validation. Used for branded\n * `StoredEvent` wrappers, `void` UI signals, and compound inline\n * types (e.g. `{ correlationId } & CommandError`). These are not\n * validated by `/bus/emit`.\n *\n * The `/bus/emit` route reads this map to validate incoming payloads.\n * Consumers can also use it to do client-side pre-flight validation\n * before emitting.\n */\nexport const CHANNEL_SCHEMAS = {\n // ── YIELD FLOW ──────────────────────────────────────────────────\n 'yield:created': null, // StoredEvent\n 'yield:cloned': null,\n 'yield:updated': null,\n 'yield:moved': null,\n 'yield:representation-added': null,\n 'yield:representation-removed': null,\n 'yield:create': 'YieldCreateCommand',\n 'yield:update': 'YieldUpdateCommand',\n 'yield:mv': 'YieldMvCommand',\n 'yield:clone': null, // void\n 'yield:clone-token-requested': 'YieldCloneTokenRequest',\n 'yield:clone-resource-requested': 'YieldCloneResourceRequest',\n 'yield:clone-create': 'YieldCloneCreateCommand',\n 'yield:create-ok': 'YieldCreateOk',\n 'yield:create-failed': 'CommandError',\n 'yield:update-ok': 'YieldUpdateOk',\n 'yield:update-failed': null, // YieldUpdateOk & CommandError\n 'yield:move-ok': 'YieldMoveOk',\n 'yield:move-failed': null, // { fromUri } & CommandError\n 'yield:clone-token-generated': null, // { correlationId; response: CloneResourceWithTokenResponse }\n 'yield:clone-token-failed': null, // { correlationId } & CommandError\n 'yield:clone-resource-result': null, // { correlationId; response: GetResourceByTokenResponse }\n 'yield:clone-resource-failed': null, // { correlationId } & CommandError\n 'yield:clone-created': 'YieldCloneCreated',\n 'yield:clone-create-failed': null, // { correlationId } & CommandError\n\n // ── MARK FLOW ───────────────────────────────────────────────────\n 'mark:added': null, // StoredEvent\n 'mark:removed': null,\n 'mark:body-updated': null,\n 'mark:entity-tag-added': null,\n 'mark:entity-tag-removed': null,\n 'frame:entity-type-added': null,\n 'frame:tag-schema-added': null,\n 'mark:archived': null,\n 'mark:unarchived': null,\n 'mark:create-request': 'MarkCreateRequest',\n 'mark:create': 'MarkCreateCommand',\n 'mark:delete': 'MarkDeleteCommand',\n 'mark:update-body': 'MarkUpdateBodyCommand',\n 'mark:archive': 'MarkArchiveCommand',\n 'mark:unarchive': 'MarkUnarchiveCommand',\n 'mark:update-entity-types': 'MarkUpdateEntityTypesCommand',\n 'frame:add-entity-type': 'FrameAddEntityTypeCommand',\n 'frame:add-tag-schema': 'FrameAddTagSchemaCommand',\n 'mark:create-ok': 'MarkCreateOk',\n 'mark:create-failed': 'CommandError',\n 'mark:delete-ok': 'MarkDeleteOk',\n 'mark:delete-failed': 'CommandError',\n 'mark:body-update-failed': 'CommandError',\n 'frame:entity-type-add-failed': 'CommandError',\n 'frame:tag-schema-add-failed': 'CommandError',\n 'mark:select-comment': 'SelectionData',\n 'mark:select-tag': 'SelectionData',\n 'mark:select-assessment': 'SelectionData',\n 'mark:select-reference': 'SelectionData',\n 'mark:requested': 'MarkRequestedEvent',\n 'mark:cancel-pending': null, // void\n 'mark:submit': 'MarkSubmitEvent',\n 'mark:assist-request': 'MarkAssistRequestEvent',\n 'mark:assist-cancelled': null, // void\n 'mark:progress-dismiss': null, // void\n 'mark:mode-toggled': null, // void\n 'mark:selection-changed': 'MarkSelectionChangedEvent',\n 'mark:click-changed': 'MarkClickChangedEvent',\n 'mark:shape-changed': 'MarkShapeChangedEvent',\n\n // ── BIND FLOW ───────────────────────────────────────────────────\n 'bind:initiate': 'BindInitiateCommand',\n 'bind:update-body': 'BindUpdateBodyCommand',\n 'bind:body-updated': 'BindBodyUpdated',\n 'bind:body-update-failed': 'CommandError',\n\n // ── MATCH FLOW ──────────────────────────────────────────────────\n 'match:search-requested': 'MatchSearchRequest',\n 'match:search-results': 'MatchSearchResult',\n 'match:search-failed': 'MatchSearchFailed',\n\n // ── GATHER FLOW ─────────────────────────────────────────────────\n 'gather:requested': 'GatherAnnotationRequest',\n 'gather:complete': 'GatherAnnotationComplete',\n 'gather:failed': null, // { correlationId; annotationId } & CommandError\n 'gather:resource-requested': 'GatherResourceRequest',\n 'gather:resource-complete': 'GatherResourceComplete',\n 'gather:resource-failed': null, // { correlationId; resourceId } & CommandError\n 'gather:summary-requested': 'GatherSummaryRequest',\n 'gather:summary-result': null, // { correlationId; response: Record<string, unknown> }\n 'gather:summary-failed': null, // { correlationId } & CommandError\n 'gather:annotation-progress': 'GatherProgress',\n 'gather:annotation-finished': 'GatherAnnotationFinished',\n 'gather:progress': 'GatherProgress',\n 'gather:finished': 'GatherFinished',\n\n // ── BROWSE FLOW ─────────────────────────────────────────────────\n 'browse:resource-requested': 'BrowseResourceRequest',\n 'browse:resource-result': 'BrowseResourceResult',\n 'browse:resource-failed': null, // { correlationId } & CommandError\n 'browse:resources-requested': 'BrowseResourcesRequest',\n 'browse:resources-result': 'BrowseResourcesResult',\n 'browse:resources-failed': null,\n 'browse:annotations-requested': 'BrowseAnnotationsRequest',\n 'browse:annotations-result': 'BrowseAnnotationsResult',\n 'browse:annotations-failed': null,\n 'browse:annotation-requested': 'BrowseAnnotationRequest',\n 'browse:annotation-result': 'BrowseAnnotationResult',\n 'browse:annotation-failed': null,\n 'browse:events-requested': 'BrowseEventsRequest',\n 'browse:events-result': 'BrowseEventsResult',\n 'browse:events-failed': null,\n 'browse:annotation-history-requested': 'BrowseAnnotationHistoryRequest',\n 'browse:annotation-history-result': 'BrowseAnnotationHistoryResult',\n 'browse:annotation-history-failed': null,\n 'browse:annotation-context-requested': 'BrowseAnnotationContextRequest',\n 'browse:annotation-context-result': null, // { correlationId; response: Record<string, unknown> }\n 'browse:annotation-context-failed': null,\n 'browse:referenced-by-requested': 'BrowseReferencedByRequest',\n 'browse:referenced-by-result': 'BrowseReferencedByResult',\n 'browse:referenced-by-failed': null,\n 'browse:entity-types-requested': 'BrowseEntityTypesRequest',\n 'browse:entity-types-result': 'BrowseEntityTypesResult',\n 'browse:entity-types-failed': null,\n 'browse:tag-schemas-requested': 'BrowseTagSchemasRequest',\n 'browse:tag-schemas-result': 'BrowseTagSchemasResult',\n 'browse:tag-schemas-failed': null,\n 'browse:directory-requested': 'BrowseDirectoryRequest',\n 'browse:directory-result': 'BrowseDirectoryResult',\n 'browse:directory-failed': null, // { correlationId; path } & CommandError\n 'browse:click': 'BrowseClickEvent',\n 'browse:reference-navigate': 'BrowseReferenceNavigateEvent',\n 'browse:entity-type-clicked': 'BrowseEntityTypeClickedEvent',\n\n // ── SHELL (app-scoped UI events, fire on SemiontBrowser bus) ────\n 'panel:toggle': 'BrowsePanelToggleEvent',\n 'panel:open': 'BrowsePanelOpenEvent',\n 'panel:close': null, // void\n 'shell:sidebar-toggle': null, // void\n 'tabs:close': 'BrowseResourceCloseEvent',\n 'tabs:reorder': 'BrowseResourceReorderEvent',\n 'nav:link-clicked': 'BrowseLinkClickedEvent',\n 'nav:push': 'BrowseRouterPushEvent',\n 'nav:external': null, // includes runtime `cancelFallback: () => void`\n\n // ── BECKON FLOW ─────────────────────────────────────────────────\n 'beckon:hover': 'BeckonHoverEvent',\n 'beckon:focus': 'BeckonFocusEvent',\n 'beckon:sparkle': 'BeckonSparkleEvent',\n\n // ── JOB FLOW ────────────────────────────────────────────────────\n 'job:started': null, // StoredEvent\n 'job:progress': null,\n 'job:completed': null,\n 'job:failed': null,\n 'job:start': 'JobStartCommand',\n 'job:report-progress': 'JobReportProgressCommand',\n 'job:complete': 'JobCompleteCommand',\n 'job:fail': 'JobFailCommand',\n 'job:queued': 'JobQueuedEvent',\n 'job:cancel-requested': 'JobCancelRequest',\n 'job:status-requested': 'JobStatusRequest',\n 'job:create': 'JobCreateCommand',\n 'job:claim': 'JobClaimCommand',\n 'job:status-result': 'JobStatusResult',\n 'job:status-failed': null, // { correlationId } & CommandError\n 'job:created': 'JobCreatedResult',\n 'job:create-failed': null,\n 'job:claimed': null, // { correlationId; response: Record<string, unknown> }\n 'job:claim-failed': null,\n\n // ── SETTINGS (frontend-only) ────────────────────────────────────\n 'settings:theme-changed': 'SettingsThemeChangedEvent',\n 'settings:line-numbers-toggled': null, // void\n 'settings:locale-changed': 'SettingsLocaleChangedEvent',\n 'settings:hover-delay-changed': 'SettingsHoverDelayChangedEvent',\n\n // ── SSE infrastructure ──────────────────────────────────────────\n 'stream-connected': null, // Record<string, never>\n 'replay-window-exceeded': null, // inline payload\n 'bus:resume-gap': null, // inline payload\n} as const satisfies Record<EventName, keyof components['schemas'] | null>;\n\n/** Channels where `/bus/emit` validates the payload (non-null schema). */\nexport type EmittableChannel = {\n [K in EventName]: typeof CHANNEL_SCHEMAS[K] extends null ? never : K\n}[EventName];\n","/**\n * Event Type Guards and Extraction Utilities\n *\n * Domain logic for working with resource events.\n * No React dependencies - safe to use in any JavaScript environment.\n */\n\nimport type { StoredEvent } from './event-base';\nimport type { AnnotationUri } from './branded-types';\n\n/**\n * Minimal event shape accepted by event utility functions.\n * Compatible with both the internal `StoredEvent` type and the OpenAPI-derived\n * schema type (`GetEventsResponse['events'][number]`), which lacks `version`.\n *\n * Flat shape — event fields and metadata are peers (no `event` wrapper).\n */\nexport interface StoredEventLike {\n id: string;\n type: string; // Intentionally loose — accepts OpenAPI-derived types where type is string\n timestamp: string;\n userId: string;\n resourceId?: string;\n payload?: unknown;\n metadata: {\n sequenceNumber: number;\n };\n}\n\n// =============================================================================\n// EVENT TYPE GUARDS AND EXTRACTION\n// =============================================================================\n\n/**\n * Extract annotation ID from event payload\n * Returns null if event is not annotation-related\n *\n * For mark:added: extracts full URI from payload.annotation.id\n * For mark:removed/mark:body-updated: constructs full URI from payload.annotationId (UUID) + resourceId\n */\nexport function getAnnotationUriFromEvent(event: StoredEventLike): AnnotationUri | null {\n const payload = event.payload as Record<string, any> | undefined;\n\n if (event.type === 'mark:added') {\n return payload?.annotation?.id as AnnotationUri || null;\n }\n\n if (event.type === 'mark:removed' || event.type === 'mark:body-updated') {\n if (payload?.annotationId && event.resourceId) {\n try {\n const resourceUri = event.resourceId;\n const baseUrl = resourceUri.substring(0, resourceUri.lastIndexOf('/resources/'));\n return `${baseUrl}/annotations/${payload.annotationId}` as AnnotationUri;\n } catch (e) {\n return null;\n }\n }\n }\n\n return null;\n}\n\n/**\n * Check if an event is related to a specific annotation\n */\nexport function isEventRelatedToAnnotation(event: StoredEventLike, annotationUri: AnnotationUri): boolean {\n const eventAnnotationUri = getAnnotationUriFromEvent(event);\n return eventAnnotationUri === annotationUri;\n}\n\n/**\n * Type guard to check if an object is a StoredEvent (flat shape)\n */\nexport function isStoredEvent(event: any): event is StoredEvent {\n return event &&\n typeof event.id === 'string' &&\n typeof event.timestamp === 'string' &&\n typeof event.type === 'string' &&\n typeof event.metadata === 'object' &&\n typeof event.metadata.sequenceNumber === 'number';\n}\n\n","/**\n * Bus logging — runtime-toggleable cross-wire visibility.\n *\n * One line per event that crosses a process boundary, in a grep-able\n * format that's symmetric across frontend and backend:\n *\n * [bus EMIT] <channel> [scope=X] [cid=<first8>] <payload>\n * [bus RECV] <channel> [scope=X] [cid=<first8>] <payload>\n * [bus SSE] <channel> [scope=X] [cid=<first8>] <payload>\n *\n * Tier 1 of `.plans/OBSERVABILITY.md`. Forward-compatible with Tier 2:\n * the `cid` printed here is exactly the prefix of the W3C trace-id we\n * adopt later.\n *\n * Cost when disabled: one property read per call, zero allocations.\n *\n * Enable:\n * - Browser: `window.__SEMIONT_BUS_LOG__ = true` (DevTools or e2e init)\n * - Node: `SEMIONT_BUS_LOG=1` in the process env (read at module load)\n */\n\nconst NODE_BUS_LOG =\n typeof process !== 'undefined' && !!process.env?.SEMIONT_BUS_LOG;\n\nexport type BusOp = 'EMIT' | 'RECV' | 'SSE' | 'PUT' | 'GET';\n\nexport function busLogEnabled(): boolean {\n const g = globalThis as { __SEMIONT_BUS_LOG__?: boolean };\n if (g.__SEMIONT_BUS_LOG__) return true;\n return NODE_BUS_LOG;\n}\n\n/**\n * Optional active-span trace-id provider. When a Tier 2 OTel SDK is\n * initialized, `@semiont/observability` registers a provider here that\n * returns the active span's W3C `trace_id`. busLog appends it to each\n * emitted line so the grep-timeline correlates with the span tree in\n * an APM UI.\n *\n * Decoupling: `@semiont/core` does not depend on `@opentelemetry/api`.\n * If no provider is registered (Tier 1-only deployments, or before\n * `initObservabilityNode` runs), the field is omitted from the line —\n * same shape as before this hook existed.\n */\nlet traceIdProvider: (() => string | undefined) | undefined;\n\nexport function setBusLogTraceIdProvider(fn: (() => string | undefined) | undefined): void {\n traceIdProvider = fn;\n}\n\nexport function busLog(\n op: BusOp,\n channel: string,\n payload: unknown,\n scope?: string,\n): void {\n if (!busLogEnabled()) return;\n const cidRaw = (payload as { correlationId?: unknown } | null | undefined)?.correlationId;\n const cid = typeof cidRaw === 'string' ? cidRaw.slice(0, 8) : undefined;\n let traceId: string | undefined;\n if (traceIdProvider) {\n try { traceId = traceIdProvider(); } catch { /* noop */ }\n }\n const tag =\n `[bus ${op}] ${channel}` +\n (scope ? ` scope=${scope}` : '') +\n (cid ? ` cid=${cid}` : '') +\n (traceId ? ` trace=${traceId.slice(0, 8)}` : '');\n // eslint-disable-next-line no-console\n console.debug(tag, payload);\n}\n","/**\n * RxJS-based Event Bus\n *\n * Framework-agnostic event bus providing direct access to typed RxJS Subjects.\n *\n * Can be used in Node.js, browser, workers, CLI - anywhere RxJS runs.\n */\n\nimport { Subject } from 'rxjs';\nimport { busLog, busLogEnabled } from './bus-log';\nimport type { EventMap } from './bus-protocol';\nimport type { StoredEvent } from './event-base';\nimport type { PersistedEventType } from './persisted-events';\n\n/**\n * RxJS-based event bus\n *\n * Provides direct access to RxJS Subjects for each event type.\n * Use standard RxJS patterns for emitting and subscribing.\n *\n * @example\n * ```typescript\n * const eventBus = new EventBus();\n *\n * // Emit events\n * eventBus.get('beckon:hover').next({ annotationId: 'ann-1' });\n *\n * // Subscribe to events\n * const subscription = eventBus.get('beckon:hover').subscribe(({ annotationId }) => {\n * console.log('Hover:', annotationId);\n * });\n *\n * // Use RxJS operators\n * import { debounceTime } from 'rxjs/operators';\n * eventBus.get('beckon:hover')\n * .pipe(debounceTime(100))\n * .subscribe(handleHover);\n *\n * // Cleanup\n * subscription.unsubscribe();\n * eventBus.destroy();\n * ```\n */\nexport class EventBus {\n private subjects: Map<keyof EventMap, Subject<any>>;\n private isDestroyed: boolean;\n\n constructor() {\n this.subjects = new Map();\n this.isDestroyed = false;\n }\n\n /**\n * Get the RxJS Subject for an event\n *\n * Returns a typed Subject that can be used with all RxJS operators.\n * Subjects are created lazily on first access.\n *\n * @param eventName - The event name\n * @returns The RxJS Subject for this event\n *\n * @example\n * ```typescript\n * // Emit\n * eventBus.get('beckon:hover').next({ annotationId: 'ann-1' });\n *\n * // Subscribe\n * const sub = eventBus.get('beckon:hover').subscribe(handleHover);\n *\n * // With operators\n * eventBus.get('beckon:hover')\n * .pipe(debounceTime(100), distinctUntilChanged())\n * .subscribe(handleHover);\n * ```\n */\n get<K extends keyof EventMap>(eventName: K): Subject<EventMap[K]> {\n if (this.isDestroyed) {\n throw new Error(`Cannot access event '${String(eventName)}' on destroyed bus`);\n }\n\n if (!this.subjects.has(eventName)) {\n const subject = new Subject<EventMap[K]>();\n // When bus-log is enabled (`SEMIONT_BUS_LOG=1` or\n // `window.__SEMIONT_BUS_LOG__ = true`), wrap `.next()` so every\n // local emit on this channel produces a `[bus EMIT] <channel> ...`\n // line on `console.debug` — same shape as cross-wire emits from\n // HttpTransport. This is what makes local-only fan-out signals\n // (`beckon.hover`, `beckon.sparkle`, `mark.changeShape`, etc.)\n // visible to the e2e bus capture and to a developer's DevTools.\n // The `busLogEnabled()` check is at first-`get` time per channel;\n // setting the flag after channels are constructed won't\n // retroactively wrap them. The bus capture fixture uses\n // `addInitScript` so the flag is set before any namespace\n // construction, which is when `get()` is first called.\n if (busLogEnabled()) {\n const originalNext = subject.next.bind(subject);\n subject.next = (value: EventMap[K]): void => {\n busLog('EMIT', String(eventName), value as object);\n originalNext(value);\n };\n }\n this.subjects.set(eventName, subject);\n }\n return this.subjects.get(eventName)!;\n }\n\n /**\n * Get the RxJS Subject for a domain event type (PersistedEventType).\n *\n * Domain event channels carry `StoredEvent`. This method avoids the need\n * for `as keyof EventMap` casts when subscribing to domain event channels\n * using runtime `PersistedEventType` strings.\n */\n getDomainEvent(eventType: PersistedEventType): Subject<StoredEvent> {\n return this.get(eventType as keyof EventMap) as unknown as Subject<StoredEvent>;\n }\n\n /**\n * Destroy the event bus and complete all subjects\n *\n * After calling destroy(), no new events can be emitted or subscribed to.\n * All active subscriptions will be completed.\n */\n destroy(): void {\n if (this.isDestroyed) {\n return;\n }\n\n for (const subject of this.subjects.values()) {\n subject.complete();\n }\n\n this.subjects.clear();\n this.isDestroyed = true;\n }\n\n /**\n * Check if the event bus has been destroyed\n */\n get destroyed(): boolean {\n return this.isDestroyed;\n }\n\n /**\n * Create a resource-scoped event bus\n *\n * Events emitted or subscribed through the scoped bus are isolated to that resource.\n * Internally, events are namespaced but the API remains identical to the parent bus.\n *\n * @param resourceId - Resource identifier to scope events to\n * @returns A scoped event bus for this resource\n *\n * @example\n * ```typescript\n * const eventBus = new EventBus();\n * const resource1 = eventBus.scope('resource-1');\n * const resource2 = eventBus.scope('resource-2');\n *\n * // These are isolated - only resource1 subscribers will fire\n * resource1.get('detection:progress').next({ status: 'started' });\n * ```\n */\n scope(resourceId: string): ScopedEventBus {\n return new ScopedEventBus(this, resourceId);\n }\n}\n\n/**\n * Resource-scoped event bus\n *\n * Provides isolated event streams per resource while maintaining the same API\n * as the parent EventBus. Events are internally namespaced by resourceId.\n */\nexport class ScopedEventBus {\n constructor(\n private parent: EventBus,\n private scopePrefix: string\n ) {}\n\n /**\n * Get the RxJS Subject for a scoped event\n *\n * Returns the same type as the parent bus, but events are isolated to this scope.\n * Internally uses namespaced keys but preserves type safety.\n *\n * @param event - The event name\n * @returns The RxJS Subject for this scoped event\n */\n get<E extends keyof EventMap>(event: E): Subject<EventMap[E]> {\n // Internally namespace the event key, but preserve return type\n const scopedKey = `${this.scopePrefix}:${event as string}`;\n\n // Access parent's subjects map directly (needs cast for private access)\n const parentSubjects = (this.parent as any).subjects as Map<string, Subject<any>>;\n\n if (!parentSubjects.has(scopedKey)) {\n parentSubjects.set(scopedKey, new Subject<EventMap[E]>());\n }\n return parentSubjects.get(scopedKey)!;\n }\n\n /** Get the RxJS Subject for a domain event type on this scoped bus. */\n getDomainEvent(eventType: PersistedEventType): Subject<StoredEvent> {\n return this.get(eventType as keyof EventMap) as unknown as Subject<StoredEvent>;\n }\n\n /**\n * Create a nested scope\n *\n * Allows hierarchical scoping like `resource-1:subsystem-a`\n *\n * @param subScope - Additional scope level\n * @returns A nested scoped event bus\n */\n scope(subScope: string): ScopedEventBus {\n return new ScopedEventBus(this.parent, `${this.scopePrefix}:${subScope}`);\n }\n}\n","/**\n * Adaptive burst buffer RxJS operator.\n *\n * Passes the first event through immediately (zero latency for interactive use).\n * If more events arrive within the burst window, switches to accumulate mode\n * and flushes batches. Returns to passthrough mode after an idle period.\n *\n * Emits individual items (T) in passthrough mode and arrays (T[]) in batch mode.\n * Consumers distinguish via Array.isArray().\n *\n * Threshold tuning:\n * burstWindowMs — How long to wait for more events before flushing a batch.\n * 50ms is a good default: longer than event-loop jitter (~1-5ms)\n * but short enough to feel responsive.\n * maxBatchSize — Force-flush at this size to bound memory. 500 is safe for\n * Neo4j UNWIND queries. Increase if graph writes are cheap.\n * idleTimeoutMs — How long after the last flush before returning to passthrough.\n * 200ms is a good default. Must be >= burstWindowMs.\n *\n * See: BATCH-GRAPH-CONSUMER-RX.md for design rationale.\n * See: packages/graph/docs/ARCHITECTURE.md for graph consumer context.\n */\n\nimport { Observable, OperatorFunction } from 'rxjs';\n\nexport interface BurstBufferOptions {\n /**\n * Time window (ms) to detect burst activity after an event.\n * If another event arrives within this window, it is buffered.\n * The buffer flushes when no new event arrives for this duration (debounce).\n *\n * Recommended: 50ms.\n */\n burstWindowMs: number;\n\n /**\n * Maximum events to accumulate before forcing a flush.\n * Prevents unbounded memory growth during sustained bursts.\n *\n * Recommended: 500.\n */\n maxBatchSize: number;\n\n /**\n * Time (ms) of silence after the last flush before returning to passthrough mode.\n * The next event after this timeout emits immediately (leading edge).\n * Must be >= burstWindowMs.\n *\n * Recommended: 200ms.\n */\n idleTimeoutMs: number;\n}\n\n/**\n * Adaptive burst buffer operator.\n *\n * State machine:\n * PASSTHROUGH → event arrives → emit immediately, transition to ACCUMULATING\n * ACCUMULATING → event arrives → buffer it, reset burst timer\n * ACCUMULATING → burst timer fires (no new events for burstWindowMs) → flush buffer as T[]\n * ACCUMULATING → buffer reaches maxBatchSize → flush buffer as T[]\n * After flush → idle timer starts\n * Idle timer fires (no new events for idleTimeoutMs) → transition to PASSTHROUGH\n */\nexport function burstBuffer<T>(\n options: BurstBufferOptions\n): OperatorFunction<T, T | T[]> {\n const { burstWindowMs, maxBatchSize, idleTimeoutMs } = options;\n\n return (source: Observable<T>) =>\n new Observable<T | T[]>((subscriber) => {\n let mode: 'passthrough' | 'accumulating' = 'passthrough';\n let buffer: T[] = [];\n let burstTimer: ReturnType<typeof setTimeout> | null = null;\n let idleTimer: ReturnType<typeof setTimeout> | null = null;\n\n function clearBurstTimer() {\n if (burstTimer !== null) {\n clearTimeout(burstTimer);\n burstTimer = null;\n }\n }\n\n function clearIdleTimer() {\n if (idleTimer !== null) {\n clearTimeout(idleTimer);\n idleTimer = null;\n }\n }\n\n function flush() {\n if (buffer.length === 0) return;\n const batch = buffer;\n buffer = [];\n subscriber.next(batch);\n }\n\n function startIdleTimer() {\n clearIdleTimer();\n idleTimer = setTimeout(() => {\n idleTimer = null;\n mode = 'passthrough';\n }, idleTimeoutMs);\n }\n\n const subscription = source.subscribe({\n next(value: T) {\n clearIdleTimer();\n\n if (mode === 'passthrough') {\n // Leading edge: emit immediately\n subscriber.next(value);\n // Transition to accumulating — next event within burstWindowMs gets buffered\n mode = 'accumulating';\n // Start a burst timer: if nothing else arrives, start idle countdown\n burstTimer = setTimeout(() => {\n burstTimer = null;\n flush(); // flush anything accumulated (normally empty at this point)\n startIdleTimer();\n }, burstWindowMs);\n return;\n }\n\n // mode === 'accumulating'\n buffer.push(value);\n\n // Reset the burst window timer (debounce pattern)\n clearBurstTimer();\n\n if (buffer.length >= maxBatchSize) {\n // Force flush at max batch size\n flush();\n startIdleTimer();\n } else {\n // Debounce: flush after burstWindowMs of silence\n burstTimer = setTimeout(() => {\n burstTimer = null;\n flush();\n startIdleTimer();\n }, burstWindowMs);\n }\n },\n\n error(err) {\n clearBurstTimer();\n clearIdleTimer();\n flush();\n subscriber.error(err);\n },\n\n complete() {\n clearBurstTimer();\n clearIdleTimer();\n flush();\n subscriber.complete();\n },\n });\n\n // Teardown: clean up timers and unsubscribe from source\n return () => {\n clearBurstTimer();\n clearIdleTimer();\n subscription.unsubscribe();\n };\n });\n}\n","/**\n * serializePerKey — run async work serialized per key, parallel across keys.\n *\n * Invariant: two calls with the same `key` run strictly in sequence (the\n * second `work` does not start until the first has settled). Calls with\n * different keys overlap freely.\n *\n * Error isolation: a rejected work function does not poison subsequent\n * tasks for the same key. The next task starts fresh from whatever state\n * the failed task left behind. The rejection still propagates to *this*\n * caller.\n *\n * Registry cleanup: the entry for a key is removed as soon as its chain\n * empties, so the Map stays bounded by the number of keys with work\n * currently in flight, not by the total number of keys ever seen.\n *\n * ## Usage\n *\n * ```ts\n * const chains = new Map<string, Promise<void>>();\n *\n * async function write(resourceId: string, event: Event) {\n * return serializePerKey(resourceId, chains, async () => {\n * // Read-modify-write on a view file. Any two concurrent calls with\n * // the same resourceId will be serialized; different resourceIds\n * // will proceed in parallel.\n * const view = await viewStorage.get(resourceId);\n * applyEvent(view, event);\n * await viewStorage.save(resourceId, view);\n * });\n * }\n * ```\n *\n * ## When to use this vs RxJS `groupBy + concatMap`\n *\n * Use `serializePerKey` when the work arrives as **direct method calls**\n * that need to block the caller until completion. This is the RPC shape\n * — think `EventStore.appendEvent` calling `await views.materializeResource(...)`\n * and needing the view written before any subscriber sees the published\n * event.\n *\n * Use RxJS `groupBy(keyFn) + concatMap(...)` when the work arrives as an\n * **event stream** that a component subscribes to once at startup. This\n * is how `Smelter`, `GraphDBConsumer`, and `Gatherer` serialize their own\n * per-resource work — see their implementations in `packages/make-meaning`.\n *\n * Both patterns solve the same logical problem (\"serialize work per key\").\n * The choice is dictated by whether the caller is awaiting the result.\n */\nexport async function serializePerKey<K, T>(\n key: K,\n chains: Map<K, Promise<void>>,\n work: () => Promise<T>,\n): Promise<T> {\n const prev = chains.get(key) ?? Promise.resolve();\n\n // Chain onto prev, swallowing any error from the previous link so one\n // bad task doesn't poison subsequent ones for the same key. The new\n // link's own errors still propagate to our caller via `await next`.\n let result: T;\n const next = prev\n .catch(() => { /* prior failure doesn't block us */ })\n .then(async () => {\n result = await work();\n });\n\n chains.set(key, next);\n\n try {\n await next;\n return result!;\n } finally {\n // Only clear the entry if we're still the tail. If another caller\n // has already chained onto us, leave it so the chain stays intact.\n if (chains.get(key) === next) {\n chains.delete(key);\n }\n }\n}\n","/**\n * Logger interface for observability\n *\n * This interface is intentionally framework-agnostic to work with any logger\n * (winston, pino, bunyan, or simple console).\n *\n * Example usage:\n * ```typescript\n * import winston from 'winston';\n *\n * const logger = winston.createLogger({\n * level: 'debug',\n * transports: [new winston.transports.Console()]\n * });\n *\n * const service = new MyService(logger);\n * ```\n */\nexport interface Logger {\n debug(message: string, meta?: any): void;\n info(message: string, meta?: any): void;\n warn(message: string, meta?: any): void;\n error(message: string, meta?: any): void;\n child(meta: Record<string, any>): Logger;\n}\n\n/**\n * Serialize an error value into a form that JSON.stringify can handle\n * meaningfully.\n *\n * Winston's default JSON formatter serializes `Error` instances as `{}`\n * because `message`, `stack`, and `name` are non-enumerable properties on\n * the Error prototype. That means `logger.error('x', { error })` with a\n * raw Error argument produces useless log lines like\n * `{\"error\":{},\"message\":\"x\",...}`, throwing away the information you\n * actually need to diagnose the failure.\n *\n * This helper extracts the parts you want to see in a log — name,\n * message, stack, and cause — and leaves non-Error values alone (so\n * strings, numbers, and plain objects pass through unchanged).\n *\n * ## Usage\n *\n * ```ts\n * try {\n * await doSomething();\n * } catch (error) {\n * logger.error('Something failed', { error: errField(error) });\n * }\n * ```\n *\n * Use this at every `logger.error` call site that includes an `error`\n * field derived from a catch block. Raw `{ error }` without this helper\n * is almost always a bug.\n */\nexport function errField(error: unknown): unknown {\n if (error instanceof Error) {\n return {\n name: error.name,\n message: error.message,\n stack: error.stack,\n ...(error.cause !== undefined && { cause: errField(error.cause) }),\n };\n }\n return error;\n}\n","/**\n * Annotation body utilities\n *\n * These are the matcher primitives used by the `mark:body-updated` event\n * replay path (ViewMaterializer and GraphDBConsumer) to apply add/remove/\n * replace operations against an annotation body.\n */\n\nimport type { components } from './types';\nimport type { Annotation } from './annotation-types';\n\ntype BodyPurpose = components['schemas']['BodyPurpose'];\n\n/**\n * Identity of a body item for matching purposes.\n *\n * Identity is `type + source` for SpecificResource and `type + value` for\n * TextualBody. `purpose` is OPTIONAL: if the caller provides it, it's\n * included in the match (used to disambiguate same-source bodies under\n * different purposes, per the W3C Web Annotation model). If the caller\n * omits it, the matcher ignores purpose and matches on identity alone.\n *\n * Callers SHOULD provide `purpose` when they know it (e.g., the bind flow\n * always unlinks a `purpose: 'linking'` body) so that future multi-purpose\n * annotations continue to disambiguate correctly. Leaving `purpose`\n * unspecified matches whichever purpose comes first in the body — which is\n * fine today because Semiont annotations currently have at most one body\n * item per (type, source/value) pair.\n */\nexport type BodyItemIdentity =\n | { type: 'SpecificResource'; source: string; purpose?: BodyPurpose }\n | { type: 'TextualBody'; value: string; purpose?: BodyPurpose };\n\n/**\n * Find a body item by identity. Returns the index of the first match, or -1.\n *\n * See `BodyItemIdentity` for matching semantics.\n */\nexport function findBodyItem(\n body: Annotation['body'],\n identity: BodyItemIdentity,\n): number {\n if (!Array.isArray(body)) {\n return -1;\n }\n\n for (let i = 0; i < body.length; i++) {\n const item = body[i];\n\n if (typeof item !== 'object' || item === null || !('type' in item)) {\n continue;\n }\n\n const itemType = (item as { type: unknown }).type;\n if (itemType !== identity.type) {\n continue;\n }\n\n // Identity field match (source or value)\n if (identity.type === 'SpecificResource') {\n if (!('source' in item)) continue;\n const itemSource = (item as { source: unknown }).source;\n if (itemSource !== identity.source) continue;\n } else {\n if (!('value' in item)) continue;\n const itemValue = (item as { value: unknown }).value;\n if (itemValue !== identity.value) continue;\n }\n\n // Purpose match — ONLY if the caller specified one. Omitted purpose\n // means \"any purpose on this identity\", which is what the bind-flow\n // unlinker wants today.\n if (identity.purpose !== undefined) {\n const itemPurpose = (item as { purpose?: unknown }).purpose;\n if (itemPurpose !== identity.purpose) continue;\n }\n\n return i;\n }\n\n return -1;\n}\n","/**\n * ID generation utilities\n */\n\n// crypto.randomUUID() is available as a global in Node 14.17+ and all modern browsers.\n// Declared here because the core package tsconfig uses lib:ES2022 (no dom types).\ndeclare const crypto: { randomUUID(): string };\n\n/**\n * Generate a UUID v4 string (without dashes)\n */\nexport function generateUuid(): string {\n return crypto.randomUUID().replace(/-/g, '');\n}\n","/**\n * Annotation Assembly\n *\n * Pure functions for building W3C Annotations and applying body operations.\n * No EventBus, no persistence — just data transformation.\n */\n\nimport type { components } from './types';\nimport type { Selector } from './payload-types';\nimport type { Annotation } from './annotation-types';\nimport { annotationId } from './identifiers';\nimport { generateUuid } from './id-generation';\n\ntype Agent = components['schemas']['Agent'];\ntype AnnotationBody = components['schemas']['AnnotationBody'];\ntype CreateAnnotationRequest = components['schemas']['CreateAnnotationRequest'];\ntype UpdateAnnotationBodyRequest = components['schemas']['UpdateAnnotationBodyRequest'];\ntype TextPositionSelector = components['schemas']['TextPositionSelector'];\ntype SvgSelector = components['schemas']['SvgSelector'];\ntype FragmentSelector = components['schemas']['FragmentSelector'];\n\nexport interface AssembledAnnotation {\n annotation: Annotation;\n bodyArray: AnnotationBody[];\n}\n\n// =============================================================================\n// Selector utilities used by assembleAnnotation\n// =============================================================================\n\n/**\n * Get TextPositionSelector from a selector (single or array)\n */\nexport function getTextPositionSelector(selector: Selector | Selector[] | undefined): TextPositionSelector | null {\n if (!selector) return null;\n const selectors = Array.isArray(selector) ? selector : [selector];\n const found = selectors.find(s => s.type === 'TextPositionSelector');\n if (!found) return null;\n return found.type === 'TextPositionSelector' ? found : null;\n}\n\n/**\n * Get SvgSelector from a selector (single or array)\n */\nexport function getSvgSelector(selector: Selector | Selector[] | undefined): SvgSelector | null {\n if (!selector) return null;\n const selectors = Array.isArray(selector) ? selector : [selector];\n const found = selectors.find(s => s.type === 'SvgSelector');\n if (!found) return null;\n return found.type === 'SvgSelector' ? found : null;\n}\n\n/**\n * Get FragmentSelector from a selector (single or array)\n */\nexport function getFragmentSelector(selector: Selector | Selector[] | undefined): FragmentSelector | null {\n if (!selector) return null;\n const selectors = Array.isArray(selector) ? selector : [selector];\n const found = selectors.find(s => s.type === 'FragmentSelector');\n if (!found) return null;\n return found.type === 'FragmentSelector' ? found : null;\n}\n\n/**\n * Validate SVG markup for W3C compliance\n *\n * @returns null if valid, error message if invalid\n */\nexport function validateSvgMarkup(svg: string): string | null {\n if (!svg.includes('xmlns=\"http://www.w3.org/2000/svg\"')) {\n return 'SVG must include xmlns=\"http://www.w3.org/2000/svg\" attribute';\n }\n\n if (!svg.includes('<svg') || !svg.includes('</svg>')) {\n return 'SVG must have opening and closing tags';\n }\n\n const shapeElements = ['rect', 'circle', 'ellipse', 'polygon', 'polyline', 'path', 'line'];\n const hasShape = shapeElements.some(shape =>\n svg.includes(`<${shape}`) || svg.includes(`<${shape} `)\n );\n\n if (!hasShape) {\n return 'SVG must contain at least one shape element (rect, circle, ellipse, polygon, polyline, path, or line)';\n }\n\n return null;\n}\n\n// =============================================================================\n// Annotation assembly\n// =============================================================================\n\n/**\n * Build a complete W3C Annotation from a CreateAnnotationRequest.\n *\n * Generates a bare annotation ID (no URL prefix). URIs are constructed\n * at the API boundary when returning responses to clients.\n *\n * Throws on invalid input (missing selector, missing motivation, invalid SVG).\n */\nexport function assembleAnnotation(\n request: CreateAnnotationRequest,\n creator: Agent,\n): AssembledAnnotation {\n const newAnnotationId = annotationId(generateUuid());\n\n // Validate selector: must have TextPositionSelector, SvgSelector, or FragmentSelector\n const posSelector = getTextPositionSelector(request.target.selector);\n const svgSelector = getSvgSelector(request.target.selector);\n const fragmentSelector = getFragmentSelector(request.target.selector);\n\n if (!posSelector && !svgSelector && !fragmentSelector) {\n throw new Error('Either TextPositionSelector, SvgSelector, or FragmentSelector is required for creating annotations');\n }\n\n // Validate SVG markup if SvgSelector is provided\n if (svgSelector) {\n const svgError = validateSvgMarkup(svgSelector.value);\n if (svgError) {\n throw new Error(`Invalid SVG markup: ${svgError}`);\n }\n }\n\n if (!request.motivation) {\n throw new Error('motivation is required');\n }\n\n const now = new Date().toISOString();\n const annotation: Annotation = {\n '@context': 'http://www.w3.org/ns/anno.jsonld' as const,\n 'type': 'Annotation' as const,\n id: newAnnotationId,\n motivation: request.motivation,\n target: request.target,\n body: request.body as Annotation['body'],\n creator,\n created: now,\n modified: now,\n };\n\n const bodyArray = (Array.isArray(request.body) ? request.body : request.body ? [request.body] : []) as AnnotationBody[];\n\n return { annotation, bodyArray };\n}\n\n/**\n * Apply body operations (add/remove/replace) to an annotation's body array.\n * Returns a new array — does not mutate the input.\n */\nexport function applyBodyOperations(\n body: Annotation['body'],\n operations: UpdateAnnotationBodyRequest['operations'],\n): AnnotationBody[] {\n const bodyArray = Array.isArray(body) ? [...body] : [];\n\n for (const op of operations) {\n if (op.op === 'add') {\n const exists = bodyArray.some(item =>\n JSON.stringify(item) === JSON.stringify(op.item)\n );\n if (!exists) {\n bodyArray.push(op.item);\n }\n } else if (op.op === 'remove') {\n const index = bodyArray.findIndex(item =>\n JSON.stringify(item) === JSON.stringify(op.item)\n );\n if (index !== -1) {\n bodyArray.splice(index, 1);\n }\n } else if (op.op === 'replace') {\n const index = bodyArray.findIndex(item =>\n JSON.stringify(item) === JSON.stringify(op.oldItem)\n );\n if (index !== -1) {\n bodyArray[index] = op.newItem;\n }\n }\n }\n\n return bodyArray;\n}\n","/**\n * Annotation and Selector Utilities\n *\n * Pure TypeScript utilities for working with W3C Web Annotations.\n * No React dependencies - safe to use in any JavaScript environment.\n *\n * Body is either empty array (stub) or single SpecificResource (resolved)\n * Body can be array of TextualBody (tagging) + SpecificResource (linking)\n * Target can be simple string IRI or object with source and optional selector\n */\n\nimport type { components } from './types';\nimport type { Selector } from './payload-types';\nimport type { Annotation } from './annotation-types';\n\n// Re-export selector utilities (canonical location is annotation-assembly)\nexport {\n getTextPositionSelector,\n getSvgSelector,\n getFragmentSelector,\n validateSvgMarkup,\n} from './annotation-assembly';\ntype HighlightAnnotation = Annotation;\ntype ReferenceAnnotation = Annotation;\ntype TextPositionSelector = components['schemas']['TextPositionSelector'];\ntype TextQuoteSelector = components['schemas']['TextQuoteSelector'];\ntype SvgSelector = components['schemas']['SvgSelector'];\ntype FragmentSelector = components['schemas']['FragmentSelector'];\n\n// Re-export selector types for convenience\nexport type { TextPositionSelector, TextQuoteSelector, SvgSelector, FragmentSelector, Selector };\n\n/**\n * Get the source from an annotation body (null if stub)\n * Search for SpecificResource in body array\n */\nexport function getBodySource(body: Annotation['body']): string | null {\n if (Array.isArray(body)) {\n // Search for SpecificResource with source\n for (const item of body) {\n if (\n typeof item === 'object' &&\n item !== null &&\n 'type' in item &&\n 'source' in item\n ) {\n const itemType = (item as { type: unknown }).type;\n const itemSource = (item as { source: unknown }).source;\n\n if (itemType === 'SpecificResource' && typeof itemSource === 'string') {\n return itemSource;\n }\n }\n }\n return null; // No SpecificResource found = stub\n }\n\n // Single body object (SpecificResource)\n if (\n typeof body === 'object' &&\n body !== null &&\n 'type' in body &&\n 'source' in body\n ) {\n const bodyType = (body as { type: unknown }).type;\n const bodySource = (body as { source: unknown }).source;\n\n if (bodyType === 'SpecificResource' && typeof bodySource === 'string') {\n return bodySource;\n }\n }\n\n return null;\n}\n\n/**\n * Get the type from an annotation body (returns first body type in array)\n */\nexport function getBodyType(body: Annotation['body']): 'TextualBody' | 'SpecificResource' | null {\n if (Array.isArray(body)) {\n if (body.length === 0) {\n return null;\n }\n // Return type of first body item\n if (typeof body[0] === 'object' && body[0] !== null && 'type' in body[0]) {\n const firstType = (body[0] as { type: unknown }).type;\n if (firstType === 'TextualBody' || firstType === 'SpecificResource') {\n return firstType;\n }\n }\n return null;\n }\n\n // Single body object\n if (typeof body === 'object' && body !== null && 'type' in body) {\n const bodyType = (body as { type: unknown }).type;\n if (bodyType === 'TextualBody' || bodyType === 'SpecificResource') {\n return bodyType;\n }\n }\n\n return null;\n}\n\n/**\n * Check if body is resolved (has a source)\n * Check for SpecificResource in body array\n */\nexport function isBodyResolved(body: Annotation['body']): boolean {\n return getBodySource(body) !== null;\n}\n\n/**\n * Get the source IRI from target (handles both string and object forms)\n */\nexport function getTargetSource(target: Annotation['target']): string {\n if (typeof target === 'string') {\n return target;\n }\n return target.source;\n}\n\n/**\n * Get the selector from target (undefined if string or no selector)\n */\nexport function getTargetSelector(target: Annotation['target']) {\n if (typeof target === 'string') {\n return undefined;\n }\n return target.selector;\n}\n\n/**\n * Check if target has a selector\n */\nexport function hasTargetSelector(target: Annotation['target']): boolean {\n return typeof target !== 'string' && target.selector !== undefined;\n}\n\n/**\n * Type guard to check if an annotation is a highlight\n */\nexport function isHighlight(annotation: Annotation): annotation is HighlightAnnotation {\n return annotation.motivation === 'highlighting';\n}\n\n/**\n * Type guard to check if an annotation is a reference (linking)\n */\nexport function isReference(annotation: Annotation): annotation is ReferenceAnnotation {\n return annotation.motivation === 'linking';\n}\n\n/**\n * Type guard to check if an annotation is an assessment\n */\nexport function isAssessment(annotation: Annotation): annotation is Annotation {\n return annotation.motivation === 'assessing';\n}\n\n/**\n * Type guard to check if an annotation is a comment\n */\nexport function isComment(annotation: Annotation): annotation is Annotation {\n return annotation.motivation === 'commenting';\n}\n\n/**\n * Type guard to check if an annotation is a tag\n */\nexport function isTag(annotation: Annotation): annotation is Annotation {\n return annotation.motivation === 'tagging';\n}\n\n/**\n * Extract comment text from a comment annotation's body\n * @param annotation - The annotation to extract comment text from\n * @returns The comment text, or undefined if not a comment or no text found\n */\nexport function getCommentText(annotation: Annotation): string | undefined {\n if (!isComment(annotation)) return undefined;\n const body = Array.isArray(annotation.body) ? annotation.body[0] : annotation.body;\n if (body && 'value' in body) {\n return body.value;\n }\n return undefined;\n}\n\n/**\n * Type guard to check if a reference annotation is a stub (unresolved)\n * Stub if no SpecificResource in body array\n */\nexport function isStubReference(annotation: Annotation): boolean {\n return isReference(annotation) && !isBodyResolved(annotation.body);\n}\n\n/**\n * Type guard to check if a reference annotation is resolved\n * Resolved if SpecificResource exists in body array\n */\nexport function isResolvedReference(annotation: Annotation): annotation is ReferenceAnnotation {\n return isReference(annotation) && isBodyResolved(annotation.body);\n}\n\n// =============================================================================\n// SELECTOR UTILITIES\n// =============================================================================\n\n/**\n * Get the exact text from a selector (single or array)\n *\n * When selector is an array, tries to find a TextQuoteSelector (which has exact text).\n * TextPositionSelector does not have exact text, only character offsets.\n * Handles undefined selector (when target is a string IRI with no selector)\n */\nexport function getExactText(selector: Selector | Selector[] | undefined): string {\n if (!selector) {\n return ''; // No selector means entire resource\n }\n const selectors = Array.isArray(selector) ? selector : [selector];\n\n // Try to find TextQuoteSelector (has exact text)\n const quoteSelector = selectors.find(s => s.type === 'TextQuoteSelector') as TextQuoteSelector | undefined;\n if (quoteSelector) {\n return quoteSelector.exact;\n }\n\n // No TextQuoteSelector found\n return '';\n}\n\n/**\n * Get the exact text from an annotation's target selector\n * Uses getTargetSelector helper to safely get selector\n */\nexport function getAnnotationExactText(annotation: Annotation): string {\n const selector = getTargetSelector(annotation.target);\n return getExactText(selector as Selector | Selector[] | undefined);\n}\n\n/**\n * Get the primary selector from a selector (single or array)\n *\n * When selector is an array, returns the first selector.\n * When selector is a single object, returns it as-is.\n */\nexport function getPrimarySelector(selector: Selector | Selector[]): Selector {\n if (Array.isArray(selector)) {\n if (selector.length === 0) {\n throw new Error('Empty selector array');\n }\n const first = selector[0];\n if (!first) {\n throw new Error('Invalid selector array');\n }\n return first;\n }\n return selector;\n}\n\n/**\n * Get TextQuoteSelector from a selector (single or array)\n *\n * Returns the first TextQuoteSelector found, or null if none exists.\n */\nexport function getTextQuoteSelector(selector: Selector | Selector[]): TextQuoteSelector | null {\n const selectors = Array.isArray(selector) ? selector : [selector];\n const found = selectors.find(s => s.type === 'TextQuoteSelector');\n if (!found) return null;\n return found.type === 'TextQuoteSelector' ? found : null;\n}\n\n/**\n * Extract bounding box from SVG markup\n *\n * Attempts to extract x, y, width, height from the SVG viewBox or root element.\n * Returns null if bounding box cannot be determined.\n */\nexport function extractBoundingBox(svg: string): { x: number; y: number; width: number; height: number } | null {\n // Try to extract viewBox attribute from SVG element\n const viewBoxMatch = svg.match(/<svg[^>]*viewBox=\"([^\"]+)\"/);\n if (viewBoxMatch) {\n const values = viewBoxMatch[1].split(/\\s+/).map(parseFloat);\n if (values.length === 4 && values.every(v => !isNaN(v))) {\n return {\n x: values[0],\n y: values[1],\n width: values[2],\n height: values[3]\n };\n }\n }\n\n // Try to extract width/height attributes from SVG element (assume x=0, y=0)\n const svgTagMatch = svg.match(/<svg[^>]*>/);\n if (svgTagMatch) {\n const svgTag = svgTagMatch[0];\n const widthMatch = svgTag.match(/width=\"([^\"]+)\"/);\n const heightMatch = svgTag.match(/height=\"([^\"]+)\"/);\n\n if (widthMatch && heightMatch) {\n const width = parseFloat(widthMatch[1]);\n const height = parseFloat(heightMatch[1]);\n\n if (!isNaN(width) && !isNaN(height)) {\n return { x: 0, y: 0, width, height };\n }\n }\n }\n\n return null;\n}\n","/**\n * PDF viewrect FragmentSelector codec.\n *\n * `PdfCoordinate` is a bounding rectangle in PDF point space: origin at the\n * bottom-left of the page, Y increasing upward. The Y-flip to canvas pixels\n * lives in the browser (`react-ui`); the server has no canvas.\n *\n * These functions are the viewrect peer of the W3C `FragmentSelector` wrapper in\n * `web-annotation-utils`: they serialize/parse the RFC 3778\n * `page=N&viewrect=left,top,width,height` value. `@semiont/content` (geometry\n * from the text layer), `@semiont/jobs` (serialization at write time), and the\n * browser canvas all import them from here — no package reaches into the UI.\n *\n * RFC 3778 PDF Fragment Identifiers: https://tools.ietf.org/html/rfc3778\n */\n\n/**\n * A bounding rectangle in PDF point coordinates.\n * Origin at the bottom-left of the page; Y increases upward.\n */\nexport interface PdfCoordinate {\n page: number;\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\n/**\n * Serialize a PdfCoordinate to an RFC 3778 FragmentSelector value.\n * Format: `page=N&viewrect=left,top,width,height` (all in PDF points).\n */\nexport function createFragmentSelector(coord: PdfCoordinate): string {\n return `page=${coord.page}&viewrect=${coord.x},${coord.y},${coord.width},${coord.height}`;\n}\n\n/**\n * Parse an RFC 3778 FragmentSelector value into PDF coordinates.\n * Returns null when the value is not a well-formed page + viewrect fragment.\n */\nexport function parseFragmentSelector(fragment: string): PdfCoordinate | null {\n const pageMatch = fragment.match(/page=(\\d+)/);\n if (!pageMatch) return null;\n\n // Each coordinate: optional sign, integer part, optional fraction — tight enough\n // to round-trip negatives and reject malformed numbers (e.g. \"1.2.3\").\n const viewrectMatch = fragment.match(\n /viewrect=(-?\\d+(?:\\.\\d+)?),(-?\\d+(?:\\.\\d+)?),(-?\\d+(?:\\.\\d+)?),(-?\\d+(?:\\.\\d+)?)/\n );\n if (!viewrectMatch) return null;\n\n return {\n page: parseInt(pageMatch[1], 10),\n x: parseFloat(viewrectMatch[1]),\n y: parseFloat(viewrectMatch[2]),\n width: parseFloat(viewrectMatch[3]),\n height: parseFloat(viewrectMatch[4]),\n };\n}\n\n/** Extract the 1-indexed page number from a FragmentSelector value. */\nexport function getPageFromFragment(fragment: string): number | null {\n const match = fragment.match(/page=(\\d+)/);\n return match ? parseInt(match[1], 10) : null;\n}\n","/**\n * Helper functions for working with W3C ResourceDescriptor\n */\n\nimport type { components } from './types';\nimport type { ResourceDescriptor } from './graph';\n\ntype Representation = components['schemas']['Representation'];\n\n/**\n * Get the resource ID from @id property\n *\n * @id is always a bare ID (UUID), never a full URI.\n */\nexport function getResourceId(resource: ResourceDescriptor | undefined): string | undefined {\n if (!resource) return undefined;\n return resource['@id'] || undefined;\n}\n\n/**\n * Get the primary representation (first or only representation)\n */\nexport function getPrimaryRepresentation(resource: ResourceDescriptor | undefined): Representation | undefined {\n if (!resource?.representations) return undefined;\n const reps = Array.isArray(resource.representations)\n ? resource.representations\n : [resource.representations];\n return reps[0];\n}\n\n/**\n * Get the media type from the primary representation\n */\nexport function getPrimaryMediaType(resource: ResourceDescriptor | undefined): string | undefined {\n return getPrimaryRepresentation(resource)?.mediaType;\n}\n\n/**\n * Get the checksum from the primary representation\n */\nexport function getChecksum(resource: ResourceDescriptor | undefined): string | undefined {\n return getPrimaryRepresentation(resource)?.checksum;\n}\n\n/**\n * Get the language from the primary representation\n */\nexport function getLanguage(resource: ResourceDescriptor | undefined): string | undefined {\n return getPrimaryRepresentation(resource)?.language;\n}\n\n/**\n * Get storage URI from primary representation\n *\n * @param resource - ResourceDescriptor\n * @returns Storage URI or undefined\n */\nexport function getStorageUri(resource: ResourceDescriptor | undefined): string | undefined {\n return getPrimaryRepresentation(resource)?.storageUri;\n}\n\n/**\n * Get creator agent from wasAttributedTo\n * Handles both single agent and array of agents\n *\n * @param resource - ResourceDescriptor\n * @returns First agent or undefined\n */\nexport function getCreator(resource: ResourceDescriptor | undefined): components['schemas']['Agent'] | undefined {\n if (!resource?.wasAttributedTo) return undefined;\n\n return Array.isArray(resource.wasAttributedTo)\n ? resource.wasAttributedTo[0]\n : resource.wasAttributedTo;\n}\n\n/**\n * Get derived-from URI\n * Handles both single URI and array of URIs\n *\n * @param resource - ResourceDescriptor\n * @returns First derivation URI or undefined\n */\nexport function getDerivedFrom(resource: ResourceDescriptor | undefined): string | undefined {\n if (!resource?.wasDerivedFrom) return undefined;\n\n return Array.isArray(resource.wasDerivedFrom)\n ? resource.wasDerivedFrom[0]\n : resource.wasDerivedFrom;\n}\n\n/**\n * Check if resource is archived (application-specific field)\n *\n * @param resource - ResourceDescriptor\n * @returns True if archived, false otherwise\n */\nexport function isArchived(resource: ResourceDescriptor | undefined): boolean {\n return resource?.archived === true;\n}\n\n/**\n * Get entity types from resource (application-specific field)\n *\n * @param resource - ResourceDescriptor\n * @returns Array of entity types, empty if not set\n */\nexport function getResourceEntityTypes(resource: ResourceDescriptor | undefined): string[] {\n return resource?.entityTypes || [];\n}\n\n/**\n * Check if resource is a draft (application-specific field)\n *\n * @param resource - ResourceDescriptor\n * @returns True if draft, false otherwise\n */\nexport function isDraft(resource: ResourceDescriptor | undefined): boolean {\n return resource?.isDraft === true;\n}\n\n/**\n * Map charset names to Node.js Buffer encoding names\n * Node.js Buffer.toString() supports: 'utf8', 'utf16le', 'latin1', 'base64', 'hex', 'ascii', 'binary', 'ucs2'\n *\n * @param charset - Charset name (e.g., \"UTF-8\", \"ISO-8859-1\", \"Windows-1252\")\n * @returns Node.js BufferEncoding\n */\nexport function getNodeEncoding(charset: string): BufferEncoding {\n const normalized = charset.toLowerCase().replace(/[-_]/g, '');\n\n // Map common charset names to Node.js encodings\n const charsetMap: Record<string, BufferEncoding> = {\n 'utf8': 'utf8',\n 'iso88591': 'latin1',\n 'latin1': 'latin1',\n 'ascii': 'ascii',\n 'usascii': 'ascii',\n 'utf16le': 'utf16le',\n 'ucs2': 'ucs2',\n 'binary': 'binary',\n 'windows1252': 'latin1', // Windows-1252 is a superset of Latin-1\n 'cp1252': 'latin1',\n };\n\n return charsetMap[normalized] || 'utf8';\n}\n\n/**\n * Decode a representation buffer to string using the correct charset\n * Extracts charset from media type and uses appropriate encoding\n *\n * @param buffer - The raw representation data\n * @param mediaType - Media type with optional charset (e.g., \"text/plain; charset=iso-8859-1\")\n * @returns Decoded string\n *\n * @example\n * ```typescript\n * const content = decodeRepresentation(buffer, \"text/plain; charset=utf-8\");\n * const legacy = decodeRepresentation(buffer, \"text/plain; charset=windows-1252\");\n * ```\n */\nexport function decodeRepresentation(buffer: Buffer, mediaType: string): string {\n // Extract charset from mediaType (e.g., \"text/plain; charset=iso-8859-1\")\n const charsetMatch = mediaType.match(/charset=([^\\s;]+)/i);\n const charset = (charsetMatch?.[1] || 'utf-8').toLowerCase();\n\n // Map to Node.js encoding\n const encoding = getNodeEncoding(charset);\n\n return buffer.toString(encoding);\n}\n","/**\n * BRIDGED_CHANNELS\n *\n * The set of bus channels that any concrete transport bridges into the\n * caller-supplied bus via `bridgeInto`. Transport-neutral: every concrete\n * `ITransport` shares the same set; HTTP delivers them via SSE,\n * in-process transports forward them directly from the local actor bus.\n *\n * Note: this is the *fan-in* set — channels for events the transport\n * receives and pushes onto the client's bus. It is not the same as the\n * channels the client emits (which is open-ended).\n *\n * Resource-scoped channels (joined/left via `subscribeToResource`) are\n * tracked separately by transports that care about scope (HTTP).\n */\nexport const BRIDGED_CHANNELS = [\n 'browse:resources-result', 'browse:resources-failed',\n 'browse:resource-result', 'browse:resource-failed',\n 'browse:annotations-result', 'browse:annotations-failed',\n 'browse:annotation-result', 'browse:annotation-failed',\n 'browse:annotation-history-result', 'browse:annotation-history-failed',\n 'browse:events-result', 'browse:events-failed',\n 'browse:referenced-by-result', 'browse:referenced-by-failed',\n 'browse:entity-types-result', 'browse:entity-types-failed',\n 'browse:tag-schemas-result', 'browse:tag-schemas-failed',\n 'browse:directory-result', 'browse:directory-failed',\n 'browse:annotation-context-result', 'browse:annotation-context-failed',\n 'mark:delete-ok', 'mark:delete-failed',\n 'mark:create-ok', 'mark:create-failed',\n 'match:search-results', 'match:search-failed',\n 'gather:complete', 'gather:failed',\n 'gather:annotation-progress', 'gather:annotation-finished',\n 'gather:summary-result', 'gather:summary-failed',\n 'bind:body-updated', 'bind:body-update-failed',\n 'job:report-progress', 'job:complete', 'job:fail',\n 'job:status-result', 'job:status-failed',\n 'job:created', 'job:create-failed',\n 'job:claimed', 'job:claim-failed',\n 'yield:create-ok', 'yield:create-failed',\n 'yield:update-ok', 'yield:update-failed',\n 'yield:clone-token-generated', 'yield:clone-token-failed',\n 'yield:clone-resource-result', 'yield:clone-resource-failed',\n 'yield:clone-created', 'yield:clone-create-failed',\n 'frame:entity-type-added',\n 'frame:tag-schema-added',\n 'beckon:focus', 'beckon:sparkle',\n 'bus:resume-gap',\n] as const;\n\nexport type BridgedChannel = typeof BRIDGED_CHANNELS[number];\n","/**\n * Fuzzy Anchoring for W3C Web Annotation TextQuoteSelector\n *\n * Uses prefix/suffix context to disambiguate when the same text appears multiple times.\n * Implements fuzzy matching as specified in the W3C Web Annotation Data Model.\n *\n * @see https://www.w3.org/TR/annotation-model/#text-quote-selector\n */\n\nexport interface TextPosition {\n start: number;\n end: number;\n}\n\nexport type MatchQuality = 'exact' | 'normalized' | 'case-insensitive' | 'fuzzy';\n\n/**\n * Normalize text for comparison - handles common document editing changes\n *\n * Collapses whitespace, converts curly quotes to straight quotes,\n * and normalizes common punctuation variations.\n */\nexport function normalizeText(text: string): string {\n return text\n .replace(/\\s+/g, ' ') // collapse whitespace\n .replace(/[\\u2018\\u2019]/g, \"'\") // curly single quotes → straight\n .replace(/[\\u201C\\u201D]/g, '\"') // curly double quotes → straight\n .replace(/\\u2014/g, '--') // em-dash → double hyphen\n .replace(/\\u2013/g, '-') // en-dash → hyphen\n .trim();\n}\n\n/**\n * Calculate Levenshtein distance between two strings\n * Used for fuzzy matching when exact text doesn't match\n */\nfunction levenshteinDistance(str1: string, str2: string): number {\n const len1 = str1.length;\n const len2 = str2.length;\n const matrix: number[][] = [];\n\n // Initialize matrix\n for (let i = 0; i <= len1; i++) {\n matrix[i] = [i];\n }\n for (let j = 0; j <= len2; j++) {\n matrix[0]![j] = j;\n }\n\n // Fill matrix\n for (let i = 1; i <= len1; i++) {\n for (let j = 1; j <= len2; j++) {\n const cost = str1[i - 1] === str2[j - 1] ? 0 : 1;\n const deletion = matrix[i - 1]![j]! + 1;\n const insertion = matrix[i]![j - 1]! + 1;\n const substitution = matrix[i - 1]![j - 1]! + cost;\n matrix[i]![j] = Math.min(deletion, insertion, substitution);\n }\n }\n\n return matrix[len1]![len2]!;\n}\n\n/**\n * Pre-computed content strings for batch fuzzy matching.\n * Avoids recomputing normalizeText(content) and content.toLowerCase()\n * for every annotation when processing many annotations against the same content.\n *\n * `normalizedMap[i]` is the original-content index that normalized\n * character `i` came from. It has length `normalizedContent.length + 1`;\n * the final entry is `content.length` so a match that ends at the end of\n * the normalized string maps back to the end of the original. This map is\n * how `findBestTextMatch` recovers the *original* offset of a normalized\n * match — counting char-by-char with `normalizeText(singleChar)` is\n * wrong, because a lone whitespace char trims to `''` (contributing 0)\n * while in a full-string normalize it collapses to a single space\n * (contributing 1). That discrepancy shifted recovered offsets by the\n * number of whitespace runs before the match.\n */\nexport interface ContentCache {\n normalizedContent: string;\n normalizedMap: number[];\n lowerContent: string;\n}\n\n/**\n * Normalize text and, in the same pass, build a map from each normalized\n * character position back to the original-content index it came from.\n * The produced `normalized` string is identical to `normalizeText(input)`\n * — a test pins this equivalence so the two can't drift.\n */\nexport function normalizeTextWithMap(input: string): { normalized: string; map: number[] } {\n let normalized = '';\n const map: number[] = [];\n\n // First pass mirrors normalizeText exactly, char by char, recording the\n // origin index for every emitted normalized character.\n let pendingWhitespaceStart = -1; // origin index of an open whitespace run, or -1\n\n const flushWhitespace = () => {\n if (pendingWhitespaceStart !== -1) {\n // A whitespace run collapses to a single space, mapped to the run's\n // first char — but a *leading* run (nothing emitted yet) is dropped,\n // matching normalizeText's trailing `.trim()`.\n if (normalized.length > 0) {\n normalized += ' ';\n map.push(pendingWhitespaceStart);\n }\n pendingWhitespaceStart = -1;\n }\n };\n\n for (let i = 0; i < input.length; i++) {\n const ch = input[i]!;\n if (/\\s/.test(ch)) {\n if (pendingWhitespaceStart === -1) pendingWhitespaceStart = i;\n continue;\n }\n flushWhitespace();\n if (ch === '‘' || ch === '’') {\n normalized += \"'\"; map.push(i);\n } else if (ch === '“' || ch === '”') {\n normalized += '\"'; map.push(i);\n } else if (ch === '—') {\n normalized += '--'; map.push(i); map.push(i);\n } else if (ch === '–') {\n normalized += '-'; map.push(i);\n } else {\n normalized += ch; map.push(i);\n }\n }\n // A trailing whitespace run is dropped by trim — do not flush it.\n\n // `normalizeText` applies `.trim()` last. Our run logic already drops a\n // trailing whitespace run; a leading run is dropped because flushWhitespace\n // only runs before a non-space char, so a run at the very start is never\n // emitted. Both ends match trim().\n map.push(input.length); // sentinel: one past the last normalized char\n return { normalized, map };\n}\n\n/**\n * Build a ContentCache for a given content string.\n * Call once per content, pass to findBestTextMatch/anchorAnnotation for all annotations.\n */\nexport function buildContentCache(content: string): ContentCache {\n const { normalized, map } = normalizeTextWithMap(content);\n return {\n normalizedContent: normalized,\n normalizedMap: map,\n lowerContent: content.toLowerCase()\n };\n}\n\n/**\n * Find best match for text in content using multi-strategy search\n *\n * Shared core logic used by both anchorAnnotation (render-time) and\n * reconcileSelector (write-time).\n *\n * @param content - Full text content to search within\n * @param searchText - The text to find\n * @param positionHint - Hint for where to search (TextPositionSelector.start)\n * @param cache - Pre-computed normalized/lowered content (from buildContentCache)\n * @returns Match with position and quality, or null if not found\n */\nexport function findBestTextMatch(\n content: string,\n searchText: string,\n positionHint: number | undefined,\n cache: ContentCache\n): { start: number; end: number; matchQuality: MatchQuality } | null {\n const maxFuzzyDistance = Math.max(5, Math.floor(searchText.length * 0.05)); // 5% tolerance or min 5 chars\n\n // Strategy 1: Exact match (case-sensitive, exact whitespace)\n const exactIndex = content.indexOf(searchText);\n if (exactIndex !== -1) {\n return {\n start: exactIndex,\n end: exactIndex + searchText.length,\n matchQuality: 'exact'\n };\n }\n\n // Strategy 2: Normalized match (handles whitespace/quote variations).\n // Map the normalized match position back to the original via the\n // precomputed index map. The naive char-by-char re-normalize is wrong:\n // a lone whitespace char trims to '' (0-width) but collapses to a single\n // space (1-width) in a full normalize, so it under-counts by the number\n // of whitespace runs before the match, shifting the recovered offset.\n const normalizedSearch = normalizeText(searchText);\n const normalizedIndex = cache.normalizedContent.indexOf(normalizedSearch);\n if (normalizedIndex !== -1) {\n const start = cache.normalizedMap[normalizedIndex] ?? 0;\n const end = cache.normalizedMap[normalizedIndex + normalizedSearch.length] ?? content.length;\n return {\n start,\n end,\n matchQuality: 'normalized'\n };\n }\n\n // Strategy 3: Case-insensitive match\n const lowerSearch = searchText.toLowerCase();\n const caseInsensitiveIndex = cache.lowerContent.indexOf(lowerSearch);\n if (caseInsensitiveIndex !== -1) {\n return {\n start: caseInsensitiveIndex,\n end: caseInsensitiveIndex + searchText.length,\n matchQuality: 'case-insensitive'\n };\n }\n\n // Strategy 4: Fuzzy match using Levenshtein distance with sliding window\n // Search near position hint if provided, otherwise search full content\n const windowSize = searchText.length;\n const searchRadius = Math.min(500, content.length);\n const searchStart = positionHint !== undefined\n ? Math.max(0, positionHint - searchRadius)\n : 0;\n const searchEnd = positionHint !== undefined\n ? Math.min(content.length, positionHint + searchRadius)\n : content.length;\n\n let bestMatch: { start: number; distance: number } | null = null;\n\n // Scan through content with sliding window\n for (let i = searchStart; i <= searchEnd - windowSize; i++) {\n const candidate = content.substring(i, i + windowSize);\n const distance = levenshteinDistance(searchText, candidate);\n\n if (distance <= maxFuzzyDistance) {\n if (!bestMatch || distance < bestMatch.distance) {\n bestMatch = { start: i, distance };\n }\n }\n }\n\n if (bestMatch) {\n return {\n start: bestMatch.start,\n end: bestMatch.start + windowSize,\n matchQuality: 'fuzzy'\n };\n }\n\n return null;\n}\n\n/**\n * Verify that a position correctly points to the exact text\n * Useful for debugging and validation\n */\nexport function verifyPosition(\n content: string,\n position: TextPosition,\n expectedExact: string\n): boolean {\n const actualText = content.substring(position.start, position.end);\n return actualText === expectedExact;\n}\n","/**\n * Anchor a W3C Web Annotation to its rendered text.\n *\n * Render-time cleverness is deliberately limited to **verbatim** quote\n * matching. The annotation's two selectors are written to agree (the\n * write-side `reconcileSelector` + `buildTextAnnotation` invariant\n * guarantee `content.substring(start, end) === exact`). At render time the\n * only legitimate discrepancy is *positional drift*: the document grew or\n * shrank above the span after the annotation was written, so the offset is\n * stale but the exact text still exists, byte-identical, elsewhere. That is\n * the W3C-intended role of `TextQuoteSelector`, and it is safe because it\n * demands identical text — no normalization, no fuzzy matching, no\n * judgment call.\n *\n * Anything that would require *fuzzy* recovery (smart-quote folding,\n * whitespace collapse, Levenshtein) is out of scope here: a non-verbatim\n * mismatch means the content representation diverged or the stored record\n * is wrong, both of which are deterministic and belong upstream (canonical\n * content, or a corrected annotation event). The renderer does not guess —\n * it renders at the stored offset and flags the anchor low-confidence so\n * the discrepancy surfaces for an upstream fix.\n *\n * Returns `null` only when nothing usable is present; otherwise always\n * returns a position with a `strategy` and `confidence`.\n */\n\nexport type AnchorStrategy =\n /** Position hint pointed exactly at the exact text. Unambiguous. */\n | 'fast-path'\n /** Exact text appears once verbatim in the content. No tiebreak needed. */\n | 'unique-occurrence'\n /** Multiple verbatim occurrences; prefix+suffix uniquely identified one. */\n | 'context-disambiguated'\n /** Multiple verbatim candidates; position closest to hint chosen. */\n | 'position-tiebreaker'\n /** Exact text not found verbatim (or no quote); raw stored offset used,\n * flagged for upstream correction. */\n | 'position-fallback';\n\nexport type AnchorConfidence = 'high' | 'medium' | 'low';\n\nexport interface RenderedAnchor {\n start: number;\n end: number;\n strategy: AnchorStrategy;\n confidence: AnchorConfidence;\n}\n\nexport interface AnchorSelectors {\n position?: { start: number; end: number };\n quote?: { exact: string; prefix?: string; suffix?: string };\n}\n\n/**\n * Distance window for the position tiebreaker. Candidates closer than this\n * to the hint receive a non-zero position score; further candidates fall\n * back to zero. Tuned for typical document sizes; calibration tests pin\n * the boundary behaviour rather than the exact value.\n */\nexport const POSITION_WINDOW = 1024;\n\n/**\n * Score weights — kept as named constants so the calibration tests can\n * import them and pin the *relationships* rather than the magnitudes.\n *\n * Invariant: a full-context match always outranks any position score.\n * (`CONTEXT_FULL_WEIGHT * 2 > POSITION_WEIGHT_MAX`, accounting for\n * prefix+suffix each contributing the full weight.)\n */\nexport const CONTEXT_FULL_WEIGHT = 10;\nexport const CONTEXT_PARTIAL_WEIGHT = 5;\nexport const POSITION_WEIGHT_MAX = 5;\n\n/**\n * Locate the best-effort anchor for an annotation against the content the\n * renderer is about to display. Verbatim-only — see the module doc.\n */\nexport function anchorAnnotation(\n content: string,\n selectors: AnchorSelectors,\n): RenderedAnchor | null {\n const { position, quote } = selectors;\n\n // No quote selector. Position is the only signal; use it verbatim if\n // present and in-range, otherwise the annotation has no anchor.\n if (!quote || !quote.exact) {\n if (!position) return null;\n if (position.start < 0 || position.end > content.length || position.start >= position.end) {\n return null;\n }\n return {\n start: position.start,\n end: position.end,\n strategy: 'position-fallback',\n confidence: 'low',\n };\n }\n\n const { exact, prefix, suffix } = quote;\n\n // Fast path: position hint exactly matches the exact text.\n if (position) {\n const probeEnd = position.start + exact.length;\n if (\n position.start >= 0 &&\n probeEnd <= content.length &&\n content.substring(position.start, probeEnd) === exact\n ) {\n return {\n start: position.start,\n end: probeEnd,\n strategy: 'fast-path',\n confidence: 'high',\n };\n }\n }\n\n // Find all occurrences via exact indexOf. Cheap; bounded by content\n // size; sufficient for the common case where the renderer's content\n // matches the worker's content character-for-character.\n const occurrences = findAllOccurrences(content, exact);\n\n if (occurrences.length === 1) {\n const start = occurrences[0]!;\n return {\n start,\n end: start + exact.length,\n strategy: 'unique-occurrence',\n confidence: 'high',\n };\n }\n\n if (occurrences.length > 1) {\n const winner = pickByScore(content, occurrences, exact, prefix, suffix, position?.start);\n return winner;\n }\n\n // No verbatim occurrence. We do NOT fuzzy-match at render time — a\n // non-verbatim mismatch means the content diverged or the record is\n // wrong, which is an upstream concern. Render at the stored offset so the\n // highlight still appears, flagged low-confidence so the discrepancy is\n // visible and gets corrected at the source.\n if (position && position.start >= 0 && position.end <= content.length && position.start < position.end) {\n return {\n start: position.start,\n end: position.end,\n strategy: 'position-fallback',\n confidence: 'low',\n };\n }\n\n return null;\n}\n\nfunction findAllOccurrences(content: string, exact: string): number[] {\n const out: number[] = [];\n let i = content.indexOf(exact);\n while (i !== -1) {\n out.push(i);\n i = content.indexOf(exact, i + 1);\n }\n return out;\n}\n\n/**\n * Context match score at a candidate offset.\n * Returns full / partial / no-match per side (prefix and suffix), then\n * sums each side weighted by `CONTEXT_FULL_WEIGHT` / `CONTEXT_PARTIAL_WEIGHT`.\n *\n * \"Full\" means the stored context aligns exactly with the source text\n * adjacent to the candidate. \"Partial\" is the looser substring check —\n * the stored context appears somewhere in the candidate's surroundings\n * but isn't anchored to the edges. This is the same partial-match logic\n * the previous `findTextWithContext` used, captured here so the scorer\n * can use it as one signal among many instead of a hard filter.\n */\nfunction contextScoreAt(\n content: string,\n pos: number,\n exact: string,\n prefix: string | undefined,\n suffix: string | undefined,\n): { score: number; full: boolean } {\n let score = 0;\n let prefixFull = true;\n let suffixFull = true;\n\n if (prefix) {\n const adj = content.substring(Math.max(0, pos - prefix.length), pos);\n if (adj.endsWith(prefix)) {\n score += CONTEXT_FULL_WEIGHT;\n prefixFull = true;\n } else if (adj.includes(prefix.trim()) && prefix.trim().length > 0) {\n score += CONTEXT_PARTIAL_WEIGHT;\n prefixFull = false;\n } else {\n prefixFull = false;\n }\n }\n\n if (suffix) {\n const adj = content.substring(pos + exact.length, Math.min(content.length, pos + exact.length + suffix.length));\n if (adj.startsWith(suffix)) {\n score += CONTEXT_FULL_WEIGHT;\n suffixFull = true;\n } else if (adj.includes(suffix.trim()) && suffix.trim().length > 0) {\n score += CONTEXT_PARTIAL_WEIGHT;\n suffixFull = false;\n } else {\n suffixFull = false;\n }\n }\n\n // \"Full\" overall match means every provided context field aligned\n // exactly — no partial fallbacks. Used to bump confidence to high.\n const full =\n (prefix === undefined || prefixFull) &&\n (suffix === undefined || suffixFull) &&\n (prefix !== undefined || suffix !== undefined);\n\n return { score, full };\n}\n\nfunction positionScoreAt(pos: number, hint: number | undefined): number {\n if (hint === undefined) return 0;\n const distance = Math.abs(pos - hint);\n if (distance >= POSITION_WINDOW) return 0;\n return POSITION_WEIGHT_MAX * (1 - distance / POSITION_WINDOW);\n}\n\nfunction pickByScore(\n content: string,\n occurrences: number[],\n exact: string,\n prefix: string | undefined,\n suffix: string | undefined,\n hint: number | undefined,\n): RenderedAnchor {\n let bestPos = occurrences[0]!;\n let bestScore = -1;\n let bestContextFull = false;\n let bestHasAnyContextSignal = false;\n let bestHasAnyPositionSignal = false;\n\n for (const pos of occurrences) {\n const ctx = contextScoreAt(content, pos, exact, prefix, suffix);\n const positionScore = positionScoreAt(pos, hint);\n const total = ctx.score + positionScore;\n if (total > bestScore) {\n bestScore = total;\n bestPos = pos;\n bestContextFull = ctx.full;\n bestHasAnyContextSignal = ctx.score > 0;\n bestHasAnyPositionSignal = positionScore > 0;\n }\n }\n\n // Strategy + confidence classification:\n // - both context fields aligned exactly → high-confidence context-disambiguated\n // - some context aligned (full or partial), no position needed → context-disambiguated, medium\n // - position broke the tie (winning candidate has position signal but no context signal,\n // or context was equal across candidates) → position-tiebreaker\n // - no signal at all (all candidates scored zero) → position-tiebreaker, low confidence,\n // deterministic first-of-many fallback\n let strategy: AnchorStrategy;\n let confidence: AnchorConfidence;\n\n if (bestContextFull) {\n strategy = 'context-disambiguated';\n confidence = 'high';\n } else if (bestHasAnyContextSignal && !bestHasAnyPositionSignal) {\n strategy = 'context-disambiguated';\n confidence = 'medium';\n } else if (bestHasAnyContextSignal && bestHasAnyPositionSignal) {\n // Context partially matched and position helped break the tie.\n strategy = 'position-tiebreaker';\n confidence = 'medium';\n } else if (bestHasAnyPositionSignal) {\n strategy = 'position-tiebreaker';\n confidence = 'medium';\n } else {\n strategy = 'position-tiebreaker';\n confidence = 'low';\n }\n\n return {\n start: bestPos,\n end: bestPos + exact.length,\n strategy,\n confidence,\n };\n}\n","/**\n * Locale information\n * Copied from SDK for frontend use\n */\n\nexport interface LocaleInfo {\n code: string;\n nativeName: string;\n englishName: string;\n}\n\nexport const LOCALES: readonly LocaleInfo[] = [\n { code: 'ar', nativeName: 'العربية', englishName: 'Arabic' },\n { code: 'bn', nativeName: 'বাংলা', englishName: 'Bengali' },\n { code: 'cs', nativeName: 'Čeština', englishName: 'Czech' },\n { code: 'da', nativeName: 'Dansk', englishName: 'Danish' },\n { code: 'de', nativeName: 'Deutsch', englishName: 'German' },\n { code: 'el', nativeName: 'Ελληνικά', englishName: 'Greek' },\n { code: 'en', nativeName: 'English', englishName: 'English' },\n { code: 'es', nativeName: 'Español', englishName: 'Spanish' },\n { code: 'fa', nativeName: 'فارسی', englishName: 'Persian' },\n { code: 'fi', nativeName: 'Suomi', englishName: 'Finnish' },\n { code: 'fr', nativeName: 'Français', englishName: 'French' },\n { code: 'he', nativeName: 'עברית', englishName: 'Hebrew' },\n { code: 'hi', nativeName: 'हिन्दी', englishName: 'Hindi' },\n { code: 'id', nativeName: 'Bahasa Indonesia', englishName: 'Indonesian' },\n { code: 'it', nativeName: 'Italiano', englishName: 'Italian' },\n { code: 'ja', nativeName: '日本語', englishName: 'Japanese' },\n { code: 'ko', nativeName: '한국어', englishName: 'Korean' },\n { code: 'ms', nativeName: 'Bahasa Melayu', englishName: 'Malay' },\n { code: 'nl', nativeName: 'Nederlands', englishName: 'Dutch' },\n { code: 'no', nativeName: 'Norsk', englishName: 'Norwegian' },\n { code: 'pl', nativeName: 'Polski', englishName: 'Polish' },\n { code: 'pt', nativeName: 'Português', englishName: 'Portuguese' },\n { code: 'ro', nativeName: 'Română', englishName: 'Romanian' },\n { code: 'sv', nativeName: 'Svenska', englishName: 'Swedish' },\n { code: 'th', nativeName: 'ไทย', englishName: 'Thai' },\n { code: 'tr', nativeName: 'Türkçe', englishName: 'Turkish' },\n { code: 'uk', nativeName: 'Українська', englishName: 'Ukrainian' },\n { code: 'vi', nativeName: 'Tiếng Việt', englishName: 'Vietnamese' },\n { code: 'zh', nativeName: '中文', englishName: 'Chinese' },\n] as const;\n\n// Create lookup map for efficient access\nconst localeByCode = new Map<string, LocaleInfo>(\n LOCALES.map(locale => [locale.code.toLowerCase(), locale])\n);\n\n/**\n * Get locale information by code\n */\nexport function getLocaleInfo(code: string | undefined): LocaleInfo | undefined {\n if (!code) return undefined;\n return localeByCode.get(code.toLowerCase());\n}\n\n/**\n * Get the native name of a language by its locale code\n */\nexport function getLocaleNativeName(code: string | undefined): string | undefined {\n return getLocaleInfo(code)?.nativeName;\n}\n\n/**\n * Get the English name of a language by its locale code\n */\nexport function getLocaleEnglishName(code: string | undefined): string | undefined {\n return getLocaleInfo(code)?.englishName;\n}\n\n/**\n * Format locale code for display as \"Native Name (code)\"\n */\nexport function formatLocaleDisplay(code: string | undefined): string | undefined {\n if (!code) return undefined;\n\n const info = getLocaleInfo(code);\n if (!info) return code;\n\n return `${info.nativeName} (${code.toLowerCase()})`;\n}\n\n/**\n * Get all supported locale codes\n */\nexport function getAllLocaleCodes(): readonly string[] {\n return LOCALES.map(l => l.code);\n}\n","/**\n * SVG Utility Functions\n *\n * Utilities for creating, parsing, and manipulating W3C-compliant SVG selectors\n * for image annotation.\n */\n\nexport interface Point {\n x: number;\n y: number;\n}\n\nexport interface BoundingBox {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\n/**\n * Create W3C-compliant SVG rectangle selector\n */\nexport function createRectangleSvg(start: Point, end: Point): string {\n const x = Math.min(start.x, end.x);\n const y = Math.min(start.y, end.y);\n const width = Math.abs(end.x - start.x);\n const height = Math.abs(end.y - start.y);\n\n return `<svg xmlns=\"http://www.w3.org/2000/svg\"><rect x=\"${x}\" y=\"${y}\" width=\"${width}\" height=\"${height}\"/></svg>`;\n}\n\n/**\n * Create W3C-compliant SVG polygon selector\n */\nexport function createPolygonSvg(points: Point[]): string {\n if (points.length < 3) {\n throw new Error('Polygon requires at least 3 points');\n }\n\n const pointsStr = points.map(p => `${p.x},${p.y}`).join(' ');\n return `<svg xmlns=\"http://www.w3.org/2000/svg\"><polygon points=\"${pointsStr}\"/></svg>`;\n}\n\n/**\n * Create W3C-compliant SVG circle selector\n */\nexport function createCircleSvg(center: Point, radius: number): string {\n if (radius <= 0) {\n throw new Error('Circle radius must be positive');\n }\n\n return `<svg xmlns=\"http://www.w3.org/2000/svg\"><circle cx=\"${center.x}\" cy=\"${center.y}\" r=\"${radius}\"/></svg>`;\n}\n\n/**\n * Parse SVG selector to extract shape type and data\n */\nexport function parseSvgSelector(svg: string): {\n type: 'rect' | 'polygon' | 'circle' | 'path';\n data: any;\n} | null {\n // Extract rectangle\n const rectMatch = svg.match(/<rect\\s+([^>]+)\\/>/);\n if (rectMatch && rectMatch[1]) {\n const attrs = rectMatch[1];\n const x = parseFloat(attrs.match(/x=\"([^\"]+)\"/)?.[1] || '0');\n const y = parseFloat(attrs.match(/y=\"([^\"]+)\"/)?.[1] || '0');\n const width = parseFloat(attrs.match(/width=\"([^\"]+)\"/)?.[1] || '0');\n const height = parseFloat(attrs.match(/height=\"([^\"]+)\"/)?.[1] || '0');\n\n return {\n type: 'rect',\n data: { x, y, width, height }\n };\n }\n\n // Extract polygon\n const polygonMatch = svg.match(/<polygon\\s+points=\"([^\"]+)\"/);\n if (polygonMatch && polygonMatch[1]) {\n const pointsStr = polygonMatch[1];\n const points = pointsStr.split(/\\s+/).map(pair => {\n const [x, y] = pair.split(',').map(parseFloat);\n return { x, y };\n });\n\n return {\n type: 'polygon',\n data: { points }\n };\n }\n\n // Extract circle\n const circleMatch = svg.match(/<circle\\s+([^>]+)\\/>/);\n if (circleMatch && circleMatch[1]) {\n const attrs = circleMatch[1];\n const cx = parseFloat(attrs.match(/cx=\"([^\"]+)\"/)?.[1] || '0');\n const cy = parseFloat(attrs.match(/cy=\"([^\"]+)\"/)?.[1] || '0');\n const r = parseFloat(attrs.match(/r=\"([^\"]+)\"/)?.[1] || '0');\n\n return {\n type: 'circle',\n data: { cx, cy, r }\n };\n }\n\n return null;\n}\n\n/**\n * Normalize coordinates from display space to image native resolution\n */\nexport function normalizeCoordinates(\n point: Point,\n displayWidth: number,\n displayHeight: number,\n imageWidth: number,\n imageHeight: number\n): Point {\n return {\n x: (point.x / displayWidth) * imageWidth,\n y: (point.y / displayHeight) * imageHeight\n };\n}\n\n/**\n * Scale entire SVG selector from display space to image native resolution\n */\nexport function scaleSvgToNative(\n svg: string,\n displayWidth: number,\n displayHeight: number,\n imageWidth: number,\n imageHeight: number\n): string {\n const parsed = parseSvgSelector(svg);\n if (!parsed) return svg;\n\n const scaleX = imageWidth / displayWidth;\n const scaleY = imageHeight / displayHeight;\n\n switch (parsed.type) {\n case 'rect': {\n const { x, y, width, height } = parsed.data;\n return createRectangleSvg(\n { x: x * scaleX, y: y * scaleY },\n { x: (x + width) * scaleX, y: (y + height) * scaleY }\n );\n }\n\n case 'circle': {\n const { cx, cy, r } = parsed.data;\n return createCircleSvg(\n { x: cx * scaleX, y: cy * scaleY },\n r * Math.min(scaleX, scaleY)\n );\n }\n\n case 'polygon': {\n const points = parsed.data.points.map((p: Point) => ({\n x: p.x * scaleX,\n y: p.y * scaleY\n }));\n return createPolygonSvg(points);\n }\n }\n\n return svg;\n}\n","/**\n * Selector reconciliation for write-time annotation construction.\n *\n * LLM-produced text offsets are guides, not authoritative anchors.\n * `reconcileSelector` takes whatever the LLM emitted and produces a\n * `TextQuoteSelector`-equivalent `start`/`end`/`exact`/`prefix`/`suffix`\n * that is provably consistent with the source content:\n *\n * - `content.substring(start, end) === exact`\n * - `content.substring(start - prefix.length, start) === prefix`\n * - `content.substring(end, end + suffix.length) === suffix`\n *\n * No caller spreads LLM-emitted prefix/suffix into the stored selector.\n * The shared helper extracts both from source at the corrected position,\n * so the no-overlap invariant holds by construction.\n *\n * Returns `null` when the LLM emitted text that doesn't appear in the\n * source. Callers filter; the helper doesn't decide for them.\n *\n * @see https://www.w3.org/TR/annotation-model/#text-quote-selector\n */\n\nimport { findBestTextMatch, buildContentCache, type MatchQuality } from './fuzzy-anchor';\n\n/**\n * How the reconciliation arrived at the chosen offset. Carried into the\n * worker log so operators can audit ambiguous matches; the\n * `first-of-many` flag, in particular, is the signal that an annotation\n * *may* be anchored at the wrong occurrence and warrants review.\n */\nexport type AnchorMethod =\n /** Exact text appears once in the source — anchored unambiguously. */\n | 'unique-match'\n /** Multiple occurrences; LLM-emitted prefix/suffix picked one. */\n | 'context-recovered'\n /** Exact text not found verbatim; fuzzy match recovered it. */\n | 'fuzzy-match'\n /** Multiple occurrences, no context disambiguated — risky fallback. */\n | 'first-of-many';\n\nexport interface ReconciledSelector {\n start: number;\n end: number;\n /** Always a substring of the source content — never the LLM's emission. */\n exact: string;\n /** Extracted from source via extractContext — never the LLM's emission. */\n prefix?: string;\n /** Extracted from source via extractContext — never the LLM's emission. */\n suffix?: string;\n anchorMethod: AnchorMethod;\n /** Present when the fuzzy fallback recovered the match, naming how. */\n matchQuality?: MatchQuality;\n}\n\nexport interface LlmSelectorInput {\n exact: string;\n /** LLM-emitted context for disambiguation only — not for storage. */\n prefix?: string;\n /** LLM-emitted context for disambiguation only — not for storage. */\n suffix?: string;\n}\n\nconst CONTEXT_LENGTH = 64;\nconst MAX_EXTENSION = 32;\n// Minimum window of source text compared against an LLM-emitted prefix/suffix\n// when disambiguating multiple occurrences. The actual window grows to the\n// length of the LLM's prefix/suffix when that's longer — the prompts invite\n// up to 64 chars, and a fixed 32-char window can't `endsWith`/`includes` a\n// 64-char string, which would silently defeat disambiguation for exactly the\n// long, distinctive contexts that disambiguate best.\nconst DISAMBIGUATION_MIN_WINDOW = 32;\n\n/**\n * Extract prefix and suffix context for a `TextQuoteSelector` from\n * source content. Used internally by `reconcileSelector` after offsets\n * are reconciled, and exported for callers (e.g. UI-side selection\n * capture) that need the same extraction semantics.\n *\n * Extracts up to 64 characters before and after the selected text,\n * extending up to 32 additional chars to reach a word boundary so the\n * prefix/suffix is meaningful context rather than mid-word fragments.\n */\nexport function extractContext(\n content: string,\n start: number,\n end: number,\n): { prefix?: string; suffix?: string } {\n const result: { prefix?: string; suffix?: string } = {};\n\n if (start > 0) {\n let prefixStart = Math.max(0, start - CONTEXT_LENGTH);\n let extensionCount = 0;\n while (prefixStart > 0 && extensionCount < MAX_EXTENSION) {\n const char = content[prefixStart - 1];\n if (!char || /[\\s.,;:!?'\"()\\[\\]{}<>\\/\\\\]/.test(char)) break;\n prefixStart--;\n extensionCount++;\n }\n result.prefix = content.substring(prefixStart, start);\n }\n\n if (end < content.length) {\n let suffixEnd = Math.min(content.length, end + CONTEXT_LENGTH);\n let extensionCount = 0;\n while (suffixEnd < content.length && extensionCount < MAX_EXTENSION) {\n const char = content[suffixEnd];\n if (!char || /[\\s.,;:!?'\"()\\[\\]{}<>\\/\\\\]/.test(char)) break;\n suffixEnd++;\n extensionCount++;\n }\n result.suffix = content.substring(end, suffixEnd);\n }\n\n return result;\n}\n\n/**\n * Reconcile LLM-emitted offsets against the source. Returns a selector\n * whose `start`/`end` are verified to bracket `exact` in `content`, and\n * whose `prefix`/`suffix` are extracted from source — never carried\n * verbatim from the LLM.\n *\n * Returns `null` if `exact` cannot be found anywhere in the content,\n * even via fuzzy match. Callers filter null and log the drop.\n */\nexport function reconcileSelector(\n content: string,\n llm: LlmSelectorInput,\n): ReconciledSelector | null {\n const { exact, prefix: llmPrefix, suffix: llmSuffix } = llm;\n if (!exact) return null;\n\n // Find all verbatim occurrences.\n const occurrences: number[] = [];\n let i = content.indexOf(exact);\n while (i !== -1) {\n occurrences.push(i);\n i = content.indexOf(exact, i + 1);\n }\n\n if (occurrences.length === 1) {\n const start = occurrences[0]!;\n const end = start + exact.length;\n const ctx = extractContext(content, start, end);\n return {\n start,\n end,\n exact,\n ...(ctx.prefix !== undefined ? { prefix: ctx.prefix } : {}),\n ...(ctx.suffix !== undefined ? { suffix: ctx.suffix } : {}),\n anchorMethod: 'unique-match',\n };\n }\n\n if (occurrences.length > 1) {\n // Disambiguate via LLM-emitted prefix/suffix when present. Size the\n // comparison window to the LLM's prefix/suffix (with a floor), so a\n // 64-char prefix is matched against ≥64 chars of source — a fixed\n // smaller window can't `endsWith`/`includes` a longer LLM string.\n if (llmPrefix || llmSuffix) {\n const prefixWindow = Math.max(DISAMBIGUATION_MIN_WINDOW, llmPrefix?.length ?? 0);\n const suffixWindow = Math.max(DISAMBIGUATION_MIN_WINDOW, llmSuffix?.length ?? 0);\n for (const pos of occurrences) {\n const candPrefix = content.substring(Math.max(0, pos - prefixWindow), pos);\n const candSuffix = content.substring(\n pos + exact.length,\n Math.min(content.length, pos + exact.length + suffixWindow),\n );\n const prefixOk = !llmPrefix || candPrefix.endsWith(llmPrefix) || candPrefix.includes(llmPrefix.trim());\n const suffixOk = !llmSuffix || candSuffix.startsWith(llmSuffix) || candSuffix.includes(llmSuffix.trim());\n if (prefixOk && suffixOk) {\n const start = pos;\n const end = start + exact.length;\n const ctx = extractContext(content, start, end);\n return {\n start,\n end,\n exact,\n ...(ctx.prefix !== undefined ? { prefix: ctx.prefix } : {}),\n ...(ctx.suffix !== undefined ? { suffix: ctx.suffix } : {}),\n anchorMethod: 'context-recovered',\n };\n }\n }\n }\n\n // No context match. Fall back to the first occurrence and flag for\n // audit. Without an LLM-emitted locality hint there's no better\n // signal at this stage; `first-of-many` callers should log loudly so\n // operators can correct misanchored annotations.\n const start = occurrences[0]!;\n const end = start + exact.length;\n const ctx = extractContext(content, start, end);\n return {\n start,\n end,\n exact,\n ...(ctx.prefix !== undefined ? { prefix: ctx.prefix } : {}),\n ...(ctx.suffix !== undefined ? { suffix: ctx.suffix } : {}),\n anchorMethod: 'first-of-many',\n };\n }\n\n // No verbatim occurrences. Try fuzzy match (case-insensitive,\n // whitespace-normalized, Levenshtein with 5% tolerance). No position\n // hint to bias the search — fuzzy match scans content globally.\n const cache = buildContentCache(content);\n const fuzzy = findBestTextMatch(content, exact, undefined, cache);\n if (!fuzzy) return null;\n\n const actual = content.substring(fuzzy.start, fuzzy.end);\n const ctx = extractContext(content, fuzzy.start, fuzzy.end);\n return {\n start: fuzzy.start,\n end: fuzzy.end,\n // Use the actual source text, not the LLM's version — the LLM may\n // have emitted slightly different characters (smart vs straight\n // quotes, etc.) and we store what's verifiable.\n exact: actual,\n ...(ctx.prefix !== undefined ? { prefix: ctx.prefix } : {}),\n ...(ctx.suffix !== undefined ? { suffix: ctx.suffix } : {}),\n anchorMethod: 'fuzzy-match',\n matchQuality: fuzzy.matchQuality,\n };\n}\n","/**\n * Text encoding utilities for consistent charset handling\n *\n * Ensures frontend decoding matches backend decoding by respecting\n * charset parameters in mediaType (e.g., \"text/plain; charset=iso-8859-1\")\n */\n\n/**\n * Extract charset from mediaType parameter\n *\n * @param mediaType - Media type with optional charset (e.g., \"text/plain; charset=utf-8\")\n * @returns Charset name in lowercase (defaults to \"utf-8\")\n *\n * @example\n * extractCharset(\"text/plain; charset=iso-8859-1\") // \"iso-8859-1\"\n * extractCharset(\"text/plain\") // \"utf-8\"\n */\nexport function extractCharset(mediaType: string): string {\n const charsetMatch = mediaType.match(/charset=([^\\s;]+)/i);\n return (charsetMatch?.[1] || 'utf-8').toLowerCase();\n}\n\n/**\n * Decode ArrayBuffer to string using charset from mediaType\n *\n * Uses TextDecoder with the charset extracted from mediaType parameter.\n * This ensures the same character space is used for both annotation creation\n * (backend) and rendering (frontend).\n *\n * @param buffer - Binary data to decode\n * @param mediaType - Media type with optional charset parameter\n * @returns Decoded string in the original character space\n *\n * @example\n * const buffer = new Uint8Array([...]);\n * const text = decodeWithCharset(buffer, \"text/plain; charset=iso-8859-1\");\n */\nexport function decodeWithCharset(buffer: ArrayBuffer, mediaType: string): string {\n const charset = extractCharset(mediaType);\n\n // TextDecoder supports standard charset names\n // Common mappings that work in browsers:\n // - utf-8, utf-16, utf-16le, utf-16be\n // - iso-8859-1 through iso-8859-15\n // - windows-1252, windows-1251, etc.\n const decoder = new TextDecoder(charset);\n return decoder.decode(buffer);\n}\n","/**\n * Generic validation utilities for @semiont/http-transport\n *\n * Pure TypeScript validation with no external dependencies.\n * Safe to use in any JavaScript environment (Node.js, browser, Deno, etc.)\n */\n\n/**\n * Validation result types\n */\nexport type ValidationSuccess<T> = { success: true; data: T };\nexport type ValidationFailure = { success: false; error: string; details?: string[] };\nexport type ValidationResult<T> = ValidationSuccess<T> | ValidationFailure;\n\n/**\n * JWT Token validation\n *\n * Validates JWT token format (header.payload.signature).\n * Does not verify signature - use for format validation only.\n */\nexport const JWTTokenSchema = {\n parse(token: unknown): string {\n if (typeof token !== 'string') {\n throw new Error('Token must be a string');\n }\n if (!token || token.length === 0) {\n throw new Error('Token is required');\n }\n // JWT format: header.payload.signature\n const jwtRegex = /^[A-Za-z0-9\\-_]+\\.[A-Za-z0-9\\-_]+\\.[A-Za-z0-9\\-_]*$/;\n if (!jwtRegex.test(token)) {\n throw new Error('Invalid JWT token format');\n }\n return token;\n },\n\n safeParse(token: unknown): ValidationResult<string> {\n try {\n const validated = this.parse(token);\n return { success: true, data: validated };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Invalid JWT token',\n };\n }\n },\n};\n\n/**\n * Generic validation helper with error formatting\n *\n * Wraps any schema's parse method with try/catch and returns ValidationResult.\n *\n * @example\n * ```typescript\n * const result = validateData(JWTTokenSchema, 'eyJ...');\n * if (result.success) {\n * console.log('Valid token:', result.data);\n * } else {\n * console.error('Invalid:', result.error);\n * }\n * ```\n */\nexport function validateData<T>(\n schema: { parse(data: unknown): T },\n data: unknown\n): ValidationResult<T> {\n try {\n const validated = schema.parse(data);\n return { success: true, data: validated };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Validation failed',\n };\n }\n}\n\n/**\n * Email validation helper\n *\n * Validates email format using RFC 5322 simplified regex.\n *\n * @param email - Email address to validate\n * @returns true if valid email format\n */\nexport function isValidEmail(email: string): boolean {\n if (email.length < 1 || email.length > 255) {\n return false;\n }\n // RFC 5322 simplified email regex\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n return emailRegex.test(email);\n}\n","/**\n * Media-type registry for Semiont\n *\n * One supported-types list, capability-tiered, keyed by the spec's\n * SupportedMediaType enum. Admission (registry membership) is the\n * create/yield gate: every member is storable, nameable, and uploadable.\n * The curated capabilities say what more the system can do with a type:\n *\n * - `render` — which viewer the UI mounts ('none' → metadata + download)\n * - `anchoring` — which annotation model applies: character-offset text\n * selectors vs spatial geometry (PDFs are spatial)\n * - `extractText` — how the Smelter gets embeddable text ('none' → skip\n * embedding, never mojibake)\n * - `authorable` — offered in the compose editor's format dropdown\n * - `uploadable` — big tent: true for every registry member\n *\n * Capabilities are orthogonal strategies, not a ladder: images render but\n * yield no text; PDFs yield text but aren't authorable. A \"tier\" is a\n * derived reading, not a stored fact.\n *\n * Import-leniency invariant: restore/import preserves archive mediaTypes\n * verbatim, so \"every stored mediaType is registry-valid\" holds only for\n * content that entered through the validated create/yield gate. No code\n * reading a stored mediaType may assume `capabilitiesOf()` succeeds — the\n * `undefined` branch is mandatory wherever stored types are read.\n */\n\nimport type { components } from './types';\n\nexport type SupportedMediaType = components['schemas']['SupportedMediaType'];\n\nexport type RenderMode = 'text' | 'image' | 'pdf' | 'none';\nexport type AnchoringModel = 'text-selector' | 'spatial' | 'none';\nexport type TextExtraction = 'decode' | 'pdf-text-layer' | 'none';\n\nexport interface MediaTypeCapabilities {\n /** Canonical file extension, with leading dot. */\n extension: `.${string}`;\n /** UI display name. */\n label: string;\n render: RenderMode;\n anchoring: AnchoringModel;\n extractText: TextExtraction;\n authorable: boolean;\n uploadable: boolean;\n}\n\n/** Storage tier: catalogued — stored, named, uploadable — but not\n * displayed or annotated. */\nconst storedBinary = (extension: `.${string}`, label: string): MediaTypeCapabilities => ({\n extension,\n label,\n render: 'none',\n anchoring: 'none',\n extractText: 'none',\n authorable: false,\n uploadable: true,\n});\n\n/** Storage tier, text-flavored: embedded (charset-aware decode), not rendered. */\nconst storedText = (extension: `.${string}`, label: string): MediaTypeCapabilities => ({\n ...storedBinary(extension, label),\n extractText: 'decode',\n});\n\n/**\n * The registry. `satisfies Record<SupportedMediaType, …>` is the\n * drift-lock: adding a type to the spec enum without a capabilities row\n * (or vice versa) is a compile error.\n *\n * Row order matters for `mediaTypeForExtension`: extension collisions\n * (.xml, .yaml, .js, .ts, .webm) resolve to the first row declaring the\n * extension.\n */\nexport const MEDIA_TYPES = {\n // Full-capability tier\n 'text/markdown': { extension: '.md', label: 'Markdown', render: 'text', anchoring: 'text-selector', extractText: 'decode', authorable: true, uploadable: true },\n 'text/plain': { extension: '.txt', label: 'Plain Text', render: 'text', anchoring: 'text-selector', extractText: 'decode', authorable: true, uploadable: true },\n 'text/html': { extension: '.html', label: 'HTML', render: 'text', anchoring: 'text-selector', extractText: 'decode', authorable: true, uploadable: true },\n 'application/json': { extension: '.json', label: 'JSON', render: 'text', anchoring: 'text-selector', extractText: 'decode', authorable: false, uploadable: true },\n 'image/png': { extension: '.png', label: 'PNG image', render: 'image', anchoring: 'spatial', extractText: 'none', authorable: false, uploadable: true },\n 'image/jpeg': { extension: '.jpg', label: 'JPEG image', render: 'image', anchoring: 'spatial', extractText: 'none', authorable: false, uploadable: true },\n 'application/pdf': { extension: '.pdf', label: 'PDF', render: 'pdf', anchoring: 'spatial', extractText: 'pdf-text-layer', authorable: false, uploadable: true },\n\n // Storage tier — the big tent. Every row is a deliberate admission,\n // promotable by editing its row. Text-flavored rows embed (decode).\n\n // Text\n 'text/css': storedText('.css', 'CSS'),\n 'text/csv': storedText('.csv', 'CSV'),\n 'text/xml': storedText('.xml', 'XML'),\n\n // Structured-text application formats\n 'application/xml': storedText('.xml', 'XML'),\n 'application/yaml': storedText('.yaml', 'YAML'),\n 'application/x-yaml': storedText('.yaml', 'YAML'),\n\n // Programming languages\n 'text/javascript': storedText('.js', 'JavaScript'),\n 'application/javascript': storedText('.js', 'JavaScript'),\n 'text/x-typescript': storedText('.ts', 'TypeScript'),\n 'application/typescript': storedText('.ts', 'TypeScript'),\n 'text/x-python': storedText('.py', 'Python source'),\n 'text/x-java': storedText('.java', 'Java source'),\n 'text/x-c': storedText('.c', 'C source'),\n 'text/x-c++': storedText('.cpp', 'C++ source'),\n 'text/x-csharp': storedText('.cs', 'C# source'),\n 'text/x-go': storedText('.go', 'Go source'),\n 'text/x-rust': storedText('.rs', 'Rust source'),\n 'text/x-ruby': storedText('.rb', 'Ruby source'),\n 'text/x-php': storedText('.php', 'PHP source'),\n 'text/x-swift': storedText('.swift', 'Swift source'),\n 'text/x-kotlin': storedText('.kt', 'Kotlin source'),\n 'text/x-shell': storedText('.sh', 'Shell script'),\n\n // Documents\n 'application/msword': storedBinary('.doc', 'Word document (legacy)'),\n 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': storedBinary('.docx', 'Word document'),\n 'application/vnd.ms-excel': storedBinary('.xls', 'Excel spreadsheet (legacy)'),\n 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': storedBinary('.xlsx', 'Excel spreadsheet'),\n 'application/vnd.ms-powerpoint': storedBinary('.ppt', 'PowerPoint presentation (legacy)'),\n 'application/vnd.openxmlformats-officedocument.presentationml.presentation': storedBinary('.pptx', 'PowerPoint presentation'),\n\n // Archives\n 'application/zip': storedBinary('.zip', 'ZIP archive'),\n 'application/gzip': storedBinary('.gz', 'Gzip archive'),\n 'application/x-tar': storedBinary('.tar', 'TAR archive'),\n 'application/x-7z-compressed': storedBinary('.7z', '7z archive'),\n\n // Binaries\n 'application/octet-stream': storedBinary('.bin', 'Binary'),\n 'application/wasm': storedBinary('.wasm', 'WebAssembly module'),\n\n // Images beyond the rendered pair\n 'image/gif': storedBinary('.gif', 'GIF image'),\n 'image/webp': storedBinary('.webp', 'WebP image'),\n 'image/svg+xml': storedBinary('.svg', 'SVG image'),\n 'image/bmp': storedBinary('.bmp', 'BMP image'),\n 'image/tiff': storedBinary('.tiff', 'TIFF image'),\n 'image/x-icon': storedBinary('.ico', 'Icon'),\n\n // Video (before audio so .webm resolves to video)\n 'video/mp4': storedBinary('.mp4', 'MP4 video'),\n 'video/mpeg': storedBinary('.mpeg', 'MPEG video'),\n 'video/webm': storedBinary('.webm', 'WebM video'),\n 'video/ogg': storedBinary('.ogv', 'Ogg video'),\n 'video/quicktime': storedBinary('.mov', 'QuickTime video'),\n 'video/x-msvideo': storedBinary('.avi', 'AVI video'),\n\n // Audio\n 'audio/mpeg': storedBinary('.mp3', 'MP3 audio'),\n 'audio/wav': storedBinary('.wav', 'WAV audio'),\n 'audio/ogg': storedBinary('.ogg', 'Ogg audio'),\n 'audio/webm': storedBinary('.webm', 'WebM audio'),\n 'audio/aac': storedBinary('.aac', 'AAC audio'),\n 'audio/flac': storedBinary('.flac', 'FLAC audio'),\n\n // Fonts\n 'font/woff': storedBinary('.woff', 'WOFF font'),\n 'font/woff2': storedBinary('.woff2', 'WOFF2 font'),\n 'font/ttf': storedBinary('.ttf', 'TrueType font'),\n 'font/otf': storedBinary('.otf', 'OpenType font'),\n} satisfies Record<SupportedMediaType, MediaTypeCapabilities>;\n\n// String-indexable view for lookups with runtime strings.\nconst REGISTRY: Readonly<Record<string, MediaTypeCapabilities>> = MEDIA_TYPES;\n\n/**\n * Strip parameters (\"; charset=...\") and normalize case.\n * Replaces the inline `split(';')[0]` sites across the codebase.\n */\nexport function baseMediaType(format: string): string {\n return format.split(';')[0]!.trim().toLowerCase();\n}\n\n/**\n * Registry membership — the admission gate. Exact match: callers pass a\n * base type (see `baseMediaType`); strings carrying parameters are not\n * members.\n */\nexport function isSupportedMediaType(format: string): format is SupportedMediaType {\n return Object.hasOwn(MEDIA_TYPES, format);\n}\n\n/** Capabilities for a format (parameters tolerated), or undefined on registry miss. */\nexport function capabilitiesOf(format: string): MediaTypeCapabilities | undefined {\n return REGISTRY[baseMediaType(format)];\n}\n\n/**\n * Lenient extension lookup for naming foreign/imported content: '.dat' on\n * registry miss. Exporters use this — a vocabulary change must never\n * refuse to name restored data.\n */\nexport function extensionForMediaType(format: string): string {\n return capabilitiesOf(format)?.extension ?? '.dat';\n}\n\nconst EXTENSION_TO_MEDIA_TYPE: ReadonlyMap<string, SupportedMediaType> = (() => {\n const map = new Map<string, SupportedMediaType>();\n for (const type of Object.keys(MEDIA_TYPES) as SupportedMediaType[]) {\n const ext = MEDIA_TYPES[type].extension;\n if (!map.has(ext)) map.set(ext, type);\n }\n return map;\n})();\n\n/** Alternate spellings accepted by `mediaTypeForExtension`, mapped to\n * canonical registry extensions. */\nconst EXTENSION_ALIASES: Readonly<Record<string, string>> = {\n '.markdown': '.md',\n '.htm': '.html',\n '.jpeg': '.jpg',\n '.yml': '.yaml',\n};\n\n/**\n * Inverted registry: extension → media type, for the CLI and the upload\n * detection chain. Accepts 'md' or '.md', any case, and common alternate\n * spellings. Returns undefined for unknown extensions — detection chains\n * fall back to 'application/octet-stream' themselves.\n */\nexport function mediaTypeForExtension(ext: string): SupportedMediaType | undefined {\n const lower = ext.trim().toLowerCase();\n const dotted = lower.startsWith('.') ? lower : `.${lower}`;\n return EXTENSION_TO_MEDIA_TYPE.get(EXTENSION_ALIASES[dotted] ?? dotted);\n}\n\n/**\n * The Smelter's gate: how to get embeddable text from a format. Registry\n * rows answer directly; on a registry miss, base types under text/* decode\n * (RFC 2046 guarantees the text top-level type is textual — imported\n * unregistered text subtypes embed too), everything else is 'none'.\n */\nexport function textExtractionOf(format: string): TextExtraction {\n const caps = capabilitiesOf(format);\n if (caps) return caps.extractText;\n return baseMediaType(format).startsWith('text/') ? 'decode' : 'none';\n}\n\nconst REGISTRY_KEYS = Object.keys(MEDIA_TYPES) as SupportedMediaType[];\n\n/** Types offered in the compose editor's format dropdown. */\nexport const AUTHORABLE_MEDIA_TYPES: readonly SupportedMediaType[] = REGISTRY_KEYS.filter(\n (type) => MEDIA_TYPES[type].authorable,\n);\n\n/** Registry rows whose text the Smelter can extract. Rows only — the\n * text/* fallback in `textExtractionOf` isn't enumerable. */\nexport const EMBEDDABLE_MEDIA_TYPES: readonly SupportedMediaType[] = REGISTRY_KEYS.filter(\n (type) => MEDIA_TYPES[type].extractText !== 'none',\n);\n","/**\n * Common type guard utilities\n */\n\n/**\n * Check if value is a string\n */\nexport function isString(value: unknown): value is string {\n return typeof value === 'string';\n}\n\n/**\n * Check if value is a number (not NaN)\n */\nexport function isNumber(value: unknown): value is number {\n return typeof value === 'number' && !isNaN(value);\n}\n\n/**\n * Check if value is an object (not null, not array)\n */\nexport function isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/**\n * Check if value is an array\n */\nexport function isArray(value: unknown): value is unknown[] {\n return Array.isArray(value);\n}\n\n/**\n * Check if value is a boolean\n */\nexport function isBoolean(value: unknown): value is boolean {\n return typeof value === 'boolean';\n}\n\n/**\n * Check if value is a function\n */\nexport function isFunction(value: unknown): value is Function {\n return typeof value === 'function';\n}\n\n/**\n * Check if value is null\n */\nexport function isNull(value: unknown): value is null {\n return value === null;\n}\n\n/**\n * Check if value is undefined\n */\nexport function isUndefined(value: unknown): value is undefined {\n return value === undefined;\n}\n\n/**\n * Check if value is null or undefined\n */\nexport function isNullish(value: unknown): value is null | undefined {\n return value === null || value === undefined;\n}\n\n/**\n * Check if value is defined (not null or undefined)\n */\nexport function isDefined<T>(value: T | null | undefined): value is T {\n return value !== null && value !== undefined;\n}","/**\n * Common error classes — the unified Semiont error hierarchy.\n *\n * `SemiontError` is the base every other Semiont error class extends:\n * `APIError` (http-transport), `BusRequestError` and `SemiontSessionError` (sdk),\n * `ValidationError`, `ScriptError`, `NotFoundError`, `UnauthorizedError`,\n * `ConflictError` (here), and `AWSError` (cli). Subclasses tighten the\n * `code` field to a literal-union for discriminated handling.\n */\n\n/**\n * Transport-neutral error vocabulary. Every transport that surfaces\n * errors over `ITransport.errors$` maps its native failure modes to one\n * of these codes — HTTP `APIError` maps from status code, in-process\n * transports map from local failure shape, gRPC would map from status\n * code, etc. Routing layers (e.g. `SemiontBrowser`'s session-expired /\n * permission-denied modal routing) match on this vocabulary so they\n * stay transport-agnostic.\n *\n * - `unauthorized` — auth required / token missing or expired (HTTP 401)\n * - `forbidden` — auth ok but lacks permission (HTTP 403)\n * - `not-found` — resource missing (HTTP 404)\n * - `conflict` — concurrent modification, duplicate, etc. (HTTP 409)\n * - `bad-request` — request malformed (HTTP 400)\n * - `unavailable` — backend unreachable, network error, 5xx\n * - `error` — unclassified fallback\n */\nexport type TransportErrorCode =\n | 'unauthorized'\n | 'forbidden'\n | 'not-found'\n | 'conflict'\n | 'bad-request'\n | 'unavailable'\n | 'error';\n\nexport class SemiontError extends Error {\n constructor(\n message: string,\n public code: string,\n public details?: Record<string, unknown>,\n ) {\n super(message);\n this.name = 'SemiontError';\n Error.captureStackTrace(this, this.constructor);\n }\n}\n\nexport class ValidationError extends SemiontError {\n constructor(message: string, details?: Record<string, unknown>) {\n super(message, 'VALIDATION_ERROR', details);\n this.name = 'ValidationError';\n }\n}\n\nexport class ScriptError extends SemiontError {\n constructor(message: string, code: string = 'SCRIPT_ERROR', details?: Record<string, unknown>) {\n super(message, code, details);\n this.name = 'ScriptError';\n }\n}\n\nexport class NotFoundError extends SemiontError {\n constructor(resource: string, id?: string) {\n const message = id ? `${resource} with id '${id}' not found` : `${resource} not found`;\n super(message, 'NOT_FOUND', { resource, id });\n this.name = 'NotFoundError';\n }\n}\n\nexport class UnauthorizedError extends SemiontError {\n constructor(message: string = 'Unauthorized', details?: Record<string, unknown>) {\n super(message, 'UNAUTHORIZED', details);\n this.name = 'UnauthorizedError';\n }\n}\n\nexport class ConflictError extends SemiontError {\n constructor(message: string, details?: Record<string, unknown>) {\n super(message, 'CONFLICT', details);\n this.name = 'ConflictError';\n }\n}\n","/**\n * DID (Decentralized Identifier) and W3C Agent utilities\n *\n * DID:WEB shapes used in Semiont:\n *\n * Person: did:web:<host>:users:<email%40host>\n * Software: did:web:<host>:agents:<provider>:<model>\n *\n * `didToAgent` is the inverse: parse the DID, recognize whether the\n * subject is a person or a software peer, and return a typed Agent.\n *\n * Humans and software peers share the same identity *shape* (a DID\n * with a typed Agent on read). What differs is the path segment\n * (`:users:` vs `:agents:`) and the schema-typed fields each kind\n * carries on its Agent record.\n */\n\nimport type { components } from './types';\n\ntype Agent = components['schemas']['Agent'];\n\n/**\n * Convert a user object to a DID:WEB identifier.\n *\n * Format: did:web:<domain>:users:<email%40domain>\n */\nexport function userToDid(user: { email: string; domain: string }): string {\n return `did:web:${user.domain}:users:${encodeURIComponent(user.email)}`;\n}\n\n/**\n * Convert a software peer's (provider, model) configuration to a DID:WEB\n * identifier. Pool-vs-individual deployment is not part of identity —\n * one DID per (provider, model) on this host.\n *\n * Format: did:web:<domain>:agents:<provider>:<model%2F-encoded>\n *\n * Model strings often contain `:` and `/` (e.g. `gemma2:27b`,\n * `library/llama3`); both must be URI-encoded so DID parsing isn't\n * ambiguous.\n */\nexport function agentToDid(agent: { domain: string; provider: string; model: string }): string {\n return `did:web:${agent.domain}:agents:${encodeURIComponent(agent.provider)}:${encodeURIComponent(agent.model)}`;\n}\n\n/**\n * Convert a user object to a typed Person Agent with a DID:WEB identifier.\n */\nexport function userToAgent(user: {\n id: string;\n domain: string;\n name: string | null;\n email: string;\n}): Agent {\n return {\n '@type': 'Person',\n '@id': userToDid(user),\n name: user.name || user.email,\n };\n}\n\n/**\n * Convert a software peer's configuration to a typed Software Agent.\n * The `name` is a stable human-friendly label, not a parseable join —\n * UI composes display from `provider`/`model` at render time.\n */\nexport function softwareToAgent(software: {\n domain: string;\n provider: string;\n model: string;\n parameters?: Record<string, unknown>;\n}): Agent {\n return {\n '@type': 'Software',\n '@id': agentToDid(software),\n name: `${software.provider} ${software.model}`,\n provider: software.provider,\n model: software.model,\n ...(software.parameters && { parameters: software.parameters }),\n };\n}\n\n/**\n * Parse a DID:WEB string into a typed Agent.\n *\n * Recognizes:\n * did:web:<host>:users:<email> → Person (name = decoded email)\n * did:web:<host>:agents:<provider>:<model> → Software (provider + model)\n *\n * Anything else falls back to a Person with the trailing segment as\n * `name`. This is the read-side inverse of `userToDid`/`agentToDid`.\n */\nexport function didToAgent(did: string | undefined | null): Agent {\n if (!did) {\n return { '@type': 'Person', '@id': 'unknown', name: 'unknown' };\n }\n const parts = did.split(':');\n\n // Find the kind segment, scanning from the right so we are not fooled\n // by `host:port` colons earlier in the string.\n const agentsIdx = parts.lastIndexOf('agents');\n const usersIdx = parts.lastIndexOf('users');\n\n if (agentsIdx >= 0 && agentsIdx === parts.length - 3) {\n const provider = decodeURIComponent(parts[agentsIdx + 1] ?? '');\n const model = decodeURIComponent(parts[agentsIdx + 2] ?? '');\n return {\n '@type': 'Software',\n '@id': did,\n name: `${provider} ${model}`,\n provider,\n model,\n };\n }\n\n if (usersIdx >= 0 && usersIdx === parts.length - 2) {\n const name = decodeURIComponent(parts[usersIdx + 1] ?? '');\n return {\n '@type': 'Person',\n '@id': did,\n name,\n };\n }\n\n // Unknown shape — preserve the DID as @id, derive a best-effort name\n // from the trailing segment. Treat as Person (the safer default for\n // unknown actors).\n const encoded = parts[parts.length - 1] || 'unknown';\n return {\n '@type': 'Person',\n '@id': did,\n name: decodeURIComponent(encoded),\n };\n}\n","/**\n * TOML Config Loader\n *\n * Reads ~/.semiontconfig (TOML) and .semiont/config (TOML) and produces\n * an EnvironmentConfig for the requested environment.\n *\n * File format: see TOML-XDG-CONFIG.md\n *\n * Loading sequence:\n * 1. Read .semiont/config → projectName, site, environments.<env>.* (project base)\n * 2. Read ~/.semiontconfig → defaults, environments.<env>.* (user overrides)\n * 3. Deep-merge: project base ← user overrides (user wins on conflicts)\n * Any environment name is valid (local, staging, production, custom, ...)\n * 4. Resolve ${VAR} references from process.env\n * 5. Apply inheritance: workers.<name> → workers.default → error\n * 6. Map to EnvironmentConfig shape\n */\n\nimport { parse as parseToml } from 'smol-toml';\nimport type { EnvironmentConfig, OllamaProviderConfig, AnthropicProviderConfig } from './config.types';\nimport type { PlatformType } from './config.types';\n\n/**\n * Deep merge two plain objects. Arrays and primitives in `override` replace those in `base`.\n * Nested objects are merged recursively. `override` takes precedence on conflicts.\n */\nfunction deepMerge<T extends Record<string, unknown>>(base: T, override: Partial<T>): T {\n const result = { ...base } as Record<string, unknown>;\n for (const key of Object.keys(override)) {\n const b = base[key];\n const o = override[key];\n if (o !== undefined && o !== null && typeof o === 'object' && !Array.isArray(o) &&\n b !== undefined && b !== null && typeof b === 'object' && !Array.isArray(b)) {\n result[key] = deepMerge(b as Record<string, unknown>, o as Record<string, unknown>);\n } else if (o !== undefined) {\n result[key] = o;\n }\n }\n return result as T;\n}\n\nfunction resolveEnvVars(obj: unknown, env: Record<string, string | undefined>): unknown {\n if (typeof obj === 'string') {\n return obj.replace(/\\$\\{([^}]+)\\}/g, (match, expr: string) => {\n const sepIdx = expr.indexOf(':-');\n const varName = sepIdx >= 0 ? expr.slice(0, sepIdx) : expr;\n const defaultValue = sepIdx >= 0 ? expr.slice(sepIdx + 2) : undefined;\n const value = env[varName];\n if (value !== undefined) return value;\n if (defaultValue !== undefined) return defaultValue;\n throw new Error(`Environment variable ${varName} is not set (referenced in config as ${match})`);\n });\n }\n if (Array.isArray(obj)) {\n return obj.map(item => resolveEnvVars(item, env));\n }\n if (obj !== null && typeof obj === 'object') {\n const resolved: Record<string, unknown> = {};\n for (const key in obj as Record<string, unknown>) {\n resolved[key] = resolveEnvVars((obj as Record<string, unknown>)[key], env);\n }\n return resolved;\n }\n return obj;\n}\n\n// ── Inference config types (mirrored from packages/make-meaning/src/config.ts) ─\n// Kept here to avoid a circular dependency: core cannot import make-meaning.\n\nexport interface InferenceConfig {\n type: 'anthropic' | 'ollama';\n model: string;\n maxTokens?: number;\n apiKey?: string;\n endpoint?: string;\n baseURL?: string;\n}\n\nexport interface ActorInferenceConfig {\n gatherer?: InferenceConfig;\n matcher?: InferenceConfig;\n}\n\nexport interface WorkerInferenceConfig {\n default?: InferenceConfig;\n 'reference-annotation'?: InferenceConfig;\n 'highlight-annotation'?: InferenceConfig;\n 'assessment-annotation'?: InferenceConfig;\n 'comment-annotation'?: InferenceConfig;\n 'tag-annotation'?: InferenceConfig;\n 'generation'?: InferenceConfig;\n}\n\n// ── Types for ~/.semiontconfig ────────────────────────────────────────────────\n\ninterface SemiontConfigFile {\n user?: {\n name?: string;\n email?: string;\n };\n defaults?: {\n environment?: string;\n platform?: string;\n };\n environments?: Record<string, EnvironmentSection>;\n}\n\ninterface GraphSection {\n platform?: string;\n type?: string;\n name?: string;\n uri?: string;\n username?: string;\n password?: string;\n database?: string;\n [key: string]: unknown;\n}\n\ninterface InferenceFlatSection {\n // Flat (single-provider) format: type = \"anthropic\"|\"ollama\" at this level\n type?: 'anthropic' | 'ollama';\n platform?: string;\n model?: string;\n maxTokens?: number;\n apiKey?: string;\n endpoint?: string;\n baseURL?: string;\n // Keyed (multi-provider) format: [inference.anthropic] / [inference.ollama]\n anthropic?: { platform?: string; apiKey?: string; endpoint?: string };\n ollama?: { platform?: string; baseURL?: string; port?: number };\n}\n\ninterface EnvironmentSection {\n backend?: {\n platform?: string;\n port?: number;\n publicURL?: string;\n frontendURL?: string;\n };\n frontend?: {\n platform?: string;\n port?: number;\n publicURL?: string;\n };\n site?: {\n domain?: string;\n siteName?: string;\n adminEmail?: string;\n oauthAllowedDomains?: string[];\n enableLocalAuth?: boolean;\n };\n database?: {\n platform?: string;\n image?: string;\n host?: string;\n port?: number;\n name?: string;\n user?: string;\n password?: string;\n };\n graph?: GraphSection;\n vectors?: {\n type?: 'qdrant' | 'memory';\n host?: string;\n port?: number;\n // Legacy: embedding nested under vectors (migrated to top-level)\n embedding?: {\n type?: 'voyage' | 'ollama';\n model?: string;\n apiKey?: string;\n baseURL?: string;\n endpoint?: string;\n };\n chunking?: {\n chunkSize?: number;\n overlap?: number;\n };\n };\n embedding?: {\n type?: 'voyage' | 'ollama';\n model?: string;\n apiKey?: string;\n baseURL?: string;\n endpoint?: string;\n chunking?: {\n chunkSize?: number;\n overlap?: number;\n };\n };\n inference?: InferenceFlatSection;\n 'make-meaning'?: {\n graph?: Record<string, unknown>;\n actors?: {\n gatherer?: { inference?: InferenceConfig };\n matcher?: { inference?: InferenceConfig };\n };\n default?: { inference?: InferenceConfig };\n };\n workers?: Record<string, { inference?: InferenceConfig }>;\n actors?: Record<string, { inference?: InferenceConfig }>;\n logLevel?: 'error' | 'warn' | 'info' | 'http' | 'debug';\n}\n\n// ── File reader abstraction (same pattern as createConfigLoader) ──────────────\n\nexport type TomlFileReader = {\n readIfExists: (path: string) => string | null;\n};\n\nfunction requirePlatform(value: string | undefined, serviceName: string): PlatformType {\n if (!value) {\n throw new Error(`platform is required for service '${serviceName}' — add 'platform = \"posix\"|\"container\"|\"external\"' to its config section`);\n }\n return value as PlatformType;\n}\n\n// ── Main loader function ──────────────────────────────────────────────────────\n\n/**\n * Parse ~/.semiontconfig and .semiont/config and return EnvironmentConfig.\n *\n * @param projectRoot - Path to the project root (contains .semiont/config)\n * @param environment - Environment name (e.g. 'local', 'production')\n * @param globalConfigPath - Path to ~/.semiontconfig (caller resolves ~ expansion)\n * @param reader - File reader abstraction\n * @param env - Environment variables for ${VAR} resolution\n */\nexport function loadTomlConfig(\n projectRoot: string | null,\n environment: string,\n globalConfigPath: string,\n reader: TomlFileReader,\n env: Record<string, string | undefined>\n): EnvironmentConfig {\n // 1. Read project config from .semiont/config (skipped when no project root)\n const projectConfigContent = projectRoot ? reader.readIfExists(`${projectRoot}/.semiont/config`) : null;\n let projectName = 'semiont-project';\n let projectVersion: string | undefined;\n let projectSite: EnvironmentSection['site'] | undefined;\n let projectEnvSection: EnvironmentSection = {};\n if (projectConfigContent) {\n const projectConfig = parseToml(projectConfigContent) as {\n project?: { name?: string; version?: string };\n site?: EnvironmentSection['site'];\n environments?: Record<string, EnvironmentSection>;\n };\n projectName = projectConfig.project?.name ?? projectName;\n projectVersion = projectConfig.project?.version;\n projectSite = projectConfig.site;\n projectEnvSection = projectConfig.environments?.[environment] ?? {};\n }\n\n // 2. Read global config (optional — missing config yields empty environments)\n const globalContent = reader.readIfExists(globalConfigPath);\n const raw = globalContent ? (parseToml(globalContent) as SemiontConfigFile) : ({} as SemiontConfigFile);\n\n // 3. Deep-merge: project base + user overrides (user wins on conflicts)\n const userEnvSection: EnvironmentSection = raw.environments?.[environment] ?? {};\n const envSection: EnvironmentSection = deepMerge(\n projectEnvSection as Record<string, unknown>,\n userEnvSection as Record<string, unknown>\n ) as EnvironmentSection;\n\n // 4. Resolve ${VAR} references\n const resolved = resolveEnvVars(envSection, env) as EnvironmentSection;\n\n // 5. Build make-meaning actor/worker inference config with inheritance\n // The flat [inference] section provides defaults (apiKey, maxTokens, endpoint/baseURL).\n // Actor/worker sections only need to specify type and model; missing fields fall back\n // to the flat inference section.\n const flatInference = resolved.inference;\n const makeMeaningSection = resolved['make-meaning'];\n const workersSection = resolved.workers ?? {};\n const actorsSection = resolved.actors ?? {};\n const defaultWorkerInference = workersSection['default']?.inference;\n const defaultMakeMeaningInference = makeMeaningSection?.default?.inference;\n\n function mergeWithFlatInference(specific: InferenceConfig): InferenceConfig {\n if (!flatInference) return specific;\n // For keyed sub-sections, inherit credentials from the matching provider sub-section.\n // For flat (legacy) format, flatInference.type is required to know which fields apply.\n const providerDefaults: Partial<InferenceConfig> = {};\n if (specific.type === 'anthropic') {\n const a = flatInference.anthropic;\n if (a) {\n providerDefaults.apiKey = a.apiKey;\n providerDefaults.endpoint = a.endpoint;\n } else {\n if (!flatInference.type) {\n throw new Error(\n `[environments.${environment}.inference] is missing 'type'. ` +\n `Add type = \"anthropic\" or use [inference.anthropic] sub-section.`\n );\n }\n providerDefaults.apiKey = flatInference.apiKey;\n providerDefaults.endpoint = flatInference.endpoint;\n }\n } else if (specific.type === 'ollama') {\n const o = flatInference.ollama;\n if (o) {\n providerDefaults.baseURL = o.baseURL;\n } else {\n if (!flatInference.type) {\n throw new Error(\n `[environments.${environment}.inference] is missing 'type'. ` +\n `Add type = \"ollama\" or use [inference.ollama] sub-section.`\n );\n }\n providerDefaults.baseURL = flatInference.baseURL;\n }\n }\n return {\n maxTokens: flatInference.maxTokens,\n ...providerDefaults,\n ...specific,\n };\n }\n\n function resolveActorInference(fromMakeMeaning?: InferenceConfig, fromActors?: InferenceConfig): InferenceConfig | undefined {\n const base = fromMakeMeaning ?? fromActors ?? defaultMakeMeaningInference;\n if (!base) return undefined;\n return mergeWithFlatInference(base);\n }\n\n const actors: ActorInferenceConfig = {};\n const gathererInference = resolveActorInference(\n makeMeaningSection?.actors?.gatherer?.inference,\n actorsSection['gatherer']?.inference\n );\n if (gathererInference) actors.gatherer = gathererInference;\n\n const matcherInference = resolveActorInference(\n makeMeaningSection?.actors?.matcher?.inference,\n actorsSection['matcher']?.inference\n );\n if (matcherInference) actors.matcher = matcherInference;\n\n const workers: WorkerInferenceConfig = {};\n const workerTypes = ['reference-annotation', 'highlight-annotation', 'assessment-annotation', 'comment-annotation', 'tag-annotation', 'generation'] as const;\n if (defaultWorkerInference) {\n workers.default = mergeWithFlatInference(defaultWorkerInference);\n }\n for (const wt of workerTypes) {\n const specific = workersSection[wt]?.inference;\n if (specific) {\n (workers as Record<string, InferenceConfig>)[wt] = mergeWithFlatInference(specific);\n }\n }\n\n // 6. Map to EnvironmentConfig\n const backend = resolved.backend;\n const site = resolved.site ?? projectSite;\n const inferenceSection = resolved.inference;\n\n // Build inference providers config.\n // Supports two formats:\n // Flat: [environments.local.inference] type = \"anthropic\"|\"ollama\" (single provider)\n // Keyed: [environments.local.inference.anthropic] / [environments.local.inference.ollama] (multi-provider)\n let inferenceProviders: EnvironmentConfig['inference'] | undefined;\n if (inferenceSection) {\n inferenceProviders = {};\n // Keyed sub-sections take priority\n if (inferenceSection.anthropic) {\n const a = inferenceSection.anthropic;\n inferenceProviders.anthropic = {\n platform: requirePlatform(a.platform, 'inference.anthropic'),\n endpoint: a.endpoint ?? 'https://api.anthropic.com',\n apiKey: a.apiKey ?? '',\n } as AnthropicProviderConfig;\n } else if (inferenceSection.type === 'anthropic') {\n inferenceProviders.anthropic = {\n platform: requirePlatform(inferenceSection.platform, 'inference'),\n endpoint: inferenceSection.endpoint ?? 'https://api.anthropic.com',\n apiKey: inferenceSection.apiKey ?? '',\n } as AnthropicProviderConfig;\n }\n if (inferenceSection.ollama) {\n const o = inferenceSection.ollama;\n inferenceProviders.ollama = {\n platform: { type: requirePlatform(o.platform, 'inference.ollama') },\n baseURL: o.baseURL,\n port: o.baseURL ? undefined : (o.port ?? 11434),\n } as OllamaProviderConfig;\n } else if (inferenceSection.type === 'ollama') {\n inferenceProviders.ollama = {\n platform: { type: requirePlatform(inferenceSection.platform, 'inference') },\n baseURL: inferenceSection.baseURL,\n port: inferenceSection.baseURL ? undefined : 11434,\n } as OllamaProviderConfig;\n }\n }\n\n // Build top-level workers/actors maps for EnvironmentConfig\n const topLevelWorkers: EnvironmentConfig['workers'] = {};\n for (const [name, w] of Object.entries(workersSection)) {\n if (w.inference) {\n topLevelWorkers[name] = { inference: { type: w.inference.type, model: w.inference.model } };\n }\n }\n const topLevelActors: EnvironmentConfig['actors'] = {};\n for (const [name, a] of Object.entries(actorsSection)) {\n if (a.inference) {\n topLevelActors[name] = { inference: { type: a.inference.type, model: a.inference.model } };\n }\n }\n // Also include make-meaning actors\n if (makeMeaningSection?.actors?.gatherer?.inference) {\n topLevelActors['gatherer'] = { inference: { type: makeMeaningSection.actors.gatherer.inference.type, model: makeMeaningSection.actors.gatherer.inference.model } };\n }\n if (makeMeaningSection?.actors?.matcher?.inference) {\n topLevelActors['matcher'] = { inference: { type: makeMeaningSection.actors.matcher.inference.type, model: makeMeaningSection.actors.matcher.inference.model } };\n }\n\n const frontend = resolved.frontend;\n\n const services: EnvironmentConfig['services'] = {};\n\n if (backend) {\n services.backend = {\n platform: { type: requirePlatform(backend.platform, 'backend') },\n port: backend.port ?? 4000,\n publicURL: backend.publicURL ?? `http://localhost:${backend.port ?? 4000}`,\n };\n }\n\n if (frontend) {\n services.frontend = {\n platform: { type: requirePlatform(frontend.platform, 'frontend') },\n port: frontend.port ?? 3000,\n siteName: site?.siteName ?? 'Semiont',\n publicURL: frontend.publicURL,\n };\n }\n\n if (resolved.graph) {\n services.graph = {\n ...resolved.graph,\n platform: { type: requirePlatform(resolved.graph.platform as string | undefined, 'graph') },\n type: (resolved.graph.type ?? 'neo4j') as import('./config.types').GraphDatabaseType,\n } as EnvironmentConfig['services']['graph'];\n } else if (makeMeaningSection?.graph) {\n services.graph = makeMeaningSection.graph as EnvironmentConfig['services']['graph'];\n }\n\n if (resolved.database) {\n services.database = {\n platform: { type: requirePlatform(resolved.database.platform, 'database') },\n type: 'postgres',\n image: resolved.database.image,\n host: resolved.database.host ?? 'localhost',\n port: resolved.database.port ?? 5432,\n name: resolved.database.name,\n user: resolved.database.user,\n password: resolved.database.password,\n } as EnvironmentConfig['services']['database'];\n }\n\n if (resolved.vectors) {\n services.vectors = {\n platform: { type: 'external' as PlatformType },\n type: (resolved.vectors.type ?? 'qdrant') as 'qdrant' | 'memory',\n host: resolved.vectors.host,\n port: resolved.vectors.port ?? 6333,\n } as EnvironmentConfig['services']['vectors'];\n }\n\n // Embedding: top-level takes precedence, fall back to legacy vectors.embedding\n const embeddingSource = resolved.embedding ?? resolved.vectors?.embedding;\n if (embeddingSource) {\n services.embedding = {\n platform: { type: 'external' as PlatformType },\n type: embeddingSource.type!,\n model: embeddingSource.model!,\n apiKey: embeddingSource.apiKey,\n baseURL: embeddingSource.baseURL,\n endpoint: embeddingSource.endpoint,\n chunking: (resolved.embedding?.chunking ?? resolved.vectors?.chunking) ? {\n chunkSize: (resolved.embedding?.chunking ?? resolved.vectors?.chunking)?.chunkSize ?? 512,\n overlap: (resolved.embedding?.chunking ?? resolved.vectors?.chunking)?.overlap ?? 64,\n } : undefined,\n } as EnvironmentConfig['services']['embedding'];\n }\n\n const config: EnvironmentConfig = {\n services,\n ...(inferenceProviders ? { inference: inferenceProviders } : {}),\n ...(Object.keys(topLevelWorkers).length > 0 ? { workers: topLevelWorkers } : {}),\n ...(Object.keys(topLevelActors).length > 0 ? { actors: topLevelActors } : {}),\n site: site ? {\n domain: site.domain ?? 'localhost',\n siteName: site.siteName,\n adminEmail: site.adminEmail,\n oauthAllowedDomains: site.oauthAllowedDomains as [string, ...string[]] | undefined,\n } : undefined,\n logLevel: resolved.logLevel,\n _metadata: {\n environment,\n projectRoot,\n projectName,\n projectVersion,\n ...(Object.keys(actors).length > 0 ? { actors } : {}),\n ...(Object.keys(workers).length > 0 ? { workers } : {}),\n },\n };\n\n return config;\n}\n\n/**\n * Create a TOML config loader backed by a file reader.\n * Drop-in replacement for createConfigLoader that reads TOML instead of JSON.\n * The caller must resolve globalConfigPath (e.g. expand '~' using process.env.HOME).\n */\nexport function createTomlConfigLoader(\n reader: TomlFileReader,\n globalConfigPath: string,\n env: Record<string, string | undefined>\n) {\n return (projectRoot: string | null, environment: string): EnvironmentConfig => {\n return loadTomlConfig(projectRoot, environment, globalConfigPath, reader, env);\n };\n}\n","/**\n * Environment validation utilities\n *\n * Pure functions - accept available environments as parameter instead of reading from filesystem\n */\n\nexport type Environment = string; // Allow any environment name\n\n/**\n * Type guard to check if a string is a valid Environment\n * @param value - The environment string to check\n * @param availableEnvironments - List of valid environment names\n */\nexport function isValidEnvironment(value: string | undefined, availableEnvironments: string[]): value is Environment {\n if (!value) return false;\n return availableEnvironments.includes(value);\n}\n\n/**\n * Parse environment string to Environment type\n * @param value - The environment string to parse\n * @param availableEnvironments - List of valid environment names\n * @returns Valid Environment type\n * @throws Error if environment is invalid or not provided\n */\nexport function parseEnvironment(value: string | undefined, availableEnvironments: string[]): Environment {\n if (!value) {\n throw new Error('Environment is required');\n }\n if (!isValidEnvironment(value, availableEnvironments)) {\n throw new Error(`Invalid environment: ${value}. Available environments: ${availableEnvironments.join(', ')}`);\n }\n return value;\n}\n\n/**\n * Validate and return environment or throw error\n * @param value - The environment string to validate\n * @param availableEnvironments - List of valid environment names\n * @throws Error if environment is invalid\n */\nexport function validateEnvironment(value: string | undefined, availableEnvironments: string[]): Environment {\n if (!value) {\n throw new Error('Environment is required');\n }\n if (!isValidEnvironment(value, availableEnvironments)) {\n throw new Error(`Invalid environment: ${value}. Available environments: ${availableEnvironments.join(', ')}`);\n }\n return value;\n}","/**\n * Configuration Error Class\n * \n * Custom error class for configuration validation and loading errors.\n * Provides structured error information with helpful suggestions.\n */\n\nexport class ConfigurationError extends Error {\n public override readonly cause?: Error;\n\n constructor(\n message: string,\n public environment?: string,\n public suggestion?: string,\n cause?: Error\n ) {\n super(message);\n this.name = 'ConfigurationError';\n this.cause = cause;\n }\n \n /**\n * Format the error nicely for CLI output\n */\n override toString(): string {\n let output = `❌ ${this.message}`;\n if (this.environment) {\n output += `\\n Environment: ${this.environment}`;\n }\n if (this.suggestion) {\n output += `\\n 💡 Suggestion: ${this.suggestion}`;\n }\n return output;\n }\n}","/**\n * Platform Types Module\n *\n * Re-exports PlatformType from schema-generated types.\n * Platforms represent WHERE services run (infrastructure targets).\n */\n\nimport { PlatformType as SchemaPlatformType } from './config.types';\n\n/**\n * Platform type literals from JSON Schema\n * These represent the infrastructure targets where services can be deployed\n */\nexport type PlatformType = SchemaPlatformType;\n\n/**\n * Type guard to check if a string is a valid platform type\n *\n * @param value - Value to check\n * @returns True if value is a valid PlatformType\n */\nexport function isValidPlatformType(value: string): value is PlatformType {\n return ['aws', 'container', 'posix', 'external'].includes(value);\n}\n\n/**\n * Get all valid platform types\n *\n * @returns Array of all platform types\n */\nexport function getAllPlatformTypes(): PlatformType[] {\n return ['aws', 'container', 'posix', 'external'];\n}"]}
|