import { PGlite } from '@electric-sql/pglite'; import { S as ShardAttachmentProjection, a as ShardCollection, b as ShardEmbeddingConfig, c as ShardEmbedding, d as ShardEmbeddingSet, e as ShardEmbeddingSetMember, f as ShardLink, g as ShardNote, h as ShardNoteSkosTag, i as ShardProvenanceEdge, j as ShardSkosConcept, k as ShardSkosRelation, l as ShardSkosScheme, m as ShardTag, n as ShardTemplate, o as ShardManifest, B as BlobStore, p as BlobReconcileOptions, q as BlobReconcileResult, r as BlobGcOptions, s as BlobGcResult, t as ShardBackend, u as ShardOperation, v as ShardComponent, w as ShardLossEntry, x as ShardCapabilityReport, y as ShardProfileRegistryEntry, E as ExportOptions, z as ShardExportResult, I as ImportOptions, A as ImportResult } from './aiwg-index-shard-BCdaz0X1.js'; export { C as AIWG_SCAN_REQUIRED_FIELDS, D as AiwgChunkedIndexBuildOptions, F as AiwgChunkedIndexBuildResult, G as AiwgChunkedIndexDetailLoader, H as AiwgChunkedIndexLoadOptions, J as AiwgChunkedIndexLoader, K as AiwgChunkedIndexProgress, L as AiwgChunkedIndexProgressPhase, M as AiwgChunkedIndexQueryOptions, N as AiwgChunkedIndexQueryResult, O as AiwgChunkedIndexValidationResult, P as AiwgFortemiAttachmentReference, Q as AiwgFortemiBinarySource, R as AiwgFortemiChunk, T as AiwgFortemiChunkDetailRef, U as AiwgFortemiChunkManifest, V as AiwgFortemiChunkPart, W as AiwgFortemiChunkPartRef, X as AiwgFortemiIndexExport, Y as AiwgFortemiIndexExportSchemaVersion, Z as AiwgFortemiProjectedRecord, _ as AiwgFortemiProvenance, $ as AiwgFortemiProvenanceEvent, a0 as AiwgFortemiRecord, a1 as AiwgFortemiRecordEmbedding, a2 as AiwgFortemiRecordSchemaVersion, a3 as AiwgFortemiRecordSource, a4 as AiwgFortemiRecordType, a5 as AiwgFortemiRelationship, a6 as AiwgFortemiRelationshipDirection, a7 as AiwgFortemiSearchProjection, a8 as AiwgFortemiSkosConcept, a9 as AiwgFortemiSkosRelation, aa as AiwgFortemiSkosRelationType, ab as AiwgHeadlessEmbeddingBackend, ac as AiwgIndexController, ad as AiwgIndexControllerListener, ae as AiwgIndexControllerSnapshot, af as AiwgIndexGraphOptions, ag as AiwgIndexQueryMatch, ah as AiwgIndexQueryOptions, ai as AiwgIndexQueryRankedItem, aj as AiwgIndexQueryResult, ak as AiwgIndexQueryWeights, al as AiwgIndexValidationResult, am as AiwgKnowledgeShardConversionResult, an as AiwgKnowledgeShardOptions, ao as AiwgPrivacyClassification, ap as AiwgPrivacyFilterOptions, aq as AiwgProvenanceConfidence, ar as AiwgRelationshipDirection, as as AiwgRelationshipEdgeSummary, at as AiwgRelationshipNodeSummary, au as AiwgRelationshipQueryOptions, av as AiwgRelationshipSetOperation, aw as AiwgRelationshipSetOptions, ax as AiwgRelationshipSetResult, ay as AiwgRelationshipTraversalOptions, az as AiwgRelationshipTraversalResult, aA as AiwgReviewAction, aB as AiwgReviewDecision, aC as AiwgReviewDecisionExport, aD as AiwgReviewInput, aE as AiwgStaticDuplicatePair, aF as AiwgStaticEmbeddingRecord, aG as AiwgStaticEmbeddingSet, aH as AiwgStaticHybridQueryOptions, aI as AiwgStaticSemanticQueryOptions, aJ as AiwgStaticSemanticResult, aK as AllowlistTrustStore, aL as BlobBackendKind, aM as BlobStoreDiagnostics, aN as BuildAiwgStaticEmbeddingSetOptions, aO as CURRENT_SHARD_VERSION, aP as ConflictStrategy, aQ as CreateBlobStoreOptions, aR as ImportCounts, aS as ImportProgress, aT as ImportProgressPhase, aU as KnowledgeShardProfile, aV as MemoryBlobStore, aW as SHARD_FORMAT, aX as SIGNATURE_ENTRY, aY as SIGNING_ENVELOPE_VERSION, aZ as ShardAuthorityStatus, a_ as ShardClusterRef, a$ as ShardLayout, b0 as ShardSignatureEnvelope, b1 as ShardSignatureVerdict, b2 as ShardSigner, b3 as ShardSigningPayload, b4 as ShardTrustStore, b5 as SignShardInput, b6 as TrustedKey, b7 as VerifyShardSignatureInput, b8 as aiwgFortemiIndexFromKnowledgeShard, b9 as aiwgFortemiIndexToCommunityGraph, ba as aiwgFortemiIndexToKnowledgeShard, bb as aiwgFortemiIndexToKnowledgeShardWithReport, bc as assertAiwgFortemiChunkManifest, bd as assertAiwgFortemiChunkPart, be as assertAiwgFortemiIndexExport, bf as assertAiwgStaticEmbeddingSet, bg as buildAiwgChunkedIndex, bh as buildAiwgStaticEmbeddingSet, bi as createAiwgFetchChunkLoader, bj as createAiwgFetchDetailLoader, bk as createAiwgIndexController, bl as createAiwgReviewDecisionExport, bm as createBlobStore, bn as createLazyBlobStore, bo as filterAiwgRecordsByPrivacy, bp as findAiwgStaticDuplicatePairs, bq as getAiwgFortemiFacets, br as isShardSigningSupported, bs as queryAiwgFortemiIndex, bt as queryAiwgHybridIndex, bu as queryAiwgSemanticIndex, bv as sidecarBlobDigests, bw as signShard, bx as validateAiwgFortemiChunkManifest, by as validateAiwgFortemiChunkPart, bz as validateAiwgFortemiIndexExport, bA as validateAiwgStaticEmbeddingSet, bB as verifyShardSignature } from './aiwg-index-shard-BCdaz0X1.js'; import { z, ZodType } from 'zod'; export { AiwgIndexSchemaValidationResult, getAiwgFortemiIndexExportSchema, validateAiwgFortemiIndexExportSchema, validateAiwgFortemiProjectedRecordSchema } from './aiwg-index-schema.js'; import '@bytecask/core'; /** * Generate a RFC 9562 UUIDv7 identifier. * * UUIDv7 embeds a Unix timestamp in the high bits, making IDs * time-sortable and monotonic within the same millisecond. */ declare function generateId(): string; /** * Typed event bus with IDisposable subscriptions (Monaco-style). * SSE-style pub/sub across all layers. * * Features: * - Exact event subscriptions via on() and once() * - Wildcard prefix subscriptions: on('note.*', handler) * - Cross-context bridging via bridge(port: MessagePort) */ interface IDisposable { dispose(): void; } interface EventMap { 'note.created': { id: string; }; 'note.updated': { id: string; }; 'note.deleted': { id: string; }; 'note.restored': { id: string; }; 'note.revised': { id: string; revisionNumber: number; }; 'source.upserted': { counts: Record; importRunId: string; }; 'purge.completed': { counts: Record; receiptId: string; }; 'search.reindexed': Record; 'embedding.ready': { noteId: string; }; 'capability.ready': { name: string; }; 'capability.disabled': { name: string; }; 'capability.loading': { name: string; progress?: number; }; 'capability.required': { jobId: string; message: string; name: string; noteId: string; type: string; }; 'job.completed': { id: string; noteId: string; type: string; }; 'job.failed': { error: string; id: string; noteId: string; type: string; }; 'job.blocked': { capability: string; id: string; message: string; noteId: string; type: string; }; 'archive.switched': { name: string; }; 'migration.applied': { version: number; }; 'provider.added': { id: string; name: string; }; 'provider.removed': { id: string; }; 'provider.active': { id: string; name: string; }; 'provider.fallback': { error: string; errorCategory: string; fromProvider: string; toProvider: string; }; 'provider.cooldown': { cooldownMs: number; errorCategory: string; expiresAt: number; providerId: string; }; } type EventHandler = (payload: T) => void; /** Wildcard pattern: a string literal ending with '.*' */ type WildcardPattern = `${string}.*`; declare class TypedEventBus { private listeners; private wildcardListeners; on(event: K, handler: EventHandler): IDisposable; on(pattern: WildcardPattern, handler: EventHandler): IDisposable; private _onExact; private _onWildcard; once(event: K, handler: EventHandler): IDisposable; emit(event: K, payload: EventMap[K]): void; bridge(port: MessagePort): IDisposable; removeAllListeners(): void; } /** * PGlite database factory. * Enforces PGlite 0.4.x conventions (explicit database: 'postgres'). * Selects persistence adapter based on config. * * PGlite is loaded LAZILY via dynamic `import()` inside `createPGliteInstance` * (issue #261) — the top-level import is type-only so the emitted `dist/index.js` * carries no static `import '@electric-sql/pglite'`. Consumers that never boot a * PGlite-backed store therefore do not pull the WASM engine into their bundle, * and `@electric-sql/pglite` is an OPTIONAL dependency of `@fortemi/core`. */ type PersistenceMode = 'idb' | 'memory' | 'opfs'; interface CreatePGliteOptions { /** * Restore the instance from a physical data-dir snapshot (issue #187) — schema * + rows + INDEXES in one binary load, with no migration / import / reindex. * The blob comes from PGlite's `dumpDataDir`; see `dumpDbSnapshot`/`restoreDbSnapshot`. * When set, callers MUST NOT run migrations — the restored dir already carries them. */ loadDataDir?: Blob | File; } declare function createPGliteInstance(persistence: PersistenceMode, archiveName?: string, options?: CreatePGliteOptions): Promise; /** * Physical data-dir snapshot (issue #187). * * A *snapshot* is a binary dump of a populated PGlite data directory — schema + * rows + INDEXES (including the HNSW vector index from migration 0004) — that * restores in a single binary load with NO migration, NO shard import, and NO * client-side HNSW build. It is the fast, pre-indexed, single-version restore * option, complementary to logical Knowledge Shards (which are portable + mergeable * but pay the import + reindex cost on every load). * * Named "snapshot" to stay distinct from: * - `ArchiveManager` / `archiveName` — a *named persistence store* (idb/opfs namespace). * - Knowledge Shards — logical, portable, mergeable interchange (`importShard`). * * Safety (the one real risk of the physical format): a Postgres data dir is coupled * to the PGlite/pgvector version and the schema-migration head it was built with. * Every snapshot carries a version stamp (a JSON sidecar); `restoreDbSnapshot` * verifies compatibility BEFORE loading and fails fast (`DbSnapshotVersionError`) on * mismatch, so a host can fall back to a shard import. */ /** Snapshot meta envelope schema. */ declare const DB_SNAPSHOT_SCHEMA_VERSION: "fortemi.db-snapshot.v1"; /** * PGlite version this build of @fortemi/core bundles and can safely restore a * snapshot from. Kept in sync with the `@electric-sql/pglite` dependency; a unit * test asserts it matches package.json so it can't silently drift. */ declare const SUPPORTED_PGLITE_VERSION = "0.4.1"; /** Schema-migration head this build expects a restored snapshot to carry. */ declare const CURRENT_MIGRATION_HEAD: number; type DbSnapshotCompression = 'auto' | 'gzip' | 'none'; interface DbSnapshotMeta { schema_version: typeof DB_SNAPSHOT_SCHEMA_VERSION; /** PGlite version the data dir was dumped from (data-dir format coupling). */ pglite_version: string; /** pgvector extension version at dump time (advisory). */ pgvector_version: null | string; /** Max applied migration version at dump time (schema coupling). */ migration_head: number; /** ISO-8601 dump time. */ created_at: string; /** @fortemi/core version that produced the snapshot (diagnostic only). */ fortemi_version?: string; } interface DbSnapshot { /** The PGlite data-dir dump (gzip by default). Serve as a static asset. */ data: Blob | File; /** Version stamp — serve alongside `data` as a `.meta.json` sidecar. */ meta: DbSnapshotMeta; } /** Minimal shape `dumpDbSnapshot` needs — PGlite satisfies it structurally. */ interface DumpableDb { query>(sql: string, params?: unknown[]): Promise<{ rows: T[]; }>; dumpDataDir(compression?: DbSnapshotCompression): Promise; } interface DumpDbSnapshotOptions { /** Defaults to 'gzip'. */ compression?: DbSnapshotCompression; /** Recorded in meta for diagnostics. */ fortemiVersion?: string; /** Override the timestamp (tests / reproducible builds). */ createdAt?: string; } /** * Dump a populated PGlite into a versioned snapshot. Build-time (Node), after the * corpus is loaded and the HNSW index has been built once. * * Returns `{ data, meta }`: write `data` to e.g. `corpus.pgdata` and `meta` to * `corpus.pgdata.meta.json` (the sidecar `restoreDbSnapshot(url)` looks for). */ declare function dumpDbSnapshot(db: DumpableDb, options?: DumpDbSnapshotOptions): Promise; interface DbSnapshotExpectations { migrationHead?: number; pgliteVersion?: string; /** When provided, a differing snapshot pgvector version is a warning, not a failure. */ pgvectorVersion?: null | string; } interface DbSnapshotCompat { compatible: boolean; /** Hard incompatibilities — restore must refuse. */ reasons: string[]; /** Advisory differences — restore proceeds. */ warnings: string[]; } /** * Verify a snapshot's version stamp against what this build supports. Pure — * unit-testable with no PGlite. Hard gates: snapshot schema, migration head * (exact), PGlite major.minor (data-dir format). pgvector is advisory. */ declare function verifyDbSnapshotMeta(meta: DbSnapshotMeta, expected?: DbSnapshotExpectations): DbSnapshotCompat; /** Thrown by `restoreDbSnapshot` when the snapshot is incompatible with this build. */ declare class DbSnapshotVersionError extends Error { readonly reasons: string[]; readonly meta: DbSnapshotMeta; constructor(reasons: string[], meta: DbSnapshotMeta); } type DbSnapshotSource = { dataUrl: string; metaUrl?: string; } | DbSnapshot | string; interface RestoreDbSnapshotOptions { /** Persistence for the restored instance. Defaults to 'memory' (read-only demos). */ persistence?: PersistenceMode; archiveName?: string; /** Verification expectations (defaults to this build's supported values). */ expectations?: DbSnapshotExpectations; /** Injectable fetch (tests / non-browser). Defaults to global `fetch`. */ fetchImpl?: typeof fetch; } /** * Restore a PGlite from a physical snapshot — verify the version stamp first, * then load the data dir with **no migration / import / HNSW build**. Throws * `DbSnapshotVersionError` on incompatibility (catch it to fall back to a shard * import). The returned instance is ready to query; do NOT run migrations on it. */ declare function restoreDbSnapshot(source: DbSnapshotSource, options?: RestoreDbSnapshotOptions): Promise; /** * Type-safe client for the PGlite Worker. * * PGliteWorkerClient wraps a Worker instance and exposes the same surface as * PGlite (query / exec / transaction) but serialises every call to a typed * postMessage exchange. Each outgoing request is tagged with a UUIDv7 `id`; * the worker echoes that id in its reply so the client can resolve or reject * the matching Promise. * * TransactionProxy is a lightweight wrapper handed to the callback in * transaction(), forwarding TX_QUERY / TX_EXEC messages with the active txId. */ declare class PGliteWorkerClient { private worker; private pending; private readyPromise; private resolveReady; constructor(worker: Worker); /** Resolves when the worker broadcasts READY after database initialisation. */ waitReady(): Promise; private send; query>(sql: string, params?: unknown[]): Promise<{ fields?: Array<{ dataTypeID: number; name: string; }>; rows: T[]; }>; exec(sql: string): Promise; transaction(fn: (tx: TransactionProxy) => Promise): Promise; /** Forward TX_QUERY for TransactionProxy — not part of the public surface. */ _txQuery(txId: string, sql: string, params?: unknown[]): Promise<{ rows: T[]; }>; /** Forward TX_EXEC for TransactionProxy — not part of the public surface. */ _txExec(txId: string, sql: string): Promise; ping(): Promise; close(): Promise; } /** Proxy passed to the transaction callback — scopes queries to the active txId. */ declare class TransactionProxy { private client; private txId; constructor(client: PGliteWorkerClient, txId: string); query>(sql: string, params?: unknown[]): Promise<{ rows: T[]; }>; exec(sql: string): Promise; } interface QueryResult> { rows: T[]; fields?: Array<{ dataTypeID: number; name: string; }>; } interface QueryExecutor { query>(sql: string, params?: unknown[]): Promise>; exec(sql: string): Promise; } interface DatabaseClient extends QueryExecutor { transaction(fn: (tx: QueryExecutor) => Promise): Promise; } interface StorageBackend extends DatabaseClient { readonly id: string; readonly mode: 'readonly' | 'readwrite'; close(): Promise; } interface StorageOpenRequest { archiveName: string; persistence: PersistenceMode; } interface StorageBackendFactory { open(input: StorageOpenRequest): Promise; } interface StorageTopology { primary: StorageBackend; secondary?: StorageBackend; policy: 'explicit-replication' | 'primary-only' | 'read-through-secondary'; } declare class PGliteStorageBackend implements StorageBackend { readonly id: string; private db; readonly mode = "readwrite"; constructor(id: string, db: PGlite); query>(sql: string, params?: unknown[]): Promise>; exec(sql: string): Promise; transaction(fn: (tx: QueryExecutor) => Promise): Promise; close(): Promise; } declare class PGliteStorageBackendFactory implements StorageBackendFactory { open(input: StorageOpenRequest): Promise; } /** * Built-in PGlite backend factory — the opt-in default (issue #261). PGlite is * loaded lazily by `createPGliteInstance` on first `open()`, so referencing * this constant does not force the WASM engine into a consumer's static graph. * Hosts wanting a different store pass their own `StorageBackendFactory` to * `ArchiveManager` instead. */ declare const defaultStorageBackendFactory: PGliteStorageBackendFactory; declare class PGliteWorkerStorageBackend implements StorageBackend { readonly id: string; private client; readonly mode = "readwrite"; constructor(id: string, client: PGliteWorkerClient); query>(sql: string, params?: unknown[]): Promise>; exec(sql: string): Promise; transaction(fn: (tx: QueryExecutor) => Promise): Promise; close(): Promise; } interface PGliteWorkerStorageBackendFactoryOptions { createWorker: () => Worker; } declare class PGliteWorkerStorageBackendFactory implements StorageBackendFactory { private options; constructor(options: PGliteWorkerStorageBackendFactoryOptions); open(input: StorageOpenRequest): Promise; } /** * Field mapper — converts between browser schema and shard (server) schema. * * The browser uses different field names than the server shard format. * This module handles all rename transforms bidirectionally. * * @implements @.aiwg/adrs/ADR-011-shard-server-conformance-and-version-negotiation.md * @schema @packages/core/schemas/knowledge-shard.schema.receipt.json * @created 2026-07-17 * @agent Codex */ /** Browser-format note row from the export query (denormalized). */ interface BrowserNoteExport { id: string; title: null | string; format: string; source: string; is_starred: boolean; is_archived: boolean; created_at: Date | string; updated_at: Date | string; deleted_at: Date | null | string; original_content: string; revised_content: null | string; ai_metadata?: unknown; collection_id?: null | string; attachments?: ShardAttachmentProjection[]; tags: string[]; } /** Convert a browser note to shard format. */ declare function noteToShard(note: BrowserNoteExport): ShardNote; /** Convert a shard note back to browser-insertable format. */ declare function noteFromShard(shard: ShardNote): BrowserNoteExport; /** Convert a browser link to shard format (accepts SQL rows or canonical ISO-string records). */ declare function linkToShard(link: { confidence: null | number; created_at: Date | string; deleted_at?: Date | null | string; id: string; link_type: string; source_note_id: string; target_note_id: string; updated_at?: Date | null | string; }): ShardLink; /** Convert a browser URL-target link row to shard format. */ declare function urlLinkToShard(link: { confidence: null | number; created_at: Date | string; deleted_at?: Date | null | string; id: string; link_type: string; metadata_json?: null | Record | string; source_note_id: string; to_url: string; updated_at?: Date | null | string; }): ShardLink; /** Convert a shard link back to browser-insertable format. */ declare function linkFromShard(shard: ShardLink): { confidence: null | number; created_at: string; deleted_at: null | string; id: string; link_type: string; metadata: unknown; source_note_id: string; target_note_id: null | string; to_url: null | string; updated_at: null | string; }; /** Convert a browser collection to shard format (accepts SQL rows or canonical ISO-string records). */ declare function collectionToShard(collection: { created_at: Date | string; deleted_at?: Date | null | string; description: null | string; id: string; name: string; parent_id: null | string; updated_at?: Date | string; }, noteCount?: number): ShardCollection; /** Convert a shard collection back to browser-insertable format. */ declare function collectionFromShard(shard: ShardCollection): { created_at: string; deleted_at: null | string; description: null | string; id: string; name: string; parent_id: null | string; updated_at: string; }; /** * Convert SKOS concepts + note_tag associations into shard flat tag format. * Shard tags are simple string arrays — deduplicated across all notes. */ declare function tagsToShard(allTags: Array<{ created_at: Date | string; name: string; }>): ShardTag[]; /** Convert a browser template row to shard format. */ declare function templateToShard(template: { collection_id: null | string; content: string; created_at: Date | string; default_tags: string | string[]; description: null | string; format: string; id: string; name: string; updated_at: Date | string; }): ShardTemplate; /** Convert a browser embedding_set to shard format. */ declare function embeddingSetToShard(set: { compatibility_json?: null | unknown; created_at: Date | string; criteria_json?: null | unknown; description?: null | string; dimensions: number; document_count?: null | number; embedding_count?: null | number; freshness_json?: null | unknown; id: string; is_system?: boolean | null; keywords_json?: null | unknown; kind?: 'filter' | 'physical' | 'virtual'; materialization_json?: null | unknown; mode?: 'auto' | 'manual' | 'mixed' | null; model_name: string; name?: string; purpose?: null | string; slug?: null | string; source_json?: null | unknown; truncate_dimension?: null | number; updated_at?: Date | string; }): ShardEmbeddingSet; /** Convert a shard embedding set back to browser format. */ declare function embeddingSetFromShard(shard: ShardEmbeddingSet, fallbackCreatedAt: string): { compatibility_json: null | string; created_at: string; criteria_json: null | string; description: null | string; dimensions: number; document_count: null | number; embedding_count: null | number; freshness_json: null | string; id: string; is_system: boolean; keywords_json: null | string; kind: 'filter' | 'physical' | 'virtual'; materialization_json: null | string; mode: 'auto' | 'manual' | 'mixed' | null; model_name: string; name: string; purpose: null | string; slug: null | string; source_json: null | string; truncate_dimension: null | number; updated_at: null | string; }; /** Convert a browser embedding_set_member to shard format. */ declare function embeddingSetMemberToShard(member: { added_at?: Date | null | string; added_by?: null | string; embedding_set_id: string; membership_type?: null | string; note_id: string; }): ShardEmbeddingSetMember; /** Convert a browser embedding_config row to shard format. */ declare function embeddingConfigToShard(config: ShardEmbeddingConfig): ShardEmbeddingConfig; /** Convert a browser embedding to shard format. */ declare function embeddingToShard(emb: { chunk_index?: null | number; created_at: Date | string; embedding_set_id: string; id: string; model_name?: null | string; model?: null | string; note_id: string; text?: null | string; vector: number[] | string; }): ShardEmbedding; /** Convert a shard embedding back to browser format. */ declare function embeddingFromShard(shard: ShardEmbedding): { chunk_index: number; created_at: null | string; embedding_set_id: null | string; id: string; model: null | string; note_id: string; text: string; vector: string; }; declare function skosSchemeToShard(scheme: { created_at: Date | string; description: null | string; id: string; title: string; updated_at: Date | string; }): ShardSkosScheme; declare function skosConceptToShard(concept: { alt_labels: null | string | string[]; created_at: Date | string; definition: null | string; id: string; pref_label: string; scheme_id: string; updated_at: Date | string; }): ShardSkosConcept; declare function skosRelationToShard(relation: { created_at: Date | string; id: string; relation_type: 'broader' | 'narrower' | 'related'; source_concept_id: string; target_concept_id: string; }): ShardSkosRelation; declare function noteSkosTagToShard(tag: { concept_id: string; created_at: Date | string; id: string; note_id: string; }): ShardNoteSkosTag; declare function provenanceEdgeToShard(edge: { activity: string; agent: string; attributes: null | Record | string; ended_at: Date | null | string; entity_id: string; entity_type: string; id: string; started_at: Date | string; }): ShardProvenanceEdge; /** * In-place Knowledge Shard reader (issue #189) — the static-file backend. * * A shard is already a self-describing bundle of formatted component files * (`notes.jsonl`, `links.jsonl`, `note_skos_tags.jsonl`, `skos_concepts.json`, …) * plus a `manifest.json`. `importShard` loads all of it into PGlite; this reader * is the *second* access mode of the SAME format: open the manifest and query the * component (or clustered) files directly, with NO PGlite — read-only, lightest. * * Capabilities (read-only): browse + get note, full-text + facet search, lazy * links/tags/concepts + full record. Semantic is opt-in via a pluggable provider * (none / brute-force cosine / prebuilt ANN snapshot) — see `StaticSemanticProvider`. */ /** The public note shape — the same browser-insertable record `importShard` produces. */ type ShardReaderNote = BrowserNoteExport; interface ShardSearchWeights { title: number; content: number; tag: number; } interface ShardListOptions { offset?: number; limit?: number; /** Include archived notes (default true). */ includeArchived?: boolean; /** Include soft-deleted notes (default false). */ includeDeleted?: boolean; } interface ShardSearchOptions extends ShardListOptions { /** AND-filter: note must carry every listed tag. */ tags?: string[]; /** OR-filter on note source. */ source?: string[]; rank?: boolean; snippets?: boolean; snippetLength?: number; weights?: Partial; } interface ShardSearchRankedNote { note: ShardReaderNote; rank: number; snippet?: string; } interface ShardSearchResult { items: ShardReaderNote[]; total: number; facets: { source: Record; tags: Record; }; rankedItems?: ShardSearchRankedNote[]; /** Cluster files fetched to serve this query (0 when served from cache). */ fetchedClusters: number; } interface ShardNoteFull { note: ShardReaderNote; links: ShardLink[]; concepts: ShardSkosConcept[]; provenance: ShardProvenanceEdge[]; } /** * Opt-in semantic search over static files. The reader stays text/facets-only * unless a provider is supplied. Implementations span the tradeoff points: * brute-force cosine over a small static vector set, or a prebuilt ANN snapshot * for the full corpus. `prepare()` may lazily load whatever static asset it needs. */ interface StaticSemanticProvider { prepare?(store: ShardComponentStore): Promise; search(query: string, k: number): Promise>; } interface OpenShardOptions { /** Static base URL when `source` is unpacked component files. */ baseUrl?: string; fetchImpl?: typeof fetch; /** Optional semantic provider; absent → `semantic()` returns []. */ semantic?: StaticSemanticProvider; /** Bounds the cross-page search match cache (total cached note records). Default 5000. */ maxCachedMatches?: number; /** Maximum bytes fetched for any unpacked component. Default 256 MiB. */ maxComponentBytes?: number; } /** Reads shard component/cluster files from a packed map or a static base URL. */ interface ShardComponentStore { readonly manifest: ShardManifest; read(filename: string): Promise; } type ShardReaderSource = { baseUrl: string; fetchImpl?: typeof fetch; } | Blob | Uint8Array; interface ShardReader { readonly manifest: ShardManifest; listNotes(options?: ShardListOptions): Promise<{ items: ShardReaderNote[]; total: number; }>; getNote(id: string): Promise; search(query: string, options?: ShardSearchOptions): Promise; linksOf(id: string): Promise; conceptsOf(id: string): Promise; relationsOf(conceptId: string): Promise; provenanceOf(id: string): Promise; getNoteFull(id: string): Promise; semantic(query: string, k?: number): Promise>; close(): void; } /** * Open a Knowledge Shard for in-place, read-only query — NO PGlite. `source` is a * packed tar.gz (`Uint8Array`/`Blob`) or a static base URL serving the unpacked * component/cluster files. Honors `min_reader_version`: a shard that needs a newer * reader than this build throws (the host should fall back to `importShard`). */ declare function openShard(source: ShardReaderSource, options?: OpenShardOptions): Promise; /** * Backend seam (#191) — a uniform tool-intent operation interface that lets the * PGlite database backend (#187) and the static-file shard backend (#189) be * selected and dispatched against the same way, plus a capability-negotiation * API so a caller asks for the operations it needs and gets the lightest backend * that provides them. * * The seam sits one level above SQL: every adapter exposes the same read * operations (and optional relationship, write, semantic, and full-content ops) * regardless of whether the data lives in a queryable PGlite instance, a set of * static shard files fetched over HTTP, or the Fortemi server tier. */ /** * Semantic-search tier a backend offers, in increasing capability: * - `none` — no vector search (text / facets only) * - `cosine-small` — brute-force cosine over a small static vector set (#189) * - `ann-full` — prebuilt/queryable approximate-nearest-neighbour over the full * corpus (PGlite + pgvector, or a prebuilt ANN snapshot) * - `server` — delegated to the remote Fortemi server backend */ type BackendSemanticTier = 'ann-full' | 'cosine-small' | 'none' | 'server'; /** Relative startup cost of bringing a backend online. */ type BackendStartupCost = 'index-build' | 'instant' | 'network'; /** What a backend can do — the unit of capability negotiation. */ interface BackendCapabilities { /** Can answer list / get / search read operations. */ read: boolean; /** Can mutate notes (manageNote). */ write: boolean; /** Can merge external shards into its store. */ merge: boolean; /** Coordinates concurrent multi-user writes. */ multiUser: boolean; /** Highest semantic-search tier available. */ semantic: BackendSemanticTier; /** Relative cost to bring the backend online. */ startupCost: BackendStartupCost; } /** * Backend-neutral note record. `source`/`starred`/`archived` are optional * because lean read paths (PGlite full-text search) do not return them; list, * get, and every shard path populate all fields. */ interface BackendNote { id: string; title: null | string; tags: string[]; createdAt: string; updatedAt: string; source?: string; starred?: boolean; archived?: boolean; } /** A note plus its current rendered content. */ interface BackendNoteFull extends BackendNote { content: string; links?: BackendLink[]; concepts?: BackendConcept[]; provenance?: BackendProvenanceEdge[]; } interface BackendLink { id: string; fromNoteId: string; toNoteId: null | string; toUrl?: null | string; kind: string; score: null | number; createdAt: string; metadata?: Record; } interface BackendConcept { id: string; schemeId: string; prefLabel: string; altLabels: string[]; definition: null | string; createdAt: string; updatedAt: string; } interface BackendProvenanceEdge { id: string; entityType: string; entityId: string; activity: string; agent: string; startedAt: string; endedAt: null | string; attributes: null | Record; } /** One search hit — note plus optional rank/snippet when the backend ranks. */ interface BackendSearchHit { note: BackendNote; rank?: number; snippet?: string; } /** Search response with optional facet counts. */ interface BackendSearchResult { hits: BackendSearchHit[]; total: number; facets?: { source?: Record; tags: Record; }; } interface BackendListOptions { offset?: number; limit?: number; } interface BackendSearchQueryOptions extends BackendListOptions { /** AND-filter: note must carry every listed tag. */ tags?: string[]; /** OR-filter on note source. */ source?: string[]; } /** * Uniform tool-intent operation interface. Every backend implements the read * core; `getNoteFull`, `semantic`, and `manageNote` are optional and present * only on backends whose capabilities advertise them. */ interface DataBackend { readonly id: string; readonly capabilities: BackendCapabilities; listNotes(options?: BackendListOptions): Promise<{ items: BackendNote[]; total: number; }>; getNote(id: string): Promise; search(query: string, options?: BackendSearchQueryOptions): Promise; /** Lazy full content (present when capabilities.read). */ getNoteFull?(id: string): Promise; /** Note links (present when capabilities.read). */ linksOf?(id: string): Promise; /** SKOS concepts assigned to a note (present when capabilities.read). */ conceptsOf?(id: string): Promise; /** W3C PROV edges for a note (present when capabilities.read). */ provenanceOf?(id: string): Promise; /** Vector search (present when capabilities.semantic !== 'none'). */ semantic?(query: string, k?: number): Promise; /** Write op (present when capabilities.write). */ manageNote?(input: unknown): Promise; } /** What a caller needs. Booleans require `true`; `semantic` is a minimum tier. */ interface BackendRequest { read?: boolean; write?: boolean; merge?: boolean; multiUser?: boolean; /** Minimum acceptable semantic tier (a higher tier satisfies a lower request). */ semantic?: BackendSemanticTier; } interface BackendCandidate { backend: DataBackend; /** Requested capabilities this backend cannot satisfy ([] = fully satisfies). */ missing: string[]; } interface BackendSelection { /** Chosen backend — fully-satisfying-and-lightest, else fewest-missing. Null only when no backends are available. */ backend: DataBackend | null; capabilities: BackendCapabilities | null; /** Requested capabilities the chosen backend cannot satisfy. */ missing: string[]; /** Every candidate with its own missing set, ordered as evaluated. */ candidates: BackendCandidate[]; } /** * Pick the backend that best satisfies `request` from `available`. Prefers a * fully-satisfying backend with the lightest startup cost; if none fully * satisfy, returns the one missing the fewest capabilities (lightest on ties) so * the caller can degrade with eyes open via `selection.missing`. */ declare function selectBackend(request: BackendRequest, available: DataBackend[]): BackendSelection; interface PGliteBackendOptions { id?: string; /** Whether embeddings exist so search can use the semantic path. */ semanticAvailable?: boolean; } /** * Wrap a PGlite-backed `DatabaseClient` as a `DataBackend`. Read ops delegate to * the repositories; writes go through the `manageNote` tool. Advertises full * read+write+merge with `ann-full` semantic when embeddings are present. */ declare function createPGliteBackend(db: DatabaseClient, options?: PGliteBackendOptions): DataBackend; interface RemoteBackendPaths { notes: string; note: string; search: string; links: string; concepts: string; provenance: string; manageNote: string; semantic: string; } interface RemoteBackendConfig { baseUrl: string; id?: string; fetchImpl?: typeof fetch; headers?: (() => HeadersInit | Promise) | HeadersInit; authToken?: string; paths?: Partial; } declare function createRemoteBackend(config: RemoteBackendConfig): DataBackend; interface ShardBackendOptions { id?: string; /** Declared semantic tier this shard provides (default `none`). Set to `cosine-small` when the reader has a vector provider. */ semantic?: BackendSemanticTier; } /** * Wrap a `ShardReader` (#189) as a read-only `DataBackend`. Startup is instant * (no index build) and the semantic tier is whatever the reader's provider * offers — `none` for text/facets-only shards, `cosine-small` when a vector * provider is attached. */ declare function createShardBackend(reader: ShardReader, options?: ShardBackendOptions): DataBackend; /** * Capability module system (ADR-002). * Tracks opt-in WASM module states. No WASM loaded by default (CAP-001). * * State machine (valid transitions): * unloaded -> loading (via enable) * loading -> ready (via markReady or successful loader) * loading -> error (via markError or failed loader) * ready -> disabled (via disable) * disabled -> loading (via enable, re-enable) * error -> loading (via enable, retry) */ type CapabilityState = 'disabled' | 'error' | 'loading' | 'ready' | 'unloaded'; type CapabilityName = 'audio' | 'llm' | 'pdf' | 'semantic' | 'vision'; declare class CapabilityManager { private events; private capabilities; private loaders; private progressMessages; constructor(events: TypedEventBus); /** * Register an async loader for a capability. * Called by enable(); if no loader is registered the capability transitions * directly to ready (useful for capabilities that require no async init). */ registerLoader(name: CapabilityName, loader: () => Promise): void; getState(name: CapabilityName): CapabilityState; isReady(name: CapabilityName): boolean; /** * Enable a capability. * Valid from: unloaded, disabled, error (retry). * Runs the registered loader if present; transitions to ready on success, * error on failure. */ enable(name: CapabilityName): Promise; /** * Disable a ready capability. * Valid from: ready only. */ disable(name: CapabilityName): void; /** * Mark a loading capability as ready (external use, e.g. bridge protocol). * Valid from: loading only. */ markReady(name: CapabilityName): void; /** * Mark a loading capability as errored (external use, e.g. bridge protocol). * Valid from: loading only. */ markError(name: CapabilityName, error: string): void; /** * Report loading progress (0-100). * Emits capability.loading with progress if the capability is currently loading. * No-op if the capability is not in loading state. */ reportProgress(name: CapabilityName, progress: number): void; /** Set a human-readable progress message for a loading capability */ setProgress(name: CapabilityName, message: string): void; /** Get the current progress message for a capability */ getProgress(name: CapabilityName): string | undefined; getError(name: CapabilityName): string | undefined; listAll(): Array<{ name: CapabilityName; state: CapabilityState; }>; } /** * Sequential SQL migration runner for DatabaseClient. * Tracks applied migrations in a schema_version table. * Each migration runs in a transaction; version updated atomically. */ interface Migration { version: number; name: string; sql: string; } declare class MigrationRunner { private db; private events?; constructor(db: DatabaseClient, events?: TypedEventBus | undefined); ensureSchemaTable(): Promise; getCurrentVersion(): Promise; apply(migrations: Migration[]): Promise; getAppliedMigrations(): Promise>; } declare const allMigrations: Migration[]; /** * Multi-archive manager for Fortemi. * Each archive is a separate PGlite instance with its own persistence path. * Migrations are applied automatically on open. */ interface ArchiveInfo { name: string; createdAt: string; } declare class ArchiveManager { private events?; private currentArchive; private db; private archives; private persistence; private backendFactory; /** * Persistence is a PLUGGABLE, opt-in backend (issue #261). Pass a * `StorageBackendFactory` to run against any `StorageBackend` * implementation; PGlite is merely the built-in default, selected only when * the convenience `PersistenceMode` string form is used. Because * `defaultStorageBackendFactory` reaches PGlite through the lazily-imported * `createPGliteInstance` (see `db.ts`), a consumer that supplies its own * factory — or never opens an archive at all — never pulls the PGlite WASM * engine into its bundle. * * @param persistenceOrFactory `PersistenceMode` string (uses the built-in * PGlite backend) OR a custom `StorageBackendFactory`. * @param persistenceOverride persistence hint passed to a custom factory. */ constructor(persistenceOrFactory: PersistenceMode | StorageBackendFactory, events?: TypedEventBus | undefined, persistenceOverride?: PersistenceMode); getCurrentArchiveName(): string; getDb(): null | StorageBackend; open(archiveName?: string): Promise; /** * Adopt an already-created backend WITHOUT running migrations — for a backend * whose schema is already present, e.g. a PGlite restored from a physical * data-dir snapshot (issue #187, `restoreDbSnapshot`). Running migrations here * would be wrong: the restored dir already carries them (and the HNSW index). */ adopt(backend: StorageBackend, archiveName?: string): Promise; create(archiveName: string): Promise; switchTo(archiveName: string): Promise; delete(archiveName: string): Promise; listArchives(): ArchiveInfo[]; close(): Promise; } /** * Factory function for creating a FortemiCore instance. * All deployment modes use this entry point. */ interface FortemiConfig { persistence: 'idb' | 'memory' | 'opfs'; archiveName?: string; } interface FortemiCore { events: TypedEventBus; config: FortemiConfig; destroy(): void; } declare function createFortemi(config: FortemiConfig): FortemiCore; /** * Compute a browser-local content-identity hash (SHA-256), encoded as * `sha256:<64-char lowercase hex>`. * * This is an internal identity/dedup digest used for note content, embedding * configs, the AIWG index, and graph identity — NOT the server's attachment * content-hash convention. Binary-attachment blobs use {@link computeBlobHash} * (BLAKE3), which is the canonical checksum defined by the binary-attachment * projection contract (`checksum: "blake3:"`). Keeping these two functions * separate preserves JSON format parity for the identity hashes above while * letting attachments match the server's `compute_content_hash`. * * @param data - Raw bytes to hash * @returns `'sha256:<64-char lowercase hex>'` */ declare function computeHash(data: Uint8Array): string; /** * Compute the canonical attachment content hash: **BLAKE3**, encoded as * `blake3:<64-char lowercase hex>`. * * Matches the fortemi server (`crates/matric-db/src/file_storage.rs` * `compute_content_hash`) and the portable Knowledge-Shard byte-sidecar * contract, where the sidecar tar entry name is the bare hex (the `blake3:` * prefix stripped). SubtleCrypto has no BLAKE3, so this uses `@noble/hashes`. * * @param data - Raw attachment bytes to hash * @returns `'blake3:<64-char lowercase hex>'` */ declare function computeBlobHash(data: Uint8Array): string; declare const FORTEMI_COMPATIBILITY_PATH = "/api/v1/system/compatibility"; declare const FORTEMI_SERVER_COMPATIBILITY_REVISION = "2026-07-06"; declare const FORTEMI_COMPATIBILITY_STATES: readonly [ "available", "degraded", "preview", "unavailable", "unknown" ]; type FortemiCompatibilityState = (typeof FORTEMI_COMPATIBILITY_STATES)[number]; declare const FORTEMI_REQUIRED_COMPATIBILITY_CAPABILITIES: readonly [ "core_notes", "search", "jobs", "realtime_activity", "hosted_auth", "premium_components", "backoffice_api", "audit_posture", "quota_status", "kms_status", "mcp_scope_gate" ]; type FortemiRequiredCompatibilityCapability = (typeof FORTEMI_REQUIRED_COMPATIBILITY_CAPABILITIES)[number]; interface FortemiCompatibilityCapability { state: FortemiCompatibilityState; reason_code?: string; } interface FortemiCompatibilityResponse { schema_version: number; contract_revision: string; api: { build_date_present: boolean; git_sha_present: boolean; minimum_hotm_enterprise_client: string; name: string; version: string; }; deployment: { edition: string; hosted_multi_tenant_ready: boolean; mode: string; }; auth: { mode: string; oauth_issuer_configured: boolean; required: boolean; tenant_context_available: boolean; }; capabilities: Record; links: { asyncapi: string; health: string; openapi: string; streaming_health: string; }; } interface FortemiCompatibilityValidationResult { ok: boolean; errors: string[]; warnings: string[]; response?: FortemiCompatibilityResponse; } interface FetchFortemiCompatibilityOptions { baseUrl?: string; fetchImpl?: typeof fetch; timeoutMs?: number; } declare function fortemiCompatibilityUrl(baseUrl?: string): string; declare function validateFortemiCompatibilityResponse(raw: unknown): FortemiCompatibilityValidationResult; declare function formatFortemiCompatibilitySummary(response: FortemiCompatibilityResponse): string; declare function fetchAndValidateFortemiCompatibility(options?: FetchFortemiCompatibilityOptions): Promise; interface SWRegistrationResult { registered: boolean; registration?: ServiceWorkerRegistration; error?: string; } declare function registerServiceWorker(swUrl?: string): Promise; /** * REST route definitions for Service Worker. * These are pure functions that transform HTTP Request → tool input and tool output → Response. * The actual DB connection is injected at registration time. * * All routes currently return 503 Not Implemented — the DB wiring happens in a later issue. * The URL structure and request/response shapes are the valuable contract defined here. */ interface RouteHandler { method: string; pattern: RegExp; handler: (request: Request, match: RegExpMatchArray, params: URLSearchParams) => Promise; } /** * Create route handlers. * db parameter will be injected when the SW gets access to PGlite. * For now, returns 503 Not Implemented for all routes. */ declare function createRoutes(): RouteHandler[]; /** * Match a request against the registered routes and return the first matching * handler, or null if no route matches. */ declare function matchRoute(routes: RouteHandler[], request: Request, url: URL): null | RouteHandler; /** * One-shot migration of the pre-bytecask blob layout into the new store. * * The legacy layout (shipped through v2026.7.x) was: * - IndexedDB: database `fortemi--blobs`, object store `blobs`, * values keyed by the full checksum string (`blake3:`, historically * also `sha256:`). * - OPFS: directory `fortemi--blobs///`. * * Migration re-`put()`s every payload — the new store recomputes BLAKE3, so * legacy `sha256:`-keyed entries converge to canonical keys for free * (ADR-012 D3). The legacy source is deleted only after every entry migrated * without error; any failure leaves it untouched for the next attempt. */ /** Outcome of one migration attempt (for diagnostics/logging). */ interface LegacyMigrationReport { migrated: number; /** Migration aborted without deleting the legacy source. */ failed: boolean; } /** * Migrate any legacy blob layout for `archiveName` into `target`, then delete * the legacy source. Failures are contained: the legacy data stays in place * and the new store keeps whatever was already re-put (idempotent on retry). */ declare function migrateLegacyBlobStore(archiveName: string, target: BlobStore, indexedDbFactory?: IDBFactory): Promise; /** * Shared postMessage protocol types for the PGlite worker. * * WorkerRequest — messages sent from the client to the worker. * WorkerResponse — messages sent from the worker back to the client. * * Every request carries a unique `id` that the worker echoes in its response, * allowing the client to correlate replies with pending promises. * The READY broadcast is the only message without an `id` — it is sent once * on startup before any requests are processed. */ /** Messages from client to worker */ type WorkerRequest = { id: string; isolationLevel?: string; type: 'BEGIN'; } | { id: string; params?: unknown[]; sql: string; txId: string; type: 'TX_QUERY'; } | { id: string; params?: unknown[]; sql: string; type: 'QUERY'; } | { id: string; sql: string; txId: string; type: 'TX_EXEC'; } | { id: string; sql: string; type: 'EXEC'; } | { id: string; txId: string; type: 'COMMIT'; } | { id: string; txId: string; type: 'ROLLBACK'; } | { id: string; type: 'CLOSE'; } | { id: string; type: 'PING'; }; /** Messages from worker to client */ type WorkerResponse = { affectedRows?: number; id: string; type: 'EXEC_DONE'; } | { error: string; id: string; type: 'ERROR'; } | { fields?: Array<{ dataTypeID: number; name: string; }>; id: string; rows: unknown[]; type: 'RESULT'; } | { id: string; txId: string; type: 'TX_STARTED'; } | { id: string; type: 'PONG'; } | { id: string; type: 'TX_DONE'; } | { type: 'READY'; }; /** * EmbeddingSetsRepository - named, filter, and virtual embedding set API. */ type EmbeddingSetKind = 'filter' | 'physical' | 'virtual'; type EmbeddingSetMode = 'auto' | 'manual' | 'mixed'; interface EmbeddingSetCriteria { query?: string; tags?: string[]; collectionIds?: string[]; conceptIds?: string[]; noteIds?: string[]; sources?: string[]; formats?: string[]; visibilities?: string[]; isStarred?: boolean; isArchived?: boolean; hasTitle?: boolean; hasEmbedding?: boolean; isUserEdited?: boolean; hasAiMetadata?: boolean; hasRevisions?: boolean; minGenerationCount?: number; maxGenerationCount?: number; updatedAfter?: string; updatedBefore?: string; } interface EmbeddingSetFreshness { status: 'fresh' | 'stale' | 'unknown'; sourceHash?: string; checkedAt?: string; reason?: string; } interface EmbeddingCompatibilityPolicy { model: 'allow-compatible-family' | 'require-same'; dimension: 'allow-truncation' | 'require-same'; duplicateVectors: 'error' | 'prefer-latest' | 'prefer-set-order'; missingVectors: 'error' | 'include-unembedded-note' | 'omit'; } interface VirtualMaterializationPolicy { allowed: boolean; includeResolvedMembers?: boolean; includeResolvedEdges?: boolean; freshness: 'fresh' | 'stale' | 'unknown'; inputHash?: string; generatedAt?: string; resolvedMemberCount?: number; } interface CriteriaVirtualSource { type: 'criteria'; baseSetId: string; criteria: EmbeddingSetCriteria; } interface SetOperationVirtualSource { type: 'set-operation'; operation: 'difference' | 'intersection' | 'union'; setIds: string[]; } interface FallbackVirtualSource { type: 'fallback'; preferredSetIds: string[]; } interface LatestCompatibleVirtualSource { type: 'latest-compatible'; candidateSetIds: string[]; model?: string; dimension?: number; } interface SnapshotVirtualSource { type: 'snapshot'; snapshotId: string; sourceDefinitionId: string; generatedAt: string; inputHash: string; } type VirtualEmbeddingSetSource = CriteriaVirtualSource | FallbackVirtualSource | LatestCompatibleVirtualSource | SetOperationVirtualSource | SnapshotVirtualSource; interface VirtualEmbeddingSetDefinition { id: string; name: string; purpose?: null | string; source: VirtualEmbeddingSetSource; compatibility: EmbeddingCompatibilityPolicy; materialization?: VirtualMaterializationPolicy; createdAt?: string; updatedAt?: string; } interface EmbeddingSetSelector { kind: 'default' | 'embedding-set' | 'virtual-definition'; embeddingSetId?: string; definition?: VirtualEmbeddingSetDefinition; } interface EmbeddingSetDescriptor { id: string; name: string; purpose?: null | string; kind: EmbeddingSetKind; mode?: EmbeddingSetMode; model?: string; dimension?: number; truncateDimension?: null | number; criteria?: EmbeddingSetCriteria | null; createdAt?: string; updatedAt?: string; freshness?: EmbeddingSetFreshness; } type VirtualEmbeddingSetValidationError = { code: 'duplicate-vector'; noteId: string; setIds: string[]; } | { code: 'missing-vector'; noteId: string; setId: string; } | { code: 'mixed-dimensions'; setIds: string[]; } | { code: 'mixed-models'; setIds: string[]; } | { code: 'stale-snapshot'; snapshotId: string; } | { code: 'unsupported-criteria'; field: string; }; interface ResolvedEmbeddingRow { note_id: string; embedding_set_id: string; embedding_id: string; vector: string; created_at: Date; } interface ResolvedEmbeddingSet { selector: EmbeddingSetSelector; rows: ResolvedEmbeddingRow[]; noteIds: string[]; embeddingIds: string[]; errors: VirtualEmbeddingSetValidationError[]; freshness: EmbeddingSetFreshness; resolutionSource: 'live' | 'materialized'; } interface EmbeddingSetRow { id: string; name: string; purpose: null | string; model_name: string; dimensions: number; kind: EmbeddingSetKind; mode: EmbeddingSetMode | null; truncate_dimension: null | number; criteria_json: null | unknown; source_json: null | unknown; compatibility_json: null | unknown; materialization_json: null | unknown; freshness_json: null | unknown; created_at: Date; updated_at: Date; } interface EmbeddingSetCreateInput { id?: string; name: string; purpose?: null | string; model_name?: string; dimensions?: number; kind?: EmbeddingSetKind; mode?: EmbeddingSetMode | null; truncate_dimension?: null | number; criteria?: EmbeddingSetCriteria | null; } interface EmbeddingSetEmbeddingInput { id?: string; note_id: string; embedding_set_id: string; vector: number[]; } declare class EmbeddingSetsRepository { private db; constructor(db: QueryExecutor); create(input: EmbeddingSetCreateInput): Promise; createVirtualDefinition(input: VirtualEmbeddingSetDefinition): Promise; ensureDefault(): Promise; get(id: string): Promise; list(): Promise; listDescriptors(): Promise; toDescriptor(row: EmbeddingSetRow): EmbeddingSetDescriptor; putEmbedding(input: EmbeddingSetEmbeddingInput): Promise<{ id: string; }>; resolveSelector(selector: EmbeddingSetSelector): Promise; refreshMaterializedVirtualSet(setId: string): Promise; markVirtualSetStale(setId: string, reason: string): Promise; private resolveDefinition; private resolvePhysicalSet; private resolvePhysicalRows; private resolveMaterializedRows; private resolveCriteriaSource; private resolveSetOperationSource; private resolveFallbackSource; private resolveLatestCompatibleSource; private validateCompatibility; private resolveDuplicateRows; private finalizeResolution; private resolutionInputHash; private definitionFromRow; private inferDefinitionModel; private inferDefinitionDimension; } declare const REGISTERED_METADATA_PATHS: readonly [ "provider", "model", "role", "event_kind", "sensitivity", "import_run_id" ]; type RegisteredMetadataPath = typeof REGISTERED_METADATA_PATHS[number]; type MetadataPredicate = { gte?: number | string; lte?: number | string; op: 'range'; path: RegisteredMetadataPath; } | { op: 'eq'; path: RegisteredMetadataPath; value: boolean | null | number | string; } | { op: 'exists'; path: RegisteredMetadataPath; value?: boolean; } | { op: 'in'; path: RegisteredMetadataPath; value: readonly (boolean | null | number | string)[]; }; interface EvidenceLocator { note_id: string; chunk?: { index: number; kind: 'attachment' | 'current' | 'title'; }; span?: { end: number; start: number; }; source?: { external_id_hash: string; import_run_id: string; namespace: string; schema_version: string; }; metadata_paths: RegisteredMetadataPath[]; } interface MetadataPredicateConditionResult { conditions: string[]; joins: string[]; params: unknown[]; nextIdx: number; } declare function buildMetadataPredicateConditions(options: Pick, startIdx: number): MetadataPredicateConditionResult; /** * Shared types for repository layer. * All repository methods use these types as inputs and outputs. */ interface NoteSummary { id: string; title: null | string; format: string; source: string; visibility: string; is_starred: boolean; is_pinned: boolean; is_archived: boolean; created_at: Date; updated_at: Date; deleted_at: Date | null; tags: string[]; } interface NoteFull extends NoteSummary { archive_id: null | string; revision_mode: string; original: { content_hash: string; content: string; created_at: Date; id: string; }; current: { ai_metadata: null | unknown; content: string; generation_count: number; is_user_edited: boolean; model: null | string; updated_at: Date; }; } interface NoteCreateInput { content: string; title?: string; format?: string; source?: string; visibility?: string; tags?: string[]; archive_id?: string; /** * Explicit primary key. When omitted a UUIDv7 is minted (the default). Supply * this only for deterministic seeding or cross-instance identity — e.g. two * in-browser databases that must agree on a shared note's id so a shard swap * can dedupe it under the `skip` conflict strategy. */ id?: string; } interface NoteUpdateInput { title?: string; content?: string; format?: string; visibility?: string; } interface NoteListOptions { limit?: number; offset?: number; sort?: 'created_at' | 'title' | 'updated_at'; order?: 'asc' | 'desc'; is_starred?: boolean; is_pinned?: boolean; is_archived?: boolean; include_deleted?: boolean; include_archived?: boolean; collection_id?: string; tags?: string[]; } interface PaginatedResult { items: T[]; total: number; limit: number; offset: number; } interface SearchResult { id: string; title: null | string; snippet: string; rank: number; created_at: Date; updated_at: Date; tags: string[]; has_embedding?: boolean; locators?: EvidenceLocator[]; } interface SearchFacets { tags: { count: number; tag: string; }[]; collections: { count: number; id: string; name: string; }[]; } interface SearchResponse { results: SearchResult[]; total: number; query: string; mode: 'hybrid' | 'semantic' | 'text'; semantic_available: boolean; limit: number; offset: number; facets?: SearchFacets; } interface SearchOptions { limit?: number; offset?: number; tags?: string[]; collection_id?: string; date_from?: Date; date_to?: Date; is_starred?: boolean; is_archived?: boolean; format?: string; source?: string; visibility?: string; tenant_id?: string; archive_id?: null | string; metadataPredicates?: readonly MetadataPredicate[]; include_facets?: boolean; mode?: 'auto' | 'hybrid' | 'semantic' | 'text'; embeddingSetId?: string; embeddingSetSelector?: EmbeddingSetSelector; } interface NoteRevision { id: string; note_id: string; revision_number: number; type: string; content: string; ai_metadata: null | unknown; model: null | string; created_at: Date; } /** * NotesRepository — CRUD and lifecycle operations for the note entity. * * Responsibilities: * - Create notes with immutable original content and mutable current revision * - Manage note lifecycle: soft-delete, restore, star, pin, archive * - List notes with filtering, pagination, and sorting * - Emit domain events via TypedEventBus on every mutation */ declare class NotesRepository { private db; private events?; constructor(db: DatabaseClient, events?: TypedEventBus | undefined); /** * Create a new note with its original content record, current revision, * optional tags, and an auto-queued title_generation job when no title * is provided. * * All writes happen in a single transaction. */ create(input: NoteCreateInput): Promise; /** * Fetch a single note by its ID. * Returns NoteFull which includes original content, current revision, and tags. * Throws when the note does not exist. */ get(id: string): Promise; /** * List notes with optional filtering, sorting, and pagination. * Excludes soft-deleted notes by default (pass include_deleted: true to override). */ list(options?: NoteListOptions): Promise>; /** * Update mutable note fields. * When content changes, the previous current content is saved as a numbered * revision before the new content is applied. */ update(id: string, input: NoteUpdateInput): Promise; /** * Soft-delete a note by setting deleted_at to the current timestamp. */ delete(id: string): Promise; /** * Restore a soft-deleted note by clearing deleted_at. */ restore(id: string): Promise; /** * Toggle the is_starred field on a note. */ star(id: string, starred: boolean): Promise; /** * Toggle the is_pinned field on a note. */ pin(id: string, pinned: boolean): Promise; /** * Toggle the is_archived field on a note. */ archive(id: string, archived: boolean): Promise; /** * Get revision history for a note, ordered by revision_number descending. */ getRevisions(noteId: string): Promise; } /** * SearchRepository - full-text search using DatabaseClient tsvector/tsquery, * with optional semantic search (pgvector) and hybrid (BM25 + vector RRF). */ declare class SearchRepository { private db; private semanticAvailable; constructor(db: DatabaseClient, semanticAvailable?: boolean); private tsqueryFn; private fetchEmbeddingSet; private selectorFromOptions; private resolveEmbeddingSet; private scopeToResolvedEmbeddingSet; private scopeToResolvedEmbeddingRows; private fetchEmbeddingStatus; private attachEmbeddingStatus; private fetchLocatorMap; private metadataPaths; search(query: string, options?: SearchOptions, queryEmbedding?: number[]): Promise; semanticSearch(queryEmbedding: number[], options?: SearchOptions): Promise; hybridSearch(query: string, queryEmbedding: number[], options?: SearchOptions): Promise; private recentNotes; private fetchFacets; private fetchTagMap; } type SourceUpsertPolicy = 'conflict' | 'replace' | 'version'; type SourceUpsertOutcome = 'conflict' | 'inserted' | 'rejected' | 'replaced' | 'unchanged' | 'versioned'; interface SourceIdentityInput { tenant_id?: string; archive_id?: null | string; namespace: string; external_id: string; source_schema_version: string; import_run_id: string; caller_stable_id?: string; } interface SourceUpsertItem { source: SourceIdentityInput; title?: null | string; content: string; format?: string; visibility?: string; metadata?: null | Record; policy?: SourceUpsertPolicy; } interface SourceUpsertOptions { dryRun?: boolean; maxItems?: number; } interface SourceUpsertItemResult { index: number; outcome: SourceUpsertOutcome; note_id?: string; external_id_hash: string; content_digest: string; reason?: string; } interface SourceUpsertBatchResult { import_run_id: string; dry_run: boolean; outcomes: SourceUpsertItemResult[]; counts: Record; } declare class SourceUpsertRepository { private db; private events?; constructor(db: DatabaseClient, events?: TypedEventBus | undefined); upsertBatch(items: readonly SourceUpsertItem[], options?: SourceUpsertOptions): Promise; private finish; } interface PurgeSelector { tenant_id?: string; archive_id?: null | string; note_ids?: readonly string[]; source?: { external_id?: string; namespace: string; }; } interface PurgeCounts { notes: number; revisions: number; links: number; tags: number; embeddings: number; attachments: number; blobs: number; graph_edges: number; provenance_edges: number; source_identities: number; } interface DeletionReceipt { id: string; operation_key: string; tenant_id: string; archive_id: null | string; selector_hash: string; outcome: 'completed'; counts: PurgeCounts; completed_at: string; policy: { authority: 'fortemi#1092'; mode: 'terminal-purge'; receipt_contains_content: false; }; } interface PurgePreview { selector_hash: string; counts: PurgeCounts; } declare class LifecyclePurgeRepository { private db; private events?; constructor(db: DatabaseClient, events?: TypedEventBus | undefined); preview(selector: PurgeSelector): Promise; purge(selector: PurgeSelector, operationKey: string): Promise; private count; private deleteSelected; } interface GraphNode { id: string; } interface GraphEdge { source: string; target: string; weight: number; kind?: string; } interface GraphCommunity { id: string; nodes: string[]; } interface CommunityGraph { nodes: GraphNode[]; edges: GraphEdge[]; communities: GraphCommunity[]; } interface SimilarityGraphOptions { k?: number; minSimilarity?: number; threshold?: number; metric?: 'cosine' | 'inner_product' | 'l2'; batchSize?: number; yieldEvery?: number; onProgress?: (progress: SimilarityGraphProgress) => void; } interface SimilarityGraphRequest extends SimilarityGraphOptions { selector: EmbeddingSetSelector; source?: 'cache-only' | 'cache-preferred' | 'live-only'; } interface SimilarityGraphProgress { phase: 'neighbors' | 'prepare'; done: number; total: number; } interface SimilarityGraphCacheKey { selectorHash: string; resolvedEmbeddingSetId?: string; virtualSetId?: string; k: number; minSimilarity: number; metric: 'cosine' | 'inner_product' | 'l2'; model: string; dimension: number; truncateDimension?: null | number; memberHash: string; vectorHash: string; parameterHash: string; } interface SimilarityGraphResult { graph: CommunityGraph; graphSource: { freshness: 'fresh' | 'stale' | 'unknown'; id: string; input_hash: string; name: string; }; cache: 'hit' | 'live-only' | 'miss-live-built' | 'stale-live-built'; freshness: 'fresh' | 'stale' | 'unknown'; } interface CommunityOptions { maxIterations?: number; } declare function detectCommunities(edges: GraphEdge[], nodes?: GraphNode[], options?: CommunityOptions): GraphCommunity[]; declare class GraphRepository { private db; constructor(db: QueryExecutor); normalizeSimilarityRequest(request: SimilarityGraphRequest): Required>; buildSimilarityGraph(embeddingSet: EmbeddingSetSelector | string, options?: SimilarityGraphOptions): Promise; buildSimilarityGraphLive(request: SimilarityGraphRequest): Promise; getCachedSimilarityGraph(request: SimilarityGraphRequest): Promise; buildOrLoadSimilarityGraph(request: SimilarityGraphRequest): Promise; saveSimilarityGraphArtifact(input: { cacheKey: SimilarityGraphCacheKey; freshness?: 'fresh' | 'stale' | 'unknown'; graph: CommunityGraph; request: Required>; resolved: ResolvedEmbeddingSet; }): Promise; markSimilarityGraphStale(graphSourceId: string, reason: string): Promise; loadGraphArtifact(graphSourceId: string, noteIds?: string[]): Promise; private buildSimilarityGraphFromResolved; private computeSimilarityGraphCacheKey; private findGraphSource; private graphFromArtifact; buildLinkGraph(linkType?: string): Promise; } type CommunitySourceType = 'computed' | 'dynamic-snapshot' | 'dynamic' | 'imported' | 'precomputed' | 'user-authored'; interface CommunityFilterDefinition { query?: string; tags?: string[]; collectionIds?: string[]; conceptIds?: string[]; noteIds?: string[]; embeddingSetSelector?: EmbeddingSetSelector; } interface CommunitySourceDescriptor { id: string; name: string; sourceType: CommunitySourceType; graphSourceId?: string; selector?: EmbeddingSetSelector; searchQuery?: string; filters?: CommunityFilterDefinition; createdAt?: string; updatedAt?: string; freshness?: 'fresh' | 'stale' | 'unknown'; } interface CommunityAssignmentView { communitySourceId: string; communityId: string; noteId: string; label?: null | string; confidence?: null | number; sourceType: CommunitySourceType; } interface CommunitySummary { id: string; label: string; sourceType: CommunitySourceType; size: number; confidence?: null | number; representativeNoteIds: string[]; freshness?: 'fresh' | 'stale' | 'unknown'; } interface CommunityCreateInput { name: string; label?: string; sourceType: 'dynamic-snapshot' | 'user-authored'; filters?: CommunityFilterDefinition; noteIds?: string[]; representativeNoteIds?: string[]; } declare class CommunitiesRepository { private db; constructor(db: DatabaseClient); previewDynamicCommunity(filters: CommunityFilterDefinition): Promise; saveCommunity(input: CommunityCreateInput): Promise; rerunDynamicCommunity(sourceId: string): Promise; listCommunitySources(): Promise; getCommunityAssignments(sourceId: string): Promise; listCommunitySummaries(sourceId: string): Promise; private resolveFilterNoteIds; } /** * Shared SQL condition builder for note filtering. * Used by both SearchRepository and NotesRepository to prevent drift * when adding new filter fields. * * @implements #87 shared condition builder */ interface ConditionResult { conditions: string[]; params: unknown[]; nextIdx: number; } /** * Build WHERE clause conditions for note filtering. * Generates parameterized SQL conditions for all shared filter fields. * * @param options - Filter options (any subset of SearchOptions fields) * @param startIdx - Starting parameter index ($N) * @param includeDeleted - Whether to include soft-deleted notes (default: false) */ declare function buildNoteConditions(options: Pick, startIdx: number, includeDeleted?: boolean): ConditionResult; /** * Job queue worker — polls job_queue for pending jobs, dispatches to registered * handlers, manages status transitions and exponential backoff retries. * * Job types and priorities (lower = runs first): * ai_revision: 1 (LLM enriches content first, requires llm) * title_generation: 2 (generate title from enriched content) * embedding: 3 (vectorize final content, requires semantic) * concept_tagging: 4 (extract concepts from enriched content, requires llm) * linking: 5 (find related notes, requires embeddings to exist) */ interface JobQueueOptions { /** How often to poll for new jobs (ms). Default: 5000 */ pollIntervalMs?: number; /** Global max retries used when job.max_retries is 0. Default: 3 */ maxRetries?: number; /** Base delay for exponential backoff (ms). Default: 1000 */ backoffBaseMs?: number; /** Maximum backoff delay cap (ms). Default: 300000 (5 min) */ backoffMaxMs?: number; } interface Job { id: string; note_id: string; job_type: string; status: string; priority: number; required_capability: null | string; retry_count: number; max_retries: number; error: null | string; result: null | unknown; created_at: Date; updated_at: Date; } type JobHandler = (job: Job, db: DatabaseClient) => Promise; /** Job types listed in execution priority order (lower number = runs first) */ type JobType = 'ai_revision' | 'concept_tagging' | 'embedding' | 'linking' | 'title_generation'; /** * Job priorities — lower number = runs first. * Correct dependency order: * 1. ai_revision — LLM enriches content first * 2. title_generation — generate title from enriched content * 3. embedding — vectorize final content * 4. concept_tagging — extract concepts from enriched content * 5. linking — find related notes (requires embeddings to exist) */ declare const JOB_PRIORITIES: Record; declare const JOB_CAPABILITIES: Partial>; interface EnqueueJobInput { noteId: string; jobType: JobType; priority?: number; requiredCapability?: null | string; } /** Enqueue a job into the job_queue table. Returns the new job ID. */ declare function enqueueJob(db: DatabaseClient, input: EnqueueJobInput): Promise; /** Enqueue the note creation pipeline: revision → title → embedding. */ declare function enqueueNoteCreationJobs(db: DatabaseClient, noteId: string, hasTitle: boolean): Promise; /** * Enqueue the complete workflow for a note. * Order: revision → title → embedding → concepts → linking. * Jobs run in priority order so each step has the richest content available. */ declare function enqueueFullWorkflow(db: DatabaseClient, noteId: string): Promise; interface JobStatus { id: string; note_id: string; job_type: string; status: string; priority: number; required_capability: null | string; retry_count: number; max_retries: number; error: null | string; result: null | unknown; created_at: Date; updated_at: Date; } /** Query job queue status. Optionally filter by note_id. */ declare function getJobQueueStatus(db: DatabaseClient, noteId?: string): Promise; declare class JobQueueWorker { private db; private events?; private capabilityManager?; private handlers; private running; private timer; private options; constructor(db: DatabaseClient, events?: TypedEventBus | undefined, options?: JobQueueOptions, capabilityManager?: CapabilityManager | undefined); registerHandler(jobType: string, handler: JobHandler): void; start(): Promise; /** Reset any 'processing' jobs back to 'pending' — they were interrupted by a restart */ private recoverStaleJobs; stop(): void; /** Process one batch of pending jobs. Useful for testing without polling. */ processOnce(): Promise; private poll; private processPendingJobs; private blockForCapability; getBackoffDelay(retryCount: number): number; } /** Title generation: LLM first, fallback to first-line extraction */ declare function titleGenerationHandler(job: Job, db: DatabaseClient): Promise; /** AI revision: LLM enhances note content, creates a revision record */ declare function aiRevisionHandler(job: Job, db: DatabaseClient): Promise; /** Concept tagging: LLM extracts SKOS concepts from revised content */ declare function conceptTaggingHandler(job: Job, db: DatabaseClient): Promise; /** Linking: find semantically related notes using FTS + vector RRF */ declare function linkingHandler(job: Job, db: DatabaseClient): Promise; /** * TagsRepository — free-form tag management for notes. * * Responsibilities: * - Add and remove tags from notes * - Look up tags by note or notes by tag * - List all tags with usage counts */ declare class TagsRepository { private db; constructor(db: DatabaseClient); addTag(noteId: string, tag: string): Promise; removeTag(noteId: string, tag: string): Promise; getTagsForNote(noteId: string): Promise; getNotesForTag(tag: string): Promise; listAllTags(): Promise>; } /** * CollectionsRepository — folder/category management for notes. * * Responsibilities: * - Create, read, update, and soft-delete collections * - Prevent circular parent references * - Assign and unassign notes from collections * - Return flat list and shallow tree views */ interface CollectionRow { id: string; name: string; description: null | string; parent_id: null | string; position: number; created_at: Date; updated_at: Date; deleted_at: Date | null; } interface CollectionCreateInput { name: string; description?: string; parent_id?: string; } declare class CollectionsRepository { private db; constructor(db: DatabaseClient); create(input: CollectionCreateInput): Promise; get(id: string): Promise; list(): Promise; listTree(): Promise>; update(id: string, fields: Partial>): Promise; delete(id: string): Promise; assignNote(collectionId: string, noteId: string): Promise; unassignNote(collectionId: string, noteId: string): Promise; getNotesInCollection(collectionId: string): Promise; } /** * LinksRepository — bidirectional note link management. * * Responsibilities: * - Create typed links between notes with duplicate prevention * - Soft-delete links * - Query outbound, inbound, and backlinks for a note */ interface LinkRow { id: string; source_note_id: string; target_note_id: string; link_type: string; confidence: null | number; created_at: Date; updated_at: Date | null; deleted_at: Date | null; } declare class LinksRepository { private db; constructor(db: DatabaseClient); create(sourceNoteId: string, targetNoteId: string, linkType?: string): Promise; get(id: string): Promise; listForNote(noteId: string): Promise<{ inbound: LinkRow[]; outbound: LinkRow[]; }>; getBacklinks(noteId: string): Promise; delete(id: string): Promise; } /** * SkosRepository — SKOS taxonomy management (schemes, concepts, relations). * * Responsibilities: * - Create and soft-delete SKOS schemes (taxonomy containers) * - Create, list, and soft-delete SKOS concepts within schemes * - Create and query broader/narrower/related concept relations */ interface SkosScheme { id: string; title: string; description: null | string; created_at: Date; updated_at: Date; deleted_at: Date | null; } interface SkosConcept { id: string; scheme_id: string; pref_label: string; alt_labels: string[]; definition: null | string; created_at: Date; updated_at: Date; deleted_at: Date | null; } interface SkosRelation { id: string; source_concept_id: string; target_concept_id: string; relation_type: string; created_at: Date; } interface NoteSkosTag { id: string; note_id: string; concept_id: string; created_at: Date; } declare class SkosRepository { private db; constructor(db: DatabaseClient); createScheme(title: string, description?: string): Promise; listSchemes(): Promise; deleteScheme(id: string): Promise; createConcept(schemeId: string, prefLabel: string, options?: { altLabels?: string[]; definition?: string; }): Promise; listConcepts(schemeId: string): Promise; deleteConcept(id: string): Promise; createRelation(sourceConceptId: string, targetConceptId: string, relationType: 'broader' | 'narrower' | 'related'): Promise; getRelations(conceptId: string): Promise; tagNote(noteId: string, conceptId: string): Promise; untagNote(noteId: string, conceptId: string): Promise; conceptsForNote(noteId: string): Promise; } interface ProvenanceEdge { id: string; entity_type: string; entity_id: string; activity: string; agent: string; started_at: Date; ended_at: Date | null; attributes: null | Record; } interface RecordProvenanceInput { activity: string; agent: string; startedAt?: Date | string; endedAt?: Date | null | string; attributes?: null | Record; } declare class ProvenanceRepository { private db; constructor(db: DatabaseClient); recordProvenance(entityType: string, entityId: string, input: RecordProvenanceInput): Promise; forEntity(entityType: string, entityId: string): Promise; } /** * captureKnowledge — tool function for creating notes. * * Supports three sub-actions: * create — create a single note from content * bulk_create — create multiple notes in sequence * from_template — interpolate a template string and create a note * * Input is Zod-validated at entry. All writes delegate to NotesRepository. */ interface CaptureKnowledgeResult { action: string; notes: NoteFull[]; } declare function captureKnowledge(db: DatabaseClient, rawInput: unknown, events?: TypedEventBus): Promise; /** * manageNote — tool function for note lifecycle operations. * * Supports: update, delete, restore, archive, unarchive, star, unstar. * * Input is Zod-validated at entry. All mutations delegate to NotesRepository. */ interface ManageNoteResult { action: string; note_id: string; note?: NoteFull; } declare function manageNote(db: DatabaseClient, rawInput: unknown, events?: TypedEventBus): Promise; /** * searchTool — tool function wrapping SearchRepository. * * Text mode is always available. Semantic, hybrid, and auto modes are available * when the host passes a query_embedding; forced semantic/hybrid fail clearly * without one while auto falls back to lexical search. * * Input is Zod-validated at entry. */ declare function searchTool(db: DatabaseClient, rawInput: unknown): Promise; /** * Zod schemas for tool function inputs. * * These schemas are the contract between callers (e.g. host platform bridge) and * the tool functions. All inputs are validated at the tool boundary so that * repository methods only receive well-typed data. */ declare const CaptureKnowledgeInputSchema: z.ZodObject<{ action: z.ZodEnum<[ "create", "bulk_create", "from_template" ]>; archive_id: z.ZodOptional; content: z.ZodOptional; format: z.ZodDefault>; notes: z.ZodOptional>; tags: z.ZodOptional>; title: z.ZodOptional; }, "strip", z.ZodTypeAny, { content: string; format: "html" | "markdown" | "plain"; tags?: string[] | undefined; title?: string | undefined; }, { content: string; format?: "html" | "markdown" | "plain" | undefined; tags?: string[] | undefined; title?: string | undefined; }>, "many">>; source: z.ZodDefault; tags: z.ZodOptional>; template: z.ZodOptional; title: z.ZodOptional; variables: z.ZodOptional>; visibility: z.ZodDefault>; }, "strip", z.ZodTypeAny, { action: "bulk_create" | "create" | "from_template"; archive_id?: string | undefined; content?: string | undefined; format: "html" | "markdown" | "plain"; notes?: { content: string; format: "html" | "markdown" | "plain"; tags?: string[] | undefined; title?: string | undefined; }[] | undefined; source: string; tags?: string[] | undefined; template?: string | undefined; title?: string | undefined; variables?: Record | undefined; visibility: "private" | "public" | "shared"; }, { action: "bulk_create" | "create" | "from_template"; archive_id?: string | undefined; content?: string | undefined; format?: "html" | "markdown" | "plain" | undefined; notes?: { content: string; format?: "html" | "markdown" | "plain" | undefined; tags?: string[] | undefined; title?: string | undefined; }[] | undefined; source?: string | undefined; tags?: string[] | undefined; template?: string | undefined; title?: string | undefined; variables?: Record | undefined; visibility?: "private" | "public" | "shared" | undefined; }>; type CaptureKnowledgeInput = z.infer; declare const ManageNoteInputSchema: z.ZodObject<{ action: z.ZodEnum<[ "update", "delete", "restore", "archive", "unarchive", "star", "unstar" ]>; content: z.ZodOptional; format: z.ZodOptional; note_id: z.ZodString; title: z.ZodOptional; visibility: z.ZodOptional; }, "strip", z.ZodTypeAny, { action: "archive" | "delete" | "restore" | "star" | "unarchive" | "unstar" | "update"; content?: string | undefined; format?: string | undefined; note_id: string; title?: string | undefined; visibility?: string | undefined; }, { action: "archive" | "delete" | "restore" | "star" | "unarchive" | "unstar" | "update"; content?: string | undefined; format?: string | undefined; note_id: string; title?: string | undefined; visibility?: string | undefined; }>; type ManageNoteInput = z.infer; declare const SearchInputSchema: z.ZodObject<{ collection_id: z.ZodOptional; date_from: z.ZodOptional; date_to: z.ZodOptional; embeddingSetId: z.ZodOptional; format: z.ZodOptional>; include_facets: z.ZodDefault; is_archived: z.ZodOptional; is_starred: z.ZodOptional; limit: z.ZodDefault; mode: z.ZodDefault>; offset: z.ZodDefault; query_embedding: z.ZodOptional>; query: z.ZodString; source: z.ZodOptional; tags: z.ZodOptional>; visibility: z.ZodOptional>; }, "strip", z.ZodTypeAny, { collection_id?: string | undefined; date_from?: Date | undefined; date_to?: Date | undefined; embeddingSetId?: string | undefined; format?: "html" | "markdown" | "plain" | undefined; include_facets: boolean; is_archived?: boolean | undefined; is_starred?: boolean | undefined; limit: number; mode: "auto" | "hybrid" | "semantic" | "text"; offset: number; query_embedding?: number[] | undefined; query: string; source?: string | undefined; tags?: string[] | undefined; visibility?: "private" | "public" | "shared" | undefined; }, { collection_id?: string | undefined; date_from?: Date | undefined; date_to?: Date | undefined; embeddingSetId?: string | undefined; format?: "html" | "markdown" | "plain" | undefined; include_facets?: boolean | undefined; is_archived?: boolean | undefined; is_starred?: boolean | undefined; limit?: number | undefined; mode?: "auto" | "hybrid" | "semantic" | "text" | undefined; offset?: number | undefined; query_embedding?: number[] | undefined; query: string; source?: string | undefined; tags?: string[] | undefined; visibility?: "private" | "public" | "shared" | undefined; }>; type SearchInput = z.infer; /** * FortemiToolManifest — registry of all Fortemi tool definitions. * * Defines the full set of tool schemas and provides BridgeCapability * projection for bridge registration. Each tool definition follows the * WHEN/WHAT/HOW/OUT description pattern so consumers understand call sites. * * The 10 tools defined here are the initial subset covering core Fortemi * operations. Additional tools will be added incrementally as repositories * are implemented. */ interface FortemiToolDefinition { id: string; name: string; description: string; category: 'analyze' | 'capture' | 'manage' | 'organize' | 'process' | 'search' | 'system'; inputSchema: ZodType; tags: string[]; sideEffects: boolean; requiredCapability?: string; } interface BridgeCapability { id: string; name: string; description: string; inputSchema: Record; tags: string[]; sideEffects: boolean; } declare class FortemiToolManifest { private tools; constructor(); /** Look up a single tool by its fully-qualified id. */ get(id: string): FortemiToolDefinition | undefined; /** Return all registered tools as a snapshot array. */ list(): FortemiToolDefinition[]; /** Return tools matching a custom predicate. */ filter(predicate: (tool: FortemiToolDefinition) => boolean): FortemiToolDefinition[]; /** Return tools belonging to a specific category. */ byCategory(category: string): FortemiToolDefinition[]; /** * Full-text search across tool name, description, and tags. * Case-insensitive. */ search(query: string): FortemiToolDefinition[]; /** Project all tools as BridgeCapability entries for bridge registration. */ toBridgeCapabilities(): BridgeCapability[]; /** Return the count of tools in each category. */ getCategoryCounts(): Record; } declare const fortemiManifest: FortemiToolManifest; declare const GetNoteInputSchema: z.ZodObject<{ note_id: z.ZodString; }, "strip", z.ZodTypeAny, { note_id: string; }, { note_id: string; }>; type GetNoteInput = z.infer; declare function getNote(db: DatabaseClient, rawInput: unknown, events?: TypedEventBus): Promise; declare const ListNotesInputSchema: z.ZodObject<{ collection_id: z.ZodOptional; include_deleted: z.ZodOptional; is_archived: z.ZodOptional; is_starred: z.ZodOptional; limit: z.ZodDefault; offset: z.ZodDefault; order: z.ZodDefault>; sort: z.ZodDefault>; tags: z.ZodOptional>; }, "strip", z.ZodTypeAny, { collection_id?: string | undefined; include_deleted?: boolean | undefined; is_archived?: boolean | undefined; is_starred?: boolean | undefined; limit: number; offset: number; order: "asc" | "desc"; sort: "created_at" | "title" | "updated_at"; tags?: string[] | undefined; }, { collection_id?: string | undefined; include_deleted?: boolean | undefined; is_archived?: boolean | undefined; is_starred?: boolean | undefined; limit?: number | undefined; offset?: number | undefined; order?: "asc" | "desc" | undefined; sort?: "created_at" | "title" | "updated_at" | undefined; tags?: string[] | undefined; }>; type ListNotesInput = z.infer; declare function listNotes(db: DatabaseClient, rawInput: unknown, events?: TypedEventBus): Promise>; declare const ManageTagsInputSchema: z.ZodObject<{ action: z.ZodEnum<[ "add", "remove", "list_for_note", "list_all" ]>; note_id: z.ZodOptional; tag: z.ZodOptional; }, "strip", z.ZodTypeAny, { action: "add" | "list_all" | "list_for_note" | "remove"; note_id?: string | undefined; tag?: string | undefined; }, { action: "add" | "list_all" | "list_for_note" | "remove"; note_id?: string | undefined; tag?: string | undefined; }>; type ManageTagsInput = z.infer; interface ManageTagsResult { action: string; tags?: string[]; all_tags?: Array<{ count: number; tag: string; }>; } declare function manageTags(db: DatabaseClient, rawInput: unknown): Promise; declare const ManageCollectionsInputSchema: z.ZodObject<{ action: z.ZodEnum<[ "create", "list", "list_tree", "assign", "unassign", "delete" ]>; collection_id: z.ZodOptional; description: z.ZodOptional; name: z.ZodOptional; note_id: z.ZodOptional; parent_id: z.ZodOptional; }, "strip", z.ZodTypeAny, { action: "assign" | "create" | "delete" | "list_tree" | "list" | "unassign"; collection_id?: string | undefined; description?: string | undefined; name?: string | undefined; note_id?: string | undefined; parent_id?: string | undefined; }, { action: "assign" | "create" | "delete" | "list_tree" | "list" | "unassign"; collection_id?: string | undefined; description?: string | undefined; name?: string | undefined; note_id?: string | undefined; parent_id?: string | undefined; }>; type ManageCollectionsInput = z.infer; interface ManageCollectionsResult { action: string; collection?: CollectionRow; collections?: CollectionRow[]; tree?: Array; collection_id?: string; note_id?: string; } declare function manageCollections(db: DatabaseClient, rawInput: unknown): Promise; declare const ManageLinksInputSchema: z.ZodObject<{ action: z.ZodEnum<[ "create", "list", "backlinks", "delete" ]>; link_id: z.ZodOptional; link_type: z.ZodDefault; note_id: z.ZodOptional; source_note_id: z.ZodOptional; target_note_id: z.ZodOptional; }, "strip", z.ZodTypeAny, { action: "backlinks" | "create" | "delete" | "list"; link_id?: string | undefined; link_type: string; note_id?: string | undefined; source_note_id?: string | undefined; target_note_id?: string | undefined; }, { action: "backlinks" | "create" | "delete" | "list"; link_id?: string | undefined; link_type?: string | undefined; note_id?: string | undefined; source_note_id?: string | undefined; target_note_id?: string | undefined; }>; type ManageLinksInput = z.infer; interface ManageLinksResult { action: string; link?: LinkRow; outbound?: LinkRow[]; inbound?: LinkRow[]; backlinks?: string[]; link_id?: string; } declare function manageLinks(db: DatabaseClient, rawInput: unknown): Promise; declare const ManageArchiveInputSchema: z.ZodObject<{ action: z.ZodEnum<[ "list", "create", "switch", "delete" ]>; name: z.ZodOptional; }, "strip", z.ZodTypeAny, { action: "create" | "delete" | "list" | "switch"; name?: string | undefined; }, { action: "create" | "delete" | "list" | "switch"; name?: string | undefined; }>; type ManageArchiveInput = z.infer; interface ManageArchiveResult { action: string; archives?: ArchiveInfo[]; current?: string; name?: string; } declare function manageArchive(archiveManager: ArchiveManager, rawInput: unknown): Promise; declare const ManageCapabilitiesInputSchema: z.ZodObject<{ action: z.ZodEnum<[ "list", "enable", "disable", "status" ]>; capability: z.ZodOptional; }, "strip", z.ZodTypeAny, { action: "disable" | "enable" | "list" | "status"; capability?: string | undefined; }, { action: "disable" | "enable" | "list" | "status"; capability?: string | undefined; }>; type ManageCapabilitiesInput = z.infer; interface CapabilityInfo { name: CapabilityName; state: CapabilityState; error?: string; } interface ManageCapabilitiesResult { action: string; capabilities?: Array<{ name: CapabilityName; state: CapabilityState; }>; capability?: CapabilityInfo; } declare function manageCapabilities(capabilityManager: CapabilityManager, rawInput: unknown): Promise; /** * AttachmentsRepository — attach and retrieve binary files linked to notes. * * Responsibilities: * - Content-addressed blob deduplication via the store-computed BLAKE3 hash * - Store blob metadata in DatabaseClient (attachment_blob table) * - Store binary data in a BlobStore implementation (bytes-first ordering) * - Create/soft-delete attachment records linked to notes * - List active attachments for a note * - Reconcile/GC blob bytes against the canonical manifest live set * (ADR-013 D2/D4: manifests are the sole lifecycle authority) */ interface AttachmentRow { id: string; note_id: string; blob_id: string; document_type_id: null | string; mime_type: null | string; extracted_text: null | string; filename: string; display_name: null | string; position: number; created_at: Date; deleted_at: Date | null; } interface AttachmentBlobRow { id: string; content_hash: string; size_bytes: number; storage_path: null | string; created_at: Date; } interface AttachInput { noteId: string; data: Uint8Array; filename: string; mimeType?: string; extractedText?: string; displayName?: string; } declare class AttachmentsRepository { private db; private blobStore; constructor(db: DatabaseClient, blobStore: BlobStore); /** * Attach a binary file to a note. * * Bytes are written first (`put()` is idempotent — content addressing makes * replays safe), then the metadata rows commit (ADR-013 D5). A crash * between the two leaves an unreferenced blob that reconcile/gc sweeps — * never a manifest without recoverable state. The store-computed BLAKE3 * `content_hash` (`blake3:`) matches the server convention and is the * key used by the portable Knowledge-Shard byte sidecar. * * If a blob row with the same content hash already exists, it is reused * (deduplication) — re-putting the bytes also heals a previously * reference-only blob whose bytes went missing. * * Returns the newly created AttachmentRow. */ attach(input: AttachInput): Promise; /** * Fetch an attachment row by its ID. * Throws when no row exists. */ get(id: string): Promise; /** * Retrieve the raw binary data for an attachment. * Returns null when the bytes are not present — the attachment is then in * the recoverable reference-only state (metadata intact, bytes * re-hydratable from a shard sidecar or a re-attach of the same content). */ getBlob(attachmentId: string): Promise; /** * True when the attachment's bytes are physically present in the BlobStore. * False means reference-only (recoverable), not an error. */ hasBlob(attachmentId: string): Promise; /** * List active (non-deleted) attachments for a note. * Ordered by position ascending, then created_at ascending. */ list(noteId: string): Promise; /** * Soft-delete an attachment by setting deleted_at to the current timestamp. * The blob row is untouched and no bytes are removed inline — physical * removal happens only through deferred `reconcileBlobs()`/`gcBlobs()` * against the canonical live set (ADR-013 D4). */ delete(id: string): Promise; /** * The authoritative live-checksum set: content hashes referenced by at * least one non-deleted attachment. This — not any refcount — decides * which bytes are reachable. */ liveBlobChecksums(): Promise; /** * Reconcile the BlobStore against the canonical live set (startup, after * quota events, after interrupted writes). `missing` lists reference-only * checksums; `unreferenced` lists GC candidates. */ reconcileBlobs(opts?: BlobReconcileOptions): Promise; /** * Deferred, age-thresholded physical removal of unreachable bytes. * Runs a reconcile first so GC always acts on current manifest truth. */ gcBlobs(opts?: BlobGcOptions): Promise; private blobChecksumOf; } declare const ManageAttachmentsInputSchema: z.ZodObject<{ /** Base64-encoded file data for the 'attach' action */ data_base64: z.ZodOptional; action: z.ZodEnum<[ "attach", "list", "get", "get_blob", "delete" ]>; attachment_id: z.ZodOptional; display_name: z.ZodOptional; extracted_text: z.ZodOptional; filename: z.ZodOptional; mime_type: z.ZodOptional; note_id: z.ZodOptional; }, "strip", z.ZodTypeAny, { action: "attach" | "delete" | "get_blob" | "get" | "list"; attachment_id?: string | undefined; data_base64?: string | undefined; display_name?: string | undefined; extracted_text?: string | undefined; filename?: string | undefined; mime_type?: string | undefined; note_id?: string | undefined; }, { action: "attach" | "delete" | "get_blob" | "get" | "list"; attachment_id?: string | undefined; data_base64?: string | undefined; display_name?: string | undefined; extracted_text?: string | undefined; filename?: string | undefined; mime_type?: string | undefined; note_id?: string | undefined; }>; type ManageAttachmentsInput = z.infer; interface ManageAttachmentsResult { action: string; attachment?: AttachmentRow; attachments?: AttachmentRow[]; attachment_id?: string; /** Base64-encoded blob data for 'get_blob' action */ data_base64?: string; size_bytes?: number; } declare function manageAttachments(db: DatabaseClient, blobStore: BlobStore, rawInput: unknown): Promise; /** * GPU capability detection for WebGPU-based LLM inference. * Used to select appropriate model tier based on available GPU memory. * * @implements #61 GPU capability detection */ interface GpuCapabilities { webgpuAvailable: boolean; vendor: string; architecture: string; maxBufferSizeBytes: number; supportsF16: boolean; } type VramTier = 'high' | 'low' | 'medium' | 'unknown'; declare function detectGpuCapabilities(): Promise; declare function estimateVramTier(caps: GpuCapabilities): VramTier; /** * Select an LLM model based on VRAM tier and f16 shader support. * Uses f32 quantization when f16 shaders aren't available (e.g., SwiftShader). */ declare function selectLlmModel(tier: VramTier, supportsF16?: boolean): string; /** * Enhanced inference capability detection. * Extends gpu-detect.ts with VRAM estimation, model fit, Chrome AI, and WebNN detection. * * @implements #115 hardware capability detection improvements */ type RecommendedTier = 'cpu-only' | 'high' | 'low' | 'medium'; interface InferenceCapabilities { webgpu: boolean; wasm: boolean; webnn: boolean; sharedArrayBuffer: boolean; chromeAI: boolean; estimatedVramMB: number; recommendedTier: RecommendedTier; gpu: GpuCapabilities; vramTier: VramTier; } interface ModelFitResult { fits: boolean; estimatedVramMB: number; availableVramMB: number; recommendation: string; } /** * Estimate VRAM in MB using known GPU heuristics. * Falls back to maxBufferSize-based estimation if no match. */ declare function estimateVramMB(gpu: GpuCapabilities): number; /** * Estimate whether a model will fit in available VRAM. */ declare function estimateModelFit(modelSizeMB: number, availableVramMB: number): ModelFitResult; /** * Comprehensive inference capability detection. * Superset of detectGpuCapabilities() — adds VRAM estimation, WebNN, Chrome AI, etc. */ declare function detectInferenceCapabilities(): Promise; /** * Text chunking utility for embedding generation. * Splits long text into overlapping chunks suitable for embedding models. * * @implements #63 embedding pipeline prerequisite */ /** Split text into overlapping chunks for embedding. */ declare function chunkText(text: string, maxChars?: number, overlap?: number): string[]; /** * Embedding generation job handler. * Generates and stores vector embeddings for note content. * Embed function is injected via setEmbedFunction — no WASM loaded by default. * * @implements #63 embedding generation */ /** Type for the embed function — injected by the semantic capability module */ type EmbedFunction = (texts: string[]) => Promise; declare function setEmbedFunction(fn: EmbedFunction | null): void; declare function getEmbedFunction(): EmbedFunction | null; /** Job handler for embedding generation. Registered in JobQueueWorker. */ declare function embeddingGenerationHandler(job: { note_id: string; }, db: DatabaseClient): Promise; /** * LLM completion function injection. * Provides the slot for an LLM function — injected by the llm capability module. * No model loading by default (CAP-001). * * @implements #66 AI title generation */ /** Type for the LLM completion function — injected by the llm capability module */ type LlmCompleteFn = (prompt: string, options?: { maxTokens?: number; temperature?: number; }) => Promise; declare function setLlmFunction(fn: LlmCompleteFn | null): void; declare function getLlmFunction(): LlmCompleteFn | null; /** * Auto-tagging utility using embedding similarity. * Suggests tags based on cosine similarity between note and tag vocabulary embeddings. * * @implements #67 auto-tagging */ /** Cosine similarity between two normalized vectors (dot product) */ declare function cosineSimilarity(a: number[], b: number[]): number; /** * Suggest tags based on embedding similarity to tag vocabulary centroids. * Returns tags sorted by descending similarity score, filtered by threshold. */ declare function suggestTags(noteEmbedding: number[], tagEmbeddings: Map, threshold?: number, maxTags?: number): string[]; /** * Off-main-thread query-embedding transport for the semantic capability. * * The semantic capability consumes a single `EmbedFunction` * (`(texts: string[]) => Promise`). With `executionMode="worker"` * (#146) the PGlite DB + HNSW query run off the main thread, but a * main-thread `EmbedFunction` closure still blocks the UI: model load janks * first paint of search, and every per-query embed blocks input. * * This module lets the host run the embed function inside a Worker (or behind * a MessagePort) so semantic search is off-thread end-to-end. Core posts * `{ texts }` to the port and awaits `number[][]`; the host owns the worker, * the model, and the model params (so build-time corpus embeddings stay an * exact match: `Xenova/all-MiniLM-L6-v2`, fp32, `{ pooling:'mean', normalize:true }`, * 384-d). * * Two halves: * - {@link createWorkerEmbedFunction} — main-thread side. Wraps a transport * into an `EmbedFunction` that round-trips each request to the worker. * - {@link handleEmbedRequests} — worker side. Wires a host-owned * `(texts) => Promise` to the message protocol. * * The existing main-thread `registerSemanticCapability(manager, embedFn)` path * is unchanged. This transport is additive and opt-in. * * @implements #180 off-main-thread / pluggable query-embedding transport */ /** * Minimal transport contract satisfied by both `Worker` and `MessagePort`. * Core only needs to post messages and listen for replies. */ interface EmbedTransportPort { postMessage(message: unknown): void; addEventListener(type: 'message', listener: (event: { data: unknown; }) => void): void; removeEventListener(type: 'message', listener: (event: { data: unknown; }) => void): void; /** MessagePort requires start() when using addEventListener; Worker does not. */ start?(): void; } /** Message discriminators for the embed protocol. */ declare const EMBED_REQUEST_KIND: "fortemi:embed:request"; declare const EMBED_RESPONSE_KIND: "fortemi:embed:response"; /** Request posted by core (main thread) to the worker. */ interface EmbedRequestMessage { kind: typeof EMBED_REQUEST_KIND; id: number; texts: string[]; } /** Reply posted by the worker back to core. Exactly one of `vectors`/`error`. */ interface EmbedResponseMessage { kind: typeof EMBED_RESPONSE_KIND; id: number; vectors?: number[][]; error?: string; } /** Options for the main-thread worker embed function. */ interface EmbedWorkerOptions { /** * Per-request timeout in milliseconds. A request that receives no reply * within this window rejects with a timeout error. Set to `0` to disable. * Default: 30000 (30s). */ timeoutMs?: number; } /** * Wrap a Worker/MessagePort transport into an `EmbedFunction` (main-thread side). * * Each `embed(texts)` call posts an {@link EmbedRequestMessage} with a unique id * and resolves when the matching {@link EmbedResponseMessage} arrives. The * message listener is attached immediately and removed by `dispose()`. * * @param port - A `Worker`, `MessagePort`, or any {@link EmbedTransportPort}. * @param options - Optional timeout configuration. * @returns The `embed` function and a `dispose` cleanup (removes the listener * and rejects any in-flight requests). * * @example * ```ts * const worker = new Worker(new URL('./queryEmbed.worker.ts', import.meta.url), { type: 'module' }) * const { embed, dispose } = createWorkerEmbedFunction(worker) * setEmbedFunction(embed) // query + job embedding now run off-thread * // later: dispose(); worker.terminate() * ``` */ declare function createWorkerEmbedFunction(port: EmbedTransportPort, options?: EmbedWorkerOptions): { dispose: () => void; embed: EmbedFunction; }; /** * Wire a host-owned embed function to the message protocol (worker side). * * Call this inside the worker (or behind a MessagePort) with the function that * loads the model and runs inference. It answers each {@link EmbedRequestMessage} * with an {@link EmbedResponseMessage}. * * @param port - The worker scope (`self`) or a `MessagePort`. * @param embed - The host embed function `(texts) => Promise`. * @returns A disposer that removes the listener. * * @example * ```ts * // queryEmbed.worker.ts * import { handleEmbedRequests } from '@fortemi/core' * import { pipeline } from '@huggingface/transformers' * * const extractor = await pipeline('feature-extraction', 'Xenova/all-MiniLM-L6-v2') * handleEmbedRequests(self as unknown as EmbedTransportPort, async (texts) => { * const out = await Promise.all( * texts.map(async (t) => { * const r = await extractor(t, { pooling: 'mean', normalize: true }) * return Array.from(r.data as Float32Array) * }), * ) * return out * }) * ``` */ declare function handleEmbedRequests(port: EmbedTransportPort, embed: EmbedFunction): () => void; /** * Semantic capability loader — registers the embedding pipeline with CapabilityManager. * * In production (browser), this loads @huggingface/transformers in a Web Worker. * In tests, call registerSemanticCapability() with a mock embed function. * * Two registration paths, both additive: * - registerSemanticCapability(manager, embedFn) — main-thread embed closure. * - registerSemanticCapabilityWorker(manager, port) — off-main-thread embed * transport (#180), so semantic search runs off-thread end-to-end. * * @implements #62 semantic capability loader * @implements #180 off-main-thread / pluggable query-embedding transport */ /** * Register the semantic capability with a CapabilityManager. * The loader will be called when capabilityManager.enable('semantic') is invoked. * * @param manager - The CapabilityManager instance * @param embedFn - The embedding function (from transformers.js worker or mock) * @param onProgress - Optional progress callback for model download */ declare function registerSemanticCapability(manager: CapabilityManager, embedFn: EmbedFunction, onProgress?: (pct: number) => void): void; /** * Register the semantic capability backed by an off-main-thread transport (#180). * * The embed function round-trips each request to a host-owned Worker/MessagePort, * so model load and per-query inference never touch the main thread. The host * owns the worker and the model params (build-time corpus match stays exact). * * The loader runs when `capabilityManager.enable('semantic')` is invoked; the * message listener is attached then and removed on * {@link unregisterSemanticCapability} (i.e. on `disable`). * * @param manager - The CapabilityManager instance. * @param port - A `Worker`, `MessagePort`, or any {@link EmbedTransportPort}. * @param options - Optional transport options (e.g. per-request timeout). * * @example * ```ts * const worker = new Worker(new URL('./queryEmbed.worker.ts', import.meta.url), { type: 'module' }) * registerSemanticCapabilityWorker(capabilityManager, worker) * await capabilityManager.enable('semantic') // off-thread end-to-end * ``` */ declare function registerSemanticCapabilityWorker(manager: CapabilityManager, port: EmbedTransportPort, options?: EmbedWorkerOptions): void; /** * Unregister the semantic capability — clears the embed function and tears down * any active off-main-thread transport. Called when the capability is disabled. */ declare function unregisterSemanticCapability(): void; /** * LLM capability loader — registers the local LLM with CapabilityManager. * * In production (browser), this loads @mlc-ai/web-llm in a Web Worker. * In tests, call registerLlmCapability() with a mock completion function. * * @implements #65 LLM capability loader */ interface LlmCapabilityOptions { modelOverride?: string; onProgress?: (pct: number, text: string) => void; } /** * Register the LLM capability with a CapabilityManager. * The loader checks WebGPU availability before loading. * * @param manager - The CapabilityManager instance * @param completeFn - The LLM completion function (from WebLLM worker or mock) * @param options - Optional model override and progress callback */ declare function registerLlmCapability(manager: CapabilityManager, completeFn: LlmCompleteFn, options?: LlmCapabilityOptions): void; /** * Unregister the LLM capability — clears the completion function. */ declare function unregisterLlmCapability(): void; /** * Formal InferenceProvider interface. * Core contract for all inference providers — remote APIs, local servers, in-browser models. * Core stays dependency-free: interface only, no implementations. * * @implements #112 formal InferenceProvider interface */ interface ProviderCapabilities { embeddings: boolean; chat: boolean; streaming: boolean; vision: boolean; toolCalling: boolean; structuredOutput: boolean; maxContextTokens?: number; } interface EmbedRequest { texts: string[]; model?: string; } interface EmbedResponse { vectors: number[][]; model: string; usage?: { totalTokens: number; }; } interface CompletionRequest { prompt: string; model?: string; maxTokens?: number; temperature?: number; systemPrompt?: string; stopSequences?: string[]; } interface CompletionResponse { text: string; model: string; usage?: { completionTokens: number; promptTokens: number; }; finishReason?: 'content_filter' | 'length' | 'stop'; } interface StreamChunk { text: string; done: boolean; } interface ModelInfo { id: string; name?: string; capabilities: Partial; contextWindow?: number; owned_by?: string; } type ProbeStatus = 'degraded' | 'down' | 'ok'; interface ProbeResult { status: ProbeStatus; latencyMs: number; message?: string; } type ProviderTier = 'chrome-ai' | 'in-browser' | 'local-server' | 'remote'; interface InferenceProvider { readonly id: string; readonly name: string; readonly tier: ProviderTier; readonly capabilities: ProviderCapabilities; /** Generate embeddings for text inputs */ embed?(request: EmbedRequest): Promise; /** Generate a completion (non-streaming) */ complete?(request: CompletionRequest): Promise; /** Generate a streaming completion */ stream?(request: CompletionRequest): AsyncIterable; /** List available models from this provider */ listModels(): Promise; /** Health check — probe the provider */ probe(): Promise; /** Clean up resources */ dispose(): void; } /** * ProviderRegistry — manages InferenceProvider instances. * Supports add/remove/getActive/setActive and derives CapabilityManager state. * * @implements #112 provider registry */ declare class ProviderRegistry { private events?; private providers; private activeId; constructor(events?: TypedEventBus | undefined); /** Register a provider. First provider with embedding capability becomes active. */ add(provider: InferenceProvider): void; /** Remove a provider by ID. If it was active, clears active. */ remove(id: string): void; /** Set the active provider by ID */ setActive(id: string): void; /** Get the currently active provider */ getActive(): InferenceProvider | null; /** Get a provider by ID */ get(id: string): InferenceProvider | undefined; /** List all registered providers */ list(): InferenceProvider[]; /** Get provider count */ get size(): number; /** Check if any provider supports embeddings */ hasEmbeddings(): boolean; /** Check if any provider supports chat */ hasChat(): boolean; /** Find first provider supporting a given capability */ findByCapability(cap: keyof InferenceProvider['capabilities']): InferenceProvider | undefined; /** Convenience: embed using active provider */ embed(request: EmbedRequest): Promise; /** Convenience: complete using active provider */ complete(request: CompletionRequest): Promise; /** Convenience: stream using active provider */ stream(request: CompletionRequest): AsyncIterable; /** Dispose all providers */ dispose(): void; /** * Sync the legacy bare function slots with the active provider. * This maintains backward compatibility: job-queue-worker.ts and other * consumers that call getEmbedFunction() / getLlmFunction() still work. */ private syncLegacyFunctions; } /** * Create an InferenceProvider from legacy bare functions. * Used by setEmbedFunction/setLlmFunction backward compat layer. */ declare function createLegacyProvider(options: { embedFn?: EmbedFunction | null; id?: string; llmFn?: LlmCompleteFn | null; name?: string; }): InferenceProvider; /** * OpenAI-compatible inference provider. * Works with OpenAI, OpenRouter, Anthropic (via OpenRouter), Ollama, LM Studio, * llama.cpp, vLLM, Jan, and any OpenAI-compatible endpoint. * * No SDK dependencies — uses raw fetch() to keep @fortemi/core lightweight. * * @implements #113 remote provider support */ interface OpenAIProviderConfig { id: string; name: string; baseURL: string; apiKey?: string; defaultModel?: string; defaultEmbeddingModel?: string; tier?: ProviderTier; headers?: Record; timeoutMs?: number; } declare class OpenAICompatibleProvider implements InferenceProvider { readonly id: string; readonly name: string; readonly tier: ProviderTier; readonly capabilities: ProviderCapabilities; private baseURL; private apiKey?; private defaultModel; private defaultEmbeddingModel; private extraHeaders; private timeoutMs; private abortController; constructor(config: OpenAIProviderConfig); embed(request: EmbedRequest): Promise; complete(request: CompletionRequest): Promise; stream(request: CompletionRequest): AsyncIterable; listModels(): Promise; probe(): Promise; dispose(): void; private buildMessages; private mapFinishReason; private isEmbeddingModel; private isLocalURL; private fetch; private rawFetch; } /** * Local inference server auto-discovery. * Probes known local endpoints (Ollama, LM Studio, llama.cpp, vLLM, Jan, LocalAI) * and returns discovered providers ready for registration. * * @implements #116 local server auto-discovery */ interface LocalEndpoint { id: string; name: string; baseURL: string; defaultPort: number; } interface DiscoveredProvider { id: string; name: string; baseURL: string; models: ModelInfo[]; } interface DiscoveryOptions { /** Additional endpoints to probe beyond the defaults */ extraEndpoints?: LocalEndpoint[]; /** Probe timeout per endpoint in ms (default: 2000) */ timeoutMs?: number; /** Ports to skip (e.g., if you know a port is used for something else) */ skipPorts?: number[]; } declare const LOCAL_ENDPOINTS: LocalEndpoint[]; type ModelCategory = 'chat' | 'embedding' | 'vision'; /** * Classify a model by its ID/name into embedding, vision, or chat. */ declare function classifyModel(modelId: string): ModelCategory; /** * Discover local inference servers by probing known endpoints. * Returns all reachable providers with their available models. */ declare function discoverLocalProviders(options?: DiscoveryOptions): Promise; /** * FallbackRouter — wraps multiple InferenceProviders with automatic failover. * Routes requests to the highest-priority available provider, falling through * on errors. Failed providers enter cooldown before retry. * * @implements #114 provider fallback chains with cooldown */ interface FallbackRouterConfig { /** Ordered list of providers (highest priority first) */ providers: InferenceProvider[]; /** Cooldown durations by error type in ms */ cooldowns?: CooldownConfig; /** Event bus for fallback notifications */ events?: TypedEventBus; } interface CooldownConfig { /** Cooldown for rate limit errors (HTTP 429) — default 30s */ rateLimit?: number; /** Cooldown for server errors (HTTP 5xx) — default 60s */ serverError?: number; /** Cooldown for connection failures — default 300s */ connectionFailure?: number; /** Cooldown for content policy errors — default 0 (immediate retry with next) */ contentPolicy?: number; } type ErrorCategory = 'connection_failure' | 'content_policy' | 'context_window' | 'rate_limit' | 'server_error' | 'unknown'; declare function classifyError(error: unknown): ErrorCategory; interface FallbackEvent { fromProvider: string; toProvider: string; errorCategory: ErrorCategory; error: string; } interface CooldownEvent { providerId: string; errorCategory: ErrorCategory; cooldownMs: number; expiresAt: number; } declare class FallbackRouter implements InferenceProvider { readonly id = "fallback-router"; readonly name = "Fallback Router"; readonly tier: ProviderTier; private providers; private cooldowns; private cooldownMap; private events?; get capabilities(): ProviderCapabilities; constructor(config: FallbackRouterConfig); /** Get providers not currently in cooldown */ getAvailableProviders(): InferenceProvider[]; /** Get providers in cooldown with their expiry info */ getCoolingDown(): Array<{ category: ErrorCategory; expiresAt: number; providerId: string; }>; /** Manually clear cooldown for a provider */ clearCooldown(providerId: string): void; /** Clear all cooldowns */ clearAllCooldowns(): void; /** Add a provider to the chain (appended at lowest priority) */ addProvider(provider: InferenceProvider): void; /** Remove a provider from the chain */ removeProvider(id: string): void; /** Reorder providers (new priority order) */ setOrder(ids: string[]): void; embed(request: EmbedRequest): Promise; complete(request: CompletionRequest): Promise; stream(request: CompletionRequest): AsyncIterable; listModels(): Promise; probe(): Promise; dispose(): void; private withFallback; private applyCooldown; } interface FortemiBridgeCapabilities { secureSecrets: boolean; providerRouting: boolean; localNetworkAccess: boolean; auditLog: boolean; } interface FortemiSecretStore { isAvailable(): boolean | Promise; getSecret(key: string): Promise; setSecret(key: string, value: string): Promise; deleteSecret(key: string): Promise; } interface BridgeProviderInfo { id: string; name: string; tier: 'chrome-ai' | 'in-browser' | 'local-server' | 'remote'; requiresApiKey: boolean; capabilities: { chat?: boolean; embeddings?: boolean; streaming?: boolean; }; } interface FortemiInferenceRouter { listProviders(): Promise; probeProvider(providerId: string): Promise; complete(providerId: string, request: CompletionRequest): Promise; embed(providerId: string, request: EmbedRequest): Promise; stream?(providerId: string, request: CompletionRequest): AsyncIterable; } interface FortemiBridge { version: string; capabilities(): Promise; secrets: FortemiSecretStore; inference?: FortemiInferenceRouter; } interface FortemiBridgeHost { fortemiBridge?: FortemiBridge; fortemiSecureStorage?: FortemiSecretStore; } declare function getFortemiBridge(host?: FortemiBridgeHost | undefined): FortemiBridge | null; declare function getFortemiSecretStore(host?: FortemiBridgeHost | undefined): FortemiSecretStore | null; declare function hasFortemiSecureSecrets(host?: FortemiBridgeHost | undefined): Promise; type CspDirectiveName = 'base-uri' | 'connect-src' | 'default-src' | 'font-src' | 'frame-ancestors' | 'img-src' | 'manifest-src' | 'object-src' | 'report-uri' | 'script-src' | 'style-src' | 'worker-src'; type CspDirectives = Partial>; interface PluginCspOptions { scriptSrc?: string[]; connectSrc?: string[]; imgSrc?: string[]; styleSrc?: string[]; reportUri?: string; extraDirectives?: CspDirectives; } interface PluginScriptPolicy { allowedOrigins: string[]; allowedUrls?: string[]; requireSri?: boolean; } interface PluginScriptDescriptor { url: string; integrity?: string; crossOrigin?: 'anonymous' | 'use-credentials'; } interface LoadedPluginScript { url: string; integrity: string; bytes: Uint8Array; text: string; } interface CspViolationReport { documentUri?: string; violatedDirective?: string; effectiveDirective?: string; blockedUri?: string; originalPolicy?: string; disposition?: string; sourceFile?: string; lineNumber?: number; columnNumber?: number; raw: unknown; } declare function buildPluginCsp(options?: PluginCspOptions): string; declare function computeSri(data: ArrayBuffer | Uint8Array, algorithm?: string): Promise; declare function verifySri(data: ArrayBuffer | Uint8Array, integrity: string): Promise; declare function isPluginScriptAllowed(url: string, policy: PluginScriptPolicy): boolean; declare function fetchPluginScript(descriptor: PluginScriptDescriptor, policy: PluginScriptPolicy, fetchFn?: typeof fetch): Promise; declare function appendPluginScript(descriptor: PluginScriptDescriptor, policy: PluginScriptPolicy, doc?: Document): Promise; declare function parseCspReport(body: unknown): CspViolationReport; declare function createCspReportHandler(onReport: (report: CspViolationReport) => Promise | void): (request: Request) => Promise; /** * Knowledge Shard portability profiles derived from the pinned Fortemi receipt. * * @implements @.aiwg/adrs/ADR-011-shard-server-conformance-and-version-negotiation.md * @schema @packages/core/schemas/knowledge-shard/upstream-contract.json * @created 2026-07-17 * @agent Codex */ declare const CORE_V1_COMPONENTS: readonly [ "notes", "collections", "tags", "templates", "links" ]; declare function getKnowledgeShardProfileRegistry(): ShardProfileRegistryEntry[]; interface CreateShardCapabilityReportInput { backend: ShardBackend; operation: ShardOperation; requestedProfile: null | string; requestedSchemaVersion?: null | string; declaredComponents?: readonly ShardComponent[]; omittedComponents?: readonly ShardComponent[]; losses?: readonly ShardLossEntry[]; } declare function createShardCapabilityReport(input: CreateShardCapabilityReportInput): ShardCapabilityReport; declare function profileSupportError(report: ShardCapabilityReport): null | string; /** * Minimal tar + gzip packing/unpacking for shard archives. * * Uses fflate for gzip compression and implements a lightweight POSIX tar * encoder/decoder (512-byte block headers, ustar format). */ /** * Pack files into a gzip-compressed tar archive. * * @param files Map of filename → file contents * @returns Compressed archive bytes (suitable for .shard file) */ declare function packTarGz(files: Map, opts?: { maxDecompressedBytes?: number; }): Uint8Array; /** * Unpack a gzip-compressed tar archive. * * Before decompressing, the gzip ISIZE footer (declared uncompressed size) is * checked against `maxDecompressedBytes` and rejected if it exceeds the cap. * fflate independently verifies the actual output length against ISIZE, so a * lying footer fails during decompression — together this bounds the memory a * malicious archive can force us to allocate. * * @param data Compressed archive bytes * @param opts.maxDecompressedBytes Cap on decompressed size (default 256 MiB) * @returns Map of filename → file contents */ declare function unpackTarGz(data: Uint8Array, opts?: { maxDecompressedBytes?: number; }): Map; /** * SHA-256 checksum utilities for shard integrity verification. * Uses the Web Crypto API (browser-native, no extra dependencies). */ /** * Compute SHA-256 hex digest of a Uint8Array. * Returns lowercase hex string (64 characters). */ declare function sha256Hex(data: Uint8Array): Promise; /** * Validate checksums listed in a shard manifest against actual file contents. * * SECURITY (SEC7 — trust model): these checksums live *inside* the same archive * as the files they hash, so they detect **transport corruption**, not * **tampering**. An attacker who controls the archive controls both the file * bytes and the manifest hashes, so a passing result proves the archive is * internally consistent — nothing more. For provenance-sensitive imports, verify * integrity out-of-band: a signed manifest, or a caller-supplied expected digest * checked against the whole archive (see `prefetchShard`'s `expectedSha256`, * which is real integrity because the hash arrives on a separate channel). * * The signed-manifest path is now implemented: `verifyShardSignature` * (`shard-signature.ts`, #324/ADR-014) authenticates publisher provenance via * an Ed25519 signature over the manifest digest + blob-digest set, and * `importShard` runs it BEFORE any record or blob mutation. These in-archive * checksums remain the consistency layer *inside* that verified boundary. * * @returns Object with `valid` flag and list of failed filenames. */ declare function validateChecksums(checksums: Record, files: Map): Promise<{ failures: string[]; valid: boolean; }>; /** Presence semantics for Knowledge Shard schema 2.0 (Fortemi #1083). */ type ShardPresenceState = 'absent' | 'empty' | 'null' | 'value'; type StoredPresenceState = 'legacy-indeterminate' | ShardPresenceState; type ShardPresenceMap = Record; /** * Shard export pipeline — query all entities, serialize, pack into .shard archive. * * Pipeline: query DB → field-map → serialize (JSONL/JSON) → compute checksums → build manifest → tar.gz * * @implements @.aiwg/adrs/ADR-011-shard-server-conformance-and-version-negotiation.md * @depends @packages/core/src/shard/profile-registry.ts * @schema @packages/core/schemas/knowledge-shard.schema.receipt.json * @created 2026-07-17 * @agent Codex */ declare function exportShardWithReport(db: DatabaseClient, options: ExportOptions & { profile: string; }): Promise; /** * Export knowledge data from the database as a .shard archive (Uint8Array). * * @param db DatabaseClient database instance * @param options Export options (includeEmbeddings, collectionId filter) * @returns Compressed shard archive bytes */ declare function exportShard(db: DatabaseClient, options?: ExportOptions): Promise; /** * Shard import pipeline — unpack, validate, field-map, transactional insert. * * Pipeline: ArrayBuffer → gunzip → untar → parse manifest → validate checksums → * parse components → field-map → BEGIN transaction → INSERT all → COMMIT * * @implements @.aiwg/adrs/ADR-011-shard-server-conformance-and-version-negotiation.md * @depends @packages/core/src/shard/schema-validator.ts * @created 2026-07-17 * @agent Codex */ /** * Import a .shard archive into the database. * * The entire import is wrapped in a single transaction — if anything fails, * all changes are rolled back. * * @param db DatabaseClient database instance * @param data Raw archive bytes (from File API or fetch) * @param options Import options (conflict strategy) * @returns Import result with counts, warnings, and errors */ declare function importShard(db: DatabaseClient, data: ArrayBuffer | Uint8Array, options?: ImportOptions): Promise; interface ShardSchemaValidationResult { valid: boolean; errors: string[]; } type ShardFiles = Map; type CoreV1SchemaVersion = '1.0.0' | '1.1.0' | '1.2.0' | '2.0.0'; declare function getKnowledgeShardSchema(): unknown; declare function getKnowledgeShardContractReceipt(): unknown; declare function validateShardManifest(value: unknown): ShardSchemaValidationResult; declare function validateShardArchive(input: ArrayBuffer | ShardFiles | Uint8Array): ShardSchemaValidationResult; declare function validateCoreV1ShardArchive(input: ArrayBuffer | ShardFiles | Uint8Array): Promise; declare function validateRecordV1ShardArchive(input: ArrayBuffer | ShardFiles | Uint8Array): Promise; declare function validateFullV1ShardArchive(input: ArrayBuffer | ShardFiles | Uint8Array): Promise; declare function validateShardComponentRecord(component: 'templates' | ShardComponent, value: unknown, profile?: 'core-v1' | 'full-v1' | 'record-v1', version?: CoreV1SchemaVersion): ShardSchemaValidationResult; declare function assertShardComponentRecord(component: 'templates' | ShardComponent, value: unknown, profile?: 'core-v1' | 'full-v1' | 'record-v1', version?: CoreV1SchemaVersion): void; /** * Pluggable semantic providers for the in-place shard reader (issue #189). * * The static-file tier is text/facets-only by default. Semantic is opt-in via a * `StaticSemanticProvider`, with three tradeoff points the host chooses from: * * 1. none — don't configure a provider (text/facets only). Lightest. * 2. cosine-small — `createCosineSemanticProvider`: brute-force cosine over a * small static vectors file. Zero prebuild; small corpora only. * 3. ANN-full — implement `StaticSemanticProvider` yourself over a prebuilt * ANN snapshot (HNSW / flat-IVF served as a static asset), * loading it in `prepare()` and querying it in `search()`. * The interface is the extension point; no ANN engine is * bundled here. */ /** A note id paired with its embedding vector, as stored in a static vectors file. */ interface VectorEntry { id: string; vector: number[]; } interface CosineSemanticProviderOptions { /** * Embeds the query into the SAME space as the corpus vectors. Host-owned so it * matches the build-time embedding model exactly (sync or async). */ embedQuery: (query: string) => number[] | Promise; /** * JSONL file (one `{ id, vector }` per line) mapping note id → vector, served * as a static asset alongside the shard. Default `vectors.jsonl`. */ vectorsFile?: string; /** Pre-supplied vectors — skips loading from the component store. */ vectors?: VectorEntry[]; } /** * Brute-force cosine semantic provider — the "cosine-small" tradeoff point. Loads * a static vectors file and scores the query embedding against every corpus * vector. Fine for small/demo corpora; for the full corpus, supply a prebuilt-ANN * `StaticSemanticProvider` instead. */ declare function createCosineSemanticProvider(options: CosineSemanticProviderOptions): StaticSemanticProvider; /** * Shard warm / prefetch API — pre-stage and (optionally) verify shard bytes * without building the index. * * Staged corpus loading (text-first, then opt-in summary vectors, then opt-in * full content) wants the operator's hard rule honored: **no blocking waits**. * The HNSW index build has to happen on the user's click (it is heavy and is * shown with progress — that is correct). The *download* of the shard bytes * does not: it can be warmed in the background on idle so the click is purely * the index build. * * fortemi-react is server-free and local-first — shards are **static assets** * (typically generated at build time and served as static files, or bundled * and handed in directly as bytes). `prefetchShard` warms those static bytes; * it does not assume any API/server. The eventual `importShard` reads the warm * bytes via {@link fromPrefetched}, so import is just the index build. * * Two-layer integrity: * - `prefetchShard(url, { expectedSha256 })` verifies the whole-archive SHA-256 * against a build-time-known hash (emitted alongside the static shard). * - `importShard` still validates the per-file checksums inside the manifest * on import. Both layers share core's `sha256Hex`. * * @implements #181 prefetchShard / shard warm API */ /** Options for {@link prefetchShard}. */ interface PrefetchOptions { /** * Provide the shard bytes directly instead of fetching `url` — e.g. a * build-time-generated `.shard` imported as a bundled asset. The `url` is * still used as the warm-store key. When set, no network/disk fetch happens. */ bytes?: ArrayBuffer | Uint8Array; /** * Compute the SHA-256 of the warmed bytes (stored on the result and in the * warm store). Implied when `expectedSha256` is set. */ verify?: boolean; /** * Build-time-known SHA-256 (hex) of the whole shard archive. When set, the * warmed bytes are verified against it and a mismatch throws — nothing is * stored. Case-insensitive. */ expectedSha256?: string; /** * Fetch implementation to use. Defaults to `globalThis.fetch`. Inject for * tests or non-standard environments. */ fetchImpl?: typeof fetch; /** * Also persist the warmed bytes to the Cache Storage API so warmth survives * a reload. Feature-detected — a no-op when `caches` is unavailable (e.g. * Node, or a worker without Cache access). */ useCacheStorage?: boolean; /** Cache Storage cache name. Default: `'fortemi-shards'`. */ cacheName?: string; /** Abort signal forwarded to the fetch. */ signal?: AbortSignal; } /** Result of a {@link prefetchShard} call. */ interface PrefetchResult { /** The warm-store key (the `url` passed to prefetchShard). */ url: string; /** The warmed shard bytes (also retrievable via {@link fromPrefetched}). */ bytes: Uint8Array; /** Convenience: `bytes.byteLength`. */ byteLength: number; /** SHA-256 hex of the warmed bytes when computed (`verify` or `expectedSha256`), else `undefined`. */ sha256?: string; /** True when the bytes came from the Cache Storage API rather than a fresh fetch. */ fromCache: boolean; } /** * Pre-stage shard bytes into the warm store without building the index. * * Resolution order for the bytes: * 1. `options.bytes` (a directly-provided / bundled asset), else * 2. the Cache Storage API (when `useCacheStorage` and a prior write exists), else * 3. `fetch(url)` of the static asset. * * Concurrent calls for the same `url` (without `options.bytes`) share a single * fetch. On `expectedSha256` mismatch the call throws and nothing is stored. * * @param url - Static asset URL (also the warm-store key). * @param options - See {@link PrefetchOptions}. * @returns The warm result (bytes are also retrievable via {@link fromPrefetched}). * * @example * ```ts * // Warm on idle so the user's opt-in click is just the index build. * requestIdleCallback(() => { * void prefetchShard('/shards/research.shard', { expectedSha256: RESEARCH_SHARD_SHA256 }) * }) * // ...later, on click: * await importShard(db, fromPrefetched('/shards/research.shard'), { onProgress }) * ``` */ declare function prefetchShard(url: string, options?: PrefetchOptions): Promise; /** * Return previously-warmed shard bytes for `url`, ready to hand to `importShard`. * * @throws If the url was not prefetched (call {@link prefetchShard} first). * * @example * ```ts * await importShard(db, fromPrefetched('/shards/research.shard'), { onProgress }) * ``` */ declare function fromPrefetched(url: string): Uint8Array; /** Whether `url` has warm bytes in the in-memory store. */ declare function isShardPrefetched(url: string): boolean; /** The computed SHA-256 (hex) of a warmed shard, if it was verified/hashed. */ declare function getPrefetchedSha256(url: string): string | undefined; /** * Evict warm bytes from the in-memory store. With no argument, clears all. * * Note: this does not delete Cache Storage entries — those persist by design * (that is the cross-reload warmth). Manage the Cache Storage cache directly if * you need to evict it. */ declare function clearPrefetchedShard(url?: string): void; /** * Canonical RecordStore contract — the writable structured-record layer that * exists independently of PGlite (#323, ADR-013 D3). * * Records mirror the browser SQL rows one-to-one (same field names, ISO-8601 * timestamp strings) so the optional PGlite projection is a row-for-row * replay of the change journal — rebuildable at any time without touching * canonical records or attachment bytes. */ interface PresenceTrackedRecord { /** Internal schema-2.0 state; never serialized as a shard component field. */ __fortemi_presence?: ShardPresenceMap; } interface NoteRecord0 extends PresenceTrackedRecord { id: string; archive_id: null | string; title: null | string; format: string; source: string; visibility: string; revision_mode: string; is_starred: boolean; is_pinned: boolean; is_archived: boolean; created_at: string; updated_at: string; deleted_at: null | string; } interface NoteOriginalRecord extends PresenceTrackedRecord { id: string; note_id: string; content: string; content_hash: string; created_at: string; } interface NoteRevisedCurrentRecord extends PresenceTrackedRecord { /** Keyed by note id (mirrors the SQL PK `note_id`). */ id: string; content: null | string; ai_metadata: null | unknown; generation_count: number; model: null | string; is_user_edited: boolean; updated_at: string; } interface NoteTagRecord extends PresenceTrackedRecord { id: string; note_id: string; tag: string; created_at: string; } interface LinkRecord0 extends PresenceTrackedRecord { id: string; source_note_id: string; target_note_id: string; link_type: string; created_at: string; deleted_at: null | string; /** Exact record-v1 shard metadata; internal projection state, not a domain field. */ __fortemi_shard_metadata?: unknown; } interface CollectionRecord extends PresenceTrackedRecord { id: string; name: string; description: null | string; /** Omitted only by legacy schema-v1 callers; built-in stores normalize it to null. */ parent_id?: null | string; created_at: string; updated_at: string; deleted_at: null | string; } interface CollectionNoteRecord extends PresenceTrackedRecord { id: string; collection_id: string; note_id: string; created_at: string; } interface AttachmentRecord extends PresenceTrackedRecord { id: string; note_id: string; blob_id: string; document_type_id: null | string; mime_type: null | string; extracted_text: null | string; filename: string; display_name: null | string; position: number; created_at: string; deleted_at: null | string; /** Exact record-v1 extraction projection state. */ __fortemi_extraction_status?: 'blocked' | 'deferred' | 'extracted' | 'failed' | 'pending'; __fortemi_extraction_reason?: unknown; __fortemi_projection_presence?: ShardPresenceMap; } interface AttachmentBlobRecord extends PresenceTrackedRecord { id: string; content_hash: string; size_bytes: number; created_at: string; } interface ShardManifestRecord extends PresenceTrackedRecord { id: string; manifest: Record; } interface SourceIdentityRecord extends PresenceTrackedRecord { id: string; tenant_id: string; archive_id: null | string; namespace: string; external_id: string; external_id_hash: string; source_schema_version: string; content_digest: string; import_run_id: string; caller_stable_id: null | string; note_id: string; created_at: string; updated_at: string; } interface SourceImportRunRecord extends PresenceTrackedRecord { id: string; tenant_id: string; archive_id: null | string; namespace: string; started_at: string; completed_at: null | string; checkpoint: Record; receipt: Record; } interface DeletionReceiptRecord extends PresenceTrackedRecord { id: string; operation_key: string; tenant_id: string; archive_id: null | string; selector_hash: string; outcome: string; counts: Record; completed_at: string; policy: Record; } /** Collection name → record type. The store is generic over this map. */ interface RecordCollections { note: NoteRecord0; note_original: NoteOriginalRecord; note_revised_current: NoteRevisedCurrentRecord; note_tag: NoteTagRecord; link: LinkRecord0; collection: CollectionRecord; collection_note: CollectionNoteRecord; attachment: AttachmentRecord; attachment_blob: AttachmentBlobRecord; shard_manifest: ShardManifestRecord; source_identity: SourceIdentityRecord; source_import_run: SourceImportRunRecord; deletion_receipt: DeletionReceiptRecord; } type RecordCollectionName = keyof RecordCollections; declare const RECORD_COLLECTIONS: readonly RecordCollectionName[]; /** * One committed mutation. Journal entries carry the full record snapshot so * the PGlite projection (and any other consumer) can replay mutations without * re-reading canonical state, and so a rebuild has a total order to follow. */ interface JournalEntry { /** Monotonically increasing commit sequence (assigned by the store). */ seq: number; /** ISO-8601 commit timestamp. */ ts: string; op: 'delete' | 'put'; collection: RecordCollectionName; id: string; /** Snapshot for `put`; absent for `delete`. */ record?: RecordCollections[RecordCollectionName]; } /** * What the canonical record tier can and cannot serve, reported explicitly * (never emulated badly). Advanced capabilities may require the optional * PGlite projection (ADR-013 D3). */ interface RecordStoreCapabilities { crud: true; journal: true; /** Multi-collection record and journal mutations commit atomically. */ atomicBatch?: true; /** Bounded substring scan over titles/content — not ranked FTS. */ boundedTextScan: true; sourceAddressedUpsert?: true; deletionReceipts?: true; typedMetadataPredicates?: false; evidenceLocators?: true; fullTextSearch: false; vectorSearch: false; sqlJoins: false; } declare const RECORD_STORE_CAPABILITIES: RecordStoreCapabilities; interface RecordListOptions { /** Maximum records returned (applied after filtering). */ limit?: number; } type RecordMutation = { [C in RecordCollectionName]: { collection: C; op: 'put'; record: RecordCollections[C]; }; }[RecordCollectionName] | { collection: RecordCollectionName; id: string; op: 'delete'; }; /** * The writable canonical structured-record store. Implementations MUST make * each `put`/`remove` an atomic commit of the record mutation plus its * journal entry (the recoverable commit protocol): a torn write leaves * neither, never one without the other. */ interface RecordStore { get(collection: C, id: string): Promise; /** Insert or replace one record, journaled atomically. */ put(collection: C, record: RecordCollections[C]): Promise; /** Hard-remove one record, journaled atomically (soft-delete is a field upstream). */ remove(collection: RecordCollectionName, id: string): Promise; /** * Commit all record mutations and their journal entries as one transaction. * An error leaves both record state and the journal unchanged. */ applyBatch?(mutations: readonly RecordMutation[]): Promise; /** All records of a collection (insertion order not guaranteed). */ list(collection: C, opts?: RecordListOptions): Promise; /** Journal entries with `seq > sinceSeq`, ascending. */ journalSince(sinceSeq: number, limit?: number): Promise; /** Highest committed sequence (0 when empty). */ headSeq(): Promise; readonly capabilities: RecordStoreCapabilities; close(): Promise; } /** * In-memory RecordStore — the test/SSR tier of the canonical record layer. * Same commit semantics as the durable store: record + journal move together. */ declare class MemoryRecordStore implements RecordStore { readonly capabilities: RecordStoreCapabilities; private collections; private journal; private seq; private table; get(collection: C, id: string): Promise; put(collection: C, record: RecordCollections[C]): Promise; remove(collection: RecordCollectionName, id: string): Promise; applyBatch(mutations: readonly RecordMutation[]): Promise; list(collection: C, opts?: RecordListOptions): Promise; journalSince(sinceSeq: number, limit?: number): Promise; headSeq(): Promise; close(): Promise; } /** * Durable canonical RecordStore over IndexedDB (#323, ADR-013 D3). * * One database per archive namespace: `fortemi--records`. Object * stores: one per record collection (keyPath `id`), plus `journal` * (autoIncrement `seq`) and `meta` (schema version). * * Recoverable commit protocol (ADR-013 D5): every mutation writes the record * change AND its journal entry in a single IndexedDB transaction, so a torn * write commits neither. The journal `seq` is the total order the optional * PGlite projection consumes. * * Schema evolution: `meta.schemaVersion` records the logical record-schema * version; `migrate` hooks run inside the version-change transaction when the * database structure grows. Additive-only, mirroring the SQL migration * discipline. */ /** Logical record-schema version stored in `meta` (independent of DB_VERSION). */ declare const RECORD_SCHEMA_VERSION = 2; interface CreateRecordStoreOptions { /** Injectable factory for tests (fake-indexeddb). Defaults to the global. */ indexedDB?: IDBFactory; } declare class IdbRecordStore implements RecordStore { private db; readonly capabilities: RecordStoreCapabilities; private constructor(); static open(archiveName: string, options?: CreateRecordStoreOptions): Promise; private ensureSchemaVersion; get(collection: C, id: string): Promise; put(collection: C, record: RecordCollections[C]): Promise; remove(collection: RecordCollectionName, id: string): Promise; applyBatch(mutations: readonly RecordMutation[]): Promise; list(collection: C, opts?: RecordListOptions): Promise; journalSince(sinceSeq: number, limit?: number): Promise; headSeq(): Promise; close(): Promise; } /** Open the durable canonical record store for one archive namespace. */ declare function createRecordStore(archiveName: string, options?: CreateRecordStoreOptions): Promise; /** * Canonical notes repository — DB-free note/tag/link/collection workflows * over the RecordStore (#323). Mirrors the SQL repositories' semantics * (UUIDv7 ids, immutable note_original, mutable note_revised_current, * soft-delete everywhere) so the PGlite projection replay is row-for-row. * * Query tier: id/recent/tag/link/collection lookups plus a bounded substring * text scan. Ranked FTS, vectors, and complex joins are explicitly NOT * served here — `store.capabilities` reports the boundary (ADR-013 D3). */ interface CanonicalNoteCreateInput { id?: string; title?: string; content: string; format?: string; source?: string; visibility?: string; } interface CanonicalNoteUpdateInput { title?: string; content?: string; format?: string; visibility?: string; is_starred?: boolean; is_pinned?: boolean; is_archived?: boolean; } interface CanonicalNoteView { note: NoteRecord0; original_content: string; revised_content: string; tags: string[]; } declare class CanonicalNotesRepository { private store; constructor(store: RecordStore); create(input: CanonicalNoteCreateInput): Promise; get(noteId: string): Promise; update(noteId: string, input: CanonicalNoteUpdateInput): Promise; /** Soft-delete: sets `deleted_at`; the record (and history) remains. */ softDelete(noteId: string): Promise; restore(noteId: string): Promise; /** Non-deleted notes, most recently updated first. */ listRecent(limit?: number): Promise; /** * Bounded substring scan over title + revised content (case-insensitive). * This is deliberately not ranked FTS — see `store.capabilities`. */ searchText(query: string, limit?: number): Promise; addTag(noteId: string, tag: string): Promise; removeTag(noteId: string, tag: string): Promise; notesByTag(tag: string): Promise; createLink(sourceNoteId: string, targetNoteId: string, linkType?: string): Promise; softDeleteLink(linkId: string): Promise; /** Active links touching a note (either direction). */ linksOf(noteId: string): Promise; createCollection(name: string, description?: string, parentId?: null | string): Promise; addNoteToCollection(collectionId: string, noteId: string): Promise; notesInCollection(collectionId: string): Promise; } /** * Canonical attachments repository — DB-free attachment manifests over the * RecordStore, bytes through the Bytecask BlobStore (#323, ADR-013 D2/D4/D5). * * Same lifecycle semantics as the SQL-backed AttachmentsRepository: bytes * first (idempotent put), then manifest commit; soft-delete never removes * bytes inline; the manifest-derived live set drives reconcile/gc; missing * bytes are the recoverable reference-only state. */ interface CanonicalAttachInput { noteId: string; data: Uint8Array; filename: string; mimeType?: string; extractedText?: string; displayName?: string; } declare class CanonicalAttachmentsRepository { private store; private blobStore; constructor(store: RecordStore, blobStore: BlobStore); /** Bytes-first attach (ADR-013 D5); dedupes on the store-computed hash. */ attach(input: CanonicalAttachInput): Promise; get(id: string): Promise; /** Null when bytes are absent — the recoverable reference-only state. */ getBlob(attachmentId: string): Promise; hasBlob(attachmentId: string): Promise; list(noteId: string): Promise; /** Soft-delete the manifest; bytes are only swept via reconcile/gc. */ delete(id: string): Promise; /** Authoritative live set: hashes referenced by non-deleted manifests. */ liveBlobChecksums(): Promise; /** Startup / post-quota reconciliation against canonical manifests (ADR-013 D4). */ reconcileBlobs(opts?: BlobReconcileOptions): Promise; /** Deferred reachability-based blob GC. */ gcBlobs(opts?: BlobGcOptions): Promise; private checksumOf; } /** * PGlite attachment projection (#320, ADR-013 D3). * * Projects canonical attachment state (RecordStore) into the optional PGlite * `attachment_blob` / `attachment` tables. Properties: * * - Idempotent: every row upserts on its primary key; re-running with the * same canonical state changes nothing. * - Rebuildable: dropping the projection rows and re-projecting yields * equivalent query results — the canonical records are the source of truth. * - Derived refcounts: `attachment_blob.reference_count` is recomputed from * live manifests on every projection pass; it is never lifecycle authority * and no trigger touches it. * - Bytes never enter PGlite; only metadata is projected. */ interface AttachmentProjectionResult { blobs: number; attachments: number; } /** * Project all canonical attachment records into PGlite. Safe to run at any * time: startup, after journal consumption, or as a full rebuild after the * projection was dropped. * * The parent `note` rows must already exist in the projection (note * projection is the #323 cycle-2 surface); this function owns only the * attachment tables. */ declare function projectAttachments(db: DatabaseClient, store: RecordStore): Promise; /** * Drop the attachment projection rows (test/rebuild support). Canonical * records and Bytecask bytes are untouched — this is the "PGlite can be * dropped and rebuilt" invariant made executable. */ declare function dropAttachmentProjection(db: DatabaseClient): Promise; /** * PGlite record projection — notes tier (#323 cycle 2, ADR-013 D3). * * Projects canonical note / tag / link / collection state (RecordStore) into * the optional PGlite tables, completing the projection the attachment tier * (#320, attachment-projection.ts) deferred to this cycle. Properties: * * - Idempotent: rows upsert on their primary keys; re-running with the same * canonical state changes nothing. * - Rebuildable: dropping the projection rows and re-projecting yields * equivalent query results — canonical records are the source of truth. * - Reconciling: canonically hard-removed rows (note_tag, collection_note) * are deleted from the projection so parity holds after removals, not just * after inserts. * - Bytes never enter PGlite; `projectRecords` composes this pass with the * attachment projection for a full canonical → PGlite rebuild. */ interface NoteProjectionResult { notes: number; tags: number; links: number; collections: number; memberships: number; } interface RecordProjectionResult extends NoteProjectionResult { attachments: AttachmentProjectionResult; } /** * Project all canonical note-tier records into PGlite. Safe to run at any * time: startup, after journal consumption, or as a full rebuild after the * projection was dropped. Parent rows land before children (note before * note_original / tags / links / memberships) so FKs hold. */ declare function projectNotes(db: DatabaseClient, store: RecordStore): Promise; /** * Full canonical → PGlite projection: note tier, then attachment tier * (parents before children). This is the "PGlite is a derived, rebuildable * projection" invariant (#322 acceptance) made executable. */ declare function projectRecords(db: DatabaseClient, store: RecordStore): Promise; /** * Drop the note-tier projection rows (test/rebuild support). Canonical * records are untouched. Callers must drop dependent projections first * (attachments via `dropAttachmentProjection`, plus any embedding/SKOS rows * created outside the canonical tier) so FKs allow the deletes. */ declare function dropNoteProjection(db: DatabaseClient): Promise; /** * Writable non-PGlite `DataBackend` over the canonical RecordStore * (#323 cycle 2, ADR-013 D3) — the record tier in the backend seam. * * Fills the seam's historical gap: the static shard backend is read-only and * the PGlite backend needs a database. This adapter serves the canonical * repositories' full write surface plus the bounded read tier (id / recent / * tag / link lookups and a bounded substring scan) with instant startup. * * Capability boundary, reported honestly: `semantic: 'none'` (no vectors) and * search is a bounded scan, not ranked FTS. SKOS concepts and provenance * edges are not part of the canonical record collections, so `conceptsOf` / * `provenanceOf` are deliberately absent — callers feature-detect via the * optional methods rather than receiving silently empty emulations. * `merge: true` is served by `importShardToRecords` (record-shard.ts). */ interface RecordBackendOptions { id?: string; } interface RecordBackendManageNoteResult { action: string; note_id: string; note?: CanonicalNoteView; } /** * Wrap a canonical `RecordStore` as a writable `DataBackend`. Reads and * writes delegate to `CanonicalNotesRepository`; `manageNote` accepts the * same Zod-validated input as the PGlite tool (update / delete / restore / * archive / unarchive / star / unstar). */ declare function createRecordBackend(store: RecordStore, options?: RecordBackendOptions): DataBackend; /** * DB-free Knowledge Shard export/import over the canonical RecordStore * (#323 cycle 2, ADR-013 D3/D6) — the same `.shard` archive format as the * PGlite pipeline (`shard/shard-export.ts` / `shard/shard-import.ts`), built * from and applied to canonical records with zero PGlite. * * Capability boundary (reported, never emulated): the canonical tier holds * notes, tags, note-to-note links, collections, and attachment manifests. * Shard components outside that set (templates, embeddings, SKOS, provenance, * graph/community artifacts, URL links) are skipped on import with explicit * warnings, and are never emitted on export. * * Atomicity: manifest, version, signature (ADR-014 verify-before-persist), * and checksum validation all run before mutation. Verified sidecar bytes are * promoted with rollback, then every record and journal mutation commits in * one multi-collection RecordStore batch. * * @implements @.aiwg/adrs/ADR-011-shard-server-conformance-and-version-negotiation.md * @depends @packages/core/src/shard/schema-validator.ts * @created 2026-07-17 * @agent Codex */ declare function exportShardFromRecordsWithReport(store: RecordStore, options: ExportOptions & { profile: string; }): Promise; /** * Export canonical records as a `.shard` archive (Uint8Array), format-parity * with the PGlite `exportShard`. Honored options: `collectionId` / `tag` * filters, `clusterNotesSize`, and the portable byte sidecar * (`includeBlobs` + `blobStore`). Embedding options are inert — the canonical * tier stores no embeddings, so there is nothing to include. */ declare function exportShardFromRecords(store: RecordStore, options?: ExportOptions): Promise; /** * Import a `.shard` archive into the canonical RecordStore (and optionally * hydrate attachment bytes into a Bytecask BlobStore) with zero PGlite. * * Honors `conflictStrategy` (`skip` default / `replace` / `error` — `error` * conflicts are pre-scanned so nothing is written), the ADR-014 * `verifySignature`/`trustStore` policy, and byte-sidecar hydration via * `blobStore`. Components the canonical tier cannot persist are skipped with * explicit warnings and reported under `skipped`. */ declare function importShardToRecords(store: RecordStore, data: ArrayBuffer | Uint8Array, options?: ImportOptions): Promise; declare function upsertRecordStoreSources(store: RecordStore, items: readonly SourceUpsertItem[], options?: SourceUpsertOptions): Promise; declare function previewRecordStorePurge(store: RecordStore, selector: PurgeSelector): Promise; declare function purgeRecordStoreGraph(store: RecordStore, selector: PurgeSelector, operationKey: string): Promise; /** * @implements @.aiwg/adrs/ADR-011-shard-server-conformance-and-version-negotiation.md * @source @packages/core/src/shard/schema-validator.ts * @created 2026-07-17 * @agent Codex */ declare const VERSION = "2026.8.0"; export { type ArchiveInfo, ArchiveManager, type AttachInput, type AttachmentBlobRecord, type AttachmentBlobRow, type AttachmentProjectionResult, type AttachmentRecord, type AttachmentRow, AttachmentsRepository, type BackendCandidate, type BackendCapabilities, type BackendConcept, type BackendLink, type BackendListOptions, type BackendNote, type BackendNoteFull, type BackendProvenanceEdge, type BackendRequest, type BackendSearchHit, type BackendSearchQueryOptions, type BackendSearchResult, type BackendSelection, type BackendSemanticTier, type BackendStartupCost, BlobGcOptions, BlobGcResult, BlobReconcileOptions, BlobReconcileResult, BlobStore, type BridgeCapability, type BridgeProviderInfo, type BrowserNoteExport, CORE_V1_COMPONENTS, CURRENT_MIGRATION_HEAD, type CanonicalAttachInput, CanonicalAttachmentsRepository, type CanonicalNoteCreateInput, type CanonicalNoteUpdateInput, type CanonicalNoteView, CanonicalNotesRepository, type CapabilityInfo, CapabilityManager, type CapabilityName, type CapabilityState, type CaptureKnowledgeInput, CaptureKnowledgeInputSchema, type CaptureKnowledgeResult, type CollectionCreateInput, type CollectionNoteRecord, type CollectionRecord, type CollectionRow, CollectionsRepository, CommunitiesRepository, type CommunityAssignmentView, type CommunityCreateInput, type CommunityFilterDefinition, type CommunityGraph, type CommunityOptions, type CommunitySourceDescriptor, type CommunitySourceType, type CommunitySummary, type CompletionRequest, type CompletionResponse, type ConditionResult, type CooldownConfig, type CooldownEvent, type CosineSemanticProviderOptions, type CreatePGliteOptions, type CreateRecordStoreOptions, type CspDirectiveName, type CspDirectives, type CspViolationReport, DB_SNAPSHOT_SCHEMA_VERSION, type DataBackend, type DatabaseClient, type DbSnapshot, type DbSnapshotCompat, type DbSnapshotCompression, type DbSnapshotExpectations, type DbSnapshotMeta, type DbSnapshotSource, DbSnapshotVersionError, type DeletionReceipt, type DeletionReceiptRecord, type DiscoveredProvider, type DiscoveryOptions, type DumpDbSnapshotOptions, type DumpableDb, EMBED_REQUEST_KIND, EMBED_RESPONSE_KIND, type EmbedFunction, type EmbedRequest, type EmbedRequestMessage, type EmbedResponse, type EmbedResponseMessage, type EmbedTransportPort, type EmbedWorkerOptions, type EmbeddingCompatibilityPolicy, type EmbeddingSetCreateInput, type EmbeddingSetCriteria, type EmbeddingSetDescriptor, type EmbeddingSetEmbeddingInput, type EmbeddingSetFreshness, type EmbeddingSetKind, type EmbeddingSetMode, type EmbeddingSetRow, type EmbeddingSetSelector, EmbeddingSetsRepository, type EnqueueJobInput, type ErrorCategory, type EventMap, type EvidenceLocator, ExportOptions, FORTEMI_COMPATIBILITY_PATH, FORTEMI_COMPATIBILITY_STATES, FORTEMI_REQUIRED_COMPATIBILITY_CAPABILITIES, FORTEMI_SERVER_COMPATIBILITY_REVISION, type FallbackEvent, FallbackRouter, type FallbackRouterConfig, type FetchFortemiCompatibilityOptions, type FortemiBridge, type FortemiBridgeCapabilities, type FortemiBridgeHost, type FortemiCompatibilityCapability, type FortemiCompatibilityResponse, type FortemiCompatibilityState, type FortemiCompatibilityValidationResult, type FortemiConfig, type FortemiCore, type FortemiInferenceRouter, type FortemiRequiredCompatibilityCapability, type FortemiSecretStore, type FortemiToolDefinition, FortemiToolManifest, type GetNoteInput, GetNoteInputSchema, type GpuCapabilities, type GraphCommunity, type GraphEdge, type GraphNode, GraphRepository, type IDisposable, IdbRecordStore, ImportOptions, ImportResult, type InferenceCapabilities, type InferenceProvider, JOB_CAPABILITIES, JOB_PRIORITIES, type JobQueueOptions, JobQueueWorker, type JobStatus, type JobType, type JournalEntry, LOCAL_ENDPOINTS, type LegacyMigrationReport, LifecyclePurgeRepository, type LinkRecord0, type LinkRow, LinksRepository, type ListNotesInput, ListNotesInputSchema, type LlmCapabilityOptions, type LlmCompleteFn, type LoadedPluginScript, type LocalEndpoint, type ManageArchiveInput, ManageArchiveInputSchema, type ManageArchiveResult, type ManageAttachmentsInput, ManageAttachmentsInputSchema, type ManageAttachmentsResult, type ManageCapabilitiesInput, ManageCapabilitiesInputSchema, type ManageCapabilitiesResult, type ManageCollectionsInput, ManageCollectionsInputSchema, type ManageCollectionsResult, type ManageLinksInput, ManageLinksInputSchema, type ManageLinksResult, type ManageNoteInput, ManageNoteInputSchema, type ManageNoteResult, type ManageTagsInput, ManageTagsInputSchema, type ManageTagsResult, MemoryRecordStore, type MetadataPredicate, type Migration, MigrationRunner, type ModelCategory, type ModelFitResult, type ModelInfo, type NoteCreateInput, type NoteFull, type NoteListOptions, type NoteOriginalRecord, type NoteProjectionResult, type NoteRecord0, type NoteRevisedCurrentRecord, type NoteRevision, type NoteSkosTag, type NoteSummary, type NoteTagRecord, type NoteUpdateInput, NotesRepository, OpenAICompatibleProvider, type OpenAIProviderConfig, type OpenShardOptions, type PGliteBackendOptions, PGliteStorageBackend, PGliteStorageBackendFactory, PGliteWorkerClient, PGliteWorkerStorageBackend, PGliteWorkerStorageBackendFactory, type PGliteWorkerStorageBackendFactoryOptions, type PaginatedResult, type PersistenceMode, type PluginCspOptions, type PluginScriptDescriptor, type PluginScriptPolicy, type PrefetchOptions, type PrefetchResult, type PresenceTrackedRecord, type ProbeResult, type ProbeStatus, type ProvenanceEdge, ProvenanceRepository, type ProviderCapabilities, ProviderRegistry, type ProviderTier, type PurgeCounts, type PurgePreview, type PurgeSelector, type QueryExecutor, type QueryResult, RECORD_COLLECTIONS, RECORD_SCHEMA_VERSION, RECORD_STORE_CAPABILITIES, REGISTERED_METADATA_PATHS, type RecommendedTier, type RecordBackendManageNoteResult, type RecordBackendOptions, type RecordCollectionName, type RecordCollections, type RecordListOptions, type RecordMutation, type RecordProjectionResult, type RecordProvenanceInput, type RecordStore, type RecordStoreCapabilities, type RegisteredMetadataPath, type RemoteBackendConfig, type RemoteBackendPaths, type ResolvedEmbeddingRow, type ResolvedEmbeddingSet, type RestoreDbSnapshotOptions, type RouteHandler, SUPPORTED_PGLITE_VERSION, type SWRegistrationResult, type SearchFacets, type SearchInput, SearchInputSchema, type SearchOptions, SearchRepository, type SearchResponse, type SearchResult, ShardBackend, type ShardBackendOptions, ShardCapabilityReport, ShardCollection, ShardComponent, type ShardComponentStore, ShardEmbedding, ShardEmbeddingConfig, ShardEmbeddingSet, ShardEmbeddingSetMember, ShardExportResult, ShardLink, type ShardListOptions, ShardLossEntry, ShardManifest, ShardNote, type ShardNoteFull, ShardNoteSkosTag, ShardOperation, ShardProfileRegistryEntry, ShardProvenanceEdge, type ShardReader, type ShardReaderNote, type ShardReaderSource, type ShardSchemaValidationResult, type ShardSearchOptions, type ShardSearchRankedNote, type ShardSearchResult, type ShardSearchWeights, ShardSkosConcept, ShardSkosRelation, ShardSkosScheme, ShardTag, ShardTemplate, type SimilarityGraphCacheKey, type SimilarityGraphOptions, type SimilarityGraphRequest, type SimilarityGraphResult, type SkosConcept, type SkosRelation, SkosRepository, type SkosScheme, type SourceIdentityInput, type SourceIdentityRecord, type SourceImportRunRecord, type SourceUpsertBatchResult, type SourceUpsertItem, type SourceUpsertItemResult, type SourceUpsertOptions, type SourceUpsertOutcome, type SourceUpsertPolicy, SourceUpsertRepository, type StaticSemanticProvider, type StorageBackend, type StorageBackendFactory, type StorageOpenRequest, type StorageTopology, type StreamChunk, TagsRepository, TransactionProxy, TypedEventBus, VERSION, type VectorEntry, type VirtualEmbeddingSetDefinition, type VirtualEmbeddingSetSource, type VirtualEmbeddingSetValidationError, type VirtualMaterializationPolicy, type VramTier, type WorkerRequest, type WorkerResponse, aiRevisionHandler, allMigrations, appendPluginScript, assertShardComponentRecord, buildMetadataPredicateConditions, buildNoteConditions, buildPluginCsp, captureKnowledge, chunkText, classifyError, classifyModel, clearPrefetchedShard, collectionFromShard, collectionToShard, computeBlobHash, computeHash, computeSri, conceptTaggingHandler, cosineSimilarity, createCosineSemanticProvider, createCspReportHandler, createFortemi, createLegacyProvider, createPGliteBackend, createPGliteInstance, createRecordBackend, createRecordStore, createRemoteBackend, createRoutes, createShardBackend, createShardCapabilityReport, createWorkerEmbedFunction, defaultStorageBackendFactory, detectCommunities, detectGpuCapabilities, detectInferenceCapabilities, discoverLocalProviders, dropAttachmentProjection, dropNoteProjection, dumpDbSnapshot, embeddingConfigToShard, embeddingFromShard, embeddingGenerationHandler, embeddingSetFromShard, embeddingSetMemberToShard, embeddingSetToShard, embeddingToShard, enqueueFullWorkflow, enqueueJob, enqueueNoteCreationJobs, estimateModelFit, estimateVramMB, estimateVramTier, exportShard, exportShardFromRecords, exportShardFromRecordsWithReport, exportShardWithReport, fetchAndValidateFortemiCompatibility, fetchPluginScript, formatFortemiCompatibilitySummary, fortemiCompatibilityUrl, fortemiManifest, fromPrefetched, generateId, getEmbedFunction, getFortemiBridge, getFortemiSecretStore, getJobQueueStatus, getKnowledgeShardContractReceipt, getKnowledgeShardProfileRegistry, getKnowledgeShardSchema, getLlmFunction, getNote, getPrefetchedSha256, handleEmbedRequests, hasFortemiSecureSecrets, importShard, importShardToRecords, isPluginScriptAllowed, isShardPrefetched, linkFromShard, linkToShard, linkingHandler, listNotes, manageArchive, manageAttachments, manageCapabilities, manageCollections, manageLinks, manageNote, manageTags, matchRoute, migrateLegacyBlobStore, noteFromShard, noteSkosTagToShard, noteToShard, openShard, packTarGz, parseCspReport, prefetchShard, previewRecordStorePurge, profileSupportError, projectAttachments, projectNotes, projectRecords, provenanceEdgeToShard, purgeRecordStoreGraph, registerLlmCapability, registerSemanticCapability, registerSemanticCapabilityWorker, registerServiceWorker, restoreDbSnapshot, searchTool, selectBackend, selectLlmModel, setEmbedFunction, setLlmFunction, sha256Hex, skosConceptToShard, skosRelationToShard, skosSchemeToShard, suggestTags, tagsToShard, templateToShard, titleGenerationHandler, unpackTarGz, unregisterLlmCapability, unregisterSemanticCapability, upsertRecordStoreSources, urlLinkToShard, validateChecksums, validateCoreV1ShardArchive, validateFortemiCompatibilityResponse, validateFullV1ShardArchive, validateRecordV1ShardArchive, validateShardArchive, validateShardComponentRecord, validateShardManifest, verifyDbSnapshotMeta, verifySri };