@cortexa/core 1.0.1 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +80 -0
- package/dist/cli/index.js +332 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/index.cjs +286 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +26 -1
- package/dist/index.d.ts +26 -1
- package/dist/index.js +278 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../node_modules/tsup/assets/cjs_shims.js","../src/connectors/mongodb.ts","../src/connectors/mssql.ts","../src/core/logger.ts","../src/behavioral/streams/types.ts","../src/behavioral/streams/postgres-stream.ts","../src/behavioral/streams/mysql-stream.ts","../src/behavioral/streams/mongodb-stream.ts","../src/index.ts","../src/core/connection.ts","../src/connectors/postgres.ts","../src/connectors/mysql.ts","../src/connectors/sqlite.ts","../src/core/storage.ts","../src/llm/factory.ts","../src/llm/openai-compatible.ts","../src/core/errors.ts","../src/llm/retry.ts","../src/llm/anthropic.ts","../src/schema/introspector.ts","../src/schema/classifier.ts","../src/schema/graph-builder.ts","../src/behavioral/watcher.ts","../src/behavioral/change-detector.ts","../src/behavioral/event-classifier.ts","../src/behavioral/pattern-engine.ts","../src/behavioral/capability-detector.ts","../src/reasoning/transition-tracker.ts","../src/reasoning/types.ts","../src/analytics/analytics-engine.ts","../src/analytics/correlator.ts","../src/analytics/types.ts","../src/analytics/distribution-tracker.ts","../src/knowledge/graph-store.ts","../src/knowledge/graph-populator.ts","../src/actions/action-registry.ts","../src/actions/action-matcher.ts","../src/actions/action-executor.ts","../src/knowledge/traversal.ts","../src/knowledge/entity-intelligence.ts","../src/knowledge/export.ts","../src/notifications/notifier.ts","../src/notifications/formatters.ts","../src/explain/explainer.ts","../src/explain/context-builder.ts","../src/ask/asker.ts","../src/ask/ask-context-builder.ts","../src/core/config.ts","../src/core/validate-config.ts"],"sourcesContent":["// Shim globals in cjs bundle\n// There's a weird bug that esbuild will always inject importMetaUrl\n// if we export it as `const importMetaUrl = ... __filename ...`\n// But using a function will not cause this issue\n\nconst getImportMetaUrl = () => \n typeof document === \"undefined\" \n ? new URL(`file:${__filename}`).href \n : (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT') \n ? document.currentScript.src \n : new URL(\"main.js\", document.baseURI).href;\n\nexport const importMetaUrl = /* @__PURE__ */ getImportMetaUrl()\n","import { MongoClient, type Db, type Document } from 'mongodb';\nimport type { ConnectionConfig } from '../core/config.js';\nimport type { DatabaseConnector, QueryResult } from './types.js';\n\nexport class MongoDBConnector implements DatabaseConnector {\n private client: MongoClient | null = null;\n private db: Db | null = null;\n private dbName: string = '';\n\n async connect(config: ConnectionConfig): Promise<void> {\n const url = config.url ?? `mongodb://${config.host ?? 'localhost'}:${config.port ?? 27017}`;\n this.dbName = config.database ?? 'test';\n this.client = new MongoClient(url);\n await this.client.connect();\n this.db = this.client.db(this.dbName);\n }\n\n async disconnect(): Promise<void> {\n if (this.client) {\n await this.client.close();\n this.client = null;\n this.db = null;\n }\n }\n\n async getTableCount(): Promise<number> {\n this.ensureConnected();\n const collections = await this.db!.listCollections().toArray();\n return collections.length;\n }\n\n async getDatabaseName(): Promise<string> {\n return this.dbName;\n }\n\n async isReadOnly(): Promise<boolean> {\n // Cortexa never writes to the target database\n return true;\n }\n\n isConnected(): boolean {\n return this.client !== null && this.db !== null;\n }\n\n /**\n * Bridge between SQL-shaped interface and MongoDB's native API.\n * Uses a command protocol for MongoDB operations:\n * - \"COLLECTIONS\" → listCollections\n * - \"SAMPLE:collection:N\" → aggregate $sample\n * - \"COUNT:collection\" → countDocuments\n * - \"INDEXES:collection\" → collection.indexes()\n * - \"FIELDS:collection:N\" → sample N docs and union field names\n * - \"COMMAND:{...}\" → run admin command (e.g. replSetGetStatus)\n */\n async query(sql: string, _params?: unknown[]): Promise<QueryResult> {\n this.ensureConnected();\n\n const trimmed = sql.trim();\n\n if (trimmed === 'COLLECTIONS') {\n const collections = await this.db!.listCollections().toArray();\n const rows = collections.map((c) => ({\n table_name: c.name,\n table_schema: this.dbName,\n }));\n return { rows, rowCount: rows.length };\n }\n\n if (trimmed.startsWith('SAMPLE:')) {\n const parts = trimmed.split(':');\n const collectionName = parts[1];\n const limit = parseInt(parts[2] ?? '5', 10);\n const docs = await this.db!.collection(collectionName)\n .aggregate<Document>([{ $sample: { size: limit } }])\n .toArray();\n const rows = docs.map((d) => this.flattenDocument(d));\n return { rows, rowCount: rows.length };\n }\n\n if (trimmed.startsWith('COUNT:')) {\n const collectionName = trimmed.slice(6);\n const count = await this.db!.collection(collectionName).countDocuments();\n return { rows: [{ count }], rowCount: 1 };\n }\n\n if (trimmed.startsWith('INDEXES:')) {\n const collectionName = trimmed.slice(8);\n const indexes = await this.db!.collection(collectionName).indexes();\n const rows = indexes.map((idx) => ({\n index_name: idx.name ?? 'unknown',\n columns: Object.keys(idx.key),\n is_unique: idx.unique ?? false,\n }));\n return { rows: rows as unknown as Record<string, unknown>[], rowCount: rows.length };\n }\n\n if (trimmed.startsWith('FIELDS:')) {\n const parts = trimmed.split(':');\n const collectionName = parts[1];\n const sampleSize = parseInt(parts[2] ?? '20', 10);\n const docs = await this.db!.collection(collectionName)\n .aggregate<Document>([{ $sample: { size: sampleSize } }])\n .toArray();\n const fieldMap = new Map<string, string>();\n for (const doc of docs) {\n this.extractFields(doc, '', fieldMap);\n }\n const rows = Array.from(fieldMap.entries()).map(([name, type]) => ({\n column_name: name,\n data_type: type,\n is_nullable: 'YES',\n column_default: null,\n }));\n return { rows, rowCount: rows.length };\n }\n\n if (trimmed.startsWith('COMMAND:')) {\n const cmdJson = trimmed.slice(8);\n const cmd = JSON.parse(cmdJson) as Document;\n const result = await this.db!.admin().command(cmd);\n return { rows: [result as Record<string, unknown>], rowCount: 1 };\n }\n\n throw new Error(`MongoDB connector does not support raw SQL. Use command protocol (COLLECTIONS, SAMPLE:name:N, COUNT:name, INDEXES:name, FIELDS:name:N, COMMAND:{...}).`);\n }\n\n private ensureConnected(): void {\n if (!this.db) {\n throw new Error('Not connected. Call connect() first.');\n }\n }\n\n private flattenDocument(doc: Document): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(doc)) {\n if (key === '_id') {\n result[key] = String(value);\n } else {\n result[key] = value;\n }\n }\n return result;\n }\n\n private extractFields(doc: Document, prefix: string, fieldMap: Map<string, string>): void {\n for (const [key, value] of Object.entries(doc)) {\n const fullKey = prefix ? `${prefix}.${key}` : key;\n const bsonType = this.inferBsonType(value);\n if (!fieldMap.has(fullKey)) {\n fieldMap.set(fullKey, bsonType);\n }\n }\n }\n\n private inferBsonType(value: unknown): string {\n if (value === null || value === undefined) return 'null';\n if (typeof value === 'string') return 'string';\n if (typeof value === 'number') return Number.isInteger(value) ? 'int' : 'double';\n if (typeof value === 'boolean') return 'bool';\n if (value instanceof Date) return 'date';\n if (Array.isArray(value)) return 'array';\n if (typeof value === 'object') return 'object';\n return 'unknown';\n }\n}\n","import sql from 'mssql';\nimport type { ConnectionConfig } from '../core/config.js';\nimport type { DatabaseConnector, QueryResult } from './types.js';\n\nexport class MSSQLConnector implements DatabaseConnector {\n private pool: sql.ConnectionPool | null = null;\n\n async connect(config: ConnectionConfig): Promise<void> {\n if (config.url) {\n this.pool = await sql.connect(config.url);\n } else {\n this.pool = await sql.connect({\n server: config.host ?? 'localhost',\n port: config.port ?? 1433,\n database: config.database,\n user: config.user,\n password: config.password,\n options: {\n encrypt: false,\n trustServerCertificate: true,\n },\n });\n }\n }\n\n async disconnect(): Promise<void> {\n if (this.pool) {\n await this.pool.close();\n this.pool = null;\n }\n }\n\n async getTableCount(): Promise<number> {\n this.ensureConnected();\n const result = await this.pool!.request().query(\n `SELECT COUNT(*) AS count FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE'`\n );\n return result.recordset[0]?.count ?? 0;\n }\n\n async getDatabaseName(): Promise<string> {\n this.ensureConnected();\n const result = await this.pool!.request().query('SELECT DB_NAME() AS db_name');\n return result.recordset[0]?.db_name ?? '';\n }\n\n async isReadOnly(): Promise<boolean> {\n this.ensureConnected();\n try {\n await this.pool!.request().query('CREATE TABLE #_cortexa_ro_test (id INT); DROP TABLE #_cortexa_ro_test;');\n return false;\n } catch {\n return true;\n }\n }\n\n isConnected(): boolean {\n return this.pool !== null && this.pool.connected;\n }\n\n async query(sqlText: string, params?: unknown[]): Promise<QueryResult> {\n this.ensureConnected();\n\n const request = this.pool!.request();\n\n // Convert $1, $2 style params to @p1, @p2\n let convertedSql = sqlText;\n if (params && params.length > 0) {\n convertedSql = sqlText.replace(/\\$(\\d+)/g, (_match, num) => `@p${num}`);\n for (let i = 0; i < params.length; i++) {\n request.input(`p${i + 1}`, params[i]);\n }\n }\n\n const result = await request.query(convertedSql);\n return {\n rows: result.recordset as Record<string, unknown>[] ?? [],\n rowCount: result.rowsAffected?.[0] ?? result.recordset?.length ?? 0,\n };\n }\n\n private ensureConnected(): void {\n if (!this.pool) {\n throw new Error('Not connected. Call connect() first.');\n }\n }\n}\n","import pino from 'pino';\n\nexport interface LoggerOptions {\n name?: string;\n level?: string;\n}\n\nexport function createLogger(options: LoggerOptions = {}): pino.Logger {\n return pino({\n name: options.name ?? 'cortexa',\n level: options.level ?? 'info',\n });\n}\n","import type { RawChange } from '../types.js';\n\nexport interface ReconnectOptions {\n maxAttempts?: number;\n initialDelayMs?: number;\n maxDelayMs?: number;\n}\n\nexport interface ChangeStream {\n start(onChange: (change: RawChange) => void): Promise<void>;\n stop(): Promise<void>;\n isRunning(): boolean;\n cleanup(): Promise<void>;\n}\n\nconst DEFAULT_MAX_ATTEMPTS = 5;\nconst DEFAULT_INITIAL_DELAY_MS = 1000;\nconst DEFAULT_MAX_DELAY_MS = 60000;\n\nexport function resolveReconnectOptions(options?: ReconnectOptions): Required<ReconnectOptions> {\n return {\n maxAttempts: options?.maxAttempts ?? DEFAULT_MAX_ATTEMPTS,\n initialDelayMs: options?.initialDelayMs ?? DEFAULT_INITIAL_DELAY_MS,\n maxDelayMs: options?.maxDelayMs ?? DEFAULT_MAX_DELAY_MS,\n };\n}\n\nexport function computeBackoff(attempt: number, opts: Required<ReconnectOptions>): number {\n const delay = opts.initialDelayMs * Math.pow(2, attempt);\n return Math.min(delay, opts.maxDelayMs);\n}\n","import type { ConnectionConfig } from '../../core/config.js';\nimport type { DatabaseConnector } from '../../connectors/types.js';\nimport type { RawChange } from '../types.js';\nimport type { ChangeStream, ReconnectOptions } from './types.js';\nimport { resolveReconnectOptions, computeBackoff } from './types.js';\nimport { createLogger } from '../../core/logger.js';\n\ninterface WalRelation {\n schema: string;\n name: string;\n columns: Array<{ name: string; typeOid: number; flags: number; typeMod: number }>;\n}\n\ninterface WalInsertEvent {\n tag: 'insert';\n relation: WalRelation;\n new: Record<string, unknown>;\n}\n\ninterface WalUpdateEvent {\n tag: 'update';\n relation: WalRelation;\n old?: Record<string, unknown>;\n new: Record<string, unknown>;\n}\n\ninterface WalDeleteEvent {\n tag: 'delete';\n relation: WalRelation;\n old: Record<string, unknown>;\n}\n\ntype WalEvent = WalInsertEvent | WalUpdateEvent | WalDeleteEvent;\n\nconst logger = createLogger({ name: 'postgres-stream' });\n\nexport class PostgresStream implements ChangeStream {\n private readonly connectionConfig: ConnectionConfig;\n private readonly connector: DatabaseConnector;\n private running: boolean;\n private service: { subscribe: (plugin: unknown, slotName: string) => Promise<void>; stop: () => Promise<void>; on: (event: string, listener: (...args: unknown[]) => void) => void; removeAllListeners: () => void } | null;\n private slotName: string;\n private reconnectOpts: Required<ReconnectOptions>;\n private reconnectAttempts: number;\n private lastOnChange: ((change: RawChange) => void) | null;\n\n constructor(connectionConfig: ConnectionConfig, connector: DatabaseConnector, reconnect?: ReconnectOptions) {\n this.connectionConfig = connectionConfig;\n this.connector = connector;\n this.running = false;\n this.service = null;\n this.slotName = '';\n this.reconnectOpts = resolveReconnectOptions(reconnect);\n this.reconnectAttempts = 0;\n this.lastOnChange = null;\n }\n\n async start(onChange: (change: RawChange) => void): Promise<void> {\n this.lastOnChange = onChange;\n this.reconnectAttempts = 0;\n await this.connectStream(onChange);\n }\n\n private async connectStream(onChange: (change: RawChange) => void): Promise<void> {\n const { LogicalReplicationService, PgoutputPlugin } = await import('pg-logical-replication');\n\n const dbName = await this.connector.getDatabaseName();\n this.slotName = `metis_${dbName.replace(/[^a-z0-9_]/gi, '_')}`;\n\n await this.ensureReplicationSlot();\n await this.ensurePublication();\n\n const connectionOptions = this.buildConnectionOptions();\n\n const service = new LogicalReplicationService(connectionOptions, {\n acknowledge: { auto: true, timeoutSeconds: 10 },\n }) as unknown as typeof this.service;\n\n if (!service) {\n throw new Error('Failed to create LogicalReplicationService');\n }\n\n this.service = service;\n\n const plugin = new PgoutputPlugin({\n protoVersion: 1,\n publicationNames: ['metis_pub'],\n });\n\n this.service.on('data', (lsn: unknown, log: unknown) => {\n const event = log as WalEvent;\n try {\n let change: RawChange | undefined;\n if (event.tag === 'insert') {\n change = this.mapWalInsert(event as WalInsertEvent);\n } else if (event.tag === 'update') {\n change = this.mapWalUpdate(event as WalUpdateEvent);\n } else if (event.tag === 'delete') {\n change = this.mapWalDelete(event as WalDeleteEvent);\n }\n\n if (change) {\n this.reconnectAttempts = 0; // Reset on successful data\n onChange(change);\n }\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n logger.error({ err: message, lsn }, 'Failed to process WAL event');\n }\n });\n\n this.service.on('error', (err: unknown) => {\n const message = err instanceof Error ? err.message : String(err);\n logger.error({ err: message }, 'Replication stream error');\n this.attemptReconnect();\n });\n\n this.service.subscribe(plugin, this.slotName).catch((err: unknown) => {\n const message = err instanceof Error ? err.message : String(err);\n logger.error({ err: message }, 'Replication subscribe failed');\n });\n\n this.running = true;\n logger.info({ slotName: this.slotName }, 'PostgreSQL WAL stream started');\n }\n\n private attemptReconnect(): void {\n if (!this.lastOnChange || this.reconnectAttempts >= this.reconnectOpts.maxAttempts) {\n logger.error({ attempts: this.reconnectAttempts }, 'Max reconnection attempts reached, stream stopped');\n this.running = false;\n return;\n }\n\n const delay = computeBackoff(this.reconnectAttempts, this.reconnectOpts);\n this.reconnectAttempts++;\n logger.info({ attempt: this.reconnectAttempts, delayMs: delay }, 'Reconnecting WAL stream');\n\n setTimeout(() => {\n if (!this.lastOnChange) return;\n this.connectStream(this.lastOnChange).catch((err: unknown) => {\n const message = err instanceof Error ? err.message : String(err);\n logger.error({ err: message }, 'Reconnection failed');\n this.attemptReconnect();\n });\n }, delay);\n }\n\n async stop(): Promise<void> {\n if (this.service) {\n await this.service.stop();\n this.service.removeAllListeners();\n this.service = null;\n }\n this.running = false;\n logger.info('PostgreSQL WAL stream stopped');\n }\n\n async cleanup(): Promise<void> {\n await this.stop();\n\n if (this.slotName) {\n try {\n await this.connector.query(\n 'SELECT pg_drop_replication_slot($1)',\n [this.slotName]\n );\n logger.info({ slotName: this.slotName }, 'Replication slot dropped');\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n logger.error({ err: message, slotName: this.slotName }, 'Failed to drop replication slot');\n }\n }\n }\n\n isRunning(): boolean {\n return this.running;\n }\n\n mapWalInsert(event: WalInsertEvent): RawChange {\n const primaryKey = this.extractPrimaryKey(event.relation, event.new);\n\n return {\n tableName: event.relation.name,\n tableSchema: event.relation.schema,\n operation: 'INSERT',\n primaryKey,\n newData: event.new as Record<string, unknown>,\n detectedAt: new Date(),\n };\n }\n\n mapWalUpdate(event: WalUpdateEvent): RawChange {\n const primaryKey = this.extractPrimaryKey(event.relation, event.new);\n const changedColumns = this.computeChangedColumns(event.old, event.new);\n\n return {\n tableName: event.relation.name,\n tableSchema: event.relation.schema,\n operation: 'UPDATE',\n primaryKey,\n newData: event.new as Record<string, unknown>,\n oldData: event.old as Record<string, unknown> | undefined,\n changedColumns,\n detectedAt: new Date(),\n };\n }\n\n mapWalDelete(event: WalDeleteEvent): RawChange {\n const primaryKey = this.extractPrimaryKey(event.relation, event.old);\n\n return {\n tableName: event.relation.name,\n tableSchema: event.relation.schema,\n operation: 'DELETE',\n primaryKey,\n oldData: event.old as Record<string, unknown>,\n detectedAt: new Date(),\n };\n }\n\n private extractPrimaryKey(\n relation: WalRelation,\n data: Record<string, unknown>\n ): string | number {\n const pkColumn = relation.columns.find((col) => (col.flags & 1) !== 0);\n\n if (pkColumn) {\n const value = data[pkColumn.name];\n if (typeof value === 'number' || typeof value === 'string') {\n return value;\n }\n return String(value);\n }\n\n if (data.id !== undefined) {\n const id = data.id;\n if (typeof id === 'number' || typeof id === 'string') {\n return id;\n }\n return String(id);\n }\n\n return 'unknown';\n }\n\n private computeChangedColumns(\n oldData: Record<string, unknown> | undefined,\n newData: Record<string, unknown>\n ): string[] {\n if (!oldData) {\n return Object.keys(newData);\n }\n\n const changed: string[] = [];\n for (const key of Object.keys(newData)) {\n if (oldData[key] !== newData[key]) {\n changed.push(key);\n }\n }\n return changed;\n }\n\n private async ensureReplicationSlot(): Promise<void> {\n const result = await this.connector.query(\n \"SELECT slot_name FROM pg_replication_slots WHERE slot_name = $1\",\n [this.slotName]\n );\n\n if (result.rowCount === 0) {\n await this.connector.query(\n \"SELECT pg_create_logical_replication_slot($1, 'pgoutput')\",\n [this.slotName]\n );\n logger.info({ slotName: this.slotName }, 'Created replication slot');\n }\n }\n\n private async ensurePublication(): Promise<void> {\n const result = await this.connector.query(\n \"SELECT pubname FROM pg_publication WHERE pubname = 'metis_pub'\"\n );\n\n if (result.rowCount === 0) {\n await this.connector.query(\n 'CREATE PUBLICATION metis_pub FOR ALL TABLES'\n );\n logger.info('Created publication metis_pub');\n }\n }\n\n private buildConnectionOptions(): Record<string, unknown> {\n if (this.connectionConfig.url) {\n return { connectionString: this.connectionConfig.url };\n }\n\n return {\n host: this.connectionConfig.host,\n port: this.connectionConfig.port,\n database: this.connectionConfig.database,\n user: this.connectionConfig.user,\n password: this.connectionConfig.password,\n };\n }\n}\n","import type { ConnectionConfig } from '../../core/config.js';\nimport type { DatabaseConnector } from '../../connectors/types.js';\nimport type { RawChange } from '../types.js';\nimport type { ChangeStream, ReconnectOptions } from './types.js';\nimport { resolveReconnectOptions, computeBackoff } from './types.js';\nimport type { ZongjiOptions } from '@powersync/mysql-zongji';\nimport { createLogger } from '../../core/logger.js';\n\nexport interface BinlogTableInfo {\n parentSchema: string;\n tableName: string;\n columns: Array<{ name: string }>;\n}\n\nexport interface BinlogEvent {\n tableMap: Record<number, BinlogTableInfo>;\n tableId: number;\n rows: Array<Record<string, unknown>>;\n}\n\nexport type BinlogEventType = 'writerows' | 'updaterows' | 'deleterows';\n\nconst logger = createLogger({ name: 'mysql-stream' });\n\nexport class MySQLStream implements ChangeStream {\n private readonly connectionConfig: ConnectionConfig;\n private readonly connector: DatabaseConnector;\n private running: boolean;\n private zongji: import('@powersync/mysql-zongji').ZongJi | null;\n private reconnectOpts: Required<ReconnectOptions>;\n private reconnectAttempts: number;\n private lastOnChange: ((change: RawChange) => void) | null;\n\n constructor(connectionConfig: ConnectionConfig, connector: DatabaseConnector, reconnect?: ReconnectOptions) {\n this.connectionConfig = connectionConfig;\n this.connector = connector;\n this.running = false;\n this.zongji = null;\n this.reconnectOpts = resolveReconnectOptions(reconnect);\n this.reconnectAttempts = 0;\n this.lastOnChange = null;\n }\n\n async start(onChange: (change: RawChange) => void): Promise<void> {\n this.lastOnChange = onChange;\n this.reconnectAttempts = 0;\n await this.connectStream(onChange);\n }\n\n private async connectStream(onChange: (change: RawChange) => void): Promise<void> {\n const { ZongJi } = await import('@powersync/mysql-zongji');\n\n const connectionOptions = this.buildConnectionOptions();\n\n const zongji = new ZongJi(connectionOptions);\n\n this.zongji = zongji;\n\n this.zongji.on('binlog', (event: unknown) => {\n try {\n const binlogEvent = event as { getEventName: () => string } & BinlogEvent;\n const eventName = binlogEvent.getEventName().toLowerCase();\n\n if (eventName === 'writerows' || eventName === 'updaterows' || eventName === 'deleterows') {\n const changes = this.mapBinlogEvent(eventName, binlogEvent);\n for (const change of changes) {\n this.reconnectAttempts = 0;\n onChange(change);\n }\n }\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n logger.error({ err: message }, 'Failed to process binlog event');\n }\n });\n\n this.zongji.on('error', (err: unknown) => {\n const message = err instanceof Error ? err.message : String(err);\n logger.error({ err: message }, 'Binlog stream error');\n this.attemptReconnect();\n });\n\n this.zongji.start({\n serverId: Math.floor(Math.random() * 100000) + 1,\n includeEvents: ['tablemap', 'writerows', 'updaterows', 'deleterows'],\n });\n\n this.running = true;\n logger.info('MySQL binlog stream started');\n }\n\n private attemptReconnect(): void {\n if (!this.lastOnChange || this.reconnectAttempts >= this.reconnectOpts.maxAttempts) {\n logger.error({ attempts: this.reconnectAttempts }, 'Max reconnection attempts reached, stream stopped');\n this.running = false;\n return;\n }\n\n const delay = computeBackoff(this.reconnectAttempts, this.reconnectOpts);\n this.reconnectAttempts++;\n logger.info({ attempt: this.reconnectAttempts, delayMs: delay }, 'Reconnecting binlog stream');\n\n setTimeout(() => {\n if (!this.lastOnChange) return;\n this.connectStream(this.lastOnChange).catch((err: unknown) => {\n const message = err instanceof Error ? err.message : String(err);\n logger.error({ err: message }, 'Reconnection failed');\n this.attemptReconnect();\n });\n }, delay);\n }\n\n async stop(): Promise<void> {\n if (this.zongji) {\n this.zongji.stop();\n this.zongji = null;\n }\n this.running = false;\n logger.info('MySQL binlog stream stopped');\n }\n\n async cleanup(): Promise<void> {\n await this.stop();\n // MySQL has no replication slot — nothing extra to clean up\n }\n\n isRunning(): boolean {\n return this.running;\n }\n\n mapBinlogEvent(eventType: BinlogEventType, event: BinlogEvent): RawChange[] {\n const tableInfo = event.tableMap[event.tableId];\n if (!tableInfo) {\n return [];\n }\n\n const changes: RawChange[] = [];\n\n switch (eventType) {\n case 'writerows': {\n for (const row of event.rows) {\n const primaryKey = this.extractPrimaryKey(row);\n\n changes.push({\n tableName: tableInfo.tableName,\n tableSchema: tableInfo.parentSchema,\n operation: 'INSERT',\n primaryKey,\n newData: row,\n detectedAt: new Date(),\n });\n }\n break;\n }\n case 'updaterows': {\n for (const row of event.rows) {\n const updateRow = row as unknown as { before: Record<string, unknown>; after: Record<string, unknown> };\n const primaryKey = this.extractPrimaryKey(updateRow.after);\n const changedColumns = this.computeChangedColumns(updateRow.before, updateRow.after);\n\n changes.push({\n tableName: tableInfo.tableName,\n tableSchema: tableInfo.parentSchema,\n operation: 'UPDATE',\n primaryKey,\n oldData: updateRow.before,\n newData: updateRow.after,\n changedColumns,\n detectedAt: new Date(),\n });\n }\n break;\n }\n case 'deleterows': {\n for (const row of event.rows) {\n const primaryKey = this.extractPrimaryKey(row);\n\n changes.push({\n tableName: tableInfo.tableName,\n tableSchema: tableInfo.parentSchema,\n operation: 'DELETE',\n primaryKey,\n oldData: row,\n detectedAt: new Date(),\n });\n }\n break;\n }\n }\n\n return changes;\n }\n\n private extractPrimaryKey(data: Record<string, unknown>): string | number {\n if (data.id !== undefined) {\n const id = data.id;\n if (typeof id === 'number' || typeof id === 'string') {\n return id;\n }\n return String(id);\n }\n\n return 'unknown';\n }\n\n private computeChangedColumns(\n oldData: Record<string, unknown>,\n newData: Record<string, unknown>\n ): string[] {\n const changed: string[] = [];\n for (const key of Object.keys(newData)) {\n if (oldData[key] !== newData[key]) {\n changed.push(key);\n }\n }\n return changed;\n }\n\n private buildConnectionOptions(): ZongjiOptions {\n if (this.connectionConfig.url) {\n const url = new URL(this.connectionConfig.url);\n return {\n host: url.hostname,\n port: url.port ? parseInt(url.port, 10) : 3306,\n user: decodeURIComponent(url.username),\n password: decodeURIComponent(url.password),\n };\n }\n\n return {\n host: this.connectionConfig.host ?? 'localhost',\n port: this.connectionConfig.port,\n user: this.connectionConfig.user ?? '',\n password: this.connectionConfig.password ?? '',\n };\n }\n}\n","import { MongoClient, type ChangeStreamDocument, type Document } from 'mongodb';\nimport type { ConnectionConfig } from '../../core/config.js';\nimport type { RawChange } from '../types.js';\nimport type { ChangeStream as CortexaChangeStream } from './types.js';\nimport { createLogger } from '../../core/logger.js';\n\nexport class MongoDBStream implements CortexaChangeStream {\n private readonly connectionConfig: ConnectionConfig;\n private readonly logger = createLogger({ name: 'mongodb-stream' });\n private client: MongoClient | null = null;\n private changeStream: ReturnType<MongoClient['db']> extends infer D ? (D extends { watch: (...args: unknown[]) => infer W } ? W : never) : never = null as never;\n private _running = false;\n\n constructor(connectionConfig: ConnectionConfig) {\n this.connectionConfig = connectionConfig;\n }\n\n async start(onChange: (change: RawChange) => void): Promise<void> {\n const url = this.connectionConfig.url ??\n `mongodb://${this.connectionConfig.host ?? 'localhost'}:${this.connectionConfig.port ?? 27017}`;\n const dbName = this.connectionConfig.database ?? 'test';\n\n this.client = new MongoClient(url);\n await this.client.connect();\n const db = this.client.db(dbName);\n\n const stream = db.watch([], { fullDocument: 'updateLookup' });\n this._running = true;\n\n stream.on('change', (event: ChangeStreamDocument<Document>) => {\n const rawChange = this.mapChangeEvent(event);\n if (rawChange) {\n onChange(rawChange);\n }\n });\n\n stream.on('error', (err: Error) => {\n this.logger.error({ error: err.message }, 'MongoDB change stream error');\n this._running = false;\n });\n\n stream.on('close', () => {\n this._running = false;\n });\n\n // Store as unknown to avoid complex type gymnastics\n this.changeStream = stream as never;\n this.logger.info('MongoDB change stream started');\n }\n\n async stop(): Promise<void> {\n if (this.changeStream) {\n await (this.changeStream as unknown as { close: () => Promise<void> }).close();\n this.changeStream = null as never;\n }\n this._running = false;\n }\n\n isRunning(): boolean {\n return this._running;\n }\n\n async cleanup(): Promise<void> {\n await this.stop();\n if (this.client) {\n await this.client.close();\n this.client = null;\n }\n }\n\n private mapChangeEvent(event: ChangeStreamDocument<Document>): RawChange | null {\n const evt = event as unknown as Record<string, unknown>;\n const ns = evt.ns as { db: string; coll: string } | undefined;\n if (!ns) return null;\n\n let operation: 'INSERT' | 'UPDATE' | 'DELETE';\n switch (event.operationType) {\n case 'insert':\n operation = 'INSERT';\n break;\n case 'update':\n case 'replace':\n operation = 'UPDATE';\n break;\n case 'delete':\n operation = 'DELETE';\n break;\n default:\n return null;\n }\n\n const documentKey = evt.documentKey as Record<string, unknown> | undefined;\n const primaryKey = documentKey?._id ? String(documentKey._id) : 'unknown';\n\n const fullDoc = evt.fullDocument as Record<string, unknown> | undefined;\n\n return {\n tableName: ns.coll,\n tableSchema: ns.db,\n operation,\n primaryKey,\n newData: fullDoc ?? undefined,\n detectedAt: new Date(),\n };\n }\n}\n","import { EventEmitter } from 'node:events';\nimport type { CortexaConfig, ConnectionConfig } from './core/config.js';\nimport { createConnector } from './core/connection.js';\nimport { CortexaStorage } from './core/storage.js';\nimport { createLogger } from './core/logger.js';\nimport { createLLMProvider } from './llm/factory.js';\nimport { SchemaIntrospector } from './schema/introspector.js';\nimport { SchemaClassifier } from './schema/classifier.js';\nimport { GraphBuilder } from './schema/graph-builder.js';\nimport { Watcher } from './behavioral/watcher.js';\nimport type { DatabaseConnector } from './connectors/types.js';\nimport type { LLMProvider } from './llm/types.js';\nimport type { ClassifiedEntity, EntityGraph, DiscoveryResult, DiscoveryOptions, RawTable } from './schema/types.js';\nimport type { BusinessEvent, Anomaly, AnomalyType, WatchOptions } from './behavioral/types.js';\nimport type { Insight, InsightType, Severity } from './reasoning/types.js';\nimport type { CorrelationStatus, DistributionSummary } from './analytics/types.js';\nimport type { KnowledgeNode, KnowledgeEdge, EntityIntelligenceResult, GraphSummary, GraphExport, KnowledgeConfig, NodeType, EdgeType } from './knowledge/types.js';\nimport { GraphStore } from './knowledge/graph-store.js';\nimport { Traversal } from './knowledge/traversal.js';\nimport { EntityIntelligence } from './knowledge/entity-intelligence.js';\nimport { GraphPopulator } from './knowledge/graph-populator.js';\nimport { exportGraph } from './knowledge/export.js';\nimport { ActionRegistry } from './actions/action-registry.js';\nimport type { ActionContext } from './actions/types.js';\nimport { Notifier } from './notifications/notifier.js';\nimport { Explainer } from './explain/explainer.js';\nimport type { ExplainTarget, ExplainOptions, ExplainResult } from './explain/types.js';\nimport { Asker } from './ask/asker.js';\nimport type { AskOptions, AskResult } from './ask/types.js';\n\nexport { defineConfig } from './core/config.js';\nexport type { CortexaConfig, ConnectionConfig, LlmConfig } from './core/config.js';\nexport type {\n ClassifiedEntity,\n Relationship,\n EntityGraph,\n DiscoveryResult,\n DiscoveryOptions,\n RawSchema,\n} from './schema/types.js';\n\nexport type { LLMProvider } from './llm/types.js';\nexport type {\n BusinessEvent,\n Anomaly,\n AnomalyType,\n Baseline,\n WatchOptions,\n StreamCapability,\n} from './behavioral/types.js';\n\nexport type { ChangeStream } from './behavioral/streams/types.js';\n\nexport type {\n WorkflowConfig,\n StateTransition,\n TransitionStats,\n Insight,\n InsightType,\n Severity,\n ReasoningConfig,\n} from './reasoning/types.js';\n\nexport type {\n AnalyticsConfig,\n CorrelationConfig,\n DistributionConfig,\n CorrelationStatus,\n DistributionSummary,\n} from './analytics/types.js';\n\nexport type {\n NodeType,\n EdgeType,\n KnowledgeNode,\n KnowledgeEdge,\n EntityIntelligenceResult,\n KnowledgeConfig,\n GraphSummary,\n GraphExport,\n} from './knowledge/types.js';\n\nexport type {\n GovernanceLevel,\n RecommendationStatus,\n ActionContext,\n ActionHandler,\n ActionRule,\n Recommendation,\n RecommendationSummary,\n ActionsConfig,\n} from './actions/types.js';\n\nexport type {\n NotificationsConfig,\n NotificationRule,\n WebhookTarget,\n NotificationTrigger,\n NotificationFilter,\n} from './notifications/types.js';\n\nexport type {\n ExplainTarget,\n ExplainOptions,\n ExplainResult,\n Evidence,\n CausalStep,\n RecommendedAction,\n} from './explain/types.js';\n\nexport type {\n AskOptions,\n AskResult,\n SupportingSignal,\n SignalType,\n} from './ask/types.js';\n\nexport class KnowledgeGraph {\n private readonly store: GraphStore;\n private readonly traversal: Traversal;\n private readonly entityIntelligence: EntityIntelligence;\n\n constructor(store: GraphStore) {\n this.store = store;\n this.traversal = new Traversal(store);\n this.entityIntelligence = new EntityIntelligence(store);\n }\n\n causesOf(nodeId: number, maxDepth?: number): KnowledgeNode[] {\n return this.traversal.causesOf(nodeId, maxDepth);\n }\n\n impactOf(nodeId: number, maxDepth?: number): KnowledgeNode[] {\n return this.traversal.impactOf(nodeId, maxDepth);\n }\n\n timeline(nodeId: number): KnowledgeNode[] {\n return this.traversal.timeline(nodeId);\n }\n\n entity(refId: string): { intelligence: () => EntityIntelligenceResult | undefined } {\n return {\n intelligence: () => this.entityIntelligence.forEntity(refId),\n };\n }\n\n getNode(id: number): KnowledgeNode | undefined {\n return this.store.getNode(id);\n }\n\n getNodeByRef(nodeType: NodeType, refId: string): KnowledgeNode | undefined {\n return this.store.getNodeByRef(nodeType, refId);\n }\n\n getEdges(nodeId: number, edgeType?: EdgeType): KnowledgeEdge[] {\n return this.store.getEdgesFrom(nodeId, edgeType);\n }\n\n neighbors(nodeId: number): KnowledgeNode[] {\n return this.store.neighbors(nodeId);\n }\n\n getSummary(): GraphSummary {\n return this.store.getSummary();\n }\n\n export(rootNodeId?: number): GraphExport {\n return exportGraph(this.store, rootNodeId);\n }\n}\n\nexport interface CortexaOptions extends CortexaConfig {\n projectRoot?: string;\n llmProvider?: LLMProvider;\n}\n\nexport interface CortexaStatus {\n connected: boolean;\n tables: number;\n db: string;\n watching: boolean;\n}\n\nexport class Cortexa extends EventEmitter {\n private readonly config: CortexaOptions;\n private connector: DatabaseConnector | null = null;\n private storage: CortexaStorage;\n private readonly logger: ReturnType<typeof createLogger>;\n private llmProvider: LLMProvider | null = null;\n private watcher: Watcher | null = null;\n private knowledgeGraph: KnowledgeGraph | null = null;\n private actionRegistry: ActionRegistry;\n private discoveredTables: RawTable[] = [];\n private _status: CortexaStatus = { connected: false, tables: 0, db: '', watching: false };\n\n constructor(config: CortexaOptions) {\n super();\n this.config = config;\n this.logger = createLogger();\n this.storage = new CortexaStorage(config.projectRoot ?? process.cwd());\n this.actionRegistry = new ActionRegistry(config.actions?.governance);\n }\n\n async connect(): Promise<void> {\n this.logger.info('Connecting to database...');\n\n this.storage.initialize();\n\n this.connector = await createConnector(this.config.connection.type);\n await this.connector.connect(this.config.connection);\n\n const tables = await this.connector.getTableCount();\n const db = await this.connector.getDatabaseName();\n\n const readOnly = await this.connector.isReadOnly();\n if (!readOnly) {\n this.logger.warn(\n 'Connection is NOT read-only. Cortexa recommends using a read-only database user.'\n );\n }\n\n if (this.config.llmProvider) {\n this.llmProvider = this.config.llmProvider;\n } else if (this.config.llm) {\n this.llmProvider = createLLMProvider(this.config.llm);\n }\n\n this.storage.setMeta('database_name', db);\n this.storage.setMeta('table_count', String(tables));\n this.storage.setMeta('connected_at', new Date().toISOString());\n\n this._status = { connected: true, tables, db, watching: false };\n this.logger.info({ db, tables }, 'Connected successfully');\n }\n\n async disconnect(): Promise<void> {\n this.unwatch();\n if (this.connector) {\n await this.connector.disconnect();\n this.connector = null;\n }\n this.llmProvider = null;\n this.knowledgeGraph = null;\n this.storage.close();\n this._status = { connected: false, tables: 0, db: '', watching: false };\n this.logger.info('Disconnected');\n }\n\n async discover(options?: DiscoveryOptions): Promise<DiscoveryResult> {\n if (!this.llmProvider) {\n throw new Error('LLM configuration required for schema discovery. Add llm config to your Cortexa options.');\n }\n if (!this.connector) {\n throw new Error('Not connected. Call connect() first.');\n }\n\n this.logger.info('Starting schema discovery...');\n\n const introspector = new SchemaIntrospector(this.connector, this.config.connection.type, options);\n const rawSchema = await introspector.introspect();\n this.logger.info({ tables: rawSchema.tables.length }, 'Schema introspected');\n\n const classifier = new SchemaClassifier(this.llmProvider, this.config.batchSize);\n const entities = await classifier.classify(rawSchema.tables);\n this.logger.info({ entities: entities.length }, 'Entities classified');\n\n const graphBuilder = new GraphBuilder();\n const graph = graphBuilder.build(rawSchema.tables, entities);\n\n // Persist to storage\n for (const entity of entities) {\n this.storage.saveEntity(entity);\n }\n this.storage.clearRelationships();\n for (const rel of graph.relationships) {\n this.storage.saveRelationship(rel);\n }\n for (const table of rawSchema.tables) {\n this.storage.saveDiscoveredTable(table);\n }\n\n this.discoveredTables = rawSchema.tables;\n\n // Populate knowledge graph if enabled\n if (this.config.knowledge?.enabled) {\n const graphStore = new GraphStore(this.storage);\n const populator = new GraphPopulator(graphStore);\n populator.populateFromSchema(rawSchema.tables);\n this.logger.info('Knowledge graph populated from schema');\n }\n\n this.logger.info('Discovery complete');\n\n return {\n entities: graph.entities,\n relationships: graph.relationships,\n raw: rawSchema,\n };\n }\n\n entity(tableName: string): ClassifiedEntity | undefined {\n return this.storage.getEntity(tableName);\n }\n\n exportGraph(): EntityGraph {\n return {\n entities: this.storage.getEntities(),\n relationships: this.storage.getRelationships(),\n };\n }\n\n async watch(options?: WatchOptions): Promise<void> {\n if (!this.connector) {\n throw new Error('Not connected. Call connect() first.');\n }\n\n this.watcher = new Watcher({\n connector: this.connector,\n dbType: this.config.connection.type,\n storage: this.storage,\n tables: this.discoveredTables,\n connectionConfig: this.config.connection,\n onEvent: (event: BusinessEvent) => this.emit('event', event),\n onAnomaly: (anomaly: Anomaly) => this.emit('anomaly', anomaly),\n onInsight: (insight: Insight) => this.emit('insight', insight),\n onRecommendation: (rec: Record<string, unknown>) => this.emit('recommendation', rec),\n onActionExecuted: (rec: Record<string, unknown>) => this.emit('action:executed', rec),\n onActionFailed: (rec: Record<string, unknown>) => this.emit('action:failed', rec),\n workflows: this.config.reasoning?.workflows,\n analytics: this.config.analytics,\n knowledge: this.config.knowledge,\n actions: this.config.actions,\n actionRegistry: this.actionRegistry,\n });\n\n // Hook up notifications if configured\n if (this.config.notifications?.enabled && this.config.notifications.rules?.length) {\n const notifier = new Notifier(this.config.notifications.rules);\n this.on('anomaly', (data) => notifier.notify('anomaly', data as Record<string, unknown>));\n this.on('insight', (data) => notifier.notify('insight', data as Record<string, unknown>));\n this.on('recommendation', (data) => notifier.notify('recommendation', data as Record<string, unknown>));\n this.on('action:executed', (data) => notifier.notify('action:executed', data as Record<string, unknown>));\n this.on('action:failed', (data) => notifier.notify('action:failed', data as Record<string, unknown>));\n }\n\n await this.watcher.start(options);\n\n if (options?.once) {\n this.watcher = null;\n this.logger.info('Single poll cycle complete');\n return;\n }\n\n this._status = { ...this._status, watching: true };\n this.logger.info('Watcher started');\n }\n\n unwatch(): void {\n if (this.watcher) {\n this.watcher.stop();\n this.watcher = null;\n this._status = { ...this._status, watching: false };\n this.logger.info('Watcher stopped');\n }\n }\n\n async cleanupStream(): Promise<void> {\n if (this.watcher) {\n await this.watcher.cleanup();\n this.watcher = null;\n this._status = { ...this._status, watching: false };\n this.logger.info('Stream cleaned up');\n }\n }\n\n getEvents(filter?: { entity?: string; last?: number; operation?: 'INSERT' | 'UPDATE' | 'DELETE'; eventType?: string }): Array<{ id: number; eventType: string; entity: string; tableName: string; operation: 'INSERT' | 'UPDATE' | 'DELETE'; rowId: string | null; rowData: string | null; timestamp: string }> {\n return this.storage.getEvents(filter) as Array<{ id: number; eventType: string; entity: string; tableName: string; operation: 'INSERT' | 'UPDATE' | 'DELETE'; rowId: string | null; rowData: string | null; timestamp: string }>;\n }\n\n getBaselines(): Array<{ entity: string; metric: string; mean: number; stddev: number; sampleSize: number }> {\n return this.storage.getBaselines();\n }\n\n getAnomalies(filter?: { last?: number; entity?: string; severity?: Severity; anomalyType?: AnomalyType }): Array<{ id: number; entity: string; anomalyType: AnomalyType; severity: Severity; expected: number; actual: number; message: string; timestamp: string }> {\n return this.storage.getAnomalies(filter) as Array<{ id: number; entity: string; anomalyType: AnomalyType; severity: Severity; expected: number; actual: number; message: string; timestamp: string }>;\n }\n\n getInsights(filter?: { entity?: string; last?: number; insightType?: InsightType; severity?: Severity }): Array<{ id: number; entity: string; insightType: InsightType; severity: Severity; message: string; context: Record<string, unknown>; timestamp: string }> {\n return this.storage.getInsights(filter) as Array<{ id: number; entity: string; insightType: InsightType; severity: Severity; message: string; context: Record<string, unknown>; timestamp: string }>;\n }\n\n getTransitions(entity?: string): Array<{ entity: string; fromState: string; toState: string; count: number; avgDurationMs: number; minDurationMs: number; maxDurationMs: number }> {\n return this.storage.getTransitionStats(entity);\n }\n\n getCorrelations(): CorrelationStatus[] {\n if (!this.config.analytics?.correlations) {\n return [];\n }\n\n const results: CorrelationStatus[] = [];\n\n for (const [name, corrConfig] of Object.entries(this.config.analytics.correlations)) {\n const rateBaseline = this.storage.getAnalyticsBaseline(`correlation:${name}:rate_ratio`);\n const coOccBaseline = this.storage.getAnalyticsBaseline(`correlation:${name}:co_occurrence`);\n\n const rateRatio = rateBaseline ? rateBaseline.mean : 0;\n const coOccurrenceRate = coOccBaseline ? coOccBaseline.mean : 0;\n\n const healthy = !!(rateBaseline && coOccBaseline);\n\n results.push({\n name,\n entities: corrConfig.entities,\n rateRatio,\n baselineRatio: rateBaseline ? rateBaseline.mean : 0,\n coOccurrenceRate,\n baselineCoOccurrence: coOccBaseline ? coOccBaseline.mean : 0,\n healthy,\n });\n }\n\n return results;\n }\n\n getDistributions(entity?: string): DistributionSummary[] {\n if (!this.config.analytics?.distributions) {\n return [];\n }\n\n const results: DistributionSummary[] = [];\n\n for (const [entityName, distConfig] of Object.entries(this.config.analytics.distributions)) {\n if (entity && entity !== entityName) continue;\n\n for (const col of distConfig.columns) {\n const buckets = this.storage.getHistogramBuckets(entityName, col, 'baseline');\n const shiftBaseline = this.storage.getAnalyticsBaseline(`distribution:${entityName}:${col}:shift`);\n\n results.push({\n entity: entityName,\n columnName: col,\n bucketCount: buckets.length,\n baselineSamples: shiftBaseline ? shiftBaseline.sampleSize : 0,\n currentShift: shiftBaseline ? shiftBaseline.mean : null,\n shifted: shiftBaseline ? Math.abs(shiftBaseline.mean) > shiftBaseline.stddev * 2 : false,\n });\n }\n }\n\n return results;\n }\n\n graph(): KnowledgeGraph {\n if (!this.knowledgeGraph) {\n const graphStore = new GraphStore(this.storage);\n this.knowledgeGraph = new KnowledgeGraph(graphStore);\n }\n return this.knowledgeGraph;\n }\n\n async explain(target: ExplainTarget, options?: ExplainOptions): Promise<ExplainResult> {\n if (!this.llmProvider) {\n throw new Error('LLM configuration required for explain(). Add llm config to your Cortexa options.');\n }\n\n const graphStore = new GraphStore(this.storage);\n const traversal = new Traversal(graphStore);\n const explainer = new Explainer(this.llmProvider, this.storage, graphStore, traversal);\n return explainer.explain(target, options);\n }\n\n async ask(question: string, options?: AskOptions): Promise<AskResult> {\n if (!this.llmProvider) {\n throw new Error('LLM configuration required for ask(). Add llm config to your Cortexa options.');\n }\n\n const graphStore = new GraphStore(this.storage);\n const asker = new Asker(this.llmProvider, this.storage, graphStore);\n return asker.ask(question, options);\n }\n\n registerAction(name: string, handler: (context: ActionContext) => Promise<void>, description?: string): void {\n this.actionRegistry.register(name, handler, description);\n }\n\n approveRecommendation(id: number): void {\n this.storage.updateRecommendationStatus(id, 'approved', 'user');\n }\n\n rejectRecommendation(id: number): void {\n this.storage.updateRecommendationStatus(id, 'rejected', 'user');\n }\n\n getRecommendations(filter?: { status?: string; action?: string; last?: number }): Array<{ id: number; action: string; reason: string; confidence: number; status: string; governance: string; insightId: string | null; entity: string; context: string; createdAt: string; resolvedAt: string | null; resolvedBy: string | null }> {\n return this.storage.getRecommendations(filter);\n }\n\n get status(): CortexaStatus {\n return { ...this._status };\n }\n}\n","import type { ConnectionConfig } from './config.js';\nimport type { DatabaseConnector } from '../connectors/types.js';\nimport { PostgresConnector } from '../connectors/postgres.js';\nimport { MySQLConnector } from '../connectors/mysql.js';\nimport { SQLiteConnector } from '../connectors/sqlite.js';\n\nexport async function createConnector(type: ConnectionConfig['type']): Promise<DatabaseConnector> {\n switch (type) {\n case 'postgres':\n case 'cockroachdb':\n return new PostgresConnector();\n case 'mysql':\n case 'mariadb':\n return new MySQLConnector();\n case 'sqlite':\n return new SQLiteConnector();\n case 'mongodb': {\n const { MongoDBConnector } = await import('../connectors/mongodb.js');\n return new MongoDBConnector();\n }\n case 'mssql': {\n const { MSSQLConnector } = await import('../connectors/mssql.js');\n return new MSSQLConnector();\n }\n default:\n throw new Error(`Unsupported database type: ${type as string}`);\n }\n}\n","import pg from 'pg';\nimport type { ConnectionConfig } from '../core/config.js';\nimport type { DatabaseConnector, QueryResult } from './types.js';\n\nconst { Pool } = pg;\n\nexport class PostgresConnector implements DatabaseConnector {\n private pool: InstanceType<typeof Pool> | null = null;\n\n async connect(config: ConnectionConfig): Promise<void> {\n if (config.url) {\n this.pool = new Pool({ connectionString: config.url });\n } else {\n this.pool = new Pool({\n host: config.host,\n port: config.port,\n database: config.database,\n user: config.user,\n password: config.password,\n });\n }\n // Verify connectivity by acquiring and releasing a client\n const client = await this.pool.connect();\n client.release();\n }\n\n async disconnect(): Promise<void> {\n if (this.pool) {\n await this.pool.end();\n this.pool = null;\n }\n }\n\n async getTableCount(): Promise<number> {\n this.ensureConnected();\n const result = await this.pool!.query(\n `SELECT COUNT(*) as count FROM information_schema.tables\n WHERE table_schema = 'public' AND table_type = 'BASE TABLE'`\n );\n return parseInt(result.rows[0].count, 10);\n }\n\n async getDatabaseName(): Promise<string> {\n this.ensureConnected();\n const result = await this.pool!.query('SELECT current_database() as db');\n return result.rows[0].db;\n }\n\n async isReadOnly(): Promise<boolean> {\n this.ensureConnected();\n try {\n await this.pool!.query(\n 'CREATE TEMP TABLE _cortexa_ro_check (id int)'\n );\n return false;\n } catch {\n return true;\n } finally {\n try {\n await this.pool!.query(\n 'DROP TABLE IF EXISTS _cortexa_ro_check'\n );\n } catch {\n // ignore cleanup errors\n }\n }\n }\n\n async query(sql: string, params?: unknown[]): Promise<QueryResult> {\n this.ensureConnected();\n const result = await this.pool!.query(sql, params);\n return {\n rows: result.rows,\n rowCount: result.rowCount ?? result.rows.length,\n };\n }\n\n isConnected(): boolean {\n return this.pool !== null;\n }\n\n private ensureConnected(): void {\n if (!this.pool) {\n throw new Error('Not connected. Call connect() first.');\n }\n }\n}\n","import mysql from 'mysql2/promise';\nimport type { ConnectionConfig } from '../core/config.js';\nimport type { DatabaseConnector, QueryResult } from './types.js';\n\nexport class MySQLConnector implements DatabaseConnector {\n private pool: mysql.Pool | null = null;\n\n async connect(config: ConnectionConfig): Promise<void> {\n if (config.url) {\n this.pool = mysql.createPool(config.url);\n } else {\n this.pool = mysql.createPool({\n host: config.host,\n port: config.port,\n database: config.database,\n user: config.user,\n password: config.password,\n });\n }\n // Verify connectivity by acquiring and releasing a connection\n const conn = await this.pool.getConnection();\n conn.release();\n }\n\n async disconnect(): Promise<void> {\n if (this.pool) {\n await this.pool.end();\n this.pool = null;\n }\n }\n\n async getTableCount(): Promise<number> {\n this.ensureConnected();\n const [rows] = await this.pool!.query(\n `SELECT COUNT(*) as count FROM information_schema.tables\n WHERE table_schema = DATABASE() AND table_type = 'BASE TABLE'`\n );\n return (rows as Record<string, unknown>[])[0].count as number;\n }\n\n async getDatabaseName(): Promise<string> {\n this.ensureConnected();\n const [rows] = await this.pool!.query('SELECT DATABASE() as db');\n return (rows as Record<string, unknown>[])[0].db as string;\n }\n\n async isReadOnly(): Promise<boolean> {\n this.ensureConnected();\n try {\n await this.pool!.query(\n 'CREATE TEMPORARY TABLE _cortexa_ro_check (id INT)'\n );\n return false;\n } catch {\n return true;\n } finally {\n try {\n await this.pool!.query(\n 'DROP TEMPORARY TABLE IF EXISTS _cortexa_ro_check'\n );\n } catch {\n // ignore cleanup errors\n }\n }\n }\n\n async query(sql: string, params?: unknown[]): Promise<QueryResult> {\n this.ensureConnected();\n const mysqlSql = sql.replace(/\\$\\d+/g, '?');\n const [rows] = await this.pool!.query(mysqlSql, params);\n const rowArray = rows as Record<string, unknown>[];\n return {\n rows: rowArray,\n rowCount: rowArray.length,\n };\n }\n\n isConnected(): boolean {\n return this.pool !== null;\n }\n\n private ensureConnected(): void {\n if (!this.pool) {\n throw new Error('Not connected. Call connect() first.');\n }\n }\n}\n","import path from 'node:path';\nimport Database from 'better-sqlite3';\nimport type { ConnectionConfig } from '../core/config.js';\nimport type { DatabaseConnector, QueryResult } from './types.js';\n\nexport class SQLiteConnector implements DatabaseConnector {\n private db: InstanceType<typeof Database> | null = null;\n private dbPath: string = '';\n\n async connect(config: ConnectionConfig): Promise<void> {\n this.dbPath = config.path ?? config.database ?? ':memory:';\n this.db = new Database(this.dbPath, { readonly: true });\n }\n\n async disconnect(): Promise<void> {\n if (this.db) {\n this.db.close();\n this.db = null;\n }\n }\n\n async getTableCount(): Promise<number> {\n this.ensureConnected();\n const row = this.db!.prepare(\n `SELECT COUNT(*) AS count FROM sqlite_master WHERE type = 'table' AND name NOT LIKE 'sqlite_%'`\n ).get() as { count: number };\n return row.count;\n }\n\n async getDatabaseName(): Promise<string> {\n return path.basename(this.dbPath, path.extname(this.dbPath));\n }\n\n async isReadOnly(): Promise<boolean> {\n // We open in readonly mode by default for safety\n return true;\n }\n\n async query(sql: string, params?: unknown[]): Promise<QueryResult> {\n this.ensureConnected();\n // Convert $1, $2 style params to ? style for better-sqlite3\n const convertedSql = sql.replace(/\\$(\\d+)/g, '?');\n const stmt = this.db!.prepare(convertedSql);\n\n if (convertedSql.trim().toUpperCase().startsWith('SELECT') ||\n convertedSql.trim().toUpperCase().startsWith('PRAGMA')) {\n const rows = (params && params.length > 0)\n ? stmt.all(...params) as Record<string, unknown>[]\n : stmt.all() as Record<string, unknown>[];\n return { rows, rowCount: rows.length };\n }\n\n const result = (params && params.length > 0)\n ? stmt.run(...params)\n : stmt.run();\n return { rows: [], rowCount: result.changes };\n }\n\n isConnected(): boolean {\n return this.db !== null;\n }\n\n private ensureConnected(): void {\n if (!this.db) {\n throw new Error('Not connected. Call connect() first.');\n }\n }\n}\n","import Database from 'better-sqlite3';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport type { ClassifiedEntity, Relationship, RawTable } from '../schema/types.js';\n\nexport class CortexaStorage {\n private db: Database.Database | null = null;\n private readonly cortexaDir: string;\n private readonly dbPath: string;\n\n constructor(projectRoot: string) {\n this.cortexaDir = path.join(projectRoot, '.cortexa');\n this.dbPath = path.join(this.cortexaDir, 'cortexa.db');\n }\n\n initialize(): void {\n fs.mkdirSync(this.cortexaDir, { recursive: true });\n\n this.db = new Database(this.dbPath);\n this.db.pragma('journal_mode = WAL');\n\n this.createSchema();\n }\n\n setMeta(key: string, value: string): void {\n this.ensureInitialized();\n this.db!.prepare(\n 'INSERT OR REPLACE INTO meta (key, value) VALUES (?, ?)'\n ).run(key, value);\n }\n\n getMeta(key: string): string | undefined {\n this.ensureInitialized();\n const row = this.db!.prepare(\n 'SELECT value FROM meta WHERE key = ?'\n ).get(key) as { value: string } | undefined;\n return row?.value;\n }\n\n getDiscoveredTableCount(): number {\n this.ensureInitialized();\n const row = this.db!.prepare(\n 'SELECT COUNT(*) as count FROM discovered_tables'\n ).get() as { count: number };\n return row.count;\n }\n\n saveEntity(entity: ClassifiedEntity): void {\n this.ensureInitialized();\n this.db!.prepare(\n `INSERT OR REPLACE INTO entities\n (table_name, entity_label, entity_type, description, confidence, columns_classified)\n VALUES (?, ?, ?, ?, ?, ?)`\n ).run(entity.tableName, entity.entityLabel, entity.entityType, entity.description, entity.confidence, JSON.stringify(entity.columns));\n }\n\n getEntities(): ClassifiedEntity[] {\n this.ensureInitialized();\n const rows = this.db!.prepare('SELECT * FROM entities').all() as any[];\n return rows.map((row) => ({\n tableName: row.table_name,\n entityLabel: row.entity_label,\n entityType: row.entity_type,\n description: row.description,\n confidence: row.confidence,\n columns: JSON.parse(row.columns_classified || '[]'),\n }));\n }\n\n getEntity(tableName: string): ClassifiedEntity | undefined {\n this.ensureInitialized();\n const row = this.db!.prepare('SELECT * FROM entities WHERE table_name = ?').get(tableName) as any;\n if (!row) return undefined;\n return {\n tableName: row.table_name,\n entityLabel: row.entity_label,\n entityType: row.entity_type,\n description: row.description,\n confidence: row.confidence,\n columns: JSON.parse(row.columns_classified || '[]'),\n };\n }\n\n saveRelationship(rel: Relationship): void {\n this.ensureInitialized();\n this.db!.prepare(\n `INSERT OR REPLACE INTO relationships\n (source_entity, target_entity, relationship, source_column, target_column, inferred, confidence)\n VALUES (?, ?, ?, ?, ?, ?, ?)`\n ).run(rel.sourceEntity, rel.targetEntity, rel.relationship, rel.sourceColumn, rel.targetColumn, rel.inferred ? 1 : 0, rel.confidence);\n }\n\n getRelationships(): Relationship[] {\n this.ensureInitialized();\n const rows = this.db!.prepare('SELECT * FROM relationships').all() as any[];\n return rows.map((row) => ({\n sourceEntity: row.source_entity,\n targetEntity: row.target_entity,\n relationship: row.relationship,\n sourceColumn: row.source_column,\n targetColumn: row.target_column,\n inferred: row.inferred === 1,\n confidence: row.confidence,\n }));\n }\n\n clearRelationships(): void {\n this.ensureInitialized();\n this.db!.prepare('DELETE FROM relationships').run();\n }\n\n saveDiscoveredTable(table: RawTable): void {\n this.ensureInitialized();\n this.db!.prepare(\n `INSERT OR REPLACE INTO discovered_tables\n (table_name, table_schema, row_count, columns_json, fk_json, indexes_json, sample_rows)\n VALUES (?, ?, ?, ?, ?, ?, ?)`\n ).run(table.tableName, table.tableSchema, table.rowCount, JSON.stringify(table.columns), JSON.stringify(table.foreignKeys), JSON.stringify(table.indexes), JSON.stringify(table.sampleRows));\n }\n\n setCache(key: string, response: string, model: string, tokensUsed: number): void {\n this.ensureInitialized();\n this.db!.prepare(\n 'INSERT OR REPLACE INTO llm_cache (cache_key, response, model, tokens_used) VALUES (?, ?, ?, ?)'\n ).run(key, response, model, tokensUsed);\n }\n\n getCache(key: string): string | undefined {\n this.ensureInitialized();\n const row = this.db!.prepare('SELECT response FROM llm_cache WHERE cache_key = ?').get(key) as { response: string } | undefined;\n return row?.response;\n }\n\n clearCache(): void {\n this.ensureInitialized();\n this.db!.prepare('DELETE FROM llm_cache').run();\n }\n\n saveEvent(event: { eventType: string; entity: string; tableName: string; operation: string; rowId?: string; rowData?: string }): void {\n this.ensureInitialized();\n this.db!.prepare(\n 'INSERT INTO events (event_type, entity, table_name, operation, row_id, row_data) VALUES (?, ?, ?, ?, ?, ?)'\n ).run(event.eventType, event.entity, event.tableName, event.operation, event.rowId ?? null, event.rowData ?? null);\n }\n\n getEvents(filter?: { entity?: string; last?: number; operation?: string; eventType?: string }): Array<{ id: number; eventType: string; entity: string; tableName: string; operation: string; rowId: string | null; rowData: string | null; timestamp: string }> {\n this.ensureInitialized();\n let sql = 'SELECT id, event_type, entity, table_name, operation, row_id, row_data, timestamp FROM events';\n const conditions: string[] = [];\n const params: unknown[] = [];\n\n if (filter?.entity) {\n conditions.push('entity = ?');\n params.push(filter.entity);\n }\n if (filter?.last) {\n conditions.push(`timestamp >= datetime('now', '-${filter.last} minutes')`);\n }\n if (filter?.operation) {\n conditions.push('operation = ?');\n params.push(filter.operation);\n }\n if (filter?.eventType) {\n conditions.push('event_type = ?');\n params.push(filter.eventType);\n }\n if (conditions.length > 0) {\n sql += ' WHERE ' + conditions.join(' AND ');\n }\n sql += ' ORDER BY timestamp DESC';\n\n const rows = this.db!.prepare(sql).all(...params) as any[];\n return rows.map((r) => ({\n id: r.id as number,\n eventType: r.event_type,\n entity: r.entity,\n tableName: r.table_name,\n operation: r.operation,\n rowId: r.row_id,\n rowData: r.row_data,\n timestamp: r.timestamp,\n }));\n }\n\n countEvents(entity: string, operation: string, lastMinutes: number): number {\n this.ensureInitialized();\n const row = this.db!.prepare(\n `SELECT COUNT(*) as count FROM events WHERE entity = ? AND operation = ? AND timestamp >= datetime('now', '-' || ? || ' minutes')`\n ).get(entity, operation, lastMinutes) as { count: number };\n return row.count;\n }\n\n saveBaseline(baseline: { entity: string; metric: string; mean: number; stddev: number; sampleSize: number }): void {\n this.ensureInitialized();\n this.db!.prepare(\n 'INSERT OR REPLACE INTO baselines (entity, metric, mean, stddev, sample_size) VALUES (?, ?, ?, ?, ?)'\n ).run(baseline.entity, baseline.metric, baseline.mean, baseline.stddev, baseline.sampleSize);\n }\n\n getBaselines(): Array<{ entity: string; metric: string; mean: number; stddev: number; sampleSize: number }> {\n this.ensureInitialized();\n const rows = this.db!.prepare('SELECT entity, metric, mean, stddev, sample_size FROM baselines').all() as any[];\n return rows.map((r) => ({\n entity: r.entity,\n metric: r.metric,\n mean: r.mean,\n stddev: r.stddev,\n sampleSize: r.sample_size,\n }));\n }\n\n saveAnomaly(anomaly: { entity: string; anomalyType: string; severity: string; expected: number; actual: number; message: string }): void {\n this.ensureInitialized();\n this.db!.prepare(\n 'INSERT INTO anomalies (entity, anomaly_type, severity, expected, actual, message) VALUES (?, ?, ?, ?, ?, ?)'\n ).run(anomaly.entity, anomaly.anomalyType, anomaly.severity, anomaly.expected, anomaly.actual, anomaly.message);\n }\n\n getAnomalies(filter?: { last?: number; entity?: string; severity?: string; anomalyType?: string }): Array<{ id: number; entity: string; anomalyType: string; severity: string; expected: number; actual: number; message: string; timestamp: string }> {\n this.ensureInitialized();\n let sql = 'SELECT id, entity, anomaly_type, severity, expected, actual, message, timestamp FROM anomalies';\n const conditions: string[] = [];\n const params: unknown[] = [];\n\n if (filter?.last) {\n conditions.push(`timestamp >= datetime('now', '-${filter.last} minutes')`);\n }\n if (filter?.entity) {\n conditions.push('entity = ?');\n params.push(filter.entity);\n }\n if (filter?.severity) {\n conditions.push('severity = ?');\n params.push(filter.severity);\n }\n if (filter?.anomalyType) {\n conditions.push('anomaly_type = ?');\n params.push(filter.anomalyType);\n }\n if (conditions.length > 0) {\n sql += ' WHERE ' + conditions.join(' AND ');\n }\n sql += ' ORDER BY timestamp DESC';\n\n const rows = this.db!.prepare(sql).all(...params) as any[];\n return rows.map((r) => ({\n id: r.id as number,\n entity: r.entity,\n anomalyType: r.anomaly_type,\n severity: r.severity,\n expected: r.expected,\n actual: r.actual,\n message: r.message,\n timestamp: r.timestamp,\n }));\n }\n\n saveWatermark(wm: { tableName: string; tableSchema: string; strategy: string; timestampColumn?: string; pkColumn?: string; lastSeenValue?: string }): void {\n this.ensureInitialized();\n this.db!.prepare(\n 'INSERT OR REPLACE INTO watch_watermarks (table_name, table_schema, strategy, timestamp_column, pk_column, last_seen_value) VALUES (?, ?, ?, ?, ?, ?)'\n ).run(wm.tableName, wm.tableSchema, wm.strategy, wm.timestampColumn ?? null, wm.pkColumn ?? null, wm.lastSeenValue ?? null);\n }\n\n getWatermark(tableName: string, tableSchema: string): { strategy: string; timestampColumn: string | null; pkColumn: string | null; lastSeenValue: string | null } | undefined {\n this.ensureInitialized();\n const row = this.db!.prepare(\n 'SELECT strategy, timestamp_column, pk_column, last_seen_value FROM watch_watermarks WHERE table_name = ? AND table_schema = ?'\n ).get(tableName, tableSchema) as any;\n if (!row) return undefined;\n return {\n strategy: row.strategy,\n timestampColumn: row.timestamp_column,\n pkColumn: row.pk_column,\n lastSeenValue: row.last_seen_value,\n };\n }\n\n saveTransition(t: { entity: string; tableName: string; primaryKey: string; fromState: string; toState: string; durationMs: number; expected: boolean }): void {\n this.ensureInitialized();\n this.db!.prepare(\n 'INSERT INTO state_transitions (entity, table_name, primary_key, from_state, to_state, duration_ms, expected) VALUES (?, ?, ?, ?, ?, ?, ?)'\n ).run(t.entity, t.tableName, t.primaryKey, t.fromState, t.toState, t.durationMs, t.expected ? 1 : 0);\n }\n\n getTransitions(filter?: { entity?: string }): Array<{ entity: string; tableName: string; primaryKey: string; fromState: string; toState: string; durationMs: number; expected: boolean; timestamp: string }> {\n this.ensureInitialized();\n let sql = 'SELECT entity, table_name, primary_key, from_state, to_state, duration_ms, expected, timestamp FROM state_transitions';\n const params: unknown[] = [];\n\n if (filter?.entity) {\n sql += ' WHERE entity = ?';\n params.push(filter.entity);\n }\n sql += ' ORDER BY timestamp DESC';\n\n const rows = this.db!.prepare(sql).all(...params) as any[];\n return rows.map((r) => ({\n entity: r.entity,\n tableName: r.table_name,\n primaryKey: r.primary_key,\n fromState: r.from_state,\n toState: r.to_state,\n durationMs: r.duration_ms,\n expected: r.expected === 1,\n timestamp: r.timestamp,\n }));\n }\n\n getTransitionStats(entity?: string): Array<{ entity: string; fromState: string; toState: string; count: number; avgDurationMs: number; minDurationMs: number; maxDurationMs: number }> {\n this.ensureInitialized();\n let sql = 'SELECT entity, from_state, to_state, COUNT(*) as count, AVG(duration_ms) as avg_duration, MIN(duration_ms) as min_duration, MAX(duration_ms) as max_duration FROM state_transitions';\n const params: unknown[] = [];\n\n if (entity) {\n sql += ' WHERE entity = ?';\n params.push(entity);\n }\n sql += ' GROUP BY entity, from_state, to_state';\n\n const rows = this.db!.prepare(sql).all(...params) as any[];\n return rows.map((r) => ({\n entity: r.entity,\n fromState: r.from_state,\n toState: r.to_state,\n count: r.count,\n avgDurationMs: Math.round(r.avg_duration),\n minDurationMs: r.min_duration,\n maxDurationMs: r.max_duration,\n }));\n }\n\n saveInsight(i: { entity: string; insightType: string; severity: string; message: string; context: Record<string, unknown> }): void {\n this.ensureInitialized();\n this.db!.prepare(\n 'INSERT INTO insights (entity, insight_type, severity, message, context_json) VALUES (?, ?, ?, ?, ?)'\n ).run(i.entity, i.insightType, i.severity, i.message, JSON.stringify(i.context));\n }\n\n getInsights(filter?: { entity?: string; last?: number; insightType?: string; severity?: string }): Array<{ id: number; entity: string; insightType: string; severity: string; message: string; context: Record<string, unknown>; timestamp: string }> {\n this.ensureInitialized();\n let sql = 'SELECT id, entity, insight_type, severity, message, context_json, timestamp FROM insights';\n const conditions: string[] = [];\n const params: unknown[] = [];\n\n if (filter?.entity) {\n conditions.push('entity = ?');\n params.push(filter.entity);\n }\n if (filter?.last !== undefined) {\n conditions.push(\"timestamp >= datetime('now', '-' || ? || ' minutes')\");\n params.push(filter.last);\n }\n if (filter?.insightType) {\n conditions.push('insight_type = ?');\n params.push(filter.insightType);\n }\n if (filter?.severity) {\n conditions.push('severity = ?');\n params.push(filter.severity);\n }\n if (conditions.length > 0) {\n sql += ' WHERE ' + conditions.join(' AND ');\n }\n sql += ' ORDER BY timestamp DESC';\n\n const rows = this.db!.prepare(sql).all(...params) as any[];\n return rows.map((r) => ({\n id: r.id as number,\n entity: r.entity,\n insightType: r.insight_type,\n severity: r.severity,\n message: r.message,\n context: JSON.parse(r.context_json || '{}'),\n timestamp: r.timestamp,\n }));\n }\n\n getEventById(id: number): { id: number; eventType: string; entity: string; tableName: string; operation: string; rowId: string | null; rowData: string | null; timestamp: string } | undefined {\n this.ensureInitialized();\n const r = this.db!.prepare('SELECT id, event_type, entity, table_name, operation, row_id, row_data, timestamp FROM events WHERE id = ?').get(id) as any;\n if (!r) return undefined;\n return { id: r.id, eventType: r.event_type, entity: r.entity, tableName: r.table_name, operation: r.operation, rowId: r.row_id, rowData: r.row_data, timestamp: r.timestamp };\n }\n\n getAnomalyById(id: number): { id: number; entity: string; anomalyType: string; severity: string; expected: number; actual: number; message: string; timestamp: string } | undefined {\n this.ensureInitialized();\n const r = this.db!.prepare('SELECT id, entity, anomaly_type, severity, expected, actual, message, timestamp FROM anomalies WHERE id = ?').get(id) as any;\n if (!r) return undefined;\n return { id: r.id, entity: r.entity, anomalyType: r.anomaly_type, severity: r.severity, expected: r.expected, actual: r.actual, message: r.message, timestamp: r.timestamp };\n }\n\n getInsightById(id: number): { id: number; entity: string; insightType: string; severity: string; message: string; context: Record<string, unknown>; timestamp: string } | undefined {\n this.ensureInitialized();\n const r = this.db!.prepare('SELECT id, entity, insight_type, severity, message, context_json, timestamp FROM insights WHERE id = ?').get(id) as any;\n if (!r) return undefined;\n return { id: r.id, entity: r.entity, insightType: r.insight_type, severity: r.severity, message: r.message, context: JSON.parse(r.context_json || '{}'), timestamp: r.timestamp };\n }\n\n saveEntityState(s: { tableName: string; primaryKey: string; state: string; enteredAt: string }): void {\n this.ensureInitialized();\n this.db!.prepare(\n 'INSERT OR REPLACE INTO entity_states (table_name, primary_key, state, entered_at) VALUES (?, ?, ?, ?)'\n ).run(s.tableName, s.primaryKey, s.state, s.enteredAt);\n }\n\n getEntityState(tableName: string, primaryKey: string): { state: string; enteredAt: string } | undefined {\n this.ensureInitialized();\n const row = this.db!.prepare(\n 'SELECT state, entered_at FROM entity_states WHERE table_name = ? AND primary_key = ?'\n ).get(tableName, primaryKey) as any;\n if (!row) return undefined;\n return {\n state: row.state,\n enteredAt: row.entered_at,\n };\n }\n\n getStuckEntityStates(tableName: string, thresholdMs: number): Array<{ primaryKey: string; state: string; enteredAt: string }> {\n this.ensureInitialized();\n const thresholdSeconds = Math.floor(thresholdMs / 1000);\n const rows = this.db!.prepare(\n \"SELECT primary_key, state, entered_at FROM entity_states WHERE table_name = ? AND entered_at <= datetime('now', '-' || ? || ' seconds')\"\n ).all(tableName, thresholdSeconds) as any[];\n return rows.map((r) => ({\n primaryKey: r.primary_key,\n state: r.state,\n enteredAt: r.entered_at,\n }));\n }\n\n saveCorrelationEvent(event: { entity: string; eventType: string; primaryKey: string }): void {\n this.ensureInitialized();\n this.db!.prepare(\n 'INSERT INTO correlation_events (entity, event_type, primary_key) VALUES (?, ?, ?)'\n ).run(event.entity, event.eventType, event.primaryKey);\n }\n\n getCorrelationEvents(entity: string, lastMinutes: number): Array<{ entity: string; eventType: string; primaryKey: string; timestamp: string }> {\n this.ensureInitialized();\n const rows = this.db!.prepare(\n \"SELECT entity, event_type, primary_key, timestamp FROM correlation_events WHERE entity = ? AND timestamp >= datetime('now', '-' || ? || ' minutes') ORDER BY timestamp DESC\"\n ).all(entity, lastMinutes) as Array<{ entity: string; event_type: string; primary_key: string; timestamp: string }>;\n return rows.map((r) => ({\n entity: r.entity,\n eventType: r.event_type,\n primaryKey: r.primary_key,\n timestamp: r.timestamp,\n }));\n }\n\n saveCorrelationRate(rate: { entity: string; bucket: string; eventCount: number }): void {\n this.ensureInitialized();\n this.db!.prepare(\n 'INSERT OR REPLACE INTO correlation_rates (entity, bucket, event_count) VALUES (?, ?, ?)'\n ).run(rate.entity, rate.bucket, rate.eventCount);\n }\n\n getCorrelationRates(entity: string, lastHours: number): Array<{ entity: string; bucket: string; eventCount: number }> {\n this.ensureInitialized();\n const cutoff = new Date(Date.now() - lastHours * 3600_000).toISOString();\n const rows = this.db!.prepare(\n 'SELECT entity, bucket, event_count FROM correlation_rates WHERE entity = ? AND bucket >= ? ORDER BY bucket DESC'\n ).all(entity, cutoff) as Array<{ entity: string; bucket: string; event_count: number }>;\n return rows.map((r) => ({\n entity: r.entity,\n bucket: r.bucket,\n eventCount: r.event_count,\n }));\n }\n\n saveHistogramBucket(bucket: { entity: string; columnName: string; bucketKey: string; count: number; period: string }): void {\n this.ensureInitialized();\n this.db!.prepare(\n 'INSERT OR REPLACE INTO distribution_histograms (entity, column_name, bucket_key, count, period) VALUES (?, ?, ?, ?, ?)'\n ).run(bucket.entity, bucket.columnName, bucket.bucketKey, bucket.count, bucket.period);\n }\n\n getHistogramBuckets(entity: string, columnName: string, period: string): Array<{ bucketKey: string; count: number }> {\n this.ensureInitialized();\n const rows = this.db!.prepare(\n 'SELECT bucket_key, count FROM distribution_histograms WHERE entity = ? AND column_name = ? AND period = ? ORDER BY bucket_key'\n ).all(entity, columnName, period) as Array<{ bucket_key: string; count: number }>;\n return rows.map((r) => ({\n bucketKey: r.bucket_key,\n count: r.count,\n }));\n }\n\n saveTemporalPattern(pattern: { entity: string; bucketType: string; bucketKey: number; count: number; period: string }): void {\n this.ensureInitialized();\n this.db!.prepare(\n 'INSERT OR REPLACE INTO temporal_patterns (entity, bucket_type, bucket_key, count, period) VALUES (?, ?, ?, ?, ?)'\n ).run(pattern.entity, pattern.bucketType, pattern.bucketKey, pattern.count, pattern.period);\n }\n\n getTemporalPatterns(entity: string, bucketType: string, period: string): Array<{ bucketKey: number; count: number }> {\n this.ensureInitialized();\n const rows = this.db!.prepare(\n 'SELECT bucket_key, count FROM temporal_patterns WHERE entity = ? AND bucket_type = ? AND period = ? ORDER BY bucket_key'\n ).all(entity, bucketType, period) as Array<{ bucket_key: number; count: number }>;\n return rows.map((r) => ({\n bucketKey: r.bucket_key,\n count: r.count,\n }));\n }\n\n saveAnalyticsBaseline(baseline: { key: string; mean: number; stddev: number; sampleSize: number }): void {\n this.ensureInitialized();\n this.db!.prepare(\n 'INSERT OR REPLACE INTO analytics_baselines (key, mean, stddev, sample_size) VALUES (?, ?, ?, ?)'\n ).run(baseline.key, baseline.mean, baseline.stddev, baseline.sampleSize);\n }\n\n getAnalyticsBaseline(key: string): { mean: number; stddev: number; sampleSize: number } | undefined {\n this.ensureInitialized();\n const row = this.db!.prepare(\n 'SELECT mean, stddev, sample_size FROM analytics_baselines WHERE key = ?'\n ).get(key) as { mean: number; stddev: number; sample_size: number } | undefined;\n if (!row) return undefined;\n return {\n mean: row.mean,\n stddev: row.stddev,\n sampleSize: row.sample_size,\n };\n }\n\n // ── Knowledge Graph ──────────────────────────────────────────\n\n saveKgNode(node: { nodeType: string; refId: string; label: string; metadata: string }): number {\n this.ensureInitialized();\n const info = this.db!.prepare(\n `INSERT INTO kg_nodes (node_type, ref_id, label, metadata) VALUES (?, ?, ?, ?)\n ON CONFLICT(node_type, ref_id) DO UPDATE SET label = excluded.label, metadata = excluded.metadata, timestamp = datetime('now')`\n ).run(node.nodeType, node.refId, node.label, node.metadata);\n // ON CONFLICT UPDATE returns the existing row id, not a new one\n if (info.changes === 0) {\n const existing = this.getKgNodeByRef(node.nodeType, node.refId);\n return existing!.id;\n }\n return Number(info.lastInsertRowid);\n }\n\n getKgNode(id: number): { id: number; nodeType: string; refId: string; label: string; metadata: string; timestamp: string } | undefined {\n this.ensureInitialized();\n const row = this.db!.prepare(\n 'SELECT id, node_type, ref_id, label, metadata, timestamp FROM kg_nodes WHERE id = ?'\n ).get(id) as { id: number; node_type: string; ref_id: string; label: string; metadata: string; timestamp: string } | undefined;\n if (!row) return undefined;\n return { id: row.id, nodeType: row.node_type, refId: row.ref_id, label: row.label, metadata: row.metadata, timestamp: row.timestamp };\n }\n\n getKgNodeByRef(nodeType: string, refId: string): { id: number; nodeType: string; refId: string; label: string; metadata: string; timestamp: string } | undefined {\n this.ensureInitialized();\n const row = this.db!.prepare(\n 'SELECT id, node_type, ref_id, label, metadata, timestamp FROM kg_nodes WHERE node_type = ? AND ref_id = ?'\n ).get(nodeType, refId) as { id: number; node_type: string; ref_id: string; label: string; metadata: string; timestamp: string } | undefined;\n if (!row) return undefined;\n return { id: row.id, nodeType: row.node_type, refId: row.ref_id, label: row.label, metadata: row.metadata, timestamp: row.timestamp };\n }\n\n getKgNodesByType(nodeType: string): Array<{ id: number; nodeType: string; refId: string; label: string; metadata: string; timestamp: string }> {\n this.ensureInitialized();\n const rows = this.db!.prepare(\n 'SELECT id, node_type, ref_id, label, metadata, timestamp FROM kg_nodes WHERE node_type = ? ORDER BY timestamp DESC'\n ).all(nodeType) as Array<{ id: number; node_type: string; ref_id: string; label: string; metadata: string; timestamp: string }>;\n return rows.map((r) => ({ id: r.id, nodeType: r.node_type, refId: r.ref_id, label: r.label, metadata: r.metadata, timestamp: r.timestamp }));\n }\n\n getAllKgNodes(): Array<{ id: number; nodeType: string; refId: string; label: string; metadata: string; timestamp: string }> {\n this.ensureInitialized();\n const rows = this.db!.prepare(\n 'SELECT id, node_type, ref_id, label, metadata, timestamp FROM kg_nodes ORDER BY timestamp DESC'\n ).all() as Array<{ id: number; node_type: string; ref_id: string; label: string; metadata: string; timestamp: string }>;\n return rows.map((r) => ({ id: r.id, nodeType: r.node_type, refId: r.ref_id, label: r.label, metadata: r.metadata, timestamp: r.timestamp }));\n }\n\n deleteKgNode(id: number): void {\n this.ensureInitialized();\n this.db!.prepare('DELETE FROM kg_edges WHERE source_id = ? OR target_id = ?').run(id, id);\n this.db!.prepare('DELETE FROM kg_nodes WHERE id = ?').run(id);\n }\n\n saveKgEdge(edge: { sourceId: number; targetId: number; edgeType: string; weight: number; metadata: string }): number {\n this.ensureInitialized();\n const info = this.db!.prepare(\n `INSERT INTO kg_edges (source_id, target_id, edge_type, weight, metadata) VALUES (?, ?, ?, ?, ?)\n ON CONFLICT(source_id, target_id, edge_type) DO UPDATE SET weight = excluded.weight, metadata = excluded.metadata, timestamp = datetime('now')`\n ).run(edge.sourceId, edge.targetId, edge.edgeType, edge.weight, edge.metadata);\n return Number(info.lastInsertRowid);\n }\n\n getKgEdgesFrom(nodeId: number, edgeType?: string): Array<{ id: number; sourceId: number; targetId: number; edgeType: string; weight: number; metadata: string; timestamp: string }> {\n this.ensureInitialized();\n let sql = 'SELECT id, source_id, target_id, edge_type, weight, metadata, timestamp FROM kg_edges WHERE source_id = ?';\n const params: unknown[] = [nodeId];\n if (edgeType) { sql += ' AND edge_type = ?'; params.push(edgeType); }\n sql += ' ORDER BY timestamp DESC';\n const rows = this.db!.prepare(sql).all(...params) as Array<{ id: number; source_id: number; target_id: number; edge_type: string; weight: number; metadata: string; timestamp: string }>;\n return rows.map((r) => ({ id: r.id, sourceId: r.source_id, targetId: r.target_id, edgeType: r.edge_type, weight: r.weight, metadata: r.metadata, timestamp: r.timestamp }));\n }\n\n getKgEdgesTo(nodeId: number, edgeType?: string): Array<{ id: number; sourceId: number; targetId: number; edgeType: string; weight: number; metadata: string; timestamp: string }> {\n this.ensureInitialized();\n let sql = 'SELECT id, source_id, target_id, edge_type, weight, metadata, timestamp FROM kg_edges WHERE target_id = ?';\n const params: unknown[] = [nodeId];\n if (edgeType) { sql += ' AND edge_type = ?'; params.push(edgeType); }\n sql += ' ORDER BY timestamp DESC';\n const rows = this.db!.prepare(sql).all(...params) as Array<{ id: number; source_id: number; target_id: number; edge_type: string; weight: number; metadata: string; timestamp: string }>;\n return rows.map((r) => ({ id: r.id, sourceId: r.source_id, targetId: r.target_id, edgeType: r.edge_type, weight: r.weight, metadata: r.metadata, timestamp: r.timestamp }));\n }\n\n getAllKgEdges(): Array<{ id: number; sourceId: number; targetId: number; edgeType: string; weight: number; metadata: string; timestamp: string }> {\n this.ensureInitialized();\n const rows = this.db!.prepare(\n 'SELECT id, source_id, target_id, edge_type, weight, metadata, timestamp FROM kg_edges ORDER BY timestamp DESC'\n ).all() as Array<{ id: number; source_id: number; target_id: number; edge_type: string; weight: number; metadata: string; timestamp: string }>;\n return rows.map((r) => ({ id: r.id, sourceId: r.source_id, targetId: r.target_id, edgeType: r.edge_type, weight: r.weight, metadata: r.metadata, timestamp: r.timestamp }));\n }\n\n getKgSummary(): { totalNodes: number; totalEdges: number; entities: number; events: number; anomalies: number; insights: number } {\n this.ensureInitialized();\n const nodeCount = this.db!.prepare('SELECT COUNT(*) as count FROM kg_nodes').get() as { count: number };\n const edgeCount = this.db!.prepare('SELECT COUNT(*) as count FROM kg_edges').get() as { count: number };\n const entityCount = this.db!.prepare(\"SELECT COUNT(*) as count FROM kg_nodes WHERE node_type = 'entity'\").get() as { count: number };\n const eventCount = this.db!.prepare(\"SELECT COUNT(*) as count FROM kg_nodes WHERE node_type = 'event'\").get() as { count: number };\n const anomalyCount = this.db!.prepare(\"SELECT COUNT(*) as count FROM kg_nodes WHERE node_type = 'anomaly'\").get() as { count: number };\n const insightCount = this.db!.prepare(\"SELECT COUNT(*) as count FROM kg_nodes WHERE node_type = 'insight'\").get() as { count: number };\n return { totalNodes: nodeCount.count, totalEdges: edgeCount.count, entities: entityCount.count, events: eventCount.count, anomalies: anomalyCount.count, insights: insightCount.count };\n }\n\n // ── Recommendations ──────────────────────────────────────────\n\n saveRecommendation(rec: { action: string; reason: string; confidence: number; status: string; governance: string; insightId: string | null; entity: string; context: string }): number {\n this.ensureInitialized();\n const info = this.db!.prepare(\n 'INSERT INTO recommendations (action, reason, confidence, status, governance, insight_id, entity, context) VALUES (?, ?, ?, ?, ?, ?, ?, ?)'\n ).run(rec.action, rec.reason, rec.confidence, rec.status, rec.governance, rec.insightId, rec.entity, rec.context);\n return Number(info.lastInsertRowid);\n }\n\n getRecommendation(id: number): { id: number; action: string; reason: string; confidence: number; status: string; governance: string; insightId: string | null; entity: string; context: string; createdAt: string; resolvedAt: string | null; resolvedBy: string | null } | undefined {\n this.ensureInitialized();\n const row = this.db!.prepare(\n 'SELECT id, action, reason, confidence, status, governance, insight_id, entity, context, created_at, resolved_at, resolved_by FROM recommendations WHERE id = ?'\n ).get(id) as { id: number; action: string; reason: string; confidence: number; status: string; governance: string; insight_id: string | null; entity: string; context: string; created_at: string; resolved_at: string | null; resolved_by: string | null } | undefined;\n if (!row) return undefined;\n return {\n id: row.id,\n action: row.action,\n reason: row.reason,\n confidence: row.confidence,\n status: row.status,\n governance: row.governance,\n insightId: row.insight_id,\n entity: row.entity,\n context: row.context,\n createdAt: row.created_at,\n resolvedAt: row.resolved_at,\n resolvedBy: row.resolved_by,\n };\n }\n\n getRecommendations(filter?: { status?: string; action?: string; last?: number }): Array<{ id: number; action: string; reason: string; confidence: number; status: string; governance: string; insightId: string | null; entity: string; context: string; createdAt: string; resolvedAt: string | null; resolvedBy: string | null }> {\n this.ensureInitialized();\n let sql = 'SELECT id, action, reason, confidence, status, governance, insight_id, entity, context, created_at, resolved_at, resolved_by FROM recommendations';\n const conditions: string[] = [];\n const params: unknown[] = [];\n\n if (filter?.status) {\n conditions.push('status = ?');\n params.push(filter.status);\n }\n if (filter?.action) {\n conditions.push('action = ?');\n params.push(filter.action);\n }\n if (conditions.length > 0) {\n sql += ' WHERE ' + conditions.join(' AND ');\n }\n sql += ' ORDER BY created_at DESC';\n if (filter?.last) {\n sql += ' LIMIT ?';\n params.push(filter.last);\n }\n\n const rows = this.db!.prepare(sql).all(...params) as Array<{ id: number; action: string; reason: string; confidence: number; status: string; governance: string; insight_id: string | null; entity: string; context: string; created_at: string; resolved_at: string | null; resolved_by: string | null }>;\n return rows.map((row) => ({\n id: row.id,\n action: row.action,\n reason: row.reason,\n confidence: row.confidence,\n status: row.status,\n governance: row.governance,\n insightId: row.insight_id,\n entity: row.entity,\n context: row.context,\n createdAt: row.created_at,\n resolvedAt: row.resolved_at,\n resolvedBy: row.resolved_by,\n }));\n }\n\n updateRecommendationStatus(id: number, status: string, resolvedBy: string): void {\n this.ensureInitialized();\n this.db!.prepare(\n \"UPDATE recommendations SET status = ?, resolved_at = datetime('now'), resolved_by = ? WHERE id = ?\"\n ).run(status, resolvedBy, id);\n }\n\n getRecommendationSummary(): { total: number; executed: number; pending: number; approved: number; rejected: number; blocked: number; failed: number } {\n this.ensureInitialized();\n const rows = this.db!.prepare(\n 'SELECT status, COUNT(*) as count FROM recommendations GROUP BY status'\n ).all() as Array<{ status: string; count: number }>;\n\n const counts: Record<string, number> = {};\n let total = 0;\n for (const row of rows) {\n counts[row.status] = row.count;\n total += row.count;\n }\n\n return {\n total,\n executed: counts['executed'] ?? 0,\n pending: counts['pending'] ?? 0,\n approved: counts['approved'] ?? 0,\n rejected: counts['rejected'] ?? 0,\n blocked: counts['blocked'] ?? 0,\n failed: counts['failed'] ?? 0,\n };\n }\n\n close(): void {\n if (this.db) {\n this.db.close();\n this.db = null;\n }\n }\n\n private createSchema(): void {\n const createMetaTable = `\n CREATE TABLE IF NOT EXISTS meta (\n key TEXT PRIMARY KEY,\n value TEXT\n )\n `;\n\n const createDiscoveredTablesTable = `\n CREATE TABLE IF NOT EXISTS discovered_tables (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n table_name TEXT NOT NULL,\n table_schema TEXT DEFAULT 'public',\n row_count INTEGER,\n columns_json TEXT,\n fk_json TEXT,\n indexes_json TEXT,\n sample_rows TEXT,\n discovered_at TEXT DEFAULT (datetime('now')),\n UNIQUE(table_name, table_schema)\n )\n `;\n\n const createEntitiesTable = `\n CREATE TABLE IF NOT EXISTS entities (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n table_name TEXT NOT NULL UNIQUE,\n entity_label TEXT NOT NULL,\n entity_type TEXT NOT NULL,\n description TEXT,\n confidence REAL DEFAULT 0.0,\n columns_classified TEXT,\n classified_at TEXT DEFAULT (datetime('now'))\n )\n `;\n\n const createRelationshipsTable = `\n CREATE TABLE IF NOT EXISTS relationships (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n source_entity TEXT NOT NULL,\n target_entity TEXT NOT NULL,\n relationship TEXT NOT NULL,\n source_column TEXT,\n target_column TEXT,\n inferred INTEGER DEFAULT 0,\n confidence REAL DEFAULT 0.0,\n UNIQUE(source_entity, target_entity, relationship)\n )\n `;\n\n const createLlmCacheTable = `\n CREATE TABLE IF NOT EXISTS llm_cache (\n cache_key TEXT PRIMARY KEY,\n response TEXT NOT NULL,\n model TEXT,\n tokens_used INTEGER,\n cached_at TEXT DEFAULT (datetime('now'))\n )\n `;\n\n\n const createEventsTable = `\n CREATE TABLE IF NOT EXISTS events (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n event_type TEXT NOT NULL,\n entity TEXT NOT NULL,\n table_name TEXT NOT NULL,\n operation TEXT NOT NULL,\n row_id TEXT,\n row_data TEXT,\n timestamp TEXT DEFAULT (datetime('now'))\n )\n `;\n\n const createEventsEntityIndex = `CREATE INDEX IF NOT EXISTS idx_events_entity ON events(entity, timestamp)`;\n const createEventsTypeIndex = `CREATE INDEX IF NOT EXISTS idx_events_type ON events(event_type, timestamp)`;\n\n const createBaselinesTable = `\n CREATE TABLE IF NOT EXISTS baselines (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n entity TEXT NOT NULL,\n metric TEXT NOT NULL,\n mean REAL NOT NULL,\n stddev REAL NOT NULL,\n sample_size INTEGER NOT NULL,\n updated_at TEXT DEFAULT (datetime('now')),\n UNIQUE(entity, metric)\n )\n `;\n\n const createAnomaliesTable = `\n CREATE TABLE IF NOT EXISTS anomalies (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n entity TEXT NOT NULL,\n anomaly_type TEXT NOT NULL,\n severity TEXT NOT NULL,\n expected REAL,\n actual REAL,\n message TEXT,\n timestamp TEXT DEFAULT (datetime('now'))\n )\n `;\n\n const createWatchWatermarksTable = `\n CREATE TABLE IF NOT EXISTS watch_watermarks (\n table_name TEXT NOT NULL,\n table_schema TEXT NOT NULL,\n strategy TEXT NOT NULL,\n timestamp_column TEXT,\n pk_column TEXT,\n last_seen_value TEXT,\n updated_at TEXT DEFAULT (datetime('now')),\n PRIMARY KEY(table_name, table_schema)\n )\n `;\n\n const createStateTransitionsTable = `\n CREATE TABLE IF NOT EXISTS state_transitions (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n entity TEXT NOT NULL,\n table_name TEXT NOT NULL,\n primary_key TEXT NOT NULL,\n from_state TEXT NOT NULL,\n to_state TEXT NOT NULL,\n duration_ms INTEGER,\n expected INTEGER NOT NULL,\n timestamp TEXT DEFAULT (datetime('now'))\n )\n `;\n const createTransitionsEntityIndex = `CREATE INDEX IF NOT EXISTS idx_transitions_entity ON state_transitions(entity, timestamp)`;\n const createTransitionsPkIndex = `CREATE INDEX IF NOT EXISTS idx_transitions_pk ON state_transitions(table_name, primary_key)`;\n\n const createInsightsTable = `\n CREATE TABLE IF NOT EXISTS insights (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n entity TEXT NOT NULL,\n insight_type TEXT NOT NULL,\n severity TEXT NOT NULL,\n message TEXT NOT NULL,\n context_json TEXT,\n timestamp TEXT DEFAULT (datetime('now'))\n )\n `;\n const createInsightsEntityIndex = `CREATE INDEX IF NOT EXISTS idx_insights_entity ON insights(entity, timestamp)`;\n\n const createEntityStatesTable = `\n CREATE TABLE IF NOT EXISTS entity_states (\n table_name TEXT NOT NULL,\n primary_key TEXT NOT NULL,\n state TEXT NOT NULL,\n entered_at TEXT NOT NULL,\n PRIMARY KEY(table_name, primary_key)\n )\n `;\n\n const createCorrelationEventsTable = `\n CREATE TABLE IF NOT EXISTS correlation_events (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n entity TEXT NOT NULL,\n event_type TEXT NOT NULL,\n primary_key TEXT,\n timestamp TEXT DEFAULT (datetime('now'))\n )\n `;\n const createCorrelationEventsIndex = `CREATE INDEX IF NOT EXISTS idx_corr_events ON correlation_events(entity, timestamp)`;\n\n const createCorrelationRatesTable = `\n CREATE TABLE IF NOT EXISTS correlation_rates (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n entity TEXT NOT NULL,\n bucket TEXT NOT NULL,\n event_count INTEGER NOT NULL,\n UNIQUE(entity, bucket)\n )\n `;\n\n const createDistributionHistogramsTable = `\n CREATE TABLE IF NOT EXISTS distribution_histograms (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n entity TEXT NOT NULL,\n column_name TEXT NOT NULL,\n bucket_key TEXT NOT NULL,\n count INTEGER NOT NULL,\n period TEXT NOT NULL,\n UNIQUE(entity, column_name, bucket_key, period)\n )\n `;\n\n const createTemporalPatternsTable = `\n CREATE TABLE IF NOT EXISTS temporal_patterns (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n entity TEXT NOT NULL,\n bucket_type TEXT NOT NULL,\n bucket_key INTEGER NOT NULL,\n count INTEGER NOT NULL,\n period TEXT NOT NULL,\n UNIQUE(entity, bucket_type, bucket_key, period)\n )\n `;\n\n const createAnalyticsBaselinesTable = `\n CREATE TABLE IF NOT EXISTS analytics_baselines (\n key TEXT PRIMARY KEY,\n mean REAL NOT NULL,\n stddev REAL NOT NULL,\n sample_size INTEGER NOT NULL,\n updated_at TEXT DEFAULT (datetime('now'))\n )\n `;\n\n const createKgNodesTable = `\n CREATE TABLE IF NOT EXISTS kg_nodes (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n node_type TEXT NOT NULL,\n ref_id TEXT NOT NULL,\n label TEXT NOT NULL,\n metadata TEXT,\n timestamp TEXT DEFAULT (datetime('now')),\n UNIQUE(node_type, ref_id)\n )\n `;\n const createKgNodesTypeIndex = `CREATE INDEX IF NOT EXISTS idx_kg_nodes_type ON kg_nodes(node_type)`;\n const createKgNodesRefIndex = `CREATE INDEX IF NOT EXISTS idx_kg_nodes_ref ON kg_nodes(ref_id)`;\n\n const createKgEdgesTable = `\n CREATE TABLE IF NOT EXISTS kg_edges (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n source_id INTEGER NOT NULL REFERENCES kg_nodes(id),\n target_id INTEGER NOT NULL REFERENCES kg_nodes(id),\n edge_type TEXT NOT NULL,\n weight REAL DEFAULT 1.0,\n metadata TEXT,\n timestamp TEXT DEFAULT (datetime('now')),\n UNIQUE(source_id, target_id, edge_type)\n )\n `;\n const createKgEdgesSourceIndex = `CREATE INDEX IF NOT EXISTS idx_kg_edges_source ON kg_edges(source_id)`;\n const createKgEdgesTargetIndex = `CREATE INDEX IF NOT EXISTS idx_kg_edges_target ON kg_edges(target_id)`;\n const createKgEdgesTypeIndex = `CREATE INDEX IF NOT EXISTS idx_kg_edges_type ON kg_edges(edge_type)`;\n\n const createRecommendationsTable = `\n CREATE TABLE IF NOT EXISTS recommendations (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n action TEXT NOT NULL,\n reason TEXT NOT NULL,\n confidence REAL NOT NULL,\n status TEXT NOT NULL DEFAULT 'pending',\n governance TEXT NOT NULL,\n insight_id TEXT,\n entity TEXT NOT NULL,\n context TEXT NOT NULL DEFAULT '{}',\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n resolved_at TEXT,\n resolved_by TEXT\n )\n `;\n const createRecommendationsStatusIndex = `CREATE INDEX IF NOT EXISTS idx_recommendations_status ON recommendations(status)`;\n const createRecommendationsEntityIndex = `CREATE INDEX IF NOT EXISTS idx_recommendations_entity ON recommendations(entity)`;\n const createRecommendationsActionIndex = `CREATE INDEX IF NOT EXISTS idx_recommendations_action ON recommendations(action)`;\n\n this.db!.prepare(createMetaTable).run();\n this.db!.prepare(createDiscoveredTablesTable).run();\n this.db!.prepare(createEntitiesTable).run();\n this.db!.prepare(createRelationshipsTable).run();\n this.db!.prepare(createLlmCacheTable).run();\n this.db!.prepare(createEventsTable).run();\n this.db!.prepare(createEventsEntityIndex).run();\n this.db!.prepare(createEventsTypeIndex).run();\n this.db!.prepare(createBaselinesTable).run();\n this.db!.prepare(createAnomaliesTable).run();\n this.db!.prepare(createWatchWatermarksTable).run();\n this.db!.prepare(createStateTransitionsTable).run();\n this.db!.prepare(createTransitionsEntityIndex).run();\n this.db!.prepare(createTransitionsPkIndex).run();\n this.db!.prepare(createInsightsTable).run();\n this.db!.prepare(createInsightsEntityIndex).run();\n this.db!.prepare(createEntityStatesTable).run();\n this.db!.prepare(createCorrelationEventsTable).run();\n this.db!.prepare(createCorrelationEventsIndex).run();\n this.db!.prepare(createCorrelationRatesTable).run();\n this.db!.prepare(createDistributionHistogramsTable).run();\n this.db!.prepare(createTemporalPatternsTable).run();\n this.db!.prepare(createAnalyticsBaselinesTable).run();\n this.db!.prepare(createKgNodesTable).run();\n this.db!.prepare(createKgNodesTypeIndex).run();\n this.db!.prepare(createKgNodesRefIndex).run();\n this.db!.prepare(createKgEdgesTable).run();\n this.db!.prepare(createKgEdgesSourceIndex).run();\n this.db!.prepare(createKgEdgesTargetIndex).run();\n this.db!.prepare(createKgEdgesTypeIndex).run();\n this.db!.prepare(createRecommendationsTable).run();\n this.db!.prepare(createRecommendationsStatusIndex).run();\n this.db!.prepare(createRecommendationsEntityIndex).run();\n this.db!.prepare(createRecommendationsActionIndex).run();\n }\n\n private ensureInitialized(): void {\n if (!this.db) {\n throw new Error('Storage not initialized. Call initialize() first.');\n }\n }\n}\n","import type { LLMProvider, LLMConfig } from './types.js';\nimport { OpenAICompatibleProvider } from './openai-compatible.js';\nimport { AnthropicProvider } from './anthropic.js';\nimport { ConfigError } from '../core/errors.js';\n\nconst KNOWN_BASE_URLS: Record<string, { baseUrl: string; defaultModel: string }> = {\n openai: { baseUrl: 'https://api.openai.com/v1', defaultModel: 'gpt-4o-mini' },\n deepseek: { baseUrl: 'https://api.deepseek.com', defaultModel: 'deepseek-chat' },\n};\n\nexport function createLLMProvider(config: LLMConfig): LLMProvider {\n if (config.provider === 'anthropic') {\n if (!config.apiKey) {\n throw new ConfigError('Anthropic provider requires an apiKey.', 'Add apiKey to llm config in cortexa.config.ts.');\n }\n return new AnthropicProvider(config.apiKey, config.model, config.retry);\n }\n\n const known = KNOWN_BASE_URLS[config.provider];\n const baseUrl = config.baseUrl ?? known?.baseUrl;\n\n if (!baseUrl) {\n throw new ConfigError(\n `Unknown provider \"${config.provider}\".`,\n `Provide a baseUrl for custom providers: { provider: \"${config.provider}\", baseUrl: \"https://api.example.com/v1\" }`,\n );\n }\n\n const model = config.model ?? known?.defaultModel ?? config.provider;\n\n return new OpenAICompatibleProvider({\n apiKey: config.apiKey,\n model,\n baseUrl,\n headers: config.headers,\n retry: config.retry,\n });\n}\n","import type { LLMProvider, LLMResponse, LLMChatOptions } from './types.js';\nimport { LLMError } from '../core/errors.js';\nimport { withRetry, type RetryConfig } from './retry.js';\n\nexport class OpenAICompatibleProvider implements LLMProvider {\n private readonly apiKey: string;\n private readonly model: string;\n private readonly baseUrl: string;\n private readonly headers: Record<string, string>;\n private readonly retry?: RetryConfig;\n\n constructor(options: {\n apiKey?: string;\n model: string;\n baseUrl: string;\n headers?: Record<string, string>;\n retry?: RetryConfig;\n }) {\n this.apiKey = options.apiKey ?? '';\n this.model = options.model;\n this.baseUrl = options.baseUrl.replace(/\\/+$/, '');\n this.headers = options.headers ?? {};\n this.retry = options.retry;\n }\n\n async chat(prompt: string, options?: LLMChatOptions): Promise<LLMResponse> {\n return withRetry(() => this.doChat(prompt, options), this.retry);\n }\n\n private async doChat(prompt: string, options?: LLMChatOptions): Promise<LLMResponse> {\n const body: Record<string, unknown> = {\n model: this.model,\n messages: [{ role: 'user', content: prompt }],\n max_tokens: options?.maxTokens ?? 4096,\n };\n\n if (options?.jsonMode) {\n body.response_format = { type: 'json_object' };\n }\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...this.headers,\n };\n\n if (this.apiKey) {\n headers['Authorization'] = `Bearer ${this.apiKey}`;\n }\n\n const url = `${this.baseUrl}/chat/completions`;\n const response = await fetch(url, {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new LLMError(\n `LLM API error (${response.status}): ${errorText}`,\n {\n statusCode: response.status,\n provider: this.model,\n hint: response.status === 401\n ? 'Check your API key in cortexa.config.ts.'\n : response.status === 429\n ? 'Rate limited. Wait a moment and retry, or use a different model.'\n : response.status >= 500\n ? 'The LLM provider returned a server error. This is usually temporary.'\n : undefined,\n },\n );\n }\n\n const data = await response.json() as {\n choices: Array<{ message: { content: string } }>;\n usage?: { prompt_tokens: number; completion_tokens: number };\n model?: string;\n };\n return {\n content: data.choices[0].message.content,\n tokensUsed: {\n prompt: data.usage?.prompt_tokens ?? 0,\n completion: data.usage?.completion_tokens ?? 0,\n },\n model: data.model ?? this.model,\n };\n }\n}\n","export class CortexaError extends Error {\n readonly code: string;\n readonly hint?: string;\n\n constructor(message: string, code: string, hint?: string) {\n super(message);\n this.name = 'CortexaError';\n this.code = code;\n this.hint = hint;\n }\n}\n\nexport class ConfigError extends CortexaError {\n constructor(message: string, hint?: string) {\n super(message, 'CONFIG_ERROR', hint);\n this.name = 'ConfigError';\n }\n}\n\nexport class ConnectionError extends CortexaError {\n constructor(message: string, hint?: string) {\n super(message, 'CONNECTION_ERROR', hint);\n this.name = 'ConnectionError';\n }\n}\n\nexport class LLMError extends CortexaError {\n readonly statusCode?: number;\n readonly provider?: string;\n\n constructor(message: string, options?: { statusCode?: number; provider?: string; hint?: string }) {\n super(message, 'LLM_ERROR', options?.hint);\n this.name = 'LLMError';\n this.statusCode = options?.statusCode;\n this.provider = options?.provider;\n }\n}\n\nexport class LLMResponseError extends LLMError {\n readonly rawContent?: string;\n\n constructor(message: string, rawContent?: string) {\n super(message, {\n hint: 'The LLM returned an unparseable response. Try reducing batchSize or using a different model.',\n });\n this.name = 'LLMResponseError';\n this.rawContent = rawContent;\n }\n}\n","import { LLMError } from '../core/errors.js';\n\nexport interface RetryConfig {\n maxRetries?: number;\n initialDelayMs?: number;\n maxDelayMs?: number;\n backoffMultiplier?: number;\n retryableStatusCodes?: number[];\n}\n\nconst DEFAULT_RETRYABLE_CODES = new Set([429, 500, 502, 503, 504]);\n\nfunction isRetryableError(error: unknown, retryableCodes: Set<number>): boolean {\n if (error instanceof LLMError && error.statusCode) {\n return retryableCodes.has(error.statusCode);\n }\n // Network errors (fetch failures) are retryable\n if (error instanceof TypeError) {\n return true;\n }\n return false;\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport async function withRetry<T>(\n fn: () => Promise<T>,\n config?: RetryConfig,\n logger?: { warn: (obj: Record<string, unknown>, msg: string) => void },\n): Promise<T> {\n const maxRetries = config?.maxRetries ?? 3;\n const initialDelay = config?.initialDelayMs ?? 1000;\n const maxDelay = config?.maxDelayMs ?? 30000;\n const multiplier = config?.backoffMultiplier ?? 2;\n const retryableCodes = config?.retryableStatusCodes\n ? new Set(config.retryableStatusCodes)\n : DEFAULT_RETRYABLE_CODES;\n\n let lastError: Error | undefined;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n return await fn();\n } catch (error) {\n lastError = error as Error;\n\n if (attempt === maxRetries) break;\n\n if (!isRetryableError(error, retryableCodes)) {\n throw error;\n }\n\n const delay = Math.min(initialDelay * Math.pow(multiplier, attempt), maxDelay);\n const jitteredDelay = delay * (0.75 + Math.random() * 0.5);\n\n logger?.warn(\n { attempt: attempt + 1, maxRetries, delayMs: Math.round(jitteredDelay) },\n `LLM call failed, retrying... (${lastError.message})`,\n );\n\n await sleep(jitteredDelay);\n }\n }\n\n throw lastError!;\n}\n","import type { LLMProvider, LLMResponse, LLMChatOptions } from './types.js';\nimport { LLMError } from '../core/errors.js';\nimport { withRetry, type RetryConfig } from './retry.js';\n\nexport class AnthropicProvider implements LLMProvider {\n private readonly apiKey: string;\n private readonly model: string;\n private readonly retry?: RetryConfig;\n\n constructor(apiKey: string, model = 'claude-haiku-4-5-20251001', retry?: RetryConfig) {\n this.apiKey = apiKey;\n this.model = model;\n this.retry = retry;\n }\n\n async chat(prompt: string, options?: LLMChatOptions): Promise<LLMResponse> {\n return withRetry(() => this.doChat(prompt, options), this.retry);\n }\n\n private async doChat(prompt: string, options?: LLMChatOptions): Promise<LLMResponse> {\n const body: Record<string, unknown> = {\n model: this.model,\n max_tokens: options?.maxTokens ?? 4096,\n messages: [{ role: 'user', content: prompt }],\n };\n\n const response = await fetch('https://api.anthropic.com/v1/messages', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': this.apiKey,\n 'anthropic-version': '2023-06-01',\n },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new LLMError(\n `Anthropic API error (${response.status}): ${errorText}`,\n {\n statusCode: response.status,\n provider: 'anthropic',\n hint: response.status === 401\n ? 'Check your Anthropic API key in cortexa.config.ts.'\n : response.status === 429\n ? 'Rate limited. Wait a moment and retry, or use a different model.'\n : response.status >= 500\n ? 'The Anthropic API returned a server error. This is usually temporary.'\n : undefined,\n },\n );\n }\n\n const data = await response.json() as {\n content: Array<{ text: string }>;\n usage: { input_tokens: number; output_tokens: number };\n model: string;\n };\n return {\n content: data.content[0].text,\n tokensUsed: {\n prompt: data.usage.input_tokens,\n completion: data.usage.output_tokens,\n },\n model: data.model,\n };\n }\n}\n","import type { ConnectionConfig } from '../core/config.js';\nimport type { DatabaseConnector } from '../connectors/types.js';\nimport type { RawSchema, RawTable, RawColumn, RawForeignKey, RawIndex, DiscoveryOptions } from './types.js';\n\nexport class SchemaIntrospector {\n private readonly connector: DatabaseConnector;\n private readonly dbType: ConnectionConfig['type'];\n private readonly options: DiscoveryOptions;\n\n constructor(connector: DatabaseConnector, dbType: ConnectionConfig['type'], options: DiscoveryOptions = {}) {\n this.connector = connector;\n this.dbType = dbType;\n this.options = options;\n }\n\n async introspect(): Promise<RawSchema> {\n const tableRows = await this.getTables();\n const tables: RawTable[] = [];\n const excludeTables = new Set(this.options.excludeTables?.map((t) => t.toLowerCase()) ?? []);\n const excludeColumns = new Set(this.options.excludeColumns?.map((c) => c.toLowerCase()) ?? []);\n const includeSampleData = this.options.includeSampleData !== false;\n const sampleLimit = this.options.sampleRowLimit ?? 5;\n\n for (const row of tableRows) {\n const tableName = row.table_name as string;\n const tableSchema = row.table_schema as string;\n\n if (excludeTables.has(tableName.toLowerCase())) {\n continue;\n }\n\n const [allColumns, foreignKeys, indexes, sampleRows, rowCount] = await Promise.all([\n this.getColumns(tableName, tableSchema),\n this.getForeignKeys(tableName, tableSchema),\n this.getIndexes(tableName, tableSchema),\n includeSampleData ? this.getSampleRows(tableName, tableSchema, sampleLimit) : Promise.resolve([]),\n this.getRowCount(tableName, tableSchema),\n ]);\n\n const columns = excludeColumns.size > 0\n ? allColumns.filter((c) => !excludeColumns.has(c.columnName.toLowerCase()))\n : allColumns;\n\n const filteredSampleRows = excludeColumns.size > 0 && sampleRows.length > 0\n ? sampleRows.map((row) => {\n const filtered: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(row)) {\n if (!excludeColumns.has(key.toLowerCase())) {\n filtered[key] = value;\n }\n }\n return filtered;\n })\n : sampleRows;\n\n tables.push({ tableName, tableSchema, columns, foreignKeys, indexes, sampleRows: filteredSampleRows, rowCount });\n }\n\n return { tables, discoveredAt: new Date().toISOString() };\n }\n\n private isPostgresLike(): boolean {\n return this.dbType === 'postgres' || this.dbType === 'cockroachdb';\n }\n\n private isMysqlLike(): boolean {\n return this.dbType === 'mysql' || this.dbType === 'mariadb';\n }\n\n private async getTables(): Promise<Record<string, unknown>[]> {\n if (this.dbType === 'sqlite') {\n const result = await this.connector.query(\n `SELECT name AS table_name, 'main' AS table_schema FROM sqlite_master WHERE type = 'table' AND name NOT LIKE 'sqlite_%' ORDER BY name`\n );\n return result.rows;\n }\n\n if (this.dbType === 'mongodb') {\n const result = await this.connector.query('COLLECTIONS');\n return result.rows;\n }\n\n const schemaFilter = this.isPostgresLike()\n ? `table_schema NOT IN ('pg_catalog', 'information_schema')`\n : this.dbType === 'mssql'\n ? `table_schema NOT IN ('sys', 'INFORMATION_SCHEMA')`\n : `table_schema = DATABASE()`;\n\n const result = await this.connector.query(\n `SELECT table_name AS table_name, table_schema AS table_schema FROM information_schema.tables WHERE table_type = 'BASE TABLE' AND ${schemaFilter} ORDER BY table_name`\n );\n return result.rows;\n }\n\n private async getColumns(tableName: string, _tableSchema: string): Promise<RawColumn[]> {\n if (this.dbType === 'sqlite') {\n const result = await this.connector.query(`PRAGMA table_info(\"${tableName}\")`);\n return result.rows.map((row) => ({\n columnName: row.name as string,\n dataType: (row.type as string) || 'TEXT',\n isNullable: (row.notnull as number) === 0,\n columnDefault: (row.dflt_value as string) ?? null,\n }));\n }\n\n if (this.dbType === 'mongodb') {\n const result = await this.connector.query(`FIELDS:${tableName}:20`);\n return result.rows.map((row) => ({\n columnName: row.column_name as string,\n dataType: row.data_type as string,\n isNullable: true,\n columnDefault: null,\n }));\n }\n\n const result = await this.connector.query(\n `SELECT column_name AS column_name, data_type AS data_type, is_nullable AS is_nullable, column_default AS column_default FROM information_schema.columns WHERE table_name = $1 AND table_schema = $2 ORDER BY ordinal_position`,\n [tableName, _tableSchema]\n );\n return result.rows.map((row) => ({\n columnName: row.column_name as string,\n dataType: row.data_type as string,\n isNullable: (row.is_nullable as string) === 'YES',\n columnDefault: (row.column_default as string) ?? null,\n }));\n }\n\n private async getForeignKeys(tableName: string, tableSchema: string): Promise<RawForeignKey[]> {\n if (this.dbType === 'mongodb') {\n // MongoDB has no formal foreign keys; infer from *_id / *Id patterns\n const columns = await this.getColumns(tableName, tableSchema);\n const fks: RawForeignKey[] = [];\n for (const col of columns) {\n if (col.columnName === '_id') continue;\n const match = col.columnName.match(/^(.+?)(?:_id|Id)$/);\n if (match) {\n fks.push({\n columnName: col.columnName,\n referencedTable: match[1] + 's', // naive pluralization\n referencedColumn: '_id',\n });\n }\n }\n return fks;\n }\n\n if (this.dbType === 'sqlite') {\n const result = await this.connector.query(`PRAGMA foreign_key_list(\"${tableName}\")`);\n return result.rows.map((row) => ({\n columnName: row.from as string,\n referencedTable: row.table as string,\n referencedColumn: row.to as string,\n }));\n }\n\n if (this.dbType === 'mssql') {\n const sql = `SELECT COL_NAME(fkc.parent_object_id, fkc.parent_column_id) AS column_name,\n OBJECT_NAME(fkc.referenced_object_id) AS referenced_table,\n COL_NAME(fkc.referenced_object_id, fkc.referenced_column_id) AS referenced_column\n FROM sys.foreign_key_columns fkc\n JOIN sys.objects o ON o.object_id = fkc.parent_object_id\n JOIN sys.schemas s ON s.schema_id = o.schema_id\n WHERE o.name = $1 AND s.name = $2`;\n const result = await this.connector.query(sql, [tableName, tableSchema]);\n return result.rows.map((row) => ({\n columnName: row.column_name as string,\n referencedTable: row.referenced_table as string,\n referencedColumn: row.referenced_column as string,\n }));\n }\n\n const sql = this.isPostgresLike()\n ? `SELECT a.attname AS column_name, cl2.relname AS referenced_table, a2.attname AS referenced_column\n FROM pg_constraint con\n JOIN pg_class cl ON con.conrelid = cl.oid\n JOIN pg_namespace ns ON cl.relnamespace = ns.oid\n JOIN pg_class cl2 ON con.confrelid = cl2.oid\n JOIN pg_attribute a ON a.attrelid = con.conrelid AND a.attnum = ANY(con.conkey)\n JOIN pg_attribute a2 ON a2.attrelid = con.confrelid AND a2.attnum = ANY(con.confkey)\n WHERE con.contype = 'f' AND cl.relname = $1 AND ns.nspname = $2`\n : `SELECT column_name AS column_name, referenced_table_name AS referenced_table, referenced_column_name AS referenced_column\n FROM information_schema.key_column_usage\n WHERE table_name = $1 AND table_schema = $2 AND referenced_table_name IS NOT NULL`;\n\n const result = await this.connector.query(sql, [tableName, tableSchema]);\n return result.rows.map((row) => ({\n columnName: row.column_name as string,\n referencedTable: row.referenced_table as string,\n referencedColumn: row.referenced_column as string,\n }));\n }\n\n private async getIndexes(tableName: string, tableSchema: string): Promise<RawIndex[]> {\n if (this.dbType === 'mongodb') {\n const result = await this.connector.query(`INDEXES:${tableName}`);\n return result.rows.map((row) => ({\n indexName: row.index_name as string,\n columns: row.columns as string[],\n isUnique: Boolean(row.is_unique),\n }));\n }\n\n if (this.dbType === 'sqlite') {\n const indexListResult = await this.connector.query(`PRAGMA index_list(\"${tableName}\")`);\n const indexes: RawIndex[] = [];\n for (const idx of indexListResult.rows) {\n const idxName = idx.name as string;\n const infoResult = await this.connector.query(`PRAGMA index_info(\"${idxName}\")`);\n indexes.push({\n indexName: idxName,\n columns: infoResult.rows.map((r) => r.name as string),\n isUnique: (idx.unique as number) === 1,\n });\n }\n return indexes;\n }\n\n if (this.dbType === 'mssql') {\n const sql = `SELECT i.name AS index_name, STRING_AGG(c.name, ',') WITHIN GROUP (ORDER BY ic.key_ordinal) AS columns, i.is_unique\n FROM sys.indexes i\n JOIN sys.index_columns ic ON ic.object_id = i.object_id AND ic.index_id = i.index_id\n JOIN sys.columns c ON c.object_id = ic.object_id AND c.column_id = ic.column_id\n JOIN sys.objects o ON o.object_id = i.object_id\n JOIN sys.schemas s ON s.schema_id = o.schema_id\n WHERE o.name = $1 AND s.name = $2 AND i.type > 0\n GROUP BY i.name, i.is_unique`;\n const result = await this.connector.query(sql, [tableName, tableSchema]);\n return result.rows.map((row) => ({\n indexName: row.index_name as string,\n columns: (row.columns as string).split(','),\n isUnique: Boolean(row.is_unique),\n }));\n }\n\n const sql = this.isPostgresLike()\n ? `SELECT i.relname AS index_name, array_agg(a.attname ORDER BY k.n) AS columns, ix.indisunique AS is_unique\n FROM pg_index ix\n JOIN pg_class t ON t.oid = ix.indrelid\n JOIN pg_class i ON i.oid = ix.indexrelid\n JOIN pg_namespace n ON n.oid = t.relnamespace\n CROSS JOIN LATERAL unnest(ix.indkey) WITH ORDINALITY AS k(attnum, n)\n JOIN pg_attribute a ON a.attrelid = t.oid AND a.attnum = k.attnum\n WHERE t.relname = $1 AND n.nspname = $2\n GROUP BY i.relname, ix.indisunique`\n : `SELECT index_name AS index_name, GROUP_CONCAT(column_name ORDER BY seq_in_index) AS columns, NOT non_unique AS is_unique\n FROM information_schema.statistics\n WHERE table_name = $1 AND table_schema = $2\n GROUP BY index_name, non_unique`;\n\n const result = await this.connector.query(sql, [tableName, tableSchema]);\n return result.rows.map((row) => ({\n indexName: row.index_name as string,\n columns: Array.isArray(row.columns) ? row.columns as string[] : (row.columns as string).split(','),\n isUnique: Boolean(row.is_unique),\n }));\n }\n\n private async getSampleRows(tableName: string, tableSchema: string, limit = 5): Promise<Record<string, unknown>[]> {\n try {\n if (this.dbType === 'mongodb') {\n return (await this.connector.query(`SAMPLE:${tableName}:${limit}`)).rows;\n }\n if (this.dbType === 'mssql') {\n return (await this.connector.query(`SELECT TOP ${limit} * FROM [${tableSchema}].[${tableName}]`)).rows;\n }\n const qualifiedName = this.dbType === 'sqlite'\n ? `\"${tableName}\"`\n : this.isPostgresLike()\n ? `\"${tableSchema}\".\"${tableName}\"`\n : `\\`${tableSchema}\\`.\\`${tableName}\\``;\n const result = await this.connector.query(`SELECT * FROM ${qualifiedName} LIMIT ${limit}`);\n return result.rows;\n } catch {\n return [];\n }\n }\n\n private async getRowCount(tableName: string, tableSchema: string): Promise<number> {\n try {\n if (this.dbType === 'mongodb') {\n const result = await this.connector.query(`COUNT:${tableName}`);\n return Number(result.rows[0]?.count ?? 0);\n }\n if (this.dbType === 'sqlite') {\n const result = await this.connector.query(`SELECT COUNT(*) AS count FROM \"${tableName}\"`);\n return Number(result.rows[0]?.count ?? 0);\n }\n if (this.isPostgresLike()) {\n const result = await this.connector.query(\n `SELECT reltuples::bigint AS count FROM pg_class c JOIN pg_namespace n ON n.oid = c.relnamespace WHERE c.relname = $1 AND n.nspname = $2`,\n [tableName, tableSchema]\n );\n const count = Number(result.rows[0]?.count ?? 0);\n return count >= 0 ? count : 0;\n }\n if (this.dbType === 'mssql') {\n const result = await this.connector.query(\n `SELECT SUM(rows) AS count FROM sys.partitions WHERE object_id = OBJECT_ID($1) AND index_id IN (0, 1)`,\n [`${tableSchema}.${tableName}`]\n );\n return Number(result.rows[0]?.count ?? 0);\n }\n // MySQL / MariaDB\n const result = await this.connector.query(\n `SELECT table_rows AS count FROM information_schema.tables WHERE table_name = $1 AND table_schema = $2`,\n [tableName, tableSchema]\n );\n return Number(result.rows[0]?.count ?? 0);\n } catch {\n return 0;\n }\n }\n}\n","import type { LLMProvider } from '../llm/types.js';\nimport type { RawTable, ClassifiedEntity, EntityType } from './types.js';\nimport { LLMResponseError } from '../core/errors.js';\n\nconst DEFAULT_BATCH_SIZE = 5;\n\nexport class SchemaClassifier {\n private readonly llm: LLMProvider;\n private readonly batchSize: number;\n\n constructor(llm: LLMProvider, batchSize?: number) {\n this.llm = llm;\n this.batchSize = batchSize ?? DEFAULT_BATCH_SIZE;\n }\n\n async classify(tables: RawTable[]): Promise<ClassifiedEntity[]> {\n const batches = this.chunk(tables, this.batchSize);\n const results: ClassifiedEntity[] = [];\n\n for (const batch of batches) {\n const classified = await this.classifyBatch(batch);\n results.push(...classified);\n }\n\n return results;\n }\n\n private async classifyBatch(tables: RawTable[]): Promise<ClassifiedEntity[]> {\n const prompt = this.buildPrompt(tables);\n const chatOptions = { jsonMode: true, maxTokens: 8192 };\n let response = await this.llm.chat(prompt, chatOptions);\n try {\n return this.parseResponse(response.content);\n } catch {\n // One retry on parse failure — LLM may return valid JSON on second attempt\n response = await this.llm.chat(prompt, chatOptions);\n return this.parseResponse(response.content);\n }\n }\n\n private buildPrompt(tables: RawTable[]): string {\n const tablesContext = tables.map((t) => {\n const columnsStr = t.columns\n .map((c) => ` - ${c.columnName} (${c.dataType}, ${c.isNullable ? 'nullable' : 'not null'}${c.columnDefault ? `, default: ${c.columnDefault}` : ''})`)\n .join('\\n');\n\n const fkStr = t.foreignKeys.length > 0\n ? `\\n Foreign Keys:\\n${t.foreignKeys.map((fk) => ` - ${fk.columnName} -> ${fk.referencedTable}.${fk.referencedColumn}`).join('\\n')}`\n : '';\n\n const sampleStr = t.sampleRows.length > 0\n ? `\\n Sample Data (${t.sampleRows.length} rows): ${JSON.stringify(t.sampleRows[0])}`\n : '';\n\n return `Table: ${t.tableName} (schema: ${t.tableSchema}, ~${t.rowCount} rows)\\n Columns:\\n${columnsStr}${fkStr}${sampleStr}`;\n }).join('\\n\\n');\n\n return `You are a database schema analyst. Analyze the following database tables and classify each one.\n\nFor each table, return a JSON object with:\n- tableName: exact table name (must match input)\n- entityLabel: human-readable business name (e.g., \"User Account\", \"Sales Order\")\n- entityType: one of \"master\" (core business entities like Users, Products), \"transaction\" (events/activities like Orders, Payments), \"reference\" (lookup/config tables like Countries, Statuses), or \"junction\" (many-to-many link tables)\n- description: one sentence describing the table's business purpose\n- confidence: 0.0 to 1.0 indicating classification confidence\n- columns: array of { columnName, label, meaning } for each column\n\nReturn valid JSON in this exact format:\n{\n \"tables\": [\n {\n \"tableName\": \"...\",\n \"entityLabel\": \"...\",\n \"entityType\": \"master|transaction|reference|junction\",\n \"description\": \"...\",\n \"confidence\": 0.95,\n \"columns\": [\n { \"columnName\": \"...\", \"label\": \"...\", \"meaning\": \"...\" }\n ]\n }\n ]\n}\n\nDATABASE TABLES:\n\n${tablesContext}`;\n }\n\n private parseResponse(content: string): ClassifiedEntity[] {\n let data: {\n tables?: Array<{\n tableName: string;\n entityLabel: string;\n entityType: EntityType;\n description: string;\n confidence: number;\n columns?: Array<{ columnName: string; label: string; meaning: string }>;\n }>;\n };\n\n try {\n data = JSON.parse(content) as typeof data;\n } catch (err) {\n throw new LLMResponseError(\n `Failed to parse LLM response: ${(err as Error).message}`,\n content.slice(0, 500),\n );\n }\n\n if (!data.tables || !Array.isArray(data.tables)) {\n throw new LLMResponseError('Invalid LLM response: missing \"tables\" array', content.slice(0, 500));\n }\n\n return data.tables.map((t) => ({\n tableName: t.tableName,\n entityLabel: t.entityLabel,\n entityType: t.entityType,\n description: t.description,\n confidence: t.confidence,\n columns: (t.columns ?? []).map((c) => ({\n columnName: c.columnName,\n label: c.label,\n meaning: c.meaning,\n })),\n }));\n }\n\n private chunk<T>(array: T[], size: number): T[][] {\n const chunks: T[][] = [];\n for (let i = 0; i < array.length; i += size) {\n chunks.push(array.slice(i, i + size));\n }\n return chunks;\n }\n}\n","import type { RawTable, ClassifiedEntity, Relationship, EntityGraph } from './types.js';\n\nexport class GraphBuilder {\n build(rawTables: RawTable[], entities: ClassifiedEntity[]): EntityGraph {\n const entityMap = new Map(entities.map((e) => [e.tableName, e]));\n const relationships: Relationship[] = [];\n\n for (const table of rawTables) {\n for (const fk of table.foreignKeys) {\n const sourceEntity = entityMap.get(table.tableName);\n const targetEntity = entityMap.get(fk.referencedTable);\n\n const relationshipLabel = this.generateLabel(\n sourceEntity?.entityLabel ?? table.tableName,\n targetEntity?.entityLabel ?? fk.referencedTable,\n fk.columnName,\n );\n\n relationships.push({\n sourceEntity: table.tableName,\n targetEntity: fk.referencedTable,\n relationship: relationshipLabel,\n sourceColumn: fk.columnName,\n targetColumn: fk.referencedColumn,\n inferred: false,\n confidence: 1.0,\n });\n }\n }\n\n return { entities, relationships };\n }\n\n private generateLabel(\n sourceLabel: string,\n targetLabel: string,\n columnName: string,\n ): string {\n const cleaned = columnName.replace(/_id$/, '').replace(/_/g, ' ').toUpperCase();\n if (cleaned.length > 0) {\n return `HAS_${cleaned}`;\n }\n return `REFERENCES_${targetLabel.replace(/\\s+/g, '_').toUpperCase()}`;\n }\n}\n","import type { DatabaseConnector } from '../connectors/types.js';\nimport type { ConnectionConfig } from '../core/config.js';\nimport type { RawTable, ClassifiedEntity } from '../schema/types.js';\nimport type { BusinessEvent, Anomaly, RawChange, WatchOptions, TableWatchConfig } from './types.js';\nimport type { ChangeStream } from './streams/types.js';\nimport { ChangeDetector } from './change-detector.js';\nimport { EventClassifier, type EntityLookup } from './event-classifier.js';\nimport { PatternEngine, type PatternStorage } from './pattern-engine.js';\nimport { CapabilityDetector } from './capability-detector.js';\nimport { TransitionTracker } from '../reasoning/transition-tracker.js';\nimport type { WorkflowConfig, Insight } from '../reasoning/types.js';\nimport type { AnalyticsConfig } from '../analytics/types.js';\nimport { AnalyticsEngine } from '../analytics/analytics-engine.js';\nimport type { KnowledgeConfig } from '../knowledge/types.js';\nimport { GraphStore } from '../knowledge/graph-store.js';\nimport { GraphPopulator } from '../knowledge/graph-populator.js';\nimport type { ActionsConfig } from '../actions/types.js';\nimport { ActionRegistry } from '../actions/action-registry.js';\nimport { ActionMatcher } from '../actions/action-matcher.js';\nimport { ActionExecutor } from '../actions/action-executor.js';\nimport { createLogger } from '../core/logger.js';\n\nexport interface WatcherStorage extends EntityLookup, PatternStorage {\n saveEvent(event: { eventType: string; entity: string; tableName: string; operation: string; rowId?: string; rowData?: string }): void;\n saveWatermark(wm: { tableName: string; tableSchema: string; strategy: string; timestampColumn?: string; pkColumn?: string; lastSeenValue?: string }): void;\n getWatermark(tableName: string, tableSchema: string): { strategy: string; timestampColumn: string | null; pkColumn: string | null; lastSeenValue: string | null } | undefined;\n getEntities(): ClassifiedEntity[];\n saveTransition(t: { entity: string; tableName: string; primaryKey: string; fromState: string; toState: string; durationMs: number; expected: boolean }): void;\n saveInsight(i: { entity: string; insightType: string; severity: string; message: string; context: Record<string, unknown> }): void;\n getInsights(filter?: { entity?: string; last?: number }): Array<{ entity: string; insightType: string; severity: string; message: string; context: Record<string, unknown>; timestamp: string }>;\n saveEntityState(s: { tableName: string; primaryKey: string; state: string; enteredAt: string }): void;\n getEntityState(tableName: string, primaryKey: string): { state: string; enteredAt: string } | undefined;\n getStuckEntityStates(tableName: string, thresholdMs: number): Array<{ primaryKey: string; state: string; enteredAt: string }>;\n // Analytics storage methods\n saveCorrelationEvent(event: { entity: string; eventType: string; primaryKey: string }): void;\n getCorrelationEvents(entity: string, lastMinutes: number): Array<{ entity: string; eventType: string; primaryKey: string; timestamp: string }>;\n saveCorrelationRate(rate: { entity: string; bucket: string; eventCount: number }): void;\n getCorrelationRates(entity: string, lastHours: number): Array<{ entity: string; bucket: string; eventCount: number }>;\n saveHistogramBucket(bucket: { entity: string; columnName: string; bucketKey: string; count: number; period: string }): void;\n getHistogramBuckets(entity: string, columnName: string, period: string): Array<{ bucketKey: string; count: number }>;\n saveTemporalPattern(pattern: { entity: string; bucketType: string; bucketKey: number; count: number; period: string }): void;\n getTemporalPatterns(entity: string, bucketType: string, period: string): Array<{ bucketKey: number; count: number }>;\n getAnalyticsBaseline(key: string): { mean: number; stddev: number; sampleSize: number } | undefined;\n saveAnalyticsBaseline(baseline: { key: string; mean: number; stddev: number; sampleSize: number }): void;\n // Knowledge Graph storage methods\n saveKgNode(node: { nodeType: string; refId: string; label: string; metadata: string }): number;\n getKgNode(id: number): { id: number; nodeType: string; refId: string; label: string; metadata: string; timestamp: string } | undefined;\n getKgNodeByRef(nodeType: string, refId: string): { id: number; nodeType: string; refId: string; label: string; metadata: string; timestamp: string } | undefined;\n getKgNodesByType(nodeType: string): Array<{ id: number; nodeType: string; refId: string; label: string; metadata: string; timestamp: string }>;\n getAllKgNodes(): Array<{ id: number; nodeType: string; refId: string; label: string; metadata: string; timestamp: string }>;\n deleteKgNode(id: number): void;\n saveKgEdge(edge: { sourceId: number; targetId: number; edgeType: string; weight: number; metadata: string }): number;\n getKgEdgesFrom(nodeId: number, edgeType?: string): Array<{ id: number; sourceId: number; targetId: number; edgeType: string; weight: number; metadata: string; timestamp: string }>;\n getKgEdgesTo(nodeId: number, edgeType?: string): Array<{ id: number; sourceId: number; targetId: number; edgeType: string; weight: number; metadata: string; timestamp: string }>;\n getAllKgEdges(): Array<{ id: number; sourceId: number; targetId: number; edgeType: string; weight: number; metadata: string; timestamp: string }>;\n getKgSummary(): { totalNodes: number; totalEdges: number; entities: number; events: number; anomalies: number; insights: number };\n // Actions storage methods\n saveRecommendation(rec: { action: string; reason: string; confidence: number; status: string; governance: string; insightId: string | null; entity: string; context: string }): number;\n getRecommendation(id: number): { id: number; action: string; reason: string; confidence: number; status: string; governance: string; insightId: string | null; entity: string; context: string; createdAt: string; resolvedAt: string | null; resolvedBy: string | null } | undefined;\n updateRecommendationStatus(id: number, status: string, resolvedBy: string): void;\n}\n\nexport interface WatcherConfig {\n connector: DatabaseConnector;\n dbType: ConnectionConfig['type'];\n storage: WatcherStorage;\n tables: RawTable[];\n connectionConfig?: ConnectionConfig;\n onEvent?: (event: BusinessEvent) => void;\n onAnomaly?: (anomaly: Anomaly) => void;\n onInsight?: (insight: Insight) => void;\n workflows?: Record<string, WorkflowConfig>;\n analytics?: AnalyticsConfig;\n knowledge?: KnowledgeConfig;\n actions?: ActionsConfig;\n actionRegistry?: ActionRegistry;\n onRecommendation?: (rec: Record<string, unknown>) => void;\n onActionExecuted?: (rec: Record<string, unknown>) => void;\n onActionFailed?: (rec: Record<string, unknown>) => void;\n}\n\nexport class Watcher {\n private readonly config: WatcherConfig;\n private readonly detector: ChangeDetector;\n private readonly classifier: EventClassifier;\n private readonly logger = createLogger({ name: 'watcher' });\n private patternEngine: PatternEngine | null = null;\n private transitionTracker: TransitionTracker | null = null;\n private analyticsEngine: AnalyticsEngine | null = null;\n private graphPopulator: GraphPopulator | null = null;\n private actionExecutor: ActionExecutor | null = null;\n private stuckInterval: ReturnType<typeof setInterval> | null = null;\n private analyticsInterval: ReturnType<typeof setInterval> | null = null;\n private interval: ReturnType<typeof setInterval> | null = null;\n private stream: ChangeStream | null = null;\n private _streaming = false;\n private watchConfigs: TableWatchConfig[] = [];\n\n constructor(config: WatcherConfig) {\n this.config = config;\n this.detector = new ChangeDetector(config.connector, config.dbType);\n this.classifier = new EventClassifier(config.storage);\n\n if (config.workflows && Object.keys(config.workflows).length > 0) {\n this.transitionTracker = new TransitionTracker(\n config.workflows,\n config.storage,\n (insight: Insight) => {\n config.onInsight?.(insight);\n this.graphPopulator?.onInsight(insight);\n this.actionExecutor?.onInsight(insight);\n },\n );\n }\n\n const hasAnalytics = config.analytics &&\n (Object.keys(config.analytics.correlations ?? {}).length > 0 ||\n Object.keys(config.analytics.distributions ?? {}).length > 0);\n\n if (hasAnalytics) {\n const analyticsStorage = {\n saveCorrelationEvent: config.storage.saveCorrelationEvent.bind(config.storage),\n getCorrelationEvents: config.storage.getCorrelationEvents.bind(config.storage),\n saveCorrelationRate: config.storage.saveCorrelationRate.bind(config.storage),\n getCorrelationRates: config.storage.getCorrelationRates.bind(config.storage),\n saveHistogramBucket: config.storage.saveHistogramBucket.bind(config.storage),\n getHistogramBuckets: config.storage.getHistogramBuckets.bind(config.storage),\n saveTemporalPattern: config.storage.saveTemporalPattern.bind(config.storage),\n getTemporalPatterns: config.storage.getTemporalPatterns.bind(config.storage),\n saveInsight: config.storage.saveInsight.bind(config.storage),\n getBaseline: config.storage.getAnalyticsBaseline.bind(config.storage),\n saveBaseline: config.storage.saveAnalyticsBaseline.bind(config.storage),\n };\n this.analyticsEngine = new AnalyticsEngine(\n config.analytics!,\n analyticsStorage,\n (insight: Insight) => {\n config.onInsight?.(insight);\n this.graphPopulator?.onInsight(insight);\n this.actionExecutor?.onInsight(insight);\n },\n );\n }\n\n if (config.knowledge?.enabled) {\n const graphStore = new GraphStore({\n saveKgNode: config.storage.saveKgNode.bind(config.storage),\n getKgNode: config.storage.getKgNode.bind(config.storage),\n getKgNodeByRef: config.storage.getKgNodeByRef.bind(config.storage),\n getKgNodesByType: config.storage.getKgNodesByType.bind(config.storage),\n getAllKgNodes: config.storage.getAllKgNodes.bind(config.storage),\n deleteKgNode: config.storage.deleteKgNode.bind(config.storage),\n saveKgEdge: config.storage.saveKgEdge.bind(config.storage),\n getKgEdgesFrom: config.storage.getKgEdgesFrom.bind(config.storage),\n getKgEdgesTo: config.storage.getKgEdgesTo.bind(config.storage),\n getAllKgEdges: config.storage.getAllKgEdges.bind(config.storage),\n getKgSummary: config.storage.getKgSummary.bind(config.storage),\n });\n this.graphPopulator = new GraphPopulator(graphStore);\n this.graphPopulator.populateFromSchema(config.tables);\n }\n\n if (config.actions?.enabled && config.actions.rules && config.actions.rules.length > 0) {\n const actionRegistry = config.actionRegistry ?? new ActionRegistry(config.actions.governance);\n const actionMatcher = new ActionMatcher(config.actions.rules);\n const actionStorage = {\n saveRecommendation: config.storage.saveRecommendation.bind(config.storage),\n getRecommendation: config.storage.getRecommendation.bind(config.storage),\n updateRecommendationStatus: config.storage.updateRecommendationStatus.bind(config.storage),\n };\n this.actionExecutor = new ActionExecutor(actionRegistry, actionMatcher, actionStorage);\n\n this.actionExecutor.on('recommendation', (rec: Record<string, unknown>) => {\n config.onRecommendation?.(rec);\n });\n this.actionExecutor.on('action:executed', (rec: Record<string, unknown>) => {\n config.onActionExecuted?.(rec);\n });\n this.actionExecutor.on('action:failed', (rec: Record<string, unknown>) => {\n config.onActionFailed?.(rec);\n });\n }\n }\n\n async start(options?: WatchOptions): Promise<void> {\n if (this.interval || this.stream) throw new Error('Watcher already running');\n\n this.patternEngine = new PatternEngine(this.config.storage, {\n anomalyThreshold: options?.anomalyThreshold,\n });\n\n // Single poll mode: run one cycle and return\n if (options?.once) {\n this.watchConfigs = ChangeDetector.buildWatchConfigs(\n this.config.tables,\n options?.excludeTables,\n );\n for (const wc of this.watchConfigs) {\n const saved = this.config.storage.getWatermark(wc.tableName, wc.tableSchema);\n if (saved?.lastSeenValue) {\n wc.lastSeenValue = saved.lastSeenValue;\n }\n }\n await this.pollCycle(options?.excludeColumns);\n return;\n }\n\n // Attempt streaming if not explicitly preferring polling and connectionConfig is available\n if (!options?.preferPolling && this.config.connectionConfig) {\n const started = await this.tryStartStreaming(options);\n if (started) {\n this.startStuckCheckInterval(options);\n return;\n }\n }\n\n // Fall back to polling\n this.watchConfigs = ChangeDetector.buildWatchConfigs(\n this.config.tables,\n options?.excludeTables\n );\n\n // Restore watermarks from storage\n for (const config of this.watchConfigs) {\n const saved = this.config.storage.getWatermark(config.tableName, config.tableSchema);\n if (saved?.lastSeenValue) {\n config.lastSeenValue = saved.lastSeenValue;\n }\n }\n\n const excludeColumns = options?.excludeColumns;\n const intervalMs = options?.interval ?? 5000;\n\n this.interval = setInterval(async () => {\n await this.pollCycle(excludeColumns);\n }, intervalMs);\n\n this.startStuckCheckInterval(options);\n }\n\n stop(): void {\n if (this.interval) {\n clearInterval(this.interval);\n this.interval = null;\n }\n if (this.stuckInterval) {\n clearInterval(this.stuckInterval);\n this.stuckInterval = null;\n }\n if (this.analyticsInterval) {\n clearInterval(this.analyticsInterval);\n this.analyticsInterval = null;\n }\n if (this.stream) {\n this.stream.stop().catch((err) => {\n this.logger.error({ error: (err as Error).message }, 'Error stopping stream');\n });\n this.stream = null;\n }\n this._streaming = false;\n }\n\n async cleanup(): Promise<void> {\n const stream = this.stream;\n this.stop();\n if (stream) {\n await stream.cleanup();\n }\n }\n\n isRunning(): boolean {\n return this.interval !== null || (this.stream !== null && this.stream.isRunning());\n }\n\n isStreaming(): boolean {\n return this._streaming;\n }\n\n private startStuckCheckInterval(options?: WatchOptions): void {\n if (this.transitionTracker) {\n this.stuckInterval = setInterval(() => {\n this.transitionTracker?.checkStuck();\n }, options?.stuckCheckInterval ?? 60000);\n }\n\n if (this.analyticsEngine) {\n this.analyticsInterval = setInterval(() => {\n this.analyticsEngine?.runPeriodicChecks();\n }, options?.stuckCheckInterval ?? 60000);\n }\n }\n\n private async tryStartStreaming(options?: WatchOptions): Promise<boolean> {\n const capDetector = new CapabilityDetector(this.config.connector, this.config.dbType);\n const capability = await capDetector.detect();\n\n if (!capability.canStream) {\n this.logger.info({ reason: capability.reason }, 'Streaming not available, will use polling');\n return false;\n }\n\n try {\n const stream = await this.createStream();\n if (!stream) {\n this.logger.info('Streaming package not installed. Falling back to polling.');\n return false;\n }\n\n await stream.start((change: RawChange) => {\n this.handleChange(change, options?.excludeColumns);\n });\n\n this.stream = stream;\n this._streaming = true;\n this.logger.info('Using streaming mode for change detection');\n return true;\n } catch (error) {\n this.logger.error({ error: (error as Error).message }, 'Failed to start streaming, falling back to polling');\n return false;\n }\n }\n\n private async createStream(): Promise<ChangeStream | null> {\n if (this.config.dbType === 'postgres' || this.config.dbType === 'cockroachdb') {\n try {\n const { PostgresStream } = await import('./streams/postgres-stream.js');\n return new PostgresStream(this.config.connectionConfig!, this.config.connector);\n } catch {\n return null;\n }\n }\n if (this.config.dbType === 'mysql' || this.config.dbType === 'mariadb') {\n try {\n const { MySQLStream } = await import('./streams/mysql-stream.js');\n return new MySQLStream(this.config.connectionConfig!, this.config.connector);\n } catch {\n return null;\n }\n }\n if (this.config.dbType === 'mongodb') {\n try {\n const { MongoDBStream } = await import('./streams/mongodb-stream.js');\n return new MongoDBStream(this.config.connectionConfig!);\n } catch {\n return null;\n }\n }\n return null;\n }\n\n private handleChange(change: RawChange, excludeColumns?: string[]): string {\n const event = this.classifier.classify(change, { excludeColumns });\n\n this.config.storage.saveEvent({\n eventType: `${event.entity} ${event.type}`,\n entity: event.entity,\n tableName: event.table,\n operation: change.operation,\n rowId: String(event.primaryKey),\n rowData: JSON.stringify(event.metadata),\n });\n\n this.config.onEvent?.(event);\n\n if (this.patternEngine) {\n this.patternEngine.updateBaselines([event.entity], change.operation);\n const anomalies = this.patternEngine.checkRateAnomalies([event.entity], change.operation);\n for (const anomaly of anomalies) {\n this.config.onAnomaly?.(anomaly);\n }\n }\n\n if (this.transitionTracker && change.operation === 'UPDATE') {\n this.transitionTracker.handleChange(change);\n }\n\n if (this.analyticsEngine) {\n this.analyticsEngine.handleEvent(\n event.entity,\n event.type,\n String(event.primaryKey),\n event.metadata,\n change.detectedAt,\n );\n }\n\n if (this.graphPopulator) {\n this.graphPopulator.onEvent(\n event.entity,\n event.type,\n String(event.primaryKey),\n event.metadata,\n );\n }\n\n return event.entity;\n }\n\n private async pollCycle(excludeColumns?: string[]): Promise<void> {\n const allEntities = new Set<string>();\n\n for (const config of this.watchConfigs) {\n try {\n const changes = await this.detector.poll(config);\n\n for (const change of changes) {\n const entity = this.handleChange(change, excludeColumns);\n allEntities.add(entity);\n }\n\n // Update watermark\n if (changes.length > 0) {\n const lastChange = changes[changes.length - 1];\n const lastValue = config.strategy === 'timestamp'\n ? String(lastChange.newData?.[config.timestampColumn!] ?? '')\n : String(lastChange.primaryKey);\n\n config.lastSeenValue = lastValue;\n }\n\n // Always persist watermark (even if no changes, to track that we polled)\n this.config.storage.saveWatermark({\n tableName: config.tableName,\n tableSchema: config.tableSchema,\n strategy: config.strategy,\n timestampColumn: config.timestampColumn,\n pkColumn: config.primaryKeyColumn,\n lastSeenValue: config.lastSeenValue,\n });\n } catch (error) {\n this.logger.error({ table: config.tableName, error: (error as Error).message }, 'Poll error');\n }\n }\n }\n}\n","import type { ConnectionConfig } from '../core/config.js';\nimport type { DatabaseConnector } from '../connectors/types.js';\nimport type { RawTable } from '../schema/types.js';\nimport type { RawChange, TableWatchConfig, TableStats } from './types.js';\n\nconst TIMESTAMP_COLUMNS = ['updated_at', 'modified_at', 'last_modified', 'updatedat', 'modifiedat'];\nconst AUTO_INCREMENT_PATTERNS = ['nextval', 'auto_increment', 'serial', 'identity'];\n\nexport class ChangeDetector {\n private readonly connector: DatabaseConnector;\n private readonly dbType: ConnectionConfig['type'];\n\n constructor(connector: DatabaseConnector, dbType: ConnectionConfig['type']) {\n this.connector = connector;\n this.dbType = dbType;\n }\n\n static buildWatchConfigs(tables: RawTable[], excludeTables?: string[]): TableWatchConfig[] {\n const excludeSet = new Set(excludeTables?.map((t) => t.toLowerCase()) ?? []);\n const configs: TableWatchConfig[] = [];\n\n for (const table of tables) {\n if (excludeSet.has(table.tableName.toLowerCase())) continue;\n\n const timestampCol = table.columns.find((c) =>\n TIMESTAMP_COLUMNS.includes(c.columnName.toLowerCase()) &&\n c.dataType.toLowerCase().includes('timestamp')\n );\n\n if (timestampCol) {\n const pkCol = table.columns.find((c) =>\n c.columnName.toLowerCase() === 'id' && !c.isNullable\n );\n configs.push({\n tableName: table.tableName,\n tableSchema: table.tableSchema,\n strategy: 'timestamp',\n timestampColumn: timestampCol.columnName,\n primaryKeyColumn: pkCol?.columnName ?? table.columns[0].columnName,\n });\n continue;\n }\n\n const autoIncrementCol = table.columns.find((c) =>\n c.columnDefault !== null &&\n AUTO_INCREMENT_PATTERNS.some((p) => (c.columnDefault ?? '').toLowerCase().includes(p))\n );\n\n if (autoIncrementCol) {\n configs.push({\n tableName: table.tableName,\n tableSchema: table.tableSchema,\n strategy: 'id_watermark',\n primaryKeyColumn: autoIncrementCol.columnName,\n });\n continue;\n }\n\n configs.push({\n tableName: table.tableName,\n tableSchema: table.tableSchema,\n strategy: 'table_stats',\n });\n }\n\n return configs;\n }\n\n async poll(config: TableWatchConfig): Promise<RawChange[]> {\n if (config.strategy === 'timestamp') {\n return this.pollTimestamp(config);\n }\n if (config.strategy === 'id_watermark') {\n return this.pollIdWatermark(config);\n }\n if (config.strategy === 'table_stats') {\n return this.pollTableStats(config);\n }\n return [];\n }\n\n private async pollTimestamp(config: TableWatchConfig): Promise<RawChange[]> {\n const qualified = this.qualifyTable(config.tableName, config.tableSchema);\n const tsCol = config.timestampColumn!;\n const pkCol = config.primaryKeyColumn ?? 'id';\n\n const lastSeen = config.lastSeenValue ?? '1970-01-01T00:00:00Z';\n const result = await this.connector.query(\n `SELECT * FROM ${qualified} WHERE ${this.quoteIdent(tsCol)} > $1 ORDER BY ${this.quoteIdent(tsCol)} ASC`,\n [lastSeen]\n );\n\n return result.rows.map((row) => ({\n tableName: config.tableName,\n tableSchema: config.tableSchema,\n operation: 'UPDATE' as const,\n primaryKey: row[pkCol] as string | number,\n newData: { ...row },\n detectedAt: new Date(),\n }));\n }\n\n private async pollIdWatermark(config: TableWatchConfig): Promise<RawChange[]> {\n const qualified = this.qualifyTable(config.tableName, config.tableSchema);\n const pkCol = config.primaryKeyColumn!;\n\n const lastSeen = config.lastSeenValue ?? '0';\n const result = await this.connector.query(\n `SELECT * FROM ${qualified} WHERE ${this.quoteIdent(pkCol)} > $1 ORDER BY ${this.quoteIdent(pkCol)} ASC`,\n [lastSeen]\n );\n\n return result.rows.map((row) => ({\n tableName: config.tableName,\n tableSchema: config.tableSchema,\n operation: 'INSERT' as const,\n primaryKey: row[pkCol] as string | number,\n newData: { ...row },\n detectedAt: new Date(),\n }));\n }\n\n private async pollTableStats(config: TableWatchConfig): Promise<RawChange[]> {\n const currentStats = await this.queryTableStats(config.tableName, config.tableSchema);\n\n // First poll — initialize baseline, no changes\n if (!config.lastStats) {\n config.lastStats = currentStats;\n return [];\n }\n\n const prev = config.lastStats;\n const changes: RawChange[] = [];\n\n const newInserts = currentStats.inserts - prev.inserts;\n const newUpdates = currentStats.updates - prev.updates;\n const newDeletes = currentStats.deletes - prev.deletes;\n\n config.lastStats = currentStats;\n\n if (newInserts === 0 && newUpdates === 0 && newDeletes === 0) return [];\n\n if (newInserts > 0) {\n changes.push({\n tableName: config.tableName,\n tableSchema: config.tableSchema,\n operation: 'INSERT',\n primaryKey: 'unknown',\n detectedAt: new Date(),\n });\n }\n\n if (newUpdates > 0) {\n changes.push({\n tableName: config.tableName,\n tableSchema: config.tableSchema,\n operation: 'UPDATE',\n primaryKey: 'unknown',\n detectedAt: new Date(),\n });\n }\n\n if (newDeletes > 0) {\n changes.push({\n tableName: config.tableName,\n tableSchema: config.tableSchema,\n operation: 'DELETE',\n primaryKey: 'unknown',\n detectedAt: new Date(),\n });\n }\n\n return changes;\n }\n\n private async queryTableStats(tableName: string, tableSchema: string): Promise<TableStats> {\n if (this.dbType === 'postgres' || this.dbType === 'cockroachdb') {\n const result = await this.connector.query(\n `SELECT COALESCE(n_tup_ins, 0) AS inserts, COALESCE(n_tup_upd, 0) AS updates, COALESCE(n_tup_del, 0) AS deletes\n FROM pg_stat_user_tables WHERE relname = $1 AND schemaname = $2`,\n [tableName, tableSchema]\n );\n if (result.rows.length === 0) return { inserts: 0, updates: 0, deletes: 0 };\n const row = result.rows[0];\n return {\n inserts: parseInt(String(row.inserts), 10),\n updates: parseInt(String(row.updates), 10),\n deletes: parseInt(String(row.deletes), 10),\n };\n }\n\n if (this.dbType === 'sqlite') {\n // SQLite has no per-operation counters; track total row count as insert proxy\n const result = await this.connector.query(\n `SELECT COUNT(*) AS row_count FROM \"${tableName}\"`\n );\n const rowCount = parseInt(String(result.rows[0]?.row_count ?? 0), 10);\n return { inserts: rowCount, updates: 0, deletes: 0 };\n }\n\n if (this.dbType === 'mongodb') {\n // MongoDB: track document count as insert proxy\n const result = await this.connector.query(`COUNT:${tableName}`);\n const docCount = parseInt(String(result.rows[0]?.count ?? 0), 10);\n return { inserts: docCount, updates: 0, deletes: 0 };\n }\n\n if (this.dbType === 'mssql') {\n const result = await this.connector.query(\n `SELECT SUM(rows) AS row_count FROM sys.partitions WHERE object_id = OBJECT_ID($1) AND index_id IN (0, 1)`,\n [`${tableSchema}.${tableName}`]\n );\n const rowCount = parseInt(String(result.rows[0]?.row_count ?? 0), 10);\n return { inserts: rowCount, updates: 0, deletes: 0 };\n }\n\n // MySQL / MariaDB: use information_schema table statistics\n const result = await this.connector.query(\n `SELECT TABLE_ROWS, UPDATE_TIME FROM information_schema.TABLES WHERE TABLE_NAME = $1 AND TABLE_SCHEMA = $2`,\n [tableName, tableSchema]\n );\n if (result.rows.length === 0) return { inserts: 0, updates: 0, deletes: 0 };\n const row = result.rows[0];\n const rowCount = parseInt(String(row.TABLE_ROWS ?? 0), 10);\n const updateTime = row.UPDATE_TIME ? new Date(String(row.UPDATE_TIME)).getTime() : 0;\n return { inserts: rowCount, updates: updateTime, deletes: 0 };\n }\n\n private qualifyTable(tableName: string, tableSchema: string): string {\n if (this.dbType === 'postgres' || this.dbType === 'cockroachdb') {\n return `\"${tableSchema}\".\"${tableName}\"`;\n }\n if (this.dbType === 'sqlite') {\n return `\"${tableName}\"`;\n }\n if (this.dbType === 'mssql') {\n return `[${tableSchema}].[${tableName}]`;\n }\n if (this.dbType === 'mongodb') {\n return tableName;\n }\n return `\\`${tableSchema}\\`.\\`${tableName}\\``;\n }\n\n private quoteIdent(name: string): string {\n if (this.dbType === 'postgres' || this.dbType === 'cockroachdb' || this.dbType === 'sqlite') {\n return `\"${name}\"`;\n }\n if (this.dbType === 'mssql') {\n return `[${name}]`;\n }\n return `\\`${name}\\``;\n }\n}\n","import type { RawChange, BusinessEvent } from './types.js';\nimport type { ClassifiedEntity, EntityType } from '../schema/types.js';\n\nexport interface EntityLookup {\n getEntity(tableName: string): ClassifiedEntity | undefined;\n}\n\nconst OPERATION_MAP: Record<RawChange['operation'], BusinessEvent['type']> = {\n INSERT: 'created',\n UPDATE: 'updated',\n DELETE: 'deleted',\n};\n\nexport class EventClassifier {\n private readonly entityLookup: EntityLookup;\n\n constructor(entityLookup: EntityLookup) {\n this.entityLookup = entityLookup;\n }\n\n classify(change: RawChange, options?: { excludeColumns?: string[] }): BusinessEvent {\n const entity = this.entityLookup.getEntity(change.tableName);\n const excludeSet = new Set(options?.excludeColumns?.map((c) => c.toLowerCase()) ?? []);\n\n const metadata = this.filterMetadata(change.newData ?? change.oldData ?? {}, excludeSet);\n\n return {\n entity: entity?.entityLabel ?? change.tableName,\n entityType: (entity?.entityType ?? 'reference') as EntityType,\n type: OPERATION_MAP[change.operation],\n table: change.tableName,\n primaryKey: change.primaryKey,\n timestamp: change.detectedAt,\n changedColumns: change.changedColumns,\n metadata,\n };\n }\n\n private filterMetadata(\n data: Record<string, unknown>,\n excludeSet: Set<string>\n ): Record<string, unknown> {\n if (excludeSet.size === 0) return { ...data };\n const filtered: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(data)) {\n if (!excludeSet.has(key.toLowerCase())) {\n filtered[key] = value;\n }\n }\n return filtered;\n }\n}\n","import type { Anomaly, Baseline } from './types.js';\n\nexport interface PatternStorage {\n getBaselines(): Baseline[];\n saveBaseline(baseline: { entity: string; metric: string; mean: number; stddev: number; sampleSize: number }): void;\n saveAnomaly(anomaly: { entity: string; anomalyType: string; severity: string; expected: number; actual: number; message: string }): void;\n countEvents(entity: string, operation: string, lastMinutes: number): number;\n}\n\nconst MIN_SAMPLE_SIZE = 12;\nconst DEFAULT_ANOMALY_THRESHOLD = 2;\n\nexport class PatternEngine {\n private readonly storage: PatternStorage;\n private readonly anomalyThreshold: number;\n\n constructor(storage: PatternStorage, options?: { anomalyThreshold?: number }) {\n this.storage = storage;\n this.anomalyThreshold = options?.anomalyThreshold ?? DEFAULT_ANOMALY_THRESHOLD;\n }\n\n updateBaselines(entities: string[], operation: string): void {\n const baselines = this.storage.getBaselines();\n const baselineMap = new Map(baselines.map((b) => [`${b.entity}:${b.metric}`, b]));\n\n for (const entity of entities) {\n const metric = `${operation}_per_hour`;\n const currentCount = this.storage.countEvents(entity, operation, 60);\n const key = `${entity}:${metric}`;\n const existing = baselineMap.get(key);\n\n if (!existing) {\n this.storage.saveBaseline({\n entity,\n metric,\n mean: currentCount,\n stddev: 0,\n sampleSize: 1,\n });\n } else {\n const n = existing.sampleSize;\n const newN = n + 1;\n const newMean = existing.mean + (currentCount - existing.mean) / newN;\n const newStddev = Math.sqrt(\n ((n - 1) * existing.stddev * existing.stddev + (currentCount - existing.mean) * (currentCount - newMean)) / Math.max(n, 1)\n );\n\n this.storage.saveBaseline({\n entity,\n metric,\n mean: newMean,\n stddev: newStddev,\n sampleSize: newN,\n });\n }\n }\n }\n\n checkRateAnomalies(entities: string[], operation: string): Anomaly[] {\n const baselines = this.storage.getBaselines();\n const baselineMap = new Map(baselines.map((b) => [`${b.entity}:${b.metric}`, b]));\n const anomalies: Anomaly[] = [];\n\n for (const entity of entities) {\n const metric = `${operation}_per_hour`;\n const baseline = baselineMap.get(`${entity}:${metric}`);\n if (!baseline || baseline.sampleSize < MIN_SAMPLE_SIZE || baseline.stddev === 0) continue;\n\n const currentCount = this.storage.countEvents(entity, operation, 60);\n const deviation = Math.abs(currentCount - baseline.mean) / baseline.stddev;\n\n if (deviation >= this.anomalyThreshold) {\n const anomalyType = currentCount > baseline.mean ? 'rate_spike' : 'rate_drop';\n const severity = PatternEngine.getSeverity(deviation);\n const anomaly: Anomaly = {\n entity,\n anomalyType,\n severity,\n expected: baseline.mean,\n actual: currentCount,\n message: `${entity} ${operation} rate ${anomalyType === 'rate_spike' ? 'spiked' : 'dropped'} to ${currentCount}/hr (expected ${baseline.mean.toFixed(0)}±${baseline.stddev.toFixed(0)})`,\n timestamp: new Date(),\n };\n\n this.storage.saveAnomaly({\n entity: anomaly.entity,\n anomalyType: anomaly.anomalyType,\n severity: anomaly.severity,\n expected: anomaly.expected,\n actual: anomaly.actual,\n message: anomaly.message,\n });\n\n anomalies.push(anomaly);\n }\n }\n\n return anomalies;\n }\n\n static getSeverity(sigma: number): Anomaly['severity'] {\n if (sigma >= 5) return 'critical';\n if (sigma >= 4) return 'high';\n if (sigma >= 3) return 'medium';\n return 'low';\n }\n}\n","import type { ConnectionConfig } from '../core/config.js';\nimport type { DatabaseConnector } from '../connectors/types.js';\nimport type { StreamCapability } from './types.js';\n\nexport class CapabilityDetector {\n private readonly connector: DatabaseConnector;\n private readonly dbType: ConnectionConfig['type'];\n\n constructor(connector: DatabaseConnector, dbType: ConnectionConfig['type']) {\n this.connector = connector;\n this.dbType = dbType;\n }\n\n async detect(): Promise<StreamCapability> {\n switch (this.dbType) {\n case 'postgres':\n return this.detectPostgres();\n case 'cockroachdb':\n return { canStream: false, reason: 'CockroachDB changefeed not yet supported. Polling mode will be used.' };\n case 'mysql':\n case 'mariadb':\n return this.detectMysql();\n case 'sqlite':\n return { canStream: false, reason: 'SQLite does not support CDC streaming. Polling mode will be used.' };\n case 'mongodb':\n return this.detectMongodb();\n case 'mssql':\n return { canStream: false, reason: 'SQL Server CDC not yet supported. Polling mode will be used.' };\n default:\n return { canStream: false, reason: `Unsupported database type: ${this.dbType as string}` };\n }\n }\n\n private async detectMongodb(): Promise<StreamCapability> {\n try {\n const result = await this.connector.query('COMMAND:{\"replSetGetStatus\":1}');\n if (result.rows.length > 0) {\n return { canStream: true, reason: 'MongoDB Change Streams supported (replica set detected)' };\n }\n return { canStream: false, reason: 'MongoDB Change Streams require a replica set. Polling mode will be used.' };\n } catch {\n return { canStream: false, reason: 'MongoDB Change Streams require a replica set. Polling mode will be used.' };\n }\n }\n\n private async detectPostgres(): Promise<StreamCapability> {\n try {\n const walResult = await this.connector.query(\n \"SELECT current_setting('wal_level') AS wal_level\"\n );\n\n const walLevel = String(walResult.rows[0]?.wal_level ?? '').toLowerCase();\n if (walLevel !== 'logical') {\n return {\n canStream: false,\n reason: \"wal_level is not set to 'logical'. Set wal_level = logical in postgresql.conf and restart.\",\n };\n }\n\n const roleResult = await this.connector.query(\n 'SELECT rolreplication FROM pg_roles WHERE rolname = current_user'\n );\n\n const rolreplication = roleResult.rows[0]?.rolreplication;\n if (rolreplication !== true) {\n return {\n canStream: false,\n reason: 'Current user lacks REPLICATION privilege required for WAL streaming',\n };\n }\n\n return { canStream: true, reason: 'WAL streaming supported' };\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n return { canStream: false, reason: `Capability detection failed: ${message}` };\n }\n }\n\n private async detectMysql(): Promise<StreamCapability> {\n try {\n const logBinResult = await this.connector.query(\"SHOW VARIABLES LIKE 'log_bin'\");\n\n const logBinValue = String(logBinResult.rows[0]?.Value ?? '').toUpperCase();\n if (logBinValue !== 'ON') {\n return {\n canStream: false,\n reason: 'log_bin is not ON; binlog streaming requires log_bin = ON',\n };\n }\n\n const binlogFormatResult = await this.connector.query(\"SHOW VARIABLES LIKE 'binlog_format'\");\n\n const binlogFormatValue = String(binlogFormatResult.rows[0]?.Value ?? '').toUpperCase();\n if (binlogFormatValue !== 'ROW') {\n return {\n canStream: false,\n reason: `binlog_format is '${binlogFormatValue}', must be 'ROW' for binlog streaming`,\n };\n }\n\n return { canStream: true, reason: 'Binlog streaming supported' };\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n return { canStream: false, reason: `Capability detection failed: ${message}` };\n }\n }\n}\n","import type { RawChange } from '../behavioral/types.js';\nimport type { WorkflowConfig, Insight, Severity, InsightType } from './types.js';\nimport { parseTransitionDuration } from './types.js';\nimport { createLogger } from '../core/logger.js';\n\nconst logger = createLogger({ name: 'transition-tracker' });\n\nexport interface TransitionStorage {\n saveTransition(t: {\n entity: string;\n tableName: string;\n primaryKey: string;\n fromState: string;\n toState: string;\n durationMs: number;\n expected: boolean;\n }): void;\n saveInsight(i: {\n entity: string;\n insightType: string;\n severity: string;\n message: string;\n context: Record<string, unknown>;\n }): void;\n getInsights(filter?: {\n entity?: string;\n last?: number;\n }): Array<{\n entity: string;\n insightType: string;\n severity: string;\n message: string;\n context: Record<string, unknown>;\n timestamp: string;\n }>;\n saveEntityState(s: {\n tableName: string;\n primaryKey: string;\n state: string;\n enteredAt: string;\n }): void;\n getEntityState(\n tableName: string,\n primaryKey: string,\n ): { state: string; enteredAt: string } | undefined;\n getStuckEntityStates(\n tableName: string,\n thresholdMs: number,\n ): Array<{ primaryKey: string; state: string; enteredAt: string }>;\n getEntity(\n tableName: string,\n ): { entityLabel: string } | undefined;\n}\n\ninterface WorkflowGraph {\n adjacency: Map<string, string[]>;\n}\n\ninterface ValidationResult {\n expected: boolean;\n insightType?: InsightType;\n severity?: Severity;\n expectedPath?: string[];\n}\n\nexport class TransitionTracker {\n private readonly workflows: Record<string, WorkflowConfig>;\n private readonly storage: TransitionStorage;\n private readonly onInsight: (insight: Insight) => void;\n private readonly graphs: Map<string, WorkflowGraph>;\n\n constructor(\n workflows: Record<string, WorkflowConfig>,\n storage: TransitionStorage,\n onInsight: (insight: Insight) => void,\n ) {\n this.workflows = workflows;\n this.storage = storage;\n this.onInsight = onInsight;\n this.graphs = new Map();\n\n for (const [tableName, config] of Object.entries(workflows)) {\n this.graphs.set(tableName, this.parseGraph(config.expectedTransitions));\n }\n }\n\n handleChange(change: RawChange): void {\n // 1. Only process UPDATE operations\n if (change.operation !== 'UPDATE') {\n return;\n }\n\n const tableName = change.tableName;\n\n // 2. Find matching workflow\n const workflow = this.workflows[tableName];\n if (!workflow) {\n return;\n }\n\n // 3. Check if changedColumns includes the stateColumn\n // If changedColumns is undefined (e.g., polling CDC), proceed — we can't tell what changed\n if (\n change.changedColumns &&\n !change.changedColumns.includes(workflow.stateColumn)\n ) {\n return;\n }\n\n // 4. Get new state from newData\n const newState = change.newData?.[workflow.stateColumn];\n if (newState === null || newState === undefined) {\n return;\n }\n const toState = String(newState);\n const primaryKey = String(change.primaryKey);\n\n // 5. Look up current state\n const currentState = this.storage.getEntityState(tableName, primaryKey);\n\n // 6. First observation — save state, return\n if (!currentState) {\n this.storage.saveEntityState({\n tableName,\n primaryKey,\n state: toState,\n enteredAt: change.detectedAt.toISOString(),\n });\n return;\n }\n\n const fromState = currentState.state;\n\n // 7. Same state — skip\n if (fromState === toState) {\n return;\n }\n\n // 8. Compute durationMs\n const enteredAt = new Date(currentState.enteredAt);\n const durationMs = change.detectedAt.getTime() - enteredAt.getTime();\n\n // 9. Resolve entity name\n const entityName =\n this.storage.getEntity(tableName)?.entityLabel ?? tableName;\n\n // 10. Validate transition against graph\n const graph = this.graphs.get(tableName);\n const validation = graph\n ? this.validateTransition(fromState, toState, graph)\n : { expected: false, insightType: 'transition_unexpected' as InsightType, severity: 'medium' as Severity };\n\n // 11. Save transition\n this.storage.saveTransition({\n entity: entityName,\n tableName,\n primaryKey,\n fromState,\n toState,\n durationMs,\n expected: validation.expected,\n });\n\n // Update entity state\n this.storage.saveEntityState({\n tableName,\n primaryKey,\n state: toState,\n enteredAt: change.detectedAt.toISOString(),\n });\n\n // 12. If not expected: build Insight, save it, call onInsight\n if (!validation.expected && validation.insightType && validation.severity) {\n const message = this.buildMessage(\n entityName,\n primaryKey,\n fromState,\n toState,\n validation.insightType,\n validation.expectedPath,\n durationMs,\n );\n\n const insight: Insight = {\n entity: entityName,\n insightType: validation.insightType,\n severity: validation.severity,\n message,\n context: {\n primaryKey,\n fromState,\n toState,\n ...(validation.expectedPath\n ? { expectedPath: validation.expectedPath }\n : {}),\n durationMs,\n },\n timestamp: change.detectedAt,\n };\n\n this.storage.saveInsight({\n entity: insight.entity,\n insightType: insight.insightType,\n severity: insight.severity,\n message: insight.message,\n context: insight.context,\n });\n\n this.onInsight(insight);\n\n logger.warn(\n { entity: entityName, primaryKey, fromState, toState, insightType: validation.insightType },\n message,\n );\n }\n }\n\n checkStuck(): void {\n for (const [tableName, workflow] of Object.entries(this.workflows)) {\n if (!workflow.stuckThreshold) {\n continue;\n }\n\n const thresholdMs = parseTransitionDuration(workflow.stuckThreshold);\n const stuckRecords = this.storage.getStuckEntityStates(\n tableName,\n thresholdMs,\n );\n\n if (stuckRecords.length === 0) {\n continue;\n }\n\n const entityName =\n this.storage.getEntity(tableName)?.entityLabel ?? tableName;\n\n // Get recent insights (last 60 min) for duplicate detection\n const recentInsights = this.storage.getInsights({\n entity: entityName,\n last: 60,\n });\n\n const recentlyAlertedKeys = new Set(\n recentInsights\n .filter((i) => i.insightType === 'transition_stuck')\n .map((i) => String((i.context as Record<string, unknown>).primaryKey)),\n );\n\n for (const record of stuckRecords) {\n if (recentlyAlertedKeys.has(record.primaryKey)) {\n continue;\n }\n\n const enteredAt = new Date(record.enteredAt);\n const now = new Date();\n const actualDurationMs = now.getTime() - enteredAt.getTime();\n const severity = this.computeStuckSeverity(actualDurationMs, thresholdMs);\n\n const message = this.buildMessage(\n entityName,\n record.primaryKey,\n record.state,\n undefined,\n 'transition_stuck',\n undefined,\n actualDurationMs,\n );\n\n const insight: Insight = {\n entity: entityName,\n insightType: 'transition_stuck',\n severity,\n message,\n context: {\n primaryKey: record.primaryKey,\n fromState: record.state,\n durationMs: actualDurationMs,\n },\n timestamp: now,\n };\n\n this.storage.saveInsight({\n entity: insight.entity,\n insightType: insight.insightType,\n severity: insight.severity,\n message: insight.message,\n context: insight.context,\n });\n\n this.onInsight(insight);\n\n logger.warn(\n { entity: entityName, primaryKey: record.primaryKey, state: record.state, severity },\n message,\n );\n }\n }\n }\n\n private parseGraph(transitions: string[]): WorkflowGraph {\n const adjacency = new Map<string, string[]>();\n\n for (const transition of transitions) {\n const parts = transition.split('->').map((s) => s.trim());\n if (parts.length !== 2) {\n logger.warn({ transition }, 'Invalid transition format, skipping');\n continue;\n }\n const [from, to] = parts;\n const neighbors = adjacency.get(from) ?? [];\n neighbors.push(to);\n adjacency.set(from, neighbors);\n }\n\n return { adjacency };\n }\n\n private validateTransition(\n from: string,\n to: string,\n graph: WorkflowGraph,\n ): ValidationResult {\n // Check direct edge\n const directNeighbors = graph.adjacency.get(from) ?? [];\n if (directNeighbors.includes(to)) {\n return { expected: true };\n }\n\n // Check reachable via BFS (skip)\n const path = this.findPath(from, to, graph.adjacency);\n if (path && path.length > 2) {\n return {\n expected: false,\n insightType: 'transition_skip',\n severity: 'high',\n expectedPath: path,\n };\n }\n\n // Not reachable at all\n return {\n expected: false,\n insightType: 'transition_unexpected',\n severity: 'medium',\n };\n }\n\n private findPath(\n from: string,\n to: string,\n adjacency: Map<string, string[]>,\n ): string[] | null {\n const visited = new Set<string>();\n const queue: string[][] = [[from]];\n visited.add(from);\n\n while (queue.length > 0) {\n const currentPath = queue.shift()!;\n const current = currentPath[currentPath.length - 1];\n\n const neighbors = adjacency.get(current) ?? [];\n for (const neighbor of neighbors) {\n if (neighbor === to) {\n return [...currentPath, neighbor];\n }\n if (!visited.has(neighbor)) {\n visited.add(neighbor);\n queue.push([...currentPath, neighbor]);\n }\n }\n }\n\n return null;\n }\n\n private computeStuckSeverity(durationMs: number, thresholdMs: number): Severity {\n const multiplier = durationMs / thresholdMs;\n\n if (multiplier >= 8) {\n return 'critical';\n }\n if (multiplier >= 4) {\n return 'high';\n }\n if (multiplier >= 2) {\n return 'medium';\n }\n return 'low';\n }\n\n private buildMessage(\n entity: string,\n primaryKey: string,\n fromState: string,\n toState: string | undefined,\n insightType: InsightType,\n expectedPath: string[] | undefined,\n durationMs: number,\n ): string {\n const formatted = this.formatDuration(durationMs);\n\n switch (insightType) {\n case 'transition_skip':\n return `${entity} ${primaryKey} skipped states: ${fromState} -> ${toState} (expected path: ${expectedPath?.join(' -> ')}) after ${formatted}`;\n case 'transition_unexpected':\n return `${entity} ${primaryKey} made unexpected transition: ${fromState} -> ${toState} after ${formatted}`;\n case 'transition_stuck':\n return `${entity} ${primaryKey} stuck in \"${fromState}\" for ${formatted}`;\n default:\n return `${entity} ${primaryKey}: ${insightType} (${fromState}${toState ? ' -> ' + toState : ''}) after ${formatted}`;\n }\n }\n\n private formatDuration(ms: number): string {\n const totalMinutes = Math.floor(ms / 60_000);\n const hours = Math.floor(totalMinutes / 60);\n const minutes = totalMinutes % 60;\n\n if (hours > 0 && minutes > 0) {\n return `${hours}h ${minutes}m`;\n }\n if (hours > 0) {\n return `${hours}h`;\n }\n if (minutes > 0) {\n return `${minutes}m`;\n }\n\n const seconds = Math.floor(ms / 1000);\n if (seconds > 0) {\n return `${seconds}s`;\n }\n\n return `${ms}ms`;\n }\n}\n","export interface WorkflowConfig {\n stateColumn: string;\n expectedTransitions: string[];\n stuckThreshold?: string;\n}\n\nexport type InsightType =\n | 'transition_skip'\n | 'transition_unexpected'\n | 'transition_stuck'\n | 'correlation_divergence'\n | 'correlation_timing'\n | 'distribution_shift'\n | 'temporal_shift';\n\nexport type Severity = 'low' | 'medium' | 'high' | 'critical';\n\nexport interface StateTransition {\n entity: string;\n tableName: string;\n primaryKey: string | number;\n fromState: string;\n toState: string;\n durationMs: number;\n timestamp: Date;\n expected: boolean;\n}\n\nexport interface TransitionStats {\n entity: string;\n fromState: string;\n toState: string;\n count: number;\n avgDurationMs: number;\n minDurationMs: number;\n maxDurationMs: number;\n}\n\nexport interface Insight {\n entity: string;\n insightType: InsightType;\n severity: Severity;\n message: string;\n context: Record<string, unknown>;\n timestamp: Date;\n}\n\nexport interface ReasoningConfig {\n workflows: Record<string, WorkflowConfig>;\n}\n\nconst DURATION_REGEX = /^(\\d+)(ms|s|m|h|d)$/;\n\nconst UNIT_TO_MS: Record<string, number> = {\n ms: 1,\n s: 1_000,\n m: 60_000,\n h: 3_600_000,\n d: 86_400_000,\n};\n\nexport function parseTransitionDuration(input: string): number {\n const match = DURATION_REGEX.exec(input);\n if (!match) {\n throw new Error(`Invalid duration string: \"${input}\". Expected format: <number><unit> (ms|s|m|h|d)`);\n }\n const value = Number(match[1]);\n const unit = match[2];\n return value * UNIT_TO_MS[unit];\n}\n","import { createLogger } from '../core/logger.js';\nimport { Correlator } from './correlator.js';\nimport type { CorrelatorStorage } from './correlator.js';\nimport { DistributionTracker } from './distribution-tracker.js';\nimport type { DistributionTrackerStorage } from './distribution-tracker.js';\nimport type { AnalyticsConfig } from './types.js';\nimport type { Insight } from '../reasoning/types.js';\n\nconst logger = createLogger({ name: 'analytics-engine' });\n\nexport interface AnalyticsEngineStorage {\n saveCorrelationEvent(event: { entity: string; eventType: string; primaryKey: string }): void;\n getCorrelationEvents(entity: string, lastMinutes: number): Array<{ entity: string; eventType: string; primaryKey: string; timestamp: string }>;\n saveCorrelationRate(rate: { entity: string; bucket: string; eventCount: number }): void;\n getCorrelationRates(entity: string, lastHours: number): Array<{ entity: string; bucket: string; eventCount: number }>;\n saveHistogramBucket(bucket: { entity: string; columnName: string; bucketKey: string; count: number; period: string }): void;\n getHistogramBuckets(entity: string, columnName: string, period: string): Array<{ bucketKey: string; count: number }>;\n saveTemporalPattern(pattern: { entity: string; bucketType: string; bucketKey: number; count: number; period: string }): void;\n getTemporalPatterns(entity: string, bucketType: string, period: string): Array<{ bucketKey: number; count: number }>;\n saveInsight(i: { entity: string; insightType: string; severity: string; message: string; context: Record<string, unknown> }): void;\n getBaseline(key: string): { mean: number; stddev: number; sampleSize: number } | undefined;\n saveBaseline(baseline: { key: string; mean: number; stddev: number; sampleSize: number }): void;\n}\n\nexport class AnalyticsEngine {\n private readonly correlator: Correlator | null;\n private readonly distributionTracker: DistributionTracker | null;\n\n constructor(\n config: AnalyticsConfig,\n storage: AnalyticsEngineStorage,\n onInsight: (insight: Insight) => void,\n ) {\n const correlationEntries = config.correlations ? Object.keys(config.correlations) : [];\n const distributionEntries = config.distributions ? Object.keys(config.distributions) : [];\n\n if (correlationEntries.length > 0 && config.correlations) {\n this.correlator = new Correlator(config.correlations, storage as CorrelatorStorage, onInsight);\n } else {\n this.correlator = null;\n }\n\n if (distributionEntries.length > 0 && config.distributions) {\n this.distributionTracker = new DistributionTracker(config.distributions, storage as DistributionTrackerStorage, onInsight);\n } else {\n this.distributionTracker = null;\n }\n\n logger.debug(\n { hasCorrelator: this.correlator !== null, hasDistributionTracker: this.distributionTracker !== null },\n 'AnalyticsEngine initialized',\n );\n }\n\n handleEvent(entity: string, eventType: string, primaryKey: string, data: Record<string, unknown>, timestamp: Date): void {\n if (this.correlator) {\n this.correlator.recordEvent(entity, eventType, primaryKey);\n }\n\n if (this.distributionTracker) {\n this.distributionTracker.recordValue(entity, data);\n this.distributionTracker.recordTemporalEvent(entity, timestamp);\n }\n }\n\n runPeriodicChecks(): void {\n if (this.correlator) {\n this.correlator.checkRateCorrelation();\n this.correlator.checkCoOccurrence();\n }\n\n if (this.distributionTracker) {\n this.distributionTracker.checkDistributionShift();\n this.distributionTracker.checkTemporalShift();\n }\n }\n}\n","import { createLogger } from '../core/logger.js';\nimport { parseTimeWindow } from './types.js';\nimport type { CorrelationConfig } from './types.js';\nimport type { Insight, Severity } from '../reasoning/types.js';\n\nconst logger = createLogger({ name: 'correlator' });\n\nconst MIN_SAMPLE_SIZE = 12;\nconst ANOMALY_THRESHOLD = 2;\n\nexport interface CorrelatorStorage {\n saveCorrelationEvent(event: { entity: string; eventType: string; primaryKey: string }): void;\n getCorrelationEvents(entity: string, lastMinutes: number): Array<{ entity: string; eventType: string; primaryKey: string; timestamp: string }>;\n saveCorrelationRate(rate: { entity: string; bucket: string; eventCount: number }): void;\n getCorrelationRates(entity: string, lastHours: number): Array<{ entity: string; bucket: string; eventCount: number }>;\n saveInsight(i: { entity: string; insightType: string; severity: string; message: string; context: Record<string, unknown> }): void;\n getBaseline(key: string): { mean: number; stddev: number; sampleSize: number } | undefined;\n saveBaseline(baseline: { key: string; mean: number; stddev: number; sampleSize: number }): void;\n}\n\ninterface ParsedConfig {\n name: string;\n entities: [string, string];\n timeWindowMs: number;\n}\n\nexport class Correlator {\n private readonly storage: CorrelatorStorage;\n private readonly onInsight: (insight: Insight) => void;\n private readonly trackedEntities: Set<string>;\n private readonly parsedConfigs: ParsedConfig[];\n\n constructor(\n configs: Record<string, CorrelationConfig>,\n storage: CorrelatorStorage,\n onInsight: (insight: Insight) => void,\n ) {\n this.storage = storage;\n this.onInsight = onInsight;\n this.trackedEntities = new Set<string>();\n this.parsedConfigs = [];\n\n for (const [name, config] of Object.entries(configs)) {\n this.trackedEntities.add(config.entities[0]);\n this.trackedEntities.add(config.entities[1]);\n this.parsedConfigs.push({\n name,\n entities: config.entities,\n timeWindowMs: parseTimeWindow(config.timeWindow),\n });\n }\n\n logger.debug({ configCount: this.parsedConfigs.length }, 'Correlator initialized');\n }\n\n recordEvent(entity: string, eventType: string, primaryKey: string): void {\n if (!this.trackedEntities.has(entity)) {\n return;\n }\n\n this.storage.saveCorrelationEvent({ entity, eventType, primaryKey });\n }\n\n checkRateCorrelation(): void {\n for (const config of this.parsedConfigs) {\n const [entityA, entityB] = config.entities;\n const ratesA = this.storage.getCorrelationRates(entityA, 24);\n const ratesB = this.storage.getCorrelationRates(entityB, 24);\n\n const avgA = this.averageEventCount(ratesA);\n const avgB = this.averageEventCount(ratesB);\n\n if (avgA === 0 || avgB === 0) {\n continue;\n }\n\n const ratio = avgA / avgB;\n const baselineKey = `correlation:${config.name}:rate_ratio`;\n const existing = this.storage.getBaseline(baselineKey);\n\n if (!existing || existing.sampleSize < MIN_SAMPLE_SIZE) {\n this.updateBaseline(baselineKey, ratio, existing);\n continue;\n }\n\n if (existing.stddev === 0) {\n this.updateBaseline(baselineKey, ratio, existing);\n continue;\n }\n\n const zScore = Math.abs(ratio - existing.mean) / existing.stddev;\n\n if (zScore >= ANOMALY_THRESHOLD) {\n const severity = Correlator.getSeverity(zScore);\n const insight: Insight = {\n entity: config.name,\n insightType: 'correlation_divergence',\n severity,\n message: `Rate ratio between ${entityA} and ${entityB} diverged to ${ratio.toFixed(2)} (expected ${existing.mean.toFixed(2)}\\u00b1${existing.stddev.toFixed(2)}, z=${zScore.toFixed(1)})`,\n context: {\n entityA,\n entityB,\n ratio,\n baselineMean: existing.mean,\n baselineStddev: existing.stddev,\n zScore,\n },\n timestamp: new Date(),\n };\n\n this.storage.saveInsight({\n entity: insight.entity,\n insightType: insight.insightType,\n severity: insight.severity,\n message: insight.message,\n context: insight.context,\n });\n\n this.onInsight(insight);\n logger.info({ config: config.name, zScore, ratio }, 'Rate correlation divergence detected');\n }\n\n this.updateBaseline(baselineKey, ratio, existing);\n }\n }\n\n checkCoOccurrence(): void {\n for (const config of this.parsedConfigs) {\n const [entityA, entityB] = config.entities;\n const timeWindowMinutes = Math.ceil(config.timeWindowMs / 60_000);\n\n const eventsA = this.storage.getCorrelationEvents(entityA, timeWindowMinutes);\n const eventsB = this.storage.getCorrelationEvents(entityB, timeWindowMinutes);\n\n const countA = eventsA.length;\n const countB = eventsB.length;\n\n if (countA === 0 && countB === 0) {\n continue;\n }\n\n const maxCount = Math.max(countA, countB);\n const minCount = Math.min(countA, countB);\n const coOccurrenceRate = maxCount === 0 ? 0 : minCount / maxCount;\n\n const baselineKey = `correlation:${config.name}:co_occurrence`;\n const existing = this.storage.getBaseline(baselineKey);\n\n if (!existing || existing.sampleSize < MIN_SAMPLE_SIZE) {\n this.updateBaseline(baselineKey, coOccurrenceRate, existing);\n continue;\n }\n\n if (existing.stddev === 0) {\n this.updateBaseline(baselineKey, coOccurrenceRate, existing);\n continue;\n }\n\n // One-sided test: we care about drops in co-occurrence\n const zScore = (existing.mean - coOccurrenceRate) / existing.stddev;\n\n if (zScore >= ANOMALY_THRESHOLD) {\n const severity = Correlator.getSeverity(zScore);\n const insight: Insight = {\n entity: config.name,\n insightType: 'correlation_timing',\n severity,\n message: `Co-occurrence between ${entityA} and ${entityB} dropped to ${(coOccurrenceRate * 100).toFixed(1)}% (expected ${(existing.mean * 100).toFixed(1)}%\\u00b1${(existing.stddev * 100).toFixed(1)}%, z=${zScore.toFixed(1)})`,\n context: {\n entityA,\n entityB,\n coOccurrenceRate,\n baselineMean: existing.mean,\n baselineStddev: existing.stddev,\n zScore,\n countA,\n countB,\n },\n timestamp: new Date(),\n };\n\n this.storage.saveInsight({\n entity: insight.entity,\n insightType: insight.insightType,\n severity: insight.severity,\n message: insight.message,\n context: insight.context,\n });\n\n this.onInsight(insight);\n logger.info({ config: config.name, zScore, coOccurrenceRate }, 'Co-occurrence timing violation detected');\n }\n\n this.updateBaseline(baselineKey, coOccurrenceRate, existing);\n }\n }\n\n static getSeverity(sigma: number): Severity {\n if (sigma >= 5) return 'critical';\n if (sigma >= 4) return 'high';\n if (sigma >= 3) return 'medium';\n return 'low';\n }\n\n private updateBaseline(\n key: string,\n currentValue: number,\n existing: { mean: number; stddev: number; sampleSize: number } | undefined,\n ): void {\n if (!existing) {\n this.storage.saveBaseline({\n key,\n mean: currentValue,\n stddev: 0,\n sampleSize: 1,\n });\n return;\n }\n\n const newN = existing.sampleSize + 1;\n const delta = currentValue - existing.mean;\n const newMean = existing.mean + delta / newN;\n const delta2 = currentValue - newMean;\n\n const newVariance =\n newN <= 2\n ? (existing.stddev * existing.stddev * Math.max(newN - 2, 0) + delta * delta2) / Math.max(newN - 1, 1)\n : (existing.stddev * existing.stddev * (newN - 2) + delta * delta2) / (newN - 1);\n\n const newStddev = Math.sqrt(Math.max(newVariance, 0));\n\n this.storage.saveBaseline({\n key,\n mean: newMean,\n stddev: newStddev,\n sampleSize: newN,\n });\n }\n\n private averageEventCount(rates: Array<{ entity: string; bucket: string; eventCount: number }>): number {\n if (rates.length === 0) return 0;\n const total = rates.reduce((sum, r) => sum + r.eventCount, 0);\n return total / rates.length;\n }\n}\n","export interface CorrelationConfig {\n entities: [string, string];\n timeWindow: string;\n}\n\nexport interface DistributionConfig {\n columns: string[];\n temporalBuckets: 'hourly' | 'daily';\n}\n\nexport interface AnalyticsConfig {\n correlations?: Record<string, CorrelationConfig>;\n distributions?: Record<string, DistributionConfig>;\n}\n\nexport interface CorrelationStatus {\n name: string;\n entities: [string, string];\n rateRatio: number;\n baselineRatio: number;\n coOccurrenceRate: number;\n baselineCoOccurrence: number;\n healthy: boolean;\n}\n\nexport interface DistributionSummary {\n entity: string;\n columnName: string;\n bucketCount: number;\n baselineSamples: number;\n currentShift: number | null;\n shifted: boolean;\n}\n\nconst TIME_WINDOW_REGEX = /^(\\d+)(s|m|h|d)$/;\n\nconst UNIT_TO_MS: Record<string, number> = {\n s: 1_000,\n m: 60_000,\n h: 3_600_000,\n d: 86_400_000,\n};\n\nexport function parseTimeWindow(input: string): number {\n const match = TIME_WINDOW_REGEX.exec(input);\n if (!match) {\n throw new Error(`Invalid time window string: \"${input}\". Expected format: <number><unit> (s|m|h|d)`);\n }\n const value = Number(match[1]);\n const unit = match[2];\n return value * UNIT_TO_MS[unit];\n}\n","import { createLogger } from '../core/logger.js';\nimport type { DistributionConfig } from './types.js';\nimport type { Insight, InsightType, Severity } from '../reasoning/types.js';\n\nconst logger = createLogger({ name: 'distribution-tracker' });\n\nconst MIN_SAMPLE_SIZE = 12;\nconst NUM_BINS = 10;\n\nexport interface DistributionTrackerStorage {\n saveHistogramBucket(bucket: {\n entity: string;\n columnName: string;\n bucketKey: string;\n count: number;\n period: string;\n }): void;\n getHistogramBuckets(\n entity: string,\n columnName: string,\n period: string,\n ): Array<{ bucketKey: string; count: number }>;\n saveTemporalPattern(pattern: {\n entity: string;\n bucketType: string;\n bucketKey: number;\n count: number;\n period: string;\n }): void;\n getTemporalPatterns(\n entity: string,\n bucketType: string,\n period: string,\n ): Array<{ bucketKey: number; count: number }>;\n saveInsight(i: {\n entity: string;\n insightType: string;\n severity: string;\n message: string;\n context: Record<string, unknown>;\n }): void;\n getBaseline(\n key: string,\n ): { mean: number; stddev: number; sampleSize: number } | undefined;\n saveBaseline(baseline: {\n key: string;\n mean: number;\n stddev: number;\n sampleSize: number;\n }): void;\n}\n\ninterface ParsedEntityConfig {\n entity: string;\n columns: string[];\n temporalBuckets: 'hourly' | 'daily';\n}\n\nexport class DistributionTracker {\n private readonly storage: DistributionTrackerStorage;\n private readonly onInsight: (insight: Insight) => void;\n private readonly entityConfigs: Map<string, ParsedEntityConfig>;\n\n constructor(\n configs: Record<string, DistributionConfig>,\n storage: DistributionTrackerStorage,\n onInsight: (insight: Insight) => void,\n ) {\n this.storage = storage;\n this.onInsight = onInsight;\n this.entityConfigs = new Map();\n\n for (const [entity, config] of Object.entries(configs)) {\n this.entityConfigs.set(entity, {\n entity,\n columns: config.columns,\n temporalBuckets: config.temporalBuckets,\n });\n }\n\n logger.debug(\n { entityCount: this.entityConfigs.size },\n 'DistributionTracker initialized',\n );\n }\n\n recordValue(entity: string, data: Record<string, unknown>): void {\n const config = this.entityConfigs.get(entity);\n if (!config) {\n return;\n }\n\n for (const column of config.columns) {\n const value = data[column];\n if (value === undefined || value === null) {\n continue;\n }\n\n const bucketKey = DistributionTracker.toBucketKey(value);\n if (bucketKey === null) {\n continue;\n }\n\n this.storage.saveHistogramBucket({\n entity,\n columnName: column,\n bucketKey,\n count: 1,\n period: 'current',\n });\n }\n }\n\n recordTemporalEvent(entity: string, timestamp: Date): void {\n const config = this.entityConfigs.get(entity);\n if (!config) {\n return;\n }\n\n if (config.temporalBuckets === 'hourly') {\n this.storage.saveTemporalPattern({\n entity,\n bucketType: 'hour_of_day',\n bucketKey: timestamp.getUTCHours(),\n count: 1,\n period: 'current',\n });\n } else {\n this.storage.saveTemporalPattern({\n entity,\n bucketType: 'day_of_week',\n bucketKey: timestamp.getUTCDay(),\n count: 1,\n period: 'current',\n });\n }\n }\n\n checkDistributionShift(): void {\n for (const config of this.entityConfigs.values()) {\n for (const column of config.columns) {\n const baselineKey = `distribution:${config.entity}:${column}:shift`;\n const baseline = this.storage.getBaseline(baselineKey);\n\n if (!baseline || baseline.sampleSize < MIN_SAMPLE_SIZE) {\n continue;\n }\n\n const baselineBuckets = this.storage.getHistogramBuckets(\n config.entity,\n column,\n 'baseline',\n );\n const currentBuckets = this.storage.getHistogramBuckets(\n config.entity,\n column,\n 'current',\n );\n\n if (baselineBuckets.length === 0 || currentBuckets.length === 0) {\n continue;\n }\n\n const { observed, expected } =\n DistributionTracker.alignAndNormalize(currentBuckets, baselineBuckets);\n\n if (observed.length === 0) {\n continue;\n }\n\n const chi2 = DistributionTracker.chiSquared(observed, expected);\n const df = Math.max(observed.length - 1, 1);\n const threshold = DistributionTracker.chiSquaredThreshold(df);\n\n if (chi2 > threshold) {\n const pValue = DistributionTracker.chiSquaredPValue(chi2, df);\n const severity = DistributionTracker.shiftSeverity(chi2, df);\n const insightType: InsightType = 'distribution_shift';\n\n const insight: Insight = {\n entity: config.entity,\n insightType,\n severity,\n message: `Distribution shift detected for ${config.entity}.${column}: chi2=${chi2.toFixed(2)}, df=${df}, p=${pValue.toFixed(4)}`,\n context: {\n column,\n chi2,\n df,\n pValue,\n threshold,\n },\n timestamp: new Date(),\n };\n\n this.storage.saveInsight({\n entity: insight.entity,\n insightType: insight.insightType,\n severity: insight.severity,\n message: insight.message,\n context: insight.context,\n });\n\n this.onInsight(insight);\n\n logger.info(\n { entity: config.entity, column, chi2, df, pValue },\n 'Distribution shift detected',\n );\n }\n }\n }\n }\n\n checkTemporalShift(): void {\n for (const config of this.entityConfigs.values()) {\n const bucketType =\n config.temporalBuckets === 'hourly' ? 'hour_of_day' : 'day_of_week';\n const baselineKey = `temporal:${config.entity}:${bucketType}:shift`;\n const baseline = this.storage.getBaseline(baselineKey);\n\n if (!baseline || baseline.sampleSize < MIN_SAMPLE_SIZE) {\n continue;\n }\n\n const baselinePatterns = this.storage.getTemporalPatterns(\n config.entity,\n bucketType,\n 'baseline',\n );\n const currentPatterns = this.storage.getTemporalPatterns(\n config.entity,\n bucketType,\n 'current',\n );\n\n if (baselinePatterns.length === 0 || currentPatterns.length === 0) {\n continue;\n }\n\n const { observed, expected } =\n DistributionTracker.alignAndNormalizeNumericBuckets(\n currentPatterns,\n baselinePatterns,\n );\n\n if (observed.length === 0) {\n continue;\n }\n\n const chi2 = DistributionTracker.chiSquared(observed, expected);\n const df = Math.max(observed.length - 1, 1);\n const threshold = DistributionTracker.chiSquaredThreshold(df);\n\n if (chi2 > threshold) {\n const pValue = DistributionTracker.chiSquaredPValue(chi2, df);\n const severity = DistributionTracker.shiftSeverity(chi2, df);\n const insightType: InsightType = 'temporal_shift';\n\n const insight: Insight = {\n entity: config.entity,\n insightType,\n severity,\n message: `Temporal pattern shift detected for ${config.entity} (${bucketType}): chi2=${chi2.toFixed(2)}, df=${df}, p=${pValue.toFixed(4)}`,\n context: {\n bucketType,\n chi2,\n df,\n pValue,\n threshold,\n },\n timestamp: new Date(),\n };\n\n this.storage.saveInsight({\n entity: insight.entity,\n insightType: insight.insightType,\n severity: insight.severity,\n message: insight.message,\n context: insight.context,\n });\n\n this.onInsight(insight);\n\n logger.info(\n { entity: config.entity, bucketType, chi2, df, pValue },\n 'Temporal pattern shift detected',\n );\n }\n }\n }\n\n static chiSquared(observed: number[], expected: number[]): number {\n let sum = 0;\n for (let i = 0; i < observed.length; i++) {\n const e = expected[i];\n if (e === 0) {\n continue;\n }\n const diff = observed[i] - e;\n sum += (diff * diff) / e;\n }\n return sum;\n }\n\n static chiSquaredThreshold(df: number): number {\n const table: Record<number, number> = {\n 1: 3.841,\n 2: 5.991,\n 3: 7.815,\n 4: 9.488,\n 5: 11.07,\n };\n\n if (df in table) {\n return table[df];\n }\n\n // Wilson-Hilferty approximation for larger df\n const term = 1 - 2 / (9 * df);\n return df * Math.pow(term, 3);\n }\n\n static chiSquaredPValue(chi2: number, df: number): number {\n if (df <= 0 || chi2 <= 0) return 1.0;\n\n // Compute upper-tail p-value using the regularized incomplete gamma function\n // P(X > chi2) = 1 - gammaIncomplete(df/2, chi2/2) / gamma(df/2)\n // Using series expansion for the regularized lower incomplete gamma function\n const a = df / 2;\n const x = chi2 / 2;\n\n return 1 - DistributionTracker.regularizedGammaP(a, x);\n }\n\n private static regularizedGammaP(a: number, x: number): number {\n if (x < 0) return 0;\n if (x === 0) return 0;\n\n // Use series expansion for x < a + 1, continued fraction otherwise\n if (x < a + 1) {\n return DistributionTracker.gammaPSeries(a, x);\n }\n return 1 - DistributionTracker.gammaPContinuedFraction(a, x);\n }\n\n private static gammaPSeries(a: number, x: number): number {\n const lnGammaA = DistributionTracker.lnGamma(a);\n let sum = 1 / a;\n let term = 1 / a;\n\n for (let n = 1; n < 200; n++) {\n term *= x / (a + n);\n sum += term;\n if (Math.abs(term) < Math.abs(sum) * 1e-10) break;\n }\n\n return sum * Math.exp(-x + a * Math.log(x) - lnGammaA);\n }\n\n private static gammaPContinuedFraction(a: number, x: number): number {\n const lnGammaA = DistributionTracker.lnGamma(a);\n // Lentz's algorithm for continued fraction\n let f = 1e-30;\n let c = 1e-30;\n let d = 1 / (x + 1 - a);\n let h = d;\n\n for (let n = 1; n < 200; n++) {\n const an = -n * (n - a);\n const bn = x + 2 * n + 1 - a;\n d = bn + an * d;\n if (Math.abs(d) < 1e-30) d = 1e-30;\n c = bn + an / c;\n if (Math.abs(c) < 1e-30) c = 1e-30;\n d = 1 / d;\n const delta = c * d;\n h *= delta;\n if (Math.abs(delta - 1) < 1e-10) break;\n }\n\n return Math.exp(-x + a * Math.log(x) - lnGammaA) * h;\n }\n\n private static lnGamma(x: number): number {\n // Lanczos approximation\n const g = 7;\n const coef = [\n 0.99999999999980993, 676.5203681218851, -1259.1392167224028,\n 771.32342877765313, -176.61502916214059, 12.507343278686905,\n -0.13857109526572012, 9.9843695780195716e-6, 1.5056327351493116e-7,\n ];\n\n if (x < 0.5) {\n return Math.log(Math.PI / Math.sin(Math.PI * x)) - DistributionTracker.lnGamma(1 - x);\n }\n\n x -= 1;\n let a = coef[0];\n const t = x + g + 0.5;\n\n for (let i = 1; i < coef.length; i++) {\n a += coef[i] / (x + i);\n }\n\n return 0.5 * Math.log(2 * Math.PI) + (x + 0.5) * Math.log(t) - t + Math.log(a);\n }\n\n private static shiftSeverity(chi2: number, df: number): Severity {\n const p = DistributionTracker.chiSquaredPValue(chi2, df);\n if (p < 0.001) return 'critical';\n if (p < 0.01) return 'high';\n if (p < 0.05) return 'medium';\n return 'low';\n }\n\n private static toBucketKey(value: unknown): string | null {\n if (typeof value === 'number') {\n return `n:${value}`;\n }\n if (typeof value === 'string') {\n return value;\n }\n return null;\n }\n\n private static alignAndNormalize(\n currentBuckets: Array<{ bucketKey: string; count: number }>,\n baselineBuckets: Array<{ bucketKey: string; count: number }>,\n ): { observed: number[]; expected: number[] } {\n // Check if data is numeric (prefixed with 'n:') or categorical\n const allBuckets = [...baselineBuckets, ...currentBuckets];\n const isNumeric = allBuckets.length > 0 && allBuckets.every((b) => b.bucketKey.startsWith('n:'));\n\n if (isNumeric) {\n return DistributionTracker.alignNumericBins(currentBuckets, baselineBuckets);\n }\n\n return DistributionTracker.alignCategoricalBuckets(currentBuckets, baselineBuckets);\n }\n\n private static alignCategoricalBuckets(\n currentBuckets: Array<{ bucketKey: string; count: number }>,\n baselineBuckets: Array<{ bucketKey: string; count: number }>,\n ): { observed: number[]; expected: number[] } {\n const allKeys = new Set<string>();\n for (const b of baselineBuckets) allKeys.add(b.bucketKey);\n for (const b of currentBuckets) allKeys.add(b.bucketKey);\n\n const baselineMap = new Map(baselineBuckets.map((b) => [b.bucketKey, b.count]));\n const currentMap = new Map(currentBuckets.map((b) => [b.bucketKey, b.count]));\n\n const keys = Array.from(allKeys).sort();\n const rawObserved: number[] = [];\n const rawExpected: number[] = [];\n\n for (const key of keys) {\n rawObserved.push(currentMap.get(key) ?? 0);\n rawExpected.push(baselineMap.get(key) ?? 0);\n }\n\n const totalObserved = rawObserved.reduce((s, v) => s + v, 0);\n const totalExpected = rawExpected.reduce((s, v) => s + v, 0);\n\n if (totalExpected === 0 || totalObserved === 0) {\n return { observed: [], expected: [] };\n }\n\n const scale = totalObserved / totalExpected;\n const expected = rawExpected.map((e) => e * scale);\n\n return { observed: rawObserved, expected };\n }\n\n private static alignNumericBins(\n currentBuckets: Array<{ bucketKey: string; count: number }>,\n baselineBuckets: Array<{ bucketKey: string; count: number }>,\n ): { observed: number[]; expected: number[] } {\n // Parse numeric values from all buckets to find global range\n const parseValue = (key: string): number => parseFloat(key.slice(2));\n\n const allValues: number[] = [];\n for (const b of baselineBuckets) allValues.push(parseValue(b.bucketKey));\n for (const b of currentBuckets) allValues.push(parseValue(b.bucketKey));\n\n if (allValues.length === 0) {\n return { observed: [], expected: [] };\n }\n\n const min = Math.min(...allValues);\n const max = Math.max(...allValues);\n const range = max - min;\n\n if (range === 0) {\n // All values identical — single bin\n const totalObs = currentBuckets.reduce((s, b) => s + b.count, 0);\n const totalExp = baselineBuckets.reduce((s, b) => s + b.count, 0);\n if (totalObs === 0 || totalExp === 0) return { observed: [], expected: [] };\n return { observed: [totalObs], expected: [totalExp] };\n }\n\n const binWidth = range / NUM_BINS;\n const observed = new Array<number>(NUM_BINS).fill(0);\n const rawExpected = new Array<number>(NUM_BINS).fill(0);\n\n for (const b of currentBuckets) {\n const val = parseValue(b.bucketKey);\n const bin = Math.min(Math.floor((val - min) / binWidth), NUM_BINS - 1);\n observed[bin] += b.count;\n }\n\n for (const b of baselineBuckets) {\n const val = parseValue(b.bucketKey);\n const bin = Math.min(Math.floor((val - min) / binWidth), NUM_BINS - 1);\n rawExpected[bin] += b.count;\n }\n\n const totalObserved = observed.reduce((s, v) => s + v, 0);\n const totalExpected = rawExpected.reduce((s, v) => s + v, 0);\n\n if (totalObserved === 0 || totalExpected === 0) {\n return { observed: [], expected: [] };\n }\n\n const scale = totalObserved / totalExpected;\n const expected = rawExpected.map((e) => e * scale);\n\n return { observed, expected };\n }\n\n private static alignAndNormalizeNumericBuckets(\n currentBuckets: Array<{ bucketKey: number; count: number }>,\n baselineBuckets: Array<{ bucketKey: number; count: number }>,\n ): { observed: number[]; expected: number[] } {\n const allKeys = new Set<number>();\n for (const b of baselineBuckets) allKeys.add(b.bucketKey);\n for (const b of currentBuckets) allKeys.add(b.bucketKey);\n\n const baselineMap = new Map(baselineBuckets.map((b) => [b.bucketKey, b.count]));\n const currentMap = new Map(currentBuckets.map((b) => [b.bucketKey, b.count]));\n\n const keys = Array.from(allKeys).sort((a, b) => a - b);\n const rawObserved: number[] = [];\n const rawExpected: number[] = [];\n\n for (const key of keys) {\n rawObserved.push(currentMap.get(key) ?? 0);\n rawExpected.push(baselineMap.get(key) ?? 0);\n }\n\n const totalObserved = rawObserved.reduce((s, v) => s + v, 0);\n const totalExpected = rawExpected.reduce((s, v) => s + v, 0);\n\n if (totalExpected === 0 || totalObserved === 0) {\n return { observed: [], expected: [] };\n }\n\n const scale = totalObserved / totalExpected;\n const expected = rawExpected.map((e) => e * scale);\n\n return { observed: rawObserved, expected };\n }\n}\n","import type { KnowledgeNode, KnowledgeEdge, NodeType, EdgeType, GraphSummary } from './types.js';\nimport { createLogger } from '../core/logger.js';\n\nconst logger = createLogger({ name: 'graph-store' });\n\nexport interface GraphStoreStorage {\n saveKgNode(node: { nodeType: string; refId: string; label: string; metadata: string }): number;\n getKgNode(id: number): { id: number; nodeType: string; refId: string; label: string; metadata: string; timestamp: string } | undefined;\n getKgNodeByRef(nodeType: string, refId: string): { id: number; nodeType: string; refId: string; label: string; metadata: string; timestamp: string } | undefined;\n getKgNodesByType(nodeType: string): Array<{ id: number; nodeType: string; refId: string; label: string; metadata: string; timestamp: string }>;\n getAllKgNodes(): Array<{ id: number; nodeType: string; refId: string; label: string; metadata: string; timestamp: string }>;\n deleteKgNode(id: number): void;\n saveKgEdge(edge: { sourceId: number; targetId: number; edgeType: string; weight: number; metadata: string }): number;\n getKgEdgesFrom(nodeId: number, edgeType?: string): Array<{ id: number; sourceId: number; targetId: number; edgeType: string; weight: number; metadata: string; timestamp: string }>;\n getKgEdgesTo(nodeId: number, edgeType?: string): Array<{ id: number; sourceId: number; targetId: number; edgeType: string; weight: number; metadata: string; timestamp: string }>;\n getAllKgEdges(): Array<{ id: number; sourceId: number; targetId: number; edgeType: string; weight: number; metadata: string; timestamp: string }>;\n getKgSummary(): { totalNodes: number; totalEdges: number; entities: number; events: number; anomalies: number; insights: number };\n}\n\nfunction toNode(raw: { id: number; nodeType: string; refId: string; label: string; metadata: string; timestamp: string }): KnowledgeNode {\n return {\n id: raw.id,\n nodeType: raw.nodeType as NodeType,\n refId: raw.refId,\n label: raw.label,\n metadata: JSON.parse(raw.metadata || '{}') as Record<string, unknown>,\n timestamp: raw.timestamp,\n };\n}\n\nfunction toEdge(raw: { id: number; sourceId: number; targetId: number; edgeType: string; weight: number; metadata: string; timestamp: string }): KnowledgeEdge {\n return {\n id: raw.id,\n sourceId: raw.sourceId,\n targetId: raw.targetId,\n edgeType: raw.edgeType as EdgeType,\n weight: raw.weight,\n metadata: JSON.parse(raw.metadata || '{}') as Record<string, unknown>,\n timestamp: raw.timestamp,\n };\n}\n\nexport class GraphStore {\n private readonly storage: GraphStoreStorage;\n\n constructor(storage: GraphStoreStorage) {\n this.storage = storage;\n }\n\n upsertNode(nodeType: NodeType, refId: string, label: string, metadata: Record<string, unknown> = {}): number {\n const id = this.storage.saveKgNode({ nodeType, refId, label, metadata: JSON.stringify(metadata) });\n logger.debug({ id, nodeType, refId }, 'Upserted node');\n return id;\n }\n\n getNode(id: number): KnowledgeNode | undefined {\n const raw = this.storage.getKgNode(id);\n return raw ? toNode(raw) : undefined;\n }\n\n getNodeByRef(nodeType: NodeType, refId: string): KnowledgeNode | undefined {\n const raw = this.storage.getKgNodeByRef(nodeType, refId);\n return raw ? toNode(raw) : undefined;\n }\n\n getNodesByType(nodeType: NodeType): KnowledgeNode[] {\n return this.storage.getKgNodesByType(nodeType).map(toNode);\n }\n\n getAllNodes(): KnowledgeNode[] {\n return this.storage.getAllKgNodes().map(toNode);\n }\n\n deleteNode(id: number): void {\n this.storage.deleteKgNode(id);\n logger.debug({ id }, 'Deleted node');\n }\n\n addEdge(sourceId: number, targetId: number, edgeType: EdgeType, weight: number = 1.0, metadata: Record<string, unknown> = {}): number {\n const id = this.storage.saveKgEdge({ sourceId, targetId, edgeType, weight, metadata: JSON.stringify(metadata) });\n logger.debug({ id, sourceId, targetId, edgeType }, 'Added edge');\n return id;\n }\n\n getEdgesFrom(nodeId: number, edgeType?: EdgeType): KnowledgeEdge[] {\n return this.storage.getKgEdgesFrom(nodeId, edgeType).map(toEdge);\n }\n\n getEdgesTo(nodeId: number, edgeType?: EdgeType): KnowledgeEdge[] {\n return this.storage.getKgEdgesTo(nodeId, edgeType).map(toEdge);\n }\n\n getAllEdges(): KnowledgeEdge[] {\n return this.storage.getAllKgEdges().map(toEdge);\n }\n\n neighbors(nodeId: number): KnowledgeNode[] {\n const outgoing = this.storage.getKgEdgesFrom(nodeId);\n const incoming = this.storage.getKgEdgesTo(nodeId);\n const neighborIds = new Set<number>();\n for (const e of outgoing) neighborIds.add(e.targetId);\n for (const e of incoming) neighborIds.add(e.sourceId);\n const nodes: KnowledgeNode[] = [];\n for (const nid of neighborIds) {\n const raw = this.storage.getKgNode(nid);\n if (raw) nodes.push(toNode(raw));\n }\n return nodes;\n }\n\n getSummary(): GraphSummary {\n return this.storage.getKgSummary();\n }\n}\n","import type { NodeType } from './types.js';\nimport type { GraphStore } from './graph-store.js';\nimport type { RawTable } from '../schema/types.js';\nimport type { Insight, Severity } from '../reasoning/types.js';\nimport { createLogger } from '../core/logger.js';\n\nconst logger = createLogger({ name: 'graph-populator' });\n\nconst HIGH_SEVERITY: Set<Severity> = new Set(['high', 'critical']);\n\nlet eventCounter = 0;\nlet insightCounter = 0;\n\nexport class GraphPopulator {\n private readonly store: GraphStore;\n\n constructor(store: GraphStore) {\n this.store = store;\n }\n\n populateFromSchema(tables: RawTable[]): void {\n for (const table of tables) {\n this.store.upsertNode('entity', table.tableName, table.tableName, {\n tableSchema: table.tableSchema,\n rowCount: table.rowCount,\n });\n }\n\n for (const table of tables) {\n for (const fk of table.foreignKeys) {\n const sourceNode = this.store.getNodeByRef('entity', fk.referencedTable);\n const targetNode = this.store.getNodeByRef('entity', table.tableName);\n\n if (sourceNode && targetNode && sourceNode.id !== targetNode.id) {\n this.store.addEdge(sourceNode.id, targetNode.id, 'contains', 1.0, {\n sourceColumn: fk.referencedColumn,\n targetColumn: fk.columnName,\n });\n }\n }\n }\n\n logger.info({ tables: tables.length }, 'Graph populated from schema');\n }\n\n onEvent(entity: string, eventType: string, primaryKey: string, data: Record<string, unknown>): void {\n const entityNode = this.store.getNodeByRef('entity', entity);\n if (!entityNode) return;\n\n eventCounter++;\n const refId = `event:${Date.now()}-${eventCounter}`;\n const label = `${entity} ${eventType}`;\n\n const eventNodeId = this.store.upsertNode('event', refId, label, {\n eventType,\n primaryKey,\n ...data,\n });\n\n this.store.addEdge(eventNodeId, entityNode.id, 'detected_on');\n }\n\n onInsight(insight: Insight): void {\n const entityNode = this.store.getNodeByRef('entity', insight.entity);\n if (!entityNode) return;\n\n insightCounter++;\n const nodeType: NodeType = HIGH_SEVERITY.has(insight.severity) ? 'anomaly' : 'insight';\n const refId = `${nodeType}:${Date.now()}-${insightCounter}`;\n\n const nodeId = this.store.upsertNode(nodeType, refId, insight.message, {\n insightType: insight.insightType,\n severity: insight.severity,\n ...insight.context,\n });\n\n this.store.addEdge(nodeId, entityNode.id, 'detected_on');\n }\n\n addCorrelation(entityA: string, entityB: string, weight: number = 1.0): void {\n const nodeA = this.store.getNodeByRef('entity', entityA);\n const nodeB = this.store.getNodeByRef('entity', entityB);\n if (!nodeA || !nodeB) return;\n\n this.store.addEdge(nodeA.id, nodeB.id, 'correlates', weight);\n }\n}\n","import type { ActionHandler, ActionContext, GovernanceLevel } from './types.js';\n\nexport class ActionRegistry {\n private readonly handlers = new Map<string, ActionHandler>();\n private readonly governance: Record<string, string>;\n\n constructor(governance?: Record<string, string>) {\n this.governance = governance ?? {};\n }\n\n register(name: string, handler: (context: ActionContext) => Promise<void>, description?: string): void {\n if (this.handlers.has(name)) {\n throw new Error(`Action handler \"${name}\" is already registered`);\n }\n this.handlers.set(name, { name, handler, description });\n }\n\n getHandler(name: string): ActionHandler | undefined {\n return this.handlers.get(name);\n }\n\n has(name: string): boolean {\n return this.handlers.has(name);\n }\n\n getNames(): string[] {\n return Array.from(this.handlers.keys());\n }\n\n getGovernance(actionName: string): GovernanceLevel {\n const level = this.governance[actionName];\n if (level === 'auto_approve' || level === 'require_approval' || level === 'never_automate') {\n return level;\n }\n return 'require_approval';\n }\n}\n","import type { ActionRule } from './types.js';\nimport type { Insight } from '../reasoning/types.js';\n\nconst DEFAULT_CONFIDENCE = 0.5;\n\nexport class ActionMatcher {\n private readonly rules: ActionRule[];\n\n constructor(rules: ActionRule[]) {\n this.rules = rules;\n }\n\n match(insight: Insight, confidence?: number): ActionRule[] {\n const effectiveConfidence = confidence ?? DEFAULT_CONFIDENCE;\n const matched: ActionRule[] = [];\n\n for (const rule of this.rules) {\n const threshold = rule.confidence ?? DEFAULT_CONFIDENCE;\n if (effectiveConfidence < threshold) {\n continue;\n }\n\n if (!this.matchesConditions(rule, insight)) {\n continue;\n }\n\n matched.push(rule);\n }\n\n return matched;\n }\n\n private matchesConditions(rule: ActionRule, insight: Insight): boolean {\n const { when } = rule;\n\n if (when.severity && when.severity.length > 0) {\n if (!when.severity.includes(insight.severity)) {\n return false;\n }\n }\n\n if (when.insightType && when.insightType.length > 0) {\n if (!when.insightType.includes(insight.insightType)) {\n return false;\n }\n }\n\n if (when.entity && when.entity.length > 0) {\n if (!when.entity.includes(insight.entity)) {\n return false;\n }\n }\n\n return true;\n }\n}\n","import { EventEmitter } from 'node:events';\nimport type { ActionRule, ActionContext, GovernanceLevel, RecommendationStatus } from './types.js';\nimport type { ActionRegistry } from './action-registry.js';\nimport type { ActionMatcher } from './action-matcher.js';\nimport type { Insight } from '../reasoning/types.js';\nimport { createLogger } from '../core/logger.js';\n\nconst logger = createLogger({ name: 'action-executor' });\n\nexport interface ActionExecutorStorage {\n saveRecommendation(rec: { action: string; reason: string; confidence: number; status: string; governance: string; insightId: string | null; entity: string; context: string }): number;\n getRecommendation(id: number): { id: number; action: string; reason: string; confidence: number; status: string; governance: string; insightId: string | null; entity: string; context: string; createdAt: string; resolvedAt: string | null; resolvedBy: string | null } | undefined;\n updateRecommendationStatus(id: number, status: string, resolvedBy: string): void;\n}\n\nexport class ActionExecutor extends EventEmitter {\n private readonly registry: ActionRegistry;\n private readonly matcher: ActionMatcher;\n private readonly storage: ActionExecutorStorage;\n\n constructor(registry: ActionRegistry, matcher: ActionMatcher, storage: ActionExecutorStorage) {\n super();\n this.registry = registry;\n this.matcher = matcher;\n this.storage = storage;\n }\n\n async onInsight(insight: Insight): Promise<void> {\n const confidence = this.computeConfidence(insight);\n const matchedRules = this.matcher.match(insight, confidence);\n\n for (const rule of matchedRules) {\n await this.processRule(rule, insight, confidence);\n }\n }\n\n private async processRule(rule: ActionRule, insight: Insight, confidence: number): Promise<void> {\n const governance = this.registry.getGovernance(rule.action);\n const handler = this.registry.getHandler(rule.action);\n\n let status: RecommendationStatus = 'pending';\n if (governance === 'never_automate') {\n status = 'blocked';\n } else if (governance === 'auto_approve' && handler) {\n status = 'executed';\n }\n\n const insightId = `insight:${insight.entity}:${insight.insightType}:${Date.now()}`;\n const recData = {\n action: rule.action,\n reason: insight.message,\n confidence,\n status: status === 'executed' ? 'executed' : status,\n governance,\n insightId,\n entity: insight.entity,\n context: JSON.stringify(insight.context),\n };\n\n const recId = this.storage.saveRecommendation(recData);\n\n const emitRec: { id: number; action: string; reason: string; confidence: number; status: RecommendationStatus; governance: GovernanceLevel; insightId: string; entity: string; context: Record<string, unknown> } = {\n id: recId,\n action: rule.action,\n reason: insight.message,\n confidence,\n status,\n governance,\n insightId,\n entity: insight.entity,\n context: insight.context,\n };\n\n if (status === 'executed' && handler) {\n try {\n const actionContext: ActionContext = {\n insight,\n entity: insight.entity,\n recommendation: {\n id: recId,\n action: rule.action,\n reason: insight.message,\n confidence,\n status: 'executed',\n governance,\n insightId,\n entity: insight.entity,\n context: insight.context,\n createdAt: new Date().toISOString(),\n resolvedAt: null,\n resolvedBy: null,\n },\n };\n await handler.handler(actionContext);\n this.emit('action:executed', emitRec);\n logger.info({ action: rule.action, entity: insight.entity }, 'Action executed');\n } catch (error) {\n this.storage.updateRecommendationStatus(recId, 'failed', 'auto');\n emitRec.status = 'failed';\n this.emit('action:failed', { ...emitRec, error: (error as Error).message });\n logger.error({ action: rule.action, error: (error as Error).message }, 'Action failed');\n }\n }\n\n this.emit('recommendation', emitRec);\n }\n\n private computeConfidence(insight: Insight): number {\n const severityWeights: Record<string, number> = {\n critical: 0.95,\n high: 0.8,\n medium: 0.6,\n low: 0.4,\n };\n return severityWeights[insight.severity] ?? 0.5;\n }\n}\n","import type { KnowledgeNode } from './types.js';\nimport type { GraphStore } from './graph-store.js';\n\nconst DEFAULT_MAX_DEPTH = 5;\n\nexport class Traversal {\n private readonly store: GraphStore;\n\n constructor(store: GraphStore) {\n this.store = store;\n }\n\n causesOf(nodeId: number, maxDepth: number = DEFAULT_MAX_DEPTH): KnowledgeNode[] {\n return this.bfs(nodeId, 'backward', maxDepth);\n }\n\n impactOf(nodeId: number, maxDepth: number = DEFAULT_MAX_DEPTH): KnowledgeNode[] {\n return this.bfs(nodeId, 'forward', maxDepth);\n }\n\n timeline(nodeId: number): KnowledgeNode[] {\n const neighbors = this.store.neighbors(nodeId);\n return neighbors.sort((a, b) => {\n if (a.timestamp > b.timestamp) return -1;\n if (a.timestamp < b.timestamp) return 1;\n return 0;\n });\n }\n\n private bfs(startId: number, direction: 'forward' | 'backward', maxDepth: number): KnowledgeNode[] {\n const visited = new Set<number>();\n visited.add(startId);\n\n const result: KnowledgeNode[] = [];\n let currentLevel: number[] = [startId];\n\n for (let depth = 0; depth < maxDepth && currentLevel.length > 0; depth++) {\n const nextLevel: number[] = [];\n\n for (const nodeId of currentLevel) {\n const edges = direction === 'forward'\n ? this.store.getEdgesFrom(nodeId, 'causes')\n : this.store.getEdgesTo(nodeId, 'causes');\n\n for (const edge of edges) {\n const neighborId = direction === 'forward' ? edge.targetId : edge.sourceId;\n if (!visited.has(neighborId)) {\n visited.add(neighborId);\n const node = this.store.getNode(neighborId);\n if (node) {\n result.push(node);\n nextLevel.push(neighborId);\n }\n }\n }\n }\n\n currentLevel = nextLevel;\n }\n\n return result;\n }\n}\n","import type { EntityIntelligenceResult } from './types.js';\nimport type { GraphStore } from './graph-store.js';\n\nconst MAX_RECENT_INSIGHTS = 10;\n\nexport class EntityIntelligence {\n private readonly store: GraphStore;\n\n constructor(store: GraphStore) {\n this.store = store;\n }\n\n forEntity(refId: string): EntityIntelligenceResult | undefined {\n const entityNode = this.store.getNodeByRef('entity', refId);\n if (!entityNode) return undefined;\n\n const containsEdges = this.store.getEdgesFrom(entityNode.id, 'contains');\n const tableCount = containsEdges.length;\n\n const incomingEdges = this.store.getEdgesTo(entityNode.id, 'detected_on');\n const connectedNodeIds = incomingEdges.map((e) => e.sourceId);\n\n let totalEvents = 0;\n let anomalyCount = 0;\n const recentInsights = [];\n\n for (const nid of connectedNodeIds) {\n const node = this.store.getNode(nid);\n if (!node) continue;\n if (node.nodeType === 'event') totalEvents++;\n if (node.nodeType === 'anomaly') anomalyCount++;\n if (node.nodeType === 'insight') {\n recentInsights.push(node);\n }\n }\n\n recentInsights.sort((a, b) => (a.timestamp > b.timestamp ? -1 : 1));\n const limitedInsights = recentInsights.slice(0, MAX_RECENT_INSIGHTS);\n\n const correlatesEdges = this.store.getEdgesFrom(entityNode.id, 'correlates');\n const topCorrelations = correlatesEdges\n .map((edge) => {\n const targetNode = this.store.getNode(edge.targetId);\n return targetNode ? { entity: targetNode.label, weight: edge.weight } : null;\n })\n .filter((c): c is { entity: string; weight: number } => c !== null)\n .sort((a, b) => b.weight - a.weight);\n\n const riskScore = totalEvents > 0 ? anomalyCount / totalEvents : 0;\n\n return {\n entityName: entityNode.label,\n tableCount,\n totalEvents,\n anomalyCount,\n topCorrelations,\n recentInsights: limitedInsights,\n riskScore,\n };\n }\n}\n","import type { GraphExport } from './types.js';\nimport type { GraphStore } from './graph-store.js';\n\nexport function exportGraph(store: GraphStore, rootNodeId?: number): GraphExport {\n if (rootNodeId === undefined) {\n return {\n nodes: store.getAllNodes(),\n edges: store.getAllEdges(),\n };\n }\n\n // BFS to find all reachable nodes\n const visited = new Set<number>();\n const queue: number[] = [rootNodeId];\n visited.add(rootNodeId);\n\n while (queue.length > 0) {\n const nodeId = queue.shift()!;\n const outgoing = store.getEdgesFrom(nodeId);\n const incoming = store.getEdgesTo(nodeId);\n\n for (const edge of [...outgoing, ...incoming]) {\n const neighborId = edge.sourceId === nodeId ? edge.targetId : edge.sourceId;\n if (!visited.has(neighborId)) {\n visited.add(neighborId);\n queue.push(neighborId);\n }\n }\n }\n\n const nodes = [];\n for (const id of visited) {\n const node = store.getNode(id);\n if (node) nodes.push(node);\n }\n\n const allEdges = store.getAllEdges();\n const edges = allEdges.filter(\n (e) => visited.has(e.sourceId) && visited.has(e.targetId)\n );\n\n return { nodes, edges };\n}\n","import { createLogger } from '../core/logger.js';\nimport type { NotificationRule, NotificationTrigger } from './types.js';\nimport { formatForSlack, formatGeneric } from './formatters.js';\n\nexport class Notifier {\n private readonly rules: NotificationRule[];\n private readonly logger = createLogger({ name: 'notifier' });\n\n constructor(rules: NotificationRule[]) {\n this.rules = rules;\n }\n\n async notify(trigger: NotificationTrigger, payload: Record<string, unknown>): Promise<void> {\n const matchingRules = this.rules.filter((rule) => {\n if (!rule.triggers.includes(trigger)) return false;\n if (rule.filter?.severity && payload.severity) {\n if (!rule.filter.severity.includes(payload.severity as 'low' | 'medium' | 'high' | 'critical')) {\n return false;\n }\n }\n if (rule.filter?.entity && payload.entity) {\n if (!rule.filter.entity.includes(payload.entity as string)) {\n return false;\n }\n }\n return true;\n });\n\n const sends: Promise<void>[] = [];\n for (const rule of matchingRules) {\n for (const target of rule.targets) {\n const body = target.type === 'slack'\n ? formatForSlack(trigger, payload)\n : formatGeneric(trigger, payload);\n\n sends.push(this.send(target.url, body, target.headers));\n }\n }\n\n const results = await Promise.allSettled(sends);\n for (const result of results) {\n if (result.status === 'rejected') {\n this.logger.error({ error: (result.reason as Error).message }, 'Webhook delivery failed');\n }\n }\n }\n\n private async send(url: string, body: Record<string, unknown>, headers?: Record<string, string>): Promise<void> {\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...headers,\n },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n throw new Error(`Webhook returned ${response.status}: ${await response.text()}`);\n }\n }\n}\n","import type { NotificationTrigger } from './types.js';\n\nconst SEVERITY_COLORS: Record<string, string> = {\n critical: '#dc2626',\n high: '#ea580c',\n medium: '#ca8a04',\n low: '#2563eb',\n};\n\nexport function formatForSlack(\n trigger: NotificationTrigger,\n payload: Record<string, unknown>,\n): Record<string, unknown> {\n const severity = (payload.severity as string) ?? 'info';\n const color = SEVERITY_COLORS[severity] ?? '#6b7280';\n const entity = (payload.entity as string) ?? 'unknown';\n const message = (payload.message as string) ?? JSON.stringify(payload);\n const timestamp = (payload.timestamp as string) ?? new Date().toISOString();\n\n return {\n attachments: [\n {\n color,\n blocks: [\n {\n type: 'section',\n text: {\n type: 'mrkdwn',\n text: `*[${trigger.toUpperCase()}]* ${message}`,\n },\n },\n {\n type: 'context',\n elements: [\n {\n type: 'mrkdwn',\n text: `Entity: *${entity}* | Severity: *${severity}* | ${timestamp}`,\n },\n ],\n },\n ],\n },\n ],\n };\n}\n\nexport function formatGeneric(\n trigger: NotificationTrigger,\n payload: Record<string, unknown>,\n): Record<string, unknown> {\n return {\n trigger,\n timestamp: (payload.timestamp as string) ?? new Date().toISOString(),\n data: payload,\n };\n}\n","import type { LLMProvider } from '../llm/types.js';\nimport type { CortexaStorage } from '../core/storage.js';\nimport type { GraphStore } from '../knowledge/graph-store.js';\nimport type { Traversal } from '../knowledge/traversal.js';\nimport { LLMResponseError } from '../core/errors.js';\nimport { createLogger } from '../core/logger.js';\nimport { ExplainContextBuilder } from './context-builder.js';\nimport type { ExplainTarget, ExplainOptions, ExplainResult, Evidence, CausalStep, RecommendedAction } from './types.js';\n\nconst logger = createLogger({ name: 'explainer' });\n\nlet explainCounter = 0;\n\nfunction generateExplanationId(target: ExplainTarget): string {\n explainCounter++;\n return `exp_${target.type}_${target.id}_${Date.now()}_${explainCounter}`;\n}\n\nexport class Explainer {\n private readonly llm: LLMProvider;\n private readonly contextBuilder: ExplainContextBuilder;\n\n constructor(llm: LLMProvider, storage: CortexaStorage, graphStore?: GraphStore, traversal?: Traversal) {\n this.llm = llm;\n this.contextBuilder = new ExplainContextBuilder(storage, graphStore, traversal);\n }\n\n async explain(target: ExplainTarget, options?: ExplainOptions): Promise<ExplainResult> {\n logger.info({ target }, 'Building explanation context');\n\n const context = this.contextBuilder.buildContext(target, options);\n const prompt = this.buildPrompt(target, context, options);\n const chatOptions = { jsonMode: true, maxTokens: 4096 };\n\n let response = await this.llm.chat(prompt, chatOptions);\n try {\n return this.parseResponse(response.content, target);\n } catch {\n logger.warn('First LLM parse failed, retrying');\n response = await this.llm.chat(prompt, chatOptions);\n return this.parseResponse(response.content, target);\n }\n }\n\n private buildPrompt(\n target: ExplainTarget,\n context: { targetDescription: string; entityInfo: string; recentEvents: string; baselines: string; transitions: string; graphContext: string; correlations: string },\n options?: ExplainOptions,\n ): string {\n const includeRecommendations = options?.includeRecommendations !== false;\n\n return `You are a database intelligence analyst. Given the following context about a detected ${target.type}, explain WHY it happened using root cause analysis.\n\nTARGET:\n${context.targetDescription}\n\nCONTEXT:\n\nEntity Information:\n${context.entityInfo}\n\nRecent Events:\n${context.recentEvents}\n\nBaselines:\n${context.baselines}\n\nState Transitions:\n${context.transitions}\n\nKnowledge Graph:\n${context.graphContext}\n\nCorrelations:\n${context.correlations}\n\nAnalyze the data above and return a JSON object with your explanation. Be specific and reference actual data points from the context.\n\nReturn valid JSON in this exact format:\n{\n \"summary\": \"1-2 sentence human-readable explanation of the root cause\",\n \"confidence\": 0.85,\n \"evidence\": [\n {\n \"type\": \"event|baseline|transition|correlation|graph_node\",\n \"description\": \"What this evidence shows\",\n \"data\": {},\n \"relevance\": 0.9\n }\n ],\n \"causalChain\": [\n {\n \"order\": 1,\n \"description\": \"First thing that happened\",\n \"confidence\": 0.8\n }\n ]${includeRecommendations ? `,\n \"recommendedActions\": [\n {\n \"action\": \"What to do\",\n \"reason\": \"Why this helps\",\n \"priority\": \"low|medium|high\"\n }\n ]` : ''}\n}`;\n }\n\n private parseResponse(content: string, target: ExplainTarget): ExplainResult {\n let data: {\n summary?: string;\n confidence?: number;\n evidence?: Evidence[];\n causalChain?: CausalStep[];\n recommendedActions?: RecommendedAction[];\n };\n\n try {\n data = JSON.parse(content) as typeof data;\n } catch (err) {\n throw new LLMResponseError(\n `Failed to parse explain response: ${(err as Error).message}`,\n content.slice(0, 500),\n );\n }\n\n if (!data.summary || typeof data.summary !== 'string') {\n throw new LLMResponseError('Invalid explain response: missing \"summary\"', content.slice(0, 500));\n }\n\n return {\n explanationId: generateExplanationId(target),\n target,\n summary: data.summary,\n confidence: typeof data.confidence === 'number' ? data.confidence : 0.5,\n evidence: Array.isArray(data.evidence) ? data.evidence.map((e) => ({\n type: e.type ?? 'event',\n description: e.description ?? '',\n data: e.data ?? {},\n relevance: typeof e.relevance === 'number' ? e.relevance : 0.5,\n })) : [],\n causalChain: Array.isArray(data.causalChain) ? data.causalChain.map((s, i) => ({\n order: s.order ?? i + 1,\n description: s.description ?? '',\n confidence: typeof s.confidence === 'number' ? s.confidence : 0.5,\n })) : [],\n recommendedActions: Array.isArray(data.recommendedActions) ? data.recommendedActions.map((a) => ({\n action: a.action ?? '',\n reason: a.reason ?? '',\n priority: (['low', 'medium', 'high'].includes(a.priority) ? a.priority : 'medium') as 'low' | 'medium' | 'high',\n })) : [],\n generatedAt: new Date().toISOString(),\n };\n }\n}\n","import type { CortexaStorage } from '../core/storage.js';\nimport type { GraphStore } from '../knowledge/graph-store.js';\nimport type { Traversal } from '../knowledge/traversal.js';\nimport type { ExplainTarget, ExplainContext, ExplainOptions } from './types.js';\n\nconst DEFAULT_MAX_EVENTS = 50;\nconst DEFAULT_MAX_GRAPH_DEPTH = 3;\n\nexport class ExplainContextBuilder {\n private readonly storage: CortexaStorage;\n private readonly graphStore: GraphStore | null;\n private readonly traversal: Traversal | null;\n\n constructor(storage: CortexaStorage, graphStore?: GraphStore, traversal?: Traversal) {\n this.storage = storage;\n this.graphStore = graphStore ?? null;\n this.traversal = traversal ?? null;\n }\n\n buildContext(target: ExplainTarget, options?: ExplainOptions): ExplainContext {\n const maxEvents = options?.maxContextEvents ?? DEFAULT_MAX_EVENTS;\n const maxGraphDepth = options?.maxGraphDepth ?? DEFAULT_MAX_GRAPH_DEPTH;\n\n switch (target.type) {\n case 'anomaly':\n return this.buildAnomalyContext(target.id, maxEvents, maxGraphDepth);\n case 'insight':\n return this.buildInsightContext(target.id, maxEvents, maxGraphDepth);\n case 'event':\n return this.buildEventContext(target.id, maxEvents);\n case 'entity':\n return this.buildEntityContext(target.id, maxEvents, maxGraphDepth);\n default:\n throw new Error(`Unknown explain target type: ${(target as ExplainTarget).type}`);\n }\n }\n\n private buildAnomalyContext(id: number, maxEvents: number, maxGraphDepth: number): ExplainContext {\n const anomaly = this.storage.getAnomalyById(id);\n if (!anomaly) {\n throw new Error(`Anomaly with id ${id} not found`);\n }\n\n const entity = anomaly.entity;\n const targetDescription = `Anomaly: ${anomaly.message} (type: ${anomaly.anomalyType}, severity: ${anomaly.severity}, expected: ${anomaly.expected}, actual: ${anomaly.actual}, at: ${anomaly.timestamp})`;\n\n return {\n targetDescription,\n entityInfo: this.getEntityInfo(entity),\n recentEvents: this.getRecentEvents(entity, maxEvents),\n baselines: this.getBaselines(entity),\n transitions: this.getTransitions(entity),\n graphContext: this.getGraphContext(entity, maxGraphDepth),\n correlations: this.getCorrelations(entity),\n };\n }\n\n private buildInsightContext(id: number, maxEvents: number, maxGraphDepth: number): ExplainContext {\n const insight = this.storage.getInsightById(id);\n if (!insight) {\n throw new Error(`Insight with id ${id} not found`);\n }\n\n const entity = insight.entity;\n const targetDescription = `Insight: ${insight.message} (type: ${insight.insightType}, severity: ${insight.severity}, at: ${insight.timestamp}, context: ${JSON.stringify(insight.context)})`;\n\n return {\n targetDescription,\n entityInfo: this.getEntityInfo(entity),\n recentEvents: this.getRecentEvents(entity, maxEvents),\n baselines: this.getBaselines(entity),\n transitions: this.getTransitions(entity),\n graphContext: this.getGraphContext(entity, maxGraphDepth),\n correlations: this.getCorrelations(entity),\n };\n }\n\n private buildEventContext(id: number, maxEvents: number): ExplainContext {\n const event = this.storage.getEventById(id);\n if (!event) {\n throw new Error(`Event with id ${id} not found`);\n }\n\n const entity = event.entity;\n const targetDescription = `Event: ${event.eventType} on ${event.tableName} (operation: ${event.operation}, row: ${event.rowId}, at: ${event.timestamp})`;\n\n return {\n targetDescription,\n entityInfo: this.getEntityInfo(entity),\n recentEvents: this.getRecentEvents(entity, maxEvents),\n baselines: this.getBaselines(entity),\n transitions: this.getTransitions(entity),\n graphContext: '',\n correlations: this.getCorrelations(entity),\n };\n }\n\n private buildEntityContext(id: number, maxEvents: number, maxGraphDepth: number): ExplainContext {\n // For entity targets, the id refers to the entity's row in entities table\n // We look up by scanning entities\n const entities = this.storage.getEntities();\n const entityRow = entities[id - 1]; // entities don't have reliable IDs, use as index fallback\n\n if (!entityRow) {\n throw new Error(`Entity with id ${id} not found`);\n }\n\n const entity = entityRow.tableName;\n const targetDescription = `Entity: ${entityRow.entityLabel} (${entity}, type: ${entityRow.entityType}, description: ${entityRow.description})`;\n\n const anomalies = this.storage.getAnomalies({ entity });\n const insights = this.storage.getInsights({ entity });\n const anomalySummary = anomalies.length > 0\n ? `Recent anomalies (${anomalies.length}): ${anomalies.slice(0, 5).map((a) => `${a.anomalyType}:${a.severity} - ${a.message}`).join('; ')}`\n : 'No anomalies detected';\n const insightSummary = insights.length > 0\n ? `Recent insights (${insights.length}): ${insights.slice(0, 5).map((i) => `${i.insightType}:${i.severity} - ${i.message}`).join('; ')}`\n : 'No insights generated';\n\n return {\n targetDescription: `${targetDescription}\\n${anomalySummary}\\n${insightSummary}`,\n entityInfo: this.getEntityInfo(entity),\n recentEvents: this.getRecentEvents(entity, maxEvents),\n baselines: this.getBaselines(entity),\n transitions: this.getTransitions(entity),\n graphContext: this.getGraphContext(entity, maxGraphDepth),\n correlations: this.getCorrelations(entity),\n };\n }\n\n private getEntityInfo(entity: string): string {\n const entityData = this.storage.getEntity(entity);\n if (!entityData) return `Entity: ${entity} (no classification data)`;\n\n return `Entity: ${entityData.entityLabel} (table: ${entity}, type: ${entityData.entityType}, description: ${entityData.description}, confidence: ${entityData.confidence})`;\n }\n\n private getRecentEvents(entity: string, maxEvents: number): string {\n const events = this.storage.getEvents({ entity });\n const limited = events.slice(0, maxEvents);\n if (limited.length === 0) return 'No recent events';\n\n return limited.map((e) => `[${e.timestamp}] ${e.eventType} ${e.operation} (row: ${e.rowId})`).join('\\n');\n }\n\n private getBaselines(entity: string): string {\n const baselines = this.storage.getBaselines();\n const entityBaselines = baselines.filter((b) => b.entity === entity);\n if (entityBaselines.length === 0) return 'No baselines established';\n\n return entityBaselines.map((b) => `${b.metric}: mean=${b.mean.toFixed(2)}, stddev=${b.stddev.toFixed(2)}, samples=${b.sampleSize}`).join('\\n');\n }\n\n private getTransitions(entity: string): string {\n const stats = this.storage.getTransitionStats(entity);\n if (stats.length === 0) return 'No state transitions recorded';\n\n return stats.map((t) => `${t.fromState} -> ${t.toState}: count=${t.count}, avg=${t.avgDurationMs}ms, min=${t.minDurationMs}ms, max=${t.maxDurationMs}ms`).join('\\n');\n }\n\n private getGraphContext(entity: string, maxDepth: number): string {\n if (!this.graphStore || !this.traversal) return 'Knowledge graph not available';\n\n const entityNode = this.graphStore.getNodeByRef('entity', entity);\n if (!entityNode) return 'Entity not found in knowledge graph';\n\n const neighbors = this.graphStore.neighbors(entityNode.id);\n const causes = this.traversal.causesOf(entityNode.id, maxDepth);\n const impacts = this.traversal.impactOf(entityNode.id, maxDepth);\n\n const parts: string[] = [];\n if (neighbors.length > 0) {\n parts.push(`Connected nodes (${neighbors.length}): ${neighbors.map((n) => `${n.nodeType}:${n.label}`).join(', ')}`);\n }\n if (causes.length > 0) {\n parts.push(`Causes (${causes.length}): ${causes.map((n) => `${n.nodeType}:${n.label}`).join(', ')}`);\n }\n if (impacts.length > 0) {\n parts.push(`Impacts (${impacts.length}): ${impacts.map((n) => `${n.nodeType}:${n.label}`).join(', ')}`);\n }\n\n return parts.length > 0 ? parts.join('\\n') : 'No graph connections found';\n }\n\n private getCorrelations(entity: string): string {\n const rates = this.storage.getCorrelationRates(entity, 24);\n if (rates.length === 0) return 'No correlation data';\n\n return `Correlation rates (last 24h): ${rates.slice(0, 10).map((r) => `${r.bucket}:${r.eventCount}`).join(', ')}`;\n }\n}\n","import type { LLMProvider } from '../llm/types.js';\nimport type { CortexaStorage } from '../core/storage.js';\nimport type { GraphStore } from '../knowledge/graph-store.js';\nimport { LLMResponseError } from '../core/errors.js';\nimport { createLogger } from '../core/logger.js';\nimport { AskContextBuilder } from './ask-context-builder.js';\nimport type { AskOptions, AskResult, SupportingSignal, SignalType } from './types.js';\n\nconst logger = createLogger({ name: 'asker' });\n\nlet askCounter = 0;\n\nfunction generateAskId(): string {\n askCounter++;\n return `ask_${Date.now()}_${askCounter}`;\n}\n\nconst VALID_SIGNAL_TYPES: Set<string> = new Set([\n 'baselineDeviation', 'anomaly', 'insight', 'eventCluster',\n 'transition', 'correlation', 'graphRelation',\n]);\n\nexport class Asker {\n private readonly llm: LLMProvider;\n private readonly contextBuilder: AskContextBuilder;\n\n constructor(llm: LLMProvider, storage: CortexaStorage, graphStore?: GraphStore) {\n this.llm = llm;\n this.contextBuilder = new AskContextBuilder(storage, graphStore);\n }\n\n async ask(question: string, options?: AskOptions): Promise<AskResult> {\n logger.info({ question }, 'Processing question');\n\n const context = this.contextBuilder.buildContext(options);\n const prompt = this.buildPrompt(question, context);\n const chatOptions = { jsonMode: true, maxTokens: 4096 };\n\n let response = await this.llm.chat(prompt, chatOptions);\n try {\n return this.parseResponse(response.content, question);\n } catch {\n logger.warn('First LLM parse failed, retrying');\n response = await this.llm.chat(prompt, chatOptions);\n return this.parseResponse(response.content, question);\n }\n }\n\n private buildPrompt(\n question: string,\n context: { entities: string; recentEvents: string; baselines: string; anomalies: string; insights: string; transitions: string; graphSummary: string; recommendations: string },\n ): string {\n return `You are a database intelligence analyst. You have access to a live monitoring system that tracks a database. Answer the user's question using ONLY the data provided below. Be specific — reference actual numbers, entity names, and timestamps from the data.\n\nQUESTION: ${question}\n\nSYSTEM STATE:\n\nEntities:\n${context.entities}\n\nRecent Events:\n${context.recentEvents}\n\nBaselines:\n${context.baselines}\n\nAnomalies:\n${context.anomalies}\n\nInsights:\n${context.insights}\n\nState Transitions:\n${context.transitions}\n\nKnowledge Graph:\n${context.graphSummary}\n\nRecommendations:\n${context.recommendations}\n\nAnalyze the data and answer the question. If the data doesn't contain enough information, say so honestly and lower your confidence score.\n\nReturn valid JSON in this exact format:\n{\n \"answer\": \"Clear, specific answer referencing actual data points\",\n \"confidence\": 0.85,\n \"supportingSignals\": [\n {\n \"type\": \"baselineDeviation|anomaly|insight|eventCluster|transition|correlation|graphRelation\",\n \"entity\": \"entity name\",\n \"description\": \"What this signal shows\",\n \"data\": {}\n }\n ],\n \"relatedEntities\": [\"entity1\", \"entity2\"],\n \"recommendedActions\": [\"Action 1\", \"Action 2\"]\n}`;\n }\n\n private parseResponse(content: string, question: string): AskResult {\n let data: {\n answer?: string;\n confidence?: number;\n supportingSignals?: SupportingSignal[];\n relatedEntities?: string[];\n recommendedActions?: string[];\n };\n\n try {\n data = JSON.parse(content) as typeof data;\n } catch (err) {\n throw new LLMResponseError(\n `Failed to parse ask response: ${(err as Error).message}`,\n content.slice(0, 500),\n );\n }\n\n if (!data.answer || typeof data.answer !== 'string') {\n throw new LLMResponseError('Invalid ask response: missing \"answer\"', content.slice(0, 500));\n }\n\n return {\n askId: generateAskId(),\n question,\n answer: data.answer,\n confidence: typeof data.confidence === 'number' ? data.confidence : 0.5,\n supportingSignals: Array.isArray(data.supportingSignals) ? data.supportingSignals.map((s) => ({\n type: (VALID_SIGNAL_TYPES.has(s.type) ? s.type : 'anomaly') as SignalType,\n entity: s.entity ?? '',\n description: s.description ?? '',\n data: s.data ?? {},\n })) : [],\n relatedEntities: Array.isArray(data.relatedEntities)\n ? data.relatedEntities.filter((e): e is string => typeof e === 'string')\n : [],\n recommendedActions: Array.isArray(data.recommendedActions)\n ? data.recommendedActions.filter((a): a is string => typeof a === 'string')\n : [],\n generatedAt: new Date().toISOString(),\n };\n }\n}\n","import type { CortexaStorage } from '../core/storage.js';\nimport type { GraphStore } from '../knowledge/graph-store.js';\nimport type { AskOptions, AskContext } from './types.js';\n\nconst DEFAULT_MAX_EVENTS = 50;\nconst MAX_ANOMALIES = 20;\nconst MAX_INSIGHTS = 20;\nconst MAX_RECOMMENDATIONS = 10;\n\nexport class AskContextBuilder {\n private readonly storage: CortexaStorage;\n private readonly graphStore: GraphStore | null;\n\n constructor(storage: CortexaStorage, graphStore?: GraphStore) {\n this.storage = storage;\n this.graphStore = graphStore ?? null;\n }\n\n buildContext(options?: AskOptions): AskContext {\n const maxEvents = options?.maxContextEvents ?? DEFAULT_MAX_EVENTS;\n const entityHint = options?.entityHint;\n\n return {\n entities: this.getEntities(),\n recentEvents: this.getRecentEvents(maxEvents, entityHint),\n baselines: this.getBaselines(),\n anomalies: this.getAnomalies(),\n insights: this.getInsights(),\n transitions: this.getTransitions(),\n graphSummary: this.getGraphSummary(),\n recommendations: this.getRecommendations(),\n };\n }\n\n private getEntities(): string {\n const entities = this.storage.getEntities();\n if (entities.length === 0) return 'No entities discovered yet';\n\n return entities.map((e) =>\n `${e.tableName} (${e.entityLabel}, type: ${e.entityType}, ${e.description})`\n ).join('\\n');\n }\n\n private getRecentEvents(maxEvents: number, entityHint?: string): string {\n const filter: { entity?: string } = {};\n if (entityHint) filter.entity = entityHint;\n\n const events = this.storage.getEvents(filter);\n const limited = events.slice(0, maxEvents);\n if (limited.length === 0) return 'No recent events';\n\n return `${events.length} total events (showing ${limited.length}):\\n` +\n limited.map((e) =>\n `[${e.timestamp}] ${e.entity} ${e.eventType} ${e.operation} (row: ${e.rowId})`\n ).join('\\n');\n }\n\n private getBaselines(): string {\n const baselines = this.storage.getBaselines();\n if (baselines.length === 0) return 'No baselines established';\n\n return baselines.map((b) =>\n `${b.entity}.${b.metric}: mean=${b.mean.toFixed(2)}, stddev=${b.stddev.toFixed(2)}, samples=${b.sampleSize}`\n ).join('\\n');\n }\n\n private getAnomalies(): string {\n const anomalies = this.storage.getAnomalies();\n const limited = anomalies.slice(0, MAX_ANOMALIES);\n if (limited.length === 0) return 'No anomalies detected';\n\n return `${anomalies.length} total anomalies (showing ${limited.length}):\\n` +\n limited.map((a) =>\n `[${a.timestamp}] ${a.entity} ${a.anomalyType} (${a.severity}): ${a.message} (expected: ${a.expected}, actual: ${a.actual})`\n ).join('\\n');\n }\n\n private getInsights(): string {\n const insights = this.storage.getInsights();\n const limited = insights.slice(0, MAX_INSIGHTS);\n if (limited.length === 0) return 'No insights generated';\n\n return `${insights.length} total insights (showing ${limited.length}):\\n` +\n limited.map((i) =>\n `[${i.timestamp}] ${i.entity} ${i.insightType} (${i.severity}): ${i.message}`\n ).join('\\n');\n }\n\n private getTransitions(): string {\n const stats = this.storage.getTransitionStats();\n if (stats.length === 0) return 'No state transitions recorded';\n\n return stats.map((t) =>\n `${t.entity}: ${t.fromState} -> ${t.toState} (count=${t.count}, avg=${t.avgDurationMs}ms)`\n ).join('\\n');\n }\n\n private getGraphSummary(): string {\n if (!this.graphStore) return 'Knowledge graph not available';\n\n const summary = this.graphStore.getSummary();\n return `Nodes: ${summary.totalNodes}, Edges: ${summary.totalEdges} (entities: ${summary.entities}, events: ${summary.events}, anomalies: ${summary.anomalies}, insights: ${summary.insights})`;\n }\n\n private getRecommendations(): string {\n const recs = this.storage.getRecommendations({ last: MAX_RECOMMENDATIONS });\n if (recs.length === 0) return 'No recommendations';\n\n return recs.map((r) =>\n `[${r.status}] ${r.action}: ${r.reason} (confidence: ${r.confidence}, entity: ${r.entity})`\n ).join('\\n');\n }\n}\n","import { cosmiconfig } from 'cosmiconfig';\nimport type { LLMConfig } from '../llm/types.js';\nimport type { ReasoningConfig } from '../reasoning/types.js';\nimport type { AnalyticsConfig } from '../analytics/types.js';\nimport type { KnowledgeConfig } from '../knowledge/types.js';\nimport type { ActionsConfig } from '../actions/types.js';\nimport type { NotificationsConfig } from '../notifications/types.js';\nimport { ConfigError } from './errors.js';\nimport { validateConfig } from './validate-config.js';\n\n// Re-export as LlmConfig for backwards compatibility\nexport type LlmConfig = LLMConfig;\n\nexport interface ConnectionConfig {\n type: 'postgres' | 'mysql' | 'mariadb' | 'cockroachdb' | 'sqlite' | 'mongodb' | 'mssql';\n url?: string;\n host?: string;\n port?: number;\n database?: string;\n user?: string;\n password?: string;\n path?: string;\n}\n\nexport interface CortexaConfig {\n connection: ConnectionConfig;\n llm?: LLMConfig;\n reasoning?: ReasoningConfig;\n analytics?: AnalyticsConfig;\n knowledge?: KnowledgeConfig;\n actions?: ActionsConfig;\n notifications?: NotificationsConfig;\n batchSize?: number;\n}\n\nexport function defineConfig(config: CortexaConfig): CortexaConfig {\n return config;\n}\n\nconst MODULE_NAME = 'cortexa';\n\nexport async function loadConfig(searchFrom?: string): Promise<CortexaConfig> {\n const explorer = cosmiconfig(MODULE_NAME, {\n searchPlaces: [\n 'cortexa.config.ts',\n 'cortexa.config.js',\n 'cortexa.config.mjs',\n 'cortexa.config.cjs',\n '.cortexarc',\n '.cortexarc.json',\n '.cortexarc.yaml',\n '.cortexarc.yml',\n ],\n });\n\n const result = await explorer.search(searchFrom);\n\n if (!result || result.isEmpty) {\n throw new ConfigError(\n 'No Cortexa configuration found.',\n 'Run `npx cortexa init` to create a cortexa.config.ts file.',\n );\n }\n\n const validationErrors = validateConfig(result.config);\n if (validationErrors.length > 0) {\n const messages = validationErrors.map((e) => ` ${e.path}: ${e.message}`).join('\\n');\n throw new ConfigError(\n `Invalid configuration:\\n${messages}`,\n 'Check your cortexa.config.ts file.',\n );\n }\n\n return result.config as CortexaConfig;\n}\n","export interface ValidationError {\n path: string;\n message: string;\n}\n\nexport function validateConfig(config: unknown): ValidationError[] {\n const errors: ValidationError[] = [];\n\n if (!config || typeof config !== 'object') {\n errors.push({ path: '', message: 'Config must be an object.' });\n return errors;\n }\n\n const cfg = config as Record<string, unknown>;\n\n // connection (required)\n if (!cfg.connection || typeof cfg.connection !== 'object') {\n errors.push({ path: 'connection', message: 'Required. Must be an object with type, and either url or host+database.' });\n return errors;\n }\n\n const conn = cfg.connection as Record<string, unknown>;\n\n const validTypes = new Set(['postgres', 'mysql', 'mariadb', 'cockroachdb', 'sqlite', 'mongodb', 'mssql']);\n if (!conn.type || !validTypes.has(conn.type as string)) {\n errors.push({ path: 'connection.type', message: `Must be one of: ${[...validTypes].join(', ')}.` });\n }\n\n if (conn.type === 'sqlite') {\n if (!conn.path && !conn.database) {\n errors.push({ path: 'connection', message: 'SQLite requires path or database (file path).' });\n }\n } else if (!conn.url && !conn.host) {\n errors.push({ path: 'connection', message: 'Provide either url or host+database.' });\n }\n\n if (conn.port !== undefined && conn.port !== null) {\n if (typeof conn.port !== 'number' || !Number.isInteger(conn.port) || conn.port <= 0) {\n errors.push({ path: 'connection.port', message: 'Must be a positive integer.' });\n }\n }\n\n // llm (optional)\n if (cfg.llm !== undefined) {\n if (typeof cfg.llm !== 'object' || cfg.llm === null) {\n errors.push({ path: 'llm', message: 'Must be an object.' });\n } else {\n const llm = cfg.llm as Record<string, unknown>;\n\n if (!llm.provider || typeof llm.provider !== 'string') {\n errors.push({ path: 'llm.provider', message: 'Required. Must be a string (e.g., \"openai\", \"deepseek\", \"anthropic\").' });\n }\n\n if (llm.apiKey !== undefined && (typeof llm.apiKey !== 'string' || llm.apiKey.length === 0)) {\n errors.push({ path: 'llm.apiKey', message: 'Must be a non-empty string.' });\n }\n\n if (llm.baseUrl !== undefined && (typeof llm.baseUrl !== 'string' || !llm.baseUrl.startsWith('http'))) {\n errors.push({ path: 'llm.baseUrl', message: 'Must be a valid URL starting with http.' });\n }\n }\n }\n\n // batchSize (optional)\n if (cfg.batchSize !== undefined) {\n if (typeof cfg.batchSize !== 'number' || !Number.isInteger(cfg.batchSize) || cfg.batchSize < 1 || cfg.batchSize > 50) {\n errors.push({ path: 'batchSize', message: 'Must be an integer between 1 and 50.' });\n }\n }\n\n // notifications (optional)\n if (cfg.notifications !== undefined) {\n if (typeof cfg.notifications !== 'object' || cfg.notifications === null) {\n errors.push({ path: 'notifications', message: 'Must be an object.' });\n } else {\n const notif = cfg.notifications as Record<string, unknown>;\n if (notif.enabled !== undefined && typeof notif.enabled !== 'boolean') {\n errors.push({ path: 'notifications.enabled', message: 'Must be a boolean.' });\n }\n if (notif.rules !== undefined) {\n if (!Array.isArray(notif.rules)) {\n errors.push({ path: 'notifications.rules', message: 'Must be an array.' });\n } else {\n const validTriggers = new Set(['anomaly', 'insight', 'recommendation', 'action:executed', 'action:failed']);\n for (let i = 0; i < notif.rules.length; i++) {\n const rule = notif.rules[i] as Record<string, unknown>;\n if (!rule.triggers || !Array.isArray(rule.triggers) || rule.triggers.length === 0) {\n errors.push({ path: `notifications.rules[${i}].triggers`, message: 'Required. Must be a non-empty array of trigger types.' });\n } else {\n for (const t of rule.triggers) {\n if (!validTriggers.has(t as string)) {\n errors.push({ path: `notifications.rules[${i}].triggers`, message: `Invalid trigger \"${t}\". Must be one of: ${[...validTriggers].join(', ')}.` });\n }\n }\n }\n if (!rule.targets || !Array.isArray(rule.targets) || rule.targets.length === 0) {\n errors.push({ path: `notifications.rules[${i}].targets`, message: 'Required. Must be a non-empty array of webhook targets.' });\n } else {\n for (let j = 0; j < rule.targets.length; j++) {\n const target = rule.targets[j] as Record<string, unknown>;\n if (!target.url || typeof target.url !== 'string' || !target.url.startsWith('http')) {\n errors.push({ path: `notifications.rules[${i}].targets[${j}].url`, message: 'Must be a valid URL starting with http.' });\n }\n }\n }\n }\n }\n }\n }\n }\n\n return errors;\n}\n"],"mappings":"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","names":["sql","sql","pino","logger","logger","import_mongodb","import_node_events","pg","sql","mysql","sql","Database","path","sql","MongoDBConnector","MSSQLConnector","import_better_sqlite3","import_node_path","path","fs","Database","sql","logger","row","result","sql","result","row","rowCount","path","UNIT_TO_MS","logger","MIN_SAMPLE_SIZE","logger","MIN_SAMPLE_SIZE","logger","logger","logger","logger","PostgresStream","MySQLStream","MongoDBStream","logger","DEFAULT_MAX_EVENTS","logger"]}
|
|
1
|
+
{"version":3,"sources":["../node_modules/tsup/assets/cjs_shims.js","../src/connectors/mongodb.ts","../src/connectors/mssql.ts","../src/core/logger.ts","../src/behavioral/streams/types.ts","../src/behavioral/streams/postgres-stream.ts","../src/behavioral/streams/mysql-stream.ts","../src/behavioral/streams/mongodb-stream.ts","../src/index.ts","../src/core/connection.ts","../src/connectors/postgres.ts","../src/connectors/mysql.ts","../src/connectors/sqlite.ts","../src/core/storage.ts","../src/llm/factory.ts","../src/llm/openai-compatible.ts","../src/core/errors.ts","../src/llm/retry.ts","../src/llm/anthropic.ts","../src/schema/introspector.ts","../src/schema/classifier.ts","../src/schema/graph-builder.ts","../src/behavioral/watcher.ts","../src/behavioral/change-detector.ts","../src/behavioral/event-classifier.ts","../src/behavioral/pattern-engine.ts","../src/behavioral/capability-detector.ts","../src/reasoning/transition-tracker.ts","../src/reasoning/types.ts","../src/analytics/analytics-engine.ts","../src/analytics/correlator.ts","../src/analytics/types.ts","../src/analytics/distribution-tracker.ts","../src/knowledge/graph-store.ts","../src/knowledge/graph-populator.ts","../src/actions/action-registry.ts","../src/actions/action-matcher.ts","../src/actions/action-executor.ts","../src/knowledge/traversal.ts","../src/knowledge/entity-intelligence.ts","../src/knowledge/export.ts","../src/notifications/notifier.ts","../src/notifications/formatters.ts","../src/explain/explainer.ts","../src/explain/context-builder.ts","../src/ask/asker.ts","../src/ask/ask-context-builder.ts","../src/core/config.ts","../src/core/validate-config.ts","../src/server/index.ts","../src/server/server.ts","../src/server/router.ts","../src/server/handlers.ts"],"sourcesContent":["// Shim globals in cjs bundle\n// There's a weird bug that esbuild will always inject importMetaUrl\n// if we export it as `const importMetaUrl = ... __filename ...`\n// But using a function will not cause this issue\n\nconst getImportMetaUrl = () => \n typeof document === \"undefined\" \n ? new URL(`file:${__filename}`).href \n : (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT') \n ? document.currentScript.src \n : new URL(\"main.js\", document.baseURI).href;\n\nexport const importMetaUrl = /* @__PURE__ */ getImportMetaUrl()\n","import { MongoClient, type Db, type Document } from 'mongodb';\nimport type { ConnectionConfig } from '../core/config.js';\nimport type { DatabaseConnector, QueryResult } from './types.js';\n\nexport class MongoDBConnector implements DatabaseConnector {\n private client: MongoClient | null = null;\n private db: Db | null = null;\n private dbName: string = '';\n\n async connect(config: ConnectionConfig): Promise<void> {\n const url = config.url ?? `mongodb://${config.host ?? 'localhost'}:${config.port ?? 27017}`;\n this.dbName = config.database ?? 'test';\n this.client = new MongoClient(url);\n await this.client.connect();\n this.db = this.client.db(this.dbName);\n }\n\n async disconnect(): Promise<void> {\n if (this.client) {\n await this.client.close();\n this.client = null;\n this.db = null;\n }\n }\n\n async getTableCount(): Promise<number> {\n this.ensureConnected();\n const collections = await this.db!.listCollections().toArray();\n return collections.length;\n }\n\n async getDatabaseName(): Promise<string> {\n return this.dbName;\n }\n\n async isReadOnly(): Promise<boolean> {\n // Cortexa never writes to the target database\n return true;\n }\n\n isConnected(): boolean {\n return this.client !== null && this.db !== null;\n }\n\n /**\n * Bridge between SQL-shaped interface and MongoDB's native API.\n * Uses a command protocol for MongoDB operations:\n * - \"COLLECTIONS\" → listCollections\n * - \"SAMPLE:collection:N\" → aggregate $sample\n * - \"COUNT:collection\" → countDocuments\n * - \"INDEXES:collection\" → collection.indexes()\n * - \"FIELDS:collection:N\" → sample N docs and union field names\n * - \"COMMAND:{...}\" → run admin command (e.g. replSetGetStatus)\n */\n async query(sql: string, _params?: unknown[]): Promise<QueryResult> {\n this.ensureConnected();\n\n const trimmed = sql.trim();\n\n if (trimmed === 'COLLECTIONS') {\n const collections = await this.db!.listCollections().toArray();\n const rows = collections.map((c) => ({\n table_name: c.name,\n table_schema: this.dbName,\n }));\n return { rows, rowCount: rows.length };\n }\n\n if (trimmed.startsWith('SAMPLE:')) {\n const parts = trimmed.split(':');\n const collectionName = parts[1];\n const limit = parseInt(parts[2] ?? '5', 10);\n const docs = await this.db!.collection(collectionName)\n .aggregate<Document>([{ $sample: { size: limit } }])\n .toArray();\n const rows = docs.map((d) => this.flattenDocument(d));\n return { rows, rowCount: rows.length };\n }\n\n if (trimmed.startsWith('COUNT:')) {\n const collectionName = trimmed.slice(6);\n const count = await this.db!.collection(collectionName).countDocuments();\n return { rows: [{ count }], rowCount: 1 };\n }\n\n if (trimmed.startsWith('INDEXES:')) {\n const collectionName = trimmed.slice(8);\n const indexes = await this.db!.collection(collectionName).indexes();\n const rows = indexes.map((idx) => ({\n index_name: idx.name ?? 'unknown',\n columns: Object.keys(idx.key),\n is_unique: idx.unique ?? false,\n }));\n return { rows: rows as unknown as Record<string, unknown>[], rowCount: rows.length };\n }\n\n if (trimmed.startsWith('FIELDS:')) {\n const parts = trimmed.split(':');\n const collectionName = parts[1];\n const sampleSize = parseInt(parts[2] ?? '20', 10);\n const docs = await this.db!.collection(collectionName)\n .aggregate<Document>([{ $sample: { size: sampleSize } }])\n .toArray();\n const fieldMap = new Map<string, string>();\n for (const doc of docs) {\n this.extractFields(doc, '', fieldMap);\n }\n const rows = Array.from(fieldMap.entries()).map(([name, type]) => ({\n column_name: name,\n data_type: type,\n is_nullable: 'YES',\n column_default: null,\n }));\n return { rows, rowCount: rows.length };\n }\n\n if (trimmed.startsWith('COMMAND:')) {\n const cmdJson = trimmed.slice(8);\n const cmd = JSON.parse(cmdJson) as Document;\n const result = await this.db!.admin().command(cmd);\n return { rows: [result as Record<string, unknown>], rowCount: 1 };\n }\n\n throw new Error(`MongoDB connector does not support raw SQL. Use command protocol (COLLECTIONS, SAMPLE:name:N, COUNT:name, INDEXES:name, FIELDS:name:N, COMMAND:{...}).`);\n }\n\n private ensureConnected(): void {\n if (!this.db) {\n throw new Error('Not connected. Call connect() first.');\n }\n }\n\n private flattenDocument(doc: Document): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(doc)) {\n if (key === '_id') {\n result[key] = String(value);\n } else {\n result[key] = value;\n }\n }\n return result;\n }\n\n private extractFields(doc: Document, prefix: string, fieldMap: Map<string, string>): void {\n for (const [key, value] of Object.entries(doc)) {\n const fullKey = prefix ? `${prefix}.${key}` : key;\n const bsonType = this.inferBsonType(value);\n if (!fieldMap.has(fullKey)) {\n fieldMap.set(fullKey, bsonType);\n }\n }\n }\n\n private inferBsonType(value: unknown): string {\n if (value === null || value === undefined) return 'null';\n if (typeof value === 'string') return 'string';\n if (typeof value === 'number') return Number.isInteger(value) ? 'int' : 'double';\n if (typeof value === 'boolean') return 'bool';\n if (value instanceof Date) return 'date';\n if (Array.isArray(value)) return 'array';\n if (typeof value === 'object') return 'object';\n return 'unknown';\n }\n}\n","import sql from 'mssql';\nimport type { ConnectionConfig } from '../core/config.js';\nimport type { DatabaseConnector, QueryResult } from './types.js';\n\nexport class MSSQLConnector implements DatabaseConnector {\n private pool: sql.ConnectionPool | null = null;\n\n async connect(config: ConnectionConfig): Promise<void> {\n if (config.url) {\n this.pool = await sql.connect(config.url);\n } else {\n this.pool = await sql.connect({\n server: config.host ?? 'localhost',\n port: config.port ?? 1433,\n database: config.database,\n user: config.user,\n password: config.password,\n options: {\n encrypt: false,\n trustServerCertificate: true,\n },\n });\n }\n }\n\n async disconnect(): Promise<void> {\n if (this.pool) {\n await this.pool.close();\n this.pool = null;\n }\n }\n\n async getTableCount(): Promise<number> {\n this.ensureConnected();\n const result = await this.pool!.request().query(\n `SELECT COUNT(*) AS count FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE'`\n );\n return result.recordset[0]?.count ?? 0;\n }\n\n async getDatabaseName(): Promise<string> {\n this.ensureConnected();\n const result = await this.pool!.request().query('SELECT DB_NAME() AS db_name');\n return result.recordset[0]?.db_name ?? '';\n }\n\n async isReadOnly(): Promise<boolean> {\n this.ensureConnected();\n try {\n await this.pool!.request().query('CREATE TABLE #_cortexa_ro_test (id INT); DROP TABLE #_cortexa_ro_test;');\n return false;\n } catch {\n return true;\n }\n }\n\n isConnected(): boolean {\n return this.pool !== null && this.pool.connected;\n }\n\n async query(sqlText: string, params?: unknown[]): Promise<QueryResult> {\n this.ensureConnected();\n\n const request = this.pool!.request();\n\n // Convert $1, $2 style params to @p1, @p2\n let convertedSql = sqlText;\n if (params && params.length > 0) {\n convertedSql = sqlText.replace(/\\$(\\d+)/g, (_match, num) => `@p${num}`);\n for (let i = 0; i < params.length; i++) {\n request.input(`p${i + 1}`, params[i]);\n }\n }\n\n const result = await request.query(convertedSql);\n return {\n rows: result.recordset as Record<string, unknown>[] ?? [],\n rowCount: result.rowsAffected?.[0] ?? result.recordset?.length ?? 0,\n };\n }\n\n private ensureConnected(): void {\n if (!this.pool) {\n throw new Error('Not connected. Call connect() first.');\n }\n }\n}\n","import pino from 'pino';\n\nexport interface LoggerOptions {\n name?: string;\n level?: string;\n}\n\nexport function createLogger(options: LoggerOptions = {}): pino.Logger {\n return pino({\n name: options.name ?? 'cortexa',\n level: options.level ?? 'info',\n });\n}\n","import type { RawChange } from '../types.js';\n\nexport interface ReconnectOptions {\n maxAttempts?: number;\n initialDelayMs?: number;\n maxDelayMs?: number;\n}\n\nexport interface ChangeStream {\n start(onChange: (change: RawChange) => void): Promise<void>;\n stop(): Promise<void>;\n isRunning(): boolean;\n cleanup(): Promise<void>;\n}\n\nconst DEFAULT_MAX_ATTEMPTS = 5;\nconst DEFAULT_INITIAL_DELAY_MS = 1000;\nconst DEFAULT_MAX_DELAY_MS = 60000;\n\nexport function resolveReconnectOptions(options?: ReconnectOptions): Required<ReconnectOptions> {\n return {\n maxAttempts: options?.maxAttempts ?? DEFAULT_MAX_ATTEMPTS,\n initialDelayMs: options?.initialDelayMs ?? DEFAULT_INITIAL_DELAY_MS,\n maxDelayMs: options?.maxDelayMs ?? DEFAULT_MAX_DELAY_MS,\n };\n}\n\nexport function computeBackoff(attempt: number, opts: Required<ReconnectOptions>): number {\n const delay = opts.initialDelayMs * Math.pow(2, attempt);\n return Math.min(delay, opts.maxDelayMs);\n}\n","import type { ConnectionConfig } from '../../core/config.js';\nimport type { DatabaseConnector } from '../../connectors/types.js';\nimport type { RawChange } from '../types.js';\nimport type { ChangeStream, ReconnectOptions } from './types.js';\nimport { resolveReconnectOptions, computeBackoff } from './types.js';\nimport { createLogger } from '../../core/logger.js';\n\ninterface WalRelation {\n schema: string;\n name: string;\n columns: Array<{ name: string; typeOid: number; flags: number; typeMod: number }>;\n}\n\ninterface WalInsertEvent {\n tag: 'insert';\n relation: WalRelation;\n new: Record<string, unknown>;\n}\n\ninterface WalUpdateEvent {\n tag: 'update';\n relation: WalRelation;\n old?: Record<string, unknown>;\n new: Record<string, unknown>;\n}\n\ninterface WalDeleteEvent {\n tag: 'delete';\n relation: WalRelation;\n old: Record<string, unknown>;\n}\n\ntype WalEvent = WalInsertEvent | WalUpdateEvent | WalDeleteEvent;\n\nconst logger = createLogger({ name: 'postgres-stream' });\n\nexport class PostgresStream implements ChangeStream {\n private readonly connectionConfig: ConnectionConfig;\n private readonly connector: DatabaseConnector;\n private running: boolean;\n private service: { subscribe: (plugin: unknown, slotName: string) => Promise<void>; stop: () => Promise<void>; on: (event: string, listener: (...args: unknown[]) => void) => void; removeAllListeners: () => void } | null;\n private slotName: string;\n private reconnectOpts: Required<ReconnectOptions>;\n private reconnectAttempts: number;\n private lastOnChange: ((change: RawChange) => void) | null;\n\n constructor(connectionConfig: ConnectionConfig, connector: DatabaseConnector, reconnect?: ReconnectOptions) {\n this.connectionConfig = connectionConfig;\n this.connector = connector;\n this.running = false;\n this.service = null;\n this.slotName = '';\n this.reconnectOpts = resolveReconnectOptions(reconnect);\n this.reconnectAttempts = 0;\n this.lastOnChange = null;\n }\n\n async start(onChange: (change: RawChange) => void): Promise<void> {\n this.lastOnChange = onChange;\n this.reconnectAttempts = 0;\n await this.connectStream(onChange);\n }\n\n private async connectStream(onChange: (change: RawChange) => void): Promise<void> {\n const { LogicalReplicationService, PgoutputPlugin } = await import('pg-logical-replication');\n\n const dbName = await this.connector.getDatabaseName();\n this.slotName = `metis_${dbName.replace(/[^a-z0-9_]/gi, '_')}`;\n\n await this.ensureReplicationSlot();\n await this.ensurePublication();\n\n const connectionOptions = this.buildConnectionOptions();\n\n const service = new LogicalReplicationService(connectionOptions, {\n acknowledge: { auto: true, timeoutSeconds: 10 },\n }) as unknown as typeof this.service;\n\n if (!service) {\n throw new Error('Failed to create LogicalReplicationService');\n }\n\n this.service = service;\n\n const plugin = new PgoutputPlugin({\n protoVersion: 1,\n publicationNames: ['metis_pub'],\n });\n\n this.service.on('data', (lsn: unknown, log: unknown) => {\n const event = log as WalEvent;\n try {\n let change: RawChange | undefined;\n if (event.tag === 'insert') {\n change = this.mapWalInsert(event as WalInsertEvent);\n } else if (event.tag === 'update') {\n change = this.mapWalUpdate(event as WalUpdateEvent);\n } else if (event.tag === 'delete') {\n change = this.mapWalDelete(event as WalDeleteEvent);\n }\n\n if (change) {\n this.reconnectAttempts = 0; // Reset on successful data\n onChange(change);\n }\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n logger.error({ err: message, lsn }, 'Failed to process WAL event');\n }\n });\n\n this.service.on('error', (err: unknown) => {\n const message = err instanceof Error ? err.message : String(err);\n logger.error({ err: message }, 'Replication stream error');\n this.attemptReconnect();\n });\n\n this.service.subscribe(plugin, this.slotName).catch((err: unknown) => {\n const message = err instanceof Error ? err.message : String(err);\n logger.error({ err: message }, 'Replication subscribe failed');\n });\n\n this.running = true;\n logger.info({ slotName: this.slotName }, 'PostgreSQL WAL stream started');\n }\n\n private attemptReconnect(): void {\n if (!this.lastOnChange || this.reconnectAttempts >= this.reconnectOpts.maxAttempts) {\n logger.error({ attempts: this.reconnectAttempts }, 'Max reconnection attempts reached, stream stopped');\n this.running = false;\n return;\n }\n\n const delay = computeBackoff(this.reconnectAttempts, this.reconnectOpts);\n this.reconnectAttempts++;\n logger.info({ attempt: this.reconnectAttempts, delayMs: delay }, 'Reconnecting WAL stream');\n\n setTimeout(() => {\n if (!this.lastOnChange) return;\n this.connectStream(this.lastOnChange).catch((err: unknown) => {\n const message = err instanceof Error ? err.message : String(err);\n logger.error({ err: message }, 'Reconnection failed');\n this.attemptReconnect();\n });\n }, delay);\n }\n\n async stop(): Promise<void> {\n if (this.service) {\n await this.service.stop();\n this.service.removeAllListeners();\n this.service = null;\n }\n this.running = false;\n logger.info('PostgreSQL WAL stream stopped');\n }\n\n async cleanup(): Promise<void> {\n await this.stop();\n\n if (this.slotName) {\n try {\n await this.connector.query(\n 'SELECT pg_drop_replication_slot($1)',\n [this.slotName]\n );\n logger.info({ slotName: this.slotName }, 'Replication slot dropped');\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n logger.error({ err: message, slotName: this.slotName }, 'Failed to drop replication slot');\n }\n }\n }\n\n isRunning(): boolean {\n return this.running;\n }\n\n mapWalInsert(event: WalInsertEvent): RawChange {\n const primaryKey = this.extractPrimaryKey(event.relation, event.new);\n\n return {\n tableName: event.relation.name,\n tableSchema: event.relation.schema,\n operation: 'INSERT',\n primaryKey,\n newData: event.new as Record<string, unknown>,\n detectedAt: new Date(),\n };\n }\n\n mapWalUpdate(event: WalUpdateEvent): RawChange {\n const primaryKey = this.extractPrimaryKey(event.relation, event.new);\n const changedColumns = this.computeChangedColumns(event.old, event.new);\n\n return {\n tableName: event.relation.name,\n tableSchema: event.relation.schema,\n operation: 'UPDATE',\n primaryKey,\n newData: event.new as Record<string, unknown>,\n oldData: event.old as Record<string, unknown> | undefined,\n changedColumns,\n detectedAt: new Date(),\n };\n }\n\n mapWalDelete(event: WalDeleteEvent): RawChange {\n const primaryKey = this.extractPrimaryKey(event.relation, event.old);\n\n return {\n tableName: event.relation.name,\n tableSchema: event.relation.schema,\n operation: 'DELETE',\n primaryKey,\n oldData: event.old as Record<string, unknown>,\n detectedAt: new Date(),\n };\n }\n\n private extractPrimaryKey(\n relation: WalRelation,\n data: Record<string, unknown>\n ): string | number {\n const pkColumn = relation.columns.find((col) => (col.flags & 1) !== 0);\n\n if (pkColumn) {\n const value = data[pkColumn.name];\n if (typeof value === 'number' || typeof value === 'string') {\n return value;\n }\n return String(value);\n }\n\n if (data.id !== undefined) {\n const id = data.id;\n if (typeof id === 'number' || typeof id === 'string') {\n return id;\n }\n return String(id);\n }\n\n return 'unknown';\n }\n\n private computeChangedColumns(\n oldData: Record<string, unknown> | undefined,\n newData: Record<string, unknown>\n ): string[] {\n if (!oldData) {\n return Object.keys(newData);\n }\n\n const changed: string[] = [];\n for (const key of Object.keys(newData)) {\n if (oldData[key] !== newData[key]) {\n changed.push(key);\n }\n }\n return changed;\n }\n\n private async ensureReplicationSlot(): Promise<void> {\n const result = await this.connector.query(\n \"SELECT slot_name FROM pg_replication_slots WHERE slot_name = $1\",\n [this.slotName]\n );\n\n if (result.rowCount === 0) {\n await this.connector.query(\n \"SELECT pg_create_logical_replication_slot($1, 'pgoutput')\",\n [this.slotName]\n );\n logger.info({ slotName: this.slotName }, 'Created replication slot');\n }\n }\n\n private async ensurePublication(): Promise<void> {\n const result = await this.connector.query(\n \"SELECT pubname FROM pg_publication WHERE pubname = 'metis_pub'\"\n );\n\n if (result.rowCount === 0) {\n await this.connector.query(\n 'CREATE PUBLICATION metis_pub FOR ALL TABLES'\n );\n logger.info('Created publication metis_pub');\n }\n }\n\n private buildConnectionOptions(): Record<string, unknown> {\n if (this.connectionConfig.url) {\n return { connectionString: this.connectionConfig.url };\n }\n\n return {\n host: this.connectionConfig.host,\n port: this.connectionConfig.port,\n database: this.connectionConfig.database,\n user: this.connectionConfig.user,\n password: this.connectionConfig.password,\n };\n }\n}\n","import type { ConnectionConfig } from '../../core/config.js';\nimport type { DatabaseConnector } from '../../connectors/types.js';\nimport type { RawChange } from '../types.js';\nimport type { ChangeStream, ReconnectOptions } from './types.js';\nimport { resolveReconnectOptions, computeBackoff } from './types.js';\nimport type { ZongjiOptions } from '@powersync/mysql-zongji';\nimport { createLogger } from '../../core/logger.js';\n\nexport interface BinlogTableInfo {\n parentSchema: string;\n tableName: string;\n columns: Array<{ name: string }>;\n}\n\nexport interface BinlogEvent {\n tableMap: Record<number, BinlogTableInfo>;\n tableId: number;\n rows: Array<Record<string, unknown>>;\n}\n\nexport type BinlogEventType = 'writerows' | 'updaterows' | 'deleterows';\n\nconst logger = createLogger({ name: 'mysql-stream' });\n\nexport class MySQLStream implements ChangeStream {\n private readonly connectionConfig: ConnectionConfig;\n private readonly connector: DatabaseConnector;\n private running: boolean;\n private zongji: import('@powersync/mysql-zongji').ZongJi | null;\n private reconnectOpts: Required<ReconnectOptions>;\n private reconnectAttempts: number;\n private lastOnChange: ((change: RawChange) => void) | null;\n\n constructor(connectionConfig: ConnectionConfig, connector: DatabaseConnector, reconnect?: ReconnectOptions) {\n this.connectionConfig = connectionConfig;\n this.connector = connector;\n this.running = false;\n this.zongji = null;\n this.reconnectOpts = resolveReconnectOptions(reconnect);\n this.reconnectAttempts = 0;\n this.lastOnChange = null;\n }\n\n async start(onChange: (change: RawChange) => void): Promise<void> {\n this.lastOnChange = onChange;\n this.reconnectAttempts = 0;\n await this.connectStream(onChange);\n }\n\n private async connectStream(onChange: (change: RawChange) => void): Promise<void> {\n const { ZongJi } = await import('@powersync/mysql-zongji');\n\n const connectionOptions = this.buildConnectionOptions();\n\n const zongji = new ZongJi(connectionOptions);\n\n this.zongji = zongji;\n\n this.zongji.on('binlog', (event: unknown) => {\n try {\n const binlogEvent = event as { getEventName: () => string } & BinlogEvent;\n const eventName = binlogEvent.getEventName().toLowerCase();\n\n if (eventName === 'writerows' || eventName === 'updaterows' || eventName === 'deleterows') {\n const changes = this.mapBinlogEvent(eventName, binlogEvent);\n for (const change of changes) {\n this.reconnectAttempts = 0;\n onChange(change);\n }\n }\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n logger.error({ err: message }, 'Failed to process binlog event');\n }\n });\n\n this.zongji.on('error', (err: unknown) => {\n const message = err instanceof Error ? err.message : String(err);\n logger.error({ err: message }, 'Binlog stream error');\n this.attemptReconnect();\n });\n\n this.zongji.start({\n serverId: Math.floor(Math.random() * 100000) + 1,\n includeEvents: ['tablemap', 'writerows', 'updaterows', 'deleterows'],\n });\n\n this.running = true;\n logger.info('MySQL binlog stream started');\n }\n\n private attemptReconnect(): void {\n if (!this.lastOnChange || this.reconnectAttempts >= this.reconnectOpts.maxAttempts) {\n logger.error({ attempts: this.reconnectAttempts }, 'Max reconnection attempts reached, stream stopped');\n this.running = false;\n return;\n }\n\n const delay = computeBackoff(this.reconnectAttempts, this.reconnectOpts);\n this.reconnectAttempts++;\n logger.info({ attempt: this.reconnectAttempts, delayMs: delay }, 'Reconnecting binlog stream');\n\n setTimeout(() => {\n if (!this.lastOnChange) return;\n this.connectStream(this.lastOnChange).catch((err: unknown) => {\n const message = err instanceof Error ? err.message : String(err);\n logger.error({ err: message }, 'Reconnection failed');\n this.attemptReconnect();\n });\n }, delay);\n }\n\n async stop(): Promise<void> {\n if (this.zongji) {\n this.zongji.stop();\n this.zongji = null;\n }\n this.running = false;\n logger.info('MySQL binlog stream stopped');\n }\n\n async cleanup(): Promise<void> {\n await this.stop();\n // MySQL has no replication slot — nothing extra to clean up\n }\n\n isRunning(): boolean {\n return this.running;\n }\n\n mapBinlogEvent(eventType: BinlogEventType, event: BinlogEvent): RawChange[] {\n const tableInfo = event.tableMap[event.tableId];\n if (!tableInfo) {\n return [];\n }\n\n const changes: RawChange[] = [];\n\n switch (eventType) {\n case 'writerows': {\n for (const row of event.rows) {\n const primaryKey = this.extractPrimaryKey(row);\n\n changes.push({\n tableName: tableInfo.tableName,\n tableSchema: tableInfo.parentSchema,\n operation: 'INSERT',\n primaryKey,\n newData: row,\n detectedAt: new Date(),\n });\n }\n break;\n }\n case 'updaterows': {\n for (const row of event.rows) {\n const updateRow = row as unknown as { before: Record<string, unknown>; after: Record<string, unknown> };\n const primaryKey = this.extractPrimaryKey(updateRow.after);\n const changedColumns = this.computeChangedColumns(updateRow.before, updateRow.after);\n\n changes.push({\n tableName: tableInfo.tableName,\n tableSchema: tableInfo.parentSchema,\n operation: 'UPDATE',\n primaryKey,\n oldData: updateRow.before,\n newData: updateRow.after,\n changedColumns,\n detectedAt: new Date(),\n });\n }\n break;\n }\n case 'deleterows': {\n for (const row of event.rows) {\n const primaryKey = this.extractPrimaryKey(row);\n\n changes.push({\n tableName: tableInfo.tableName,\n tableSchema: tableInfo.parentSchema,\n operation: 'DELETE',\n primaryKey,\n oldData: row,\n detectedAt: new Date(),\n });\n }\n break;\n }\n }\n\n return changes;\n }\n\n private extractPrimaryKey(data: Record<string, unknown>): string | number {\n if (data.id !== undefined) {\n const id = data.id;\n if (typeof id === 'number' || typeof id === 'string') {\n return id;\n }\n return String(id);\n }\n\n return 'unknown';\n }\n\n private computeChangedColumns(\n oldData: Record<string, unknown>,\n newData: Record<string, unknown>\n ): string[] {\n const changed: string[] = [];\n for (const key of Object.keys(newData)) {\n if (oldData[key] !== newData[key]) {\n changed.push(key);\n }\n }\n return changed;\n }\n\n private buildConnectionOptions(): ZongjiOptions {\n if (this.connectionConfig.url) {\n const url = new URL(this.connectionConfig.url);\n return {\n host: url.hostname,\n port: url.port ? parseInt(url.port, 10) : 3306,\n user: decodeURIComponent(url.username),\n password: decodeURIComponent(url.password),\n };\n }\n\n return {\n host: this.connectionConfig.host ?? 'localhost',\n port: this.connectionConfig.port,\n user: this.connectionConfig.user ?? '',\n password: this.connectionConfig.password ?? '',\n };\n }\n}\n","import { MongoClient, type ChangeStreamDocument, type Document } from 'mongodb';\nimport type { ConnectionConfig } from '../../core/config.js';\nimport type { RawChange } from '../types.js';\nimport type { ChangeStream as CortexaChangeStream } from './types.js';\nimport { createLogger } from '../../core/logger.js';\n\nexport class MongoDBStream implements CortexaChangeStream {\n private readonly connectionConfig: ConnectionConfig;\n private readonly logger = createLogger({ name: 'mongodb-stream' });\n private client: MongoClient | null = null;\n private changeStream: ReturnType<MongoClient['db']> extends infer D ? (D extends { watch: (...args: unknown[]) => infer W } ? W : never) : never = null as never;\n private _running = false;\n\n constructor(connectionConfig: ConnectionConfig) {\n this.connectionConfig = connectionConfig;\n }\n\n async start(onChange: (change: RawChange) => void): Promise<void> {\n const url = this.connectionConfig.url ??\n `mongodb://${this.connectionConfig.host ?? 'localhost'}:${this.connectionConfig.port ?? 27017}`;\n const dbName = this.connectionConfig.database ?? 'test';\n\n this.client = new MongoClient(url);\n await this.client.connect();\n const db = this.client.db(dbName);\n\n const stream = db.watch([], { fullDocument: 'updateLookup' });\n this._running = true;\n\n stream.on('change', (event: ChangeStreamDocument<Document>) => {\n const rawChange = this.mapChangeEvent(event);\n if (rawChange) {\n onChange(rawChange);\n }\n });\n\n stream.on('error', (err: Error) => {\n this.logger.error({ error: err.message }, 'MongoDB change stream error');\n this._running = false;\n });\n\n stream.on('close', () => {\n this._running = false;\n });\n\n // Store as unknown to avoid complex type gymnastics\n this.changeStream = stream as never;\n this.logger.info('MongoDB change stream started');\n }\n\n async stop(): Promise<void> {\n if (this.changeStream) {\n await (this.changeStream as unknown as { close: () => Promise<void> }).close();\n this.changeStream = null as never;\n }\n this._running = false;\n }\n\n isRunning(): boolean {\n return this._running;\n }\n\n async cleanup(): Promise<void> {\n await this.stop();\n if (this.client) {\n await this.client.close();\n this.client = null;\n }\n }\n\n private mapChangeEvent(event: ChangeStreamDocument<Document>): RawChange | null {\n const evt = event as unknown as Record<string, unknown>;\n const ns = evt.ns as { db: string; coll: string } | undefined;\n if (!ns) return null;\n\n let operation: 'INSERT' | 'UPDATE' | 'DELETE';\n switch (event.operationType) {\n case 'insert':\n operation = 'INSERT';\n break;\n case 'update':\n case 'replace':\n operation = 'UPDATE';\n break;\n case 'delete':\n operation = 'DELETE';\n break;\n default:\n return null;\n }\n\n const documentKey = evt.documentKey as Record<string, unknown> | undefined;\n const primaryKey = documentKey?._id ? String(documentKey._id) : 'unknown';\n\n const fullDoc = evt.fullDocument as Record<string, unknown> | undefined;\n\n return {\n tableName: ns.coll,\n tableSchema: ns.db,\n operation,\n primaryKey,\n newData: fullDoc ?? undefined,\n detectedAt: new Date(),\n };\n }\n}\n","import { EventEmitter } from 'node:events';\nimport type { CortexaConfig, ConnectionConfig } from './core/config.js';\nimport { createConnector } from './core/connection.js';\nimport { CortexaStorage } from './core/storage.js';\nimport { createLogger } from './core/logger.js';\nimport { createLLMProvider } from './llm/factory.js';\nimport { SchemaIntrospector } from './schema/introspector.js';\nimport { SchemaClassifier } from './schema/classifier.js';\nimport { GraphBuilder } from './schema/graph-builder.js';\nimport { Watcher } from './behavioral/watcher.js';\nimport type { DatabaseConnector } from './connectors/types.js';\nimport type { LLMProvider } from './llm/types.js';\nimport type { ClassifiedEntity, EntityGraph, DiscoveryResult, DiscoveryOptions, RawTable } from './schema/types.js';\nimport type { BusinessEvent, Anomaly, AnomalyType, WatchOptions } from './behavioral/types.js';\nimport type { Insight, InsightType, Severity } from './reasoning/types.js';\nimport type { CorrelationStatus, DistributionSummary } from './analytics/types.js';\nimport type { KnowledgeNode, KnowledgeEdge, EntityIntelligenceResult, GraphSummary, GraphExport, KnowledgeConfig, NodeType, EdgeType } from './knowledge/types.js';\nimport { GraphStore } from './knowledge/graph-store.js';\nimport { Traversal } from './knowledge/traversal.js';\nimport { EntityIntelligence } from './knowledge/entity-intelligence.js';\nimport { GraphPopulator } from './knowledge/graph-populator.js';\nimport { exportGraph } from './knowledge/export.js';\nimport { ActionRegistry } from './actions/action-registry.js';\nimport type { ActionContext } from './actions/types.js';\nimport { Notifier } from './notifications/notifier.js';\nimport { Explainer } from './explain/explainer.js';\nimport type { ExplainTarget, ExplainOptions, ExplainResult } from './explain/types.js';\nimport { Asker } from './ask/asker.js';\nimport type { AskOptions, AskResult } from './ask/types.js';\n\nexport { defineConfig } from './core/config.js';\nexport type { CortexaConfig, ConnectionConfig, LlmConfig } from './core/config.js';\nexport { CortexaServer } from './server/index.js';\nexport type { ServerConfig, ApiResponse } from './server/types.js';\nexport type {\n ClassifiedEntity,\n Relationship,\n EntityGraph,\n DiscoveryResult,\n DiscoveryOptions,\n RawSchema,\n} from './schema/types.js';\n\nexport type { LLMProvider } from './llm/types.js';\nexport type {\n BusinessEvent,\n Anomaly,\n AnomalyType,\n Baseline,\n WatchOptions,\n StreamCapability,\n} from './behavioral/types.js';\n\nexport type { ChangeStream } from './behavioral/streams/types.js';\n\nexport type {\n WorkflowConfig,\n StateTransition,\n TransitionStats,\n Insight,\n InsightType,\n Severity,\n ReasoningConfig,\n} from './reasoning/types.js';\n\nexport type {\n AnalyticsConfig,\n CorrelationConfig,\n DistributionConfig,\n CorrelationStatus,\n DistributionSummary,\n} from './analytics/types.js';\n\nexport type {\n NodeType,\n EdgeType,\n KnowledgeNode,\n KnowledgeEdge,\n EntityIntelligenceResult,\n KnowledgeConfig,\n GraphSummary,\n GraphExport,\n} from './knowledge/types.js';\n\nexport type {\n GovernanceLevel,\n RecommendationStatus,\n ActionContext,\n ActionHandler,\n ActionRule,\n Recommendation,\n RecommendationSummary,\n ActionsConfig,\n} from './actions/types.js';\n\nexport type {\n NotificationsConfig,\n NotificationRule,\n WebhookTarget,\n NotificationTrigger,\n NotificationFilter,\n} from './notifications/types.js';\n\nexport type {\n ExplainTarget,\n ExplainOptions,\n ExplainResult,\n Evidence,\n CausalStep,\n RecommendedAction,\n} from './explain/types.js';\n\nexport type {\n AskOptions,\n AskResult,\n SupportingSignal,\n SignalType,\n} from './ask/types.js';\n\nexport class KnowledgeGraph {\n private readonly store: GraphStore;\n private readonly traversal: Traversal;\n private readonly entityIntelligence: EntityIntelligence;\n\n constructor(store: GraphStore) {\n this.store = store;\n this.traversal = new Traversal(store);\n this.entityIntelligence = new EntityIntelligence(store);\n }\n\n causesOf(nodeId: number, maxDepth?: number): KnowledgeNode[] {\n return this.traversal.causesOf(nodeId, maxDepth);\n }\n\n impactOf(nodeId: number, maxDepth?: number): KnowledgeNode[] {\n return this.traversal.impactOf(nodeId, maxDepth);\n }\n\n timeline(nodeId: number): KnowledgeNode[] {\n return this.traversal.timeline(nodeId);\n }\n\n entity(refId: string): { intelligence: () => EntityIntelligenceResult | undefined } {\n return {\n intelligence: () => this.entityIntelligence.forEntity(refId),\n };\n }\n\n getNode(id: number): KnowledgeNode | undefined {\n return this.store.getNode(id);\n }\n\n getNodeByRef(nodeType: NodeType, refId: string): KnowledgeNode | undefined {\n return this.store.getNodeByRef(nodeType, refId);\n }\n\n getEdges(nodeId: number, edgeType?: EdgeType): KnowledgeEdge[] {\n return this.store.getEdgesFrom(nodeId, edgeType);\n }\n\n neighbors(nodeId: number): KnowledgeNode[] {\n return this.store.neighbors(nodeId);\n }\n\n getSummary(): GraphSummary {\n return this.store.getSummary();\n }\n\n export(rootNodeId?: number): GraphExport {\n return exportGraph(this.store, rootNodeId);\n }\n}\n\nexport interface CortexaOptions extends CortexaConfig {\n projectRoot?: string;\n llmProvider?: LLMProvider;\n}\n\nexport interface CortexaStatus {\n connected: boolean;\n tables: number;\n db: string;\n watching: boolean;\n}\n\nexport class Cortexa extends EventEmitter {\n private readonly config: CortexaOptions;\n private connector: DatabaseConnector | null = null;\n private storage: CortexaStorage;\n private readonly logger: ReturnType<typeof createLogger>;\n private llmProvider: LLMProvider | null = null;\n private watcher: Watcher | null = null;\n private knowledgeGraph: KnowledgeGraph | null = null;\n private actionRegistry: ActionRegistry;\n private discoveredTables: RawTable[] = [];\n private _status: CortexaStatus = { connected: false, tables: 0, db: '', watching: false };\n\n constructor(config: CortexaOptions) {\n super();\n this.config = config;\n this.logger = createLogger();\n this.storage = new CortexaStorage(config.projectRoot ?? process.cwd());\n this.actionRegistry = new ActionRegistry(config.actions?.governance);\n }\n\n async connect(): Promise<void> {\n this.logger.info('Connecting to database...');\n\n this.storage.initialize();\n\n this.connector = await createConnector(this.config.connection.type);\n await this.connector.connect(this.config.connection);\n\n const tables = await this.connector.getTableCount();\n const db = await this.connector.getDatabaseName();\n\n const readOnly = await this.connector.isReadOnly();\n if (!readOnly) {\n this.logger.warn(\n 'Connection is NOT read-only. Cortexa recommends using a read-only database user.'\n );\n }\n\n if (this.config.llmProvider) {\n this.llmProvider = this.config.llmProvider;\n } else if (this.config.llm) {\n this.llmProvider = createLLMProvider(this.config.llm);\n }\n\n this.storage.setMeta('database_name', db);\n this.storage.setMeta('table_count', String(tables));\n this.storage.setMeta('connected_at', new Date().toISOString());\n\n this._status = { connected: true, tables, db, watching: false };\n this.logger.info({ db, tables }, 'Connected successfully');\n }\n\n async disconnect(): Promise<void> {\n this.unwatch();\n if (this.connector) {\n await this.connector.disconnect();\n this.connector = null;\n }\n this.llmProvider = null;\n this.knowledgeGraph = null;\n this.storage.close();\n this._status = { connected: false, tables: 0, db: '', watching: false };\n this.logger.info('Disconnected');\n }\n\n async discover(options?: DiscoveryOptions): Promise<DiscoveryResult> {\n if (!this.llmProvider) {\n throw new Error('LLM configuration required for schema discovery. Add llm config to your Cortexa options.');\n }\n if (!this.connector) {\n throw new Error('Not connected. Call connect() first.');\n }\n\n this.logger.info('Starting schema discovery...');\n\n const introspector = new SchemaIntrospector(this.connector, this.config.connection.type, options);\n const rawSchema = await introspector.introspect();\n this.logger.info({ tables: rawSchema.tables.length }, 'Schema introspected');\n\n const classifier = new SchemaClassifier(this.llmProvider, this.config.batchSize);\n const entities = await classifier.classify(rawSchema.tables);\n this.logger.info({ entities: entities.length }, 'Entities classified');\n\n const graphBuilder = new GraphBuilder();\n const graph = graphBuilder.build(rawSchema.tables, entities);\n\n // Persist to storage\n for (const entity of entities) {\n this.storage.saveEntity(entity);\n }\n this.storage.clearRelationships();\n for (const rel of graph.relationships) {\n this.storage.saveRelationship(rel);\n }\n for (const table of rawSchema.tables) {\n this.storage.saveDiscoveredTable(table);\n }\n\n this.discoveredTables = rawSchema.tables;\n\n // Populate knowledge graph if enabled\n if (this.config.knowledge?.enabled) {\n const graphStore = new GraphStore(this.storage);\n const populator = new GraphPopulator(graphStore);\n populator.populateFromSchema(rawSchema.tables);\n this.logger.info('Knowledge graph populated from schema');\n }\n\n this.logger.info('Discovery complete');\n\n return {\n entities: graph.entities,\n relationships: graph.relationships,\n raw: rawSchema,\n };\n }\n\n entity(tableName: string): ClassifiedEntity | undefined {\n return this.storage.getEntity(tableName);\n }\n\n exportGraph(): EntityGraph {\n return {\n entities: this.storage.getEntities(),\n relationships: this.storage.getRelationships(),\n };\n }\n\n async watch(options?: WatchOptions): Promise<void> {\n if (!this.connector) {\n throw new Error('Not connected. Call connect() first.');\n }\n\n this.watcher = new Watcher({\n connector: this.connector,\n dbType: this.config.connection.type,\n storage: this.storage,\n tables: this.discoveredTables,\n connectionConfig: this.config.connection,\n onEvent: (event: BusinessEvent) => this.emit('event', event),\n onAnomaly: (anomaly: Anomaly) => this.emit('anomaly', anomaly),\n onInsight: (insight: Insight) => this.emit('insight', insight),\n onRecommendation: (rec: Record<string, unknown>) => this.emit('recommendation', rec),\n onActionExecuted: (rec: Record<string, unknown>) => this.emit('action:executed', rec),\n onActionFailed: (rec: Record<string, unknown>) => this.emit('action:failed', rec),\n workflows: this.config.reasoning?.workflows,\n analytics: this.config.analytics,\n knowledge: this.config.knowledge,\n actions: this.config.actions,\n actionRegistry: this.actionRegistry,\n });\n\n // Hook up notifications if configured\n if (this.config.notifications?.enabled && this.config.notifications.rules?.length) {\n const notifier = new Notifier(this.config.notifications.rules);\n this.on('anomaly', (data) => notifier.notify('anomaly', data as Record<string, unknown>));\n this.on('insight', (data) => notifier.notify('insight', data as Record<string, unknown>));\n this.on('recommendation', (data) => notifier.notify('recommendation', data as Record<string, unknown>));\n this.on('action:executed', (data) => notifier.notify('action:executed', data as Record<string, unknown>));\n this.on('action:failed', (data) => notifier.notify('action:failed', data as Record<string, unknown>));\n }\n\n await this.watcher.start(options);\n\n if (options?.once) {\n this.watcher = null;\n this.logger.info('Single poll cycle complete');\n return;\n }\n\n this._status = { ...this._status, watching: true };\n this.logger.info('Watcher started');\n }\n\n unwatch(): void {\n if (this.watcher) {\n this.watcher.stop();\n this.watcher = null;\n this._status = { ...this._status, watching: false };\n this.logger.info('Watcher stopped');\n }\n }\n\n async cleanupStream(): Promise<void> {\n if (this.watcher) {\n await this.watcher.cleanup();\n this.watcher = null;\n this._status = { ...this._status, watching: false };\n this.logger.info('Stream cleaned up');\n }\n }\n\n getEvents(filter?: { entity?: string; last?: number; operation?: 'INSERT' | 'UPDATE' | 'DELETE'; eventType?: string }): Array<{ id: number; eventType: string; entity: string; tableName: string; operation: 'INSERT' | 'UPDATE' | 'DELETE'; rowId: string | null; rowData: string | null; timestamp: string }> {\n return this.storage.getEvents(filter) as Array<{ id: number; eventType: string; entity: string; tableName: string; operation: 'INSERT' | 'UPDATE' | 'DELETE'; rowId: string | null; rowData: string | null; timestamp: string }>;\n }\n\n getBaselines(): Array<{ entity: string; metric: string; mean: number; stddev: number; sampleSize: number }> {\n return this.storage.getBaselines();\n }\n\n getAnomalies(filter?: { last?: number; entity?: string; severity?: Severity; anomalyType?: AnomalyType }): Array<{ id: number; entity: string; anomalyType: AnomalyType; severity: Severity; expected: number; actual: number; message: string; timestamp: string }> {\n return this.storage.getAnomalies(filter) as Array<{ id: number; entity: string; anomalyType: AnomalyType; severity: Severity; expected: number; actual: number; message: string; timestamp: string }>;\n }\n\n getInsights(filter?: { entity?: string; last?: number; insightType?: InsightType; severity?: Severity }): Array<{ id: number; entity: string; insightType: InsightType; severity: Severity; message: string; context: Record<string, unknown>; timestamp: string }> {\n return this.storage.getInsights(filter) as Array<{ id: number; entity: string; insightType: InsightType; severity: Severity; message: string; context: Record<string, unknown>; timestamp: string }>;\n }\n\n getTransitions(entity?: string): Array<{ entity: string; fromState: string; toState: string; count: number; avgDurationMs: number; minDurationMs: number; maxDurationMs: number }> {\n return this.storage.getTransitionStats(entity);\n }\n\n getCorrelations(): CorrelationStatus[] {\n if (!this.config.analytics?.correlations) {\n return [];\n }\n\n const results: CorrelationStatus[] = [];\n\n for (const [name, corrConfig] of Object.entries(this.config.analytics.correlations)) {\n const rateBaseline = this.storage.getAnalyticsBaseline(`correlation:${name}:rate_ratio`);\n const coOccBaseline = this.storage.getAnalyticsBaseline(`correlation:${name}:co_occurrence`);\n\n const rateRatio = rateBaseline ? rateBaseline.mean : 0;\n const coOccurrenceRate = coOccBaseline ? coOccBaseline.mean : 0;\n\n const healthy = !!(rateBaseline && coOccBaseline);\n\n results.push({\n name,\n entities: corrConfig.entities,\n rateRatio,\n baselineRatio: rateBaseline ? rateBaseline.mean : 0,\n coOccurrenceRate,\n baselineCoOccurrence: coOccBaseline ? coOccBaseline.mean : 0,\n healthy,\n });\n }\n\n return results;\n }\n\n getDistributions(entity?: string): DistributionSummary[] {\n if (!this.config.analytics?.distributions) {\n return [];\n }\n\n const results: DistributionSummary[] = [];\n\n for (const [entityName, distConfig] of Object.entries(this.config.analytics.distributions)) {\n if (entity && entity !== entityName) continue;\n\n for (const col of distConfig.columns) {\n const buckets = this.storage.getHistogramBuckets(entityName, col, 'baseline');\n const shiftBaseline = this.storage.getAnalyticsBaseline(`distribution:${entityName}:${col}:shift`);\n\n results.push({\n entity: entityName,\n columnName: col,\n bucketCount: buckets.length,\n baselineSamples: shiftBaseline ? shiftBaseline.sampleSize : 0,\n currentShift: shiftBaseline ? shiftBaseline.mean : null,\n shifted: shiftBaseline ? Math.abs(shiftBaseline.mean) > shiftBaseline.stddev * 2 : false,\n });\n }\n }\n\n return results;\n }\n\n graph(): KnowledgeGraph {\n if (!this.knowledgeGraph) {\n const graphStore = new GraphStore(this.storage);\n this.knowledgeGraph = new KnowledgeGraph(graphStore);\n }\n return this.knowledgeGraph;\n }\n\n async explain(target: ExplainTarget, options?: ExplainOptions): Promise<ExplainResult> {\n if (!this.llmProvider) {\n throw new Error('LLM configuration required for explain(). Add llm config to your Cortexa options.');\n }\n\n const graphStore = new GraphStore(this.storage);\n const traversal = new Traversal(graphStore);\n const explainer = new Explainer(this.llmProvider, this.storage, graphStore, traversal);\n return explainer.explain(target, options);\n }\n\n async ask(question: string, options?: AskOptions): Promise<AskResult> {\n if (!this.llmProvider) {\n throw new Error('LLM configuration required for ask(). Add llm config to your Cortexa options.');\n }\n\n const graphStore = new GraphStore(this.storage);\n const asker = new Asker(this.llmProvider, this.storage, graphStore);\n return asker.ask(question, options);\n }\n\n registerAction(name: string, handler: (context: ActionContext) => Promise<void>, description?: string): void {\n this.actionRegistry.register(name, handler, description);\n }\n\n approveRecommendation(id: number): void {\n this.storage.updateRecommendationStatus(id, 'approved', 'user');\n }\n\n rejectRecommendation(id: number): void {\n this.storage.updateRecommendationStatus(id, 'rejected', 'user');\n }\n\n getRecommendations(filter?: { status?: string; action?: string; last?: number }): Array<{ id: number; action: string; reason: string; confidence: number; status: string; governance: string; insightId: string | null; entity: string; context: string; createdAt: string; resolvedAt: string | null; resolvedBy: string | null }> {\n return this.storage.getRecommendations(filter);\n }\n\n get status(): CortexaStatus {\n return { ...this._status };\n }\n}\n","import type { ConnectionConfig } from './config.js';\nimport type { DatabaseConnector } from '../connectors/types.js';\nimport { PostgresConnector } from '../connectors/postgres.js';\nimport { MySQLConnector } from '../connectors/mysql.js';\nimport { SQLiteConnector } from '../connectors/sqlite.js';\n\nexport async function createConnector(type: ConnectionConfig['type']): Promise<DatabaseConnector> {\n switch (type) {\n case 'postgres':\n case 'cockroachdb':\n return new PostgresConnector();\n case 'mysql':\n case 'mariadb':\n return new MySQLConnector();\n case 'sqlite':\n return new SQLiteConnector();\n case 'mongodb': {\n const { MongoDBConnector } = await import('../connectors/mongodb.js');\n return new MongoDBConnector();\n }\n case 'mssql': {\n const { MSSQLConnector } = await import('../connectors/mssql.js');\n return new MSSQLConnector();\n }\n default:\n throw new Error(`Unsupported database type: ${type as string}`);\n }\n}\n","import pg from 'pg';\nimport type { ConnectionConfig } from '../core/config.js';\nimport type { DatabaseConnector, QueryResult } from './types.js';\n\nconst { Pool } = pg;\n\nexport class PostgresConnector implements DatabaseConnector {\n private pool: InstanceType<typeof Pool> | null = null;\n\n async connect(config: ConnectionConfig): Promise<void> {\n if (config.url) {\n this.pool = new Pool({ connectionString: config.url });\n } else {\n this.pool = new Pool({\n host: config.host,\n port: config.port,\n database: config.database,\n user: config.user,\n password: config.password,\n });\n }\n // Verify connectivity by acquiring and releasing a client\n const client = await this.pool.connect();\n client.release();\n }\n\n async disconnect(): Promise<void> {\n if (this.pool) {\n await this.pool.end();\n this.pool = null;\n }\n }\n\n async getTableCount(): Promise<number> {\n this.ensureConnected();\n const result = await this.pool!.query(\n `SELECT COUNT(*) as count FROM information_schema.tables\n WHERE table_schema = 'public' AND table_type = 'BASE TABLE'`\n );\n return parseInt(result.rows[0].count, 10);\n }\n\n async getDatabaseName(): Promise<string> {\n this.ensureConnected();\n const result = await this.pool!.query('SELECT current_database() as db');\n return result.rows[0].db;\n }\n\n async isReadOnly(): Promise<boolean> {\n this.ensureConnected();\n try {\n await this.pool!.query(\n 'CREATE TEMP TABLE _cortexa_ro_check (id int)'\n );\n return false;\n } catch {\n return true;\n } finally {\n try {\n await this.pool!.query(\n 'DROP TABLE IF EXISTS _cortexa_ro_check'\n );\n } catch {\n // ignore cleanup errors\n }\n }\n }\n\n async query(sql: string, params?: unknown[]): Promise<QueryResult> {\n this.ensureConnected();\n const result = await this.pool!.query(sql, params);\n return {\n rows: result.rows,\n rowCount: result.rowCount ?? result.rows.length,\n };\n }\n\n isConnected(): boolean {\n return this.pool !== null;\n }\n\n private ensureConnected(): void {\n if (!this.pool) {\n throw new Error('Not connected. Call connect() first.');\n }\n }\n}\n","import mysql from 'mysql2/promise';\nimport type { ConnectionConfig } from '../core/config.js';\nimport type { DatabaseConnector, QueryResult } from './types.js';\n\nexport class MySQLConnector implements DatabaseConnector {\n private pool: mysql.Pool | null = null;\n\n async connect(config: ConnectionConfig): Promise<void> {\n if (config.url) {\n this.pool = mysql.createPool(config.url);\n } else {\n this.pool = mysql.createPool({\n host: config.host,\n port: config.port,\n database: config.database,\n user: config.user,\n password: config.password,\n });\n }\n // Verify connectivity by acquiring and releasing a connection\n const conn = await this.pool.getConnection();\n conn.release();\n }\n\n async disconnect(): Promise<void> {\n if (this.pool) {\n await this.pool.end();\n this.pool = null;\n }\n }\n\n async getTableCount(): Promise<number> {\n this.ensureConnected();\n const [rows] = await this.pool!.query(\n `SELECT COUNT(*) as count FROM information_schema.tables\n WHERE table_schema = DATABASE() AND table_type = 'BASE TABLE'`\n );\n return (rows as Record<string, unknown>[])[0].count as number;\n }\n\n async getDatabaseName(): Promise<string> {\n this.ensureConnected();\n const [rows] = await this.pool!.query('SELECT DATABASE() as db');\n return (rows as Record<string, unknown>[])[0].db as string;\n }\n\n async isReadOnly(): Promise<boolean> {\n this.ensureConnected();\n try {\n await this.pool!.query(\n 'CREATE TEMPORARY TABLE _cortexa_ro_check (id INT)'\n );\n return false;\n } catch {\n return true;\n } finally {\n try {\n await this.pool!.query(\n 'DROP TEMPORARY TABLE IF EXISTS _cortexa_ro_check'\n );\n } catch {\n // ignore cleanup errors\n }\n }\n }\n\n async query(sql: string, params?: unknown[]): Promise<QueryResult> {\n this.ensureConnected();\n const mysqlSql = sql.replace(/\\$\\d+/g, '?');\n const [rows] = await this.pool!.query(mysqlSql, params);\n const rowArray = rows as Record<string, unknown>[];\n return {\n rows: rowArray,\n rowCount: rowArray.length,\n };\n }\n\n isConnected(): boolean {\n return this.pool !== null;\n }\n\n private ensureConnected(): void {\n if (!this.pool) {\n throw new Error('Not connected. Call connect() first.');\n }\n }\n}\n","import path from 'node:path';\nimport Database from 'better-sqlite3';\nimport type { ConnectionConfig } from '../core/config.js';\nimport type { DatabaseConnector, QueryResult } from './types.js';\n\nexport class SQLiteConnector implements DatabaseConnector {\n private db: InstanceType<typeof Database> | null = null;\n private dbPath: string = '';\n\n async connect(config: ConnectionConfig): Promise<void> {\n this.dbPath = config.path ?? config.database ?? ':memory:';\n this.db = new Database(this.dbPath, { readonly: true });\n }\n\n async disconnect(): Promise<void> {\n if (this.db) {\n this.db.close();\n this.db = null;\n }\n }\n\n async getTableCount(): Promise<number> {\n this.ensureConnected();\n const row = this.db!.prepare(\n `SELECT COUNT(*) AS count FROM sqlite_master WHERE type = 'table' AND name NOT LIKE 'sqlite_%'`\n ).get() as { count: number };\n return row.count;\n }\n\n async getDatabaseName(): Promise<string> {\n return path.basename(this.dbPath, path.extname(this.dbPath));\n }\n\n async isReadOnly(): Promise<boolean> {\n // We open in readonly mode by default for safety\n return true;\n }\n\n async query(sql: string, params?: unknown[]): Promise<QueryResult> {\n this.ensureConnected();\n // Convert $1, $2 style params to ? style for better-sqlite3\n const convertedSql = sql.replace(/\\$(\\d+)/g, '?');\n const stmt = this.db!.prepare(convertedSql);\n\n if (convertedSql.trim().toUpperCase().startsWith('SELECT') ||\n convertedSql.trim().toUpperCase().startsWith('PRAGMA')) {\n const rows = (params && params.length > 0)\n ? stmt.all(...params) as Record<string, unknown>[]\n : stmt.all() as Record<string, unknown>[];\n return { rows, rowCount: rows.length };\n }\n\n const result = (params && params.length > 0)\n ? stmt.run(...params)\n : stmt.run();\n return { rows: [], rowCount: result.changes };\n }\n\n isConnected(): boolean {\n return this.db !== null;\n }\n\n private ensureConnected(): void {\n if (!this.db) {\n throw new Error('Not connected. Call connect() first.');\n }\n }\n}\n","import Database from 'better-sqlite3';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport type { ClassifiedEntity, Relationship, RawTable } from '../schema/types.js';\n\nexport class CortexaStorage {\n private db: Database.Database | null = null;\n private readonly cortexaDir: string;\n private readonly dbPath: string;\n\n constructor(projectRoot: string) {\n this.cortexaDir = path.join(projectRoot, '.cortexa');\n this.dbPath = path.join(this.cortexaDir, 'cortexa.db');\n }\n\n initialize(): void {\n fs.mkdirSync(this.cortexaDir, { recursive: true });\n\n this.db = new Database(this.dbPath);\n this.db.pragma('journal_mode = WAL');\n\n this.createSchema();\n }\n\n setMeta(key: string, value: string): void {\n this.ensureInitialized();\n this.db!.prepare(\n 'INSERT OR REPLACE INTO meta (key, value) VALUES (?, ?)'\n ).run(key, value);\n }\n\n getMeta(key: string): string | undefined {\n this.ensureInitialized();\n const row = this.db!.prepare(\n 'SELECT value FROM meta WHERE key = ?'\n ).get(key) as { value: string } | undefined;\n return row?.value;\n }\n\n getDiscoveredTableCount(): number {\n this.ensureInitialized();\n const row = this.db!.prepare(\n 'SELECT COUNT(*) as count FROM discovered_tables'\n ).get() as { count: number };\n return row.count;\n }\n\n saveEntity(entity: ClassifiedEntity): void {\n this.ensureInitialized();\n this.db!.prepare(\n `INSERT OR REPLACE INTO entities\n (table_name, entity_label, entity_type, description, confidence, columns_classified)\n VALUES (?, ?, ?, ?, ?, ?)`\n ).run(entity.tableName, entity.entityLabel, entity.entityType, entity.description, entity.confidence, JSON.stringify(entity.columns));\n }\n\n getEntities(): ClassifiedEntity[] {\n this.ensureInitialized();\n const rows = this.db!.prepare('SELECT * FROM entities').all() as any[];\n return rows.map((row) => ({\n tableName: row.table_name,\n entityLabel: row.entity_label,\n entityType: row.entity_type,\n description: row.description,\n confidence: row.confidence,\n columns: JSON.parse(row.columns_classified || '[]'),\n }));\n }\n\n getEntity(tableName: string): ClassifiedEntity | undefined {\n this.ensureInitialized();\n const row = this.db!.prepare('SELECT * FROM entities WHERE table_name = ?').get(tableName) as any;\n if (!row) return undefined;\n return {\n tableName: row.table_name,\n entityLabel: row.entity_label,\n entityType: row.entity_type,\n description: row.description,\n confidence: row.confidence,\n columns: JSON.parse(row.columns_classified || '[]'),\n };\n }\n\n saveRelationship(rel: Relationship): void {\n this.ensureInitialized();\n this.db!.prepare(\n `INSERT OR REPLACE INTO relationships\n (source_entity, target_entity, relationship, source_column, target_column, inferred, confidence)\n VALUES (?, ?, ?, ?, ?, ?, ?)`\n ).run(rel.sourceEntity, rel.targetEntity, rel.relationship, rel.sourceColumn, rel.targetColumn, rel.inferred ? 1 : 0, rel.confidence);\n }\n\n getRelationships(): Relationship[] {\n this.ensureInitialized();\n const rows = this.db!.prepare('SELECT * FROM relationships').all() as any[];\n return rows.map((row) => ({\n sourceEntity: row.source_entity,\n targetEntity: row.target_entity,\n relationship: row.relationship,\n sourceColumn: row.source_column,\n targetColumn: row.target_column,\n inferred: row.inferred === 1,\n confidence: row.confidence,\n }));\n }\n\n clearRelationships(): void {\n this.ensureInitialized();\n this.db!.prepare('DELETE FROM relationships').run();\n }\n\n saveDiscoveredTable(table: RawTable): void {\n this.ensureInitialized();\n this.db!.prepare(\n `INSERT OR REPLACE INTO discovered_tables\n (table_name, table_schema, row_count, columns_json, fk_json, indexes_json, sample_rows)\n VALUES (?, ?, ?, ?, ?, ?, ?)`\n ).run(table.tableName, table.tableSchema, table.rowCount, JSON.stringify(table.columns), JSON.stringify(table.foreignKeys), JSON.stringify(table.indexes), JSON.stringify(table.sampleRows));\n }\n\n setCache(key: string, response: string, model: string, tokensUsed: number): void {\n this.ensureInitialized();\n this.db!.prepare(\n 'INSERT OR REPLACE INTO llm_cache (cache_key, response, model, tokens_used) VALUES (?, ?, ?, ?)'\n ).run(key, response, model, tokensUsed);\n }\n\n getCache(key: string): string | undefined {\n this.ensureInitialized();\n const row = this.db!.prepare('SELECT response FROM llm_cache WHERE cache_key = ?').get(key) as { response: string } | undefined;\n return row?.response;\n }\n\n clearCache(): void {\n this.ensureInitialized();\n this.db!.prepare('DELETE FROM llm_cache').run();\n }\n\n saveEvent(event: { eventType: string; entity: string; tableName: string; operation: string; rowId?: string; rowData?: string }): void {\n this.ensureInitialized();\n this.db!.prepare(\n 'INSERT INTO events (event_type, entity, table_name, operation, row_id, row_data) VALUES (?, ?, ?, ?, ?, ?)'\n ).run(event.eventType, event.entity, event.tableName, event.operation, event.rowId ?? null, event.rowData ?? null);\n }\n\n getEvents(filter?: { entity?: string; last?: number; operation?: string; eventType?: string }): Array<{ id: number; eventType: string; entity: string; tableName: string; operation: string; rowId: string | null; rowData: string | null; timestamp: string }> {\n this.ensureInitialized();\n let sql = 'SELECT id, event_type, entity, table_name, operation, row_id, row_data, timestamp FROM events';\n const conditions: string[] = [];\n const params: unknown[] = [];\n\n if (filter?.entity) {\n conditions.push('entity = ?');\n params.push(filter.entity);\n }\n if (filter?.last) {\n conditions.push(`timestamp >= datetime('now', '-${filter.last} minutes')`);\n }\n if (filter?.operation) {\n conditions.push('operation = ?');\n params.push(filter.operation);\n }\n if (filter?.eventType) {\n conditions.push('event_type = ?');\n params.push(filter.eventType);\n }\n if (conditions.length > 0) {\n sql += ' WHERE ' + conditions.join(' AND ');\n }\n sql += ' ORDER BY timestamp DESC';\n\n const rows = this.db!.prepare(sql).all(...params) as any[];\n return rows.map((r) => ({\n id: r.id as number,\n eventType: r.event_type,\n entity: r.entity,\n tableName: r.table_name,\n operation: r.operation,\n rowId: r.row_id,\n rowData: r.row_data,\n timestamp: r.timestamp,\n }));\n }\n\n countEvents(entity: string, operation: string, lastMinutes: number): number {\n this.ensureInitialized();\n const row = this.db!.prepare(\n `SELECT COUNT(*) as count FROM events WHERE entity = ? AND operation = ? AND timestamp >= datetime('now', '-' || ? || ' minutes')`\n ).get(entity, operation, lastMinutes) as { count: number };\n return row.count;\n }\n\n saveBaseline(baseline: { entity: string; metric: string; mean: number; stddev: number; sampleSize: number }): void {\n this.ensureInitialized();\n this.db!.prepare(\n 'INSERT OR REPLACE INTO baselines (entity, metric, mean, stddev, sample_size) VALUES (?, ?, ?, ?, ?)'\n ).run(baseline.entity, baseline.metric, baseline.mean, baseline.stddev, baseline.sampleSize);\n }\n\n getBaselines(): Array<{ entity: string; metric: string; mean: number; stddev: number; sampleSize: number }> {\n this.ensureInitialized();\n const rows = this.db!.prepare('SELECT entity, metric, mean, stddev, sample_size FROM baselines').all() as any[];\n return rows.map((r) => ({\n entity: r.entity,\n metric: r.metric,\n mean: r.mean,\n stddev: r.stddev,\n sampleSize: r.sample_size,\n }));\n }\n\n saveAnomaly(anomaly: { entity: string; anomalyType: string; severity: string; expected: number; actual: number; message: string }): void {\n this.ensureInitialized();\n this.db!.prepare(\n 'INSERT INTO anomalies (entity, anomaly_type, severity, expected, actual, message) VALUES (?, ?, ?, ?, ?, ?)'\n ).run(anomaly.entity, anomaly.anomalyType, anomaly.severity, anomaly.expected, anomaly.actual, anomaly.message);\n }\n\n getAnomalies(filter?: { last?: number; entity?: string; severity?: string; anomalyType?: string }): Array<{ id: number; entity: string; anomalyType: string; severity: string; expected: number; actual: number; message: string; timestamp: string }> {\n this.ensureInitialized();\n let sql = 'SELECT id, entity, anomaly_type, severity, expected, actual, message, timestamp FROM anomalies';\n const conditions: string[] = [];\n const params: unknown[] = [];\n\n if (filter?.last) {\n conditions.push(`timestamp >= datetime('now', '-${filter.last} minutes')`);\n }\n if (filter?.entity) {\n conditions.push('entity = ?');\n params.push(filter.entity);\n }\n if (filter?.severity) {\n conditions.push('severity = ?');\n params.push(filter.severity);\n }\n if (filter?.anomalyType) {\n conditions.push('anomaly_type = ?');\n params.push(filter.anomalyType);\n }\n if (conditions.length > 0) {\n sql += ' WHERE ' + conditions.join(' AND ');\n }\n sql += ' ORDER BY timestamp DESC';\n\n const rows = this.db!.prepare(sql).all(...params) as any[];\n return rows.map((r) => ({\n id: r.id as number,\n entity: r.entity,\n anomalyType: r.anomaly_type,\n severity: r.severity,\n expected: r.expected,\n actual: r.actual,\n message: r.message,\n timestamp: r.timestamp,\n }));\n }\n\n saveWatermark(wm: { tableName: string; tableSchema: string; strategy: string; timestampColumn?: string; pkColumn?: string; lastSeenValue?: string }): void {\n this.ensureInitialized();\n this.db!.prepare(\n 'INSERT OR REPLACE INTO watch_watermarks (table_name, table_schema, strategy, timestamp_column, pk_column, last_seen_value) VALUES (?, ?, ?, ?, ?, ?)'\n ).run(wm.tableName, wm.tableSchema, wm.strategy, wm.timestampColumn ?? null, wm.pkColumn ?? null, wm.lastSeenValue ?? null);\n }\n\n getWatermark(tableName: string, tableSchema: string): { strategy: string; timestampColumn: string | null; pkColumn: string | null; lastSeenValue: string | null } | undefined {\n this.ensureInitialized();\n const row = this.db!.prepare(\n 'SELECT strategy, timestamp_column, pk_column, last_seen_value FROM watch_watermarks WHERE table_name = ? AND table_schema = ?'\n ).get(tableName, tableSchema) as any;\n if (!row) return undefined;\n return {\n strategy: row.strategy,\n timestampColumn: row.timestamp_column,\n pkColumn: row.pk_column,\n lastSeenValue: row.last_seen_value,\n };\n }\n\n saveTransition(t: { entity: string; tableName: string; primaryKey: string; fromState: string; toState: string; durationMs: number; expected: boolean }): void {\n this.ensureInitialized();\n this.db!.prepare(\n 'INSERT INTO state_transitions (entity, table_name, primary_key, from_state, to_state, duration_ms, expected) VALUES (?, ?, ?, ?, ?, ?, ?)'\n ).run(t.entity, t.tableName, t.primaryKey, t.fromState, t.toState, t.durationMs, t.expected ? 1 : 0);\n }\n\n getTransitions(filter?: { entity?: string }): Array<{ entity: string; tableName: string; primaryKey: string; fromState: string; toState: string; durationMs: number; expected: boolean; timestamp: string }> {\n this.ensureInitialized();\n let sql = 'SELECT entity, table_name, primary_key, from_state, to_state, duration_ms, expected, timestamp FROM state_transitions';\n const params: unknown[] = [];\n\n if (filter?.entity) {\n sql += ' WHERE entity = ?';\n params.push(filter.entity);\n }\n sql += ' ORDER BY timestamp DESC';\n\n const rows = this.db!.prepare(sql).all(...params) as any[];\n return rows.map((r) => ({\n entity: r.entity,\n tableName: r.table_name,\n primaryKey: r.primary_key,\n fromState: r.from_state,\n toState: r.to_state,\n durationMs: r.duration_ms,\n expected: r.expected === 1,\n timestamp: r.timestamp,\n }));\n }\n\n getTransitionStats(entity?: string): Array<{ entity: string; fromState: string; toState: string; count: number; avgDurationMs: number; minDurationMs: number; maxDurationMs: number }> {\n this.ensureInitialized();\n let sql = 'SELECT entity, from_state, to_state, COUNT(*) as count, AVG(duration_ms) as avg_duration, MIN(duration_ms) as min_duration, MAX(duration_ms) as max_duration FROM state_transitions';\n const params: unknown[] = [];\n\n if (entity) {\n sql += ' WHERE entity = ?';\n params.push(entity);\n }\n sql += ' GROUP BY entity, from_state, to_state';\n\n const rows = this.db!.prepare(sql).all(...params) as any[];\n return rows.map((r) => ({\n entity: r.entity,\n fromState: r.from_state,\n toState: r.to_state,\n count: r.count,\n avgDurationMs: Math.round(r.avg_duration),\n minDurationMs: r.min_duration,\n maxDurationMs: r.max_duration,\n }));\n }\n\n saveInsight(i: { entity: string; insightType: string; severity: string; message: string; context: Record<string, unknown> }): void {\n this.ensureInitialized();\n this.db!.prepare(\n 'INSERT INTO insights (entity, insight_type, severity, message, context_json) VALUES (?, ?, ?, ?, ?)'\n ).run(i.entity, i.insightType, i.severity, i.message, JSON.stringify(i.context));\n }\n\n getInsights(filter?: { entity?: string; last?: number; insightType?: string; severity?: string }): Array<{ id: number; entity: string; insightType: string; severity: string; message: string; context: Record<string, unknown>; timestamp: string }> {\n this.ensureInitialized();\n let sql = 'SELECT id, entity, insight_type, severity, message, context_json, timestamp FROM insights';\n const conditions: string[] = [];\n const params: unknown[] = [];\n\n if (filter?.entity) {\n conditions.push('entity = ?');\n params.push(filter.entity);\n }\n if (filter?.last !== undefined) {\n conditions.push(\"timestamp >= datetime('now', '-' || ? || ' minutes')\");\n params.push(filter.last);\n }\n if (filter?.insightType) {\n conditions.push('insight_type = ?');\n params.push(filter.insightType);\n }\n if (filter?.severity) {\n conditions.push('severity = ?');\n params.push(filter.severity);\n }\n if (conditions.length > 0) {\n sql += ' WHERE ' + conditions.join(' AND ');\n }\n sql += ' ORDER BY timestamp DESC';\n\n const rows = this.db!.prepare(sql).all(...params) as any[];\n return rows.map((r) => ({\n id: r.id as number,\n entity: r.entity,\n insightType: r.insight_type,\n severity: r.severity,\n message: r.message,\n context: JSON.parse(r.context_json || '{}'),\n timestamp: r.timestamp,\n }));\n }\n\n getEventById(id: number): { id: number; eventType: string; entity: string; tableName: string; operation: string; rowId: string | null; rowData: string | null; timestamp: string } | undefined {\n this.ensureInitialized();\n const r = this.db!.prepare('SELECT id, event_type, entity, table_name, operation, row_id, row_data, timestamp FROM events WHERE id = ?').get(id) as any;\n if (!r) return undefined;\n return { id: r.id, eventType: r.event_type, entity: r.entity, tableName: r.table_name, operation: r.operation, rowId: r.row_id, rowData: r.row_data, timestamp: r.timestamp };\n }\n\n getAnomalyById(id: number): { id: number; entity: string; anomalyType: string; severity: string; expected: number; actual: number; message: string; timestamp: string } | undefined {\n this.ensureInitialized();\n const r = this.db!.prepare('SELECT id, entity, anomaly_type, severity, expected, actual, message, timestamp FROM anomalies WHERE id = ?').get(id) as any;\n if (!r) return undefined;\n return { id: r.id, entity: r.entity, anomalyType: r.anomaly_type, severity: r.severity, expected: r.expected, actual: r.actual, message: r.message, timestamp: r.timestamp };\n }\n\n getInsightById(id: number): { id: number; entity: string; insightType: string; severity: string; message: string; context: Record<string, unknown>; timestamp: string } | undefined {\n this.ensureInitialized();\n const r = this.db!.prepare('SELECT id, entity, insight_type, severity, message, context_json, timestamp FROM insights WHERE id = ?').get(id) as any;\n if (!r) return undefined;\n return { id: r.id, entity: r.entity, insightType: r.insight_type, severity: r.severity, message: r.message, context: JSON.parse(r.context_json || '{}'), timestamp: r.timestamp };\n }\n\n saveEntityState(s: { tableName: string; primaryKey: string; state: string; enteredAt: string }): void {\n this.ensureInitialized();\n this.db!.prepare(\n 'INSERT OR REPLACE INTO entity_states (table_name, primary_key, state, entered_at) VALUES (?, ?, ?, ?)'\n ).run(s.tableName, s.primaryKey, s.state, s.enteredAt);\n }\n\n getEntityState(tableName: string, primaryKey: string): { state: string; enteredAt: string } | undefined {\n this.ensureInitialized();\n const row = this.db!.prepare(\n 'SELECT state, entered_at FROM entity_states WHERE table_name = ? AND primary_key = ?'\n ).get(tableName, primaryKey) as any;\n if (!row) return undefined;\n return {\n state: row.state,\n enteredAt: row.entered_at,\n };\n }\n\n getStuckEntityStates(tableName: string, thresholdMs: number): Array<{ primaryKey: string; state: string; enteredAt: string }> {\n this.ensureInitialized();\n const thresholdSeconds = Math.floor(thresholdMs / 1000);\n const rows = this.db!.prepare(\n \"SELECT primary_key, state, entered_at FROM entity_states WHERE table_name = ? AND entered_at <= datetime('now', '-' || ? || ' seconds')\"\n ).all(tableName, thresholdSeconds) as any[];\n return rows.map((r) => ({\n primaryKey: r.primary_key,\n state: r.state,\n enteredAt: r.entered_at,\n }));\n }\n\n saveCorrelationEvent(event: { entity: string; eventType: string; primaryKey: string }): void {\n this.ensureInitialized();\n this.db!.prepare(\n 'INSERT INTO correlation_events (entity, event_type, primary_key) VALUES (?, ?, ?)'\n ).run(event.entity, event.eventType, event.primaryKey);\n }\n\n getCorrelationEvents(entity: string, lastMinutes: number): Array<{ entity: string; eventType: string; primaryKey: string; timestamp: string }> {\n this.ensureInitialized();\n const rows = this.db!.prepare(\n \"SELECT entity, event_type, primary_key, timestamp FROM correlation_events WHERE entity = ? AND timestamp >= datetime('now', '-' || ? || ' minutes') ORDER BY timestamp DESC\"\n ).all(entity, lastMinutes) as Array<{ entity: string; event_type: string; primary_key: string; timestamp: string }>;\n return rows.map((r) => ({\n entity: r.entity,\n eventType: r.event_type,\n primaryKey: r.primary_key,\n timestamp: r.timestamp,\n }));\n }\n\n saveCorrelationRate(rate: { entity: string; bucket: string; eventCount: number }): void {\n this.ensureInitialized();\n this.db!.prepare(\n 'INSERT OR REPLACE INTO correlation_rates (entity, bucket, event_count) VALUES (?, ?, ?)'\n ).run(rate.entity, rate.bucket, rate.eventCount);\n }\n\n getCorrelationRates(entity: string, lastHours: number): Array<{ entity: string; bucket: string; eventCount: number }> {\n this.ensureInitialized();\n const cutoff = new Date(Date.now() - lastHours * 3600_000).toISOString();\n const rows = this.db!.prepare(\n 'SELECT entity, bucket, event_count FROM correlation_rates WHERE entity = ? AND bucket >= ? ORDER BY bucket DESC'\n ).all(entity, cutoff) as Array<{ entity: string; bucket: string; event_count: number }>;\n return rows.map((r) => ({\n entity: r.entity,\n bucket: r.bucket,\n eventCount: r.event_count,\n }));\n }\n\n saveHistogramBucket(bucket: { entity: string; columnName: string; bucketKey: string; count: number; period: string }): void {\n this.ensureInitialized();\n this.db!.prepare(\n 'INSERT OR REPLACE INTO distribution_histograms (entity, column_name, bucket_key, count, period) VALUES (?, ?, ?, ?, ?)'\n ).run(bucket.entity, bucket.columnName, bucket.bucketKey, bucket.count, bucket.period);\n }\n\n getHistogramBuckets(entity: string, columnName: string, period: string): Array<{ bucketKey: string; count: number }> {\n this.ensureInitialized();\n const rows = this.db!.prepare(\n 'SELECT bucket_key, count FROM distribution_histograms WHERE entity = ? AND column_name = ? AND period = ? ORDER BY bucket_key'\n ).all(entity, columnName, period) as Array<{ bucket_key: string; count: number }>;\n return rows.map((r) => ({\n bucketKey: r.bucket_key,\n count: r.count,\n }));\n }\n\n saveTemporalPattern(pattern: { entity: string; bucketType: string; bucketKey: number; count: number; period: string }): void {\n this.ensureInitialized();\n this.db!.prepare(\n 'INSERT OR REPLACE INTO temporal_patterns (entity, bucket_type, bucket_key, count, period) VALUES (?, ?, ?, ?, ?)'\n ).run(pattern.entity, pattern.bucketType, pattern.bucketKey, pattern.count, pattern.period);\n }\n\n getTemporalPatterns(entity: string, bucketType: string, period: string): Array<{ bucketKey: number; count: number }> {\n this.ensureInitialized();\n const rows = this.db!.prepare(\n 'SELECT bucket_key, count FROM temporal_patterns WHERE entity = ? AND bucket_type = ? AND period = ? ORDER BY bucket_key'\n ).all(entity, bucketType, period) as Array<{ bucket_key: number; count: number }>;\n return rows.map((r) => ({\n bucketKey: r.bucket_key,\n count: r.count,\n }));\n }\n\n saveAnalyticsBaseline(baseline: { key: string; mean: number; stddev: number; sampleSize: number }): void {\n this.ensureInitialized();\n this.db!.prepare(\n 'INSERT OR REPLACE INTO analytics_baselines (key, mean, stddev, sample_size) VALUES (?, ?, ?, ?)'\n ).run(baseline.key, baseline.mean, baseline.stddev, baseline.sampleSize);\n }\n\n getAnalyticsBaseline(key: string): { mean: number; stddev: number; sampleSize: number } | undefined {\n this.ensureInitialized();\n const row = this.db!.prepare(\n 'SELECT mean, stddev, sample_size FROM analytics_baselines WHERE key = ?'\n ).get(key) as { mean: number; stddev: number; sample_size: number } | undefined;\n if (!row) return undefined;\n return {\n mean: row.mean,\n stddev: row.stddev,\n sampleSize: row.sample_size,\n };\n }\n\n // ── Knowledge Graph ──────────────────────────────────────────\n\n saveKgNode(node: { nodeType: string; refId: string; label: string; metadata: string }): number {\n this.ensureInitialized();\n const info = this.db!.prepare(\n `INSERT INTO kg_nodes (node_type, ref_id, label, metadata) VALUES (?, ?, ?, ?)\n ON CONFLICT(node_type, ref_id) DO UPDATE SET label = excluded.label, metadata = excluded.metadata, timestamp = datetime('now')`\n ).run(node.nodeType, node.refId, node.label, node.metadata);\n // ON CONFLICT UPDATE returns the existing row id, not a new one\n if (info.changes === 0) {\n const existing = this.getKgNodeByRef(node.nodeType, node.refId);\n return existing!.id;\n }\n return Number(info.lastInsertRowid);\n }\n\n getKgNode(id: number): { id: number; nodeType: string; refId: string; label: string; metadata: string; timestamp: string } | undefined {\n this.ensureInitialized();\n const row = this.db!.prepare(\n 'SELECT id, node_type, ref_id, label, metadata, timestamp FROM kg_nodes WHERE id = ?'\n ).get(id) as { id: number; node_type: string; ref_id: string; label: string; metadata: string; timestamp: string } | undefined;\n if (!row) return undefined;\n return { id: row.id, nodeType: row.node_type, refId: row.ref_id, label: row.label, metadata: row.metadata, timestamp: row.timestamp };\n }\n\n getKgNodeByRef(nodeType: string, refId: string): { id: number; nodeType: string; refId: string; label: string; metadata: string; timestamp: string } | undefined {\n this.ensureInitialized();\n const row = this.db!.prepare(\n 'SELECT id, node_type, ref_id, label, metadata, timestamp FROM kg_nodes WHERE node_type = ? AND ref_id = ?'\n ).get(nodeType, refId) as { id: number; node_type: string; ref_id: string; label: string; metadata: string; timestamp: string } | undefined;\n if (!row) return undefined;\n return { id: row.id, nodeType: row.node_type, refId: row.ref_id, label: row.label, metadata: row.metadata, timestamp: row.timestamp };\n }\n\n getKgNodesByType(nodeType: string): Array<{ id: number; nodeType: string; refId: string; label: string; metadata: string; timestamp: string }> {\n this.ensureInitialized();\n const rows = this.db!.prepare(\n 'SELECT id, node_type, ref_id, label, metadata, timestamp FROM kg_nodes WHERE node_type = ? ORDER BY timestamp DESC'\n ).all(nodeType) as Array<{ id: number; node_type: string; ref_id: string; label: string; metadata: string; timestamp: string }>;\n return rows.map((r) => ({ id: r.id, nodeType: r.node_type, refId: r.ref_id, label: r.label, metadata: r.metadata, timestamp: r.timestamp }));\n }\n\n getAllKgNodes(): Array<{ id: number; nodeType: string; refId: string; label: string; metadata: string; timestamp: string }> {\n this.ensureInitialized();\n const rows = this.db!.prepare(\n 'SELECT id, node_type, ref_id, label, metadata, timestamp FROM kg_nodes ORDER BY timestamp DESC'\n ).all() as Array<{ id: number; node_type: string; ref_id: string; label: string; metadata: string; timestamp: string }>;\n return rows.map((r) => ({ id: r.id, nodeType: r.node_type, refId: r.ref_id, label: r.label, metadata: r.metadata, timestamp: r.timestamp }));\n }\n\n deleteKgNode(id: number): void {\n this.ensureInitialized();\n this.db!.prepare('DELETE FROM kg_edges WHERE source_id = ? OR target_id = ?').run(id, id);\n this.db!.prepare('DELETE FROM kg_nodes WHERE id = ?').run(id);\n }\n\n saveKgEdge(edge: { sourceId: number; targetId: number; edgeType: string; weight: number; metadata: string }): number {\n this.ensureInitialized();\n const info = this.db!.prepare(\n `INSERT INTO kg_edges (source_id, target_id, edge_type, weight, metadata) VALUES (?, ?, ?, ?, ?)\n ON CONFLICT(source_id, target_id, edge_type) DO UPDATE SET weight = excluded.weight, metadata = excluded.metadata, timestamp = datetime('now')`\n ).run(edge.sourceId, edge.targetId, edge.edgeType, edge.weight, edge.metadata);\n return Number(info.lastInsertRowid);\n }\n\n getKgEdgesFrom(nodeId: number, edgeType?: string): Array<{ id: number; sourceId: number; targetId: number; edgeType: string; weight: number; metadata: string; timestamp: string }> {\n this.ensureInitialized();\n let sql = 'SELECT id, source_id, target_id, edge_type, weight, metadata, timestamp FROM kg_edges WHERE source_id = ?';\n const params: unknown[] = [nodeId];\n if (edgeType) { sql += ' AND edge_type = ?'; params.push(edgeType); }\n sql += ' ORDER BY timestamp DESC';\n const rows = this.db!.prepare(sql).all(...params) as Array<{ id: number; source_id: number; target_id: number; edge_type: string; weight: number; metadata: string; timestamp: string }>;\n return rows.map((r) => ({ id: r.id, sourceId: r.source_id, targetId: r.target_id, edgeType: r.edge_type, weight: r.weight, metadata: r.metadata, timestamp: r.timestamp }));\n }\n\n getKgEdgesTo(nodeId: number, edgeType?: string): Array<{ id: number; sourceId: number; targetId: number; edgeType: string; weight: number; metadata: string; timestamp: string }> {\n this.ensureInitialized();\n let sql = 'SELECT id, source_id, target_id, edge_type, weight, metadata, timestamp FROM kg_edges WHERE target_id = ?';\n const params: unknown[] = [nodeId];\n if (edgeType) { sql += ' AND edge_type = ?'; params.push(edgeType); }\n sql += ' ORDER BY timestamp DESC';\n const rows = this.db!.prepare(sql).all(...params) as Array<{ id: number; source_id: number; target_id: number; edge_type: string; weight: number; metadata: string; timestamp: string }>;\n return rows.map((r) => ({ id: r.id, sourceId: r.source_id, targetId: r.target_id, edgeType: r.edge_type, weight: r.weight, metadata: r.metadata, timestamp: r.timestamp }));\n }\n\n getAllKgEdges(): Array<{ id: number; sourceId: number; targetId: number; edgeType: string; weight: number; metadata: string; timestamp: string }> {\n this.ensureInitialized();\n const rows = this.db!.prepare(\n 'SELECT id, source_id, target_id, edge_type, weight, metadata, timestamp FROM kg_edges ORDER BY timestamp DESC'\n ).all() as Array<{ id: number; source_id: number; target_id: number; edge_type: string; weight: number; metadata: string; timestamp: string }>;\n return rows.map((r) => ({ id: r.id, sourceId: r.source_id, targetId: r.target_id, edgeType: r.edge_type, weight: r.weight, metadata: r.metadata, timestamp: r.timestamp }));\n }\n\n getKgSummary(): { totalNodes: number; totalEdges: number; entities: number; events: number; anomalies: number; insights: number } {\n this.ensureInitialized();\n const nodeCount = this.db!.prepare('SELECT COUNT(*) as count FROM kg_nodes').get() as { count: number };\n const edgeCount = this.db!.prepare('SELECT COUNT(*) as count FROM kg_edges').get() as { count: number };\n const entityCount = this.db!.prepare(\"SELECT COUNT(*) as count FROM kg_nodes WHERE node_type = 'entity'\").get() as { count: number };\n const eventCount = this.db!.prepare(\"SELECT COUNT(*) as count FROM kg_nodes WHERE node_type = 'event'\").get() as { count: number };\n const anomalyCount = this.db!.prepare(\"SELECT COUNT(*) as count FROM kg_nodes WHERE node_type = 'anomaly'\").get() as { count: number };\n const insightCount = this.db!.prepare(\"SELECT COUNT(*) as count FROM kg_nodes WHERE node_type = 'insight'\").get() as { count: number };\n return { totalNodes: nodeCount.count, totalEdges: edgeCount.count, entities: entityCount.count, events: eventCount.count, anomalies: anomalyCount.count, insights: insightCount.count };\n }\n\n // ── Recommendations ──────────────────────────────────────────\n\n saveRecommendation(rec: { action: string; reason: string; confidence: number; status: string; governance: string; insightId: string | null; entity: string; context: string }): number {\n this.ensureInitialized();\n const info = this.db!.prepare(\n 'INSERT INTO recommendations (action, reason, confidence, status, governance, insight_id, entity, context) VALUES (?, ?, ?, ?, ?, ?, ?, ?)'\n ).run(rec.action, rec.reason, rec.confidence, rec.status, rec.governance, rec.insightId, rec.entity, rec.context);\n return Number(info.lastInsertRowid);\n }\n\n getRecommendation(id: number): { id: number; action: string; reason: string; confidence: number; status: string; governance: string; insightId: string | null; entity: string; context: string; createdAt: string; resolvedAt: string | null; resolvedBy: string | null } | undefined {\n this.ensureInitialized();\n const row = this.db!.prepare(\n 'SELECT id, action, reason, confidence, status, governance, insight_id, entity, context, created_at, resolved_at, resolved_by FROM recommendations WHERE id = ?'\n ).get(id) as { id: number; action: string; reason: string; confidence: number; status: string; governance: string; insight_id: string | null; entity: string; context: string; created_at: string; resolved_at: string | null; resolved_by: string | null } | undefined;\n if (!row) return undefined;\n return {\n id: row.id,\n action: row.action,\n reason: row.reason,\n confidence: row.confidence,\n status: row.status,\n governance: row.governance,\n insightId: row.insight_id,\n entity: row.entity,\n context: row.context,\n createdAt: row.created_at,\n resolvedAt: row.resolved_at,\n resolvedBy: row.resolved_by,\n };\n }\n\n getRecommendations(filter?: { status?: string; action?: string; last?: number }): Array<{ id: number; action: string; reason: string; confidence: number; status: string; governance: string; insightId: string | null; entity: string; context: string; createdAt: string; resolvedAt: string | null; resolvedBy: string | null }> {\n this.ensureInitialized();\n let sql = 'SELECT id, action, reason, confidence, status, governance, insight_id, entity, context, created_at, resolved_at, resolved_by FROM recommendations';\n const conditions: string[] = [];\n const params: unknown[] = [];\n\n if (filter?.status) {\n conditions.push('status = ?');\n params.push(filter.status);\n }\n if (filter?.action) {\n conditions.push('action = ?');\n params.push(filter.action);\n }\n if (conditions.length > 0) {\n sql += ' WHERE ' + conditions.join(' AND ');\n }\n sql += ' ORDER BY created_at DESC';\n if (filter?.last) {\n sql += ' LIMIT ?';\n params.push(filter.last);\n }\n\n const rows = this.db!.prepare(sql).all(...params) as Array<{ id: number; action: string; reason: string; confidence: number; status: string; governance: string; insight_id: string | null; entity: string; context: string; created_at: string; resolved_at: string | null; resolved_by: string | null }>;\n return rows.map((row) => ({\n id: row.id,\n action: row.action,\n reason: row.reason,\n confidence: row.confidence,\n status: row.status,\n governance: row.governance,\n insightId: row.insight_id,\n entity: row.entity,\n context: row.context,\n createdAt: row.created_at,\n resolvedAt: row.resolved_at,\n resolvedBy: row.resolved_by,\n }));\n }\n\n updateRecommendationStatus(id: number, status: string, resolvedBy: string): void {\n this.ensureInitialized();\n this.db!.prepare(\n \"UPDATE recommendations SET status = ?, resolved_at = datetime('now'), resolved_by = ? WHERE id = ?\"\n ).run(status, resolvedBy, id);\n }\n\n getRecommendationSummary(): { total: number; executed: number; pending: number; approved: number; rejected: number; blocked: number; failed: number } {\n this.ensureInitialized();\n const rows = this.db!.prepare(\n 'SELECT status, COUNT(*) as count FROM recommendations GROUP BY status'\n ).all() as Array<{ status: string; count: number }>;\n\n const counts: Record<string, number> = {};\n let total = 0;\n for (const row of rows) {\n counts[row.status] = row.count;\n total += row.count;\n }\n\n return {\n total,\n executed: counts['executed'] ?? 0,\n pending: counts['pending'] ?? 0,\n approved: counts['approved'] ?? 0,\n rejected: counts['rejected'] ?? 0,\n blocked: counts['blocked'] ?? 0,\n failed: counts['failed'] ?? 0,\n };\n }\n\n close(): void {\n if (this.db) {\n this.db.close();\n this.db = null;\n }\n }\n\n private createSchema(): void {\n const createMetaTable = `\n CREATE TABLE IF NOT EXISTS meta (\n key TEXT PRIMARY KEY,\n value TEXT\n )\n `;\n\n const createDiscoveredTablesTable = `\n CREATE TABLE IF NOT EXISTS discovered_tables (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n table_name TEXT NOT NULL,\n table_schema TEXT DEFAULT 'public',\n row_count INTEGER,\n columns_json TEXT,\n fk_json TEXT,\n indexes_json TEXT,\n sample_rows TEXT,\n discovered_at TEXT DEFAULT (datetime('now')),\n UNIQUE(table_name, table_schema)\n )\n `;\n\n const createEntitiesTable = `\n CREATE TABLE IF NOT EXISTS entities (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n table_name TEXT NOT NULL UNIQUE,\n entity_label TEXT NOT NULL,\n entity_type TEXT NOT NULL,\n description TEXT,\n confidence REAL DEFAULT 0.0,\n columns_classified TEXT,\n classified_at TEXT DEFAULT (datetime('now'))\n )\n `;\n\n const createRelationshipsTable = `\n CREATE TABLE IF NOT EXISTS relationships (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n source_entity TEXT NOT NULL,\n target_entity TEXT NOT NULL,\n relationship TEXT NOT NULL,\n source_column TEXT,\n target_column TEXT,\n inferred INTEGER DEFAULT 0,\n confidence REAL DEFAULT 0.0,\n UNIQUE(source_entity, target_entity, relationship)\n )\n `;\n\n const createLlmCacheTable = `\n CREATE TABLE IF NOT EXISTS llm_cache (\n cache_key TEXT PRIMARY KEY,\n response TEXT NOT NULL,\n model TEXT,\n tokens_used INTEGER,\n cached_at TEXT DEFAULT (datetime('now'))\n )\n `;\n\n\n const createEventsTable = `\n CREATE TABLE IF NOT EXISTS events (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n event_type TEXT NOT NULL,\n entity TEXT NOT NULL,\n table_name TEXT NOT NULL,\n operation TEXT NOT NULL,\n row_id TEXT,\n row_data TEXT,\n timestamp TEXT DEFAULT (datetime('now'))\n )\n `;\n\n const createEventsEntityIndex = `CREATE INDEX IF NOT EXISTS idx_events_entity ON events(entity, timestamp)`;\n const createEventsTypeIndex = `CREATE INDEX IF NOT EXISTS idx_events_type ON events(event_type, timestamp)`;\n\n const createBaselinesTable = `\n CREATE TABLE IF NOT EXISTS baselines (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n entity TEXT NOT NULL,\n metric TEXT NOT NULL,\n mean REAL NOT NULL,\n stddev REAL NOT NULL,\n sample_size INTEGER NOT NULL,\n updated_at TEXT DEFAULT (datetime('now')),\n UNIQUE(entity, metric)\n )\n `;\n\n const createAnomaliesTable = `\n CREATE TABLE IF NOT EXISTS anomalies (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n entity TEXT NOT NULL,\n anomaly_type TEXT NOT NULL,\n severity TEXT NOT NULL,\n expected REAL,\n actual REAL,\n message TEXT,\n timestamp TEXT DEFAULT (datetime('now'))\n )\n `;\n\n const createWatchWatermarksTable = `\n CREATE TABLE IF NOT EXISTS watch_watermarks (\n table_name TEXT NOT NULL,\n table_schema TEXT NOT NULL,\n strategy TEXT NOT NULL,\n timestamp_column TEXT,\n pk_column TEXT,\n last_seen_value TEXT,\n updated_at TEXT DEFAULT (datetime('now')),\n PRIMARY KEY(table_name, table_schema)\n )\n `;\n\n const createStateTransitionsTable = `\n CREATE TABLE IF NOT EXISTS state_transitions (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n entity TEXT NOT NULL,\n table_name TEXT NOT NULL,\n primary_key TEXT NOT NULL,\n from_state TEXT NOT NULL,\n to_state TEXT NOT NULL,\n duration_ms INTEGER,\n expected INTEGER NOT NULL,\n timestamp TEXT DEFAULT (datetime('now'))\n )\n `;\n const createTransitionsEntityIndex = `CREATE INDEX IF NOT EXISTS idx_transitions_entity ON state_transitions(entity, timestamp)`;\n const createTransitionsPkIndex = `CREATE INDEX IF NOT EXISTS idx_transitions_pk ON state_transitions(table_name, primary_key)`;\n\n const createInsightsTable = `\n CREATE TABLE IF NOT EXISTS insights (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n entity TEXT NOT NULL,\n insight_type TEXT NOT NULL,\n severity TEXT NOT NULL,\n message TEXT NOT NULL,\n context_json TEXT,\n timestamp TEXT DEFAULT (datetime('now'))\n )\n `;\n const createInsightsEntityIndex = `CREATE INDEX IF NOT EXISTS idx_insights_entity ON insights(entity, timestamp)`;\n\n const createEntityStatesTable = `\n CREATE TABLE IF NOT EXISTS entity_states (\n table_name TEXT NOT NULL,\n primary_key TEXT NOT NULL,\n state TEXT NOT NULL,\n entered_at TEXT NOT NULL,\n PRIMARY KEY(table_name, primary_key)\n )\n `;\n\n const createCorrelationEventsTable = `\n CREATE TABLE IF NOT EXISTS correlation_events (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n entity TEXT NOT NULL,\n event_type TEXT NOT NULL,\n primary_key TEXT,\n timestamp TEXT DEFAULT (datetime('now'))\n )\n `;\n const createCorrelationEventsIndex = `CREATE INDEX IF NOT EXISTS idx_corr_events ON correlation_events(entity, timestamp)`;\n\n const createCorrelationRatesTable = `\n CREATE TABLE IF NOT EXISTS correlation_rates (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n entity TEXT NOT NULL,\n bucket TEXT NOT NULL,\n event_count INTEGER NOT NULL,\n UNIQUE(entity, bucket)\n )\n `;\n\n const createDistributionHistogramsTable = `\n CREATE TABLE IF NOT EXISTS distribution_histograms (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n entity TEXT NOT NULL,\n column_name TEXT NOT NULL,\n bucket_key TEXT NOT NULL,\n count INTEGER NOT NULL,\n period TEXT NOT NULL,\n UNIQUE(entity, column_name, bucket_key, period)\n )\n `;\n\n const createTemporalPatternsTable = `\n CREATE TABLE IF NOT EXISTS temporal_patterns (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n entity TEXT NOT NULL,\n bucket_type TEXT NOT NULL,\n bucket_key INTEGER NOT NULL,\n count INTEGER NOT NULL,\n period TEXT NOT NULL,\n UNIQUE(entity, bucket_type, bucket_key, period)\n )\n `;\n\n const createAnalyticsBaselinesTable = `\n CREATE TABLE IF NOT EXISTS analytics_baselines (\n key TEXT PRIMARY KEY,\n mean REAL NOT NULL,\n stddev REAL NOT NULL,\n sample_size INTEGER NOT NULL,\n updated_at TEXT DEFAULT (datetime('now'))\n )\n `;\n\n const createKgNodesTable = `\n CREATE TABLE IF NOT EXISTS kg_nodes (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n node_type TEXT NOT NULL,\n ref_id TEXT NOT NULL,\n label TEXT NOT NULL,\n metadata TEXT,\n timestamp TEXT DEFAULT (datetime('now')),\n UNIQUE(node_type, ref_id)\n )\n `;\n const createKgNodesTypeIndex = `CREATE INDEX IF NOT EXISTS idx_kg_nodes_type ON kg_nodes(node_type)`;\n const createKgNodesRefIndex = `CREATE INDEX IF NOT EXISTS idx_kg_nodes_ref ON kg_nodes(ref_id)`;\n\n const createKgEdgesTable = `\n CREATE TABLE IF NOT EXISTS kg_edges (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n source_id INTEGER NOT NULL REFERENCES kg_nodes(id),\n target_id INTEGER NOT NULL REFERENCES kg_nodes(id),\n edge_type TEXT NOT NULL,\n weight REAL DEFAULT 1.0,\n metadata TEXT,\n timestamp TEXT DEFAULT (datetime('now')),\n UNIQUE(source_id, target_id, edge_type)\n )\n `;\n const createKgEdgesSourceIndex = `CREATE INDEX IF NOT EXISTS idx_kg_edges_source ON kg_edges(source_id)`;\n const createKgEdgesTargetIndex = `CREATE INDEX IF NOT EXISTS idx_kg_edges_target ON kg_edges(target_id)`;\n const createKgEdgesTypeIndex = `CREATE INDEX IF NOT EXISTS idx_kg_edges_type ON kg_edges(edge_type)`;\n\n const createRecommendationsTable = `\n CREATE TABLE IF NOT EXISTS recommendations (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n action TEXT NOT NULL,\n reason TEXT NOT NULL,\n confidence REAL NOT NULL,\n status TEXT NOT NULL DEFAULT 'pending',\n governance TEXT NOT NULL,\n insight_id TEXT,\n entity TEXT NOT NULL,\n context TEXT NOT NULL DEFAULT '{}',\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n resolved_at TEXT,\n resolved_by TEXT\n )\n `;\n const createRecommendationsStatusIndex = `CREATE INDEX IF NOT EXISTS idx_recommendations_status ON recommendations(status)`;\n const createRecommendationsEntityIndex = `CREATE INDEX IF NOT EXISTS idx_recommendations_entity ON recommendations(entity)`;\n const createRecommendationsActionIndex = `CREATE INDEX IF NOT EXISTS idx_recommendations_action ON recommendations(action)`;\n\n this.db!.prepare(createMetaTable).run();\n this.db!.prepare(createDiscoveredTablesTable).run();\n this.db!.prepare(createEntitiesTable).run();\n this.db!.prepare(createRelationshipsTable).run();\n this.db!.prepare(createLlmCacheTable).run();\n this.db!.prepare(createEventsTable).run();\n this.db!.prepare(createEventsEntityIndex).run();\n this.db!.prepare(createEventsTypeIndex).run();\n this.db!.prepare(createBaselinesTable).run();\n this.db!.prepare(createAnomaliesTable).run();\n this.db!.prepare(createWatchWatermarksTable).run();\n this.db!.prepare(createStateTransitionsTable).run();\n this.db!.prepare(createTransitionsEntityIndex).run();\n this.db!.prepare(createTransitionsPkIndex).run();\n this.db!.prepare(createInsightsTable).run();\n this.db!.prepare(createInsightsEntityIndex).run();\n this.db!.prepare(createEntityStatesTable).run();\n this.db!.prepare(createCorrelationEventsTable).run();\n this.db!.prepare(createCorrelationEventsIndex).run();\n this.db!.prepare(createCorrelationRatesTable).run();\n this.db!.prepare(createDistributionHistogramsTable).run();\n this.db!.prepare(createTemporalPatternsTable).run();\n this.db!.prepare(createAnalyticsBaselinesTable).run();\n this.db!.prepare(createKgNodesTable).run();\n this.db!.prepare(createKgNodesTypeIndex).run();\n this.db!.prepare(createKgNodesRefIndex).run();\n this.db!.prepare(createKgEdgesTable).run();\n this.db!.prepare(createKgEdgesSourceIndex).run();\n this.db!.prepare(createKgEdgesTargetIndex).run();\n this.db!.prepare(createKgEdgesTypeIndex).run();\n this.db!.prepare(createRecommendationsTable).run();\n this.db!.prepare(createRecommendationsStatusIndex).run();\n this.db!.prepare(createRecommendationsEntityIndex).run();\n this.db!.prepare(createRecommendationsActionIndex).run();\n }\n\n private ensureInitialized(): void {\n if (!this.db) {\n throw new Error('Storage not initialized. Call initialize() first.');\n }\n }\n}\n","import type { LLMProvider, LLMConfig } from './types.js';\nimport { OpenAICompatibleProvider } from './openai-compatible.js';\nimport { AnthropicProvider } from './anthropic.js';\nimport { ConfigError } from '../core/errors.js';\n\nconst KNOWN_BASE_URLS: Record<string, { baseUrl: string; defaultModel: string }> = {\n openai: { baseUrl: 'https://api.openai.com/v1', defaultModel: 'gpt-4o-mini' },\n deepseek: { baseUrl: 'https://api.deepseek.com', defaultModel: 'deepseek-chat' },\n};\n\nexport function createLLMProvider(config: LLMConfig): LLMProvider {\n if (config.provider === 'anthropic') {\n if (!config.apiKey) {\n throw new ConfigError('Anthropic provider requires an apiKey.', 'Add apiKey to llm config in cortexa.config.ts.');\n }\n return new AnthropicProvider(config.apiKey, config.model, config.retry);\n }\n\n const known = KNOWN_BASE_URLS[config.provider];\n const baseUrl = config.baseUrl ?? known?.baseUrl;\n\n if (!baseUrl) {\n throw new ConfigError(\n `Unknown provider \"${config.provider}\".`,\n `Provide a baseUrl for custom providers: { provider: \"${config.provider}\", baseUrl: \"https://api.example.com/v1\" }`,\n );\n }\n\n const model = config.model ?? known?.defaultModel ?? config.provider;\n\n return new OpenAICompatibleProvider({\n apiKey: config.apiKey,\n model,\n baseUrl,\n headers: config.headers,\n retry: config.retry,\n });\n}\n","import type { LLMProvider, LLMResponse, LLMChatOptions } from './types.js';\nimport { LLMError } from '../core/errors.js';\nimport { withRetry, type RetryConfig } from './retry.js';\n\nexport class OpenAICompatibleProvider implements LLMProvider {\n private readonly apiKey: string;\n private readonly model: string;\n private readonly baseUrl: string;\n private readonly headers: Record<string, string>;\n private readonly retry?: RetryConfig;\n\n constructor(options: {\n apiKey?: string;\n model: string;\n baseUrl: string;\n headers?: Record<string, string>;\n retry?: RetryConfig;\n }) {\n this.apiKey = options.apiKey ?? '';\n this.model = options.model;\n this.baseUrl = options.baseUrl.replace(/\\/+$/, '');\n this.headers = options.headers ?? {};\n this.retry = options.retry;\n }\n\n async chat(prompt: string, options?: LLMChatOptions): Promise<LLMResponse> {\n return withRetry(() => this.doChat(prompt, options), this.retry);\n }\n\n private async doChat(prompt: string, options?: LLMChatOptions): Promise<LLMResponse> {\n const body: Record<string, unknown> = {\n model: this.model,\n messages: [{ role: 'user', content: prompt }],\n max_tokens: options?.maxTokens ?? 4096,\n };\n\n if (options?.jsonMode) {\n body.response_format = { type: 'json_object' };\n }\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...this.headers,\n };\n\n if (this.apiKey) {\n headers['Authorization'] = `Bearer ${this.apiKey}`;\n }\n\n const url = `${this.baseUrl}/chat/completions`;\n const response = await fetch(url, {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new LLMError(\n `LLM API error (${response.status}): ${errorText}`,\n {\n statusCode: response.status,\n provider: this.model,\n hint: response.status === 401\n ? 'Check your API key in cortexa.config.ts.'\n : response.status === 429\n ? 'Rate limited. Wait a moment and retry, or use a different model.'\n : response.status >= 500\n ? 'The LLM provider returned a server error. This is usually temporary.'\n : undefined,\n },\n );\n }\n\n const data = await response.json() as {\n choices: Array<{ message: { content: string } }>;\n usage?: { prompt_tokens: number; completion_tokens: number };\n model?: string;\n };\n return {\n content: data.choices[0].message.content,\n tokensUsed: {\n prompt: data.usage?.prompt_tokens ?? 0,\n completion: data.usage?.completion_tokens ?? 0,\n },\n model: data.model ?? this.model,\n };\n }\n}\n","export class CortexaError extends Error {\n readonly code: string;\n readonly hint?: string;\n\n constructor(message: string, code: string, hint?: string) {\n super(message);\n this.name = 'CortexaError';\n this.code = code;\n this.hint = hint;\n }\n}\n\nexport class ConfigError extends CortexaError {\n constructor(message: string, hint?: string) {\n super(message, 'CONFIG_ERROR', hint);\n this.name = 'ConfigError';\n }\n}\n\nexport class ConnectionError extends CortexaError {\n constructor(message: string, hint?: string) {\n super(message, 'CONNECTION_ERROR', hint);\n this.name = 'ConnectionError';\n }\n}\n\nexport class LLMError extends CortexaError {\n readonly statusCode?: number;\n readonly provider?: string;\n\n constructor(message: string, options?: { statusCode?: number; provider?: string; hint?: string }) {\n super(message, 'LLM_ERROR', options?.hint);\n this.name = 'LLMError';\n this.statusCode = options?.statusCode;\n this.provider = options?.provider;\n }\n}\n\nexport class LLMResponseError extends LLMError {\n readonly rawContent?: string;\n\n constructor(message: string, rawContent?: string) {\n super(message, {\n hint: 'The LLM returned an unparseable response. Try reducing batchSize or using a different model.',\n });\n this.name = 'LLMResponseError';\n this.rawContent = rawContent;\n }\n}\n","import { LLMError } from '../core/errors.js';\n\nexport interface RetryConfig {\n maxRetries?: number;\n initialDelayMs?: number;\n maxDelayMs?: number;\n backoffMultiplier?: number;\n retryableStatusCodes?: number[];\n}\n\nconst DEFAULT_RETRYABLE_CODES = new Set([429, 500, 502, 503, 504]);\n\nfunction isRetryableError(error: unknown, retryableCodes: Set<number>): boolean {\n if (error instanceof LLMError && error.statusCode) {\n return retryableCodes.has(error.statusCode);\n }\n // Network errors (fetch failures) are retryable\n if (error instanceof TypeError) {\n return true;\n }\n return false;\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport async function withRetry<T>(\n fn: () => Promise<T>,\n config?: RetryConfig,\n logger?: { warn: (obj: Record<string, unknown>, msg: string) => void },\n): Promise<T> {\n const maxRetries = config?.maxRetries ?? 3;\n const initialDelay = config?.initialDelayMs ?? 1000;\n const maxDelay = config?.maxDelayMs ?? 30000;\n const multiplier = config?.backoffMultiplier ?? 2;\n const retryableCodes = config?.retryableStatusCodes\n ? new Set(config.retryableStatusCodes)\n : DEFAULT_RETRYABLE_CODES;\n\n let lastError: Error | undefined;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n return await fn();\n } catch (error) {\n lastError = error as Error;\n\n if (attempt === maxRetries) break;\n\n if (!isRetryableError(error, retryableCodes)) {\n throw error;\n }\n\n const delay = Math.min(initialDelay * Math.pow(multiplier, attempt), maxDelay);\n const jitteredDelay = delay * (0.75 + Math.random() * 0.5);\n\n logger?.warn(\n { attempt: attempt + 1, maxRetries, delayMs: Math.round(jitteredDelay) },\n `LLM call failed, retrying... (${lastError.message})`,\n );\n\n await sleep(jitteredDelay);\n }\n }\n\n throw lastError!;\n}\n","import type { LLMProvider, LLMResponse, LLMChatOptions } from './types.js';\nimport { LLMError } from '../core/errors.js';\nimport { withRetry, type RetryConfig } from './retry.js';\n\nexport class AnthropicProvider implements LLMProvider {\n private readonly apiKey: string;\n private readonly model: string;\n private readonly retry?: RetryConfig;\n\n constructor(apiKey: string, model = 'claude-haiku-4-5-20251001', retry?: RetryConfig) {\n this.apiKey = apiKey;\n this.model = model;\n this.retry = retry;\n }\n\n async chat(prompt: string, options?: LLMChatOptions): Promise<LLMResponse> {\n return withRetry(() => this.doChat(prompt, options), this.retry);\n }\n\n private async doChat(prompt: string, options?: LLMChatOptions): Promise<LLMResponse> {\n const body: Record<string, unknown> = {\n model: this.model,\n max_tokens: options?.maxTokens ?? 4096,\n messages: [{ role: 'user', content: prompt }],\n };\n\n const response = await fetch('https://api.anthropic.com/v1/messages', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': this.apiKey,\n 'anthropic-version': '2023-06-01',\n },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new LLMError(\n `Anthropic API error (${response.status}): ${errorText}`,\n {\n statusCode: response.status,\n provider: 'anthropic',\n hint: response.status === 401\n ? 'Check your Anthropic API key in cortexa.config.ts.'\n : response.status === 429\n ? 'Rate limited. Wait a moment and retry, or use a different model.'\n : response.status >= 500\n ? 'The Anthropic API returned a server error. This is usually temporary.'\n : undefined,\n },\n );\n }\n\n const data = await response.json() as {\n content: Array<{ text: string }>;\n usage: { input_tokens: number; output_tokens: number };\n model: string;\n };\n return {\n content: data.content[0].text,\n tokensUsed: {\n prompt: data.usage.input_tokens,\n completion: data.usage.output_tokens,\n },\n model: data.model,\n };\n }\n}\n","import type { ConnectionConfig } from '../core/config.js';\nimport type { DatabaseConnector } from '../connectors/types.js';\nimport type { RawSchema, RawTable, RawColumn, RawForeignKey, RawIndex, DiscoveryOptions } from './types.js';\n\nexport class SchemaIntrospector {\n private readonly connector: DatabaseConnector;\n private readonly dbType: ConnectionConfig['type'];\n private readonly options: DiscoveryOptions;\n\n constructor(connector: DatabaseConnector, dbType: ConnectionConfig['type'], options: DiscoveryOptions = {}) {\n this.connector = connector;\n this.dbType = dbType;\n this.options = options;\n }\n\n async introspect(): Promise<RawSchema> {\n const tableRows = await this.getTables();\n const tables: RawTable[] = [];\n const excludeTables = new Set(this.options.excludeTables?.map((t) => t.toLowerCase()) ?? []);\n const excludeColumns = new Set(this.options.excludeColumns?.map((c) => c.toLowerCase()) ?? []);\n const includeSampleData = this.options.includeSampleData !== false;\n const sampleLimit = this.options.sampleRowLimit ?? 5;\n\n for (const row of tableRows) {\n const tableName = row.table_name as string;\n const tableSchema = row.table_schema as string;\n\n if (excludeTables.has(tableName.toLowerCase())) {\n continue;\n }\n\n const [allColumns, foreignKeys, indexes, sampleRows, rowCount] = await Promise.all([\n this.getColumns(tableName, tableSchema),\n this.getForeignKeys(tableName, tableSchema),\n this.getIndexes(tableName, tableSchema),\n includeSampleData ? this.getSampleRows(tableName, tableSchema, sampleLimit) : Promise.resolve([]),\n this.getRowCount(tableName, tableSchema),\n ]);\n\n const columns = excludeColumns.size > 0\n ? allColumns.filter((c) => !excludeColumns.has(c.columnName.toLowerCase()))\n : allColumns;\n\n const filteredSampleRows = excludeColumns.size > 0 && sampleRows.length > 0\n ? sampleRows.map((row) => {\n const filtered: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(row)) {\n if (!excludeColumns.has(key.toLowerCase())) {\n filtered[key] = value;\n }\n }\n return filtered;\n })\n : sampleRows;\n\n tables.push({ tableName, tableSchema, columns, foreignKeys, indexes, sampleRows: filteredSampleRows, rowCount });\n }\n\n return { tables, discoveredAt: new Date().toISOString() };\n }\n\n private isPostgresLike(): boolean {\n return this.dbType === 'postgres' || this.dbType === 'cockroachdb';\n }\n\n private isMysqlLike(): boolean {\n return this.dbType === 'mysql' || this.dbType === 'mariadb';\n }\n\n private async getTables(): Promise<Record<string, unknown>[]> {\n if (this.dbType === 'sqlite') {\n const result = await this.connector.query(\n `SELECT name AS table_name, 'main' AS table_schema FROM sqlite_master WHERE type = 'table' AND name NOT LIKE 'sqlite_%' ORDER BY name`\n );\n return result.rows;\n }\n\n if (this.dbType === 'mongodb') {\n const result = await this.connector.query('COLLECTIONS');\n return result.rows;\n }\n\n const schemaFilter = this.isPostgresLike()\n ? `table_schema NOT IN ('pg_catalog', 'information_schema')`\n : this.dbType === 'mssql'\n ? `table_schema NOT IN ('sys', 'INFORMATION_SCHEMA')`\n : `table_schema = DATABASE()`;\n\n const result = await this.connector.query(\n `SELECT table_name AS table_name, table_schema AS table_schema FROM information_schema.tables WHERE table_type = 'BASE TABLE' AND ${schemaFilter} ORDER BY table_name`\n );\n return result.rows;\n }\n\n private async getColumns(tableName: string, _tableSchema: string): Promise<RawColumn[]> {\n if (this.dbType === 'sqlite') {\n const result = await this.connector.query(`PRAGMA table_info(\"${tableName}\")`);\n return result.rows.map((row) => ({\n columnName: row.name as string,\n dataType: (row.type as string) || 'TEXT',\n isNullable: (row.notnull as number) === 0,\n columnDefault: (row.dflt_value as string) ?? null,\n }));\n }\n\n if (this.dbType === 'mongodb') {\n const result = await this.connector.query(`FIELDS:${tableName}:20`);\n return result.rows.map((row) => ({\n columnName: row.column_name as string,\n dataType: row.data_type as string,\n isNullable: true,\n columnDefault: null,\n }));\n }\n\n const result = await this.connector.query(\n `SELECT column_name AS column_name, data_type AS data_type, is_nullable AS is_nullable, column_default AS column_default FROM information_schema.columns WHERE table_name = $1 AND table_schema = $2 ORDER BY ordinal_position`,\n [tableName, _tableSchema]\n );\n return result.rows.map((row) => ({\n columnName: row.column_name as string,\n dataType: row.data_type as string,\n isNullable: (row.is_nullable as string) === 'YES',\n columnDefault: (row.column_default as string) ?? null,\n }));\n }\n\n private async getForeignKeys(tableName: string, tableSchema: string): Promise<RawForeignKey[]> {\n if (this.dbType === 'mongodb') {\n // MongoDB has no formal foreign keys; infer from *_id / *Id patterns\n const columns = await this.getColumns(tableName, tableSchema);\n const fks: RawForeignKey[] = [];\n for (const col of columns) {\n if (col.columnName === '_id') continue;\n const match = col.columnName.match(/^(.+?)(?:_id|Id)$/);\n if (match) {\n fks.push({\n columnName: col.columnName,\n referencedTable: match[1] + 's', // naive pluralization\n referencedColumn: '_id',\n });\n }\n }\n return fks;\n }\n\n if (this.dbType === 'sqlite') {\n const result = await this.connector.query(`PRAGMA foreign_key_list(\"${tableName}\")`);\n return result.rows.map((row) => ({\n columnName: row.from as string,\n referencedTable: row.table as string,\n referencedColumn: row.to as string,\n }));\n }\n\n if (this.dbType === 'mssql') {\n const sql = `SELECT COL_NAME(fkc.parent_object_id, fkc.parent_column_id) AS column_name,\n OBJECT_NAME(fkc.referenced_object_id) AS referenced_table,\n COL_NAME(fkc.referenced_object_id, fkc.referenced_column_id) AS referenced_column\n FROM sys.foreign_key_columns fkc\n JOIN sys.objects o ON o.object_id = fkc.parent_object_id\n JOIN sys.schemas s ON s.schema_id = o.schema_id\n WHERE o.name = $1 AND s.name = $2`;\n const result = await this.connector.query(sql, [tableName, tableSchema]);\n return result.rows.map((row) => ({\n columnName: row.column_name as string,\n referencedTable: row.referenced_table as string,\n referencedColumn: row.referenced_column as string,\n }));\n }\n\n const sql = this.isPostgresLike()\n ? `SELECT a.attname AS column_name, cl2.relname AS referenced_table, a2.attname AS referenced_column\n FROM pg_constraint con\n JOIN pg_class cl ON con.conrelid = cl.oid\n JOIN pg_namespace ns ON cl.relnamespace = ns.oid\n JOIN pg_class cl2 ON con.confrelid = cl2.oid\n JOIN pg_attribute a ON a.attrelid = con.conrelid AND a.attnum = ANY(con.conkey)\n JOIN pg_attribute a2 ON a2.attrelid = con.confrelid AND a2.attnum = ANY(con.confkey)\n WHERE con.contype = 'f' AND cl.relname = $1 AND ns.nspname = $2`\n : `SELECT column_name AS column_name, referenced_table_name AS referenced_table, referenced_column_name AS referenced_column\n FROM information_schema.key_column_usage\n WHERE table_name = $1 AND table_schema = $2 AND referenced_table_name IS NOT NULL`;\n\n const result = await this.connector.query(sql, [tableName, tableSchema]);\n return result.rows.map((row) => ({\n columnName: row.column_name as string,\n referencedTable: row.referenced_table as string,\n referencedColumn: row.referenced_column as string,\n }));\n }\n\n private async getIndexes(tableName: string, tableSchema: string): Promise<RawIndex[]> {\n if (this.dbType === 'mongodb') {\n const result = await this.connector.query(`INDEXES:${tableName}`);\n return result.rows.map((row) => ({\n indexName: row.index_name as string,\n columns: row.columns as string[],\n isUnique: Boolean(row.is_unique),\n }));\n }\n\n if (this.dbType === 'sqlite') {\n const indexListResult = await this.connector.query(`PRAGMA index_list(\"${tableName}\")`);\n const indexes: RawIndex[] = [];\n for (const idx of indexListResult.rows) {\n const idxName = idx.name as string;\n const infoResult = await this.connector.query(`PRAGMA index_info(\"${idxName}\")`);\n indexes.push({\n indexName: idxName,\n columns: infoResult.rows.map((r) => r.name as string),\n isUnique: (idx.unique as number) === 1,\n });\n }\n return indexes;\n }\n\n if (this.dbType === 'mssql') {\n const sql = `SELECT i.name AS index_name, STRING_AGG(c.name, ',') WITHIN GROUP (ORDER BY ic.key_ordinal) AS columns, i.is_unique\n FROM sys.indexes i\n JOIN sys.index_columns ic ON ic.object_id = i.object_id AND ic.index_id = i.index_id\n JOIN sys.columns c ON c.object_id = ic.object_id AND c.column_id = ic.column_id\n JOIN sys.objects o ON o.object_id = i.object_id\n JOIN sys.schemas s ON s.schema_id = o.schema_id\n WHERE o.name = $1 AND s.name = $2 AND i.type > 0\n GROUP BY i.name, i.is_unique`;\n const result = await this.connector.query(sql, [tableName, tableSchema]);\n return result.rows.map((row) => ({\n indexName: row.index_name as string,\n columns: (row.columns as string).split(','),\n isUnique: Boolean(row.is_unique),\n }));\n }\n\n const sql = this.isPostgresLike()\n ? `SELECT i.relname AS index_name, array_agg(a.attname ORDER BY k.n) AS columns, ix.indisunique AS is_unique\n FROM pg_index ix\n JOIN pg_class t ON t.oid = ix.indrelid\n JOIN pg_class i ON i.oid = ix.indexrelid\n JOIN pg_namespace n ON n.oid = t.relnamespace\n CROSS JOIN LATERAL unnest(ix.indkey) WITH ORDINALITY AS k(attnum, n)\n JOIN pg_attribute a ON a.attrelid = t.oid AND a.attnum = k.attnum\n WHERE t.relname = $1 AND n.nspname = $2\n GROUP BY i.relname, ix.indisunique`\n : `SELECT index_name AS index_name, GROUP_CONCAT(column_name ORDER BY seq_in_index) AS columns, NOT non_unique AS is_unique\n FROM information_schema.statistics\n WHERE table_name = $1 AND table_schema = $2\n GROUP BY index_name, non_unique`;\n\n const result = await this.connector.query(sql, [tableName, tableSchema]);\n return result.rows.map((row) => ({\n indexName: row.index_name as string,\n columns: Array.isArray(row.columns) ? row.columns as string[] : (row.columns as string).split(','),\n isUnique: Boolean(row.is_unique),\n }));\n }\n\n private async getSampleRows(tableName: string, tableSchema: string, limit = 5): Promise<Record<string, unknown>[]> {\n try {\n if (this.dbType === 'mongodb') {\n return (await this.connector.query(`SAMPLE:${tableName}:${limit}`)).rows;\n }\n if (this.dbType === 'mssql') {\n return (await this.connector.query(`SELECT TOP ${limit} * FROM [${tableSchema}].[${tableName}]`)).rows;\n }\n const qualifiedName = this.dbType === 'sqlite'\n ? `\"${tableName}\"`\n : this.isPostgresLike()\n ? `\"${tableSchema}\".\"${tableName}\"`\n : `\\`${tableSchema}\\`.\\`${tableName}\\``;\n const result = await this.connector.query(`SELECT * FROM ${qualifiedName} LIMIT ${limit}`);\n return result.rows;\n } catch {\n return [];\n }\n }\n\n private async getRowCount(tableName: string, tableSchema: string): Promise<number> {\n try {\n if (this.dbType === 'mongodb') {\n const result = await this.connector.query(`COUNT:${tableName}`);\n return Number(result.rows[0]?.count ?? 0);\n }\n if (this.dbType === 'sqlite') {\n const result = await this.connector.query(`SELECT COUNT(*) AS count FROM \"${tableName}\"`);\n return Number(result.rows[0]?.count ?? 0);\n }\n if (this.isPostgresLike()) {\n const result = await this.connector.query(\n `SELECT reltuples::bigint AS count FROM pg_class c JOIN pg_namespace n ON n.oid = c.relnamespace WHERE c.relname = $1 AND n.nspname = $2`,\n [tableName, tableSchema]\n );\n const count = Number(result.rows[0]?.count ?? 0);\n return count >= 0 ? count : 0;\n }\n if (this.dbType === 'mssql') {\n const result = await this.connector.query(\n `SELECT SUM(rows) AS count FROM sys.partitions WHERE object_id = OBJECT_ID($1) AND index_id IN (0, 1)`,\n [`${tableSchema}.${tableName}`]\n );\n return Number(result.rows[0]?.count ?? 0);\n }\n // MySQL / MariaDB\n const result = await this.connector.query(\n `SELECT table_rows AS count FROM information_schema.tables WHERE table_name = $1 AND table_schema = $2`,\n [tableName, tableSchema]\n );\n return Number(result.rows[0]?.count ?? 0);\n } catch {\n return 0;\n }\n }\n}\n","import type { LLMProvider } from '../llm/types.js';\nimport type { RawTable, ClassifiedEntity, EntityType } from './types.js';\nimport { LLMResponseError } from '../core/errors.js';\n\nconst DEFAULT_BATCH_SIZE = 5;\n\nexport class SchemaClassifier {\n private readonly llm: LLMProvider;\n private readonly batchSize: number;\n\n constructor(llm: LLMProvider, batchSize?: number) {\n this.llm = llm;\n this.batchSize = batchSize ?? DEFAULT_BATCH_SIZE;\n }\n\n async classify(tables: RawTable[]): Promise<ClassifiedEntity[]> {\n const batches = this.chunk(tables, this.batchSize);\n const results: ClassifiedEntity[] = [];\n\n for (const batch of batches) {\n const classified = await this.classifyBatch(batch);\n results.push(...classified);\n }\n\n return results;\n }\n\n private async classifyBatch(tables: RawTable[]): Promise<ClassifiedEntity[]> {\n const prompt = this.buildPrompt(tables);\n const chatOptions = { jsonMode: true, maxTokens: 8192 };\n let response = await this.llm.chat(prompt, chatOptions);\n try {\n return this.parseResponse(response.content);\n } catch {\n // One retry on parse failure — LLM may return valid JSON on second attempt\n response = await this.llm.chat(prompt, chatOptions);\n return this.parseResponse(response.content);\n }\n }\n\n private buildPrompt(tables: RawTable[]): string {\n const tablesContext = tables.map((t) => {\n const columnsStr = t.columns\n .map((c) => ` - ${c.columnName} (${c.dataType}, ${c.isNullable ? 'nullable' : 'not null'}${c.columnDefault ? `, default: ${c.columnDefault}` : ''})`)\n .join('\\n');\n\n const fkStr = t.foreignKeys.length > 0\n ? `\\n Foreign Keys:\\n${t.foreignKeys.map((fk) => ` - ${fk.columnName} -> ${fk.referencedTable}.${fk.referencedColumn}`).join('\\n')}`\n : '';\n\n const sampleStr = t.sampleRows.length > 0\n ? `\\n Sample Data (${t.sampleRows.length} rows): ${JSON.stringify(t.sampleRows[0])}`\n : '';\n\n return `Table: ${t.tableName} (schema: ${t.tableSchema}, ~${t.rowCount} rows)\\n Columns:\\n${columnsStr}${fkStr}${sampleStr}`;\n }).join('\\n\\n');\n\n return `You are a database schema analyst. Analyze the following database tables and classify each one.\n\nFor each table, return a JSON object with:\n- tableName: exact table name (must match input)\n- entityLabel: human-readable business name (e.g., \"User Account\", \"Sales Order\")\n- entityType: one of \"master\" (core business entities like Users, Products), \"transaction\" (events/activities like Orders, Payments), \"reference\" (lookup/config tables like Countries, Statuses), or \"junction\" (many-to-many link tables)\n- description: one sentence describing the table's business purpose\n- confidence: 0.0 to 1.0 indicating classification confidence\n- columns: array of { columnName, label, meaning } for each column\n\nReturn valid JSON in this exact format:\n{\n \"tables\": [\n {\n \"tableName\": \"...\",\n \"entityLabel\": \"...\",\n \"entityType\": \"master|transaction|reference|junction\",\n \"description\": \"...\",\n \"confidence\": 0.95,\n \"columns\": [\n { \"columnName\": \"...\", \"label\": \"...\", \"meaning\": \"...\" }\n ]\n }\n ]\n}\n\nDATABASE TABLES:\n\n${tablesContext}`;\n }\n\n private parseResponse(content: string): ClassifiedEntity[] {\n let data: {\n tables?: Array<{\n tableName: string;\n entityLabel: string;\n entityType: EntityType;\n description: string;\n confidence: number;\n columns?: Array<{ columnName: string; label: string; meaning: string }>;\n }>;\n };\n\n try {\n data = JSON.parse(content) as typeof data;\n } catch (err) {\n throw new LLMResponseError(\n `Failed to parse LLM response: ${(err as Error).message}`,\n content.slice(0, 500),\n );\n }\n\n if (!data.tables || !Array.isArray(data.tables)) {\n throw new LLMResponseError('Invalid LLM response: missing \"tables\" array', content.slice(0, 500));\n }\n\n return data.tables.map((t) => ({\n tableName: t.tableName,\n entityLabel: t.entityLabel,\n entityType: t.entityType,\n description: t.description,\n confidence: t.confidence,\n columns: (t.columns ?? []).map((c) => ({\n columnName: c.columnName,\n label: c.label,\n meaning: c.meaning,\n })),\n }));\n }\n\n private chunk<T>(array: T[], size: number): T[][] {\n const chunks: T[][] = [];\n for (let i = 0; i < array.length; i += size) {\n chunks.push(array.slice(i, i + size));\n }\n return chunks;\n }\n}\n","import type { RawTable, ClassifiedEntity, Relationship, EntityGraph } from './types.js';\n\nexport class GraphBuilder {\n build(rawTables: RawTable[], entities: ClassifiedEntity[]): EntityGraph {\n const entityMap = new Map(entities.map((e) => [e.tableName, e]));\n const relationships: Relationship[] = [];\n\n for (const table of rawTables) {\n for (const fk of table.foreignKeys) {\n const sourceEntity = entityMap.get(table.tableName);\n const targetEntity = entityMap.get(fk.referencedTable);\n\n const relationshipLabel = this.generateLabel(\n sourceEntity?.entityLabel ?? table.tableName,\n targetEntity?.entityLabel ?? fk.referencedTable,\n fk.columnName,\n );\n\n relationships.push({\n sourceEntity: table.tableName,\n targetEntity: fk.referencedTable,\n relationship: relationshipLabel,\n sourceColumn: fk.columnName,\n targetColumn: fk.referencedColumn,\n inferred: false,\n confidence: 1.0,\n });\n }\n }\n\n return { entities, relationships };\n }\n\n private generateLabel(\n sourceLabel: string,\n targetLabel: string,\n columnName: string,\n ): string {\n const cleaned = columnName.replace(/_id$/, '').replace(/_/g, ' ').toUpperCase();\n if (cleaned.length > 0) {\n return `HAS_${cleaned}`;\n }\n return `REFERENCES_${targetLabel.replace(/\\s+/g, '_').toUpperCase()}`;\n }\n}\n","import type { DatabaseConnector } from '../connectors/types.js';\nimport type { ConnectionConfig } from '../core/config.js';\nimport type { RawTable, ClassifiedEntity } from '../schema/types.js';\nimport type { BusinessEvent, Anomaly, RawChange, WatchOptions, TableWatchConfig } from './types.js';\nimport type { ChangeStream } from './streams/types.js';\nimport { ChangeDetector } from './change-detector.js';\nimport { EventClassifier, type EntityLookup } from './event-classifier.js';\nimport { PatternEngine, type PatternStorage } from './pattern-engine.js';\nimport { CapabilityDetector } from './capability-detector.js';\nimport { TransitionTracker } from '../reasoning/transition-tracker.js';\nimport type { WorkflowConfig, Insight } from '../reasoning/types.js';\nimport type { AnalyticsConfig } from '../analytics/types.js';\nimport { AnalyticsEngine } from '../analytics/analytics-engine.js';\nimport type { KnowledgeConfig } from '../knowledge/types.js';\nimport { GraphStore } from '../knowledge/graph-store.js';\nimport { GraphPopulator } from '../knowledge/graph-populator.js';\nimport type { ActionsConfig } from '../actions/types.js';\nimport { ActionRegistry } from '../actions/action-registry.js';\nimport { ActionMatcher } from '../actions/action-matcher.js';\nimport { ActionExecutor } from '../actions/action-executor.js';\nimport { createLogger } from '../core/logger.js';\n\nexport interface WatcherStorage extends EntityLookup, PatternStorage {\n saveEvent(event: { eventType: string; entity: string; tableName: string; operation: string; rowId?: string; rowData?: string }): void;\n saveWatermark(wm: { tableName: string; tableSchema: string; strategy: string; timestampColumn?: string; pkColumn?: string; lastSeenValue?: string }): void;\n getWatermark(tableName: string, tableSchema: string): { strategy: string; timestampColumn: string | null; pkColumn: string | null; lastSeenValue: string | null } | undefined;\n getEntities(): ClassifiedEntity[];\n saveTransition(t: { entity: string; tableName: string; primaryKey: string; fromState: string; toState: string; durationMs: number; expected: boolean }): void;\n saveInsight(i: { entity: string; insightType: string; severity: string; message: string; context: Record<string, unknown> }): void;\n getInsights(filter?: { entity?: string; last?: number }): Array<{ entity: string; insightType: string; severity: string; message: string; context: Record<string, unknown>; timestamp: string }>;\n saveEntityState(s: { tableName: string; primaryKey: string; state: string; enteredAt: string }): void;\n getEntityState(tableName: string, primaryKey: string): { state: string; enteredAt: string } | undefined;\n getStuckEntityStates(tableName: string, thresholdMs: number): Array<{ primaryKey: string; state: string; enteredAt: string }>;\n // Analytics storage methods\n saveCorrelationEvent(event: { entity: string; eventType: string; primaryKey: string }): void;\n getCorrelationEvents(entity: string, lastMinutes: number): Array<{ entity: string; eventType: string; primaryKey: string; timestamp: string }>;\n saveCorrelationRate(rate: { entity: string; bucket: string; eventCount: number }): void;\n getCorrelationRates(entity: string, lastHours: number): Array<{ entity: string; bucket: string; eventCount: number }>;\n saveHistogramBucket(bucket: { entity: string; columnName: string; bucketKey: string; count: number; period: string }): void;\n getHistogramBuckets(entity: string, columnName: string, period: string): Array<{ bucketKey: string; count: number }>;\n saveTemporalPattern(pattern: { entity: string; bucketType: string; bucketKey: number; count: number; period: string }): void;\n getTemporalPatterns(entity: string, bucketType: string, period: string): Array<{ bucketKey: number; count: number }>;\n getAnalyticsBaseline(key: string): { mean: number; stddev: number; sampleSize: number } | undefined;\n saveAnalyticsBaseline(baseline: { key: string; mean: number; stddev: number; sampleSize: number }): void;\n // Knowledge Graph storage methods\n saveKgNode(node: { nodeType: string; refId: string; label: string; metadata: string }): number;\n getKgNode(id: number): { id: number; nodeType: string; refId: string; label: string; metadata: string; timestamp: string } | undefined;\n getKgNodeByRef(nodeType: string, refId: string): { id: number; nodeType: string; refId: string; label: string; metadata: string; timestamp: string } | undefined;\n getKgNodesByType(nodeType: string): Array<{ id: number; nodeType: string; refId: string; label: string; metadata: string; timestamp: string }>;\n getAllKgNodes(): Array<{ id: number; nodeType: string; refId: string; label: string; metadata: string; timestamp: string }>;\n deleteKgNode(id: number): void;\n saveKgEdge(edge: { sourceId: number; targetId: number; edgeType: string; weight: number; metadata: string }): number;\n getKgEdgesFrom(nodeId: number, edgeType?: string): Array<{ id: number; sourceId: number; targetId: number; edgeType: string; weight: number; metadata: string; timestamp: string }>;\n getKgEdgesTo(nodeId: number, edgeType?: string): Array<{ id: number; sourceId: number; targetId: number; edgeType: string; weight: number; metadata: string; timestamp: string }>;\n getAllKgEdges(): Array<{ id: number; sourceId: number; targetId: number; edgeType: string; weight: number; metadata: string; timestamp: string }>;\n getKgSummary(): { totalNodes: number; totalEdges: number; entities: number; events: number; anomalies: number; insights: number };\n // Actions storage methods\n saveRecommendation(rec: { action: string; reason: string; confidence: number; status: string; governance: string; insightId: string | null; entity: string; context: string }): number;\n getRecommendation(id: number): { id: number; action: string; reason: string; confidence: number; status: string; governance: string; insightId: string | null; entity: string; context: string; createdAt: string; resolvedAt: string | null; resolvedBy: string | null } | undefined;\n updateRecommendationStatus(id: number, status: string, resolvedBy: string): void;\n}\n\nexport interface WatcherConfig {\n connector: DatabaseConnector;\n dbType: ConnectionConfig['type'];\n storage: WatcherStorage;\n tables: RawTable[];\n connectionConfig?: ConnectionConfig;\n onEvent?: (event: BusinessEvent) => void;\n onAnomaly?: (anomaly: Anomaly) => void;\n onInsight?: (insight: Insight) => void;\n workflows?: Record<string, WorkflowConfig>;\n analytics?: AnalyticsConfig;\n knowledge?: KnowledgeConfig;\n actions?: ActionsConfig;\n actionRegistry?: ActionRegistry;\n onRecommendation?: (rec: Record<string, unknown>) => void;\n onActionExecuted?: (rec: Record<string, unknown>) => void;\n onActionFailed?: (rec: Record<string, unknown>) => void;\n}\n\nexport class Watcher {\n private readonly config: WatcherConfig;\n private readonly detector: ChangeDetector;\n private readonly classifier: EventClassifier;\n private readonly logger = createLogger({ name: 'watcher' });\n private patternEngine: PatternEngine | null = null;\n private transitionTracker: TransitionTracker | null = null;\n private analyticsEngine: AnalyticsEngine | null = null;\n private graphPopulator: GraphPopulator | null = null;\n private actionExecutor: ActionExecutor | null = null;\n private stuckInterval: ReturnType<typeof setInterval> | null = null;\n private analyticsInterval: ReturnType<typeof setInterval> | null = null;\n private interval: ReturnType<typeof setInterval> | null = null;\n private stream: ChangeStream | null = null;\n private _streaming = false;\n private watchConfigs: TableWatchConfig[] = [];\n\n constructor(config: WatcherConfig) {\n this.config = config;\n this.detector = new ChangeDetector(config.connector, config.dbType);\n this.classifier = new EventClassifier(config.storage);\n\n if (config.workflows && Object.keys(config.workflows).length > 0) {\n this.transitionTracker = new TransitionTracker(\n config.workflows,\n config.storage,\n (insight: Insight) => {\n config.onInsight?.(insight);\n this.graphPopulator?.onInsight(insight);\n this.actionExecutor?.onInsight(insight);\n },\n );\n }\n\n const hasAnalytics = config.analytics &&\n (Object.keys(config.analytics.correlations ?? {}).length > 0 ||\n Object.keys(config.analytics.distributions ?? {}).length > 0);\n\n if (hasAnalytics) {\n const analyticsStorage = {\n saveCorrelationEvent: config.storage.saveCorrelationEvent.bind(config.storage),\n getCorrelationEvents: config.storage.getCorrelationEvents.bind(config.storage),\n saveCorrelationRate: config.storage.saveCorrelationRate.bind(config.storage),\n getCorrelationRates: config.storage.getCorrelationRates.bind(config.storage),\n saveHistogramBucket: config.storage.saveHistogramBucket.bind(config.storage),\n getHistogramBuckets: config.storage.getHistogramBuckets.bind(config.storage),\n saveTemporalPattern: config.storage.saveTemporalPattern.bind(config.storage),\n getTemporalPatterns: config.storage.getTemporalPatterns.bind(config.storage),\n saveInsight: config.storage.saveInsight.bind(config.storage),\n getBaseline: config.storage.getAnalyticsBaseline.bind(config.storage),\n saveBaseline: config.storage.saveAnalyticsBaseline.bind(config.storage),\n };\n this.analyticsEngine = new AnalyticsEngine(\n config.analytics!,\n analyticsStorage,\n (insight: Insight) => {\n config.onInsight?.(insight);\n this.graphPopulator?.onInsight(insight);\n this.actionExecutor?.onInsight(insight);\n },\n );\n }\n\n if (config.knowledge?.enabled) {\n const graphStore = new GraphStore({\n saveKgNode: config.storage.saveKgNode.bind(config.storage),\n getKgNode: config.storage.getKgNode.bind(config.storage),\n getKgNodeByRef: config.storage.getKgNodeByRef.bind(config.storage),\n getKgNodesByType: config.storage.getKgNodesByType.bind(config.storage),\n getAllKgNodes: config.storage.getAllKgNodes.bind(config.storage),\n deleteKgNode: config.storage.deleteKgNode.bind(config.storage),\n saveKgEdge: config.storage.saveKgEdge.bind(config.storage),\n getKgEdgesFrom: config.storage.getKgEdgesFrom.bind(config.storage),\n getKgEdgesTo: config.storage.getKgEdgesTo.bind(config.storage),\n getAllKgEdges: config.storage.getAllKgEdges.bind(config.storage),\n getKgSummary: config.storage.getKgSummary.bind(config.storage),\n });\n this.graphPopulator = new GraphPopulator(graphStore);\n this.graphPopulator.populateFromSchema(config.tables);\n }\n\n if (config.actions?.enabled && config.actions.rules && config.actions.rules.length > 0) {\n const actionRegistry = config.actionRegistry ?? new ActionRegistry(config.actions.governance);\n const actionMatcher = new ActionMatcher(config.actions.rules);\n const actionStorage = {\n saveRecommendation: config.storage.saveRecommendation.bind(config.storage),\n getRecommendation: config.storage.getRecommendation.bind(config.storage),\n updateRecommendationStatus: config.storage.updateRecommendationStatus.bind(config.storage),\n };\n this.actionExecutor = new ActionExecutor(actionRegistry, actionMatcher, actionStorage);\n\n this.actionExecutor.on('recommendation', (rec: Record<string, unknown>) => {\n config.onRecommendation?.(rec);\n });\n this.actionExecutor.on('action:executed', (rec: Record<string, unknown>) => {\n config.onActionExecuted?.(rec);\n });\n this.actionExecutor.on('action:failed', (rec: Record<string, unknown>) => {\n config.onActionFailed?.(rec);\n });\n }\n }\n\n async start(options?: WatchOptions): Promise<void> {\n if (this.interval || this.stream) throw new Error('Watcher already running');\n\n this.patternEngine = new PatternEngine(this.config.storage, {\n anomalyThreshold: options?.anomalyThreshold,\n });\n\n // Single poll mode: run one cycle and return\n if (options?.once) {\n this.watchConfigs = ChangeDetector.buildWatchConfigs(\n this.config.tables,\n options?.excludeTables,\n );\n for (const wc of this.watchConfigs) {\n const saved = this.config.storage.getWatermark(wc.tableName, wc.tableSchema);\n if (saved?.lastSeenValue) {\n wc.lastSeenValue = saved.lastSeenValue;\n }\n }\n await this.pollCycle(options?.excludeColumns);\n return;\n }\n\n // Attempt streaming if not explicitly preferring polling and connectionConfig is available\n if (!options?.preferPolling && this.config.connectionConfig) {\n const started = await this.tryStartStreaming(options);\n if (started) {\n this.startStuckCheckInterval(options);\n return;\n }\n }\n\n // Fall back to polling\n this.watchConfigs = ChangeDetector.buildWatchConfigs(\n this.config.tables,\n options?.excludeTables\n );\n\n // Restore watermarks from storage\n for (const config of this.watchConfigs) {\n const saved = this.config.storage.getWatermark(config.tableName, config.tableSchema);\n if (saved?.lastSeenValue) {\n config.lastSeenValue = saved.lastSeenValue;\n }\n }\n\n const excludeColumns = options?.excludeColumns;\n const intervalMs = options?.interval ?? 5000;\n\n this.interval = setInterval(async () => {\n await this.pollCycle(excludeColumns);\n }, intervalMs);\n\n this.startStuckCheckInterval(options);\n }\n\n stop(): void {\n if (this.interval) {\n clearInterval(this.interval);\n this.interval = null;\n }\n if (this.stuckInterval) {\n clearInterval(this.stuckInterval);\n this.stuckInterval = null;\n }\n if (this.analyticsInterval) {\n clearInterval(this.analyticsInterval);\n this.analyticsInterval = null;\n }\n if (this.stream) {\n this.stream.stop().catch((err) => {\n this.logger.error({ error: (err as Error).message }, 'Error stopping stream');\n });\n this.stream = null;\n }\n this._streaming = false;\n }\n\n async cleanup(): Promise<void> {\n const stream = this.stream;\n this.stop();\n if (stream) {\n await stream.cleanup();\n }\n }\n\n isRunning(): boolean {\n return this.interval !== null || (this.stream !== null && this.stream.isRunning());\n }\n\n isStreaming(): boolean {\n return this._streaming;\n }\n\n private startStuckCheckInterval(options?: WatchOptions): void {\n if (this.transitionTracker) {\n this.stuckInterval = setInterval(() => {\n this.transitionTracker?.checkStuck();\n }, options?.stuckCheckInterval ?? 60000);\n }\n\n if (this.analyticsEngine) {\n this.analyticsInterval = setInterval(() => {\n this.analyticsEngine?.runPeriodicChecks();\n }, options?.stuckCheckInterval ?? 60000);\n }\n }\n\n private async tryStartStreaming(options?: WatchOptions): Promise<boolean> {\n const capDetector = new CapabilityDetector(this.config.connector, this.config.dbType);\n const capability = await capDetector.detect();\n\n if (!capability.canStream) {\n this.logger.info({ reason: capability.reason }, 'Streaming not available, will use polling');\n return false;\n }\n\n try {\n const stream = await this.createStream();\n if (!stream) {\n this.logger.info('Streaming package not installed. Falling back to polling.');\n return false;\n }\n\n await stream.start((change: RawChange) => {\n this.handleChange(change, options?.excludeColumns);\n });\n\n this.stream = stream;\n this._streaming = true;\n this.logger.info('Using streaming mode for change detection');\n return true;\n } catch (error) {\n this.logger.error({ error: (error as Error).message }, 'Failed to start streaming, falling back to polling');\n return false;\n }\n }\n\n private async createStream(): Promise<ChangeStream | null> {\n if (this.config.dbType === 'postgres' || this.config.dbType === 'cockroachdb') {\n try {\n const { PostgresStream } = await import('./streams/postgres-stream.js');\n return new PostgresStream(this.config.connectionConfig!, this.config.connector);\n } catch {\n return null;\n }\n }\n if (this.config.dbType === 'mysql' || this.config.dbType === 'mariadb') {\n try {\n const { MySQLStream } = await import('./streams/mysql-stream.js');\n return new MySQLStream(this.config.connectionConfig!, this.config.connector);\n } catch {\n return null;\n }\n }\n if (this.config.dbType === 'mongodb') {\n try {\n const { MongoDBStream } = await import('./streams/mongodb-stream.js');\n return new MongoDBStream(this.config.connectionConfig!);\n } catch {\n return null;\n }\n }\n return null;\n }\n\n private handleChange(change: RawChange, excludeColumns?: string[]): string {\n const event = this.classifier.classify(change, { excludeColumns });\n\n this.config.storage.saveEvent({\n eventType: `${event.entity} ${event.type}`,\n entity: event.entity,\n tableName: event.table,\n operation: change.operation,\n rowId: String(event.primaryKey),\n rowData: JSON.stringify(event.metadata),\n });\n\n this.config.onEvent?.(event);\n\n if (this.patternEngine) {\n this.patternEngine.updateBaselines([event.entity], change.operation);\n const anomalies = this.patternEngine.checkRateAnomalies([event.entity], change.operation);\n for (const anomaly of anomalies) {\n this.config.onAnomaly?.(anomaly);\n }\n }\n\n if (this.transitionTracker && change.operation === 'UPDATE') {\n this.transitionTracker.handleChange(change);\n }\n\n if (this.analyticsEngine) {\n this.analyticsEngine.handleEvent(\n event.entity,\n event.type,\n String(event.primaryKey),\n event.metadata,\n change.detectedAt,\n );\n }\n\n if (this.graphPopulator) {\n this.graphPopulator.onEvent(\n event.entity,\n event.type,\n String(event.primaryKey),\n event.metadata,\n );\n }\n\n return event.entity;\n }\n\n private async pollCycle(excludeColumns?: string[]): Promise<void> {\n const allEntities = new Set<string>();\n\n for (const config of this.watchConfigs) {\n try {\n const changes = await this.detector.poll(config);\n\n for (const change of changes) {\n const entity = this.handleChange(change, excludeColumns);\n allEntities.add(entity);\n }\n\n // Update watermark\n if (changes.length > 0) {\n const lastChange = changes[changes.length - 1];\n const lastValue = config.strategy === 'timestamp'\n ? String(lastChange.newData?.[config.timestampColumn!] ?? '')\n : String(lastChange.primaryKey);\n\n config.lastSeenValue = lastValue;\n }\n\n // Always persist watermark (even if no changes, to track that we polled)\n this.config.storage.saveWatermark({\n tableName: config.tableName,\n tableSchema: config.tableSchema,\n strategy: config.strategy,\n timestampColumn: config.timestampColumn,\n pkColumn: config.primaryKeyColumn,\n lastSeenValue: config.lastSeenValue,\n });\n } catch (error) {\n this.logger.error({ table: config.tableName, error: (error as Error).message }, 'Poll error');\n }\n }\n }\n}\n","import type { ConnectionConfig } from '../core/config.js';\nimport type { DatabaseConnector } from '../connectors/types.js';\nimport type { RawTable } from '../schema/types.js';\nimport type { RawChange, TableWatchConfig, TableStats } from './types.js';\n\nconst TIMESTAMP_COLUMNS = ['updated_at', 'modified_at', 'last_modified', 'updatedat', 'modifiedat'];\nconst AUTO_INCREMENT_PATTERNS = ['nextval', 'auto_increment', 'serial', 'identity'];\n\nexport class ChangeDetector {\n private readonly connector: DatabaseConnector;\n private readonly dbType: ConnectionConfig['type'];\n\n constructor(connector: DatabaseConnector, dbType: ConnectionConfig['type']) {\n this.connector = connector;\n this.dbType = dbType;\n }\n\n static buildWatchConfigs(tables: RawTable[], excludeTables?: string[]): TableWatchConfig[] {\n const excludeSet = new Set(excludeTables?.map((t) => t.toLowerCase()) ?? []);\n const configs: TableWatchConfig[] = [];\n\n for (const table of tables) {\n if (excludeSet.has(table.tableName.toLowerCase())) continue;\n\n const timestampCol = table.columns.find((c) =>\n TIMESTAMP_COLUMNS.includes(c.columnName.toLowerCase()) &&\n c.dataType.toLowerCase().includes('timestamp')\n );\n\n if (timestampCol) {\n const pkCol = table.columns.find((c) =>\n c.columnName.toLowerCase() === 'id' && !c.isNullable\n );\n configs.push({\n tableName: table.tableName,\n tableSchema: table.tableSchema,\n strategy: 'timestamp',\n timestampColumn: timestampCol.columnName,\n primaryKeyColumn: pkCol?.columnName ?? table.columns[0].columnName,\n });\n continue;\n }\n\n const autoIncrementCol = table.columns.find((c) =>\n c.columnDefault !== null &&\n AUTO_INCREMENT_PATTERNS.some((p) => (c.columnDefault ?? '').toLowerCase().includes(p))\n );\n\n if (autoIncrementCol) {\n configs.push({\n tableName: table.tableName,\n tableSchema: table.tableSchema,\n strategy: 'id_watermark',\n primaryKeyColumn: autoIncrementCol.columnName,\n });\n continue;\n }\n\n configs.push({\n tableName: table.tableName,\n tableSchema: table.tableSchema,\n strategy: 'table_stats',\n });\n }\n\n return configs;\n }\n\n async poll(config: TableWatchConfig): Promise<RawChange[]> {\n if (config.strategy === 'timestamp') {\n return this.pollTimestamp(config);\n }\n if (config.strategy === 'id_watermark') {\n return this.pollIdWatermark(config);\n }\n if (config.strategy === 'table_stats') {\n return this.pollTableStats(config);\n }\n return [];\n }\n\n private async pollTimestamp(config: TableWatchConfig): Promise<RawChange[]> {\n const qualified = this.qualifyTable(config.tableName, config.tableSchema);\n const tsCol = config.timestampColumn!;\n const pkCol = config.primaryKeyColumn ?? 'id';\n\n const lastSeen = config.lastSeenValue ?? '1970-01-01T00:00:00Z';\n const result = await this.connector.query(\n `SELECT * FROM ${qualified} WHERE ${this.quoteIdent(tsCol)} > $1 ORDER BY ${this.quoteIdent(tsCol)} ASC`,\n [lastSeen]\n );\n\n return result.rows.map((row) => ({\n tableName: config.tableName,\n tableSchema: config.tableSchema,\n operation: 'UPDATE' as const,\n primaryKey: row[pkCol] as string | number,\n newData: { ...row },\n detectedAt: new Date(),\n }));\n }\n\n private async pollIdWatermark(config: TableWatchConfig): Promise<RawChange[]> {\n const qualified = this.qualifyTable(config.tableName, config.tableSchema);\n const pkCol = config.primaryKeyColumn!;\n\n const lastSeen = config.lastSeenValue ?? '0';\n const result = await this.connector.query(\n `SELECT * FROM ${qualified} WHERE ${this.quoteIdent(pkCol)} > $1 ORDER BY ${this.quoteIdent(pkCol)} ASC`,\n [lastSeen]\n );\n\n return result.rows.map((row) => ({\n tableName: config.tableName,\n tableSchema: config.tableSchema,\n operation: 'INSERT' as const,\n primaryKey: row[pkCol] as string | number,\n newData: { ...row },\n detectedAt: new Date(),\n }));\n }\n\n private async pollTableStats(config: TableWatchConfig): Promise<RawChange[]> {\n const currentStats = await this.queryTableStats(config.tableName, config.tableSchema);\n\n // First poll — initialize baseline, no changes\n if (!config.lastStats) {\n config.lastStats = currentStats;\n return [];\n }\n\n const prev = config.lastStats;\n const changes: RawChange[] = [];\n\n const newInserts = currentStats.inserts - prev.inserts;\n const newUpdates = currentStats.updates - prev.updates;\n const newDeletes = currentStats.deletes - prev.deletes;\n\n config.lastStats = currentStats;\n\n if (newInserts === 0 && newUpdates === 0 && newDeletes === 0) return [];\n\n if (newInserts > 0) {\n changes.push({\n tableName: config.tableName,\n tableSchema: config.tableSchema,\n operation: 'INSERT',\n primaryKey: 'unknown',\n detectedAt: new Date(),\n });\n }\n\n if (newUpdates > 0) {\n changes.push({\n tableName: config.tableName,\n tableSchema: config.tableSchema,\n operation: 'UPDATE',\n primaryKey: 'unknown',\n detectedAt: new Date(),\n });\n }\n\n if (newDeletes > 0) {\n changes.push({\n tableName: config.tableName,\n tableSchema: config.tableSchema,\n operation: 'DELETE',\n primaryKey: 'unknown',\n detectedAt: new Date(),\n });\n }\n\n return changes;\n }\n\n private async queryTableStats(tableName: string, tableSchema: string): Promise<TableStats> {\n if (this.dbType === 'postgres' || this.dbType === 'cockroachdb') {\n const result = await this.connector.query(\n `SELECT COALESCE(n_tup_ins, 0) AS inserts, COALESCE(n_tup_upd, 0) AS updates, COALESCE(n_tup_del, 0) AS deletes\n FROM pg_stat_user_tables WHERE relname = $1 AND schemaname = $2`,\n [tableName, tableSchema]\n );\n if (result.rows.length === 0) return { inserts: 0, updates: 0, deletes: 0 };\n const row = result.rows[0];\n return {\n inserts: parseInt(String(row.inserts), 10),\n updates: parseInt(String(row.updates), 10),\n deletes: parseInt(String(row.deletes), 10),\n };\n }\n\n if (this.dbType === 'sqlite') {\n // SQLite has no per-operation counters; track total row count as insert proxy\n const result = await this.connector.query(\n `SELECT COUNT(*) AS row_count FROM \"${tableName}\"`\n );\n const rowCount = parseInt(String(result.rows[0]?.row_count ?? 0), 10);\n return { inserts: rowCount, updates: 0, deletes: 0 };\n }\n\n if (this.dbType === 'mongodb') {\n // MongoDB: track document count as insert proxy\n const result = await this.connector.query(`COUNT:${tableName}`);\n const docCount = parseInt(String(result.rows[0]?.count ?? 0), 10);\n return { inserts: docCount, updates: 0, deletes: 0 };\n }\n\n if (this.dbType === 'mssql') {\n const result = await this.connector.query(\n `SELECT SUM(rows) AS row_count FROM sys.partitions WHERE object_id = OBJECT_ID($1) AND index_id IN (0, 1)`,\n [`${tableSchema}.${tableName}`]\n );\n const rowCount = parseInt(String(result.rows[0]?.row_count ?? 0), 10);\n return { inserts: rowCount, updates: 0, deletes: 0 };\n }\n\n // MySQL / MariaDB: use information_schema table statistics\n const result = await this.connector.query(\n `SELECT TABLE_ROWS, UPDATE_TIME FROM information_schema.TABLES WHERE TABLE_NAME = $1 AND TABLE_SCHEMA = $2`,\n [tableName, tableSchema]\n );\n if (result.rows.length === 0) return { inserts: 0, updates: 0, deletes: 0 };\n const row = result.rows[0];\n const rowCount = parseInt(String(row.TABLE_ROWS ?? 0), 10);\n const updateTime = row.UPDATE_TIME ? new Date(String(row.UPDATE_TIME)).getTime() : 0;\n return { inserts: rowCount, updates: updateTime, deletes: 0 };\n }\n\n private qualifyTable(tableName: string, tableSchema: string): string {\n if (this.dbType === 'postgres' || this.dbType === 'cockroachdb') {\n return `\"${tableSchema}\".\"${tableName}\"`;\n }\n if (this.dbType === 'sqlite') {\n return `\"${tableName}\"`;\n }\n if (this.dbType === 'mssql') {\n return `[${tableSchema}].[${tableName}]`;\n }\n if (this.dbType === 'mongodb') {\n return tableName;\n }\n return `\\`${tableSchema}\\`.\\`${tableName}\\``;\n }\n\n private quoteIdent(name: string): string {\n if (this.dbType === 'postgres' || this.dbType === 'cockroachdb' || this.dbType === 'sqlite') {\n return `\"${name}\"`;\n }\n if (this.dbType === 'mssql') {\n return `[${name}]`;\n }\n return `\\`${name}\\``;\n }\n}\n","import type { RawChange, BusinessEvent } from './types.js';\nimport type { ClassifiedEntity, EntityType } from '../schema/types.js';\n\nexport interface EntityLookup {\n getEntity(tableName: string): ClassifiedEntity | undefined;\n}\n\nconst OPERATION_MAP: Record<RawChange['operation'], BusinessEvent['type']> = {\n INSERT: 'created',\n UPDATE: 'updated',\n DELETE: 'deleted',\n};\n\nexport class EventClassifier {\n private readonly entityLookup: EntityLookup;\n\n constructor(entityLookup: EntityLookup) {\n this.entityLookup = entityLookup;\n }\n\n classify(change: RawChange, options?: { excludeColumns?: string[] }): BusinessEvent {\n const entity = this.entityLookup.getEntity(change.tableName);\n const excludeSet = new Set(options?.excludeColumns?.map((c) => c.toLowerCase()) ?? []);\n\n const metadata = this.filterMetadata(change.newData ?? change.oldData ?? {}, excludeSet);\n\n return {\n entity: entity?.entityLabel ?? change.tableName,\n entityType: (entity?.entityType ?? 'reference') as EntityType,\n type: OPERATION_MAP[change.operation],\n table: change.tableName,\n primaryKey: change.primaryKey,\n timestamp: change.detectedAt,\n changedColumns: change.changedColumns,\n metadata,\n };\n }\n\n private filterMetadata(\n data: Record<string, unknown>,\n excludeSet: Set<string>\n ): Record<string, unknown> {\n if (excludeSet.size === 0) return { ...data };\n const filtered: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(data)) {\n if (!excludeSet.has(key.toLowerCase())) {\n filtered[key] = value;\n }\n }\n return filtered;\n }\n}\n","import type { Anomaly, Baseline } from './types.js';\n\nexport interface PatternStorage {\n getBaselines(): Baseline[];\n saveBaseline(baseline: { entity: string; metric: string; mean: number; stddev: number; sampleSize: number }): void;\n saveAnomaly(anomaly: { entity: string; anomalyType: string; severity: string; expected: number; actual: number; message: string }): void;\n countEvents(entity: string, operation: string, lastMinutes: number): number;\n}\n\nconst MIN_SAMPLE_SIZE = 12;\nconst DEFAULT_ANOMALY_THRESHOLD = 2;\n\nexport class PatternEngine {\n private readonly storage: PatternStorage;\n private readonly anomalyThreshold: number;\n\n constructor(storage: PatternStorage, options?: { anomalyThreshold?: number }) {\n this.storage = storage;\n this.anomalyThreshold = options?.anomalyThreshold ?? DEFAULT_ANOMALY_THRESHOLD;\n }\n\n updateBaselines(entities: string[], operation: string): void {\n const baselines = this.storage.getBaselines();\n const baselineMap = new Map(baselines.map((b) => [`${b.entity}:${b.metric}`, b]));\n\n for (const entity of entities) {\n const metric = `${operation}_per_hour`;\n const currentCount = this.storage.countEvents(entity, operation, 60);\n const key = `${entity}:${metric}`;\n const existing = baselineMap.get(key);\n\n if (!existing) {\n this.storage.saveBaseline({\n entity,\n metric,\n mean: currentCount,\n stddev: 0,\n sampleSize: 1,\n });\n } else {\n const n = existing.sampleSize;\n const newN = n + 1;\n const newMean = existing.mean + (currentCount - existing.mean) / newN;\n const newStddev = Math.sqrt(\n ((n - 1) * existing.stddev * existing.stddev + (currentCount - existing.mean) * (currentCount - newMean)) / Math.max(n, 1)\n );\n\n this.storage.saveBaseline({\n entity,\n metric,\n mean: newMean,\n stddev: newStddev,\n sampleSize: newN,\n });\n }\n }\n }\n\n checkRateAnomalies(entities: string[], operation: string): Anomaly[] {\n const baselines = this.storage.getBaselines();\n const baselineMap = new Map(baselines.map((b) => [`${b.entity}:${b.metric}`, b]));\n const anomalies: Anomaly[] = [];\n\n for (const entity of entities) {\n const metric = `${operation}_per_hour`;\n const baseline = baselineMap.get(`${entity}:${metric}`);\n if (!baseline || baseline.sampleSize < MIN_SAMPLE_SIZE || baseline.stddev === 0) continue;\n\n const currentCount = this.storage.countEvents(entity, operation, 60);\n const deviation = Math.abs(currentCount - baseline.mean) / baseline.stddev;\n\n if (deviation >= this.anomalyThreshold) {\n const anomalyType = currentCount > baseline.mean ? 'rate_spike' : 'rate_drop';\n const severity = PatternEngine.getSeverity(deviation);\n const anomaly: Anomaly = {\n entity,\n anomalyType,\n severity,\n expected: baseline.mean,\n actual: currentCount,\n message: `${entity} ${operation} rate ${anomalyType === 'rate_spike' ? 'spiked' : 'dropped'} to ${currentCount}/hr (expected ${baseline.mean.toFixed(0)}±${baseline.stddev.toFixed(0)})`,\n timestamp: new Date(),\n };\n\n this.storage.saveAnomaly({\n entity: anomaly.entity,\n anomalyType: anomaly.anomalyType,\n severity: anomaly.severity,\n expected: anomaly.expected,\n actual: anomaly.actual,\n message: anomaly.message,\n });\n\n anomalies.push(anomaly);\n }\n }\n\n return anomalies;\n }\n\n static getSeverity(sigma: number): Anomaly['severity'] {\n if (sigma >= 5) return 'critical';\n if (sigma >= 4) return 'high';\n if (sigma >= 3) return 'medium';\n return 'low';\n }\n}\n","import type { ConnectionConfig } from '../core/config.js';\nimport type { DatabaseConnector } from '../connectors/types.js';\nimport type { StreamCapability } from './types.js';\n\nexport class CapabilityDetector {\n private readonly connector: DatabaseConnector;\n private readonly dbType: ConnectionConfig['type'];\n\n constructor(connector: DatabaseConnector, dbType: ConnectionConfig['type']) {\n this.connector = connector;\n this.dbType = dbType;\n }\n\n async detect(): Promise<StreamCapability> {\n switch (this.dbType) {\n case 'postgres':\n return this.detectPostgres();\n case 'cockroachdb':\n return { canStream: false, reason: 'CockroachDB changefeed not yet supported. Polling mode will be used.' };\n case 'mysql':\n case 'mariadb':\n return this.detectMysql();\n case 'sqlite':\n return { canStream: false, reason: 'SQLite does not support CDC streaming. Polling mode will be used.' };\n case 'mongodb':\n return this.detectMongodb();\n case 'mssql':\n return { canStream: false, reason: 'SQL Server CDC not yet supported. Polling mode will be used.' };\n default:\n return { canStream: false, reason: `Unsupported database type: ${this.dbType as string}` };\n }\n }\n\n private async detectMongodb(): Promise<StreamCapability> {\n try {\n const result = await this.connector.query('COMMAND:{\"replSetGetStatus\":1}');\n if (result.rows.length > 0) {\n return { canStream: true, reason: 'MongoDB Change Streams supported (replica set detected)' };\n }\n return { canStream: false, reason: 'MongoDB Change Streams require a replica set. Polling mode will be used.' };\n } catch {\n return { canStream: false, reason: 'MongoDB Change Streams require a replica set. Polling mode will be used.' };\n }\n }\n\n private async detectPostgres(): Promise<StreamCapability> {\n try {\n const walResult = await this.connector.query(\n \"SELECT current_setting('wal_level') AS wal_level\"\n );\n\n const walLevel = String(walResult.rows[0]?.wal_level ?? '').toLowerCase();\n if (walLevel !== 'logical') {\n return {\n canStream: false,\n reason: \"wal_level is not set to 'logical'. Set wal_level = logical in postgresql.conf and restart.\",\n };\n }\n\n const roleResult = await this.connector.query(\n 'SELECT rolreplication FROM pg_roles WHERE rolname = current_user'\n );\n\n const rolreplication = roleResult.rows[0]?.rolreplication;\n if (rolreplication !== true) {\n return {\n canStream: false,\n reason: 'Current user lacks REPLICATION privilege required for WAL streaming',\n };\n }\n\n return { canStream: true, reason: 'WAL streaming supported' };\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n return { canStream: false, reason: `Capability detection failed: ${message}` };\n }\n }\n\n private async detectMysql(): Promise<StreamCapability> {\n try {\n const logBinResult = await this.connector.query(\"SHOW VARIABLES LIKE 'log_bin'\");\n\n const logBinValue = String(logBinResult.rows[0]?.Value ?? '').toUpperCase();\n if (logBinValue !== 'ON') {\n return {\n canStream: false,\n reason: 'log_bin is not ON; binlog streaming requires log_bin = ON',\n };\n }\n\n const binlogFormatResult = await this.connector.query(\"SHOW VARIABLES LIKE 'binlog_format'\");\n\n const binlogFormatValue = String(binlogFormatResult.rows[0]?.Value ?? '').toUpperCase();\n if (binlogFormatValue !== 'ROW') {\n return {\n canStream: false,\n reason: `binlog_format is '${binlogFormatValue}', must be 'ROW' for binlog streaming`,\n };\n }\n\n return { canStream: true, reason: 'Binlog streaming supported' };\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n return { canStream: false, reason: `Capability detection failed: ${message}` };\n }\n }\n}\n","import type { RawChange } from '../behavioral/types.js';\nimport type { WorkflowConfig, Insight, Severity, InsightType } from './types.js';\nimport { parseTransitionDuration } from './types.js';\nimport { createLogger } from '../core/logger.js';\n\nconst logger = createLogger({ name: 'transition-tracker' });\n\nexport interface TransitionStorage {\n saveTransition(t: {\n entity: string;\n tableName: string;\n primaryKey: string;\n fromState: string;\n toState: string;\n durationMs: number;\n expected: boolean;\n }): void;\n saveInsight(i: {\n entity: string;\n insightType: string;\n severity: string;\n message: string;\n context: Record<string, unknown>;\n }): void;\n getInsights(filter?: {\n entity?: string;\n last?: number;\n }): Array<{\n entity: string;\n insightType: string;\n severity: string;\n message: string;\n context: Record<string, unknown>;\n timestamp: string;\n }>;\n saveEntityState(s: {\n tableName: string;\n primaryKey: string;\n state: string;\n enteredAt: string;\n }): void;\n getEntityState(\n tableName: string,\n primaryKey: string,\n ): { state: string; enteredAt: string } | undefined;\n getStuckEntityStates(\n tableName: string,\n thresholdMs: number,\n ): Array<{ primaryKey: string; state: string; enteredAt: string }>;\n getEntity(\n tableName: string,\n ): { entityLabel: string } | undefined;\n}\n\ninterface WorkflowGraph {\n adjacency: Map<string, string[]>;\n}\n\ninterface ValidationResult {\n expected: boolean;\n insightType?: InsightType;\n severity?: Severity;\n expectedPath?: string[];\n}\n\nexport class TransitionTracker {\n private readonly workflows: Record<string, WorkflowConfig>;\n private readonly storage: TransitionStorage;\n private readonly onInsight: (insight: Insight) => void;\n private readonly graphs: Map<string, WorkflowGraph>;\n\n constructor(\n workflows: Record<string, WorkflowConfig>,\n storage: TransitionStorage,\n onInsight: (insight: Insight) => void,\n ) {\n this.workflows = workflows;\n this.storage = storage;\n this.onInsight = onInsight;\n this.graphs = new Map();\n\n for (const [tableName, config] of Object.entries(workflows)) {\n this.graphs.set(tableName, this.parseGraph(config.expectedTransitions));\n }\n }\n\n handleChange(change: RawChange): void {\n // 1. Only process UPDATE operations\n if (change.operation !== 'UPDATE') {\n return;\n }\n\n const tableName = change.tableName;\n\n // 2. Find matching workflow\n const workflow = this.workflows[tableName];\n if (!workflow) {\n return;\n }\n\n // 3. Check if changedColumns includes the stateColumn\n // If changedColumns is undefined (e.g., polling CDC), proceed — we can't tell what changed\n if (\n change.changedColumns &&\n !change.changedColumns.includes(workflow.stateColumn)\n ) {\n return;\n }\n\n // 4. Get new state from newData\n const newState = change.newData?.[workflow.stateColumn];\n if (newState === null || newState === undefined) {\n return;\n }\n const toState = String(newState);\n const primaryKey = String(change.primaryKey);\n\n // 5. Look up current state\n const currentState = this.storage.getEntityState(tableName, primaryKey);\n\n // 6. First observation — save state, return\n if (!currentState) {\n this.storage.saveEntityState({\n tableName,\n primaryKey,\n state: toState,\n enteredAt: change.detectedAt.toISOString(),\n });\n return;\n }\n\n const fromState = currentState.state;\n\n // 7. Same state — skip\n if (fromState === toState) {\n return;\n }\n\n // 8. Compute durationMs\n const enteredAt = new Date(currentState.enteredAt);\n const durationMs = change.detectedAt.getTime() - enteredAt.getTime();\n\n // 9. Resolve entity name\n const entityName =\n this.storage.getEntity(tableName)?.entityLabel ?? tableName;\n\n // 10. Validate transition against graph\n const graph = this.graphs.get(tableName);\n const validation = graph\n ? this.validateTransition(fromState, toState, graph)\n : { expected: false, insightType: 'transition_unexpected' as InsightType, severity: 'medium' as Severity };\n\n // 11. Save transition\n this.storage.saveTransition({\n entity: entityName,\n tableName,\n primaryKey,\n fromState,\n toState,\n durationMs,\n expected: validation.expected,\n });\n\n // Update entity state\n this.storage.saveEntityState({\n tableName,\n primaryKey,\n state: toState,\n enteredAt: change.detectedAt.toISOString(),\n });\n\n // 12. If not expected: build Insight, save it, call onInsight\n if (!validation.expected && validation.insightType && validation.severity) {\n const message = this.buildMessage(\n entityName,\n primaryKey,\n fromState,\n toState,\n validation.insightType,\n validation.expectedPath,\n durationMs,\n );\n\n const insight: Insight = {\n entity: entityName,\n insightType: validation.insightType,\n severity: validation.severity,\n message,\n context: {\n primaryKey,\n fromState,\n toState,\n ...(validation.expectedPath\n ? { expectedPath: validation.expectedPath }\n : {}),\n durationMs,\n },\n timestamp: change.detectedAt,\n };\n\n this.storage.saveInsight({\n entity: insight.entity,\n insightType: insight.insightType,\n severity: insight.severity,\n message: insight.message,\n context: insight.context,\n });\n\n this.onInsight(insight);\n\n logger.warn(\n { entity: entityName, primaryKey, fromState, toState, insightType: validation.insightType },\n message,\n );\n }\n }\n\n checkStuck(): void {\n for (const [tableName, workflow] of Object.entries(this.workflows)) {\n if (!workflow.stuckThreshold) {\n continue;\n }\n\n const thresholdMs = parseTransitionDuration(workflow.stuckThreshold);\n const stuckRecords = this.storage.getStuckEntityStates(\n tableName,\n thresholdMs,\n );\n\n if (stuckRecords.length === 0) {\n continue;\n }\n\n const entityName =\n this.storage.getEntity(tableName)?.entityLabel ?? tableName;\n\n // Get recent insights (last 60 min) for duplicate detection\n const recentInsights = this.storage.getInsights({\n entity: entityName,\n last: 60,\n });\n\n const recentlyAlertedKeys = new Set(\n recentInsights\n .filter((i) => i.insightType === 'transition_stuck')\n .map((i) => String((i.context as Record<string, unknown>).primaryKey)),\n );\n\n for (const record of stuckRecords) {\n if (recentlyAlertedKeys.has(record.primaryKey)) {\n continue;\n }\n\n const enteredAt = new Date(record.enteredAt);\n const now = new Date();\n const actualDurationMs = now.getTime() - enteredAt.getTime();\n const severity = this.computeStuckSeverity(actualDurationMs, thresholdMs);\n\n const message = this.buildMessage(\n entityName,\n record.primaryKey,\n record.state,\n undefined,\n 'transition_stuck',\n undefined,\n actualDurationMs,\n );\n\n const insight: Insight = {\n entity: entityName,\n insightType: 'transition_stuck',\n severity,\n message,\n context: {\n primaryKey: record.primaryKey,\n fromState: record.state,\n durationMs: actualDurationMs,\n },\n timestamp: now,\n };\n\n this.storage.saveInsight({\n entity: insight.entity,\n insightType: insight.insightType,\n severity: insight.severity,\n message: insight.message,\n context: insight.context,\n });\n\n this.onInsight(insight);\n\n logger.warn(\n { entity: entityName, primaryKey: record.primaryKey, state: record.state, severity },\n message,\n );\n }\n }\n }\n\n private parseGraph(transitions: string[]): WorkflowGraph {\n const adjacency = new Map<string, string[]>();\n\n for (const transition of transitions) {\n const parts = transition.split('->').map((s) => s.trim());\n if (parts.length !== 2) {\n logger.warn({ transition }, 'Invalid transition format, skipping');\n continue;\n }\n const [from, to] = parts;\n const neighbors = adjacency.get(from) ?? [];\n neighbors.push(to);\n adjacency.set(from, neighbors);\n }\n\n return { adjacency };\n }\n\n private validateTransition(\n from: string,\n to: string,\n graph: WorkflowGraph,\n ): ValidationResult {\n // Check direct edge\n const directNeighbors = graph.adjacency.get(from) ?? [];\n if (directNeighbors.includes(to)) {\n return { expected: true };\n }\n\n // Check reachable via BFS (skip)\n const path = this.findPath(from, to, graph.adjacency);\n if (path && path.length > 2) {\n return {\n expected: false,\n insightType: 'transition_skip',\n severity: 'high',\n expectedPath: path,\n };\n }\n\n // Not reachable at all\n return {\n expected: false,\n insightType: 'transition_unexpected',\n severity: 'medium',\n };\n }\n\n private findPath(\n from: string,\n to: string,\n adjacency: Map<string, string[]>,\n ): string[] | null {\n const visited = new Set<string>();\n const queue: string[][] = [[from]];\n visited.add(from);\n\n while (queue.length > 0) {\n const currentPath = queue.shift()!;\n const current = currentPath[currentPath.length - 1];\n\n const neighbors = adjacency.get(current) ?? [];\n for (const neighbor of neighbors) {\n if (neighbor === to) {\n return [...currentPath, neighbor];\n }\n if (!visited.has(neighbor)) {\n visited.add(neighbor);\n queue.push([...currentPath, neighbor]);\n }\n }\n }\n\n return null;\n }\n\n private computeStuckSeverity(durationMs: number, thresholdMs: number): Severity {\n const multiplier = durationMs / thresholdMs;\n\n if (multiplier >= 8) {\n return 'critical';\n }\n if (multiplier >= 4) {\n return 'high';\n }\n if (multiplier >= 2) {\n return 'medium';\n }\n return 'low';\n }\n\n private buildMessage(\n entity: string,\n primaryKey: string,\n fromState: string,\n toState: string | undefined,\n insightType: InsightType,\n expectedPath: string[] | undefined,\n durationMs: number,\n ): string {\n const formatted = this.formatDuration(durationMs);\n\n switch (insightType) {\n case 'transition_skip':\n return `${entity} ${primaryKey} skipped states: ${fromState} -> ${toState} (expected path: ${expectedPath?.join(' -> ')}) after ${formatted}`;\n case 'transition_unexpected':\n return `${entity} ${primaryKey} made unexpected transition: ${fromState} -> ${toState} after ${formatted}`;\n case 'transition_stuck':\n return `${entity} ${primaryKey} stuck in \"${fromState}\" for ${formatted}`;\n default:\n return `${entity} ${primaryKey}: ${insightType} (${fromState}${toState ? ' -> ' + toState : ''}) after ${formatted}`;\n }\n }\n\n private formatDuration(ms: number): string {\n const totalMinutes = Math.floor(ms / 60_000);\n const hours = Math.floor(totalMinutes / 60);\n const minutes = totalMinutes % 60;\n\n if (hours > 0 && minutes > 0) {\n return `${hours}h ${minutes}m`;\n }\n if (hours > 0) {\n return `${hours}h`;\n }\n if (minutes > 0) {\n return `${minutes}m`;\n }\n\n const seconds = Math.floor(ms / 1000);\n if (seconds > 0) {\n return `${seconds}s`;\n }\n\n return `${ms}ms`;\n }\n}\n","export interface WorkflowConfig {\n stateColumn: string;\n expectedTransitions: string[];\n stuckThreshold?: string;\n}\n\nexport type InsightType =\n | 'transition_skip'\n | 'transition_unexpected'\n | 'transition_stuck'\n | 'correlation_divergence'\n | 'correlation_timing'\n | 'distribution_shift'\n | 'temporal_shift';\n\nexport type Severity = 'low' | 'medium' | 'high' | 'critical';\n\nexport interface StateTransition {\n entity: string;\n tableName: string;\n primaryKey: string | number;\n fromState: string;\n toState: string;\n durationMs: number;\n timestamp: Date;\n expected: boolean;\n}\n\nexport interface TransitionStats {\n entity: string;\n fromState: string;\n toState: string;\n count: number;\n avgDurationMs: number;\n minDurationMs: number;\n maxDurationMs: number;\n}\n\nexport interface Insight {\n entity: string;\n insightType: InsightType;\n severity: Severity;\n message: string;\n context: Record<string, unknown>;\n timestamp: Date;\n}\n\nexport interface ReasoningConfig {\n workflows: Record<string, WorkflowConfig>;\n}\n\nconst DURATION_REGEX = /^(\\d+)(ms|s|m|h|d)$/;\n\nconst UNIT_TO_MS: Record<string, number> = {\n ms: 1,\n s: 1_000,\n m: 60_000,\n h: 3_600_000,\n d: 86_400_000,\n};\n\nexport function parseTransitionDuration(input: string): number {\n const match = DURATION_REGEX.exec(input);\n if (!match) {\n throw new Error(`Invalid duration string: \"${input}\". Expected format: <number><unit> (ms|s|m|h|d)`);\n }\n const value = Number(match[1]);\n const unit = match[2];\n return value * UNIT_TO_MS[unit];\n}\n","import { createLogger } from '../core/logger.js';\nimport { Correlator } from './correlator.js';\nimport type { CorrelatorStorage } from './correlator.js';\nimport { DistributionTracker } from './distribution-tracker.js';\nimport type { DistributionTrackerStorage } from './distribution-tracker.js';\nimport type { AnalyticsConfig } from './types.js';\nimport type { Insight } from '../reasoning/types.js';\n\nconst logger = createLogger({ name: 'analytics-engine' });\n\nexport interface AnalyticsEngineStorage {\n saveCorrelationEvent(event: { entity: string; eventType: string; primaryKey: string }): void;\n getCorrelationEvents(entity: string, lastMinutes: number): Array<{ entity: string; eventType: string; primaryKey: string; timestamp: string }>;\n saveCorrelationRate(rate: { entity: string; bucket: string; eventCount: number }): void;\n getCorrelationRates(entity: string, lastHours: number): Array<{ entity: string; bucket: string; eventCount: number }>;\n saveHistogramBucket(bucket: { entity: string; columnName: string; bucketKey: string; count: number; period: string }): void;\n getHistogramBuckets(entity: string, columnName: string, period: string): Array<{ bucketKey: string; count: number }>;\n saveTemporalPattern(pattern: { entity: string; bucketType: string; bucketKey: number; count: number; period: string }): void;\n getTemporalPatterns(entity: string, bucketType: string, period: string): Array<{ bucketKey: number; count: number }>;\n saveInsight(i: { entity: string; insightType: string; severity: string; message: string; context: Record<string, unknown> }): void;\n getBaseline(key: string): { mean: number; stddev: number; sampleSize: number } | undefined;\n saveBaseline(baseline: { key: string; mean: number; stddev: number; sampleSize: number }): void;\n}\n\nexport class AnalyticsEngine {\n private readonly correlator: Correlator | null;\n private readonly distributionTracker: DistributionTracker | null;\n\n constructor(\n config: AnalyticsConfig,\n storage: AnalyticsEngineStorage,\n onInsight: (insight: Insight) => void,\n ) {\n const correlationEntries = config.correlations ? Object.keys(config.correlations) : [];\n const distributionEntries = config.distributions ? Object.keys(config.distributions) : [];\n\n if (correlationEntries.length > 0 && config.correlations) {\n this.correlator = new Correlator(config.correlations, storage as CorrelatorStorage, onInsight);\n } else {\n this.correlator = null;\n }\n\n if (distributionEntries.length > 0 && config.distributions) {\n this.distributionTracker = new DistributionTracker(config.distributions, storage as DistributionTrackerStorage, onInsight);\n } else {\n this.distributionTracker = null;\n }\n\n logger.debug(\n { hasCorrelator: this.correlator !== null, hasDistributionTracker: this.distributionTracker !== null },\n 'AnalyticsEngine initialized',\n );\n }\n\n handleEvent(entity: string, eventType: string, primaryKey: string, data: Record<string, unknown>, timestamp: Date): void {\n if (this.correlator) {\n this.correlator.recordEvent(entity, eventType, primaryKey);\n }\n\n if (this.distributionTracker) {\n this.distributionTracker.recordValue(entity, data);\n this.distributionTracker.recordTemporalEvent(entity, timestamp);\n }\n }\n\n runPeriodicChecks(): void {\n if (this.correlator) {\n this.correlator.checkRateCorrelation();\n this.correlator.checkCoOccurrence();\n }\n\n if (this.distributionTracker) {\n this.distributionTracker.checkDistributionShift();\n this.distributionTracker.checkTemporalShift();\n }\n }\n}\n","import { createLogger } from '../core/logger.js';\nimport { parseTimeWindow } from './types.js';\nimport type { CorrelationConfig } from './types.js';\nimport type { Insight, Severity } from '../reasoning/types.js';\n\nconst logger = createLogger({ name: 'correlator' });\n\nconst MIN_SAMPLE_SIZE = 12;\nconst ANOMALY_THRESHOLD = 2;\n\nexport interface CorrelatorStorage {\n saveCorrelationEvent(event: { entity: string; eventType: string; primaryKey: string }): void;\n getCorrelationEvents(entity: string, lastMinutes: number): Array<{ entity: string; eventType: string; primaryKey: string; timestamp: string }>;\n saveCorrelationRate(rate: { entity: string; bucket: string; eventCount: number }): void;\n getCorrelationRates(entity: string, lastHours: number): Array<{ entity: string; bucket: string; eventCount: number }>;\n saveInsight(i: { entity: string; insightType: string; severity: string; message: string; context: Record<string, unknown> }): void;\n getBaseline(key: string): { mean: number; stddev: number; sampleSize: number } | undefined;\n saveBaseline(baseline: { key: string; mean: number; stddev: number; sampleSize: number }): void;\n}\n\ninterface ParsedConfig {\n name: string;\n entities: [string, string];\n timeWindowMs: number;\n}\n\nexport class Correlator {\n private readonly storage: CorrelatorStorage;\n private readonly onInsight: (insight: Insight) => void;\n private readonly trackedEntities: Set<string>;\n private readonly parsedConfigs: ParsedConfig[];\n\n constructor(\n configs: Record<string, CorrelationConfig>,\n storage: CorrelatorStorage,\n onInsight: (insight: Insight) => void,\n ) {\n this.storage = storage;\n this.onInsight = onInsight;\n this.trackedEntities = new Set<string>();\n this.parsedConfigs = [];\n\n for (const [name, config] of Object.entries(configs)) {\n this.trackedEntities.add(config.entities[0]);\n this.trackedEntities.add(config.entities[1]);\n this.parsedConfigs.push({\n name,\n entities: config.entities,\n timeWindowMs: parseTimeWindow(config.timeWindow),\n });\n }\n\n logger.debug({ configCount: this.parsedConfigs.length }, 'Correlator initialized');\n }\n\n recordEvent(entity: string, eventType: string, primaryKey: string): void {\n if (!this.trackedEntities.has(entity)) {\n return;\n }\n\n this.storage.saveCorrelationEvent({ entity, eventType, primaryKey });\n }\n\n checkRateCorrelation(): void {\n for (const config of this.parsedConfigs) {\n const [entityA, entityB] = config.entities;\n const ratesA = this.storage.getCorrelationRates(entityA, 24);\n const ratesB = this.storage.getCorrelationRates(entityB, 24);\n\n const avgA = this.averageEventCount(ratesA);\n const avgB = this.averageEventCount(ratesB);\n\n if (avgA === 0 || avgB === 0) {\n continue;\n }\n\n const ratio = avgA / avgB;\n const baselineKey = `correlation:${config.name}:rate_ratio`;\n const existing = this.storage.getBaseline(baselineKey);\n\n if (!existing || existing.sampleSize < MIN_SAMPLE_SIZE) {\n this.updateBaseline(baselineKey, ratio, existing);\n continue;\n }\n\n if (existing.stddev === 0) {\n this.updateBaseline(baselineKey, ratio, existing);\n continue;\n }\n\n const zScore = Math.abs(ratio - existing.mean) / existing.stddev;\n\n if (zScore >= ANOMALY_THRESHOLD) {\n const severity = Correlator.getSeverity(zScore);\n const insight: Insight = {\n entity: config.name,\n insightType: 'correlation_divergence',\n severity,\n message: `Rate ratio between ${entityA} and ${entityB} diverged to ${ratio.toFixed(2)} (expected ${existing.mean.toFixed(2)}\\u00b1${existing.stddev.toFixed(2)}, z=${zScore.toFixed(1)})`,\n context: {\n entityA,\n entityB,\n ratio,\n baselineMean: existing.mean,\n baselineStddev: existing.stddev,\n zScore,\n },\n timestamp: new Date(),\n };\n\n this.storage.saveInsight({\n entity: insight.entity,\n insightType: insight.insightType,\n severity: insight.severity,\n message: insight.message,\n context: insight.context,\n });\n\n this.onInsight(insight);\n logger.info({ config: config.name, zScore, ratio }, 'Rate correlation divergence detected');\n }\n\n this.updateBaseline(baselineKey, ratio, existing);\n }\n }\n\n checkCoOccurrence(): void {\n for (const config of this.parsedConfigs) {\n const [entityA, entityB] = config.entities;\n const timeWindowMinutes = Math.ceil(config.timeWindowMs / 60_000);\n\n const eventsA = this.storage.getCorrelationEvents(entityA, timeWindowMinutes);\n const eventsB = this.storage.getCorrelationEvents(entityB, timeWindowMinutes);\n\n const countA = eventsA.length;\n const countB = eventsB.length;\n\n if (countA === 0 && countB === 0) {\n continue;\n }\n\n const maxCount = Math.max(countA, countB);\n const minCount = Math.min(countA, countB);\n const coOccurrenceRate = maxCount === 0 ? 0 : minCount / maxCount;\n\n const baselineKey = `correlation:${config.name}:co_occurrence`;\n const existing = this.storage.getBaseline(baselineKey);\n\n if (!existing || existing.sampleSize < MIN_SAMPLE_SIZE) {\n this.updateBaseline(baselineKey, coOccurrenceRate, existing);\n continue;\n }\n\n if (existing.stddev === 0) {\n this.updateBaseline(baselineKey, coOccurrenceRate, existing);\n continue;\n }\n\n // One-sided test: we care about drops in co-occurrence\n const zScore = (existing.mean - coOccurrenceRate) / existing.stddev;\n\n if (zScore >= ANOMALY_THRESHOLD) {\n const severity = Correlator.getSeverity(zScore);\n const insight: Insight = {\n entity: config.name,\n insightType: 'correlation_timing',\n severity,\n message: `Co-occurrence between ${entityA} and ${entityB} dropped to ${(coOccurrenceRate * 100).toFixed(1)}% (expected ${(existing.mean * 100).toFixed(1)}%\\u00b1${(existing.stddev * 100).toFixed(1)}%, z=${zScore.toFixed(1)})`,\n context: {\n entityA,\n entityB,\n coOccurrenceRate,\n baselineMean: existing.mean,\n baselineStddev: existing.stddev,\n zScore,\n countA,\n countB,\n },\n timestamp: new Date(),\n };\n\n this.storage.saveInsight({\n entity: insight.entity,\n insightType: insight.insightType,\n severity: insight.severity,\n message: insight.message,\n context: insight.context,\n });\n\n this.onInsight(insight);\n logger.info({ config: config.name, zScore, coOccurrenceRate }, 'Co-occurrence timing violation detected');\n }\n\n this.updateBaseline(baselineKey, coOccurrenceRate, existing);\n }\n }\n\n static getSeverity(sigma: number): Severity {\n if (sigma >= 5) return 'critical';\n if (sigma >= 4) return 'high';\n if (sigma >= 3) return 'medium';\n return 'low';\n }\n\n private updateBaseline(\n key: string,\n currentValue: number,\n existing: { mean: number; stddev: number; sampleSize: number } | undefined,\n ): void {\n if (!existing) {\n this.storage.saveBaseline({\n key,\n mean: currentValue,\n stddev: 0,\n sampleSize: 1,\n });\n return;\n }\n\n const newN = existing.sampleSize + 1;\n const delta = currentValue - existing.mean;\n const newMean = existing.mean + delta / newN;\n const delta2 = currentValue - newMean;\n\n const newVariance =\n newN <= 2\n ? (existing.stddev * existing.stddev * Math.max(newN - 2, 0) + delta * delta2) / Math.max(newN - 1, 1)\n : (existing.stddev * existing.stddev * (newN - 2) + delta * delta2) / (newN - 1);\n\n const newStddev = Math.sqrt(Math.max(newVariance, 0));\n\n this.storage.saveBaseline({\n key,\n mean: newMean,\n stddev: newStddev,\n sampleSize: newN,\n });\n }\n\n private averageEventCount(rates: Array<{ entity: string; bucket: string; eventCount: number }>): number {\n if (rates.length === 0) return 0;\n const total = rates.reduce((sum, r) => sum + r.eventCount, 0);\n return total / rates.length;\n }\n}\n","export interface CorrelationConfig {\n entities: [string, string];\n timeWindow: string;\n}\n\nexport interface DistributionConfig {\n columns: string[];\n temporalBuckets: 'hourly' | 'daily';\n}\n\nexport interface AnalyticsConfig {\n correlations?: Record<string, CorrelationConfig>;\n distributions?: Record<string, DistributionConfig>;\n}\n\nexport interface CorrelationStatus {\n name: string;\n entities: [string, string];\n rateRatio: number;\n baselineRatio: number;\n coOccurrenceRate: number;\n baselineCoOccurrence: number;\n healthy: boolean;\n}\n\nexport interface DistributionSummary {\n entity: string;\n columnName: string;\n bucketCount: number;\n baselineSamples: number;\n currentShift: number | null;\n shifted: boolean;\n}\n\nconst TIME_WINDOW_REGEX = /^(\\d+)(s|m|h|d)$/;\n\nconst UNIT_TO_MS: Record<string, number> = {\n s: 1_000,\n m: 60_000,\n h: 3_600_000,\n d: 86_400_000,\n};\n\nexport function parseTimeWindow(input: string): number {\n const match = TIME_WINDOW_REGEX.exec(input);\n if (!match) {\n throw new Error(`Invalid time window string: \"${input}\". Expected format: <number><unit> (s|m|h|d)`);\n }\n const value = Number(match[1]);\n const unit = match[2];\n return value * UNIT_TO_MS[unit];\n}\n","import { createLogger } from '../core/logger.js';\nimport type { DistributionConfig } from './types.js';\nimport type { Insight, InsightType, Severity } from '../reasoning/types.js';\n\nconst logger = createLogger({ name: 'distribution-tracker' });\n\nconst MIN_SAMPLE_SIZE = 12;\nconst NUM_BINS = 10;\n\nexport interface DistributionTrackerStorage {\n saveHistogramBucket(bucket: {\n entity: string;\n columnName: string;\n bucketKey: string;\n count: number;\n period: string;\n }): void;\n getHistogramBuckets(\n entity: string,\n columnName: string,\n period: string,\n ): Array<{ bucketKey: string; count: number }>;\n saveTemporalPattern(pattern: {\n entity: string;\n bucketType: string;\n bucketKey: number;\n count: number;\n period: string;\n }): void;\n getTemporalPatterns(\n entity: string,\n bucketType: string,\n period: string,\n ): Array<{ bucketKey: number; count: number }>;\n saveInsight(i: {\n entity: string;\n insightType: string;\n severity: string;\n message: string;\n context: Record<string, unknown>;\n }): void;\n getBaseline(\n key: string,\n ): { mean: number; stddev: number; sampleSize: number } | undefined;\n saveBaseline(baseline: {\n key: string;\n mean: number;\n stddev: number;\n sampleSize: number;\n }): void;\n}\n\ninterface ParsedEntityConfig {\n entity: string;\n columns: string[];\n temporalBuckets: 'hourly' | 'daily';\n}\n\nexport class DistributionTracker {\n private readonly storage: DistributionTrackerStorage;\n private readonly onInsight: (insight: Insight) => void;\n private readonly entityConfigs: Map<string, ParsedEntityConfig>;\n\n constructor(\n configs: Record<string, DistributionConfig>,\n storage: DistributionTrackerStorage,\n onInsight: (insight: Insight) => void,\n ) {\n this.storage = storage;\n this.onInsight = onInsight;\n this.entityConfigs = new Map();\n\n for (const [entity, config] of Object.entries(configs)) {\n this.entityConfigs.set(entity, {\n entity,\n columns: config.columns,\n temporalBuckets: config.temporalBuckets,\n });\n }\n\n logger.debug(\n { entityCount: this.entityConfigs.size },\n 'DistributionTracker initialized',\n );\n }\n\n recordValue(entity: string, data: Record<string, unknown>): void {\n const config = this.entityConfigs.get(entity);\n if (!config) {\n return;\n }\n\n for (const column of config.columns) {\n const value = data[column];\n if (value === undefined || value === null) {\n continue;\n }\n\n const bucketKey = DistributionTracker.toBucketKey(value);\n if (bucketKey === null) {\n continue;\n }\n\n this.storage.saveHistogramBucket({\n entity,\n columnName: column,\n bucketKey,\n count: 1,\n period: 'current',\n });\n }\n }\n\n recordTemporalEvent(entity: string, timestamp: Date): void {\n const config = this.entityConfigs.get(entity);\n if (!config) {\n return;\n }\n\n if (config.temporalBuckets === 'hourly') {\n this.storage.saveTemporalPattern({\n entity,\n bucketType: 'hour_of_day',\n bucketKey: timestamp.getUTCHours(),\n count: 1,\n period: 'current',\n });\n } else {\n this.storage.saveTemporalPattern({\n entity,\n bucketType: 'day_of_week',\n bucketKey: timestamp.getUTCDay(),\n count: 1,\n period: 'current',\n });\n }\n }\n\n checkDistributionShift(): void {\n for (const config of this.entityConfigs.values()) {\n for (const column of config.columns) {\n const baselineKey = `distribution:${config.entity}:${column}:shift`;\n const baseline = this.storage.getBaseline(baselineKey);\n\n if (!baseline || baseline.sampleSize < MIN_SAMPLE_SIZE) {\n continue;\n }\n\n const baselineBuckets = this.storage.getHistogramBuckets(\n config.entity,\n column,\n 'baseline',\n );\n const currentBuckets = this.storage.getHistogramBuckets(\n config.entity,\n column,\n 'current',\n );\n\n if (baselineBuckets.length === 0 || currentBuckets.length === 0) {\n continue;\n }\n\n const { observed, expected } =\n DistributionTracker.alignAndNormalize(currentBuckets, baselineBuckets);\n\n if (observed.length === 0) {\n continue;\n }\n\n const chi2 = DistributionTracker.chiSquared(observed, expected);\n const df = Math.max(observed.length - 1, 1);\n const threshold = DistributionTracker.chiSquaredThreshold(df);\n\n if (chi2 > threshold) {\n const pValue = DistributionTracker.chiSquaredPValue(chi2, df);\n const severity = DistributionTracker.shiftSeverity(chi2, df);\n const insightType: InsightType = 'distribution_shift';\n\n const insight: Insight = {\n entity: config.entity,\n insightType,\n severity,\n message: `Distribution shift detected for ${config.entity}.${column}: chi2=${chi2.toFixed(2)}, df=${df}, p=${pValue.toFixed(4)}`,\n context: {\n column,\n chi2,\n df,\n pValue,\n threshold,\n },\n timestamp: new Date(),\n };\n\n this.storage.saveInsight({\n entity: insight.entity,\n insightType: insight.insightType,\n severity: insight.severity,\n message: insight.message,\n context: insight.context,\n });\n\n this.onInsight(insight);\n\n logger.info(\n { entity: config.entity, column, chi2, df, pValue },\n 'Distribution shift detected',\n );\n }\n }\n }\n }\n\n checkTemporalShift(): void {\n for (const config of this.entityConfigs.values()) {\n const bucketType =\n config.temporalBuckets === 'hourly' ? 'hour_of_day' : 'day_of_week';\n const baselineKey = `temporal:${config.entity}:${bucketType}:shift`;\n const baseline = this.storage.getBaseline(baselineKey);\n\n if (!baseline || baseline.sampleSize < MIN_SAMPLE_SIZE) {\n continue;\n }\n\n const baselinePatterns = this.storage.getTemporalPatterns(\n config.entity,\n bucketType,\n 'baseline',\n );\n const currentPatterns = this.storage.getTemporalPatterns(\n config.entity,\n bucketType,\n 'current',\n );\n\n if (baselinePatterns.length === 0 || currentPatterns.length === 0) {\n continue;\n }\n\n const { observed, expected } =\n DistributionTracker.alignAndNormalizeNumericBuckets(\n currentPatterns,\n baselinePatterns,\n );\n\n if (observed.length === 0) {\n continue;\n }\n\n const chi2 = DistributionTracker.chiSquared(observed, expected);\n const df = Math.max(observed.length - 1, 1);\n const threshold = DistributionTracker.chiSquaredThreshold(df);\n\n if (chi2 > threshold) {\n const pValue = DistributionTracker.chiSquaredPValue(chi2, df);\n const severity = DistributionTracker.shiftSeverity(chi2, df);\n const insightType: InsightType = 'temporal_shift';\n\n const insight: Insight = {\n entity: config.entity,\n insightType,\n severity,\n message: `Temporal pattern shift detected for ${config.entity} (${bucketType}): chi2=${chi2.toFixed(2)}, df=${df}, p=${pValue.toFixed(4)}`,\n context: {\n bucketType,\n chi2,\n df,\n pValue,\n threshold,\n },\n timestamp: new Date(),\n };\n\n this.storage.saveInsight({\n entity: insight.entity,\n insightType: insight.insightType,\n severity: insight.severity,\n message: insight.message,\n context: insight.context,\n });\n\n this.onInsight(insight);\n\n logger.info(\n { entity: config.entity, bucketType, chi2, df, pValue },\n 'Temporal pattern shift detected',\n );\n }\n }\n }\n\n static chiSquared(observed: number[], expected: number[]): number {\n let sum = 0;\n for (let i = 0; i < observed.length; i++) {\n const e = expected[i];\n if (e === 0) {\n continue;\n }\n const diff = observed[i] - e;\n sum += (diff * diff) / e;\n }\n return sum;\n }\n\n static chiSquaredThreshold(df: number): number {\n const table: Record<number, number> = {\n 1: 3.841,\n 2: 5.991,\n 3: 7.815,\n 4: 9.488,\n 5: 11.07,\n };\n\n if (df in table) {\n return table[df];\n }\n\n // Wilson-Hilferty approximation for larger df\n const term = 1 - 2 / (9 * df);\n return df * Math.pow(term, 3);\n }\n\n static chiSquaredPValue(chi2: number, df: number): number {\n if (df <= 0 || chi2 <= 0) return 1.0;\n\n // Compute upper-tail p-value using the regularized incomplete gamma function\n // P(X > chi2) = 1 - gammaIncomplete(df/2, chi2/2) / gamma(df/2)\n // Using series expansion for the regularized lower incomplete gamma function\n const a = df / 2;\n const x = chi2 / 2;\n\n return 1 - DistributionTracker.regularizedGammaP(a, x);\n }\n\n private static regularizedGammaP(a: number, x: number): number {\n if (x < 0) return 0;\n if (x === 0) return 0;\n\n // Use series expansion for x < a + 1, continued fraction otherwise\n if (x < a + 1) {\n return DistributionTracker.gammaPSeries(a, x);\n }\n return 1 - DistributionTracker.gammaPContinuedFraction(a, x);\n }\n\n private static gammaPSeries(a: number, x: number): number {\n const lnGammaA = DistributionTracker.lnGamma(a);\n let sum = 1 / a;\n let term = 1 / a;\n\n for (let n = 1; n < 200; n++) {\n term *= x / (a + n);\n sum += term;\n if (Math.abs(term) < Math.abs(sum) * 1e-10) break;\n }\n\n return sum * Math.exp(-x + a * Math.log(x) - lnGammaA);\n }\n\n private static gammaPContinuedFraction(a: number, x: number): number {\n const lnGammaA = DistributionTracker.lnGamma(a);\n // Lentz's algorithm for continued fraction\n let f = 1e-30;\n let c = 1e-30;\n let d = 1 / (x + 1 - a);\n let h = d;\n\n for (let n = 1; n < 200; n++) {\n const an = -n * (n - a);\n const bn = x + 2 * n + 1 - a;\n d = bn + an * d;\n if (Math.abs(d) < 1e-30) d = 1e-30;\n c = bn + an / c;\n if (Math.abs(c) < 1e-30) c = 1e-30;\n d = 1 / d;\n const delta = c * d;\n h *= delta;\n if (Math.abs(delta - 1) < 1e-10) break;\n }\n\n return Math.exp(-x + a * Math.log(x) - lnGammaA) * h;\n }\n\n private static lnGamma(x: number): number {\n // Lanczos approximation\n const g = 7;\n const coef = [\n 0.99999999999980993, 676.5203681218851, -1259.1392167224028,\n 771.32342877765313, -176.61502916214059, 12.507343278686905,\n -0.13857109526572012, 9.9843695780195716e-6, 1.5056327351493116e-7,\n ];\n\n if (x < 0.5) {\n return Math.log(Math.PI / Math.sin(Math.PI * x)) - DistributionTracker.lnGamma(1 - x);\n }\n\n x -= 1;\n let a = coef[0];\n const t = x + g + 0.5;\n\n for (let i = 1; i < coef.length; i++) {\n a += coef[i] / (x + i);\n }\n\n return 0.5 * Math.log(2 * Math.PI) + (x + 0.5) * Math.log(t) - t + Math.log(a);\n }\n\n private static shiftSeverity(chi2: number, df: number): Severity {\n const p = DistributionTracker.chiSquaredPValue(chi2, df);\n if (p < 0.001) return 'critical';\n if (p < 0.01) return 'high';\n if (p < 0.05) return 'medium';\n return 'low';\n }\n\n private static toBucketKey(value: unknown): string | null {\n if (typeof value === 'number') {\n return `n:${value}`;\n }\n if (typeof value === 'string') {\n return value;\n }\n return null;\n }\n\n private static alignAndNormalize(\n currentBuckets: Array<{ bucketKey: string; count: number }>,\n baselineBuckets: Array<{ bucketKey: string; count: number }>,\n ): { observed: number[]; expected: number[] } {\n // Check if data is numeric (prefixed with 'n:') or categorical\n const allBuckets = [...baselineBuckets, ...currentBuckets];\n const isNumeric = allBuckets.length > 0 && allBuckets.every((b) => b.bucketKey.startsWith('n:'));\n\n if (isNumeric) {\n return DistributionTracker.alignNumericBins(currentBuckets, baselineBuckets);\n }\n\n return DistributionTracker.alignCategoricalBuckets(currentBuckets, baselineBuckets);\n }\n\n private static alignCategoricalBuckets(\n currentBuckets: Array<{ bucketKey: string; count: number }>,\n baselineBuckets: Array<{ bucketKey: string; count: number }>,\n ): { observed: number[]; expected: number[] } {\n const allKeys = new Set<string>();\n for (const b of baselineBuckets) allKeys.add(b.bucketKey);\n for (const b of currentBuckets) allKeys.add(b.bucketKey);\n\n const baselineMap = new Map(baselineBuckets.map((b) => [b.bucketKey, b.count]));\n const currentMap = new Map(currentBuckets.map((b) => [b.bucketKey, b.count]));\n\n const keys = Array.from(allKeys).sort();\n const rawObserved: number[] = [];\n const rawExpected: number[] = [];\n\n for (const key of keys) {\n rawObserved.push(currentMap.get(key) ?? 0);\n rawExpected.push(baselineMap.get(key) ?? 0);\n }\n\n const totalObserved = rawObserved.reduce((s, v) => s + v, 0);\n const totalExpected = rawExpected.reduce((s, v) => s + v, 0);\n\n if (totalExpected === 0 || totalObserved === 0) {\n return { observed: [], expected: [] };\n }\n\n const scale = totalObserved / totalExpected;\n const expected = rawExpected.map((e) => e * scale);\n\n return { observed: rawObserved, expected };\n }\n\n private static alignNumericBins(\n currentBuckets: Array<{ bucketKey: string; count: number }>,\n baselineBuckets: Array<{ bucketKey: string; count: number }>,\n ): { observed: number[]; expected: number[] } {\n // Parse numeric values from all buckets to find global range\n const parseValue = (key: string): number => parseFloat(key.slice(2));\n\n const allValues: number[] = [];\n for (const b of baselineBuckets) allValues.push(parseValue(b.bucketKey));\n for (const b of currentBuckets) allValues.push(parseValue(b.bucketKey));\n\n if (allValues.length === 0) {\n return { observed: [], expected: [] };\n }\n\n const min = Math.min(...allValues);\n const max = Math.max(...allValues);\n const range = max - min;\n\n if (range === 0) {\n // All values identical — single bin\n const totalObs = currentBuckets.reduce((s, b) => s + b.count, 0);\n const totalExp = baselineBuckets.reduce((s, b) => s + b.count, 0);\n if (totalObs === 0 || totalExp === 0) return { observed: [], expected: [] };\n return { observed: [totalObs], expected: [totalExp] };\n }\n\n const binWidth = range / NUM_BINS;\n const observed = new Array<number>(NUM_BINS).fill(0);\n const rawExpected = new Array<number>(NUM_BINS).fill(0);\n\n for (const b of currentBuckets) {\n const val = parseValue(b.bucketKey);\n const bin = Math.min(Math.floor((val - min) / binWidth), NUM_BINS - 1);\n observed[bin] += b.count;\n }\n\n for (const b of baselineBuckets) {\n const val = parseValue(b.bucketKey);\n const bin = Math.min(Math.floor((val - min) / binWidth), NUM_BINS - 1);\n rawExpected[bin] += b.count;\n }\n\n const totalObserved = observed.reduce((s, v) => s + v, 0);\n const totalExpected = rawExpected.reduce((s, v) => s + v, 0);\n\n if (totalObserved === 0 || totalExpected === 0) {\n return { observed: [], expected: [] };\n }\n\n const scale = totalObserved / totalExpected;\n const expected = rawExpected.map((e) => e * scale);\n\n return { observed, expected };\n }\n\n private static alignAndNormalizeNumericBuckets(\n currentBuckets: Array<{ bucketKey: number; count: number }>,\n baselineBuckets: Array<{ bucketKey: number; count: number }>,\n ): { observed: number[]; expected: number[] } {\n const allKeys = new Set<number>();\n for (const b of baselineBuckets) allKeys.add(b.bucketKey);\n for (const b of currentBuckets) allKeys.add(b.bucketKey);\n\n const baselineMap = new Map(baselineBuckets.map((b) => [b.bucketKey, b.count]));\n const currentMap = new Map(currentBuckets.map((b) => [b.bucketKey, b.count]));\n\n const keys = Array.from(allKeys).sort((a, b) => a - b);\n const rawObserved: number[] = [];\n const rawExpected: number[] = [];\n\n for (const key of keys) {\n rawObserved.push(currentMap.get(key) ?? 0);\n rawExpected.push(baselineMap.get(key) ?? 0);\n }\n\n const totalObserved = rawObserved.reduce((s, v) => s + v, 0);\n const totalExpected = rawExpected.reduce((s, v) => s + v, 0);\n\n if (totalExpected === 0 || totalObserved === 0) {\n return { observed: [], expected: [] };\n }\n\n const scale = totalObserved / totalExpected;\n const expected = rawExpected.map((e) => e * scale);\n\n return { observed: rawObserved, expected };\n }\n}\n","import type { KnowledgeNode, KnowledgeEdge, NodeType, EdgeType, GraphSummary } from './types.js';\nimport { createLogger } from '../core/logger.js';\n\nconst logger = createLogger({ name: 'graph-store' });\n\nexport interface GraphStoreStorage {\n saveKgNode(node: { nodeType: string; refId: string; label: string; metadata: string }): number;\n getKgNode(id: number): { id: number; nodeType: string; refId: string; label: string; metadata: string; timestamp: string } | undefined;\n getKgNodeByRef(nodeType: string, refId: string): { id: number; nodeType: string; refId: string; label: string; metadata: string; timestamp: string } | undefined;\n getKgNodesByType(nodeType: string): Array<{ id: number; nodeType: string; refId: string; label: string; metadata: string; timestamp: string }>;\n getAllKgNodes(): Array<{ id: number; nodeType: string; refId: string; label: string; metadata: string; timestamp: string }>;\n deleteKgNode(id: number): void;\n saveKgEdge(edge: { sourceId: number; targetId: number; edgeType: string; weight: number; metadata: string }): number;\n getKgEdgesFrom(nodeId: number, edgeType?: string): Array<{ id: number; sourceId: number; targetId: number; edgeType: string; weight: number; metadata: string; timestamp: string }>;\n getKgEdgesTo(nodeId: number, edgeType?: string): Array<{ id: number; sourceId: number; targetId: number; edgeType: string; weight: number; metadata: string; timestamp: string }>;\n getAllKgEdges(): Array<{ id: number; sourceId: number; targetId: number; edgeType: string; weight: number; metadata: string; timestamp: string }>;\n getKgSummary(): { totalNodes: number; totalEdges: number; entities: number; events: number; anomalies: number; insights: number };\n}\n\nfunction toNode(raw: { id: number; nodeType: string; refId: string; label: string; metadata: string; timestamp: string }): KnowledgeNode {\n return {\n id: raw.id,\n nodeType: raw.nodeType as NodeType,\n refId: raw.refId,\n label: raw.label,\n metadata: JSON.parse(raw.metadata || '{}') as Record<string, unknown>,\n timestamp: raw.timestamp,\n };\n}\n\nfunction toEdge(raw: { id: number; sourceId: number; targetId: number; edgeType: string; weight: number; metadata: string; timestamp: string }): KnowledgeEdge {\n return {\n id: raw.id,\n sourceId: raw.sourceId,\n targetId: raw.targetId,\n edgeType: raw.edgeType as EdgeType,\n weight: raw.weight,\n metadata: JSON.parse(raw.metadata || '{}') as Record<string, unknown>,\n timestamp: raw.timestamp,\n };\n}\n\nexport class GraphStore {\n private readonly storage: GraphStoreStorage;\n\n constructor(storage: GraphStoreStorage) {\n this.storage = storage;\n }\n\n upsertNode(nodeType: NodeType, refId: string, label: string, metadata: Record<string, unknown> = {}): number {\n const id = this.storage.saveKgNode({ nodeType, refId, label, metadata: JSON.stringify(metadata) });\n logger.debug({ id, nodeType, refId }, 'Upserted node');\n return id;\n }\n\n getNode(id: number): KnowledgeNode | undefined {\n const raw = this.storage.getKgNode(id);\n return raw ? toNode(raw) : undefined;\n }\n\n getNodeByRef(nodeType: NodeType, refId: string): KnowledgeNode | undefined {\n const raw = this.storage.getKgNodeByRef(nodeType, refId);\n return raw ? toNode(raw) : undefined;\n }\n\n getNodesByType(nodeType: NodeType): KnowledgeNode[] {\n return this.storage.getKgNodesByType(nodeType).map(toNode);\n }\n\n getAllNodes(): KnowledgeNode[] {\n return this.storage.getAllKgNodes().map(toNode);\n }\n\n deleteNode(id: number): void {\n this.storage.deleteKgNode(id);\n logger.debug({ id }, 'Deleted node');\n }\n\n addEdge(sourceId: number, targetId: number, edgeType: EdgeType, weight: number = 1.0, metadata: Record<string, unknown> = {}): number {\n const id = this.storage.saveKgEdge({ sourceId, targetId, edgeType, weight, metadata: JSON.stringify(metadata) });\n logger.debug({ id, sourceId, targetId, edgeType }, 'Added edge');\n return id;\n }\n\n getEdgesFrom(nodeId: number, edgeType?: EdgeType): KnowledgeEdge[] {\n return this.storage.getKgEdgesFrom(nodeId, edgeType).map(toEdge);\n }\n\n getEdgesTo(nodeId: number, edgeType?: EdgeType): KnowledgeEdge[] {\n return this.storage.getKgEdgesTo(nodeId, edgeType).map(toEdge);\n }\n\n getAllEdges(): KnowledgeEdge[] {\n return this.storage.getAllKgEdges().map(toEdge);\n }\n\n neighbors(nodeId: number): KnowledgeNode[] {\n const outgoing = this.storage.getKgEdgesFrom(nodeId);\n const incoming = this.storage.getKgEdgesTo(nodeId);\n const neighborIds = new Set<number>();\n for (const e of outgoing) neighborIds.add(e.targetId);\n for (const e of incoming) neighborIds.add(e.sourceId);\n const nodes: KnowledgeNode[] = [];\n for (const nid of neighborIds) {\n const raw = this.storage.getKgNode(nid);\n if (raw) nodes.push(toNode(raw));\n }\n return nodes;\n }\n\n getSummary(): GraphSummary {\n return this.storage.getKgSummary();\n }\n}\n","import type { NodeType } from './types.js';\nimport type { GraphStore } from './graph-store.js';\nimport type { RawTable } from '../schema/types.js';\nimport type { Insight, Severity } from '../reasoning/types.js';\nimport { createLogger } from '../core/logger.js';\n\nconst logger = createLogger({ name: 'graph-populator' });\n\nconst HIGH_SEVERITY: Set<Severity> = new Set(['high', 'critical']);\n\nlet eventCounter = 0;\nlet insightCounter = 0;\n\nexport class GraphPopulator {\n private readonly store: GraphStore;\n\n constructor(store: GraphStore) {\n this.store = store;\n }\n\n populateFromSchema(tables: RawTable[]): void {\n for (const table of tables) {\n this.store.upsertNode('entity', table.tableName, table.tableName, {\n tableSchema: table.tableSchema,\n rowCount: table.rowCount,\n });\n }\n\n for (const table of tables) {\n for (const fk of table.foreignKeys) {\n const sourceNode = this.store.getNodeByRef('entity', fk.referencedTable);\n const targetNode = this.store.getNodeByRef('entity', table.tableName);\n\n if (sourceNode && targetNode && sourceNode.id !== targetNode.id) {\n this.store.addEdge(sourceNode.id, targetNode.id, 'contains', 1.0, {\n sourceColumn: fk.referencedColumn,\n targetColumn: fk.columnName,\n });\n }\n }\n }\n\n logger.info({ tables: tables.length }, 'Graph populated from schema');\n }\n\n onEvent(entity: string, eventType: string, primaryKey: string, data: Record<string, unknown>): void {\n const entityNode = this.store.getNodeByRef('entity', entity);\n if (!entityNode) return;\n\n eventCounter++;\n const refId = `event:${Date.now()}-${eventCounter}`;\n const label = `${entity} ${eventType}`;\n\n const eventNodeId = this.store.upsertNode('event', refId, label, {\n eventType,\n primaryKey,\n ...data,\n });\n\n this.store.addEdge(eventNodeId, entityNode.id, 'detected_on');\n }\n\n onInsight(insight: Insight): void {\n const entityNode = this.store.getNodeByRef('entity', insight.entity);\n if (!entityNode) return;\n\n insightCounter++;\n const nodeType: NodeType = HIGH_SEVERITY.has(insight.severity) ? 'anomaly' : 'insight';\n const refId = `${nodeType}:${Date.now()}-${insightCounter}`;\n\n const nodeId = this.store.upsertNode(nodeType, refId, insight.message, {\n insightType: insight.insightType,\n severity: insight.severity,\n ...insight.context,\n });\n\n this.store.addEdge(nodeId, entityNode.id, 'detected_on');\n }\n\n addCorrelation(entityA: string, entityB: string, weight: number = 1.0): void {\n const nodeA = this.store.getNodeByRef('entity', entityA);\n const nodeB = this.store.getNodeByRef('entity', entityB);\n if (!nodeA || !nodeB) return;\n\n this.store.addEdge(nodeA.id, nodeB.id, 'correlates', weight);\n }\n}\n","import type { ActionHandler, ActionContext, GovernanceLevel } from './types.js';\n\nexport class ActionRegistry {\n private readonly handlers = new Map<string, ActionHandler>();\n private readonly governance: Record<string, string>;\n\n constructor(governance?: Record<string, string>) {\n this.governance = governance ?? {};\n }\n\n register(name: string, handler: (context: ActionContext) => Promise<void>, description?: string): void {\n if (this.handlers.has(name)) {\n throw new Error(`Action handler \"${name}\" is already registered`);\n }\n this.handlers.set(name, { name, handler, description });\n }\n\n getHandler(name: string): ActionHandler | undefined {\n return this.handlers.get(name);\n }\n\n has(name: string): boolean {\n return this.handlers.has(name);\n }\n\n getNames(): string[] {\n return Array.from(this.handlers.keys());\n }\n\n getGovernance(actionName: string): GovernanceLevel {\n const level = this.governance[actionName];\n if (level === 'auto_approve' || level === 'require_approval' || level === 'never_automate') {\n return level;\n }\n return 'require_approval';\n }\n}\n","import type { ActionRule } from './types.js';\nimport type { Insight } from '../reasoning/types.js';\n\nconst DEFAULT_CONFIDENCE = 0.5;\n\nexport class ActionMatcher {\n private readonly rules: ActionRule[];\n\n constructor(rules: ActionRule[]) {\n this.rules = rules;\n }\n\n match(insight: Insight, confidence?: number): ActionRule[] {\n const effectiveConfidence = confidence ?? DEFAULT_CONFIDENCE;\n const matched: ActionRule[] = [];\n\n for (const rule of this.rules) {\n const threshold = rule.confidence ?? DEFAULT_CONFIDENCE;\n if (effectiveConfidence < threshold) {\n continue;\n }\n\n if (!this.matchesConditions(rule, insight)) {\n continue;\n }\n\n matched.push(rule);\n }\n\n return matched;\n }\n\n private matchesConditions(rule: ActionRule, insight: Insight): boolean {\n const { when } = rule;\n\n if (when.severity && when.severity.length > 0) {\n if (!when.severity.includes(insight.severity)) {\n return false;\n }\n }\n\n if (when.insightType && when.insightType.length > 0) {\n if (!when.insightType.includes(insight.insightType)) {\n return false;\n }\n }\n\n if (when.entity && when.entity.length > 0) {\n if (!when.entity.includes(insight.entity)) {\n return false;\n }\n }\n\n return true;\n }\n}\n","import { EventEmitter } from 'node:events';\nimport type { ActionRule, ActionContext, GovernanceLevel, RecommendationStatus } from './types.js';\nimport type { ActionRegistry } from './action-registry.js';\nimport type { ActionMatcher } from './action-matcher.js';\nimport type { Insight } from '../reasoning/types.js';\nimport { createLogger } from '../core/logger.js';\n\nconst logger = createLogger({ name: 'action-executor' });\n\nexport interface ActionExecutorStorage {\n saveRecommendation(rec: { action: string; reason: string; confidence: number; status: string; governance: string; insightId: string | null; entity: string; context: string }): number;\n getRecommendation(id: number): { id: number; action: string; reason: string; confidence: number; status: string; governance: string; insightId: string | null; entity: string; context: string; createdAt: string; resolvedAt: string | null; resolvedBy: string | null } | undefined;\n updateRecommendationStatus(id: number, status: string, resolvedBy: string): void;\n}\n\nexport class ActionExecutor extends EventEmitter {\n private readonly registry: ActionRegistry;\n private readonly matcher: ActionMatcher;\n private readonly storage: ActionExecutorStorage;\n\n constructor(registry: ActionRegistry, matcher: ActionMatcher, storage: ActionExecutorStorage) {\n super();\n this.registry = registry;\n this.matcher = matcher;\n this.storage = storage;\n }\n\n async onInsight(insight: Insight): Promise<void> {\n const confidence = this.computeConfidence(insight);\n const matchedRules = this.matcher.match(insight, confidence);\n\n for (const rule of matchedRules) {\n await this.processRule(rule, insight, confidence);\n }\n }\n\n private async processRule(rule: ActionRule, insight: Insight, confidence: number): Promise<void> {\n const governance = this.registry.getGovernance(rule.action);\n const handler = this.registry.getHandler(rule.action);\n\n let status: RecommendationStatus = 'pending';\n if (governance === 'never_automate') {\n status = 'blocked';\n } else if (governance === 'auto_approve' && handler) {\n status = 'executed';\n }\n\n const insightId = `insight:${insight.entity}:${insight.insightType}:${Date.now()}`;\n const recData = {\n action: rule.action,\n reason: insight.message,\n confidence,\n status: status === 'executed' ? 'executed' : status,\n governance,\n insightId,\n entity: insight.entity,\n context: JSON.stringify(insight.context),\n };\n\n const recId = this.storage.saveRecommendation(recData);\n\n const emitRec: { id: number; action: string; reason: string; confidence: number; status: RecommendationStatus; governance: GovernanceLevel; insightId: string; entity: string; context: Record<string, unknown> } = {\n id: recId,\n action: rule.action,\n reason: insight.message,\n confidence,\n status,\n governance,\n insightId,\n entity: insight.entity,\n context: insight.context,\n };\n\n if (status === 'executed' && handler) {\n try {\n const actionContext: ActionContext = {\n insight,\n entity: insight.entity,\n recommendation: {\n id: recId,\n action: rule.action,\n reason: insight.message,\n confidence,\n status: 'executed',\n governance,\n insightId,\n entity: insight.entity,\n context: insight.context,\n createdAt: new Date().toISOString(),\n resolvedAt: null,\n resolvedBy: null,\n },\n };\n await handler.handler(actionContext);\n this.emit('action:executed', emitRec);\n logger.info({ action: rule.action, entity: insight.entity }, 'Action executed');\n } catch (error) {\n this.storage.updateRecommendationStatus(recId, 'failed', 'auto');\n emitRec.status = 'failed';\n this.emit('action:failed', { ...emitRec, error: (error as Error).message });\n logger.error({ action: rule.action, error: (error as Error).message }, 'Action failed');\n }\n }\n\n this.emit('recommendation', emitRec);\n }\n\n private computeConfidence(insight: Insight): number {\n const severityWeights: Record<string, number> = {\n critical: 0.95,\n high: 0.8,\n medium: 0.6,\n low: 0.4,\n };\n return severityWeights[insight.severity] ?? 0.5;\n }\n}\n","import type { KnowledgeNode } from './types.js';\nimport type { GraphStore } from './graph-store.js';\n\nconst DEFAULT_MAX_DEPTH = 5;\n\nexport class Traversal {\n private readonly store: GraphStore;\n\n constructor(store: GraphStore) {\n this.store = store;\n }\n\n causesOf(nodeId: number, maxDepth: number = DEFAULT_MAX_DEPTH): KnowledgeNode[] {\n return this.bfs(nodeId, 'backward', maxDepth);\n }\n\n impactOf(nodeId: number, maxDepth: number = DEFAULT_MAX_DEPTH): KnowledgeNode[] {\n return this.bfs(nodeId, 'forward', maxDepth);\n }\n\n timeline(nodeId: number): KnowledgeNode[] {\n const neighbors = this.store.neighbors(nodeId);\n return neighbors.sort((a, b) => {\n if (a.timestamp > b.timestamp) return -1;\n if (a.timestamp < b.timestamp) return 1;\n return 0;\n });\n }\n\n private bfs(startId: number, direction: 'forward' | 'backward', maxDepth: number): KnowledgeNode[] {\n const visited = new Set<number>();\n visited.add(startId);\n\n const result: KnowledgeNode[] = [];\n let currentLevel: number[] = [startId];\n\n for (let depth = 0; depth < maxDepth && currentLevel.length > 0; depth++) {\n const nextLevel: number[] = [];\n\n for (const nodeId of currentLevel) {\n const edges = direction === 'forward'\n ? this.store.getEdgesFrom(nodeId, 'causes')\n : this.store.getEdgesTo(nodeId, 'causes');\n\n for (const edge of edges) {\n const neighborId = direction === 'forward' ? edge.targetId : edge.sourceId;\n if (!visited.has(neighborId)) {\n visited.add(neighborId);\n const node = this.store.getNode(neighborId);\n if (node) {\n result.push(node);\n nextLevel.push(neighborId);\n }\n }\n }\n }\n\n currentLevel = nextLevel;\n }\n\n return result;\n }\n}\n","import type { EntityIntelligenceResult } from './types.js';\nimport type { GraphStore } from './graph-store.js';\n\nconst MAX_RECENT_INSIGHTS = 10;\n\nexport class EntityIntelligence {\n private readonly store: GraphStore;\n\n constructor(store: GraphStore) {\n this.store = store;\n }\n\n forEntity(refId: string): EntityIntelligenceResult | undefined {\n const entityNode = this.store.getNodeByRef('entity', refId);\n if (!entityNode) return undefined;\n\n const containsEdges = this.store.getEdgesFrom(entityNode.id, 'contains');\n const tableCount = containsEdges.length;\n\n const incomingEdges = this.store.getEdgesTo(entityNode.id, 'detected_on');\n const connectedNodeIds = incomingEdges.map((e) => e.sourceId);\n\n let totalEvents = 0;\n let anomalyCount = 0;\n const recentInsights = [];\n\n for (const nid of connectedNodeIds) {\n const node = this.store.getNode(nid);\n if (!node) continue;\n if (node.nodeType === 'event') totalEvents++;\n if (node.nodeType === 'anomaly') anomalyCount++;\n if (node.nodeType === 'insight') {\n recentInsights.push(node);\n }\n }\n\n recentInsights.sort((a, b) => (a.timestamp > b.timestamp ? -1 : 1));\n const limitedInsights = recentInsights.slice(0, MAX_RECENT_INSIGHTS);\n\n const correlatesEdges = this.store.getEdgesFrom(entityNode.id, 'correlates');\n const topCorrelations = correlatesEdges\n .map((edge) => {\n const targetNode = this.store.getNode(edge.targetId);\n return targetNode ? { entity: targetNode.label, weight: edge.weight } : null;\n })\n .filter((c): c is { entity: string; weight: number } => c !== null)\n .sort((a, b) => b.weight - a.weight);\n\n const riskScore = totalEvents > 0 ? anomalyCount / totalEvents : 0;\n\n return {\n entityName: entityNode.label,\n tableCount,\n totalEvents,\n anomalyCount,\n topCorrelations,\n recentInsights: limitedInsights,\n riskScore,\n };\n }\n}\n","import type { GraphExport } from './types.js';\nimport type { GraphStore } from './graph-store.js';\n\nexport function exportGraph(store: GraphStore, rootNodeId?: number): GraphExport {\n if (rootNodeId === undefined) {\n return {\n nodes: store.getAllNodes(),\n edges: store.getAllEdges(),\n };\n }\n\n // BFS to find all reachable nodes\n const visited = new Set<number>();\n const queue: number[] = [rootNodeId];\n visited.add(rootNodeId);\n\n while (queue.length > 0) {\n const nodeId = queue.shift()!;\n const outgoing = store.getEdgesFrom(nodeId);\n const incoming = store.getEdgesTo(nodeId);\n\n for (const edge of [...outgoing, ...incoming]) {\n const neighborId = edge.sourceId === nodeId ? edge.targetId : edge.sourceId;\n if (!visited.has(neighborId)) {\n visited.add(neighborId);\n queue.push(neighborId);\n }\n }\n }\n\n const nodes = [];\n for (const id of visited) {\n const node = store.getNode(id);\n if (node) nodes.push(node);\n }\n\n const allEdges = store.getAllEdges();\n const edges = allEdges.filter(\n (e) => visited.has(e.sourceId) && visited.has(e.targetId)\n );\n\n return { nodes, edges };\n}\n","import { createLogger } from '../core/logger.js';\nimport type { NotificationRule, NotificationTrigger } from './types.js';\nimport { formatForSlack, formatGeneric } from './formatters.js';\n\nexport class Notifier {\n private readonly rules: NotificationRule[];\n private readonly logger = createLogger({ name: 'notifier' });\n\n constructor(rules: NotificationRule[]) {\n this.rules = rules;\n }\n\n async notify(trigger: NotificationTrigger, payload: Record<string, unknown>): Promise<void> {\n const matchingRules = this.rules.filter((rule) => {\n if (!rule.triggers.includes(trigger)) return false;\n if (rule.filter?.severity && payload.severity) {\n if (!rule.filter.severity.includes(payload.severity as 'low' | 'medium' | 'high' | 'critical')) {\n return false;\n }\n }\n if (rule.filter?.entity && payload.entity) {\n if (!rule.filter.entity.includes(payload.entity as string)) {\n return false;\n }\n }\n return true;\n });\n\n const sends: Promise<void>[] = [];\n for (const rule of matchingRules) {\n for (const target of rule.targets) {\n const body = target.type === 'slack'\n ? formatForSlack(trigger, payload)\n : formatGeneric(trigger, payload);\n\n sends.push(this.send(target.url, body, target.headers));\n }\n }\n\n const results = await Promise.allSettled(sends);\n for (const result of results) {\n if (result.status === 'rejected') {\n this.logger.error({ error: (result.reason as Error).message }, 'Webhook delivery failed');\n }\n }\n }\n\n private async send(url: string, body: Record<string, unknown>, headers?: Record<string, string>): Promise<void> {\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...headers,\n },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n throw new Error(`Webhook returned ${response.status}: ${await response.text()}`);\n }\n }\n}\n","import type { NotificationTrigger } from './types.js';\n\nconst SEVERITY_COLORS: Record<string, string> = {\n critical: '#dc2626',\n high: '#ea580c',\n medium: '#ca8a04',\n low: '#2563eb',\n};\n\nexport function formatForSlack(\n trigger: NotificationTrigger,\n payload: Record<string, unknown>,\n): Record<string, unknown> {\n const severity = (payload.severity as string) ?? 'info';\n const color = SEVERITY_COLORS[severity] ?? '#6b7280';\n const entity = (payload.entity as string) ?? 'unknown';\n const message = (payload.message as string) ?? JSON.stringify(payload);\n const timestamp = (payload.timestamp as string) ?? new Date().toISOString();\n\n return {\n attachments: [\n {\n color,\n blocks: [\n {\n type: 'section',\n text: {\n type: 'mrkdwn',\n text: `*[${trigger.toUpperCase()}]* ${message}`,\n },\n },\n {\n type: 'context',\n elements: [\n {\n type: 'mrkdwn',\n text: `Entity: *${entity}* | Severity: *${severity}* | ${timestamp}`,\n },\n ],\n },\n ],\n },\n ],\n };\n}\n\nexport function formatGeneric(\n trigger: NotificationTrigger,\n payload: Record<string, unknown>,\n): Record<string, unknown> {\n return {\n trigger,\n timestamp: (payload.timestamp as string) ?? new Date().toISOString(),\n data: payload,\n };\n}\n","import type { LLMProvider } from '../llm/types.js';\nimport type { CortexaStorage } from '../core/storage.js';\nimport type { GraphStore } from '../knowledge/graph-store.js';\nimport type { Traversal } from '../knowledge/traversal.js';\nimport { LLMResponseError } from '../core/errors.js';\nimport { createLogger } from '../core/logger.js';\nimport { ExplainContextBuilder } from './context-builder.js';\nimport type { ExplainTarget, ExplainOptions, ExplainResult, Evidence, CausalStep, RecommendedAction } from './types.js';\n\nconst logger = createLogger({ name: 'explainer' });\n\nlet explainCounter = 0;\n\nfunction generateExplanationId(target: ExplainTarget): string {\n explainCounter++;\n return `exp_${target.type}_${target.id}_${Date.now()}_${explainCounter}`;\n}\n\nexport class Explainer {\n private readonly llm: LLMProvider;\n private readonly contextBuilder: ExplainContextBuilder;\n\n constructor(llm: LLMProvider, storage: CortexaStorage, graphStore?: GraphStore, traversal?: Traversal) {\n this.llm = llm;\n this.contextBuilder = new ExplainContextBuilder(storage, graphStore, traversal);\n }\n\n async explain(target: ExplainTarget, options?: ExplainOptions): Promise<ExplainResult> {\n logger.info({ target }, 'Building explanation context');\n\n const context = this.contextBuilder.buildContext(target, options);\n const prompt = this.buildPrompt(target, context, options);\n const chatOptions = { jsonMode: true, maxTokens: 4096 };\n\n let response = await this.llm.chat(prompt, chatOptions);\n try {\n return this.parseResponse(response.content, target);\n } catch {\n logger.warn('First LLM parse failed, retrying');\n response = await this.llm.chat(prompt, chatOptions);\n return this.parseResponse(response.content, target);\n }\n }\n\n private buildPrompt(\n target: ExplainTarget,\n context: { targetDescription: string; entityInfo: string; recentEvents: string; baselines: string; transitions: string; graphContext: string; correlations: string },\n options?: ExplainOptions,\n ): string {\n const includeRecommendations = options?.includeRecommendations !== false;\n\n return `You are a database intelligence analyst. Given the following context about a detected ${target.type}, explain WHY it happened using root cause analysis.\n\nTARGET:\n${context.targetDescription}\n\nCONTEXT:\n\nEntity Information:\n${context.entityInfo}\n\nRecent Events:\n${context.recentEvents}\n\nBaselines:\n${context.baselines}\n\nState Transitions:\n${context.transitions}\n\nKnowledge Graph:\n${context.graphContext}\n\nCorrelations:\n${context.correlations}\n\nAnalyze the data above and return a JSON object with your explanation. Be specific and reference actual data points from the context.\n\nReturn valid JSON in this exact format:\n{\n \"summary\": \"1-2 sentence human-readable explanation of the root cause\",\n \"confidence\": 0.85,\n \"evidence\": [\n {\n \"type\": \"event|baseline|transition|correlation|graph_node\",\n \"description\": \"What this evidence shows\",\n \"data\": {},\n \"relevance\": 0.9\n }\n ],\n \"causalChain\": [\n {\n \"order\": 1,\n \"description\": \"First thing that happened\",\n \"confidence\": 0.8\n }\n ]${includeRecommendations ? `,\n \"recommendedActions\": [\n {\n \"action\": \"What to do\",\n \"reason\": \"Why this helps\",\n \"priority\": \"low|medium|high\"\n }\n ]` : ''}\n}`;\n }\n\n private parseResponse(content: string, target: ExplainTarget): ExplainResult {\n let data: {\n summary?: string;\n confidence?: number;\n evidence?: Evidence[];\n causalChain?: CausalStep[];\n recommendedActions?: RecommendedAction[];\n };\n\n try {\n data = JSON.parse(content) as typeof data;\n } catch (err) {\n throw new LLMResponseError(\n `Failed to parse explain response: ${(err as Error).message}`,\n content.slice(0, 500),\n );\n }\n\n if (!data.summary || typeof data.summary !== 'string') {\n throw new LLMResponseError('Invalid explain response: missing \"summary\"', content.slice(0, 500));\n }\n\n return {\n explanationId: generateExplanationId(target),\n target,\n summary: data.summary,\n confidence: typeof data.confidence === 'number' ? data.confidence : 0.5,\n evidence: Array.isArray(data.evidence) ? data.evidence.map((e) => ({\n type: e.type ?? 'event',\n description: e.description ?? '',\n data: e.data ?? {},\n relevance: typeof e.relevance === 'number' ? e.relevance : 0.5,\n })) : [],\n causalChain: Array.isArray(data.causalChain) ? data.causalChain.map((s, i) => ({\n order: s.order ?? i + 1,\n description: s.description ?? '',\n confidence: typeof s.confidence === 'number' ? s.confidence : 0.5,\n })) : [],\n recommendedActions: Array.isArray(data.recommendedActions) ? data.recommendedActions.map((a) => ({\n action: a.action ?? '',\n reason: a.reason ?? '',\n priority: (['low', 'medium', 'high'].includes(a.priority) ? a.priority : 'medium') as 'low' | 'medium' | 'high',\n })) : [],\n generatedAt: new Date().toISOString(),\n };\n }\n}\n","import type { CortexaStorage } from '../core/storage.js';\nimport type { GraphStore } from '../knowledge/graph-store.js';\nimport type { Traversal } from '../knowledge/traversal.js';\nimport type { ExplainTarget, ExplainContext, ExplainOptions } from './types.js';\n\nconst DEFAULT_MAX_EVENTS = 50;\nconst DEFAULT_MAX_GRAPH_DEPTH = 3;\n\nexport class ExplainContextBuilder {\n private readonly storage: CortexaStorage;\n private readonly graphStore: GraphStore | null;\n private readonly traversal: Traversal | null;\n\n constructor(storage: CortexaStorage, graphStore?: GraphStore, traversal?: Traversal) {\n this.storage = storage;\n this.graphStore = graphStore ?? null;\n this.traversal = traversal ?? null;\n }\n\n buildContext(target: ExplainTarget, options?: ExplainOptions): ExplainContext {\n const maxEvents = options?.maxContextEvents ?? DEFAULT_MAX_EVENTS;\n const maxGraphDepth = options?.maxGraphDepth ?? DEFAULT_MAX_GRAPH_DEPTH;\n\n switch (target.type) {\n case 'anomaly':\n return this.buildAnomalyContext(target.id, maxEvents, maxGraphDepth);\n case 'insight':\n return this.buildInsightContext(target.id, maxEvents, maxGraphDepth);\n case 'event':\n return this.buildEventContext(target.id, maxEvents);\n case 'entity':\n return this.buildEntityContext(target.id, maxEvents, maxGraphDepth);\n default:\n throw new Error(`Unknown explain target type: ${(target as ExplainTarget).type}`);\n }\n }\n\n private buildAnomalyContext(id: number, maxEvents: number, maxGraphDepth: number): ExplainContext {\n const anomaly = this.storage.getAnomalyById(id);\n if (!anomaly) {\n throw new Error(`Anomaly with id ${id} not found`);\n }\n\n const entity = anomaly.entity;\n const targetDescription = `Anomaly: ${anomaly.message} (type: ${anomaly.anomalyType}, severity: ${anomaly.severity}, expected: ${anomaly.expected}, actual: ${anomaly.actual}, at: ${anomaly.timestamp})`;\n\n return {\n targetDescription,\n entityInfo: this.getEntityInfo(entity),\n recentEvents: this.getRecentEvents(entity, maxEvents),\n baselines: this.getBaselines(entity),\n transitions: this.getTransitions(entity),\n graphContext: this.getGraphContext(entity, maxGraphDepth),\n correlations: this.getCorrelations(entity),\n };\n }\n\n private buildInsightContext(id: number, maxEvents: number, maxGraphDepth: number): ExplainContext {\n const insight = this.storage.getInsightById(id);\n if (!insight) {\n throw new Error(`Insight with id ${id} not found`);\n }\n\n const entity = insight.entity;\n const targetDescription = `Insight: ${insight.message} (type: ${insight.insightType}, severity: ${insight.severity}, at: ${insight.timestamp}, context: ${JSON.stringify(insight.context)})`;\n\n return {\n targetDescription,\n entityInfo: this.getEntityInfo(entity),\n recentEvents: this.getRecentEvents(entity, maxEvents),\n baselines: this.getBaselines(entity),\n transitions: this.getTransitions(entity),\n graphContext: this.getGraphContext(entity, maxGraphDepth),\n correlations: this.getCorrelations(entity),\n };\n }\n\n private buildEventContext(id: number, maxEvents: number): ExplainContext {\n const event = this.storage.getEventById(id);\n if (!event) {\n throw new Error(`Event with id ${id} not found`);\n }\n\n const entity = event.entity;\n const targetDescription = `Event: ${event.eventType} on ${event.tableName} (operation: ${event.operation}, row: ${event.rowId}, at: ${event.timestamp})`;\n\n return {\n targetDescription,\n entityInfo: this.getEntityInfo(entity),\n recentEvents: this.getRecentEvents(entity, maxEvents),\n baselines: this.getBaselines(entity),\n transitions: this.getTransitions(entity),\n graphContext: '',\n correlations: this.getCorrelations(entity),\n };\n }\n\n private buildEntityContext(id: number, maxEvents: number, maxGraphDepth: number): ExplainContext {\n // For entity targets, the id refers to the entity's row in entities table\n // We look up by scanning entities\n const entities = this.storage.getEntities();\n const entityRow = entities[id - 1]; // entities don't have reliable IDs, use as index fallback\n\n if (!entityRow) {\n throw new Error(`Entity with id ${id} not found`);\n }\n\n const entity = entityRow.tableName;\n const targetDescription = `Entity: ${entityRow.entityLabel} (${entity}, type: ${entityRow.entityType}, description: ${entityRow.description})`;\n\n const anomalies = this.storage.getAnomalies({ entity });\n const insights = this.storage.getInsights({ entity });\n const anomalySummary = anomalies.length > 0\n ? `Recent anomalies (${anomalies.length}): ${anomalies.slice(0, 5).map((a) => `${a.anomalyType}:${a.severity} - ${a.message}`).join('; ')}`\n : 'No anomalies detected';\n const insightSummary = insights.length > 0\n ? `Recent insights (${insights.length}): ${insights.slice(0, 5).map((i) => `${i.insightType}:${i.severity} - ${i.message}`).join('; ')}`\n : 'No insights generated';\n\n return {\n targetDescription: `${targetDescription}\\n${anomalySummary}\\n${insightSummary}`,\n entityInfo: this.getEntityInfo(entity),\n recentEvents: this.getRecentEvents(entity, maxEvents),\n baselines: this.getBaselines(entity),\n transitions: this.getTransitions(entity),\n graphContext: this.getGraphContext(entity, maxGraphDepth),\n correlations: this.getCorrelations(entity),\n };\n }\n\n private getEntityInfo(entity: string): string {\n const entityData = this.storage.getEntity(entity);\n if (!entityData) return `Entity: ${entity} (no classification data)`;\n\n return `Entity: ${entityData.entityLabel} (table: ${entity}, type: ${entityData.entityType}, description: ${entityData.description}, confidence: ${entityData.confidence})`;\n }\n\n private getRecentEvents(entity: string, maxEvents: number): string {\n const events = this.storage.getEvents({ entity });\n const limited = events.slice(0, maxEvents);\n if (limited.length === 0) return 'No recent events';\n\n return limited.map((e) => `[${e.timestamp}] ${e.eventType} ${e.operation} (row: ${e.rowId})`).join('\\n');\n }\n\n private getBaselines(entity: string): string {\n const baselines = this.storage.getBaselines();\n const entityBaselines = baselines.filter((b) => b.entity === entity);\n if (entityBaselines.length === 0) return 'No baselines established';\n\n return entityBaselines.map((b) => `${b.metric}: mean=${b.mean.toFixed(2)}, stddev=${b.stddev.toFixed(2)}, samples=${b.sampleSize}`).join('\\n');\n }\n\n private getTransitions(entity: string): string {\n const stats = this.storage.getTransitionStats(entity);\n if (stats.length === 0) return 'No state transitions recorded';\n\n return stats.map((t) => `${t.fromState} -> ${t.toState}: count=${t.count}, avg=${t.avgDurationMs}ms, min=${t.minDurationMs}ms, max=${t.maxDurationMs}ms`).join('\\n');\n }\n\n private getGraphContext(entity: string, maxDepth: number): string {\n if (!this.graphStore || !this.traversal) return 'Knowledge graph not available';\n\n const entityNode = this.graphStore.getNodeByRef('entity', entity);\n if (!entityNode) return 'Entity not found in knowledge graph';\n\n const neighbors = this.graphStore.neighbors(entityNode.id);\n const causes = this.traversal.causesOf(entityNode.id, maxDepth);\n const impacts = this.traversal.impactOf(entityNode.id, maxDepth);\n\n const parts: string[] = [];\n if (neighbors.length > 0) {\n parts.push(`Connected nodes (${neighbors.length}): ${neighbors.map((n) => `${n.nodeType}:${n.label}`).join(', ')}`);\n }\n if (causes.length > 0) {\n parts.push(`Causes (${causes.length}): ${causes.map((n) => `${n.nodeType}:${n.label}`).join(', ')}`);\n }\n if (impacts.length > 0) {\n parts.push(`Impacts (${impacts.length}): ${impacts.map((n) => `${n.nodeType}:${n.label}`).join(', ')}`);\n }\n\n return parts.length > 0 ? parts.join('\\n') : 'No graph connections found';\n }\n\n private getCorrelations(entity: string): string {\n const rates = this.storage.getCorrelationRates(entity, 24);\n if (rates.length === 0) return 'No correlation data';\n\n return `Correlation rates (last 24h): ${rates.slice(0, 10).map((r) => `${r.bucket}:${r.eventCount}`).join(', ')}`;\n }\n}\n","import type { LLMProvider } from '../llm/types.js';\nimport type { CortexaStorage } from '../core/storage.js';\nimport type { GraphStore } from '../knowledge/graph-store.js';\nimport { LLMResponseError } from '../core/errors.js';\nimport { createLogger } from '../core/logger.js';\nimport { AskContextBuilder } from './ask-context-builder.js';\nimport type { AskOptions, AskResult, SupportingSignal, SignalType } from './types.js';\n\nconst logger = createLogger({ name: 'asker' });\n\nlet askCounter = 0;\n\nfunction generateAskId(): string {\n askCounter++;\n return `ask_${Date.now()}_${askCounter}`;\n}\n\nconst VALID_SIGNAL_TYPES: Set<string> = new Set([\n 'baselineDeviation', 'anomaly', 'insight', 'eventCluster',\n 'transition', 'correlation', 'graphRelation',\n]);\n\nexport class Asker {\n private readonly llm: LLMProvider;\n private readonly contextBuilder: AskContextBuilder;\n\n constructor(llm: LLMProvider, storage: CortexaStorage, graphStore?: GraphStore) {\n this.llm = llm;\n this.contextBuilder = new AskContextBuilder(storage, graphStore);\n }\n\n async ask(question: string, options?: AskOptions): Promise<AskResult> {\n logger.info({ question }, 'Processing question');\n\n const context = this.contextBuilder.buildContext(options);\n const prompt = this.buildPrompt(question, context);\n const chatOptions = { jsonMode: true, maxTokens: 4096 };\n\n let response = await this.llm.chat(prompt, chatOptions);\n try {\n return this.parseResponse(response.content, question);\n } catch {\n logger.warn('First LLM parse failed, retrying');\n response = await this.llm.chat(prompt, chatOptions);\n return this.parseResponse(response.content, question);\n }\n }\n\n private buildPrompt(\n question: string,\n context: { entities: string; recentEvents: string; baselines: string; anomalies: string; insights: string; transitions: string; graphSummary: string; recommendations: string },\n ): string {\n return `You are a database intelligence analyst. You have access to a live monitoring system that tracks a database. Answer the user's question using ONLY the data provided below. Be specific — reference actual numbers, entity names, and timestamps from the data.\n\nQUESTION: ${question}\n\nSYSTEM STATE:\n\nEntities:\n${context.entities}\n\nRecent Events:\n${context.recentEvents}\n\nBaselines:\n${context.baselines}\n\nAnomalies:\n${context.anomalies}\n\nInsights:\n${context.insights}\n\nState Transitions:\n${context.transitions}\n\nKnowledge Graph:\n${context.graphSummary}\n\nRecommendations:\n${context.recommendations}\n\nAnalyze the data and answer the question. If the data doesn't contain enough information, say so honestly and lower your confidence score.\n\nReturn valid JSON in this exact format:\n{\n \"answer\": \"Clear, specific answer referencing actual data points\",\n \"confidence\": 0.85,\n \"supportingSignals\": [\n {\n \"type\": \"baselineDeviation|anomaly|insight|eventCluster|transition|correlation|graphRelation\",\n \"entity\": \"entity name\",\n \"description\": \"What this signal shows\",\n \"data\": {}\n }\n ],\n \"relatedEntities\": [\"entity1\", \"entity2\"],\n \"recommendedActions\": [\"Action 1\", \"Action 2\"]\n}`;\n }\n\n private parseResponse(content: string, question: string): AskResult {\n let data: {\n answer?: string;\n confidence?: number;\n supportingSignals?: SupportingSignal[];\n relatedEntities?: string[];\n recommendedActions?: string[];\n };\n\n try {\n data = JSON.parse(content) as typeof data;\n } catch (err) {\n throw new LLMResponseError(\n `Failed to parse ask response: ${(err as Error).message}`,\n content.slice(0, 500),\n );\n }\n\n if (!data.answer || typeof data.answer !== 'string') {\n throw new LLMResponseError('Invalid ask response: missing \"answer\"', content.slice(0, 500));\n }\n\n return {\n askId: generateAskId(),\n question,\n answer: data.answer,\n confidence: typeof data.confidence === 'number' ? data.confidence : 0.5,\n supportingSignals: Array.isArray(data.supportingSignals) ? data.supportingSignals.map((s) => ({\n type: (VALID_SIGNAL_TYPES.has(s.type) ? s.type : 'anomaly') as SignalType,\n entity: s.entity ?? '',\n description: s.description ?? '',\n data: s.data ?? {},\n })) : [],\n relatedEntities: Array.isArray(data.relatedEntities)\n ? data.relatedEntities.filter((e): e is string => typeof e === 'string')\n : [],\n recommendedActions: Array.isArray(data.recommendedActions)\n ? data.recommendedActions.filter((a): a is string => typeof a === 'string')\n : [],\n generatedAt: new Date().toISOString(),\n };\n }\n}\n","import type { CortexaStorage } from '../core/storage.js';\nimport type { GraphStore } from '../knowledge/graph-store.js';\nimport type { AskOptions, AskContext } from './types.js';\n\nconst DEFAULT_MAX_EVENTS = 50;\nconst MAX_ANOMALIES = 20;\nconst MAX_INSIGHTS = 20;\nconst MAX_RECOMMENDATIONS = 10;\n\nexport class AskContextBuilder {\n private readonly storage: CortexaStorage;\n private readonly graphStore: GraphStore | null;\n\n constructor(storage: CortexaStorage, graphStore?: GraphStore) {\n this.storage = storage;\n this.graphStore = graphStore ?? null;\n }\n\n buildContext(options?: AskOptions): AskContext {\n const maxEvents = options?.maxContextEvents ?? DEFAULT_MAX_EVENTS;\n const entityHint = options?.entityHint;\n\n return {\n entities: this.getEntities(),\n recentEvents: this.getRecentEvents(maxEvents, entityHint),\n baselines: this.getBaselines(),\n anomalies: this.getAnomalies(),\n insights: this.getInsights(),\n transitions: this.getTransitions(),\n graphSummary: this.getGraphSummary(),\n recommendations: this.getRecommendations(),\n };\n }\n\n private getEntities(): string {\n const entities = this.storage.getEntities();\n if (entities.length === 0) return 'No entities discovered yet';\n\n return entities.map((e) =>\n `${e.tableName} (${e.entityLabel}, type: ${e.entityType}, ${e.description})`\n ).join('\\n');\n }\n\n private getRecentEvents(maxEvents: number, entityHint?: string): string {\n const filter: { entity?: string } = {};\n if (entityHint) filter.entity = entityHint;\n\n const events = this.storage.getEvents(filter);\n const limited = events.slice(0, maxEvents);\n if (limited.length === 0) return 'No recent events';\n\n return `${events.length} total events (showing ${limited.length}):\\n` +\n limited.map((e) =>\n `[${e.timestamp}] ${e.entity} ${e.eventType} ${e.operation} (row: ${e.rowId})`\n ).join('\\n');\n }\n\n private getBaselines(): string {\n const baselines = this.storage.getBaselines();\n if (baselines.length === 0) return 'No baselines established';\n\n return baselines.map((b) =>\n `${b.entity}.${b.metric}: mean=${b.mean.toFixed(2)}, stddev=${b.stddev.toFixed(2)}, samples=${b.sampleSize}`\n ).join('\\n');\n }\n\n private getAnomalies(): string {\n const anomalies = this.storage.getAnomalies();\n const limited = anomalies.slice(0, MAX_ANOMALIES);\n if (limited.length === 0) return 'No anomalies detected';\n\n return `${anomalies.length} total anomalies (showing ${limited.length}):\\n` +\n limited.map((a) =>\n `[${a.timestamp}] ${a.entity} ${a.anomalyType} (${a.severity}): ${a.message} (expected: ${a.expected}, actual: ${a.actual})`\n ).join('\\n');\n }\n\n private getInsights(): string {\n const insights = this.storage.getInsights();\n const limited = insights.slice(0, MAX_INSIGHTS);\n if (limited.length === 0) return 'No insights generated';\n\n return `${insights.length} total insights (showing ${limited.length}):\\n` +\n limited.map((i) =>\n `[${i.timestamp}] ${i.entity} ${i.insightType} (${i.severity}): ${i.message}`\n ).join('\\n');\n }\n\n private getTransitions(): string {\n const stats = this.storage.getTransitionStats();\n if (stats.length === 0) return 'No state transitions recorded';\n\n return stats.map((t) =>\n `${t.entity}: ${t.fromState} -> ${t.toState} (count=${t.count}, avg=${t.avgDurationMs}ms)`\n ).join('\\n');\n }\n\n private getGraphSummary(): string {\n if (!this.graphStore) return 'Knowledge graph not available';\n\n const summary = this.graphStore.getSummary();\n return `Nodes: ${summary.totalNodes}, Edges: ${summary.totalEdges} (entities: ${summary.entities}, events: ${summary.events}, anomalies: ${summary.anomalies}, insights: ${summary.insights})`;\n }\n\n private getRecommendations(): string {\n const recs = this.storage.getRecommendations({ last: MAX_RECOMMENDATIONS });\n if (recs.length === 0) return 'No recommendations';\n\n return recs.map((r) =>\n `[${r.status}] ${r.action}: ${r.reason} (confidence: ${r.confidence}, entity: ${r.entity})`\n ).join('\\n');\n }\n}\n","import { cosmiconfig } from 'cosmiconfig';\nimport type { LLMConfig } from '../llm/types.js';\nimport type { ReasoningConfig } from '../reasoning/types.js';\nimport type { AnalyticsConfig } from '../analytics/types.js';\nimport type { KnowledgeConfig } from '../knowledge/types.js';\nimport type { ActionsConfig } from '../actions/types.js';\nimport type { NotificationsConfig } from '../notifications/types.js';\nimport { ConfigError } from './errors.js';\nimport { validateConfig } from './validate-config.js';\n\n// Re-export as LlmConfig for backwards compatibility\nexport type LlmConfig = LLMConfig;\n\nexport interface ConnectionConfig {\n type: 'postgres' | 'mysql' | 'mariadb' | 'cockroachdb' | 'sqlite' | 'mongodb' | 'mssql';\n url?: string;\n host?: string;\n port?: number;\n database?: string;\n user?: string;\n password?: string;\n path?: string;\n}\n\nexport interface CortexaConfig {\n connection: ConnectionConfig;\n llm?: LLMConfig;\n reasoning?: ReasoningConfig;\n analytics?: AnalyticsConfig;\n knowledge?: KnowledgeConfig;\n actions?: ActionsConfig;\n notifications?: NotificationsConfig;\n batchSize?: number;\n}\n\nexport function defineConfig(config: CortexaConfig): CortexaConfig {\n return config;\n}\n\nconst MODULE_NAME = 'cortexa';\n\nexport async function loadConfig(searchFrom?: string): Promise<CortexaConfig> {\n const explorer = cosmiconfig(MODULE_NAME, {\n searchPlaces: [\n 'cortexa.config.ts',\n 'cortexa.config.js',\n 'cortexa.config.mjs',\n 'cortexa.config.cjs',\n '.cortexarc',\n '.cortexarc.json',\n '.cortexarc.yaml',\n '.cortexarc.yml',\n ],\n });\n\n const result = await explorer.search(searchFrom);\n\n if (!result || result.isEmpty) {\n throw new ConfigError(\n 'No Cortexa configuration found.',\n 'Run `npx cortexa init` to create a cortexa.config.ts file.',\n );\n }\n\n const validationErrors = validateConfig(result.config);\n if (validationErrors.length > 0) {\n const messages = validationErrors.map((e) => ` ${e.path}: ${e.message}`).join('\\n');\n throw new ConfigError(\n `Invalid configuration:\\n${messages}`,\n 'Check your cortexa.config.ts file.',\n );\n }\n\n return result.config as CortexaConfig;\n}\n","export interface ValidationError {\n path: string;\n message: string;\n}\n\nexport function validateConfig(config: unknown): ValidationError[] {\n const errors: ValidationError[] = [];\n\n if (!config || typeof config !== 'object') {\n errors.push({ path: '', message: 'Config must be an object.' });\n return errors;\n }\n\n const cfg = config as Record<string, unknown>;\n\n // connection (required)\n if (!cfg.connection || typeof cfg.connection !== 'object') {\n errors.push({ path: 'connection', message: 'Required. Must be an object with type, and either url or host+database.' });\n return errors;\n }\n\n const conn = cfg.connection as Record<string, unknown>;\n\n const validTypes = new Set(['postgres', 'mysql', 'mariadb', 'cockroachdb', 'sqlite', 'mongodb', 'mssql']);\n if (!conn.type || !validTypes.has(conn.type as string)) {\n errors.push({ path: 'connection.type', message: `Must be one of: ${[...validTypes].join(', ')}.` });\n }\n\n if (conn.type === 'sqlite') {\n if (!conn.path && !conn.database) {\n errors.push({ path: 'connection', message: 'SQLite requires path or database (file path).' });\n }\n } else if (!conn.url && !conn.host) {\n errors.push({ path: 'connection', message: 'Provide either url or host+database.' });\n }\n\n if (conn.port !== undefined && conn.port !== null) {\n if (typeof conn.port !== 'number' || !Number.isInteger(conn.port) || conn.port <= 0) {\n errors.push({ path: 'connection.port', message: 'Must be a positive integer.' });\n }\n }\n\n // llm (optional)\n if (cfg.llm !== undefined) {\n if (typeof cfg.llm !== 'object' || cfg.llm === null) {\n errors.push({ path: 'llm', message: 'Must be an object.' });\n } else {\n const llm = cfg.llm as Record<string, unknown>;\n\n if (!llm.provider || typeof llm.provider !== 'string') {\n errors.push({ path: 'llm.provider', message: 'Required. Must be a string (e.g., \"openai\", \"deepseek\", \"anthropic\").' });\n }\n\n if (llm.apiKey !== undefined && (typeof llm.apiKey !== 'string' || llm.apiKey.length === 0)) {\n errors.push({ path: 'llm.apiKey', message: 'Must be a non-empty string.' });\n }\n\n if (llm.baseUrl !== undefined && (typeof llm.baseUrl !== 'string' || !llm.baseUrl.startsWith('http'))) {\n errors.push({ path: 'llm.baseUrl', message: 'Must be a valid URL starting with http.' });\n }\n }\n }\n\n // batchSize (optional)\n if (cfg.batchSize !== undefined) {\n if (typeof cfg.batchSize !== 'number' || !Number.isInteger(cfg.batchSize) || cfg.batchSize < 1 || cfg.batchSize > 50) {\n errors.push({ path: 'batchSize', message: 'Must be an integer between 1 and 50.' });\n }\n }\n\n // notifications (optional)\n if (cfg.notifications !== undefined) {\n if (typeof cfg.notifications !== 'object' || cfg.notifications === null) {\n errors.push({ path: 'notifications', message: 'Must be an object.' });\n } else {\n const notif = cfg.notifications as Record<string, unknown>;\n if (notif.enabled !== undefined && typeof notif.enabled !== 'boolean') {\n errors.push({ path: 'notifications.enabled', message: 'Must be a boolean.' });\n }\n if (notif.rules !== undefined) {\n if (!Array.isArray(notif.rules)) {\n errors.push({ path: 'notifications.rules', message: 'Must be an array.' });\n } else {\n const validTriggers = new Set(['anomaly', 'insight', 'recommendation', 'action:executed', 'action:failed']);\n for (let i = 0; i < notif.rules.length; i++) {\n const rule = notif.rules[i] as Record<string, unknown>;\n if (!rule.triggers || !Array.isArray(rule.triggers) || rule.triggers.length === 0) {\n errors.push({ path: `notifications.rules[${i}].triggers`, message: 'Required. Must be a non-empty array of trigger types.' });\n } else {\n for (const t of rule.triggers) {\n if (!validTriggers.has(t as string)) {\n errors.push({ path: `notifications.rules[${i}].triggers`, message: `Invalid trigger \"${t}\". Must be one of: ${[...validTriggers].join(', ')}.` });\n }\n }\n }\n if (!rule.targets || !Array.isArray(rule.targets) || rule.targets.length === 0) {\n errors.push({ path: `notifications.rules[${i}].targets`, message: 'Required. Must be a non-empty array of webhook targets.' });\n } else {\n for (let j = 0; j < rule.targets.length; j++) {\n const target = rule.targets[j] as Record<string, unknown>;\n if (!target.url || typeof target.url !== 'string' || !target.url.startsWith('http')) {\n errors.push({ path: `notifications.rules[${i}].targets[${j}].url`, message: 'Must be a valid URL starting with http.' });\n }\n }\n }\n }\n }\n }\n }\n }\n\n return errors;\n}\n","export { CortexaServer } from './server.js';\nexport type { ServerConfig, ApiResponse } from './types.js';\n","import { createServer, type Server } from 'node:http';\nimport type { CortexaOptions } from '../index.js';\nimport { Cortexa } from '../index.js';\nimport type { ServerConfig } from './types.js';\nimport { Router } from './router.js';\nimport { registerHandlers } from './handlers.js';\nimport { createLogger } from '../core/logger.js';\n\nexport class CortexaServer {\n private readonly cortexa: Cortexa;\n private readonly serverConfig: ServerConfig;\n private readonly logger: ReturnType<typeof createLogger>;\n private httpServer: Server | null = null;\n\n constructor(cortexaConfig: CortexaOptions, serverConfig?: ServerConfig) {\n this.cortexa = new Cortexa(cortexaConfig);\n this.serverConfig = {\n port: serverConfig?.port ?? 3210,\n host: serverConfig?.host ?? '127.0.0.1',\n cors: serverConfig?.cors ?? true,\n };\n this.logger = createLogger();\n }\n\n async start(): Promise<void> {\n await this.cortexa.connect();\n\n const router = new Router();\n registerHandlers(router, this.cortexa);\n\n const cors = this.serverConfig.cors ?? true;\n\n this.httpServer = createServer((req, res) => {\n router.handle(req, res, cors).catch((err) => {\n this.logger.error({ err }, 'Unhandled request error');\n res.writeHead(500, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ ok: false, error: 'Internal server error' }));\n });\n });\n\n const { port, host } = this.serverConfig;\n\n await new Promise<void>((resolve) => {\n this.httpServer!.listen(port, host, () => {\n this.logger.info({ port, host }, 'Cortexa REST API server started');\n resolve();\n });\n });\n }\n\n async stop(): Promise<void> {\n if (this.httpServer) {\n await new Promise<void>((resolve, reject) => {\n this.httpServer!.close((err) => {\n if (err) reject(err);\n else resolve();\n });\n });\n this.httpServer = null;\n }\n await this.cortexa.disconnect();\n this.logger.info('Cortexa REST API server stopped');\n }\n\n get address(): { port: number; host: string } {\n return {\n port: this.serverConfig.port ?? 3210,\n host: this.serverConfig.host ?? '127.0.0.1',\n };\n }\n}\n","import type { IncomingMessage, ServerResponse } from 'node:http';\nimport type { Route, RouteHandler, RouteParams, ApiResponse } from './types.js';\n\nexport class Router {\n private readonly routes: Route[] = [];\n\n get(path: string, handler: RouteHandler): void {\n this.addRoute('GET', path, handler);\n }\n\n post(path: string, handler: RouteHandler): void {\n this.addRoute('POST', path, handler);\n }\n\n private addRoute(method: string, path: string, handler: RouteHandler): void {\n const paramNames: string[] = [];\n const patternStr = path.replace(/:(\\w+)/g, (_match, name: string) => {\n paramNames.push(name);\n return '([^/]+)';\n });\n this.routes.push({\n method,\n pattern: new RegExp(`^${patternStr}$`),\n paramNames,\n handler,\n });\n }\n\n async handle(req: IncomingMessage, res: ServerResponse, cors: boolean): Promise<void> {\n if (cors) {\n res.setHeader('Access-Control-Allow-Origin', '*');\n res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');\n res.setHeader('Access-Control-Allow-Headers', 'Content-Type');\n }\n\n if (req.method === 'OPTIONS') {\n res.writeHead(204);\n res.end();\n return;\n }\n\n const url = new URL(req.url ?? '/', `http://${req.headers.host ?? 'localhost'}`);\n const path = url.pathname;\n const method = req.method ?? 'GET';\n\n const query: Record<string, string> = {};\n url.searchParams.forEach((value, key) => {\n query[key] = value;\n });\n\n for (const route of this.routes) {\n if (route.method !== method) continue;\n const match = route.pattern.exec(path);\n if (!match) continue;\n\n const pathParams: Record<string, string> = {};\n for (let i = 0; i < route.paramNames.length; i++) {\n pathParams[route.paramNames[i]] = match[i + 1];\n }\n\n let body: unknown = undefined;\n if (method === 'POST') {\n body = await readBody(req);\n }\n\n const params: RouteParams = { path, method, query, body, pathParams };\n\n try {\n const result = await route.handler(params);\n sendJson(res, result.ok ? 200 : 400, result);\n } catch (err) {\n const message = err instanceof Error ? err.message : 'Internal server error';\n sendJson(res, 500, { ok: false, error: message });\n }\n return;\n }\n\n sendJson(res, 404, { ok: false, error: `Not found: ${method} ${path}` });\n }\n}\n\nfunction sendJson(res: ServerResponse, statusCode: number, data: ApiResponse): void {\n res.writeHead(statusCode, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify(data));\n}\n\nfunction readBody(req: IncomingMessage): Promise<unknown> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n req.on('data', (chunk: Buffer) => chunks.push(chunk));\n req.on('end', () => {\n const raw = Buffer.concat(chunks).toString();\n if (!raw) {\n resolve(undefined);\n return;\n }\n try {\n resolve(JSON.parse(raw));\n } catch {\n reject(new Error('Invalid JSON body'));\n }\n });\n req.on('error', reject);\n });\n}\n","import type { Cortexa } from '../index.js';\nimport type { RouteParams, ApiResponse } from './types.js';\nimport { Router } from './router.js';\nimport type { ExplainTarget } from '../explain/types.js';\n\nexport function registerHandlers(router: Router, cortexa: Cortexa): void {\n // GET /api/status\n router.get('/api/status', async (): Promise<ApiResponse> => {\n return { ok: true, data: cortexa.status };\n });\n\n // GET /api/entities\n router.get('/api/entities', async (): Promise<ApiResponse> => {\n const { entities } = cortexa.exportGraph();\n return { ok: true, data: entities };\n });\n\n // GET /api/relationships\n router.get('/api/relationships', async (): Promise<ApiResponse> => {\n const { relationships } = cortexa.exportGraph();\n return { ok: true, data: relationships };\n });\n\n // POST /api/discover\n router.post('/api/discover', async (params: RouteParams): Promise<ApiResponse> => {\n const body = (params.body ?? {}) as Record<string, unknown>;\n const result = await cortexa.discover({\n includeSampleData: body.includeSampleData !== false,\n excludeTables: body.excludeTables as string[] | undefined,\n excludeColumns: body.excludeColumns as string[] | undefined,\n });\n return {\n ok: true,\n data: {\n tables: result.raw.tables.length,\n entities: result.entities.length,\n relationships: result.relationships.length,\n },\n };\n });\n\n // GET /api/events\n router.get('/api/events', async (params: RouteParams): Promise<ApiResponse> => {\n const filter: Record<string, unknown> = {};\n if (params.query.entity) filter.entity = params.query.entity;\n if (params.query.last) filter.last = parseInt(params.query.last, 10);\n if (params.query.operation) filter.operation = params.query.operation;\n return { ok: true, data: cortexa.getEvents(filter as Parameters<typeof cortexa.getEvents>[0]) };\n });\n\n // GET /api/baselines\n router.get('/api/baselines', async (): Promise<ApiResponse> => {\n return { ok: true, data: cortexa.getBaselines() };\n });\n\n // GET /api/anomalies\n router.get('/api/anomalies', async (params: RouteParams): Promise<ApiResponse> => {\n const filter: Record<string, unknown> = {};\n if (params.query.entity) filter.entity = params.query.entity;\n if (params.query.last) filter.last = parseInt(params.query.last, 10);\n if (params.query.severity) filter.severity = params.query.severity;\n return { ok: true, data: cortexa.getAnomalies(filter as Parameters<typeof cortexa.getAnomalies>[0]) };\n });\n\n // GET /api/insights\n router.get('/api/insights', async (params: RouteParams): Promise<ApiResponse> => {\n const filter: Record<string, unknown> = {};\n if (params.query.entity) filter.entity = params.query.entity;\n if (params.query.last) filter.last = parseInt(params.query.last, 10);\n if (params.query.severity) filter.severity = params.query.severity;\n return { ok: true, data: cortexa.getInsights(filter as Parameters<typeof cortexa.getInsights>[0]) };\n });\n\n // GET /api/transitions\n router.get('/api/transitions', async (params: RouteParams): Promise<ApiResponse> => {\n return { ok: true, data: cortexa.getTransitions(params.query.entity) };\n });\n\n // GET /api/correlations\n router.get('/api/correlations', async (): Promise<ApiResponse> => {\n return { ok: true, data: cortexa.getCorrelations() };\n });\n\n // GET /api/distributions\n router.get('/api/distributions', async (params: RouteParams): Promise<ApiResponse> => {\n return { ok: true, data: cortexa.getDistributions(params.query.entity) };\n });\n\n // GET /api/graph\n router.get('/api/graph', async (): Promise<ApiResponse> => {\n return { ok: true, data: cortexa.graph().getSummary() };\n });\n\n // GET /api/graph/export\n router.get('/api/graph/export', async (): Promise<ApiResponse> => {\n return { ok: true, data: cortexa.graph().export() };\n });\n\n // GET /api/graph/entity/:name\n router.get('/api/graph/entity/:name', async (params: RouteParams): Promise<ApiResponse> => {\n const intel = cortexa.graph().entity(params.pathParams.name).intelligence();\n if (!intel) {\n return { ok: false, error: `Entity \"${params.pathParams.name}\" not found in knowledge graph` };\n }\n return { ok: true, data: intel };\n });\n\n // GET /api/actions\n router.get('/api/actions', async (params: RouteParams): Promise<ApiResponse> => {\n const filter: Record<string, unknown> = {};\n if (params.query.status) filter.status = params.query.status;\n if (params.query.action) filter.action = params.query.action;\n return { ok: true, data: cortexa.getRecommendations(filter as Parameters<typeof cortexa.getRecommendations>[0]) };\n });\n\n // POST /api/actions/:id/approve\n router.post('/api/actions/:id/approve', async (params: RouteParams): Promise<ApiResponse> => {\n const id = parseInt(params.pathParams.id, 10);\n if (isNaN(id)) return { ok: false, error: 'Invalid id' };\n cortexa.approveRecommendation(id);\n return { ok: true, data: { id, status: 'approved' } };\n });\n\n // POST /api/actions/:id/reject\n router.post('/api/actions/:id/reject', async (params: RouteParams): Promise<ApiResponse> => {\n const id = parseInt(params.pathParams.id, 10);\n if (isNaN(id)) return { ok: false, error: 'Invalid id' };\n cortexa.rejectRecommendation(id);\n return { ok: true, data: { id, status: 'rejected' } };\n });\n\n // POST /api/explain\n router.post('/api/explain', async (params: RouteParams): Promise<ApiResponse> => {\n const body = params.body as Record<string, unknown> | undefined;\n if (!body?.type || !body?.id) {\n return { ok: false, error: 'Required: { type: \"anomaly\"|\"insight\"|\"event\"|\"entity\", id: number }' };\n }\n const target: ExplainTarget = {\n type: body.type as ExplainTarget['type'],\n id: body.id as number,\n };\n const result = await cortexa.explain(target);\n return { ok: true, data: result };\n });\n\n // POST /api/ask\n router.post('/api/ask', async (params: RouteParams): Promise<ApiResponse> => {\n const body = params.body as Record<string, unknown> | undefined;\n if (!body?.question || typeof body.question !== 'string') {\n return { ok: false, error: 'Required: { question: string }' };\n }\n const result = await cortexa.ask(body.question, {\n entityHint: body.entity as string | undefined,\n });\n return { ok: true, data: result };\n });\n\n // POST /api/watch\n router.post('/api/watch', async (params: RouteParams): Promise<ApiResponse> => {\n const body = (params.body ?? {}) as Record<string, unknown>;\n await cortexa.watch({\n interval: body.interval as number | undefined,\n once: body.once as boolean | undefined,\n });\n return { ok: true, data: { watching: true } };\n });\n\n // POST /api/unwatch\n router.post('/api/unwatch', async (): Promise<ApiResponse> => {\n cortexa.unwatch();\n return { ok: true, data: { watching: false } };\n });\n}\n"],"mappings":"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","names":["sql","sql","pino","logger","logger","import_mongodb","import_node_events","pg","sql","mysql","sql","Database","path","sql","MongoDBConnector","MSSQLConnector","import_better_sqlite3","import_node_path","path","fs","Database","sql","logger","row","result","sql","result","row","rowCount","path","UNIT_TO_MS","logger","MIN_SAMPLE_SIZE","logger","MIN_SAMPLE_SIZE","logger","logger","logger","logger","PostgresStream","MySQLStream","MongoDBStream","logger","DEFAULT_MAX_EVENTS","logger","path"]}
|