@semiont/core 0.4.18 → 0.4.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -193,22 +193,36 @@ import { fetchAPI, createFetchAPI } from '@semiont/core';
193
193
  const response = await fetchAPI(url, { method: 'POST', body: data });
194
194
  ```
195
195
 
196
- ### Backend-Specific Annotation Utilities
196
+ ### Annotation body matcher
197
197
 
198
- Utilities that work with internal backend types:
198
+ `findBodyItem` locates a body item in an annotation body by identity
199
+ (type + source for `SpecificResource`, type + value for `TextualBody`).
200
+ Used by the `mark:body-updated` event replay path to apply add / remove /
201
+ replace operations.
199
202
 
200
203
  ```typescript
201
- import { bodyItemsMatch, findBodyItem } from '@semiont/core';
202
-
203
- // Find specific body item in annotation
204
- const item = findBodyItem(annotation.body, (item) => item.purpose === 'tagging');
205
-
206
- // Check if two body items match
207
- if (bodyItemsMatch(item1, item2)) {
208
- // ...
209
- }
204
+ import { findBodyItem, type BodyItemIdentity } from '@semiont/core';
205
+
206
+ // Loose match: any body item with this source, regardless of purpose.
207
+ // This is the common case for Semiont's bind/unbind flow.
208
+ const index = findBodyItem(annotation.body, {
209
+ type: 'SpecificResource',
210
+ source: 'https://example.com/target',
211
+ });
212
+
213
+ // Strict match: disambiguate among same-source bodies under different
214
+ // purposes. Needed when an annotation has multiple SpecificResource bodies
215
+ // pointing at the same target under different W3C purposes.
216
+ const linkingIdx = findBodyItem(annotation.body, {
217
+ type: 'SpecificResource',
218
+ source: 'https://example.com/target',
219
+ purpose: 'linking',
220
+ });
210
221
  ```
211
222
 
223
+ `purpose` is optional in the identity. Omit it to match on identity alone;
224
+ provide it when the caller knows which purpose to target.
225
+
212
226
  ### Backend Internal Types
213
227
 
214
228
  Types not in the OpenAPI spec:
@@ -14,6 +14,7 @@ import { E as EnvironmentConfig } from '../config.types-oPv3Ajk-.js';
14
14
  * configDir — $XDG_CONFIG_HOME/semiont/{name}/ (generated config for managed processes)
15
15
  * dataHome — $XDG_DATA_HOME/semiont/{name}/ (persistent user data, e.g. database files)
16
16
  * stateDir — $XDG_STATE_HOME/semiont/{name}/
17
+ * embeddingsDir — stateDir/embeddings/
17
18
  * projectionsDir — stateDir/projections/
18
19
  * jobsDir — stateDir/jobs/
19
20
  * backendLogsDir — stateDir/backend/
@@ -37,6 +38,7 @@ declare class SemiontProject {
37
38
  readonly configDir: string;
38
39
  readonly dataHome: string;
39
40
  readonly stateDir: string;
41
+ readonly embeddingsDir: string;
40
42
  readonly projectionsDir: string;
41
43
  readonly jobsDir: string;
42
44
  readonly backendLogsDir: string;
@@ -293,6 +293,7 @@ var SemiontProject = class _SemiontProject {
293
293
  dataHome;
294
294
  // Ephemeral — state
295
295
  stateDir;
296
+ embeddingsDir;
296
297
  projectionsDir;
297
298
  jobsDir;
298
299
  backendLogsDir;
@@ -322,6 +323,7 @@ name = "${name}"
322
323
  this.dataHome = path.join(xdgData, "semiont", this.name);
323
324
  const xdgState = process.env.XDG_STATE_HOME || path.join(os.homedir(), ".local", "state");
324
325
  this.stateDir = path.join(xdgState, "semiont", this.name);
326
+ this.embeddingsDir = path.join(this.stateDir, "embeddings");
325
327
  this.projectionsDir = path.join(this.stateDir, "projections");
326
328
  this.jobsDir = path.join(this.stateDir, "jobs");
327
329
  this.backendLogsDir = path.join(this.stateDir, "backend");
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/config/toml-loader.ts","../../src/project.ts","../../src/config/node-config-loader.ts"],"names":["parseToml","fs2","path2","os2"],"mappings":"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","file":"node-config-loader.js","sourcesContent":["/**\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, varName) => {\n if (env[varName] === undefined) {\n throw new Error(`Environment variable ${varName} is not set (referenced in config as ${match})`);\n }\n return env[varName] as string;\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","import * as fs from 'fs';\nimport * as os from 'os';\nimport * as path from 'path';\nimport { execFileSync } from 'child_process';\n\n/**\n * Represents a Semiont project rooted at a given directory.\n *\n * Computes all paths — durable and ephemeral — once at construction time.\n * XDG environment variables are read here and nowhere else.\n *\n * Durable paths (inside the project root, committed or repo-local):\n * eventsDir — .semiont/events/ (system of record, committed)\n * representationsDir — representations/ (content store, committed)\n *\n * Ephemeral paths (outside the project root, never committed):\n * configDir — $XDG_CONFIG_HOME/semiont/{name}/ (generated config for managed processes)\n * dataHome — $XDG_DATA_HOME/semiont/{name}/ (persistent user data, e.g. database files)\n * stateDir — $XDG_STATE_HOME/semiont/{name}/\n * projectionsDir — stateDir/projections/\n * jobsDir — stateDir/jobs/\n * backendLogsDir — stateDir/backend/\n * backendAppLogFile — backendLogsDir/app.log\n * backendErrorLogFile — backendLogsDir/error.log\n * runtimeDir — $XDG_RUNTIME_DIR/semiont/{name}/ (or $TMPDIR fallback)\n * backendPidFile — runtimeDir/backend.pid\n *\n * Note: frontend paths are NOT project-scoped. The frontend service is bundled\n * with the CLI and uses fixed XDG paths keyed by \"frontend\", not project name.\n * See apps/cli/src/platforms/posix/handlers/frontend-paths.ts.\n */\nexport class SemiontProject {\n readonly root: string;\n readonly name: string;\n\n /** True if [git] sync = true in .semiont/config. When true, semiont stages\n * working-tree and event-log changes in the git index automatically. */\n readonly gitSync: boolean;\n\n // Durable\n readonly eventsDir: string;\n readonly representationsDir: string;\n\n // Ephemeral — config (generated config files for managed processes)\n readonly configDir: string;\n\n // Ephemeral — data (persistent user data managed by semiont)\n readonly dataHome: string;\n\n // Ephemeral — state\n readonly stateDir: string;\n readonly projectionsDir: string;\n readonly jobsDir: string;\n readonly backendLogsDir: string;\n readonly backendAppLogFile: string;\n readonly backendErrorLogFile: string;\n\n // Ephemeral — runtime\n readonly runtimeDir: string;\n readonly backendPidFile: string;\n\n constructor(projectRoot: string, name?: string) {\n this.root = projectRoot;\n if (name !== undefined) {\n const configPath = path.join(projectRoot, '.semiont', 'config');\n if (!fs.existsSync(configPath)) {\n fs.mkdirSync(path.join(projectRoot, '.semiont'), { recursive: true });\n fs.writeFileSync(configPath, `[project]\\nname = \"${name}\"\\n`);\n }\n }\n this.name = SemiontProject.readName(projectRoot);\n this.gitSync = SemiontProject.readGitSync(projectRoot);\n\n this.eventsDir = path.join(projectRoot, '.semiont', 'events');\n this.representationsDir = path.join(projectRoot, 'representations');\n\n const xdgConfig = process.env.XDG_CONFIG_HOME || path.join(os.homedir(), '.config');\n this.configDir = path.join(xdgConfig, 'semiont', this.name);\n\n const xdgData = process.env.XDG_DATA_HOME || path.join(os.homedir(), '.local', 'share');\n this.dataHome = path.join(xdgData, 'semiont', this.name);\n\n const xdgState = process.env.XDG_STATE_HOME || path.join(os.homedir(), '.local', 'state');\n this.stateDir = path.join(xdgState, 'semiont', this.name);\n this.projectionsDir = path.join(this.stateDir, 'projections');\n this.jobsDir = path.join(this.stateDir, 'jobs');\n this.backendLogsDir = path.join(this.stateDir, 'backend');\n this.backendAppLogFile = path.join(this.backendLogsDir, 'app.log');\n this.backendErrorLogFile = path.join(this.backendLogsDir, 'error.log');\n\n const xdgRuntime = process.env.XDG_RUNTIME_DIR;\n const runtimeBase = xdgRuntime ?? process.env.TMPDIR ?? '/tmp';\n this.runtimeDir = path.join(runtimeBase, 'semiont', this.name);\n this.backendPidFile = path.join(this.runtimeDir, 'backend.pid');\n }\n\n /**\n * Read the current git branch for the project root.\n * Returns null if the project is not a git repo or git is not available.\n */\n gitBranch(): string | null {\n try {\n return execFileSync('git', ['rev-parse', '--abbrev-ref', 'HEAD'], {\n cwd: this.root,\n encoding: 'utf-8',\n stdio: ['ignore', 'pipe', 'ignore'],\n }).trim() || null;\n } catch {\n return null;\n }\n }\n\n /**\n * Delete all ephemeral state for this project (stateDir + runtimeDir).\n * Does not touch eventsDir or dataDir.\n */\n async destroy(): Promise<void> {\n await Promise.all([\n fs.promises.rm(this.configDir, { recursive: true, force: true }),\n fs.promises.rm(this.stateDir, { recursive: true, force: true }),\n fs.promises.rm(this.runtimeDir, { recursive: true, force: true }),\n ]);\n }\n\n /**\n * Read [git] sync from .semiont/config.\n * Defaults to false if the section or key is absent.\n */\n private static readGitSync(projectRoot: string): boolean {\n const configPath = path.join(projectRoot, '.semiont', 'config');\n if (!fs.existsSync(configPath)) return false;\n const content = fs.readFileSync(configPath, 'utf-8');\n let inGitSection = false;\n for (const line of content.split('\\n')) {\n const trimmed = line.trim();\n if (trimmed === '[git]') { inGitSection = true; continue; }\n if (trimmed.startsWith('[')) { inGitSection = false; continue; }\n if (inGitSection && trimmed.startsWith('sync') && trimmed.includes('=')) {\n const value = trimmed.split('=')[1]?.trim();\n return value === 'true';\n }\n }\n return false;\n }\n\n /**\n * Read the project name from .semiont/config [project] name = \"...\"\n * Falls back to the directory basename if the config is absent or has no name.\n */\n private static readName(projectRoot: string): string {\n const configPath = path.join(projectRoot, '.semiont', 'config');\n if (fs.existsSync(configPath)) {\n const content = fs.readFileSync(configPath, 'utf-8');\n for (const line of content.split('\\n')) {\n const trimmed = line.trim();\n if (trimmed.startsWith('name') && trimmed.includes('=')) {\n const [, ...rest] = trimmed.split('=');\n return rest.join('=').trim().replace(/^\"(.*)\"$/, '$1');\n }\n }\n }\n return path.basename(projectRoot);\n }\n}\n","import * as fs from 'fs';\nimport * as os from 'os';\nimport * as path from 'path';\nimport { createTomlConfigLoader } from './toml-loader.js';\nimport type { EnvironmentConfig } from './config.types.js';\n\nexport { SemiontProject } from '../project.js';\n\nconst nodeTomlFileReader = {\n readIfExists: (filePath: string): string | null =>\n fs.existsSync(filePath) ? fs.readFileSync(filePath, 'utf-8') : null,\n};\n\n/**\n * Load semiont environment config for a Node.js process.\n *\n * Reads ~/.semiontconfig (global) merged with .semiont/config (project-local),\n * then selects the given environment overlay.\n *\n * This is the canonical config loader for any Node.js process. SEMIONT_ENV\n * should be read once at the process entry point and passed as `environment`.\n */\nexport function loadEnvironmentConfig(\n projectRoot: string,\n environment: string\n): EnvironmentConfig {\n const globalConfigPath = path.join(os.homedir(), '.semiontconfig');\n return createTomlConfigLoader(\n nodeTomlFileReader,\n globalConfigPath,\n process.env\n )(projectRoot, environment);\n}\n"]}
1
+ {"version":3,"sources":["../../src/config/toml-loader.ts","../../src/project.ts","../../src/config/node-config-loader.ts"],"names":["parseToml","fs2","path2","os2"],"mappings":"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","file":"node-config-loader.js","sourcesContent":["/**\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, varName) => {\n if (env[varName] === undefined) {\n throw new Error(`Environment variable ${varName} is not set (referenced in config as ${match})`);\n }\n return env[varName] as string;\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","import * as fs from 'fs';\nimport * as os from 'os';\nimport * as path from 'path';\nimport { execFileSync } from 'child_process';\n\n/**\n * Represents a Semiont project rooted at a given directory.\n *\n * Computes all paths — durable and ephemeral — once at construction time.\n * XDG environment variables are read here and nowhere else.\n *\n * Durable paths (inside the project root, committed or repo-local):\n * eventsDir — .semiont/events/ (system of record, committed)\n * representationsDir — representations/ (content store, committed)\n *\n * Ephemeral paths (outside the project root, never committed):\n * configDir — $XDG_CONFIG_HOME/semiont/{name}/ (generated config for managed processes)\n * dataHome — $XDG_DATA_HOME/semiont/{name}/ (persistent user data, e.g. database files)\n * stateDir — $XDG_STATE_HOME/semiont/{name}/\n * embeddingsDir — stateDir/embeddings/\n * projectionsDir — stateDir/projections/\n * jobsDir — stateDir/jobs/\n * backendLogsDir — stateDir/backend/\n * backendAppLogFile — backendLogsDir/app.log\n * backendErrorLogFile — backendLogsDir/error.log\n * runtimeDir — $XDG_RUNTIME_DIR/semiont/{name}/ (or $TMPDIR fallback)\n * backendPidFile — runtimeDir/backend.pid\n *\n * Note: frontend paths are NOT project-scoped. The frontend service is bundled\n * with the CLI and uses fixed XDG paths keyed by \"frontend\", not project name.\n * See apps/cli/src/platforms/posix/handlers/frontend-paths.ts.\n */\nexport class SemiontProject {\n readonly root: string;\n readonly name: string;\n\n /** True if [git] sync = true in .semiont/config. When true, semiont stages\n * working-tree and event-log changes in the git index automatically. */\n readonly gitSync: boolean;\n\n // Durable\n readonly eventsDir: string;\n readonly representationsDir: string;\n\n // Ephemeral — config (generated config files for managed processes)\n readonly configDir: string;\n\n // Ephemeral — data (persistent user data managed by semiont)\n readonly dataHome: string;\n\n // Ephemeral — state\n readonly stateDir: string;\n readonly embeddingsDir: string;\n readonly projectionsDir: string;\n readonly jobsDir: string;\n readonly backendLogsDir: string;\n readonly backendAppLogFile: string;\n readonly backendErrorLogFile: string;\n\n // Ephemeral — runtime\n readonly runtimeDir: string;\n readonly backendPidFile: string;\n\n constructor(projectRoot: string, name?: string) {\n this.root = projectRoot;\n if (name !== undefined) {\n const configPath = path.join(projectRoot, '.semiont', 'config');\n if (!fs.existsSync(configPath)) {\n fs.mkdirSync(path.join(projectRoot, '.semiont'), { recursive: true });\n fs.writeFileSync(configPath, `[project]\\nname = \"${name}\"\\n`);\n }\n }\n this.name = SemiontProject.readName(projectRoot);\n this.gitSync = SemiontProject.readGitSync(projectRoot);\n\n this.eventsDir = path.join(projectRoot, '.semiont', 'events');\n this.representationsDir = path.join(projectRoot, 'representations');\n\n const xdgConfig = process.env.XDG_CONFIG_HOME || path.join(os.homedir(), '.config');\n this.configDir = path.join(xdgConfig, 'semiont', this.name);\n\n const xdgData = process.env.XDG_DATA_HOME || path.join(os.homedir(), '.local', 'share');\n this.dataHome = path.join(xdgData, 'semiont', this.name);\n\n const xdgState = process.env.XDG_STATE_HOME || path.join(os.homedir(), '.local', 'state');\n this.stateDir = path.join(xdgState, 'semiont', this.name);\n this.embeddingsDir = path.join(this.stateDir, 'embeddings');\n this.projectionsDir = path.join(this.stateDir, 'projections');\n this.jobsDir = path.join(this.stateDir, 'jobs');\n this.backendLogsDir = path.join(this.stateDir, 'backend');\n this.backendAppLogFile = path.join(this.backendLogsDir, 'app.log');\n this.backendErrorLogFile = path.join(this.backendLogsDir, 'error.log');\n\n const xdgRuntime = process.env.XDG_RUNTIME_DIR;\n const runtimeBase = xdgRuntime ?? process.env.TMPDIR ?? '/tmp';\n this.runtimeDir = path.join(runtimeBase, 'semiont', this.name);\n this.backendPidFile = path.join(this.runtimeDir, 'backend.pid');\n }\n\n /**\n * Read the current git branch for the project root.\n * Returns null if the project is not a git repo or git is not available.\n */\n gitBranch(): string | null {\n try {\n return execFileSync('git', ['rev-parse', '--abbrev-ref', 'HEAD'], {\n cwd: this.root,\n encoding: 'utf-8',\n stdio: ['ignore', 'pipe', 'ignore'],\n }).trim() || null;\n } catch {\n return null;\n }\n }\n\n /**\n * Delete all ephemeral state for this project (stateDir + runtimeDir).\n * Does not touch eventsDir or dataDir.\n */\n async destroy(): Promise<void> {\n await Promise.all([\n fs.promises.rm(this.configDir, { recursive: true, force: true }),\n fs.promises.rm(this.stateDir, { recursive: true, force: true }),\n fs.promises.rm(this.runtimeDir, { recursive: true, force: true }),\n ]);\n }\n\n /**\n * Read [git] sync from .semiont/config.\n * Defaults to false if the section or key is absent.\n */\n private static readGitSync(projectRoot: string): boolean {\n const configPath = path.join(projectRoot, '.semiont', 'config');\n if (!fs.existsSync(configPath)) return false;\n const content = fs.readFileSync(configPath, 'utf-8');\n let inGitSection = false;\n for (const line of content.split('\\n')) {\n const trimmed = line.trim();\n if (trimmed === '[git]') { inGitSection = true; continue; }\n if (trimmed.startsWith('[')) { inGitSection = false; continue; }\n if (inGitSection && trimmed.startsWith('sync') && trimmed.includes('=')) {\n const value = trimmed.split('=')[1]?.trim();\n return value === 'true';\n }\n }\n return false;\n }\n\n /**\n * Read the project name from .semiont/config [project] name = \"...\"\n * Falls back to the directory basename if the config is absent or has no name.\n */\n private static readName(projectRoot: string): string {\n const configPath = path.join(projectRoot, '.semiont', 'config');\n if (fs.existsSync(configPath)) {\n const content = fs.readFileSync(configPath, 'utf-8');\n for (const line of content.split('\\n')) {\n const trimmed = line.trim();\n if (trimmed.startsWith('name') && trimmed.includes('=')) {\n const [, ...rest] = trimmed.split('=');\n return rest.join('=').trim().replace(/^\"(.*)\"$/, '$1');\n }\n }\n }\n return path.basename(projectRoot);\n }\n}\n","import * as fs from 'fs';\nimport * as os from 'os';\nimport * as path from 'path';\nimport { createTomlConfigLoader } from './toml-loader.js';\nimport type { EnvironmentConfig } from './config.types.js';\n\nexport { SemiontProject } from '../project.js';\n\nconst nodeTomlFileReader = {\n readIfExists: (filePath: string): string | null =>\n fs.existsSync(filePath) ? fs.readFileSync(filePath, 'utf-8') : null,\n};\n\n/**\n * Load semiont environment config for a Node.js process.\n *\n * Reads ~/.semiontconfig (global) merged with .semiont/config (project-local),\n * then selects the given environment overlay.\n *\n * This is the canonical config loader for any Node.js process. SEMIONT_ENV\n * should be read once at the process entry point and passed as `environment`.\n */\nexport function loadEnvironmentConfig(\n projectRoot: string,\n environment: string\n): EnvironmentConfig {\n const globalConfigPath = path.join(os.homedir(), '.semiontconfig');\n return createTomlConfigLoader(\n nodeTomlFileReader,\n globalConfigPath,\n process.env\n )(projectRoot, environment);\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -3411,16 +3411,12 @@ interface components {
3411
3411
  percentage?: number;
3412
3412
  message?: string;
3413
3413
  };
3414
- /** @description Metadata added at persistence time. Part of every StoredEvent. */
3414
+ /** @description Metadata added at persistence time. Part of every StoredEvent. Integrity is provided by git at the commit level (when gitSync is enabled), not by in-event metadata fields. */
3415
3415
  EventMetadata: {
3416
3416
  /** @description Monotonic position in the event log (ordering authority) */
3417
3417
  sequenceNumber: number;
3418
3418
  /** @description Byte offset in the JSONL file */
3419
3419
  streamPosition: number;
3420
- /** @description SHA-256 of the previous event (hash chain) */
3421
- prevEventHash?: string;
3422
- /** @description SHA-256 of this event (integrity verification) */
3423
- checksum?: string;
3424
3420
  /** @description Optional correlation id propagated from a command. Lets clients match command-result events back to the POST that initiated them. Set by EventStore.appendEvent's options when a route handler passes one through. */
3425
3421
  correlationId?: string;
3426
3422
  };
@@ -3607,19 +3603,6 @@ interface components {
3607
3603
  error: string;
3608
3604
  details?: string;
3609
3605
  };
3610
- /** @description Payload for embedding:computed domain event */
3611
- EmbeddingComputedPayload: {
3612
- annotationId?: string;
3613
- chunkIndex: number;
3614
- chunkText: string;
3615
- embedding: number[];
3616
- model: string;
3617
- dimensions: number;
3618
- };
3619
- /** @description Payload for embedding:deleted domain event */
3620
- EmbeddingDeletedPayload: {
3621
- annotationId?: string;
3622
- };
3623
3606
  AnnotateHighlightsStreamRequest: {
3624
3607
  /** @description Optional instructions to guide AI highlight annotation */
3625
3608
  instructions?: string;
@@ -4312,21 +4295,6 @@ interface components {
4312
4295
  path: string;
4313
4296
  reason?: string;
4314
4297
  };
4315
- /** @description Command to store a computed embedding for a resource chunk */
4316
- EmbeddingComputeCommand: {
4317
- resourceId: string;
4318
- annotationId?: string;
4319
- chunkIndex: number;
4320
- chunkText: string;
4321
- embedding: number[];
4322
- model: string;
4323
- dimensions: number;
4324
- };
4325
- /** @description Command to delete embeddings for a resource or annotation */
4326
- EmbeddingDeleteCommand: {
4327
- resourceId: string;
4328
- annotationId?: string;
4329
- };
4330
4298
  /** @description W3C Web Annotation FragmentSelector for media fragment identifiers (RFC 3778 for PDFs) */
4331
4299
  FragmentSelector: {
4332
4300
  /** @enum {string} */
@@ -4963,7 +4931,7 @@ interface EntityTypeStats {
4963
4931
  /**
4964
4932
  * Persisted Events
4965
4933
  *
4966
- * The 20 event types that get appended to the JSONL event log.
4934
+ * The 18 event types that get appended to the JSONL event log.
4967
4935
  * Each maps a type string to its OpenAPI payload schema.
4968
4936
  * The PersistedEvent union derives from this catalog.
4969
4937
  */
@@ -4991,8 +4959,6 @@ type PersistedEventCatalog = {
4991
4959
  'job:progress': components['schemas']['JobProgressPayload'];
4992
4960
  'job:completed': components['schemas']['JobCompletedPayload'];
4993
4961
  'job:failed': components['schemas']['JobFailedPayload'];
4994
- 'embedding:computed': components['schemas']['EmbeddingComputedPayload'];
4995
- 'embedding:deleted': components['schemas']['EmbeddingDeletedPayload'];
4996
4962
  };
4997
4963
  /** System event types — persisted events that have no resourceId. */
4998
4964
  type SystemEventType = 'mark:entity-type-added';
@@ -5020,7 +4986,7 @@ type PersistedEventType = PersistedEvent['type'];
5020
4986
  * also adding it here: forgetting fails to typecheck rather than silently
5021
4987
  * dropping the event from the events-stream.
5022
4988
  */
5023
- declare const PERSISTED_EVENT_TYPES: readonly ["yield:created", "yield:cloned", "yield:updated", "yield:moved", "yield:representation-added", "yield:representation-removed", "mark:added", "mark:removed", "mark:body-updated", "mark:archived", "mark:unarchived", "mark:entity-tag-added", "mark:entity-tag-removed", "mark:entity-type-added", "job:started", "job:progress", "job:completed", "job:failed", "embedding:computed", "embedding:deleted"];
4989
+ declare const PERSISTED_EVENT_TYPES: readonly ["yield:created", "yield:cloned", "yield:updated", "yield:moved", "yield:representation-added", "yield:representation-removed", "mark:added", "mark:removed", "mark:body-updated", "mark:archived", "mark:unarchived", "mark:entity-tag-added", "mark:entity-tag-removed", "mark:entity-type-added", "job:started", "job:progress", "job:completed", "job:failed"];
5024
4990
  /** Input type for appendEvent — PersistedEvent without id/timestamp (assigned at persistence time). */
5025
4991
  type EventInput = Omit<PersistedEvent, 'id' | 'timestamp'>;
5026
4992
 
@@ -5306,8 +5272,6 @@ type EventMap = {
5306
5272
  'job:status-failed': {
5307
5273
  correlationId: string;
5308
5274
  } & components['schemas']['CommandError'];
5309
- 'embedding:compute': components['schemas']['EmbeddingComputeCommand'];
5310
- 'embedding:delete': components['schemas']['EmbeddingDeleteCommand'];
5311
5275
  'settings:theme-changed': components['schemas']['SettingsThemeChangedEvent'];
5312
5276
  'settings:line-numbers-toggled': void;
5313
5277
  'settings:locale-changed': components['schemas']['SettingsLocaleChangedEvent'];
@@ -5363,8 +5327,6 @@ interface StoredEventLike {
5363
5327
  payload?: unknown;
5364
5328
  metadata: {
5365
5329
  sequenceNumber: number;
5366
- prevEventHash?: string;
5367
- checksum?: string;
5368
5330
  };
5369
5331
  }
5370
5332
  /**
@@ -5610,15 +5572,46 @@ interface Logger {
5610
5572
  }
5611
5573
 
5612
5574
  /**
5613
- * Backend-specific annotation utility functions
5575
+ * Annotation body utilities
5576
+ *
5577
+ * These are the matcher primitives used by the `mark:body-updated` event
5578
+ * replay path (ViewMaterializer and GraphDBConsumer) to apply add/remove/
5579
+ * replace operations against an annotation body.
5614
5580
  */
5615
5581
 
5616
5582
  type Annotation$2 = components['schemas']['Annotation'];
5583
+ type BodyPurpose = components['schemas']['BodyPurpose'];
5584
+ /**
5585
+ * Identity of a body item for matching purposes.
5586
+ *
5587
+ * Identity is `type + source` for SpecificResource and `type + value` for
5588
+ * TextualBody. `purpose` is OPTIONAL: if the caller provides it, it's
5589
+ * included in the match (used to disambiguate same-source bodies under
5590
+ * different purposes, per the W3C Web Annotation model). If the caller
5591
+ * omits it, the matcher ignores purpose and matches on identity alone.
5592
+ *
5593
+ * Callers SHOULD provide `purpose` when they know it (e.g., the bind flow
5594
+ * always unlinks a `purpose: 'linking'` body) so that future multi-purpose
5595
+ * annotations continue to disambiguate correctly. Leaving `purpose`
5596
+ * unspecified matches whichever purpose comes first in the body — which is
5597
+ * fine today because Semiont annotations currently have at most one body
5598
+ * item per (type, source/value) pair.
5599
+ */
5600
+ type BodyItemIdentity = {
5601
+ type: 'SpecificResource';
5602
+ source: string;
5603
+ purpose?: BodyPurpose;
5604
+ } | {
5605
+ type: 'TextualBody';
5606
+ value: string;
5607
+ purpose?: BodyPurpose;
5608
+ };
5617
5609
  /**
5618
- * Find a body item in an array
5619
- * Returns the index of the first matching item, or -1 if not found
5610
+ * Find a body item by identity. Returns the index of the first match, or -1.
5611
+ *
5612
+ * See `BodyItemIdentity` for matching semantics.
5620
5613
  */
5621
- declare function findBodyItem(body: Annotation$2['body'], targetItem: BodyItem): number;
5614
+ declare function findBodyItem(body: Annotation$2['body'], identity: BodyItemIdentity): number;
5622
5615
 
5623
5616
  /**
5624
5617
  * Annotation Assembly
@@ -5997,4 +5990,4 @@ declare function getAllPlatformTypes(): PlatformType[];
5997
5990
  declare const CORE_TYPES_VERSION = "0.1.0";
5998
5991
  declare const SDK_VERSION = "0.1.0";
5999
5992
 
6000
- export { APIError, type AccessToken, type AnnotationCategory, type AnnotationId, type AnnotationUri, type AssembledAnnotation, type AuthCode, type BaseUrl, type BodyItem, type BodyOperation, type Brand, type BurstBufferOptions, CORE_TYPES_VERSION, CREATION_METHODS, type CloneToken, ConfigurationError, ConflictError, type ContentFormat, type CreateAnnotationInternal, type CreationMethod, type Email, type EntityType, type EntityTypeStats, type Environment, EnvironmentConfig, type EventBase, EventBus, type EventInput, type EventMap, type EventMetadata, type EventName, type EventOfType, type EventQuery, type EventSignature, type GatheredContext, type GoogleAuthRequest, type GoogleCredential, type GraphConnection, type GraphPath, type JobId, type Logger, type MCPToken, type MarkProgress, type Motivation, NotFoundError, PERSISTED_EVENT_TYPES, type PersistedEvent, type PersistedEventType, type PlatformType, type RefreshToken, type ResourceAnnotationUri, type ResourceAnnotations, type ResourceFilter, type ResourceId, type ResourceUri, SDK_VERSION, STREAM_COMMAND_RESULT_TYPES, ScopedEventBus, ScriptError, type SearchQuery, type SelectionData, type Selector, SemiontError, type StoredEvent, type StoredEventLike, type ActorInferenceConfig as TomlActorInferenceConfig, type TomlFileReader, type InferenceConfig as TomlInferenceConfig, type WorkerInferenceConfig as TomlWorkerInferenceConfig, UnauthorizedError, type UpdateResourceInput, type UserDID, type UserId, ValidationError, type YieldProgress, accessToken, annotationId, annotationUri, applyBodyOperations, assembleAnnotation, authCode, baseUrl, burstBuffer, cloneToken, type components, createTomlConfigLoader, didToAgent, email, entityType, findBodyItem, generateUuid, getAllPlatformTypes, getAnnotationUriFromEvent, getFragmentSelector, getSvgSelector, getTextPositionSelector, googleCredential, isAnnotationId, isArray, isBoolean, isDefined, isEventRelatedToAnnotation, isFunction, isNull, isNullish, isNumber, isObject, isResourceId, isStoredEvent, isString, isUndefined, isValidPlatformType, jobId, loadTomlConfig, mcpToken, type operations, parseEnvironment, type paths, refreshToken, resourceAnnotationUri, resourceId, resourceUri, searchQuery, userDID, userId, userToAgent, userToDid, validateEnvironment, validateSvgMarkup };
5993
+ export { APIError, type AccessToken, type AnnotationCategory, type AnnotationId, type AnnotationUri, type AssembledAnnotation, type AuthCode, type BaseUrl, type BodyItem, type BodyItemIdentity, type BodyOperation, type Brand, type BurstBufferOptions, CORE_TYPES_VERSION, CREATION_METHODS, type CloneToken, ConfigurationError, ConflictError, type ContentFormat, type CreateAnnotationInternal, type CreationMethod, type Email, type EntityType, type EntityTypeStats, type Environment, EnvironmentConfig, type EventBase, EventBus, type EventInput, type EventMap, type EventMetadata, type EventName, type EventOfType, type EventQuery, type EventSignature, type GatheredContext, type GoogleAuthRequest, type GoogleCredential, type GraphConnection, type GraphPath, type JobId, type Logger, type MCPToken, type MarkProgress, type Motivation, NotFoundError, PERSISTED_EVENT_TYPES, type PersistedEvent, type PersistedEventType, type PlatformType, type RefreshToken, type ResourceAnnotationUri, type ResourceAnnotations, type ResourceFilter, type ResourceId, type ResourceUri, SDK_VERSION, STREAM_COMMAND_RESULT_TYPES, ScopedEventBus, ScriptError, type SearchQuery, type SelectionData, type Selector, SemiontError, type StoredEvent, type StoredEventLike, type ActorInferenceConfig as TomlActorInferenceConfig, type TomlFileReader, type InferenceConfig as TomlInferenceConfig, type WorkerInferenceConfig as TomlWorkerInferenceConfig, UnauthorizedError, type UpdateResourceInput, type UserDID, type UserId, ValidationError, type YieldProgress, accessToken, annotationId, annotationUri, applyBodyOperations, assembleAnnotation, authCode, baseUrl, burstBuffer, cloneToken, type components, createTomlConfigLoader, didToAgent, email, entityType, findBodyItem, generateUuid, getAllPlatformTypes, getAnnotationUriFromEvent, getFragmentSelector, getSvgSelector, getTextPositionSelector, googleCredential, isAnnotationId, isArray, isBoolean, isDefined, isEventRelatedToAnnotation, isFunction, isNull, isNullish, isNumber, isObject, isResourceId, isStoredEvent, isString, isUndefined, isValidPlatformType, jobId, loadTomlConfig, mcpToken, type operations, parseEnvironment, type paths, refreshToken, resourceAnnotationUri, resourceId, resourceUri, searchQuery, userDID, userId, userToAgent, userToDid, validateEnvironment, validateSvgMarkup };
package/dist/index.js CHANGED
@@ -113,9 +113,7 @@ var PERSISTED_EVENT_TYPES = [
113
113
  "job:started",
114
114
  "job:progress",
115
115
  "job:completed",
116
- "job:failed",
117
- "embedding:computed",
118
- "embedding:deleted"
116
+ "job:failed"
119
117
  ];
120
118
 
121
119
  // src/bus-protocol.ts
@@ -375,31 +373,33 @@ function burstBuffer(options) {
375
373
  }
376
374
 
377
375
  // src/annotation-utils.ts
378
- function findBodyItem(body, targetItem) {
376
+ function findBodyItem(body, identity) {
379
377
  if (!Array.isArray(body)) {
380
378
  return -1;
381
379
  }
382
380
  for (let i = 0; i < body.length; i++) {
383
381
  const item = body[i];
384
- if (typeof item === "object" && item !== null && "type" in item && "purpose" in item) {
385
- const itemType = item.type;
382
+ if (typeof item !== "object" || item === null || !("type" in item)) {
383
+ continue;
384
+ }
385
+ const itemType = item.type;
386
+ if (itemType !== identity.type) {
387
+ continue;
388
+ }
389
+ if (identity.type === "SpecificResource") {
390
+ if (!("source" in item)) continue;
391
+ const itemSource = item.source;
392
+ if (itemSource !== identity.source) continue;
393
+ } else {
394
+ if (!("value" in item)) continue;
395
+ const itemValue = item.value;
396
+ if (itemValue !== identity.value) continue;
397
+ }
398
+ if (identity.purpose !== void 0) {
386
399
  const itemPurpose = item.purpose;
387
- if (itemType !== targetItem.type || itemPurpose !== targetItem.purpose) {
388
- continue;
389
- }
390
- if (targetItem.type === "TextualBody" && "value" in item) {
391
- const itemValue = item.value;
392
- if (itemValue === targetItem.value) {
393
- return i;
394
- }
395
- }
396
- if (targetItem.type === "SpecificResource" && "source" in item) {
397
- const itemSource = item.source;
398
- if (itemSource === targetItem.source) {
399
- return i;
400
- }
401
- }
400
+ if (itemPurpose !== identity.purpose) continue;
402
401
  }
402
+ return i;
403
403
  }
404
404
  return -1;
405
405
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/branded-types.ts","../src/creation-methods.ts","../src/identifiers.ts","../src/persisted-events.ts","../src/bus-protocol.ts","../src/event-utils.ts","../src/event-bus.ts","../src/operators/burst-buffer.ts","../src/annotation-utils.ts","../src/id-generation.ts","../src/annotation-assembly.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","../src/index.ts"],"names":["resourceUri","baseUrl","annotationUri","resourceId","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 and ContentFormat use OpenAPI enums - no helpers needed\n// Use the enum values directly from the OpenAPI spec\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 * Resource creation methods - How resources are created in the system\n */\n\n/**\n * Enumeration of all possible resource creation methods\n */\nexport const CREATION_METHODS = {\n API: 'api',\n UPLOAD: 'upload',\n UI: 'ui',\n REFERENCE: 'reference',\n CLI: 'cli',\n CLONE: 'clone',\n GENERATED: 'generated',\n} as const;\n\n/**\n * Type for resource creation methods\n */\nexport type CreationMethod = typeof CREATION_METHODS[keyof typeof CREATION_METHODS];","/**\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/api-client\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 20 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 { ResourceId } from './identifiers';\nimport type { EventBase } from './event-base';\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': components['schemas']['AnnotationAddedPayload'];\n 'mark:removed': components['schemas']['AnnotationRemovedPayload'];\n 'mark:body-updated': components['schemas']['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 'mark:entity-type-added': components['schemas']['EntityTypeAddedPayload'];\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 'embedding:computed': components['schemas']['EmbeddingComputedPayload'];\n 'embedding:deleted': components['schemas']['EmbeddingDeletedPayload'];\n};\n\n// ── Derived types ────────────────────────────────────────────────────────────\n\n/** System event types — persisted events that have no resourceId. */\ntype SystemEventType = 'mark:entity-type-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 20 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 'mark:entity-type-added',\n 'job:started',\n 'job:progress',\n 'job:completed',\n 'job:failed',\n 'embedding:computed',\n 'embedding:deleted',\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 * Command and result payloads use OpenAPI-generated types (plain strings\n * for identifiers). Branded type safety (ResourceId, UserId, etc.) is\n * enforced at function boundaries, not on bus payloads — callers use\n * factory functions (resourceId(), userId()) at the consume boundary.\n *\n * Domain events (StoredEvent<Interface>) retain branded types as they\n * are the system of record, not wire-format payloads.\n *\n * Organized by flow (verb), then by category within each flow.\n */\n\nimport type { components } from './types';\nimport type { StoredEvent } from './event-base';\nimport type { EventOfType } from './persisted-events';\n\n// ── Shared type aliases (re-exported for convenience) ────────────────────────\n\nexport type Selector =\n | components['schemas']['TextPositionSelector']\n | components['schemas']['TextQuoteSelector']\n | components['schemas']['SvgSelector']\n | components['schemas']['FragmentSelector'];\n\nexport type GatheredContext = components['schemas']['GatheredContext'];\nexport type YieldProgress = components['schemas']['YieldProgress'];\nexport type MarkProgress = components['schemas']['MarkProgress'];\nexport type SelectionData = components['schemas']['SelectionData'];\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 // SSE stream payloads\n 'yield:progress': components['schemas']['YieldProgress'];\n 'yield:finished': components['schemas']['YieldProgress'];\n 'yield:failed': components['schemas']['YieldStreamError'];\n\n // Commands\n 'yield:request': components['schemas']['YieldRequestCommand'];\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, entity types, AI assist\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:entity-type-added': StoredEvent<EventOfType<'mark:entity-type-added'>>;\n 'mark:archived': StoredEvent<EventOfType<'mark:archived'>>;\n 'mark:unarchived': StoredEvent<EventOfType<'mark:unarchived'>>;\n\n // SSE stream payloads\n 'mark:progress': components['schemas']['MarkProgress'];\n 'mark:assist-finished': components['schemas']['MarkAssistFinished'];\n 'mark:assist-failed': components['schemas']['MarkAssistFailed'];\n\n // Commands\n 'mark:create': components['schemas']['MarkCreateCommand'];\n 'mark:delete': components['schemas']['MarkDeleteCommand'];\n 'mark:update-body': components['schemas']['MarkUpdateBodyCommand'];\n 'mark:archive': components['schemas']['MarkArchiveCommand'];\n 'mark:unarchive': components['schemas']['MarkUnarchiveCommand'];\n 'mark:update-entity-types': components['schemas']['MarkUpdateEntityTypesCommand'];\n 'mark:add-entity-type': components['schemas']['MarkAddEntityTypeCommand'];\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 'mark:entity-type-add-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 // BIND FLOW — reference linking\n // ========================================================================\n\n 'bind:initiate': components['schemas']['BindInitiateCommand'];\n 'bind:update-body': components['schemas']['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 // 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: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: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\n 'browse:click': components['schemas']['BrowseClickEvent'];\n 'browse:panel-toggle': components['schemas']['BrowsePanelToggleEvent'];\n 'browse:panel-open': components['schemas']['BrowsePanelOpenEvent'];\n 'browse:panel-close': void;\n 'browse:sidebar-toggle': void;\n 'browse:resource-close': components['schemas']['BrowseResourceCloseEvent'];\n 'browse:resource-reorder': components['schemas']['BrowseResourceReorderEvent'];\n 'browse:link-clicked': components['schemas']['BrowseLinkClickedEvent'];\n 'browse:router-push': components['schemas']['BrowseRouterPushEvent'];\n 'browse:external-navigate': components['schemas']['BrowseExternalNavigateEvent'] & { cancelFallback: () => void };\n 'browse:reference-navigate': components['schemas']['BrowseReferenceNavigateEvent'];\n 'browse:entity-type-clicked': components['schemas']['BrowseEntityTypeClickedEvent'];\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\n // Results\n 'job:status-result': components['schemas']['JobStatusResult'];\n 'job:status-failed': { correlationId: string } & components['schemas']['CommandError'];\n\n // ========================================================================\n // EMBEDDING FLOW — Smelter commands; domain events are in event-catalog.ts\n // ========================================================================\n\n 'embedding:compute': components['schemas']['EmbeddingComputeCommand'];\n 'embedding:delete': components['schemas']['EmbeddingDeleteCommand'];\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\n/** Any valid channel name on the EventBus. */\nexport type EventName = keyof EventMap;\n\n/**\n * Non-persisted event types that the per-resource events-stream should deliver\n * to all connected clients. These are ephemeral command-result and progress\n * events that don't go through EventStore.appendEvent but still need to reach\n * every participant viewing the resource for real-time collaboration.\n *\n * Actors (Binder, Gatherer, workers) publish these on the scoped EventBus\n * (`eventBus.scope(resourceId)`). The events-stream route subscribes to them\n * alongside the persisted event types.\n *\n * Unlike PERSISTED_EVENT_TYPES, there's no compile-time exhaustiveness check\n * here because these event types are a curated subset of EventMap — not every\n * non-persisted event should flow to all participants. Adding a new one is a\n * deliberate choice, not an automatic cascade.\n */\nexport const STREAM_COMMAND_RESULT_TYPES = [\n // Match flow — search results for binding candidates\n 'match:search-results',\n 'match:search-failed',\n // Gather flow — assembled context for reference resolution\n 'gather:complete',\n 'gather:failed',\n 'gather:annotation-progress',\n // Mark flow — AI-assisted annotation progress\n 'mark:progress',\n 'mark:assist-finished',\n 'mark:assist-failed',\n // Yield flow — resource generation progress\n 'yield:progress',\n 'yield:finished',\n 'yield:failed',\n] as const satisfies readonly 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 prevEventHash?: string;\n checksum?: string;\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 * 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 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 this.subjects.set(eventName, new Subject<EventMap[K]>());\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 * Backend-specific annotation utility functions\n */\n\nimport type { components } from './types';\nimport type { BodyItem } from './event-base';\n\ntype Annotation = components['schemas']['Annotation'];\n\n/**\n * Find a body item in an array\n * Returns the index of the first matching item, or -1 if not found\n */\nexport function findBodyItem(body: Annotation['body'], targetItem: BodyItem): 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 // Check if this is a valid body item that can be matched\n if (\n typeof item === 'object' &&\n item !== null &&\n 'type' in item &&\n 'purpose' in item\n ) {\n const itemType = (item as { type: unknown }).type;\n const itemPurpose = (item as { purpose: unknown }).purpose;\n\n // Type and purpose must match\n if (itemType !== targetItem.type || itemPurpose !== targetItem.purpose) {\n continue;\n }\n\n // For TextualBody, match by value\n if (targetItem.type === 'TextualBody' && 'value' in item) {\n const itemValue = (item as { value: unknown }).value;\n if (itemValue === targetItem.value) {\n return i;\n }\n }\n\n // For SpecificResource, match by source\n if (targetItem.type === 'SpecificResource' && 'source' in item) {\n const itemSource = (item as { source: unknown }).source;\n if (itemSource === targetItem.source) {\n return i;\n }\n }\n }\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 './bus-protocol';\nimport { generateUuid } from './id-generation';\n\ntype Agent = components['schemas']['Agent'];\ntype Annotation = components['schemas']['Annotation'];\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 = 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 * 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\n */\n\n/**\n * Base error class for Semiont applications\n */\nexport class SemiontError extends Error {\n constructor(\n message: string,\n public code: string,\n public details?: Record<string, any>\n ) {\n super(message);\n this.name = 'SemiontError';\n Error.captureStackTrace(this, this.constructor);\n }\n}\n\n/**\n * Error thrown when validation fails\n */\nexport class ValidationError extends SemiontError {\n constructor(message: string, details?: Record<string, any>) {\n super(message, 'VALIDATION_ERROR', details);\n this.name = 'ValidationError';\n }\n}\n\n/**\n * Error thrown by scripts\n */\nexport class ScriptError extends SemiontError {\n constructor(message: string, code: string = 'SCRIPT_ERROR', details?: Record<string, any>) {\n super(message, code, details);\n this.name = 'ScriptError';\n }\n}\n\n/**\n * Error thrown when a resource is not found\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\n/**\n * Error thrown when user is not authorized\n */\nexport class UnauthorizedError extends SemiontError {\n constructor(message: string = 'Unauthorized', details?: Record<string, any>) {\n super(message, 'UNAUTHORIZED', details);\n this.name = 'UnauthorizedError';\n }\n}\n\n/**\n * Error thrown when operation would conflict with existing data\n */\nexport class ConflictError extends SemiontError {\n constructor(message: string, details?: Record<string, any>) {\n super(message, 'CONFLICT', details);\n this.name = 'ConflictError';\n }\n}\n\n/**\n * API Error class for handling HTTP errors\n * Used by API clients to represent failed HTTP requests\n */\nexport class APIError extends Error {\n constructor(\n public status: number,\n public data: any,\n message?: string\n ) {\n super(message || `API Error: ${status}`);\n this.name = 'APIError';\n Error.captureStackTrace(this, this.constructor);\n }\n}","/**\n * DID (Decentralized Identifier) and W3C Agent utilities\n *\n * Provides utilities for working with DID:WEB identifiers and converting\n * between user representations and W3C Web Annotation Agent objects.\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.com:users:email%40domain.com\n * Example: did:web:example.com:users:alice%40example.com\n *\n * Email is used as the stable, human-readable identifier (URI-encoded).\n * This is used for W3C Web Annotation compliance and federation readiness.\n *\n * @param user - User object with email and domain\n * @returns DID:WEB identifier string\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 user object to a W3C Agent object with DID:WEB identifier\n *\n * Creates a full Agent object for W3C Web Annotation compliance.\n * Includes DID:WEB identifier, type, and name.\n *\n * @param user - User object with id, domain, name, and email\n * @returns W3C Agent object\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' as const,\n id: userToDid(user),\n name: user.name || user.email,\n };\n}\n\n/**\n * Convert a DID string to a minimal W3C Agent object\n *\n * Used when reconstructing annotations from events where only the DID is available.\n * Creates a minimal Agent with just the required fields (id, type).\n * Name is derived from the DID for display purposes.\n *\n * @param did - DID:WEB identifier string\n * @returns Minimal W3C Agent object\n */\nexport function didToAgent(did: string): Agent {\n // Extract email from DID format: did:web:domain.com:users:alice%40example.com\n const parts = did.split(':');\n const encoded = parts[parts.length - 1] || 'unknown';\n const name = decodeURIComponent(encoded);\n\n return {\n type: 'Person' as const,\n id: did,\n name,\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, varName) => {\n if (env[varName] === undefined) {\n throw new Error(`Environment variable ${varName} is not set (referenced in config as ${match})`);\n }\n return env[varName] as string;\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}","/**\n * @semiont/core\n *\n * Core domain logic and utilities for the Semiont semantic knowledge platform.\n * OpenAPI types are generated here and exported for use across the monorepo.\n */\n\n// OpenAPI-generated types (source of truth for API schemas)\nexport type { components, paths, operations } from './types';\n\n// Branded types (compile-time type safety)\nexport type {\n // OpenAPI types\n Motivation,\n ContentFormat,\n // Authentication & tokens\n Email,\n AuthCode,\n GoogleCredential,\n AccessToken,\n RefreshToken,\n MCPToken,\n CloneToken,\n // System identifiers\n JobId,\n UserDID,\n EntityType,\n SearchQuery,\n BaseUrl,\n // HTTP URI types\n ResourceUri,\n AnnotationUri,\n ResourceAnnotationUri,\n} from './branded-types';\nexport {\n // Helper functions\n email,\n authCode,\n googleCredential,\n accessToken,\n refreshToken,\n mcpToken,\n cloneToken,\n jobId,\n userDID,\n entityType,\n searchQuery,\n baseUrl,\n // URI factory functions\n resourceUri,\n annotationUri,\n resourceAnnotationUri,\n} from './branded-types';\n\n// Creation methods\nexport { CREATION_METHODS } from './creation-methods';\nexport type { CreationMethod } from './creation-methods';\n\n// Identifier types (only IDs - URIs are in @semiont/api-client)\nexport type { ResourceId, AnnotationId, UserId } from './identifiers';\nexport {\n resourceId,\n annotationId,\n userId,\n isResourceId,\n isAnnotationId,\n} from './identifiers';\n\n// Graph types\nexport type {\n GraphConnection,\n GraphPath,\n EntityTypeStats,\n} from './graph';\n\n// Event base types (persistence model foundations)\nexport type {\n Brand,\n EventBase,\n EventMetadata,\n EventSignature,\n StoredEvent,\n BodyOperation,\n BodyItem,\n EventQuery,\n ResourceAnnotations,\n} from './event-base';\n\n// Persisted events (the 20 event types written to the log)\nexport type {\n EventOfType,\n PersistedEvent,\n PersistedEventType,\n EventInput,\n} from './persisted-events';\nexport { PERSISTED_EVENT_TYPES } from './persisted-events';\n\n// Bus protocol (unified EventMap — all channels on the EventBus)\nexport type {\n EventMap,\n EventName,\n Selector,\n GatheredContext,\n YieldProgress,\n MarkProgress,\n SelectionData,\n} from './bus-protocol';\nexport { STREAM_COMMAND_RESULT_TYPES } from './bus-protocol';\n\n// Event utilities\nexport type { StoredEventLike } from './event-utils';\nexport {\n getAnnotationUriFromEvent,\n isEventRelatedToAnnotation,\n isStoredEvent,\n} from './event-utils';\n\n// Event bus (RxJS-based, framework-agnostic)\nexport { EventBus, ScopedEventBus } from './event-bus';\n\n// RxJS operators\nexport { burstBuffer, type BurstBufferOptions } from './operators/burst-buffer';\n\n// Logger interface (framework-agnostic)\nexport type { Logger } from './logger';\n\n// Backend-specific annotation utilities\nexport { findBodyItem } from './annotation-utils';\n\n// Annotation assembly (pure functions for building W3C Annotations)\nexport {\n assembleAnnotation,\n applyBodyOperations,\n getTextPositionSelector,\n getSvgSelector,\n getFragmentSelector,\n validateSvgMarkup,\n} from './annotation-assembly';\nexport type { AssembledAnnotation } from './annotation-assembly';\n\n// Resource types\nexport type { UpdateResourceInput, ResourceFilter } from './resource-types';\n\n// Annotation types\nexport type { AnnotationCategory, CreateAnnotationInternal } from './annotation-types';\n\n// Auth types\nexport type { GoogleAuthRequest } from './auth-types';\n\n// ID generation\nexport { generateUuid } from './id-generation';\n\n// Utility functions\nexport * from './type-guards';\nexport * from './errors';\nexport * from './did-utils';\n\n// Configuration types\nexport type {\n EnvironmentConfig,\n SiteConfig,\n AppConfig,\n} from './config/config.types';\n\nexport {\n loadTomlConfig,\n createTomlConfigLoader,\n type TomlFileReader,\n type InferenceConfig as TomlInferenceConfig,\n type ActorInferenceConfig as TomlActorInferenceConfig,\n type WorkerInferenceConfig as TomlWorkerInferenceConfig,\n} from './config/toml-loader';\n\nexport {\n parseEnvironment,\n validateEnvironment,\n type Environment,\n} from './config/environment-validator';\nexport { ConfigurationError } from './config/configuration-error';\nexport {\n type PlatformType,\n isValidPlatformType,\n getAllPlatformTypes,\n} from './config/platform-types';\n\n// Schema-generated configuration types\nexport type {\n BackendServiceConfig,\n FrontendServiceConfig,\n DatabaseServiceConfig,\n GraphServiceConfig,\n OllamaProviderConfig,\n AnthropicProviderConfig,\n InferenceProvidersConfig,\n McpServiceConfig,\n ServicesConfig,\n VectorsServiceConfig,\n EmbeddingServiceConfig,\n SemiontConfig,\n GraphDatabaseType,\n ServicePlatformConfig\n} from './config/config.types';\n\n// Version information\nexport const CORE_TYPES_VERSION = '0.1.0';\nexport const SDK_VERSION = '0.1.0';\n"]}
1
+ {"version":3,"sources":["../src/branded-types.ts","../src/creation-methods.ts","../src/identifiers.ts","../src/persisted-events.ts","../src/bus-protocol.ts","../src/event-utils.ts","../src/event-bus.ts","../src/operators/burst-buffer.ts","../src/annotation-utils.ts","../src/id-generation.ts","../src/annotation-assembly.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","../src/index.ts"],"names":["resourceUri","baseUrl","annotationUri","resourceId","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 and ContentFormat use OpenAPI enums - no helpers needed\n// Use the enum values directly from the OpenAPI spec\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 * Resource creation methods - How resources are created in the system\n */\n\n/**\n * Enumeration of all possible resource creation methods\n */\nexport const CREATION_METHODS = {\n API: 'api',\n UPLOAD: 'upload',\n UI: 'ui',\n REFERENCE: 'reference',\n CLI: 'cli',\n CLONE: 'clone',\n GENERATED: 'generated',\n} as const;\n\n/**\n * Type for resource creation methods\n */\nexport type CreationMethod = typeof CREATION_METHODS[keyof typeof CREATION_METHODS];","/**\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/api-client\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 18 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 { ResourceId } from './identifiers';\nimport type { EventBase } from './event-base';\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': components['schemas']['AnnotationAddedPayload'];\n 'mark:removed': components['schemas']['AnnotationRemovedPayload'];\n 'mark:body-updated': components['schemas']['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 'mark:entity-type-added': components['schemas']['EntityTypeAddedPayload'];\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 = 'mark:entity-type-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 20 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 'mark:entity-type-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 * Command and result payloads use OpenAPI-generated types (plain strings\n * for identifiers). Branded type safety (ResourceId, UserId, etc.) is\n * enforced at function boundaries, not on bus payloads — callers use\n * factory functions (resourceId(), userId()) at the consume boundary.\n *\n * Domain events (StoredEvent<Interface>) retain branded types as they\n * are the system of record, not wire-format payloads.\n *\n * Organized by flow (verb), then by category within each flow.\n */\n\nimport type { components } from './types';\nimport type { StoredEvent } from './event-base';\nimport type { EventOfType } from './persisted-events';\n\n// ── Shared type aliases (re-exported for convenience) ────────────────────────\n\nexport type Selector =\n | components['schemas']['TextPositionSelector']\n | components['schemas']['TextQuoteSelector']\n | components['schemas']['SvgSelector']\n | components['schemas']['FragmentSelector'];\n\nexport type GatheredContext = components['schemas']['GatheredContext'];\nexport type YieldProgress = components['schemas']['YieldProgress'];\nexport type MarkProgress = components['schemas']['MarkProgress'];\nexport type SelectionData = components['schemas']['SelectionData'];\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 // SSE stream payloads\n 'yield:progress': components['schemas']['YieldProgress'];\n 'yield:finished': components['schemas']['YieldProgress'];\n 'yield:failed': components['schemas']['YieldStreamError'];\n\n // Commands\n 'yield:request': components['schemas']['YieldRequestCommand'];\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, entity types, AI assist\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:entity-type-added': StoredEvent<EventOfType<'mark:entity-type-added'>>;\n 'mark:archived': StoredEvent<EventOfType<'mark:archived'>>;\n 'mark:unarchived': StoredEvent<EventOfType<'mark:unarchived'>>;\n\n // SSE stream payloads\n 'mark:progress': components['schemas']['MarkProgress'];\n 'mark:assist-finished': components['schemas']['MarkAssistFinished'];\n 'mark:assist-failed': components['schemas']['MarkAssistFailed'];\n\n // Commands\n 'mark:create': components['schemas']['MarkCreateCommand'];\n 'mark:delete': components['schemas']['MarkDeleteCommand'];\n 'mark:update-body': components['schemas']['MarkUpdateBodyCommand'];\n 'mark:archive': components['schemas']['MarkArchiveCommand'];\n 'mark:unarchive': components['schemas']['MarkUnarchiveCommand'];\n 'mark:update-entity-types': components['schemas']['MarkUpdateEntityTypesCommand'];\n 'mark:add-entity-type': components['schemas']['MarkAddEntityTypeCommand'];\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 'mark:entity-type-add-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 // BIND FLOW — reference linking\n // ========================================================================\n\n 'bind:initiate': components['schemas']['BindInitiateCommand'];\n 'bind:update-body': components['schemas']['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 // 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: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: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\n 'browse:click': components['schemas']['BrowseClickEvent'];\n 'browse:panel-toggle': components['schemas']['BrowsePanelToggleEvent'];\n 'browse:panel-open': components['schemas']['BrowsePanelOpenEvent'];\n 'browse:panel-close': void;\n 'browse:sidebar-toggle': void;\n 'browse:resource-close': components['schemas']['BrowseResourceCloseEvent'];\n 'browse:resource-reorder': components['schemas']['BrowseResourceReorderEvent'];\n 'browse:link-clicked': components['schemas']['BrowseLinkClickedEvent'];\n 'browse:router-push': components['schemas']['BrowseRouterPushEvent'];\n 'browse:external-navigate': components['schemas']['BrowseExternalNavigateEvent'] & { cancelFallback: () => void };\n 'browse:reference-navigate': components['schemas']['BrowseReferenceNavigateEvent'];\n 'browse:entity-type-clicked': components['schemas']['BrowseEntityTypeClickedEvent'];\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\n // Results\n 'job:status-result': components['schemas']['JobStatusResult'];\n 'job:status-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\n/** Any valid channel name on the EventBus. */\nexport type EventName = keyof EventMap;\n\n/**\n * Non-persisted event types that the per-resource events-stream should deliver\n * to all connected clients. These are ephemeral command-result and progress\n * events that don't go through EventStore.appendEvent but still need to reach\n * every participant viewing the resource for real-time collaboration.\n *\n * Actors (Binder, Gatherer, workers) publish these on the scoped EventBus\n * (`eventBus.scope(resourceId)`). The events-stream route subscribes to them\n * alongside the persisted event types.\n *\n * Unlike PERSISTED_EVENT_TYPES, there's no compile-time exhaustiveness check\n * here because these event types are a curated subset of EventMap — not every\n * non-persisted event should flow to all participants. Adding a new one is a\n * deliberate choice, not an automatic cascade.\n */\nexport const STREAM_COMMAND_RESULT_TYPES = [\n // Match flow — search results for binding candidates\n 'match:search-results',\n 'match:search-failed',\n // Gather flow — assembled context for reference resolution\n 'gather:complete',\n 'gather:failed',\n 'gather:annotation-progress',\n // Mark flow — AI-assisted annotation progress\n 'mark:progress',\n 'mark:assist-finished',\n 'mark:assist-failed',\n // Yield flow — resource generation progress\n 'yield:progress',\n 'yield:finished',\n 'yield:failed',\n] as const satisfies readonly 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 * 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 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 this.subjects.set(eventName, new Subject<EventMap[K]>());\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 * 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';\n\ntype Annotation = components['schemas']['Annotation'];\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 './bus-protocol';\nimport { generateUuid } from './id-generation';\n\ntype Agent = components['schemas']['Agent'];\ntype Annotation = components['schemas']['Annotation'];\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 = 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 * 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\n */\n\n/**\n * Base error class for Semiont applications\n */\nexport class SemiontError extends Error {\n constructor(\n message: string,\n public code: string,\n public details?: Record<string, any>\n ) {\n super(message);\n this.name = 'SemiontError';\n Error.captureStackTrace(this, this.constructor);\n }\n}\n\n/**\n * Error thrown when validation fails\n */\nexport class ValidationError extends SemiontError {\n constructor(message: string, details?: Record<string, any>) {\n super(message, 'VALIDATION_ERROR', details);\n this.name = 'ValidationError';\n }\n}\n\n/**\n * Error thrown by scripts\n */\nexport class ScriptError extends SemiontError {\n constructor(message: string, code: string = 'SCRIPT_ERROR', details?: Record<string, any>) {\n super(message, code, details);\n this.name = 'ScriptError';\n }\n}\n\n/**\n * Error thrown when a resource is not found\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\n/**\n * Error thrown when user is not authorized\n */\nexport class UnauthorizedError extends SemiontError {\n constructor(message: string = 'Unauthorized', details?: Record<string, any>) {\n super(message, 'UNAUTHORIZED', details);\n this.name = 'UnauthorizedError';\n }\n}\n\n/**\n * Error thrown when operation would conflict with existing data\n */\nexport class ConflictError extends SemiontError {\n constructor(message: string, details?: Record<string, any>) {\n super(message, 'CONFLICT', details);\n this.name = 'ConflictError';\n }\n}\n\n/**\n * API Error class for handling HTTP errors\n * Used by API clients to represent failed HTTP requests\n */\nexport class APIError extends Error {\n constructor(\n public status: number,\n public data: any,\n message?: string\n ) {\n super(message || `API Error: ${status}`);\n this.name = 'APIError';\n Error.captureStackTrace(this, this.constructor);\n }\n}","/**\n * DID (Decentralized Identifier) and W3C Agent utilities\n *\n * Provides utilities for working with DID:WEB identifiers and converting\n * between user representations and W3C Web Annotation Agent objects.\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.com:users:email%40domain.com\n * Example: did:web:example.com:users:alice%40example.com\n *\n * Email is used as the stable, human-readable identifier (URI-encoded).\n * This is used for W3C Web Annotation compliance and federation readiness.\n *\n * @param user - User object with email and domain\n * @returns DID:WEB identifier string\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 user object to a W3C Agent object with DID:WEB identifier\n *\n * Creates a full Agent object for W3C Web Annotation compliance.\n * Includes DID:WEB identifier, type, and name.\n *\n * @param user - User object with id, domain, name, and email\n * @returns W3C Agent object\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' as const,\n id: userToDid(user),\n name: user.name || user.email,\n };\n}\n\n/**\n * Convert a DID string to a minimal W3C Agent object\n *\n * Used when reconstructing annotations from events where only the DID is available.\n * Creates a minimal Agent with just the required fields (id, type).\n * Name is derived from the DID for display purposes.\n *\n * @param did - DID:WEB identifier string\n * @returns Minimal W3C Agent object\n */\nexport function didToAgent(did: string): Agent {\n // Extract email from DID format: did:web:domain.com:users:alice%40example.com\n const parts = did.split(':');\n const encoded = parts[parts.length - 1] || 'unknown';\n const name = decodeURIComponent(encoded);\n\n return {\n type: 'Person' as const,\n id: did,\n name,\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, varName) => {\n if (env[varName] === undefined) {\n throw new Error(`Environment variable ${varName} is not set (referenced in config as ${match})`);\n }\n return env[varName] as string;\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}","/**\n * @semiont/core\n *\n * Core domain logic and utilities for the Semiont semantic knowledge platform.\n * OpenAPI types are generated here and exported for use across the monorepo.\n */\n\n// OpenAPI-generated types (source of truth for API schemas)\nexport type { components, paths, operations } from './types';\n\n// Branded types (compile-time type safety)\nexport type {\n // OpenAPI types\n Motivation,\n ContentFormat,\n // Authentication & tokens\n Email,\n AuthCode,\n GoogleCredential,\n AccessToken,\n RefreshToken,\n MCPToken,\n CloneToken,\n // System identifiers\n JobId,\n UserDID,\n EntityType,\n SearchQuery,\n BaseUrl,\n // HTTP URI types\n ResourceUri,\n AnnotationUri,\n ResourceAnnotationUri,\n} from './branded-types';\nexport {\n // Helper functions\n email,\n authCode,\n googleCredential,\n accessToken,\n refreshToken,\n mcpToken,\n cloneToken,\n jobId,\n userDID,\n entityType,\n searchQuery,\n baseUrl,\n // URI factory functions\n resourceUri,\n annotationUri,\n resourceAnnotationUri,\n} from './branded-types';\n\n// Creation methods\nexport { CREATION_METHODS } from './creation-methods';\nexport type { CreationMethod } from './creation-methods';\n\n// Identifier types (only IDs - URIs are in @semiont/api-client)\nexport type { ResourceId, AnnotationId, UserId } from './identifiers';\nexport {\n resourceId,\n annotationId,\n userId,\n isResourceId,\n isAnnotationId,\n} from './identifiers';\n\n// Graph types\nexport type {\n GraphConnection,\n GraphPath,\n EntityTypeStats,\n} from './graph';\n\n// Event base types (persistence model foundations)\nexport type {\n Brand,\n EventBase,\n EventMetadata,\n EventSignature,\n StoredEvent,\n BodyOperation,\n BodyItem,\n EventQuery,\n ResourceAnnotations,\n} from './event-base';\n\n// Persisted events (the 20 event types written to the log)\nexport type {\n EventOfType,\n PersistedEvent,\n PersistedEventType,\n EventInput,\n} from './persisted-events';\nexport { PERSISTED_EVENT_TYPES } from './persisted-events';\n\n// Bus protocol (unified EventMap — all channels on the EventBus)\nexport type {\n EventMap,\n EventName,\n Selector,\n GatheredContext,\n YieldProgress,\n MarkProgress,\n SelectionData,\n} from './bus-protocol';\nexport { STREAM_COMMAND_RESULT_TYPES } from './bus-protocol';\n\n// Event utilities\nexport type { StoredEventLike } from './event-utils';\nexport {\n getAnnotationUriFromEvent,\n isEventRelatedToAnnotation,\n isStoredEvent,\n} from './event-utils';\n\n// Event bus (RxJS-based, framework-agnostic)\nexport { EventBus, ScopedEventBus } from './event-bus';\n\n// RxJS operators\nexport { burstBuffer, type BurstBufferOptions } from './operators/burst-buffer';\n\n// Logger interface (framework-agnostic)\nexport type { Logger } from './logger';\n\n// Annotation body matcher (used by mark:body-updated event replay)\nexport { findBodyItem } from './annotation-utils';\nexport type { BodyItemIdentity } from './annotation-utils';\n\n// Annotation assembly (pure functions for building W3C Annotations)\nexport {\n assembleAnnotation,\n applyBodyOperations,\n getTextPositionSelector,\n getSvgSelector,\n getFragmentSelector,\n validateSvgMarkup,\n} from './annotation-assembly';\nexport type { AssembledAnnotation } from './annotation-assembly';\n\n// Resource types\nexport type { UpdateResourceInput, ResourceFilter } from './resource-types';\n\n// Annotation types\nexport type { AnnotationCategory, CreateAnnotationInternal } from './annotation-types';\n\n// Auth types\nexport type { GoogleAuthRequest } from './auth-types';\n\n// ID generation\nexport { generateUuid } from './id-generation';\n\n// Utility functions\nexport * from './type-guards';\nexport * from './errors';\nexport * from './did-utils';\n\n// Configuration types\nexport type {\n EnvironmentConfig,\n SiteConfig,\n AppConfig,\n} from './config/config.types';\n\nexport {\n loadTomlConfig,\n createTomlConfigLoader,\n type TomlFileReader,\n type InferenceConfig as TomlInferenceConfig,\n type ActorInferenceConfig as TomlActorInferenceConfig,\n type WorkerInferenceConfig as TomlWorkerInferenceConfig,\n} from './config/toml-loader';\n\nexport {\n parseEnvironment,\n validateEnvironment,\n type Environment,\n} from './config/environment-validator';\nexport { ConfigurationError } from './config/configuration-error';\nexport {\n type PlatformType,\n isValidPlatformType,\n getAllPlatformTypes,\n} from './config/platform-types';\n\n// Schema-generated configuration types\nexport type {\n BackendServiceConfig,\n FrontendServiceConfig,\n DatabaseServiceConfig,\n GraphServiceConfig,\n OllamaProviderConfig,\n AnthropicProviderConfig,\n InferenceProvidersConfig,\n McpServiceConfig,\n ServicesConfig,\n VectorsServiceConfig,\n EmbeddingServiceConfig,\n SemiontConfig,\n GraphDatabaseType,\n ServicePlatformConfig\n} from './config/config.types';\n\n// Version information\nexport const CORE_TYPES_VERSION = '0.1.0';\nexport const SDK_VERSION = '0.1.0';\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@semiont/core",
3
- "version": "0.4.18",
3
+ "version": "0.4.19",
4
4
  "description": "Core domain types for Semiont - Document, Annotation, and Graph models",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",