@utaba/deep-memory 0.9.1 → 0.9.3

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/core/errors.ts","../src/entities/IdGenerator.ts","../src/vocabulary/similarity.ts","../src/vocabulary/VocabularyValidator.ts","../src/entities/EntityManager.ts","../src/relationships/RelationshipManager.ts","../src/entities/entityProjection.ts","../src/relationships/TraversalValidator.ts","../src/relationships/PropertyFilterMatcher.ts","../src/relationships/FallbackTraversalExecutor.ts","../src/relationships/GraphTraversal.ts","../src/search/SearchOrchestrator.ts","../src/validation/RepositoryValidator.ts","../src/core/MemoryRepository.ts","../src/vocabulary/SemanticDeduplicator.ts","../src/vocabulary/VocabularySchema.ts","../src/vocabulary/VocabularyGovernor.ts","../src/core/VocabularyEngine.ts","../src/core/ProvenanceTracker.ts","../src/core/EventBus.ts","../src/portability/RepositoryExporter.ts","../src/vocabulary/VocabularyDiff.ts","../src/portability/MigrationEngine.ts","../src/portability/RepositoryImporter.ts","../src/core/DeepMemory.ts","../src/usage/safeSink.ts","../src/relationships/compilers/GremlinCompiler.ts","../src/relationships/compilers/CypherCompiler.ts","../src/providers-builtin/InMemoryStorageProvider.ts","../src/providers-builtin/InMemorySearchProvider.ts","../src/providers-builtin/NoOpEmbeddingProvider.ts"],"sourcesContent":["// @utaba/deep-memory — Public API\n// Vocabulary-driven graph memory for AI agents\n\nexport * from './types/index.js';\nexport * from './providers/index.js';\n\n// Errors\nexport {\n DeepMemoryError,\n InvalidInputError,\n EntityNotFoundError,\n DuplicateEntityError,\n RelationshipNotFoundError,\n DuplicateRelationshipError,\n RepositoryNotFoundError,\n DuplicateRepositoryError,\n VocabularyValidationError,\n RelationshipConstraintError,\n SelfReferentialRelationshipError,\n GovernanceDeniedError,\n OperationCancelledError,\n EmbeddingProviderRequiredError,\n ImportError,\n ExportError,\n ProviderError,\n GraphTraversalProviderRequiredError,\n TraversalValidationError,\n TraversalVocabularyError,\n TraversalTimeoutError,\n} from './core/errors.js';\nexport type { DeepMemoryErrorCode } from './core/errors.js';\n\n// Core classes\nexport { DeepMemory, generateId, isValidUuid } from './core/DeepMemory.js';\nexport type { DeepMemoryConfig } from './core/DeepMemory.js';\nexport { MemoryRepository } from './core/MemoryRepository.js';\nexport { RepositoryValidator } from './validation/RepositoryValidator.js';\n\n// Utilities\nexport { matchesPropertyFilters } from './relationships/PropertyFilterMatcher.js';\nexport { projectEntity } from './entities/entityProjection.js';\nexport { createSafeSink } from './usage/safeSink.js';\n\n// Compilers (for provider authors who want to reuse them)\nexport { GremlinCompiler } from './relationships/compilers/GremlinCompiler.js';\nexport { CypherCompiler } from './relationships/compilers/CypherCompiler.js';\nexport type { TraversalCompiler, CompiledQuery } from './relationships/compilers/TraversalCompiler.js';\n\n// Built-in providers\nexport { InMemoryStorageProvider } from './providers-builtin/InMemoryStorageProvider.js';\nexport { InMemorySearchProvider } from './providers-builtin/InMemorySearchProvider.js';\nexport { NoOpEmbeddingProvider } from './providers-builtin/NoOpEmbeddingProvider.js';\n","// Error hierarchy — typed errors with actionable suggestions\n\n/** Error codes for all Deep Memory errors */\nexport type DeepMemoryErrorCode =\n | 'INVALID_INPUT'\n | 'ENTITY_NOT_FOUND'\n | 'ENTITY_ALREADY_EXISTS'\n | 'RELATIONSHIP_NOT_FOUND'\n | 'RELATIONSHIP_ALREADY_EXISTS'\n | 'REPOSITORY_NOT_FOUND'\n | 'REPOSITORY_ALREADY_EXISTS'\n | 'VOCABULARY_VALIDATION_FAILED'\n | 'RELATIONSHIP_CONSTRAINT_FAILED'\n | 'SELF_REFERENTIAL_RELATIONSHIP'\n | 'GOVERNANCE_DENIED'\n | 'OPERATION_CANCELLED'\n | 'EMBEDDING_PROVIDER_REQUIRED'\n | 'IMPORT_ERROR'\n | 'EXPORT_ERROR'\n | 'PROVIDER_ERROR'\n | 'GRAPH_TRAVERSAL_PROVIDER_REQUIRED'\n | 'TRAVERSAL_VALIDATION_FAILED'\n | 'TRAVERSAL_VOCABULARY_ERROR'\n | 'TRAVERSAL_TIMEOUT';\n\n/** Base error class for all Deep Memory errors */\nexport class DeepMemoryError extends Error {\n readonly code: DeepMemoryErrorCode;\n readonly suggestion?: string;\n\n constructor(code: DeepMemoryErrorCode, message: string, suggestion?: string) {\n super(message);\n this.name = 'DeepMemoryError';\n this.code = code;\n this.suggestion = suggestion;\n }\n}\n\n/** Input validation failed (e.g. invalid ID format) */\nexport class InvalidInputError extends DeepMemoryError {\n readonly field: string;\n\n constructor(field: string, message: string, suggestion?: string) {\n super(\n 'INVALID_INPUT',\n message,\n suggestion ?? `Check the value of \"${field}\" and try again.`,\n );\n this.name = 'InvalidInputError';\n this.field = field;\n }\n}\n\n/** Entity was not found in the repository */\nexport class EntityNotFoundError extends DeepMemoryError {\n readonly id: string;\n readonly slug?: string;\n\n constructor(idOrSlug: string, slug?: string) {\n super(\n 'ENTITY_NOT_FOUND',\n `Entity \"${idOrSlug}\" not found`,\n `Check the entity ID or slug is correct. Use findEntities() to search by label if unknown.`,\n );\n this.name = 'EntityNotFoundError';\n this.id = idOrSlug;\n this.slug = slug;\n }\n}\n\n/** Attempted to create an entity with an ID that already exists */\nexport class DuplicateEntityError extends DeepMemoryError {\n readonly id: string;\n\n constructor(id: string) {\n super(\n 'ENTITY_ALREADY_EXISTS',\n `Entity \"${id}\" already exists`,\n `Use updateEntity() to modify an existing entity, or omit id to auto-generate a unique one.`,\n );\n this.name = 'DuplicateEntityError';\n this.id = id;\n }\n}\n\n/** Relationship was not found */\nexport class RelationshipNotFoundError extends DeepMemoryError {\n readonly relationshipId: string;\n\n constructor(relationshipId: string) {\n super(\n 'RELATIONSHIP_NOT_FOUND',\n `Relationship \"${relationshipId}\" not found`,\n `Check the relationship ID is correct. Use getRelationships() to list relationships for an entity.`,\n );\n this.name = 'RelationshipNotFoundError';\n this.relationshipId = relationshipId;\n }\n}\n\n/** Attempted to create a relationship with an ID that already exists */\nexport class DuplicateRelationshipError extends DeepMemoryError {\n readonly relationshipId: string;\n\n constructor(relationshipId: string) {\n super(\n 'RELATIONSHIP_ALREADY_EXISTS',\n `Relationship \"${relationshipId}\" already exists`,\n `Omit relationshipId to auto-generate a unique one, or use a different explicit ID.`,\n );\n this.name = 'DuplicateRelationshipError';\n this.relationshipId = relationshipId;\n }\n}\n\n/** Repository was not found */\nexport class RepositoryNotFoundError extends DeepMemoryError {\n readonly repositoryId: string;\n\n constructor(repositoryId: string) {\n super(\n 'REPOSITORY_NOT_FOUND',\n `Repository \"${repositoryId}\" not found`,\n `Use listRepositories() to see available repositories, or createRepository() to create a new one.`,\n );\n this.name = 'RepositoryNotFoundError';\n this.repositoryId = repositoryId;\n }\n}\n\n/** Attempted to create a repository with an ID that already exists */\nexport class DuplicateRepositoryError extends DeepMemoryError {\n readonly repositoryId: string;\n\n constructor(repositoryId: string) {\n super(\n 'REPOSITORY_ALREADY_EXISTS',\n `Repository \"${repositoryId}\" already exists`,\n `Use openRepository() to access an existing repository, or choose a different ID.`,\n );\n this.name = 'DuplicateRepositoryError';\n this.repositoryId = repositoryId;\n }\n}\n\n/** Entity or relationship failed vocabulary validation */\nexport class VocabularyValidationError extends DeepMemoryError {\n readonly errors: Array<{ field: string; message: string; suggestion?: string }>;\n\n constructor(\n errors: Array<{ field: string; message: string; suggestion?: string }>,\n ) {\n const errorMsg = errors.map((e) => e.message).join('; ');\n const suggestions = errors\n .filter((e) => e.suggestion)\n .map((e) => e.suggestion!);\n\n super(\n 'VOCABULARY_VALIDATION_FAILED',\n `Vocabulary validation failed: ${errorMsg}`,\n suggestions.length > 0\n ? suggestions.join(' ')\n : `Check the repository vocabulary with getVocabulary() to see valid types and properties.`,\n );\n this.name = 'VocabularyValidationError';\n this.errors = errors;\n }\n}\n\n/** Relationship source/target entity types violate vocabulary constraints */\nexport class RelationshipConstraintError extends DeepMemoryError {\n readonly relationshipType: string;\n readonly sourceType?: string;\n readonly targetType?: string;\n\n constructor(\n relationshipType: string,\n message: string,\n sourceType?: string,\n targetType?: string,\n ) {\n super(\n 'RELATIONSHIP_CONSTRAINT_FAILED',\n message,\n `Check the vocabulary for allowed source/target types on \"${relationshipType}\".`,\n );\n this.name = 'RelationshipConstraintError';\n this.relationshipType = relationshipType;\n this.sourceType = sourceType;\n this.targetType = targetType;\n }\n}\n\n/** Relationship source and target entity are the same — self-references are not permitted */\nexport class SelfReferentialRelationshipError extends DeepMemoryError {\n readonly entityId: string;\n readonly relationshipType: string;\n\n constructor(entityId: string, relationshipType: string) {\n super(\n 'SELF_REFERENTIAL_RELATIONSHIP',\n `Self-referential relationship not allowed: \"${relationshipType}\" from entity \"${entityId}\" to itself`,\n `Relationships must connect two different entities. Check that sourceEntityId and targetEntityId refer to distinct entities.`,\n );\n this.name = 'SelfReferentialRelationshipError';\n this.entityId = entityId;\n this.relationshipType = relationshipType;\n }\n}\n\n/** Governance rules denied the operation */\nexport class GovernanceDeniedError extends DeepMemoryError {\n readonly governanceMode: string;\n\n constructor(governanceMode: string, reason: string) {\n super(\n 'GOVERNANCE_DENIED',\n `Governance denied: ${reason}`,\n governanceMode === 'locked'\n ? `The vocabulary is locked. Change governance mode to \"managed\" or \"open\" to allow modifications.`\n : `The operation was denied by governance rules. Review the governance configuration.`,\n );\n this.name = 'GovernanceDeniedError';\n this.governanceMode = governanceMode;\n }\n}\n\n/** A pre-mutation hook cancelled the operation */\nexport class OperationCancelledError extends DeepMemoryError {\n readonly operation: string;\n readonly reason: string;\n\n constructor(operation: string, reason: string) {\n super(\n 'OPERATION_CANCELLED',\n `${operation} cancelled: ${reason}`,\n `A pre-mutation hook cancelled this operation. Review registered hooks if this is unexpected.`,\n );\n this.name = 'OperationCancelledError';\n this.operation = operation;\n this.reason = reason;\n }\n}\n\n/** Semantic search was attempted without an embedding provider */\nexport class EmbeddingProviderRequiredError extends DeepMemoryError {\n constructor() {\n super(\n 'EMBEDDING_PROVIDER_REQUIRED',\n 'EmbeddingProvider required: no embedding provider is configured',\n `Provide an EmbeddingProvider in the DeepMemory config to use semantic search (searchByConcept).`,\n );\n this.name = 'EmbeddingProviderRequiredError';\n }\n}\n\n/** Error during import operations */\nexport class ImportError extends DeepMemoryError {\n constructor(message: string, suggestion?: string) {\n super(\n 'IMPORT_ERROR',\n message,\n suggestion ?? `Verify the archive format and check that the target repository is accessible.`,\n );\n this.name = 'ImportError';\n }\n}\n\n/** Error during export operations */\nexport class ExportError extends DeepMemoryError {\n constructor(message: string, suggestion?: string) {\n super(\n 'EXPORT_ERROR',\n message,\n suggestion ?? `Verify the repository exists and the storage provider is accessible.`,\n );\n this.name = 'ExportError';\n }\n}\n\n/** Generic provider-level error */\nexport class ProviderError extends DeepMemoryError {\n constructor(message: string, suggestion?: string) {\n super(\n 'PROVIDER_ERROR',\n message,\n suggestion ?? `Check provider configuration and connectivity.`,\n );\n this.name = 'ProviderError';\n }\n}\n\n/** Thrown when executeNativeQuery() is called but no GraphTraversalProvider is registered. */\nexport class GraphTraversalProviderRequiredError extends DeepMemoryError {\n constructor() {\n super(\n 'GRAPH_TRAVERSAL_PROVIDER_REQUIRED',\n 'GraphTraversalProvider required: no graph traversal provider is configured',\n `Provide a GraphTraversalProvider in the DeepMemory config to use native graph queries. Structured traversals via traverse() work without a provider using fallback BFS.`,\n );\n this.name = 'GraphTraversalProviderRequiredError';\n }\n}\n\n/** Thrown when a TraversalSpec is structurally invalid. */\nexport class TraversalValidationError extends DeepMemoryError {\n readonly errors: string[];\n\n constructor(errors: string[]) {\n super(\n 'TRAVERSAL_VALIDATION_FAILED',\n `Traversal validation failed: ${errors.join('; ')}`,\n `Check the TraversalSpec structure. Each spec needs a start (entityId, entityType, or filter), at least one step, and a returnMode.`,\n );\n this.name = 'TraversalValidationError';\n this.errors = errors;\n }\n}\n\n/** Thrown when a TraversalSpec references relationship/entity types not in the vocabulary. */\nexport class TraversalVocabularyError extends DeepMemoryError {\n readonly unknownTypes: string[];\n\n constructor(unknownTypes: string[]) {\n super(\n 'TRAVERSAL_VOCABULARY_ERROR',\n `Traversal references unknown types: ${unknownTypes.join(', ')}`,\n `Use getVocabulary() to see valid entity and relationship types for this repository.`,\n );\n this.name = 'TraversalVocabularyError';\n this.unknownTypes = unknownTypes;\n }\n}\n\n/** Thrown when a native query times out. */\nexport class TraversalTimeoutError extends DeepMemoryError {\n readonly timeoutMs: number;\n\n constructor(timeoutMs: number) {\n super(\n 'TRAVERSAL_TIMEOUT',\n `Traversal timed out after ${timeoutMs}ms`,\n `Try reducing the traversal depth, adding more specific filters, or increasing the timeout on your GraphTraversalProvider.`,\n );\n this.name = 'TraversalTimeoutError';\n this.timeoutMs = timeoutMs;\n }\n}\n","// IdGenerator — GUID and slug generation for entities and relationships\n\nimport { generateId } from '../core/DeepMemory.js';\n\n/**\n * Slugify a string for use in entity slugs.\n * Lowercases, replaces non-alphanumeric with hyphens, collapses/trims hyphens.\n */\nfunction slugify(text: string): string {\n return text\n .toLowerCase()\n .trim()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '');\n}\n\n/**\n * Generate a deterministic slug from type and label.\n * Format: `{type}:{slugified-label}`\n *\n * @param entityType - The entity type (e.g., \"person\")\n * @param label - The entity label (e.g., \"Tim Wheeler\")\n * @returns Slug (e.g., \"person:tim-wheeler\")\n */\nexport function generateSlug(entityType: string, label: string): string {\n const slug = slugify(label);\n return `${entityType}:${slug || 'unnamed'}`;\n}\n\n/**\n * Generate a unique slug, appending a suffix if the base slug already exists.\n *\n * @param entityType - The entity type\n * @param label - The entity label\n * @param existsCheck - Async function to check if a slug is already taken\n * @returns A unique slug\n */\nexport async function generateUniqueSlug(\n entityType: string,\n label: string,\n existsCheck: (slug: string) => Promise<boolean>,\n): Promise<string> {\n const baseSlug = generateSlug(entityType, label);\n\n if (!(await existsCheck(baseSlug))) {\n return baseSlug;\n }\n\n // Append incrementing suffix until unique\n for (let i = 2; i <= 100; i++) {\n const candidateSlug = `${baseSlug}-${i}`;\n if (!(await existsCheck(candidateSlug))) {\n return candidateSlug;\n }\n }\n\n // Fallback: append random suffix\n const randomSuffix = Math.random().toString(36).slice(2, 8);\n return `${baseSlug}-${randomSuffix}`;\n}\n\n/**\n * Generate a GUID for an entity.\n */\nexport function generateEntityId(): string {\n return generateId();\n}\n\n/**\n * Generate a GUID for a relationship.\n */\nexport function generateRelationshipId(): string {\n return generateId();\n}\n","// String similarity — Jaro-Winkler distance (zero dependencies)\n// Used by SemanticDeduplicator as fallback when no EmbeddingProvider is available\n\n/**\n * Compute Jaro similarity between two strings.\n * Returns a value between 0 (no similarity) and 1 (identical).\n */\nexport function jaroSimilarity(a: string, b: string): number {\n if (a === b) return 1;\n if (a.length === 0 || b.length === 0) return 0;\n\n const matchWindow = Math.max(Math.floor(Math.max(a.length, b.length) / 2) - 1, 0);\n\n const aMatches = new Array<boolean>(a.length).fill(false);\n const bMatches = new Array<boolean>(b.length).fill(false);\n\n let matches = 0;\n let transpositions = 0;\n\n // Find matches\n for (let i = 0; i < a.length; i++) {\n const start = Math.max(0, i - matchWindow);\n const end = Math.min(i + matchWindow + 1, b.length);\n\n for (let j = start; j < end; j++) {\n if (bMatches[j] || a[i] !== b[j]) continue;\n aMatches[i] = true;\n bMatches[j] = true;\n matches++;\n break;\n }\n }\n\n if (matches === 0) return 0;\n\n // Count transpositions\n let k = 0;\n for (let i = 0; i < a.length; i++) {\n if (!aMatches[i]) continue;\n while (!bMatches[k]) k++;\n if (a[i] !== b[k]) transpositions++;\n k++;\n }\n\n return (\n (matches / a.length + matches / b.length + (matches - transpositions / 2) / matches) / 3\n );\n}\n\n/**\n * Compute Jaro-Winkler similarity between two strings.\n * Gives extra weight to common prefixes (up to 4 characters).\n * Returns a value between 0 (no similarity) and 1 (identical).\n *\n * @param scalingFactor - Prefix scaling factor (default 0.1, max 0.25)\n */\nexport function jaroWinklerSimilarity(a: string, b: string, scalingFactor = 0.1): number {\n const jaro = jaroSimilarity(a, b);\n if (jaro === 0) return 0;\n\n // Common prefix length (max 4)\n const prefixLength = Math.min(4, Math.min(a.length, b.length));\n let commonPrefix = 0;\n for (let i = 0; i < prefixLength; i++) {\n if (a[i] === b[i]) {\n commonPrefix++;\n } else {\n break;\n }\n }\n\n return jaro + commonPrefix * Math.min(scalingFactor, 0.25) * (1 - jaro);\n}\n\n/**\n * Normalize a type name for comparison.\n * Lowercases, replaces separators with underscores, trims.\n */\nexport function normalizeTypeName(name: string): string {\n return name\n .toLowerCase()\n .trim()\n .replace(/[-\\s.]+/g, '_')\n .replace(/[^a-z0-9_]/g, '');\n}\n\n/**\n * Convert a relationship type name to SCREAMING_SNAKE_CASE.\n * Handles camelCase, PascalCase, kebab-case, dot.case, space-separated, and existing snake_case.\n *\n * Examples:\n * \"worksOn\" → \"WORKS_ON\"\n * \"works-on\" → \"WORKS_ON\"\n * \"works_on\" → \"WORKS_ON\"\n * \"WORKS_ON\" → \"WORKS_ON\" (idempotent)\n * \"Works On\" → \"WORKS_ON\"\n * \"componentOf\" → \"COMPONENT_OF\"\n */\nexport function toScreamingSnakeCase(name: string): string {\n return name\n .trim()\n // Insert underscore before uppercase letters that follow lowercase letters or digits (camelCase boundaries)\n .replace(/([a-z0-9])([A-Z])/g, '$1_$2')\n // Insert underscore between consecutive uppercase followed by lowercase (e.g., \"HTMLParser\" → \"HTML_Parser\")\n .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')\n // Replace hyphens, spaces, dots with underscores\n .replace(/[-\\s.]+/g, '_')\n // Remove any non-alphanumeric/underscore characters\n .replace(/[^A-Za-z0-9_]/g, '')\n // Collapse multiple underscores\n .replace(/_+/g, '_')\n // Remove leading/trailing underscores\n .replace(/^_+|_+$/g, '')\n .toUpperCase();\n}\n","// VocabularyValidator — validates entities and relationships against vocabulary definitions\n\nimport type { CreateEntityInput, UpdateEntityInput } from '../types/entities.js';\nimport type { CreateRelationshipInput } from '../types/relationships.js';\nimport type {\n EntityTypeDefinition,\n MemoryVocabulary,\n PropertySchema,\n RelationshipTypeDefinition,\n} from '../types/vocabulary.js';\nimport { toScreamingSnakeCase } from './similarity.js';\n\n/** A single validation error with optional suggestion */\nexport interface ValidationError {\n field: string;\n message: string;\n suggestion?: string;\n}\n\n/** Result of a validation check */\nexport interface ValidationResult {\n valid: boolean;\n errors: ValidationError[];\n}\n\nfunction ok(): ValidationResult {\n return { valid: true, errors: [] };\n}\n\nfunction fail(...errors: ValidationError[]): ValidationResult {\n return { valid: false, errors };\n}\n\nfunction merge(...results: ValidationResult[]): ValidationResult {\n const errors = results.flatMap((r) => r.errors);\n return { valid: errors.length === 0, errors };\n}\n\n/** Find the closest matching type name for suggestions */\nfunction findClosestType(typeName: string, types: Array<{ type: string }>): string | undefined {\n if (types.length === 0) return undefined;\n // Simple prefix/substring match for suggestions\n const lower = typeName.toLowerCase();\n const match = types.find(\n (t) => t.type.toLowerCase().includes(lower) || lower.includes(t.type.toLowerCase()),\n );\n return match?.type;\n}\n\n/** Validate a PropertySchema definition — catches invalid embeddable declarations */\nexport function validatePropertySchema(schema: PropertySchema): ValidationResult {\n if (schema.embeddable === true && schema.type !== 'string') {\n return fail({\n field: `properties.${schema.name}`,\n message: `Property \"${schema.name}\" cannot be embeddable — only string properties support embedding (type is \"${schema.type}\")`,\n });\n }\n return ok();\n}\n\n/** Validate a property value against its schema */\nexport function validatePropertyValue(\n name: string,\n value: unknown,\n schema: PropertySchema,\n): ValidationResult {\n if (value === undefined || value === null) {\n if (schema.required) {\n return fail({\n field: `properties.${name}`,\n message: `Required property \"${name}\" is missing`,\n });\n }\n return ok();\n }\n\n switch (schema.type) {\n case 'string':\n if (typeof value !== 'string') {\n return fail({\n field: `properties.${name}`,\n message: `Property \"${name}\" must be a string, got ${typeof value}`,\n });\n }\n break;\n\n case 'number':\n if (typeof value !== 'number' || Number.isNaN(value)) {\n return fail({\n field: `properties.${name}`,\n message: `Property \"${name}\" must be a number, got ${typeof value}`,\n });\n }\n break;\n\n case 'boolean':\n if (typeof value !== 'boolean') {\n return fail({\n field: `properties.${name}`,\n message: `Property \"${name}\" must be a boolean, got ${typeof value}`,\n });\n }\n break;\n\n case 'date':\n if (typeof value !== 'string' || Number.isNaN(Date.parse(value))) {\n return fail({\n field: `properties.${name}`,\n message: `Property \"${name}\" must be a valid ISO date string`,\n });\n }\n break;\n\n case 'enum':\n if (typeof value !== 'string') {\n return fail({\n field: `properties.${name}`,\n message: `Property \"${name}\" must be a string (enum value), got ${typeof value}`,\n });\n }\n if (schema.enumValues && !schema.enumValues.includes(value)) {\n return fail({\n field: `properties.${name}`,\n message: `Property \"${name}\" must be one of: ${schema.enumValues.join(', ')}`,\n suggestion: `Valid values: ${schema.enumValues.join(', ')}`,\n });\n }\n break;\n }\n\n return ok();\n}\n\n/** Validate properties against the type's property schemas */\nfunction validateProperties(\n properties: Record<string, unknown> | undefined,\n schemas: PropertySchema[],\n): ValidationResult {\n const results: ValidationResult[] = [];\n const providedProperties = properties ?? {};\n\n for (const schema of schemas) {\n const value = providedProperties[schema.name];\n results.push(validatePropertyValue(schema.name, value, schema));\n }\n\n // Only reject unknown properties when the vocab explicitly defines at least one\n // property for the type. A type with no properties defined is open to anything.\n if (schemas.length > 0) {\n const knownNames = new Set(schemas.map((s) => s.name));\n for (const key of Object.keys(providedProperties)) {\n if (!knownNames.has(key)) {\n results.push(fail({\n field: `properties.${key}`,\n message: `Unknown property \"${key}\"`,\n suggestion: `Known properties: ${schemas.map((s) => s.name).join(', ')}`,\n }));\n }\n }\n }\n\n return merge(...results);\n}\n\n/** Validate a CreateEntityInput against the vocabulary */\nexport function validateEntity(\n input: CreateEntityInput,\n vocabulary: MemoryVocabulary,\n): ValidationResult {\n const entityTypeDef = vocabulary.entityTypes.find((et) => et.type === input.entityType);\n\n if (!entityTypeDef) {\n const closest = findClosestType(input.entityType, vocabulary.entityTypes);\n return fail({\n field: 'entityType',\n message: `Entity type \"${input.entityType}\" does not exist in the vocabulary`,\n suggestion: closest\n ? `Did you mean \"${closest}\"?`\n : `Available types: ${vocabulary.entityTypes.map((et) => et.type).join(', ') || 'none'}`,\n });\n }\n\n if (!input.label || input.label.trim().length === 0) {\n return fail({\n field: 'label',\n message: 'Entity label is required and cannot be empty',\n });\n }\n\n return validateProperties(input.properties, entityTypeDef.properties);\n}\n\n/**\n * Validate an UpdateEntityInput against the vocabulary.\n *\n * When `input.entityType` is set and differs from `currentEntityTypeDef.type`,\n * the target type must exist in the vocabulary, and any provided properties\n * are validated against the new type's schema (not the current type's).\n */\nexport function validateEntityUpdate(\n input: UpdateEntityInput,\n currentEntityTypeDef: EntityTypeDefinition,\n vocabulary: MemoryVocabulary,\n): ValidationResult {\n if (input.label !== undefined && input.label.trim().length === 0) {\n return fail({\n field: 'label',\n message: 'Entity label cannot be empty',\n });\n }\n\n // Resolve the target type definition — either the new type (if changing) or the current one.\n let targetTypeDef: EntityTypeDefinition = currentEntityTypeDef;\n if (input.entityType !== undefined && input.entityType !== currentEntityTypeDef.type) {\n const newTypeDef = vocabulary.entityTypes.find((et) => et.type === input.entityType);\n if (!newTypeDef) {\n const closest = findClosestType(input.entityType, vocabulary.entityTypes);\n return fail({\n field: 'entityType',\n message: `Entity type \"${input.entityType}\" does not exist in the vocabulary`,\n suggestion: closest\n ? `Did you mean \"${closest}\"?`\n : `Available types: ${vocabulary.entityTypes.map((et) => et.type).join(', ') || 'none'}`,\n });\n }\n targetTypeDef = newTypeDef;\n }\n\n // Only validate provided properties — updates are partial.\n // Validated against the target type (new if changing, else current).\n if (input.properties) {\n const results: ValidationResult[] = [];\n const hasDefinedProps = targetTypeDef.properties.length > 0;\n for (const [key, value] of Object.entries(input.properties)) {\n // RFC 7396 JSON Merge Patch: null signals deletion of the key, so skip\n // schema validation for it — an unknown or ill-typed property being\n // removed should never block the update.\n if (value === null) continue;\n const schema = targetTypeDef.properties.find((p) => p.name === key);\n if (!schema) {\n if (hasDefinedProps) {\n results.push(fail({\n field: `properties.${key}`,\n message: `Unknown property \"${key}\"`,\n suggestion: `Known properties: ${targetTypeDef.properties.map((p) => p.name).join(', ')}`,\n }));\n }\n } else {\n results.push(validatePropertyValue(key, value, schema));\n }\n }\n return merge(...results);\n }\n\n return ok();\n}\n\n/** Validate a CreateRelationshipInput against the vocabulary */\nexport function validateRelationship(\n input: CreateRelationshipInput,\n vocabulary: MemoryVocabulary,\n sourceEntityType: string,\n targetEntityType: string,\n): ValidationResult {\n const normalizedType = toScreamingSnakeCase(input.relationshipType);\n const relTypeDef = vocabulary.relationshipTypes.find(\n (rt) => rt.type === normalizedType,\n );\n\n if (!relTypeDef) {\n const closest = findClosestType(input.relationshipType, vocabulary.relationshipTypes);\n return fail({\n field: 'relationshipType',\n message: `Relationship type \"${input.relationshipType}\" does not exist in the vocabulary`,\n suggestion: closest\n ? `Did you mean \"${closest}\"?`\n : `Available types: ${vocabulary.relationshipTypes.map((rt) => rt.type).join(', ') || 'none'}`,\n });\n }\n\n const results: ValidationResult[] = [];\n\n // Validate source entity type constraint\n if (\n relTypeDef.allowedSourceTypes.length > 0 &&\n !relTypeDef.allowedSourceTypes.includes(sourceEntityType)\n ) {\n results.push(\n fail({\n field: 'sourceEntityId',\n message: `Entity type \"${sourceEntityType}\" is not allowed as source for relationship type \"${input.relationshipType}\"`,\n suggestion: `Allowed source types: ${relTypeDef.allowedSourceTypes.join(', ')}`,\n }),\n );\n }\n\n // Validate target entity type constraint\n if (\n relTypeDef.allowedTargetTypes.length > 0 &&\n !relTypeDef.allowedTargetTypes.includes(targetEntityType)\n ) {\n results.push(\n fail({\n field: 'targetEntityId',\n message: `Entity type \"${targetEntityType}\" is not allowed as target for relationship type \"${input.relationshipType}\"`,\n suggestion: `Allowed target types: ${relTypeDef.allowedTargetTypes.join(', ')}`,\n }),\n );\n }\n\n // Validate relationship properties\n if (relTypeDef.properties) {\n results.push(\n validateProperties(input.properties, relTypeDef.properties),\n );\n }\n\n return merge(...results);\n}\n\n/** Get an entity type definition from the vocabulary, or null if not found */\nexport function getEntityTypeDef(\n entityType: string,\n vocabulary: MemoryVocabulary,\n): EntityTypeDefinition | null {\n return vocabulary.entityTypes.find((et) => et.type === entityType) ?? null;\n}\n\n/** Get a relationship type definition from the vocabulary, or null if not found */\nexport function getRelationshipTypeDef(\n relationshipType: string,\n vocabulary: MemoryVocabulary,\n): RelationshipTypeDefinition | null {\n const normalized = toScreamingSnakeCase(relationshipType);\n return vocabulary.relationshipTypes.find((rt) => rt.type === normalized) ?? null;\n}\n","// EntityManager — CRUD orchestration for entities with validation, provenance, and events\n\nimport type { StorageProvider } from '../providers/StorageProvider.js';\nimport type { EmbeddingProvider } from '../providers/EmbeddingProvider.js';\nimport type {\n CreateEntityInput,\n DetailLevel,\n Entity,\n EntityBrief,\n EntitySummary,\n StoredEntity,\n UpdateEntityInput,\n} from '../types/entities.js';\nimport type { PaginatedResult, ReembedResult } from '../types/results.js';\nimport type { FindEntitiesQuery, StorageFindQuery } from '../types/queries.js';\nimport type { DeleteEntitiesResult } from '../types/entities.js';\nimport type { VocabularyEngine } from '../core/VocabularyEngine.js';\nimport type { ProvenanceTracker } from '../core/ProvenanceTracker.js';\nimport type { EventBus } from '../core/EventBus.js';\nimport { generateEntityId, generateUniqueSlug } from './IdGenerator.js';\nimport {\n EntityNotFoundError,\n VocabularyValidationError,\n OperationCancelledError,\n EmbeddingProviderRequiredError,\n} from '../core/errors.js';\nimport { getEntityTypeDef } from '../vocabulary/VocabularyValidator.js';\n\nexport class EntityManager {\n private embedding?: EmbeddingProvider;\n\n constructor(\n private readonly repositoryId: string,\n private readonly vocabularyEngine: VocabularyEngine,\n private readonly provenanceTracker: ProvenanceTracker,\n private readonly eventBus: EventBus,\n private readonly storage: StorageProvider,\n embedding?: EmbeddingProvider,\n ) {\n this.embedding = embedding;\n }\n\n /** Swap the embedding provider, e.g. after a repository re-embed changes the model or dimensionality */\n setEmbeddingProvider(embedding: EmbeddingProvider | undefined): void {\n this.embedding = embedding;\n }\n\n /** Create one or more entities with vocabulary validation, ID generation, provenance, and events */\n async create(inputs: CreateEntityInput[]): Promise<Entity[]> {\n const results: Entity[] = [];\n\n for (const input of inputs) {\n // Validate against vocabulary\n const validation = await this.vocabularyEngine.validateEntity(input);\n if (!validation.valid) {\n const errorMsg = validation.errors.map((e) => e.message).join('; ');\n const suggestions = validation.errors\n .filter((e) => e.suggestion)\n .map((e) => e.suggestion!);\n\n await this.eventBus.emit('validation:failed', {\n operation: 'createEntity',\n error: errorMsg,\n suggestions,\n });\n\n throw new VocabularyValidationError(validation.errors);\n }\n\n // Pre-mutation hook\n const hookResult = await this.eventBus.emitHook('entity:creating', { input });\n if (hookResult.cancelled) {\n throw new OperationCancelledError('Entity creation', hookResult.reason ?? 'cancelled by hook');\n }\n\n // Generate GUID (or use provided)\n const id = input.id ?? generateEntityId();\n\n // Generate unique slug\n const slug = await generateUniqueSlug(\n input.entityType,\n input.label,\n async (candidateSlug) => {\n const existing = await this.storage.getEntityBySlug(this.repositoryId, candidateSlug);\n return existing !== null;\n },\n );\n\n // Stamp provenance\n const provenance = this.provenanceTracker.stampCreate();\n\n // Generate embedding if provider available\n const entityEmbedding = await this.generateEmbedding(input.label, input.summary, input.properties ?? {}, input.entityType);\n\n // Build stored entity\n const storedEntity: StoredEntity = {\n id,\n slug,\n entityType: input.entityType,\n label: input.label,\n summary: input.summary,\n properties: input.properties ?? {},\n data: input.data,\n dataFormat: input.dataFormat,\n provenance,\n embedding: entityEmbedding,\n };\n\n // Persist\n const created = await this.storage.createEntity(this.repositoryId, storedEntity);\n\n // Map to public type\n const entity = storedToEntity(created);\n\n // Emit created event\n await this.eventBus.emit('entity:created', { entity });\n\n results.push(entity);\n }\n\n return results;\n }\n\n /** Update an existing entity */\n async update(entityId: string, updates: UpdateEntityInput): Promise<Entity> {\n // Get existing entity to determine its type for validation\n const existing = await this.storage.getEntity(this.repositoryId, entityId);\n if (!existing) {\n throw new EntityNotFoundError(entityId);\n }\n\n // Validate updates against vocabulary\n const validation = await this.vocabularyEngine.validateEntityUpdate(\n updates,\n existing.entityType,\n );\n if (!validation.valid) {\n await this.eventBus.emit('validation:failed', {\n operation: 'updateEntity',\n error: validation.errors.map((e) => e.message).join('; '),\n suggestions: validation.errors.filter((e) => e.suggestion).map((e) => e.suggestion!),\n });\n throw new VocabularyValidationError(validation.errors);\n }\n\n // Pre-mutation hook\n const hookResult = await this.eventBus.emitHook('entity:updating', {\n id: entityId,\n updates,\n });\n if (hookResult.cancelled) {\n throw new OperationCancelledError('Entity update', hookResult.reason ?? 'cancelled by hook');\n }\n\n // Stamp provenance\n const provenance = this.provenanceTracker.stampUpdate(existing.provenance);\n\n // Merge properties. RFC 7396 semantics: incoming `null` values delete the\n // corresponding key rather than storing `null`.\n let mergedProperties = existing.properties;\n if (updates.properties) {\n const merged: Record<string, unknown> = { ...existing.properties };\n for (const [key, value] of Object.entries(updates.properties)) {\n if (value === null) {\n delete merged[key];\n } else {\n merged[key] = value;\n }\n }\n mergedProperties = merged;\n }\n\n // Regenerate slug when entityType or label changes — both are part of the slug.\n const typeChanged = updates.entityType !== undefined && updates.entityType !== existing.entityType;\n const labelChanged = updates.label !== undefined && updates.label !== existing.label;\n let newSlug: string | undefined;\n if (typeChanged || labelChanged) {\n const nextType = updates.entityType ?? existing.entityType;\n const nextLabel = updates.label ?? existing.label;\n newSlug = await generateUniqueSlug(\n nextType,\n nextLabel,\n async (candidateSlug) => {\n if (candidateSlug === existing.slug) return false; // the entity's own slug isn't a conflict\n const other = await this.storage.getEntityBySlug(this.repositoryId, candidateSlug);\n return other !== null;\n },\n );\n }\n\n // Regenerate embedding if label/summary changed or reembed explicitly requested.\n // `summary === null` means \"clear\", so the embedding is computed from label alone.\n // Reembed when label, summary, or any property changes (properties may include embeddable ones).\n const needsReembed = updates.reembed === true || updates.label !== undefined || updates.summary !== undefined || updates.properties !== undefined;\n const nextSummary = updates.summary === undefined ? existing.summary : (updates.summary ?? undefined);\n const nextEntityType = updates.entityType ?? existing.entityType;\n const entityEmbedding = needsReembed\n ? await this.generateEmbedding(updates.label ?? existing.label, nextSummary, mergedProperties, nextEntityType)\n : undefined; // undefined preserves the existing embedding in storage\n\n // Persist\n const updated = await this.storage.updateEntity(this.repositoryId, entityId, {\n entityType: typeChanged ? updates.entityType : undefined,\n label: updates.label,\n slug: newSlug,\n summary: updates.summary,\n properties: updates.properties ? mergedProperties : undefined,\n data: updates.data,\n dataFormat: updates.dataFormat,\n provenance,\n embedding: entityEmbedding,\n });\n\n const entity = storedToEntity(updated);\n await this.eventBus.emit('entity:updated', { entity });\n\n return entity;\n }\n\n /** Get a single entity with configurable detail level */\n async get(entityId: string, detailLevel: DetailLevel = 'full'): Promise<Entity | EntitySummary | EntityBrief | null> {\n const stored = await this.storage.getEntity(this.repositoryId, entityId);\n if (!stored) return null;\n\n switch (detailLevel) {\n case 'brief':\n return storedToBrief(stored);\n case 'summary':\n return storedToSummary(stored);\n case 'full':\n default:\n return storedToEntity(stored);\n }\n }\n\n /** Get an entity by its slug */\n async getBySlug(slug: string, detailLevel: DetailLevel = 'full'): Promise<Entity | EntitySummary | EntityBrief | null> {\n const stored = await this.storage.getEntityBySlug(this.repositoryId, slug);\n if (!stored) return null;\n\n switch (detailLevel) {\n case 'brief':\n return storedToBrief(stored);\n case 'summary':\n return storedToSummary(stored);\n case 'full':\n default:\n return storedToEntity(stored);\n }\n }\n\n /** Get multiple entities in a single call (max 50, brief or summary only) */\n async getMany(\n entityIds: string[],\n detailLevel: 'brief' | 'summary' = 'summary',\n ): Promise<Map<string, EntitySummary | EntityBrief>> {\n const ids = entityIds.slice(0, 50);\n const storedMap = await this.storage.getEntities(this.repositoryId, ids);\n const result = new Map<string, EntitySummary | EntityBrief>();\n\n for (const [id, stored] of storedMap) {\n result.set(\n id,\n detailLevel === 'brief' ? storedToBrief(stored) : storedToSummary(stored),\n );\n }\n\n return result;\n }\n\n /** Find entities by search criteria */\n async find(query: FindEntitiesQuery): Promise<PaginatedResult<EntitySummary>> {\n const storageQuery: StorageFindQuery = {\n searchTerm: query.searchTerm,\n entityTypes: query.entityTypes,\n properties: query.properties,\n limit: Math.min(query.limit ?? 10, 50),\n offset: query.offset ?? 0,\n };\n\n const result = await this.storage.findEntities(this.repositoryId, storageQuery);\n\n return {\n items: result.items.map(storedToSummary),\n total: result.total,\n hasMore: result.hasMore,\n limit: result.limit,\n offset: result.offset,\n };\n }\n\n /** Delete an entity — throws EntityNotFoundError if it does not exist */\n async delete(entityId: string): Promise<void> {\n const existing = await this.storage.getEntity(this.repositoryId, entityId);\n if (!existing) {\n throw new EntityNotFoundError(entityId);\n }\n\n const hookResult = await this.eventBus.emitHook('entity:deleting', { ids: [entityId] });\n if (hookResult.cancelled) {\n throw new OperationCancelledError('Entity deletion', hookResult.reason ?? 'cancelled by hook');\n }\n\n await this.storage.deleteEntity(this.repositoryId, entityId);\n await this.eventBus.emit('entity:deleted', { ids: [entityId] });\n }\n\n /** Delete multiple entities in a single batch operation */\n async deleteMany(ids: string[]): Promise<DeleteEntitiesResult> {\n const hookResult = await this.eventBus.emitHook('entity:deleting', { ids });\n if (hookResult.cancelled) {\n throw new OperationCancelledError('Entity deletion', hookResult.reason ?? 'cancelled by hook');\n }\n\n const { deleted, notFound } = await this.storage.deleteEntities(this.repositoryId, ids);\n\n if (deleted.length > 0) {\n await this.eventBus.emit('entity:deleted', { ids: deleted });\n }\n\n return {\n deleted,\n failed: notFound.map((id) => ({ id, error: `Entity '${id}' not found` })),\n };\n }\n\n /**\n * Re-embed a specific set of entities using the current EmbeddingProvider.\n * Retries embedBatch up to maxRetries times with exponential backoff on failure.\n */\n async reembedEntities(entityIds: string[], options?: {\n maxRetries?: number;\n }): Promise<ReembedResult> {\n if (!this.embedding) {\n throw new EmbeddingProviderRequiredError();\n }\n\n const maxRetries = options?.maxRetries ?? 3;\n\n const storedMap = await this.storage.getEntities(this.repositoryId, entityIds);\n const entries = Array.from(storedMap.entries());\n\n const vocab = await this.vocabularyEngine.getVocabulary();\n const texts = entries.map(([, e]) => {\n const typeDef = getEntityTypeDef(e.entityType, vocab);\n const embeddableValues = typeDef\n ? typeDef.properties\n .filter((p) => p.embeddable === true && typeof e.properties[p.name] === 'string')\n .map((p) => e.properties[p.name] as string)\n : [];\n return [e.label, e.summary ?? '', ...embeddableValues].filter(Boolean).join(' ');\n });\n\n // Attempt embedBatch with retry and exponential backoff\n let embeddings: number[][];\n let attempt = 0;\n while (true) {\n try {\n embeddings = await this.embedding.embedBatch(texts);\n break;\n } catch (err) {\n attempt++;\n if (attempt > maxRetries) {\n // All retries exhausted — record every entity in this batch as failed\n const errorMsg = err instanceof Error ? err.message : String(err);\n return {\n processed: 0,\n failed: entries.length,\n errors: entries.map(([id]) => ({ entityId: id, error: `embedBatch failed after ${maxRetries} retries: ${errorMsg}` })),\n modelId: this.embedding.modelId(),\n dimensions: this.embedding.dimensions(),\n };\n }\n // Exponential backoff: 1s, 2s, 4s, ...\n const backoffMs = 1000 * (2 ** (attempt - 1));\n await new Promise<void>((resolve) => { setTimeout(resolve, backoffMs); });\n }\n }\n\n // Persist embeddings — individual storage failures are non-fatal\n const errors: Array<{ entityId: string; error: string }> = [];\n let processed = 0;\n\n for (let i = 0; i < entries.length; i++) {\n const [id, entity] = entries[i]!;\n try {\n await this.storage.updateEntity(this.repositoryId, id, {\n provenance: entity.provenance, // preserve existing provenance — not a content edit\n embedding: embeddings[i],\n });\n processed++;\n } catch (err) {\n errors.push({ entityId: id, error: err instanceof Error ? err.message : String(err) });\n }\n }\n\n return {\n processed,\n failed: errors.length,\n errors,\n modelId: this.embedding.modelId(),\n dimensions: this.embedding.dimensions(),\n };\n }\n\n /**\n * Re-embed all entities in the repository, processing in batches.\n * @param options.batchSize — entities per batch (default 50)\n * @param options.maxRetries — retries per batch on embedding failure (default 3)\n * @param options.errorThresholdToAbort — abort after this many cumulative failures (default: no limit)\n * @param options.delayBetweenBatchesMs — milliseconds to wait between batches for rate limiting (default 0)\n * @param options.onProgress — callback invoked after each batch\n */\n async reembedAll(options?: {\n batchSize?: number;\n maxRetries?: number;\n errorThresholdToAbort?: number;\n delayBetweenBatchesMs?: number;\n onProgress?: (processed: number, total: number, failed: number) => void;\n }): Promise<ReembedResult> {\n if (!this.embedding) {\n throw new EmbeddingProviderRequiredError();\n }\n\n const batchSize = options?.batchSize ?? 50;\n const errorThreshold = options?.errorThresholdToAbort;\n\n // Count total entities\n const firstPage = await this.storage.findEntities(this.repositoryId, { limit: 1, offset: 0 });\n const total = firstPage.total;\n\n let totalProcessed = 0;\n let totalFailed = 0;\n const allErrors: Array<{ entityId: string; error: string }> = [];\n let offset = 0;\n\n while (offset < total) {\n const page = await this.storage.findEntities(this.repositoryId, {\n limit: batchSize,\n offset,\n });\n\n if (page.items.length === 0) break;\n\n const ids = page.items.map((e) => e.id);\n const result = await this.reembedEntities(ids, {\n maxRetries: options?.maxRetries,\n });\n\n totalProcessed += result.processed;\n totalFailed += result.failed;\n allErrors.push(...result.errors);\n\n options?.onProgress?.(totalProcessed, total, totalFailed);\n\n // Check abort threshold\n if (errorThreshold !== undefined && totalFailed >= errorThreshold) {\n allErrors.push({ entityId: '', error: `Aborted: error threshold of ${errorThreshold} reached (${totalFailed} failures)` });\n break;\n }\n\n offset += page.items.length;\n\n // Rate limiting: pause between batches if configured\n const delayMs = options?.delayBetweenBatchesMs ?? 0;\n if (delayMs > 0 && offset < total) {\n await new Promise<void>((resolve) => { setTimeout(resolve, delayMs); });\n }\n }\n\n return {\n processed: totalProcessed,\n failed: totalFailed,\n errors: allErrors,\n modelId: this.embedding.modelId(),\n dimensions: this.embedding.dimensions(),\n };\n }\n\n /** Generate an embedding vector from label + summary + embeddable string properties if a provider is available */\n private async generateEmbedding(label: string, summary: string | undefined, properties: Record<string, unknown>, entityType: string): Promise<number[] | undefined> {\n if (!this.embedding) return undefined;\n const vocab = await this.vocabularyEngine.getVocabulary();\n const typeDef = getEntityTypeDef(entityType, vocab);\n const embeddableValues = typeDef\n ? typeDef.properties\n .filter((p) => p.embeddable === true && typeof properties[p.name] === 'string')\n .map((p) => properties[p.name] as string)\n : [];\n const text = [label, summary ?? '', ...embeddableValues].filter(Boolean).join(' ');\n return this.embedding.embed(text);\n }\n}\n\n// ─── Mapping helpers ────────────────────────────────────────────────\n\nfunction storedToEntity(stored: StoredEntity): Entity {\n return {\n id: stored.id,\n slug: stored.slug,\n entityType: stored.entityType,\n label: stored.label,\n summary: stored.summary,\n properties: stored.properties,\n data: stored.data,\n dataFormat: stored.dataFormat,\n provenance: stored.provenance,\n };\n}\n\nfunction storedToSummary(stored: StoredEntity): EntitySummary {\n return {\n id: stored.id,\n slug: stored.slug,\n entityType: stored.entityType,\n label: stored.label,\n summary: stored.summary,\n properties: stored.properties,\n };\n}\n\nfunction storedToBrief(stored: StoredEntity): EntityBrief {\n return {\n id: stored.id,\n slug: stored.slug,\n entityType: stored.entityType,\n label: stored.label,\n summary: stored.summary,\n };\n}\n","// RelationshipManager — CRUD orchestration for relationships with validation, provenance, and events\n\nimport type { StorageProvider } from '../providers/StorageProvider.js';\nimport type {\n CreateRelationshipInput,\n Relationship,\n RelationshipQueryOptions,\n RemoveRelationshipsResult,\n StoredRelationship,\n} from '../types/relationships.js';\nimport type { PaginatedResult } from '../types/results.js';\nimport type { VocabularyEngine } from '../core/VocabularyEngine.js';\nimport type { ProvenanceTracker } from '../core/ProvenanceTracker.js';\nimport type { EventBus } from '../core/EventBus.js';\nimport { generateRelationshipId } from '../entities/IdGenerator.js';\nimport { toScreamingSnakeCase } from '../vocabulary/similarity.js';\nimport {\n EntityNotFoundError,\n VocabularyValidationError,\n OperationCancelledError,\n SelfReferentialRelationshipError,\n} from '../core/errors.js';\n\nexport class RelationshipManager {\n constructor(\n private readonly repositoryId: string,\n private readonly vocabularyEngine: VocabularyEngine,\n private readonly provenanceTracker: ProvenanceTracker,\n private readonly eventBus: EventBus,\n private readonly storage: StorageProvider,\n ) {}\n\n /** Create one or more relationships with vocabulary validation, provenance, and events */\n async create(inputs: CreateRelationshipInput[]): Promise<Relationship[]> {\n const results: Relationship[] = [];\n\n for (const input of inputs) {\n if (input.sourceEntityId === input.targetEntityId) {\n throw new SelfReferentialRelationshipError(input.sourceEntityId, input.relationshipType);\n }\n\n // Resolve source and target entity types for constraint validation\n const sourceEntity = await this.storage.getEntity(this.repositoryId, input.sourceEntityId);\n if (!sourceEntity) {\n throw new EntityNotFoundError(input.sourceEntityId);\n }\n\n const targetEntity = await this.storage.getEntity(this.repositoryId, input.targetEntityId);\n if (!targetEntity) {\n throw new EntityNotFoundError(input.targetEntityId);\n }\n\n // Validate against vocabulary\n const validation = await this.vocabularyEngine.validateRelationship(\n input,\n sourceEntity.entityType,\n targetEntity.entityType,\n );\n if (!validation.valid) {\n await this.eventBus.emit('validation:failed', {\n operation: 'createRelationship',\n error: validation.errors.map((e) => e.message).join('; '),\n suggestions: validation.errors.filter((e) => e.suggestion).map((e) => e.suggestion!),\n });\n throw new VocabularyValidationError(validation.errors);\n }\n\n // Pre-mutation hook\n const hookResult = await this.eventBus.emitHook('relationship:creating', { input });\n if (hookResult.cancelled) {\n throw new OperationCancelledError(\n 'Relationship creation', hookResult.reason ?? 'cancelled by hook',\n );\n }\n\n // Normalize relationship type to SCREAMING_SNAKE_CASE\n const normalizedType = toScreamingSnakeCase(input.relationshipType);\n\n // Get relationship type definition for bidirectional flag\n const vocabulary = await this.vocabularyEngine.getVocabulary();\n const relType = vocabulary.relationshipTypes.find((rt) => rt.type === normalizedType);\n const bidirectional = relType?.bidirectional ?? false;\n\n // Generate GUID (or use provided)\n const id = input.id ?? generateRelationshipId();\n\n // Stamp provenance\n const provenance = this.provenanceTracker.stampCreate();\n\n // Build stored relationship\n const storedRelationship: StoredRelationship = {\n id,\n relationshipType: normalizedType,\n sourceEntityId: input.sourceEntityId,\n targetEntityId: input.targetEntityId,\n properties: input.properties ?? {},\n bidirectional,\n provenance,\n };\n\n // Persist\n const created = await this.storage.createRelationship(this.repositoryId, storedRelationship);\n\n // Map to public type\n const relationship = storedToRelationship(created);\n\n // Emit created event\n await this.eventBus.emit('relationship:created', { relationship });\n\n results.push(relationship);\n }\n\n return results;\n }\n\n /** Remove one or more relationships in a single batch storage operation */\n async removeMany(ids: string[]): Promise<RemoveRelationshipsResult> {\n const hookResult = await this.eventBus.emitHook('relationship:removing', { ids });\n if (hookResult.cancelled) {\n throw new OperationCancelledError('Relationship removal', hookResult.reason ?? 'cancelled by hook');\n }\n\n const { deleted, notFound } = await this.storage.deleteRelationships(this.repositoryId, ids);\n\n if (deleted.length > 0) {\n await this.eventBus.emit('relationship:removed', { ids: deleted });\n }\n\n return {\n removed: deleted,\n failed: notFound.map((id) => ({ id, error: `Relationship '${id}' not found` })),\n };\n }\n\n /** Get relationships for an entity with filtering */\n async getForEntity(\n entityId: string,\n options?: RelationshipQueryOptions,\n ): Promise<PaginatedResult<Relationship>> {\n const result = await this.storage.getEntityRelationships(\n this.repositoryId,\n entityId,\n options,\n );\n\n return {\n items: result.items.map(storedToRelationship),\n total: result.total,\n hasMore: result.hasMore,\n limit: result.limit,\n offset: result.offset,\n };\n }\n}\n\n// ─── Mapping helpers ────────────────────────────────────────────────\n\nfunction storedToRelationship(stored: StoredRelationship): Relationship {\n return {\n id: stored.id,\n relationshipType: stored.relationshipType,\n sourceEntityId: stored.sourceEntityId,\n targetEntityId: stored.targetEntityId,\n properties: stored.properties,\n bidirectional: stored.bidirectional,\n provenance: stored.provenance,\n };\n}\n","// Entity projection — maps StoredEntity to the appropriate detail level\n\nimport type {\n DetailLevel,\n Entity,\n EntityBrief,\n EntitySummary,\n StoredEntity,\n} from '../types/entities.js';\n\n/** Project a stored entity to the requested detail level */\nexport function projectEntity(stored: StoredEntity, level: DetailLevel): Entity | EntitySummary | EntityBrief {\n switch (level) {\n case 'brief':\n return {\n id: stored.id,\n slug: stored.slug,\n entityType: stored.entityType,\n label: stored.label,\n summary: stored.summary,\n };\n case 'summary':\n return {\n id: stored.id,\n slug: stored.slug,\n entityType: stored.entityType,\n label: stored.label,\n summary: stored.summary,\n properties: stored.properties,\n };\n case 'full':\n return {\n id: stored.id,\n slug: stored.slug,\n entityType: stored.entityType,\n label: stored.label,\n summary: stored.summary,\n properties: stored.properties,\n data: stored.data,\n dataFormat: stored.dataFormat,\n provenance: stored.provenance,\n };\n }\n}\n\n/** Project an EntitySummary down to brief level */\nexport function projectSummaryToBrief(entity: EntitySummary): EntityBrief {\n return {\n id: entity.id,\n slug: entity.slug,\n entityType: entity.entityType,\n label: entity.label,\n summary: entity.summary,\n };\n}\n","// TraversalValidator — validates a TraversalSpec against structural\n// constraints and the repository vocabulary before execution.\n\nimport type { TraversalSpec } from '../types/traversal.js';\nimport type { MemoryVocabulary } from '../types/vocabulary.js';\nimport type { GraphTraversalCapabilities } from '../providers/GraphTraversalProvider.js';\n\nexport interface ValidationResult {\n valid: boolean;\n errors: string[];\n}\n\nconst DEFAULT_MAX_STEPS = 6;\nconst DEFAULT_MAX_LIMIT = 200;\nconst DEFAULT_FALLBACK_MAX_DEPTH = 10;\n\n/**\n * Validates a TraversalSpec against structural rules and vocabulary.\n * Returns all validation failures rather than stopping at the first.\n */\nexport function validateTraversalSpec(\n spec: TraversalSpec,\n vocabulary?: MemoryVocabulary,\n capabilities?: GraphTraversalCapabilities,\n): ValidationResult {\n const errors: string[] = [];\n const steps = spec.steps ?? [];\n\n // ─── Structural validation ────────────────────────────────────\n\n // Start must have at least one of entityId, entityType, or filter\n if (!spec.start) {\n errors.push('start is required');\n } else {\n const hasEntityId = spec.start.entityId !== undefined && spec.start.entityId !== '';\n const hasEntityType = spec.start.entityType !== undefined && spec.start.entityType !== '';\n const hasFilter = spec.start.filter !== undefined && spec.start.filter.length > 0;\n\n if (!hasEntityId && !hasEntityType && !hasFilter) {\n errors.push('start must have at least one of entityId, entityType, or filter');\n }\n\n // start.entityType without entityId requires limit on the spec\n if (hasEntityType && !hasEntityId && (spec.limit === undefined || spec.limit === 0)) {\n errors.push('start.entityType without entityId requires limit on the spec to prevent full type scans');\n }\n }\n\n // Steps are optional (zero steps = vertex query), but validate if present\n const maxSteps = capabilities?.maxTraversalDepth ?? DEFAULT_MAX_STEPS;\n if (steps.length > maxSteps) {\n errors.push(`steps length ${steps.length} exceeds maximum ${maxSteps}`);\n }\n\n // Validate individual steps\n for (let i = 0; i < steps.length; i++) {\n const step = steps[i]!;\n\n if (!step.direction || !['out', 'in', 'both'].includes(step.direction)) {\n errors.push(`steps[${i}].direction must be 'out', 'in', or 'both'`);\n }\n\n if (step.repeat) {\n if (step.repeat.maxDepth === undefined || step.repeat.maxDepth <= 0) {\n errors.push(`steps[${i}].repeat.maxDepth must be a positive number`);\n }\n }\n }\n\n // Total potential depth check (only when steps present)\n if (steps.length > 0) {\n const maxProviderDepth = capabilities?.maxTraversalDepth ?? DEFAULT_FALLBACK_MAX_DEPTH;\n let totalDepth = 0;\n for (const step of steps) {\n totalDepth += step.repeat ? step.repeat.maxDepth : 1;\n }\n if (totalDepth > maxProviderDepth) {\n errors.push(`total potential depth ${totalDepth} exceeds provider maximum ${maxProviderDepth}`);\n }\n }\n\n // Path mode requires at least one step\n if (spec.returnMode === 'path' && steps.length === 0) {\n errors.push(\"returnMode 'path' requires at least one step\");\n }\n\n // Return mode\n if (spec.returnMode && !['terminal', 'path', 'all'].includes(spec.returnMode)) {\n errors.push(`returnMode must be 'terminal', 'path', or 'all'`);\n }\n\n // Projection validation\n if (spec.projection) {\n if (!spec.projection.properties || spec.projection.properties.length === 0) {\n errors.push('projection.properties must contain at least one property name');\n }\n if (spec.projection.mode && !['count', 'values'].includes(spec.projection.mode)) {\n errors.push(\"projection.mode must be 'count' or 'values'\");\n }\n }\n\n // Limit bounds\n if (spec.limit !== undefined) {\n if (spec.limit < 1 || spec.limit > DEFAULT_MAX_LIMIT) {\n errors.push(`limit must be between 1 and ${DEFAULT_MAX_LIMIT}`);\n }\n }\n\n // Offset bounds\n if (spec.offset !== undefined && spec.offset < 0) {\n errors.push('offset must be >= 0');\n }\n\n // ─── Vocabulary validation ────────────────────────────────────\n\n if (vocabulary) {\n const entityTypeSet = new Set(vocabulary.entityTypes.map((et) => et.type));\n const relationshipTypeSet = new Set(vocabulary.relationshipTypes.map((rt) => rt.type));\n const unknownTypes: string[] = [];\n\n // Validate start.entityType\n if (spec.start?.entityType && !entityTypeSet.has(spec.start.entityType)) {\n unknownTypes.push(`entity type \"${spec.start.entityType}\"`);\n }\n\n // Validate types in each step\n for (let i = 0; i < steps.length; i++) {\n const step = steps[i]!;\n\n if (step.relationshipTypes) {\n for (const rt of step.relationshipTypes) {\n if (!relationshipTypeSet.has(rt)) {\n unknownTypes.push(`relationship type \"${rt}\" in steps[${i}]`);\n }\n }\n }\n\n if (step.entityTypes) {\n for (const et of step.entityTypes) {\n if (!entityTypeSet.has(et)) {\n unknownTypes.push(`entity type \"${et}\" in steps[${i}]`);\n }\n }\n }\n }\n\n if (unknownTypes.length > 0) {\n errors.push(`Unknown vocabulary types: ${unknownTypes.join(', ')}`);\n }\n }\n\n return {\n valid: errors.length === 0,\n errors,\n };\n}\n","// PropertyFilterMatcher — evaluates property filters against relationship properties\n\nimport type { PropertyFilter } from '../types/queries.js';\n\n/**\n * Evaluate whether a set of properties matches all given filters.\n * All filters are AND'd — every filter must match for the result to be true.\n */\nexport function matchesPropertyFilters(\n properties: Record<string, unknown>,\n filters: PropertyFilter[],\n): boolean {\n return filters.every((filter) => matchesSingleFilter(properties, filter));\n}\n\nfunction matchesSingleFilter(\n properties: Record<string, unknown>,\n filter: PropertyFilter,\n): boolean {\n const value = properties[filter.key];\n\n switch (filter.operator) {\n case 'isNull':\n return value === null || value === undefined;\n\n case 'isNotNull':\n return value !== null && value !== undefined;\n\n case 'eq':\n return value === filter.value;\n\n case 'neq':\n return value !== filter.value;\n\n case 'gt':\n return typeof value === 'number' && typeof filter.value === 'number'\n ? value > filter.value\n : typeof value === 'string' && typeof filter.value === 'string'\n ? value > filter.value\n : false;\n\n case 'lt':\n return typeof value === 'number' && typeof filter.value === 'number'\n ? value < filter.value\n : typeof value === 'string' && typeof filter.value === 'string'\n ? value < filter.value\n : false;\n\n case 'gte':\n return typeof value === 'number' && typeof filter.value === 'number'\n ? value >= filter.value\n : typeof value === 'string' && typeof filter.value === 'string'\n ? value >= filter.value\n : false;\n\n case 'lte':\n return typeof value === 'number' && typeof filter.value === 'number'\n ? value <= filter.value\n : typeof value === 'string' && typeof filter.value === 'string'\n ? value <= filter.value\n : false;\n\n case 'contains':\n return typeof value === 'string' && typeof filter.value === 'string'\n ? value.toLowerCase().includes(filter.value.toLowerCase())\n : false;\n\n default:\n return false;\n }\n}\n","// FallbackTraversalExecutor — executes a TraversalSpec over StorageProvider\n// using iterative relationship lookups with batched entity resolution.\n// Provides multi-hop traversal for implementers who don't have a graph database.\n\nimport type { StorageProvider } from '../providers/StorageProvider.js';\nimport type { TraversalSpec, TraversalStep, TraversalResult, TraversalRelationship, TraversalPath, TraversalAggregation, TraversalEntity } from '../types/traversal.js';\nimport type { RelationshipSummary } from '../types/relationships.js';\nimport type { StoredEntity, DetailLevel } from '../types/entities.js';\nimport type { StoredRelationship, RelationshipDirection } from '../types/relationships.js';\nimport { projectEntity } from '../entities/entityProjection.js';\nimport { matchesPropertyFilters } from './PropertyFilterMatcher.js';\nimport { EntityNotFoundError } from '../core/errors.js';\n\n/** Maximum storage round-trips before aborting to prevent runaway traversals. */\nconst MAX_STORAGE_CALLS = 500;\n\n/** Maximum entities to scan for vertex queries and aggregation. */\nconst MAX_ENTITY_SCAN = 10000;\n\n/**\n * Maximum number of relationship results to fetch per frontier entity.\n * Set high to avoid truncation — client-side filtering handles the rest.\n */\nconst REL_FETCH_LIMIT = 1000;\n\ninterface FrontierEntry {\n entity: StoredEntity;\n /** Path of entity IDs from start to this entity. */\n entityPath: string[];\n /** Path of relationships from start to this entity. */\n relationshipPath: StoredRelationship[];\n}\n\n/**\n * Execute a TraversalSpec using application-level BFS over StorageProvider.\n *\n * Optimized for SQL Server round-trips:\n * - Relationship lookups are per-entity (unavoidable without a batch interface)\n * - Entity resolution is batched via getEntities() — one call per step\n * instead of one call per relationship result\n */\nexport async function executeFallbackTraversal(\n repositoryId: string,\n storage: StorageProvider,\n spec: TraversalSpec,\n): Promise<TraversalResult> {\n const startTime = Date.now();\n let storageCalls = 0;\n\n const checkCallLimit = (): void => {\n if (storageCalls >= MAX_STORAGE_CALLS) {\n throw new Error(`Fallback traversal exceeded ${MAX_STORAGE_CALLS} storage calls. Consider using a GraphTraversalProvider for large traversals.`);\n }\n };\n\n // ─── 1. Resolve starting entities ─────────────────────────────\n\n // When select is present or no steps (vertex query), fetch all matching\n // entities so aggregation is computed over the full dataset.\n // When traversing with steps, use the spec limit as the fetch cap.\n const isVertexQuery = !spec.steps || spec.steps.length === 0;\n const needsFullScan = isVertexQuery || spec.projection !== undefined;\n const fetchLimit = needsFullScan ? MAX_ENTITY_SCAN : (spec.limit ?? 50);\n\n let frontier: FrontierEntry[] = [];\n\n if (spec.start.entityId) {\n const entity = await resolveEntity(repositoryId, storage, spec.start.entityId);\n storageCalls++;\n if (entity) {\n frontier.push({ entity, entityPath: [entity.id], relationshipPath: [] });\n } else {\n throw new EntityNotFoundError(spec.start.entityId);\n }\n } else if (spec.start.entityType) {\n const result = await storage.findEntities(repositoryId, {\n entityTypes: [spec.start.entityType],\n limit: fetchLimit,\n offset: 0,\n });\n storageCalls++;\n frontier = result.items.map((e) => ({\n entity: e,\n entityPath: [e.id],\n relationshipPath: [],\n }));\n } else if (spec.start.filter && spec.start.filter.length > 0) {\n const result = await storage.findEntities(repositoryId, {\n limit: fetchLimit,\n offset: 0,\n });\n storageCalls++;\n frontier = result.items\n .filter((e) => matchesPropertyFilters(e.properties, spec.start.filter!))\n .map((e) => ({\n entity: e,\n entityPath: [e.id],\n relationshipPath: [],\n }));\n }\n\n // Apply start filters to frontier (when combined with entityId or entityType)\n if (spec.start.filter && spec.start.filter.length > 0 && (spec.start.entityId || spec.start.entityType)) {\n frontier = frontier.filter((entry) =>\n matchesPropertyFilters(entry.entity.properties, spec.start.filter!),\n );\n }\n\n // ─── 2. Execute steps (if any) ─────────────────────────────────\n\n const steps = spec.steps ?? [];\n const allCollected: FrontierEntry[] = spec.returnMode === 'all' ? [...frontier] : [];\n\n for (const step of steps) {\n checkCallLimit();\n\n if (step.repeat) {\n const result = await executeRepeatStep(\n repositoryId, storage, frontier, step,\n () => { storageCalls++; checkCallLimit(); },\n );\n frontier = result.terminal;\n if (spec.returnMode === 'all') {\n allCollected.push(...result.intermediates);\n }\n } else {\n frontier = await executeSingleStep(\n repositoryId, storage, frontier, step,\n () => { storageCalls++; checkCallLimit(); },\n );\n if (spec.returnMode === 'all') {\n allCollected.push(...frontier);\n }\n }\n }\n\n // ─── 3. Assemble results ──────────────────────────────────────\n\n const detailLevel: DetailLevel = spec.detailLevel ?? 'summary';\n const dedup = spec.dedup !== false;\n const limit = spec.limit ?? 50;\n const offset = spec.offset ?? 0;\n\n let resultEntries: FrontierEntry[];\n if (spec.returnMode === 'all') {\n resultEntries = allCollected;\n } else {\n resultEntries = frontier;\n }\n\n // Dedup by entity ID\n if (dedup) {\n const seen = new Set<string>();\n resultEntries = resultEntries.filter((entry) => {\n if (seen.has(entry.entity.id)) return false;\n seen.add(entry.entity.id);\n return true;\n });\n }\n\n const total = resultEntries.length;\n const paged = resultEntries.slice(offset, offset + limit);\n\n // Build result\n // When projection is present, entities are suppressed by default (projection replaces full output).\n // Set projection.includeEntities to get both.\n const suppressEntities = spec.projection !== undefined && spec.projection.includeEntities !== true;\n\n let entities: TraversalEntity[];\n if (suppressEntities) {\n entities = [];\n } else {\n entities = paged.map((entry) => {\n const projected = projectEntity(entry.entity, detailLevel) as TraversalEntity;\n // Strip provenance unless explicitly requested (only present at detailLevel 'full')\n if (!spec.includeProvenance) {\n delete (projected as unknown as Record<string, unknown>)['provenance'];\n }\n return projected;\n });\n\n // Attach relationship summaries.\n // Fallback path: N parallel storage calls (one per result entity).\n // Native GraphTraversalProviders should handle this in a single query instead.\n if (spec.includeRelationshipSummary && entities.length > 0) {\n const summaryResults = await Promise.all(\n paged.map(async (entry) => {\n storageCalls++;\n const result = await storage.getEntityRelationships(repositoryId, entry.entity.id, {\n direction: 'both',\n limit: 10000,\n });\n const summary: RelationshipSummary = { outbound: {}, inbound: {} };\n for (const rel of result.items) {\n if (rel.sourceEntityId === entry.entity.id) {\n summary.outbound[rel.relationshipType] = (summary.outbound[rel.relationshipType] ?? 0) + 1;\n }\n if (rel.targetEntityId === entry.entity.id) {\n summary.inbound[rel.relationshipType] = (summary.inbound[rel.relationshipType] ?? 0) + 1;\n }\n }\n return summary;\n }),\n );\n\n entities = entities.map((e, i) => ({ ...e, relationshipSummary: summaryResults[i] }));\n }\n }\n\n // Build aggregations if projection is specified\n let aggregations: TraversalAggregation[] | undefined;\n if (spec.projection) {\n const propNames = spec.projection.properties;\n const mode = spec.projection.mode ?? 'values';\n const distinct = spec.projection.distinct ?? false;\n\n // Operate on ALL matching entities (pre-pagination) for aggregation\n const sourceEntries = dedup\n ? (() => {\n const seen = new Set<string>();\n return (spec.returnMode === 'all' ? allCollected : frontier).filter((e) => {\n if (seen.has(e.entity.id)) return false;\n seen.add(e.entity.id);\n return true;\n });\n })()\n : (spec.returnMode === 'all' ? allCollected : frontier);\n\n if (mode === 'count' || distinct) {\n // Group by distinct value combinations\n const groups = new Map<string, { values: Record<string, unknown>; count: number }>();\n for (const entry of sourceEntries) {\n const vals: Record<string, unknown> = {};\n for (const prop of propNames) {\n vals[prop] = entry.entity.properties[prop] ?? null;\n }\n const key = JSON.stringify(vals);\n const existing = groups.get(key);\n if (existing) {\n existing.count++;\n } else {\n groups.set(key, { values: vals, count: 1 });\n }\n }\n\n aggregations = Array.from(groups.values()).map((g) => ({\n values: g.values,\n ...(mode === 'count' ? { count: g.count } : {}),\n }));\n\n // Sort by count descending for count mode\n if (mode === 'count') {\n aggregations.sort((a, b) => (b.count ?? 0) - (a.count ?? 0));\n }\n } else {\n // Raw values mode — extract properties from each entity\n aggregations = sourceEntries.map((entry) => {\n const vals: Record<string, unknown> = {};\n for (const prop of propNames) {\n vals[prop] = entry.entity.properties[prop] ?? null;\n }\n return { values: vals };\n });\n }\n }\n\n let relationships: TraversalRelationship[] | undefined;\n let paths: TraversalPath[] | undefined;\n\n if (!suppressEntities && (spec.returnMode === 'path' || spec.returnMode === 'all')) {\n const relMap = new Map<string, TraversalRelationship>();\n for (const entry of paged) {\n for (const rel of entry.relationshipPath) {\n if (!relMap.has(rel.id)) {\n relMap.set(rel.id, {\n id: rel.id,\n type: rel.relationshipType,\n sourceEntityId: rel.sourceEntityId,\n targetEntityId: rel.targetEntityId,\n direction: 'outbound',\n properties: rel.properties,\n });\n }\n }\n }\n relationships = Array.from(relMap.values());\n }\n\n if (!suppressEntities && spec.returnMode === 'path') {\n paths = paged.map((entry) => ({\n length: entry.entityPath.length - 1,\n entities: [(() => {\n const e = projectEntity(entry.entity, detailLevel) as TraversalEntity;\n if (!spec.includeProvenance) delete (e as unknown as Record<string, unknown>)['provenance'];\n return e;\n })()],\n relationships: entry.relationshipPath.map((rel) => ({\n id: rel.id,\n type: rel.relationshipType,\n sourceEntityId: rel.sourceEntityId,\n targetEntityId: rel.targetEntityId,\n direction: 'outbound' as const,\n properties: rel.properties,\n })),\n }));\n }\n\n const executionTimeMs = Date.now() - startTime;\n\n return {\n entities,\n relationships,\n paths,\n aggregations,\n total,\n returned: paged.length,\n hasMore: offset + limit < total,\n queryMetadata: {\n executionTimeMs,\n appliedLimits: {\n maxResults: limit,\n },\n truncated: total > limit + offset,\n truncationReason: total > limit + offset ? 'result_limit' : undefined,\n },\n };\n}\n\n/**\n * Execute a single (non-repeat) traversal step across the frontier.\n *\n * Optimization: relationship queries are per-entity (required by StorageProvider\n * interface), but entity resolution is batched — one getEntities() call for\n * all target IDs discovered in this step, instead of one getEntity() per target.\n */\nasync function executeSingleStep(\n repositoryId: string,\n storage: StorageProvider,\n frontier: FrontierEntry[],\n step: TraversalStep,\n onStorageCall: () => void,\n): Promise<FrontierEntry[]> {\n // Phase 1: Collect all relationships from the frontier (N queries, 1 per frontier entity)\n const direction = mapDirection(step.direction);\n const pendingEdges: Array<{\n entry: FrontierEntry;\n rel: StoredRelationship;\n targetId: string;\n }> = [];\n\n for (const entry of frontier) {\n const rels = await storage.getEntityRelationships(repositoryId, entry.entity.id, {\n direction,\n relationshipTypes: step.relationshipTypes,\n limit: REL_FETCH_LIMIT,\n });\n onStorageCall();\n\n for (const rel of rels.items) {\n // Apply relationship property filters early (avoids unnecessary entity lookups)\n if (step.relationshipFilter && step.relationshipFilter.length > 0) {\n if (!matchesPropertyFilters(rel.properties, step.relationshipFilter)) {\n continue;\n }\n }\n\n const targetId = getTargetId(rel, entry.entity.id);\n pendingEdges.push({ entry, rel, targetId });\n }\n }\n\n if (pendingEdges.length === 0) return [];\n\n // Phase 2: Batch-resolve all target entities in one call\n const uniqueTargetIds = [...new Set(pendingEdges.map((e) => e.targetId))];\n const entityMap = await storage.getEntities(repositoryId, uniqueTargetIds);\n onStorageCall();\n\n // Phase 3: Assemble the next frontier with client-side filtering\n const nextFrontier: FrontierEntry[] = [];\n\n for (const { entry, rel, targetId } of pendingEdges) {\n const targetEntity = entityMap.get(targetId);\n if (!targetEntity) continue;\n\n // Apply entity type filter\n if (step.entityTypes && step.entityTypes.length > 0) {\n if (!step.entityTypes.includes(targetEntity.entityType)) continue;\n }\n\n // Apply entity property filters\n if (step.entityFilter && step.entityFilter.length > 0) {\n if (!matchesPropertyFilters(targetEntity.properties, step.entityFilter)) continue;\n }\n\n nextFrontier.push({\n entity: targetEntity,\n entityPath: [...entry.entityPath, targetEntity.id],\n relationshipPath: [...entry.relationshipPath, rel],\n });\n }\n\n return nextFrontier;\n}\n\n/** Execute a repeat/loop step, iterating up to maxDepth times. */\nasync function executeRepeatStep(\n repositoryId: string,\n storage: StorageProvider,\n frontier: FrontierEntry[],\n step: TraversalStep,\n onStorageCall: () => void,\n): Promise<{ terminal: FrontierEntry[]; intermediates: FrontierEntry[] }> {\n const maxDepth = step.repeat?.maxDepth ?? 1;\n const emitIntermediates = step.repeat?.emitIntermediates !== false;\n const untilFilters = step.repeat?.until;\n\n let current = frontier;\n const allIntermediates: FrontierEntry[] = [];\n const visited = new Set<string>();\n\n for (const entry of frontier) {\n visited.add(entry.entity.id);\n }\n\n for (let depth = 0; depth < maxDepth; depth++) {\n const next = await executeSingleStep(repositoryId, storage, current, step, onStorageCall);\n\n // Filter out already-visited to prevent cycles\n const unvisited = next.filter((entry) => {\n if (visited.has(entry.entity.id)) return false;\n visited.add(entry.entity.id);\n return true;\n });\n\n if (unvisited.length === 0) break;\n\n if (untilFilters && untilFilters.length > 0) {\n const matching: FrontierEntry[] = [];\n const continuing: FrontierEntry[] = [];\n\n for (const entry of unvisited) {\n if (matchesPropertyFilters(entry.entity.properties, untilFilters)) {\n matching.push(entry);\n } else {\n continuing.push(entry);\n }\n }\n\n if (emitIntermediates) {\n allIntermediates.push(...continuing);\n }\n allIntermediates.push(...matching);\n\n if (matching.length > 0 && continuing.length === 0) {\n current = matching;\n break;\n }\n current = continuing;\n } else {\n if (emitIntermediates) {\n allIntermediates.push(...unvisited);\n }\n current = unvisited;\n }\n }\n\n return {\n terminal: current,\n intermediates: allIntermediates,\n };\n}\n\n/** Resolve an entity by ID or slug. */\nasync function resolveEntity(\n repositoryId: string,\n storage: StorageProvider,\n idOrSlug: string,\n): Promise<StoredEntity | null> {\n const byId = await storage.getEntity(repositoryId, idOrSlug);\n if (byId) return byId;\n return storage.getEntityBySlug(repositoryId, idOrSlug);\n}\n\n/** Map traversal direction to storage direction. */\nfunction mapDirection(direction: 'out' | 'in' | 'both'): RelationshipDirection {\n switch (direction) {\n case 'out': return 'outbound';\n case 'in': return 'inbound';\n case 'both': return 'both';\n }\n}\n\n/** Get the target entity ID from a relationship relative to the current entity. */\nfunction getTargetId(rel: StoredRelationship, currentEntityId: string): string {\n if (rel.sourceEntityId === currentEntityId) {\n return rel.targetEntityId;\n }\n return rel.sourceEntityId;\n}\n","// GraphTraversal — BFS neighborhood exploration, path finding, and\n// structured multi-hop traversal.\n// Sits between MemoryRepository and StorageProvider, mapping storage-level\n// results to the public Neighborhood, PathResult, and TraversalResult types.\n\nimport type { StorageProvider } from '../providers/StorageProvider.js';\nimport type { GraphTraversalProvider } from '../providers/GraphTraversalProvider.js';\nimport type {\n ExploreOptions,\n PathOptions,\n} from '../types/queries.js';\nimport type { DetailLevel } from '../types/entities.js';\nimport type { VocabularyEngine } from '../core/VocabularyEngine.js';\nimport type {\n Neighborhood,\n NeighborhoodLayer,\n PathResult,\n} from '../types/results.js';\nimport type { TraversalSpec, TraversalResult } from '../types/traversal.js';\nimport { projectEntity } from '../entities/entityProjection.js';\nimport { EntityNotFoundError, GraphTraversalProviderRequiredError, TraversalValidationError, TraversalVocabularyError } from '../core/errors.js';\nimport { validateTraversalSpec } from './TraversalValidator.js';\nimport { executeFallbackTraversal } from './FallbackTraversalExecutor.js';\n\nexport class GraphTraversal {\n constructor(\n private readonly repositoryId: string,\n private readonly storage: StorageProvider,\n private readonly graphTraversalProvider?: GraphTraversalProvider,\n private readonly vocabularyEngine?: VocabularyEngine,\n ) {}\n\n /** BFS neighborhood exploration from a center entity */\n async exploreNeighborhood(\n entityId: string,\n options?: ExploreOptions,\n ): Promise<Neighborhood> {\n const storageOptions = {\n depth: options?.depth ?? 1,\n relationshipTypes: options?.relationshipTypes,\n entityTypes: options?.entityTypes,\n direction: options?.direction ?? 'both' as const,\n limitPerType: options?.limitPerType ?? 10,\n offsetPerType: options?.offsetPerType ?? 0,\n relationshipPropertyFilters: options?.relationshipPropertyFilters,\n };\n\n const storageResult = await this.storage.exploreNeighborhood(\n this.repositoryId,\n entityId,\n storageOptions,\n );\n\n // Get the center entity for the public response\n const centerEntity = await this.storage.getEntity(this.repositoryId, entityId);\n if (!centerEntity) {\n throw new EntityNotFoundError(entityId);\n }\n\n // Map storage layers to public layers with statistics\n const detailLevel: DetailLevel = options?.detailLevel ?? 'summary';\n let totalEntities = 0;\n let returnedEntities = 0;\n const truncatedTypes: string[] = [];\n\n const layers: NeighborhoodLayer[] = storageResult.layers.map((storageLayer) => {\n const layer: NeighborhoodLayer = {};\n\n for (const [relType, group] of Object.entries(storageLayer)) {\n totalEntities += group.total;\n returnedEntities += group.entities.length;\n\n if (group.entities.length < group.total && !truncatedTypes.includes(relType)) {\n truncatedTypes.push(relType);\n }\n\n layer[relType] = {\n total: group.total,\n returned: group.entities.length,\n entities: group.entities.map((e) => projectEntity(e, detailLevel)),\n };\n }\n\n return layer;\n });\n\n return {\n center: {\n id: centerEntity.id,\n slug: centerEntity.slug,\n entityType: centerEntity.entityType,\n label: centerEntity.label,\n },\n layers,\n statistics: {\n totalEntities,\n returnedEntities,\n truncatedTypes,\n },\n };\n }\n\n /** BFS shortest path finding between two entities */\n async findPaths(\n sourceId: string,\n targetId: string,\n options?: PathOptions,\n ): Promise<PathResult> {\n const storageOptions = {\n maxDepth: options?.maxDepth ?? 3,\n relationshipTypes: options?.relationshipTypes,\n entityTypes: options?.entityTypes,\n limit: options?.limit ?? 5,\n offset: options?.offset ?? 0,\n relationshipPropertyFilters: options?.relationshipPropertyFilters,\n };\n\n const storageResult = await this.storage.findPaths(\n this.repositoryId,\n sourceId,\n targetId,\n storageOptions,\n );\n\n // Collect all entity and relationship IDs for batch lookup\n const entityIdSet = new Set<string>();\n const relIdSet = new Set<string>();\n for (const path of storageResult.paths) {\n for (const eid of path.entityIds) entityIdSet.add(eid);\n for (const rid of path.relationshipIds) relIdSet.add(rid);\n }\n\n // Batch fetch entities\n const entityMap = await this.storage.getEntities(\n this.repositoryId,\n Array.from(entityIdSet),\n );\n\n // Fetch relationships individually\n const relMap = new Map<string, { id: string; type: string; sourceEntityId: string; properties: Record<string, unknown> }>();\n for (const rid of relIdSet) {\n const rel = await this.storage.getRelationship(this.repositoryId, rid);\n if (rel) {\n relMap.set(rid, {\n id: rel.id,\n type: rel.relationshipType,\n sourceEntityId: rel.sourceEntityId,\n properties: rel.properties,\n });\n }\n }\n\n // Filter paths by entity types if specified\n const entityTypeFilter = options?.entityTypes;\n const filteredPaths = entityTypeFilter\n ? storageResult.paths.filter((sp) =>\n sp.entityIds.every((eid) => {\n const e = entityMap.get(eid);\n return e ? entityTypeFilter.includes(e.entityType) : true;\n }),\n )\n : storageResult.paths;\n\n const pathDetailLevel: DetailLevel = options?.detailLevel ?? 'brief';\n\n return {\n totalPaths: entityTypeFilter ? filteredPaths.length : storageResult.totalPaths,\n returned: filteredPaths.length,\n paths: filteredPaths.map((sp) => ({\n length: sp.entityIds.length - 1,\n entities: sp.entityIds.map((eid) => {\n const e = entityMap.get(eid);\n if (e) return projectEntity(e, pathDetailLevel);\n return {\n id: eid,\n slug: eid,\n entityType: 'unknown',\n label: eid,\n summary: undefined,\n };\n }),\n relationships: sp.relationshipIds.map((rid, idx) => {\n const r = relMap.get(rid);\n const currentEntityId = sp.entityIds[idx];\n return {\n id: rid,\n type: r?.type ?? 'unknown',\n direction: r?.sourceEntityId === currentEntityId ? 'outbound' : 'inbound',\n properties: r?.properties ?? {},\n };\n }),\n })),\n };\n }\n\n /**\n * Execute a structured traversal.\n * Validates the spec, delegates to the GraphTraversalProvider if one is\n * registered (the provider owns native compilation), or falls back to\n * application-level BFS over StorageProvider.\n */\n async traverse(spec: TraversalSpec): Promise<TraversalResult> {\n // 1. Validate spec against structural rules and vocabulary\n const capabilities = this.graphTraversalProvider?.getCapabilities();\n const vocabulary = this.vocabularyEngine\n ? await this.vocabularyEngine.getVocabulary()\n : undefined;\n const validation = validateTraversalSpec(spec, vocabulary, capabilities);\n\n if (!validation.valid) {\n // Separate vocabulary errors from structural errors\n const vocabErrors = validation.errors.filter((e) => e.startsWith('Unknown vocabulary types:'));\n const structErrors = validation.errors.filter((e) => !e.startsWith('Unknown vocabulary types:'));\n\n if (vocabErrors.length > 0) {\n const unknownTypes = vocabErrors.join('; ')\n .replace(/Unknown vocabulary types: /g, '')\n .split(', ')\n .map((t) => t.trim());\n throw new TraversalVocabularyError(unknownTypes);\n }\n\n throw new TraversalValidationError(structErrors.length > 0 ? structErrors : validation.errors);\n }\n\n // 2. If GraphTraversalProvider registered, delegate — the provider owns\n // compilation to its native dialect.\n if (this.graphTraversalProvider) {\n return this.graphTraversalProvider.traverse(this.repositoryId, spec);\n }\n\n // 3. Fallback: execute over StorageProvider\n return executeFallbackTraversal(this.repositoryId, this.storage, spec);\n }\n\n /**\n * Execute a native graph query.\n * Pass-through to GraphTraversalProvider.executeNativeQuery().\n * Throws GraphTraversalProviderRequiredError if no provider registered.\n */\n async executeNativeQuery(\n query: string,\n params?: Record<string, unknown>,\n ): Promise<TraversalResult> {\n if (!this.graphTraversalProvider) {\n throw new GraphTraversalProviderRequiredError();\n }\n return this.graphTraversalProvider.executeNativeQuery(this.repositoryId, query, params);\n }\n}\n","// SearchOrchestrator — coordinates StorageProvider, SearchProvider, and EmbeddingProvider\n// for entity finding and semantic concept search.\n\nimport type { StorageProvider } from '../providers/StorageProvider.js';\nimport type { SearchProvider } from '../providers/SearchProvider.js';\nimport type { EmbeddingProvider } from '../providers/EmbeddingProvider.js';\nimport type { EventBus } from '../core/EventBus.js';\nimport type { VocabularyEngine } from '../core/VocabularyEngine.js';\nimport { getEntityTypeDef } from '../vocabulary/VocabularyValidator.js';\nimport type { DetailLevel, StoredEntity } from '../types/entities.js';\nimport type {\n FindEntitiesQuery,\n ConceptSearchOptions,\n StorageFindQuery,\n} from '../types/queries.js';\nimport type {\n PaginatedResult,\n ScoredEntity,\n SearchHit,\n} from '../types/results.js';\nimport type { Entity, EntityBrief, EntitySummary } from '../types/entities.js';\nimport { projectEntity } from '../entities/entityProjection.js';\nimport { EmbeddingProviderRequiredError } from '../core/errors.js';\n\nexport interface SearchOrchestratorConfig {\n repositoryId: string;\n storage: StorageProvider;\n search?: SearchProvider;\n embedding?: EmbeddingProvider;\n eventBus?: EventBus;\n vocabularyEngine?: VocabularyEngine;\n /** Default similarity threshold for semantic search (0.0-1.0, default 0.5) */\n defaultSimilarityThreshold?: number;\n /** Maximum entities to scan for concept search (default 1000). Higher values improve recall at the cost of latency. */\n conceptSearchScanLimit?: number;\n}\n\nexport class SearchOrchestrator {\n private readonly repositoryId: string;\n private readonly storage: StorageProvider;\n private readonly search?: SearchProvider;\n private embedding?: EmbeddingProvider;\n private readonly eventBus?: EventBus;\n private readonly vocabularyEngine?: VocabularyEngine;\n private readonly defaultSimilarityThreshold: number;\n private readonly conceptSearchScanLimit: number;\n\n constructor(config: SearchOrchestratorConfig) {\n this.repositoryId = config.repositoryId;\n this.storage = config.storage;\n this.search = config.search;\n this.embedding = config.embedding;\n this.eventBus = config.eventBus;\n this.vocabularyEngine = config.vocabularyEngine;\n this.defaultSimilarityThreshold = config.defaultSimilarityThreshold ?? 0.5;\n this.conceptSearchScanLimit = config.conceptSearchScanLimit ?? 1000;\n }\n\n /** Swap the embedding provider, e.g. after a repository re-embed changes the model or dimensionality */\n setEmbeddingProvider(embedding: EmbeddingProvider | undefined): void {\n this.embedding = embedding;\n }\n\n /**\n * Find entities by label, type, and property filters.\n * When a SearchProvider is available, its results are merged with\n * storage-level results for better relevance ranking.\n */\n async findEntities(query: FindEntitiesQuery): Promise<PaginatedResult<Entity | EntitySummary | EntityBrief>> {\n const limit = Math.min(query.limit ?? 10, 50);\n const offset = query.offset ?? 0;\n const detailLevel: DetailLevel = query.detailLevel ?? 'summary';\n\n const storageQuery: StorageFindQuery = {\n searchTerm: query.searchTerm,\n entityTypes: query.entityTypes,\n properties: query.properties,\n provenance: query.provenance,\n limit,\n offset,\n };\n\n // If we have a SearchProvider and a search term, merge results\n if (this.search && query.searchTerm) {\n const [storageResult, searchResult] = await Promise.all([\n this.storage.findEntities(this.repositoryId, storageQuery),\n this.search.search(this.repositoryId, query.searchTerm, {\n entityTypes: query.entityTypes,\n limit: limit * 2, // fetch more from search to merge\n offset: 0,\n }),\n ]);\n\n // Merge: use search result ordering but supplement with storage results\n const merged = this.mergeResults(storageResult.items, searchResult.items, limit, offset, detailLevel);\n\n await this.emitSearchEvent(query.searchTerm, merged.items.length);\n\n return merged;\n }\n\n // No SearchProvider or no search term — delegate to storage only\n const result = await this.storage.findEntities(this.repositoryId, storageQuery);\n\n if (query.searchTerm) {\n await this.emitSearchEvent(query.searchTerm, result.items.length);\n }\n\n return {\n items: result.items.map((e) => projectEntity(e, detailLevel)),\n total: result.total,\n hasMore: result.hasMore,\n limit: result.limit,\n offset: result.offset,\n };\n }\n\n /**\n * Semantic concept search using the EmbeddingProvider.\n * Embeds the query, then compares against entity embeddings.\n * Falls back to label/summary text matching when no embeddings exist on entities.\n */\n async searchByConcept(\n query: string,\n options?: ConceptSearchOptions,\n ): Promise<PaginatedResult<ScoredEntity>> {\n if (!this.embedding) {\n throw new EmbeddingProviderRequiredError();\n }\n\n const limit = Math.min(options?.limit ?? 10, 50);\n const offset = options?.offset ?? 0;\n const threshold = options?.similarityThreshold ?? this.defaultSimilarityThreshold;\n\n // Embed the query\n const queryEmbedding = await this.embedding.embed(query);\n\n // Get all entities (paginated scan — for production, a vector index would be used)\n const allEntities = await this.storage.findEntities(this.repositoryId, {\n entityTypes: options?.entityTypes,\n limit: this.conceptSearchScanLimit,\n offset: 0,\n });\n\n // Score each entity against the query embedding\n const scored: ScoredEntity[] = [];\n\n for (const entity of allEntities.items) {\n let score: number;\n\n if (entity.embedding && entity.embedding.length > 0) {\n // Use stored embedding\n score = this.cosineSimilarity(queryEmbedding, entity.embedding);\n } else {\n // Generate embedding on the fly for comparison — include embeddable properties\n const entityText = await this.buildEmbeddingText(entity.entityType, entity.label, entity.summary, entity.properties);\n const entityEmbedding = await this.embedding.embed(entityText);\n score = this.cosineSimilarity(queryEmbedding, entityEmbedding);\n }\n\n if (score >= threshold) {\n scored.push({\n id: entity.id,\n slug: entity.slug,\n entityType: entity.entityType,\n label: entity.label,\n summary: entity.summary,\n score,\n });\n }\n }\n\n // Sort by score descending\n scored.sort((a, b) => b.score - a.score);\n\n const total = scored.length;\n const items = scored.slice(offset, offset + limit);\n\n await this.emitSearchEvent(query, items.length);\n\n return {\n items,\n total,\n hasMore: offset + limit < total,\n limit,\n offset,\n };\n }\n\n /** Merge storage results with search provider results */\n private mergeResults(\n storageItems: StoredEntity[],\n searchHits: SearchHit[],\n limit: number,\n offset: number,\n detailLevel: DetailLevel = 'summary',\n ): PaginatedResult<Entity | EntitySummary | EntityBrief> {\n // Build a map of search scores by entity ID\n const scoreMap = new Map<string, number>();\n for (const hit of searchHits) {\n scoreMap.set(hit.id, hit.score);\n }\n\n // Combine: entities from storage, ranked by search score if available\n const allEntityIds = new Set<string>();\n const rankedItems: Array<{ entity: StoredEntity; score: number }> = [];\n\n // Add search hits first (higher relevance)\n for (const hit of searchHits) {\n const storageEntity = storageItems.find((e) => e.id === hit.id);\n if (storageEntity) {\n rankedItems.push({ entity: storageEntity, score: hit.score });\n allEntityIds.add(hit.id);\n }\n }\n\n // Add remaining storage items (not in search results)\n for (const entity of storageItems) {\n if (!allEntityIds.has(entity.id)) {\n rankedItems.push({ entity, score: 0 });\n allEntityIds.add(entity.id);\n }\n }\n\n // Sort by score descending\n rankedItems.sort((a, b) => b.score - a.score);\n\n const total = rankedItems.length;\n const page = rankedItems.slice(offset, offset + limit);\n\n return {\n items: page.map((r) => projectEntity(r.entity, detailLevel)),\n total,\n hasMore: offset + limit < total,\n limit,\n offset,\n };\n }\n\n /** Build the embedding text for an entity — label + summary + embeddable string properties */\n private async buildEmbeddingText(entityType: string, label: string, summary: string | undefined, properties: Record<string, unknown>): Promise<string> {\n const embeddableValues: string[] = [];\n if (this.vocabularyEngine) {\n const vocab = await this.vocabularyEngine.getVocabulary();\n const typeDef = getEntityTypeDef(entityType, vocab);\n if (typeDef) {\n for (const p of typeDef.properties) {\n if (p.embeddable === true && typeof properties[p.name] === 'string') {\n embeddableValues.push(properties[p.name] as string);\n }\n }\n }\n }\n return [label, summary ?? '', ...embeddableValues].filter(Boolean).join(' ');\n }\n\n /** Cosine similarity between two vectors */\n private cosineSimilarity(a: number[], b: number[]): number {\n // Use provider's similarity if available\n if (this.embedding?.similarity) {\n return this.embedding.similarity(a, b);\n }\n\n // Fallback: manual cosine similarity\n if (a.length !== b.length || a.length === 0) return 0;\n\n let dotProduct = 0;\n let normA = 0;\n let normB = 0;\n\n for (let i = 0; i < a.length; i++) {\n const ai = a[i]!;\n const bi = b[i]!;\n dotProduct += ai * bi;\n normA += ai * ai;\n normB += bi * bi;\n }\n\n const denominator = Math.sqrt(normA) * Math.sqrt(normB);\n return denominator === 0 ? 0 : dotProduct / denominator;\n }\n\n private async emitSearchEvent(query: string, resultCount: number): Promise<void> {\n if (this.eventBus) {\n await this.eventBus.emit('search:executed', { query, resultCount });\n }\n }\n}\n\n","// RepositoryValidator — audits entities and relationships in a repository\n// against the current vocabulary. Exposes two paged methods so MCP clients\n// with limited context can drill in one window at a time.\n//\n// Paging is applied over *issues*. `offset` skips that many issues, `take`\n// caps how many issues this page returns. The export stream is scanned from\n// the start every call — callers typically loop at offset=0 after fixing,\n// and `nextOffset` is only useful when inspecting a later slice without\n// mutating. `scanned` reports items inspected, for diagnostics.\n\nimport type { StorageProvider } from '../providers/StorageProvider.js';\nimport type { VocabularyEngine } from '../core/VocabularyEngine.js';\nimport type { StoredEntity } from '../types/entities.js';\nimport type { StoredRelationship } from '../types/relationships.js';\nimport type {\n EntityValidationPage,\n RelationshipValidationPage,\n EntityValidationIssue,\n RelationshipValidationIssue,\n ValidateEntitiesOptions,\n ValidateRelationshipsOptions,\n} from '../types/results.js';\nimport {\n validateEntity,\n validateRelationship,\n type ValidationError,\n} from '../vocabulary/VocabularyValidator.js';\n\ninterface EntityMapEntry {\n entityType: string;\n label: string;\n slug: string;\n}\n\nconst DEFAULT_TAKE = 200;\n\nexport class RepositoryValidator {\n constructor(\n private readonly repositoryId: string,\n private readonly storage: StorageProvider,\n private readonly vocabularyEngine: VocabularyEngine,\n ) {}\n\n async validateEntities(options?: ValidateEntitiesOptions): Promise<EntityValidationPage> {\n const offset = options?.offset ?? 0;\n const take = options?.take ?? DEFAULT_TAKE;\n const delayMs = options?.delayBetweenChunksMs ?? 0;\n\n const vocabulary = await this.vocabularyEngine.getVocabulary();\n\n const issues: EntityValidationIssue[] = [];\n let scanned = 0;\n let skipped = 0;\n let stoppedEarly = false;\n\n for await (const chunk of this.storage.exportAll(this.repositoryId)) {\n if (chunk.type !== 'entities') {\n // Relationships phase — no further entities to scan.\n break;\n }\n\n const data = chunk.data as StoredEntity[];\n for (const entity of data) {\n scanned++;\n\n const result = validateEntity(\n {\n entityType: entity.entityType,\n label: entity.label,\n properties: entity.properties,\n },\n vocabulary,\n );\n if (!result.valid) {\n if (skipped < offset) {\n skipped++;\n continue;\n }\n issues.push({\n entityId: entity.id,\n slug: entity.slug,\n entityType: entity.entityType,\n label: entity.label,\n errors: result.errors,\n });\n if (issues.length >= take) {\n stoppedEarly = true;\n break;\n }\n }\n }\n\n if (stoppedEarly) break;\n\n if (delayMs > 0 && !chunk.isLast) {\n await new Promise<void>((resolve) => { setTimeout(resolve, delayMs); });\n }\n }\n\n return {\n issues,\n scanned,\n nextOffset: offset + issues.length,\n done: !stoppedEarly,\n };\n }\n\n async validateRelationships(options?: ValidateRelationshipsOptions): Promise<RelationshipValidationPage> {\n const offset = options?.offset ?? 0;\n const take = options?.take ?? DEFAULT_TAKE;\n const delayMs = options?.delayBetweenChunksMs ?? 0;\n\n const vocabulary = await this.vocabularyEngine.getVocabulary();\n\n // Orphan checks and type-mismatch checks need every entity resolvable,\n // so the entity-map pass can't be paged.\n const entityMap = new Map<string, EntityMapEntry>();\n const issues: RelationshipValidationIssue[] = [];\n let scanned = 0;\n let skipped = 0;\n let stoppedEarly = false;\n\n for await (const chunk of this.storage.exportAll(this.repositoryId)) {\n if (chunk.type === 'entities') {\n for (const entity of chunk.data as StoredEntity[]) {\n entityMap.set(entity.id, {\n entityType: entity.entityType,\n label: entity.label,\n slug: entity.slug,\n });\n }\n\n if (delayMs > 0 && !chunk.isLast) {\n await new Promise<void>((resolve) => { setTimeout(resolve, delayMs); });\n }\n continue;\n }\n\n const data = chunk.data as StoredRelationship[];\n for (const rel of data) {\n scanned++;\n\n const src = entityMap.get(rel.sourceEntityId);\n const tgt = entityMap.get(rel.targetEntityId);\n\n const errors: ValidationError[] = [];\n\n if (!src) {\n errors.push({\n field: 'sourceEntityId',\n message: `Source entity \"${rel.sourceEntityId}\" does not exist in this repository`,\n });\n }\n if (!tgt) {\n errors.push({\n field: 'targetEntityId',\n message: `Target entity \"${rel.targetEntityId}\" does not exist in this repository`,\n });\n }\n\n if (rel.sourceEntityId === rel.targetEntityId) {\n errors.push({\n field: 'targetEntityId',\n message: `Self-referential relationship: source and target are the same entity \"${rel.sourceEntityId}\"`,\n suggestion: 'Remove the relationship, or repoint it to a different entity.',\n });\n }\n\n // Only run full vocabulary validation when both endpoints exist —\n // otherwise type-based checks would pile noise on top of the orphan error.\n if (src && tgt) {\n const result = validateRelationship(\n {\n relationshipType: rel.relationshipType,\n sourceEntityId: rel.sourceEntityId,\n targetEntityId: rel.targetEntityId,\n properties: rel.properties,\n },\n vocabulary,\n src.entityType,\n tgt.entityType,\n );\n errors.push(...result.errors);\n }\n\n if (errors.length > 0) {\n if (skipped < offset) {\n skipped++;\n continue;\n }\n issues.push({\n relationshipId: rel.id,\n relationshipType: rel.relationshipType,\n sourceEntityId: rel.sourceEntityId,\n targetEntityId: rel.targetEntityId,\n sourceLabel: src?.label,\n targetLabel: tgt?.label,\n sourceEntityType: src?.entityType,\n targetEntityType: tgt?.entityType,\n errors,\n });\n if (issues.length >= take) {\n stoppedEarly = true;\n break;\n }\n }\n }\n\n if (stoppedEarly) break;\n\n if (delayMs > 0 && !chunk.isLast) {\n await new Promise<void>((resolve) => { setTimeout(resolve, delayMs); });\n }\n }\n\n return {\n issues,\n scanned,\n nextOffset: offset + issues.length,\n done: !stoppedEarly,\n entitiesInMap: entityMap.size,\n };\n }\n}\n","// MemoryRepository — public API for a single memory repository\n\nimport type { StorageProvider } from '../providers/StorageProvider.js';\nimport type { SearchProvider } from '../providers/SearchProvider.js';\nimport type { EmbeddingProvider, EmbeddingProviderFactory } from '../providers/EmbeddingProvider.js';\nimport type {\n CreateEntityInput,\n DeleteEntitiesResult,\n DetailLevel,\n Entity,\n EntityBrief,\n EntitySummary,\n UpdateEntityInput,\n} from '../types/entities.js';\nimport type {\n CreateRelationshipInput,\n EnrichedRelationship,\n Relationship,\n RelationshipSummary,\n RemoveRelationshipsResult,\n} from '../types/relationships.js';\nimport type {\n FindEntitiesQuery,\n ExploreOptions,\n PathOptions,\n TimelineOptions,\n ConceptSearchOptions,\n} from '../types/queries.js';\nimport type { TraversalSpec, TraversalResult } from '../types/traversal.js';\nimport type { GraphTraversalProvider } from '../providers/GraphTraversalProvider.js';\nimport type {\n PaginatedResult,\n Neighborhood,\n PathResult,\n GraphResult,\n TimelineEvent,\n TimelineEntityRef,\n TimelineRelationshipDetail,\n TimelineResult,\n ScoredEntity,\n ReembedResult,\n EntityValidationPage,\n RelationshipValidationPage,\n ValidateEntitiesOptions,\n ValidateRelationshipsOptions,\n} from '../types/results.js';\nimport type {\n ResolvedVocabulary,\n VocabularyProposal,\n VocabularyProposalResult,\n RepositoryStats,\n} from '../types/index.js';\nimport type {\n DeepMemoryEventType,\n EventHandler,\n Unsubscribe,\n} from '../types/events.js';\nimport type { VocabularyEngine } from './VocabularyEngine.js';\nimport type { ProvenanceTracker } from './ProvenanceTracker.js';\nimport type { EventBus, HookHandler } from './EventBus.js';\nimport { EntityManager } from '../entities/EntityManager.js';\nimport { RelationshipManager } from '../relationships/RelationshipManager.js';\nimport { GraphTraversal } from '../relationships/GraphTraversal.js';\nimport { SearchOrchestrator } from '../search/SearchOrchestrator.js';\nimport { RepositoryValidator } from '../validation/RepositoryValidator.js';\n\nexport interface MemoryRepositoryConfig {\n repositoryId: string;\n storage: StorageProvider;\n search?: SearchProvider;\n /** Embedding provider configured for this repository's model + dimensions */\n embedding?: EmbeddingProvider;\n /**\n * Factory for producing embedding providers with different model/dimensions.\n * Required only if reembedAll will be called with a new model or dimensions.\n */\n embeddingFactory?: EmbeddingProviderFactory;\n graphTraversal?: GraphTraversalProvider;\n vocabularyEngine: VocabularyEngine;\n provenanceTracker: ProvenanceTracker;\n eventBus: EventBus;\n}\n\nexport class MemoryRepository {\n readonly repositoryId: string;\n private readonly storage: StorageProvider;\n private readonly search?: SearchProvider;\n private readonly vocabularyEngine: VocabularyEngine;\n private readonly provenanceTracker: ProvenanceTracker;\n private readonly eventBus: EventBus;\n private readonly entityManager: EntityManager;\n private readonly relationshipManager: RelationshipManager;\n private readonly graphTraversal: GraphTraversal;\n private readonly searchOrchestrator: SearchOrchestrator;\n private readonly embeddingFactory?: EmbeddingProviderFactory;\n private embedding?: EmbeddingProvider;\n\n constructor(config: MemoryRepositoryConfig) {\n this.repositoryId = config.repositoryId;\n this.storage = config.storage;\n this.search = config.search;\n this.vocabularyEngine = config.vocabularyEngine;\n this.provenanceTracker = config.provenanceTracker;\n this.eventBus = config.eventBus;\n this.embedding = config.embedding;\n this.embeddingFactory = config.embeddingFactory;\n\n this.entityManager = new EntityManager(\n config.repositoryId,\n config.vocabularyEngine,\n config.provenanceTracker,\n config.eventBus,\n config.storage,\n config.embedding,\n );\n\n this.relationshipManager = new RelationshipManager(\n config.repositoryId,\n config.vocabularyEngine,\n config.provenanceTracker,\n config.eventBus,\n config.storage,\n );\n\n this.graphTraversal = new GraphTraversal(\n config.repositoryId,\n config.storage,\n config.graphTraversal,\n config.vocabularyEngine,\n );\n\n this.searchOrchestrator = new SearchOrchestrator({\n repositoryId: config.repositoryId,\n storage: config.storage,\n search: config.search,\n embedding: config.embedding,\n eventBus: config.eventBus,\n vocabularyEngine: config.vocabularyEngine,\n defaultSimilarityThreshold: config.vocabularyEngine.getGovernanceConfig().defaultSimilarityThreshold,\n });\n }\n\n // ─── Vocabulary ────────────────────────────────────────────────────\n\n async getVocabulary(): Promise<ResolvedVocabulary> {\n return this.vocabularyEngine.getResolvedVocabulary();\n }\n\n async proposeVocabularyChange(\n proposal: VocabularyProposal,\n ): Promise<VocabularyProposalResult> {\n const context = this.provenanceTracker.getContext();\n return this.vocabularyEngine.proposeChange(proposal, context.actorId);\n }\n\n /** @deprecated Use proposeVocabularyChange instead */\n async proposeVocabularyExtension(\n proposal: VocabularyProposal,\n ): Promise<VocabularyProposalResult> {\n return this.proposeVocabularyChange(proposal);\n }\n\n // ─── Entities ──────────────────────────────────────────────────────\n\n async createEntities(inputs: CreateEntityInput[]): Promise<Entity[]> {\n const entities = await this.entityManager.create(inputs);\n\n // Index in search provider if available\n if (this.search) {\n for (const entity of entities) {\n await this.search.indexEntity(this.repositoryId, {\n entityId: entity.id,\n entityType: entity.entityType,\n label: entity.label,\n summary: entity.summary,\n properties: entity.properties,\n data: entity.data,\n });\n }\n }\n\n return entities;\n }\n\n async updateEntity(entityId: string, updates: UpdateEntityInput): Promise<Entity> {\n const entity = await this.entityManager.update(entityId, updates);\n\n // Re-index in search provider if available\n if (this.search) {\n await this.search.indexEntity(this.repositoryId, {\n entityId: entity.id,\n entityType: entity.entityType,\n label: entity.label,\n summary: entity.summary,\n properties: entity.properties,\n data: entity.data,\n });\n }\n\n return entity;\n }\n\n async getEntity(\n entityId: string,\n detailLevel?: DetailLevel,\n ): Promise<Entity | EntitySummary | EntityBrief | null> {\n return this.entityManager.get(entityId, detailLevel);\n }\n\n async getBySlug(\n slug: string,\n detailLevel?: DetailLevel,\n ): Promise<Entity | EntitySummary | EntityBrief | null> {\n return this.entityManager.getBySlug(slug, detailLevel);\n }\n\n async getEntities(\n entityIds: string[],\n detailLevel?: 'brief' | 'summary',\n ): Promise<Map<string, EntitySummary | EntityBrief>> {\n return this.entityManager.getMany(entityIds, detailLevel);\n }\n\n async findEntities(query: FindEntitiesQuery): Promise<PaginatedResult<Entity | EntitySummary | EntityBrief>> {\n return this.searchOrchestrator.findEntities(query);\n }\n\n async deleteEntities(ids: string[]): Promise<DeleteEntitiesResult> {\n const result = await this.entityManager.deleteMany(ids);\n\n if (this.search && result.deleted.length > 0) {\n for (const id of result.deleted) {\n await this.search.removeEntity(this.repositoryId, id);\n }\n }\n\n return result;\n }\n\n // ─── Re-embedding ──────────────────────────────────────────────────\n\n /** Re-embed specific entities using the current EmbeddingProvider */\n async reembedEntities(entityIds: string[]): Promise<ReembedResult> {\n return this.entityManager.reembedEntities(entityIds);\n }\n\n /**\n * Re-embed all entities in the repository. If `model` or `dimensions` is provided,\n * the repository's embedding configuration is updated to the new values before\n * re-embedding, so all subsequent entity writes use the new model/dimensionality.\n *\n * Processes in batches with optional rate limiting. Emits reembed:* events for progress tracking.\n * Updates repository metadata with the new model ID and dimensions on completion.\n */\n async reembedAll(options?: {\n /** New embedding model to switch to. Requires an embeddingFactory on DeepMemory. */\n model?: string;\n /** New embedding dimensionality to switch to. Requires an embeddingFactory on DeepMemory. */\n dimensions?: number;\n batchSize?: number;\n /** Max retries per batch on embedding failure (default 3) */\n maxRetries?: number;\n /** Abort after this many cumulative failures (default: no limit) */\n errorThresholdToAbort?: number;\n /** Milliseconds to wait between batches for rate limiting (default 0) */\n delayBetweenBatchesMs?: number;\n }): Promise<ReembedResult> {\n // If the caller asked for a model or dimension change, swap in a new provider\n // built from the factory and point every component that uses embeddings at it.\n // This must happen before re-embedding so the new vectors use the new config.\n if (options?.model !== undefined || options?.dimensions !== undefined) {\n if (!this.embeddingFactory) {\n throw new Error(\n 'Cannot change embedding model or dimensions: DeepMemory was constructed without an embeddingFactory. ' +\n 'Provide embeddingFactory in DeepMemoryConfig to enable per-repository embedding reconfiguration.',\n );\n }\n const currentModel = this.embedding?.modelId();\n // dimensions() throws if unknown — fall back to undefined when the current provider has never embedded\n let currentDimensions: number | undefined;\n try { currentDimensions = this.embedding?.dimensions(); } catch { currentDimensions = undefined; }\n\n const nextModel = options.model ?? currentModel;\n const nextDimensions = options.dimensions ?? currentDimensions;\n\n if (!nextModel || nextDimensions === undefined) {\n throw new Error(\n 'Cannot rebuild embedding provider: model and dimensions must both be known. ' +\n `Got model=\"${nextModel ?? 'undefined'}\", dimensions=${nextDimensions ?? 'undefined'}.`,\n );\n }\n\n const newProvider = this.embeddingFactory({ model: nextModel, dimensions: nextDimensions });\n this.embedding = newProvider;\n this.entityManager.setEmbeddingProvider(newProvider);\n this.searchOrchestrator.setEmbeddingProvider(newProvider);\n\n // Persist the new embedding configuration on the repository itself, so that any\n // subsequent openRepository() call rebuilds a provider with the matching config.\n await this.storage.updateRepository(this.repositoryId, {\n metadata: {\n embeddingModelId: nextModel,\n embeddingDimensions: nextDimensions,\n },\n });\n }\n\n // Emit started event\n const stats = await this.getStats();\n await this.eventBus.emit('reembed:started', {\n repositoryId: this.repositoryId,\n totalEntities: stats.entityCount,\n });\n\n try {\n const result = await this.entityManager.reembedAll({\n batchSize: options?.batchSize,\n maxRetries: options?.maxRetries,\n errorThresholdToAbort: options?.errorThresholdToAbort,\n delayBetweenBatchesMs: options?.delayBetweenBatchesMs,\n onProgress: async (processed, total, failed) => {\n await this.eventBus.emit('reembed:progress', {\n repositoryId: this.repositoryId,\n processed,\n totalEntities: total,\n failed,\n });\n },\n });\n\n // Update repository metadata with the model/dimensions actually produced by the run\n await this.storage.updateRepository(this.repositoryId, {\n metadata: {\n embeddingModelId: result.modelId,\n embeddingDimensions: result.dimensions,\n },\n });\n\n await this.eventBus.emit('reembed:completed', {\n repositoryId: this.repositoryId,\n processed: result.processed,\n failed: result.failed,\n modelId: result.modelId,\n });\n\n return result;\n } catch (err) {\n await this.eventBus.emit('reembed:failed', {\n repositoryId: this.repositoryId,\n error: err instanceof Error ? err.message : String(err),\n });\n throw err;\n }\n }\n\n // ─── Relationships ─────────────────────────────────────────────────\n\n async createRelationships(inputs: CreateRelationshipInput[]): Promise<Relationship[]> {\n return this.relationshipManager.create(inputs);\n }\n\n async removeRelationships(ids: string[]): Promise<RemoveRelationshipsResult> {\n return this.relationshipManager.removeMany(ids);\n }\n\n async getRelationships(\n entityId: string,\n options?: { relationshipTypes?: string[]; direction?: 'outbound' | 'inbound' | 'both'; limit?: number; offset?: number; propertyFilters?: import('../types/queries.js').PropertyFilter[] },\n ): Promise<PaginatedResult<Relationship>> {\n return this.relationshipManager.getForEntity(entityId, options);\n }\n\n async getRelationshipSummary(entityId: string): Promise<RelationshipSummary> {\n const result = await this.storage.getEntityRelationships(\n this.repositoryId,\n entityId,\n { direction: 'both', limit: 10000 },\n );\n\n const outbound: Record<string, number> = {};\n const inbound: Record<string, number> = {};\n\n for (const rel of result.items) {\n if (rel.sourceEntityId === entityId) {\n outbound[rel.relationshipType] = (outbound[rel.relationshipType] ?? 0) + 1;\n }\n if (rel.targetEntityId === entityId) {\n inbound[rel.relationshipType] = (inbound[rel.relationshipType] ?? 0) + 1;\n }\n }\n\n return { outbound, inbound };\n }\n\n async getRelationshipsForEntities(entityIds: string[]): Promise<Relationship[]> {\n const seen = new Set<string>();\n const results: Relationship[] = [];\n\n for (const entityId of entityIds) {\n const rels = await this.relationshipManager.getForEntity(entityId, {\n direction: 'both',\n limit: 10000,\n });\n\n for (const rel of rels.items) {\n if (!seen.has(rel.id)) {\n seen.add(rel.id);\n results.push(rel);\n }\n }\n }\n\n return results;\n }\n\n // ─── Graph ─────────────────────────────────────────────────────────\n\n /** Get the full graph — entities with enriched relationships, vocabulary, and stats. Paginated. */\n async getGraph(options?: { limit?: number; offset?: number; detailLevel?: DetailLevel }): Promise<GraphResult> {\n const pageSize = options?.limit ?? 200;\n const offset = options?.offset ?? 0;\n\n const [stats, vocabulary] = await Promise.all([\n this.getStats(),\n this.getVocabulary(),\n ]);\n\n const entities = await this.findEntities({ limit: pageSize, offset, detailLevel: options?.detailLevel ?? 'summary' });\n\n // Fetch relationships for this page of entities\n const rawRelationships = await this.getRelationshipsForEntities(\n entities.items.map((e) => e.id),\n );\n\n // Build entity lookup for enrichment\n const entityLookup = new Map<string, { slug: string; label: string }>();\n for (const e of entities.items) {\n entityLookup.set(e.id, { slug: e.slug, label: e.label });\n }\n\n // Enrich relationships with slug/label, capped at 1000\n const MAX_RELATIONSHIPS = 1000;\n const totalRelationships = rawRelationships.length;\n const cappedRelationships = rawRelationships.slice(0, MAX_RELATIONSHIPS);\n const relationships: EnrichedRelationship[] = cappedRelationships.map((rel) => {\n const source = entityLookup.get(rel.sourceEntityId);\n const target = entityLookup.get(rel.targetEntityId);\n return {\n ...rel,\n sourceSlug: source?.slug ?? rel.sourceEntityId,\n sourceLabel: source?.label ?? rel.sourceEntityId,\n targetSlug: target?.slug ?? rel.targetEntityId,\n targetLabel: target?.label ?? rel.targetEntityId,\n };\n });\n\n const nextOffset = offset + entities.items.length;\n const hasMore = nextOffset < stats.entityCount;\n\n return {\n vocabulary,\n stats,\n entities: entities.items,\n relationships,\n totalRelationships,\n relationshipsTruncated: totalRelationships > MAX_RELATIONSHIPS,\n hasMore,\n ...(hasMore ? { cursor: `offset:${nextOffset}` } : {}),\n };\n }\n\n // ─── Graph Traversal ───────────────────────────────────────────────\n\n async exploreNeighborhood(\n entityId: string,\n options?: ExploreOptions,\n ): Promise<Neighborhood> {\n return this.graphTraversal.exploreNeighborhood(entityId, options);\n }\n\n async findPaths(\n sourceId: string,\n targetId: string,\n options?: PathOptions,\n ): Promise<PathResult> {\n return this.graphTraversal.findPaths(sourceId, targetId, options);\n }\n\n async traverse(spec: TraversalSpec): Promise<TraversalResult> {\n return this.graphTraversal.traverse(spec);\n }\n\n async executeNativeQuery(\n query: string,\n params?: Record<string, unknown>,\n ): Promise<TraversalResult> {\n return this.graphTraversal.executeNativeQuery(query, params);\n }\n\n // ─── Search ────────────────────────────────────────────────────────\n\n async searchByConcept(\n query: string,\n options?: ConceptSearchOptions,\n ): Promise<PaginatedResult<ScoredEntity>> {\n return this.searchOrchestrator.searchByConcept(query, options);\n }\n\n // ─── Timeline ──────────────────────────────────────────────────────\n\n async getTimeline(entityId: string, options?: TimelineOptions): Promise<TimelineResult> {\n const storageOptions = {\n timeRange: options?.timeRange,\n eventTypes: options?.eventTypes,\n provenance: options?.provenance,\n limit: options?.limit ?? 20,\n offset: options?.offset ?? 0,\n };\n\n const storageResult = await this.storage.getTimeline(\n this.repositoryId,\n entityId,\n storageOptions,\n );\n\n // Get the center entity for slug info\n const entity = await this.storage.getEntity(this.repositoryId, entityId);\n const centerRef: TimelineEntityRef = {\n id: entityId,\n slug: entity?.slug ?? entityId,\n label: entity?.label ?? entityId,\n };\n\n // Batch-collect all relationship IDs to resolve\n const relIds = storageResult.events\n .filter((e) => e.relationshipId)\n .map((e) => e.relationshipId!);\n\n // Fetch relationships and collect entity IDs from them\n const relMap = new Map<string, { id: string; type: string; sourceId: string; targetId: string }>();\n const entityIdsToResolve = new Set<string>();\n\n for (const rid of relIds) {\n const rel = await this.storage.getRelationship(this.repositoryId, rid);\n if (rel) {\n relMap.set(rid, {\n id: rel.id,\n type: rel.relationshipType,\n sourceId: rel.sourceEntityId,\n targetId: rel.targetEntityId,\n });\n entityIdsToResolve.add(rel.sourceEntityId);\n entityIdsToResolve.add(rel.targetEntityId);\n }\n }\n\n // Batch-fetch all referenced entities\n const entityMap = await this.storage.getEntities(\n this.repositoryId,\n Array.from(entityIdsToResolve),\n );\n\n const toRef = (eid: string): TimelineEntityRef => {\n const e = entityMap.get(eid);\n return { id: eid, slug: e?.slug ?? eid, label: e?.label ?? eid };\n };\n\n // Build enriched events\n const events: TimelineEvent[] = storageResult.events.map((e) => {\n if (e.relationshipId && relMap.has(e.relationshipId)) {\n const rel = relMap.get(e.relationshipId)!;\n const sourceRef = toRef(rel.sourceId);\n const targetRef = toRef(rel.targetId);\n const otherRef = rel.sourceId === entityId ? targetRef : sourceRef;\n const direction = rel.sourceId === entityId ? 'to' : 'from';\n const relDetail: TimelineRelationshipDetail = {\n id: rel.id,\n relationshipType: rel.type,\n sourceEntity: sourceRef,\n targetEntity: targetRef,\n };\n\n return {\n timestamp: e.timestamp,\n eventType: e.eventType,\n description: `${rel.type} relationship created ${direction} ${otherRef.label}`,\n relatedEntities: [centerRef, otherRef],\n relationship: relDetail,\n };\n }\n\n // Entity events (created/updated)\n const action = e.eventType === 'entity:created' ? 'created' : 'updated';\n return {\n timestamp: e.timestamp,\n eventType: e.eventType,\n description: `${centerRef.label} ${action}`,\n relatedEntities: [centerRef],\n };\n });\n\n return {\n id: entityId,\n slug: centerRef.slug,\n totalEvents: storageResult.total,\n returned: events.length,\n events,\n };\n }\n\n // ─── Stats ─────────────────────────────────────────────────────────\n\n async getStats(): Promise<RepositoryStats> {\n return this.storage.getRepositoryStats(this.repositoryId);\n }\n\n // ─── Validation ────────────────────────────────────────────────────\n\n /**\n * Audit a window of entities against the current vocabulary. Returns a single\n * page; callers loop until `done` is true. Paging is over scanned entities,\n * not issues. Does not mutate anything.\n */\n async validateEntities(options?: ValidateEntitiesOptions): Promise<EntityValidationPage> {\n const validator = new RepositoryValidator(\n this.repositoryId,\n this.storage,\n this.vocabularyEngine,\n );\n return validator.validateEntities(options);\n }\n\n /**\n * Audit a window of relationships against the current vocabulary. Returns a\n * single page; callers loop until `done` is true. The full entity set is\n * loaded once per call to resolve orphan and type-mismatch checks, then\n * offset/take is applied to the relationship stream. Does not mutate anything.\n */\n async validateRelationships(options?: ValidateRelationshipsOptions): Promise<RelationshipValidationPage> {\n const validator = new RepositoryValidator(\n this.repositoryId,\n this.storage,\n this.vocabularyEngine,\n );\n return validator.validateRelationships(options);\n }\n\n // ─── Bulk Operations ──────────────────────────────────────────────\n\n /** Delete all entities and relationships in this repository, preserving the repository and vocabulary */\n async deleteAllContents(): Promise<{ deletedEntities: number; deletedRelationships: number }> {\n return this.storage.deleteAllContents(this.repositoryId);\n }\n\n /**\n * Returns a static markdown guide describing the recommended query strategy\n * for AI agents and other consumers of the repository.\n */\n getQueryGuide(): string {\n return `## Query Strategy Guide\n\n### Step 1 — Discover before you traverse\n\nBefore following relationships from an entity, check that it actually has relationships.\nGraph queries include \\`relationshipSummary\\` on every returned entity by default\n(outbound and inbound counts by type). Inspect this before traversing — entities with\nzero outbound counts for the relationship type you need have no connections to follow.\nTo skip summaries and reduce response size, set \\`includeRelationshipSummary: false\\`.\n\n### Step 2 — Use projection for aggregation\n\nTo understand what data exists (e.g. all distinct values of a property, or counts by\ncategory), use a graph query with \\`projection\\` instead of fetching full entities:\n\\`{ start: { entityType: \"...\" }, projection: { properties: [\"propName\"], distinct: true }, limit: 200 }\\`\n\nThis returns only the aggregated values — no entity objects — keeping responses lightweight.\n\n### Step 3 — Traverse efficiently\n\n- **Omit relationshipTypes** in a traversal step to follow all relationship types at once,\n rather than making separate calls per type.\n- **Use multi-step traversals** for multi-hop patterns. A two-step traverse operation\n (e.g. Equipment → Component → MaintenanceProcedure) is one call, not two sequential calls.\n- **Use returnMode \"all\"** when you need intermediate entities along the path, not just\n the terminal nodes.\n\n### Step 4 — Use semantic search for known-unknowns\n\nSemantic/concept search is best for finding specific entities when you know roughly\nwhat you're looking for but not the exact label or type. It is not efficient for broad\ndiscovery — use projection or entity finding for that.\n\n### Common anti-patterns to avoid\n\n- **Don't traverse from entities with zero relationship counts.** The \\`relationshipSummary\\` on each entity tells you what is connected before you traverse.\n- **Don't split queries by relationship type.** One traverse step with no type filter is better\n than three separate single-type calls.\n- **Don't use sequential single-hop traversals** when a multi-step traverse operation achieves the\n same result in one call.\n- **Don't fetch full entities when you only need property values.** Use projection.`;\n }\n\n // ─── Events ────────────────────────────────────────────────────────\n\n on<E extends DeepMemoryEventType>(event: E, handler: EventHandler<E>): Unsubscribe {\n return this.eventBus.on(event, handler);\n }\n\n onHook<E extends Extract<DeepMemoryEventType, 'entity:creating' | 'entity:updating' | 'entity:deleting' | 'relationship:creating' | 'relationship:removing'>>(\n event: E,\n handler: HookHandler<E>,\n ): Unsubscribe {\n return this.eventBus.onHook(event, handler);\n }\n}\n","// SemanticDeduplicator — detects duplicate type proposals using string or embedding similarity\n\nimport type { EmbeddingProvider } from '../providers/EmbeddingProvider.js';\nimport { jaroWinklerSimilarity, normalizeTypeName } from './similarity.js';\n\n/** A match found during deduplication */\nexport interface DeduplicationMatch {\n type: string;\n description: string;\n similarity: number;\n}\n\n/** Result of a deduplication check */\nexport interface DeduplicationResult {\n isDuplicate: boolean;\n matches: DeduplicationMatch[];\n}\n\n/** An existing type to check against */\nexport interface ExistingType {\n type: string;\n description: string;\n}\n\nexport interface SemanticDeduplicatorConfig {\n /** Similarity threshold above which a proposed type is considered a duplicate (default 0.85) */\n similarityThreshold?: number;\n /** Optional embedding provider for semantic comparison */\n embeddingProvider?: EmbeddingProvider;\n}\n\nconst DEFAULT_THRESHOLD = 0.85;\n\nexport class SemanticDeduplicator {\n private readonly threshold: number;\n private readonly embeddingProvider?: EmbeddingProvider;\n\n constructor(config: SemanticDeduplicatorConfig = {}) {\n this.threshold = config.similarityThreshold ?? DEFAULT_THRESHOLD;\n this.embeddingProvider = config.embeddingProvider;\n }\n\n /**\n * Check whether a proposed type name is a duplicate of an existing type.\n * Uses embedding similarity if an EmbeddingProvider is available, otherwise falls back\n * to Jaro-Winkler string similarity on normalized type names.\n */\n async checkDuplicate(\n proposedType: string,\n proposedDescription: string,\n existingTypes: ExistingType[],\n ): Promise<DeduplicationResult> {\n if (existingTypes.length === 0) {\n return { isDuplicate: false, matches: [] };\n }\n\n // Exact match check first (normalized)\n const normProposed = normalizeTypeName(proposedType);\n const exactMatch = existingTypes.find((t) => normalizeTypeName(t.type) === normProposed);\n if (exactMatch) {\n return {\n isDuplicate: true,\n matches: [{ type: exactMatch.type, description: exactMatch.description, similarity: 1.0 }],\n };\n }\n\n // Try embedding-based similarity if available\n if (this.embeddingProvider) {\n return this.checkWithEmbeddings(proposedType, proposedDescription, existingTypes);\n }\n\n // Fall back to Jaro-Winkler on type names\n return this.checkWithStringSimilarity(proposedType, existingTypes);\n }\n\n private async checkWithEmbeddings(\n proposedType: string,\n proposedDescription: string,\n existingTypes: ExistingType[],\n ): Promise<DeduplicationResult> {\n const proposedText = `${proposedType}: ${proposedDescription}`;\n const existingTexts = existingTypes.map((t) => `${t.type}: ${t.description}`);\n\n const allTexts = [proposedText, ...existingTexts];\n const embeddings = await this.embeddingProvider!.embedBatch(allTexts);\n const proposedEmbedding = embeddings[0]!;\n\n const matches: DeduplicationMatch[] = [];\n\n for (let i = 0; i < existingTypes.length; i++) {\n const similarity = this.cosineSimilarity(proposedEmbedding, embeddings[i + 1]!);\n if (similarity >= this.threshold) {\n matches.push({\n type: existingTypes[i]!.type,\n description: existingTypes[i]!.description,\n similarity,\n });\n }\n }\n\n // Sort by similarity descending\n matches.sort((a, b) => b.similarity - a.similarity);\n\n return {\n isDuplicate: matches.length > 0,\n matches,\n };\n }\n\n private checkWithStringSimilarity(\n proposedType: string,\n existingTypes: ExistingType[],\n ): DeduplicationResult {\n const normProposed = normalizeTypeName(proposedType);\n const matches: DeduplicationMatch[] = [];\n\n for (const existing of existingTypes) {\n const normExisting = normalizeTypeName(existing.type);\n const similarity = jaroWinklerSimilarity(normProposed, normExisting);\n\n if (similarity >= this.threshold) {\n matches.push({\n type: existing.type,\n description: existing.description,\n similarity,\n });\n }\n }\n\n // Sort by similarity descending\n matches.sort((a, b) => b.similarity - a.similarity);\n\n return {\n isDuplicate: matches.length > 0,\n matches,\n };\n }\n\n private cosineSimilarity(a: number[], b: number[]): number {\n // Use provider's similarity function if available\n if (this.embeddingProvider?.similarity) {\n return this.embeddingProvider.similarity(a, b);\n }\n\n // Default cosine similarity\n let dotProduct = 0;\n let normA = 0;\n let normB = 0;\n\n for (let i = 0; i < a.length; i++) {\n dotProduct += a[i]! * b[i]!;\n normA += a[i]! * a[i]!;\n normB += b[i]! * b[i]!;\n }\n\n const denominator = Math.sqrt(normA) * Math.sqrt(normB);\n return denominator === 0 ? 0 : dotProduct / denominator;\n }\n}\n","// VocabularySchema — factory functions for creating well-formed vocabulary definitions\n\nimport type {\n EntityTypeDefinition,\n EntityTypeInput,\n MemoryVocabulary,\n PropertySchema,\n RelationshipTypeDefinition,\n RelationshipTypeInput,\n VocabularyInput,\n VocabularyProposal,\n} from '../types/vocabulary.js';\nimport { toScreamingSnakeCase } from './similarity.js';\n\n/** Create an empty vocabulary with version \"0.0.0\" */\nexport function createEmptyVocabulary(modifiedBy: string): MemoryVocabulary {\n const now = new Date().toISOString();\n return {\n version: '0.0.0',\n lastModified: now,\n modifiedBy,\n entityTypes: [],\n relationshipTypes: [],\n };\n}\n\n/** Create an EntityTypeDefinition from an input, filling in system-managed fields */\nexport function createEntityTypeDefinition(\n input: EntityTypeInput,\n createdBy: string,\n): EntityTypeDefinition {\n const now = new Date().toISOString();\n return {\n type: input.type,\n description: input.description,\n version: '1.0.0',\n properties: input.properties ?? [],\n createdAt: now,\n createdBy,\n modifiedAt: now,\n modifiedBy: createdBy,\n };\n}\n\n/** Create a RelationshipTypeDefinition from an input, filling in system-managed fields */\nexport function createRelationshipTypeDefinition(\n input: RelationshipTypeInput,\n createdBy: string,\n): RelationshipTypeDefinition {\n const now = new Date().toISOString();\n return {\n type: toScreamingSnakeCase(input.type),\n description: input.description,\n version: '1.0.0',\n allowedSourceTypes: input.allowedSourceTypes,\n allowedTargetTypes: input.allowedTargetTypes,\n bidirectional: input.bidirectional ?? false,\n properties: input.properties,\n createdAt: now,\n createdBy,\n modifiedAt: now,\n modifiedBy: createdBy,\n };\n}\n\n/** Build a full MemoryVocabulary from a VocabularyInput */\nexport function buildVocabulary(input: VocabularyInput, createdBy: string): MemoryVocabulary {\n const now = new Date().toISOString();\n return {\n version: '1.0.0',\n lastModified: now,\n modifiedBy: createdBy,\n entityTypes: (input.entityTypes ?? []).map((et) => createEntityTypeDefinition(et, createdBy)),\n relationshipTypes: (input.relationshipTypes ?? []).map((rt) =>\n createRelationshipTypeDefinition(rt, createdBy),\n ),\n };\n}\n\n/** Increment a semantic version string (patch by default) */\nexport function incrementVersion(\n version: string,\n level: 'major' | 'minor' | 'patch' = 'patch',\n): string {\n const parts = version.split('.').map(Number);\n const major = parts[0] ?? 0;\n const minor = parts[1] ?? 0;\n const patch = parts[2] ?? 0;\n\n switch (level) {\n case 'major':\n return `${major + 1}.0.0`;\n case 'minor':\n return `${major}.${minor + 1}.0`;\n case 'patch':\n return `${major}.${minor}.${patch + 1}`;\n }\n}\n\n/** Merge property edits into an existing properties array */\nfunction mergeProperties(\n existing: PropertySchema[],\n addProperties?: PropertySchema[],\n removeProperties?: string[],\n updateProperties?: PropertySchema[],\n): PropertySchema[] {\n // Start from existing\n let result = [...existing];\n\n // Remove\n if (removeProperties && removeProperties.length > 0) {\n const removeSet = new Set(removeProperties);\n result = result.filter((p) => !removeSet.has(p.name));\n }\n\n // Update (replace by name)\n if (updateProperties && updateProperties.length > 0) {\n const updateMap = new Map(updateProperties.map((p) => [p.name, p]));\n result = result.map((p) => updateMap.get(p.name) ?? p);\n }\n\n // Add\n if (addProperties && addProperties.length > 0) {\n const existingNames = new Set(result.map((p) => p.name));\n for (const prop of addProperties) {\n if (!existingNames.has(prop.name)) {\n result.push(prop);\n }\n }\n }\n\n return result;\n}\n\n/** Apply an edit to an existing EntityTypeDefinition */\nexport function mergeEntityTypeEdit(\n existing: EntityTypeDefinition,\n edit: NonNullable<VocabularyProposal['editEntityType']>,\n modifiedBy: string,\n): EntityTypeDefinition {\n const now = new Date().toISOString();\n return {\n ...existing,\n description: edit.description ?? existing.description,\n version: incrementVersion(existing.version, 'minor'),\n properties: mergeProperties(\n existing.properties,\n edit.addProperties,\n edit.removeProperties,\n edit.updateProperties,\n ),\n modifiedAt: now,\n modifiedBy,\n };\n}\n\n/** Apply an edit to an existing RelationshipTypeDefinition */\nexport function mergeRelationshipTypeEdit(\n existing: RelationshipTypeDefinition,\n edit: NonNullable<VocabularyProposal['editRelationshipType']>,\n modifiedBy: string,\n): RelationshipTypeDefinition {\n const now = new Date().toISOString();\n return {\n ...existing,\n description: edit.description ?? existing.description,\n allowedSourceTypes: edit.allowedSourceTypes ?? existing.allowedSourceTypes,\n allowedTargetTypes: edit.allowedTargetTypes ?? existing.allowedTargetTypes,\n bidirectional: edit.bidirectional ?? existing.bidirectional,\n version: incrementVersion(existing.version, 'minor'),\n properties: mergeProperties(\n existing.properties ?? [],\n edit.addProperties,\n edit.removeProperties,\n edit.updateProperties,\n ),\n modifiedAt: now,\n modifiedBy,\n };\n}\n","// VocabularyGovernor — implements governance modes for vocabulary evolution\n\nimport type {\n GovernanceConfig,\n MemoryVocabulary,\n VocabularyProposal,\n VocabularyProposalResult,\n VocabularyChangeRecord,\n} from '../types/vocabulary.js';\nimport {\n createEntityTypeDefinition,\n createRelationshipTypeDefinition,\n incrementVersion,\n mergeEntityTypeEdit,\n mergeRelationshipTypeEdit,\n} from './VocabularySchema.js';\n\n/** Why a proposal was denied */\nexport interface GovernanceDenial {\n allowed: false;\n reason: string;\n}\n\n/** Proposal is allowed to proceed */\nexport interface GovernanceApproval {\n allowed: true;\n}\n\nexport type GovernanceDecision = GovernanceDenial | GovernanceApproval;\n\n/** Check whether a proposal is allowed under the given governance mode */\nexport function canPropose(\n governanceConfig: GovernanceConfig,\n _proposal: VocabularyProposal,\n): GovernanceDecision {\n switch (governanceConfig.mode) {\n case 'locked':\n return {\n allowed: false,\n reason:\n 'Vocabulary is locked. Only organization admins can modify the vocabulary via the admin API.',\n };\n case 'managed':\n case 'open':\n return { allowed: true };\n }\n}\n\nexport interface ProcessProposalOptions {\n /** Pre-checked deduplication result — if duplicates were found, pass them here */\n duplicates?: Array<{ type: string; description: string; similarity: number }>;\n /** The actor proposing the change */\n proposedBy: string;\n}\n\n/**\n * Process a vocabulary proposal according to governance rules.\n * Returns the updated vocabulary (if approved) and a proposal result.\n */\nexport function processProposal(\n vocabulary: MemoryVocabulary,\n proposal: VocabularyProposal,\n governanceConfig: GovernanceConfig,\n options: ProcessProposalOptions,\n): {\n result: VocabularyProposalResult;\n updatedVocabulary?: MemoryVocabulary;\n changeRecord?: VocabularyChangeRecord;\n} {\n const decision = canPropose(governanceConfig, proposal);\n if (!decision.allowed) {\n return {\n result: {\n status: 'rejected',\n type: getProposedTypeName(proposal),\n reason: decision.reason,\n },\n };\n }\n\n // Edit and delete proposals skip deduplication\n const isAddProposal =\n proposal.proposalType === 'entity_type' || proposal.proposalType === 'relationship_type';\n\n // If duplicates were found (add proposals only), reject\n if (isAddProposal && options.duplicates && options.duplicates.length > 0) {\n return {\n result: {\n status: 'rejected',\n type: getProposedTypeName(proposal),\n reason: `Similar type(s) already exist in the vocabulary`,\n duplicates: options.duplicates,\n },\n };\n }\n\n // Managed mode with requireApproval — queue for human approval\n if (governanceConfig.mode === 'managed' && governanceConfig.requireApproval) {\n return {\n result: {\n status: 'pending_approval',\n type: getProposedTypeName(proposal),\n proposalId: generateProposalId(),\n },\n };\n }\n\n // Auto-approve: managed (without requireApproval) or open\n switch (proposal.proposalType) {\n case 'entity_type':\n case 'relationship_type':\n return applyAddProposal(vocabulary, proposal, options.proposedBy);\n case 'edit_entity_type':\n case 'edit_relationship_type':\n return applyEditProposal(vocabulary, proposal, options.proposedBy);\n case 'delete_entity_type':\n case 'delete_relationship_type':\n return applyDeleteProposal(vocabulary, proposal, options.proposedBy);\n }\n}\n\n/** Apply an add proposal to the vocabulary */\nfunction applyAddProposal(\n vocabulary: MemoryVocabulary,\n proposal: VocabularyProposal,\n proposedBy: string,\n): {\n result: VocabularyProposalResult;\n updatedVocabulary: MemoryVocabulary;\n changeRecord: VocabularyChangeRecord;\n} {\n const now = new Date().toISOString();\n const newVersion = incrementVersion(vocabulary.version, 'minor');\n const typeName = getProposedTypeName(proposal);\n\n let updatedVocabulary: MemoryVocabulary;\n let changeType: VocabularyChangeRecord['changeType'];\n\n if (proposal.proposalType === 'entity_type' && proposal.entityType) {\n const newType = createEntityTypeDefinition(proposal.entityType, proposedBy);\n updatedVocabulary = {\n ...vocabulary,\n version: newVersion,\n lastModified: now,\n modifiedBy: proposedBy,\n entityTypes: [...vocabulary.entityTypes, newType],\n };\n changeType = 'entity_type_added';\n } else if (proposal.proposalType === 'relationship_type' && proposal.relationshipType) {\n const newType = createRelationshipTypeDefinition(\n {\n type: proposal.relationshipType.type,\n description: proposal.relationshipType.description,\n allowedSourceTypes: proposal.relationshipType.allowedSourceTypes,\n allowedTargetTypes: proposal.relationshipType.allowedTargetTypes,\n bidirectional: proposal.relationshipType.bidirectional,\n properties: proposal.relationshipType.properties,\n },\n proposedBy,\n );\n updatedVocabulary = {\n ...vocabulary,\n version: newVersion,\n lastModified: now,\n modifiedBy: proposedBy,\n relationshipTypes: [...vocabulary.relationshipTypes, newType],\n };\n changeType = 'relationship_type_added';\n } else {\n return {\n result: {\n status: 'rejected',\n type: typeName,\n reason: 'Invalid proposal: missing type definition for the specified proposal type',\n },\n updatedVocabulary: vocabulary,\n changeRecord: {\n changeId: generateChangeId(),\n changeType: 'entity_type_added',\n typeName,\n newVersion: vocabulary.version,\n proposedBy,\n proposedAt: now,\n reason: proposal.justification,\n },\n };\n }\n\n const changeRecord: VocabularyChangeRecord = {\n changeId: generateChangeId(),\n changeType,\n typeName,\n previousVersion: vocabulary.version,\n newVersion,\n proposedBy,\n proposedAt: now,\n approvedAt: now,\n reason: proposal.justification,\n };\n\n return {\n result: { status: 'approved', type: typeName, vocabularyVersion: newVersion },\n updatedVocabulary,\n changeRecord,\n };\n}\n\n/** Apply an edit proposal to the vocabulary */\nfunction applyEditProposal(\n vocabulary: MemoryVocabulary,\n proposal: VocabularyProposal,\n proposedBy: string,\n): {\n result: VocabularyProposalResult;\n updatedVocabulary?: MemoryVocabulary;\n changeRecord?: VocabularyChangeRecord;\n} {\n const now = new Date().toISOString();\n const typeName = getProposedTypeName(proposal);\n const newVersion = incrementVersion(vocabulary.version, 'minor');\n\n let updatedVocabulary: MemoryVocabulary;\n let changeType: VocabularyChangeRecord['changeType'];\n\n if (proposal.proposalType === 'edit_entity_type' && proposal.editEntityType) {\n const existing = vocabulary.entityTypes.find((et) => et.type === proposal.editEntityType!.type);\n if (!existing) {\n return {\n result: {\n status: 'rejected',\n type: typeName,\n reason: `Entity type \"${typeName}\" not found in vocabulary`,\n },\n };\n }\n const merged = mergeEntityTypeEdit(existing, proposal.editEntityType, proposedBy);\n updatedVocabulary = {\n ...vocabulary,\n version: newVersion,\n lastModified: now,\n modifiedBy: proposedBy,\n entityTypes: vocabulary.entityTypes.map((et) => (et.type === typeName ? merged : et)),\n };\n changeType = 'entity_type_modified';\n } else if (proposal.proposalType === 'edit_relationship_type' && proposal.editRelationshipType) {\n const existing = vocabulary.relationshipTypes.find(\n (rt) => rt.type === proposal.editRelationshipType!.type,\n );\n if (!existing) {\n return {\n result: {\n status: 'rejected',\n type: typeName,\n reason: `Relationship type \"${typeName}\" not found in vocabulary`,\n },\n };\n }\n const merged = mergeRelationshipTypeEdit(existing, proposal.editRelationshipType, proposedBy);\n updatedVocabulary = {\n ...vocabulary,\n version: newVersion,\n lastModified: now,\n modifiedBy: proposedBy,\n relationshipTypes: vocabulary.relationshipTypes.map((rt) =>\n rt.type === typeName ? merged : rt,\n ),\n };\n changeType = 'relationship_type_modified';\n } else {\n return {\n result: {\n status: 'rejected',\n type: typeName,\n reason: 'Invalid proposal: missing edit definition for the specified proposal type',\n },\n };\n }\n\n const changeRecord: VocabularyChangeRecord = {\n changeId: generateChangeId(),\n changeType,\n typeName,\n previousVersion: vocabulary.version,\n newVersion,\n proposedBy,\n proposedAt: now,\n approvedAt: now,\n reason: proposal.justification,\n };\n\n return {\n result: { status: 'approved', type: typeName, vocabularyVersion: newVersion },\n updatedVocabulary,\n changeRecord,\n };\n}\n\n/** Apply a delete proposal to the vocabulary (vocabulary only — data cascade is handled by VocabularyEngine) */\nfunction applyDeleteProposal(\n vocabulary: MemoryVocabulary,\n proposal: VocabularyProposal,\n proposedBy: string,\n): {\n result: VocabularyProposalResult;\n updatedVocabulary?: MemoryVocabulary;\n changeRecord?: VocabularyChangeRecord;\n} {\n const now = new Date().toISOString();\n const typeName = getProposedTypeName(proposal);\n const newVersion = incrementVersion(vocabulary.version, 'major');\n\n let updatedVocabulary: MemoryVocabulary;\n let changeType: VocabularyChangeRecord['changeType'];\n\n if (proposal.proposalType === 'delete_entity_type' && proposal.deleteEntityType) {\n const exists = vocabulary.entityTypes.some((et) => et.type === proposal.deleteEntityType!.type);\n if (!exists) {\n return {\n result: {\n status: 'rejected',\n type: typeName,\n reason: `Entity type \"${typeName}\" not found in vocabulary`,\n },\n };\n }\n updatedVocabulary = {\n ...vocabulary,\n version: newVersion,\n lastModified: now,\n modifiedBy: proposedBy,\n entityTypes: vocabulary.entityTypes.filter((et) => et.type !== typeName),\n };\n changeType = 'entity_type_removed';\n } else if (\n proposal.proposalType === 'delete_relationship_type' &&\n proposal.deleteRelationshipType\n ) {\n const exists = vocabulary.relationshipTypes.some(\n (rt) => rt.type === proposal.deleteRelationshipType!.type,\n );\n if (!exists) {\n return {\n result: {\n status: 'rejected',\n type: typeName,\n reason: `Relationship type \"${typeName}\" not found in vocabulary`,\n },\n };\n }\n updatedVocabulary = {\n ...vocabulary,\n version: newVersion,\n lastModified: now,\n modifiedBy: proposedBy,\n relationshipTypes: vocabulary.relationshipTypes.filter((rt) => rt.type !== typeName),\n };\n changeType = 'relationship_type_removed';\n } else {\n return {\n result: {\n status: 'rejected',\n type: typeName,\n reason: 'Invalid proposal: missing delete definition for the specified proposal type',\n },\n };\n }\n\n const changeRecord: VocabularyChangeRecord = {\n changeId: generateChangeId(),\n changeType,\n typeName,\n previousVersion: vocabulary.version,\n newVersion,\n proposedBy,\n proposedAt: now,\n approvedAt: now,\n reason: proposal.justification,\n };\n\n return {\n result: { status: 'approved', type: typeName, vocabularyVersion: newVersion },\n updatedVocabulary,\n changeRecord,\n };\n}\n\nfunction getProposedTypeName(proposal: VocabularyProposal): string {\n switch (proposal.proposalType) {\n case 'entity_type':\n return proposal.entityType?.type ?? 'unknown';\n case 'relationship_type':\n return proposal.relationshipType?.type ?? 'unknown';\n case 'edit_entity_type':\n return proposal.editEntityType?.type ?? 'unknown';\n case 'edit_relationship_type':\n return proposal.editRelationshipType?.type ?? 'unknown';\n case 'delete_entity_type':\n return proposal.deleteEntityType?.type ?? 'unknown';\n case 'delete_relationship_type':\n return proposal.deleteRelationshipType?.type ?? 'unknown';\n }\n}\n\nfunction generateProposalId(): string {\n return `proposal_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;\n}\n\nfunction generateChangeId(): string {\n return `change_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;\n}\n","// VocabularyEngine — orchestrates vocabulary validation, governance, and deduplication\n\nimport type { EmbeddingProvider } from '../providers/EmbeddingProvider.js';\nimport type { StorageProvider } from '../providers/StorageProvider.js';\nimport type { CreateEntityInput, UpdateEntityInput } from '../types/entities.js';\nimport type { CreateRelationshipInput } from '../types/relationships.js';\nimport type {\n GovernanceConfig,\n MemoryVocabulary,\n VocabularyProposal,\n VocabularyProposalResult,\n ResolvedVocabulary,\n EntityTypeDefinition,\n} from '../types/vocabulary.js';\nimport {\n SemanticDeduplicator,\n type ExistingType,\n} from '../vocabulary/SemanticDeduplicator.js';\nimport {\n processProposal,\n} from '../vocabulary/VocabularyGovernor.js';\nimport {\n validateEntity,\n validateEntityUpdate,\n validateRelationship,\n validatePropertySchema,\n getEntityTypeDef,\n type ValidationResult,\n} from '../vocabulary/VocabularyValidator.js';\nimport type { PropertySchema } from '../types/vocabulary.js';\n\nexport interface VocabularyEngineConfig {\n repositoryId: string;\n storageProvider: StorageProvider;\n governanceConfig: GovernanceConfig;\n embeddingProvider?: EmbeddingProvider;\n /** Similarity threshold for deduplication (default 0.85) */\n deduplicationThreshold?: number;\n}\n\nexport class VocabularyEngine {\n private readonly repositoryId: string;\n private readonly storage: StorageProvider;\n private readonly governanceConfig: GovernanceConfig;\n private readonly deduplicator: SemanticDeduplicator;\n\n /** Cached vocabulary — invalidated on mutation */\n private cachedVocabulary: MemoryVocabulary | null = null;\n\n constructor(config: VocabularyEngineConfig) {\n this.repositoryId = config.repositoryId;\n this.storage = config.storageProvider;\n this.governanceConfig = config.governanceConfig;\n this.deduplicator = new SemanticDeduplicator({\n similarityThreshold: config.deduplicationThreshold,\n embeddingProvider: config.embeddingProvider,\n });\n }\n\n /** Get the governance configuration for this repository */\n getGovernanceConfig(): GovernanceConfig {\n return this.governanceConfig;\n }\n\n /** Get the current vocabulary from storage (cached) */\n async getVocabulary(): Promise<MemoryVocabulary> {\n if (!this.cachedVocabulary) {\n this.cachedVocabulary = await this.storage.getVocabulary(this.repositoryId);\n }\n return this.cachedVocabulary;\n }\n\n /** Get the resolved vocabulary with governance info */\n async getResolvedVocabulary(): Promise<ResolvedVocabulary> {\n const vocabulary = await this.getVocabulary();\n return {\n vocabulary,\n governanceMode: this.governanceConfig.mode,\n governanceConfig: this.governanceConfig,\n };\n }\n\n /** Invalidate the cached vocabulary (call after external mutations) */\n invalidateCache(): void {\n this.cachedVocabulary = null;\n }\n\n /** Validate an entity creation input against the vocabulary */\n async validateEntity(input: CreateEntityInput): Promise<ValidationResult> {\n const vocabulary = await this.getVocabulary();\n return validateEntity(input, vocabulary);\n }\n\n /** Validate an entity update input against the vocabulary */\n async validateEntityUpdate(\n input: UpdateEntityInput,\n entityType: string,\n ): Promise<ValidationResult> {\n const vocabulary = await this.getVocabulary();\n const typeDef = getEntityTypeDef(entityType, vocabulary);\n if (!typeDef) {\n return {\n valid: false,\n errors: [\n {\n field: 'entityType',\n message: `Entity type \"${entityType}\" does not exist in the vocabulary`,\n },\n ],\n };\n }\n return validateEntityUpdate(input, typeDef, vocabulary);\n }\n\n /** Validate a relationship creation input against the vocabulary */\n async validateRelationship(\n input: CreateRelationshipInput,\n sourceEntityType: string,\n targetEntityType: string,\n ): Promise<ValidationResult> {\n const vocabulary = await this.getVocabulary();\n return validateRelationship(input, vocabulary, sourceEntityType, targetEntityType);\n }\n\n /** Get an entity type definition from the vocabulary */\n async getEntityTypeDef(entityType: string): Promise<EntityTypeDefinition | null> {\n const vocabulary = await this.getVocabulary();\n return getEntityTypeDef(entityType, vocabulary);\n }\n\n /**\n * Propose a vocabulary change (add, edit, or delete).\n * Runs deduplication for add proposals, then governance rules.\n * For delete proposals, cascades data deletion if approved.\n */\n async proposeChange(\n proposal: VocabularyProposal,\n proposedBy: string,\n ): Promise<VocabularyProposalResult> {\n const vocabulary = await this.getVocabulary();\n\n // Only run deduplication for add proposals\n const isAddProposal =\n proposal.proposalType === 'entity_type' || proposal.proposalType === 'relationship_type';\n\n let duplicates: Array<{ type: string; description: string; similarity: number }> | undefined;\n\n if (isAddProposal) {\n const existingTypes = this.getExistingTypesForProposal(proposal, vocabulary);\n const proposedTypeName = this.getProposedTypeName(proposal);\n const proposedDescription = this.getProposedDescription(proposal);\n\n const skipDedup =\n this.governanceConfig.mode === 'open' &&\n this.governanceConfig.deduplicationEnabled === false;\n\n if (!skipDedup) {\n const dedupResult = await this.deduplicator.checkDuplicate(\n proposedTypeName,\n proposedDescription,\n existingTypes,\n );\n if (dedupResult.isDuplicate) {\n duplicates = dedupResult.matches;\n }\n }\n }\n\n // Validate property schemas in the proposal (e.g. embeddable only allowed on string)\n const propertySchemaErrors = this.validateProposalPropertySchemas(proposal);\n if (propertySchemaErrors) {\n return propertySchemaErrors;\n }\n\n // Process through governance\n const { result, updatedVocabulary } = processProposal(\n vocabulary,\n proposal,\n this.governanceConfig,\n { duplicates, proposedBy },\n );\n\n // Persist if approved\n if (result.status === 'approved' && updatedVocabulary) {\n // For delete proposals, cascade-delete data before updating vocabulary\n const isDeleteProposal =\n proposal.proposalType === 'delete_entity_type' ||\n proposal.proposalType === 'delete_relationship_type';\n\n if (isDeleteProposal) {\n await this.cascadeDeleteData(proposal);\n }\n\n await this.storage.saveVocabulary(this.repositoryId, updatedVocabulary);\n this.cachedVocabulary = updatedVocabulary;\n }\n\n return result;\n }\n\n /** @deprecated Use proposeChange instead */\n async proposeExtension(\n proposal: VocabularyProposal,\n proposedBy: string,\n ): Promise<VocabularyProposalResult> {\n return this.proposeChange(proposal, proposedBy);\n }\n\n /** Cascade-delete all data for a deleted vocabulary type */\n private async cascadeDeleteData(\n proposal: VocabularyProposal,\n ): Promise<{ deletedEntities: number; deletedRelationships: number }> {\n if (proposal.proposalType === 'delete_entity_type' && proposal.deleteEntityType) {\n return this.storage.deleteEntitiesByType(\n this.repositoryId,\n proposal.deleteEntityType.type,\n );\n }\n\n if (proposal.proposalType === 'delete_relationship_type' && proposal.deleteRelationshipType) {\n const result = await this.storage.deleteRelationshipsByType(\n this.repositoryId,\n proposal.deleteRelationshipType.type,\n );\n return { deletedEntities: 0, deletedRelationships: result.deletedRelationships };\n }\n\n return { deletedEntities: 0, deletedRelationships: 0 };\n }\n\n /** Validate all property schemas in a proposal — returns a rejected result on the first invalid schema, or undefined if all pass */\n private validateProposalPropertySchemas(proposal: VocabularyProposal): VocabularyProposalResult | undefined {\n const schemas: PropertySchema[] = [];\n let typeName = '';\n\n if (proposal.proposalType === 'entity_type' && proposal.entityType) {\n schemas.push(...(proposal.entityType.properties ?? []));\n typeName = proposal.entityType.type;\n } else if (proposal.proposalType === 'relationship_type' && proposal.relationshipType) {\n schemas.push(...(proposal.relationshipType.properties ?? []));\n typeName = proposal.relationshipType.type;\n } else if (proposal.proposalType === 'edit_entity_type' && proposal.editEntityType) {\n schemas.push(...(proposal.editEntityType.addProperties ?? []));\n schemas.push(...(proposal.editEntityType.updateProperties ?? []));\n typeName = proposal.editEntityType.type;\n } else if (proposal.proposalType === 'edit_relationship_type' && proposal.editRelationshipType) {\n schemas.push(...(proposal.editRelationshipType.addProperties ?? []));\n schemas.push(...(proposal.editRelationshipType.updateProperties ?? []));\n typeName = proposal.editRelationshipType.type;\n }\n\n for (const schema of schemas) {\n const result = validatePropertySchema(schema);\n if (!result.valid) {\n return {\n status: 'rejected',\n type: typeName,\n reason: result.errors.map((e) => e.message).join('; '),\n };\n }\n }\n\n return undefined;\n }\n\n private getExistingTypesForProposal(\n proposal: VocabularyProposal,\n vocabulary: MemoryVocabulary,\n ): ExistingType[] {\n if (proposal.proposalType === 'entity_type') {\n return vocabulary.entityTypes.map((et) => ({\n type: et.type,\n description: et.description,\n }));\n }\n return vocabulary.relationshipTypes.map((rt) => ({\n type: rt.type,\n description: rt.description,\n }));\n }\n\n private getProposedTypeName(proposal: VocabularyProposal): string {\n if (proposal.proposalType === 'entity_type') {\n return proposal.entityType?.type ?? '';\n }\n return proposal.relationshipType?.type ?? '';\n }\n\n private getProposedDescription(proposal: VocabularyProposal): string {\n if (proposal.proposalType === 'entity_type') {\n return proposal.entityType?.description ?? '';\n }\n return proposal.relationshipType?.description ?? '';\n }\n}\n","// ProvenanceTracker — automatic provenance stamping on all mutations\n\nimport type { Provenance, ProvenanceContext } from '../types/provenance.js';\n\n/**\n * Stamps provenance metadata on entities and relationships.\n * The storage provider never needs to worry about provenance —\n * it just stores what it receives from the tracker.\n */\nexport class ProvenanceTracker {\n private context: ProvenanceContext;\n\n constructor(context: ProvenanceContext) {\n this.context = { ...context };\n }\n\n /** Update the active provenance context (e.g., different conversation) */\n updateContext(newContext: Partial<ProvenanceContext>): void {\n this.context = { ...this.context, ...newContext };\n }\n\n /** Get the current provenance context */\n getContext(): ProvenanceContext {\n return { ...this.context };\n }\n\n /** Stamp a newly created entity or relationship with full provenance */\n stampCreate(): Provenance {\n const now = new Date().toISOString();\n return {\n createdBy: this.context.actorId,\n createdByType: this.context.actorType,\n createdAt: now,\n createdInConversation: this.context.conversationId,\n createdFromMessage: this.context.messageId,\n modifiedBy: this.context.actorId,\n modifiedByType: this.context.actorType,\n modifiedAt: now,\n modifiedInConversation: this.context.conversationId,\n modifiedFromMessage: this.context.messageId,\n };\n }\n\n /** Stamp an updated entity or relationship — preserves creation fields, updates modified fields */\n stampUpdate(existing: Provenance): Provenance {\n const now = new Date().toISOString();\n return {\n ...existing,\n modifiedBy: this.context.actorId,\n modifiedByType: this.context.actorType,\n modifiedAt: now,\n modifiedInConversation: this.context.conversationId,\n modifiedFromMessage: this.context.messageId,\n };\n }\n}\n","// EventBus — zero-dependency typed event emitter\n\nimport type {\n DeepMemoryEvent,\n DeepMemoryEventType,\n EventHandler,\n EventPayload,\n HookResult,\n Unsubscribe,\n} from '../types/events.js';\nimport type { ProvenanceContext } from '../types/provenance.js';\n\n/** Pre-mutation event types (those ending in \"ing\") */\ntype PreMutationEvent = Extract<\n DeepMemoryEventType,\n 'entity:creating' | 'entity:updating' | 'entity:deleting' |\n 'relationship:creating' | 'relationship:removing'\n>;\n\n/** Hook handler that can cancel or modify operations */\nexport type HookHandler<T extends PreMutationEvent> = (\n event: DeepMemoryEvent<T>,\n) => HookResult | Promise<HookResult>;\n\nexport class EventBus {\n private handlers = new Map<string, Set<EventHandler<any>>>();\n private hookHandlers = new Map<string, Set<HookHandler<any>>>();\n private provenance: ProvenanceContext;\n private repositoryId?: string;\n\n constructor(provenance: ProvenanceContext, repositoryId?: string) {\n this.provenance = provenance;\n this.repositoryId = repositoryId;\n }\n\n /** Update provenance context (e.g., when conversation changes) */\n updateProvenance(provenance: ProvenanceContext): void {\n this.provenance = provenance;\n }\n\n /** Subscribe to an event. Returns an unsubscribe function. */\n on<E extends DeepMemoryEventType>(event: E, handler: EventHandler<E>): Unsubscribe {\n if (!this.handlers.has(event)) {\n this.handlers.set(event, new Set());\n }\n this.handlers.get(event)!.add(handler);\n\n return () => {\n this.handlers.get(event)?.delete(handler);\n };\n }\n\n /** Register a pre-mutation hook that can cancel operations */\n onHook<E extends PreMutationEvent>(event: E, handler: HookHandler<E>): Unsubscribe {\n if (!this.hookHandlers.has(event)) {\n this.hookHandlers.set(event, new Set());\n }\n this.hookHandlers.get(event)!.add(handler);\n\n return () => {\n this.hookHandlers.get(event)?.delete(handler);\n };\n }\n\n /** Emit an event to all registered handlers */\n async emit<E extends DeepMemoryEventType>(\n event: E,\n payload: EventPayload<E>,\n ): Promise<void> {\n const handlers = this.handlers.get(event);\n if (!handlers || handlers.size === 0) return;\n\n const eventObj: DeepMemoryEvent<E> = {\n type: event,\n timestamp: new Date().toISOString(),\n repositoryId: this.repositoryId,\n provenance: { ...this.provenance },\n payload,\n };\n\n for (const handler of handlers) {\n await handler(eventObj);\n }\n }\n\n /**\n * Emit a pre-mutation hook event.\n * Returns `{ cancelled: false }` if all hooks pass,\n * or `{ cancelled: true, reason }` if any hook cancels.\n */\n async emitHook<E extends PreMutationEvent>(\n event: E,\n payload: EventPayload<E>,\n ): Promise<{ cancelled: boolean; reason?: string }> {\n const hooks = this.hookHandlers.get(event);\n if (!hooks || hooks.size === 0) return { cancelled: false };\n\n const eventObj: DeepMemoryEvent<E> = {\n type: event,\n timestamp: new Date().toISOString(),\n repositoryId: this.repositoryId,\n provenance: { ...this.provenance },\n payload,\n };\n\n for (const hook of hooks) {\n const result = await hook(eventObj);\n if (result.cancel) {\n return { cancelled: true, reason: result.reason };\n }\n }\n\n return { cancelled: false };\n }\n\n /** Remove all listeners and hooks */\n removeAllListeners(): void {\n this.handlers.clear();\n this.hookHandlers.clear();\n }\n}\n","// RepositoryExporter — exports a repository to a portable archive\n\nimport type { StorageProvider } from '../providers/StorageProvider.js';\nimport type { ProvenanceContext } from '../types/provenance.js';\nimport type { ExportArchive, ExportLegalMetadata, ExportManifest, ExportStreamItem } from '../types/portability.js';\nimport { RepositoryNotFoundError } from '../core/errors.js';\nimport type { StoredEntity } from '../types/entities.js';\nimport type { StoredRelationship } from '../types/relationships.js';\n\ndeclare const __DEEP_MEMORY_VERSION__: string | undefined;\n\n/** Injected by tsup at build time; falls back to package.json version in dev/test */\nconst LIBRARY_VERSION: string =\n typeof __DEEP_MEMORY_VERSION__ !== 'undefined'\n ? __DEEP_MEMORY_VERSION__\n : '0.1.0';\n\nexport interface ExporterConfig {\n storage: StorageProvider;\n provenance: ProvenanceContext;\n /** Legal/copyright metadata to embed in the export manifest */\n legal?: ExportLegalMetadata;\n}\n\nexport class RepositoryExporter {\n private readonly storage: StorageProvider;\n private readonly provenance: ProvenanceContext;\n private readonly legal?: ExportLegalMetadata;\n\n constructor(config: ExporterConfig) {\n this.storage = config.storage;\n this.provenance = config.provenance;\n this.legal = config.legal;\n }\n\n /**\n * Stream a repository export as an async generator.\n * Yields: manifest → vocabulary → entity chunks → relationship chunks.\n * The caller can pipe this to a file, zip stream, or HTTP response.\n */\n async *exportStream(repositoryId: string): AsyncGenerator<ExportStreamItem> {\n const repo = await this.storage.getRepository(repositoryId);\n if (!repo) {\n throw new RepositoryNotFoundError(repositoryId);\n }\n\n const vocabulary = await this.storage.getVocabulary(repositoryId);\n const stats = await this.storage.getRepositoryStats(repositoryId);\n\n // Build and yield manifest\n const manifest: ExportManifest = {\n formatVersion: '1.0.0',\n libraryVersion: LIBRARY_VERSION,\n exportedAt: new Date().toISOString(),\n exportedBy: this.provenance,\n repository: {\n repositoryId,\n type: repo.type,\n label: repo.label,\n description: repo.description,\n vocabularyVersion: vocabulary.version,\n governanceMode: repo.governanceConfig.mode,\n },\n statistics: {\n entityCount: stats.entityCount,\n relationshipCount: stats.relationshipCount,\n entityTypeBreakdown: stats.entityTypeBreakdown,\n relationshipTypeBreakdown: stats.relationshipTypeBreakdown,\n },\n };\n\n // Legal metadata — set by the publisher of the archive\n if (this.legal) {\n manifest.legal = this.legal;\n }\n\n // Embedding metadata from the repository record — no live provider needed\n if (repo.metadata?.embeddingModelId) {\n manifest.embedding = {\n modelId: repo.metadata.embeddingModelId,\n dimensions: (repo.metadata.embeddingDimensions as number) ?? 0,\n note: 'Embeddings are model-specific. Re-embed after import if using a different model.',\n };\n }\n\n yield { type: 'manifest', data: manifest };\n yield { type: 'vocabulary', data: vocabulary };\n\n // Stream entity and relationship chunks from the storage provider\n for await (const chunk of this.storage.exportAll(repositoryId)) {\n if (chunk.type === 'entities') {\n yield {\n type: 'entities',\n data: chunk.data as StoredEntity[],\n sequence: chunk.sequence,\n isLast: chunk.isLast,\n };\n } else {\n yield {\n type: 'relationships',\n data: chunk.data as StoredRelationship[],\n sequence: chunk.sequence,\n isLast: chunk.isLast,\n };\n }\n }\n }\n\n /**\n * Export a repository to a complete in-memory archive.\n * Convenience wrapper around exportStream() — use for small repositories.\n * For large repositories, use exportStream() directly.\n */\n async export(repositoryId: string): Promise<ExportArchive> {\n let manifest: ExportManifest | undefined;\n let vocabulary: import('../types/vocabulary.js').MemoryVocabulary | undefined;\n const entities: StoredEntity[] = [];\n const relationships: StoredRelationship[] = [];\n\n for await (const item of this.exportStream(repositoryId)) {\n switch (item.type) {\n case 'manifest':\n manifest = item.data;\n break;\n case 'vocabulary':\n vocabulary = item.data;\n break;\n case 'entities':\n entities.push(...item.data);\n break;\n case 'relationships':\n relationships.push(...item.data);\n break;\n }\n }\n\n return {\n manifest: manifest!,\n vocabulary: vocabulary!,\n entities,\n relationships,\n };\n }\n}\n","// VocabularyDiff — computes diffs between two vocabulary versions\n\nimport type {\n EntityTypeDefinition,\n MemoryVocabulary,\n PropertySchema,\n RelationshipTypeDefinition,\n} from '../types/vocabulary.js';\n\n/** A single change in a vocabulary diff */\nexport interface VocabularyChange {\n changeType: 'added' | 'removed' | 'modified';\n category: 'entity_type' | 'relationship_type';\n typeName: string;\n details?: string;\n}\n\n/** Complete diff between two vocabulary versions */\nexport interface VocabularyDiffResult {\n fromVersion: string;\n toVersion: string;\n changes: VocabularyChange[];\n hasChanges: boolean;\n}\n\n/** Compute the diff between two vocabulary versions */\nexport function diffVocabularies(\n from: MemoryVocabulary,\n to: MemoryVocabulary,\n): VocabularyDiffResult {\n const changes: VocabularyChange[] = [];\n\n // Entity type diffs\n diffTypes(\n from.entityTypes,\n to.entityTypes,\n 'entity_type',\n diffEntityType,\n changes,\n );\n\n // Relationship type diffs\n diffTypes(\n from.relationshipTypes,\n to.relationshipTypes,\n 'relationship_type',\n diffRelationshipType,\n changes,\n );\n\n return {\n fromVersion: from.version,\n toVersion: to.version,\n changes,\n hasChanges: changes.length > 0,\n };\n}\n\nfunction diffTypes<T extends { type: string }>(\n fromTypes: T[],\n toTypes: T[],\n category: 'entity_type' | 'relationship_type',\n detailDiff: (from: T, to: T) => string | null,\n changes: VocabularyChange[],\n): void {\n const fromMap = new Map(fromTypes.map((t) => [t.type, t]));\n const toMap = new Map(toTypes.map((t) => [t.type, t]));\n\n // Added types\n for (const [typeName] of toMap) {\n if (!fromMap.has(typeName)) {\n changes.push({ changeType: 'added', category, typeName });\n }\n }\n\n // Removed types\n for (const [typeName] of fromMap) {\n if (!toMap.has(typeName)) {\n changes.push({ changeType: 'removed', category, typeName });\n }\n }\n\n // Modified types\n for (const [typeName, fromType] of fromMap) {\n const toType = toMap.get(typeName);\n if (!toType) continue;\n\n const details = detailDiff(fromType, toType);\n if (details) {\n changes.push({ changeType: 'modified', category, typeName, details });\n }\n }\n}\n\nfunction diffEntityType(\n from: EntityTypeDefinition,\n to: EntityTypeDefinition,\n): string | null {\n const diffs: string[] = [];\n\n if (from.description !== to.description) {\n diffs.push('description changed');\n }\n\n const propDiff = diffPropertySchemas(from.properties, to.properties);\n if (propDiff) {\n diffs.push(propDiff);\n }\n\n return diffs.length > 0 ? diffs.join('; ') : null;\n}\n\nfunction diffRelationshipType(\n from: RelationshipTypeDefinition,\n to: RelationshipTypeDefinition,\n): string | null {\n const diffs: string[] = [];\n\n if (from.description !== to.description) {\n diffs.push('description changed');\n }\n\n if (from.bidirectional !== to.bidirectional) {\n diffs.push(`bidirectional: ${from.bidirectional} → ${to.bidirectional}`);\n }\n\n const srcDiff = diffArrays(from.allowedSourceTypes, to.allowedSourceTypes);\n if (srcDiff) diffs.push(`allowedSourceTypes: ${srcDiff}`);\n\n const tgtDiff = diffArrays(from.allowedTargetTypes, to.allowedTargetTypes);\n if (tgtDiff) diffs.push(`allowedTargetTypes: ${tgtDiff}`);\n\n const propDiff = diffPropertySchemas(from.properties ?? [], to.properties ?? []);\n if (propDiff) diffs.push(propDiff);\n\n return diffs.length > 0 ? diffs.join('; ') : null;\n}\n\nfunction diffPropertySchemas(from: PropertySchema[], to: PropertySchema[]): string | null {\n const fromMap = new Map(from.map((p) => [p.name, p]));\n const toMap = new Map(to.map((p) => [p.name, p]));\n const parts: string[] = [];\n\n for (const [name] of toMap) {\n if (!fromMap.has(name)) parts.push(`property \"${name}\" added`);\n }\n\n for (const [name] of fromMap) {\n if (!toMap.has(name)) parts.push(`property \"${name}\" removed`);\n }\n\n for (const [name, fromProp] of fromMap) {\n const toProp = toMap.get(name);\n if (!toProp) continue;\n\n if (fromProp.type !== toProp.type) {\n parts.push(`property \"${name}\" type: ${fromProp.type} → ${toProp.type}`);\n }\n if (fromProp.required !== toProp.required) {\n parts.push(`property \"${name}\" required: ${fromProp.required} → ${toProp.required}`);\n }\n }\n\n return parts.length > 0 ? parts.join(', ') : null;\n}\n\nfunction diffArrays(from: string[], to: string[]): string | null {\n const fromSet = new Set(from);\n const toSet = new Set(to);\n const added = to.filter((t) => !fromSet.has(t));\n const removed = from.filter((f) => !toSet.has(f));\n\n const parts: string[] = [];\n if (added.length > 0) parts.push(`+[${added.join(', ')}]`);\n if (removed.length > 0) parts.push(`-[${removed.join(', ')}]`);\n\n return parts.length > 0 ? parts.join(' ') : null;\n}\n","// MigrationEngine — handles vocabulary differences between source and target repositories\n\nimport type { MemoryVocabulary } from '../types/vocabulary.js';\nimport type { ImportWarning } from '../types/portability.js';\nimport {\n diffVocabularies,\n type VocabularyChange,\n} from '../vocabulary/VocabularyDiff.js';\nimport {\n createEntityTypeDefinition,\n createRelationshipTypeDefinition,\n incrementVersion,\n} from '../vocabulary/VocabularySchema.js';\n\n/** How to handle vocabulary conflicts */\nexport type VocabularyConflictMode = 'reject' | 'extend' | 'prompt';\n\nexport interface MigrationResult {\n /** Whether migration succeeded */\n success: boolean;\n /** The merged vocabulary (only if success) */\n mergedVocabulary?: MemoryVocabulary;\n /** Warnings generated during migration */\n warnings: ImportWarning[];\n /** Rejection reason (only if success === false) */\n reason?: string;\n}\n\nexport class MigrationEngine {\n /**\n * Analyze and migrate vocabulary differences between source and target.\n *\n * @param sourceVocabulary - vocabulary from the export archive\n * @param targetVocabulary - vocabulary in the target repository\n * @param conflictMode - how to handle differences\n * @param migratedBy - actor performing the migration\n */\n migrate(\n sourceVocabulary: MemoryVocabulary,\n targetVocabulary: MemoryVocabulary,\n conflictMode: VocabularyConflictMode,\n migratedBy: string,\n ): MigrationResult {\n const diff = diffVocabularies(targetVocabulary, sourceVocabulary);\n\n // No changes needed\n if (!diff.hasChanges) {\n return { success: true, mergedVocabulary: targetVocabulary, warnings: [] };\n }\n\n const warnings: ImportWarning[] = [];\n\n switch (conflictMode) {\n case 'reject':\n return {\n success: false,\n warnings: [],\n reason: `Vocabulary mismatch: ${diff.changes.length} difference(s) found. ` +\n `Changes: ${diff.changes.map(describeChange).join('; ')}`,\n };\n\n case 'prompt':\n return {\n success: false,\n warnings: diff.changes.map((c) => ({\n code: 'vocabulary_mismatch',\n message: describeChange(c),\n })),\n reason: 'Vocabulary differences require manual resolution',\n };\n\n case 'extend': {\n // Merge: add new types from source, warn about conflicts\n const merged = this.extendVocabulary(\n sourceVocabulary,\n targetVocabulary,\n diff.changes,\n migratedBy,\n warnings,\n );\n return { success: true, mergedVocabulary: merged, warnings };\n }\n }\n }\n\n /** Extend the target vocabulary with types from the source */\n private extendVocabulary(\n source: MemoryVocabulary,\n target: MemoryVocabulary,\n changes: VocabularyChange[],\n migratedBy: string,\n warnings: ImportWarning[],\n ): MemoryVocabulary {\n // Start with a copy of the target\n const merged: MemoryVocabulary = {\n ...target,\n entityTypes: [...target.entityTypes],\n relationshipTypes: [...target.relationshipTypes],\n };\n\n for (const change of changes) {\n if (change.changeType === 'added') {\n // Type exists in source but not target — add it\n if (change.category === 'entity_type') {\n const sourceType = source.entityTypes.find((t) => t.type === change.typeName);\n if (sourceType) {\n merged.entityTypes.push(\n createEntityTypeDefinition(\n { type: sourceType.type, description: sourceType.description, properties: sourceType.properties },\n migratedBy,\n ),\n );\n warnings.push({\n code: 'entity_type_added',\n message: `Entity type \"${change.typeName}\" added from source vocabulary`,\n });\n }\n } else {\n const sourceType = source.relationshipTypes.find((t) => t.type === change.typeName);\n if (sourceType) {\n merged.relationshipTypes.push(\n createRelationshipTypeDefinition(\n {\n type: sourceType.type,\n description: sourceType.description,\n allowedSourceTypes: sourceType.allowedSourceTypes,\n allowedTargetTypes: sourceType.allowedTargetTypes,\n bidirectional: sourceType.bidirectional,\n properties: sourceType.properties,\n },\n migratedBy,\n ),\n );\n warnings.push({\n code: 'relationship_type_added',\n message: `Relationship type \"${change.typeName}\" added from source vocabulary`,\n });\n }\n }\n } else if (change.changeType === 'modified') {\n // Type exists in both but differs — keep target version, warn\n warnings.push({\n code: 'vocabulary_conflict',\n message: `Type \"${change.typeName}\" differs between source and target: ${change.details ?? 'unknown'}. Target version kept.`,\n });\n } else if (change.changeType === 'removed') {\n // Type exists in target but not source — keep it, no action needed\n warnings.push({\n code: 'vocabulary_extra',\n message: `Type \"${change.typeName}\" exists in target but not in source — kept as-is`,\n });\n }\n }\n\n // Use the higher of the source version or the incremented target version,\n // so importing into an empty repo preserves the source version.\n const bumped = incrementVersion(merged.version, 'minor');\n merged.version = compareVersions(source.version, bumped) > 0 ? source.version : bumped;\n merged.lastModified = new Date().toISOString();\n merged.modifiedBy = migratedBy;\n\n return merged;\n }\n}\n\n/** Compare two semver strings. Returns >0 if a > b, <0 if a < b, 0 if equal. */\nfunction compareVersions(a: string, b: string): number {\n const pa = a.split('.').map(Number);\n const pb = b.split('.').map(Number);\n for (let i = 0; i < 3; i++) {\n const diff = (pa[i] ?? 0) - (pb[i] ?? 0);\n if (diff !== 0) return diff;\n }\n return 0;\n}\n\nfunction describeChange(change: VocabularyChange): string {\n const label = change.category === 'entity_type' ? 'entity type' : 'relationship type';\n switch (change.changeType) {\n case 'added':\n return `${label} \"${change.typeName}\" exists in source but not target`;\n case 'removed':\n return `${label} \"${change.typeName}\" exists in target but not source`;\n case 'modified':\n return `${label} \"${change.typeName}\" differs: ${change.details ?? 'unknown'}`;\n }\n}\n","// RepositoryImporter — imports an export archive into a repository\n\nimport type { StorageProvider } from '../providers/StorageProvider.js';\nimport type {\n ExportArchive,\n ImportOptions,\n ImportResult,\n ImportWarning,\n ImportChunk,\n ImportStreamHeader,\n} from '../types/portability.js';\nimport type { RepositoryConfig } from '../types/repositories.js';\nimport { MigrationEngine } from './MigrationEngine.js';\nimport { generateId } from '../core/DeepMemory.js';\nimport { DuplicateRelationshipError } from '../core/errors.js';\n\n/** Progress info emitted after each chunk is processed */\nexport interface ImportProgress {\n repositoryId: string;\n entitiesImported: number;\n relationshipsImported: number;\n totalEntities: number;\n totalRelationships: number;\n chunksCompleted: number;\n totalChunks: number;\n}\n\nexport interface ImporterConfig {\n storage: StorageProvider;\n actorId: string;\n /** Called after each chunk is processed — wire to EventBus or progress UI */\n onProgress?: (progress: ImportProgress) => void | Promise<void>;\n}\n\n/** Estimate total chunks from entity + relationship counts */\nfunction estimateChunkCount(totalEntities: number, totalRelationships: number): number {\n const ESTIMATED_CHUNK_SIZE = 100;\n return Math.max(\n 1,\n Math.ceil(totalEntities / ESTIMATED_CHUNK_SIZE) + Math.ceil(totalRelationships / ESTIMATED_CHUNK_SIZE),\n );\n}\n\nexport class RepositoryImporter {\n private readonly storage: StorageProvider;\n private readonly actorId: string;\n private readonly onProgress?: (progress: ImportProgress) => void | Promise<void>;\n private readonly migrationEngine = new MigrationEngine();\n\n constructor(config: ImporterConfig) {\n this.storage = config.storage;\n this.actorId = config.actorId;\n this.onProgress = config.onProgress;\n }\n\n /**\n * Import an export archive according to the provided options.\n * Convenience wrapper around importStream() — use for small repositories.\n * For large repositories, use importStream() directly.\n */\n async import(archive: ExportArchive, options: ImportOptions): Promise<ImportResult> {\n const validationWarnings = this.validateArchive(archive);\n if (validationWarnings.length > 0) {\n // If basic validation fails, return early\n const hasCritical = validationWarnings.some((w) => w.code === 'invalid_archive');\n if (hasCritical) {\n return {\n success: false,\n repositoryId: options.target.repositoryId,\n statistics: { entitiesImported: 0, entitiesSkipped: 0, relationshipsImported: 0, relationshipsSkipped: 0, vocabularyExtensions: 0 },\n warnings: validationWarnings,\n };\n }\n }\n\n const header: ImportStreamHeader = {\n manifest: archive.manifest,\n vocabulary: archive.vocabulary,\n };\n\n // Convert the archive arrays into a single chunk\n async function* toChunks(): AsyncGenerator<ImportChunk> {\n yield { entities: archive.entities };\n yield { relationships: archive.relationships };\n }\n\n return this.importStream(header, toChunks(), options);\n }\n\n /**\n * Streaming import — processes data from an async iterable of chunks.\n * For large repositories, this avoids loading everything into memory at once.\n *\n * The caller provides the header (manifest + vocabulary) up front,\n * then streams ImportChunks containing batches of entities and/or relationships.\n */\n async importStream(\n header: ImportStreamHeader,\n chunks: AsyncIterable<ImportChunk>,\n options: ImportOptions,\n ): Promise<ImportResult> {\n const warnings: ImportWarning[] = [];\n\n if (!header.manifest) {\n warnings.push({ code: 'invalid_archive', message: 'Header is missing manifest' });\n }\n if (!header.vocabulary) {\n warnings.push({ code: 'invalid_archive', message: 'Header is missing vocabulary' });\n }\n\n if (options.target.mode === 'create') {\n return this.importStreamCreate(header, chunks, options, warnings);\n } else {\n return this.importStreamMerge(header, chunks, options, warnings);\n }\n }\n\n /** Streaming create mode — fast bulk inserts with no existence checks */\n private async importStreamCreate(\n header: ImportStreamHeader,\n chunks: AsyncIterable<ImportChunk>,\n options: ImportOptions,\n warnings: ImportWarning[],\n ): Promise<ImportResult> {\n const target = options.target as { mode: 'create'; repositoryId: string; config: RepositoryConfig };\n\n // Create the repository if it doesn't already exist\n const existing = await this.storage.getRepository(target.repositoryId);\n if (!existing) {\n const now = new Date().toISOString();\n await this.storage.createRepository({\n repositoryId: target.repositoryId,\n type: target.config.type,\n label: target.config.label,\n description: target.config.description,\n governanceConfig: target.config.governance ?? { mode: 'open' },\n createdAt: now,\n createdBy: this.actorId,\n });\n }\n\n // Save the vocabulary from the header\n await this.storage.saveVocabulary(target.repositoryId, header.vocabulary);\n\n // Process chunks incrementally — skip existence checks since the repo is freshly created\n const totalEntities = header.manifest?.statistics?.entityCount ?? 0;\n const totalRelationships = header.manifest?.statistics?.relationshipCount ?? 0;\n const totalChunks = estimateChunkCount(totalEntities, totalRelationships);\n let entitiesImported = 0;\n let relationshipsImported = 0;\n let chunksCompleted = 0;\n\n for await (const chunk of chunks) {\n const bulkResult = await this.storage.importBulk(target.repositoryId, [chunk], { skipExistenceCheck: true });\n entitiesImported += bulkResult.entitiesImported;\n relationshipsImported += bulkResult.relationshipsImported;\n chunksCompleted++;\n\n for (const e of bulkResult.errors) {\n warnings.push({\n code: 'import_error',\n message: `Failed to import ${e.item}: ${e.error}`,\n id: e.item,\n });\n }\n\n await this.onProgress?.({\n repositoryId: target.repositoryId,\n entitiesImported,\n relationshipsImported,\n totalEntities,\n totalRelationships,\n chunksCompleted,\n totalChunks,\n });\n }\n\n return {\n success: true,\n repositoryId: target.repositoryId,\n statistics: {\n entitiesImported,\n entitiesSkipped: 0,\n relationshipsImported,\n relationshipsSkipped: 0,\n vocabularyExtensions: 0,\n },\n warnings,\n };\n }\n\n /** Streaming merge mode — process chunks with per-entity conflict resolution */\n private async importStreamMerge(\n header: ImportStreamHeader,\n chunks: AsyncIterable<ImportChunk>,\n options: ImportOptions,\n warnings: ImportWarning[],\n ): Promise<ImportResult> {\n const target = options.target as { mode: 'merge'; repositoryId: string };\n const repositoryId = target.repositoryId;\n\n // Verify target exists\n const existingRepo = await this.storage.getRepository(repositoryId);\n if (!existingRepo) {\n return {\n success: false,\n repositoryId,\n statistics: { entitiesImported: 0, entitiesSkipped: 0, relationshipsImported: 0, relationshipsSkipped: 0, vocabularyExtensions: 0 },\n warnings: [{ code: 'repository_not_found', message: `Repository \"${repositoryId}\" not found` }],\n };\n }\n\n // Handle vocabulary migration\n const targetVocabulary = await this.storage.getVocabulary(repositoryId);\n const conflictMode = options.vocabularyConflict ?? 'reject';\n const migrationResult = this.migrationEngine.migrate(\n header.vocabulary,\n targetVocabulary,\n conflictMode,\n this.actorId,\n );\n\n warnings.push(...migrationResult.warnings);\n\n if (!migrationResult.success) {\n return {\n success: false,\n repositoryId,\n statistics: { entitiesImported: 0, entitiesSkipped: 0, relationshipsImported: 0, relationshipsSkipped: 0, vocabularyExtensions: 0 },\n warnings: [...warnings, { code: 'vocabulary_migration_failed', message: migrationResult.reason ?? 'Vocabulary migration failed' }],\n };\n }\n\n if (migrationResult.mergedVocabulary && migrationResult.mergedVocabulary !== targetVocabulary) {\n await this.storage.saveVocabulary(repositoryId, migrationResult.mergedVocabulary);\n }\n\n // Process chunks incrementally with conflict resolution\n const totalEntities = header.manifest?.statistics?.entityCount ?? 0;\n const totalRelationships = header.manifest?.statistics?.relationshipCount ?? 0;\n const totalChunks = estimateChunkCount(totalEntities, totalRelationships);\n const entityConflict = options.entityConflict ?? 'skip';\n let entitiesImported = 0;\n let entitiesSkipped = 0;\n let relationshipsImported = 0;\n let relationshipsSkipped = 0;\n let chunksCompleted = 0;\n\n for await (const chunk of chunks) {\n // Process entities in this chunk\n if (chunk.entities) {\n for (const entity of chunk.entities) {\n // Check for conflict by GUID first, then fall back to slug match\n let existing = await this.storage.getEntity(repositoryId, entity.id);\n if (!existing && entity.slug) {\n existing = await this.storage.getEntityBySlug(repositoryId, entity.slug);\n }\n\n if (existing) {\n const existingId = existing.id;\n switch (entityConflict) {\n case 'skip':\n entitiesSkipped++;\n warnings.push({\n code: 'entity_skipped',\n message: `Entity \"${entity.slug}\" already exists — skipped`,\n id: existingId,\n });\n continue;\n\n case 'overwrite':\n await this.storage.updateEntity(repositoryId, existingId, {\n label: entity.label,\n slug: entity.slug,\n summary: entity.summary,\n properties: entity.properties,\n data: entity.data,\n dataFormat: entity.dataFormat,\n provenance: entity.provenance,\n embedding: entity.embedding,\n });\n entitiesImported++;\n warnings.push({\n code: 'entity_overwritten',\n message: `Entity \"${entity.slug}\" overwritten`,\n id: existingId,\n });\n continue;\n\n case 'rename': {\n // Create a new entity with a new GUID and modified slug to avoid collision\n const renamedEntity = { ...entity, id: generateId(), slug: `${entity.slug}-imported` };\n await this.storage.createEntity(repositoryId, renamedEntity);\n entitiesImported++;\n warnings.push({\n code: 'entity_renamed',\n message: `Entity \"${entity.slug}\" slug renamed to \"${renamedEntity.slug}\"`,\n id: entity.id,\n });\n continue;\n }\n }\n } else {\n await this.storage.createEntity(repositoryId, entity);\n entitiesImported++;\n }\n }\n }\n\n // Process relationships in this chunk\n if (chunk.relationships) {\n for (const rel of chunk.relationships) {\n const existing = await this.storage.getRelationship(repositoryId, rel.id);\n\n if (existing) {\n relationshipsSkipped++;\n warnings.push({\n code: 'relationship_skipped',\n message: `Relationship \"${rel.id}\" already exists — skipped`,\n relationshipId: rel.id,\n });\n } else {\n const sourceExists = await this.storage.getEntity(repositoryId, rel.sourceEntityId);\n const targetExists = await this.storage.getEntity(repositoryId, rel.targetEntityId);\n\n if (!sourceExists || !targetExists) {\n relationshipsSkipped++;\n warnings.push({\n code: 'relationship_orphaned',\n message: `Relationship \"${rel.id}\" skipped — source or target entity missing`,\n relationshipId: rel.id,\n });\n } else {\n try {\n await this.storage.createRelationship(repositoryId, rel);\n relationshipsImported++;\n } catch (err) {\n // Storage layers may enforce composite uniqueness (e.g. source+target+type)\n // that getRelationship() by ID cannot detect. Treat as skip+warning,\n // consistent with the duplicate-by-id branch above.\n if (err instanceof DuplicateRelationshipError) {\n relationshipsSkipped++;\n warnings.push({\n code: 'relationship_skipped',\n message: `Relationship \"${rel.id}\" already exists — skipped`,\n relationshipId: rel.id,\n });\n } else {\n throw err;\n }\n }\n }\n }\n }\n }\n\n chunksCompleted++;\n await this.onProgress?.({\n repositoryId,\n entitiesImported,\n relationshipsImported,\n totalEntities,\n totalRelationships,\n chunksCompleted,\n totalChunks,\n });\n }\n\n const vocabExtensions = migrationResult.warnings.filter(\n (w) => w.code === 'entity_type_added' || w.code === 'relationship_type_added',\n ).length;\n\n return {\n success: true,\n repositoryId,\n statistics: {\n entitiesImported,\n entitiesSkipped,\n relationshipsImported,\n relationshipsSkipped,\n vocabularyExtensions: vocabExtensions,\n },\n warnings,\n };\n }\n\n /** Basic archive validation */\n private validateArchive(archive: ExportArchive): ImportWarning[] {\n const warnings: ImportWarning[] = [];\n\n if (!archive.manifest) {\n warnings.push({ code: 'invalid_archive', message: 'Archive is missing manifest' });\n }\n if (!archive.vocabulary) {\n warnings.push({ code: 'invalid_archive', message: 'Archive is missing vocabulary' });\n }\n if (!archive.entities) {\n warnings.push({ code: 'invalid_archive', message: 'Archive is missing entities array' });\n }\n if (!archive.relationships) {\n warnings.push({ code: 'invalid_archive', message: 'Archive is missing relationships array' });\n }\n\n return warnings;\n }\n}\n","// DeepMemory — top-level API for managing memory repositories\n\nimport type { StorageProvider, EnsureSchemaResult } from '../providers/StorageProvider.js';\nimport type { SearchProvider } from '../providers/SearchProvider.js';\nimport type { EmbeddingProvider, EmbeddingProviderFactory } from '../providers/EmbeddingProvider.js';\nimport type { LockProvider } from '../providers/LockProvider.js';\nimport type { GraphTraversalProvider } from '../providers/GraphTraversalProvider.js';\nimport type { ProvenanceContext } from '../types/provenance.js';\nimport type {\n RepositoryConfig,\n RepositoryUpdate,\n RepositorySummary,\n RepositoryFilter,\n StoredRepository,\n} from '../types/repositories.js';\nimport type {\n DeepMemoryEventType,\n EventHandler,\n Unsubscribe,\n} from '../types/events.js';\nimport type { PaginatedResult } from '../types/results.js';\nimport type { ExportArchive, ExportOptions, ExportStreamItem, ImportOptions, ImportResult, ImportChunk, ImportStreamHeader } from '../types/portability.js';\nimport { MemoryRepository } from './MemoryRepository.js';\nimport { VocabularyEngine } from './VocabularyEngine.js';\nimport { ProvenanceTracker } from './ProvenanceTracker.js';\nimport { EventBus } from './EventBus.js';\nimport {\n buildVocabulary,\n createEmptyVocabulary,\n} from '../vocabulary/VocabularySchema.js';\nimport { RepositoryExporter } from '../portability/RepositoryExporter.js';\nimport { RepositoryImporter } from '../portability/RepositoryImporter.js';\nimport { InvalidInputError, RepositoryNotFoundError } from './errors.js';\n\nconst UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n\n/** Generate a v4 UUID without depending on node:crypto */\nexport function generateId(): string {\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n const r = (Math.random() * 16) | 0;\n return (c === 'x' ? r : (r & 0x3) | 0x8).toString(16);\n });\n}\n\n/** Validate that a string is a valid UUID */\nexport function isValidUuid(value: string): boolean {\n return UUID_RE.test(value);\n}\n\n/** Configuration for creating a DeepMemory instance */\nexport interface DeepMemoryConfig {\n /** Required: the storage provider for persistence */\n storage: StorageProvider;\n /** Optional: search provider for full-text search */\n search?: SearchProvider;\n /**\n * Optional: factory that produces an EmbeddingProvider configured for a specific\n * model + dimensionality. Called once per repository open/create using the repo's\n * stored embedding metadata, so different repositories can use different models\n * and embedding dimensions without any per-mutation lookups.\n */\n embeddingFactory?: EmbeddingProviderFactory;\n /** Default embedding model for new repositories that don't specify one in metadata */\n defaultEmbeddingModel?: string;\n /** Default embedding dimensions for new repositories that don't specify one in metadata */\n defaultEmbeddingDimensions?: number;\n /** Optional: lock provider for distributed locking */\n lock?: LockProvider;\n /** Optional: graph traversal provider for native multi-hop queries */\n graphTraversal?: GraphTraversalProvider;\n /** Required: provenance context identifying the actor */\n provenance: ProvenanceContext;\n}\n\nexport class DeepMemory {\n private readonly storage: StorageProvider;\n private readonly search?: SearchProvider;\n private readonly embeddingFactory?: EmbeddingProviderFactory;\n private readonly defaultEmbeddingModel?: string;\n private readonly defaultEmbeddingDimensions?: number;\n /** Reserved for future distributed locking support */\n readonly lock?: LockProvider;\n private readonly graphTraversalProvider?: GraphTraversalProvider;\n private readonly provenance: ProvenanceTracker;\n private readonly globalEventBus: EventBus;\n private initialized = false;\n\n constructor(config: DeepMemoryConfig) {\n this.storage = config.storage;\n this.search = config.search;\n this.embeddingFactory = config.embeddingFactory;\n this.defaultEmbeddingModel = config.defaultEmbeddingModel;\n this.defaultEmbeddingDimensions = config.defaultEmbeddingDimensions;\n this.lock = config.lock;\n this.graphTraversalProvider = config.graphTraversal;\n this.provenance = new ProvenanceTracker(config.provenance);\n this.globalEventBus = new EventBus(config.provenance);\n }\n\n /**\n * Build an embedding provider for a repository given its stored model + dimensions.\n * Returns undefined when no factory is configured or when model/dimensions are missing.\n */\n private buildEmbeddingForRepository(\n model: string | undefined,\n dimensions: number | undefined,\n ): EmbeddingProvider | undefined {\n if (!this.embeddingFactory || !model || dimensions === undefined) return undefined;\n return this.embeddingFactory({ model, dimensions });\n }\n\n /** Initialize the storage provider and optional providers (call once before use) */\n private async ensureInitialized(): Promise<void> {\n if (!this.initialized) {\n if (this.storage.initialize) {\n await this.storage.initialize();\n }\n if (this.graphTraversalProvider?.initialize) {\n await this.graphTraversalProvider.initialize();\n }\n this.initialized = true;\n }\n }\n\n /** Create or migrate the storage schema. Call once at deployment / startup, not per-request. */\n async ensureSchema(): Promise<EnsureSchemaResult> {\n const noOpResult: EnsureSchemaResult = {\n databaseCreated: false,\n schemaCreated: false,\n alreadyUpToDate: true,\n schemaVersion: 0,\n };\n\n // Try to initialize normally first. If the storage provider's ensureSchema\n // can create the database itself, we allow init to fail and retry after.\n try {\n await this.ensureInitialized();\n } catch {\n // initialize may fail if the database doesn't exist yet — ensureSchema\n // on the storage provider can create it, so we continue.\n }\n\n let result: EnsureSchemaResult = noOpResult;\n if (this.storage.ensureSchema) {\n result = await this.storage.ensureSchema();\n }\n\n // If initialize failed earlier (e.g. DB didn't exist), retry now that\n // ensureSchema may have created it.\n if (!this.initialized) {\n await this.ensureInitialized();\n }\n\n return result;\n }\n\n private validateRepositoryId(repositoryId: string): void {\n if (!isValidUuid(repositoryId)) {\n throw new InvalidInputError(\n 'repositoryId',\n `Repository ID \"${repositoryId}\" is not a valid UUID`,\n `Provide a valid UUID (e.g. \"550e8400-e29b-41d4-a716-446655440000\") or omit repositoryId to auto-generate one.`,\n );\n }\n }\n\n /** Create a new memory repository */\n async createRepository(config: RepositoryConfig): Promise<MemoryRepository> {\n await this.ensureInitialized();\n\n const repositoryId = config.repositoryId ?? generateId();\n this.validateRepositoryId(repositoryId);\n const context = this.provenance.getContext();\n const now = new Date().toISOString();\n\n const governanceConfig = config.governance ?? { mode: 'open' as const };\n\n // Build metadata: explicit config values take precedence, then fall back to server defaults.\n // Embedding model + dimensions live on the repository itself so each repo can use a\n // different configuration without per-mutation lookups.\n const metadata = { ...config.metadata };\n if (!metadata.embeddingModelId && this.defaultEmbeddingModel) {\n metadata.embeddingModelId = this.defaultEmbeddingModel;\n }\n if (metadata.embeddingDimensions === undefined && this.defaultEmbeddingDimensions !== undefined) {\n metadata.embeddingDimensions = this.defaultEmbeddingDimensions;\n }\n\n // Create the repository in storage\n await this.storage.createRepository({\n repositoryId,\n type: config.type,\n label: config.label,\n description: config.description,\n legal: config.legal,\n owner: config.owner,\n governanceConfig,\n metadata: Object.keys(metadata).length > 0 ? metadata : undefined,\n createdAt: now,\n createdBy: context.actorId,\n });\n\n // Build and save initial vocabulary\n const vocabulary = config.vocabulary\n ? buildVocabulary(config.vocabulary, context.actorId)\n : createEmptyVocabulary(context.actorId);\n\n await this.storage.saveVocabulary(repositoryId, vocabulary);\n\n // Build per-repository embedding provider from the repo's stored model + dimensions\n const embedding = this.buildEmbeddingForRepository(\n metadata.embeddingModelId,\n metadata.embeddingDimensions,\n );\n\n // Create internal components\n const eventBus = new EventBus(context, repositoryId);\n const vocabularyEngine = new VocabularyEngine({\n repositoryId,\n storageProvider: this.storage,\n governanceConfig,\n embeddingProvider: embedding,\n });\n\n const repo = new MemoryRepository({\n repositoryId,\n storage: this.storage,\n search: this.search,\n embedding,\n embeddingFactory: this.embeddingFactory,\n graphTraversal: this.graphTraversalProvider,\n vocabularyEngine,\n provenanceTracker: this.provenance,\n eventBus,\n });\n\n // Emit repository created event\n await this.globalEventBus.emit('repository:created', {\n repositoryId,\n label: config.label,\n });\n\n return repo;\n }\n\n /** Open an existing repository */\n async openRepository(repositoryId: string): Promise<MemoryRepository> {\n await this.ensureInitialized();\n this.validateRepositoryId(repositoryId);\n\n const storedRepo = await this.storage.getRepository(repositoryId);\n if (!storedRepo) {\n throw new RepositoryNotFoundError(repositoryId);\n }\n\n const context = this.provenance.getContext();\n const eventBus = new EventBus(context, repositoryId);\n\n // Build the per-repository embedding provider from stored metadata.\n // Falls back to server defaults only if the repo has no embedding metadata\n // recorded yet (e.g. created before this field existed).\n const embedding = this.buildEmbeddingForRepository(\n storedRepo.metadata?.embeddingModelId ?? this.defaultEmbeddingModel,\n storedRepo.metadata?.embeddingDimensions ?? this.defaultEmbeddingDimensions,\n );\n\n const vocabularyEngine = new VocabularyEngine({\n repositoryId,\n storageProvider: this.storage,\n governanceConfig: storedRepo.governanceConfig,\n embeddingProvider: embedding,\n });\n\n const repo = new MemoryRepository({\n repositoryId,\n storage: this.storage,\n search: this.search,\n embedding,\n embeddingFactory: this.embeddingFactory,\n graphTraversal: this.graphTraversalProvider,\n vocabularyEngine,\n provenanceTracker: this.provenance,\n eventBus,\n });\n\n await this.globalEventBus.emit('repository:opened', { repositoryId });\n\n return repo;\n }\n\n /** Get the full stored record for a single repository (including legal, owner, metadata, governance) */\n async getRepository(repositoryId: string): Promise<StoredRepository> {\n await this.ensureInitialized();\n this.validateRepositoryId(repositoryId);\n\n const storedRepo = await this.storage.getRepository(repositoryId);\n if (!storedRepo) {\n throw new RepositoryNotFoundError(repositoryId);\n }\n return storedRepo;\n }\n\n /** List all repositories */\n async listRepositories(\n filter?: RepositoryFilter,\n ): Promise<PaginatedResult<RepositorySummary>> {\n await this.ensureInitialized();\n\n const result = await this.storage.listRepositories(filter);\n\n return {\n items: result.items.map((stored) => ({\n repositoryId: stored.repositoryId,\n type: stored.type,\n label: stored.label,\n description: stored.description,\n governanceMode: stored.governanceConfig.mode,\n })),\n total: result.total,\n hasMore: result.hasMore,\n limit: result.limit,\n offset: result.offset,\n };\n }\n\n /** Update repository metadata and settings */\n async updateRepository(repositoryId: string, updates: RepositoryUpdate): Promise<StoredRepository> {\n await this.ensureInitialized();\n this.validateRepositoryId(repositoryId);\n const updated = await this.storage.updateRepository(repositoryId, updates);\n await this.globalEventBus.emit('repository:updated', { repositoryId });\n return updated;\n }\n\n /** Delete a repository */\n async deleteRepository(repositoryId: string): Promise<void> {\n await this.ensureInitialized();\n this.validateRepositoryId(repositoryId);\n\n const stats = await this.storage.getRepositoryStats(repositoryId);\n await this.globalEventBus.emit('delete:started', {\n repositoryId,\n totalEntities: stats.entityCount,\n totalRelationships: stats.relationshipCount,\n });\n\n await this.storage.deleteRepository(repositoryId, (progress) =>\n this.globalEventBus.emit('delete:progress', { repositoryId, ...progress }),\n );\n\n await this.globalEventBus.emit('delete:completed', {\n repositoryId,\n entitiesDeleted: stats.entityCount,\n relationshipsDeleted: stats.relationshipCount,\n });\n await this.globalEventBus.emit('repository:deleted', { repositoryId });\n }\n\n /** Delete all entities and relationships in a repository, preserving the repository and vocabulary */\n async deleteAllContents(repositoryId: string): Promise<{ deletedEntities: number; deletedRelationships: number }> {\n await this.ensureInitialized();\n this.validateRepositoryId(repositoryId);\n\n const stats = await this.storage.getRepositoryStats(repositoryId);\n await this.globalEventBus.emit('delete:started', {\n repositoryId,\n totalEntities: stats.entityCount,\n totalRelationships: stats.relationshipCount,\n });\n\n const result = await this.storage.deleteAllContents(repositoryId, (progress) =>\n this.globalEventBus.emit('delete:progress', { repositoryId, ...progress }),\n );\n\n await this.globalEventBus.emit('delete:completed', {\n repositoryId,\n entitiesDeleted: result.deletedEntities,\n relationshipsDeleted: result.deletedRelationships,\n });\n\n return result;\n }\n\n /** Export a repository to a portable archive */\n async exportRepository(repositoryId: string, options?: ExportOptions): Promise<ExportArchive> {\n await this.ensureInitialized();\n\n const stats = await this.storage.getRepositoryStats(repositoryId);\n await this.globalEventBus.emit('export:started', {\n repositoryId,\n totalEntities: stats.entityCount,\n totalRelationships: stats.relationshipCount,\n });\n\n const exporter = new RepositoryExporter({\n storage: this.storage,\n provenance: this.provenance.getContext(),\n legal: options?.legal,\n });\n\n const archive = await exporter.export(repositoryId);\n\n await this.globalEventBus.emit('export:completed', {\n repositoryId,\n entityCount: archive.entities.length,\n relationshipCount: archive.relationships.length,\n });\n\n return archive;\n }\n\n /** Import a repository from a portable archive */\n async importRepository(\n archive: ExportArchive,\n options: ImportOptions,\n ): Promise<ImportResult> {\n await this.ensureInitialized();\n\n await this.globalEventBus.emit('import:started', { repositoryId: options.target.repositoryId });\n\n const importer = new RepositoryImporter({\n storage: this.storage,\n actorId: this.provenance.getContext().actorId,\n onProgress: (progress) => this.globalEventBus.emit('import:progress', progress),\n });\n\n const result = await importer.import(archive, options);\n\n if (result.success) {\n await this.globalEventBus.emit('import:completed', {\n repositoryId: result.repositoryId,\n entitiesImported: result.statistics.entitiesImported,\n relationshipsImported: result.statistics.relationshipsImported,\n });\n } else {\n await this.globalEventBus.emit('import:failed', {\n repositoryId: result.repositoryId,\n error: result.warnings.map((w) => w.message).join('; '),\n });\n }\n\n return result;\n }\n\n /**\n * Stream a repository export as an async generator.\n * Yields: manifest → vocabulary → entity chunks → relationship chunks.\n * Use for large repositories to avoid loading everything into memory.\n */\n async *exportRepositoryStream(repositoryId: string, options?: ExportOptions): AsyncGenerator<ExportStreamItem> {\n await this.ensureInitialized();\n\n const exporter = new RepositoryExporter({\n storage: this.storage,\n provenance: this.provenance.getContext(),\n legal: options?.legal,\n });\n\n // Get stats up front so progress events have totals\n const stats = await this.storage.getRepositoryStats(repositoryId);\n const totalEntities = stats.entityCount;\n const totalRelationships = stats.relationshipCount;\n const estimatedChunkSize = 100;\n const totalChunks = Math.max(\n 1,\n Math.ceil(totalEntities / estimatedChunkSize) + Math.ceil(totalRelationships / estimatedChunkSize),\n );\n\n await this.globalEventBus.emit('export:started', { repositoryId, totalEntities, totalRelationships });\n\n let entityCount = 0;\n let relationshipCount = 0;\n let chunksCompleted = 0;\n\n for await (const item of exporter.exportStream(repositoryId)) {\n yield item;\n\n if (item.type === 'entities') {\n entityCount += item.data.length;\n chunksCompleted++;\n await this.globalEventBus.emit('export:progress', {\n repositoryId,\n entitiesExported: entityCount,\n relationshipsExported: relationshipCount,\n totalEntities,\n totalRelationships,\n chunksCompleted,\n totalChunks,\n });\n } else if (item.type === 'relationships') {\n relationshipCount += item.data.length;\n chunksCompleted++;\n await this.globalEventBus.emit('export:progress', {\n repositoryId,\n entitiesExported: entityCount,\n relationshipsExported: relationshipCount,\n totalEntities,\n totalRelationships,\n chunksCompleted,\n totalChunks,\n });\n }\n }\n\n await this.globalEventBus.emit('export:completed', {\n repositoryId,\n entityCount,\n relationshipCount,\n });\n }\n\n /**\n * Import a repository from a stream of chunks.\n * Use for large repositories to avoid loading everything into memory.\n */\n async importRepositoryStream(\n header: ImportStreamHeader,\n chunks: AsyncIterable<ImportChunk>,\n options: ImportOptions,\n ): Promise<ImportResult> {\n await this.ensureInitialized();\n\n const importer = new RepositoryImporter({\n storage: this.storage,\n actorId: this.provenance.getContext().actorId,\n onProgress: (progress) => this.globalEventBus.emit('import:progress', progress),\n });\n\n await this.globalEventBus.emit('import:started', { repositoryId: options.target.repositoryId });\n\n const result = await importer.importStream(header, chunks, options);\n\n if (result.success) {\n await this.globalEventBus.emit('import:completed', {\n repositoryId: result.repositoryId,\n entitiesImported: result.statistics.entitiesImported,\n relationshipsImported: result.statistics.relationshipsImported,\n });\n } else {\n await this.globalEventBus.emit('import:failed', {\n repositoryId: result.repositoryId,\n error: result.warnings.map((w) => w.message).join('; '),\n });\n }\n\n return result;\n }\n\n /** Subscribe to global events */\n on<E extends DeepMemoryEventType>(event: E, handler: EventHandler<E>): Unsubscribe {\n return this.globalEventBus.on(event, handler);\n }\n\n /** Update the provenance context (e.g., new conversation) */\n updateProvenance(context: Partial<ProvenanceContext>): void {\n this.provenance.updateContext(context);\n this.globalEventBus.updateProvenance(this.provenance.getContext());\n }\n\n /** Dispose of all resources */\n async dispose(): Promise<void> {\n this.globalEventBus.removeAllListeners();\n if (this.graphTraversalProvider?.dispose) {\n await this.graphTraversalProvider.dispose();\n }\n if (this.storage.dispose) {\n await this.storage.dispose();\n }\n this.initialized = false;\n }\n}\n","// safeSink — wraps a UsageSink so provider code can invoke it without\n// worrying that a buggy caller implementation will break the storage call.\n\nimport type { UsageSink } from '../types/usage.js';\n\n/**\n * Wrap a sink with try/catch so a throwing caller sink never aborts the\n * underlying operation. Errors from the caller's sink are silently swallowed;\n * if the caller cares about internal failures they can catch in their own\n * implementation.\n *\n * Returns `undefined` if the input sink is `undefined`, letting providers\n * cheaply skip sink machinery when nobody is listening.\n */\nexport function createSafeSink(sink: UsageSink | undefined): UsageSink | undefined {\n if (!sink) return undefined;\n return (usage) => {\n try {\n sink(usage);\n } catch {\n // Deliberately swallowed — a failing caller sink must never abort the\n // provider operation it was observing.\n }\n };\n}\n","// GremlinCompiler — compiles TraversalSpec to Gremlin query strings\n// Zero runtime dependencies — pure string construction with parameterized bindings.\n\nimport type { TraversalSpec, TraversalStep } from '../../types/traversal.js';\nimport type { MemoryVocabulary } from '../../types/vocabulary.js';\nimport type { PropertyFilter } from '../../types/queries.js';\nimport type { TraversalCompiler, CompiledQuery } from './TraversalCompiler.js';\n\nconst DEFAULT_ESTIMATED_FANOUT_PER_HOP = 10;\n\nexport class GremlinCompiler implements TraversalCompiler {\n readonly language = 'gremlin' as const;\n\n compile(spec: TraversalSpec, _vocabulary: MemoryVocabulary): CompiledQuery {\n const parts: string[] = [];\n const params: Record<string, unknown> = {};\n let paramIndex = 0;\n let estimatedFanOut = 1;\n\n const nextParam = (value: unknown): string => {\n const name = `p${paramIndex++}`;\n params[name] = value;\n return name;\n };\n\n // ─── Start ──────────────────────────────────────────────────\n\n parts.push('g.V()');\n\n if (spec.start.entityId) {\n const p = nextParam(spec.start.entityId);\n parts.push(`.has('id', ${p})`);\n } else if (spec.start.entityType) {\n const p = nextParam(spec.start.entityType);\n parts.push(`.has('entityType', ${p})`);\n estimatedFanOut *= DEFAULT_ESTIMATED_FANOUT_PER_HOP;\n }\n\n if (spec.start.filter) {\n for (const f of spec.start.filter) {\n parts.push(compilePropertyFilter(f, nextParam));\n }\n }\n\n // ─── Steps ──────────────────────────────────────────────────\n\n const steps = spec.steps ?? [];\n for (const step of steps) {\n if (step.repeat) {\n parts.push(compileRepeatStep(step, nextParam));\n estimatedFanOut *= step.repeat.maxDepth * DEFAULT_ESTIMATED_FANOUT_PER_HOP;\n } else if (step.relationshipFilter && step.relationshipFilter.length > 0) {\n // Edge-explicit traversal for relationship property filters\n parts.push(compileEdgeStep(step, nextParam));\n estimatedFanOut *= DEFAULT_ESTIMATED_FANOUT_PER_HOP;\n } else {\n parts.push(compileSimpleStep(step, nextParam));\n estimatedFanOut *= DEFAULT_ESTIMATED_FANOUT_PER_HOP;\n }\n\n // Entity type filter on target vertices\n if (step.entityTypes && step.entityTypes.length > 0) {\n const typeParams = step.entityTypes.map((t) => nextParam(t));\n parts.push(`.has('entityType', within(${typeParams.join(', ')}))`);\n }\n\n // Entity property filters on target vertices\n if (step.entityFilter) {\n for (const f of step.entityFilter) {\n parts.push(compilePropertyFilter(f, nextParam));\n }\n }\n }\n\n // ─── Return mode modifiers ──────────────────────────────────\n\n if (spec.returnMode === 'all') {\n // emit() at each step is handled within repeat; for non-repeat this is implicit\n }\n\n if (spec.dedup !== false) {\n parts.push('.dedup()');\n }\n\n // ─── Pagination ─────────────────────────────────────────────\n\n const limit = spec.limit ?? 50;\n const offset = spec.offset ?? 0;\n const pOffset = nextParam(offset);\n const pEnd = nextParam(offset + limit);\n parts.push(`.range(${pOffset}, ${pEnd})`);\n\n params['_limit'] = limit;\n params['_offset'] = offset;\n\n // ─── Path mode ──────────────────────────────────────────────\n\n if (spec.returnMode === 'path') {\n parts.push('.path()');\n }\n\n // ─── Value projection ───────────────────────────────────────\n\n if (spec.returnMode !== 'path') {\n parts.push('.valueMap(true)');\n }\n\n return {\n query: parts.join(''),\n params,\n estimatedFanOut: Math.min(estimatedFanOut, 10000),\n };\n }\n}\n\n/** Compile a simple vertex-to-vertex step (no relationship property filters). */\nfunction compileSimpleStep(\n step: TraversalStep,\n nextParam: (value: unknown) => string,\n): string {\n const types = step.relationshipTypes;\n const typeArgs = types ? types.map((t) => nextParam(t)).join(', ') : '';\n\n switch (step.direction) {\n case 'out':\n return types ? `.out(${typeArgs})` : '.out()';\n case 'in':\n return types ? `.in(${typeArgs})` : '.in()';\n case 'both':\n return types ? `.both(${typeArgs})` : '.both()';\n }\n}\n\n/** Compile an edge-explicit step for relationship property filtering. */\nfunction compileEdgeStep(\n step: TraversalStep,\n nextParam: (value: unknown) => string,\n): string {\n const parts: string[] = [];\n const types = step.relationshipTypes;\n const typeArgs = types ? types.map((t) => nextParam(t)).join(', ') : '';\n\n // Edge traversal\n switch (step.direction) {\n case 'out':\n parts.push(types ? `.outE(${typeArgs})` : '.outE()');\n break;\n case 'in':\n parts.push(types ? `.inE(${typeArgs})` : '.inE()');\n break;\n case 'both':\n parts.push(types ? `.bothE(${typeArgs})` : '.bothE()');\n break;\n }\n\n // Relationship property filters on the edge\n if (step.relationshipFilter) {\n for (const f of step.relationshipFilter) {\n parts.push(compilePropertyFilter(f, nextParam));\n }\n }\n\n // Traverse to the target vertex\n switch (step.direction) {\n case 'out':\n parts.push('.inV()');\n break;\n case 'in':\n parts.push('.outV()');\n break;\n case 'both':\n parts.push('.otherV()');\n break;\n }\n\n return parts.join('');\n}\n\n/** Compile a repeat/loop step. */\nfunction compileRepeatStep(\n step: TraversalStep,\n nextParam: (value: unknown) => string,\n): string {\n const parts: string[] = [];\n const innerStep = step.relationshipFilter?.length\n ? compileEdgeStep({ ...step, repeat: undefined }, nextParam)\n : compileSimpleStep(step, nextParam);\n\n // emit() placement: before repeat for intermediates, after for terminal-only\n if (step.repeat?.emitIntermediates !== false) {\n parts.push('.emit()');\n }\n\n parts.push(`.repeat(${innerStep.startsWith('.') ? `__${innerStep}` : innerStep})`);\n\n // Until condition\n if (step.repeat?.until && step.repeat.until.length > 0) {\n const untilParts = step.repeat.until.map((f) => compilePropertyFilter(f, nextParam));\n parts.push(`.until(${untilParts.join('')})`);\n }\n\n // Max depth via times()\n if (step.repeat?.maxDepth) {\n const p = nextParam(step.repeat.maxDepth);\n parts.push(`.times(${p})`);\n }\n\n if (step.repeat?.emitIntermediates === false) {\n parts.push('.emit()');\n }\n\n return parts.join('');\n}\n\n/** Compile a single property filter to a Gremlin .has() predicate. */\nfunction compilePropertyFilter(\n filter: PropertyFilter,\n nextParam: (value: unknown) => string,\n): string {\n const key = nextParam(filter.key);\n\n switch (filter.operator) {\n case 'eq': {\n const val = nextParam(filter.value);\n return `.has(${key}, ${val})`;\n }\n case 'neq': {\n const val = nextParam(filter.value);\n return `.has(${key}, neq(${val}))`;\n }\n case 'gt': {\n const val = nextParam(filter.value);\n return `.has(${key}, gt(${val}))`;\n }\n case 'gte': {\n const val = nextParam(filter.value);\n return `.has(${key}, gte(${val}))`;\n }\n case 'lt': {\n const val = nextParam(filter.value);\n return `.has(${key}, lt(${val}))`;\n }\n case 'lte': {\n const val = nextParam(filter.value);\n return `.has(${key}, lte(${val}))`;\n }\n case 'contains': {\n const val = nextParam(filter.value);\n return `.has(${key}, containing(${val}))`;\n }\n case 'isNull':\n return `.hasNot(${key})`;\n case 'isNotNull':\n return `.has(${key})`;\n }\n}\n","// CypherCompiler — compiles TraversalSpec to Cypher query strings\n// Zero runtime dependencies — pure string construction with parameterized bindings.\n\nimport type { TraversalSpec } from '../../types/traversal.js';\nimport type { MemoryVocabulary } from '../../types/vocabulary.js';\nimport type { PropertyFilter } from '../../types/queries.js';\nimport type { TraversalCompiler, CompiledQuery } from './TraversalCompiler.js';\n\nconst DEFAULT_ESTIMATED_FANOUT_PER_HOP = 10;\n\nexport class CypherCompiler implements TraversalCompiler {\n readonly language = 'cypher' as const;\n\n compile(spec: TraversalSpec, _vocabulary: MemoryVocabulary): CompiledQuery {\n const params: Record<string, unknown> = {};\n let paramIndex = 0;\n let estimatedFanOut = 1;\n const whereClauses: string[] = [];\n let nodeIndex = 0;\n\n const nextParam = (value: unknown): string => {\n const name = `p${paramIndex++}`;\n params[name] = value;\n return `$${name}`;\n };\n\n // ─── Start ──────────────────────────────────────────────────\n\n const startNode = `n${nodeIndex++}`;\n let matchParts: string[] = [];\n\n if (spec.start.entityId) {\n matchParts.push(`(${startNode})`);\n whereClauses.push(`${startNode}.id = ${nextParam(spec.start.entityId)}`);\n } else if (spec.start.entityType) {\n matchParts.push(`(${startNode})`);\n whereClauses.push(`${startNode}.entityType = ${nextParam(spec.start.entityType)}`);\n estimatedFanOut *= DEFAULT_ESTIMATED_FANOUT_PER_HOP;\n } else {\n matchParts.push(`(${startNode})`);\n }\n\n if (spec.start.filter) {\n for (const f of spec.start.filter) {\n whereClauses.push(compilePropertyFilterCypher(startNode, f, nextParam));\n }\n }\n\n // ─── Steps ──────────────────────────────────────────────────\n\n let lastNode = startNode;\n const steps = spec.steps ?? [];\n\n for (let i = 0; i < steps.length; i++) {\n const step = steps[i]!;\n const targetNode = `n${nodeIndex++}`;\n const relAlias = `r${i}`;\n\n // Relationship type pattern\n const relTypes = step.relationshipTypes?.length\n ? step.relationshipTypes.join('|')\n : '';\n const relTypePattern = relTypes ? `:${relTypes}` : '';\n\n // Repeat — variable-length path\n const depthPattern = step.repeat\n ? `*1..${step.repeat.maxDepth}`\n : '';\n\n // Direction — only include the relationship and target node (left node is already in the chain)\n let pattern: string;\n switch (step.direction) {\n case 'out':\n pattern = `-[${relAlias}${relTypePattern}${depthPattern}]->(${targetNode})`;\n break;\n case 'in':\n pattern = `<-[${relAlias}${relTypePattern}${depthPattern}]-(${targetNode})`;\n break;\n case 'both':\n pattern = `-[${relAlias}${relTypePattern}${depthPattern}]-(${targetNode})`;\n break;\n }\n\n matchParts.push(pattern);\n estimatedFanOut *= step.repeat\n ? step.repeat.maxDepth * DEFAULT_ESTIMATED_FANOUT_PER_HOP\n : DEFAULT_ESTIMATED_FANOUT_PER_HOP;\n\n // Entity type filter\n if (step.entityTypes && step.entityTypes.length > 0) {\n const typeParam = nextParam(step.entityTypes);\n whereClauses.push(`${targetNode}.entityType IN ${typeParam}`);\n }\n\n // Entity property filters\n if (step.entityFilter) {\n for (const f of step.entityFilter) {\n whereClauses.push(compilePropertyFilterCypher(targetNode, f, nextParam));\n }\n }\n\n // Relationship property filters\n if (step.relationshipFilter) {\n for (const f of step.relationshipFilter) {\n whereClauses.push(compilePropertyFilterCypher(relAlias, f, nextParam));\n }\n }\n\n lastNode = targetNode;\n }\n\n // ─── Build query ────────────────────────────────────────────\n\n const matchClause = `MATCH ${matchParts[0]}${matchParts.slice(1).join('')}`;\n const whereClause = whereClauses.length > 0\n ? `\\nWHERE ${whereClauses.join(' AND ')}`\n : '';\n\n // Return clause\n let returnClause: string;\n if (spec.returnMode === 'path') {\n // Return full paths\n const allNodes = Array.from({ length: nodeIndex }, (_, i) => `n${i}`);\n const allRels = steps.map((_, i) => `r${i}`);\n returnClause = `RETURN ${[...allNodes, ...allRels].join(', ')}`;\n } else if (spec.returnMode === 'all') {\n // Return all nodes\n const allNodes = Array.from({ length: nodeIndex }, (_, i) => `n${i}`);\n returnClause = spec.dedup !== false\n ? `RETURN DISTINCT ${allNodes.join(', ')}`\n : `RETURN ${allNodes.join(', ')}`;\n } else {\n // Terminal — return only the last node\n returnClause = spec.dedup !== false\n ? `RETURN DISTINCT ${lastNode}`\n : `RETURN ${lastNode}`;\n }\n\n // Pagination\n const offset = spec.offset ?? 0;\n const limit = spec.limit ?? 50;\n const skipClause = offset > 0 ? `\\nSKIP ${nextParam(offset)}` : '';\n const limitClause = `\\nLIMIT ${nextParam(limit)}`;\n\n params['_limit'] = limit;\n params['_offset'] = offset;\n\n const query = `${matchClause}${whereClause}\\n${returnClause}${skipClause}${limitClause}`;\n\n return {\n query,\n params,\n estimatedFanOut: Math.min(estimatedFanOut, 10000),\n };\n }\n}\n\n/** Compile a single property filter to a Cypher WHERE clause fragment. */\nfunction compilePropertyFilterCypher(\n nodeAlias: string,\n filter: PropertyFilter,\n nextParam: (value: unknown) => string,\n): string {\n const prop = `${nodeAlias}.${filter.key}`;\n\n switch (filter.operator) {\n case 'eq':\n return `${prop} = ${nextParam(filter.value)}`;\n case 'neq':\n return `${prop} <> ${nextParam(filter.value)}`;\n case 'gt':\n return `${prop} > ${nextParam(filter.value)}`;\n case 'gte':\n return `${prop} >= ${nextParam(filter.value)}`;\n case 'lt':\n return `${prop} < ${nextParam(filter.value)}`;\n case 'lte':\n return `${prop} <= ${nextParam(filter.value)}`;\n case 'contains':\n return `${prop} CONTAINS ${nextParam(filter.value)}`;\n case 'isNull':\n return `${prop} IS NULL`;\n case 'isNotNull':\n return `${prop} IS NOT NULL`;\n }\n}\n","// InMemoryStorageProvider — reference implementation of StorageProvider using Maps\n\nimport type { StorageProvider } from '../providers/StorageProvider.js';\nimport type {\n StoredEntity,\n StoredEntityUpdate,\n} from '../types/entities.js';\nimport type {\n StoredRelationship,\n RelationshipQueryOptions,\n} from '../types/relationships.js';\nimport type { MemoryVocabulary, VocabularyChangeRecord } from '../types/vocabulary.js';\nimport type {\n StorageRepositoryConfig,\n StoredRepository,\n StoredRepositorySummary,\n RepositoryFilter,\n RepositoryStats,\n RepositoryUpdate,\n} from '../types/repositories.js';\nimport type {\n StorageFindQuery,\n StorageExploreOptions,\n StoragePathOptions,\n StorageTimelineOptions,\n PaginationOptions,\n ProvenanceFilter,\n} from '../types/queries.js';\nimport type { Provenance } from '../types/provenance.js';\nimport type {\n PaginatedResult,\n StorageNeighborhood,\n StoragePathResult,\n StorageTimelineResult,\n BulkImportResult,\n} from '../types/results.js';\nimport type { ExportChunk, ImportChunk } from '../types/portability.js';\nimport { matchesPropertyFilters } from '../relationships/PropertyFilterMatcher.js';\nimport { createEmptyVocabulary } from '../vocabulary/VocabularySchema.js';\nimport {\n RepositoryNotFoundError,\n DuplicateRepositoryError,\n EntityNotFoundError,\n DuplicateEntityError,\n RelationshipNotFoundError,\n DuplicateRelationshipError,\n} from '../core/errors.js';\n\n/** Per-repository data store */\ninterface RepositoryStore {\n repository: StoredRepository;\n vocabulary: MemoryVocabulary;\n vocabularyChangeLog: VocabularyChangeRecord[];\n entities: Map<string, StoredEntity>;\n /** Secondary index: slug → GUID for fast slug lookups */\n slugIndex: Map<string, string>;\n relationships: Map<string, StoredRelationship>;\n}\n\nexport class InMemoryStorageProvider implements StorageProvider {\n private stores = new Map<string, RepositoryStore>();\n\n private getStore(repositoryId: string): RepositoryStore {\n const store = this.stores.get(repositoryId);\n if (!store) {\n throw new RepositoryNotFoundError(repositoryId);\n }\n return store;\n }\n\n // ─── Lifecycle ─────────────────────────────────────────────────────\n\n async initialize(): Promise<void> {\n // No-op for in-memory\n }\n\n async dispose(): Promise<void> {\n this.stores.clear();\n }\n\n // ─── Repository ────────────────────────────────────────────────────\n\n async createRepository(config: StorageRepositoryConfig): Promise<StoredRepository> {\n if (this.stores.has(config.repositoryId)) {\n throw new DuplicateRepositoryError(config.repositoryId);\n }\n\n const repository: StoredRepository = {\n repositoryId: config.repositoryId,\n type: config.type,\n label: config.label,\n description: config.description,\n legal: config.legal,\n owner: config.owner,\n governanceConfig: config.governanceConfig,\n metadata: config.metadata,\n createdAt: config.createdAt,\n createdBy: config.createdBy,\n };\n\n this.stores.set(config.repositoryId, {\n repository,\n vocabulary: createEmptyVocabulary(config.createdBy),\n vocabularyChangeLog: [],\n entities: new Map(),\n slugIndex: new Map(),\n relationships: new Map(),\n });\n\n return repository;\n }\n\n async getRepository(repositoryId: string): Promise<StoredRepository | null> {\n return this.stores.get(repositoryId)?.repository ?? null;\n }\n\n async listRepositories(\n filter?: RepositoryFilter,\n ): Promise<PaginatedResult<StoredRepositorySummary>> {\n let items = Array.from(this.stores.values()).map((store) => ({\n repositoryId: store.repository.repositoryId,\n type: store.repository.type,\n label: store.repository.label,\n description: store.repository.description,\n governanceConfig: store.repository.governanceConfig,\n }));\n\n if (filter?.type) {\n items = items.filter((r) => r.type === filter.type);\n }\n\n const total = items.length;\n const offset = filter?.offset ?? 0;\n const limit = filter?.limit ?? 20;\n const paged = items.slice(offset, offset + limit);\n\n return {\n items: paged,\n total,\n hasMore: offset + paged.length < total,\n limit,\n offset,\n };\n }\n\n async updateRepository(repositoryId: string, updates: RepositoryUpdate): Promise<StoredRepository> {\n const store = this.stores.get(repositoryId);\n if (!store) {\n throw new RepositoryNotFoundError(repositoryId);\n }\n const repo = store.repository;\n if (updates.label !== undefined) repo.label = updates.label;\n if (updates.description !== undefined) repo.description = updates.description;\n if (updates.type !== undefined) repo.type = updates.type;\n if (updates.legal !== undefined) repo.legal = updates.legal;\n if (updates.owner !== undefined) repo.owner = updates.owner;\n if (updates.governanceConfig !== undefined) repo.governanceConfig = updates.governanceConfig;\n if (updates.metadata !== undefined) repo.metadata = { ...repo.metadata, ...updates.metadata };\n return repo;\n }\n\n async deleteRepository(repositoryId: string, _onProgress?: import('../types/portability.js').DeleteProgressCallback): Promise<void> {\n if (!this.stores.has(repositoryId)) {\n throw new RepositoryNotFoundError(repositoryId);\n }\n this.stores.delete(repositoryId);\n }\n\n async deleteAllContents(repositoryId: string, _onProgress?: import('../types/portability.js').DeleteProgressCallback): Promise<{ deletedEntities: number; deletedRelationships: number }> {\n const store = this.getStore(repositoryId);\n const deletedEntities = store.entities.size;\n const deletedRelationships = store.relationships.size;\n store.entities.clear();\n store.slugIndex.clear();\n store.relationships.clear();\n return { deletedEntities, deletedRelationships };\n }\n\n async getRepositoryStats(repositoryId: string): Promise<RepositoryStats> {\n const store = this.getStore(repositoryId);\n\n const entityTypeBreakdown: Record<string, number> = {};\n for (const entity of store.entities.values()) {\n entityTypeBreakdown[entity.entityType] = (entityTypeBreakdown[entity.entityType] ?? 0) + 1;\n }\n\n const relationshipTypeBreakdown: Record<string, number> = {};\n for (const rel of store.relationships.values()) {\n relationshipTypeBreakdown[rel.relationshipType] =\n (relationshipTypeBreakdown[rel.relationshipType] ?? 0) + 1;\n }\n\n return {\n entityCount: store.entities.size,\n relationshipCount: store.relationships.size,\n vocabularyVersion: store.vocabulary.version,\n entityTypeBreakdown,\n relationshipTypeBreakdown,\n };\n }\n\n // ─── Vocabulary ────────────────────────────────────────────────────\n\n async getVocabulary(repositoryId: string): Promise<MemoryVocabulary> {\n const store = this.getStore(repositoryId);\n return store.vocabulary;\n }\n\n async saveVocabulary(repositoryId: string, vocabulary: MemoryVocabulary): Promise<void> {\n const store = this.getStore(repositoryId);\n store.vocabulary = vocabulary;\n }\n\n async getVocabularyChangeLog(\n repositoryId: string,\n options?: PaginationOptions,\n ): Promise<PaginatedResult<VocabularyChangeRecord>> {\n const store = this.getStore(repositoryId);\n const limit = options?.limit ?? 10;\n const offset = options?.offset ?? 0;\n const items = store.vocabularyChangeLog.slice(offset, offset + limit);\n\n return {\n items,\n total: store.vocabularyChangeLog.length,\n hasMore: offset + limit < store.vocabularyChangeLog.length,\n limit,\n offset,\n };\n }\n\n // ─── Entities ──────────────────────────────────────────────────────\n\n async createEntity(repositoryId: string, entity: StoredEntity): Promise<StoredEntity> {\n const store = this.getStore(repositoryId);\n if (store.entities.has(entity.id)) {\n throw new DuplicateEntityError(entity.id);\n }\n store.entities.set(entity.id, entity);\n store.slugIndex.set(entity.slug, entity.id);\n return entity;\n }\n\n async getEntity(repositoryId: string, entityId: string): Promise<StoredEntity | null> {\n const store = this.getStore(repositoryId);\n return store.entities.get(entityId) ?? null;\n }\n\n async getEntityBySlug(repositoryId: string, slug: string): Promise<StoredEntity | null> {\n const store = this.getStore(repositoryId);\n const id = store.slugIndex.get(slug);\n if (!id) return null;\n return store.entities.get(id) ?? null;\n }\n\n async getEntities(\n repositoryId: string,\n entityIds: string[],\n ): Promise<Map<string, StoredEntity>> {\n const store = this.getStore(repositoryId);\n const result = new Map<string, StoredEntity>();\n for (const id of entityIds) {\n const entity = store.entities.get(id);\n if (entity) {\n result.set(id, entity);\n }\n }\n return result;\n }\n\n async updateEntity(\n repositoryId: string,\n entityId: string,\n updates: StoredEntityUpdate,\n ): Promise<StoredEntity> {\n const store = this.getStore(repositoryId);\n const existing = store.entities.get(entityId);\n if (!existing) {\n throw new EntityNotFoundError(entityId);\n }\n\n // For optional string fields, null clears, undefined preserves, string sets.\n const updated: StoredEntity = {\n ...existing,\n entityType: updates.entityType ?? existing.entityType,\n label: updates.label ?? existing.label,\n summary: updates.summary === undefined ? existing.summary : (updates.summary ?? undefined),\n properties: updates.properties ?? existing.properties,\n data: updates.data === undefined ? existing.data : (updates.data ?? undefined),\n dataFormat: updates.dataFormat === undefined ? existing.dataFormat : (updates.dataFormat ?? undefined),\n provenance: updates.provenance,\n embedding: updates.embedding ?? existing.embedding,\n };\n\n // If slug needs to change (type or label changed), update slug index\n if (updates.slug && updates.slug !== existing.slug) {\n store.slugIndex.delete(existing.slug);\n updated.slug = updates.slug;\n store.slugIndex.set(updates.slug, entityId);\n }\n\n store.entities.set(entityId, updated);\n return updated;\n }\n\n async deleteEntity(repositoryId: string, entityId: string): Promise<void> {\n const store = this.getStore(repositoryId);\n const existing = store.entities.get(entityId);\n if (!existing) {\n throw new EntityNotFoundError(entityId);\n }\n store.slugIndex.delete(existing.slug);\n store.entities.delete(entityId);\n\n // Also remove relationships involving this entity\n for (const [relId, rel] of store.relationships) {\n if (rel.sourceEntityId === entityId || rel.targetEntityId === entityId) {\n store.relationships.delete(relId);\n }\n }\n }\n\n async deleteEntitiesByType(\n repositoryId: string,\n entityType: string,\n ): Promise<{ deletedEntities: number; deletedRelationships: number }> {\n const store = this.getStore(repositoryId);\n\n // Collect entity IDs of the given type\n const entityIds = new Set<string>();\n for (const [id, entity] of store.entities) {\n if (entity.entityType === entityType) {\n entityIds.add(id);\n store.slugIndex.delete(entity.slug);\n }\n }\n\n // Delete relationships involving those entities\n let deletedRelationships = 0;\n for (const [relId, rel] of store.relationships) {\n if (entityIds.has(rel.sourceEntityId) || entityIds.has(rel.targetEntityId)) {\n store.relationships.delete(relId);\n deletedRelationships++;\n }\n }\n\n // Delete the entities\n for (const id of entityIds) {\n store.entities.delete(id);\n }\n\n return { deletedEntities: entityIds.size, deletedRelationships };\n }\n\n async findEntities(\n repositoryId: string,\n query: StorageFindQuery,\n ): Promise<PaginatedResult<StoredEntity>> {\n const store = this.getStore(repositoryId);\n let matches = Array.from(store.entities.values());\n\n // Filter by entity types\n if (query.entityTypes && query.entityTypes.length > 0) {\n matches = matches.filter((e) => query.entityTypes!.includes(e.entityType));\n }\n\n // Filter by search term (label substring, case-insensitive)\n if (query.searchTerm) {\n const term = query.searchTerm.toLowerCase();\n matches = matches.filter(\n (e) =>\n e.label.toLowerCase().includes(term) ||\n (e.summary && e.summary.toLowerCase().includes(term)),\n );\n }\n\n // Filter by property values\n if (query.properties) {\n const entries = Object.entries(query.properties);\n matches = matches.filter((e) =>\n entries.every(([key, value]) => e.properties[key] === value),\n );\n }\n\n // Filter by provenance\n if (query.provenance) {\n matches = matches.filter((e) => matchesProvenance(e.provenance, query.provenance!));\n }\n\n const total = matches.length;\n const items = matches.slice(query.offset, query.offset + query.limit);\n\n return {\n items,\n total,\n hasMore: query.offset + query.limit < total,\n limit: query.limit,\n offset: query.offset,\n };\n }\n\n // ─── Relationships ─────────────────────────────────────────────────\n\n async createRelationship(\n repositoryId: string,\n relationship: StoredRelationship,\n ): Promise<StoredRelationship> {\n const store = this.getStore(repositoryId);\n if (store.relationships.has(relationship.id)) {\n throw new DuplicateRelationshipError(relationship.id);\n }\n store.relationships.set(relationship.id, relationship);\n return relationship;\n }\n\n async getRelationship(\n repositoryId: string,\n relationshipId: string,\n ): Promise<StoredRelationship | null> {\n const store = this.getStore(repositoryId);\n return store.relationships.get(relationshipId) ?? null;\n }\n\n async getEntityRelationships(\n repositoryId: string,\n entityId: string,\n options?: RelationshipQueryOptions,\n ): Promise<PaginatedResult<StoredRelationship>> {\n const store = this.getStore(repositoryId);\n const direction = options?.direction ?? 'both';\n let matches = Array.from(store.relationships.values());\n\n // Filter by entity involvement and direction\n matches = matches.filter((rel) => {\n const isSource = rel.sourceEntityId === entityId;\n const isTarget = rel.targetEntityId === entityId;\n const isBidirectionalTarget = rel.bidirectional && isTarget;\n\n switch (direction) {\n case 'outbound':\n return isSource || isBidirectionalTarget;\n case 'inbound':\n return isTarget || (rel.bidirectional && isSource);\n case 'both':\n default:\n return isSource || isTarget;\n }\n });\n\n // Filter by relationship types\n if (options?.relationshipTypes && options.relationshipTypes.length > 0) {\n matches = matches.filter((r) => options.relationshipTypes!.includes(r.relationshipType));\n }\n\n // Filter by property values\n if (options?.propertyFilters && options.propertyFilters.length > 0) {\n matches = matches.filter((r) => matchesPropertyFilters(r.properties, options.propertyFilters!));\n }\n\n const total = matches.length;\n const limit = options?.limit ?? 10;\n const offset = options?.offset ?? 0;\n const items = matches.slice(offset, offset + limit);\n\n return {\n items,\n total,\n hasMore: offset + limit < total,\n limit,\n offset,\n };\n }\n\n async deleteEntities(\n repositoryId: string,\n ids: string[],\n ): Promise<{ deleted: string[]; notFound: string[] }> {\n const store = this.getStore(repositoryId);\n const deleted: string[] = [];\n const notFound: string[] = [];\n const deletedSet = new Set<string>();\n\n for (const id of ids) {\n const existing = store.entities.get(id);\n if (!existing) {\n notFound.push(id);\n continue;\n }\n store.slugIndex.delete(existing.slug);\n store.entities.delete(id);\n deleted.push(id);\n deletedSet.add(id);\n }\n\n // Cascade-delete relationships involving any of the deleted entities\n for (const [relId, rel] of store.relationships) {\n if (deletedSet.has(rel.sourceEntityId) || deletedSet.has(rel.targetEntityId)) {\n store.relationships.delete(relId);\n }\n }\n\n return { deleted, notFound };\n }\n\n async deleteRelationship(repositoryId: string, relationshipId: string): Promise<void> {\n const store = this.getStore(repositoryId);\n if (!store.relationships.has(relationshipId)) {\n throw new RelationshipNotFoundError(relationshipId);\n }\n store.relationships.delete(relationshipId);\n }\n\n async deleteRelationships(\n repositoryId: string,\n ids: string[],\n ): Promise<{ deleted: string[]; notFound: string[] }> {\n const store = this.getStore(repositoryId);\n const deleted: string[] = [];\n const notFound: string[] = [];\n for (const id of ids) {\n if (store.relationships.has(id)) {\n store.relationships.delete(id);\n deleted.push(id);\n } else {\n notFound.push(id);\n }\n }\n return { deleted, notFound };\n }\n\n async deleteRelationshipsByType(\n repositoryId: string,\n relationshipType: string,\n ): Promise<{ deletedRelationships: number }> {\n const store = this.getStore(repositoryId);\n let deletedRelationships = 0;\n for (const [relId, rel] of store.relationships) {\n if (rel.relationshipType === relationshipType) {\n store.relationships.delete(relId);\n deletedRelationships++;\n }\n }\n return { deletedRelationships };\n }\n\n // ─── Graph Traversal ───────────────────────────────────────────────\n\n async exploreNeighborhood(\n repositoryId: string,\n entityId: string,\n options: StorageExploreOptions,\n ): Promise<StorageNeighborhood> {\n const store = this.getStore(repositoryId);\n\n if (!store.entities.has(entityId)) {\n throw new EntityNotFoundError(entityId);\n }\n\n const layers: StorageNeighborhood['layers'] = [];\n const visited = new Set<string>([entityId]);\n let currentFrontier = new Set<string>([entityId]);\n\n for (let depth = 0; depth < options.depth; depth++) {\n const layer: Record<string, { total: number; entities: StoredEntity[]; relationships: StoredRelationship[] }> = {};\n const nextFrontier = new Set<string>();\n\n for (const frontierEntityId of currentFrontier) {\n for (const rel of store.relationships.values()) {\n // Check direction filter\n const isSource = rel.sourceEntityId === frontierEntityId;\n const isTarget = rel.targetEntityId === frontierEntityId;\n\n let matchesDirection = false;\n let connectedEntityId: string | undefined;\n\n if (isSource && (options.direction === 'outbound' || options.direction === 'both')) {\n matchesDirection = true;\n connectedEntityId = rel.targetEntityId;\n } else if (isTarget && (options.direction === 'inbound' || options.direction === 'both')) {\n matchesDirection = true;\n connectedEntityId = rel.sourceEntityId;\n } else if (rel.bidirectional) {\n if (isSource && options.direction === 'inbound') {\n matchesDirection = true;\n connectedEntityId = rel.targetEntityId;\n } else if (isTarget && options.direction === 'outbound') {\n matchesDirection = true;\n connectedEntityId = rel.sourceEntityId;\n }\n }\n\n if (!matchesDirection || !connectedEntityId) continue;\n if (visited.has(connectedEntityId)) continue;\n\n // Filter by relationship type\n if (options.relationshipTypes && !options.relationshipTypes.includes(rel.relationshipType)) {\n continue;\n }\n\n // Filter by relationship property values\n if (options.relationshipPropertyFilters && options.relationshipPropertyFilters.length > 0) {\n if (!matchesPropertyFilters(rel.properties, options.relationshipPropertyFilters)) {\n continue;\n }\n }\n\n const connectedEntity = store.entities.get(connectedEntityId);\n if (!connectedEntity) continue;\n\n // Filter by entity type\n if (options.entityTypes && !options.entityTypes.includes(connectedEntity.entityType)) {\n continue;\n }\n\n const relType = rel.relationshipType;\n if (!layer[relType]) {\n layer[relType] = { total: 0, entities: [], relationships: [] };\n }\n\n layer[relType].total++;\n\n // Apply per-type pagination\n const group = layer[relType];\n if (group.entities.length < options.limitPerType) {\n group.entities.push(connectedEntity);\n group.relationships.push(rel);\n }\n\n nextFrontier.add(connectedEntityId);\n visited.add(connectedEntityId);\n }\n }\n\n layers.push(layer);\n currentFrontier = nextFrontier;\n\n if (nextFrontier.size === 0) break;\n }\n\n return {\n centerId: entityId,\n layers,\n };\n }\n\n async findPaths(\n repositoryId: string,\n sourceId: string,\n targetId: string,\n options: StoragePathOptions,\n ): Promise<StoragePathResult> {\n const store = this.getStore(repositoryId);\n\n if (!store.entities.has(sourceId)) {\n throw new EntityNotFoundError(sourceId);\n }\n if (!store.entities.has(targetId)) {\n throw new EntityNotFoundError(targetId);\n }\n\n if (sourceId === targetId) {\n return { paths: [{ entityIds: [sourceId], relationshipIds: [] }], totalPaths: 1 };\n }\n\n // BFS path finding\n const paths: Array<{ entityIds: string[]; relationshipIds: string[] }> = [];\n const queue: Array<{ entityId: string; path: string[]; relPath: string[] }> = [\n { entityId: sourceId, path: [sourceId], relPath: [] },\n ];\n\n // Track visited per path-length to allow multiple paths\n const visitedAtDepth = new Map<string, number>();\n visitedAtDepth.set(sourceId, 0);\n\n while (queue.length > 0 && paths.length < options.limit + options.offset) {\n const current = queue.shift()!;\n\n if (current.path.length > options.maxDepth + 1) continue;\n\n for (const rel of store.relationships.values()) {\n // Filter by relationship type\n if (options.relationshipTypes && !options.relationshipTypes.includes(rel.relationshipType)) {\n continue;\n }\n\n // Filter by relationship property values\n if (options.relationshipPropertyFilters && options.relationshipPropertyFilters.length > 0) {\n if (!matchesPropertyFilters(rel.properties, options.relationshipPropertyFilters)) {\n continue;\n }\n }\n\n // Traverse edges in both directions for path discovery,\n // regardless of bidirectional flag. The flag controls semantic\n // meaning, not graph reachability — paths should follow all edges.\n let nextEntityId: string | undefined;\n if (rel.sourceEntityId === current.entityId) {\n nextEntityId = rel.targetEntityId;\n } else if (rel.targetEntityId === current.entityId) {\n nextEntityId = rel.sourceEntityId;\n }\n\n if (!nextEntityId) continue;\n if (current.path.includes(nextEntityId) && nextEntityId !== targetId) continue;\n\n // Filter intermediate entities by type (always allow source and target)\n if (options.entityTypes && nextEntityId !== targetId) {\n const nextEntity = store.entities.get(nextEntityId);\n if (nextEntity && !options.entityTypes.includes(nextEntity.entityType)) continue;\n }\n\n const newPath = [...current.path, nextEntityId];\n const newRelPath = [...current.relPath, rel.id];\n\n if (nextEntityId === targetId) {\n paths.push({ entityIds: newPath, relationshipIds: newRelPath });\n } else if (newPath.length <= options.maxDepth) {\n const prevDepth = visitedAtDepth.get(nextEntityId);\n if (prevDepth === undefined || prevDepth >= newPath.length - 1) {\n visitedAtDepth.set(nextEntityId, newPath.length - 1);\n queue.push({ entityId: nextEntityId, path: newPath, relPath: newRelPath });\n }\n }\n }\n }\n\n const paginatedPaths = paths.slice(options.offset, options.offset + options.limit);\n\n return {\n paths: paginatedPaths,\n totalPaths: paths.length,\n };\n }\n\n // ─── Timeline ──────────────────────────────────────────────────────\n\n async getTimeline(\n repositoryId: string,\n entityId: string,\n options: StorageTimelineOptions,\n ): Promise<StorageTimelineResult> {\n const store = this.getStore(repositoryId);\n const entity = store.entities.get(entityId);\n if (!entity) {\n throw new EntityNotFoundError(entityId);\n }\n\n const events: StorageTimelineResult['events'] = [];\n\n // Entity creation event\n events.push({\n timestamp: entity.provenance.createdAt,\n eventType: 'entity:created',\n entityId,\n });\n\n // Entity modification event (if different from creation)\n if (entity.provenance.modifiedAt !== entity.provenance.createdAt) {\n events.push({\n timestamp: entity.provenance.modifiedAt,\n eventType: 'entity:updated',\n entityId,\n });\n }\n\n // Relationship events involving this entity\n for (const rel of store.relationships.values()) {\n if (rel.sourceEntityId === entityId || rel.targetEntityId === entityId) {\n events.push({\n timestamp: rel.provenance.createdAt,\n eventType: 'relationship:created',\n entityId,\n relationshipId: rel.id,\n });\n }\n }\n\n // Filter by time range\n let filtered = events;\n if (options.timeRange) {\n const from = new Date(options.timeRange.from).getTime();\n const to = new Date(options.timeRange.to).getTime();\n filtered = filtered.filter((e) => {\n const t = new Date(e.timestamp).getTime();\n return t >= from && t <= to;\n });\n }\n\n // Filter by event types\n if (options.eventTypes && options.eventTypes.length > 0) {\n filtered = filtered.filter((e) => options.eventTypes!.includes(e.eventType));\n }\n\n // Filter by provenance (conversation ID)\n if (options.provenance) {\n const prov = options.provenance;\n filtered = filtered.filter((e) => {\n // For entity events, check entity provenance\n if (e.eventType.startsWith('entity:')) {\n const ent = store.entities.get(e.entityId);\n return ent ? matchesProvenance(ent.provenance, prov) : false;\n }\n // For relationship events, check relationship provenance\n if (e.relationshipId) {\n const rel = store.relationships.get(e.relationshipId);\n return rel ? matchesProvenance(rel.provenance, prov) : false;\n }\n return true;\n });\n }\n\n // Sort by timestamp descending (most recent first)\n filtered.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime());\n\n const total = filtered.length;\n const items = filtered.slice(options.offset, options.offset + options.limit);\n\n return {\n events: items,\n total,\n };\n }\n\n // ─── Bulk Operations ───────────────────────────────────────────────\n\n async *exportAll(repositoryId: string): AsyncIterable<ExportChunk> {\n const store = this.getStore(repositoryId);\n\n const entities = Array.from(store.entities.values());\n const batchSize = 100;\n\n for (let i = 0; i < entities.length; i += batchSize) {\n const batch = entities.slice(i, i + batchSize);\n yield {\n type: 'entities',\n data: batch,\n sequence: Math.floor(i / batchSize),\n isLast: i + batchSize >= entities.length,\n };\n }\n\n // If no entities, still yield an empty last chunk\n if (entities.length === 0) {\n yield { type: 'entities', data: [], sequence: 0, isLast: true };\n }\n\n const relationships = Array.from(store.relationships.values());\n for (let i = 0; i < relationships.length; i += batchSize) {\n const batch = relationships.slice(i, i + batchSize);\n yield {\n type: 'relationships',\n data: batch,\n sequence: Math.floor(i / batchSize),\n isLast: i + batchSize >= relationships.length,\n };\n }\n\n if (relationships.length === 0) {\n yield { type: 'relationships', data: [], sequence: 0, isLast: true };\n }\n }\n\n async importBulk(\n repositoryId: string,\n data: ImportChunk[],\n _options?: import('../types/portability.js').BulkImportOptions,\n ): Promise<BulkImportResult> {\n const store = this.getStore(repositoryId);\n let entitiesImported = 0;\n let relationshipsImported = 0;\n const errors: Array<{ item: string; error: string }> = [];\n\n for (const chunk of data) {\n if (chunk.entities) {\n for (const entity of chunk.entities) {\n try {\n store.entities.set(entity.id, entity);\n store.slugIndex.set(entity.slug, entity.id);\n entitiesImported++;\n } catch (err) {\n errors.push({\n item: entity.id,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n }\n }\n\n if (chunk.relationships) {\n for (const rel of chunk.relationships) {\n try {\n store.relationships.set(rel.id, rel);\n relationshipsImported++;\n } catch (err) {\n errors.push({\n item: rel.id,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n }\n }\n }\n\n return { entitiesImported, relationshipsImported, errors };\n }\n}\n\n// ─── Provenance filter helper ──────────────────────────────────────\n\nfunction matchesProvenance(prov: Provenance, filter: ProvenanceFilter): boolean {\n if (filter.conversationIds && filter.conversationIds.length > 0) {\n const matchesCreated = prov.createdInConversation && filter.conversationIds.includes(prov.createdInConversation);\n const matchesModified = prov.modifiedInConversation && filter.conversationIds.includes(prov.modifiedInConversation);\n if (!matchesCreated && !matchesModified) return false;\n }\n if (filter.actors && filter.actors.length > 0) {\n const matchesCreator = filter.actors.includes(prov.createdBy);\n const matchesModifier = filter.actors.includes(prov.modifiedBy);\n if (!matchesCreator && !matchesModifier) return false;\n }\n if (filter.dateRange) {\n const from = new Date(filter.dateRange.from).getTime();\n const to = new Date(filter.dateRange.to).getTime();\n const created = new Date(prov.createdAt).getTime();\n const modified = new Date(prov.modifiedAt).getTime();\n if (!(created >= from && created <= to) && !(modified >= from && modified <= to)) return false;\n }\n return true;\n}\n","// InMemorySearchProvider — basic in-memory full-text search\n\nimport type { SearchProvider, SearchableEntity } from '../providers/SearchProvider.js';\nimport type { SearchOptions } from '../types/queries.js';\nimport type { PaginatedResult, SearchHit } from '../types/results.js';\n\ninterface IndexedEntry {\n entityId: string;\n entityType: string;\n text: string; // concatenated searchable text (lowercased)\n}\n\nexport class InMemorySearchProvider implements SearchProvider {\n private indices = new Map<string, Map<string, IndexedEntry>>();\n\n private getIndex(repositoryId: string): Map<string, IndexedEntry> {\n if (!this.indices.has(repositoryId)) {\n this.indices.set(repositoryId, new Map());\n }\n return this.indices.get(repositoryId)!;\n }\n\n async indexEntity(repositoryId: string, entity: SearchableEntity): Promise<void> {\n const index = this.getIndex(repositoryId);\n\n // Build searchable text from label, summary, properties, and data\n const parts = [entity.label, entity.summary ?? ''];\n\n if (entity.properties) {\n for (const value of Object.values(entity.properties)) {\n if (typeof value === 'string') {\n parts.push(value);\n }\n }\n }\n\n if (entity.data) {\n parts.push(entity.data);\n }\n\n index.set(entity.entityId, {\n entityId: entity.entityId,\n entityType: entity.entityType,\n text: parts.join(' ').toLowerCase(),\n });\n }\n\n async removeEntity(repositoryId: string, entityId: string): Promise<void> {\n this.getIndex(repositoryId).delete(entityId);\n }\n\n async search(\n repositoryId: string,\n query: string,\n options?: SearchOptions,\n ): Promise<PaginatedResult<SearchHit>> {\n const index = this.getIndex(repositoryId);\n const terms = query.toLowerCase().split(/\\s+/).filter(Boolean);\n\n if (terms.length === 0) {\n return { items: [], total: 0, hasMore: false, limit: options?.limit ?? 10, offset: options?.offset ?? 0 };\n }\n\n let hits: Array<{ entry: IndexedEntry; score: number }> = [];\n\n for (const entry of index.values()) {\n // Filter by entity types\n if (options?.entityTypes && options.entityTypes.length > 0) {\n if (!options.entityTypes.includes(entry.entityType)) continue;\n }\n\n // Score: count of matching terms / total terms\n let matchCount = 0;\n for (const term of terms) {\n if (entry.text.includes(term)) {\n matchCount++;\n }\n }\n\n if (matchCount > 0) {\n hits.push({ entry, score: matchCount / terms.length });\n }\n }\n\n // Sort by score descending\n hits.sort((a, b) => b.score - a.score);\n\n const total = hits.length;\n const limit = options?.limit ?? 10;\n const offset = options?.offset ?? 0;\n const page = hits.slice(offset, offset + limit);\n\n return {\n items: page.map((h) => ({\n id: h.entry.entityId,\n score: h.score,\n })),\n total,\n hasMore: offset + limit < total,\n limit,\n offset,\n };\n }\n\n async reindexRepository(\n repositoryId: string,\n entities: AsyncIterable<SearchableEntity>,\n ): Promise<void> {\n // Clear existing index\n this.indices.set(repositoryId, new Map());\n\n for await (const entity of entities) {\n await this.indexEntity(repositoryId, entity);\n }\n }\n}\n","// NoOpEmbeddingProvider — stub used when no embedding provider is configured\n\nimport type { EmbeddingProvider } from '../providers/EmbeddingProvider.js';\nimport { EmbeddingProviderRequiredError } from '../core/errors.js';\n\nexport class NoOpEmbeddingProvider implements EmbeddingProvider {\n async embed(_text: string): Promise<number[]> {\n throw new EmbeddingProviderRequiredError();\n }\n\n async embedBatch(_texts: string[]): Promise<number[][]> {\n throw new EmbeddingProviderRequiredError();\n }\n\n dimensions(): number {\n return 0;\n }\n\n modelId(): string {\n return 'none';\n }\n}\n"],"mappings":"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","names":["DEFAULT_ESTIMATED_FANOUT_PER_HOP"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/core/errors.ts","../src/core/DeepMemory.ts","../src/entities/IdGenerator.ts","../src/vocabulary/similarity.ts","../src/vocabulary/VocabularyValidator.ts","../src/entities/EntityManager.ts","../src/relationships/RelationshipManager.ts","../src/entities/entityProjection.ts","../src/relationships/TraversalValidator.ts","../src/relationships/PropertyFilterMatcher.ts","../src/relationships/FallbackTraversalExecutor.ts","../src/relationships/GraphTraversal.ts","../src/search/SearchOrchestrator.ts","../src/validation/RepositoryValidator.ts","../src/core/MemoryRepository.ts","../src/vocabulary/SemanticDeduplicator.ts","../src/vocabulary/VocabularySchema.ts","../src/vocabulary/VocabularyGovernor.ts","../src/core/VocabularyEngine.ts","../src/core/ProvenanceTracker.ts","../src/core/EventBus.ts","../src/portability/RepositoryExporter.ts","../src/vocabulary/VocabularyDiff.ts","../src/portability/MigrationEngine.ts","../src/portability/RepositoryImporter.ts","../src/usage/safeSink.ts","../src/relationships/compilers/GremlinCompiler.ts","../src/relationships/compilers/CypherCompiler.ts","../src/providers-builtin/InMemoryStorageProvider.ts","../src/providers-builtin/InMemorySearchProvider.ts","../src/providers-builtin/NoOpEmbeddingProvider.ts"],"sourcesContent":["// @utaba/deep-memory — Public API\n// Vocabulary-driven graph memory for AI agents\n\nexport * from './types/index.js';\nexport * from './providers/index.js';\n\n// Errors\nexport {\n DeepMemoryError,\n InvalidInputError,\n EntityNotFoundError,\n DuplicateEntityError,\n RelationshipNotFoundError,\n DuplicateRelationshipError,\n RepositoryNotFoundError,\n DuplicateRepositoryError,\n VocabularyValidationError,\n RelationshipConstraintError,\n SelfReferentialRelationshipError,\n GovernanceDeniedError,\n OperationCancelledError,\n EmbeddingProviderRequiredError,\n ImportError,\n ExportError,\n ProviderError,\n GraphTraversalProviderRequiredError,\n TraversalValidationError,\n TraversalVocabularyError,\n TraversalTimeoutError,\n} from './core/errors.js';\nexport type { DeepMemoryErrorCode } from './core/errors.js';\n\n// Core classes\nexport { DeepMemory, generateId, isValidUuid } from './core/DeepMemory.js';\nexport type { DeepMemoryConfig } from './core/DeepMemory.js';\nexport { MemoryRepository } from './core/MemoryRepository.js';\nexport { RepositoryValidator } from './validation/RepositoryValidator.js';\n\n// Utilities\nexport { matchesPropertyFilters } from './relationships/PropertyFilterMatcher.js';\nexport { projectEntity } from './entities/entityProjection.js';\nexport { createSafeSink } from './usage/safeSink.js';\n\n// Compilers (for provider authors who want to reuse them)\nexport { GremlinCompiler } from './relationships/compilers/GremlinCompiler.js';\nexport { CypherCompiler } from './relationships/compilers/CypherCompiler.js';\nexport type { TraversalCompiler, CompiledQuery } from './relationships/compilers/TraversalCompiler.js';\n\n// Built-in providers\nexport { InMemoryStorageProvider } from './providers-builtin/InMemoryStorageProvider.js';\nexport { InMemorySearchProvider } from './providers-builtin/InMemorySearchProvider.js';\nexport { NoOpEmbeddingProvider } from './providers-builtin/NoOpEmbeddingProvider.js';\n","// Error hierarchy — typed errors with actionable suggestions\n\n/** Error codes for all Deep Memory errors */\nexport type DeepMemoryErrorCode =\n | 'INVALID_INPUT'\n | 'ENTITY_NOT_FOUND'\n | 'ENTITY_ALREADY_EXISTS'\n | 'RELATIONSHIP_NOT_FOUND'\n | 'RELATIONSHIP_ALREADY_EXISTS'\n | 'REPOSITORY_NOT_FOUND'\n | 'REPOSITORY_ALREADY_EXISTS'\n | 'VOCABULARY_VALIDATION_FAILED'\n | 'RELATIONSHIP_CONSTRAINT_FAILED'\n | 'SELF_REFERENTIAL_RELATIONSHIP'\n | 'GOVERNANCE_DENIED'\n | 'OPERATION_CANCELLED'\n | 'EMBEDDING_PROVIDER_REQUIRED'\n | 'IMPORT_ERROR'\n | 'EXPORT_ERROR'\n | 'PROVIDER_ERROR'\n | 'GRAPH_TRAVERSAL_PROVIDER_REQUIRED'\n | 'TRAVERSAL_VALIDATION_FAILED'\n | 'TRAVERSAL_VOCABULARY_ERROR'\n | 'TRAVERSAL_TIMEOUT';\n\n/** Base error class for all Deep Memory errors */\nexport class DeepMemoryError extends Error {\n readonly code: DeepMemoryErrorCode;\n readonly suggestion?: string;\n\n constructor(code: DeepMemoryErrorCode, message: string, suggestion?: string) {\n super(message);\n this.name = 'DeepMemoryError';\n this.code = code;\n this.suggestion = suggestion;\n }\n}\n\n/** Input validation failed (e.g. invalid ID format) */\nexport class InvalidInputError extends DeepMemoryError {\n readonly field: string;\n\n constructor(field: string, message: string, suggestion?: string) {\n super(\n 'INVALID_INPUT',\n message,\n suggestion ?? `Check the value of \"${field}\" and try again.`,\n );\n this.name = 'InvalidInputError';\n this.field = field;\n }\n}\n\n/** Entity was not found in the repository */\nexport class EntityNotFoundError extends DeepMemoryError {\n readonly id: string;\n readonly slug?: string;\n\n constructor(idOrSlug: string, slug?: string) {\n super(\n 'ENTITY_NOT_FOUND',\n `Entity \"${idOrSlug}\" not found`,\n `Check the entity ID or slug is correct. Use findEntities() to search by label if unknown.`,\n );\n this.name = 'EntityNotFoundError';\n this.id = idOrSlug;\n this.slug = slug;\n }\n}\n\n/** Attempted to create an entity with an ID that already exists */\nexport class DuplicateEntityError extends DeepMemoryError {\n readonly id: string;\n\n constructor(id: string) {\n super(\n 'ENTITY_ALREADY_EXISTS',\n `Entity \"${id}\" already exists`,\n `Use updateEntity() to modify an existing entity, or omit id to auto-generate a unique one.`,\n );\n this.name = 'DuplicateEntityError';\n this.id = id;\n }\n}\n\n/** Relationship was not found */\nexport class RelationshipNotFoundError extends DeepMemoryError {\n readonly relationshipId: string;\n\n constructor(relationshipId: string) {\n super(\n 'RELATIONSHIP_NOT_FOUND',\n `Relationship \"${relationshipId}\" not found`,\n `Check the relationship ID is correct. Use getRelationships() to list relationships for an entity.`,\n );\n this.name = 'RelationshipNotFoundError';\n this.relationshipId = relationshipId;\n }\n}\n\n/** Attempted to create a relationship with an ID that already exists */\nexport class DuplicateRelationshipError extends DeepMemoryError {\n readonly relationshipId: string;\n\n constructor(relationshipId: string) {\n super(\n 'RELATIONSHIP_ALREADY_EXISTS',\n `Relationship \"${relationshipId}\" already exists`,\n `Omit relationshipId to auto-generate a unique one, or use a different explicit ID.`,\n );\n this.name = 'DuplicateRelationshipError';\n this.relationshipId = relationshipId;\n }\n}\n\n/** Repository was not found */\nexport class RepositoryNotFoundError extends DeepMemoryError {\n readonly repositoryId: string;\n\n constructor(repositoryId: string) {\n super(\n 'REPOSITORY_NOT_FOUND',\n `Repository \"${repositoryId}\" not found`,\n `Use listRepositories() to see available repositories, or createRepository() to create a new one.`,\n );\n this.name = 'RepositoryNotFoundError';\n this.repositoryId = repositoryId;\n }\n}\n\n/** Attempted to create a repository with an ID that already exists */\nexport class DuplicateRepositoryError extends DeepMemoryError {\n readonly repositoryId: string;\n\n constructor(repositoryId: string) {\n super(\n 'REPOSITORY_ALREADY_EXISTS',\n `Repository \"${repositoryId}\" already exists`,\n `Use openRepository() to access an existing repository, or choose a different ID.`,\n );\n this.name = 'DuplicateRepositoryError';\n this.repositoryId = repositoryId;\n }\n}\n\n/** Entity or relationship failed vocabulary validation */\nexport class VocabularyValidationError extends DeepMemoryError {\n readonly errors: Array<{ field: string; message: string; suggestion?: string }>;\n\n constructor(\n errors: Array<{ field: string; message: string; suggestion?: string }>,\n ) {\n const errorMsg = errors.map((e) => e.message).join('; ');\n const suggestions = errors\n .filter((e) => e.suggestion)\n .map((e) => e.suggestion!);\n\n super(\n 'VOCABULARY_VALIDATION_FAILED',\n `Vocabulary validation failed: ${errorMsg}`,\n suggestions.length > 0\n ? suggestions.join(' ')\n : `Check the repository vocabulary with getVocabulary() to see valid types and properties.`,\n );\n this.name = 'VocabularyValidationError';\n this.errors = errors;\n }\n}\n\n/** Relationship source/target entity types violate vocabulary constraints */\nexport class RelationshipConstraintError extends DeepMemoryError {\n readonly relationshipType: string;\n readonly sourceType?: string;\n readonly targetType?: string;\n\n constructor(\n relationshipType: string,\n message: string,\n sourceType?: string,\n targetType?: string,\n ) {\n super(\n 'RELATIONSHIP_CONSTRAINT_FAILED',\n message,\n `Check the vocabulary for allowed source/target types on \"${relationshipType}\".`,\n );\n this.name = 'RelationshipConstraintError';\n this.relationshipType = relationshipType;\n this.sourceType = sourceType;\n this.targetType = targetType;\n }\n}\n\n/** Relationship source and target entity are the same — self-references are not permitted */\nexport class SelfReferentialRelationshipError extends DeepMemoryError {\n readonly entityId: string;\n readonly relationshipType: string;\n\n constructor(entityId: string, relationshipType: string) {\n super(\n 'SELF_REFERENTIAL_RELATIONSHIP',\n `Self-referential relationship not allowed: \"${relationshipType}\" from entity \"${entityId}\" to itself`,\n `Relationships must connect two different entities. Check that sourceEntityId and targetEntityId refer to distinct entities.`,\n );\n this.name = 'SelfReferentialRelationshipError';\n this.entityId = entityId;\n this.relationshipType = relationshipType;\n }\n}\n\n/** Governance rules denied the operation */\nexport class GovernanceDeniedError extends DeepMemoryError {\n readonly governanceMode: string;\n\n constructor(governanceMode: string, reason: string) {\n super(\n 'GOVERNANCE_DENIED',\n `Governance denied: ${reason}`,\n governanceMode === 'locked'\n ? `The vocabulary is locked. Change governance mode to \"managed\" or \"open\" to allow modifications.`\n : `The operation was denied by governance rules. Review the governance configuration.`,\n );\n this.name = 'GovernanceDeniedError';\n this.governanceMode = governanceMode;\n }\n}\n\n/** A pre-mutation hook cancelled the operation */\nexport class OperationCancelledError extends DeepMemoryError {\n readonly operation: string;\n readonly reason: string;\n\n constructor(operation: string, reason: string) {\n super(\n 'OPERATION_CANCELLED',\n `${operation} cancelled: ${reason}`,\n `A pre-mutation hook cancelled this operation. Review registered hooks if this is unexpected.`,\n );\n this.name = 'OperationCancelledError';\n this.operation = operation;\n this.reason = reason;\n }\n}\n\n/** Semantic search was attempted without an embedding provider */\nexport class EmbeddingProviderRequiredError extends DeepMemoryError {\n constructor() {\n super(\n 'EMBEDDING_PROVIDER_REQUIRED',\n 'EmbeddingProvider required: no embedding provider is configured',\n `Provide an EmbeddingProvider in the DeepMemory config to use semantic search (searchByConcept).`,\n );\n this.name = 'EmbeddingProviderRequiredError';\n }\n}\n\n/** Error during import operations */\nexport class ImportError extends DeepMemoryError {\n constructor(message: string, suggestion?: string) {\n super(\n 'IMPORT_ERROR',\n message,\n suggestion ?? `Verify the archive format and check that the target repository is accessible.`,\n );\n this.name = 'ImportError';\n }\n}\n\n/** Error during export operations */\nexport class ExportError extends DeepMemoryError {\n constructor(message: string, suggestion?: string) {\n super(\n 'EXPORT_ERROR',\n message,\n suggestion ?? `Verify the repository exists and the storage provider is accessible.`,\n );\n this.name = 'ExportError';\n }\n}\n\n/** Generic provider-level error */\nexport class ProviderError extends DeepMemoryError {\n constructor(message: string, suggestion?: string) {\n super(\n 'PROVIDER_ERROR',\n message,\n suggestion ?? `Check provider configuration and connectivity.`,\n );\n this.name = 'ProviderError';\n }\n}\n\n/** Thrown when executeNativeQuery() is called but no GraphTraversalProvider is registered. */\nexport class GraphTraversalProviderRequiredError extends DeepMemoryError {\n constructor() {\n super(\n 'GRAPH_TRAVERSAL_PROVIDER_REQUIRED',\n 'GraphTraversalProvider required: no graph traversal provider is configured',\n `Provide a GraphTraversalProvider in the DeepMemory config to use native graph queries. Structured traversals via traverse() work without a provider using fallback BFS.`,\n );\n this.name = 'GraphTraversalProviderRequiredError';\n }\n}\n\n/** Thrown when a TraversalSpec is structurally invalid. */\nexport class TraversalValidationError extends DeepMemoryError {\n readonly errors: string[];\n\n constructor(errors: string[]) {\n super(\n 'TRAVERSAL_VALIDATION_FAILED',\n `Traversal validation failed: ${errors.join('; ')}`,\n `Check the TraversalSpec structure. Each spec needs a start (entityId, entityType, or filter), at least one step, and a returnMode.`,\n );\n this.name = 'TraversalValidationError';\n this.errors = errors;\n }\n}\n\n/** Thrown when a TraversalSpec references relationship/entity types not in the vocabulary. */\nexport class TraversalVocabularyError extends DeepMemoryError {\n readonly unknownTypes: string[];\n\n constructor(unknownTypes: string[]) {\n super(\n 'TRAVERSAL_VOCABULARY_ERROR',\n `Traversal references unknown types: ${unknownTypes.join(', ')}`,\n `Use getVocabulary() to see valid entity and relationship types for this repository.`,\n );\n this.name = 'TraversalVocabularyError';\n this.unknownTypes = unknownTypes;\n }\n}\n\n/** Thrown when a native query times out. */\nexport class TraversalTimeoutError extends DeepMemoryError {\n readonly timeoutMs: number;\n\n constructor(timeoutMs: number) {\n super(\n 'TRAVERSAL_TIMEOUT',\n `Traversal timed out after ${timeoutMs}ms`,\n `Try reducing the traversal depth, adding more specific filters, or increasing the timeout on your GraphTraversalProvider.`,\n );\n this.name = 'TraversalTimeoutError';\n this.timeoutMs = timeoutMs;\n }\n}\n","// DeepMemory — top-level API for managing memory repositories\n\nimport { randomUUID } from 'node:crypto';\nimport type { StorageProvider, EnsureSchemaResult } from '../providers/StorageProvider.js';\nimport type { SearchProvider } from '../providers/SearchProvider.js';\nimport type { EmbeddingProvider, EmbeddingProviderFactory } from '../providers/EmbeddingProvider.js';\nimport type { LockProvider } from '../providers/LockProvider.js';\nimport type { GraphTraversalProvider } from '../providers/GraphTraversalProvider.js';\nimport type { ProvenanceContext } from '../types/provenance.js';\nimport type {\n RepositoryConfig,\n RepositoryUpdate,\n RepositorySummary,\n RepositoryFilter,\n StoredRepository,\n} from '../types/repositories.js';\nimport type {\n DeepMemoryEventType,\n EventHandler,\n Unsubscribe,\n} from '../types/events.js';\nimport type { PaginatedResult } from '../types/results.js';\nimport type { ExportArchive, ExportOptions, ExportStreamItem, ImportOptions, ImportResult, ImportChunk, ImportStreamHeader } from '../types/portability.js';\nimport { MemoryRepository } from './MemoryRepository.js';\nimport { VocabularyEngine } from './VocabularyEngine.js';\nimport { ProvenanceTracker } from './ProvenanceTracker.js';\nimport { EventBus } from './EventBus.js';\nimport {\n buildVocabulary,\n createEmptyVocabulary,\n} from '../vocabulary/VocabularySchema.js';\nimport { RepositoryExporter } from '../portability/RepositoryExporter.js';\nimport { RepositoryImporter } from '../portability/RepositoryImporter.js';\nimport { InvalidInputError, RepositoryNotFoundError } from './errors.js';\n\nconst UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n\n/** Generate a v4 UUID using Node's crypto.randomUUID (CSPRNG-backed). */\nexport function generateId(): string {\n return randomUUID();\n}\n\n/** Validate that a string is a valid UUID */\nexport function isValidUuid(value: string): boolean {\n return UUID_RE.test(value);\n}\n\n/** Configuration for creating a DeepMemory instance */\nexport interface DeepMemoryConfig {\n /** Required: the storage provider for persistence */\n storage: StorageProvider;\n /** Optional: search provider for full-text search */\n search?: SearchProvider;\n /**\n * Optional: factory that produces an EmbeddingProvider configured for a specific\n * model + dimensionality. Called once per repository open/create using the repo's\n * stored embedding metadata, so different repositories can use different models\n * and embedding dimensions without any per-mutation lookups.\n */\n embeddingFactory?: EmbeddingProviderFactory;\n /** Default embedding model for new repositories that don't specify one in metadata */\n defaultEmbeddingModel?: string;\n /** Default embedding dimensions for new repositories that don't specify one in metadata */\n defaultEmbeddingDimensions?: number;\n /** Optional: lock provider for distributed locking */\n lock?: LockProvider;\n /** Optional: graph traversal provider for native multi-hop queries */\n graphTraversal?: GraphTraversalProvider;\n /** Required: provenance context identifying the actor */\n provenance: ProvenanceContext;\n}\n\nexport class DeepMemory {\n private readonly storage: StorageProvider;\n private readonly search?: SearchProvider;\n private readonly embeddingFactory?: EmbeddingProviderFactory;\n private readonly defaultEmbeddingModel?: string;\n private readonly defaultEmbeddingDimensions?: number;\n /** Reserved for future distributed locking support */\n readonly lock?: LockProvider;\n private readonly graphTraversalProvider?: GraphTraversalProvider;\n private readonly provenance: ProvenanceTracker;\n private readonly globalEventBus: EventBus;\n private initialized = false;\n\n constructor(config: DeepMemoryConfig) {\n this.storage = config.storage;\n this.search = config.search;\n this.embeddingFactory = config.embeddingFactory;\n this.defaultEmbeddingModel = config.defaultEmbeddingModel;\n this.defaultEmbeddingDimensions = config.defaultEmbeddingDimensions;\n this.lock = config.lock;\n this.graphTraversalProvider = config.graphTraversal;\n this.provenance = new ProvenanceTracker(config.provenance);\n this.globalEventBus = new EventBus(config.provenance);\n }\n\n /**\n * Build an embedding provider for a repository given its stored model + dimensions.\n * Returns undefined when no factory is configured or when model/dimensions are missing.\n */\n private buildEmbeddingForRepository(\n model: string | undefined,\n dimensions: number | undefined,\n ): EmbeddingProvider | undefined {\n if (!this.embeddingFactory || !model || dimensions === undefined) return undefined;\n return this.embeddingFactory({ model, dimensions });\n }\n\n /** Initialize the storage provider and optional providers (call once before use) */\n private async ensureInitialized(): Promise<void> {\n if (!this.initialized) {\n if (this.storage.initialize) {\n await this.storage.initialize();\n }\n if (this.graphTraversalProvider?.initialize) {\n await this.graphTraversalProvider.initialize();\n }\n this.initialized = true;\n }\n }\n\n /** Create or migrate the storage schema. Call once at deployment / startup, not per-request. */\n async ensureSchema(): Promise<EnsureSchemaResult> {\n const noOpResult: EnsureSchemaResult = {\n databaseCreated: false,\n schemaCreated: false,\n alreadyUpToDate: true,\n schemaVersion: 0,\n };\n\n // Try to initialize normally first. If the storage provider's ensureSchema\n // can create the database itself, we allow init to fail and retry after.\n try {\n await this.ensureInitialized();\n } catch {\n // initialize may fail if the database doesn't exist yet — ensureSchema\n // on the storage provider can create it, so we continue.\n }\n\n let result: EnsureSchemaResult = noOpResult;\n if (this.storage.ensureSchema) {\n result = await this.storage.ensureSchema();\n }\n\n // If initialize failed earlier (e.g. DB didn't exist), retry now that\n // ensureSchema may have created it.\n if (!this.initialized) {\n await this.ensureInitialized();\n }\n\n return result;\n }\n\n private validateRepositoryId(repositoryId: string): void {\n if (!isValidUuid(repositoryId)) {\n throw new InvalidInputError(\n 'repositoryId',\n `Repository ID \"${repositoryId}\" is not a valid UUID`,\n `Provide a valid UUID (e.g. \"550e8400-e29b-41d4-a716-446655440000\") or omit repositoryId to auto-generate one.`,\n );\n }\n }\n\n /** Create a new memory repository */\n async createRepository(config: RepositoryConfig): Promise<MemoryRepository> {\n await this.ensureInitialized();\n\n const repositoryId = config.repositoryId ?? generateId();\n this.validateRepositoryId(repositoryId);\n const context = this.provenance.getContext();\n const now = new Date().toISOString();\n\n const governanceConfig = config.governance ?? { mode: 'open' as const };\n\n // Build metadata: explicit config values take precedence, then fall back to server defaults.\n // Embedding model + dimensions live on the repository itself so each repo can use a\n // different configuration without per-mutation lookups.\n const metadata = { ...config.metadata };\n if (!metadata.embeddingModelId && this.defaultEmbeddingModel) {\n metadata.embeddingModelId = this.defaultEmbeddingModel;\n }\n if (metadata.embeddingDimensions === undefined && this.defaultEmbeddingDimensions !== undefined) {\n metadata.embeddingDimensions = this.defaultEmbeddingDimensions;\n }\n\n // Create the repository in storage\n await this.storage.createRepository({\n repositoryId,\n type: config.type,\n label: config.label,\n description: config.description,\n legal: config.legal,\n owner: config.owner,\n governanceConfig,\n metadata: Object.keys(metadata).length > 0 ? metadata : undefined,\n createdAt: now,\n createdBy: context.actorId,\n });\n\n // Build and save initial vocabulary\n const vocabulary = config.vocabulary\n ? buildVocabulary(config.vocabulary, context.actorId)\n : createEmptyVocabulary(context.actorId);\n\n await this.storage.saveVocabulary(repositoryId, vocabulary);\n\n // Build per-repository embedding provider from the repo's stored model + dimensions\n const embedding = this.buildEmbeddingForRepository(\n metadata.embeddingModelId,\n metadata.embeddingDimensions,\n );\n\n // Create internal components\n const eventBus = new EventBus(context, repositoryId);\n const vocabularyEngine = new VocabularyEngine({\n repositoryId,\n storageProvider: this.storage,\n governanceConfig,\n embeddingProvider: embedding,\n });\n\n const repo = new MemoryRepository({\n repositoryId,\n storage: this.storage,\n search: this.search,\n embedding,\n embeddingFactory: this.embeddingFactory,\n graphTraversal: this.graphTraversalProvider,\n vocabularyEngine,\n provenanceTracker: this.provenance,\n eventBus,\n });\n\n // Emit repository created event\n await this.globalEventBus.emit('repository:created', {\n repositoryId,\n label: config.label,\n });\n\n return repo;\n }\n\n /** Open an existing repository */\n async openRepository(repositoryId: string): Promise<MemoryRepository> {\n await this.ensureInitialized();\n this.validateRepositoryId(repositoryId);\n\n const storedRepo = await this.storage.getRepository(repositoryId);\n if (!storedRepo) {\n throw new RepositoryNotFoundError(repositoryId);\n }\n\n const context = this.provenance.getContext();\n const eventBus = new EventBus(context, repositoryId);\n\n // Build the per-repository embedding provider from stored metadata.\n // Falls back to server defaults only if the repo has no embedding metadata\n // recorded yet (e.g. created before this field existed).\n const embedding = this.buildEmbeddingForRepository(\n storedRepo.metadata?.embeddingModelId ?? this.defaultEmbeddingModel,\n storedRepo.metadata?.embeddingDimensions ?? this.defaultEmbeddingDimensions,\n );\n\n const vocabularyEngine = new VocabularyEngine({\n repositoryId,\n storageProvider: this.storage,\n governanceConfig: storedRepo.governanceConfig,\n embeddingProvider: embedding,\n });\n\n const repo = new MemoryRepository({\n repositoryId,\n storage: this.storage,\n search: this.search,\n embedding,\n embeddingFactory: this.embeddingFactory,\n graphTraversal: this.graphTraversalProvider,\n vocabularyEngine,\n provenanceTracker: this.provenance,\n eventBus,\n });\n\n await this.globalEventBus.emit('repository:opened', { repositoryId });\n\n return repo;\n }\n\n /** Get the full stored record for a single repository (including legal, owner, metadata, governance) */\n async getRepository(repositoryId: string): Promise<StoredRepository> {\n await this.ensureInitialized();\n this.validateRepositoryId(repositoryId);\n\n const storedRepo = await this.storage.getRepository(repositoryId);\n if (!storedRepo) {\n throw new RepositoryNotFoundError(repositoryId);\n }\n return storedRepo;\n }\n\n /** List all repositories */\n async listRepositories(\n filter?: RepositoryFilter,\n ): Promise<PaginatedResult<RepositorySummary>> {\n await this.ensureInitialized();\n\n const result = await this.storage.listRepositories(filter);\n\n return {\n items: result.items.map((stored) => ({\n repositoryId: stored.repositoryId,\n type: stored.type,\n label: stored.label,\n description: stored.description,\n governanceMode: stored.governanceConfig.mode,\n })),\n total: result.total,\n hasMore: result.hasMore,\n limit: result.limit,\n offset: result.offset,\n };\n }\n\n /** Update repository metadata and settings */\n async updateRepository(repositoryId: string, updates: RepositoryUpdate): Promise<StoredRepository> {\n await this.ensureInitialized();\n this.validateRepositoryId(repositoryId);\n const updated = await this.storage.updateRepository(repositoryId, updates);\n await this.globalEventBus.emit('repository:updated', { repositoryId });\n return updated;\n }\n\n /** Delete a repository */\n async deleteRepository(repositoryId: string): Promise<void> {\n await this.ensureInitialized();\n this.validateRepositoryId(repositoryId);\n\n const stats = await this.storage.getRepositoryStats(repositoryId);\n await this.globalEventBus.emit('delete:started', {\n repositoryId,\n totalEntities: stats.entityCount,\n totalRelationships: stats.relationshipCount,\n });\n\n await this.storage.deleteRepository(repositoryId, (progress) =>\n this.globalEventBus.emit('delete:progress', { repositoryId, ...progress }),\n );\n\n await this.globalEventBus.emit('delete:completed', {\n repositoryId,\n entitiesDeleted: stats.entityCount,\n relationshipsDeleted: stats.relationshipCount,\n });\n await this.globalEventBus.emit('repository:deleted', { repositoryId });\n }\n\n /** Delete all entities and relationships in a repository, preserving the repository and vocabulary */\n async deleteAllContents(repositoryId: string): Promise<{ deletedEntities: number; deletedRelationships: number }> {\n await this.ensureInitialized();\n this.validateRepositoryId(repositoryId);\n\n const stats = await this.storage.getRepositoryStats(repositoryId);\n await this.globalEventBus.emit('delete:started', {\n repositoryId,\n totalEntities: stats.entityCount,\n totalRelationships: stats.relationshipCount,\n });\n\n const result = await this.storage.deleteAllContents(repositoryId, (progress) =>\n this.globalEventBus.emit('delete:progress', { repositoryId, ...progress }),\n );\n\n await this.globalEventBus.emit('delete:completed', {\n repositoryId,\n entitiesDeleted: result.deletedEntities,\n relationshipsDeleted: result.deletedRelationships,\n });\n\n return result;\n }\n\n /** Export a repository to a portable archive */\n async exportRepository(repositoryId: string, options?: ExportOptions): Promise<ExportArchive> {\n await this.ensureInitialized();\n\n const stats = await this.storage.getRepositoryStats(repositoryId);\n await this.globalEventBus.emit('export:started', {\n repositoryId,\n totalEntities: stats.entityCount,\n totalRelationships: stats.relationshipCount,\n });\n\n const exporter = new RepositoryExporter({\n storage: this.storage,\n provenance: this.provenance.getContext(),\n legal: options?.legal,\n });\n\n const archive = await exporter.export(repositoryId);\n\n await this.globalEventBus.emit('export:completed', {\n repositoryId,\n entityCount: archive.entities.length,\n relationshipCount: archive.relationships.length,\n });\n\n return archive;\n }\n\n /** Import a repository from a portable archive */\n async importRepository(\n archive: ExportArchive,\n options: ImportOptions,\n ): Promise<ImportResult> {\n await this.ensureInitialized();\n\n await this.globalEventBus.emit('import:started', { repositoryId: options.target.repositoryId });\n\n const importer = new RepositoryImporter({\n storage: this.storage,\n actorId: this.provenance.getContext().actorId,\n onProgress: (progress) => this.globalEventBus.emit('import:progress', progress),\n });\n\n const result = await importer.import(archive, options);\n\n if (result.success) {\n await this.globalEventBus.emit('import:completed', {\n repositoryId: result.repositoryId,\n entitiesImported: result.statistics.entitiesImported,\n relationshipsImported: result.statistics.relationshipsImported,\n });\n } else {\n await this.globalEventBus.emit('import:failed', {\n repositoryId: result.repositoryId,\n error: result.warnings.map((w) => w.message).join('; '),\n });\n }\n\n return result;\n }\n\n /**\n * Stream a repository export as an async generator.\n * Yields: manifest → vocabulary → entity chunks → relationship chunks.\n * Use for large repositories to avoid loading everything into memory.\n */\n async *exportRepositoryStream(repositoryId: string, options?: ExportOptions): AsyncGenerator<ExportStreamItem> {\n await this.ensureInitialized();\n\n const exporter = new RepositoryExporter({\n storage: this.storage,\n provenance: this.provenance.getContext(),\n legal: options?.legal,\n });\n\n // Get stats up front so progress events have totals\n const stats = await this.storage.getRepositoryStats(repositoryId);\n const totalEntities = stats.entityCount;\n const totalRelationships = stats.relationshipCount;\n const estimatedChunkSize = 100;\n const totalChunks = Math.max(\n 1,\n Math.ceil(totalEntities / estimatedChunkSize) + Math.ceil(totalRelationships / estimatedChunkSize),\n );\n\n await this.globalEventBus.emit('export:started', { repositoryId, totalEntities, totalRelationships });\n\n let entityCount = 0;\n let relationshipCount = 0;\n let chunksCompleted = 0;\n\n for await (const item of exporter.exportStream(repositoryId)) {\n yield item;\n\n if (item.type === 'entities') {\n entityCount += item.data.length;\n chunksCompleted++;\n await this.globalEventBus.emit('export:progress', {\n repositoryId,\n entitiesExported: entityCount,\n relationshipsExported: relationshipCount,\n totalEntities,\n totalRelationships,\n chunksCompleted,\n totalChunks,\n });\n } else if (item.type === 'relationships') {\n relationshipCount += item.data.length;\n chunksCompleted++;\n await this.globalEventBus.emit('export:progress', {\n repositoryId,\n entitiesExported: entityCount,\n relationshipsExported: relationshipCount,\n totalEntities,\n totalRelationships,\n chunksCompleted,\n totalChunks,\n });\n }\n }\n\n await this.globalEventBus.emit('export:completed', {\n repositoryId,\n entityCount,\n relationshipCount,\n });\n }\n\n /**\n * Import a repository from a stream of chunks.\n * Use for large repositories to avoid loading everything into memory.\n */\n async importRepositoryStream(\n header: ImportStreamHeader,\n chunks: AsyncIterable<ImportChunk>,\n options: ImportOptions,\n ): Promise<ImportResult> {\n await this.ensureInitialized();\n\n const importer = new RepositoryImporter({\n storage: this.storage,\n actorId: this.provenance.getContext().actorId,\n onProgress: (progress) => this.globalEventBus.emit('import:progress', progress),\n });\n\n await this.globalEventBus.emit('import:started', { repositoryId: options.target.repositoryId });\n\n const result = await importer.importStream(header, chunks, options);\n\n if (result.success) {\n await this.globalEventBus.emit('import:completed', {\n repositoryId: result.repositoryId,\n entitiesImported: result.statistics.entitiesImported,\n relationshipsImported: result.statistics.relationshipsImported,\n });\n } else {\n await this.globalEventBus.emit('import:failed', {\n repositoryId: result.repositoryId,\n error: result.warnings.map((w) => w.message).join('; '),\n });\n }\n\n return result;\n }\n\n /** Subscribe to global events */\n on<E extends DeepMemoryEventType>(event: E, handler: EventHandler<E>): Unsubscribe {\n return this.globalEventBus.on(event, handler);\n }\n\n /** Update the provenance context (e.g., new conversation) */\n updateProvenance(context: Partial<ProvenanceContext>): void {\n this.provenance.updateContext(context);\n this.globalEventBus.updateProvenance(this.provenance.getContext());\n }\n\n /** Dispose of all resources */\n async dispose(): Promise<void> {\n this.globalEventBus.removeAllListeners();\n if (this.graphTraversalProvider?.dispose) {\n await this.graphTraversalProvider.dispose();\n }\n if (this.storage.dispose) {\n await this.storage.dispose();\n }\n this.initialized = false;\n }\n}\n","// IdGenerator — GUID and slug generation for entities and relationships\n\nimport { generateId } from '../core/DeepMemory.js';\n\n/**\n * Slugify a string for use in entity slugs.\n * Lowercases, replaces non-alphanumeric with hyphens, collapses/trims hyphens.\n */\nfunction slugify(text: string): string {\n return text\n .toLowerCase()\n .trim()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '');\n}\n\n/**\n * Generate a deterministic slug from type and label.\n * Format: `{type}:{slugified-label}`\n *\n * @param entityType - The entity type (e.g., \"person\")\n * @param label - The entity label (e.g., \"Tim Wheeler\")\n * @returns Slug (e.g., \"person:tim-wheeler\")\n */\nexport function generateSlug(entityType: string, label: string): string {\n const slug = slugify(label);\n return `${entityType}:${slug || 'unnamed'}`;\n}\n\n/**\n * Generate a unique slug, appending a suffix if the base slug already exists.\n *\n * @param entityType - The entity type\n * @param label - The entity label\n * @param existsCheck - Async function to check if a slug is already taken\n * @returns A unique slug\n */\nexport async function generateUniqueSlug(\n entityType: string,\n label: string,\n existsCheck: (slug: string) => Promise<boolean>,\n): Promise<string> {\n const baseSlug = generateSlug(entityType, label);\n\n if (!(await existsCheck(baseSlug))) {\n return baseSlug;\n }\n\n // Append incrementing suffix until unique\n for (let i = 2; i <= 100; i++) {\n const candidateSlug = `${baseSlug}-${i}`;\n if (!(await existsCheck(candidateSlug))) {\n return candidateSlug;\n }\n }\n\n // Fallback: append random suffix\n const randomSuffix = Math.random().toString(36).slice(2, 8);\n return `${baseSlug}-${randomSuffix}`;\n}\n\n/**\n * Generate a GUID for an entity.\n */\nexport function generateEntityId(): string {\n return generateId();\n}\n\n/**\n * Generate a GUID for a relationship.\n */\nexport function generateRelationshipId(): string {\n return generateId();\n}\n","// String similarity — Jaro-Winkler distance (zero dependencies)\n// Used by SemanticDeduplicator as fallback when no EmbeddingProvider is available\n\n/**\n * Compute Jaro similarity between two strings.\n * Returns a value between 0 (no similarity) and 1 (identical).\n */\nexport function jaroSimilarity(a: string, b: string): number {\n if (a === b) return 1;\n if (a.length === 0 || b.length === 0) return 0;\n\n const matchWindow = Math.max(Math.floor(Math.max(a.length, b.length) / 2) - 1, 0);\n\n const aMatches = new Array<boolean>(a.length).fill(false);\n const bMatches = new Array<boolean>(b.length).fill(false);\n\n let matches = 0;\n let transpositions = 0;\n\n // Find matches\n for (let i = 0; i < a.length; i++) {\n const start = Math.max(0, i - matchWindow);\n const end = Math.min(i + matchWindow + 1, b.length);\n\n for (let j = start; j < end; j++) {\n if (bMatches[j] || a[i] !== b[j]) continue;\n aMatches[i] = true;\n bMatches[j] = true;\n matches++;\n break;\n }\n }\n\n if (matches === 0) return 0;\n\n // Count transpositions\n let k = 0;\n for (let i = 0; i < a.length; i++) {\n if (!aMatches[i]) continue;\n while (!bMatches[k]) k++;\n if (a[i] !== b[k]) transpositions++;\n k++;\n }\n\n return (\n (matches / a.length + matches / b.length + (matches - transpositions / 2) / matches) / 3\n );\n}\n\n/**\n * Compute Jaro-Winkler similarity between two strings.\n * Gives extra weight to common prefixes (up to 4 characters).\n * Returns a value between 0 (no similarity) and 1 (identical).\n *\n * @param scalingFactor - Prefix scaling factor (default 0.1, max 0.25)\n */\nexport function jaroWinklerSimilarity(a: string, b: string, scalingFactor = 0.1): number {\n const jaro = jaroSimilarity(a, b);\n if (jaro === 0) return 0;\n\n // Common prefix length (max 4)\n const prefixLength = Math.min(4, Math.min(a.length, b.length));\n let commonPrefix = 0;\n for (let i = 0; i < prefixLength; i++) {\n if (a[i] === b[i]) {\n commonPrefix++;\n } else {\n break;\n }\n }\n\n return jaro + commonPrefix * Math.min(scalingFactor, 0.25) * (1 - jaro);\n}\n\n/**\n * Normalize a type name for comparison.\n * Lowercases, replaces separators with underscores, trims.\n */\nexport function normalizeTypeName(name: string): string {\n return name\n .toLowerCase()\n .trim()\n .replace(/[-\\s.]+/g, '_')\n .replace(/[^a-z0-9_]/g, '');\n}\n\n/**\n * Convert a relationship type name to SCREAMING_SNAKE_CASE.\n * Handles camelCase, PascalCase, kebab-case, dot.case, space-separated, and existing snake_case.\n *\n * Examples:\n * \"worksOn\" → \"WORKS_ON\"\n * \"works-on\" → \"WORKS_ON\"\n * \"works_on\" → \"WORKS_ON\"\n * \"WORKS_ON\" → \"WORKS_ON\" (idempotent)\n * \"Works On\" → \"WORKS_ON\"\n * \"componentOf\" → \"COMPONENT_OF\"\n */\nexport function toScreamingSnakeCase(name: string): string {\n return name\n .trim()\n // Insert underscore before uppercase letters that follow lowercase letters or digits (camelCase boundaries)\n .replace(/([a-z0-9])([A-Z])/g, '$1_$2')\n // Insert underscore between consecutive uppercase followed by lowercase (e.g., \"HTMLParser\" → \"HTML_Parser\")\n .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')\n // Replace hyphens, spaces, dots with underscores\n .replace(/[-\\s.]+/g, '_')\n // Remove any non-alphanumeric/underscore characters\n .replace(/[^A-Za-z0-9_]/g, '')\n // Collapse multiple underscores\n .replace(/_+/g, '_')\n // Remove leading/trailing underscores\n .replace(/^_+|_+$/g, '')\n .toUpperCase();\n}\n","// VocabularyValidator — validates entities and relationships against vocabulary definitions\n\nimport type { CreateEntityInput, UpdateEntityInput } from '../types/entities.js';\nimport type { CreateRelationshipInput } from '../types/relationships.js';\nimport type {\n EntityTypeDefinition,\n MemoryVocabulary,\n PropertySchema,\n RelationshipTypeDefinition,\n} from '../types/vocabulary.js';\nimport { toScreamingSnakeCase } from './similarity.js';\n\n/** A single validation error with optional suggestion */\nexport interface ValidationError {\n field: string;\n message: string;\n suggestion?: string;\n}\n\n/** Result of a validation check */\nexport interface ValidationResult {\n valid: boolean;\n errors: ValidationError[];\n}\n\nfunction ok(): ValidationResult {\n return { valid: true, errors: [] };\n}\n\nfunction fail(...errors: ValidationError[]): ValidationResult {\n return { valid: false, errors };\n}\n\nfunction merge(...results: ValidationResult[]): ValidationResult {\n const errors = results.flatMap((r) => r.errors);\n return { valid: errors.length === 0, errors };\n}\n\n/** Find the closest matching type name for suggestions */\nfunction findClosestType(typeName: string, types: Array<{ type: string }>): string | undefined {\n if (types.length === 0) return undefined;\n // Simple prefix/substring match for suggestions\n const lower = typeName.toLowerCase();\n const match = types.find(\n (t) => t.type.toLowerCase().includes(lower) || lower.includes(t.type.toLowerCase()),\n );\n return match?.type;\n}\n\n/** Validate a PropertySchema definition — catches invalid embeddable declarations */\nexport function validatePropertySchema(schema: PropertySchema): ValidationResult {\n if (schema.embeddable === true && schema.type !== 'string') {\n return fail({\n field: `properties.${schema.name}`,\n message: `Property \"${schema.name}\" cannot be embeddable — only string properties support embedding (type is \"${schema.type}\")`,\n });\n }\n return ok();\n}\n\n/** Validate a property value against its schema */\nexport function validatePropertyValue(\n name: string,\n value: unknown,\n schema: PropertySchema,\n): ValidationResult {\n if (value === undefined || value === null) {\n if (schema.required) {\n return fail({\n field: `properties.${name}`,\n message: `Required property \"${name}\" is missing`,\n });\n }\n return ok();\n }\n\n switch (schema.type) {\n case 'string':\n if (typeof value !== 'string') {\n return fail({\n field: `properties.${name}`,\n message: `Property \"${name}\" must be a string, got ${typeof value}`,\n });\n }\n break;\n\n case 'number':\n if (typeof value !== 'number' || Number.isNaN(value)) {\n return fail({\n field: `properties.${name}`,\n message: `Property \"${name}\" must be a number, got ${typeof value}`,\n });\n }\n break;\n\n case 'boolean':\n if (typeof value !== 'boolean') {\n return fail({\n field: `properties.${name}`,\n message: `Property \"${name}\" must be a boolean, got ${typeof value}`,\n });\n }\n break;\n\n case 'date':\n if (typeof value !== 'string' || Number.isNaN(Date.parse(value))) {\n return fail({\n field: `properties.${name}`,\n message: `Property \"${name}\" must be a valid ISO date string`,\n });\n }\n break;\n\n case 'enum':\n if (typeof value !== 'string') {\n return fail({\n field: `properties.${name}`,\n message: `Property \"${name}\" must be a string (enum value), got ${typeof value}`,\n });\n }\n if (schema.enumValues && !schema.enumValues.includes(value)) {\n return fail({\n field: `properties.${name}`,\n message: `Property \"${name}\" must be one of: ${schema.enumValues.join(', ')}`,\n suggestion: `Valid values: ${schema.enumValues.join(', ')}`,\n });\n }\n break;\n }\n\n return ok();\n}\n\n/** Validate properties against the type's property schemas */\nfunction validateProperties(\n properties: Record<string, unknown> | undefined,\n schemas: PropertySchema[],\n): ValidationResult {\n const results: ValidationResult[] = [];\n const providedProperties = properties ?? {};\n\n for (const schema of schemas) {\n const value = providedProperties[schema.name];\n results.push(validatePropertyValue(schema.name, value, schema));\n }\n\n // Only reject unknown properties when the vocab explicitly defines at least one\n // property for the type. A type with no properties defined is open to anything.\n if (schemas.length > 0) {\n const knownNames = new Set(schemas.map((s) => s.name));\n for (const key of Object.keys(providedProperties)) {\n if (!knownNames.has(key)) {\n results.push(fail({\n field: `properties.${key}`,\n message: `Unknown property \"${key}\"`,\n suggestion: `Known properties: ${schemas.map((s) => s.name).join(', ')}`,\n }));\n }\n }\n }\n\n return merge(...results);\n}\n\n/** Validate a CreateEntityInput against the vocabulary */\nexport function validateEntity(\n input: CreateEntityInput,\n vocabulary: MemoryVocabulary,\n): ValidationResult {\n const entityTypeDef = vocabulary.entityTypes.find((et) => et.type === input.entityType);\n\n if (!entityTypeDef) {\n const closest = findClosestType(input.entityType, vocabulary.entityTypes);\n return fail({\n field: 'entityType',\n message: `Entity type \"${input.entityType}\" does not exist in the vocabulary`,\n suggestion: closest\n ? `Did you mean \"${closest}\"?`\n : `Available types: ${vocabulary.entityTypes.map((et) => et.type).join(', ') || 'none'}`,\n });\n }\n\n if (!input.label || input.label.trim().length === 0) {\n return fail({\n field: 'label',\n message: 'Entity label is required and cannot be empty',\n });\n }\n\n return validateProperties(input.properties, entityTypeDef.properties);\n}\n\n/**\n * Validate an UpdateEntityInput against the vocabulary.\n *\n * When `input.entityType` is set and differs from `currentEntityTypeDef.type`,\n * the target type must exist in the vocabulary, and any provided properties\n * are validated against the new type's schema (not the current type's).\n */\nexport function validateEntityUpdate(\n input: UpdateEntityInput,\n currentEntityTypeDef: EntityTypeDefinition,\n vocabulary: MemoryVocabulary,\n): ValidationResult {\n if (input.label !== undefined && input.label.trim().length === 0) {\n return fail({\n field: 'label',\n message: 'Entity label cannot be empty',\n });\n }\n\n // Resolve the target type definition — either the new type (if changing) or the current one.\n let targetTypeDef: EntityTypeDefinition = currentEntityTypeDef;\n if (input.entityType !== undefined && input.entityType !== currentEntityTypeDef.type) {\n const newTypeDef = vocabulary.entityTypes.find((et) => et.type === input.entityType);\n if (!newTypeDef) {\n const closest = findClosestType(input.entityType, vocabulary.entityTypes);\n return fail({\n field: 'entityType',\n message: `Entity type \"${input.entityType}\" does not exist in the vocabulary`,\n suggestion: closest\n ? `Did you mean \"${closest}\"?`\n : `Available types: ${vocabulary.entityTypes.map((et) => et.type).join(', ') || 'none'}`,\n });\n }\n targetTypeDef = newTypeDef;\n }\n\n // Only validate provided properties — updates are partial.\n // Validated against the target type (new if changing, else current).\n if (input.properties) {\n const results: ValidationResult[] = [];\n const hasDefinedProps = targetTypeDef.properties.length > 0;\n for (const [key, value] of Object.entries(input.properties)) {\n // RFC 7396 JSON Merge Patch: null signals deletion of the key, so skip\n // schema validation for it — an unknown or ill-typed property being\n // removed should never block the update.\n if (value === null) continue;\n const schema = targetTypeDef.properties.find((p) => p.name === key);\n if (!schema) {\n if (hasDefinedProps) {\n results.push(fail({\n field: `properties.${key}`,\n message: `Unknown property \"${key}\"`,\n suggestion: `Known properties: ${targetTypeDef.properties.map((p) => p.name).join(', ')}`,\n }));\n }\n } else {\n results.push(validatePropertyValue(key, value, schema));\n }\n }\n return merge(...results);\n }\n\n return ok();\n}\n\n/** Validate a CreateRelationshipInput against the vocabulary */\nexport function validateRelationship(\n input: CreateRelationshipInput,\n vocabulary: MemoryVocabulary,\n sourceEntityType: string,\n targetEntityType: string,\n): ValidationResult {\n const normalizedType = toScreamingSnakeCase(input.relationshipType);\n const relTypeDef = vocabulary.relationshipTypes.find(\n (rt) => rt.type === normalizedType,\n );\n\n if (!relTypeDef) {\n const closest = findClosestType(input.relationshipType, vocabulary.relationshipTypes);\n return fail({\n field: 'relationshipType',\n message: `Relationship type \"${input.relationshipType}\" does not exist in the vocabulary`,\n suggestion: closest\n ? `Did you mean \"${closest}\"?`\n : `Available types: ${vocabulary.relationshipTypes.map((rt) => rt.type).join(', ') || 'none'}`,\n });\n }\n\n const results: ValidationResult[] = [];\n\n // Validate source entity type constraint\n if (\n relTypeDef.allowedSourceTypes.length > 0 &&\n !relTypeDef.allowedSourceTypes.includes(sourceEntityType)\n ) {\n results.push(\n fail({\n field: 'sourceEntityId',\n message: `Entity type \"${sourceEntityType}\" is not allowed as source for relationship type \"${input.relationshipType}\"`,\n suggestion: `Allowed source types: ${relTypeDef.allowedSourceTypes.join(', ')}`,\n }),\n );\n }\n\n // Validate target entity type constraint\n if (\n relTypeDef.allowedTargetTypes.length > 0 &&\n !relTypeDef.allowedTargetTypes.includes(targetEntityType)\n ) {\n results.push(\n fail({\n field: 'targetEntityId',\n message: `Entity type \"${targetEntityType}\" is not allowed as target for relationship type \"${input.relationshipType}\"`,\n suggestion: `Allowed target types: ${relTypeDef.allowedTargetTypes.join(', ')}`,\n }),\n );\n }\n\n // Validate relationship properties\n if (relTypeDef.properties) {\n results.push(\n validateProperties(input.properties, relTypeDef.properties),\n );\n }\n\n return merge(...results);\n}\n\n/** Get an entity type definition from the vocabulary, or null if not found */\nexport function getEntityTypeDef(\n entityType: string,\n vocabulary: MemoryVocabulary,\n): EntityTypeDefinition | null {\n return vocabulary.entityTypes.find((et) => et.type === entityType) ?? null;\n}\n\n/** Get a relationship type definition from the vocabulary, or null if not found */\nexport function getRelationshipTypeDef(\n relationshipType: string,\n vocabulary: MemoryVocabulary,\n): RelationshipTypeDefinition | null {\n const normalized = toScreamingSnakeCase(relationshipType);\n return vocabulary.relationshipTypes.find((rt) => rt.type === normalized) ?? null;\n}\n","// EntityManager — CRUD orchestration for entities with validation, provenance, and events\n\nimport type { StorageProvider } from '../providers/StorageProvider.js';\nimport type { EmbeddingProvider } from '../providers/EmbeddingProvider.js';\nimport type {\n CreateEntityInput,\n DetailLevel,\n Entity,\n EntityBrief,\n EntitySummary,\n StoredEntity,\n UpdateEntityInput,\n} from '../types/entities.js';\nimport type { PaginatedResult, ReembedResult } from '../types/results.js';\nimport type { FindEntitiesQuery, StorageFindQuery } from '../types/queries.js';\nimport type { DeleteEntitiesResult } from '../types/entities.js';\nimport type { VocabularyEngine } from '../core/VocabularyEngine.js';\nimport type { ProvenanceTracker } from '../core/ProvenanceTracker.js';\nimport type { EventBus } from '../core/EventBus.js';\nimport { generateEntityId, generateUniqueSlug } from './IdGenerator.js';\nimport {\n EntityNotFoundError,\n VocabularyValidationError,\n OperationCancelledError,\n EmbeddingProviderRequiredError,\n} from '../core/errors.js';\nimport { getEntityTypeDef } from '../vocabulary/VocabularyValidator.js';\n\nexport class EntityManager {\n private embedding?: EmbeddingProvider;\n\n constructor(\n private readonly repositoryId: string,\n private readonly vocabularyEngine: VocabularyEngine,\n private readonly provenanceTracker: ProvenanceTracker,\n private readonly eventBus: EventBus,\n private readonly storage: StorageProvider,\n embedding?: EmbeddingProvider,\n ) {\n this.embedding = embedding;\n }\n\n /** Swap the embedding provider, e.g. after a repository re-embed changes the model or dimensionality */\n setEmbeddingProvider(embedding: EmbeddingProvider | undefined): void {\n this.embedding = embedding;\n }\n\n /** Create one or more entities with vocabulary validation, ID generation, provenance, and events */\n async create(inputs: CreateEntityInput[]): Promise<Entity[]> {\n const results: Entity[] = [];\n\n for (const input of inputs) {\n // Validate against vocabulary\n const validation = await this.vocabularyEngine.validateEntity(input);\n if (!validation.valid) {\n const errorMsg = validation.errors.map((e) => e.message).join('; ');\n const suggestions = validation.errors\n .filter((e) => e.suggestion)\n .map((e) => e.suggestion!);\n\n await this.eventBus.emit('validation:failed', {\n operation: 'createEntity',\n error: errorMsg,\n suggestions,\n });\n\n throw new VocabularyValidationError(validation.errors);\n }\n\n // Pre-mutation hook\n const hookResult = await this.eventBus.emitHook('entity:creating', { input });\n if (hookResult.cancelled) {\n throw new OperationCancelledError('Entity creation', hookResult.reason ?? 'cancelled by hook');\n }\n\n // Generate GUID (or use provided)\n const id = input.id ?? generateEntityId();\n\n // Generate unique slug\n const slug = await generateUniqueSlug(\n input.entityType,\n input.label,\n async (candidateSlug) => {\n const existing = await this.storage.getEntityBySlug(this.repositoryId, candidateSlug);\n return existing !== null;\n },\n );\n\n // Stamp provenance\n const provenance = this.provenanceTracker.stampCreate();\n\n // Generate embedding if provider available\n const entityEmbedding = await this.generateEmbedding(input.label, input.summary, input.properties ?? {}, input.entityType);\n\n // Build stored entity\n const storedEntity: StoredEntity = {\n id,\n slug,\n entityType: input.entityType,\n label: input.label,\n summary: input.summary,\n properties: input.properties ?? {},\n data: input.data,\n dataFormat: input.dataFormat,\n provenance,\n embedding: entityEmbedding,\n };\n\n // Persist\n const created = await this.storage.createEntity(this.repositoryId, storedEntity);\n\n // Map to public type\n const entity = storedToEntity(created);\n\n // Emit created event\n await this.eventBus.emit('entity:created', { entity });\n\n results.push(entity);\n }\n\n return results;\n }\n\n /** Update an existing entity */\n async update(entityId: string, updates: UpdateEntityInput): Promise<Entity> {\n // Get existing entity to determine its type for validation\n const existing = await this.storage.getEntity(this.repositoryId, entityId);\n if (!existing) {\n throw new EntityNotFoundError(entityId);\n }\n\n // Validate updates against vocabulary\n const validation = await this.vocabularyEngine.validateEntityUpdate(\n updates,\n existing.entityType,\n );\n if (!validation.valid) {\n await this.eventBus.emit('validation:failed', {\n operation: 'updateEntity',\n error: validation.errors.map((e) => e.message).join('; '),\n suggestions: validation.errors.filter((e) => e.suggestion).map((e) => e.suggestion!),\n });\n throw new VocabularyValidationError(validation.errors);\n }\n\n // Pre-mutation hook\n const hookResult = await this.eventBus.emitHook('entity:updating', {\n id: entityId,\n updates,\n });\n if (hookResult.cancelled) {\n throw new OperationCancelledError('Entity update', hookResult.reason ?? 'cancelled by hook');\n }\n\n // Stamp provenance\n const provenance = this.provenanceTracker.stampUpdate(existing.provenance);\n\n // Merge properties. RFC 7396 semantics: incoming `null` values delete the\n // corresponding key rather than storing `null`.\n let mergedProperties = existing.properties;\n if (updates.properties) {\n const merged: Record<string, unknown> = { ...existing.properties };\n for (const [key, value] of Object.entries(updates.properties)) {\n if (value === null) {\n delete merged[key];\n } else {\n merged[key] = value;\n }\n }\n mergedProperties = merged;\n }\n\n // Regenerate slug when entityType or label changes — both are part of the slug.\n const typeChanged = updates.entityType !== undefined && updates.entityType !== existing.entityType;\n const labelChanged = updates.label !== undefined && updates.label !== existing.label;\n let newSlug: string | undefined;\n if (typeChanged || labelChanged) {\n const nextType = updates.entityType ?? existing.entityType;\n const nextLabel = updates.label ?? existing.label;\n newSlug = await generateUniqueSlug(\n nextType,\n nextLabel,\n async (candidateSlug) => {\n if (candidateSlug === existing.slug) return false; // the entity's own slug isn't a conflict\n const other = await this.storage.getEntityBySlug(this.repositoryId, candidateSlug);\n return other !== null;\n },\n );\n }\n\n // Regenerate embedding if label/summary changed or reembed explicitly requested.\n // `summary === null` means \"clear\", so the embedding is computed from label alone.\n // Reembed when label, summary, or any property changes (properties may include embeddable ones).\n const needsReembed = updates.reembed === true || updates.label !== undefined || updates.summary !== undefined || updates.properties !== undefined;\n const nextSummary = updates.summary === undefined ? existing.summary : (updates.summary ?? undefined);\n const nextEntityType = updates.entityType ?? existing.entityType;\n const entityEmbedding = needsReembed\n ? await this.generateEmbedding(updates.label ?? existing.label, nextSummary, mergedProperties, nextEntityType)\n : undefined; // undefined preserves the existing embedding in storage\n\n // Persist\n const updated = await this.storage.updateEntity(this.repositoryId, entityId, {\n entityType: typeChanged ? updates.entityType : undefined,\n label: updates.label,\n slug: newSlug,\n summary: updates.summary,\n properties: updates.properties ? mergedProperties : undefined,\n data: updates.data,\n dataFormat: updates.dataFormat,\n provenance,\n embedding: entityEmbedding,\n });\n\n const entity = storedToEntity(updated);\n await this.eventBus.emit('entity:updated', { entity });\n\n return entity;\n }\n\n /** Get a single entity with configurable detail level */\n async get(entityId: string, detailLevel: DetailLevel = 'full'): Promise<Entity | EntitySummary | EntityBrief | null> {\n const stored = await this.storage.getEntity(this.repositoryId, entityId);\n if (!stored) return null;\n\n switch (detailLevel) {\n case 'brief':\n return storedToBrief(stored);\n case 'summary':\n return storedToSummary(stored);\n case 'full':\n default:\n return storedToEntity(stored);\n }\n }\n\n /** Get an entity by its slug */\n async getBySlug(slug: string, detailLevel: DetailLevel = 'full'): Promise<Entity | EntitySummary | EntityBrief | null> {\n const stored = await this.storage.getEntityBySlug(this.repositoryId, slug);\n if (!stored) return null;\n\n switch (detailLevel) {\n case 'brief':\n return storedToBrief(stored);\n case 'summary':\n return storedToSummary(stored);\n case 'full':\n default:\n return storedToEntity(stored);\n }\n }\n\n /** Get multiple entities in a single call (max 50, brief or summary only) */\n async getMany(\n entityIds: string[],\n detailLevel: 'brief' | 'summary' = 'summary',\n ): Promise<Map<string, EntitySummary | EntityBrief>> {\n const ids = entityIds.slice(0, 50);\n const storedMap = await this.storage.getEntities(this.repositoryId, ids);\n const result = new Map<string, EntitySummary | EntityBrief>();\n\n for (const [id, stored] of storedMap) {\n result.set(\n id,\n detailLevel === 'brief' ? storedToBrief(stored) : storedToSummary(stored),\n );\n }\n\n return result;\n }\n\n /** Find entities by search criteria */\n async find(query: FindEntitiesQuery): Promise<PaginatedResult<EntitySummary>> {\n const storageQuery: StorageFindQuery = {\n searchTerm: query.searchTerm,\n entityTypes: query.entityTypes,\n properties: query.properties,\n limit: Math.min(query.limit ?? 10, 50),\n offset: query.offset ?? 0,\n };\n\n const result = await this.storage.findEntities(this.repositoryId, storageQuery);\n\n return {\n items: result.items.map(storedToSummary),\n total: result.total,\n hasMore: result.hasMore,\n limit: result.limit,\n offset: result.offset,\n };\n }\n\n /** Delete an entity — throws EntityNotFoundError if it does not exist */\n async delete(entityId: string): Promise<void> {\n const existing = await this.storage.getEntity(this.repositoryId, entityId);\n if (!existing) {\n throw new EntityNotFoundError(entityId);\n }\n\n const hookResult = await this.eventBus.emitHook('entity:deleting', { ids: [entityId] });\n if (hookResult.cancelled) {\n throw new OperationCancelledError('Entity deletion', hookResult.reason ?? 'cancelled by hook');\n }\n\n await this.storage.deleteEntity(this.repositoryId, entityId);\n await this.eventBus.emit('entity:deleted', { ids: [entityId] });\n }\n\n /** Delete multiple entities in a single batch operation */\n async deleteMany(ids: string[]): Promise<DeleteEntitiesResult> {\n const hookResult = await this.eventBus.emitHook('entity:deleting', { ids });\n if (hookResult.cancelled) {\n throw new OperationCancelledError('Entity deletion', hookResult.reason ?? 'cancelled by hook');\n }\n\n const { deleted, notFound } = await this.storage.deleteEntities(this.repositoryId, ids);\n\n if (deleted.length > 0) {\n await this.eventBus.emit('entity:deleted', { ids: deleted });\n }\n\n return {\n deleted,\n failed: notFound.map((id) => ({ id, error: `Entity '${id}' not found` })),\n };\n }\n\n /**\n * Re-embed a specific set of entities using the current EmbeddingProvider.\n * Retries embedBatch up to maxRetries times with exponential backoff on failure.\n */\n async reembedEntities(entityIds: string[], options?: {\n maxRetries?: number;\n }): Promise<ReembedResult> {\n if (!this.embedding) {\n throw new EmbeddingProviderRequiredError();\n }\n\n const maxRetries = options?.maxRetries ?? 3;\n\n const storedMap = await this.storage.getEntities(this.repositoryId, entityIds);\n const entries = Array.from(storedMap.entries());\n\n const vocab = await this.vocabularyEngine.getVocabulary();\n const texts = entries.map(([, e]) => {\n const typeDef = getEntityTypeDef(e.entityType, vocab);\n const embeddableValues = typeDef\n ? typeDef.properties\n .filter((p) => p.embeddable === true && typeof e.properties[p.name] === 'string')\n .map((p) => e.properties[p.name] as string)\n : [];\n return [e.label, e.summary ?? '', ...embeddableValues].filter(Boolean).join(' ');\n });\n\n // Attempt embedBatch with retry and exponential backoff\n let embeddings: number[][];\n let attempt = 0;\n while (true) {\n try {\n embeddings = await this.embedding.embedBatch(texts);\n break;\n } catch (err) {\n attempt++;\n if (attempt > maxRetries) {\n // All retries exhausted — record every entity in this batch as failed\n const errorMsg = err instanceof Error ? err.message : String(err);\n return {\n processed: 0,\n failed: entries.length,\n errors: entries.map(([id]) => ({ entityId: id, error: `embedBatch failed after ${maxRetries} retries: ${errorMsg}` })),\n modelId: this.embedding.modelId(),\n dimensions: this.embedding.dimensions(),\n };\n }\n // Exponential backoff: 1s, 2s, 4s, ...\n const backoffMs = 1000 * (2 ** (attempt - 1));\n await new Promise<void>((resolve) => { setTimeout(resolve, backoffMs); });\n }\n }\n\n // Persist embeddings — individual storage failures are non-fatal\n const errors: Array<{ entityId: string; error: string }> = [];\n let processed = 0;\n\n for (let i = 0; i < entries.length; i++) {\n const [id, entity] = entries[i]!;\n try {\n await this.storage.updateEntity(this.repositoryId, id, {\n provenance: entity.provenance, // preserve existing provenance — not a content edit\n embedding: embeddings[i],\n });\n processed++;\n } catch (err) {\n errors.push({ entityId: id, error: err instanceof Error ? err.message : String(err) });\n }\n }\n\n return {\n processed,\n failed: errors.length,\n errors,\n modelId: this.embedding.modelId(),\n dimensions: this.embedding.dimensions(),\n };\n }\n\n /**\n * Re-embed all entities in the repository, processing in batches.\n * @param options.batchSize — entities per batch (default 50)\n * @param options.maxRetries — retries per batch on embedding failure (default 3)\n * @param options.errorThresholdToAbort — abort after this many cumulative failures (default: no limit)\n * @param options.delayBetweenBatchesMs — milliseconds to wait between batches for rate limiting (default 0)\n * @param options.onProgress — callback invoked after each batch\n */\n async reembedAll(options?: {\n batchSize?: number;\n maxRetries?: number;\n errorThresholdToAbort?: number;\n delayBetweenBatchesMs?: number;\n onProgress?: (processed: number, total: number, failed: number) => void;\n }): Promise<ReembedResult> {\n if (!this.embedding) {\n throw new EmbeddingProviderRequiredError();\n }\n\n const batchSize = options?.batchSize ?? 50;\n const errorThreshold = options?.errorThresholdToAbort;\n\n // Count total entities\n const firstPage = await this.storage.findEntities(this.repositoryId, { limit: 1, offset: 0 });\n const total = firstPage.total;\n\n let totalProcessed = 0;\n let totalFailed = 0;\n const allErrors: Array<{ entityId: string; error: string }> = [];\n let offset = 0;\n\n while (offset < total) {\n const page = await this.storage.findEntities(this.repositoryId, {\n limit: batchSize,\n offset,\n });\n\n if (page.items.length === 0) break;\n\n const ids = page.items.map((e) => e.id);\n const result = await this.reembedEntities(ids, {\n maxRetries: options?.maxRetries,\n });\n\n totalProcessed += result.processed;\n totalFailed += result.failed;\n allErrors.push(...result.errors);\n\n options?.onProgress?.(totalProcessed, total, totalFailed);\n\n // Check abort threshold\n if (errorThreshold !== undefined && totalFailed >= errorThreshold) {\n allErrors.push({ entityId: '', error: `Aborted: error threshold of ${errorThreshold} reached (${totalFailed} failures)` });\n break;\n }\n\n offset += page.items.length;\n\n // Rate limiting: pause between batches if configured\n const delayMs = options?.delayBetweenBatchesMs ?? 0;\n if (delayMs > 0 && offset < total) {\n await new Promise<void>((resolve) => { setTimeout(resolve, delayMs); });\n }\n }\n\n return {\n processed: totalProcessed,\n failed: totalFailed,\n errors: allErrors,\n modelId: this.embedding.modelId(),\n dimensions: this.embedding.dimensions(),\n };\n }\n\n /** Generate an embedding vector from label + summary + embeddable string properties if a provider is available */\n private async generateEmbedding(label: string, summary: string | undefined, properties: Record<string, unknown>, entityType: string): Promise<number[] | undefined> {\n if (!this.embedding) return undefined;\n const vocab = await this.vocabularyEngine.getVocabulary();\n const typeDef = getEntityTypeDef(entityType, vocab);\n const embeddableValues = typeDef\n ? typeDef.properties\n .filter((p) => p.embeddable === true && typeof properties[p.name] === 'string')\n .map((p) => properties[p.name] as string)\n : [];\n const text = [label, summary ?? '', ...embeddableValues].filter(Boolean).join(' ');\n return this.embedding.embed(text);\n }\n}\n\n// ─── Mapping helpers ────────────────────────────────────────────────\n\nfunction storedToEntity(stored: StoredEntity): Entity {\n return {\n id: stored.id,\n slug: stored.slug,\n entityType: stored.entityType,\n label: stored.label,\n summary: stored.summary,\n properties: stored.properties,\n data: stored.data,\n dataFormat: stored.dataFormat,\n provenance: stored.provenance,\n };\n}\n\nfunction storedToSummary(stored: StoredEntity): EntitySummary {\n return {\n id: stored.id,\n slug: stored.slug,\n entityType: stored.entityType,\n label: stored.label,\n summary: stored.summary,\n properties: stored.properties,\n };\n}\n\nfunction storedToBrief(stored: StoredEntity): EntityBrief {\n return {\n id: stored.id,\n slug: stored.slug,\n entityType: stored.entityType,\n label: stored.label,\n summary: stored.summary,\n };\n}\n","// RelationshipManager — CRUD orchestration for relationships with validation, provenance, and events\n\nimport type { StorageProvider } from '../providers/StorageProvider.js';\nimport type {\n CreateRelationshipInput,\n Relationship,\n RelationshipQueryOptions,\n RemoveRelationshipsResult,\n StoredRelationship,\n} from '../types/relationships.js';\nimport type { PaginatedResult } from '../types/results.js';\nimport type { VocabularyEngine } from '../core/VocabularyEngine.js';\nimport type { ProvenanceTracker } from '../core/ProvenanceTracker.js';\nimport type { EventBus } from '../core/EventBus.js';\nimport { generateRelationshipId } from '../entities/IdGenerator.js';\nimport { toScreamingSnakeCase } from '../vocabulary/similarity.js';\nimport {\n EntityNotFoundError,\n VocabularyValidationError,\n OperationCancelledError,\n SelfReferentialRelationshipError,\n} from '../core/errors.js';\n\nexport class RelationshipManager {\n constructor(\n private readonly repositoryId: string,\n private readonly vocabularyEngine: VocabularyEngine,\n private readonly provenanceTracker: ProvenanceTracker,\n private readonly eventBus: EventBus,\n private readonly storage: StorageProvider,\n ) {}\n\n /** Create one or more relationships with vocabulary validation, provenance, and events */\n async create(inputs: CreateRelationshipInput[]): Promise<Relationship[]> {\n const results: Relationship[] = [];\n\n for (const input of inputs) {\n if (input.sourceEntityId === input.targetEntityId) {\n throw new SelfReferentialRelationshipError(input.sourceEntityId, input.relationshipType);\n }\n\n // Resolve source and target entity types for constraint validation\n const sourceEntity = await this.storage.getEntity(this.repositoryId, input.sourceEntityId);\n if (!sourceEntity) {\n throw new EntityNotFoundError(input.sourceEntityId);\n }\n\n const targetEntity = await this.storage.getEntity(this.repositoryId, input.targetEntityId);\n if (!targetEntity) {\n throw new EntityNotFoundError(input.targetEntityId);\n }\n\n // Validate against vocabulary\n const validation = await this.vocabularyEngine.validateRelationship(\n input,\n sourceEntity.entityType,\n targetEntity.entityType,\n );\n if (!validation.valid) {\n await this.eventBus.emit('validation:failed', {\n operation: 'createRelationship',\n error: validation.errors.map((e) => e.message).join('; '),\n suggestions: validation.errors.filter((e) => e.suggestion).map((e) => e.suggestion!),\n });\n throw new VocabularyValidationError(validation.errors);\n }\n\n // Pre-mutation hook\n const hookResult = await this.eventBus.emitHook('relationship:creating', { input });\n if (hookResult.cancelled) {\n throw new OperationCancelledError(\n 'Relationship creation', hookResult.reason ?? 'cancelled by hook',\n );\n }\n\n // Normalize relationship type to SCREAMING_SNAKE_CASE\n const normalizedType = toScreamingSnakeCase(input.relationshipType);\n\n // Get relationship type definition for bidirectional flag\n const vocabulary = await this.vocabularyEngine.getVocabulary();\n const relType = vocabulary.relationshipTypes.find((rt) => rt.type === normalizedType);\n const bidirectional = relType?.bidirectional ?? false;\n\n // Generate GUID (or use provided)\n const id = input.id ?? generateRelationshipId();\n\n // Stamp provenance\n const provenance = this.provenanceTracker.stampCreate();\n\n // Build stored relationship\n const storedRelationship: StoredRelationship = {\n id,\n relationshipType: normalizedType,\n sourceEntityId: input.sourceEntityId,\n targetEntityId: input.targetEntityId,\n properties: input.properties ?? {},\n bidirectional,\n provenance,\n };\n\n // Persist\n const created = await this.storage.createRelationship(this.repositoryId, storedRelationship);\n\n // Map to public type\n const relationship = storedToRelationship(created);\n\n // Emit created event\n await this.eventBus.emit('relationship:created', { relationship });\n\n results.push(relationship);\n }\n\n return results;\n }\n\n /** Remove one or more relationships in a single batch storage operation */\n async removeMany(ids: string[]): Promise<RemoveRelationshipsResult> {\n const hookResult = await this.eventBus.emitHook('relationship:removing', { ids });\n if (hookResult.cancelled) {\n throw new OperationCancelledError('Relationship removal', hookResult.reason ?? 'cancelled by hook');\n }\n\n const { deleted, notFound } = await this.storage.deleteRelationships(this.repositoryId, ids);\n\n if (deleted.length > 0) {\n await this.eventBus.emit('relationship:removed', { ids: deleted });\n }\n\n return {\n removed: deleted,\n failed: notFound.map((id) => ({ id, error: `Relationship '${id}' not found` })),\n };\n }\n\n /** Get relationships for an entity with filtering */\n async getForEntity(\n entityId: string,\n options?: RelationshipQueryOptions,\n ): Promise<PaginatedResult<Relationship>> {\n const result = await this.storage.getEntityRelationships(\n this.repositoryId,\n entityId,\n options,\n );\n\n return {\n items: result.items.map(storedToRelationship),\n total: result.total,\n hasMore: result.hasMore,\n limit: result.limit,\n offset: result.offset,\n };\n }\n}\n\n// ─── Mapping helpers ────────────────────────────────────────────────\n\nfunction storedToRelationship(stored: StoredRelationship): Relationship {\n return {\n id: stored.id,\n relationshipType: stored.relationshipType,\n sourceEntityId: stored.sourceEntityId,\n targetEntityId: stored.targetEntityId,\n properties: stored.properties,\n bidirectional: stored.bidirectional,\n provenance: stored.provenance,\n };\n}\n","// Entity projection — maps StoredEntity to the appropriate detail level\n\nimport type {\n DetailLevel,\n Entity,\n EntityBrief,\n EntitySummary,\n StoredEntity,\n} from '../types/entities.js';\n\n/** Project a stored entity to the requested detail level */\nexport function projectEntity(stored: StoredEntity, level: DetailLevel): Entity | EntitySummary | EntityBrief {\n switch (level) {\n case 'brief':\n return {\n id: stored.id,\n slug: stored.slug,\n entityType: stored.entityType,\n label: stored.label,\n summary: stored.summary,\n };\n case 'summary':\n return {\n id: stored.id,\n slug: stored.slug,\n entityType: stored.entityType,\n label: stored.label,\n summary: stored.summary,\n properties: stored.properties,\n };\n case 'full':\n return {\n id: stored.id,\n slug: stored.slug,\n entityType: stored.entityType,\n label: stored.label,\n summary: stored.summary,\n properties: stored.properties,\n data: stored.data,\n dataFormat: stored.dataFormat,\n provenance: stored.provenance,\n };\n }\n}\n\n/** Project an EntitySummary down to brief level */\nexport function projectSummaryToBrief(entity: EntitySummary): EntityBrief {\n return {\n id: entity.id,\n slug: entity.slug,\n entityType: entity.entityType,\n label: entity.label,\n summary: entity.summary,\n };\n}\n","// TraversalValidator — validates a TraversalSpec against structural\n// constraints and the repository vocabulary before execution.\n\nimport type { TraversalSpec } from '../types/traversal.js';\nimport type { MemoryVocabulary } from '../types/vocabulary.js';\nimport type { GraphTraversalCapabilities } from '../providers/GraphTraversalProvider.js';\n\nexport interface ValidationResult {\n valid: boolean;\n errors: string[];\n}\n\nconst DEFAULT_MAX_STEPS = 6;\nconst DEFAULT_MAX_LIMIT = 200;\nconst DEFAULT_FALLBACK_MAX_DEPTH = 10;\n\n/**\n * Validates a TraversalSpec against structural rules and vocabulary.\n * Returns all validation failures rather than stopping at the first.\n */\nexport function validateTraversalSpec(\n spec: TraversalSpec,\n vocabulary?: MemoryVocabulary,\n capabilities?: GraphTraversalCapabilities,\n): ValidationResult {\n const errors: string[] = [];\n const steps = spec.steps ?? [];\n\n // ─── Structural validation ────────────────────────────────────\n\n // Start must have at least one of entityId, entityType, or filter\n if (!spec.start) {\n errors.push('start is required');\n } else {\n const hasEntityId = spec.start.entityId !== undefined && spec.start.entityId !== '';\n const hasEntityType = spec.start.entityType !== undefined && spec.start.entityType !== '';\n const hasFilter = spec.start.filter !== undefined && spec.start.filter.length > 0;\n\n if (!hasEntityId && !hasEntityType && !hasFilter) {\n errors.push('start must have at least one of entityId, entityType, or filter');\n }\n\n // start.entityType without entityId requires limit on the spec\n if (hasEntityType && !hasEntityId && (spec.limit === undefined || spec.limit === 0)) {\n errors.push('start.entityType without entityId requires limit on the spec to prevent full type scans');\n }\n }\n\n // Steps are optional (zero steps = vertex query), but validate if present\n const maxSteps = capabilities?.maxTraversalDepth ?? DEFAULT_MAX_STEPS;\n if (steps.length > maxSteps) {\n errors.push(`steps length ${steps.length} exceeds maximum ${maxSteps}`);\n }\n\n // Validate individual steps\n for (let i = 0; i < steps.length; i++) {\n const step = steps[i]!;\n\n if (!step.direction || !['out', 'in', 'both'].includes(step.direction)) {\n errors.push(`steps[${i}].direction must be 'out', 'in', or 'both'`);\n }\n\n if (step.repeat) {\n if (step.repeat.maxDepth === undefined || step.repeat.maxDepth <= 0) {\n errors.push(`steps[${i}].repeat.maxDepth must be a positive number`);\n }\n }\n }\n\n // Total potential depth check (only when steps present)\n if (steps.length > 0) {\n const maxProviderDepth = capabilities?.maxTraversalDepth ?? DEFAULT_FALLBACK_MAX_DEPTH;\n let totalDepth = 0;\n for (const step of steps) {\n totalDepth += step.repeat ? step.repeat.maxDepth : 1;\n }\n if (totalDepth > maxProviderDepth) {\n errors.push(`total potential depth ${totalDepth} exceeds provider maximum ${maxProviderDepth}`);\n }\n }\n\n // Path mode requires at least one step\n if (spec.returnMode === 'path' && steps.length === 0) {\n errors.push(\"returnMode 'path' requires at least one step\");\n }\n\n // Return mode\n if (spec.returnMode && !['terminal', 'path', 'all'].includes(spec.returnMode)) {\n errors.push(`returnMode must be 'terminal', 'path', or 'all'`);\n }\n\n // Projection validation\n if (spec.projection) {\n if (!spec.projection.properties || spec.projection.properties.length === 0) {\n errors.push('projection.properties must contain at least one property name');\n }\n if (spec.projection.mode && !['count', 'values'].includes(spec.projection.mode)) {\n errors.push(\"projection.mode must be 'count' or 'values'\");\n }\n }\n\n // Limit bounds\n if (spec.limit !== undefined) {\n if (spec.limit < 1 || spec.limit > DEFAULT_MAX_LIMIT) {\n errors.push(`limit must be between 1 and ${DEFAULT_MAX_LIMIT}`);\n }\n }\n\n // Offset bounds\n if (spec.offset !== undefined && spec.offset < 0) {\n errors.push('offset must be >= 0');\n }\n\n // ─── Vocabulary validation ────────────────────────────────────\n\n if (vocabulary) {\n const entityTypeSet = new Set(vocabulary.entityTypes.map((et) => et.type));\n const relationshipTypeSet = new Set(vocabulary.relationshipTypes.map((rt) => rt.type));\n const unknownTypes: string[] = [];\n\n // Validate start.entityType\n if (spec.start?.entityType && !entityTypeSet.has(spec.start.entityType)) {\n unknownTypes.push(`entity type \"${spec.start.entityType}\"`);\n }\n\n // Validate types in each step\n for (let i = 0; i < steps.length; i++) {\n const step = steps[i]!;\n\n if (step.relationshipTypes) {\n for (const rt of step.relationshipTypes) {\n if (!relationshipTypeSet.has(rt)) {\n unknownTypes.push(`relationship type \"${rt}\" in steps[${i}]`);\n }\n }\n }\n\n if (step.entityTypes) {\n for (const et of step.entityTypes) {\n if (!entityTypeSet.has(et)) {\n unknownTypes.push(`entity type \"${et}\" in steps[${i}]`);\n }\n }\n }\n }\n\n if (unknownTypes.length > 0) {\n errors.push(`Unknown vocabulary types: ${unknownTypes.join(', ')}`);\n }\n }\n\n return {\n valid: errors.length === 0,\n errors,\n };\n}\n","// PropertyFilterMatcher — evaluates property filters against relationship properties\n\nimport type { PropertyFilter } from '../types/queries.js';\n\n/**\n * Evaluate whether a set of properties matches all given filters.\n * All filters are AND'd — every filter must match for the result to be true.\n */\nexport function matchesPropertyFilters(\n properties: Record<string, unknown>,\n filters: PropertyFilter[],\n): boolean {\n return filters.every((filter) => matchesSingleFilter(properties, filter));\n}\n\nfunction matchesSingleFilter(\n properties: Record<string, unknown>,\n filter: PropertyFilter,\n): boolean {\n const value = properties[filter.key];\n\n switch (filter.operator) {\n case 'isNull':\n return value === null || value === undefined;\n\n case 'isNotNull':\n return value !== null && value !== undefined;\n\n case 'eq':\n return value === filter.value;\n\n case 'neq':\n return value !== filter.value;\n\n case 'gt':\n return typeof value === 'number' && typeof filter.value === 'number'\n ? value > filter.value\n : typeof value === 'string' && typeof filter.value === 'string'\n ? value > filter.value\n : false;\n\n case 'lt':\n return typeof value === 'number' && typeof filter.value === 'number'\n ? value < filter.value\n : typeof value === 'string' && typeof filter.value === 'string'\n ? value < filter.value\n : false;\n\n case 'gte':\n return typeof value === 'number' && typeof filter.value === 'number'\n ? value >= filter.value\n : typeof value === 'string' && typeof filter.value === 'string'\n ? value >= filter.value\n : false;\n\n case 'lte':\n return typeof value === 'number' && typeof filter.value === 'number'\n ? value <= filter.value\n : typeof value === 'string' && typeof filter.value === 'string'\n ? value <= filter.value\n : false;\n\n case 'contains':\n return typeof value === 'string' && typeof filter.value === 'string'\n ? value.toLowerCase().includes(filter.value.toLowerCase())\n : false;\n\n default:\n return false;\n }\n}\n","// FallbackTraversalExecutor — executes a TraversalSpec over StorageProvider\n// using iterative relationship lookups with batched entity resolution.\n// Provides multi-hop traversal for implementers who don't have a graph database.\n\nimport type { StorageProvider } from '../providers/StorageProvider.js';\nimport type { TraversalSpec, TraversalStep, TraversalResult, TraversalRelationship, TraversalPath, TraversalAggregation, TraversalEntity } from '../types/traversal.js';\nimport type { RelationshipSummary } from '../types/relationships.js';\nimport type { StoredEntity, DetailLevel } from '../types/entities.js';\nimport type { StoredRelationship, RelationshipDirection } from '../types/relationships.js';\nimport { projectEntity } from '../entities/entityProjection.js';\nimport { matchesPropertyFilters } from './PropertyFilterMatcher.js';\nimport { EntityNotFoundError } from '../core/errors.js';\n\n/** Maximum storage round-trips before aborting to prevent runaway traversals. */\nconst MAX_STORAGE_CALLS = 500;\n\n/** Maximum entities to scan for vertex queries and aggregation. */\nconst MAX_ENTITY_SCAN = 10000;\n\n/**\n * Maximum number of relationship results to fetch per frontier entity.\n * Set high to avoid truncation — client-side filtering handles the rest.\n */\nconst REL_FETCH_LIMIT = 1000;\n\ninterface FrontierEntry {\n entity: StoredEntity;\n /** Path of entity IDs from start to this entity. */\n entityPath: string[];\n /** Path of relationships from start to this entity. */\n relationshipPath: StoredRelationship[];\n}\n\n/**\n * Execute a TraversalSpec using application-level BFS over StorageProvider.\n *\n * Optimized for SQL Server round-trips:\n * - Relationship lookups are per-entity (unavoidable without a batch interface)\n * - Entity resolution is batched via getEntities() — one call per step\n * instead of one call per relationship result\n */\nexport async function executeFallbackTraversal(\n repositoryId: string,\n storage: StorageProvider,\n spec: TraversalSpec,\n): Promise<TraversalResult> {\n const startTime = Date.now();\n let storageCalls = 0;\n\n const checkCallLimit = (): void => {\n if (storageCalls >= MAX_STORAGE_CALLS) {\n throw new Error(`Fallback traversal exceeded ${MAX_STORAGE_CALLS} storage calls. Consider using a GraphTraversalProvider for large traversals.`);\n }\n };\n\n // ─── 1. Resolve starting entities ─────────────────────────────\n\n // When select is present or no steps (vertex query), fetch all matching\n // entities so aggregation is computed over the full dataset.\n // When traversing with steps, use the spec limit as the fetch cap.\n const isVertexQuery = !spec.steps || spec.steps.length === 0;\n const needsFullScan = isVertexQuery || spec.projection !== undefined;\n const fetchLimit = needsFullScan ? MAX_ENTITY_SCAN : (spec.limit ?? 50);\n\n let frontier: FrontierEntry[] = [];\n\n if (spec.start.entityId) {\n const entity = await resolveEntity(repositoryId, storage, spec.start.entityId);\n storageCalls++;\n if (entity) {\n frontier.push({ entity, entityPath: [entity.id], relationshipPath: [] });\n } else {\n throw new EntityNotFoundError(spec.start.entityId);\n }\n } else if (spec.start.entityType) {\n const result = await storage.findEntities(repositoryId, {\n entityTypes: [spec.start.entityType],\n limit: fetchLimit,\n offset: 0,\n });\n storageCalls++;\n frontier = result.items.map((e) => ({\n entity: e,\n entityPath: [e.id],\n relationshipPath: [],\n }));\n } else if (spec.start.filter && spec.start.filter.length > 0) {\n const result = await storage.findEntities(repositoryId, {\n limit: fetchLimit,\n offset: 0,\n });\n storageCalls++;\n frontier = result.items\n .filter((e) => matchesPropertyFilters(e.properties, spec.start.filter!))\n .map((e) => ({\n entity: e,\n entityPath: [e.id],\n relationshipPath: [],\n }));\n }\n\n // Apply start filters to frontier (when combined with entityId or entityType)\n if (spec.start.filter && spec.start.filter.length > 0 && (spec.start.entityId || spec.start.entityType)) {\n frontier = frontier.filter((entry) =>\n matchesPropertyFilters(entry.entity.properties, spec.start.filter!),\n );\n }\n\n // ─── 2. Execute steps (if any) ─────────────────────────────────\n\n const steps = spec.steps ?? [];\n const allCollected: FrontierEntry[] = spec.returnMode === 'all' ? [...frontier] : [];\n\n for (const step of steps) {\n checkCallLimit();\n\n if (step.repeat) {\n const result = await executeRepeatStep(\n repositoryId, storage, frontier, step,\n () => { storageCalls++; checkCallLimit(); },\n );\n frontier = result.terminal;\n if (spec.returnMode === 'all') {\n allCollected.push(...result.intermediates);\n }\n } else {\n frontier = await executeSingleStep(\n repositoryId, storage, frontier, step,\n () => { storageCalls++; checkCallLimit(); },\n );\n if (spec.returnMode === 'all') {\n allCollected.push(...frontier);\n }\n }\n }\n\n // ─── 3. Assemble results ──────────────────────────────────────\n\n const detailLevel: DetailLevel = spec.detailLevel ?? 'summary';\n const dedup = spec.dedup !== false;\n const limit = spec.limit ?? 50;\n const offset = spec.offset ?? 0;\n\n let resultEntries: FrontierEntry[];\n if (spec.returnMode === 'all') {\n resultEntries = allCollected;\n } else {\n resultEntries = frontier;\n }\n\n // Dedup by entity ID\n if (dedup) {\n const seen = new Set<string>();\n resultEntries = resultEntries.filter((entry) => {\n if (seen.has(entry.entity.id)) return false;\n seen.add(entry.entity.id);\n return true;\n });\n }\n\n const total = resultEntries.length;\n const paged = resultEntries.slice(offset, offset + limit);\n\n // Build result\n // When projection is present, entities are suppressed by default (projection replaces full output).\n // Set projection.includeEntities to get both.\n const suppressEntities = spec.projection !== undefined && spec.projection.includeEntities !== true;\n\n let entities: TraversalEntity[];\n if (suppressEntities) {\n entities = [];\n } else {\n entities = paged.map((entry) => {\n const projected = projectEntity(entry.entity, detailLevel) as TraversalEntity;\n // Strip provenance unless explicitly requested (only present at detailLevel 'full')\n if (!spec.includeProvenance) {\n delete (projected as unknown as Record<string, unknown>)['provenance'];\n }\n return projected;\n });\n\n // Attach relationship summaries.\n // Fallback path: N parallel storage calls (one per result entity).\n // Native GraphTraversalProviders should handle this in a single query instead.\n if (spec.includeRelationshipSummary && entities.length > 0) {\n const summaryResults = await Promise.all(\n paged.map(async (entry) => {\n storageCalls++;\n const result = await storage.getEntityRelationships(repositoryId, entry.entity.id, {\n direction: 'both',\n limit: 10000,\n });\n const summary: RelationshipSummary = { outbound: {}, inbound: {} };\n for (const rel of result.items) {\n if (rel.sourceEntityId === entry.entity.id) {\n summary.outbound[rel.relationshipType] = (summary.outbound[rel.relationshipType] ?? 0) + 1;\n }\n if (rel.targetEntityId === entry.entity.id) {\n summary.inbound[rel.relationshipType] = (summary.inbound[rel.relationshipType] ?? 0) + 1;\n }\n }\n return summary;\n }),\n );\n\n entities = entities.map((e, i) => ({ ...e, relationshipSummary: summaryResults[i] }));\n }\n }\n\n // Build aggregations if projection is specified\n let aggregations: TraversalAggregation[] | undefined;\n if (spec.projection) {\n const propNames = spec.projection.properties;\n const mode = spec.projection.mode ?? 'values';\n const distinct = spec.projection.distinct ?? false;\n\n // Operate on ALL matching entities (pre-pagination) for aggregation\n const sourceEntries = dedup\n ? (() => {\n const seen = new Set<string>();\n return (spec.returnMode === 'all' ? allCollected : frontier).filter((e) => {\n if (seen.has(e.entity.id)) return false;\n seen.add(e.entity.id);\n return true;\n });\n })()\n : (spec.returnMode === 'all' ? allCollected : frontier);\n\n if (mode === 'count' || distinct) {\n // Group by distinct value combinations\n const groups = new Map<string, { values: Record<string, unknown>; count: number }>();\n for (const entry of sourceEntries) {\n const vals: Record<string, unknown> = {};\n for (const prop of propNames) {\n vals[prop] = entry.entity.properties[prop] ?? null;\n }\n const key = JSON.stringify(vals);\n const existing = groups.get(key);\n if (existing) {\n existing.count++;\n } else {\n groups.set(key, { values: vals, count: 1 });\n }\n }\n\n aggregations = Array.from(groups.values()).map((g) => ({\n values: g.values,\n ...(mode === 'count' ? { count: g.count } : {}),\n }));\n\n // Sort by count descending for count mode\n if (mode === 'count') {\n aggregations.sort((a, b) => (b.count ?? 0) - (a.count ?? 0));\n }\n } else {\n // Raw values mode — extract properties from each entity\n aggregations = sourceEntries.map((entry) => {\n const vals: Record<string, unknown> = {};\n for (const prop of propNames) {\n vals[prop] = entry.entity.properties[prop] ?? null;\n }\n return { values: vals };\n });\n }\n }\n\n let relationships: TraversalRelationship[] | undefined;\n let paths: TraversalPath[] | undefined;\n\n if (!suppressEntities && (spec.returnMode === 'path' || spec.returnMode === 'all')) {\n const relMap = new Map<string, TraversalRelationship>();\n for (const entry of paged) {\n for (const rel of entry.relationshipPath) {\n if (!relMap.has(rel.id)) {\n relMap.set(rel.id, {\n id: rel.id,\n type: rel.relationshipType,\n sourceEntityId: rel.sourceEntityId,\n targetEntityId: rel.targetEntityId,\n direction: 'outbound',\n properties: rel.properties,\n });\n }\n }\n }\n relationships = Array.from(relMap.values());\n }\n\n if (!suppressEntities && spec.returnMode === 'path') {\n paths = paged.map((entry) => ({\n length: entry.entityPath.length - 1,\n entities: [(() => {\n const e = projectEntity(entry.entity, detailLevel) as TraversalEntity;\n if (!spec.includeProvenance) delete (e as unknown as Record<string, unknown>)['provenance'];\n return e;\n })()],\n relationships: entry.relationshipPath.map((rel) => ({\n id: rel.id,\n type: rel.relationshipType,\n sourceEntityId: rel.sourceEntityId,\n targetEntityId: rel.targetEntityId,\n direction: 'outbound' as const,\n properties: rel.properties,\n })),\n }));\n }\n\n const executionTimeMs = Date.now() - startTime;\n\n return {\n entities,\n relationships,\n paths,\n aggregations,\n total,\n returned: paged.length,\n hasMore: offset + limit < total,\n queryMetadata: {\n executionTimeMs,\n appliedLimits: {\n maxResults: limit,\n },\n truncated: total > limit + offset,\n truncationReason: total > limit + offset ? 'result_limit' : undefined,\n },\n };\n}\n\n/**\n * Execute a single (non-repeat) traversal step across the frontier.\n *\n * Optimization: relationship queries are per-entity (required by StorageProvider\n * interface), but entity resolution is batched — one getEntities() call for\n * all target IDs discovered in this step, instead of one getEntity() per target.\n */\nasync function executeSingleStep(\n repositoryId: string,\n storage: StorageProvider,\n frontier: FrontierEntry[],\n step: TraversalStep,\n onStorageCall: () => void,\n): Promise<FrontierEntry[]> {\n // Phase 1: Collect all relationships from the frontier (N queries, 1 per frontier entity)\n const direction = mapDirection(step.direction);\n const pendingEdges: Array<{\n entry: FrontierEntry;\n rel: StoredRelationship;\n targetId: string;\n }> = [];\n\n for (const entry of frontier) {\n const rels = await storage.getEntityRelationships(repositoryId, entry.entity.id, {\n direction,\n relationshipTypes: step.relationshipTypes,\n limit: REL_FETCH_LIMIT,\n });\n onStorageCall();\n\n for (const rel of rels.items) {\n // Apply relationship property filters early (avoids unnecessary entity lookups)\n if (step.relationshipFilter && step.relationshipFilter.length > 0) {\n if (!matchesPropertyFilters(rel.properties, step.relationshipFilter)) {\n continue;\n }\n }\n\n const targetId = getTargetId(rel, entry.entity.id);\n pendingEdges.push({ entry, rel, targetId });\n }\n }\n\n if (pendingEdges.length === 0) return [];\n\n // Phase 2: Batch-resolve all target entities in one call\n const uniqueTargetIds = [...new Set(pendingEdges.map((e) => e.targetId))];\n const entityMap = await storage.getEntities(repositoryId, uniqueTargetIds);\n onStorageCall();\n\n // Phase 3: Assemble the next frontier with client-side filtering\n const nextFrontier: FrontierEntry[] = [];\n\n for (const { entry, rel, targetId } of pendingEdges) {\n const targetEntity = entityMap.get(targetId);\n if (!targetEntity) continue;\n\n // Apply entity type filter\n if (step.entityTypes && step.entityTypes.length > 0) {\n if (!step.entityTypes.includes(targetEntity.entityType)) continue;\n }\n\n // Apply entity property filters\n if (step.entityFilter && step.entityFilter.length > 0) {\n if (!matchesPropertyFilters(targetEntity.properties, step.entityFilter)) continue;\n }\n\n nextFrontier.push({\n entity: targetEntity,\n entityPath: [...entry.entityPath, targetEntity.id],\n relationshipPath: [...entry.relationshipPath, rel],\n });\n }\n\n return nextFrontier;\n}\n\n/** Execute a repeat/loop step, iterating up to maxDepth times. */\nasync function executeRepeatStep(\n repositoryId: string,\n storage: StorageProvider,\n frontier: FrontierEntry[],\n step: TraversalStep,\n onStorageCall: () => void,\n): Promise<{ terminal: FrontierEntry[]; intermediates: FrontierEntry[] }> {\n const maxDepth = step.repeat?.maxDepth ?? 1;\n const emitIntermediates = step.repeat?.emitIntermediates !== false;\n const untilFilters = step.repeat?.until;\n\n let current = frontier;\n const allIntermediates: FrontierEntry[] = [];\n const visited = new Set<string>();\n\n for (const entry of frontier) {\n visited.add(entry.entity.id);\n }\n\n for (let depth = 0; depth < maxDepth; depth++) {\n const next = await executeSingleStep(repositoryId, storage, current, step, onStorageCall);\n\n // Filter out already-visited to prevent cycles\n const unvisited = next.filter((entry) => {\n if (visited.has(entry.entity.id)) return false;\n visited.add(entry.entity.id);\n return true;\n });\n\n if (unvisited.length === 0) break;\n\n if (untilFilters && untilFilters.length > 0) {\n const matching: FrontierEntry[] = [];\n const continuing: FrontierEntry[] = [];\n\n for (const entry of unvisited) {\n if (matchesPropertyFilters(entry.entity.properties, untilFilters)) {\n matching.push(entry);\n } else {\n continuing.push(entry);\n }\n }\n\n if (emitIntermediates) {\n allIntermediates.push(...continuing);\n }\n allIntermediates.push(...matching);\n\n if (matching.length > 0 && continuing.length === 0) {\n current = matching;\n break;\n }\n current = continuing;\n } else {\n if (emitIntermediates) {\n allIntermediates.push(...unvisited);\n }\n current = unvisited;\n }\n }\n\n return {\n terminal: current,\n intermediates: allIntermediates,\n };\n}\n\n/** Resolve an entity by ID or slug. */\nasync function resolveEntity(\n repositoryId: string,\n storage: StorageProvider,\n idOrSlug: string,\n): Promise<StoredEntity | null> {\n const byId = await storage.getEntity(repositoryId, idOrSlug);\n if (byId) return byId;\n return storage.getEntityBySlug(repositoryId, idOrSlug);\n}\n\n/** Map traversal direction to storage direction. */\nfunction mapDirection(direction: 'out' | 'in' | 'both'): RelationshipDirection {\n switch (direction) {\n case 'out': return 'outbound';\n case 'in': return 'inbound';\n case 'both': return 'both';\n }\n}\n\n/** Get the target entity ID from a relationship relative to the current entity. */\nfunction getTargetId(rel: StoredRelationship, currentEntityId: string): string {\n if (rel.sourceEntityId === currentEntityId) {\n return rel.targetEntityId;\n }\n return rel.sourceEntityId;\n}\n","// GraphTraversal — BFS neighborhood exploration, path finding, and\n// structured multi-hop traversal.\n// Sits between MemoryRepository and StorageProvider, mapping storage-level\n// results to the public Neighborhood, PathResult, and TraversalResult types.\n\nimport type { StorageProvider } from '../providers/StorageProvider.js';\nimport type { GraphTraversalProvider } from '../providers/GraphTraversalProvider.js';\nimport type {\n ExploreOptions,\n PathOptions,\n} from '../types/queries.js';\nimport type { DetailLevel } from '../types/entities.js';\nimport type { VocabularyEngine } from '../core/VocabularyEngine.js';\nimport type {\n Neighborhood,\n NeighborhoodLayer,\n PathResult,\n} from '../types/results.js';\nimport type { TraversalSpec, TraversalResult } from '../types/traversal.js';\nimport { projectEntity } from '../entities/entityProjection.js';\nimport { EntityNotFoundError, GraphTraversalProviderRequiredError, TraversalValidationError, TraversalVocabularyError } from '../core/errors.js';\nimport { validateTraversalSpec } from './TraversalValidator.js';\nimport { executeFallbackTraversal } from './FallbackTraversalExecutor.js';\n\nexport class GraphTraversal {\n constructor(\n private readonly repositoryId: string,\n private readonly storage: StorageProvider,\n private readonly graphTraversalProvider?: GraphTraversalProvider,\n private readonly vocabularyEngine?: VocabularyEngine,\n ) {}\n\n /** BFS neighborhood exploration from a center entity */\n async exploreNeighborhood(\n entityId: string,\n options?: ExploreOptions,\n ): Promise<Neighborhood> {\n const storageOptions = {\n depth: options?.depth ?? 1,\n relationshipTypes: options?.relationshipTypes,\n entityTypes: options?.entityTypes,\n direction: options?.direction ?? 'both' as const,\n limitPerType: options?.limitPerType ?? 10,\n offsetPerType: options?.offsetPerType ?? 0,\n relationshipPropertyFilters: options?.relationshipPropertyFilters,\n };\n\n const storageResult = await this.storage.exploreNeighborhood(\n this.repositoryId,\n entityId,\n storageOptions,\n );\n\n // Get the center entity for the public response\n const centerEntity = await this.storage.getEntity(this.repositoryId, entityId);\n if (!centerEntity) {\n throw new EntityNotFoundError(entityId);\n }\n\n // Map storage layers to public layers with statistics\n const detailLevel: DetailLevel = options?.detailLevel ?? 'summary';\n let totalEntities = 0;\n let returnedEntities = 0;\n const truncatedTypes: string[] = [];\n\n const layers: NeighborhoodLayer[] = storageResult.layers.map((storageLayer) => {\n const layer: NeighborhoodLayer = {};\n\n for (const [relType, group] of Object.entries(storageLayer)) {\n totalEntities += group.total;\n returnedEntities += group.entities.length;\n\n if (group.entities.length < group.total && !truncatedTypes.includes(relType)) {\n truncatedTypes.push(relType);\n }\n\n layer[relType] = {\n total: group.total,\n returned: group.entities.length,\n entities: group.entities.map((e) => projectEntity(e, detailLevel)),\n };\n }\n\n return layer;\n });\n\n return {\n center: {\n id: centerEntity.id,\n slug: centerEntity.slug,\n entityType: centerEntity.entityType,\n label: centerEntity.label,\n },\n layers,\n statistics: {\n totalEntities,\n returnedEntities,\n truncatedTypes,\n },\n };\n }\n\n /** BFS shortest path finding between two entities */\n async findPaths(\n sourceId: string,\n targetId: string,\n options?: PathOptions,\n ): Promise<PathResult> {\n const storageOptions = {\n maxDepth: options?.maxDepth ?? 3,\n relationshipTypes: options?.relationshipTypes,\n entityTypes: options?.entityTypes,\n limit: options?.limit ?? 5,\n offset: options?.offset ?? 0,\n relationshipPropertyFilters: options?.relationshipPropertyFilters,\n };\n\n const storageResult = await this.storage.findPaths(\n this.repositoryId,\n sourceId,\n targetId,\n storageOptions,\n );\n\n // Collect all entity and relationship IDs for batch lookup\n const entityIdSet = new Set<string>();\n const relIdSet = new Set<string>();\n for (const path of storageResult.paths) {\n for (const eid of path.entityIds) entityIdSet.add(eid);\n for (const rid of path.relationshipIds) relIdSet.add(rid);\n }\n\n // Batch fetch entities\n const entityMap = await this.storage.getEntities(\n this.repositoryId,\n Array.from(entityIdSet),\n );\n\n // Fetch relationships individually\n const relMap = new Map<string, { id: string; type: string; sourceEntityId: string; properties: Record<string, unknown> }>();\n for (const rid of relIdSet) {\n const rel = await this.storage.getRelationship(this.repositoryId, rid);\n if (rel) {\n relMap.set(rid, {\n id: rel.id,\n type: rel.relationshipType,\n sourceEntityId: rel.sourceEntityId,\n properties: rel.properties,\n });\n }\n }\n\n // Filter paths by entity types if specified\n const entityTypeFilter = options?.entityTypes;\n const filteredPaths = entityTypeFilter\n ? storageResult.paths.filter((sp) =>\n sp.entityIds.every((eid) => {\n const e = entityMap.get(eid);\n return e ? entityTypeFilter.includes(e.entityType) : true;\n }),\n )\n : storageResult.paths;\n\n const pathDetailLevel: DetailLevel = options?.detailLevel ?? 'brief';\n\n return {\n totalPaths: entityTypeFilter ? filteredPaths.length : storageResult.totalPaths,\n returned: filteredPaths.length,\n paths: filteredPaths.map((sp) => ({\n length: sp.entityIds.length - 1,\n entities: sp.entityIds.map((eid) => {\n const e = entityMap.get(eid);\n if (e) return projectEntity(e, pathDetailLevel);\n return {\n id: eid,\n slug: eid,\n entityType: 'unknown',\n label: eid,\n summary: undefined,\n };\n }),\n relationships: sp.relationshipIds.map((rid, idx) => {\n const r = relMap.get(rid);\n const currentEntityId = sp.entityIds[idx];\n return {\n id: rid,\n type: r?.type ?? 'unknown',\n direction: r?.sourceEntityId === currentEntityId ? 'outbound' : 'inbound',\n properties: r?.properties ?? {},\n };\n }),\n })),\n };\n }\n\n /**\n * Execute a structured traversal.\n * Validates the spec, delegates to the GraphTraversalProvider if one is\n * registered (the provider owns native compilation), or falls back to\n * application-level BFS over StorageProvider.\n */\n async traverse(spec: TraversalSpec): Promise<TraversalResult> {\n // 1. Validate spec against structural rules and vocabulary\n const capabilities = this.graphTraversalProvider?.getCapabilities();\n const vocabulary = this.vocabularyEngine\n ? await this.vocabularyEngine.getVocabulary()\n : undefined;\n const validation = validateTraversalSpec(spec, vocabulary, capabilities);\n\n if (!validation.valid) {\n // Separate vocabulary errors from structural errors\n const vocabErrors = validation.errors.filter((e) => e.startsWith('Unknown vocabulary types:'));\n const structErrors = validation.errors.filter((e) => !e.startsWith('Unknown vocabulary types:'));\n\n if (vocabErrors.length > 0) {\n const unknownTypes = vocabErrors.join('; ')\n .replace(/Unknown vocabulary types: /g, '')\n .split(', ')\n .map((t) => t.trim());\n throw new TraversalVocabularyError(unknownTypes);\n }\n\n throw new TraversalValidationError(structErrors.length > 0 ? structErrors : validation.errors);\n }\n\n // 2. If GraphTraversalProvider registered, delegate — the provider owns\n // compilation to its native dialect.\n if (this.graphTraversalProvider) {\n return this.graphTraversalProvider.traverse(this.repositoryId, spec);\n }\n\n // 3. Fallback: execute over StorageProvider\n return executeFallbackTraversal(this.repositoryId, this.storage, spec);\n }\n\n /**\n * Execute a native graph query.\n * Pass-through to GraphTraversalProvider.executeNativeQuery().\n * Throws GraphTraversalProviderRequiredError if no provider registered.\n */\n async executeNativeQuery(\n query: string,\n params?: Record<string, unknown>,\n ): Promise<TraversalResult> {\n if (!this.graphTraversalProvider) {\n throw new GraphTraversalProviderRequiredError();\n }\n return this.graphTraversalProvider.executeNativeQuery(this.repositoryId, query, params);\n }\n}\n","// SearchOrchestrator — coordinates StorageProvider, SearchProvider, and EmbeddingProvider\n// for entity finding and semantic concept search.\n\nimport type { StorageProvider } from '../providers/StorageProvider.js';\nimport type { SearchProvider } from '../providers/SearchProvider.js';\nimport type { EmbeddingProvider } from '../providers/EmbeddingProvider.js';\nimport type { EventBus } from '../core/EventBus.js';\nimport type { VocabularyEngine } from '../core/VocabularyEngine.js';\nimport { getEntityTypeDef } from '../vocabulary/VocabularyValidator.js';\nimport type { DetailLevel, StoredEntity } from '../types/entities.js';\nimport type {\n FindEntitiesQuery,\n ConceptSearchOptions,\n StorageFindQuery,\n} from '../types/queries.js';\nimport type {\n PaginatedResult,\n ScoredEntity,\n SearchHit,\n} from '../types/results.js';\nimport type { Entity, EntityBrief, EntitySummary } from '../types/entities.js';\nimport { projectEntity } from '../entities/entityProjection.js';\nimport { EmbeddingProviderRequiredError } from '../core/errors.js';\n\nexport interface SearchOrchestratorConfig {\n repositoryId: string;\n storage: StorageProvider;\n search?: SearchProvider;\n embedding?: EmbeddingProvider;\n eventBus?: EventBus;\n vocabularyEngine?: VocabularyEngine;\n /** Default similarity threshold for semantic search (0.0-1.0, default 0.5) */\n defaultSimilarityThreshold?: number;\n /** Maximum entities to scan for concept search (default 1000). Higher values improve recall at the cost of latency. */\n conceptSearchScanLimit?: number;\n}\n\nexport class SearchOrchestrator {\n private readonly repositoryId: string;\n private readonly storage: StorageProvider;\n private readonly search?: SearchProvider;\n private embedding?: EmbeddingProvider;\n private readonly eventBus?: EventBus;\n private readonly vocabularyEngine?: VocabularyEngine;\n private readonly defaultSimilarityThreshold: number;\n private readonly conceptSearchScanLimit: number;\n\n constructor(config: SearchOrchestratorConfig) {\n this.repositoryId = config.repositoryId;\n this.storage = config.storage;\n this.search = config.search;\n this.embedding = config.embedding;\n this.eventBus = config.eventBus;\n this.vocabularyEngine = config.vocabularyEngine;\n this.defaultSimilarityThreshold = config.defaultSimilarityThreshold ?? 0.5;\n this.conceptSearchScanLimit = config.conceptSearchScanLimit ?? 1000;\n }\n\n /** Swap the embedding provider, e.g. after a repository re-embed changes the model or dimensionality */\n setEmbeddingProvider(embedding: EmbeddingProvider | undefined): void {\n this.embedding = embedding;\n }\n\n /**\n * Find entities by label, type, and property filters.\n * When a SearchProvider is available, its results are merged with\n * storage-level results for better relevance ranking.\n */\n async findEntities(query: FindEntitiesQuery): Promise<PaginatedResult<Entity | EntitySummary | EntityBrief>> {\n const limit = Math.min(query.limit ?? 10, 50);\n const offset = query.offset ?? 0;\n const detailLevel: DetailLevel = query.detailLevel ?? 'summary';\n\n const storageQuery: StorageFindQuery = {\n searchTerm: query.searchTerm,\n entityTypes: query.entityTypes,\n properties: query.properties,\n provenance: query.provenance,\n limit,\n offset,\n };\n\n // If we have a SearchProvider and a search term, merge results\n if (this.search && query.searchTerm) {\n const [storageResult, searchResult] = await Promise.all([\n this.storage.findEntities(this.repositoryId, storageQuery),\n this.search.search(this.repositoryId, query.searchTerm, {\n entityTypes: query.entityTypes,\n limit: limit * 2, // fetch more from search to merge\n offset: 0,\n }),\n ]);\n\n // Merge: use search result ordering but supplement with storage results\n const merged = this.mergeResults(storageResult.items, searchResult.items, limit, offset, detailLevel);\n\n await this.emitSearchEvent(query.searchTerm, merged.items.length);\n\n return merged;\n }\n\n // No SearchProvider or no search term — delegate to storage only\n const result = await this.storage.findEntities(this.repositoryId, storageQuery);\n\n if (query.searchTerm) {\n await this.emitSearchEvent(query.searchTerm, result.items.length);\n }\n\n return {\n items: result.items.map((e) => projectEntity(e, detailLevel)),\n total: result.total,\n hasMore: result.hasMore,\n limit: result.limit,\n offset: result.offset,\n };\n }\n\n /**\n * Semantic concept search using the EmbeddingProvider.\n * Embeds the query, then compares against entity embeddings.\n * Falls back to label/summary text matching when no embeddings exist on entities.\n */\n async searchByConcept(\n query: string,\n options?: ConceptSearchOptions,\n ): Promise<PaginatedResult<ScoredEntity>> {\n if (!this.embedding) {\n throw new EmbeddingProviderRequiredError();\n }\n\n const limit = Math.min(options?.limit ?? 10, 50);\n const offset = options?.offset ?? 0;\n const threshold = options?.similarityThreshold ?? this.defaultSimilarityThreshold;\n\n // Embed the query\n const queryEmbedding = await this.embedding.embed(query);\n\n // Get all entities (paginated scan — for production, a vector index would be used)\n const allEntities = await this.storage.findEntities(this.repositoryId, {\n entityTypes: options?.entityTypes,\n limit: this.conceptSearchScanLimit,\n offset: 0,\n });\n\n // Score each entity against the query embedding\n const scored: ScoredEntity[] = [];\n\n for (const entity of allEntities.items) {\n let score: number;\n\n if (entity.embedding && entity.embedding.length > 0) {\n // Use stored embedding\n score = this.cosineSimilarity(queryEmbedding, entity.embedding);\n } else {\n // Generate embedding on the fly for comparison — include embeddable properties\n const entityText = await this.buildEmbeddingText(entity.entityType, entity.label, entity.summary, entity.properties);\n const entityEmbedding = await this.embedding.embed(entityText);\n score = this.cosineSimilarity(queryEmbedding, entityEmbedding);\n }\n\n if (score >= threshold) {\n scored.push({\n id: entity.id,\n slug: entity.slug,\n entityType: entity.entityType,\n label: entity.label,\n summary: entity.summary,\n score,\n });\n }\n }\n\n // Sort by score descending\n scored.sort((a, b) => b.score - a.score);\n\n const total = scored.length;\n const items = scored.slice(offset, offset + limit);\n\n await this.emitSearchEvent(query, items.length);\n\n return {\n items,\n total,\n hasMore: offset + limit < total,\n limit,\n offset,\n };\n }\n\n /** Merge storage results with search provider results */\n private mergeResults(\n storageItems: StoredEntity[],\n searchHits: SearchHit[],\n limit: number,\n offset: number,\n detailLevel: DetailLevel = 'summary',\n ): PaginatedResult<Entity | EntitySummary | EntityBrief> {\n // Build a map of search scores by entity ID\n const scoreMap = new Map<string, number>();\n for (const hit of searchHits) {\n scoreMap.set(hit.id, hit.score);\n }\n\n // Combine: entities from storage, ranked by search score if available\n const allEntityIds = new Set<string>();\n const rankedItems: Array<{ entity: StoredEntity; score: number }> = [];\n\n // Add search hits first (higher relevance)\n for (const hit of searchHits) {\n const storageEntity = storageItems.find((e) => e.id === hit.id);\n if (storageEntity) {\n rankedItems.push({ entity: storageEntity, score: hit.score });\n allEntityIds.add(hit.id);\n }\n }\n\n // Add remaining storage items (not in search results)\n for (const entity of storageItems) {\n if (!allEntityIds.has(entity.id)) {\n rankedItems.push({ entity, score: 0 });\n allEntityIds.add(entity.id);\n }\n }\n\n // Sort by score descending\n rankedItems.sort((a, b) => b.score - a.score);\n\n const total = rankedItems.length;\n const page = rankedItems.slice(offset, offset + limit);\n\n return {\n items: page.map((r) => projectEntity(r.entity, detailLevel)),\n total,\n hasMore: offset + limit < total,\n limit,\n offset,\n };\n }\n\n /** Build the embedding text for an entity — label + summary + embeddable string properties */\n private async buildEmbeddingText(entityType: string, label: string, summary: string | undefined, properties: Record<string, unknown>): Promise<string> {\n const embeddableValues: string[] = [];\n if (this.vocabularyEngine) {\n const vocab = await this.vocabularyEngine.getVocabulary();\n const typeDef = getEntityTypeDef(entityType, vocab);\n if (typeDef) {\n for (const p of typeDef.properties) {\n if (p.embeddable === true && typeof properties[p.name] === 'string') {\n embeddableValues.push(properties[p.name] as string);\n }\n }\n }\n }\n return [label, summary ?? '', ...embeddableValues].filter(Boolean).join(' ');\n }\n\n /** Cosine similarity between two vectors */\n private cosineSimilarity(a: number[], b: number[]): number {\n // Use provider's similarity if available\n if (this.embedding?.similarity) {\n return this.embedding.similarity(a, b);\n }\n\n // Fallback: manual cosine similarity\n if (a.length !== b.length || a.length === 0) return 0;\n\n let dotProduct = 0;\n let normA = 0;\n let normB = 0;\n\n for (let i = 0; i < a.length; i++) {\n const ai = a[i]!;\n const bi = b[i]!;\n dotProduct += ai * bi;\n normA += ai * ai;\n normB += bi * bi;\n }\n\n const denominator = Math.sqrt(normA) * Math.sqrt(normB);\n return denominator === 0 ? 0 : dotProduct / denominator;\n }\n\n private async emitSearchEvent(query: string, resultCount: number): Promise<void> {\n if (this.eventBus) {\n await this.eventBus.emit('search:executed', { query, resultCount });\n }\n }\n}\n\n","// RepositoryValidator — audits entities and relationships in a repository\n// against the current vocabulary. Exposes two paged methods so MCP clients\n// with limited context can drill in one window at a time.\n//\n// Paging is applied over *issues*. `offset` skips that many issues, `take`\n// caps how many issues this page returns. The export stream is scanned from\n// the start every call — callers typically loop at offset=0 after fixing,\n// and `nextOffset` is only useful when inspecting a later slice without\n// mutating. `scanned` reports items inspected, for diagnostics.\n\nimport type { StorageProvider } from '../providers/StorageProvider.js';\nimport type { VocabularyEngine } from '../core/VocabularyEngine.js';\nimport type { StoredEntity } from '../types/entities.js';\nimport type { StoredRelationship } from '../types/relationships.js';\nimport type {\n EntityValidationPage,\n RelationshipValidationPage,\n EntityValidationIssue,\n RelationshipValidationIssue,\n ValidateEntitiesOptions,\n ValidateRelationshipsOptions,\n} from '../types/results.js';\nimport {\n validateEntity,\n validateRelationship,\n type ValidationError,\n} from '../vocabulary/VocabularyValidator.js';\n\ninterface EntityMapEntry {\n entityType: string;\n label: string;\n slug: string;\n}\n\nconst DEFAULT_TAKE = 200;\n\nexport class RepositoryValidator {\n constructor(\n private readonly repositoryId: string,\n private readonly storage: StorageProvider,\n private readonly vocabularyEngine: VocabularyEngine,\n ) {}\n\n async validateEntities(options?: ValidateEntitiesOptions): Promise<EntityValidationPage> {\n const offset = options?.offset ?? 0;\n const take = options?.take ?? DEFAULT_TAKE;\n const delayMs = options?.delayBetweenChunksMs ?? 0;\n\n const vocabulary = await this.vocabularyEngine.getVocabulary();\n\n const issues: EntityValidationIssue[] = [];\n let scanned = 0;\n let skipped = 0;\n let stoppedEarly = false;\n\n for await (const chunk of this.storage.exportAll(this.repositoryId)) {\n if (chunk.type !== 'entities') {\n // Relationships phase — no further entities to scan.\n break;\n }\n\n const data = chunk.data as StoredEntity[];\n for (const entity of data) {\n scanned++;\n\n const result = validateEntity(\n {\n entityType: entity.entityType,\n label: entity.label,\n properties: entity.properties,\n },\n vocabulary,\n );\n if (!result.valid) {\n if (skipped < offset) {\n skipped++;\n continue;\n }\n issues.push({\n entityId: entity.id,\n slug: entity.slug,\n entityType: entity.entityType,\n label: entity.label,\n errors: result.errors,\n });\n if (issues.length >= take) {\n stoppedEarly = true;\n break;\n }\n }\n }\n\n if (stoppedEarly) break;\n\n if (delayMs > 0 && !chunk.isLast) {\n await new Promise<void>((resolve) => { setTimeout(resolve, delayMs); });\n }\n }\n\n return {\n issues,\n scanned,\n nextOffset: offset + issues.length,\n done: !stoppedEarly,\n };\n }\n\n async validateRelationships(options?: ValidateRelationshipsOptions): Promise<RelationshipValidationPage> {\n const offset = options?.offset ?? 0;\n const take = options?.take ?? DEFAULT_TAKE;\n const delayMs = options?.delayBetweenChunksMs ?? 0;\n\n const vocabulary = await this.vocabularyEngine.getVocabulary();\n\n // Orphan checks and type-mismatch checks need every entity resolvable,\n // so the entity-map pass can't be paged.\n const entityMap = new Map<string, EntityMapEntry>();\n const issues: RelationshipValidationIssue[] = [];\n let scanned = 0;\n let skipped = 0;\n let stoppedEarly = false;\n\n for await (const chunk of this.storage.exportAll(this.repositoryId)) {\n if (chunk.type === 'entities') {\n for (const entity of chunk.data as StoredEntity[]) {\n entityMap.set(entity.id, {\n entityType: entity.entityType,\n label: entity.label,\n slug: entity.slug,\n });\n }\n\n if (delayMs > 0 && !chunk.isLast) {\n await new Promise<void>((resolve) => { setTimeout(resolve, delayMs); });\n }\n continue;\n }\n\n const data = chunk.data as StoredRelationship[];\n for (const rel of data) {\n scanned++;\n\n const src = entityMap.get(rel.sourceEntityId);\n const tgt = entityMap.get(rel.targetEntityId);\n\n const errors: ValidationError[] = [];\n\n if (!src) {\n errors.push({\n field: 'sourceEntityId',\n message: `Source entity \"${rel.sourceEntityId}\" does not exist in this repository`,\n });\n }\n if (!tgt) {\n errors.push({\n field: 'targetEntityId',\n message: `Target entity \"${rel.targetEntityId}\" does not exist in this repository`,\n });\n }\n\n if (rel.sourceEntityId === rel.targetEntityId) {\n errors.push({\n field: 'targetEntityId',\n message: `Self-referential relationship: source and target are the same entity \"${rel.sourceEntityId}\"`,\n suggestion: 'Remove the relationship, or repoint it to a different entity.',\n });\n }\n\n // Only run full vocabulary validation when both endpoints exist —\n // otherwise type-based checks would pile noise on top of the orphan error.\n if (src && tgt) {\n const result = validateRelationship(\n {\n relationshipType: rel.relationshipType,\n sourceEntityId: rel.sourceEntityId,\n targetEntityId: rel.targetEntityId,\n properties: rel.properties,\n },\n vocabulary,\n src.entityType,\n tgt.entityType,\n );\n errors.push(...result.errors);\n }\n\n if (errors.length > 0) {\n if (skipped < offset) {\n skipped++;\n continue;\n }\n issues.push({\n relationshipId: rel.id,\n relationshipType: rel.relationshipType,\n sourceEntityId: rel.sourceEntityId,\n targetEntityId: rel.targetEntityId,\n sourceLabel: src?.label,\n targetLabel: tgt?.label,\n sourceEntityType: src?.entityType,\n targetEntityType: tgt?.entityType,\n errors,\n });\n if (issues.length >= take) {\n stoppedEarly = true;\n break;\n }\n }\n }\n\n if (stoppedEarly) break;\n\n if (delayMs > 0 && !chunk.isLast) {\n await new Promise<void>((resolve) => { setTimeout(resolve, delayMs); });\n }\n }\n\n return {\n issues,\n scanned,\n nextOffset: offset + issues.length,\n done: !stoppedEarly,\n entitiesInMap: entityMap.size,\n };\n }\n}\n","// MemoryRepository — public API for a single memory repository\n\nimport type { StorageProvider } from '../providers/StorageProvider.js';\nimport type { SearchProvider } from '../providers/SearchProvider.js';\nimport type { EmbeddingProvider, EmbeddingProviderFactory } from '../providers/EmbeddingProvider.js';\nimport type {\n CreateEntityInput,\n DeleteEntitiesResult,\n DetailLevel,\n Entity,\n EntityBrief,\n EntitySummary,\n UpdateEntityInput,\n} from '../types/entities.js';\nimport type {\n CreateRelationshipInput,\n EnrichedRelationship,\n Relationship,\n RelationshipSummary,\n RemoveRelationshipsResult,\n} from '../types/relationships.js';\nimport type {\n FindEntitiesQuery,\n ExploreOptions,\n PathOptions,\n TimelineOptions,\n ConceptSearchOptions,\n} from '../types/queries.js';\nimport type { TraversalSpec, TraversalResult } from '../types/traversal.js';\nimport type { GraphTraversalProvider } from '../providers/GraphTraversalProvider.js';\nimport type {\n PaginatedResult,\n Neighborhood,\n PathResult,\n GraphResult,\n TimelineEvent,\n TimelineEntityRef,\n TimelineRelationshipDetail,\n TimelineResult,\n ScoredEntity,\n ReembedResult,\n EntityValidationPage,\n RelationshipValidationPage,\n ValidateEntitiesOptions,\n ValidateRelationshipsOptions,\n} from '../types/results.js';\nimport type {\n ResolvedVocabulary,\n VocabularyProposal,\n VocabularyProposalResult,\n RepositoryStats,\n} from '../types/index.js';\nimport type {\n DeepMemoryEventType,\n EventHandler,\n Unsubscribe,\n} from '../types/events.js';\nimport type { VocabularyEngine } from './VocabularyEngine.js';\nimport type { ProvenanceTracker } from './ProvenanceTracker.js';\nimport type { EventBus, HookHandler } from './EventBus.js';\nimport { EntityManager } from '../entities/EntityManager.js';\nimport { RelationshipManager } from '../relationships/RelationshipManager.js';\nimport { GraphTraversal } from '../relationships/GraphTraversal.js';\nimport { SearchOrchestrator } from '../search/SearchOrchestrator.js';\nimport { RepositoryValidator } from '../validation/RepositoryValidator.js';\n\nexport interface MemoryRepositoryConfig {\n repositoryId: string;\n storage: StorageProvider;\n search?: SearchProvider;\n /** Embedding provider configured for this repository's model + dimensions */\n embedding?: EmbeddingProvider;\n /**\n * Factory for producing embedding providers with different model/dimensions.\n * Required only if reembedAll will be called with a new model or dimensions.\n */\n embeddingFactory?: EmbeddingProviderFactory;\n graphTraversal?: GraphTraversalProvider;\n vocabularyEngine: VocabularyEngine;\n provenanceTracker: ProvenanceTracker;\n eventBus: EventBus;\n}\n\nexport class MemoryRepository {\n readonly repositoryId: string;\n private readonly storage: StorageProvider;\n private readonly search?: SearchProvider;\n private readonly vocabularyEngine: VocabularyEngine;\n private readonly provenanceTracker: ProvenanceTracker;\n private readonly eventBus: EventBus;\n private readonly entityManager: EntityManager;\n private readonly relationshipManager: RelationshipManager;\n private readonly graphTraversal: GraphTraversal;\n private readonly searchOrchestrator: SearchOrchestrator;\n private readonly embeddingFactory?: EmbeddingProviderFactory;\n private embedding?: EmbeddingProvider;\n\n constructor(config: MemoryRepositoryConfig) {\n this.repositoryId = config.repositoryId;\n this.storage = config.storage;\n this.search = config.search;\n this.vocabularyEngine = config.vocabularyEngine;\n this.provenanceTracker = config.provenanceTracker;\n this.eventBus = config.eventBus;\n this.embedding = config.embedding;\n this.embeddingFactory = config.embeddingFactory;\n\n this.entityManager = new EntityManager(\n config.repositoryId,\n config.vocabularyEngine,\n config.provenanceTracker,\n config.eventBus,\n config.storage,\n config.embedding,\n );\n\n this.relationshipManager = new RelationshipManager(\n config.repositoryId,\n config.vocabularyEngine,\n config.provenanceTracker,\n config.eventBus,\n config.storage,\n );\n\n this.graphTraversal = new GraphTraversal(\n config.repositoryId,\n config.storage,\n config.graphTraversal,\n config.vocabularyEngine,\n );\n\n this.searchOrchestrator = new SearchOrchestrator({\n repositoryId: config.repositoryId,\n storage: config.storage,\n search: config.search,\n embedding: config.embedding,\n eventBus: config.eventBus,\n vocabularyEngine: config.vocabularyEngine,\n defaultSimilarityThreshold: config.vocabularyEngine.getGovernanceConfig().defaultSimilarityThreshold,\n });\n }\n\n // ─── Vocabulary ────────────────────────────────────────────────────\n\n async getVocabulary(): Promise<ResolvedVocabulary> {\n return this.vocabularyEngine.getResolvedVocabulary();\n }\n\n async proposeVocabularyChange(\n proposal: VocabularyProposal,\n ): Promise<VocabularyProposalResult> {\n const context = this.provenanceTracker.getContext();\n return this.vocabularyEngine.proposeChange(proposal, context.actorId);\n }\n\n /** @deprecated Use proposeVocabularyChange instead */\n async proposeVocabularyExtension(\n proposal: VocabularyProposal,\n ): Promise<VocabularyProposalResult> {\n return this.proposeVocabularyChange(proposal);\n }\n\n // ─── Entities ──────────────────────────────────────────────────────\n\n async createEntities(inputs: CreateEntityInput[]): Promise<Entity[]> {\n const entities = await this.entityManager.create(inputs);\n\n // Index in search provider if available\n if (this.search) {\n for (const entity of entities) {\n await this.search.indexEntity(this.repositoryId, {\n entityId: entity.id,\n entityType: entity.entityType,\n label: entity.label,\n summary: entity.summary,\n properties: entity.properties,\n data: entity.data,\n });\n }\n }\n\n return entities;\n }\n\n async updateEntity(entityId: string, updates: UpdateEntityInput): Promise<Entity> {\n const entity = await this.entityManager.update(entityId, updates);\n\n // Re-index in search provider if available\n if (this.search) {\n await this.search.indexEntity(this.repositoryId, {\n entityId: entity.id,\n entityType: entity.entityType,\n label: entity.label,\n summary: entity.summary,\n properties: entity.properties,\n data: entity.data,\n });\n }\n\n return entity;\n }\n\n async getEntity(\n entityId: string,\n detailLevel?: DetailLevel,\n ): Promise<Entity | EntitySummary | EntityBrief | null> {\n return this.entityManager.get(entityId, detailLevel);\n }\n\n async getBySlug(\n slug: string,\n detailLevel?: DetailLevel,\n ): Promise<Entity | EntitySummary | EntityBrief | null> {\n return this.entityManager.getBySlug(slug, detailLevel);\n }\n\n async getEntities(\n entityIds: string[],\n detailLevel?: 'brief' | 'summary',\n ): Promise<Map<string, EntitySummary | EntityBrief>> {\n return this.entityManager.getMany(entityIds, detailLevel);\n }\n\n async findEntities(query: FindEntitiesQuery): Promise<PaginatedResult<Entity | EntitySummary | EntityBrief>> {\n return this.searchOrchestrator.findEntities(query);\n }\n\n async deleteEntities(ids: string[]): Promise<DeleteEntitiesResult> {\n const result = await this.entityManager.deleteMany(ids);\n\n if (this.search && result.deleted.length > 0) {\n for (const id of result.deleted) {\n await this.search.removeEntity(this.repositoryId, id);\n }\n }\n\n return result;\n }\n\n // ─── Re-embedding ──────────────────────────────────────────────────\n\n /** Re-embed specific entities using the current EmbeddingProvider */\n async reembedEntities(entityIds: string[]): Promise<ReembedResult> {\n return this.entityManager.reembedEntities(entityIds);\n }\n\n /**\n * Re-embed all entities in the repository. If `model` or `dimensions` is provided,\n * the repository's embedding configuration is updated to the new values before\n * re-embedding, so all subsequent entity writes use the new model/dimensionality.\n *\n * Processes in batches with optional rate limiting. Emits reembed:* events for progress tracking.\n * Updates repository metadata with the new model ID and dimensions on completion.\n */\n async reembedAll(options?: {\n /** New embedding model to switch to. Requires an embeddingFactory on DeepMemory. */\n model?: string;\n /** New embedding dimensionality to switch to. Requires an embeddingFactory on DeepMemory. */\n dimensions?: number;\n batchSize?: number;\n /** Max retries per batch on embedding failure (default 3) */\n maxRetries?: number;\n /** Abort after this many cumulative failures (default: no limit) */\n errorThresholdToAbort?: number;\n /** Milliseconds to wait between batches for rate limiting (default 0) */\n delayBetweenBatchesMs?: number;\n }): Promise<ReembedResult> {\n // If the caller asked for a model or dimension change, swap in a new provider\n // built from the factory and point every component that uses embeddings at it.\n // This must happen before re-embedding so the new vectors use the new config.\n if (options?.model !== undefined || options?.dimensions !== undefined) {\n if (!this.embeddingFactory) {\n throw new Error(\n 'Cannot change embedding model or dimensions: DeepMemory was constructed without an embeddingFactory. ' +\n 'Provide embeddingFactory in DeepMemoryConfig to enable per-repository embedding reconfiguration.',\n );\n }\n const currentModel = this.embedding?.modelId();\n // dimensions() throws if unknown — fall back to undefined when the current provider has never embedded\n let currentDimensions: number | undefined;\n try { currentDimensions = this.embedding?.dimensions(); } catch { currentDimensions = undefined; }\n\n const nextModel = options.model ?? currentModel;\n const nextDimensions = options.dimensions ?? currentDimensions;\n\n if (!nextModel || nextDimensions === undefined) {\n throw new Error(\n 'Cannot rebuild embedding provider: model and dimensions must both be known. ' +\n `Got model=\"${nextModel ?? 'undefined'}\", dimensions=${nextDimensions ?? 'undefined'}.`,\n );\n }\n\n const newProvider = this.embeddingFactory({ model: nextModel, dimensions: nextDimensions });\n this.embedding = newProvider;\n this.entityManager.setEmbeddingProvider(newProvider);\n this.searchOrchestrator.setEmbeddingProvider(newProvider);\n\n // Persist the new embedding configuration on the repository itself, so that any\n // subsequent openRepository() call rebuilds a provider with the matching config.\n await this.storage.updateRepository(this.repositoryId, {\n metadata: {\n embeddingModelId: nextModel,\n embeddingDimensions: nextDimensions,\n },\n });\n }\n\n // Emit started event\n const stats = await this.getStats();\n await this.eventBus.emit('reembed:started', {\n repositoryId: this.repositoryId,\n totalEntities: stats.entityCount,\n });\n\n try {\n const result = await this.entityManager.reembedAll({\n batchSize: options?.batchSize,\n maxRetries: options?.maxRetries,\n errorThresholdToAbort: options?.errorThresholdToAbort,\n delayBetweenBatchesMs: options?.delayBetweenBatchesMs,\n onProgress: async (processed, total, failed) => {\n await this.eventBus.emit('reembed:progress', {\n repositoryId: this.repositoryId,\n processed,\n totalEntities: total,\n failed,\n });\n },\n });\n\n // Update repository metadata with the model/dimensions actually produced by the run\n await this.storage.updateRepository(this.repositoryId, {\n metadata: {\n embeddingModelId: result.modelId,\n embeddingDimensions: result.dimensions,\n },\n });\n\n await this.eventBus.emit('reembed:completed', {\n repositoryId: this.repositoryId,\n processed: result.processed,\n failed: result.failed,\n modelId: result.modelId,\n });\n\n return result;\n } catch (err) {\n await this.eventBus.emit('reembed:failed', {\n repositoryId: this.repositoryId,\n error: err instanceof Error ? err.message : String(err),\n });\n throw err;\n }\n }\n\n // ─── Relationships ─────────────────────────────────────────────────\n\n async createRelationships(inputs: CreateRelationshipInput[]): Promise<Relationship[]> {\n return this.relationshipManager.create(inputs);\n }\n\n async removeRelationships(ids: string[]): Promise<RemoveRelationshipsResult> {\n return this.relationshipManager.removeMany(ids);\n }\n\n async getRelationships(\n entityId: string,\n options?: { relationshipTypes?: string[]; direction?: 'outbound' | 'inbound' | 'both'; limit?: number; offset?: number; propertyFilters?: import('../types/queries.js').PropertyFilter[] },\n ): Promise<PaginatedResult<Relationship>> {\n return this.relationshipManager.getForEntity(entityId, options);\n }\n\n async getRelationshipSummary(entityId: string): Promise<RelationshipSummary> {\n const result = await this.storage.getEntityRelationships(\n this.repositoryId,\n entityId,\n { direction: 'both', limit: 10000 },\n );\n\n const outbound: Record<string, number> = {};\n const inbound: Record<string, number> = {};\n\n for (const rel of result.items) {\n if (rel.sourceEntityId === entityId) {\n outbound[rel.relationshipType] = (outbound[rel.relationshipType] ?? 0) + 1;\n }\n if (rel.targetEntityId === entityId) {\n inbound[rel.relationshipType] = (inbound[rel.relationshipType] ?? 0) + 1;\n }\n }\n\n return { outbound, inbound };\n }\n\n async getRelationshipsForEntities(entityIds: string[]): Promise<Relationship[]> {\n const seen = new Set<string>();\n const results: Relationship[] = [];\n\n for (const entityId of entityIds) {\n const rels = await this.relationshipManager.getForEntity(entityId, {\n direction: 'both',\n limit: 10000,\n });\n\n for (const rel of rels.items) {\n if (!seen.has(rel.id)) {\n seen.add(rel.id);\n results.push(rel);\n }\n }\n }\n\n return results;\n }\n\n // ─── Graph ─────────────────────────────────────────────────────────\n\n /** Get the full graph — entities with enriched relationships, vocabulary, and stats. Paginated. */\n async getGraph(options?: { limit?: number; offset?: number; detailLevel?: DetailLevel }): Promise<GraphResult> {\n const pageSize = options?.limit ?? 200;\n const offset = options?.offset ?? 0;\n\n const [stats, vocabulary] = await Promise.all([\n this.getStats(),\n this.getVocabulary(),\n ]);\n\n const entities = await this.findEntities({ limit: pageSize, offset, detailLevel: options?.detailLevel ?? 'summary' });\n\n // Fetch relationships for this page of entities\n const rawRelationships = await this.getRelationshipsForEntities(\n entities.items.map((e) => e.id),\n );\n\n // Build entity lookup for enrichment\n const entityLookup = new Map<string, { slug: string; label: string }>();\n for (const e of entities.items) {\n entityLookup.set(e.id, { slug: e.slug, label: e.label });\n }\n\n // Enrich relationships with slug/label, capped at 1000\n const MAX_RELATIONSHIPS = 1000;\n const totalRelationships = rawRelationships.length;\n const cappedRelationships = rawRelationships.slice(0, MAX_RELATIONSHIPS);\n const relationships: EnrichedRelationship[] = cappedRelationships.map((rel) => {\n const source = entityLookup.get(rel.sourceEntityId);\n const target = entityLookup.get(rel.targetEntityId);\n return {\n ...rel,\n sourceSlug: source?.slug ?? rel.sourceEntityId,\n sourceLabel: source?.label ?? rel.sourceEntityId,\n targetSlug: target?.slug ?? rel.targetEntityId,\n targetLabel: target?.label ?? rel.targetEntityId,\n };\n });\n\n const nextOffset = offset + entities.items.length;\n const hasMore = nextOffset < stats.entityCount;\n\n return {\n vocabulary,\n stats,\n entities: entities.items,\n relationships,\n totalRelationships,\n relationshipsTruncated: totalRelationships > MAX_RELATIONSHIPS,\n hasMore,\n ...(hasMore ? { cursor: `offset:${nextOffset}` } : {}),\n };\n }\n\n // ─── Graph Traversal ───────────────────────────────────────────────\n\n async exploreNeighborhood(\n entityId: string,\n options?: ExploreOptions,\n ): Promise<Neighborhood> {\n return this.graphTraversal.exploreNeighborhood(entityId, options);\n }\n\n async findPaths(\n sourceId: string,\n targetId: string,\n options?: PathOptions,\n ): Promise<PathResult> {\n return this.graphTraversal.findPaths(sourceId, targetId, options);\n }\n\n async traverse(spec: TraversalSpec): Promise<TraversalResult> {\n return this.graphTraversal.traverse(spec);\n }\n\n async executeNativeQuery(\n query: string,\n params?: Record<string, unknown>,\n ): Promise<TraversalResult> {\n return this.graphTraversal.executeNativeQuery(query, params);\n }\n\n // ─── Search ────────────────────────────────────────────────────────\n\n async searchByConcept(\n query: string,\n options?: ConceptSearchOptions,\n ): Promise<PaginatedResult<ScoredEntity>> {\n return this.searchOrchestrator.searchByConcept(query, options);\n }\n\n // ─── Timeline ──────────────────────────────────────────────────────\n\n async getTimeline(entityId: string, options?: TimelineOptions): Promise<TimelineResult> {\n const storageOptions = {\n timeRange: options?.timeRange,\n eventTypes: options?.eventTypes,\n provenance: options?.provenance,\n limit: options?.limit ?? 20,\n offset: options?.offset ?? 0,\n };\n\n const storageResult = await this.storage.getTimeline(\n this.repositoryId,\n entityId,\n storageOptions,\n );\n\n // Get the center entity for slug info\n const entity = await this.storage.getEntity(this.repositoryId, entityId);\n const centerRef: TimelineEntityRef = {\n id: entityId,\n slug: entity?.slug ?? entityId,\n label: entity?.label ?? entityId,\n };\n\n // Batch-collect all relationship IDs to resolve\n const relIds = storageResult.events\n .filter((e) => e.relationshipId)\n .map((e) => e.relationshipId!);\n\n // Fetch relationships and collect entity IDs from them\n const relMap = new Map<string, { id: string; type: string; sourceId: string; targetId: string }>();\n const entityIdsToResolve = new Set<string>();\n\n for (const rid of relIds) {\n const rel = await this.storage.getRelationship(this.repositoryId, rid);\n if (rel) {\n relMap.set(rid, {\n id: rel.id,\n type: rel.relationshipType,\n sourceId: rel.sourceEntityId,\n targetId: rel.targetEntityId,\n });\n entityIdsToResolve.add(rel.sourceEntityId);\n entityIdsToResolve.add(rel.targetEntityId);\n }\n }\n\n // Batch-fetch all referenced entities\n const entityMap = await this.storage.getEntities(\n this.repositoryId,\n Array.from(entityIdsToResolve),\n );\n\n const toRef = (eid: string): TimelineEntityRef => {\n const e = entityMap.get(eid);\n return { id: eid, slug: e?.slug ?? eid, label: e?.label ?? eid };\n };\n\n // Build enriched events\n const events: TimelineEvent[] = storageResult.events.map((e) => {\n if (e.relationshipId && relMap.has(e.relationshipId)) {\n const rel = relMap.get(e.relationshipId)!;\n const sourceRef = toRef(rel.sourceId);\n const targetRef = toRef(rel.targetId);\n const otherRef = rel.sourceId === entityId ? targetRef : sourceRef;\n const direction = rel.sourceId === entityId ? 'to' : 'from';\n const relDetail: TimelineRelationshipDetail = {\n id: rel.id,\n relationshipType: rel.type,\n sourceEntity: sourceRef,\n targetEntity: targetRef,\n };\n\n return {\n timestamp: e.timestamp,\n eventType: e.eventType,\n description: `${rel.type} relationship created ${direction} ${otherRef.label}`,\n relatedEntities: [centerRef, otherRef],\n relationship: relDetail,\n };\n }\n\n // Entity events (created/updated)\n const action = e.eventType === 'entity:created' ? 'created' : 'updated';\n return {\n timestamp: e.timestamp,\n eventType: e.eventType,\n description: `${centerRef.label} ${action}`,\n relatedEntities: [centerRef],\n };\n });\n\n return {\n id: entityId,\n slug: centerRef.slug,\n totalEvents: storageResult.total,\n returned: events.length,\n events,\n };\n }\n\n // ─── Stats ─────────────────────────────────────────────────────────\n\n async getStats(): Promise<RepositoryStats> {\n return this.storage.getRepositoryStats(this.repositoryId);\n }\n\n // ─── Validation ────────────────────────────────────────────────────\n\n /**\n * Audit a window of entities against the current vocabulary. Returns a single\n * page; callers loop until `done` is true. Paging is over scanned entities,\n * not issues. Does not mutate anything.\n */\n async validateEntities(options?: ValidateEntitiesOptions): Promise<EntityValidationPage> {\n const validator = new RepositoryValidator(\n this.repositoryId,\n this.storage,\n this.vocabularyEngine,\n );\n return validator.validateEntities(options);\n }\n\n /**\n * Audit a window of relationships against the current vocabulary. Returns a\n * single page; callers loop until `done` is true. The full entity set is\n * loaded once per call to resolve orphan and type-mismatch checks, then\n * offset/take is applied to the relationship stream. Does not mutate anything.\n */\n async validateRelationships(options?: ValidateRelationshipsOptions): Promise<RelationshipValidationPage> {\n const validator = new RepositoryValidator(\n this.repositoryId,\n this.storage,\n this.vocabularyEngine,\n );\n return validator.validateRelationships(options);\n }\n\n // ─── Bulk Operations ──────────────────────────────────────────────\n\n /** Delete all entities and relationships in this repository, preserving the repository and vocabulary */\n async deleteAllContents(): Promise<{ deletedEntities: number; deletedRelationships: number }> {\n return this.storage.deleteAllContents(this.repositoryId);\n }\n\n /**\n * Returns a static markdown guide describing the recommended query strategy\n * for AI agents and other consumers of the repository.\n */\n getQueryGuide(): string {\n return `## Query Strategy Guide\n\n### Step 1 — Discover before you traverse\n\nBefore following relationships from an entity, check that it actually has relationships.\nGraph queries include \\`relationshipSummary\\` on every returned entity by default\n(outbound and inbound counts by type). Inspect this before traversing — entities with\nzero outbound counts for the relationship type you need have no connections to follow.\nTo skip summaries and reduce response size, set \\`includeRelationshipSummary: false\\`.\n\n### Step 2 — Use projection for aggregation\n\nTo understand what data exists (e.g. all distinct values of a property, or counts by\ncategory), use a graph query with \\`projection\\` instead of fetching full entities:\n\\`{ start: { entityType: \"...\" }, projection: { properties: [\"propName\"], distinct: true }, limit: 200 }\\`\n\nThis returns only the aggregated values — no entity objects — keeping responses lightweight.\n\n### Step 3 — Traverse efficiently\n\n- **Omit relationshipTypes** in a traversal step to follow all relationship types at once,\n rather than making separate calls per type.\n- **Use multi-step traversals** for multi-hop patterns. A two-step traverse operation\n (e.g. Equipment → Component → MaintenanceProcedure) is one call, not two sequential calls.\n- **Use returnMode \"all\"** when you need intermediate entities along the path, not just\n the terminal nodes.\n\n### Step 4 — Use semantic search for known-unknowns\n\nSemantic/concept search is best for finding specific entities when you know roughly\nwhat you're looking for but not the exact label or type. It is not efficient for broad\ndiscovery — use projection or entity finding for that.\n\n### Common anti-patterns to avoid\n\n- **Don't traverse from entities with zero relationship counts.** The \\`relationshipSummary\\` on each entity tells you what is connected before you traverse.\n- **Don't split queries by relationship type.** One traverse step with no type filter is better\n than three separate single-type calls.\n- **Don't use sequential single-hop traversals** when a multi-step traverse operation achieves the\n same result in one call.\n- **Don't fetch full entities when you only need property values.** Use projection.`;\n }\n\n // ─── Events ────────────────────────────────────────────────────────\n\n on<E extends DeepMemoryEventType>(event: E, handler: EventHandler<E>): Unsubscribe {\n return this.eventBus.on(event, handler);\n }\n\n onHook<E extends Extract<DeepMemoryEventType, 'entity:creating' | 'entity:updating' | 'entity:deleting' | 'relationship:creating' | 'relationship:removing'>>(\n event: E,\n handler: HookHandler<E>,\n ): Unsubscribe {\n return this.eventBus.onHook(event, handler);\n }\n}\n","// SemanticDeduplicator — detects duplicate type proposals using string or embedding similarity\n\nimport type { EmbeddingProvider } from '../providers/EmbeddingProvider.js';\nimport { jaroWinklerSimilarity, normalizeTypeName } from './similarity.js';\n\n/** A match found during deduplication */\nexport interface DeduplicationMatch {\n type: string;\n description: string;\n similarity: number;\n}\n\n/** Result of a deduplication check */\nexport interface DeduplicationResult {\n isDuplicate: boolean;\n matches: DeduplicationMatch[];\n}\n\n/** An existing type to check against */\nexport interface ExistingType {\n type: string;\n description: string;\n}\n\nexport interface SemanticDeduplicatorConfig {\n /** Similarity threshold above which a proposed type is considered a duplicate (default 0.85) */\n similarityThreshold?: number;\n /** Optional embedding provider for semantic comparison */\n embeddingProvider?: EmbeddingProvider;\n}\n\nconst DEFAULT_THRESHOLD = 0.85;\n\nexport class SemanticDeduplicator {\n private readonly threshold: number;\n private readonly embeddingProvider?: EmbeddingProvider;\n\n constructor(config: SemanticDeduplicatorConfig = {}) {\n this.threshold = config.similarityThreshold ?? DEFAULT_THRESHOLD;\n this.embeddingProvider = config.embeddingProvider;\n }\n\n /**\n * Check whether a proposed type name is a duplicate of an existing type.\n * Uses embedding similarity if an EmbeddingProvider is available, otherwise falls back\n * to Jaro-Winkler string similarity on normalized type names.\n */\n async checkDuplicate(\n proposedType: string,\n proposedDescription: string,\n existingTypes: ExistingType[],\n ): Promise<DeduplicationResult> {\n if (existingTypes.length === 0) {\n return { isDuplicate: false, matches: [] };\n }\n\n // Exact match check first (normalized)\n const normProposed = normalizeTypeName(proposedType);\n const exactMatch = existingTypes.find((t) => normalizeTypeName(t.type) === normProposed);\n if (exactMatch) {\n return {\n isDuplicate: true,\n matches: [{ type: exactMatch.type, description: exactMatch.description, similarity: 1.0 }],\n };\n }\n\n // Try embedding-based similarity if available\n if (this.embeddingProvider) {\n return this.checkWithEmbeddings(proposedType, proposedDescription, existingTypes);\n }\n\n // Fall back to Jaro-Winkler on type names\n return this.checkWithStringSimilarity(proposedType, existingTypes);\n }\n\n private async checkWithEmbeddings(\n proposedType: string,\n proposedDescription: string,\n existingTypes: ExistingType[],\n ): Promise<DeduplicationResult> {\n const proposedText = `${proposedType}: ${proposedDescription}`;\n const existingTexts = existingTypes.map((t) => `${t.type}: ${t.description}`);\n\n const allTexts = [proposedText, ...existingTexts];\n const embeddings = await this.embeddingProvider!.embedBatch(allTexts);\n const proposedEmbedding = embeddings[0]!;\n\n const matches: DeduplicationMatch[] = [];\n\n for (let i = 0; i < existingTypes.length; i++) {\n const similarity = this.cosineSimilarity(proposedEmbedding, embeddings[i + 1]!);\n if (similarity >= this.threshold) {\n matches.push({\n type: existingTypes[i]!.type,\n description: existingTypes[i]!.description,\n similarity,\n });\n }\n }\n\n // Sort by similarity descending\n matches.sort((a, b) => b.similarity - a.similarity);\n\n return {\n isDuplicate: matches.length > 0,\n matches,\n };\n }\n\n private checkWithStringSimilarity(\n proposedType: string,\n existingTypes: ExistingType[],\n ): DeduplicationResult {\n const normProposed = normalizeTypeName(proposedType);\n const matches: DeduplicationMatch[] = [];\n\n for (const existing of existingTypes) {\n const normExisting = normalizeTypeName(existing.type);\n const similarity = jaroWinklerSimilarity(normProposed, normExisting);\n\n if (similarity >= this.threshold) {\n matches.push({\n type: existing.type,\n description: existing.description,\n similarity,\n });\n }\n }\n\n // Sort by similarity descending\n matches.sort((a, b) => b.similarity - a.similarity);\n\n return {\n isDuplicate: matches.length > 0,\n matches,\n };\n }\n\n private cosineSimilarity(a: number[], b: number[]): number {\n // Use provider's similarity function if available\n if (this.embeddingProvider?.similarity) {\n return this.embeddingProvider.similarity(a, b);\n }\n\n // Default cosine similarity\n let dotProduct = 0;\n let normA = 0;\n let normB = 0;\n\n for (let i = 0; i < a.length; i++) {\n dotProduct += a[i]! * b[i]!;\n normA += a[i]! * a[i]!;\n normB += b[i]! * b[i]!;\n }\n\n const denominator = Math.sqrt(normA) * Math.sqrt(normB);\n return denominator === 0 ? 0 : dotProduct / denominator;\n }\n}\n","// VocabularySchema — factory functions for creating well-formed vocabulary definitions\n\nimport type {\n EntityTypeDefinition,\n EntityTypeInput,\n MemoryVocabulary,\n PropertySchema,\n RelationshipTypeDefinition,\n RelationshipTypeInput,\n VocabularyInput,\n VocabularyProposal,\n} from '../types/vocabulary.js';\nimport { toScreamingSnakeCase } from './similarity.js';\n\n/** Create an empty vocabulary with version \"0.0.0\" */\nexport function createEmptyVocabulary(modifiedBy: string): MemoryVocabulary {\n const now = new Date().toISOString();\n return {\n version: '0.0.0',\n lastModified: now,\n modifiedBy,\n entityTypes: [],\n relationshipTypes: [],\n };\n}\n\n/** Create an EntityTypeDefinition from an input, filling in system-managed fields */\nexport function createEntityTypeDefinition(\n input: EntityTypeInput,\n createdBy: string,\n): EntityTypeDefinition {\n const now = new Date().toISOString();\n return {\n type: input.type,\n description: input.description,\n version: '1.0.0',\n properties: input.properties ?? [],\n createdAt: now,\n createdBy,\n modifiedAt: now,\n modifiedBy: createdBy,\n };\n}\n\n/** Create a RelationshipTypeDefinition from an input, filling in system-managed fields */\nexport function createRelationshipTypeDefinition(\n input: RelationshipTypeInput,\n createdBy: string,\n): RelationshipTypeDefinition {\n const now = new Date().toISOString();\n return {\n type: toScreamingSnakeCase(input.type),\n description: input.description,\n version: '1.0.0',\n allowedSourceTypes: input.allowedSourceTypes,\n allowedTargetTypes: input.allowedTargetTypes,\n bidirectional: input.bidirectional ?? false,\n properties: input.properties,\n createdAt: now,\n createdBy,\n modifiedAt: now,\n modifiedBy: createdBy,\n };\n}\n\n/** Build a full MemoryVocabulary from a VocabularyInput */\nexport function buildVocabulary(input: VocabularyInput, createdBy: string): MemoryVocabulary {\n const now = new Date().toISOString();\n return {\n version: '1.0.0',\n lastModified: now,\n modifiedBy: createdBy,\n entityTypes: (input.entityTypes ?? []).map((et) => createEntityTypeDefinition(et, createdBy)),\n relationshipTypes: (input.relationshipTypes ?? []).map((rt) =>\n createRelationshipTypeDefinition(rt, createdBy),\n ),\n };\n}\n\n/** Increment a semantic version string (patch by default) */\nexport function incrementVersion(\n version: string,\n level: 'major' | 'minor' | 'patch' = 'patch',\n): string {\n const parts = version.split('.').map(Number);\n const major = parts[0] ?? 0;\n const minor = parts[1] ?? 0;\n const patch = parts[2] ?? 0;\n\n switch (level) {\n case 'major':\n return `${major + 1}.0.0`;\n case 'minor':\n return `${major}.${minor + 1}.0`;\n case 'patch':\n return `${major}.${minor}.${patch + 1}`;\n }\n}\n\n/** Merge property edits into an existing properties array */\nfunction mergeProperties(\n existing: PropertySchema[],\n addProperties?: PropertySchema[],\n removeProperties?: string[],\n updateProperties?: PropertySchema[],\n): PropertySchema[] {\n // Start from existing\n let result = [...existing];\n\n // Remove\n if (removeProperties && removeProperties.length > 0) {\n const removeSet = new Set(removeProperties);\n result = result.filter((p) => !removeSet.has(p.name));\n }\n\n // Update (replace by name)\n if (updateProperties && updateProperties.length > 0) {\n const updateMap = new Map(updateProperties.map((p) => [p.name, p]));\n result = result.map((p) => updateMap.get(p.name) ?? p);\n }\n\n // Add\n if (addProperties && addProperties.length > 0) {\n const existingNames = new Set(result.map((p) => p.name));\n for (const prop of addProperties) {\n if (!existingNames.has(prop.name)) {\n result.push(prop);\n }\n }\n }\n\n return result;\n}\n\n/** Apply an edit to an existing EntityTypeDefinition */\nexport function mergeEntityTypeEdit(\n existing: EntityTypeDefinition,\n edit: NonNullable<VocabularyProposal['editEntityType']>,\n modifiedBy: string,\n): EntityTypeDefinition {\n const now = new Date().toISOString();\n return {\n ...existing,\n description: edit.description ?? existing.description,\n version: incrementVersion(existing.version, 'minor'),\n properties: mergeProperties(\n existing.properties,\n edit.addProperties,\n edit.removeProperties,\n edit.updateProperties,\n ),\n modifiedAt: now,\n modifiedBy,\n };\n}\n\n/** Apply an edit to an existing RelationshipTypeDefinition */\nexport function mergeRelationshipTypeEdit(\n existing: RelationshipTypeDefinition,\n edit: NonNullable<VocabularyProposal['editRelationshipType']>,\n modifiedBy: string,\n): RelationshipTypeDefinition {\n const now = new Date().toISOString();\n return {\n ...existing,\n description: edit.description ?? existing.description,\n allowedSourceTypes: edit.allowedSourceTypes ?? existing.allowedSourceTypes,\n allowedTargetTypes: edit.allowedTargetTypes ?? existing.allowedTargetTypes,\n bidirectional: edit.bidirectional ?? existing.bidirectional,\n version: incrementVersion(existing.version, 'minor'),\n properties: mergeProperties(\n existing.properties ?? [],\n edit.addProperties,\n edit.removeProperties,\n edit.updateProperties,\n ),\n modifiedAt: now,\n modifiedBy,\n };\n}\n","// VocabularyGovernor — implements governance modes for vocabulary evolution\n\nimport type {\n GovernanceConfig,\n MemoryVocabulary,\n VocabularyProposal,\n VocabularyProposalResult,\n VocabularyChangeRecord,\n} from '../types/vocabulary.js';\nimport {\n createEntityTypeDefinition,\n createRelationshipTypeDefinition,\n incrementVersion,\n mergeEntityTypeEdit,\n mergeRelationshipTypeEdit,\n} from './VocabularySchema.js';\n\n/** Why a proposal was denied */\nexport interface GovernanceDenial {\n allowed: false;\n reason: string;\n}\n\n/** Proposal is allowed to proceed */\nexport interface GovernanceApproval {\n allowed: true;\n}\n\nexport type GovernanceDecision = GovernanceDenial | GovernanceApproval;\n\n/** Check whether a proposal is allowed under the given governance mode */\nexport function canPropose(\n governanceConfig: GovernanceConfig,\n _proposal: VocabularyProposal,\n): GovernanceDecision {\n switch (governanceConfig.mode) {\n case 'locked':\n return {\n allowed: false,\n reason:\n 'Vocabulary is locked. Only organization admins can modify the vocabulary via the admin API.',\n };\n case 'managed':\n case 'open':\n return { allowed: true };\n }\n}\n\nexport interface ProcessProposalOptions {\n /** Pre-checked deduplication result — if duplicates were found, pass them here */\n duplicates?: Array<{ type: string; description: string; similarity: number }>;\n /** The actor proposing the change */\n proposedBy: string;\n}\n\n/**\n * Process a vocabulary proposal according to governance rules.\n * Returns the updated vocabulary (if approved) and a proposal result.\n */\nexport function processProposal(\n vocabulary: MemoryVocabulary,\n proposal: VocabularyProposal,\n governanceConfig: GovernanceConfig,\n options: ProcessProposalOptions,\n): {\n result: VocabularyProposalResult;\n updatedVocabulary?: MemoryVocabulary;\n changeRecord?: VocabularyChangeRecord;\n} {\n const decision = canPropose(governanceConfig, proposal);\n if (!decision.allowed) {\n return {\n result: {\n status: 'rejected',\n type: getProposedTypeName(proposal),\n reason: decision.reason,\n },\n };\n }\n\n // Edit and delete proposals skip deduplication\n const isAddProposal =\n proposal.proposalType === 'entity_type' || proposal.proposalType === 'relationship_type';\n\n // If duplicates were found (add proposals only), reject\n if (isAddProposal && options.duplicates && options.duplicates.length > 0) {\n return {\n result: {\n status: 'rejected',\n type: getProposedTypeName(proposal),\n reason: `Similar type(s) already exist in the vocabulary`,\n duplicates: options.duplicates,\n },\n };\n }\n\n // Managed mode with requireApproval — queue for human approval\n if (governanceConfig.mode === 'managed' && governanceConfig.requireApproval) {\n return {\n result: {\n status: 'pending_approval',\n type: getProposedTypeName(proposal),\n proposalId: generateProposalId(),\n },\n };\n }\n\n // Auto-approve: managed (without requireApproval) or open\n switch (proposal.proposalType) {\n case 'entity_type':\n case 'relationship_type':\n return applyAddProposal(vocabulary, proposal, options.proposedBy);\n case 'edit_entity_type':\n case 'edit_relationship_type':\n return applyEditProposal(vocabulary, proposal, options.proposedBy);\n case 'delete_entity_type':\n case 'delete_relationship_type':\n return applyDeleteProposal(vocabulary, proposal, options.proposedBy);\n }\n}\n\n/** Apply an add proposal to the vocabulary */\nfunction applyAddProposal(\n vocabulary: MemoryVocabulary,\n proposal: VocabularyProposal,\n proposedBy: string,\n): {\n result: VocabularyProposalResult;\n updatedVocabulary: MemoryVocabulary;\n changeRecord: VocabularyChangeRecord;\n} {\n const now = new Date().toISOString();\n const newVersion = incrementVersion(vocabulary.version, 'minor');\n const typeName = getProposedTypeName(proposal);\n\n let updatedVocabulary: MemoryVocabulary;\n let changeType: VocabularyChangeRecord['changeType'];\n\n if (proposal.proposalType === 'entity_type' && proposal.entityType) {\n const newType = createEntityTypeDefinition(proposal.entityType, proposedBy);\n updatedVocabulary = {\n ...vocabulary,\n version: newVersion,\n lastModified: now,\n modifiedBy: proposedBy,\n entityTypes: [...vocabulary.entityTypes, newType],\n };\n changeType = 'entity_type_added';\n } else if (proposal.proposalType === 'relationship_type' && proposal.relationshipType) {\n const newType = createRelationshipTypeDefinition(\n {\n type: proposal.relationshipType.type,\n description: proposal.relationshipType.description,\n allowedSourceTypes: proposal.relationshipType.allowedSourceTypes,\n allowedTargetTypes: proposal.relationshipType.allowedTargetTypes,\n bidirectional: proposal.relationshipType.bidirectional,\n properties: proposal.relationshipType.properties,\n },\n proposedBy,\n );\n updatedVocabulary = {\n ...vocabulary,\n version: newVersion,\n lastModified: now,\n modifiedBy: proposedBy,\n relationshipTypes: [...vocabulary.relationshipTypes, newType],\n };\n changeType = 'relationship_type_added';\n } else {\n return {\n result: {\n status: 'rejected',\n type: typeName,\n reason: 'Invalid proposal: missing type definition for the specified proposal type',\n },\n updatedVocabulary: vocabulary,\n changeRecord: {\n changeId: generateChangeId(),\n changeType: 'entity_type_added',\n typeName,\n newVersion: vocabulary.version,\n proposedBy,\n proposedAt: now,\n reason: proposal.justification,\n },\n };\n }\n\n const changeRecord: VocabularyChangeRecord = {\n changeId: generateChangeId(),\n changeType,\n typeName,\n previousVersion: vocabulary.version,\n newVersion,\n proposedBy,\n proposedAt: now,\n approvedAt: now,\n reason: proposal.justification,\n };\n\n return {\n result: { status: 'approved', type: typeName, vocabularyVersion: newVersion },\n updatedVocabulary,\n changeRecord,\n };\n}\n\n/** Apply an edit proposal to the vocabulary */\nfunction applyEditProposal(\n vocabulary: MemoryVocabulary,\n proposal: VocabularyProposal,\n proposedBy: string,\n): {\n result: VocabularyProposalResult;\n updatedVocabulary?: MemoryVocabulary;\n changeRecord?: VocabularyChangeRecord;\n} {\n const now = new Date().toISOString();\n const typeName = getProposedTypeName(proposal);\n const newVersion = incrementVersion(vocabulary.version, 'minor');\n\n let updatedVocabulary: MemoryVocabulary;\n let changeType: VocabularyChangeRecord['changeType'];\n\n if (proposal.proposalType === 'edit_entity_type' && proposal.editEntityType) {\n const existing = vocabulary.entityTypes.find((et) => et.type === proposal.editEntityType!.type);\n if (!existing) {\n return {\n result: {\n status: 'rejected',\n type: typeName,\n reason: `Entity type \"${typeName}\" not found in vocabulary`,\n },\n };\n }\n const merged = mergeEntityTypeEdit(existing, proposal.editEntityType, proposedBy);\n updatedVocabulary = {\n ...vocabulary,\n version: newVersion,\n lastModified: now,\n modifiedBy: proposedBy,\n entityTypes: vocabulary.entityTypes.map((et) => (et.type === typeName ? merged : et)),\n };\n changeType = 'entity_type_modified';\n } else if (proposal.proposalType === 'edit_relationship_type' && proposal.editRelationshipType) {\n const existing = vocabulary.relationshipTypes.find(\n (rt) => rt.type === proposal.editRelationshipType!.type,\n );\n if (!existing) {\n return {\n result: {\n status: 'rejected',\n type: typeName,\n reason: `Relationship type \"${typeName}\" not found in vocabulary`,\n },\n };\n }\n const merged = mergeRelationshipTypeEdit(existing, proposal.editRelationshipType, proposedBy);\n updatedVocabulary = {\n ...vocabulary,\n version: newVersion,\n lastModified: now,\n modifiedBy: proposedBy,\n relationshipTypes: vocabulary.relationshipTypes.map((rt) =>\n rt.type === typeName ? merged : rt,\n ),\n };\n changeType = 'relationship_type_modified';\n } else {\n return {\n result: {\n status: 'rejected',\n type: typeName,\n reason: 'Invalid proposal: missing edit definition for the specified proposal type',\n },\n };\n }\n\n const changeRecord: VocabularyChangeRecord = {\n changeId: generateChangeId(),\n changeType,\n typeName,\n previousVersion: vocabulary.version,\n newVersion,\n proposedBy,\n proposedAt: now,\n approvedAt: now,\n reason: proposal.justification,\n };\n\n return {\n result: { status: 'approved', type: typeName, vocabularyVersion: newVersion },\n updatedVocabulary,\n changeRecord,\n };\n}\n\n/** Apply a delete proposal to the vocabulary (vocabulary only — data cascade is handled by VocabularyEngine) */\nfunction applyDeleteProposal(\n vocabulary: MemoryVocabulary,\n proposal: VocabularyProposal,\n proposedBy: string,\n): {\n result: VocabularyProposalResult;\n updatedVocabulary?: MemoryVocabulary;\n changeRecord?: VocabularyChangeRecord;\n} {\n const now = new Date().toISOString();\n const typeName = getProposedTypeName(proposal);\n const newVersion = incrementVersion(vocabulary.version, 'major');\n\n let updatedVocabulary: MemoryVocabulary;\n let changeType: VocabularyChangeRecord['changeType'];\n\n if (proposal.proposalType === 'delete_entity_type' && proposal.deleteEntityType) {\n const exists = vocabulary.entityTypes.some((et) => et.type === proposal.deleteEntityType!.type);\n if (!exists) {\n return {\n result: {\n status: 'rejected',\n type: typeName,\n reason: `Entity type \"${typeName}\" not found in vocabulary`,\n },\n };\n }\n updatedVocabulary = {\n ...vocabulary,\n version: newVersion,\n lastModified: now,\n modifiedBy: proposedBy,\n entityTypes: vocabulary.entityTypes.filter((et) => et.type !== typeName),\n };\n changeType = 'entity_type_removed';\n } else if (\n proposal.proposalType === 'delete_relationship_type' &&\n proposal.deleteRelationshipType\n ) {\n const exists = vocabulary.relationshipTypes.some(\n (rt) => rt.type === proposal.deleteRelationshipType!.type,\n );\n if (!exists) {\n return {\n result: {\n status: 'rejected',\n type: typeName,\n reason: `Relationship type \"${typeName}\" not found in vocabulary`,\n },\n };\n }\n updatedVocabulary = {\n ...vocabulary,\n version: newVersion,\n lastModified: now,\n modifiedBy: proposedBy,\n relationshipTypes: vocabulary.relationshipTypes.filter((rt) => rt.type !== typeName),\n };\n changeType = 'relationship_type_removed';\n } else {\n return {\n result: {\n status: 'rejected',\n type: typeName,\n reason: 'Invalid proposal: missing delete definition for the specified proposal type',\n },\n };\n }\n\n const changeRecord: VocabularyChangeRecord = {\n changeId: generateChangeId(),\n changeType,\n typeName,\n previousVersion: vocabulary.version,\n newVersion,\n proposedBy,\n proposedAt: now,\n approvedAt: now,\n reason: proposal.justification,\n };\n\n return {\n result: { status: 'approved', type: typeName, vocabularyVersion: newVersion },\n updatedVocabulary,\n changeRecord,\n };\n}\n\nfunction getProposedTypeName(proposal: VocabularyProposal): string {\n switch (proposal.proposalType) {\n case 'entity_type':\n return proposal.entityType?.type ?? 'unknown';\n case 'relationship_type':\n return proposal.relationshipType?.type ?? 'unknown';\n case 'edit_entity_type':\n return proposal.editEntityType?.type ?? 'unknown';\n case 'edit_relationship_type':\n return proposal.editRelationshipType?.type ?? 'unknown';\n case 'delete_entity_type':\n return proposal.deleteEntityType?.type ?? 'unknown';\n case 'delete_relationship_type':\n return proposal.deleteRelationshipType?.type ?? 'unknown';\n }\n}\n\nfunction generateProposalId(): string {\n return `proposal_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;\n}\n\nfunction generateChangeId(): string {\n return `change_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;\n}\n","// VocabularyEngine — orchestrates vocabulary validation, governance, and deduplication\n\nimport type { EmbeddingProvider } from '../providers/EmbeddingProvider.js';\nimport type { StorageProvider } from '../providers/StorageProvider.js';\nimport type { CreateEntityInput, UpdateEntityInput } from '../types/entities.js';\nimport type { CreateRelationshipInput } from '../types/relationships.js';\nimport type {\n GovernanceConfig,\n MemoryVocabulary,\n VocabularyProposal,\n VocabularyProposalResult,\n ResolvedVocabulary,\n EntityTypeDefinition,\n} from '../types/vocabulary.js';\nimport {\n SemanticDeduplicator,\n type ExistingType,\n} from '../vocabulary/SemanticDeduplicator.js';\nimport {\n processProposal,\n} from '../vocabulary/VocabularyGovernor.js';\nimport {\n validateEntity,\n validateEntityUpdate,\n validateRelationship,\n validatePropertySchema,\n getEntityTypeDef,\n type ValidationResult,\n} from '../vocabulary/VocabularyValidator.js';\nimport type { PropertySchema } from '../types/vocabulary.js';\n\nexport interface VocabularyEngineConfig {\n repositoryId: string;\n storageProvider: StorageProvider;\n governanceConfig: GovernanceConfig;\n embeddingProvider?: EmbeddingProvider;\n /** Similarity threshold for deduplication (default 0.85) */\n deduplicationThreshold?: number;\n}\n\nexport class VocabularyEngine {\n private readonly repositoryId: string;\n private readonly storage: StorageProvider;\n private readonly governanceConfig: GovernanceConfig;\n private readonly deduplicator: SemanticDeduplicator;\n\n /** Cached vocabulary — invalidated on mutation */\n private cachedVocabulary: MemoryVocabulary | null = null;\n\n constructor(config: VocabularyEngineConfig) {\n this.repositoryId = config.repositoryId;\n this.storage = config.storageProvider;\n this.governanceConfig = config.governanceConfig;\n this.deduplicator = new SemanticDeduplicator({\n similarityThreshold: config.deduplicationThreshold,\n embeddingProvider: config.embeddingProvider,\n });\n }\n\n /** Get the governance configuration for this repository */\n getGovernanceConfig(): GovernanceConfig {\n return this.governanceConfig;\n }\n\n /** Get the current vocabulary from storage (cached) */\n async getVocabulary(): Promise<MemoryVocabulary> {\n if (!this.cachedVocabulary) {\n this.cachedVocabulary = await this.storage.getVocabulary(this.repositoryId);\n }\n return this.cachedVocabulary;\n }\n\n /** Get the resolved vocabulary with governance info */\n async getResolvedVocabulary(): Promise<ResolvedVocabulary> {\n const vocabulary = await this.getVocabulary();\n return {\n vocabulary,\n governanceMode: this.governanceConfig.mode,\n governanceConfig: this.governanceConfig,\n };\n }\n\n /** Invalidate the cached vocabulary (call after external mutations) */\n invalidateCache(): void {\n this.cachedVocabulary = null;\n }\n\n /** Validate an entity creation input against the vocabulary */\n async validateEntity(input: CreateEntityInput): Promise<ValidationResult> {\n const vocabulary = await this.getVocabulary();\n return validateEntity(input, vocabulary);\n }\n\n /** Validate an entity update input against the vocabulary */\n async validateEntityUpdate(\n input: UpdateEntityInput,\n entityType: string,\n ): Promise<ValidationResult> {\n const vocabulary = await this.getVocabulary();\n const typeDef = getEntityTypeDef(entityType, vocabulary);\n if (!typeDef) {\n return {\n valid: false,\n errors: [\n {\n field: 'entityType',\n message: `Entity type \"${entityType}\" does not exist in the vocabulary`,\n },\n ],\n };\n }\n return validateEntityUpdate(input, typeDef, vocabulary);\n }\n\n /** Validate a relationship creation input against the vocabulary */\n async validateRelationship(\n input: CreateRelationshipInput,\n sourceEntityType: string,\n targetEntityType: string,\n ): Promise<ValidationResult> {\n const vocabulary = await this.getVocabulary();\n return validateRelationship(input, vocabulary, sourceEntityType, targetEntityType);\n }\n\n /** Get an entity type definition from the vocabulary */\n async getEntityTypeDef(entityType: string): Promise<EntityTypeDefinition | null> {\n const vocabulary = await this.getVocabulary();\n return getEntityTypeDef(entityType, vocabulary);\n }\n\n /**\n * Propose a vocabulary change (add, edit, or delete).\n * Runs deduplication for add proposals, then governance rules.\n * For delete proposals, cascades data deletion if approved.\n */\n async proposeChange(\n proposal: VocabularyProposal,\n proposedBy: string,\n ): Promise<VocabularyProposalResult> {\n const vocabulary = await this.getVocabulary();\n\n // Only run deduplication for add proposals\n const isAddProposal =\n proposal.proposalType === 'entity_type' || proposal.proposalType === 'relationship_type';\n\n let duplicates: Array<{ type: string; description: string; similarity: number }> | undefined;\n\n if (isAddProposal) {\n const existingTypes = this.getExistingTypesForProposal(proposal, vocabulary);\n const proposedTypeName = this.getProposedTypeName(proposal);\n const proposedDescription = this.getProposedDescription(proposal);\n\n const skipDedup =\n this.governanceConfig.mode === 'open' &&\n this.governanceConfig.deduplicationEnabled === false;\n\n if (!skipDedup) {\n const dedupResult = await this.deduplicator.checkDuplicate(\n proposedTypeName,\n proposedDescription,\n existingTypes,\n );\n if (dedupResult.isDuplicate) {\n duplicates = dedupResult.matches;\n }\n }\n }\n\n // Validate property schemas in the proposal (e.g. embeddable only allowed on string)\n const propertySchemaErrors = this.validateProposalPropertySchemas(proposal);\n if (propertySchemaErrors) {\n return propertySchemaErrors;\n }\n\n // Process through governance\n const { result, updatedVocabulary } = processProposal(\n vocabulary,\n proposal,\n this.governanceConfig,\n { duplicates, proposedBy },\n );\n\n // Persist if approved\n if (result.status === 'approved' && updatedVocabulary) {\n // For delete proposals, cascade-delete data before updating vocabulary\n const isDeleteProposal =\n proposal.proposalType === 'delete_entity_type' ||\n proposal.proposalType === 'delete_relationship_type';\n\n if (isDeleteProposal) {\n await this.cascadeDeleteData(proposal);\n }\n\n await this.storage.saveVocabulary(this.repositoryId, updatedVocabulary);\n this.cachedVocabulary = updatedVocabulary;\n }\n\n return result;\n }\n\n /** @deprecated Use proposeChange instead */\n async proposeExtension(\n proposal: VocabularyProposal,\n proposedBy: string,\n ): Promise<VocabularyProposalResult> {\n return this.proposeChange(proposal, proposedBy);\n }\n\n /** Cascade-delete all data for a deleted vocabulary type */\n private async cascadeDeleteData(\n proposal: VocabularyProposal,\n ): Promise<{ deletedEntities: number; deletedRelationships: number }> {\n if (proposal.proposalType === 'delete_entity_type' && proposal.deleteEntityType) {\n return this.storage.deleteEntitiesByType(\n this.repositoryId,\n proposal.deleteEntityType.type,\n );\n }\n\n if (proposal.proposalType === 'delete_relationship_type' && proposal.deleteRelationshipType) {\n const result = await this.storage.deleteRelationshipsByType(\n this.repositoryId,\n proposal.deleteRelationshipType.type,\n );\n return { deletedEntities: 0, deletedRelationships: result.deletedRelationships };\n }\n\n return { deletedEntities: 0, deletedRelationships: 0 };\n }\n\n /** Validate all property schemas in a proposal — returns a rejected result on the first invalid schema, or undefined if all pass */\n private validateProposalPropertySchemas(proposal: VocabularyProposal): VocabularyProposalResult | undefined {\n const schemas: PropertySchema[] = [];\n let typeName = '';\n\n if (proposal.proposalType === 'entity_type' && proposal.entityType) {\n schemas.push(...(proposal.entityType.properties ?? []));\n typeName = proposal.entityType.type;\n } else if (proposal.proposalType === 'relationship_type' && proposal.relationshipType) {\n schemas.push(...(proposal.relationshipType.properties ?? []));\n typeName = proposal.relationshipType.type;\n } else if (proposal.proposalType === 'edit_entity_type' && proposal.editEntityType) {\n schemas.push(...(proposal.editEntityType.addProperties ?? []));\n schemas.push(...(proposal.editEntityType.updateProperties ?? []));\n typeName = proposal.editEntityType.type;\n } else if (proposal.proposalType === 'edit_relationship_type' && proposal.editRelationshipType) {\n schemas.push(...(proposal.editRelationshipType.addProperties ?? []));\n schemas.push(...(proposal.editRelationshipType.updateProperties ?? []));\n typeName = proposal.editRelationshipType.type;\n }\n\n for (const schema of schemas) {\n const result = validatePropertySchema(schema);\n if (!result.valid) {\n return {\n status: 'rejected',\n type: typeName,\n reason: result.errors.map((e) => e.message).join('; '),\n };\n }\n }\n\n return undefined;\n }\n\n private getExistingTypesForProposal(\n proposal: VocabularyProposal,\n vocabulary: MemoryVocabulary,\n ): ExistingType[] {\n if (proposal.proposalType === 'entity_type') {\n return vocabulary.entityTypes.map((et) => ({\n type: et.type,\n description: et.description,\n }));\n }\n return vocabulary.relationshipTypes.map((rt) => ({\n type: rt.type,\n description: rt.description,\n }));\n }\n\n private getProposedTypeName(proposal: VocabularyProposal): string {\n if (proposal.proposalType === 'entity_type') {\n return proposal.entityType?.type ?? '';\n }\n return proposal.relationshipType?.type ?? '';\n }\n\n private getProposedDescription(proposal: VocabularyProposal): string {\n if (proposal.proposalType === 'entity_type') {\n return proposal.entityType?.description ?? '';\n }\n return proposal.relationshipType?.description ?? '';\n }\n}\n","// ProvenanceTracker — automatic provenance stamping on all mutations\n\nimport type { Provenance, ProvenanceContext } from '../types/provenance.js';\n\n/**\n * Stamps provenance metadata on entities and relationships.\n * The storage provider never needs to worry about provenance —\n * it just stores what it receives from the tracker.\n */\nexport class ProvenanceTracker {\n private context: ProvenanceContext;\n\n constructor(context: ProvenanceContext) {\n this.context = { ...context };\n }\n\n /** Update the active provenance context (e.g., different conversation) */\n updateContext(newContext: Partial<ProvenanceContext>): void {\n this.context = { ...this.context, ...newContext };\n }\n\n /** Get the current provenance context */\n getContext(): ProvenanceContext {\n return { ...this.context };\n }\n\n /** Stamp a newly created entity or relationship with full provenance */\n stampCreate(): Provenance {\n const now = new Date().toISOString();\n return {\n createdBy: this.context.actorId,\n createdByType: this.context.actorType,\n createdAt: now,\n createdInConversation: this.context.conversationId,\n createdFromMessage: this.context.messageId,\n modifiedBy: this.context.actorId,\n modifiedByType: this.context.actorType,\n modifiedAt: now,\n modifiedInConversation: this.context.conversationId,\n modifiedFromMessage: this.context.messageId,\n };\n }\n\n /** Stamp an updated entity or relationship — preserves creation fields, updates modified fields */\n stampUpdate(existing: Provenance): Provenance {\n const now = new Date().toISOString();\n return {\n ...existing,\n modifiedBy: this.context.actorId,\n modifiedByType: this.context.actorType,\n modifiedAt: now,\n modifiedInConversation: this.context.conversationId,\n modifiedFromMessage: this.context.messageId,\n };\n }\n}\n","// EventBus — zero-dependency typed event emitter\n\nimport type {\n DeepMemoryEvent,\n DeepMemoryEventType,\n EventHandler,\n EventPayload,\n HookResult,\n Unsubscribe,\n} from '../types/events.js';\nimport type { ProvenanceContext } from '../types/provenance.js';\n\n/** Pre-mutation event types (those ending in \"ing\") */\ntype PreMutationEvent = Extract<\n DeepMemoryEventType,\n 'entity:creating' | 'entity:updating' | 'entity:deleting' |\n 'relationship:creating' | 'relationship:removing'\n>;\n\n/** Hook handler that can cancel or modify operations */\nexport type HookHandler<T extends PreMutationEvent> = (\n event: DeepMemoryEvent<T>,\n) => HookResult | Promise<HookResult>;\n\nexport class EventBus {\n private handlers = new Map<string, Set<EventHandler<any>>>();\n private hookHandlers = new Map<string, Set<HookHandler<any>>>();\n private provenance: ProvenanceContext;\n private repositoryId?: string;\n\n constructor(provenance: ProvenanceContext, repositoryId?: string) {\n this.provenance = provenance;\n this.repositoryId = repositoryId;\n }\n\n /** Update provenance context (e.g., when conversation changes) */\n updateProvenance(provenance: ProvenanceContext): void {\n this.provenance = provenance;\n }\n\n /** Subscribe to an event. Returns an unsubscribe function. */\n on<E extends DeepMemoryEventType>(event: E, handler: EventHandler<E>): Unsubscribe {\n if (!this.handlers.has(event)) {\n this.handlers.set(event, new Set());\n }\n this.handlers.get(event)!.add(handler);\n\n return () => {\n this.handlers.get(event)?.delete(handler);\n };\n }\n\n /** Register a pre-mutation hook that can cancel operations */\n onHook<E extends PreMutationEvent>(event: E, handler: HookHandler<E>): Unsubscribe {\n if (!this.hookHandlers.has(event)) {\n this.hookHandlers.set(event, new Set());\n }\n this.hookHandlers.get(event)!.add(handler);\n\n return () => {\n this.hookHandlers.get(event)?.delete(handler);\n };\n }\n\n /** Emit an event to all registered handlers */\n async emit<E extends DeepMemoryEventType>(\n event: E,\n payload: EventPayload<E>,\n ): Promise<void> {\n const handlers = this.handlers.get(event);\n if (!handlers || handlers.size === 0) return;\n\n const eventObj: DeepMemoryEvent<E> = {\n type: event,\n timestamp: new Date().toISOString(),\n repositoryId: this.repositoryId,\n provenance: { ...this.provenance },\n payload,\n };\n\n for (const handler of handlers) {\n await handler(eventObj);\n }\n }\n\n /**\n * Emit a pre-mutation hook event.\n * Returns `{ cancelled: false }` if all hooks pass,\n * or `{ cancelled: true, reason }` if any hook cancels.\n */\n async emitHook<E extends PreMutationEvent>(\n event: E,\n payload: EventPayload<E>,\n ): Promise<{ cancelled: boolean; reason?: string }> {\n const hooks = this.hookHandlers.get(event);\n if (!hooks || hooks.size === 0) return { cancelled: false };\n\n const eventObj: DeepMemoryEvent<E> = {\n type: event,\n timestamp: new Date().toISOString(),\n repositoryId: this.repositoryId,\n provenance: { ...this.provenance },\n payload,\n };\n\n for (const hook of hooks) {\n const result = await hook(eventObj);\n if (result.cancel) {\n return { cancelled: true, reason: result.reason };\n }\n }\n\n return { cancelled: false };\n }\n\n /** Remove all listeners and hooks */\n removeAllListeners(): void {\n this.handlers.clear();\n this.hookHandlers.clear();\n }\n}\n","// RepositoryExporter — exports a repository to a portable archive\n\nimport type { StorageProvider } from '../providers/StorageProvider.js';\nimport type { ProvenanceContext } from '../types/provenance.js';\nimport type { ExportArchive, ExportLegalMetadata, ExportManifest, ExportStreamItem } from '../types/portability.js';\nimport { RepositoryNotFoundError } from '../core/errors.js';\nimport type { StoredEntity } from '../types/entities.js';\nimport type { StoredRelationship } from '../types/relationships.js';\n\ndeclare const __DEEP_MEMORY_VERSION__: string | undefined;\n\n/** Injected by tsup at build time; falls back to package.json version in dev/test */\nconst LIBRARY_VERSION: string =\n typeof __DEEP_MEMORY_VERSION__ !== 'undefined'\n ? __DEEP_MEMORY_VERSION__\n : '0.1.0';\n\nexport interface ExporterConfig {\n storage: StorageProvider;\n provenance: ProvenanceContext;\n /** Legal/copyright metadata to embed in the export manifest */\n legal?: ExportLegalMetadata;\n}\n\nexport class RepositoryExporter {\n private readonly storage: StorageProvider;\n private readonly provenance: ProvenanceContext;\n private readonly legal?: ExportLegalMetadata;\n\n constructor(config: ExporterConfig) {\n this.storage = config.storage;\n this.provenance = config.provenance;\n this.legal = config.legal;\n }\n\n /**\n * Stream a repository export as an async generator.\n * Yields: manifest → vocabulary → entity chunks → relationship chunks.\n * The caller can pipe this to a file, zip stream, or HTTP response.\n */\n async *exportStream(repositoryId: string): AsyncGenerator<ExportStreamItem> {\n const repo = await this.storage.getRepository(repositoryId);\n if (!repo) {\n throw new RepositoryNotFoundError(repositoryId);\n }\n\n const vocabulary = await this.storage.getVocabulary(repositoryId);\n const stats = await this.storage.getRepositoryStats(repositoryId);\n\n // Build and yield manifest\n const manifest: ExportManifest = {\n formatVersion: '1.0.0',\n libraryVersion: LIBRARY_VERSION,\n exportedAt: new Date().toISOString(),\n exportedBy: this.provenance,\n repository: {\n repositoryId,\n type: repo.type,\n label: repo.label,\n description: repo.description,\n vocabularyVersion: vocabulary.version,\n governanceMode: repo.governanceConfig.mode,\n },\n statistics: {\n entityCount: stats.entityCount,\n relationshipCount: stats.relationshipCount,\n entityTypeBreakdown: stats.entityTypeBreakdown,\n relationshipTypeBreakdown: stats.relationshipTypeBreakdown,\n },\n };\n\n // Legal metadata — set by the publisher of the archive\n if (this.legal) {\n manifest.legal = this.legal;\n }\n\n // Embedding metadata from the repository record — no live provider needed\n if (repo.metadata?.embeddingModelId) {\n manifest.embedding = {\n modelId: repo.metadata.embeddingModelId,\n dimensions: (repo.metadata.embeddingDimensions as number) ?? 0,\n note: 'Embeddings are model-specific. Re-embed after import if using a different model.',\n };\n }\n\n yield { type: 'manifest', data: manifest };\n yield { type: 'vocabulary', data: vocabulary };\n\n // Stream entity and relationship chunks from the storage provider\n for await (const chunk of this.storage.exportAll(repositoryId)) {\n if (chunk.type === 'entities') {\n yield {\n type: 'entities',\n data: chunk.data as StoredEntity[],\n sequence: chunk.sequence,\n isLast: chunk.isLast,\n };\n } else {\n yield {\n type: 'relationships',\n data: chunk.data as StoredRelationship[],\n sequence: chunk.sequence,\n isLast: chunk.isLast,\n };\n }\n }\n }\n\n /**\n * Export a repository to a complete in-memory archive.\n * Convenience wrapper around exportStream() — use for small repositories.\n * For large repositories, use exportStream() directly.\n */\n async export(repositoryId: string): Promise<ExportArchive> {\n let manifest: ExportManifest | undefined;\n let vocabulary: import('../types/vocabulary.js').MemoryVocabulary | undefined;\n const entities: StoredEntity[] = [];\n const relationships: StoredRelationship[] = [];\n\n for await (const item of this.exportStream(repositoryId)) {\n switch (item.type) {\n case 'manifest':\n manifest = item.data;\n break;\n case 'vocabulary':\n vocabulary = item.data;\n break;\n case 'entities':\n entities.push(...item.data);\n break;\n case 'relationships':\n relationships.push(...item.data);\n break;\n }\n }\n\n return {\n manifest: manifest!,\n vocabulary: vocabulary!,\n entities,\n relationships,\n };\n }\n}\n","// VocabularyDiff — computes diffs between two vocabulary versions\n\nimport type {\n EntityTypeDefinition,\n MemoryVocabulary,\n PropertySchema,\n RelationshipTypeDefinition,\n} from '../types/vocabulary.js';\n\n/** A single change in a vocabulary diff */\nexport interface VocabularyChange {\n changeType: 'added' | 'removed' | 'modified';\n category: 'entity_type' | 'relationship_type';\n typeName: string;\n details?: string;\n}\n\n/** Complete diff between two vocabulary versions */\nexport interface VocabularyDiffResult {\n fromVersion: string;\n toVersion: string;\n changes: VocabularyChange[];\n hasChanges: boolean;\n}\n\n/** Compute the diff between two vocabulary versions */\nexport function diffVocabularies(\n from: MemoryVocabulary,\n to: MemoryVocabulary,\n): VocabularyDiffResult {\n const changes: VocabularyChange[] = [];\n\n // Entity type diffs\n diffTypes(\n from.entityTypes,\n to.entityTypes,\n 'entity_type',\n diffEntityType,\n changes,\n );\n\n // Relationship type diffs\n diffTypes(\n from.relationshipTypes,\n to.relationshipTypes,\n 'relationship_type',\n diffRelationshipType,\n changes,\n );\n\n return {\n fromVersion: from.version,\n toVersion: to.version,\n changes,\n hasChanges: changes.length > 0,\n };\n}\n\nfunction diffTypes<T extends { type: string }>(\n fromTypes: T[],\n toTypes: T[],\n category: 'entity_type' | 'relationship_type',\n detailDiff: (from: T, to: T) => string | null,\n changes: VocabularyChange[],\n): void {\n const fromMap = new Map(fromTypes.map((t) => [t.type, t]));\n const toMap = new Map(toTypes.map((t) => [t.type, t]));\n\n // Added types\n for (const [typeName] of toMap) {\n if (!fromMap.has(typeName)) {\n changes.push({ changeType: 'added', category, typeName });\n }\n }\n\n // Removed types\n for (const [typeName] of fromMap) {\n if (!toMap.has(typeName)) {\n changes.push({ changeType: 'removed', category, typeName });\n }\n }\n\n // Modified types\n for (const [typeName, fromType] of fromMap) {\n const toType = toMap.get(typeName);\n if (!toType) continue;\n\n const details = detailDiff(fromType, toType);\n if (details) {\n changes.push({ changeType: 'modified', category, typeName, details });\n }\n }\n}\n\nfunction diffEntityType(\n from: EntityTypeDefinition,\n to: EntityTypeDefinition,\n): string | null {\n const diffs: string[] = [];\n\n if (from.description !== to.description) {\n diffs.push('description changed');\n }\n\n const propDiff = diffPropertySchemas(from.properties, to.properties);\n if (propDiff) {\n diffs.push(propDiff);\n }\n\n return diffs.length > 0 ? diffs.join('; ') : null;\n}\n\nfunction diffRelationshipType(\n from: RelationshipTypeDefinition,\n to: RelationshipTypeDefinition,\n): string | null {\n const diffs: string[] = [];\n\n if (from.description !== to.description) {\n diffs.push('description changed');\n }\n\n if (from.bidirectional !== to.bidirectional) {\n diffs.push(`bidirectional: ${from.bidirectional} → ${to.bidirectional}`);\n }\n\n const srcDiff = diffArrays(from.allowedSourceTypes, to.allowedSourceTypes);\n if (srcDiff) diffs.push(`allowedSourceTypes: ${srcDiff}`);\n\n const tgtDiff = diffArrays(from.allowedTargetTypes, to.allowedTargetTypes);\n if (tgtDiff) diffs.push(`allowedTargetTypes: ${tgtDiff}`);\n\n const propDiff = diffPropertySchemas(from.properties ?? [], to.properties ?? []);\n if (propDiff) diffs.push(propDiff);\n\n return diffs.length > 0 ? diffs.join('; ') : null;\n}\n\nfunction diffPropertySchemas(from: PropertySchema[], to: PropertySchema[]): string | null {\n const fromMap = new Map(from.map((p) => [p.name, p]));\n const toMap = new Map(to.map((p) => [p.name, p]));\n const parts: string[] = [];\n\n for (const [name] of toMap) {\n if (!fromMap.has(name)) parts.push(`property \"${name}\" added`);\n }\n\n for (const [name] of fromMap) {\n if (!toMap.has(name)) parts.push(`property \"${name}\" removed`);\n }\n\n for (const [name, fromProp] of fromMap) {\n const toProp = toMap.get(name);\n if (!toProp) continue;\n\n if (fromProp.type !== toProp.type) {\n parts.push(`property \"${name}\" type: ${fromProp.type} → ${toProp.type}`);\n }\n if (fromProp.required !== toProp.required) {\n parts.push(`property \"${name}\" required: ${fromProp.required} → ${toProp.required}`);\n }\n }\n\n return parts.length > 0 ? parts.join(', ') : null;\n}\n\nfunction diffArrays(from: string[], to: string[]): string | null {\n const fromSet = new Set(from);\n const toSet = new Set(to);\n const added = to.filter((t) => !fromSet.has(t));\n const removed = from.filter((f) => !toSet.has(f));\n\n const parts: string[] = [];\n if (added.length > 0) parts.push(`+[${added.join(', ')}]`);\n if (removed.length > 0) parts.push(`-[${removed.join(', ')}]`);\n\n return parts.length > 0 ? parts.join(' ') : null;\n}\n","// MigrationEngine — handles vocabulary differences between source and target repositories\n\nimport type { MemoryVocabulary } from '../types/vocabulary.js';\nimport type { ImportWarning } from '../types/portability.js';\nimport {\n diffVocabularies,\n type VocabularyChange,\n} from '../vocabulary/VocabularyDiff.js';\nimport {\n createEntityTypeDefinition,\n createRelationshipTypeDefinition,\n incrementVersion,\n} from '../vocabulary/VocabularySchema.js';\n\n/** How to handle vocabulary conflicts */\nexport type VocabularyConflictMode = 'reject' | 'extend' | 'prompt';\n\nexport interface MigrationResult {\n /** Whether migration succeeded */\n success: boolean;\n /** The merged vocabulary (only if success) */\n mergedVocabulary?: MemoryVocabulary;\n /** Warnings generated during migration */\n warnings: ImportWarning[];\n /** Rejection reason (only if success === false) */\n reason?: string;\n}\n\nexport class MigrationEngine {\n /**\n * Analyze and migrate vocabulary differences between source and target.\n *\n * @param sourceVocabulary - vocabulary from the export archive\n * @param targetVocabulary - vocabulary in the target repository\n * @param conflictMode - how to handle differences\n * @param migratedBy - actor performing the migration\n */\n migrate(\n sourceVocabulary: MemoryVocabulary,\n targetVocabulary: MemoryVocabulary,\n conflictMode: VocabularyConflictMode,\n migratedBy: string,\n ): MigrationResult {\n const diff = diffVocabularies(targetVocabulary, sourceVocabulary);\n\n // No changes needed\n if (!diff.hasChanges) {\n return { success: true, mergedVocabulary: targetVocabulary, warnings: [] };\n }\n\n const warnings: ImportWarning[] = [];\n\n switch (conflictMode) {\n case 'reject':\n return {\n success: false,\n warnings: [],\n reason: `Vocabulary mismatch: ${diff.changes.length} difference(s) found. ` +\n `Changes: ${diff.changes.map(describeChange).join('; ')}`,\n };\n\n case 'prompt':\n return {\n success: false,\n warnings: diff.changes.map((c) => ({\n code: 'vocabulary_mismatch',\n message: describeChange(c),\n })),\n reason: 'Vocabulary differences require manual resolution',\n };\n\n case 'extend': {\n // Merge: add new types from source, warn about conflicts\n const merged = this.extendVocabulary(\n sourceVocabulary,\n targetVocabulary,\n diff.changes,\n migratedBy,\n warnings,\n );\n return { success: true, mergedVocabulary: merged, warnings };\n }\n }\n }\n\n /** Extend the target vocabulary with types from the source */\n private extendVocabulary(\n source: MemoryVocabulary,\n target: MemoryVocabulary,\n changes: VocabularyChange[],\n migratedBy: string,\n warnings: ImportWarning[],\n ): MemoryVocabulary {\n // Start with a copy of the target\n const merged: MemoryVocabulary = {\n ...target,\n entityTypes: [...target.entityTypes],\n relationshipTypes: [...target.relationshipTypes],\n };\n\n for (const change of changes) {\n if (change.changeType === 'added') {\n // Type exists in source but not target — add it\n if (change.category === 'entity_type') {\n const sourceType = source.entityTypes.find((t) => t.type === change.typeName);\n if (sourceType) {\n merged.entityTypes.push(\n createEntityTypeDefinition(\n { type: sourceType.type, description: sourceType.description, properties: sourceType.properties },\n migratedBy,\n ),\n );\n warnings.push({\n code: 'entity_type_added',\n message: `Entity type \"${change.typeName}\" added from source vocabulary`,\n });\n }\n } else {\n const sourceType = source.relationshipTypes.find((t) => t.type === change.typeName);\n if (sourceType) {\n merged.relationshipTypes.push(\n createRelationshipTypeDefinition(\n {\n type: sourceType.type,\n description: sourceType.description,\n allowedSourceTypes: sourceType.allowedSourceTypes,\n allowedTargetTypes: sourceType.allowedTargetTypes,\n bidirectional: sourceType.bidirectional,\n properties: sourceType.properties,\n },\n migratedBy,\n ),\n );\n warnings.push({\n code: 'relationship_type_added',\n message: `Relationship type \"${change.typeName}\" added from source vocabulary`,\n });\n }\n }\n } else if (change.changeType === 'modified') {\n // Type exists in both but differs — keep target version, warn\n warnings.push({\n code: 'vocabulary_conflict',\n message: `Type \"${change.typeName}\" differs between source and target: ${change.details ?? 'unknown'}. Target version kept.`,\n });\n } else if (change.changeType === 'removed') {\n // Type exists in target but not source — keep it, no action needed\n warnings.push({\n code: 'vocabulary_extra',\n message: `Type \"${change.typeName}\" exists in target but not in source — kept as-is`,\n });\n }\n }\n\n // Use the higher of the source version or the incremented target version,\n // so importing into an empty repo preserves the source version.\n const bumped = incrementVersion(merged.version, 'minor');\n merged.version = compareVersions(source.version, bumped) > 0 ? source.version : bumped;\n merged.lastModified = new Date().toISOString();\n merged.modifiedBy = migratedBy;\n\n return merged;\n }\n}\n\n/** Compare two semver strings. Returns >0 if a > b, <0 if a < b, 0 if equal. */\nfunction compareVersions(a: string, b: string): number {\n const pa = a.split('.').map(Number);\n const pb = b.split('.').map(Number);\n for (let i = 0; i < 3; i++) {\n const diff = (pa[i] ?? 0) - (pb[i] ?? 0);\n if (diff !== 0) return diff;\n }\n return 0;\n}\n\nfunction describeChange(change: VocabularyChange): string {\n const label = change.category === 'entity_type' ? 'entity type' : 'relationship type';\n switch (change.changeType) {\n case 'added':\n return `${label} \"${change.typeName}\" exists in source but not target`;\n case 'removed':\n return `${label} \"${change.typeName}\" exists in target but not source`;\n case 'modified':\n return `${label} \"${change.typeName}\" differs: ${change.details ?? 'unknown'}`;\n }\n}\n","// RepositoryImporter — imports an export archive into a repository\n\nimport type { StorageProvider } from '../providers/StorageProvider.js';\nimport type {\n ExportArchive,\n ImportOptions,\n ImportResult,\n ImportWarning,\n ImportChunk,\n ImportStreamHeader,\n} from '../types/portability.js';\nimport type { RepositoryConfig } from '../types/repositories.js';\nimport { MigrationEngine } from './MigrationEngine.js';\nimport { generateId } from '../core/DeepMemory.js';\nimport { DuplicateRelationshipError } from '../core/errors.js';\n\n/** Progress info emitted after each chunk is processed */\nexport interface ImportProgress {\n repositoryId: string;\n entitiesImported: number;\n relationshipsImported: number;\n totalEntities: number;\n totalRelationships: number;\n chunksCompleted: number;\n totalChunks: number;\n}\n\nexport interface ImporterConfig {\n storage: StorageProvider;\n actorId: string;\n /** Called after each chunk is processed — wire to EventBus or progress UI */\n onProgress?: (progress: ImportProgress) => void | Promise<void>;\n}\n\n/** Estimate total chunks from entity + relationship counts */\nfunction estimateChunkCount(totalEntities: number, totalRelationships: number): number {\n const ESTIMATED_CHUNK_SIZE = 100;\n return Math.max(\n 1,\n Math.ceil(totalEntities / ESTIMATED_CHUNK_SIZE) + Math.ceil(totalRelationships / ESTIMATED_CHUNK_SIZE),\n );\n}\n\nexport class RepositoryImporter {\n private readonly storage: StorageProvider;\n private readonly actorId: string;\n private readonly onProgress?: (progress: ImportProgress) => void | Promise<void>;\n private readonly migrationEngine = new MigrationEngine();\n\n constructor(config: ImporterConfig) {\n this.storage = config.storage;\n this.actorId = config.actorId;\n this.onProgress = config.onProgress;\n }\n\n /**\n * Import an export archive according to the provided options.\n * Convenience wrapper around importStream() — use for small repositories.\n * For large repositories, use importStream() directly.\n */\n async import(archive: ExportArchive, options: ImportOptions): Promise<ImportResult> {\n const validationWarnings = this.validateArchive(archive);\n if (validationWarnings.length > 0) {\n // If basic validation fails, return early\n const hasCritical = validationWarnings.some((w) => w.code === 'invalid_archive');\n if (hasCritical) {\n return {\n success: false,\n repositoryId: options.target.repositoryId,\n statistics: { entitiesImported: 0, entitiesSkipped: 0, relationshipsImported: 0, relationshipsSkipped: 0, vocabularyExtensions: 0 },\n warnings: validationWarnings,\n };\n }\n }\n\n const header: ImportStreamHeader = {\n manifest: archive.manifest,\n vocabulary: archive.vocabulary,\n };\n\n // Convert the archive arrays into a single chunk\n async function* toChunks(): AsyncGenerator<ImportChunk> {\n yield { entities: archive.entities };\n yield { relationships: archive.relationships };\n }\n\n return this.importStream(header, toChunks(), options);\n }\n\n /**\n * Streaming import — processes data from an async iterable of chunks.\n * For large repositories, this avoids loading everything into memory at once.\n *\n * The caller provides the header (manifest + vocabulary) up front,\n * then streams ImportChunks containing batches of entities and/or relationships.\n */\n async importStream(\n header: ImportStreamHeader,\n chunks: AsyncIterable<ImportChunk>,\n options: ImportOptions,\n ): Promise<ImportResult> {\n const warnings: ImportWarning[] = [];\n\n if (!header.manifest) {\n warnings.push({ code: 'invalid_archive', message: 'Header is missing manifest' });\n }\n if (!header.vocabulary) {\n warnings.push({ code: 'invalid_archive', message: 'Header is missing vocabulary' });\n }\n\n if (options.target.mode === 'create') {\n return this.importStreamCreate(header, chunks, options, warnings);\n } else {\n return this.importStreamMerge(header, chunks, options, warnings);\n }\n }\n\n /** Streaming create mode — fast bulk inserts with no existence checks */\n private async importStreamCreate(\n header: ImportStreamHeader,\n chunks: AsyncIterable<ImportChunk>,\n options: ImportOptions,\n warnings: ImportWarning[],\n ): Promise<ImportResult> {\n const target = options.target as { mode: 'create'; repositoryId: string; config: RepositoryConfig };\n\n // Create the repository if it doesn't already exist\n const existing = await this.storage.getRepository(target.repositoryId);\n if (!existing) {\n const now = new Date().toISOString();\n await this.storage.createRepository({\n repositoryId: target.repositoryId,\n type: target.config.type,\n label: target.config.label,\n description: target.config.description,\n governanceConfig: target.config.governance ?? { mode: 'open' },\n createdAt: now,\n createdBy: this.actorId,\n });\n }\n\n // Save the vocabulary from the header\n await this.storage.saveVocabulary(target.repositoryId, header.vocabulary);\n\n // Process chunks incrementally — skip existence checks since the repo is freshly created\n const totalEntities = header.manifest?.statistics?.entityCount ?? 0;\n const totalRelationships = header.manifest?.statistics?.relationshipCount ?? 0;\n const totalChunks = estimateChunkCount(totalEntities, totalRelationships);\n let entitiesImported = 0;\n let relationshipsImported = 0;\n let chunksCompleted = 0;\n\n for await (const chunk of chunks) {\n const bulkResult = await this.storage.importBulk(target.repositoryId, [chunk], { skipExistenceCheck: true });\n entitiesImported += bulkResult.entitiesImported;\n relationshipsImported += bulkResult.relationshipsImported;\n chunksCompleted++;\n\n for (const e of bulkResult.errors) {\n warnings.push({\n code: 'import_error',\n message: `Failed to import ${e.item}: ${e.error}`,\n id: e.item,\n });\n }\n\n await this.onProgress?.({\n repositoryId: target.repositoryId,\n entitiesImported,\n relationshipsImported,\n totalEntities,\n totalRelationships,\n chunksCompleted,\n totalChunks,\n });\n }\n\n return {\n success: true,\n repositoryId: target.repositoryId,\n statistics: {\n entitiesImported,\n entitiesSkipped: 0,\n relationshipsImported,\n relationshipsSkipped: 0,\n vocabularyExtensions: 0,\n },\n warnings,\n };\n }\n\n /** Streaming merge mode — process chunks with per-entity conflict resolution */\n private async importStreamMerge(\n header: ImportStreamHeader,\n chunks: AsyncIterable<ImportChunk>,\n options: ImportOptions,\n warnings: ImportWarning[],\n ): Promise<ImportResult> {\n const target = options.target as { mode: 'merge'; repositoryId: string };\n const repositoryId = target.repositoryId;\n\n // Verify target exists\n const existingRepo = await this.storage.getRepository(repositoryId);\n if (!existingRepo) {\n return {\n success: false,\n repositoryId,\n statistics: { entitiesImported: 0, entitiesSkipped: 0, relationshipsImported: 0, relationshipsSkipped: 0, vocabularyExtensions: 0 },\n warnings: [{ code: 'repository_not_found', message: `Repository \"${repositoryId}\" not found` }],\n };\n }\n\n // Handle vocabulary migration\n const targetVocabulary = await this.storage.getVocabulary(repositoryId);\n const conflictMode = options.vocabularyConflict ?? 'reject';\n const migrationResult = this.migrationEngine.migrate(\n header.vocabulary,\n targetVocabulary,\n conflictMode,\n this.actorId,\n );\n\n warnings.push(...migrationResult.warnings);\n\n if (!migrationResult.success) {\n return {\n success: false,\n repositoryId,\n statistics: { entitiesImported: 0, entitiesSkipped: 0, relationshipsImported: 0, relationshipsSkipped: 0, vocabularyExtensions: 0 },\n warnings: [...warnings, { code: 'vocabulary_migration_failed', message: migrationResult.reason ?? 'Vocabulary migration failed' }],\n };\n }\n\n if (migrationResult.mergedVocabulary && migrationResult.mergedVocabulary !== targetVocabulary) {\n await this.storage.saveVocabulary(repositoryId, migrationResult.mergedVocabulary);\n }\n\n // Process chunks incrementally with conflict resolution\n const totalEntities = header.manifest?.statistics?.entityCount ?? 0;\n const totalRelationships = header.manifest?.statistics?.relationshipCount ?? 0;\n const totalChunks = estimateChunkCount(totalEntities, totalRelationships);\n const entityConflict = options.entityConflict ?? 'skip';\n let entitiesImported = 0;\n let entitiesSkipped = 0;\n let relationshipsImported = 0;\n let relationshipsSkipped = 0;\n let chunksCompleted = 0;\n\n for await (const chunk of chunks) {\n // Process entities in this chunk\n if (chunk.entities) {\n for (const entity of chunk.entities) {\n // Check for conflict by GUID first, then fall back to slug match\n let existing = await this.storage.getEntity(repositoryId, entity.id);\n if (!existing && entity.slug) {\n existing = await this.storage.getEntityBySlug(repositoryId, entity.slug);\n }\n\n if (existing) {\n const existingId = existing.id;\n switch (entityConflict) {\n case 'skip':\n entitiesSkipped++;\n warnings.push({\n code: 'entity_skipped',\n message: `Entity \"${entity.slug}\" already exists — skipped`,\n id: existingId,\n });\n continue;\n\n case 'overwrite':\n await this.storage.updateEntity(repositoryId, existingId, {\n label: entity.label,\n slug: entity.slug,\n summary: entity.summary,\n properties: entity.properties,\n data: entity.data,\n dataFormat: entity.dataFormat,\n provenance: entity.provenance,\n embedding: entity.embedding,\n });\n entitiesImported++;\n warnings.push({\n code: 'entity_overwritten',\n message: `Entity \"${entity.slug}\" overwritten`,\n id: existingId,\n });\n continue;\n\n case 'rename': {\n // Create a new entity with a new GUID and modified slug to avoid collision\n const renamedEntity = { ...entity, id: generateId(), slug: `${entity.slug}-imported` };\n await this.storage.createEntity(repositoryId, renamedEntity);\n entitiesImported++;\n warnings.push({\n code: 'entity_renamed',\n message: `Entity \"${entity.slug}\" slug renamed to \"${renamedEntity.slug}\"`,\n id: entity.id,\n });\n continue;\n }\n }\n } else {\n await this.storage.createEntity(repositoryId, entity);\n entitiesImported++;\n }\n }\n }\n\n // Process relationships in this chunk\n if (chunk.relationships) {\n for (const rel of chunk.relationships) {\n const existing = await this.storage.getRelationship(repositoryId, rel.id);\n\n if (existing) {\n relationshipsSkipped++;\n warnings.push({\n code: 'relationship_skipped',\n message: `Relationship \"${rel.id}\" already exists — skipped`,\n relationshipId: rel.id,\n });\n } else {\n const sourceExists = await this.storage.getEntity(repositoryId, rel.sourceEntityId);\n const targetExists = await this.storage.getEntity(repositoryId, rel.targetEntityId);\n\n if (!sourceExists || !targetExists) {\n relationshipsSkipped++;\n warnings.push({\n code: 'relationship_orphaned',\n message: `Relationship \"${rel.id}\" skipped — source or target entity missing`,\n relationshipId: rel.id,\n });\n } else {\n try {\n await this.storage.createRelationship(repositoryId, rel);\n relationshipsImported++;\n } catch (err) {\n // Storage layers may enforce composite uniqueness (e.g. source+target+type)\n // that getRelationship() by ID cannot detect. Treat as skip+warning,\n // consistent with the duplicate-by-id branch above.\n if (err instanceof DuplicateRelationshipError) {\n relationshipsSkipped++;\n warnings.push({\n code: 'relationship_skipped',\n message: `Relationship \"${rel.id}\" already exists — skipped`,\n relationshipId: rel.id,\n });\n } else {\n throw err;\n }\n }\n }\n }\n }\n }\n\n chunksCompleted++;\n await this.onProgress?.({\n repositoryId,\n entitiesImported,\n relationshipsImported,\n totalEntities,\n totalRelationships,\n chunksCompleted,\n totalChunks,\n });\n }\n\n const vocabExtensions = migrationResult.warnings.filter(\n (w) => w.code === 'entity_type_added' || w.code === 'relationship_type_added',\n ).length;\n\n return {\n success: true,\n repositoryId,\n statistics: {\n entitiesImported,\n entitiesSkipped,\n relationshipsImported,\n relationshipsSkipped,\n vocabularyExtensions: vocabExtensions,\n },\n warnings,\n };\n }\n\n /** Basic archive validation */\n private validateArchive(archive: ExportArchive): ImportWarning[] {\n const warnings: ImportWarning[] = [];\n\n if (!archive.manifest) {\n warnings.push({ code: 'invalid_archive', message: 'Archive is missing manifest' });\n }\n if (!archive.vocabulary) {\n warnings.push({ code: 'invalid_archive', message: 'Archive is missing vocabulary' });\n }\n if (!archive.entities) {\n warnings.push({ code: 'invalid_archive', message: 'Archive is missing entities array' });\n }\n if (!archive.relationships) {\n warnings.push({ code: 'invalid_archive', message: 'Archive is missing relationships array' });\n }\n\n return warnings;\n }\n}\n","// safeSink — wraps a UsageSink so provider code can invoke it without\n// worrying that a buggy caller implementation will break the storage call.\n\nimport type { UsageSink } from '../types/usage.js';\n\n/**\n * Wrap a sink with try/catch so a throwing caller sink never aborts the\n * underlying operation. Errors from the caller's sink are silently swallowed;\n * if the caller cares about internal failures they can catch in their own\n * implementation.\n *\n * Returns `undefined` if the input sink is `undefined`, letting providers\n * cheaply skip sink machinery when nobody is listening.\n */\nexport function createSafeSink(sink: UsageSink | undefined): UsageSink | undefined {\n if (!sink) return undefined;\n return (usage) => {\n try {\n sink(usage);\n } catch {\n // Deliberately swallowed — a failing caller sink must never abort the\n // provider operation it was observing.\n }\n };\n}\n","// GremlinCompiler — compiles TraversalSpec to Gremlin query strings\n// Zero runtime dependencies — pure string construction with parameterized bindings.\n\nimport type { TraversalSpec, TraversalStep } from '../../types/traversal.js';\nimport type { MemoryVocabulary } from '../../types/vocabulary.js';\nimport type { PropertyFilter } from '../../types/queries.js';\nimport type { TraversalCompiler, CompiledQuery } from './TraversalCompiler.js';\n\nconst DEFAULT_ESTIMATED_FANOUT_PER_HOP = 10;\n\nexport class GremlinCompiler implements TraversalCompiler {\n readonly language = 'gremlin' as const;\n\n compile(spec: TraversalSpec, _vocabulary: MemoryVocabulary): CompiledQuery {\n const parts: string[] = [];\n const params: Record<string, unknown> = {};\n let paramIndex = 0;\n let estimatedFanOut = 1;\n\n const nextParam = (value: unknown): string => {\n const name = `p${paramIndex++}`;\n params[name] = value;\n return name;\n };\n\n // ─── Start ──────────────────────────────────────────────────\n\n parts.push('g.V()');\n\n if (spec.start.entityId) {\n const p = nextParam(spec.start.entityId);\n parts.push(`.has('id', ${p})`);\n } else if (spec.start.entityType) {\n const p = nextParam(spec.start.entityType);\n parts.push(`.has('entityType', ${p})`);\n estimatedFanOut *= DEFAULT_ESTIMATED_FANOUT_PER_HOP;\n }\n\n if (spec.start.filter) {\n for (const f of spec.start.filter) {\n parts.push(compilePropertyFilter(f, nextParam));\n }\n }\n\n // ─── Steps ──────────────────────────────────────────────────\n\n const steps = spec.steps ?? [];\n for (const step of steps) {\n if (step.repeat) {\n parts.push(compileRepeatStep(step, nextParam));\n estimatedFanOut *= step.repeat.maxDepth * DEFAULT_ESTIMATED_FANOUT_PER_HOP;\n } else if (step.relationshipFilter && step.relationshipFilter.length > 0) {\n // Edge-explicit traversal for relationship property filters\n parts.push(compileEdgeStep(step, nextParam));\n estimatedFanOut *= DEFAULT_ESTIMATED_FANOUT_PER_HOP;\n } else {\n parts.push(compileSimpleStep(step, nextParam));\n estimatedFanOut *= DEFAULT_ESTIMATED_FANOUT_PER_HOP;\n }\n\n // Entity type filter on target vertices\n if (step.entityTypes && step.entityTypes.length > 0) {\n const typeParams = step.entityTypes.map((t) => nextParam(t));\n parts.push(`.has('entityType', within(${typeParams.join(', ')}))`);\n }\n\n // Entity property filters on target vertices\n if (step.entityFilter) {\n for (const f of step.entityFilter) {\n parts.push(compilePropertyFilter(f, nextParam));\n }\n }\n }\n\n // ─── Return mode modifiers ──────────────────────────────────\n\n if (spec.returnMode === 'all') {\n // emit() at each step is handled within repeat; for non-repeat this is implicit\n }\n\n if (spec.dedup !== false) {\n parts.push('.dedup()');\n }\n\n // ─── Pagination ─────────────────────────────────────────────\n\n const limit = spec.limit ?? 50;\n const offset = spec.offset ?? 0;\n const pOffset = nextParam(offset);\n const pEnd = nextParam(offset + limit);\n parts.push(`.range(${pOffset}, ${pEnd})`);\n\n params['_limit'] = limit;\n params['_offset'] = offset;\n\n // ─── Path mode ──────────────────────────────────────────────\n\n if (spec.returnMode === 'path') {\n parts.push('.path()');\n }\n\n // ─── Value projection ───────────────────────────────────────\n\n if (spec.returnMode !== 'path') {\n parts.push('.valueMap(true)');\n }\n\n return {\n query: parts.join(''),\n params,\n estimatedFanOut: Math.min(estimatedFanOut, 10000),\n };\n }\n}\n\n/** Compile a simple vertex-to-vertex step (no relationship property filters). */\nfunction compileSimpleStep(\n step: TraversalStep,\n nextParam: (value: unknown) => string,\n): string {\n const types = step.relationshipTypes;\n const typeArgs = types ? types.map((t) => nextParam(t)).join(', ') : '';\n\n switch (step.direction) {\n case 'out':\n return types ? `.out(${typeArgs})` : '.out()';\n case 'in':\n return types ? `.in(${typeArgs})` : '.in()';\n case 'both':\n return types ? `.both(${typeArgs})` : '.both()';\n }\n}\n\n/** Compile an edge-explicit step for relationship property filtering. */\nfunction compileEdgeStep(\n step: TraversalStep,\n nextParam: (value: unknown) => string,\n): string {\n const parts: string[] = [];\n const types = step.relationshipTypes;\n const typeArgs = types ? types.map((t) => nextParam(t)).join(', ') : '';\n\n // Edge traversal\n switch (step.direction) {\n case 'out':\n parts.push(types ? `.outE(${typeArgs})` : '.outE()');\n break;\n case 'in':\n parts.push(types ? `.inE(${typeArgs})` : '.inE()');\n break;\n case 'both':\n parts.push(types ? `.bothE(${typeArgs})` : '.bothE()');\n break;\n }\n\n // Relationship property filters on the edge\n if (step.relationshipFilter) {\n for (const f of step.relationshipFilter) {\n parts.push(compilePropertyFilter(f, nextParam));\n }\n }\n\n // Traverse to the target vertex\n switch (step.direction) {\n case 'out':\n parts.push('.inV()');\n break;\n case 'in':\n parts.push('.outV()');\n break;\n case 'both':\n parts.push('.otherV()');\n break;\n }\n\n return parts.join('');\n}\n\n/** Compile a repeat/loop step. */\nfunction compileRepeatStep(\n step: TraversalStep,\n nextParam: (value: unknown) => string,\n): string {\n const parts: string[] = [];\n const innerStep = step.relationshipFilter?.length\n ? compileEdgeStep({ ...step, repeat: undefined }, nextParam)\n : compileSimpleStep(step, nextParam);\n\n // emit() placement: before repeat for intermediates, after for terminal-only\n if (step.repeat?.emitIntermediates !== false) {\n parts.push('.emit()');\n }\n\n parts.push(`.repeat(${innerStep.startsWith('.') ? `__${innerStep}` : innerStep})`);\n\n // Until condition\n if (step.repeat?.until && step.repeat.until.length > 0) {\n const untilParts = step.repeat.until.map((f) => compilePropertyFilter(f, nextParam));\n parts.push(`.until(${untilParts.join('')})`);\n }\n\n // Max depth via times()\n if (step.repeat?.maxDepth) {\n const p = nextParam(step.repeat.maxDepth);\n parts.push(`.times(${p})`);\n }\n\n if (step.repeat?.emitIntermediates === false) {\n parts.push('.emit()');\n }\n\n return parts.join('');\n}\n\n/** Compile a single property filter to a Gremlin .has() predicate. */\nfunction compilePropertyFilter(\n filter: PropertyFilter,\n nextParam: (value: unknown) => string,\n): string {\n const key = nextParam(filter.key);\n\n switch (filter.operator) {\n case 'eq': {\n const val = nextParam(filter.value);\n return `.has(${key}, ${val})`;\n }\n case 'neq': {\n const val = nextParam(filter.value);\n return `.has(${key}, neq(${val}))`;\n }\n case 'gt': {\n const val = nextParam(filter.value);\n return `.has(${key}, gt(${val}))`;\n }\n case 'gte': {\n const val = nextParam(filter.value);\n return `.has(${key}, gte(${val}))`;\n }\n case 'lt': {\n const val = nextParam(filter.value);\n return `.has(${key}, lt(${val}))`;\n }\n case 'lte': {\n const val = nextParam(filter.value);\n return `.has(${key}, lte(${val}))`;\n }\n case 'contains': {\n const val = nextParam(filter.value);\n return `.has(${key}, containing(${val}))`;\n }\n case 'isNull':\n return `.hasNot(${key})`;\n case 'isNotNull':\n return `.has(${key})`;\n }\n}\n","// CypherCompiler — compiles TraversalSpec to Cypher query strings\n// Zero runtime dependencies — pure string construction with parameterized bindings.\n\nimport type { TraversalSpec } from '../../types/traversal.js';\nimport type { MemoryVocabulary } from '../../types/vocabulary.js';\nimport type { PropertyFilter } from '../../types/queries.js';\nimport type { TraversalCompiler, CompiledQuery } from './TraversalCompiler.js';\n\nconst DEFAULT_ESTIMATED_FANOUT_PER_HOP = 10;\n\nexport class CypherCompiler implements TraversalCompiler {\n readonly language = 'cypher' as const;\n\n compile(spec: TraversalSpec, _vocabulary: MemoryVocabulary): CompiledQuery {\n const params: Record<string, unknown> = {};\n let paramIndex = 0;\n let estimatedFanOut = 1;\n const whereClauses: string[] = [];\n let nodeIndex = 0;\n\n const nextParam = (value: unknown): string => {\n const name = `p${paramIndex++}`;\n params[name] = value;\n return `$${name}`;\n };\n\n // ─── Start ──────────────────────────────────────────────────\n\n const startNode = `n${nodeIndex++}`;\n let matchParts: string[] = [];\n\n if (spec.start.entityId) {\n matchParts.push(`(${startNode})`);\n whereClauses.push(`${startNode}.id = ${nextParam(spec.start.entityId)}`);\n } else if (spec.start.entityType) {\n matchParts.push(`(${startNode})`);\n whereClauses.push(`${startNode}.entityType = ${nextParam(spec.start.entityType)}`);\n estimatedFanOut *= DEFAULT_ESTIMATED_FANOUT_PER_HOP;\n } else {\n matchParts.push(`(${startNode})`);\n }\n\n if (spec.start.filter) {\n for (const f of spec.start.filter) {\n whereClauses.push(compilePropertyFilterCypher(startNode, f, nextParam));\n }\n }\n\n // ─── Steps ──────────────────────────────────────────────────\n\n let lastNode = startNode;\n const steps = spec.steps ?? [];\n\n for (let i = 0; i < steps.length; i++) {\n const step = steps[i]!;\n const targetNode = `n${nodeIndex++}`;\n const relAlias = `r${i}`;\n\n // Relationship type pattern\n const relTypes = step.relationshipTypes?.length\n ? step.relationshipTypes.join('|')\n : '';\n const relTypePattern = relTypes ? `:${relTypes}` : '';\n\n // Repeat — variable-length path\n const depthPattern = step.repeat\n ? `*1..${step.repeat.maxDepth}`\n : '';\n\n // Direction — only include the relationship and target node (left node is already in the chain)\n let pattern: string;\n switch (step.direction) {\n case 'out':\n pattern = `-[${relAlias}${relTypePattern}${depthPattern}]->(${targetNode})`;\n break;\n case 'in':\n pattern = `<-[${relAlias}${relTypePattern}${depthPattern}]-(${targetNode})`;\n break;\n case 'both':\n pattern = `-[${relAlias}${relTypePattern}${depthPattern}]-(${targetNode})`;\n break;\n }\n\n matchParts.push(pattern);\n estimatedFanOut *= step.repeat\n ? step.repeat.maxDepth * DEFAULT_ESTIMATED_FANOUT_PER_HOP\n : DEFAULT_ESTIMATED_FANOUT_PER_HOP;\n\n // Entity type filter\n if (step.entityTypes && step.entityTypes.length > 0) {\n const typeParam = nextParam(step.entityTypes);\n whereClauses.push(`${targetNode}.entityType IN ${typeParam}`);\n }\n\n // Entity property filters\n if (step.entityFilter) {\n for (const f of step.entityFilter) {\n whereClauses.push(compilePropertyFilterCypher(targetNode, f, nextParam));\n }\n }\n\n // Relationship property filters\n if (step.relationshipFilter) {\n for (const f of step.relationshipFilter) {\n whereClauses.push(compilePropertyFilterCypher(relAlias, f, nextParam));\n }\n }\n\n lastNode = targetNode;\n }\n\n // ─── Build query ────────────────────────────────────────────\n\n const matchClause = `MATCH ${matchParts[0]}${matchParts.slice(1).join('')}`;\n const whereClause = whereClauses.length > 0\n ? `\\nWHERE ${whereClauses.join(' AND ')}`\n : '';\n\n // Return clause\n let returnClause: string;\n if (spec.returnMode === 'path') {\n // Return full paths\n const allNodes = Array.from({ length: nodeIndex }, (_, i) => `n${i}`);\n const allRels = steps.map((_, i) => `r${i}`);\n returnClause = `RETURN ${[...allNodes, ...allRels].join(', ')}`;\n } else if (spec.returnMode === 'all') {\n // Return all nodes\n const allNodes = Array.from({ length: nodeIndex }, (_, i) => `n${i}`);\n returnClause = spec.dedup !== false\n ? `RETURN DISTINCT ${allNodes.join(', ')}`\n : `RETURN ${allNodes.join(', ')}`;\n } else {\n // Terminal — return only the last node\n returnClause = spec.dedup !== false\n ? `RETURN DISTINCT ${lastNode}`\n : `RETURN ${lastNode}`;\n }\n\n // Pagination\n const offset = spec.offset ?? 0;\n const limit = spec.limit ?? 50;\n const skipClause = offset > 0 ? `\\nSKIP ${nextParam(offset)}` : '';\n const limitClause = `\\nLIMIT ${nextParam(limit)}`;\n\n params['_limit'] = limit;\n params['_offset'] = offset;\n\n const query = `${matchClause}${whereClause}\\n${returnClause}${skipClause}${limitClause}`;\n\n return {\n query,\n params,\n estimatedFanOut: Math.min(estimatedFanOut, 10000),\n };\n }\n}\n\n/** Compile a single property filter to a Cypher WHERE clause fragment. */\nfunction compilePropertyFilterCypher(\n nodeAlias: string,\n filter: PropertyFilter,\n nextParam: (value: unknown) => string,\n): string {\n const prop = `${nodeAlias}.${filter.key}`;\n\n switch (filter.operator) {\n case 'eq':\n return `${prop} = ${nextParam(filter.value)}`;\n case 'neq':\n return `${prop} <> ${nextParam(filter.value)}`;\n case 'gt':\n return `${prop} > ${nextParam(filter.value)}`;\n case 'gte':\n return `${prop} >= ${nextParam(filter.value)}`;\n case 'lt':\n return `${prop} < ${nextParam(filter.value)}`;\n case 'lte':\n return `${prop} <= ${nextParam(filter.value)}`;\n case 'contains':\n return `${prop} CONTAINS ${nextParam(filter.value)}`;\n case 'isNull':\n return `${prop} IS NULL`;\n case 'isNotNull':\n return `${prop} IS NOT NULL`;\n }\n}\n","// InMemoryStorageProvider — reference implementation of StorageProvider using Maps\n\nimport type { StorageProvider } from '../providers/StorageProvider.js';\nimport type {\n StoredEntity,\n StoredEntityUpdate,\n} from '../types/entities.js';\nimport type {\n StoredRelationship,\n RelationshipQueryOptions,\n} from '../types/relationships.js';\nimport type { MemoryVocabulary, VocabularyChangeRecord } from '../types/vocabulary.js';\nimport type {\n StorageRepositoryConfig,\n StoredRepository,\n StoredRepositorySummary,\n RepositoryFilter,\n RepositoryStats,\n RepositoryUpdate,\n} from '../types/repositories.js';\nimport type {\n StorageFindQuery,\n StorageExploreOptions,\n StoragePathOptions,\n StorageTimelineOptions,\n PaginationOptions,\n ProvenanceFilter,\n} from '../types/queries.js';\nimport type { Provenance } from '../types/provenance.js';\nimport type {\n PaginatedResult,\n StorageNeighborhood,\n StoragePathResult,\n StorageTimelineResult,\n BulkImportResult,\n} from '../types/results.js';\nimport type { ExportChunk, ImportChunk } from '../types/portability.js';\nimport { matchesPropertyFilters } from '../relationships/PropertyFilterMatcher.js';\nimport { createEmptyVocabulary } from '../vocabulary/VocabularySchema.js';\nimport {\n RepositoryNotFoundError,\n DuplicateRepositoryError,\n EntityNotFoundError,\n DuplicateEntityError,\n RelationshipNotFoundError,\n DuplicateRelationshipError,\n} from '../core/errors.js';\n\n/** Per-repository data store */\ninterface RepositoryStore {\n repository: StoredRepository;\n vocabulary: MemoryVocabulary;\n vocabularyChangeLog: VocabularyChangeRecord[];\n entities: Map<string, StoredEntity>;\n /** Secondary index: slug → GUID for fast slug lookups */\n slugIndex: Map<string, string>;\n relationships: Map<string, StoredRelationship>;\n}\n\nexport class InMemoryStorageProvider implements StorageProvider {\n private stores = new Map<string, RepositoryStore>();\n\n private getStore(repositoryId: string): RepositoryStore {\n const store = this.stores.get(repositoryId);\n if (!store) {\n throw new RepositoryNotFoundError(repositoryId);\n }\n return store;\n }\n\n // ─── Lifecycle ─────────────────────────────────────────────────────\n\n async initialize(): Promise<void> {\n // No-op for in-memory\n }\n\n async dispose(): Promise<void> {\n this.stores.clear();\n }\n\n // ─── Repository ────────────────────────────────────────────────────\n\n async createRepository(config: StorageRepositoryConfig): Promise<StoredRepository> {\n if (this.stores.has(config.repositoryId)) {\n throw new DuplicateRepositoryError(config.repositoryId);\n }\n\n const repository: StoredRepository = {\n repositoryId: config.repositoryId,\n type: config.type,\n label: config.label,\n description: config.description,\n legal: config.legal,\n owner: config.owner,\n governanceConfig: config.governanceConfig,\n metadata: config.metadata,\n createdAt: config.createdAt,\n createdBy: config.createdBy,\n };\n\n this.stores.set(config.repositoryId, {\n repository,\n vocabulary: createEmptyVocabulary(config.createdBy),\n vocabularyChangeLog: [],\n entities: new Map(),\n slugIndex: new Map(),\n relationships: new Map(),\n });\n\n return repository;\n }\n\n async getRepository(repositoryId: string): Promise<StoredRepository | null> {\n return this.stores.get(repositoryId)?.repository ?? null;\n }\n\n async listRepositories(\n filter?: RepositoryFilter,\n ): Promise<PaginatedResult<StoredRepositorySummary>> {\n let items = Array.from(this.stores.values()).map((store) => ({\n repositoryId: store.repository.repositoryId,\n type: store.repository.type,\n label: store.repository.label,\n description: store.repository.description,\n governanceConfig: store.repository.governanceConfig,\n }));\n\n if (filter?.type) {\n items = items.filter((r) => r.type === filter.type);\n }\n\n const total = items.length;\n const offset = filter?.offset ?? 0;\n const limit = filter?.limit ?? 20;\n const paged = items.slice(offset, offset + limit);\n\n return {\n items: paged,\n total,\n hasMore: offset + paged.length < total,\n limit,\n offset,\n };\n }\n\n async updateRepository(repositoryId: string, updates: RepositoryUpdate): Promise<StoredRepository> {\n const store = this.stores.get(repositoryId);\n if (!store) {\n throw new RepositoryNotFoundError(repositoryId);\n }\n const repo = store.repository;\n if (updates.label !== undefined) repo.label = updates.label;\n if (updates.description !== undefined) repo.description = updates.description;\n if (updates.type !== undefined) repo.type = updates.type;\n if (updates.legal !== undefined) repo.legal = updates.legal;\n if (updates.owner !== undefined) repo.owner = updates.owner;\n if (updates.governanceConfig !== undefined) repo.governanceConfig = updates.governanceConfig;\n if (updates.metadata !== undefined) repo.metadata = { ...repo.metadata, ...updates.metadata };\n return repo;\n }\n\n async deleteRepository(repositoryId: string, _onProgress?: import('../types/portability.js').DeleteProgressCallback): Promise<void> {\n if (!this.stores.has(repositoryId)) {\n throw new RepositoryNotFoundError(repositoryId);\n }\n this.stores.delete(repositoryId);\n }\n\n async deleteAllContents(repositoryId: string, _onProgress?: import('../types/portability.js').DeleteProgressCallback): Promise<{ deletedEntities: number; deletedRelationships: number }> {\n const store = this.getStore(repositoryId);\n const deletedEntities = store.entities.size;\n const deletedRelationships = store.relationships.size;\n store.entities.clear();\n store.slugIndex.clear();\n store.relationships.clear();\n return { deletedEntities, deletedRelationships };\n }\n\n async getRepositoryStats(repositoryId: string): Promise<RepositoryStats> {\n const store = this.getStore(repositoryId);\n\n const entityTypeBreakdown: Record<string, number> = {};\n for (const entity of store.entities.values()) {\n entityTypeBreakdown[entity.entityType] = (entityTypeBreakdown[entity.entityType] ?? 0) + 1;\n }\n\n const relationshipTypeBreakdown: Record<string, number> = {};\n for (const rel of store.relationships.values()) {\n relationshipTypeBreakdown[rel.relationshipType] =\n (relationshipTypeBreakdown[rel.relationshipType] ?? 0) + 1;\n }\n\n return {\n entityCount: store.entities.size,\n relationshipCount: store.relationships.size,\n vocabularyVersion: store.vocabulary.version,\n entityTypeBreakdown,\n relationshipTypeBreakdown,\n };\n }\n\n // ─── Vocabulary ────────────────────────────────────────────────────\n\n async getVocabulary(repositoryId: string): Promise<MemoryVocabulary> {\n const store = this.getStore(repositoryId);\n return store.vocabulary;\n }\n\n async saveVocabulary(repositoryId: string, vocabulary: MemoryVocabulary): Promise<void> {\n const store = this.getStore(repositoryId);\n store.vocabulary = vocabulary;\n }\n\n async getVocabularyChangeLog(\n repositoryId: string,\n options?: PaginationOptions,\n ): Promise<PaginatedResult<VocabularyChangeRecord>> {\n const store = this.getStore(repositoryId);\n const limit = options?.limit ?? 10;\n const offset = options?.offset ?? 0;\n const items = store.vocabularyChangeLog.slice(offset, offset + limit);\n\n return {\n items,\n total: store.vocabularyChangeLog.length,\n hasMore: offset + limit < store.vocabularyChangeLog.length,\n limit,\n offset,\n };\n }\n\n // ─── Entities ──────────────────────────────────────────────────────\n\n async createEntity(repositoryId: string, entity: StoredEntity): Promise<StoredEntity> {\n const store = this.getStore(repositoryId);\n if (store.entities.has(entity.id)) {\n throw new DuplicateEntityError(entity.id);\n }\n store.entities.set(entity.id, entity);\n store.slugIndex.set(entity.slug, entity.id);\n return entity;\n }\n\n async getEntity(repositoryId: string, entityId: string): Promise<StoredEntity | null> {\n const store = this.getStore(repositoryId);\n return store.entities.get(entityId) ?? null;\n }\n\n async getEntityBySlug(repositoryId: string, slug: string): Promise<StoredEntity | null> {\n const store = this.getStore(repositoryId);\n const id = store.slugIndex.get(slug);\n if (!id) return null;\n return store.entities.get(id) ?? null;\n }\n\n async getEntities(\n repositoryId: string,\n entityIds: string[],\n ): Promise<Map<string, StoredEntity>> {\n const store = this.getStore(repositoryId);\n const result = new Map<string, StoredEntity>();\n for (const id of entityIds) {\n const entity = store.entities.get(id);\n if (entity) {\n result.set(id, entity);\n }\n }\n return result;\n }\n\n async updateEntity(\n repositoryId: string,\n entityId: string,\n updates: StoredEntityUpdate,\n ): Promise<StoredEntity> {\n const store = this.getStore(repositoryId);\n const existing = store.entities.get(entityId);\n if (!existing) {\n throw new EntityNotFoundError(entityId);\n }\n\n // For optional string fields, null clears, undefined preserves, string sets.\n const updated: StoredEntity = {\n ...existing,\n entityType: updates.entityType ?? existing.entityType,\n label: updates.label ?? existing.label,\n summary: updates.summary === undefined ? existing.summary : (updates.summary ?? undefined),\n properties: updates.properties ?? existing.properties,\n data: updates.data === undefined ? existing.data : (updates.data ?? undefined),\n dataFormat: updates.dataFormat === undefined ? existing.dataFormat : (updates.dataFormat ?? undefined),\n provenance: updates.provenance,\n embedding: updates.embedding ?? existing.embedding,\n };\n\n // If slug needs to change (type or label changed), update slug index\n if (updates.slug && updates.slug !== existing.slug) {\n store.slugIndex.delete(existing.slug);\n updated.slug = updates.slug;\n store.slugIndex.set(updates.slug, entityId);\n }\n\n store.entities.set(entityId, updated);\n return updated;\n }\n\n async deleteEntity(repositoryId: string, entityId: string): Promise<void> {\n const store = this.getStore(repositoryId);\n const existing = store.entities.get(entityId);\n if (!existing) {\n throw new EntityNotFoundError(entityId);\n }\n store.slugIndex.delete(existing.slug);\n store.entities.delete(entityId);\n\n // Also remove relationships involving this entity\n for (const [relId, rel] of store.relationships) {\n if (rel.sourceEntityId === entityId || rel.targetEntityId === entityId) {\n store.relationships.delete(relId);\n }\n }\n }\n\n async deleteEntitiesByType(\n repositoryId: string,\n entityType: string,\n ): Promise<{ deletedEntities: number; deletedRelationships: number }> {\n const store = this.getStore(repositoryId);\n\n // Collect entity IDs of the given type\n const entityIds = new Set<string>();\n for (const [id, entity] of store.entities) {\n if (entity.entityType === entityType) {\n entityIds.add(id);\n store.slugIndex.delete(entity.slug);\n }\n }\n\n // Delete relationships involving those entities\n let deletedRelationships = 0;\n for (const [relId, rel] of store.relationships) {\n if (entityIds.has(rel.sourceEntityId) || entityIds.has(rel.targetEntityId)) {\n store.relationships.delete(relId);\n deletedRelationships++;\n }\n }\n\n // Delete the entities\n for (const id of entityIds) {\n store.entities.delete(id);\n }\n\n return { deletedEntities: entityIds.size, deletedRelationships };\n }\n\n async findEntities(\n repositoryId: string,\n query: StorageFindQuery,\n ): Promise<PaginatedResult<StoredEntity>> {\n const store = this.getStore(repositoryId);\n let matches = Array.from(store.entities.values());\n\n // Filter by entity types\n if (query.entityTypes && query.entityTypes.length > 0) {\n matches = matches.filter((e) => query.entityTypes!.includes(e.entityType));\n }\n\n // Filter by search term (label substring, case-insensitive)\n if (query.searchTerm) {\n const term = query.searchTerm.toLowerCase();\n matches = matches.filter(\n (e) =>\n e.label.toLowerCase().includes(term) ||\n (e.summary && e.summary.toLowerCase().includes(term)),\n );\n }\n\n // Filter by property values\n if (query.properties) {\n const entries = Object.entries(query.properties);\n matches = matches.filter((e) =>\n entries.every(([key, value]) => e.properties[key] === value),\n );\n }\n\n // Filter by provenance\n if (query.provenance) {\n matches = matches.filter((e) => matchesProvenance(e.provenance, query.provenance!));\n }\n\n const total = matches.length;\n const items = matches.slice(query.offset, query.offset + query.limit);\n\n return {\n items,\n total,\n hasMore: query.offset + query.limit < total,\n limit: query.limit,\n offset: query.offset,\n };\n }\n\n // ─── Relationships ─────────────────────────────────────────────────\n\n async createRelationship(\n repositoryId: string,\n relationship: StoredRelationship,\n ): Promise<StoredRelationship> {\n const store = this.getStore(repositoryId);\n if (store.relationships.has(relationship.id)) {\n throw new DuplicateRelationshipError(relationship.id);\n }\n store.relationships.set(relationship.id, relationship);\n return relationship;\n }\n\n async getRelationship(\n repositoryId: string,\n relationshipId: string,\n ): Promise<StoredRelationship | null> {\n const store = this.getStore(repositoryId);\n return store.relationships.get(relationshipId) ?? null;\n }\n\n async getEntityRelationships(\n repositoryId: string,\n entityId: string,\n options?: RelationshipQueryOptions,\n ): Promise<PaginatedResult<StoredRelationship>> {\n const store = this.getStore(repositoryId);\n const direction = options?.direction ?? 'both';\n let matches = Array.from(store.relationships.values());\n\n // Filter by entity involvement and direction\n matches = matches.filter((rel) => {\n const isSource = rel.sourceEntityId === entityId;\n const isTarget = rel.targetEntityId === entityId;\n const isBidirectionalTarget = rel.bidirectional && isTarget;\n\n switch (direction) {\n case 'outbound':\n return isSource || isBidirectionalTarget;\n case 'inbound':\n return isTarget || (rel.bidirectional && isSource);\n case 'both':\n default:\n return isSource || isTarget;\n }\n });\n\n // Filter by relationship types\n if (options?.relationshipTypes && options.relationshipTypes.length > 0) {\n matches = matches.filter((r) => options.relationshipTypes!.includes(r.relationshipType));\n }\n\n // Filter by property values\n if (options?.propertyFilters && options.propertyFilters.length > 0) {\n matches = matches.filter((r) => matchesPropertyFilters(r.properties, options.propertyFilters!));\n }\n\n const total = matches.length;\n const limit = options?.limit ?? 10;\n const offset = options?.offset ?? 0;\n const items = matches.slice(offset, offset + limit);\n\n return {\n items,\n total,\n hasMore: offset + limit < total,\n limit,\n offset,\n };\n }\n\n async deleteEntities(\n repositoryId: string,\n ids: string[],\n ): Promise<{ deleted: string[]; notFound: string[] }> {\n const store = this.getStore(repositoryId);\n const deleted: string[] = [];\n const notFound: string[] = [];\n const deletedSet = new Set<string>();\n\n for (const id of ids) {\n const existing = store.entities.get(id);\n if (!existing) {\n notFound.push(id);\n continue;\n }\n store.slugIndex.delete(existing.slug);\n store.entities.delete(id);\n deleted.push(id);\n deletedSet.add(id);\n }\n\n // Cascade-delete relationships involving any of the deleted entities\n for (const [relId, rel] of store.relationships) {\n if (deletedSet.has(rel.sourceEntityId) || deletedSet.has(rel.targetEntityId)) {\n store.relationships.delete(relId);\n }\n }\n\n return { deleted, notFound };\n }\n\n async deleteRelationship(repositoryId: string, relationshipId: string): Promise<void> {\n const store = this.getStore(repositoryId);\n if (!store.relationships.has(relationshipId)) {\n throw new RelationshipNotFoundError(relationshipId);\n }\n store.relationships.delete(relationshipId);\n }\n\n async deleteRelationships(\n repositoryId: string,\n ids: string[],\n ): Promise<{ deleted: string[]; notFound: string[] }> {\n const store = this.getStore(repositoryId);\n const deleted: string[] = [];\n const notFound: string[] = [];\n for (const id of ids) {\n if (store.relationships.has(id)) {\n store.relationships.delete(id);\n deleted.push(id);\n } else {\n notFound.push(id);\n }\n }\n return { deleted, notFound };\n }\n\n async deleteRelationshipsByType(\n repositoryId: string,\n relationshipType: string,\n ): Promise<{ deletedRelationships: number }> {\n const store = this.getStore(repositoryId);\n let deletedRelationships = 0;\n for (const [relId, rel] of store.relationships) {\n if (rel.relationshipType === relationshipType) {\n store.relationships.delete(relId);\n deletedRelationships++;\n }\n }\n return { deletedRelationships };\n }\n\n // ─── Graph Traversal ───────────────────────────────────────────────\n\n async exploreNeighborhood(\n repositoryId: string,\n entityId: string,\n options: StorageExploreOptions,\n ): Promise<StorageNeighborhood> {\n const store = this.getStore(repositoryId);\n\n if (!store.entities.has(entityId)) {\n throw new EntityNotFoundError(entityId);\n }\n\n const layers: StorageNeighborhood['layers'] = [];\n const visited = new Set<string>([entityId]);\n let currentFrontier = new Set<string>([entityId]);\n\n for (let depth = 0; depth < options.depth; depth++) {\n const layer: Record<string, { total: number; entities: StoredEntity[]; relationships: StoredRelationship[] }> = {};\n const nextFrontier = new Set<string>();\n\n for (const frontierEntityId of currentFrontier) {\n for (const rel of store.relationships.values()) {\n // Check direction filter\n const isSource = rel.sourceEntityId === frontierEntityId;\n const isTarget = rel.targetEntityId === frontierEntityId;\n\n let matchesDirection = false;\n let connectedEntityId: string | undefined;\n\n if (isSource && (options.direction === 'outbound' || options.direction === 'both')) {\n matchesDirection = true;\n connectedEntityId = rel.targetEntityId;\n } else if (isTarget && (options.direction === 'inbound' || options.direction === 'both')) {\n matchesDirection = true;\n connectedEntityId = rel.sourceEntityId;\n } else if (rel.bidirectional) {\n if (isSource && options.direction === 'inbound') {\n matchesDirection = true;\n connectedEntityId = rel.targetEntityId;\n } else if (isTarget && options.direction === 'outbound') {\n matchesDirection = true;\n connectedEntityId = rel.sourceEntityId;\n }\n }\n\n if (!matchesDirection || !connectedEntityId) continue;\n if (visited.has(connectedEntityId)) continue;\n\n // Filter by relationship type\n if (options.relationshipTypes && !options.relationshipTypes.includes(rel.relationshipType)) {\n continue;\n }\n\n // Filter by relationship property values\n if (options.relationshipPropertyFilters && options.relationshipPropertyFilters.length > 0) {\n if (!matchesPropertyFilters(rel.properties, options.relationshipPropertyFilters)) {\n continue;\n }\n }\n\n const connectedEntity = store.entities.get(connectedEntityId);\n if (!connectedEntity) continue;\n\n // Filter by entity type\n if (options.entityTypes && !options.entityTypes.includes(connectedEntity.entityType)) {\n continue;\n }\n\n const relType = rel.relationshipType;\n if (!layer[relType]) {\n layer[relType] = { total: 0, entities: [], relationships: [] };\n }\n\n layer[relType].total++;\n\n // Apply per-type pagination\n const group = layer[relType];\n if (group.entities.length < options.limitPerType) {\n group.entities.push(connectedEntity);\n group.relationships.push(rel);\n }\n\n nextFrontier.add(connectedEntityId);\n }\n }\n\n for (const id of nextFrontier) {\n visited.add(id);\n }\n\n layers.push(layer);\n currentFrontier = nextFrontier;\n\n if (nextFrontier.size === 0) break;\n }\n\n return {\n centerId: entityId,\n layers,\n };\n }\n\n async findPaths(\n repositoryId: string,\n sourceId: string,\n targetId: string,\n options: StoragePathOptions,\n ): Promise<StoragePathResult> {\n const store = this.getStore(repositoryId);\n\n if (!store.entities.has(sourceId)) {\n throw new EntityNotFoundError(sourceId);\n }\n if (!store.entities.has(targetId)) {\n throw new EntityNotFoundError(targetId);\n }\n\n if (sourceId === targetId) {\n return { paths: [{ entityIds: [sourceId], relationshipIds: [] }], totalPaths: 1 };\n }\n\n // BFS path finding\n const paths: Array<{ entityIds: string[]; relationshipIds: string[] }> = [];\n const queue: Array<{ entityId: string; path: string[]; relPath: string[] }> = [\n { entityId: sourceId, path: [sourceId], relPath: [] },\n ];\n\n // Track visited per path-length to allow multiple paths\n const visitedAtDepth = new Map<string, number>();\n visitedAtDepth.set(sourceId, 0);\n\n while (queue.length > 0 && paths.length < options.limit + options.offset) {\n const current = queue.shift()!;\n\n if (current.path.length > options.maxDepth + 1) continue;\n\n for (const rel of store.relationships.values()) {\n // Filter by relationship type\n if (options.relationshipTypes && !options.relationshipTypes.includes(rel.relationshipType)) {\n continue;\n }\n\n // Filter by relationship property values\n if (options.relationshipPropertyFilters && options.relationshipPropertyFilters.length > 0) {\n if (!matchesPropertyFilters(rel.properties, options.relationshipPropertyFilters)) {\n continue;\n }\n }\n\n // Traverse edges in both directions for path discovery,\n // regardless of bidirectional flag. The flag controls semantic\n // meaning, not graph reachability — paths should follow all edges.\n let nextEntityId: string | undefined;\n if (rel.sourceEntityId === current.entityId) {\n nextEntityId = rel.targetEntityId;\n } else if (rel.targetEntityId === current.entityId) {\n nextEntityId = rel.sourceEntityId;\n }\n\n if (!nextEntityId) continue;\n if (current.path.includes(nextEntityId) && nextEntityId !== targetId) continue;\n\n // Filter intermediate entities by type (always allow source and target)\n if (options.entityTypes && nextEntityId !== targetId) {\n const nextEntity = store.entities.get(nextEntityId);\n if (nextEntity && !options.entityTypes.includes(nextEntity.entityType)) continue;\n }\n\n const newPath = [...current.path, nextEntityId];\n const newRelPath = [...current.relPath, rel.id];\n\n if (nextEntityId === targetId) {\n paths.push({ entityIds: newPath, relationshipIds: newRelPath });\n } else if (newPath.length <= options.maxDepth) {\n const prevDepth = visitedAtDepth.get(nextEntityId);\n if (prevDepth === undefined || prevDepth >= newPath.length - 1) {\n visitedAtDepth.set(nextEntityId, newPath.length - 1);\n queue.push({ entityId: nextEntityId, path: newPath, relPath: newRelPath });\n }\n }\n }\n }\n\n const paginatedPaths = paths.slice(options.offset, options.offset + options.limit);\n\n return {\n paths: paginatedPaths,\n totalPaths: paths.length,\n };\n }\n\n // ─── Timeline ──────────────────────────────────────────────────────\n\n async getTimeline(\n repositoryId: string,\n entityId: string,\n options: StorageTimelineOptions,\n ): Promise<StorageTimelineResult> {\n const store = this.getStore(repositoryId);\n const entity = store.entities.get(entityId);\n if (!entity) {\n throw new EntityNotFoundError(entityId);\n }\n\n const events: StorageTimelineResult['events'] = [];\n\n // Entity creation event\n events.push({\n timestamp: entity.provenance.createdAt,\n eventType: 'entity:created',\n entityId,\n });\n\n // Entity modification event (if different from creation)\n if (entity.provenance.modifiedAt !== entity.provenance.createdAt) {\n events.push({\n timestamp: entity.provenance.modifiedAt,\n eventType: 'entity:updated',\n entityId,\n });\n }\n\n // Relationship events involving this entity\n for (const rel of store.relationships.values()) {\n if (rel.sourceEntityId === entityId || rel.targetEntityId === entityId) {\n events.push({\n timestamp: rel.provenance.createdAt,\n eventType: 'relationship:created',\n entityId,\n relationshipId: rel.id,\n });\n }\n }\n\n // Filter by time range\n let filtered = events;\n if (options.timeRange) {\n const from = new Date(options.timeRange.from).getTime();\n const to = new Date(options.timeRange.to).getTime();\n filtered = filtered.filter((e) => {\n const t = new Date(e.timestamp).getTime();\n return t >= from && t <= to;\n });\n }\n\n // Filter by event types\n if (options.eventTypes && options.eventTypes.length > 0) {\n filtered = filtered.filter((e) => options.eventTypes!.includes(e.eventType));\n }\n\n // Filter by provenance (conversation ID)\n if (options.provenance) {\n const prov = options.provenance;\n filtered = filtered.filter((e) => {\n // For entity events, check entity provenance\n if (e.eventType.startsWith('entity:')) {\n const ent = store.entities.get(e.entityId);\n return ent ? matchesProvenance(ent.provenance, prov) : false;\n }\n // For relationship events, check relationship provenance\n if (e.relationshipId) {\n const rel = store.relationships.get(e.relationshipId);\n return rel ? matchesProvenance(rel.provenance, prov) : false;\n }\n return true;\n });\n }\n\n // Sort by timestamp descending (most recent first)\n filtered.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime());\n\n const total = filtered.length;\n const items = filtered.slice(options.offset, options.offset + options.limit);\n\n return {\n events: items,\n total,\n };\n }\n\n // ─── Bulk Operations ───────────────────────────────────────────────\n\n async *exportAll(repositoryId: string): AsyncIterable<ExportChunk> {\n const store = this.getStore(repositoryId);\n\n const entities = Array.from(store.entities.values());\n const batchSize = 100;\n\n for (let i = 0; i < entities.length; i += batchSize) {\n const batch = entities.slice(i, i + batchSize);\n yield {\n type: 'entities',\n data: batch,\n sequence: Math.floor(i / batchSize),\n isLast: i + batchSize >= entities.length,\n };\n }\n\n // If no entities, still yield an empty last chunk\n if (entities.length === 0) {\n yield { type: 'entities', data: [], sequence: 0, isLast: true };\n }\n\n const relationships = Array.from(store.relationships.values());\n for (let i = 0; i < relationships.length; i += batchSize) {\n const batch = relationships.slice(i, i + batchSize);\n yield {\n type: 'relationships',\n data: batch,\n sequence: Math.floor(i / batchSize),\n isLast: i + batchSize >= relationships.length,\n };\n }\n\n if (relationships.length === 0) {\n yield { type: 'relationships', data: [], sequence: 0, isLast: true };\n }\n }\n\n async importBulk(\n repositoryId: string,\n data: ImportChunk[],\n _options?: import('../types/portability.js').BulkImportOptions,\n ): Promise<BulkImportResult> {\n const store = this.getStore(repositoryId);\n let entitiesImported = 0;\n let relationshipsImported = 0;\n const errors: Array<{ item: string; error: string }> = [];\n\n for (const chunk of data) {\n if (chunk.entities) {\n for (const entity of chunk.entities) {\n try {\n store.entities.set(entity.id, entity);\n store.slugIndex.set(entity.slug, entity.id);\n entitiesImported++;\n } catch (err) {\n errors.push({\n item: entity.id,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n }\n }\n\n if (chunk.relationships) {\n for (const rel of chunk.relationships) {\n try {\n store.relationships.set(rel.id, rel);\n relationshipsImported++;\n } catch (err) {\n errors.push({\n item: rel.id,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n }\n }\n }\n\n return { entitiesImported, relationshipsImported, errors };\n }\n}\n\n// ─── Provenance filter helper ──────────────────────────────────────\n\nfunction matchesProvenance(prov: Provenance, filter: ProvenanceFilter): boolean {\n if (filter.conversationIds && filter.conversationIds.length > 0) {\n const matchesCreated = prov.createdInConversation && filter.conversationIds.includes(prov.createdInConversation);\n const matchesModified = prov.modifiedInConversation && filter.conversationIds.includes(prov.modifiedInConversation);\n if (!matchesCreated && !matchesModified) return false;\n }\n if (filter.actors && filter.actors.length > 0) {\n const matchesCreator = filter.actors.includes(prov.createdBy);\n const matchesModifier = filter.actors.includes(prov.modifiedBy);\n if (!matchesCreator && !matchesModifier) return false;\n }\n if (filter.dateRange) {\n const from = new Date(filter.dateRange.from).getTime();\n const to = new Date(filter.dateRange.to).getTime();\n const created = new Date(prov.createdAt).getTime();\n const modified = new Date(prov.modifiedAt).getTime();\n if (!(created >= from && created <= to) && !(modified >= from && modified <= to)) return false;\n }\n return true;\n}\n","// InMemorySearchProvider — basic in-memory full-text search\n\nimport type { SearchProvider, SearchableEntity } from '../providers/SearchProvider.js';\nimport type { SearchOptions } from '../types/queries.js';\nimport type { PaginatedResult, SearchHit } from '../types/results.js';\n\ninterface IndexedEntry {\n entityId: string;\n entityType: string;\n text: string; // concatenated searchable text (lowercased)\n}\n\nexport class InMemorySearchProvider implements SearchProvider {\n private indices = new Map<string, Map<string, IndexedEntry>>();\n\n private getIndex(repositoryId: string): Map<string, IndexedEntry> {\n if (!this.indices.has(repositoryId)) {\n this.indices.set(repositoryId, new Map());\n }\n return this.indices.get(repositoryId)!;\n }\n\n async indexEntity(repositoryId: string, entity: SearchableEntity): Promise<void> {\n const index = this.getIndex(repositoryId);\n\n // Build searchable text from label, summary, properties, and data\n const parts = [entity.label, entity.summary ?? ''];\n\n if (entity.properties) {\n for (const value of Object.values(entity.properties)) {\n if (typeof value === 'string') {\n parts.push(value);\n }\n }\n }\n\n if (entity.data) {\n parts.push(entity.data);\n }\n\n index.set(entity.entityId, {\n entityId: entity.entityId,\n entityType: entity.entityType,\n text: parts.join(' ').toLowerCase(),\n });\n }\n\n async removeEntity(repositoryId: string, entityId: string): Promise<void> {\n this.getIndex(repositoryId).delete(entityId);\n }\n\n async search(\n repositoryId: string,\n query: string,\n options?: SearchOptions,\n ): Promise<PaginatedResult<SearchHit>> {\n const index = this.getIndex(repositoryId);\n const terms = query.toLowerCase().split(/\\s+/).filter(Boolean);\n\n if (terms.length === 0) {\n return { items: [], total: 0, hasMore: false, limit: options?.limit ?? 10, offset: options?.offset ?? 0 };\n }\n\n let hits: Array<{ entry: IndexedEntry; score: number }> = [];\n\n for (const entry of index.values()) {\n // Filter by entity types\n if (options?.entityTypes && options.entityTypes.length > 0) {\n if (!options.entityTypes.includes(entry.entityType)) continue;\n }\n\n // Score: count of matching terms / total terms\n let matchCount = 0;\n for (const term of terms) {\n if (entry.text.includes(term)) {\n matchCount++;\n }\n }\n\n if (matchCount > 0) {\n hits.push({ entry, score: matchCount / terms.length });\n }\n }\n\n // Sort by score descending\n hits.sort((a, b) => b.score - a.score);\n\n const total = hits.length;\n const limit = options?.limit ?? 10;\n const offset = options?.offset ?? 0;\n const page = hits.slice(offset, offset + limit);\n\n return {\n items: page.map((h) => ({\n id: h.entry.entityId,\n score: h.score,\n })),\n total,\n hasMore: offset + limit < total,\n limit,\n offset,\n };\n }\n\n async reindexRepository(\n repositoryId: string,\n entities: AsyncIterable<SearchableEntity>,\n ): Promise<void> {\n // Clear existing index\n this.indices.set(repositoryId, new Map());\n\n for await (const entity of entities) {\n await this.indexEntity(repositoryId, entity);\n }\n }\n}\n","// NoOpEmbeddingProvider — stub used when no embedding provider is configured\n\nimport type { EmbeddingProvider } from '../providers/EmbeddingProvider.js';\nimport { EmbeddingProviderRequiredError } from '../core/errors.js';\n\nexport class NoOpEmbeddingProvider implements EmbeddingProvider {\n async embed(_text: string): Promise<number[]> {\n throw new EmbeddingProviderRequiredError();\n }\n\n async embedBatch(_texts: string[]): Promise<number[][]> {\n throw new EmbeddingProviderRequiredError();\n }\n\n dimensions(): number {\n return 0;\n }\n\n modelId(): string {\n return 'none';\n }\n}\n"],"mappings":"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","names":["DEFAULT_ESTIMATED_FANOUT_PER_HOP"]}